舟泊烟渚 发表于 2013-9-22 00:38:12

基于SIM900A的智能家居之----远程完全控制电脑

SIM900A,集成GSM和GPRS功能,可是鲜见玩GPRS 的,论坛里也没有多少用900a的朋友,早想远程控制家电,觉得论便携移动还有成本来说,900a比ENC28J60和W5100有优势,当然实时数据传输还得后者,所以小弟斗胆献丑,扒一扒SIM900a的事儿。
上个月我把家里路由器的9v电源插到SIM900A上让电流倒灌到uno中烧了板子和1602,后来用万用表测电压,着实被吓了一跳,明明是直流电但是电压高一下低一下,我勒个去,还是PWM的电压?!
后来买了mega2560,没有了uno程序到19kb就烧录不了(可能是变量太多?)的问题,这次写智能家居也差不多这么大,完全没问题,可是为什么uno上能播放的SD卡音乐mega却识别不了??
进入正题,先前装了网灵客户端,可以用手机或者电脑访问控制另一台电脑,晚上手机AP上网不用下床就能关了电脑,远程调文件什么的so easy,当然用GPRS流量访问的话一个电脑截屏300多kb,您自己斟酌着用。这么好的软件(俺还不是付费升级用户)唯一不能做的,就是开电脑了,咱不能为了以防万一需要电脑文件就24小时开着PC吧。睡眠休眠?不好意思,那样的话会自动断网,断网了的话当然控制不了电脑了。所以,我的智能家居第一步,控制电脑开机(关机什么的就用网灵)。
所用配件:
         Arduino什么板都可以,本人2560,60元;
         SIM900A 模块,142元;
         USBtinyISP(这个因为我不小心下程序时没拔连900a的串口线,不知道烧了什么,后来bootloader也烧不上,万幸用编程器下载程序能用,就是每次下载完了拔掉线插mega麻烦),35元;
         舵机,耳麦,红外遥控器和接收头,三色RGB灯,蜂鸣器;
         木板,钉子,锯子等,反正您看着什么合适能成就用吧;

连线的话根据自己的板子在代码开头相应位置改,就不说了,上代码(I2C什么的被我烧了,有的可以连上,没有的不管也可):
int ledpin=13;   //定义数字接口13
int val;         //定义变量val
#include<LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);
#include<Wire.h>
#include <Servo.h>
Servo myservo;
#define MAXCHAR 81 //recive buff max char,81 orginally

#include<IRremote.h>
int RECV_PIN = 5;
IRrecv irrecv(RECV_PIN);
decode_results results;

int buzzer=53;
int redpin=A9;
int bluepin=A10;
int greenpin=A8;

//#include "Raw.h"
//#include "Message.h"
char aa;//recive gsm model back signal,接收GSM的返回信号GSM》》Atmega
int j=0;         //recive index   
int g_timeout=0;   //handing time
int k=0;         //sms content identifier
int l=0;         //sms send to number identifier
int m=0;         //call identifier
//boolean flag2=0;
//unsigned long time;
boolean flag=0;
boolean flag1=0;
////////////////////////////////////////////////////
char ATE0[]="ATE0";
char CREG_CMD[]="AT+CREG?";////////////网络注册信息
char SMS_send[]="AT+CMGS=18";//////////发送短消息
char ATCN[]="AT+CNMI=2,1";///////////////新消息指示
char CMGF0[]="AT+CMGF=0";//////////////设置短消息的发送格式PDU
char CMGF1[]="AT+CMGF=1";//////////////纯文本
char CMGR="AT+CMGR=1";////////////读取短消息
char CMGD="AT+CMGD=1";////////////删除所有已读短消息
///////////////////////////////////////////////////
#define SEND_MESSA_TO_YOUR "at+cmgs=\"159********\"\r\n"    //l=0
#define SEND_MESSA_TO_YOUR_1 "at+cmgs=\"182********\"\r\n"//l=1

#define SEND_MESSA_CONTENT "From SIM900A"                   //k=0
#define SEND_MESSA_CONTENT_1 "Master,servo moved done"      //k=1

