sim900a读取短信之后TCP通信就无法进行。。
我想请教一个问题,我用arduino mega 2560连sim900a实现了两个功能,一个是读短信条数,读取短信,删除短信,第二个是TCP连接,两个功能单独实现能成功,但是合在一起TCP就无法连接,请问这是怎么回事。#include <Narcoleptic.h>#include <EEPROM.h>
#include <SPI.h>
#include <stdlib.h>
int dustPin = 0; //从A0读扬尘值
int ledPower = 2; //扬尘传感器的LED灯开关接引脚2
int pmof = 3; //控制扬尘传感器的开关是3号引脚
int noiseof = 4; //控制噪声传感器的开关是4号引脚
int simof = 5; //控制sim900a的开关是5号引脚
int duanxinnum = 0; //短信的条数
int sleeptime = 0, noisenum = 0; //睡眠时间和噪音测量时间
String ip = ""; //TCP连接时发送用的
String port = ""; //TCP连接时发送用的
String iphex = ""; //存放ip的8个十六进制字符
int ipdec = {0}; //ip四段的十进制数字
int porteeprom1 = 0, porteeprom2 = 0 ; //两字节的端口号
unsigned char noise = 0; //噪声值
int pm = 0; //扬尘值,在0到500之间
unsigned char pmh = 0, pml = 0; //扬尘高位值和低位的值
unsigned char datasend = {0}; //要发送的11个字节的数组
unsigned char datarece = {0}; //接收数据的数组
void setup() {
Serial.begin(9600);
Serial2.begin(2400);
Serial3.begin(9600);
pinMode(ledPower, OUTPUT); //2号引脚设为输出
pinMode(pmof, OUTPUT); //3号引脚设为输出
pinMode(noiseof, OUTPUT); //4号引脚设为输出
pinMode(simof, OUTPUT); //5号引脚设为输出
}
void loop() {
chushihua();
//chulismsip();
while(1)
{
digitalWrite(simof, HIGH); //打开sim900a
digitalWrite(pmof, HIGH);
delay(18000);
pm = getpmnum();
pml = pm % 256; //低位的pm值
pmh = (pm - pml) / 256; //高位的pm值
digitalWrite(pmof, LOW);
// noise = maxnoise(EEPROM.read(7)); //得到噪声值
noise = 62;
duanxinnum = SMSnum();
if ((duanxinnum > 0) && (duanxinnum < 10))
{
chuliduanxin(duanxinnum);
xierueeprom();
}
delallsms();
package();
tcplink();
digitalWrite(simof, LOW); //关闭sim900a
delay(2000);
sleepmode(EEPROM.read(6));
}
//Serial.println(EEPROM.read(8));
//Serial.println(EEPROM.read(9));
//Serial.println(EEPROM.read(10));
// Serial.println(EEPROM.read(11));
// Serial.println(EEPROM.read(12));
// Serial.println();
//Serial.println(sleeptime);
//Serial.println(noisenum);
//Serial.println(ip);
// Serial.println(port);
// Serial.print(iphex);
//Serial.println(pm);
// Serial.println(pmh);
//Serial.println(pml);
delay(5000);
}
int SMSnum() //get the num of sms
{
String datasim = "";
int i = 0, mark = 0, num = 0;
Serial3.print("AT+CPMS=");
Serial3.print('"');
Serial3.print("SM");
Serial3.print('"');
Serial3.print("\r\n");
delay(1000);
while (Serial3.available() > 0)
{
//读入之后将字符串,串接到comdata上面。
datasim += char(Serial3.read());
//延时一会,让串口缓存准备好下一个数字,不延时会导致数据丢失,
delay(2);
//标记串口读过数据,如果没有数据的话,直接不执行这个while了。
mark = 1;
}
if (mark == 1)
// {
//Serial.println(datasim.length());
// for (i = 0; i < datasim.length(); i++)
// {
// Serial.print(datasim);
// delay(100);
//}
// Serial.print(datasim);
num = int(datasim) - 48;
// Serial.print(num);
//datasim = "";
//delay(1000);
//mark = 0;
// }
return num;
}
voidchuliduanxin(int n) //fen 9 tiao du duan xin
{
int i = 1;
//Serial.println(n);
for (i = 1; i <= n; i++)
{
switch (i)
{
case 1:
{
Serial3.print("AT+CMGR=1\r\n");
chulisms();
break;
}
case 2:
{
Serial3.print("AT+CMGR=2\r\n");
chulisms();
break;
}
case 3:
{
Serial3.print("AT+CMGR=3\r\n");
chulisms();
break;
}
case 4:
{
Serial3.print("AT+CMGR=4\r\n");
chulisms();
break;
}
case 5:
{
Serial3.print("AT+CMGR=5\r\n");
chulisms();
break;
}
case 6:
{
Serial3.print("AT+CMGR=6\r\n");
chulisms();
break;
}
case 7:
{
Serial3.print("AT+CMGR=7\r\n");
chulisms();
break;
}
case 8:
{
Serial3.print("AT+CMGR=8\r\n");
chulisms();
break;
}
case 9:
{
Serial3.print("AT+CMGR=9\r\n");
chulisms();
break;
}
}
}
}
void chulisms() //get sms and deal with it
{
int a = 0, mark = 0, i = 0, douhaonum = 0, j = 0, k = 0, p = 0, first = 0, second = 0;
int b = 0, m = 0, n = 0;
unsigned long telnum = 0 ; //电话号码后9位的十进制数
unsigned long time0 = 0, time1 = 0; //记录程序运行的时间差,超过就退出
unsigned long int tempip = 0; //字符型转化为长整型ip的值
long int tempport = 0; //字符型转化为长整型Port的值
int douhao = {0}; //逗号出现的位置
String datasim = "";
char datafirst; //第二个和第三个逗号之间
char datasecond; //第三个和第四个逗号之间
int datajia1 = {0}; //电话号码的前两位的五位八进制
int datajia2 = {0}; //电话号码的后9位的五位八进制
int datajia3 = {0}; //电话号码的进位的五位八进制
for (a = 0 ; a < 2; a++)
{
time0 = millis();
while (!Serial3.available()) //wait until data appear
{
time1 = millis();
if ((time1 - time0) > 2000) //两秒还没有就退出等待
break;
}
while (Serial3.available() > 0)
{
datasim += char(Serial3.read());
//延时一会,让串口缓存准备好下一个数字,不延时会导致数据丢失,
delay(2);
//标记串口读过数据,如果没有数据的话,直接不执行这个while了。
mark = 1;
}
}
if (mark == 1) // deal with sms
{
// Serial.println(datasim.length());
//for (i = 0; i < datasim.length(); i++)
// {
// Serial.print(datasim);
// delay(30);
//}
for (i = 0; i < (datasim.length()); i++)
{
if (datasim == 'Z')
if (datasim == 'N')
if (datasim == 'G')
if (datasim == 'Y') //add a if jiaoyan
{
if (datasim == '2')
{
for (j = i; j < i + 28; j++) //标记逗号在datasim里的位置
{
if (datasim == ',')
{
douhao = j;
douhaonum++;
}
}
for (k = douhao + 1; k < douhao; k++) //逗号2和逗号3之间的赋给datafirst
{
datafirst = datasim;
first++;
}
datafirst = '\0';
for (p = douhao + 1; p < douhao; p++) //逗号3和逗号4之间的赋给datasecond
{
datasecond = datasim;
second++;
}
datasecond = '\0';
tempip = atol(datafirst);
tempport = atol(datasecond);
PrintHex(tempip);
ipdec = hextodec(iphex, iphex); //将ip从十六进制转化为4段十进制数
ipdec = hextodec(iphex, iphex);
ipdec = hextodec(iphex, iphex);
ipdec = hextodec(iphex, iphex);
dectostring(ipdec, ipdec, ipdec, ipdec); //将十进制数转化成ip字符串
port = "";
for (b = 0; b < 8; b++)
{
if (datasecond == '\0')
break;
port += datasecond;
}
porteeprom2 = tempport % 256;
porteeprom1 = (tempport - porteeprom2) / 256;
Serial.println(tempip);
Serial.println(tempport);
}
if (datasim == '3')
{
for (j = i; j < i + 20; j++) //标记逗号在datasim里的位置
{
if (datasim == ',')
{
douhao = j;
douhaonum++;
}
}
for (k = douhao + 1; k < douhao; k++) //逗号2和逗号3之间的赋给datafirst
{
datafirst = datasim;
first++;
}
datafirst = '\0';
for (p = douhao + 1; p < douhao; p++) //逗号3和逗号4之间的赋给datasecond
{
datasecond = datasim;
second++;
}
datasecond = '\0';
sleeptime = atoi(datafirst);
noisenum = atoi(datasecond);
}
if (datasim == '6')
{
for (j = i; j < i + 25; j++) //标记逗号在datasim里的位置
{
if (datasim == ',')
{
douhao = j;
douhaonum++;
}
}
for (k = douhao + 3; k < douhao; k++) //逗号2和逗号3之间的赋给datafirst
{ //datafirst存储电话号码后九位的字符串
datafirst = datasim;
first++;
}
datafirst = '\0';
telnum = atol(datafirst); //后九位从字符串转换为十进制数
datajia2 = bitRead(telnum, 0) + bitRead(telnum, 1) * 2 + bitRead(telnum, 2) * 4 + bitRead(telnum, 3) * 8 + bitRead(telnum, 4) * 16 + bitRead(telnum, 5) * 32 + bitRead(telnum, 6) * 64 + bitRead(telnum, 7) * 128;
datajia2 = bitRead(telnum, 8) + bitRead(telnum, 9) * 2 + bitRead(telnum, 10) * 4 + bitRead(telnum, 11) * 8 + bitRead(telnum, 12) * 16 + bitRead(telnum, 13) * 32 + bitRead(telnum, 14) * 64 + bitRead(telnum, 15) * 128;
datajia2 = bitRead(telnum, 16) + bitRead(telnum, 17) * 2 + bitRead(telnum, 18) * 4 + bitRead(telnum, 19) * 8 + bitRead(telnum, 20) * 16 + bitRead(telnum, 21) * 32 + bitRead(telnum, 22) * 64 + bitRead(telnum, 23) * 128;
datajia2 = bitRead(telnum, 24) + bitRead(telnum, 25) * 2 + bitRead(telnum, 26) * 4 + bitRead(telnum, 27) * 8 + bitRead(telnum, 28) * 16 + bitRead(telnum, 29) * 32 + bitRead(telnum, 30) * 64 + bitRead(telnum, 31) * 128;
datajia2 = 0;
m = int(datasim + 2]);
switch (m)
{
case 48:
{
datajia1 = 2; datajia1 = 84; datajia1 = 11;
datajia1 = 228; datajia1 = 0;
break;
}
case 49: {
datajia1 = 2; datajia1 = 143; datajia1 = 166;
datajia1 = 174; datajia1 = 0;
break;
}
case 50: {
datajia1 = 2; datajia1 = 203; datajia1 = 65;
datajia1 = 120; datajia1 = 0;
break;
}
case 51: {
datajia1 = 3; datajia1 = 6; datajia1 = 220;
datajia1 = 66; datajia1 = 0;
break;
}
case 52: {
datajia1 = 3; datajia1 = 66; datajia1 = 119;
datajia1 = 12; datajia1 = 0;
break;
}
case 53: {
datajia1 = 3; datajia1 = 126; datajia1 = 17;
datajia1 = 214; datajia1 = 0;
break;
}
case 54: {
datajia1 = 3; datajia1 = 185; datajia1 = 172;
datajia1 = 160; datajia1 = 0;
break;
}
case 55: {
datajia1 = 3; datajia1 = 245; datajia1 = 71;
datajia1 = 106; datajia1 = 0;
break;
}
case 56: {
datajia1 = 4; datajia1 = 48; datajia1 = 226;
datajia1 = 52; datajia1 = 0;
break;
}
case 57: {
datajia1 = 4; datajia1 = 108; datajia1 = 124;
datajia1 = 254; datajia1 = 0;
break;
}
}
datajia1 = datajia2;
for (n = 3; n > 0; n--)
{
datajia1 = datajia2 + datajia1 + datajia3;
if (datajia1 > 255)
{
datajia1 = datajia1 - 256;
datajia3 = 1;
}
}
datajia1 = datajia1 + datajia3;
EEPROM.write(8, datajia1);
delay(10);
EEPROM.write(9, datajia1);
delay(10);
EEPROM.write(10, datajia1);
delay(10);
EEPROM.write(11, datajia1);
delay(10);
EEPROM.write(12, datajia1);
delay(10);
}
}
}
datasim = "";
mark = 0;
}
Serial.print("\r\n");
}
void PrintHex(unsigned long a) //将ip从长整型转化为十六进制的8个字符
{
iphex = "";
char *Hex = "0123456789ABCDEF";
if (!a)return;
PrintHex(a / 16);
iphex += Hex;
}
int hextodec(char a, char b)
{
int num = 0, c = 0, d = 0;
if (a < 58)
c = a - 48;
else
c = a - 55;
if (b < 58)
d = b - 48;
else
d = b - 55;
num = c * 16 + d;
return num;
}
void dectostring(int a, int b, int c, int d) //将十进制数转化成ip字符串
{
int ipbit1 = 0, ipbit2 = 0, ipbit3 = 0;
ip = "";
ipbit3 = a % 10;
ipbit2 = ((a - ipbit3) / 10) % 10;
ipbit1 = (a - ipbit3 - 10 * ipbit2) / 100;
if (ipbit1 != 0)
ip += char(ipbit1 + 48);
ip += char(ipbit2 + 48);
ip += char(ipbit3 + 48);
ip += '.';
ipbit3 = b % 10;
ipbit2 = ((b - ipbit3) / 10) % 10;
ipbit1 = (b - ipbit3 - 10 * ipbit2) / 100;
if (ipbit1 != 0)
ip += char(ipbit1 + 48);
ip += char(ipbit2 + 48);
ip += char(ipbit3 + 48);
ip += '.';
ipbit3 = c % 10;
ipbit2 = ((c - ipbit3) / 10) % 10;
ipbit1 = (c - ipbit3 - 10 * ipbit2) / 100;
if (ipbit1 != 0)
ip += char(ipbit1 + 48);
ip += char(ipbit2 + 48);
ip += char(ipbit3 + 48);
ip += '.';
ipbit3 = d % 10;
ipbit2 = ((d - ipbit3) / 10) % 10;
ipbit1 = (d - ipbit3 - 10 * ipbit2) / 100;
if (ipbit1 != 0)
ip += char(ipbit1 + 48);
ip += char(ipbit2 + 48);
ip += char(ipbit3 + 48);
}
void xierueeprom()
{
EEPROM.write(0, ipdec); //将四段ip和两字节的端口号写入EEPROM
delay(10);
EEPROM.write(1, ipdec);
delay(10);
EEPROM.write(2, ipdec);
delay(10);
EEPROM.write(3, ipdec);
delay(10);
EEPROM.write(4, porteeprom1);
delay(10);
EEPROM.write(5, porteeprom2);
delay(10);
EEPROM.write(6, sleeptime); //向EEPROM写入睡眠时间
EEPROM.write(7, noisenum); //向EEPROM写入噪音的次数
}
int getpmnum()
{
float ppm = 0;
//char s;
float voltage = 0;
float dustdensity = 0;
float ppmpercf = 0;
int i = 0, a = 0, b = 0;
int delayTime = 280;
int delayTime2 = 40;
int dustVal = 0;
float offTime = 9680;
for (a = 0; a < 2; a++)
{
//i = i + 1;
digitalWrite(ledPower, LOW); // power on the LED++++++
delayMicroseconds(delayTime);
dustVal = analogRead(dustPin); // read the dust value
//ppm = ppm + dustVal;
delayMicroseconds(delayTime2);
digitalWrite(ledPower, HIGH); // turn the LED off
delayMicroseconds(offTime);
voltage = dustVal* 0.0049;
//voltage = ppm / i * 0.0049;
dustdensity = 0.17 * voltage - 0.1;
ppmpercf = (voltage - 0.0256) * 120000;
if (ppmpercf < 0)
ppmpercf = 0;
if (dustdensity < 0 )
dustdensity = 0;
if (dustdensity > 0.5)
dustdensity = 0.5;
// dataString = "";
// dataString += dtostrf(voltage, 9, 4, s);
// dataString += ",";
// dataString += dtostrf(dustdensity, 5, 2, s);
//dataString += ",";
//dataString += dtostrf(ppmpercf, 8, 0, s);
//i = 0;
//ppm = 0;
delay(200);
}
b = dustdensity * 1000;
return b;
}
int getnoisenum()
{
String noise = ""; //噪声字符串
int a = 0, i = 0, j = 0, k = 0, m = 0;
int noiseint = 0; //整型噪声值
noise = "";
while (!Serial2.available())
{
}
while (Serial2.available() > 0)
{
noise += char(Serial2.read());
delay(2);
}
noiseint = (noise - 48) * 100 + (noise - 48) * 10 + (noise - 48);
return noiseint;
}
void chushihua() //初始化,如果EEPROM是255,加参数写入,然后将EEPROM的数据赋给全局变量。
{
int a = 0, b = 0, port1 = 0, port2 = 0;
unsigned int c = 0, i = 0; //端口的整型
int d = 0, e = 0;
char f = 0;
char aa;
a = EEPROM.read(0);
b = EEPROM.read(1);
if ((a == 255) && (b == 255))
{
EEPROM.write(0, 219); //初始化的数据,包括ip,Port,休眠时间(30),噪音采集次数(3)
delay(10);
EEPROM.write(1, 245);
delay(10);
EEPROM.write(2, 68);
delay(10);
EEPROM.write(3, 1);
delay(10);
EEPROM.write(4, 39);
delay(10);
EEPROM.write(5, 15);
delay(10);
EEPROM.write(6, 30); //休眠时间(30)
delay(10);
EEPROM.write(7, 3); //噪音采集次数(3)
delay(10);
}
ipdec = EEPROM.read(0);
ipdec = EEPROM.read(1);
ipdec = EEPROM.read(2);
ipdec = EEPROM.read(3);
dectostring(ipdec, ipdec, ipdec, ipdec); //将十进制数转化成ip字符串
porteeprom1 = EEPROM.read(4);
porteeprom2 = EEPROM.read(5);
c = porteeprom1 * 256 + porteeprom2; //itoa只能取到3万多,所以要把最高位单独列出来
e = c % 10000;
d = (c - e) / 10000;
f = d + 48;
itoa(e, aa, 10);
if (d != 0)
port += f;
for (i = 0; i < 6; i++)
{
if (aa != '\0')
port += aa;
}
sleeptime = EEPROM.read(6);
noisenum = EEPROM.read(7);
}
void package() //将数据组包
{
int i = 0;
int j = 0;
datasend = 11;
datasend = 1;
datasend = EEPROM.read(8);
datasend = EEPROM.read(9);
datasend = EEPROM.read(10);
datasend = EEPROM.read(11);
datasend = EEPROM.read(12);
datasend = pmh;
datasend = pml;
datasend = noise;
for (i = 0; i < 10; i++)
j = datasend + j;
datasend = j ^ 169;
}
void tcplink() //与数据中心进行TCP通信传输数据接收配置参数
{
int i = 0;
unsigned int c = 0; //端口的整型
int d = 0, e = 0;
char f = 0;
char aa;
Serial3.print("AT+CIPMODE=1\r\n");
delay(2000);
Serial3.print("AT+CIPSTART=");
Serial3.print('"');
Serial3.print("TCP");
Serial3.print('"');
Serial3.print(',');
Serial3.print('"');
Serial3.print(ip);
Serial3.print('"');
Serial3.print(',');
Serial3.print(port);
Serial3.print("\r\n");
while (1)
{
if (Serial3.find("CONNECT"))
break;
delay(10);
}
for (i = 0; i < 11; i++)
Serial3.write(datasend);
while (1)
{
i = 0;
while (!Serial3.available())
{
}
while (Serial3.available() > 0)
{
datarece = Serial3.read();
i++;
delay(2);
}
// for (j = 0; j < i; j++)
// Serial.println(datarece);
if (datarece == 2)
{
if (datarece == 129)
for (i = 0; i < 11; i++)
Serial3.write(datasend);
if (datarece == 161)
break;
}
if (datarece == 8)
{
EEPROM.write(0, datarece);
delay(10);
EEPROM.write(1, datarece);
delay(10);
EEPROM.write(2, datarece);
delay(10);
EEPROM.write(3, datarece);
delay(10);
EEPROM.write(4, datarece);
delay(10);
EEPROM.write(5, datarece);
delay(10);
dectostring(datarece, datarece, datarece, datarece); //将十进制数转化成ip字符串
port = "";
porteeprom1 = datarece;
porteeprom2 = datarece;
c = porteeprom1 * 256 + porteeprom2; //itoa只能取到3万多,所以要把最高位单独列出来
e = c % 10000;
d = (c - e) / 10000;
f = d + 48;
itoa(e, aa, 10);
if (d != 0)
port += f;
for (i = 0; i < 6; i++)
{
if (aa != '\0')
port += aa;
}
Serial3.write(2); //配置ip和Port并发出响应
Serial3.write(162);
if (datarece == 162)
break;
}
if (datarece == 4)
{
EEPROM.write(6, datarece);
delay(10);
EEPROM.write(7, datarece);
delay(10);
sleeptime = datarece;
noisenum = datarece;
Serial3.write(2); //配置休眠时间和噪音采集次数并发出响应
Serial3.write(163);
if (datarece == 163)
break;
}
}
}
int maxnoise(int a)
{
unsigned char nn = {0}, b = 0;
int i = 0;
for (i = 0; i < a; i++)
{
nn = getnoisenum();
delay(16000);
}
for (i = 0; i < a; i++)
{
b = max(b, nn);
}
return b;
}
void delallsms() //删除所有短信
{
Serial3.print("AT+CMGDA=");
Serial3.print('"');
Serial3.print("DEL ALL");
Serial3.print('"');
Serial3.print("\r\n");
}
void sleepmode(int a) //进入休眠模式
{
int i = 0;
for(i = 0;i < (2*a);i++)
Narcoleptic.delay(30000);
}
void chulismsip() //每隔一段时间读短信,有电话号码就跳出否则一直循环
{
while (1)
{
int a = 0;
a = EEPROM.read(8);
if (a == 255)
{
duanxinnum = SMSnum();
if ((duanxinnum > 0) && (duanxinnum < 10))
chuliduanxin(duanxinnum);
}
else
break;
a = EEPROM.read(8);
if (a == 255)
sleepmode(30);
else
break;
}
} 代码有点长,参考一下就可以了 34行和46到52行屏蔽了,下面的TCP连接就行,恢复短信操作后就不行了 另外,我单独用串口调试工具操作sim900a,就不存在这个问题,短信操作之后TCP也能连上啊。
内存爆了? 不是,全局变量用了10%,程序存储空间用了6% 想问一下ardunio uno和sim900a您是怎么连接的用的哪些口 'Serial2'was not declared in this scope请问下这个是怎么回事 'Serial2只有arduino mega 2560里才有,Uno只有一对串口,mega 2560有4对,你是不是用Uno的,极客工坊的知识库里有。 你如果想要在Uno用多对串口,可以用软串口库试试。
页:
[1]