
在击败
CAN总线之前 ,我们必须破坏下一个硬件,即GPRS模块。 这就是她作为开发人员的生活-始终必须赢得别人的支持(应该禁止微笑)。
对于其中一个自定义项目,我需要添加使用SMS通过GSM控制和接收遥测功能。 我查看了可用选项的列表,并选择了Amperka的GPRS Shield。 为什么不呢 它看起来像样,由一家知名公司生产,具有技术支持,价格与竞争对手没有太大差异,通常给人留下很好的印象。
但事实确实如此。 您可以通过单击下面的按钮将此GPRS模块与
Arduino Mega Server集成,以了解该任务以及我必须经历的令人难以置信的继续教育课程。
模块本身
正如我所说,
该模块本身的执行准确性以及与一家知名公司的关系都给人留下了很好的印象。 同样,制造商的网站上有用法示例和本机库。 由于模块是品牌商标,因此希望在模块出现任何问题时获得足够的支持。
展望未来,我会说技术支持可以在两周内正确回答我的问题,在库中查找错误,甚至根据与我交流的原因发布了新版本。 但是...我仍然必须使模块自己工作。
专案
关于需要GPRS模块的
GSM Coop项目的几句话。 有必要发展自动化管理鸡舍。 确实,在我们生活的美好时光中,现在需要通过网络浏览器,无线智能传感器和GSM遥测来控制鸡舍。 这是某种战略目标,而不是鸡舍。
但是,如果有必要,那就有必要。 我们购买组件,其中包括GPRS模块,然后继续。
阿喀琉斯之heel
现在介绍该模块的功能。 基本上,它可以工作。 他使用制造商网站上的示例进行工作,甚至可以在此基础上创建一些简单的草图。 但是有三个“ buts”。
注意事项 该项目中使用了两个主板: Arduino Mega 2560和Arduino Due,以下所有内容仅适用于它们。第一个“但是”硬件。 该模块不适用于Arduino Due。 没办法 即使与Amperka的技术支持进行多天的通信也无济于事。 我和公司的专家都没有设法使GPRS Shield与Arduino Due一起使用。 而且这非常令人失望,因为Due是一款功能强大的出色控制器,希望将其与GPRS Shield一起使用。
第二个“ but”是系统性的。 该模块需要SoftwareSerial库才能工作。 当我开始与GPRS Shield和Amperka的技术支持进行对话时,这是一个非替代性的解决方案。 经过我们的诉讼,该库的修订版得到了支持,可以在Iron Serial上进行工作,但是……它从来没有赚过Due或Mega。 通常很难解释什么-如果模块在SoftSerial上工作,那么是什么阻止了它在Iron Serial上工作呢?
第三个“但是”,概念上的。 这还不是全部。 主要的埋伏在于模块库的原理。 它在关闭模式下工作,也就是说,它在等待SMS到达时(这是99%的时间)以及模块的所有其他操作期间,会阻止控制器的操作。 这是什么意思? 这意味着在制造商的标准库中,您只能构建测试草图。 战略鸡舍对您而言并不发光,因为像安全系统,温室管理,通过GSM进行的智能家居控制等成千上万的炫酷应用程序都不会发光。
有关SoftwareSerial的更多信息
该模块不适用于Arduino Due,因此我们将讨论Arduino Mega。 这种情况的麻烦之处在于,Mega具有三个免费的硬件端口Serial1,Serial2和Seria3,我们被迫连接并使用SoftwareSerial库。 以任何无法想象和无法想象的方式,包括重新配置模块上的跳线以及对Amperka的技术支持进行沉思,都无法使GPRS Shield与Arduino Mega上的硬件端口配合使用。
好的...我们使用SoftwareSerial,但是在这里我们等待伏击。 SoftwareSerial可以在许多Arduino Mega引脚上工作,但由于某些原因,它只能在62和63引脚上工作。 为什么只在他们身上? 这个谜语很棒。 从表面上看,我们永远不会知道这个问题的答案。
选择的面粉
现在,像往常一样,我们逐渐了解到标准库不适合实际使用。 通过在控制器等待接收来自GPRS模块的响应的过程中阻止控制器,该库还阻止了所有其他进程。 控制器仅在99%的时间内就脱离了现实,一直等到请求或响应到达或超时结束。
这结束了GPRS Shield的所有应用,除了测试之一:发送了一个打开套接字的请求-已打开,发送了一个关闭请求-已关闭。 谈不上Web服务器的任何工作,传感器的工作,执行器的控制等;这些都不能简单地工作。
问题出现了:要么我们放弃制造商的资料库,编写我们的GPRS Shield控制代码(说起来容易),要么我们放弃模块本身,寻找替代解决方案。 但是模块已经在那里,因此决定放弃该库并编写您的模块控制代码。
征服珠穆朗玛峰
我跳过了创建代码以替换Amperka标准库的整个过程,我只注意到这非常非常非常困难,需要大量的研究工作,复杂的算法编译以及大量的工作来测试最终的解决方案。
一切对您来说都很简单-有点神奇,并且支持GPRS Shield的AMS模块的现成工作代码已经准备就绪。
完整的AMS模块代码替换标准库 #ifdef GPRS_FEATURE #include <SoftwareSerial.h> #define ALWAYS 1 #define GPRS_ON_PIN 2 #define GPRS_STATE_PIN 3 #define GPRS_RX_PIN 62 #define GPRS_TX_PIN 63 #define MASTER "+7yyyxxxxxxx" #define MESSAGE "Hello" #define CHECK_ERROR 0 #define CHECK_MARKER 1 #define CHECK_OK 2 #define NO_CHECK 3 #define MARKER_OK "OK" #define MARKER_NO_CHECK "-"
该模块是在Arduino Mega的AMS版本0.16上开发和测试的。 测试表明,在此模块的控制下,GPRS Shield的运行绝对稳定可靠。
连接到AMS GPRS Shield支持模块
为了将GPRS Shield模块连接到Arduino Mega Server,您需要执行一些简单的步骤。 首先,将以下行添加到AMS主文件中
#define GPRS_FEATURE
和
byte modulGprs = MODUL_NOT_COMPILLED;
在适当的部分。 在那里,您需要添加测试变量,该变量在您的实际项目中将负责受控参数(温度,接触状态等)。
float lpTempTemp; byte lpContCont1; byte lpLeakLeak1; byte smokeSmoke; byte relayRelay; byte servoState;
支持功能的说明
该模块包含一组基本的查询和命令,但是您可以将这些命令替换为其他命令和/或扩展所需的基本命令和查询。
咨询处
通过SMS发送请求,系统(也通过SMS)发送包含有关所请求参数信息的响应。 非常简单:我们从电话发送请求“ temp1”,系统作为响应发送当前温度值
temp1=20.50
。
temp1-温度要求
cont1-请求联系状态
泄漏1-请求泄漏传感器的状态
smoke1-查询烟雾探测器状态
relay1-请求继电器的状态(键)
伺服1-请求伺服进纸器的状态
period-请求自动遥测软件包的期限
全部 -请求所有系统参数
响应“ all”请求,系统发送所有参数的列表。 在发送未注册命令的情况下,系统将发送“错误”响应。 如果监视的参数超出正常范围,则系统本身可以向操作员的智能手机发送警报消息。
为了仅由注册操作员来管理系统,该系统具有防止未授权访问的保护-它仅响应来自特定电话号码的命令。
队伍
通过SMS发送命令,接受命令后,系统会更改其状态并发送包含有关其执行器或设置的新状态信息的响应。
relay1 = -继电器控制命令(键)
伺服1 = -馈线控制命令
period = -更改遥测自动发送周期的命令
一个例子。 命令
relay1=1
,响应
relay1=ON
。 命令
relay1=0
,响应
relay1=OFF
。
代码说明
GPRS模块初始化。 AMS模块的标准初始化,SoftwareSerial的启动以及GSM AT命令的魔力。 该模块的目的是使GPRS模块栩栩如生,并从涅rv中退回它,前提是此时由于某种原因我们已经离开了它。
void gprsInit() { initStart("GPRS", true); GPRS.begin(9600); gprsOnOff(); gprsStart(); sendGprs("AT+CFUN=1", "OK"); sendGprs("AT+CNMI=2,1", "OK"); sendGprs("AT+CMGF=1", "OK"); sendGprs("AT+CLIP=1", "OK"); modulGprs = MODUL_ENABLE; initDone(true); }
模块的主要工作功能。 每隔20秒,Arduino Mega Server就会检查传入的SMS,并在有任何请求或命令的情况下执行它们。 结果,命令执行的平均延迟为10秒(不包括电信运营商发送SMS消息的延迟)。 可以配置此间隔,选择20秒作为对SMS命令的响应速度和系统引导之间的折衷。
在这20秒内,AMS可以做任何需要的事情,并且在这段时间内到达的SMS不会丢失。 使用标准库时,系统只能等待SMS到达,否则将什么也不会做(否则控制器将无法执行任何操作)。
还有一个遥测发送代码,其指定时间间隔为1小时,6小时,12小时或24小时。 可以通过SMS发送适当的命令来更改此间隔。
void gprsWorks() { if (cycle20s) { readSms(); } switch (gprsPeriod) { case 1: if (cycle1h) {sendPeriod();} break; case 6: if (cycle6h) {sendPeriod();} break; case 12: if (cycle12h) {sendPeriod();} break; default: if (cycle24h) {sendPeriod();} break; } }
GPRS模块和控制器之间的交互是通过特殊的AT命令执行的,以下功能以易于理解的代码形式形成了GPRS模块命令。
短信发送功能。 在功能的参数中,目标电话号码和命令或请求以文本形式传输。
bool sendSms(char *number, String data) { String numstr = "AT+CMGS=\"" + String(number) + "\""; String messtr = data + String((char)26); if (sendGprs(numstr, ">")) { if (sendGprs(messtr, MARKER_NO_CHECK)) { return true; } } return false; }
短信阅读功能。 接受的值放在变量message,phone和datetime中,它们分别包含接收的命令,电话号码和发送时间。
void readSms() { byte result = sendGprs("AT+CMGR=1,1", "+CMGR:"); if (result == CHECK_MARKER) { parseSms(message, phone, datetime); Serial.print(F("Number: ")); Serial.println(phone); Serial.print(F("Datetime: ")); Serial.println(datetime); Serial.print(F("Message: ")); Serial.println(message); deleteSms(); if (String(phone) == String(MASTER)) { Serial.println(F("Message from MASTER!")); gprsAnswer(); } } else if (result == CHECK_OK) { Serial.println(F("No SMS")); } else { Serial.println(F("Error read SMS")); } }
形成对SMS请求和命令的响应的功能。 此功能特定于每个项目,您可以根据系统逻辑在项目中对其进行更改。
void gprsAnswer() { String s = ""; String mess = String(message); String data = ""; if (mess == DATA_TEMP1) {s += mkTemp1();} else if (mess == DATA_CONT1) {s += mkCont1();} else if (mess == DATA_LEAK1) {s += mkLeak1();} else if (mess == DATA_SMOKE1) {s += mkSmoke1();} else if (mess == DATA_RELAY1) {s += mkRelay1();} else if (mess == DATA_SERVO1) {s += mkServo1();} else if (mess == DATA_PERIOD) {s += mkPeriod();} else if (mess == DATA_ALL) {s += mkAll();} else if (mess.indexOf(F("=")) >= 0) { byte p = mess.indexOf(F("=")); if (mess.indexOf(CMD_RELAY1) >= 0) {data = mess.substring(p + 1); gprsSetRelay(data.toInt()); s += DATA_RELAY1; s += '='; s += stringSens(relayRelay);} else if (mess.indexOf(CMD_SERVO1) >= 0) {data = mess.substring(p + 1); gprsSetServo(data.toInt()); s += DATA_SERVO1; s += '='; s += stringSens(servoState);} else if (mess.indexOf(CMD_PERIOD) >= 0) {data = mess.substring(p + 1); gprsPeriod = data.toInt(); s += DATA_PERIOD; s += '='; s += String(gprsPeriod);} } else { Serial.println(F("Not command!")); }
形成答案的功能。 这些功能构成了系统根据所制定的程序,通过SMS响应用户的请求或自行决定,通过SMS发送到用户的智能手机的响应。
String stringSens(byte v) String stringLeak(byte v) String stringSmoke(byte v) String mkTemp1() String mkCont1() String mkLeak1() String mkSmoke1() String mkRelay1() String mkServo1() String mkPeriod() String mkAll()
以及命令执行的功能。 这些是由SMS命令执行的功能,它们可以更改系统的状态,即更改其设置或启用或禁用执行器。
void gprsSetRelay(byte v) void gprsSetServo(byte v)
其余功能纯属技术,可以完成GPRS Shield与微控制器之间交互的所有粗略工作。
有关SoftwareSerial的更多信息
以上所有内容不足以使GPRS Shield透明模式下工作并停止阻止微控制器上运行的其他进程。 还需要修改SoftwareSerial库的代码。 事实是,其标准的64字节缓冲区不足以消化大多数AT GSM命令并维持模块与控制器之间的动态交互。
您需要将该缓冲区增加到至少128个字节,只有在此之后魔术才会起作用,并且GPRS Shield将在透明模式下开始正常工作。 这是在
SoftwareSerial.h
文件中完成的。 线
#define _SS_MAX_RX_BUFF 64
需要更改为
#define _SS_MAX_RX_BUFF 128
结论
您会在智能手机屏幕上看到操作员命令和系统响应的交换。 并且,系统以伪多任务处理模式执行数十个过程。 GPRS Shield开始占用不到1%的处理器时间,而不是以前的99%,从而为Web服务器和管理鸡舍的其他任务腾出了其余时间。
就是这样,我们将GPRS Shield Shield集成到
AMS中 ,克服了所有障碍,使其以透明模式工作,而不会阻止其他进程(例如Web服务器,无线传感器和执行器的运行),这为构建具有GSM SMS控制功能的大量系统打开了诱人的前景。基于AMS的控制-温室,安全和供暖系统,智能家居的各种选项等,几乎是无限的。