https://www.arduino.cn/thread-19432-1-2.html

1.所需工具:
(1)arduino UNO,(2)sim900a模块,(3)单路继电器,(4)220v ac转12v dc的降压模块【给arduino供电,12V是官方说明的供电极限】(我用的是高能立方),(5)插头,插孔,电线。

2.连线:
我是小白,不会设计电路,没法画图了,就直接说我自己的连线了。
火线接降压模块的L,零线接N,地线接E(插头遵守 左零右火上接地 原则);降压模块的正极接VIN,负极接GND;arduino 7脚接sim900a的5VR,8脚接sim900a的5VT;arduino的5V接sim900a的VCC,arduino的GND接sim900a的GND;arduino的11脚接继电器GND,12脚接继电器VCC,13脚接继电器的控制端;插孔的地线、零线接插头的地线、零线,插孔的火线一段接插头、一端接插孔、中间连入继电器。

3.注意事项:
(1)事先检查线有没有断(我就因为RX的线断了,折腾了好几天)
(2)保证sim卡安装好,sim卡的内容提前保存好程序会删除所有短信
(3)为了接收短信的全部内容可以增加串口缓冲区的大小,方法:找到Arduino\hardware\arduino\avr\libraries\SoftwareSerial\SoftwareSerial.h,里面有一行#define _SS_MAX_RX_BUFF 64 // RX buffer size。把64(或者其他数字)改大一点,我改成1024.

#include <SoftwareSerial.h>

