短信控制的 智能插头(sim900a arduino uno)
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&¤tMillis-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)的更多相关文章
- android 监听短信数据库,制作短信控制工具,控制别人的手机!!(一)
序言:本程序示例本着简洁易懂的目的,只做了简单的功能实现,需要用户启动应用,收到短信才有效果.作者将会在后面的(二)篇中加入服务后台运行.自动启动功能,实现一个真正的短信控制工具.本文的目的很简单,让 ...
- 发短信utils
package cn.itcast.bos.utils; import com.aliyuncs.DefaultAcsClient; import com.aliyuncs.IAcsClient; ...
- 4、ABPZero系列教程之拼多多卖家工具 集成短信发送模块
ABPZero并没有手机短信发送功能,现在我们来集成一个,为后面注册.登录作铺垫. 阿里云短信服务 首先需要在阿里云开通短信服务,连接地址 开通后,在签名管理中添加一个签名 在模板管理中添加一个模板, ...
- Java调用阿里云短信通道服务【千锋】
这里我们使用SpringBoot 来调用阿里通信的服务. 阿里通信,双11.收到短信,日发送达6亿条.保障力度非常高. 使用的步骤: 1.1. 第一步:需要开通账户 1.2. 第二步:阅读接口文档 1 ...
- 零基础大数据入门教程:Java调用阿里云短信通道服务
这里我们使用SpringBoot 来调用阿里通信的服务. 阿里通信,双11.收到短信,日发送达6亿条.保障力度非常高. 使用的步骤: 1.1. 第一步:需要开通账户 1.2. 第二步:阅读接口文档 1 ...
- 【云短信】腾讯&阿里
腾讯 : https://github.com/qcloudsms/qcloudsms_csharp 安装nuget包: using qcloudsms_csharp; using System.Co ...
- thinkphp3.2.3集成腾讯云短信文档流程
昨天晚上折腾了一个小时没解决 今天折腾了20分钟就搞定了 看了thinkphp3.2.3的命名空间解释方法 把文件放到这里 /ThinkPHP/Library/Org/ 把新建了一个Sms文件夹 把 ...
- ABP集成短信发送模块
ABPZero并没有手机短信发送功能,现在我们来集成一个,为后面注册.登录作铺垫. 阿里云短信服务 首先需要在阿里云开通短信服务,连接地址 开通后,在签名管理中添加一个签名 在模板管理中添加一个模板, ...
- Python发送短信提醒
Python发送短信可借助腾讯云平台提供的短信服务 发送短信需要的及格参数: 1.SDK_AppID和SDK_Key 2.签名: 3.模板ID 下面贴出源码DEMO: from qcloudsms_p ...
随机推荐
- acwing 848 有向图的拓扑序列
地址 https://www.acwing.com/problem/content/description/850/ 题目描述给定一个n个点m条边的有向图,图中可能存在重边和自环. 请输出任意一个该有 ...
- 从傅里叶变换(FFT)到数论变换(NTT)
FFT可以用来计算多项式乘法,但是复数的运算中含有大量的浮点数,精度较低.对于只有整数参与运算的多项式,有时,\(\text{NTT(Number-Theoretic Transform)}\)会是更 ...
- HttpClient之用CloseableHttpClient发送post请求
使用HttpClient发送请求的一般步骤(1) 创建HttpClient对象.(2)创建请求方法的实例,并指定请求URL.如果需要发送GET请求,创建HttpGet对象:如果需要发送POST请求,创 ...
- 设计模式-FlyWeight(结构型模式) 针对 需要创建大量对象的情形,被共享的状态作为内部状态,不被共享的状态作为外部状态
以下代码来源: 设计模式精解-GoF 23种设计模式解析附C++实现源码 //Flyweight.h #pragma once #include<string> class FlyWeig ...
- html背景音乐
标签<audio> 参用属性 autoplay="autoplay"自动播放 controls="controls",在页面内显示显示控件,如播放按 ...
- copy-and-swap idiom
This answer is from https://stackoverflow.com/a/3279550/10133369 Overview Why do we need the copy-an ...
- [算法]LeetCode 120:三角形最小路径和
题目描述: 给定一个三角形,找出自顶向下的最小路径和.每一步只能移动到下一行中相邻的结点上. 例如,给定三角形: [ [2], [3,4], [6,5,7], [4,1,8,3]]自顶向下的最小路径和 ...
- java高并发系列 - 第2天:并发级别
由于临界区的存在,多线程之间的并发必须受到控制.根据控制并发的策略,我们可以把并发的级别分为阻塞.无饥饿.无障碍.无锁.无等待几种. 阻塞 一个线程是阻塞的,那么在其他线程释放资源之前,当前线程无法继 ...
- Java日期时间API系列2-----Jdk7及以前的日期时间类在mysql数据库中的应用
1.java中与数据库相关的时间类 java提供与mysql方便交互的三种数据类型: java.sql.Date java.sql.Time java.sql.Timestamp 它们都是继承java ...
- C++ this指针的理解和作用
01 C++ 程序到 C 程序的翻译 要想理解 C++ 的 this 指针,我们先把下面的 C++ 代码转换成 C 的代码 class Car { public: int m_price; // 成员 ...