SMS Scheduler that will automatically send and receive text messages using the Enfora 1308 GSM Modem. Please note that it uses a modified NetServices library and to set the baud rate for the GSM Modem to 19.2K.

Dependencies:   mbed

main.cpp

Committer:
mafischl
Date:
2011-10-13
Revision:
0:d9266031f832
Child:
1:5a7cce9994a3

File content as of revision 0:d9266031f832:

//Contest Winner using GSM Modem

#include "mbed.h"
#include "NetServices/if/eth/EthernetNetIf.h"
#include "NetServices/core/ipaddr.h"
#include "NetServices/services/http/server/HTTPServer.h"
#include "NetServices/services/ntp/NTPClient.h"
#include "TextLCD.h"
#include "MODSERIAL.h"
#include <math.h>
#include <iostream>
#include <string>
#define MESSAGE_BUFFER_SIZE 1024
using namespace std;

MODSERIAL gsm(p28,p27);
//Serial gsm(p28, p27);
EthernetNetIf eth;  
HTTPServer svr;
NTPClient ntp;
Serial pc(USBTX, USBRX); // PC Virtual Serial Port over USB
TextLCD lcd(p15, p16, p17, p11, p12, p20); // rs, e, d4-d7
DigitalOut heartBeat(LED1); //Heartbeat
DigitalOut led2(LED2); //Test for message process
DigitalOut wdtLED(LED4); //WatchDog Indicator
Timer t, timeOrDateTimer, clockSyncTimer, statusMessageInterruptTimer, send_SMS_Timer, GSM_Buffer_Timer;
int SMSinterval = 15;   //ceil(3600/SMSperHour);
int SMScount = 0;
int TIMEZONE = 4;
int timeCount;
int statusMessage = 0;
int compareResult = 0;
int messageResponse = 0;
int mpResult = 0;
bool timeOrDate = 0;
bool statusMessageAlert = 0;
bool statusMessageInterrupt = 0;
char messageBufferIncoming[MESSAGE_BUFFER_SIZE];
char messageBufferOutgoing[MESSAGE_BUFFER_SIZE];
bool messageReceived;
LocalFileSystem local("local");


  char buf[40];
  char buf1[40];
  char buf2= 0x1A;    //CTRL+Z, Substitute character

extern "C" void mbed_mac_address(char *mac);

class Watchdog {
public:
// Load timeout value in watchdog timer and enable
    void kick(float s) {
        LPC_WDT->WDCLKSEL = 0x1;                // Set CLK src to PCLK
        uint32_t clk = SystemCoreClock / 16;    // WD has a fixed /4 prescaler, PCLK default is /4
        LPC_WDT->WDTC = s * (float)clk;
        LPC_WDT->WDMOD = 0x3;                   // Enabled and Reset
        kick();
    }
// "kick" or "feed" the dog - reset the watchdog timer
// by writing this required bit pattern
    void kick() {
        LPC_WDT->WDFEED = 0xAA;
        LPC_WDT->WDFEED = 0x55;
    }
};

Watchdog wdt;


void messageReceive(MODSERIAL_IRQ_INFO *q) {
    MODSERIAL *sys = q->serial;
    sys->move(messageBufferIncoming, MESSAGE_BUFFER_SIZE);
    messageReceived = true;
    return;
}

int messageProcess(void) {
         if (!strncmp(messageBufferIncoming, "OK", sizeof("OK")-1)) mpResult = 1;
    else if (!strncmp(messageBufferIncoming, "ERROR", sizeof("ERROR")-1)) mpResult = 2;
 //   else if (!strncmp(messageBufferIncoming, "LED1:2", sizeof("LED1:2")-1)) led1 = !led1;
    
 //   if (!strncmp(messageBufferIncoming, "LED2:1", sizeof("LED2:1")-1)) led2 = 1;
 //   else if (!strncmp(messageBufferIncoming, "LED2:0", sizeof("LED2:0")-1)) led2 = 0;
 //   else if (!strncmp(messageBufferIncoming, "LED2:2", sizeof("LED2:2")-1)) led2 = !led2;
    
 //   else if (!strncmp(messageBufferIncoming, "LED3:1", sizeof("LED3:1")-1)) led3 = 1;
 //   else if (!strncmp(messageBufferIncoming, "LED3:0", sizeof("LED3:0")-1)) led3 = 0;
 //   else if (!strncmp(messageBufferIncoming, "LED3:2", sizeof("LED3:2")-1)) led3 = !led3;
    
 //   else if (!strncmp(messageBufferIncoming, "LED4:1", sizeof("LED4:1")-1)) led4 = 1;
 //   else if (!strncmp(messageBufferIncoming, "LED4:0", sizeof("LED4:0")-1)) led4 = 0;
 //   else if (!strncmp(messageBufferIncoming, "LED4:2", sizeof("LED4:2")-1)) led4 = !led4;
    else mpResult = 1;
    pc.printf("%s\r\n", messageBufferIncoming);
    gsm.rxBufferFlush();                            //Flush the Buffer
    messageReceived = false;
    return mpResult;
}

