极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 11889|回复: 1

求助SIM900模块无法执行AT命令。

[复制链接]
发表于 2015-8-2 13:25:50 | 显示全部楼层 |阅读模式
本帖最后由 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。


  1. #include <dht.h>
  2. #include <TinyGPS.h>
  3. #include <LCD5110_Basic.h>
  4. #include <SoftwareSerial.h>
  5. // GPRS UP LINK Test 01
  6. // Jul_22_2015

  7. // *********************************for yeelink api*****************************************//
  8. //const String APIKey[] PROGMEM = "XXXX"; // replace your yeelink api key here
  9. long  DeviceID  = 168888; // replace your device ID
  10. // 固定的网关
  11. //const char website[] PROGMEM = "api.yeelink.net";
  12. //传感器个数及对应传感器ID
  13. #define N 4
  14. //上传数据的字符串变量及字符串长度变量
  15. char sensorData[N][50];
  16. int  dataLength[N];
  17. //传感器ID  [1]GPS[2]TEMP[3]HUM[4]PM25
  18. const long  SensorID[N] = {183754,  183755, 183756, 183757, };

  19. //********************************End of Yeelink *****************************************//
  20. // 发送到服务器时间间隔,N大了可以适当缩短,
  21. //每个传感器发送时间间隔为PostingInterval*N
  22. const uint16_t PostingInterval = 5000;
  23. // last time you connected to the server, in milliseconds
  24. uint32_t lastConnectionTime = 0;
  25. //轮流向服务器发送相应传感器变量 0 <= i <N,
  26. uint8_t i = 0; //

  27. //DHT11
  28. #define DHT_PIN A0
  29. //DSM501B
  30. #define DSM_PIN_10 A4
  31. #define DSM_PIN_25 A2
  32. #define LINEBREAK "\r\n"
  33. //DHT
  34. DHT sensor = DHT();
  35. LCD5110 lcd(2, 3, 4, 6, 5);
  36. extern uint8_t SmallFont[];
  37. SoftwareSerial GSMSerial(10, 9); //RX TX
  38. TinyGPS gps;

  39. SoftwareSerial GPS_SERIAL(7, 8);
  40. //GPS data
  41. bool newData = false;
  42. char gps_lon[20];
  43. char gps_lat[20];
  44. float fkmph;//速度km/h
  45. byte satnum = 0;
  46. void setup() {
  47.   // put your setup code here, to run once:

  48.   Serial.begin(9600);
  49.   lcd.InitLCD();
  50.   lcd.setFont(SmallFont);
  51.   lcd.print("Initial Sensor...", CENTER, 0);
  52.   lcd.print("Enable DHT..", LEFT, 10);
  53.   sensor.attach(DHT_PIN);
  54.   lcd.print("GPS Searching...", LEFT, 20);
  55.   GPS_SERIAL.begin(9600);
  56.   //satnum = gps.satellites();

  57.   lcd.print("Register GPRS...", LEFT, 30);
  58.   GSMSerial.begin(9600);

  59.   GSMSerial.listen();
  60.   Serial.println("**********************************************************************");
  61.   Serial.println("debug========================GPRSINI");

  62.   //Serial.println(GSMSerial.print("ATI\r\n"));
  63.   delay(500);
  64.   //  //connect();

  65.   while (!gprsINI());

  66. }

  67. void loop()
  68. {
  69.   // if (!ether.dhcpValid() && !ether.dhcpSetup())
  70.   //   Serial.println("DHCP failed");
  71.   // ether.packetLoop(ether.packetReceive());
  72.   if ( millis() < lastConnectionTime || millis() - lastConnectionTime > PostingInterval) {
  73.     Serial.println(i);
  74.     get_Send_String(i);
  75.     send_Data(i);
  76.     i++;
  77.     if (i == N) i = 0;
  78.   }
  79.   else dsmStatistics();
  80. }

  81. void send_Data(uint8_t j) {
  82.   // Serial.print(sensorData[j]);
  83.   // Serial.print(SensorID[j]);
  84.   // Serial.println(j);
  85.   // sim800MSG("AT+CIPSTART="TCP","api.yeelink.net","80"");
  86.   char *pstr = (char *)malloc(100 * sizeof(char));

  87.   sprintf(pstr, "POST /v1.0/device/%ld/sensor/%ld/datapoints HTTP/1.1" "\r\n"
  88.           "Host: api.yeelink.net" "\r\n"
  89.           "U-ApiKey: xxxxxxxxxxxxxxxxxx" "\r\n"
  90.           "Content-Length: %d" "\r\n"
  91.           "Content-Type: application/x-www-form-urlencoded" "\r\n"
  92.           "%s" "\r\n0x1a",
  93.           DeviceID, SensorID[j], dataLength[j], sensorData[j]);
  94.   Serial.println(pstr);
  95.   Serial.println(sim800MSG(pstr));
  96.   lastConnectionTime = millis();
  97. }
  98. //比较周数,成功返回0-6的数,错误返回7
  99. //p代表周数,取周数前3个字母,如Mon代表周1,以此类推
  100. //改动周几不影响返回的时间值,可以通过改动日期的日数来达到修改时间

  101. //比较月份,成功返回0-11的数,错误返回12
  102. //P 为月份的前三个字母,如Feb代表二月,以此类推


  103. //将字串格式的时间转换为结构体,返回距离1970年1月1日0:0:0的秒数,当字符串格式错误或超值时返回0
  104. //BUF 为类似Tue May 15 14:46:02 2007格式的,p为时间结构体

  105. //dsm501统计变量
  106. uint32_t dsmStatTimes10 = 0; //DSM
  107. uint32_t sumTimeofLow10 = 0;
  108. uint32_t dsmStatTimes25 = 0;
  109. uint32_t sumTimeofLow25 = 0;
  110. uint8_t switch1025 = 0;
  111. //递推滤波变量
  112. #define FILT_N 10
  113. #define FILT_I 2
  114. uint8_t filtI[FILT_I] = {
  115.   0, 0
  116. };
  117. uint16_t filtDsm[FILT_I][FILT_N];
  118. uint32_t filtSum[FILT_I] = {
  119.   0, 0
  120. };

  121. void dsmStatistics() {
  122.   if (switch1025) {
  123.     dsmStatTimes10 ++;
  124.     sumTimeofLow10 += !digitalRead(DSM_PIN_10);
  125.     switch1025 = 0;
  126.   }
  127.   else {
  128.     dsmStatTimes25 ++;
  129.     sumTimeofLow25 += !digitalRead(DSM_PIN_25);
  130.     switch1025 = 1;
  131.   }
  132. }

  133. uint16_t filteringDsm(uint8_t l, uint16_t _dsmData) {
  134.   filtSum[l] = filtSum[l] - filtDsm[l][filtI[l]];
  135.   filtSum[l] = filtSum[l] + _dsmData;
  136.   filtDsm[l][filtI[l]] = _dsmData;
  137.   filtI[l] = filtI[l] + 1;
  138.   if (filtI[l] >= FILT_N) filtI[l] = 0;
  139.   return filtSum[l] / FILT_N;
  140. }

  141. float dsmTemp25;

  142. void get_Send_String(uint8_t k) {
  143.   switch (k) {
  144.     case 0: //DSM501
  145.       {
  146.         // gps型传感器格式如下:
  147.         //{
  148.         //  "value": {"lat":35.4321,"lng":46.3451,"speed":98.2}
  149.         //}
  150.         feed_gps(k);
  151.       }

  152.     case 1://DHT temperature
  153.       {

  154.         sensor.update();
  155.         uint16_t tempData = (sensor.getTemperatureInt() << 8) | sensor.getTemperatureFrac();

  156.         lcd.print(String(tempData), LEFT, 0);
  157.         //lcd.print(".");
  158.         //lcd.print(tempData % 10);
  159.         //lcd.print("C");
  160.         format_String(k, tempData);
  161.         break;
  162.       }
  163.     case 2://DHT humidity
  164.       {
  165.         sensor.update();
  166.         uint16_t humiData = (sensor.getHumidityInt() << 8) | sensor.getHumidityFrac();
  167.         //lcd.setCursor(6, 0);
  168.         lcd.print(String(humiData / 10) + "%", LEFT, 20);
  169.         //lcd.print(".");
  170.         //lcd.print(humiData % 10);
  171.         //lcd.print("%");
  172.         format_String(k, humiData);
  173.         break;
  174.       }
  175.     case 3://PM10
  176.       {
  177.         lcd.clrScr();
  178.         float dsmTemp0 = (sumTimeofLow10 * 100.0) / dsmStatTimes10;
  179.         float dsmTemp10 = 0.1776 * pow(dsmTemp0, 3) - 0.24 * pow(dsmTemp0, 2) + 94.003 * dsmTemp0;
  180.         // lcd.setCursor(12, 0);
  181.         // lcd.print(dsmTemp10);
  182.         dataLength[k] = sprintf(sensorData[k], "{"value":%d}", filteringDsm(k, int(dsmTemp10)));
  183.         sumTimeofLow10 = 0;
  184.         dsmStatTimes10 = 0;
  185.         dsmTemp0 = (sumTimeofLow25 * 100.0) / dsmStatTimes25;
  186.         dsmTemp25 = 0.1776 * pow(dsmTemp0, 3) - 0.24 * pow(dsmTemp0, 2) + 94.003 * dsmTemp0;
  187.         dsmTemp25 = dsmTemp10 - dsmTemp25;
  188.         sumTimeofLow25 = 0;
  189.         dsmStatTimes25 = 0;
  190.         lcd.print("PM10:" + String(dsmTemp10), LEFT, 0);
  191.         break;
  192.       }
  193.     case 4://pm25
  194.       {
  195.         dataLength[k] = sprintf(sensorData[k], "{"value":%d}", filteringDsm(k, int(dsmTemp25)));
  196.         lcd.print("PM2.5:" + String(dsmTemp25), LEFT, 10);
  197.         break;
  198.       }
  199.   }
  200. }

  201. void format_String(uint8_t l, uint16_t sensor_Data) {
  202.   uint16_t Tc_100 = sensor_Data;
  203.   uint8_t whole, fract;
  204.   whole = Tc_100 / 10 ; // separate off the whole and fractional portions
  205.   fract = Tc_100 % 10;
  206.   dataLength[l] = sprintf(sensorData[l], "{"value":%d.%d}", whole, fract);
  207. }


  208. boolean gprsINI()
  209. {
  210.   Serial.println("GPRS INI");
  211.   String msg;
  212.   msg = sim800MSG("AT+SAPBR=2,1");
  213.   Serial.println(msg);
  214.   sim800MSG("ATE");
  215.   if (msg.indexOf("OK") > 0)
  216.     if (msg.indexOf("0.0.0.0") > 0)
  217.     {
  218.       sim800MSG("AT+SAPBR=3,1,"Contype","GPRS"");
  219.       sim800MSG("AT+SAPBR=3,1,"APN","UNINET"");
  220.       sim800MSG("AT+SAPBR=1,1");
  221.     }
  222.     else return 1;
  223.   delay(2000);
  224.   return 0;
  225. }

  226. String sim800MSG(String msg)
  227. {
  228.   Serial.println(String("") + "POST DATA:" + msg);
  229.   String str;
  230.   boolean ActionFlag = false;

  231.   if (msg.indexOf("HTTPACTION") > 0)
  232.     ActionFlag = true;

  233.   GSMSerial.println(msg);
  234.   while (!GSMSerial.available())
  235.     delay(10);
  236.   while (GSMSerial.available())
  237.   {
  238.     char c = GSMSerial.read();
  239.     str += c;
  240.     delayMicroseconds(1200);
  241.     // delay(2);
  242.   }

  243.   if (ActionFlag)
  244.   {
  245.     while (!GSMSerial.available())
  246.       delay(10);

  247.     while (GSMSerial.available())
  248.     {
  249.       char c = GSMSerial.read();
  250.       str += c;
  251.       delay(2);
  252.     }
  253.   }
  254.   //  Serial.println(str);
  255.   return str;
  256. }
  257. char feed_gps(uint8_t dataid)
  258. {
  259.   lcd.clrScr();
  260.   newData = false;
  261.   unsigned long chars;
  262.   unsigned short sentences, failed;

  263.   // For one second we parse GPS data and report some key values
  264.   // for (unsigned long start = millis(); millis() - start < 1000;)
  265.   // {
  266.   while (GPS_SERIAL.available())
  267.   {
  268.     char c = GPS_SERIAL.read();
  269.     Serial.write(c); // uncomment this line if you want to see the GPS data flowing
  270.     if (gps.encode(c)) // Did a new valid sentence come in?
  271.       newData = true;
  272.     lcd.clrScr();
  273.     Serial.println("GPS READY!");
  274.     // lcd.print("GPS READY!", CENTER, 15);
  275.   }
  276.   // }

  277.   if (newData)
  278.   {

  279.     float flat, flon;
  280.     unsigned long age;
  281.     int _year;
  282.     byte _month, _day, _hour, _minute, _second, _hundredths;
  283.     gps.f_get_position(&flat, &flon, &age);
  284.     gps.crack_datetime(&_year, &_month, &_day, &_hour, &_minute, &_second, &_hundredths, &age);
  285.     fkmph = gps.f_speed_kmph();
  286.     if ( satnum != TinyGPS::GPS_INVALID_SATELLITES) {
  287.       lcd.print("SAT:" + satnum, CENTER, 40);
  288.     }

  289.     if (fkmph != TinyGPS::GPS_INVALID_F_SPEED)
  290.     {
  291.       if (fkmph < 0.5) fkmph = 0.0; //屏蔽0时速时的误差显示
  292.     }
  293.     else
  294.     {
  295.       fkmph = 0.0;
  296.     }

  297.     if (age == TinyGPS::GPS_INVALID_AGE) {
  298.       Serial.print("********** ******** ");
  299.       //myLCD.print("********** ********", CENTER, 20);
  300.     }
  301.     else
  302.     {
  303.       char gps_date[20];
  304.       char gps_time[9];
  305.       sprintf(gps_date, "%02d/%02d/%02d",
  306.               _month, _day, _year);
  307.       lcd.print(gps_date, LEFT, 20);
  308.       sprintf(gps_time, "%02d:%02d:%02d ",
  309.               _hour, _minute, _second);
  310.       lcd.print(gps_time, LEFT, 30);
  311.     }
  312.     // float fkmph = gps.f_speed_kmph(); // speed in km/hr
  313.     flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6;
  314.     flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 6;
  315.     dtostrf(flat, 11, 6, gps_lat);
  316.     dtostrf(flon, 10, 6, gps_lon);
  317.     sprintf(gps_lon, "LON: %ld", gps_lon);
  318.     sprintf(gps_lat, "LAT: %ld", gps_lat);
  319.     lcd.print(gps_lat, LEFT, 0);
  320.     lcd.print(gps_lon, LEFT, 10);
  321.     Serial.println("lat:"); //latitude
  322.     Serial.println(gps_lat);
  323.     Serial.println("lon:");
  324.     Serial.println(gps_lon);//longitude
  325.     dataLength[dataid] = sprintf(sensorData[dataid], "{"value":{"lat":%d,"lng":%d,"speed":%f}", gps_lat, gps_lon, fkmph);
  326.   }
  327. }

  328. void ShowSerialData()
  329. {
  330.   String str;
  331.   while (GSMSerial.available() != 0)
  332.   {
  333.     char c = GSMSerial.read();
  334.     str += c;
  335.   }
  336.   Serial.print(str);
  337. }
  338. int getLength(int someValue) {
  339.   // there's at least one byte:
  340.   int digits = 1;
  341.   // continually divide the value by ten,
  342.   // adding one to the digit count for each
  343.   // time you divide, until you're at 0:
  344.   int dividend = someValue / 10;
  345.   while (dividend > 0) {
  346.     dividend = dividend / 10;
  347.     digits++;
  348.   }
  349.   // return the number of digits:
  350.   return digits;
  351. }

复制代码

回复

使用道具 举报

 楼主| 发表于 2015-8-3 16:40:59 | 显示全部楼层
求助高手提供一下调试思路或方法。串口没回显不知道怎么改啊!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|联系我们|极客工坊

GMT+8, 2026-6-16 22:38 , Processed in 0.051596 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表