#define CALL_YOU_TELNUMBER "ATD159********;\r\n"            //m=0
#define CALL_YOU_TELNUMBER_1 "ATD182********;\r\n"          //m=1
///////////////////////////////////////////////////

/*
Read input serial
*/
int readSerial(char result[])///////////////////////////////////SIM900a to Arduino
{
int i = 0;
while (Serial.available() > 0)//返回串口缓冲区字符个数 已经传输到,并存储在串行接收缓冲区(能够存储64个字节)的字节数(字符)。
{
    char inChar = Serial.read();
    if (inChar == '\n')////////////////换行,一次只能读一行
    {
      result = '\0';///////////////string end
      Serial.flush();/////////////////一次发送串口接收缓冲器中存储的数据(ATD159*******)
      return 0;//////////////////////if中的跳出用法
    }
    if(inChar!='\r')
    {
      result = inChar;
      i++;
    }
}
}

/*
clean buff
*/
void clearBuff(void)
{
for(j=0;j<MAXCHAR;j++)
{
    aa=0x00;
}
j=0;
}

/*
clean buff
*/
int Hand(char *s)
{
delay(200);
clearBuff();
delay(300);
readSerial(aa);//////////////////////////aa[]=result[]
if(strstr(aa,s)!=NULL)             //检测单片机和模块的连接,aa中若有s字符 串
{
    g_timeout=0;
    clearBuff();
    return 1;
}
if(g_timeout>50)
{
    g_timeout=0;
    return -1;
}
g_timeout++;////////////////半秒加一
return 0;
}


/*
13 LED test
*/
void led(int i)
{
if(i)
{
    digitalWrite(ledpin,HIGH);//点亮数字13 口LED。
    delay(500);
}
else
{
    digitalWrite(ledpin,LOW);//熄灭数字13 口LED
    delay(500);
}
}

void AT(void)
{
clearBuff();
Serial.println(ATE0);////////////
delay(100);
readSerial(aa);

while(strstr(aa,"OK")==NULL)//////////OK在aa中第一次出现的位置,如果没有则返回NULL
{
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("connect [..]");

    clearBuff();
    led(1);
    Serial.println(ATE0);
    delay(500);
    readSerial(aa);
    led(0);
}

    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print(" connected");

clearBuff();
Serial.println(ATCN);
delay(500);
while(Hand("OK")==0);//////////////////aa中第二次出现OK字符串

clearBuff();
Serial.println("AT+CLCC");
delay(500);
while(Hand("OK")==0);               //laidianxianshi phone number
clearBuff();
Serial.println("AT+CLIP=1\r\n");
delay(500);
while(Hand("OK")==0);//////////////////aa中第二次出现OK字符串

while(1)
{
    clearBuff();
    Serial.println(CREG_CMD);          //AT+CREG?
    delay(500);
    readSerial(aa);

    if((strstr(aa,"0,1")!=NULL)||(strstr(aa,"0,5")!=NULL))/////////出现0,1或0,5了的话……
    {
      clearBuff();
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print(" register ");
      Serial.println("OK");
      break;//////////////////////跳出while(1)
    }
    else
    {
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print(" register [..]");
      delay(500);
    }
}
}


void send_english(int l,int k)
{
clearBuff();
Serial.println(CMGF1);/////////设置发送格式为文本
delay(200);               //not necessary as hand() delay 0.5s
while(Hand("OK")==0);////////aa中没有OK字符串就先在此等待;

clearBuff();
switch(l){
    case 0:
         Serial.println(SEND_MESSA_TO_YOUR);
         break;
    case 1:
         Serial.println(SEND_MESSA_TO_YOUR_1);
         break;
}
delay(200);
while(Hand(">")==0);/*在接收电话号码与短信内容之间的必填字符,we can't use delay() here,cause??????????
function Hand() invoking readSerial(aa),and ">" will be transmitted immediately,once we missed ">",aa can not got it one more time*/
switch(k){
case 0:
clearBuff();
Serial.println(SEND_MESSA_CONTENT);//发短信内容
break;
case 1:
clearBuff();
Serial.println(SEND_MESSA_CONTENT_1);//发短信内容
break;
}
while(Hand(">")==0);
delay(100);               //not necessary
Serial.print("\x1A");      //发送结束符号,\x means hex
delay(10);

delay(1000);                //real sending sms time
while(Hand("OK")==0);
}



