提示1:锐米所有 LoRa 产品严格遵循国标标准的 LoRaWAN 协议。
提示2:您可以免费复制,修改和商用本项目,请注明锐米原创。
提示3:如果您有其他 LoRa 需求或建议,欢迎联系锐米 [email protected]
测量电池电压,计算电池容量,基于 LoRa 传送到服务器,App 可实时演示。
LoRa LoRaWAN Arduino 物联网 开源设计
LoRa 扩展板 x 1 采购链接
Arduino Pro Mini x 1 采购链接
电池盒 x 1 采购链接
杜邦线 x 6 采购链接
下载烧录器 采购链接
数字万用表 采购链接
LoRaServer 下载链接
LoRaApp 下载链接
Arduino IDE 下载链接
超过 80% 的 LoRa 终端基于电池供电,尽管我们最大化降低功耗,然而电池终将有耗尽的那一天。计算电池容量,对于 LoRa 终端的维保意义重大。
相比传统的检测技术,LoRa 检测电池容量的优点为:
本项目开源设计 LoRa检测电池容量的核心—软件和硬件,用户可以直接使用在自己的 LoRa 终端产品中。
同时,简介了 LoRa 网络组件,轻松构建一个商用的物联网。
这是专为 Arduino 而设计的 LoRa 扩展板,既可以安装在 Arduino UNO 上,也能使用杜邦线连接到 Arduino Pro Mini。
它能达到空旷 10km 的通信距离,休眠电流仅 1.3uA。精心设计的软件库,使其开发极为容易:
LoRa.write("123", 3);
if (LoRa.availabe()) {
len = LoRa.read(buf, MAX_LEN);
}
Arduino Pro Mini 是最小的开发板,它功耗极低(休眠 0.1uA),便宜简单,接线方便。
470MHz 胶棒天线,增益 3.5dB,特别适合中国 LoRa 频段范围(470~510MHz)。
如下图所示,使用杜邦线连接 Arduino Pro Mini,LoRa 扩展板和电池盒。
如下图所示,LoRa 检测电池电压和容量,App 实时显示。
为此,需要配置如下的网络组件:
如下图所示,LoRa 终端每分钟检测电池电压和容量,通过 LoRa 发送消息,App 显示电池电压和容量。
如下图所示(实物拍摄),ArduinoLoRa+ 的低功耗可达 1.4uA,这不仅是行业第一的超低功耗,而且达到了器件极限!
如下图所示,2 节 5 号碱性电池容量约 2890mAH,在典型的采集应用中(设每 10 分钟采集)电池可工作近 6 年。
终端电池寿命计算器
给 Arduino Pro Mini 下载程序请参考 《ArduinoLoRa 休眠极限 1.4uA》 参考链接
编译本工程需要添加 LoRa 驱动库 下载链接
使用 Arduino IDE 打开工程,点击"Sketch -> Include Library -> Add .ZIP Library…"
Arduino 的 zip 库安装路径一般为:C:\Users\Administrator\Documents\Arduino\libraries
Arduino 的代码简洁,容易理解,下载链接
#include
lora LoRa;
const int ledPin = 13; // choose the pin for the LED
#define DEBUG 0
#if DEBUG
#include
SoftwareSerial debugSerial(8, 9); // 8=RX, 9=TX
#endif
/* results are Vcc * 100, So for example, 3V would be 30 */
int getVccVoltage()
{
/* Adjust this value to your board's specific internal BG voltage */
static const long InternalReferenceVoltage = 1075; // 1.075V measured on the AREF pin
/* REFS0: Selects AVcc external reference
* MUX3 MUX2 MUX1: Selects 1.1V (VBG)
*/
bitSet(ADMUX, REFS0);
bitSet(ADMUX, MUX3);
bitSet(ADMUX, MUX2);
bitSet(ADMUX, MUX1);
/* START and WAIT for ADC conversion to complete
*
* ADC start conversion when set the ADSC to 1
* ADSC will read as 1 as long as a conversion in progress
* when the conversion is complete, the ADSC returns to 0
*
* add dead time to avoid ENDLESS LOOP if the ADC failed
* ADC conversion is 115us in normal, so set MAX is 200us
*/
unsigned long duration = 0;
unsigned long microseconds = micros();
bitSet(ADCSRA, ADSC); // start conversion
while(bitRead(ADCSRA, ADSC) && (duration < 200))
{
duration = micros() - microseconds;
}
int results = (((InternalReferenceVoltage * 1024) / ADC) + 5) / 10;
return results;
}
/* argument are Vcc * 100, So for example, 3V would be 300 */
int getBatteryCapacity(int VccVoltage)
{
/* Adjust this value to your board's specific battery voltage */
#define BATTERY_MAX_VOLTAGE 300 // 3.0V
#define BATTERY_MIN_VOLTAGE 180 // 1.8V
int capacity;
capacity = (VccVoltage - BATTERY_MIN_VOLTAGE) * 100L / (BATTERY_MAX_VOLTAGE - BATTERY_MIN_VOLTAGE);
capacity = constrain(capacity, 0, 100); // constrained between 0 and 100
return capacity;
}
void setup()
{
pinMode(ledPin, OUTPUT); // declare LED as output
Serial.begin(115200); // for LoRa Node
#if DEBUG
debugSerial.begin(115200); // start software serial port at 115200-8-N-1
#endif
}
void loop()
{
int voltage, capacity;
int array[2]; // voltage, capacity
voltage = getVccVoltage();
capacity = getBatteryCapacity(voltage);
#if DEBUG
debugSerial.print("Vcc: ");
debugSerial.print(voltage);
debugSerial.print("V, Battery Capacity: ");
debugSerial.print(capacity);
debugSerial.println("%");
#endif
array[0] = voltage;
array[1] = capacity;
LoRa.write(array, sizeof(array));
digitalWrite(ledPin, HIGH); // indicate that have send a LoRa message
delay(100);
digitalWrite(ledPin, LOW);
delay(60000); // 60 seconds
}
为了获得更准确的结果,这需要测量 MCU 内部基准电压。 为此,请运行以下代码:
// Find internal 1.1 reference voltage on AREF pin
void setup ()
{
analogReference(INTERNAL);
analogRead(A0); // force voltage reference to be turned on
}
void loop () { }
然后使用电压表测量处理器的 AREF 引脚上的电压。 将该值乘以1000,并将其用作 Arduino 代码的 InternalReferenceVoltage 变量。
如下图,测量得到1.075V,那么设置 InternalReferenceVoltage 为 1075
因为 MCU 的个体差异,它们的基准电压有细微不同。如果要求非常精确测量 Vcc 电压,这需要将参考电压存储在每个 MCU 的 EEPROM 中。这样,程序可以参考该值以找到计算电压时要使用的确切数字。
当 ADC 用于测量 Vcc 电压时,模拟读数代表的数值含义为:
模拟读数 / 模拟总长 = 基准电压 / Vcc 电压
模拟总长为 1024(Arduino Pro Mini 的 ADC 是 10 位),基准电压和模拟读数是已知量,求 Vcc 电压需要转换公式为:
Vcc 电压 = 基准电压 * 模拟总长 / 模拟读数
下图是实验用的南孚电池放电曲线,电压从 1.5V 到 0.9V,分别代表 95% 到 5% 的电量。为简化计算,我们拟定电量和电压为线性函数,即:电量(Capacity) 和电压(Voltage)为
Capacity = (Voltage - 0.9V) / (1.5V - 0.9V) * 100%
考虑 MCU 计算浮点数代价大,我们使用定点数,将电压放大 100 倍。同时,防止整数除法的精度丢失,先乘法,后除法,因此有:
实际应用中,需要根据电池电压调整下面 2 个数值:BATTERY_MAX_VOLTAGE(最高电压) 和BATTERY_MIN_VOLTAGE(最低电压)。在本次实验中,2 节 7 号电池的最高电压为 3.0V,最低电压为 1.8V