ESP8266+AM2302联动数据库

请注意,本文编写于 1629 天前,最后修改于 1628 天前,其中某些信息可能已经过气。

没想到在模块到手的当天就能做出demo来。

demo
demo

看到了么,就是这么硬核的捆绑。传感器和电源模块之间用了纸隔离,尽可能地减少干扰并绝缘。这个作品实际就是个典型的物联网案例,网上的教程也是多到不知道哪里去了。不过大多数是用各种云来实现数据储存和远程可视化,用到自己服务器的例子并不多。
代码最后再放出,先讲讲这次经历的一些小问题。
AM2302模块
AM2302模块

传感器用的是AM2302,这个系列还挺多的。功能差不多,这个量程对于室内环境够用。温度零下40到80摄氏度,湿度0到100,精度0.2。最关键的,价格超级便宜。美中不足的就是他的汇报率比较低,不能毫秒级的获取数据。
8266mini
8266mini

另外,这次用的开发板也不一样。你可以叫他8266mini,你也可以叫他WeMos。就当他是个副厂WeMos吧,毕竟芯片相同,编译器来都以一样的。相比NoedeMCU,这个留的接口少了很多,但GPIO都在,只是和某些其他接口共用了,代码里可以具体定义。然后就是少了很多供电,只剩下一个3.3和GND了。多了个5v,直接从USB接过来的,不知道能不能用它反向供电。
这个体积非常妙,做不复杂的项目非常合适。再小就要用8266芯片加烧录器了,可以用它先做个过渡。
18650
18650

供电当然是用最简单粗暴的18650,网传芯片功耗大这电池顶不住主要还是看跑了什么。经过测试不加休眠代码,一小时50mah左右,所以一节电池直接跑大概就是两天左右。当然不要忘了,还有很多休眠代码,可以在执行任务期间保持最低的功耗,具体还测试,但估计还可以续一段时间。
说来蛋疼,买了两个8266的电池盒模块,上来第一个就接反了。其实我是看到正负的,开始正常插上去,发现USB口不输出,觉得很奇怪,习惯性的开始反接,怀疑是本来板子上就印错了。哪知反向一接,背后瞬间烫了我一下。当时想这东西估计歇逼了,果不其然,用万用表测了一下,倒也不是说全是0,只是输出的电压很低,并且开关不再起作用,充电也充不进去。
用第二个模块测试,正常接,还是没输出。插一下外接供电,再拔掉,这突然就有输出了。哪门子情况,难道是里面有拿个电容还需要充个电?当时就猜想,刚才被我反接的那个也不一定真就不行了。电子元件没那么脆弱,只要没烧糊,都有可能生还。
过了几个小时,再去测电压,不错,电压已经有些回来了,但还达不到5v。于是无聊开始拨弄开关,拨了几下,再测,恢复了。原因?未知。
好了,说回单片机Sniper再半个月前其实就做出了一摸一样的东西,只不过用了不一样的库,那时候它实际上给过我一份源码。然而,那份源码被我删了。
仿照示例,get到环境信息并不困难。问题还是出在了上传数据库这个环节。在之前,用8266传粉丝数据的时候就提到过,对char字符串进行了转换。
这次我们获取到的数据时浮点(float),这个东西比较蛋疼,当你直接定义值为INT的时候,他会四舍五入但能正常的传入数据库,INT是整形,没法在它上面添加小数点。最好还是能把float直接存入数据库,经过多种方法尝试,未果。所以最后还是决定把float转化为char,这个操作具体可以看下面的代码,也并不是太容易。

#include <ESP8266WiFi.h>             // esp8266库
#include <MySQL_Connection.h>    // Arduino连接Mysql的库
#include <MySQL_Cursor.h>
#include <ESP8266HTTPClient.h>
#include <Wire.h>
#include <WiFiUdp.h>
#include <Ethernet.h>
#include <Dns.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>


#define DHTPIN 2     // Digital pin connected to the DHT sensor 
#define DHTTYPE    DHT22     // DHT 22 (AM2302)

DHT_Unified dht(DHTPIN, DHTTYPE);

uint32_t delayMS;

char deviceid[] = "XXXXX";
char domain[] = "XXXXXXX";       //server host
char user[] = "XXXXX";                   // Mysql的用户名
char password[] = "XXXXX";           // 登陆Mysql的密码
char INSERT_SQL[] = "INSERT INTO XXXXX.XXXX(Temp, Humi, Device) VALUES (%s, %s, %d)";
char ssid[] = "XXXXX";                      // WiFi名
char pass[] = "XXXXXXX";               // WiFi密码
char Temp[15];
char Humi[15];
const unsigned long HTTP_TIMEOUT = 5000;

IPAddress server_ip;
WiFiClient client;
HTTPClient http;
WiFiUDP udp;
MySQL_Connection conn((Client *)&client);
MySQL_Cursor* cursor;
DNSClient dns_client;