void send_call(int m)
{
clearBuff();
switch(m){
    case 0:
         Serial.println(CALL_YOU_TELNUMBER); //打电话
         break;
    case 1:
         Serial.println(CALL_YOU_TELNUMBER_1); //打电话
         break;
}
delay(2000);
while(Hand("OK")==0);
}

void color (unsigned char red, unsigned char green, unsigned char blue)
{   
          analogWrite(redpin, 255-red);   
          analogWrite(bluepin, 255-blue);
          analogWrite(greenpin, 255-green);
}

void setup (void) {
pinMode(buzzer,OUTPUT);
pinMode(redpin, OUTPUT);
pinMode(greenpin, OUTPUT);
pinMode(bluepin, OUTPUT);
myservo.attach(9);
myservo.write(90);

lcd.init(); // initialize the lcd
lcd.backlight();
Serial.begin(9600);//设置波特率为9600
pinMode(ledpin,OUTPUT);//设置数字13 口为输出接
irrecv.enableIRIn();          //启动红外解码
Serial.println("serial port !");//显示字符串
}

void loop (void) {
int aa13,aa12,y;//index,index1;
char sms,cmgr;
boolean flag_read=0;
//String comdata="";
//char subaa;
//String aaa;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Welcome To");
lcd.setCursor(0,1); // 定义光标位置为第二行第二个位置
delay(10);
lcd.print("www.csgsm.com");
delay(100);
color(255,0,255);         //待机中,绿色
digitalWrite(buzzer,LOW);
AT();
myservo.write(100);
clearBuff();            //删除则报错
while(1)
{
   while(Serial.available()>0)
   {
   delay(50);      //'L'型读写串行数据缓冲器
   readSerial(aa);
   if(strstr(aa,"RING")!=NULL)               //call in
       {
       Serial.println(aa);
       lcd.print("got a call from:");
       Serial.println("RING,Answer?");      //set buzzer on,which modulated by pulse wave
       flag=1;                                 //zhi jie ting biao zhi
       Serial.flush();                        //
       clearBuff();
       color(0,255,255);                     //来电话,红色
       while(!(irrecv.decode(&results)))
       {
       digitalWrite(buzzer,HIGH);
       delay(300);
       digitalWrite(buzzer,LOW);
       delay(400);
       }
      
       }
      if(strstr(aa,"+CMTI: \"SM\","))            //if we got a message
      {
      color(255,255,0);    //blue
      aa13=aa;
      aa12=aa;
      y=(aa12-48)*10+(aa13-48);
      lcd.clear();
      lcd.print(aa);
      Serial.print("Read message ");
      /*Serial.print(aa);          //+
      Serial.print(aa);         //"
      Serial.print(aa);         //,
      Serial.print(aa);         //3
      Serial.print(aa);         //4
      Serial.print(aa);         //
      Serial.print(aa); */
      Serial.print(y);
      Serial.println("?");
      Serial.println(aa);
      flag1=1;      //got a sms
      flag_read=0;//haven't read yet
         cmgr='A';
         cmgr='T';
         cmgr='+';
         cmgr='C';
         cmgr='M';
         cmgr='G';
         cmgr='R';
         cmgr='=';
         cmgr=aa;
         cmgr=aa;
         cmgr='\r';
         cmgr='\n';
         cmgr='\0';
         Serial.flush();//if we don't clear now,this serial.available check would run all the time and occupy too much ir's check time
      }
   }                                              //while(Serial.available) end
   if (irrecv.decode(&results))
   {
    switch(results.value)
    {
   case 0xFF22DD:
          color(0,0,0);
          AT();                     //initialization
          color(255,0,255);             //white light
          break;
   case 0xFF30CF:               //"1",发短信
          lcd.clear();            // 屏幕清空,光标位置归零
          lcd.setCursor(0,0);
          lcd.print(" send sms [..]");
          k=0;
          send_english(l,k);      //k
          break;
   case 0xFF18E7:               //"2",发短信
          lcd.clear();            // 屏幕清空,光标位置归零
          lcd.setCursor(0,0);
          lcd.print(" send sms [..]");
          k=1;
          l=0;
          send_english(l,k);      
          break;
      case 0xFF42BD:                  //"7"call out
         lcd.clear(); // 屏幕清空,光标位置归零
         lcd.setCursor(1,1);// 定义光标位置为第二行第二个位置
         lcd.print(CALL_YOU_TELNUMBER);
         delay(10);
         lcd.setCursor(1,0);
         delay(10);
         m=0;
         color(0,255,255);
         send_call(m);
         delay(5000);
      case 0xFF52AD:                  //"9"answer call in
         if(flag)
         {
         color(255,255,0);
         for(int w=0;w<50;w++)
         {
         digitalWrite(buzzer,HIGH);
         delay(5);
         digitalWrite(buzzer,LOW);
         delay(5);
         }
         digitalWrite(buzzer,LOW);
         Serial.println("ATA\r\n");
         }
         break;
      case 0xFFA25D:                      //"ON/OFF" hang up
         Serial.println("ATH\r\n");
         color(255,0,255);
         break;
      case 0xFFB04F:                     //press U\SD button,read SMS again;at the first time we read automatically
         clearBuff();
         Serial.flush();
         color(255,0,255);
         Serial.print(cmgr);
         delay(200);
         readSerial(aa);         //读出第一行,带走换行符,下一个a
         while(strstr(aa,"+CMGR:")==NULL)
         {
             clearBuff();
             delay(400);
             readSerial(aa);
         }
         Serial.println(aa);
         
         Serial.println("Receive SMS from:");
         if(flag_read==0)
         {
         for(int i=24;i<35;i++)
         {
             Serial.print(aa);
         }
         }
         else
         {
             for(int i=22;i<33;i++)
             {
             Serial.print(aa);
             }
         }
         flag_read=1;
         
         Serial.print("\r\n");      //0x0D其十进制ASCII码为13.第二次读短信read变unread,号码位置有所变动
         Serial.println("Remaining room of serial buffer:");
         Serial.println(Serial.available()); //aa接收完了串口缓冲器里的数据,读一个少一个,最后没了为0
         for(int j=0;j<5;j++)
         {
             sms=char (Serial.read());
         }
         Serial.print(sms);
         
         switch(sms)
         {
         case 0x61:
                  myservo.write(110);    //110 middle,90 up
                  delay(400);
                  break;
            default:break;
         }
         
         clearBuff();
         Serial.flush();
         color(255,0,255);
         break;
    }                                    //switch over
    irrecv.resume();
} //if(IR.available) over
    if(flag1==1)
    {
         clearBuff();
         Serial.flush();
         color(255,255,0);
         Serial.println(cmgr);
         delay(200);
         readSerial(aa);         //读出第一行,带走换行符,下一个b
         while(strstr(aa,"+CMGR:")==NULL)
         {
             clearBuff();
             delay(400);
             readSerial(aa);
         }
         Serial.println("move servo");
         Serial.println(aa);
         clearBuff();
         for(int j=0;j<5;j++)
         {
             sms=char (Serial.read());
         }
         Serial.println(sms);
         switch(sms)
         {
         case 0x62:
                myservo.write(120);
                delay(2500);
                myservo.write(80);
                //send_english(1,1);
                delay(1000);
                break;
         }
         color(255,0,255);
         flag1=0;
         flag_read=1;
    }//if(flag1)end
}//while(1) never end
} //loop end
注意由于读取短信的AT指令长于64字节,要把串口缓冲区改到128字节,这个在吧里搜(先前一直怕引起其他麻烦没用,后来实验效果很好)。
目前功能,正常的拨打电话,接听电话,读取短信(产生控制舵机命令),发送某内容短信给某电话。读取短信时是首先Arduino自己读一遍,是某个命令(这里收到“b”就让舵机工作)就执行指定的操作,不是不执行,这是远程控制操作,而后遥控器按键可以再次读取这条短信,即使是已读的(可以改改液晶显示放在客厅当座机用)。
接下来扒一扒本屌自制的舵机驱动的开电脑开关,手头只有木头钉子,什么乐高积木、机械之类的东西一概没有。制成才发现木头确实是最适合的材料。图见““C”形舵机架”。
三块木板钉一起成“C”形,舵机用螺丝、钢针固定,用粗铁丝或钢丝折成“L"形,小拐弯处用于插入舵机头。铁丝另一端插入一根小木头(我用的筷子^_^...),木头下端穿过固定在木板上的瓶盖,最后将铁丝和舵机柄上的小孔捆绑起来。舵机转到100居中,转到120时木头向下顶住笔记本电源键。

