First commit
This commit is contained in:
commit
8c79fce887
875
GPRS_Shield_Arduino.cpp
Normal file
875
GPRS_Shield_Arduino.cpp
Normal file
@ -0,0 +1,875 @@
|
||||
/*
|
||||
* GPRS_Shield_Arduino.cpp
|
||||
* A library for SeeedStudio seeeduino GPRS shield
|
||||
*
|
||||
* Copyright (c) 2015 seeed technology inc.
|
||||
* Website : www.seeed.cc
|
||||
* Author : lawliet zou
|
||||
* Create Time: April 2015
|
||||
* Change Log :
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <HardwareSerial.h>
|
||||
#include "GPRS_Shield_Arduino.h"
|
||||
|
||||
GPRS* GPRS::inst;
|
||||
|
||||
GPRS::GPRS(Stream& serial, uint8_t pkPin) {
|
||||
_pkPin = pkPin;
|
||||
|
||||
inst = this;
|
||||
|
||||
stream = &serial;
|
||||
sim900_init(stream);
|
||||
}
|
||||
|
||||
bool GPRS::init(void) {
|
||||
if (!sim900_check_with_cmd("AT\r\n","OK\r\n",CMD))
|
||||
return false;
|
||||
|
||||
if (!sim900_check_with_cmd("AT+CFUN=1\r\n","OK\r\n",CMD))
|
||||
return false;
|
||||
|
||||
if (!checkSIMStatus())
|
||||
return false;
|
||||
|
||||
if (!sim900_check_with_cmd("AT+CNMI?\r\n", "+CNMI: 2,2,0,0,0\r\nOK\r\n", CMD)) {
|
||||
if (!sim900_check_with_cmd("AT+CNMI=2,2,0,0,0\r\n","OK\r\n", CMD)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!sim900_check_with_cmd("AT+CMGF?\r\n", "+CMGF: 1\r\nOK\r\n", CMD)) {
|
||||
if (!sim900_check_with_cmd("AT+CMGF=1\r\n","OK\r\n", CMD)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!sim900_check_with_cmd("AT+CLIP=1\r\n","OK\r\n", CMD)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GPRS::checkPowerUp(void) {
|
||||
return sim900_check_with_cmd("AT\r\n","OK\r\n", CMD);
|
||||
}
|
||||
|
||||
// power Up GPRS Shield
|
||||
void GPRS::powerOn() {
|
||||
//delay(1000);
|
||||
pinMode(_pkPin, OUTPUT);
|
||||
digitalWrite(_pkPin, HIGH);
|
||||
delay(500);
|
||||
digitalWrite(_pkPin, LOW);
|
||||
delay(3000);
|
||||
}
|
||||
|
||||
// power Off GPRS Shield
|
||||
void GPRS::powerOff() {
|
||||
pinMode(_pkPin, OUTPUT);
|
||||
digitalWrite(_pkPin, HIGH);
|
||||
delay(2000);
|
||||
digitalWrite(_pkPin, LOW);
|
||||
delay(3000);
|
||||
}
|
||||
|
||||
void GPRS::reset() {
|
||||
powerOff();
|
||||
powerOn();
|
||||
}
|
||||
|
||||
bool GPRS::checkSIMStatus(void) {
|
||||
char gprsBuffer[32];
|
||||
byte count = 0;
|
||||
sim900_clean_buffer(gprsBuffer,32);
|
||||
while(count < 3) {
|
||||
sim900_send_cmd("AT+CPIN?\r\n");
|
||||
sim900_read_buffer(gprsBuffer,32,DEFAULT_TIMEOUT);
|
||||
if((NULL != strstr(gprsBuffer,"+CPIN: READY"))) {
|
||||
break;
|
||||
}
|
||||
count++;
|
||||
delay(300);
|
||||
}
|
||||
if(count == 3) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GPRS::sendSMS(const char *number, const char *data) {
|
||||
// Set message mode to ASCII
|
||||
if(!sim900_check_with_cmd("AT+CMGF=1\r\n", "OK\r\n", CMD)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
delay(500);
|
||||
sim900_send_cmd("AT+CMGS=\"");
|
||||
sim900_send_cmd(number);
|
||||
|
||||
if(!sim900_check_with_cmd("\"\r\n",">",CMD)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
delay(1000);
|
||||
sim900_send_cmd(data);
|
||||
delay(500);
|
||||
sim900_send_End_Mark();
|
||||
|
||||
return sim900_wait_for_resp("OK\r\n", CMD, 2);
|
||||
}
|
||||
|
||||
char GPRS::isSMSunread() {
|
||||
char gprsBuffer[48]; //48 is enough to see +CMGL:
|
||||
char *s;
|
||||
|
||||
//List of all UNREAD SMS and DON'T change the SMS UNREAD STATUS
|
||||
sim900_send_cmd(F("AT+CMGL=\"REC UNREAD\",1\r\n"));
|
||||
/*If you want to change SMS status to READ you will need to send:
|
||||
AT+CMGL=\"REC UNREAD\"\r\n
|
||||
This command will list all UNREAD SMS and change all of them to READ
|
||||
If there is not SMS, response is (30 chars)
|
||||
AT+CMGL="REC UNREAD",1 --> 22 + 2
|
||||
--> 2
|
||||
OK --> 2 + 2
|
||||
If there is SMS, response is like (>64 chars)
|
||||
AT+CMGL="REC UNREAD",1
|
||||
+CMGL: 9,"REC UNREAD","XXXXXXXXX","","14/10/16,21:40:08+08"
|
||||
Here SMS text.
|
||||
OK
|
||||
or
|
||||
AT+CMGL="REC UNREAD",1
|
||||
+CMGL: 9,"REC UNREAD","XXXXXXXXX","","14/10/16,21:40:08+08"
|
||||
Here SMS text.
|
||||
+CMGL: 10,"REC UNREAD","YYYYYYYYY","","14/10/16,21:40:08+08"
|
||||
Here second SMS
|
||||
OK
|
||||
*/
|
||||
|
||||
sim900_clean_buffer(gprsBuffer,31);
|
||||
sim900_read_buffer(gprsBuffer, 30, DEFAULT_TIMEOUT);
|
||||
//Serial.print("Buffer isSMSunread: ");Serial.println(gprsBuffer);
|
||||
|
||||
if(NULL != ( s = strstr(gprsBuffer,"OK"))) {
|
||||
//In 30 bytes "doesn't" fit whole +CMGL: response, if recieve only "OK"
|
||||
// means you don't have any UNREAD SMS
|
||||
delay(50);
|
||||
return 0;
|
||||
} else {
|
||||
//More buffer to read
|
||||
//We are going to flush serial data until OK is recieved
|
||||
sim900_wait_for_resp("OK\r\n", CMD);
|
||||
//sim900_flush_serial();
|
||||
//We have to call command again
|
||||
sim900_send_cmd("AT+CMGL=\"REC UNREAD\",1\r\n");
|
||||
sim900_clean_buffer(gprsBuffer,48);
|
||||
sim900_read_buffer(gprsBuffer,47,DEFAULT_TIMEOUT);
|
||||
//Serial.print("Buffer isSMSunread 2: ");Serial.println(gprsBuffer);
|
||||
if(NULL != ( s = strstr(gprsBuffer,"+CMGL:"))) {
|
||||
//There is at least one UNREAD SMS, get index/position
|
||||
s = strstr(gprsBuffer,":");
|
||||
if (s != NULL) {
|
||||
//We are going to flush serial data until OK is recieved
|
||||
sim900_wait_for_resp("OK\r\n", CMD);
|
||||
return atoi(s+1);
|
||||
}
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool GPRS::readSMS(int messageIndex, char *message, byte length) {
|
||||
byte i = 0;
|
||||
char gprsBuffer[100];
|
||||
char num[4];
|
||||
char *p,*s;
|
||||
sim900_check_with_cmd("AT+CMGF=1\r\n","OK\r\n",CMD);
|
||||
delay(1000);
|
||||
sim900_send_cmd("AT+CMGR=");
|
||||
itoa(messageIndex, num, 10);
|
||||
sim900_send_cmd(num);
|
||||
sim900_send_cmd("\r\n");
|
||||
sim900_clean_buffer(gprsBuffer,sizeof(gprsBuffer));
|
||||
sim900_read_buffer(gprsBuffer,sizeof(gprsBuffer),DEFAULT_TIMEOUT);
|
||||
if(NULL != ( s = strstr(gprsBuffer,"+CMGR:"))){
|
||||
if(NULL != ( s = strstr(s,"\r\n"))){
|
||||
p = s + 2;
|
||||
while((*p != '\r')&&(i < length-1)) {
|
||||
message[i++] = *(p++);
|
||||
}
|
||||
message[i] = '\0';
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
byte GPRS::getEvent(char *message, char *phone, char *datetime, char *gprsBuffer, byte size, bool check) {
|
||||
int len;
|
||||
byte i = 0;
|
||||
char *s, *p1, *p2;
|
||||
|
||||
// Read buffer
|
||||
sim900_clean_buffer(gprsBuffer, size);
|
||||
sim900_read_buffer(gprsBuffer, size - 1);
|
||||
|
||||
len = strlen(gprsBuffer);
|
||||
|
||||
// Get SMS
|
||||
s = strstr(gprsBuffer,"+CMT: ");
|
||||
if (s != NULL) {
|
||||
// Extract phone number string
|
||||
p1 = strstr(gprsBuffer, "\"+");
|
||||
p2 = p1 + 1; //First phone number character
|
||||
p1 = strstr((char *)(p2), "\"");
|
||||
if (p1 != NULL) {
|
||||
i = 0;
|
||||
while (p2 < p1) {
|
||||
phone[i++] = *(p2++);
|
||||
}
|
||||
phone[i] = '\0';
|
||||
}
|
||||
|
||||
// Extract date time string
|
||||
p1 = strstr((char *)(p2), ",");
|
||||
p2 = p1 + 1;
|
||||
p1 = strstr((char *)(p2), ",");
|
||||
p2 = p1 + 2; //First date time character
|
||||
p1 = strstr((char *)(p2), "\"");
|
||||
if (p1 != NULL) {
|
||||
i = 0;
|
||||
while (p2 < p1) {
|
||||
datetime[i++] = *(p2++);
|
||||
}
|
||||
datetime[i] = '\0';
|
||||
}
|
||||
|
||||
// Extract message
|
||||
p2 = strstr(gprsBuffer, "\r\n");
|
||||
p2 = p2 + 2;
|
||||
p1 = strstr(p2, "\r\n");
|
||||
if (p1 != NULL) {
|
||||
i = 0;
|
||||
p1 = p1 + 2; //First message character
|
||||
while((*p1 != '\r') && (i < len - 1)) {
|
||||
message[i++] = *(p1++);
|
||||
}
|
||||
message[i] = '\0';
|
||||
}
|
||||
|
||||
return SMS;
|
||||
}
|
||||
|
||||
// Get Call
|
||||
s = strstr(gprsBuffer,"+CLIP: ");
|
||||
if (s != NULL) {
|
||||
// Extract phone number string
|
||||
p1 = strstr(gprsBuffer, "\"+");
|
||||
p2 = p1 + 1; //First phone number character
|
||||
p1 = strstr((char *)(p2), "\"");
|
||||
if (p1 != NULL) {
|
||||
i = 0;
|
||||
while (p2 < p1) {
|
||||
phone[i++] = *(p2++);
|
||||
}
|
||||
phone[i] = '\0';
|
||||
}
|
||||
|
||||
return CALL;
|
||||
}
|
||||
|
||||
// Get outgoing call
|
||||
s = strstr(gprsBuffer,"+COLP: ");
|
||||
if (s != NULL) {
|
||||
// Extract phone number string
|
||||
p1 = strstr(gprsBuffer, "\"+");
|
||||
p2 = p1 + 1; //First phone number character
|
||||
p1 = strstr((char *)(p2), "\"");
|
||||
if (p1 != NULL) {
|
||||
i = 0;
|
||||
while (p2 < p1) {
|
||||
phone[i++] = *(p2++);
|
||||
}
|
||||
phone[i] = '\0';
|
||||
}
|
||||
|
||||
return ANSWER;
|
||||
}
|
||||
|
||||
// Get BUSY
|
||||
s = strstr(gprsBuffer,"BUSY");
|
||||
if (s != NULL) {
|
||||
return BUSY;
|
||||
}
|
||||
|
||||
// Get NO CARRIER
|
||||
s = strstr(gprsBuffer,"NO CARRIER");
|
||||
if (s != NULL) {
|
||||
return NO_CARRIER;
|
||||
}
|
||||
|
||||
// Get NO ANSWER
|
||||
s = strstr(gprsBuffer,"NO ANSWER");
|
||||
if (s != NULL) {
|
||||
return NO_ANSWER;
|
||||
}
|
||||
|
||||
// Check modem
|
||||
if (check) {
|
||||
if (!sim900_check_with_cmd("AT\r\n","OK\r\n", CMD)) return ERR;
|
||||
}
|
||||
|
||||
return NONE;
|
||||
}
|
||||
|
||||
bool GPRS::getSMS(char *message, char *phone, char *datetime, char *gprsBuffer, byte size) {
|
||||
/* Response is like:
|
||||
+CMT: "+79772941911","","15/12/15,01:51:24+12"
|
||||
SMS text here
|
||||
*/
|
||||
|
||||
//if(!sim900_check_with_cmd("","+CMT: ", CMD, 3)) return false;
|
||||
if(!sim900_wait_for_resp("+CMT: ", CMD, 1)) return false;
|
||||
|
||||
byte i = 0;
|
||||
//char gprsBuffer[80 + 160];
|
||||
char *p1, *p2;
|
||||
|
||||
sim900_clean_buffer(gprsBuffer, size);//sizeof(gprsBuffer));
|
||||
sim900_read_buffer(gprsBuffer, size - 1);//sizeof(gprsBuffer));
|
||||
|
||||
int len = strlen(gprsBuffer);
|
||||
//int len = sizeof(message);
|
||||
//byte len = 160;
|
||||
|
||||
// Serial.print("Buff len: ");
|
||||
// Serial.println(len);
|
||||
// Serial.print("Buff: ");
|
||||
// Serial.println(gprsBuffer);
|
||||
|
||||
// Serial.println("----- buffer -----");
|
||||
// Serial.println(gprsBuffer);
|
||||
// Serial.println("^^^^^ buffer ^^^^^");
|
||||
|
||||
// Extract phone number string
|
||||
p1 = strstr(gprsBuffer, "\"+");
|
||||
p2 = p1 + 1; //First phone number character
|
||||
p1 = strstr((char *)(p2), "\"");
|
||||
if (p1 != NULL) {
|
||||
i = 0;
|
||||
while (p2 < p1) {
|
||||
phone[i++] = *(p2++);
|
||||
}
|
||||
phone[i] = '\0';
|
||||
}
|
||||
|
||||
// Extract date time string
|
||||
p1 = strstr((char *)(p2), ",");
|
||||
p2 = p1 + 1;
|
||||
p1 = strstr((char *)(p2), ",");
|
||||
p2 = p1 + 2; //First date time character
|
||||
p1 = strstr((char *)(p2), "\"");
|
||||
if (p1 != NULL) {
|
||||
i = 0;
|
||||
while (p2 < p1) {
|
||||
datetime[i++] = *(p2++);
|
||||
}
|
||||
datetime[i] = '\0';
|
||||
}
|
||||
|
||||
// Extract message
|
||||
p1 = strstr(gprsBuffer, "\r\n");
|
||||
if (p1 != NULL) {
|
||||
i = 0;
|
||||
p1 = p1 + 2; //First message character
|
||||
while((*p1 != '\r') && (i < len - 1)) {
|
||||
message[i++] = *(p1++);
|
||||
}
|
||||
message[i] = '\0';
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GPRS::deleteSMS(int index)
|
||||
{
|
||||
char num[4];
|
||||
sim900_send_cmd("AT+CMGD=");
|
||||
itoa(index, num, 10);
|
||||
sim900_send_cmd(num);
|
||||
return sim900_check_with_cmd("\r\n","OK\r\n",CMD);
|
||||
}
|
||||
|
||||
bool GPRS::callUp(char *number)
|
||||
{
|
||||
if(!sim900_check_with_cmd("AT+COLP=1\r\n","OK\r\n",CMD)) {
|
||||
return false;
|
||||
}
|
||||
delay(1000);
|
||||
sim900_send_cmd("ATD");
|
||||
sim900_send_cmd(number);
|
||||
sim900_send_cmd(";\r\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
void GPRS::answer(void)
|
||||
{
|
||||
//TO CHECK: ATA doesnt return "OK" ????
|
||||
sim900_send_cmd("ATA\r\n");
|
||||
}
|
||||
|
||||
bool GPRS::ifcallNow(byte timeout)
|
||||
{
|
||||
return sim900_check_with_cmd("","RING\r\n",CMD, timeout);
|
||||
}
|
||||
|
||||
bool GPRS::ifcallEnd(void)
|
||||
{
|
||||
return sim900_check_with_cmd("","NO CARRIER\r\n",CMD);
|
||||
}
|
||||
|
||||
void GPRS::callEnd(void)
|
||||
{
|
||||
sim900_send_cmd("ATH0\r\n");
|
||||
}
|
||||
|
||||
bool GPRS::hangup(void)
|
||||
{
|
||||
return sim900_check_with_cmd("ATH\r\n","OK\r\n",CMD);
|
||||
}
|
||||
|
||||
bool GPRS::disableCLIPring(void)
|
||||
{
|
||||
return sim900_check_with_cmd("AT+CLIP=0\r\n","OK\r\n",CMD);
|
||||
}
|
||||
|
||||
bool GPRS::isCallActive(char *number, char *gprsBuffer)
|
||||
{
|
||||
//char gprsBuffer[46]; //46 is enough to see +CPAS: and CLCC:
|
||||
char *p, *s;
|
||||
int i = 0;
|
||||
|
||||
sim900_send_cmd("AT+CPAS\r\n");
|
||||
/*Result code:
|
||||
0: ready
|
||||
2: unknown
|
||||
3: ringing
|
||||
4: call in progress
|
||||
AT+CPAS --> 7 + 2 = 9 chars
|
||||
--> 2 char
|
||||
+CPAS: 3 --> 8 + 2 = 10 chars
|
||||
--> 2 char
|
||||
OK --> 2 + 2 = 4 chars
|
||||
AT+CPAS
|
||||
+CPAS: 0
|
||||
OK
|
||||
*/
|
||||
|
||||
sim900_clean_buffer(gprsBuffer, 46);
|
||||
sim900_read_buffer(gprsBuffer, 45);
|
||||
//HACERR cuando haga lo de esperar a OK no me haría falta esto
|
||||
//We are going to flush serial data until OK is recieved
|
||||
//Serial.println("Wait OK");
|
||||
//sim900_wait_for_resp("OK\r\n", CMD);
|
||||
//Serial.print("Buffer isCallActive 1: ");Serial.println(gprsBuffer);
|
||||
if(NULL != ( s = strstr(gprsBuffer,"+CPAS:"))) {
|
||||
s = s + 7;
|
||||
if (*s != '0') {
|
||||
//There is something "running" (but number 2 that is unknow)
|
||||
if (*s != '2') {
|
||||
//3 or 4, let's go to check for the number
|
||||
sim900_send_cmd("AT+CLCC\r\n");
|
||||
/*
|
||||
AT+CLCC --> 9
|
||||
+CLCC: 1,1,4,0,0,"656783741",161,""
|
||||
OK
|
||||
Without ringing:
|
||||
AT+CLCC
|
||||
OK
|
||||
*/
|
||||
|
||||
sim900_clean_buffer(gprsBuffer, 46);
|
||||
sim900_read_buffer(gprsBuffer, 45);
|
||||
//Serial.print("Buffer isCallActive 2: ");Serial.println(gprsBuffer);
|
||||
if(NULL != ( s = strstr(gprsBuffer,"+CLCC:"))) {
|
||||
//There is at least one CALL ACTIVE, get number
|
||||
s = strstr((char *)(s),"\"");
|
||||
s = s + 1; //We are in the first phone number character
|
||||
p = strstr((char *)(s),"\""); //p is last character """
|
||||
if (NULL != s) {
|
||||
i = 0;
|
||||
while (s < p) {
|
||||
number[i++] = *(s++);
|
||||
}
|
||||
number[i] = '\0';
|
||||
}
|
||||
//I need to read more buffer
|
||||
//We are going to flush serial data until OK is recieved
|
||||
return sim900_wait_for_resp("OK\r\n", CMD);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GPRS::getDateTime(char *buffer) {
|
||||
//AT+CCLK? --> 8 + CRLF = 10
|
||||
//+CCLK: "14/11/13,21:14:41+04" --> 29+ CRLF = 31
|
||||
// --> CRLF = 2
|
||||
//OK
|
||||
|
||||
byte i = 0;
|
||||
char gprsBuffer[46];
|
||||
char *p,*s;
|
||||
sim900_send_cmd("AT+CCLK?\r\n");
|
||||
sim900_clean_buffer(gprsBuffer,43);
|
||||
sim900_read_buffer(gprsBuffer,43,DEFAULT_TIMEOUT);
|
||||
if(NULL != ( s = strstr(gprsBuffer,"+CCLK:"))) {
|
||||
s = strstr((char *)(s),"\"");
|
||||
s = s + 1; //We are in the first phone number character
|
||||
p = strstr((char *)(s),"\""); //p is last character """
|
||||
if (NULL != s) {
|
||||
i = 0;
|
||||
while (s < p) {
|
||||
buffer[i++] = *(s++);
|
||||
}
|
||||
buffer[i] = '\0';
|
||||
}
|
||||
//We are going to flush serial data until OK is recieved
|
||||
return sim900_wait_for_resp("OK\r\n", CMD);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
byte GPRS::getSignalStrength() {
|
||||
//AT+CSQ: 00,00 --> 13 + CRLF = 15
|
||||
// --> CRLF = 2
|
||||
//OK --> 2 + CRLF = 4
|
||||
|
||||
|
||||
byte result = 99;
|
||||
char gprsBuffer[21];
|
||||
sim900_clean_buffer(gprsBuffer,21);
|
||||
char *s;
|
||||
sim900_send_cmd("AT+CSQ\r\n");
|
||||
sim900_read_buffer(gprsBuffer,21,DEFAULT_TIMEOUT);
|
||||
if(NULL != ( s = strstr(gprsBuffer,"+CSQ: "))) {
|
||||
result = atoi(s+6);
|
||||
sim900_wait_for_resp("OK\r\n", CMD);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//Here is where we ask for APN configuration, with F() so we can save MEMORY
|
||||
//bool GPRS::join(const __FlashStringHelper *apn, const __FlashStringHelper *userName, const __FlashStringHelper *passWord)
|
||||
bool GPRS::join(char* apn, char* userName, char* passWord, int timeout) {
|
||||
byte i;
|
||||
char *p, *s;
|
||||
char ipAddr[32];
|
||||
/* if(!sim900_check_with_cmd("AT+CIPSHUT\r\n","SHUT OK\r\n", CMD)) {
|
||||
Serial.write("Error = 1\r\n");
|
||||
return false;
|
||||
}
|
||||
delay(1000);
|
||||
*/
|
||||
sim900_send_cmd("AT+CIPSHUT\r\n");
|
||||
delay(500);
|
||||
//Select multiple connection
|
||||
//sim900_check_with_cmd("AT+CIPMUX=1\r\n","OK",DEFAULT_TIMEOUT,CMD);
|
||||
|
||||
//set APN. OLD VERSION
|
||||
//snprintf(cmd,sizeof(cmd),"AT+CSTT=\"%s\",\"%s\",\"%s\"\r\n",_apn,_userName,_passWord);
|
||||
//sim900_check_with_cmd(cmd, "OK\r\n", DEFAULT_TIMEOUT,CMD);
|
||||
sim900_send_cmd("AT+CSTT=\"");
|
||||
sim900_send_cmd(apn);
|
||||
sim900_send_cmd("\",\"");
|
||||
sim900_send_cmd(userName);
|
||||
sim900_send_cmd("\",\"");
|
||||
sim900_send_cmd(passWord);
|
||||
sim900_send_cmd("\"\r\n");
|
||||
delay(500);
|
||||
//Brings up wireless connection
|
||||
|
||||
sim900_send_cmd("AT+CIICR\r\n");
|
||||
delay(4000);
|
||||
sim900_wait_for_resp("OK\r\n", CMD);
|
||||
delay(500);
|
||||
// sim900_check_with_cmd("AT+CIICR\r\n","OK\r\n", CMD);
|
||||
|
||||
|
||||
//Get local IP address
|
||||
sim900_send_cmd("AT+CIFSR\r\n");
|
||||
delay(500);
|
||||
sim900_clean_buffer(ipAddr,32);
|
||||
sim900_read_buffer(ipAddr,32,DEFAULT_TIMEOUT);
|
||||
|
||||
//Response:
|
||||
//AT+CIFSR\r\n --> 8 + 2
|
||||
//\r\n --> 0 + 2
|
||||
//10.160.57.120\r\n --> 15 + 2 (max) : TOTAL: 29
|
||||
//Response error:
|
||||
//AT+CIFSR\r\n
|
||||
//\r\n
|
||||
//ERROR\r\n
|
||||
if (NULL != strstr(ipAddr,"ERROR")) {
|
||||
Serial.write("Error = 2\r\n");
|
||||
return false;
|
||||
}
|
||||
s = ipAddr + 12;
|
||||
p = strstr((char *)(s),"\r\n"); //p is last character \r\n
|
||||
if (NULL != s) {
|
||||
i = 0;
|
||||
while (s < p) {
|
||||
ip_string[i++] = *(s++);
|
||||
}
|
||||
ip_string[i] = '\0';
|
||||
}
|
||||
_ip = str_to_ip(ip_string);
|
||||
if(_ip != 0) {
|
||||
|
||||
return true;
|
||||
}
|
||||
Serial.write("Error = 3\r\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
void GPRS::disconnect() {
|
||||
sim900_send_cmd("AT+CIPSHUT\r\n");
|
||||
}
|
||||
|
||||
bool GPRS::connect(Protocol ptl,const char * host, int port, int timeout) {
|
||||
//char cmd[64];
|
||||
char num[4];
|
||||
char resp[96];
|
||||
|
||||
//sim900_clean_buffer(cmd,64);
|
||||
if(ptl == TCP) {
|
||||
sim900_send_cmd("AT+CIPSTART=\"TCP\",\"");
|
||||
sim900_send_cmd(host);
|
||||
sim900_send_cmd("\",");
|
||||
itoa(port, num, 10);
|
||||
sim900_send_cmd(num);
|
||||
sim900_send_cmd("\r\n");
|
||||
// sprintf(cmd, "AT+CIPSTART=\"TCP\",\"%s\",%d\r\n",host, port);
|
||||
} else if(ptl == UDP) {
|
||||
sim900_send_cmd("AT+CIPSTART=\"UDP\",\"");
|
||||
sim900_send_cmd(host);
|
||||
sim900_send_cmd("\",");
|
||||
itoa(port, num, 10);
|
||||
sim900_send_cmd(num);
|
||||
sim900_send_cmd("\r\n");
|
||||
|
||||
// sprintf(cmd, "AT+CIPSTART=\"UDP\",\"%s\",%d\r\n",host, port);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
delay(2000);
|
||||
//sim900_send_cmd(cmd);
|
||||
sim900_read_buffer(resp,96,timeout);
|
||||
|
||||
//Serial.print("Connect resp: "); Serial.println(resp);
|
||||
if(NULL != strstr(resp,"CONNECT")) { //ALREADY CONNECT or CONNECT OK
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//Overload with F() macro to SAVE memory
|
||||
bool GPRS::connect(Protocol ptl,const __FlashStringHelper *host, const __FlashStringHelper *port, int timeout) {
|
||||
//char cmd[64];
|
||||
char resp[96];
|
||||
|
||||
//sim900_clean_buffer(cmd,64);
|
||||
if(ptl == TCP) {
|
||||
sim900_send_cmd(F("AT+CIPSTART=\"TCP\",\"")); //%s\",%d\r\n",host, port);
|
||||
} else if(ptl == UDP) {
|
||||
sim900_send_cmd(F("AT+CIPSTART=\"UDP\",\"")); //%s\",%d\r\n",host, port);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
sim900_send_cmd(host);
|
||||
sim900_send_cmd(F("\","));
|
||||
sim900_send_cmd(port);
|
||||
sim900_send_cmd(F("\r\n"));
|
||||
//Serial.print("Connect: "); Serial.println(cmd);
|
||||
sim900_read_buffer(resp, 96, timeout);
|
||||
//Serial.print("Connect resp: "); Serial.println(resp);
|
||||
if(NULL != strstr(resp,"CONNECT")) { //ALREADY CONNECT or CONNECT OK
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GPRS::is_connected(void) {
|
||||
char resp[96];
|
||||
sim900_send_cmd("AT+CIPSTATUS\r\n");
|
||||
sim900_read_buffer(resp,sizeof(resp),DEFAULT_TIMEOUT);
|
||||
if(NULL != strstr(resp,"CONNECTED")) {
|
||||
//+CIPSTATUS: 1,0,"TCP","216.52.233.120","80","CONNECTED"
|
||||
return true;
|
||||
} else {
|
||||
//+CIPSTATUS: 1,0,"TCP","216.52.233.120","80","CLOSED"
|
||||
//+CIPSTATUS: 0,,"","","","INITIAL"
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool GPRS::close() {
|
||||
// if not connected, return
|
||||
if (!is_connected()) {
|
||||
return true;
|
||||
}
|
||||
return sim900_check_with_cmd("AT+CIPCLOSE\r\n", "CLOSE OK\r\n", CMD);
|
||||
}
|
||||
|
||||
int GPRS::readable(void) {
|
||||
return sim900_check_readable();
|
||||
}
|
||||
|
||||
int GPRS::wait_readable(int wait_time) {
|
||||
return sim900_wait_readable(wait_time);
|
||||
}
|
||||
|
||||
int GPRS::wait_writeable(int req_size) {
|
||||
return req_size+1;
|
||||
}
|
||||
|
||||
int GPRS::send(const char * str, int len) {
|
||||
//char cmd[32];
|
||||
char num[4];
|
||||
if(len > 0){
|
||||
//snprintf(cmd,sizeof(cmd),"AT+CIPSEND=%d\r\n",len);
|
||||
//sprintf(cmd,"AT+CIPSEND=%d\r\n",len);
|
||||
sim900_send_cmd("AT+CIPSEND=");
|
||||
itoa(len, num, 10);
|
||||
sim900_send_cmd(num);
|
||||
if(!sim900_check_with_cmd("\r\n",">",CMD)) {
|
||||
//if(!sim900_check_with_cmd(cmd,">",CMD)) {
|
||||
return 0;
|
||||
}
|
||||
/*if(0 != sim900_check_with_cmd(str,"SEND OK\r\n", DEFAULT_TIMEOUT * 10 ,DATA)) {
|
||||
return 0;
|
||||
}*/
|
||||
delay(500);
|
||||
sim900_send_cmd(str);
|
||||
delay(500);
|
||||
sim900_send_End_Mark();
|
||||
if(!sim900_wait_for_resp("SEND OK\r\n", DATA, DEFAULT_TIMEOUT * 10, DEFAULT_INTERCHAR_TIMEOUT * 10)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
int GPRS::send(const char * str) {
|
||||
//char cmd[32];
|
||||
int len=strlen(str);
|
||||
char num[4];
|
||||
if(len > 0){
|
||||
//snprintf(cmd,sizeof(cmd),"AT+CIPSEND=%d\r\n",len);
|
||||
//sprintf(cmd,"AT+CIPSEND=%d\r\n",len);
|
||||
sim900_send_cmd("AT+CIPSEND=");
|
||||
itoa(len, num, 10);
|
||||
sim900_send_cmd(num);
|
||||
if(!sim900_check_with_cmd("\r\n",">",CMD)) {
|
||||
//if(!sim900_check_with_cmd(cmd,">",CMD)) {
|
||||
return 0;
|
||||
}
|
||||
/*if(0 != sim900_check_with_cmd(str,"SEND OK\r\n", DEFAULT_TIMEOUT * 10 ,DATA)) {
|
||||
return 0;
|
||||
}*/
|
||||
delay(500);
|
||||
sim900_send_cmd(str);
|
||||
delay(500);
|
||||
sim900_send_End_Mark();
|
||||
if(!sim900_wait_for_resp("SEND OK\r\n", DATA, DEFAULT_TIMEOUT * 10, DEFAULT_INTERCHAR_TIMEOUT * 10)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
int GPRS::recv(char* buf, int len)
|
||||
{
|
||||
sim900_clean_buffer(buf,len);
|
||||
sim900_read_buffer(buf,len); //Ya he llamado a la funcion con la longitud del buffer - 1 y luego le estoy añadiendo el 0
|
||||
return strlen(buf);
|
||||
}
|
||||
|
||||
uint32_t GPRS::str_to_ip(const char* str) {
|
||||
uint32_t ip = 0;
|
||||
char* p = (char*)str;
|
||||
for(int i = 0; i < 4; i++) {
|
||||
ip |= atoi(p);
|
||||
p = strchr(p, '.');
|
||||
if (p == NULL) {
|
||||
break;
|
||||
}
|
||||
ip <<= 8;
|
||||
p++;
|
||||
}
|
||||
|
||||
return ip;
|
||||
}
|
||||
|
||||
char* GPRS::getIPAddress() {
|
||||
//I have already a buffer with ip_string: snprintf(ip_string, sizeof(ip_string), "%d.%d.%d.%d", (_ip>>24)&0xff,(_ip>>16)&0xff,(_ip>>8)&0xff,_ip&0xff);
|
||||
return ip_string;
|
||||
}
|
||||
|
||||
unsigned long GPRS::getIPnumber() {
|
||||
return _ip;
|
||||
}
|
||||
|
||||
bool GPRS::controlGPIO(uint8_t index, uint8_t level) {
|
||||
char num[4];
|
||||
|
||||
sim900_send_cmd("AT+SGPIO=0,");
|
||||
itoa(index, num, 10);
|
||||
sim900_send_cmd(num);
|
||||
sim900_send_cmd(",1,");
|
||||
itoa(level, num, 10);
|
||||
sim900_send_cmd(num);
|
||||
sim900_send_cmd("\r\n");
|
||||
return sim900_wait_for_resp("OK\r\n", CMD);
|
||||
}
|
||||
|
||||
/* NOT USED bool GPRS::gethostbyname(const char* host, uint32_t* ip)
|
||||
{
|
||||
uint32_t addr = str_to_ip(host);
|
||||
char buf[17];
|
||||
//snprintf(buf, sizeof(buf), "%d.%d.%d.%d", (addr>>24)&0xff, (addr>>16)&0xff, (addr>>8)&0xff, addr&0xff);
|
||||
if (strcmp(buf, host) == 0) {
|
||||
*ip = addr;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
*/
|
304
GPRS_Shield_Arduino.h
Normal file
304
GPRS_Shield_Arduino.h
Normal file
@ -0,0 +1,304 @@
|
||||
/*
|
||||
* GPRS_Shield_Arduino.h
|
||||
* A library for SeeedStudio seeeduino GPRS shield
|
||||
*
|
||||
* Copyright (c) 2015 seeed technology inc.
|
||||
* Website : www.seeed.cc
|
||||
* Author : lawliet zou
|
||||
* Create Time: April 2015
|
||||
* Change Log :
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __GPRS_SHIELD_ARDUINO_H__
|
||||
#define __GPRS_SHIELD_ARDUINO_H__
|
||||
|
||||
#define NONE 0
|
||||
#define SMS 1
|
||||
#define CALL 2
|
||||
#define BUSY 3
|
||||
#define NO_CARRIER 4
|
||||
#define NO_ANSWER 5
|
||||
#define ANSWER 6
|
||||
#define ERR 7
|
||||
|
||||
#define CHECK true
|
||||
#define NO_CHECK false
|
||||
|
||||
#include "sim900.h"
|
||||
|
||||
/** GPRS class.
|
||||
* used to realize GPRS communication
|
||||
*/
|
||||
|
||||
enum Protocol {
|
||||
CLOSED = 0,
|
||||
TCP = 1,
|
||||
UDP = 2,
|
||||
};
|
||||
|
||||
class GPRS {
|
||||
public:
|
||||
/** Create GPRS instance
|
||||
*/
|
||||
|
||||
GPRS(Stream& serial, uint8_t pkPin = 9);
|
||||
|
||||
/** get instance of GPRS class
|
||||
*/
|
||||
static GPRS* getInstance() {
|
||||
return inst;
|
||||
};
|
||||
|
||||
/** initialize GPRS module including SIM card check & signal strength
|
||||
* @return true if connected, false otherwise
|
||||
*/
|
||||
|
||||
bool init(void);
|
||||
|
||||
|
||||
/** check if GPRS module is powered on or not
|
||||
* @returns
|
||||
* true on success
|
||||
* false on error
|
||||
*/
|
||||
bool checkPowerUp(void);
|
||||
|
||||
|
||||
/** power Up GPRS module (JP has to be soldered)
|
||||
* @param pin pin 9 connected to JP jumper so we can power up and down through software
|
||||
* @returns
|
||||
*
|
||||
*/
|
||||
void powerOn();
|
||||
void powerOff();
|
||||
void reset();
|
||||
|
||||
/** send text SMS
|
||||
* @param *number phone number which SMS will be send to
|
||||
* @param *data message that will be send to
|
||||
* @returns
|
||||
* false on success
|
||||
* true on error
|
||||
*/
|
||||
bool sendSMS(const char* number, const char* data);
|
||||
|
||||
/** Check if there is any UNREAD SMS: this function DOESN'T change the UNREAD status of the SMS
|
||||
* @returns
|
||||
* 1..20 on success, position/index where SMS is stored, suitable for the function ReadSMS
|
||||
* -1 on error
|
||||
* 0 - there is no SMS with specified status (UNREAD)
|
||||
*/
|
||||
|
||||
char isSMSunread();
|
||||
|
||||
/** read SMS if getting a SMS message
|
||||
* @param buffer buffer that get from GPRS module(when getting a SMS, GPRS module will return a buffer array)
|
||||
* @param message buffer used to get SMS message
|
||||
* @param check whether to check phone number(we may only want to read SMS from specified phone number)
|
||||
* @returns
|
||||
* true on success
|
||||
* false on error
|
||||
*/
|
||||
|
||||
bool readSMS(int messageIndex, char *message, byte length);
|
||||
|
||||
byte getEvent(char *message, char *phone, char *datetime, char *gprsBuffer, byte size, bool check = true);
|
||||
|
||||
/** get SMS on the fly, phone and date
|
||||
* @param message buffer used to get SMS message
|
||||
* @param phone buffer used to get SMS's sender phone number
|
||||
* @param datetime buffer used to get SMS's send datetime
|
||||
* @returns
|
||||
* true on success
|
||||
* false on error
|
||||
*/
|
||||
|
||||
bool getSMS(char *message, char *phone, char *datetime, char *gprsBuffer, byte size);
|
||||
|
||||
/** delete SMS message on SIM card
|
||||
* @param index the index number which SMS message will be delete
|
||||
* @returns
|
||||
* true on success
|
||||
* false on error
|
||||
*/
|
||||
|
||||
bool deleteSMS(int index);
|
||||
|
||||
/** call someone
|
||||
* @param number the phone number which you want to call
|
||||
* @returns
|
||||
* true on success
|
||||
* false on error
|
||||
*/
|
||||
bool callUp(char* number);
|
||||
|
||||
/** auto answer if coming a call
|
||||
* @returns
|
||||
*/
|
||||
void answer(void);
|
||||
|
||||
/** hang up if coming a call
|
||||
* @returns
|
||||
* true on success
|
||||
* false on error
|
||||
*/
|
||||
bool hangup(void);
|
||||
|
||||
/** Disable +CLIP notification when an incoming call is active, RING text is always shown. See isCallActive function
|
||||
* This is done in order no to overload serial outputCheck if there is a call active and get the phone number in that case
|
||||
* @returns
|
||||
* true on success
|
||||
* false on error
|
||||
*/
|
||||
bool ifcallNow(byte timeout = 1);
|
||||
|
||||
bool ifcallEnd(void);
|
||||
|
||||
void callEnd(void);
|
||||
|
||||
bool disableCLIPring(void);
|
||||
|
||||
/** Check if there is a call active and get the phone number in that case
|
||||
* @returns
|
||||
* true on success
|
||||
* false on error
|
||||
*/
|
||||
bool isCallActive(char *number, char *gprsBuffer);
|
||||
|
||||
/** get DateTime from SIM900 (see AT command: AT+CLTS=1) as string
|
||||
* @param
|
||||
* @returns
|
||||
* true on success
|
||||
* false on error
|
||||
*/
|
||||
bool getDateTime(char *buffer);
|
||||
|
||||
/** getSignalStrength from SIM900 (see AT command: AT+CSQ)
|
||||
* @returns
|
||||
0 — 113 dBm or less
|
||||
1 — 111 dBm
|
||||
2...30 — 109... 53 dBm
|
||||
31 — 51 dBm or greater
|
||||
99 — not known or not detectable
|
||||
*/
|
||||
byte getSignalStrength();
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
/// GPRS
|
||||
//////////////////////////////////////////////////////
|
||||
/** Connect the GPRS module to the network.
|
||||
* @return true if connected, false otherwise
|
||||
*/
|
||||
|
||||
// bool join(const __FlashStringHelper *apn = 0, const __FlashStringHelper *userName = 0, const __FlashStringHelper *passWord = 0);
|
||||
bool join(char* apn = 0, char* = 0, char* = 0, int timeout = 2 * DEFAULT_TIMEOUT);
|
||||
|
||||
/** Disconnect the GPRS module from the network
|
||||
* @returns
|
||||
*/
|
||||
void disconnect(void);
|
||||
|
||||
/** Open a tcp/udp connection with the specified host on the specified port
|
||||
* @param socket an endpoint of an inter-process communication flow of GPRS module,for SIM900 module, it is in [0,6]
|
||||
* @param ptl protocol for socket, TCP/UDP can be choosen
|
||||
* @param host host (can be either an ip address or a name. If a name is provided, a dns request will be established)
|
||||
* @param port port
|
||||
* @param timeout wait seconds till connected
|
||||
* @returns true if successful
|
||||
*/
|
||||
bool connect(Protocol ptl, const char * host, int port, int timeout = 2 * DEFAULT_TIMEOUT);
|
||||
bool connect(Protocol ptl, const __FlashStringHelper *host, const __FlashStringHelper *port, int timeout = 2 * DEFAULT_TIMEOUT);
|
||||
|
||||
/** Check if a tcp link is active
|
||||
* @returns true if successful
|
||||
*/
|
||||
bool is_connected(void);
|
||||
|
||||
/** Close a tcp connection
|
||||
* @returns true if successful
|
||||
*/
|
||||
bool close(void);
|
||||
|
||||
/** check if GPRS module is readable or not
|
||||
* @returns true if readable
|
||||
*/
|
||||
int readable(void);
|
||||
|
||||
/** wait a few time to check if GPRS module is readable or not
|
||||
* @param socket socket
|
||||
* @param wait_time time of waiting
|
||||
*/
|
||||
int wait_readable(int wait_time);
|
||||
|
||||
/** wait a few time to check if GPRS module is writeable or not
|
||||
* @param socket socket
|
||||
* @param wait_time time of waiting
|
||||
*/
|
||||
int wait_writeable(int req_size);
|
||||
|
||||
int send(const char * str);
|
||||
/** send data to socket
|
||||
* @param socket socket
|
||||
* @param str string to be sent
|
||||
* @param len string length
|
||||
* @returns return bytes that actually been send
|
||||
*/
|
||||
int send(const char * str, int len);
|
||||
|
||||
/** read data from socket
|
||||
* @param socket socket
|
||||
* @param buf buffer that will store the data read from socket
|
||||
* @param len string length need to read from socket
|
||||
* @returns bytes that actually read
|
||||
*/
|
||||
int recv(char* buf, int len);
|
||||
|
||||
/** convert the host to ip
|
||||
* @param host host ip string, ex. 10.11.12.13
|
||||
* @param ip long int ip address, ex. 0x11223344
|
||||
* @returns true if successful
|
||||
*/
|
||||
//NOT USED bool gethostbyname(const char* host, uint32_t* ip);
|
||||
|
||||
char* getIPAddress();
|
||||
unsigned long getIPnumber();
|
||||
|
||||
/** set GPIO level
|
||||
* @param GPIO number
|
||||
* @param GPIO level
|
||||
* @returns true if successful
|
||||
*/
|
||||
bool controlGPIO(uint8_t num, uint8_t level);
|
||||
|
||||
private:
|
||||
bool checkSIMStatus(void);
|
||||
uint8_t _pkPin = 9;
|
||||
|
||||
uint32_t str_to_ip(const char* str);
|
||||
Stream* stream;
|
||||
static GPRS* inst;
|
||||
uint32_t _ip;
|
||||
char ip_string[16]; //XXX.YYY.ZZZ.WWW + \0
|
||||
};
|
||||
#endif
|
201
sim900.cpp
Normal file
201
sim900.cpp
Normal file
@ -0,0 +1,201 @@
|
||||
/*
|
||||
* sim900.cpp
|
||||
* A library for SeeedStudio seeeduino GPRS shield
|
||||
*
|
||||
* Copyright (c) 2015 seeed technology inc.
|
||||
* Website : www.seeed.cc
|
||||
* Author : lawliet zou
|
||||
* Create Time: April 2015
|
||||
* Change Log :
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "sim900.h"
|
||||
|
||||
|
||||
Stream *serialSIM900 = NULL;
|
||||
|
||||
|
||||
void sim900_init(void * uart_device)
|
||||
{
|
||||
serialSIM900 = (Stream*)uart_device;
|
||||
}
|
||||
|
||||
int sim900_check_readable()
|
||||
{
|
||||
return serialSIM900->available();
|
||||
}
|
||||
|
||||
int sim900_wait_readable (int wait_time)
|
||||
{
|
||||
unsigned long timerStart;
|
||||
int dataLen = 0;
|
||||
timerStart = millis();
|
||||
while((unsigned long) (millis() - timerStart) > wait_time * 1000UL) {
|
||||
delay(500);
|
||||
dataLen = sim900_check_readable();
|
||||
if(dataLen > 0){
|
||||
break;
|
||||
}
|
||||
}
|
||||
return dataLen;
|
||||
}
|
||||
|
||||
void sim900_flush_serial() {
|
||||
while(sim900_check_readable()) {
|
||||
char c = serialSIM900->read();
|
||||
}
|
||||
}
|
||||
|
||||
void sim900_read_buffer(char *buffer, int count, unsigned int timeout, unsigned int chartimeout)
|
||||
{
|
||||
//Serial.println("Read buff");
|
||||
int i = 0;
|
||||
unsigned long timerStart, prevChar;
|
||||
timerStart = millis();
|
||||
prevChar = 0;
|
||||
while(1) {
|
||||
while (sim900_check_readable()) {
|
||||
char c = serialSIM900->read();
|
||||
//Serial.print(c);
|
||||
prevChar = millis();
|
||||
buffer[i++] = c;
|
||||
if(i >= count) break;
|
||||
}
|
||||
if(i >= count) break;
|
||||
if ((unsigned long) (millis() - timerStart) > timeout * 1000UL) {
|
||||
break;
|
||||
}
|
||||
//If interchar Timeout => return FALSE. So we can return sooner from this function. Not DO it if we dont recieve at least one char (prevChar <> 0)
|
||||
if (((unsigned long) (millis() - prevChar) > chartimeout) && (prevChar != 0)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sim900_clean_buffer(char *buffer, int count)
|
||||
{
|
||||
for(int i = 0; i < count; i++) {
|
||||
buffer[i] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
//HACERR quitar esta funcion ?
|
||||
void sim900_send_byte(uint8_t data)
|
||||
{
|
||||
serialSIM900->write(data);
|
||||
//Serial.print((char)data);
|
||||
}
|
||||
|
||||
void sim900_send_char(const char c)
|
||||
{
|
||||
serialSIM900->write(c);
|
||||
//Serial.print((char)c);
|
||||
}
|
||||
|
||||
void sim900_send_cmd(const char* cmd)
|
||||
{
|
||||
for(int i=0; i<strlen(cmd); i++)
|
||||
{
|
||||
sim900_send_byte(cmd[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void sim900_send_cmd(const __FlashStringHelper* cmd)
|
||||
{
|
||||
int i = 0;
|
||||
const char *ptr = (const char *) cmd;
|
||||
while (pgm_read_byte(ptr + i) != 0x00) {
|
||||
sim900_send_byte(pgm_read_byte(ptr + i++));
|
||||
}
|
||||
}
|
||||
|
||||
void sim900_send_cmd_P(const char* cmd)
|
||||
{
|
||||
while (pgm_read_byte(cmd) != 0x00)
|
||||
sim900_send_byte(pgm_read_byte(cmd++));
|
||||
}
|
||||
|
||||
void sim900_send_AT(void)
|
||||
{
|
||||
sim900_check_with_cmd(F("AT\r\n"),"OK",CMD);
|
||||
}
|
||||
|
||||
void sim900_send_End_Mark(void)
|
||||
{
|
||||
sim900_send_byte((char)26);
|
||||
}
|
||||
|
||||
boolean sim900_wait_for_resp(const char* resp, DataType type, unsigned int timeout, unsigned int chartimeout)
|
||||
{
|
||||
int len = strlen(resp);
|
||||
int sum = 0;
|
||||
unsigned long timerStart, prevChar; //prevChar is the time when the previous Char has been read.
|
||||
|
||||
// Serial.println("Wait for resp");
|
||||
// Serial.println(resp);
|
||||
// Serial.print("with length: ");
|
||||
// Serial.println(len);
|
||||
|
||||
timerStart = millis();
|
||||
prevChar = 0;
|
||||
//Serial.println("Received: ");
|
||||
while(1) {
|
||||
if(sim900_check_readable()) {
|
||||
char c = serialSIM900->read();
|
||||
//Serial.print(c);
|
||||
prevChar = millis();
|
||||
sum = (c==resp[sum]) ? sum+1 : 0;
|
||||
if(sum == len - 1) {
|
||||
//Serial.print("BREAK");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((unsigned long) (millis() - timerStart) > timeout * 1000UL) {
|
||||
//Serial.println("Timeout");
|
||||
return false;
|
||||
}
|
||||
//If interchar Timeout => return FALSE. So we can return sooner from this function.
|
||||
if (((unsigned long) (millis() - prevChar) > chartimeout) && (prevChar != 0)) {
|
||||
//Serial.println("Interchar timeout");
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
//Serial.println("End wait cycle");
|
||||
//If is a CMD, we will finish to read buffer.
|
||||
if(type == CMD) sim900_flush_serial();
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean sim900_check_with_cmd(const char* cmd, const char *resp, DataType type, unsigned int timeout, unsigned int chartimeout)
|
||||
{
|
||||
sim900_send_cmd(cmd);
|
||||
return sim900_wait_for_resp(resp,type,timeout,chartimeout);
|
||||
}
|
||||
|
||||
//HACERR que tambien la respuesta pueda ser FLASH STRING
|
||||
boolean sim900_check_with_cmd(const __FlashStringHelper* cmd, const char *resp, DataType type, unsigned int timeout, unsigned int chartimeout)
|
||||
{
|
||||
sim900_send_cmd(cmd);
|
||||
return sim900_wait_for_resp(resp,type,timeout,chartimeout);
|
||||
}
|
62
sim900.h
Normal file
62
sim900.h
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* sim900.h
|
||||
* A library for SeeedStudio seeeduino GPRS shield
|
||||
*
|
||||
* Copyright (c) 2015 seeed technology inc.
|
||||
* Website : www.seeed.cc
|
||||
* Author : lawliet zou
|
||||
* Create Time: April 2015
|
||||
* Change Log :
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __SIM900_H__
|
||||
#define __SIM900_H__
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#define DEFAULT_TIMEOUT 5 //seconds
|
||||
#define DEFAULT_INTERCHAR_TIMEOUT 1500 //miliseconds
|
||||
|
||||
enum DataType {
|
||||
CMD = 0,
|
||||
DATA = 1,
|
||||
};
|
||||
|
||||
void sim900_init(void * uart_device);
|
||||
int sim900_check_readable();
|
||||
int sim900_wait_readable(int wait_time);
|
||||
void sim900_flush_serial();
|
||||
void sim900_read_buffer(char* buffer,int count, unsigned int timeout = DEFAULT_TIMEOUT, unsigned int chartimeout = DEFAULT_INTERCHAR_TIMEOUT);
|
||||
void sim900_clean_buffer(char* buffer, int count);
|
||||
void sim900_send_byte(uint8_t data);
|
||||
void sim900_send_char(const char c);
|
||||
void sim900_send_cmd(const char* cmd);
|
||||
void sim900_send_cmd(const __FlashStringHelper* cmd);
|
||||
void sim900_send_cmd_P(const char* cmd);
|
||||
void sim900_send_AT(void);
|
||||
void sim900_send_End_Mark(void);
|
||||
boolean sim900_wait_for_resp(const char* resp, DataType type, unsigned int timeout = DEFAULT_TIMEOUT, unsigned int chartimeout = DEFAULT_INTERCHAR_TIMEOUT);
|
||||
boolean sim900_check_with_cmd(const char* cmd, const char *resp, DataType type, unsigned int timeout = DEFAULT_TIMEOUT, unsigned int chartimeout = DEFAULT_INTERCHAR_TIMEOUT);
|
||||
boolean sim900_check_with_cmd(const __FlashStringHelper* cmd, const char *resp, DataType type, unsigned int timeout = DEFAULT_TIMEOUT, unsigned int chartimeout = DEFAULT_INTERCHAR_TIMEOUT);
|
||||
|
||||
#endif
|
877
watchdog_3-leonardo.ino
Normal file
877
watchdog_3-leonardo.ino
Normal file
@ -0,0 +1,877 @@
|
||||
// ----------------------------------------------------------------------------------------------------
|
||||
// Watchdog v3 - Leonardo
|
||||
// EoF 2017
|
||||
// ----------------------------------------------------------------------------------------------------
|
||||
|
||||
#include "watchdog_3.h"
|
||||
|
||||
GPRS modem(Serial1, MOD_PWR);
|
||||
bool modemOK = false;
|
||||
byte modemErrCount = 0;
|
||||
DHT dht(T_PIN, DHT11);
|
||||
|
||||
char command[CMD_SIZE];
|
||||
char message[SMS_SIZE];
|
||||
char phone[PHONE_SIZE];
|
||||
char datetime[DATE_SIZE];
|
||||
char s_buffer[BUFFER_SIZE];
|
||||
char l_buffer[LONG_BUFFER_SIZE];
|
||||
|
||||
bool cmdFromModem = false;
|
||||
|
||||
unsigned long t = 0;
|
||||
int addr = 0;
|
||||
|
||||
byte temp = 0, hum = 0, loud = 0, power = 0, battery = 0;
|
||||
|
||||
byte btnCount = 0;
|
||||
bool btnTrigger = false;
|
||||
byte event;
|
||||
|
||||
const float r12_1 = 20000; // 20K
|
||||
const float r12_2 = 10000; // 10K
|
||||
const float r5_1 = 10000; // 20K
|
||||
const float r5_2 = 10000; // 10K
|
||||
const float rbat_1 = 10000; // 10K
|
||||
const float rbat_2 = 10000; // 10K
|
||||
const float rout_1 = 10000; // 10K
|
||||
const float rout_2 = 10000; // 10K
|
||||
|
||||
float vcc = 0.0;
|
||||
float k12, k5, kbat, kout;
|
||||
float v12, v5, vbat, vout;
|
||||
|
||||
// эту константу (typVbg) необходимо откалибровать индивидуально
|
||||
const float typVbg = 1.08; // 1.0 -- 1.2
|
||||
|
||||
void setup() {
|
||||
Serial.begin(COM_BR);
|
||||
Serial1.begin(MOD_BR);
|
||||
modem.powerOn();
|
||||
modemOK = modem.init();
|
||||
|
||||
// Конфигурируем пины
|
||||
pinMode(A_PIN, INPUT);
|
||||
pinMode(V5_PIN, INPUT);
|
||||
pinMode(V12_PIN, INPUT);
|
||||
pinMode(VBAT_PIN, INPUT);
|
||||
pinMode(VOUT_PIN, INPUT);
|
||||
|
||||
pinMode(LED_PIN, OUTPUT);
|
||||
pinMode(BTN_PIN, INPUT);
|
||||
pinMode(FAN_PIN, OUTPUT);
|
||||
|
||||
// Инициализируем климатический сенсор
|
||||
dht.begin();
|
||||
|
||||
// Коэффициенты делителей напряжений
|
||||
k12 = r12_2 / (r12_1 + r12_2);
|
||||
k5 = r5_2 / (r5_1 + r5_2);
|
||||
kbat = rbat_2 / (rbat_1 + rbat_2);
|
||||
kout = rout_2 / (rout_1 + rout_2);
|
||||
|
||||
modem.controlGPIO(1, 0);
|
||||
modem.controlGPIO(2, 0);
|
||||
modem.controlGPIO(3, 0);
|
||||
modem.controlGPIO(4, 0);
|
||||
|
||||
sprint("Init");
|
||||
printParams();
|
||||
sprint_P(str_help);
|
||||
|
||||
initEEPROM();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
if (millis() - t > PERIOD) {
|
||||
getStatus();
|
||||
t = millis();
|
||||
//sprint("Status!");
|
||||
}
|
||||
|
||||
checkModem();
|
||||
|
||||
if (!cmdFromModem) {
|
||||
readSerial(command, CMD_SIZE);
|
||||
}
|
||||
|
||||
if (command[0] != '\0') {
|
||||
sprint(">", false);
|
||||
sprint(command);
|
||||
|
||||
if (!strcmp_P(command, cmd_status)) {
|
||||
getStatusMessage(message);
|
||||
returnAnswer(message);
|
||||
} else if (!strcmp_P(command, cmd_help)) {
|
||||
sprint_P(str_help);
|
||||
sendHelp();
|
||||
} else if (!strcmp_P(command, cmd_sms_on)) {
|
||||
smsOn(true);
|
||||
returnAnswer();
|
||||
} else if (!strcmp_P(command, cmd_sms_off)) {
|
||||
smsOn(false);
|
||||
returnAnswer();
|
||||
} else if (!strcmp_P(command, cmd_auth_on)) {
|
||||
authOn(true);
|
||||
returnAnswer();
|
||||
} else if (!strcmp_P(command, cmd_auth_off)) {
|
||||
authOn(false);
|
||||
returnAnswer();
|
||||
} else if (!strcmp_P(command, cmd_fwd_on)) {
|
||||
fwdOn(true);
|
||||
returnAnswer();
|
||||
} else if (!strcmp_P(command, cmd_fwd_off)) {
|
||||
fwdOn(false);
|
||||
returnAnswer();
|
||||
} else if (!strcmp_P(command, cmd_on)) {
|
||||
mainPowerOn();
|
||||
returnAnswer();
|
||||
} else if (!strcmp_P(command, cmd_off)) {
|
||||
mainPowerOff();
|
||||
returnAnswer();
|
||||
} else if (!strcmp_P(command, cmd_reset)) {
|
||||
mainReset();
|
||||
returnAnswer();
|
||||
} else if (!strcmp_P(command, cmd_a)) {
|
||||
a_PowerBreak();
|
||||
returnAnswer();
|
||||
} else if (!strcmp_P(command, cmd_b)) {
|
||||
b_PowerBreak();
|
||||
returnAnswer();
|
||||
} else if (!strcmp_P(command, cmd_forward)) {
|
||||
forwardLastSMS();
|
||||
} else if (!strcmp_P(command, cmd_modem_reset) && !cmdFromModem) {
|
||||
modem.reset();
|
||||
modem.init();
|
||||
returnAnswer();
|
||||
} else if (!strcmp_P(command, cmd_modem_console) && !cmdFromModem) {
|
||||
modemConsole();
|
||||
} else if (!strcmp_P(command, cmd_edit_ab) && !cmdFromModem) {
|
||||
editAddressBook();
|
||||
} else if (!strcmp_P(command, cmd_show_ab) && !cmdFromModem) {
|
||||
printAddressBook();
|
||||
} else {
|
||||
sprint_P(str_help);
|
||||
sendHelp();
|
||||
}
|
||||
}
|
||||
|
||||
ledOn();
|
||||
delay(5);
|
||||
ledOff();
|
||||
|
||||
if (buttonPressed()) {
|
||||
ledOn();
|
||||
if (btnCount < BTN_COUNT) btnCount++;
|
||||
} else {
|
||||
ledOff();
|
||||
btnCount = 0;
|
||||
btnTrigger = false;
|
||||
}
|
||||
|
||||
if (btnCount >= BTN_COUNT && !btnTrigger) {
|
||||
btnTrigger = true;
|
||||
if (entryNotEmpty(0)) {
|
||||
loadPhoneNumber(0, phone);
|
||||
modem.callUp(phone);
|
||||
sprint("Out call: ", phone);
|
||||
while (true) {
|
||||
ledOn();
|
||||
event = modem.getEvent(message, phone, datetime, l_buffer, LONG_BUFFER_SIZE, NO_CHECK);
|
||||
ledOff();
|
||||
delay(150);
|
||||
|
||||
if (event == BUSY || event == NO_CARRIER || event == NO_ANSWER) break;
|
||||
if (event == ANSWER) t = millis();
|
||||
|
||||
if (!buttonPressed()) btnTrigger = false;
|
||||
|
||||
if (millis() - t > CALL_TIMEOUT || (buttonPressed() && !btnTrigger)) {
|
||||
btnTrigger = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
modem.hangup();
|
||||
sprint("Call over");
|
||||
} else {
|
||||
flash(5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Запрос статуса
|
||||
word getStatus() {
|
||||
unsigned int stat = 0;
|
||||
|
||||
// Get sensors
|
||||
getTH();
|
||||
if (temp > 28) stat |= TEMP_WARN;
|
||||
if (hum > 85) stat |= HUM_WARN;
|
||||
|
||||
loud = analogRead(A_PIN);
|
||||
if (loud > 250) stat |= LOUD_WARN;
|
||||
|
||||
getVs();
|
||||
if (v12 < 10) stat |= POWER_WARN;
|
||||
if (vbat < 6.4) stat |= BAT_WARN;
|
||||
|
||||
return stat;
|
||||
}
|
||||
|
||||
//
|
||||
void printAll() {
|
||||
sprint("phone: ", phone);
|
||||
sprint("date: ", datetime);
|
||||
sprint("msg: ", message);
|
||||
sprint("msg len: ", strlen(message));
|
||||
sprint("cmd: ", command);
|
||||
|
||||
sprint("t: ", temp);
|
||||
sprint("h: ", hum);
|
||||
sprint("l: ", loud);
|
||||
|
||||
sprint("mdm: ", modemOK, true);
|
||||
sprint("sms: ", smsOn(), true);
|
||||
sprint("auth: ", authOn(), true);
|
||||
sprint("fwd: ", fwdOn(), true);
|
||||
|
||||
sprint("Vcc: ", vcc);
|
||||
sprint("V12: ", v12);
|
||||
sprint("V5: ", v5);
|
||||
sprint("Vbat: ", vbat);
|
||||
sprint("Vout: ", vout);
|
||||
}
|
||||
|
||||
// Формируем читабельную строку со статусом
|
||||
void getStatusMessage(char *message) {
|
||||
word stat = getStatus();
|
||||
char s[10];
|
||||
|
||||
message[0] = '\0';
|
||||
if (stat != 0) {
|
||||
strcat(message, "WARNING");
|
||||
} else {
|
||||
strcat(message, "OK");
|
||||
}
|
||||
|
||||
strcat(message, "\nT: ");
|
||||
itoa(temp, s, 10);
|
||||
strcat(message, s);
|
||||
strcat(message, "C");
|
||||
if (stat & TEMP_WARN) strcat(message, " !");
|
||||
|
||||
strcat(message, " H: ");
|
||||
itoa(hum, s, 10);
|
||||
strcat(message, s);
|
||||
strcat(message, "%");
|
||||
if (stat & HUM_WARN) strcat(message, " !");
|
||||
|
||||
strcat(message, " L: ");
|
||||
itoa(loud, s, 10);
|
||||
strcat(message, s);
|
||||
strcat(message, "UE");
|
||||
if (stat & LOUD_WARN) strcat(message, " !");
|
||||
|
||||
strcat(message, "\nVcc: ");
|
||||
ftoa(vcc, s);
|
||||
strcat(message, s);
|
||||
strcat(message, "V");
|
||||
|
||||
strcat(message, "\nV12: ");
|
||||
ftoa(v12, s);
|
||||
strcat(message, s);
|
||||
strcat(message, "V");
|
||||
|
||||
strcat(message, " V5: ");
|
||||
ftoa(v5, s);
|
||||
strcat(message, s);
|
||||
strcat(message, "V");
|
||||
|
||||
strcat(message, "\nVbat: ");
|
||||
ftoa(vbat, s);
|
||||
strcat(message, s);
|
||||
strcat(message, "V");
|
||||
|
||||
strcat(message, " Vout: ");
|
||||
ftoa(vout, s);
|
||||
strcat(message, s);
|
||||
strcat(message, "V");
|
||||
|
||||
strcat(message, "\n\nPower: ");
|
||||
if (stat & POWER_WARN) strcat(message, "Off");
|
||||
else strcat(message, "On");
|
||||
|
||||
strcat(message, " Battery: ");
|
||||
if (stat & BAT_WARN) strcat(message, "Low");
|
||||
else strcat(message, "Ok");
|
||||
|
||||
strcat(message, "\nSMS: ");
|
||||
if (smsOn()) strcat(message, "On");
|
||||
else strcat(message, "Off");
|
||||
|
||||
strcat(message, " Auth: ");
|
||||
if (authOn()) strcat(message, "On");
|
||||
else strcat(message, "Off");
|
||||
|
||||
strcat(message, " Fwd: ");
|
||||
if (fwdOn()) strcat(message, "On");
|
||||
else strcat(message, "Off");
|
||||
}
|
||||
|
||||
// Обработка событий модема
|
||||
void checkModem() {
|
||||
cmdFromModem = false;
|
||||
command[0] = '\0';
|
||||
|
||||
switch (modem.getEvent(message, phone, datetime, l_buffer, LONG_BUFFER_SIZE)) {
|
||||
case ERR:
|
||||
sprint("Mdm err!");
|
||||
modemOK = false;
|
||||
if (modemErrCount < MAX_ERROR) modemErrCount++;
|
||||
|
||||
if (modemErrCount >= MAX_ERROR) {
|
||||
sprint("Rst mdm...");
|
||||
modem.reset();
|
||||
if (modem.init()) {
|
||||
sprint("Mdm OK");
|
||||
modemOK = true;
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
case SMS:
|
||||
sprint("SMS: ", phone);
|
||||
flash(3);
|
||||
|
||||
if (authOn() && !authOK(phone)) {
|
||||
strcpy_P(command, cmd_forward);
|
||||
} else {
|
||||
strncpy(command, message, CMD_SIZE);
|
||||
}
|
||||
cmdFromModem = true;
|
||||
break;
|
||||
|
||||
case CALL:
|
||||
sprint("Call: ", phone);
|
||||
|
||||
if (authOn() && !authOK(phone)) {
|
||||
modem.hangup();
|
||||
sprint("Unauth call");
|
||||
} else {
|
||||
modem.answer();
|
||||
t = millis();
|
||||
while (!modem.ifcallEnd()) {
|
||||
ledOn();
|
||||
delay(1000);
|
||||
ledOff();
|
||||
|
||||
if (millis() - t > CALL_TIMEOUT || buttonPressed()) {
|
||||
modem.hangup();
|
||||
break;
|
||||
}
|
||||
}
|
||||
sprint("Call over");
|
||||
}
|
||||
cmdFromModem = true;
|
||||
break;
|
||||
|
||||
case NONE:
|
||||
cmdFromModem = false;
|
||||
break;
|
||||
}
|
||||
|
||||
modemErrCount = 0;
|
||||
modemOK = true;
|
||||
}
|
||||
|
||||
// Консоль модема
|
||||
void modemConsole() {
|
||||
sprint_P(str_modem_cons_on);
|
||||
sprint("Timeout is ", TIMEOUT, false);
|
||||
sprint(" ms after last command");
|
||||
|
||||
t = millis();
|
||||
byte i = 0;
|
||||
while (millis() - t < TIMEOUT) {
|
||||
if (Serial1.available()) {
|
||||
while(Serial1.available()) {
|
||||
s_buffer[i++] = Serial1.read();
|
||||
if(i == BUFFER_SIZE) break;
|
||||
}
|
||||
|
||||
Serial.write(s_buffer, i);
|
||||
i = 0;
|
||||
}
|
||||
|
||||
if (Serial.available()) {
|
||||
Serial1.write(Serial.read());
|
||||
t = millis();
|
||||
}
|
||||
}
|
||||
sprint_P(str_modem_cons_off);
|
||||
}
|
||||
|
||||
// Читаем команды с COM-порта
|
||||
void readSerial(char *com, byte com_size) {
|
||||
com[0] = '\0';
|
||||
com[com_size - 1] = '\0';
|
||||
|
||||
byte i = 0;
|
||||
while (Serial.available() > 0 && i < com_size - 1) {
|
||||
com[i] = Serial.read();
|
||||
if (com[i] == '\r') {
|
||||
com[i] = '\0';
|
||||
} else if (com[i] == '\n') {
|
||||
com[i] = '\0';
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
// Отправляем ответ
|
||||
void returnAnswer(const char * answer) {
|
||||
sprint(answer);
|
||||
|
||||
if (modemOK && smsOn() && cmdFromModem) {
|
||||
modem.sendSMS(phone, answer);
|
||||
}
|
||||
}
|
||||
|
||||
void sendHelp() {
|
||||
if (modemOK && smsOn() && cmdFromModem) {
|
||||
if (authOn() && !authOK(phone)) return;
|
||||
modem.sendSMS(phone, str_help);
|
||||
}
|
||||
}
|
||||
|
||||
void forwardLastSMS() {
|
||||
char main_phone[PHONE_SIZE];
|
||||
|
||||
sprint("Get SMS from: ", false);
|
||||
sprint(phone);
|
||||
sprint("at: ", false);
|
||||
sprint(datetime);
|
||||
sprint(message);
|
||||
|
||||
if (fwdOn() && entryNotEmpty(0)) {
|
||||
loadPhoneNumber(0, main_phone);
|
||||
s_buffer[0] = '\0';
|
||||
strcat(s_buffer, "SMS from ");
|
||||
strcat(s_buffer, phone);
|
||||
strcat(s_buffer, " at ");
|
||||
strcat(s_buffer, datetime);
|
||||
modem.sendSMS(main_phone, s_buffer);
|
||||
modem.sendSMS(main_phone, message);
|
||||
}
|
||||
}
|
||||
|
||||
// Управление подключенным оборудованием
|
||||
void mainPowerOn() {
|
||||
if (!isPowerOn()) {
|
||||
modem.controlGPIO(1, 1);
|
||||
delay(500);
|
||||
modem.controlGPIO(1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void mainPowerOff() {
|
||||
modem.controlGPIO(1, 1);
|
||||
delay(6000);
|
||||
modem.controlGPIO(1, 0);
|
||||
}
|
||||
|
||||
void mainReset() {
|
||||
modem.controlGPIO(2, 1);
|
||||
delay(500);
|
||||
modem.controlGPIO(2, 0);
|
||||
}
|
||||
|
||||
void a_PowerBreak() {
|
||||
modem.controlGPIO(3, 1);
|
||||
delay(5000);
|
||||
modem.controlGPIO(3, 0);
|
||||
}
|
||||
|
||||
void b_PowerBreak() {
|
||||
modem.controlGPIO(4, 1);
|
||||
delay(5000);
|
||||
modem.controlGPIO(4, 0);
|
||||
}
|
||||
|
||||
bool isPowerOn() {
|
||||
getVs();
|
||||
if (v12 > 10) return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
// Адресная книга
|
||||
bool savePhoneNumber(byte index, char * phone) {
|
||||
if (index > AB_MAX_INDEX) return false;
|
||||
|
||||
addr = AB_ADDR + index * PHONE_SIZE;
|
||||
|
||||
for (byte i = 0; i < PHONE_SIZE; i++)
|
||||
EEPROM.update(addr + i, phone[i]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool delPhoneNumber(byte index) {
|
||||
if (index > AB_MAX_INDEX) return false;
|
||||
|
||||
clearBuffer(phone, PHONE_SIZE);
|
||||
strcpy(phone, "<NONE>");
|
||||
|
||||
return savePhoneNumber(index, phone);
|
||||
}
|
||||
|
||||
bool loadPhoneNumber(byte index, char * phone) {
|
||||
if (index > AB_MAX_INDEX) return false;
|
||||
|
||||
addr = AB_ADDR + index * PHONE_SIZE;
|
||||
|
||||
for (byte i = 0; i < PHONE_SIZE - 1; i++)
|
||||
phone[i] = EEPROM.read(addr + i);
|
||||
phone[PHONE_SIZE - 1] = '\0';
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool entryNotEmpty(byte index) {
|
||||
char phone[PHONE_SIZE];
|
||||
|
||||
loadPhoneNumber(index, phone);
|
||||
return strcmp(phone, "<NONE>");
|
||||
}
|
||||
|
||||
void printPhoneNumber(byte index) {
|
||||
if (index > AB_MAX_INDEX) {
|
||||
sprint("Max index is: ", AB_MAX_INDEX);
|
||||
return;
|
||||
}
|
||||
|
||||
loadPhoneNumber(index, phone);
|
||||
sprint("", index, false);
|
||||
sprint(": ", false);
|
||||
sprint(phone);
|
||||
}
|
||||
|
||||
void printAddressBook() {
|
||||
sprint("i Phone");
|
||||
for (byte i = 0; i <= AB_MAX_INDEX; i++)
|
||||
printPhoneNumber(i);
|
||||
}
|
||||
|
||||
void clearAddressBook() {
|
||||
for (byte i = 0; i <= AB_MAX_INDEX; i++)
|
||||
delPhoneNumber(i);
|
||||
}
|
||||
|
||||
void editAddressBook() {
|
||||
char *p;
|
||||
char indexString[4];
|
||||
byte index, i = 0;
|
||||
|
||||
sprint_P(str_eab);
|
||||
sprint_P(str_help_ab);
|
||||
sprint_P(str_format_ab);
|
||||
|
||||
t = millis();
|
||||
while (millis() - t < TIMEOUT) {
|
||||
readSerial(s_buffer, BUFFER_SIZE);
|
||||
|
||||
if (s_buffer[0] != '\0') {
|
||||
t = millis();
|
||||
|
||||
if (!strcmp_P(s_buffer, cmd_exit)) {
|
||||
break;
|
||||
} else if (!strcmp_P(s_buffer, cmd_show)) {
|
||||
printAddressBook();
|
||||
} else if (!strcmp_P(s_buffer, cmd_clear)) {
|
||||
clearAddressBook();
|
||||
} else {
|
||||
p = strstr(s_buffer, ":");
|
||||
i = 0;
|
||||
while(s_buffer[i] != ':' && i < BUFFER_SIZE) i++;
|
||||
|
||||
if (p == NULL || i == 0 || i > 1) {
|
||||
sprint_P(str_format_ab);
|
||||
} else {
|
||||
// Get index
|
||||
clearBuffer(indexString, 4);
|
||||
strncpy(indexString, s_buffer, i);
|
||||
index = atoi(indexString);
|
||||
// Get phone
|
||||
i = 0;
|
||||
p = strstr(s_buffer, ":") + 1;
|
||||
strcpy(phone, p);
|
||||
|
||||
if (strcmp(phone, "delete")) {
|
||||
// Save
|
||||
savePhoneNumber(index, phone);
|
||||
sprint("OK");
|
||||
} else {
|
||||
// Delete
|
||||
delPhoneNumber(index);
|
||||
sprint("OK");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
sprint_P(str_help);
|
||||
}
|
||||
|
||||
// Утилиты
|
||||
void clearBuffer(char *in_buffer, byte in_size) {
|
||||
for(byte i = 0; i < in_size - 1; i++) in_buffer[i] = '\0';
|
||||
}
|
||||
|
||||
void printParams() {
|
||||
if(smsOn()) sprint("SMS on | ", false); else sprint("SMS off | ", false);
|
||||
if(authOn()) sprint("Auth on | ", false); else sprint("Auth off | ", false);
|
||||
if(smsOn()) sprint("Fwd on"); else sprint("Fwd off");
|
||||
}
|
||||
|
||||
bool authOK(char *phone) {
|
||||
char t_phone[PHONE_SIZE];
|
||||
|
||||
for(byte i = 0; i <= AB_MAX_INDEX; i++) {
|
||||
loadPhoneNumber(i, t_phone);
|
||||
if (!strcmp(phone, t_phone)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void sprint(const char *description, const byte data, const bool ln) {
|
||||
Serial.print(description);
|
||||
Serial.print(data);
|
||||
if (ln) Serial.println();
|
||||
}
|
||||
|
||||
void sprint(const char *description, const char *data, const bool ln) {
|
||||
Serial.print(description);
|
||||
Serial.print(data);
|
||||
if (ln) Serial.println();
|
||||
}
|
||||
|
||||
void sprint(const char *description, const int data, const bool ln) {
|
||||
Serial.print(description);
|
||||
Serial.print(data);
|
||||
if (ln) Serial.println();
|
||||
}
|
||||
|
||||
void sprint(const char *description, const unsigned int data, const bool ln) {
|
||||
Serial.print(description);
|
||||
Serial.print(data);
|
||||
if (ln) Serial.println();
|
||||
}
|
||||
|
||||
void sprint(const char *description, const long int data, const bool ln) {
|
||||
Serial.print(description);
|
||||
Serial.print(data);
|
||||
if (ln) Serial.println();
|
||||
}
|
||||
|
||||
void sprint(const char *description, const long unsigned int data, const bool ln) {
|
||||
Serial.print(description);
|
||||
Serial.print(data);
|
||||
if (ln) Serial.println();
|
||||
}
|
||||
|
||||
void sprint(const char *description, const float data, const bool ln) {
|
||||
Serial.print(description);
|
||||
Serial.print(data);
|
||||
if (ln) Serial.println();
|
||||
}
|
||||
|
||||
void sprint(const char *description, const bool ln) {
|
||||
Serial.print(description);
|
||||
if (ln) Serial.println();
|
||||
}
|
||||
|
||||
void sprint_P(const char *description, const bool ln) {
|
||||
int len = strlen_P(description);
|
||||
char c;
|
||||
|
||||
for (byte i = 0; i < len; i++) {
|
||||
c = pgm_read_byte_near(description + i);
|
||||
Serial.print(c);
|
||||
}
|
||||
if (ln) Serial.println();
|
||||
}
|
||||
|
||||
bool smsOn() {
|
||||
addr = PARAM_ADDR + SMS_ON_INDEX;
|
||||
return (bool)EEPROM.read(addr);
|
||||
}
|
||||
|
||||
void smsOn(bool temp) {
|
||||
addr = PARAM_ADDR + SMS_ON_INDEX;
|
||||
EEPROM.update(addr, (byte)temp);
|
||||
}
|
||||
|
||||
bool authOn() {
|
||||
addr = PARAM_ADDR + AUTH_ON_INDEX;
|
||||
return (bool)EEPROM.read(addr);
|
||||
}
|
||||
|
||||
void authOn(bool temp) {
|
||||
addr = PARAM_ADDR + AUTH_ON_INDEX;
|
||||
EEPROM.update(addr, (byte)temp);
|
||||
}
|
||||
|
||||
bool fwdOn() {
|
||||
addr = PARAM_ADDR + FWD_ON_INDEX;
|
||||
return (bool)EEPROM.read(addr);
|
||||
}
|
||||
|
||||
void fwdOn(bool temp) {
|
||||
addr = PARAM_ADDR + FWD_ON_INDEX;
|
||||
EEPROM.update(addr, (byte)temp);
|
||||
}
|
||||
|
||||
void fanPWM(byte power) {
|
||||
analogWrite(FAN_PIN, power);
|
||||
}
|
||||
|
||||
void fanOn() {
|
||||
digitalWrite(FAN_PIN, HIGH);
|
||||
}
|
||||
|
||||
void fanOff() {
|
||||
digitalWrite(FAN_PIN, LOW);
|
||||
}
|
||||
|
||||
void ledPWM(byte power) {
|
||||
analogWrite(LED_PIN, power);
|
||||
}
|
||||
|
||||
void ledOn() {
|
||||
digitalWrite(LED_PIN, HIGH);
|
||||
}
|
||||
|
||||
void ledOff() {
|
||||
digitalWrite(LED_PIN, LOW);
|
||||
}
|
||||
|
||||
void flash(byte count) {
|
||||
for (byte i = 0; i < count; i++) {
|
||||
ledOn();
|
||||
delay(5);
|
||||
ledOff();
|
||||
delay(150);
|
||||
}
|
||||
}
|
||||
|
||||
bool buttonPressed() {
|
||||
if (digitalRead(BTN_PIN) == LOW) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
float readvcc() {
|
||||
byte i;
|
||||
float tmp = 0.0;
|
||||
|
||||
// Read 1.1V reference against Avcc
|
||||
// set the reference to vcc and the measurement to the internal 1.1V reference
|
||||
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
|
||||
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
|
||||
ADMUX = _BV(MUX5) | _BV(MUX0);
|
||||
#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
|
||||
ADMUX = _BV(MUX3) | _BV(MUX2);
|
||||
#else
|
||||
// works on an Arduino 168 or 328
|
||||
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
|
||||
#endif
|
||||
|
||||
delay(3); // Wait for Vref to settle
|
||||
ADCSRA |= _BV(ADSC); // Start conversion
|
||||
while (bit_is_set(ADCSRA,ADSC)); // measuring
|
||||
|
||||
uint8_t low = ADCL; // must read ADCL first - it then locks ADCH
|
||||
uint8_t high = ADCH; // unlocks both
|
||||
|
||||
tmp = (high<<8) | low;
|
||||
tmp = (typVbg * 1023.0) / tmp;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void getVs() {
|
||||
v12 = 0.0;
|
||||
v5 = 0.0;
|
||||
vbat = 0.0;
|
||||
vout = 0.0;
|
||||
|
||||
v12 += readvcc() * analogRead(V12_PIN);
|
||||
v5 += readvcc() * analogRead(V5_PIN);
|
||||
vbat += readvcc() * analogRead(VBAT_PIN);
|
||||
vout += readvcc() * analogRead(VOUT_PIN);
|
||||
|
||||
vcc = readvcc();
|
||||
v12 = v12 / 1024.0 / k12;
|
||||
v5 = v5 / 1024.0 / k5;
|
||||
vbat = vbat / 1024.0 / kbat;
|
||||
vout = vout / 1024.0 / kout;
|
||||
}
|
||||
|
||||
void printVs() {
|
||||
sprint("Vcc: ", vcc);
|
||||
sprint("V12: ", v12);
|
||||
sprint("V5: ", v5);
|
||||
sprint("Vbat: ", vbat);
|
||||
sprint("Vout: ", vout);
|
||||
}
|
||||
|
||||
void getTH() {
|
||||
int check;
|
||||
|
||||
check = dht.read();
|
||||
switch (check) {
|
||||
case DHT_OK:
|
||||
temp = dht.getTemperatureC();
|
||||
hum = dht.getHumidity();
|
||||
break;
|
||||
case DHT_ERROR_TIMEOUT:
|
||||
temp = 253;
|
||||
break;
|
||||
case DHT_ERROR_CHECKSUM:
|
||||
temp = 254;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ftoa(float f, char *s) {
|
||||
int d1, d2;
|
||||
char t[10];
|
||||
|
||||
s[0] = '\0';
|
||||
|
||||
d1 = (int)f;
|
||||
f = f - d1;
|
||||
f = f * 100;
|
||||
d2 = (int)f;
|
||||
|
||||
itoa(d1, t, 10);
|
||||
strcat(s, t);
|
||||
strcat(s, ".");
|
||||
itoa(d2, t, 10);
|
||||
strcat(s, t);
|
||||
}
|
||||
|
||||
void initEEPROM() {
|
||||
int flag_addr = PARAM_ADDR + EEPROM_INIT_INDEX;
|
||||
|
||||
if (EEPROM.read(flag_addr) != INIT_FLAG) {
|
||||
clearAddressBook();
|
||||
smsOn(false);
|
||||
authOn(true);
|
||||
fwdOn(true);
|
||||
EEPROM.write(flag_addr, INIT_FLAG);
|
||||
}
|
||||
}
|
168
watchdog_3.h
Normal file
168
watchdog_3.h
Normal file
@ -0,0 +1,168 @@
|
||||
// ----------------------------------------------------------------------------------------------------
|
||||
// Watchdog v3 - Leonardo
|
||||
// EoF 2017
|
||||
// Header
|
||||
// ----------------------------------------------------------------------------------------------------
|
||||
|
||||
#include <EEPROM.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include "GPRS_Shield_Arduino.h"
|
||||
#include <TroykaDHT.h>
|
||||
|
||||
/*
|
||||
* EEPROM mapping
|
||||
* 1024 Kb
|
||||
* 10 x 16 = 160 - address book | first addr 0
|
||||
* 16 x 1 = 16 - parameters | first addr 160
|
||||
* -------------
|
||||
* 176 bytes
|
||||
* 848 bytes free
|
||||
*/
|
||||
|
||||
#define AB_ADDR 0
|
||||
#define AB_MAX_INDEX 9
|
||||
|
||||
#define PARAM_ADDR 160
|
||||
#define PARAM_MAX_INDEX 15
|
||||
#define SMS_ON_INDEX 0
|
||||
#define AUTH_ON_INDEX 1
|
||||
#define FWD_ON_INDEX 2
|
||||
#define EEPROM_INIT_INDEX 15
|
||||
|
||||
#define INIT_FLAG 0xAC
|
||||
|
||||
const char cmd_status[] PROGMEM = {"status"};
|
||||
const char cmd_help[] PROGMEM = {"help"};
|
||||
const char cmd_sms_on[] PROGMEM = {"sms on"};
|
||||
const char cmd_sms_off[] PROGMEM = {"sms off"};
|
||||
const char cmd_on[] PROGMEM = {"on"};
|
||||
const char cmd_off[] PROGMEM = {"off"};
|
||||
const char cmd_reset[] PROGMEM = {"reset"};
|
||||
const char cmd_a[] PROGMEM = {"a"};
|
||||
const char cmd_b[] PROGMEM = {"b"};
|
||||
const char cmd_forward[] PROGMEM = {"forward"};
|
||||
const char cmd_modem_reset[] PROGMEM = {"modem reset"};
|
||||
const char cmd_modem_console[] PROGMEM = {"modem console"};
|
||||
const char cmd_edit_ab[] PROGMEM = {"edit ab"};
|
||||
const char cmd_show_ab[] PROGMEM = {"show ab"};
|
||||
const char cmd_show[] PROGMEM = {"show"};
|
||||
const char cmd_clear[] PROGMEM = {"clear"};
|
||||
const char cmd_exit[] PROGMEM = {"exit"};
|
||||
const char cmd_auth_on[] PROGMEM = {"auth on"};
|
||||
const char cmd_auth_off[] PROGMEM = {"auth off"};
|
||||
const char cmd_fwd_on[] PROGMEM = {"forward on"};
|
||||
const char cmd_fwd_off[] PROGMEM = {"forward off"};
|
||||
|
||||
const char str_init_eeprom[] PROGMEM = {"EEPROM init complete"};
|
||||
const char str_eab[] PROGMEM = {"Edit address book mode"};
|
||||
const char str_modem_cons_on[] PROGMEM = {"Modem console mode on"};
|
||||
const char str_modem_cons_off[] PROGMEM = {"Modem console mode off"};
|
||||
|
||||
const char str_help[] PROGMEM = {"Usage: help/status/on/off/reset/a/b/modem reset|console/edit ab/show ab/sms on|off/auth on|off/fwd on|off"};
|
||||
const char str_help_ab[] PROGMEM = {"Type \"show\" to view, \"clear\" to erase, \"exit\" to return"};
|
||||
const char str_format_ab[] PROGMEM = {"Format: \"i:+xxxxxxxxxxx\" to update or \"i:delete\" to delete"};
|
||||
|
||||
// Всякое
|
||||
#define TIMEOUT 60000
|
||||
#define PERIOD 15000
|
||||
#define MAX_ERROR 5
|
||||
#define CALL_TIMEOUT 60000
|
||||
#define BTN_COUNT 3
|
||||
|
||||
// Сенсоры
|
||||
#define A_PIN A0
|
||||
#define T_PIN A1
|
||||
#define VOUT_PIN A2
|
||||
#define VBAT_PIN A3
|
||||
#define V5_PIN A4
|
||||
#define V12_PIN A5
|
||||
|
||||
#define LED_PIN 13
|
||||
#define BTN_PIN 12
|
||||
#define FAN_PIN 11
|
||||
|
||||
// GSM-модем
|
||||
#define MOD_PWR 9
|
||||
#define MOD_BR 115200
|
||||
#define COM_BR 115200
|
||||
#define SMS_LEN 160
|
||||
|
||||
// Размеры буферов;
|
||||
#define CMD_SIZE 16
|
||||
#define SMS_SIZE 160
|
||||
#define PHONE_SIZE 16
|
||||
#define DATE_SIZE 24
|
||||
#define BUFFER_SIZE 64
|
||||
#define LONG_BUFFER_SIZE 240
|
||||
|
||||
// Флаги статуса
|
||||
#define TEMP_WARN 0x01
|
||||
#define HUM_WARN 0x02
|
||||
#define LOUD_WARN 0x04
|
||||
#define POWER_WARN 0x08
|
||||
#define BAT_WARN 0x016
|
||||
|
||||
word getStatus();
|
||||
void getStatusMessage(char * message);
|
||||
bool isCommandMatchIndex(const char * command, byte index);
|
||||
void checkModem();
|
||||
void modemConsole();
|
||||
void incomingCall();
|
||||
void readModem(char* msg, byte size);
|
||||
void readSerial(char *com, byte size);
|
||||
void returnAnswer(const char * answer = "OK");
|
||||
void sendHelp();
|
||||
void mainPowerOn();
|
||||
void mainPowerOff();
|
||||
void mainReset();
|
||||
void a_PowerBreak();
|
||||
void b_PowerBreak();
|
||||
bool isPowerOn();
|
||||
|
||||
// Адресная книга
|
||||
bool savePhoneNumber(byte index, char * phone);
|
||||
bool delPhoneNumber(byte index);
|
||||
bool loadPhoneNumber(byte index, char * phone);
|
||||
bool entryNotEmpty(byte index);
|
||||
void printPhoneNumber(byte index);
|
||||
void printAddressBook();
|
||||
void clearAddressBook();
|
||||
void editAddressBook();
|
||||
|
||||
// Утилиты
|
||||
void clearBuffer(char *buffer, byte size);
|
||||
void printShortString(byte index, bool ln = true);
|
||||
void printLongString(byte index, bool ln = true);
|
||||
void printHelp();
|
||||
void printParams();
|
||||
bool authOK(char *phone);
|
||||
|
||||
void sprint(const char *description, const byte data, const bool ln = true);
|
||||
void sprint(const char *description, const char *data, const bool ln = true);
|
||||
void sprint(const char *description, const int data, const bool ln = true);
|
||||
void sprint(const char *description, const unsigned int data, const bool ln = true);
|
||||
void sprint(const char *description, const long int data, const bool ln = true);
|
||||
void sprint(const char *description, const long unsigned int data, const bool ln = true);
|
||||
void sprint(const char *description, const float data, const bool ln = true);
|
||||
void sprint(const char *description, const bool ln = true);
|
||||
void sprint_P(const char *description, const bool ln = true);
|
||||
|
||||
bool smsOn();
|
||||
void smsOn(bool temp);
|
||||
bool authOn();
|
||||
void authOn(bool temp);
|
||||
bool fwdOn();
|
||||
void fwdOn(bool temp);
|
||||
void fanPWM(byte power = 128);
|
||||
void fanOn();
|
||||
void fanOff();
|
||||
void ledPWM(byte power = 128);
|
||||
void ledOn();
|
||||
void ledOff();
|
||||
void flash(byte count = 3);
|
||||
bool buttonPressed();
|
||||
float readvcc();
|
||||
void getVs();
|
||||
void printVs();
|
||||
void getTH();
|
||||
void initEEPROM();
|
Loading…
Reference in New Issue
Block a user