求助SIM900模块无法执行AT命令。
本帖最后由 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
longDeviceID= 168888; // replace your device ID
// 固定的网关
//const char website[] PROGMEM = "api.yeelink.net";
//传感器个数及对应传感器ID
#define N 4
//上传数据的字符串变量及字符串长度变量
char sensorData;
intdataLength;
//传感器IDGPSTEMPHUMPM25
const longSensorID = {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;
char gps_lat;
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);
// Serial.print(SensorID);
// 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, dataLength, sensorData);
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 = {
0, 0
};
uint16_t filtDsm;
uint32_t filtSum = {
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 = filtSum - filtDsm];
filtSum = filtSum + _dsmData;
filtDsm] = _dsmData;
filtI = filtI + 1;
if (filtI >= FILT_N) filtI = 0;
return filtSum / 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 = sprintf(sensorData, "{\"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 = sprintf(sensorData, "{\"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 = sprintf(sensorData, "{\"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;
char gps_time;
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 = sprintf(sensorData, "{\"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;
}
求助高手提供一下调试思路或方法。串口没回显不知道怎么改啊!
页:
[1]