最后说SIM900A的事儿,没有的童鞋绕道吧,都是些繁琐的细节问题。
一、串口调试方法(先用GSM串口调试工具玩熟练,把该记的指令记下)
1.短接跳线帽不要
2.插SIM卡,RS232线连好,电源接上等到由0.8s闪烁一次变为3s闪烁一次时打开串口调试助手
3.COM口不要大于5,越小越好
4.Arduino和电脑间有串行数据缓冲器,但是与SIM900a间没有?
5.打电话测试ATD13399059548;分号必须
6.接电话 AT+CLIP=1来电显示,ATA接听,ATH挂机
7.开机加电源后等几秒再开串口调试器
8.持续CREG不返回OK时试试重启或按reset
9.持续ATE0?串口调试工具没有关闭并安全退出,重新打开并关闭退出,或等模块灯3s闪两次后再开IDE串口
即-下程序,拔USB,开服务器,插USB,等3s灯,开串口
10.while();{}中的“;”编译器检测不出来,复制代码时注意
11.使用USBtinyISP下载程序时先连ISP到电脑,再连到mega,下载程序需要1分钟,红线靠Uart口.十根线不能拔
12.多次发送AT指令并检测返回信号提高接收率且最主要能接收几行readSerial(aa)遇换行跳出

一个小问题,执行程序时舵机不停地响动,貌似是检测位置,不知道如何解决,有经验的请留步。
SIM900A调试起来不像吧里其他GSM模块,没有库函数,只能发送接收AT指令,问题很多,欢迎交流。

heiketiguo 发表于 2013-9-22 12:14:15

我有个SIM900A,一直放着。多谢分享!

long1225cn 发表于 2013-9-27 22:16:11

原来你的是笔记本电脑,用陀机控制。我做的是台式办公电脑的远程开机,直接加个继电器并接至电脑的电源开关,需要的时候发脉冲模拟电源开关动作电脑就启动了,也就是继电器合上150ms后断开就可以了。我的代码很简单哦!你都已经把串口缓冲区改到128字节了,直接使用String函数就可以了。我在TC35i,sim900A,GTB900B等几个模块上都调试通过了!

程序与GTM900通信正常,接收短信正常,可以控制继电器。完全能判断是不是我的手机号发的短信,短信内容也能判断,必须是我的手机号发的正确的短信内容,继电器才会动作。否则只是指示灯闪烁6次。添加了断电又上电后的判断,因为模块上电后就会向单片机发送AT-Command Interpreter ready命令,程序判断收到关键词“Interpreter”或者短信收到“Interpreter”,整个模块(等待30秒,给模块找网络的时间,单片机就向模块发AT指令初始化)就重新初始化。
String comdate="";
String s1="+CMT:";
String s2="861388XXXXXXX";
String s3="QDDN2013QC";
String s4="Interpreter";


while(Serial.available()>0)
{
comdate+=char(Serial.read());
   delay(10);
}

