|
|
本帖最后由 DaVinciChang 于 2015-8-3 14:23 编辑
本程序参考本论坛zcbzjx所发表的【第二弹】基于dht22+dsm501A+enc28J60+arduino+lcd1602+yeelink+实现家居环境监控。
使用网络上流传的SIM800 TCP代码经测试可以使用并能上传单个传感器数据到Yeelink。
以下代码SIM900和GPS模块使用了软串口,由于不会使用SoftSerial代码中没有使用listen监听可能有错误,但后来SIM900改为硬件串口。
Arduino nano
传感器及接口:
- Ublox NEO-5M GPS模块 PIN D7 D8
- SIM900 模块 PIN D9 D10
- DHT11温湿度传感器 PIN A0
- DSM501B粉尘传感器 PIN A2 A4
问题描述:
- 设备上电后呼叫SIM900手机号码提示无法接通。
- SIM900执行AT命令无响应。
- 使用硬件串口同样无响应。
- 单独测试SIM900部分代码可以运行并能上传单个数据到Yeelink。
- #include <dht.h>
- #include <TinyGPS.h>
- #include <LCD5110_Basic.h>
- #include <SoftwareSerial.h>
- // GPRS UP LINK Test 01
- // Jul_22_2015
- // *********************************for yeelink api*****************************************//
- //const String APIKey[] PROGMEM = "XXXX"; // replace your yeelink api key here
- long DeviceID = 168888; // replace your device ID
- // 固定的网关
- //const char website[] PROGMEM = "api.yeelink.net";
- //传感器个数及对应传感器ID
- #define N 4
- //上传数据的字符串变量及字符串长度变量
- char sensorData[N][50];
- int dataLength[N];
- //传感器ID [1]GPS[2]TEMP[3]HUM[4]PM25
- const long SensorID[N] = {183754, 183755, 183756, 183757, };
- //********************************End of Yeelink *****************************************//
- // 发送到服务器时间间隔,N大了可以适当缩短,
- //每个传感器发送时间间隔为PostingInterval*N
- const uint16_t PostingInterval = 5000;
- // last time you connected to the server, in milliseconds
- uint32_t lastConnectionTime = 0;
- //轮流向服务器发送相应传感器变量 0 <= i <N,
- uint8_t i = 0; //
- //DHT11
- #define DHT_PIN A0
- //DSM501B
- #define DSM_PIN_10 A4
- #define DSM_PIN_25 A2
- #define LINEBREAK "\r\n"
- //DHT
- DHT sensor = DHT();
- LCD5110 lcd(2, 3, 4, 6, 5);
- extern uint8_t SmallFont[];
- SoftwareSerial GSMSerial(10, 9); //RX TX
- TinyGPS gps;
- SoftwareSerial GPS_SERIAL(7, 8);
- //GPS data
- bool newData = false;
- char gps_lon[20];
- char gps_lat[20];
- float fkmph;//速度km/h
- byte satnum = 0;
- void setup() {
- // put your setup code here, to run once:
- Serial.begin(9600);
- lcd.InitLCD();
- lcd.setFont(SmallFont);
- lcd.print("Initial Sensor...", CENTER, 0);
- lcd.print("Enable DHT..", LEFT, 10);
- sensor.attach(DHT_PIN);
- lcd.print("GPS Searching...", LEFT, 20);
- GPS_SERIAL.begin(9600);
- //satnum = gps.satellites();
- lcd.print("Register GPRS...", LEFT, 30);
- GSMSerial.begin(9600);
- GSMSerial.listen();
- Serial.println("**********************************************************************");
- Serial.println("debug========================GPRSINI");
- //Serial.println(GSMSerial.print("ATI\r\n"));
- delay(500);
- // //connect();
- while (!gprsINI());
- }
- void loop()
- {
- // if (!ether.dhcpValid() && !ether.dhcpSetup())
- // Serial.println("DHCP failed");
- // ether.packetLoop(ether.packetReceive());
- if ( millis() < lastConnectionTime || millis() - lastConnectionTime > PostingInterval) {
- Serial.println(i);
- get_Send_String(i);
- send_Data(i);
- i++;
- if (i == N) i = 0;
- }
- else dsmStatistics();
- }
- void send_Data(uint8_t j) {
- // Serial.print(sensorData[j]);
- // Serial.print(SensorID[j]);
- // Serial.println(j);
- // sim800MSG("AT+CIPSTART="TCP","api.yeelink.net","80"");
- char *pstr = (char *)malloc(100 * sizeof(char));
- sprintf(pstr, "POST /v1.0/device/%ld/sensor/%ld/datapoints HTTP/1.1" "\r\n"
- "Host: api.yeelink.net" "\r\n"
- "U-ApiKey: xxxxxxxxxxxxxxxxxx" "\r\n"
- "Content-Length: %d" "\r\n"
- "Content-Type: application/x-www-form-urlencoded" "\r\n"
- "%s" "\r\n0x1a",
- DeviceID, SensorID[j], dataLength[j], sensorData[j]);
- Serial.println(pstr);
- Serial.println(sim800MSG(pstr));
- lastConnectionTime = millis();
- }
- //比较周数,成功返回0-6的数,错误返回7
- //p代表周数,取周数前3个字母,如Mon代表周1,以此类推
- //改动周几不影响返回的时间值,可以通过改动日期的日数来达到修改时间
- //比较月份,成功返回0-11的数,错误返回12
- //P 为月份的前三个字母,如Feb代表二月,以此类推
- //将字串格式的时间转换为结构体,返回距离1970年1月1日0:0:0的秒数,当字符串格式错误或超值时返回0
- //BUF 为类似Tue May 15 14:46:02 2007格式的,p为时间结构体
- //dsm501统计变量
- uint32_t dsmStatTimes10 = 0; //DSM
- uint32_t sumTimeofLow10 = 0;
- uint32_t dsmStatTimes25 = 0;
- uint32_t sumTimeofLow25 = 0;
- uint8_t switch1025 = 0;
- //递推滤波变量
- #define FILT_N 10
- #define FILT_I 2
- uint8_t filtI[FILT_I] = {
- 0, 0
- };
- uint16_t filtDsm[FILT_I][FILT_N];
- uint32_t filtSum[FILT_I] = {
- 0, 0
- };
- void dsmStatistics() {
- if (switch1025) {
- dsmStatTimes10 ++;
- sumTimeofLow10 += !digitalRead(DSM_PIN_10);
- switch1025 = 0;
- }
- else {
- dsmStatTimes25 ++;
- sumTimeofLow25 += !digitalRead(DSM_PIN_25);
- switch1025 = 1;
- }
- }
- uint16_t filteringDsm(uint8_t l, uint16_t _dsmData) {
- filtSum[l] = filtSum[l] - filtDsm[l][filtI[l]];
- filtSum[l] = filtSum[l] + _dsmData;
- filtDsm[l][filtI[l]] = _dsmData;
- filtI[l] = filtI[l] + 1;
- if (filtI[l] >= FILT_N) filtI[l] = 0;
- return filtSum[l] / FILT_N;
- }
- float dsmTemp25;
- void get_Send_String(uint8_t k) {
- switch (k) {
- case 0: //DSM501
- {
- // gps型传感器格式如下:
- //{
- // "value": {"lat":35.4321,"lng":46.3451,"speed":98.2}
- //}
- feed_gps(k);
- }
- case 1://DHT temperature
- {
- sensor.update();
- uint16_t tempData = (sensor.getTemperatureInt() << 8) | sensor.getTemperatureFrac();
- lcd.print(String(tempData), LEFT, 0);
- //lcd.print(".");
- //lcd.print(tempData % 10);
- //lcd.print("C");
- format_String(k, tempData);
- break;
- }
- case 2://DHT humidity
- {
- sensor.update();
- uint16_t humiData = (sensor.getHumidityInt() << 8) | sensor.getHumidityFrac();
- //lcd.setCursor(6, 0);
- lcd.print(String(humiData / 10) + "%", LEFT, 20);
- //lcd.print(".");
- //lcd.print(humiData % 10);
- //lcd.print("%");
- format_String(k, humiData);
- break;
- }
- case 3://PM10
- {
- lcd.clrScr();
- float dsmTemp0 = (sumTimeofLow10 * 100.0) / dsmStatTimes10;
- float dsmTemp10 = 0.1776 * pow(dsmTemp0, 3) - 0.24 * pow(dsmTemp0, 2) + 94.003 * dsmTemp0;
- // lcd.setCursor(12, 0);
- // lcd.print(dsmTemp10);
- dataLength[k] = sprintf(sensorData[k], "{"value":%d}", filteringDsm(k, int(dsmTemp10)));
- sumTimeofLow10 = 0;
- dsmStatTimes10 = 0;
- dsmTemp0 = (sumTimeofLow25 * 100.0) / dsmStatTimes25;
- dsmTemp25 = 0.1776 * pow(dsmTemp0, 3) - 0.24 * pow(dsmTemp0, 2) + 94.003 * dsmTemp0;
- dsmTemp25 = dsmTemp10 - dsmTemp25;
- sumTimeofLow25 = 0;
- dsmStatTimes25 = 0;
- lcd.print("PM10:" + String(dsmTemp10), LEFT, 0);
- break;
- }
- case 4://pm25
- {
- dataLength[k] = sprintf(sensorData[k], "{"value":%d}", filteringDsm(k, int(dsmTemp25)));
- lcd.print("PM2.5:" + String(dsmTemp25), LEFT, 10);
- break;
- }
- }
- }
- void format_String(uint8_t l, uint16_t sensor_Data) {
- uint16_t Tc_100 = sensor_Data;
- uint8_t whole, fract;
- whole = Tc_100 / 10 ; // separate off the whole and fractional portions
- fract = Tc_100 % 10;
- dataLength[l] = sprintf(sensorData[l], "{"value":%d.%d}", whole, fract);
- }
- boolean gprsINI()
- {
- Serial.println("GPRS INI");
- String msg;
- msg = sim800MSG("AT+SAPBR=2,1");
- Serial.println(msg);
- sim800MSG("ATE");
- if (msg.indexOf("OK") > 0)
- if (msg.indexOf("0.0.0.0") > 0)
- {
- sim800MSG("AT+SAPBR=3,1,"Contype","GPRS"");
- sim800MSG("AT+SAPBR=3,1,"APN","UNINET"");
- sim800MSG("AT+SAPBR=1,1");
- }
- else return 1;
- delay(2000);
- return 0;
- }
- String sim800MSG(String msg)
- {
- Serial.println(String("") + "POST DATA:" + msg);
- String str;
- boolean ActionFlag = false;
- if (msg.indexOf("HTTPACTION") > 0)
- ActionFlag = true;
- GSMSerial.println(msg);
- while (!GSMSerial.available())
- delay(10);
- while (GSMSerial.available())
- {
- char c = GSMSerial.read();
- str += c;
- delayMicroseconds(1200);
- // delay(2);
- }
- if (ActionFlag)
- {
- while (!GSMSerial.available())
- delay(10);
- while (GSMSerial.available())
- {
- char c = GSMSerial.read();
- str += c;
- delay(2);
- }
- }
- // Serial.println(str);
- return str;
- }
- char feed_gps(uint8_t dataid)
- {
- lcd.clrScr();
- newData = false;
- unsigned long chars;
- unsigned short sentences, failed;
- // For one second we parse GPS data and report some key values
- // for (unsigned long start = millis(); millis() - start < 1000;)
- // {
- while (GPS_SERIAL.available())
- {
- char c = GPS_SERIAL.read();
- Serial.write(c); // uncomment this line if you want to see the GPS data flowing
- if (gps.encode(c)) // Did a new valid sentence come in?
- newData = true;
- lcd.clrScr();
- Serial.println("GPS READY!");
- // lcd.print("GPS READY!", CENTER, 15);
- }
- // }
- if (newData)
- {
- float flat, flon;
- unsigned long age;
- int _year;
- byte _month, _day, _hour, _minute, _second, _hundredths;
- gps.f_get_position(&flat, &flon, &age);
- gps.crack_datetime(&_year, &_month, &_day, &_hour, &_minute, &_second, &_hundredths, &age);
- fkmph = gps.f_speed_kmph();
- if ( satnum != TinyGPS::GPS_INVALID_SATELLITES) {
- lcd.print("SAT:" + satnum, CENTER, 40);
- }
- if (fkmph != TinyGPS::GPS_INVALID_F_SPEED)
- {
- if (fkmph < 0.5) fkmph = 0.0; //屏蔽0时速时的误差显示
- }
- else
- {
- fkmph = 0.0;
- }
- if (age == TinyGPS::GPS_INVALID_AGE) {
- Serial.print("********** ******** ");
- //myLCD.print("********** ********", CENTER, 20);
- }
- else
- {
- char gps_date[20];
- char gps_time[9];
- sprintf(gps_date, "%02d/%02d/%02d",
- _month, _day, _year);
- lcd.print(gps_date, LEFT, 20);
- sprintf(gps_time, "%02d:%02d:%02d ",
- _hour, _minute, _second);
- lcd.print(gps_time, LEFT, 30);
- }
- // float fkmph = gps.f_speed_kmph(); // speed in km/hr
- flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6;
- flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 6;
- dtostrf(flat, 11, 6, gps_lat);
- dtostrf(flon, 10, 6, gps_lon);
- sprintf(gps_lon, "LON: %ld", gps_lon);
- sprintf(gps_lat, "LAT: %ld", gps_lat);
- lcd.print(gps_lat, LEFT, 0);
- lcd.print(gps_lon, LEFT, 10);
- Serial.println("lat:"); //latitude
- Serial.println(gps_lat);
- Serial.println("lon:");
- Serial.println(gps_lon);//longitude
- dataLength[dataid] = sprintf(sensorData[dataid], "{"value":{"lat":%d,"lng":%d,"speed":%f}", gps_lat, gps_lon, fkmph);
- }
- }
- void ShowSerialData()
- {
- String str;
- while (GSMSerial.available() != 0)
- {
- char c = GSMSerial.read();
- str += c;
- }
- Serial.print(str);
- }
- int getLength(int someValue) {
- // there's at least one byte:
- int digits = 1;
- // continually divide the value by ten,
- // adding one to the digit count for each
- // time you divide, until you're at 0:
- int dividend = someValue / 10;
- while (dividend > 0) {
- dividend = dividend / 10;
- digits++;
- }
- // return the number of digits:
- return digits;
- }
复制代码
|
|