//define Pins and Data
#define rxPin 8
#define txPin 7
#define relayPin 13
#define relayVCC 12
#define relayGND 11
#define relay_close LOW
#define relay_open HIGH
enum SMStype {UNRELATED,OPEN,CLOSE,ASK}; //globle variable
SoftwareSerial m_serial(rxPin,txPin);
String MSG("");
String SMS("");
char myRelay=1;
char myPhone[]={"18843109531"};
char snd_tips[]={"Send open to open. Send close to close. Send ask to get the status. Case-Insensitive!"};
char snd_unrelated[]={"Sorry.I can't understand what you sent!"};
char snd_open[]={"The Plug has been Opened!"},snd_close[]={"The Plug has been Colsed!"},snd_ask_o[]={"The Plug is Opening..."},snd_ask_c[]={"The Plug is Closing..."}; //function declaration
void init(SoftwareSerial &p_serial); //initialize the sim900a module
void getMSG(String &p_MSG,SoftwareSerial &p_serial); //get the sim900a module's message
bool chkMSG(String &p_MSG); //check the message's type
void rcvSMS(String &p_SMS,SoftwareSerial &p_serial); //recieve the first SMS
char chkSMS(String &p_SMS); //check the SMS's type
void sndSMS(const char *phone_num,const char *content,SoftwareSerial &p_serial);//send Short Message
void openRelay(char relay_VCC,char relay_GND);
void ctrlRelay(char relayType); //contral the relay //main function
void setup() {
openRelay(relayVCC,relayGND);
init(m_serial);
ctrlRelay(relayPin,relay_open);
sndSMS(myPhone,snd_tips,m_serial);
} void loop() {
delay(100);
getMSG(MSG,m_serial);
//delay(100);
if(!chkMSG(MSG))
return;
rcvSMS(SMS,m_serial);
delay(100);
switch(chkSMS(SMS))
{
case OPEN:
{
myRelay=relay_open;
sndSMS(myPhone,snd_open,m_serial);
delay(100);
break;
}
case CLOSE:
{
myRelay=relay_close;
sndSMS(myPhone,snd_close,m_serial);
delay(100);
break;
}
case ASK:
{
if(myRelay)
{
sndSMS(myPhone,snd_ask_o,m_serial);
delay(100);
}
else
{
sndSMS(myPhone,snd_ask_c,m_serial);
delay(100);
}
break;
}
default:
{
sndSMS(myPhone,snd_unrelated,m_serial);
delay(100);
sndSMS(myPhone,snd_tips,m_serial);
delay(100);
}
}
ctrlRelay(relayPin,myRelay);
} void init(SoftwareSerial &p_serial)
{
p_serial.begin(9600);
p_serial.println("AT");
delay(500);
p_serial.println("AT+CMGD=1, 4");
delay(500);
p_serial.flush();
delay(100);
} void getMSG(String &p_MSG,SoftwareSerial &p_serial)
{
p_MSG="";
while(!p_serial.available()) ;
for(char in='\0',flag=0;p_serial.available();)
{
in=p_serial.read();
if(in=='+')
flag=1;
if(flag&&((in=='\r')||(in=='\n')))
break;
if(flag)
p_MSG+=in;
}
p_MSG.trim();
p_serial.flush();
} bool chkMSG(String &p_MSG)
{
for(int p_begin=0;(p_begin+5)<p_MSG.length();p_begin++)
{
if(p_MSG.substring(p_begin,p_begin+5)=="+CMTI")
return true;
}
return false;
} void sndSMS(const char *phone_num,const char *content,SoftwareSerial &p_serial)
{
p_serial.println("AT");
delay(500);
p_serial.println("AT+CSCS=\"GSM\"");
delay(500);
p_serial.println("AT+CMGF=1");
delay(500);
p_serial.print("AT+CMGS=\"");
p_serial.print(phone_num);
p_serial.println("\"");
for(;m_serial.read()!='>';) ;
p_serial.print(content);
delay(500);
p_serial.write(0x1A);
delay(500);
p_serial.flush();
delay(100);
} void rcvSMS(String &p_SMS,SoftwareSerial &p_serial)
{
p_SMS="";
m_serial.println("AT");
delay(500);
m_serial.println("AT+CSCS=\"GSM\"");
delay(500);
m_serial.println("AT+CMGF=1");
delay(500);
m_serial.flush();
m_serial.println("AT+CMGR=1");
delay(500);
while(!p_serial.available()) ;
for(char in='\0',flag=0;p_serial.available();)
{
in=p_serial.read();
if(in=='\"')
flag++;
if(flag==8)
{
p_serial.read();
p_serial.read();
while((in!='\r')&&(in!='\n')&&p_serial.available())
{
in=p_serial.read();
p_SMS+=in;
}
break;
}
}
p_serial.println("AT+CMGD=1, 4");
delay(500);
p_serial.flush();
delay(100);
} char chkSMS(String &p_SMS)
{
String temp_open="open\r",temp_close="close\r",temp_ask="ask\r"; if(p_SMS.equalsIgnoreCase(temp_open))
return OPEN;
if(p_SMS.equalsIgnoreCase(temp_close))
return CLOSE;
if(p_SMS.equalsIgnoreCase(temp_ask))
return ASK;
return UNRELATED;
} void openRelay(char relay_VCC,char relay_GND)
{
pinMode(relay_VCC,OUTPUT);
digitalWrite(relay_VCC,HIGH);
pinMode(relay_GND,OUTPUT);
digitalWrite(relay_GND,LOW);
} void ctrlRelay(char p_pin,char relayType)
{
pinMode(p_pin,OUTPUT);
digitalWrite(p_pin,relayType);
}

  5.代码解释
(1)之所以用软串口,是因为硬串口用来查bug。
(2)sim900a模块发送短信流程:
首先要同步波特率,给sim900a发送“AT\r”,详见init()。//应该是一次就行
发送英文短信要设置GSM字符集设置文本模式发送“AT+CMGS=\"188xxxxxxxxx\"\r"(188xxxxxxxx是手机号)
等模块返回">"后,发送短信内容不要加\r或\n
最后发送16进制的0x1A(注意是16进制的,不要发送成字符)
然后就发送成功了,详见sndSMS()。
(3)sim900a模块接收短信流程
sim900a模块接收到短信后会给arduino发送含有”+CMTI"的字符串
要设置GSM字符集
设置文本模式
发送”AT+CMGF=1"查询第一条短信,=2就查询第二条以此类推
在sim900a返回的字符中查找短信的内容,第8个 “ 后就是短信内容

6.还需改进
(1)在chkSMS()中可以判断短信内容,为了安全考虑,可以在短信内加入密码(如sim卡的pin),如发送“pin码+open”表示打开。
(2)未来可以做一个有收发短信功能的手机app,还可以实现定时开关(定时发送短信)。