if(comdate.length()>0)
{
if(comdate.indexOf(s1)!=-1&&comdate.indexOf(s2)!=-1&&comdate.indexOf(s3)!=-1)
{
    digitalWrite(8,HIGH);
      delay(150);
      digitalWrite(8,LOW);
       delay(50);
      
       digitalWrite(13,HIGH);
      delay(1000);
      digitalWrite(13,LOW);
       delay(50);
comdate=String("");
Serial.println("AT+CMGD=1,4");
      
}



long1225cn 发表于 2013-9-27 22:19:43

自己用AT命令很灵活啊,官网的库函数换模块的时候就要去修改库函数了哦!
我都是自己写:
delay(3500);
pinMode(8,OUTPUT);
pinMode(13,OUTPUT);
Serial.begin(9600);
delay(100);
Serial.println("AT");
delay(350);
Serial.println("ATE0");
delay(350);
Serial.println("AT+CMGF=1");
delay(350);
Serial.println("AT+CNMI=2,2");
delay(350);
Serial.println("AT&W");
delay(350);
Serial.println("AT+CMGD=1,4");
delay(350);
comdate=String("");

long1225cn 发表于 2013-9-27 22:24:20

你的代码太像 创思通信的示例代码了!我不太会用指针,也不喜欢用哦!所有自己写了自己的代码!

long1225cn 发表于 2013-9-27 22:25:53

下面是创思通信的代码:
int DI = 12;
int RW = 11;
int DB[] = {
3, 4, 5, 6, 7, 8, 9, 10};//使用数组来定义总线需要的管脚
int Enable = 2;
int ledpin=13;   //定义数字接口13
int val;         //定义变量val
#define MAXCHAR 81 //recive buff max char
char aa;//recive gsm model back signal
int j=0;         //recive index
int g_timeout=0;   //handing time
////////////////////////////////////////////////////
char ATE0[]="ATE0";
char CREG_CMD[]="AT+CREG?";
char SMS_send[]="AT+CMGS=18";
char ATCN[]="AT+CNMI=2,1";
char CMGF0[]="AT+CMGF=0";
char CMGF1[]="AT+CMGF=1";
char CMGR="AT+CMGR=1";
char CMGD="AT+CMGD=1";
///////////////////////////////////////////////////
#define SEND_MESSA_TO_YOUR "at+cmgs=\"18622944083\"\r\n"    //填入你手上的手机号码 不是板子的
#define SEND_MESSA_CONTENT "tpytongxin.taobao.com"
#define CALL_YOU_TELNUMBER "ATD18622944083;\r\n"    //填入你手上的手机号码 不是板子的
///////////////////////////////////////////////////
void LcdCommandWrite(int value) {
// 定义所有引脚
int i = 0;
for (i=DB; i <= DI; i++) //总线赋值
{
    digitalWrite(i,value & 01);//因为1602液晶信号识别是D7-D0(不是D0-D7),这里是用来反转信号。
    value >>= 1;
}
digitalWrite(Enable,LOW);
delayMicroseconds(1);
digitalWrite(Enable,HIGH);
delayMicroseconds(1); // 延时1ms
digitalWrite(Enable,LOW);
delayMicroseconds(1); // 延时1ms
}
void LcdDataWrite(int value) {
// 定义所有引脚
int i = 0;
digitalWrite(DI, HIGH);
digitalWrite(RW, LOW);
for (i=DB; i <= DB; i++) {
    digitalWrite(i,value & 01);
    value >>= 1;
}
digitalWrite(Enable,LOW);
delayMicroseconds(1);
digitalWrite(Enable,HIGH);
delayMicroseconds(1);
digitalWrite(Enable,LOW);
delayMicroseconds(1); // 延时1ms
}

/*
Read input serial
*/
int readSerial(char result[])
{
int i = 0;
while (Serial.available() > 0)
{
    char inChar = Serial.read();
    if (inChar == '\n')
    {
      result = '\0';
      Serial.flush();
      return 0;
    }
    if(inChar!='\r')
    {
      result = inChar;
      i++;
    }
}
}

/*
clean buff
*/
void clearBuff(void)
{
for(j=0;j   {
    aa=0x00;
}
j=0;
}

/*
clean buff
*/
int Hand(char *s)
{
delay(200);
clearBuff();
delay(300);
readSerial(aa);
if(strstr(aa,s)!=NULL)             //检测单片机和模块的连接
{
    g_timeout=0;
    clearBuff();
    return 1;
}
if(g_timeout>50)
{
    g_timeout=0;
    return -1;
}
g_timeout++;
return 0;
}

/*
lcd 1602 string
*/
void lcd(char *str)
{
while(*str!='\0')
{
    LcdDataWrite(*str);
    delay(2);
    str++;
}
}

/*
13 LED test
*/
void led(int i)
{
if(i)
{
    digitalWrite(ledpin,HIGH);//点亮数字13 口LED。
    delay(500);
}
else
{
    digitalWrite(ledpin,LOW);//熄灭数字13 口LED
    delay(500);
}
}

void AT(void)
{
clearBuff();
Serial.println(ATE0);
delay(500);
readSerial(aa);

while(strstr(aa,"OK")==NULL)
{
    LcdCommandWrite(0x01); // 屏幕清空,光标位置归零
    lcd(" connect [..]");

    clearBuff();
    led(1);
    Serial.println(ATE0);
    delay(500);
    readSerial(aa);
    led(0);
}


LcdCommandWrite(0x01); // 屏幕清空,光标位置归零
lcd(" connect ");

clearBuff();
Serial.println(ATCN);
delay(500);
while(Hand("OK")==0);

while(1)
{
    clearBuff();
    Serial.println(CREG_CMD);
    delay(500);
    readSerial(aa);

    if((strstr(aa,"0,1")!=NULL)||(strstr(aa,"0,5")!=NULL))
    {
      clearBuff();
      LcdCommandWrite(0x01); // 屏幕清空,光标位置归零
      lcd(" register ");
      break;
    }
    else
    {
      LcdCommandWrite(0x01); // 屏幕清空,光标位置归零
      lcd(" register [..]");
      delay(500);
    }
}
}


void send_english(void)
{
clearBuff();
Serial.println(CMGF1);
delay(500);
while(Hand("OK")==0);

clearBuff();
Serial.println(SEND_MESSA_TO_YOUR);
delay(500);
while(Hand(">")==0);

Serial.println(SEND_MESSA_CONTENT);//发短信内容
delay(100);
Serial.print("\x01A");      //发送结束符号
delay(10);

delay(1000);
while(Hand("OK")==0);
}



void send_call(void)
{
clearBuff();
Serial.println(CALL_YOU_TELNUMBER); //打电话
delay(2000);
while(Hand("OK")==0);
}



void setup (void) {
int i = 0;
for (i=Enable; i <= DI; i++) {
    pinMode(i,OUTPUT);
}
delay(100);
// 短暂的停顿后初始化LCD
// 用于LCD控制需要
LcdCommandWrite(0x38); // 设置为8-bit接口,2行显示,5x7文字大小
delay(64);
LcdCommandWrite(0x38); // 设置为8-bit接口,2行显示,5x7文字大小
delay(50);
LcdCommandWrite(0x38); // 设置为8-bit接口,2行显示,5x7文字大小
delay(20);
LcdCommandWrite(0x06); // 输入方式设定
// 自动增量,没有显示移位
delay(20);
LcdCommandWrite(0x0E); // 显示设置
// 开启显示屏,光标显示,无闪烁
delay(20);
LcdCommandWrite(0x01); // 屏幕清空,光标位置归零
delay(100);
LcdCommandWrite(0x80); // 显示设置
// 开启显示屏,光标显示,无闪烁
delay(20);

Serial.begin(9600);//设置波特率为9600
pinMode(ledpin,OUTPUT);//设置数字13 口为输出接

Serial.println("serial port !");//显示“Hello World!”字符串
}
void loop (void) {
LcdCommandWrite(0x01); // 屏幕清空,光标位置归零
delay(10);
LcdCommandWrite(0x80+3);
delay(10);
// 写入欢迎信息
lcd("Welcome To");
delay(10);
LcdCommandWrite(0xc0+1); // 定义光标位置为第二行第二个位置
delay(10);
lcd("www.csgsm.com");
delay(2000);

AT();

LcdCommandWrite(0x01); // 屏幕清空,光标位置归零
lcd(" send sms [..]");
send_english();

LcdCommandWrite(0x01); // 屏幕清空,光标位置归零

LcdCommandWrite(0x80+1); // 定义光标位置为第二行第二个位置
lcd(CALL_YOU_TELNUMBER);
delay(10);
LcdCommandWrite(0xC0);
delay(10);
lcd(SEND_MESSA_CONTENT);

send_call();
delay(5000);

LcdCommandWrite(0x01); // 屏幕清空,光标位置归零
lcd(" Test over,thanks");
while(1);
}

long1225cn 发表于 2013-9-27 22:46:28

本帖最后由 long1225cn 于 2013-10-8 16:18 编辑

我还把代码改了控制我家的热水器,因为我经常出差10天以上,只要在我回来的路上提前1个小时发短信打开我的热水器,回家就直接可以洗澡了哦,我已经用了5个月了,没有发现什么问题!



舟泊烟渚 发表于 2013-9-28 00:59:28

long1225cn 发表于 2013-9-27 22:19 static/image/common/back.gif
自己用AT命令很灵活啊,官网的库函数换模块的时候就要去修改库函数了哦!
我都是自己写:
delay(3500);...

只用了I2C,舵机,红外的库函数啊,都是很方便的。你这里调用延时太多,我做的感觉靠延时去等待串口信号不可靠(你都没验证返回的“OK”),比如说gprs里要发送一个比较长的服务器IP信息,干等的话得不到返回信号,我是发了三遍(有时候一边发一边接收)在第二遍得到回复的。

舟泊烟渚 发表于 2013-9-28 01:03:45

long1225cn 发表于 2013-9-27 22:24 static/image/common/back.gif
你的代码太像 创思通信的示例代码了!我不太会用指针,也不喜欢用哦!所有自己写了自己的代码!

一看就是行家,我也没说不是啊,本来就是在给的调试程序的基础上改的。本来是在自己写,但是字符串指针什么的老出错,索性就用了调试程序。他们这个readSerial函数读到换行回车就不读了,很不方便,本来想改,做成了之后感觉没意思了就不管了

舟泊烟渚 发表于 2013-9-28 01:10:59

long1225cn 发表于 2013-9-27 22:16 static/image/common/back.gif
原来你的是笔记本电脑,用陀机控制。我做的是台式办公电脑的远程开机,直接加个继电器并接至电脑的电源开关 ...

您的代码确实简单,这些string我看了好多,也试了很多,可能因为要实现的功能多一些,效果总出不来,一般都会先像你这样写。

long1225cn 发表于 2013-9-28 20:40:11

哈哈,其实我是新手!因为一看就知道你的代码更像C代码风格!我的代码像玩Aduino风格!见笑了!
我控制热水器追求稳定,所以删除了很多以前做的检测电流电压,人体红外,门磁等等的代码!

long1225cn 发表于 2013-9-28 20:48:59

只用了I2C,舵机,红外的库函数啊,都是很方便的。你这里调用延时太多,我做的感觉靠延时去等待串口信号不可靠(你都没验证返回的“OK”),比如说gprs里要发送一个比较长的服务器IP信息,干等的话得不到返回信号,我是发了三遍(有时候一边发一边接收)在第二遍得到回复的。

delay(3500);   开机等3.5S是个人的习惯,也就是等一切都稳定的意思!我职业的习惯吧!并不是等串口数据,这个是一开机第一条指令哦!

验证返回的“OK”,不用验证啊,我一开始也验证的,但我模拟调试从来不出问题,就删掉了哦!
两条命令中间加个延时就可以了!不加延时,GRPS模块有的时候会读不出Arduino发的命令!

舟泊烟渚 发表于 2013-9-28 21:07:25

long1225cn 发表于 2013-9-28 20:48 static/image/common/back.gif
只用了I2C,舵机,红外的库函数啊,都是很方便的。你这里调用延时太多,我做的感觉靠延时去等待串口信号不可 ...

呵呵,也许您的模块比较稳定吧,我的就。。。BTW,您做过红外发送实验吗,不是NEC码之类的(像我家电视东芝码的)编码接收到的Raw那串数字是变化的,怎么发送呢?自己写的发东芝码0xFF******根本没反应

long1225cn 发表于 2013-9-28 22:16:21

红外发送没有做过啊!我做GSM这个都是为了去单位得QC奖项才做的哦!3000元现金,很爽的哦!

舟泊烟渚 发表于 2013-9-29 00:21:26

long1225cn 发表于 2013-9-28 22:16 static/image/common/back.gif
红外发送没有做过啊!我做GSM这个都是为了去单位得QC奖项才做的哦!3000元现金,很爽的哦!

{:3_50:}3K?!鼓励做这个的单位是好单位啊~
页: [1] 2 3
查看完整版本: 基于SIM900A的智能家居之----远程完全控制电脑