Skip to content

Instantly share code, notes, and snippets.

@zdila
Last active August 26, 2017 16:01
Show Gist options
  • Save zdila/a02e0e2bc8bf41bd595b to your computer and use it in GitHub Desktop.
Save zdila/a02e0e2bc8bf41bd595b to your computer and use it in GitHub Desktop.
SMS controlled GPS tracker
#include <TinyGPS++.h>
#include <AltSoftSerial.h>
AltSoftSerial altSerial;
TinyGPSPlus gps;
char line[256] = "";
int p = 0;
const char * initCommands[] = {
"AT",
"ATE0",
"AT+CPIN=\"0000\"",
"AT+CMGF=1",
"AT+CNMI=2,2,0,0,0"
};
const char * receivedSmsPrefix = "+CMT: \"+4219########\"";
typedef enum {IDLE, WAIT_FOR_RESPONSE, SMS_READ_TEXT, SMS_WAIT_FOR_PROMPT} status_t;
int initLine = 0;
boolean sendSms = false;
status_t status = IDLE;
void setup() {
Serial.begin(9600);
altSerial.begin(9600);
pinMode(3, OUTPUT);
pinMode(13, OUTPUT);
}
void loop() {
digitalWrite(3, status == IDLE ? LOW : HIGH);
int hdop = gps.hdop.value();
if (hdop == 0) {
hdop = 10000;
}
digitalWrite(13, millis() % 100 > 50 && (millis() / 100) % 50 < (hdop / 100.0 - 0.95) * 10);
// digitalWrite(13, status != IDLE || millis() % 200 > 100 ? HIGH : LOW);
if (status == IDLE) {
if (initLine < sizeof(initCommands) / sizeof(initCommands[0])) {
altSerial.println(initCommands[initLine++]);
status = WAIT_FOR_RESPONSE;
} else if (sendSms) {
sendSms = false;
altSerial.println("AT+CMGS=\"+421########\"");
status = SMS_WAIT_FOR_PROMPT;
}
}
if (altSerial.available()) {
char c = altSerial.read();
if (c == '\r') {
// ingore
} else if (c == '\n') {
switch (status) {
case SMS_READ_TEXT:
status = IDLE;
// Serial.print("Received SMS: ");
// Serial.println(line);
sendSms = true;
break;
case WAIT_FOR_RESPONSE:
if (!strcmp(line, "OK") || !strcmp(line, "ERROR")) {
status = IDLE;
}
break;
case IDLE:
if (!strncmp(receivedSmsPrefix, line, strlen(receivedSmsPrefix))) {
// received sms, read next line
status = SMS_READ_TEXT;
}
break;
case SMS_WAIT_FOR_PROMPT:
default:
// do nothing
break;
}
line[p = 0] = '\0';
} else if (status == SMS_WAIT_FOR_PROMPT && !strcmp(line, ">")) {
status = WAIT_FOR_RESPONSE;
// now we can send the sms
char smsText[161], latStr[11], lngStr[11];
dtostrf(gps.location.lat(), 9, 6, latStr);
dtostrf(gps.location.lng(), 9, 6, lngStr);
snprintf(smsText, 161, "%0.4d-%0.2d-%0.2d %0.2d:%0.2d:%0.2d @ %s %s, %d mnm, %d km/h, %d deg, HDOP: %d, sats: %d",
gps.date.year(),
gps.date.month(),
gps.date.day(),
gps.time.hour(),
gps.time.minute(),
gps.time.second(),
latStr,
lngStr,
(int) gps.altitude.meters(),
(int) gps.speed.kmph(),
(int) gps.course.deg(),
gps.hdop.value(),
gps.satellites.value());
altSerial.print(smsText);
altSerial.write(0x1A);
} else if (p < sizeof(line) - 1) {
line[p++] = c;
line[p] = '\0';
}
}
if (Serial.available() > 0) {
gps.encode(Serial.read());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment