猫-气象站

猫-气象站的详细介绍

创作者:KanameAimu | 更新日期:2024-04-10 | 在线时长:146天
西安天气

 

简介

本项目是一个基于Arduino和NRF24L01的环境监测硬件。

能实时获取当前气温,气压,光照,湿度,降水,PM2.5值,以及自身的电池电量,使用2.4G模块传到网关节点,再由节点上传到云。

节点本身不接受信息,仅以40s的间隔采集并发送数据。

硬件构成

主控:Arduino Pro Mini(5V/16MHz)

通信:NRF24L01+

气温:BMP180(0.01) DS18B20(0.50)

气压:BMP180(0.01)

光照:GY-30(IC为BH1750FVI)

湿度:DHT11(1)

降水:PCB 雨滴模块(他的编号是YL-83)

PM2.5:GP2Y1010AU0F

供电:18650一节

关于节电

由于设备处于阳台的位置,因此有线供电较为麻烦,太阳能供电也麻烦,所以采用可更换的18650锂电池供电;

电池供电方案显然要考虑能耗问题,因此有通信选择的问题:有esp01(WiFi)和NRF24L01(2.4G)可供选择。

ESP8266是耗电模块(工作:80mA(264mW),最高:200mA(660mW)),而NRF24L01+工作电流只有11.3mA(TX,0dbm)和13.5mA(RX),掉电模式电流仅为900nA,显然是一个比较好的选择。

一个合理的选择是设备用NRF将数据发送到室内的节点,这个节点再将数据传到云。室内节点可以使用电源供电,不存在能耗问题。

Promini和3v3和雨滴模块上都有LED,这些也很耗电(每个10到20mA),因此全部焊掉。

空气质量之前采用的是MQ135,但是这个东西由于要电热,非常耗电。资料上提到加热功率居然有900mW(!)。于是用低功耗的粉尘模块替换之。

为减小工作电流以获得尽可能长的工作时间,设备绝大多数时间进入睡眠模式(使用LowPower库),利用watchdog周期性醒来发送数据,然后立刻回到睡眠模式。

nrf24l01模块也需要同时睡眠和醒来,使用Mirf库里的powerDown()命令。

这样设计的待机电流:9.6mA(36mW),工作电流31mA(120mW),一节3000mAh的电池能工作12天左右。

电路设计

用EasyEDA画了下原理图,先在面包板上搭建了实验电路,再焊到一块5x7cm的洞洞板上。所有模块都采用可更换式的设计,同时保证布局尽可能紧凑。

由于雨滴模块和光照模块都要安装在阳台边,因此预留了接口。使用的时候用线连接出去。

EasyEDA链接:https://easyeda.com/KanameAimu/WeatherStation-e9dae2dacdea4157baf0bea2717fbf6c

原理图

成品图

室内节点

室内节点使用了一个ArduinoProMini+NRF24L01用于接收NRF链路数据并处理,以及一个Wemos D1用来提供WiFi通信。二者之间用I2C总线实现通信。由于工作电压不同,中间使用一个txs0108e模块做电平转换。

基本的功能是存储转发,还有一些附加的功能,例如在1602上显示收到的数据等。

Wemos D1是一个Arduino兼容的ESP8266开发板,可以直接使用Arduino IDE和很多的库,非常方便。这里用来从promini拿数据并上传到bigiot。

外形设计

接下来就是3D打印个盒子来安装电路板和固定传感器。模型设计使用OpenSCAD,生成STL切片后打印。

盒子

上面的部分用来固定18650电池盒,左下用来固定GP2Y1010传感器,右下用来固定DHT11模块。悬空的地方设计了支撑方便打印。

盒盖

采用卡扣式设计,将DHT11线,下载口和BMP180口留了出来。

完成后如图。

成品图

软件设计

设备需要采集数据并放入缓冲区,用nrf模块发送,然后再用LowPower.powerDown。

电池电压数据在传感器工作前采集一次,传感器工作后再采集一次取平均。

DS18B20是备用温度计。BMP180出问题后才使用,实际硬件可以不用。

另外注意ArduinoProMini(ATMega328P-AU)的int是16位,float=double=32位,要注意数据包和32位系统的兼容性。

数据包格式:

字节 类型 数据
0 byte 设备ID
1 byte 包ID
2 uint16_t 电池电压
4 uint16_t 雨滴传感器电压
6 float 粉尘传感器电压
10 uint16_t 光照数值
12 float 气压
16 float 气温
20 byte 湿度
21~31   保留

代码摘要:

void loop() {
  char data[Mirf.payload];

  data[0] = device_id;
  data[1] = packet_id;
  packet_id++;

  int battery_value_1 = analogRead(PIN_BatteryVoltage);
  
  int rain_value = analogRead(PIN_RAIN_SENSOR);
  data[4] = *(((byte *)&rain_value)+0);
  data[5] = *(((byte *)&rain_value)+1);

  float dust_volt =  getSharpDustSensorVoltage();
  data[6] = *(((byte *)&dust_volt)+0);
  data[7] = *(((byte *)&dust_volt)+1);
  data[8] = *(((byte *)&dust_volt)+2);
  data[9] = *(((byte *)&dust_volt)+3);

  unsigned int brightness_val = (unsigned int)getGY30Reading();
  data[10] = *(((byte *)&brightness_val)+0);
  data[11] = *(((byte *)&brightness_val)+1);

  float pres,temp;
  if(!getBMP180Readings(&pres, &temp))
  {
    pres = 0;
    temp = getDS18B20Temp();
  }
  data[12] = *(((byte *)&pres)+0);
  data[13] = *(((byte *)&pres)+1);
  data[14] = *(((byte *)&pres)+2);
  data[15] = *(((byte *)&pres)+3);
  data[16] = *(((byte *)&temp)+0);
  data[17] = *(((byte *)&temp)+1);
  data[18] = *(((byte *)&temp)+2);
  data[19] = *(((byte *)&temp)+3);

  data[20] = getDHT11Humidity();

  int battery_value_2 = analogRead(PIN_BatteryVoltage);
  int battery_value = (battery_value_1 + battery_value_2) / 2;
  data[2] = *(((byte *)&battery_value)+0);
  data[3] = *(((byte *)&battery_value)+1);

  for(int i=21;i<32;i++)
  {
    data[i] = 0;
  }
  
  Mirf.setTADDR((byte *)"iotc1");
  Mirf.send(data);
  while(Mirf.isSending());
  Mirf.powerDown();
  
  LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
  LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
  LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
  LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
  LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
}

全部代码和设计文件可以在我的GitHub上找到:https://github.com/KanameAimu/WeatherStation

此文章欢迎转载,转载请注明作者和原始链接。


2016-11-28

查了下ESP8266的功耗。DeepSleep有10mA(33mW),有个待机模式似乎是0.9uA,不过问题是8266只有1个ADC,本项目至少需要2个。

而且不想用那么多WiFi设备连路由器,个人认为还是控制中心这种设计比较好。各设备用nrf构成局域网。

8266的3.3v电压也是个问题,因为GP2Y要5v,还有dht11什么的东西,还是用arduino比较方便。


2019-10-9

数据包装其实可以用union解决。理论上可以用三极管给模块供电,可以进一步降低功耗。

还是不想拿8266当节点。可能是怕麻烦吧。

近期打算画个pcb来整合器件和接口。