#include<SoftwareSerial.h>
SoftwareSerial softSerial1(4,5);//软串口RXD4、TXD5,与短信模块通信
#define yudi_d 2 //水传感器口
#define relay 3 //继电器口
unsigned long previousMillis=0;//存储时间,用于计时
const long interval=10000; //短信间隔10000ms
int flag=0;//出水短信发送 int sendMeg(String phonenum,String text)//发送信息的函数,直接调用即可,无需修改
{
char comdata=0;//判断接收到的最后一位是否对
String phone="";//电话号码存储
phone="AT+CMGS=\""+phonenum+'\"';
while (softSerial1.available() > 0){
comdata = softSerial1.read(); //每次读一个char字符,并相加
delay(2);
}
softSerial1.println("AT");//对GSM发送AT,看响应
delay(1000);
while (softSerial1.available() > 2){
comdata = softSerial1.read(); //每次读一个char字符,并相加
Serial.print(comdata);//错误
delay(2);
}
if(comdata!='K')//判断没有收到OK
{
Serial.println("error1");//错误
// return 0;
}
comdata=0;
softSerial1.println("AT+CMGF=1");//设置GSM文本模式
delay(500);
while (softSerial1.available() > 2){
comdata = softSerial1.read(); //每次读一个char字符,并相加
delay(2);
} if(comdata!='K')//没有收到OK
{
Serial.println("error2");
// return 0;
}
comdata=0;
softSerial1.println(phone);//发送的目标号码
delay(1000);
while (softSerial1.available() > 1){
comdata = softSerial1.read(); //每次读一个char字符,并相加
delay(2);
} if(comdata!='>')//没有收到>
{
Serial.println("error3");
// return 0;
}
comdata=0;
softSerial1.print(text);//发送所写内容
delay(500);
softSerial1.write(0x1A); //结束输入文本,并发送
Serial.println("success"); //成功 }
void setup(){ Serial.begin(9600);//串口
softSerial1.begin(9600);
//监听软串口通信
softSerial1.listen();
pinMode(A7,INPUT);//水传感器模拟端口设置模式
pinMode(relay,OUTPUT);//继电器端口模式
pinMode(yudi_d,INPUT);//水传感器数字端口设置模式
} void loop(){
unsigned long currentMillis=millis();//当前时间,用于判断时间
int a0= analogRead(A7);//获取模拟端口值
//Serial.print(a0);
//Serial.print("--");//串口输出,主要用于电脑监视和调试 int d2=digitalRead(yudi_d);//获取数字端口值
//Serial.println(d2);//串口输出,主要用于电脑监视和调试
if(d2==0)//判断是否浸入水中
digitalWrite(relay,LOW);//进入,打开继电器
else
digitalWrite(relay,HIGH);//未进入,关闭
if(d2==0&&currentMillis-previousMillis>=interval)//浸入水中,并时间间隔大于10s
{
previousMillis=currentMillis;//获取当前时间,以便于为下次发短信计时
sendMeg("15147300333","Water logging alarm of No.2 well of 110kV gold lead cable tunnel, please handle it quickly");//给15147300333 发送信息
Serial.println("1"); //成功
flag=1;
}
if(d2==1&&flag==1)//出水
{
delay(2000);
sendMeg("15147300333","The water logging alarm of No.2 well of 110kV gold lead cable tunnel has been removed.the equipment is normal");//给15147300333 发送的信息
Serial.println("2"); //成功
flag=0;
}
delay(100);
}

  

短信控制的 智能插头(sim900a arduino uno)的更多相关文章

  1. android 监听短信数据库,制作短信控制工具,控制别人的手机!!(一)

    序言:本程序示例本着简洁易懂的目的,只做了简单的功能实现,需要用户启动应用,收到短信才有效果.作者将会在后面的(二)篇中加入服务后台运行.自动启动功能,实现一个真正的短信控制工具.本文的目的很简单,让 ...

  2. 发短信utils

    package cn.itcast.bos.utils;   import com.aliyuncs.DefaultAcsClient; import com.aliyuncs.IAcsClient; ...

  3. 4、ABPZero系列教程之拼多多卖家工具 集成短信发送模块

    ABPZero并没有手机短信发送功能,现在我们来集成一个,为后面注册.登录作铺垫. 阿里云短信服务 首先需要在阿里云开通短信服务,连接地址 开通后,在签名管理中添加一个签名 在模板管理中添加一个模板, ...

  4. Java调用阿里云短信通道服务【千锋】

    这里我们使用SpringBoot 来调用阿里通信的服务. 阿里通信,双11.收到短信,日发送达6亿条.保障力度非常高. 使用的步骤: 1.1. 第一步:需要开通账户 1.2. 第二步:阅读接口文档 1 ...

  5. 零基础大数据入门教程:Java调用阿里云短信通道服务

    这里我们使用SpringBoot 来调用阿里通信的服务. 阿里通信,双11.收到短信,日发送达6亿条.保障力度非常高. 使用的步骤: 1.1. 第一步:需要开通账户 1.2. 第二步:阅读接口文档 1 ...

  6. 【云短信】腾讯&阿里

    腾讯 : https://github.com/qcloudsms/qcloudsms_csharp 安装nuget包: using qcloudsms_csharp; using System.Co ...

  7. thinkphp3.2.3集成腾讯云短信文档流程

    昨天晚上折腾了一个小时没解决 今天折腾了20分钟就搞定了 看了thinkphp3.2.3的命名空间解释方法  把文件放到这里 /ThinkPHP/Library/Org/ 把新建了一个Sms文件夹 把 ...

  8. ABP集成短信发送模块

    ABPZero并没有手机短信发送功能,现在我们来集成一个,为后面注册.登录作铺垫. 阿里云短信服务 首先需要在阿里云开通短信服务,连接地址 开通后,在签名管理中添加一个签名 在模板管理中添加一个模板, ...

  9. Python发送短信提醒

    Python发送短信可借助腾讯云平台提供的短信服务 发送短信需要的及格参数: 1.SDK_AppID和SDK_Key 2.签名: 3.模板ID 下面贴出源码DEMO: from qcloudsms_p ...

随机推荐

  1. macOS 安装 Docker Desktop CE(转)

    现在基本上都使用docker进行部署项目,所以还是有必要学习下,关于docker的简介这里就不在描述,本文转载自https://yeasy.gitbooks.io/docker_practice/co ...

  2. SpringBoot(二十一)_使用xml

    springboot使用xml 虽然springboot不提倡用xml,但是我们有可能也是会用到的 代码示例 1.创建一个配置文件在resources下,如下图所示 2.设置配置类 @Configur ...

  3. 记MacOs视频mov与mp4格式转换问题解决

    综述 记录了mov转mp4格式的方法 记录了自己是多蠢 问题背景 这学期选修的<工程英语视听说>课,需要提交一段口语考试视频,于是乎: 带着我的大疆Mavic Mini 和iPad Pro ...

  4. 推荐一款可以直接下载浏览器sources资源的Chrome插件

    github地址:https://github.com/up209d/ResourcesSaverExt 经常在仿站的时候回遇到下载别人的图片.css.js等资源,发现要一个个的手动下载.直接使用仿站 ...

  5. django--通过jwt获取用户信息的两种方式

    HTTP请求是无状态的,我们通常会使用cookie或session对其进行状态保持,cookie存储在客户端,容易被用户误删,安全性不高,session存储在服务端,在服务器集群情况下需要解决sess ...

  6. 使用php开发,基于swoole扩展开发的工具 swoole-crontab 作业/任务调度

    Swoole-Crontab(基于Swoole扩展) 1.概述 基于swoole的定时器程序,支持秒级处理. 异步多进程处理. 完全兼容crontab语法,且支持秒的配置,可使用数组规定好精确操作时间 ...

  7. python学习第一天第二天总结

    变量赋值 1, 变量由字⺟, 数字,下划线搭配组合⽽成 2, 不可以⽤数字开头,更不能是全数字 3,不能是pythond的关键字, 这些符号和字⺟已经被python占⽤, 不可以更改 4,不要⽤中⽂ ...

  8. 05-Django模型(2)

    1.特殊查询 F和Q查询: 之前的查询都是模型对象的属性与常量值比较,两个属性怎么比较呢?使用F查询. F查询语法: from django.db.models import F F('属性名称') ...

  9. pytest框架之fixture前置和后置

    一.conftest.py 定义公共的fixture,多个测试类中都可以调用 pytest提供了conftest.py文件,可以将fixture定义在此文件中 运行测试用例时,不需要去导入这个文件,会 ...

  10. pixijs shader 案例

    pixijs shader 案例 const app = new PIXI.Application({ transparent: true }); document.body.appendChild( ...