深入理解物联网:LoRa简明解析及其实际应用实例
物联网的端点网通传输技术,有许多技术方案可以选择,除了lora以外,还有NB-IoT、WiFi、蓝牙、zigbee、Dustl和sub-1GHz等,不同的通讯技术有着不同的特点,也各有适合自己的应用场景。但是对于长距离,低功耗,只有少量数据需要传输的应用场景,目前还没有能更满足上述需求的无线通信技术,这也就是LoRa技术诞生的原因。
举例来说,NB-IoT适合用在实时、大数据量的传输;LoRa则适合用在小数据量、定期、大范围、低功耗需求的管理。
建设物联网应用,必须完整审慎目的与需求,决定正确的传输技术,不能求神问卜凭感觉。选择拥有多元能力与实务的厂商,才能让物联网架构发挥预期效益。
LoRa,它究竟是什么?
LoRa联盟是一个开放的非营利组织,它在北美,欧洲,非洲和亚洲拥有约400家会员公司,其创始成员包括IBM,MicroChip,思科,Semtech, Singtel,KPN,Swisscom,Fastnet和Belgacom。
LoRa就是LongRange的简称,它是应用在物联网的低功耗广域网传输技术,就像丝丝有3种,LoRa一样有3种,可以应对不同的使用目的,分别是Class A(Baseline,基本定时传输用,强调省电)、Class B(Beacon,除基本传输功能外,增加触发性传输能力)、Class C(提供持续传输功能)。
LoRa具备符合物联网应用的三大特色.
第一大特色,是最远15公里的传输距离。
第二大特色是低功耗,一颗钮扣电池可以让感测节点运作1年。
第三大特色是低成本,免牌照的频段、基础设施以及节点/终端的低成本让网络建设运维都十分容易。
不管是智慧城市、工商业管理、农林渔牧,都是LoRa在物联网环境下的智能应用场域。
LoRa低功耗广域网技术究境可以如何改善我们的生活和工作呢?透过下例的实务应用来说给你听。
在智慧城市应用方面,道路旁若使用了智慧路灯,就可以透过LoRa传送灯具灯泡使用状况,及时通知养护单位进行保养维修与更换灯泡。
在智能家居方面,智能电表∕水表若是结合了LoRa传输,不但省下人力抄表费用,更可在异常情况时提供警示,让屋主掌握用水用电情况,避免浪费。
智能停车场在车位上布建LoRa传感器时,安装过程不用拉线,节省大量施工成本;1个LoRa网关即可管理数百个车位的LoRa传感器,实时监控车位状况,全面控管车位使用情形。
水库可以用LoRa传感器,监测水位变化;河川水道可用LoRa传感器,监控大雨或干旱时的水位异常,提供防洪管理。
在智慧建筑方面,以往的建筑设备渐渐无法满足人类对于居住质量的要求,建筑智能化已蔚为趋势。对于建筑的改造,加入温湿度以及安全等传感器,并定时地将监测的讯息上传,便于建筑管理者的监管,随时掌握建筑的最新状况。
在智慧消防方面,消防救灾工作以及火场逃生,两者都是分秒必争。现有的消防设备于火灾发生时能达到的效果有限。以逃生指示号志为例,静态的指示信号无法应对火场的变化,实时告诉避难者正确的逃生方向,往往耽误了逃生的时间。动态导引系统利用LoRa无线传输技术远距离、低频以及低功耗的特性,在火灾发生时,由动态导引主机发送讯号给布建于建筑物内的动态导引灯板,由于LoRa走的是低于1GHz以下的低频段,因此不用担心讯号受到其他无线通信的干扰,灯板在收到讯号后,会立即做出指示,引导避难者前往安全的逃生路径。
在智慧农业方面,对农业来说,低功耗及低成本的的传感器是十分重要的。智慧农业就是将物联网技术运用于传统农业,将温、湿度以及盐碱度等环境数据透过传感器定期上传,这些信息可以有效帮助农业提高产量以及减少水资源的消耗。
在物流追踪方面,终端的电池使用寿命对于追踪或是定位都十分重要,由于追踪系统的成本以及电池续航都必须纳入考虑,因此相当适合利用LoRa技术进行追踪。物流企业可以根据定位的需要在特定的场所布网,例如,在运送过程中,货品有大部分的时间会被放置在仓库,或是透过卡车分送至各地,所以业者只需要在仓库、物流网涵盖区,甚至是货车上装设LoRa网关,就能让货品上的追踪器连至网络。对于业者来说,加强了管理与效率,并能避免货品遗失 ; 对消费者而言,也能发挥掌握货品流向以及时程的功效。
共享单车服务与管理最近成为话题,若是在共享单车上安装LoRa传感器,就可以利用城市中的LoRa网关∕基地台,运用三角定位的计算原理,当握车辆位置,方便管理。
除了智慧城市领域的应用外,在农林、畜牧、工商业应用中,LoRa技术都能协助建构物联网应用,等待大家一起来实现物联网下的智慧生活。
本文转自d1net(转载)
推荐阅读
-
深入理解物联网:LoRa简明解析及其实际应用实例
-
【Netty】「萌新入门」(七)ByteBuf 的性能优化-堆内存的分配和释放都是由 Java 虚拟机自动管理的,这意味着它们可以快速地被分配和释放,但是也会产生一些开销。 直接内存需要手动分配和释放,因为它由操作系统管理,这使得分配和释放的速度更快,但是也需要更多的系统资源。 另外,直接内存可以映射到本地文件中,这对于需要频繁读写文件的应用程序非常有用。 此外,直接内存还可以避免在使用 NIO 进行网络传输时发生数据拷贝的情况。在使用传统的 I/O 时,数据必须先从文件或网络中读取到堆内存中,然后再从堆内存中复制到直接缓冲区中,最后再通过 SocketChannel 发送到网络中。而使用直接缓冲区时,数据可以直接从文件或网络中读取到直接缓冲区中,并且可以直接从直接缓冲区中发送到网络中,避免了不必要的数据拷贝和内存分配。 通过 ByteBufAllocator.DEFAULT.directBuffer 方法来创建基于直接内存的 ByteBuf: ByteBuf directBuf = ByteBufAllocator.DEFAULT.directBuffer(16); 通过 ByteBufAllocator.DEFAULT.heapBuffer 方法来创建基于堆内存的 ByteBuf: ByteBuf heapBuf = ByteBufAllocator.DEFAULT.heapBuffer(16); 注意: 直接内存是一种特殊的内存分配方式,可以通过在堆外申请内存来避免 JVM 堆内存的限制,从而提高读写性能和降低 GC 压力。但是,直接内存的创建和销毁代价昂贵,因此需要慎重使用。 此外,由于直接内存不受 JVM 垃圾回收的管理,我们需要主动释放这部分内存,否则会造成内存泄漏。通常情况下,可以使用 ByteBuffer.clear 方法来释放直接内存中的数据,或者使用 ByteBuffer.cleaner 方法来手动释放直接内存空间。 测试代码: public static void testCreateByteBuf { ByteBuf buf = ByteBufAllocator.DEFAULT.buffer(16); System.out.println(buf.getClass); ByteBuf heapBuf = ByteBufAllocator.DEFAULT.heapBuffer(16); System.out.println(heapBuf.getClass); ByteBuf directBuf = ByteBufAllocator.DEFAULT.directBuffer(16); System.out.println(directBuf.getClass); } 运行结果: class io.netty.buffer.PooledUnsafeDirectByteBuf class io.netty.buffer.PooledUnsafeHeapByteBuf class io.netty.buffer.PooledUnsafeDirectByteBuf 池化技术 在 Netty 中,池化技术指的是通过对象池来重用已经创建的对象,从而避免了频繁地创建和销毁对象,这种技术可以提高系统的性能和可伸缩性。 通过设置 VM options,来决定池化功能是否开启: -Dio.netty.allocator.type={unpooled|pooled} 在 Netty 4.1 版本以后,非 Android 平台默认启用池化实现,Android 平台启用非池化实现; 这里我们使用非池化功能进行测试,依旧使用的是上面的测试代码 testCreateByteBuf,运行结果如下所示: class io.netty.buffer.UnpooledByteBufAllocator$InstrumentedUnpooledUnsafeDirectByteBuf class io.netty.buffer.UnpooledByteBufAllocator$InstrumentedUnpooledUnsafeHeapByteBuf class io.netty.buffer.UnpooledByteBufAllocator$InstrumentedUnpooledUnsafeDirectByteBuf 可以看到,ByteBuf 类由 PooledUnsafeDirectByteBuf 变成了 UnpooledUnsafeDirectByteBuf; 在没有池化的情况下,每次使用都需要创建新的 ByteBuf 实例,这个操作会涉及到内存的分配和初始化,如果是直接内存则代价更为昂贵,而且频繁的内存分配也可能导致内存碎片问题,增加 GC 压力。 使用池化技术可以避免频繁内存分配带来的开销,并且重用池中的 ByteBuf 实例,减少了内存占用和内存碎片问题。另外,池化技术还可以采用类似 jemalloc 的内存分配算法,进一步提升分配效率。 在高并发环境下,池化技术的优点更加明显,因为内存的分配和释放都是比较耗时的操作,频繁的内存分配和释放会导致系统性能下降,甚至可能出现内存溢出的风险。使用池化技术可以将内存分配和释放的操作集中到预先分配的池中,从而有效地降低系统的内存开销和风险。 内存释放 当在 Netty 中使用 ByteBuf 来处理数据时,需要特别注意内存回收问题。 Netty 提供了不同类型的 ByteBuf 实现,包括堆内存(JVM 内存)实现 UnpooledHeapByteBuf 和堆外内存(直接内存)实现 UnpooledDirectByteBuf,以及池化技术实现的 PooledByteBuf 及其子类。 UnpooledHeapByteBuf:通过 Java 的垃圾回收机制来自动回收内存; UnpooledDirectByteBuf:由于 JVM 的垃圾回收机制无法管理这些内存,因此需要手动调用 release 方法来释放内存; PooledByteBuf:使用了池化机制,需要更复杂的规则来回收内存; 由于池化技术的特殊性质,释放 PooledByteBuf 对象所使用的内存并不是立即被回收的,而是被放入一个内存池中,待下次分配内存时再次使用。因此,释放 PooledByteBuf 对象的内存可能会延迟到后续的某个时间点。为了避免内存泄漏和占用过多内存,我们需要根据实际情况来设置池化技术的相关参数,以便及时回收内存; Netty 采用了引用计数法来控制 ByteBuf 对象的内存回收,在博文 「源码解析」ByteBuf 的引用计数机制 中将会通过解读源码的形式对 ByteBuf 的引用计数法进行深入理解; 每个 ByteBuf 对象被创建时,都会初始化为1,表示该对象的初始计数为1。 在使用 ByteBuf 对象过程中,如果当前 handler 已经使用完该对象,需要通过调用 release 方法将计数减1,当计数为0时,底层内存会被回收,该对象也就被销毁了。此时即使 ByteBuf 对象还在,其各个方法均无法正常使用。 但是,如果当前 handler 还需要继续使用该对象,可以通过调用 retain 方法将计数加1,这样即使其他 handler 已经调用了 release 方法,该对象的内存仍然不会被回收。这种机制可以有效地避免了内存泄漏和意外访问已经释放的内存的情况。 一般来说,应该尽可能地保证 retain 和 release 方法成对出现,以确保计数正确。