void setup() {
  Serial.begin(9600);
  // Initialize device.
  dht.begin();
  Serial.println(F("Sensor"));
  // Print temperature sensor details.
  sensor_t sensor;
  
  dht.temperature().getSensor(&sensor);
  Serial.println(F("------------------------------------"));
  Serial.println(F("Temperature Sensor"));
  Serial.print  (F("Sensor Type: ")); Serial.println(sensor.name);
  Serial.print  (F("Driver Ver:  ")); Serial.println(sensor.version);
  Serial.print  (F("Unique ID:   ")); Serial.println(sensor.sensor_id);
  Serial.print  (F("Max Value:   ")); Serial.print(sensor.max_value); Serial.println(F("°C"));
  Serial.print  (F("Min Value:   ")); Serial.print(sensor.min_value); Serial.println(F("°C"));
  Serial.print  (F("Resolution:  ")); Serial.print(sensor.resolution); Serial.println(F("°C"));
  Serial.println(F("------------------------------------"));
  // Print humidity sensor details.
  dht.humidity().getSensor(&sensor);
  Serial.println(F("Humidity Sensor"));
  Serial.print  (F("Sensor Type: ")); Serial.println(sensor.name);
  Serial.print  (F("Driver Ver:  ")); Serial.println(sensor.version);
  Serial.print  (F("Unique ID:   ")); Serial.println(sensor.sensor_id);
  Serial.print  (F("Max Value:   ")); Serial.print(sensor.max_value); Serial.println(F("%"));
  Serial.print  (F("Min Value:   ")); Serial.print(sensor.min_value); Serial.println(F("%"));
  Serial.print  (F("Resolution:  ")); Serial.print(sensor.resolution); Serial.println(F("%"));
  Serial.println(F("------------------------------------"));
  // Set delay between sensor readings based on sensor details.

  delayMS = sensor.min_delay / 10000;
  Serial.println("Device ID:");
  Serial.print(deviceid);
  Serial.printf("\nConnecting to WiFi");

  WiFi.begin(ssid, pass);                        // 连接WiFi
  while (WiFi.status() != WL_CONNECTED)
  { // 如果WiFi没有连接,一直循环打印点
    delay(500);
    Serial.print(".");
  }
  Serial.printf("\nConnected to %s", ssid);
  Serial.print("\nLocal IP address: ");
  Serial.print(WiFi.localIP());                   // 打印开发板的IP地址
  Serial.print("\nDevice MAC:");
  Serial.println(WiFi.macAddress());
  Serial.printf("DNS Server getting IP from hostname: %s", domain);
  delay(1000);
  dns_client.begin(Ethernet.dnsServerIP());
  WiFi.hostByName(domain, server_ip);
  Serial.print("\nDNS Process Successed !");
  Serial.print("\nServer IP address: ");
  Serial.println(server_ip);
  Serial.print("Connecting to Database...  \n");
  delay(1000);
}


void pushsql()
{
  char query[128];
  sprintf(query, INSERT_SQL, Temp, Humi, deviceid);
  delay(1000);
  Serial.print("Ready to Push: ");
  Serial.println(query);
  delay(1000);
  MySQL_Cursor *cur_mem = new MySQL_Cursor(&conn);
  cur_mem->execute(query);
  delay(1000);
  Serial.print("Data Pushed !");
  delay(1000);
  delete cur_mem;

}

void umweltdata()
{
  // Delay between measurements.
  delay(2000);
  delay(delayMS);
  // Get temperature event and print its value.
  sensors_event_t event;
  dht.temperature().getEvent(&event);
  if (isnan(event.temperature)) {
    Serial.println(F("Error reading temperature!"));
  }
  
  else {
   float tem = event.temperature;
   dtostrf(tem,1,2,Temp);
    Serial.print(Temp);
    Serial.print(F("Temperature: "));
    Serial.print(event.temperature);
    Serial.println(F("°C"));
  }
  

  // Get humidity event and print its value.

  dht.humidity().getEvent(&event);
  if (isnan(event.relative_humidity)) {
    Serial.println(F("Error reading humidity!"));
  }
  else {
   float hum = event.relative_humidity;
   dtostrf(hum,1,2,Humi);
   Serial.print(Humi);
    Serial.print(F("Humidity: "));
    Serial.print(event.relative_humidity);
    Serial.println(F("%"));
  }
  
}

void loop() {

    umweltdata();
    delay(5000);

  if (WiFi.status() == WL_CONNECTED)
  {
    
    if (conn.connect(server_ip, 3306, user, password))         // 连接数据库
      Serial.print("Start getting Data!");
    else
      Serial.print("Connection to Server FAILED !!!");
    cursor = new MySQL_Cursor(&conn);    // 创建一个数据库游标实例
    pushsql();
  }

  Serial.print("\nWaiting for next Push... 5min remaining!");
  Serial.print("\n");
  delay(15000);
}

评论区

已有 2 条评论


可以看看SHTC3,精度挺高的,价格也比DHT22便宜,具体可以看我博客

看了一下,对比DHT22确实不错,目前使用BME的传感器。体积很小。