void sync_time(){
  //Connect to NIST and get time
  time_t ctTime;
  ctTime = time(NULL);  

  Host server(IpAddr(), 123, "nist1-atl.ustiming.org");
  ntp.setTime(server);
  
  ctTime = time(NULL);
}

void send_SMS(){
    //Send SMS Vote
  
  gsm.printf("AT+CMGS=\"78527\"\r\n");

  gsm.printf("Buzz%c\r\n",buf2);
  if(messageProcess()){
    statusMessageAlert = 1;
    statusMessage = 5;
    SMScount = SMScount + 1;
    pc.printf("SMS sent: %d\r\n", SMScount);
    }
  else{
    statusMessageAlert = 1;
    statusMessage = 7; //This value will also force a auto re-send
    pc.printf("SMS send failed\r\n");
    }
}

int main() {
  messageReceived = false;
  
  if ((LPC_WDT->WDMOD >> 2) & 1)
      wdtLED = 1; else wdtLED = 0;
        
// 30 second timeout on watchdog timer hardware
  wdt.kick(30.0);  

  gsm.baud(19200);
  gsm.format(8, Serial::None, 1);
  gsm.attach(&messageReceive, MODSERIAL::RxAutoDetect);     //Attaches Interrupts
  gsm.autoDetectChar('\n');                                 //Set Detection to Line Feed
  pc.baud(19200);
  
  lcd.cls();
  lcd.locate(0,0);
  lcd.printf("----------------");
  lcd.locate(0,1);
  lcd.printf("----------------");
  lcd.cls();
  lcd.locate(0,0);
  lcd.printf(" Contest Winner");
  lcd.locate(0,1);
  lcd.printf("    Please Wait");
  wait(2);
  lcd.cls();
  lcd.locate(0,0);
  lcd.printf("Setting up...\n");
  pc.printf("Program Started, setting up Ethernet Connection...\r\n");
  EthernetErr ethErr = eth.setup();
  if(ethErr)
  {
    lcd.printf("Error %d in setup.\n", ethErr);
    pc.printf("Error %d in setup.\r\n", ethErr);
    return -1;
  }
  wdt.kick();
  
  // Set-UP GSM Modem
  
  pc.printf("Setting up GSM Modem\r\n");
  lcd.locate(0,0);
  lcd.printf("GSM Modem Setup");
  wait(1);
  
  gsm.printf("AT\r\n");                     //Check Connection
  wait(0.5);
  messageProcess();                         //Process incoming message

  gsm.printf("AT+CSMP=17,167,0,0\r\n");     //Set Text Parameters
  wait(0.5);
  messageProcess();                         //Process incoming message

  gsm.printf("AT+CSCA?\r\n");               //Check Service Center
  wait(0.5);
  messageProcess();                         //Process incoming message
  
  gsm.printf("AT+CMGF=1\r\n");              //Set format to Text Mode
  wait(0.5);
  messageProcess();                         //Process incoming message
  
  gsm.printf("AT+CNMI=1,1,0,0,0\r\n");      //Set the new messages indicator
  wait(0.5);
  messageProcess();                         //Process incoming message
  
  gsm.printf("AT+CSAS\r\n");                //Save the Current Setup, REGLED will light SOLID
  wait(3.0);
  messageProcess();                         //Process incoming message
  
  lcd.locate(0,0);
  lcd.printf("Setup OK        ");
  pc.printf("Setup Done\r\n");
  wait(1);
  wdt.kick();
  
  //Define RPC Controls
  //Base::add_rpc_class<DigitalOut>(p21);
  
  
  //Add RPC Handler
  svr.addHandler<SimpleHandler>("/");
  svr.addHandler<RPCHandler>("/rpc"); //Default handler
  pc.printf("Handlers installed\r\n");
  svr.bind(80);
  
  lcd.locate(0,0);
  lcd.printf("Listening...");
  pc.printf("Connection is live, listening on port 80\r\n");
  
  wdt.kick();
  //Connect to NIST and get time
  time_t ctTime;
  sync_time(); //sync time for the first time
  
  
  statusMessageAlert = 1;
  statusMessage = 1;
  
  
  pc.printf("Time was synced to NIST\r\n");
  wdt.kick();
  
  timeOrDateTimer.start();
  clockSyncTimer.start();
  Timer tm;
  t.start();
  tm.start();
  send_SMS_Timer.start();
  GSM_Buffer_Timer.start();

  while(true)
  {
    ctTime = time(NULL) - (TIMEZONE*60*60); //Update clock and adjust for timezone
    char buffer[32];
    
    if(statusMessageAlert){
        statusMessageInterruptTimer.start();
        statusMessageAlert = 0;
        statusMessageInterrupt = 1;
        }
    
    if(statusMessageInterrupt){     //Status Messages to be displayed where Date/Time
        lcd.locate(0,0);
        if(statusMessage==0){
            lcd.printf("System is OK    ");
            }
        else if(statusMessage==1){
            lcd.printf("Clock Sync..DONE");
            }
        else if(statusMessage==2){
            lcd.printf("Clock Sync..FAIL");
            }
        else if(statusMessage==3){
            lcd.printf("GSM Modem OK    ");
            }
        else if(statusMessage==4){
            lcd.printf("GSM Modem Error ");
            }
        else if(statusMessage==5){
            lcd.printf("Message Sent    ");
            }
        else if(statusMessage==6){
            lcd.printf("Message Received");
            }
        else if(statusMessage==7){              //SMS Send Failed, force auto re-send
            lcd.printf("Msg Send Error  ");
            }
        else if(statusMessage==8){
            lcd.printf("Msg Recv Error  ");
            }
        }
    
    else{
        if(timeOrDate){
            strftime(buffer, 32, "%X", localtime(&ctTime));
            lcd.locate(0,0);
            lcd.printf("%s (-%d:00)", buffer, TIMEZONE);
        }
        else{
            strftime(buffer, 32, "%a %b %d, %Y", localtime(&ctTime));
            lcd.locate(0,0);
            lcd.printf("%s", buffer);
        }
    }
    
    Net::poll();
    timeCount = t.read();
    
    //Timers
    
    if(timeCount > 0){
       heartBeat = !heartBeat;
       t.stop();
       t.reset();
       t.start();
       }
       
    if(timeOrDateTimer > 3){
       timeOrDate = !timeOrDate;
       timeOrDateTimer.stop();
       timeOrDateTimer.reset();
       timeOrDateTimer.start();
       }
       
    if(send_SMS_Timer > SMSinterval){
       statusMessage = 0;
       send_SMS();
       send_SMS_Timer.stop();
       send_SMS_Timer.reset();
       send_SMS_Timer.start();
       }
        
    if(clockSyncTimer > 3600){  //Re-Sync every hour
        sync_time();
        pc.printf("Time was synced to NIST\r\n");
        clockSyncTimer.stop();
        clockSyncTimer.reset();
        clockSyncTimer.start();
        statusMessageAlert = 1;
        statusMessage = 1;
        }
        
     if(GSM_Buffer_Timer > (25*SMSinterval)){
        gsm.printf("AT+CMGD= 1, 1\r\n");                            //Clears out entire buffer
        pc.printf("GSM Buffer Cleared\r\n");
        GSM_Buffer_Timer.stop();
        GSM_Buffer_Timer.reset();
        }
        
    if(statusMessageInterruptTimer > 2){
        statusMessageInterrupt = 0;
        statusMessageInterruptTimer.stop();
        statusMessageInterruptTimer.reset();
        }
        
    if (messageReceived) {      //Handle received messages
    messageProcess();
    statusMessageAlert = 1;
    statusMessage = 6;
    }
        
    wdt.kick();
  }
  
  return 0;
}