A simple WIP that logs data from a Grove sensor, and can send and receive information over USB and SMS.
Dependencies: DHT DS_1337 SDFileSystem USBDevice mbed
Handlers/GprsHandler.cpp
- Committer:
- Joseph Radford
- Date:
- 2016-04-10
- Revision:
- 0:2df78a4443cd
File content as of revision 0:2df78a4443cd:
#ifdef ENABLE_GPRS_TESTING #include "GprsHandler.h" #include "mbed.h" #include "config.h" #include "UsbComms.h" #include "circbuff.h" #define TX_GSM P1_27 #define RX_GSM P1_26 // declare led3 to display GPRS handler state extern DigitalOut myled3; /* * PINPWR to low on Q10 drives 3V3 to Q7, which drives Q5 to ground, which powers VBAT_900, with * either VCC_BUCK or VCC_BAT */ #define PINPWR P1_2 #define PINONOFF P1_7 #define REQ_SEND_SMS 0b00000001 #define USB_BUFF_SIZE 256 #define SIM900_SERIAL_TIMEOUT 10000 GprsHandler::GprsHandler(MyTimers * _timer, UsbComms *_usb) : AbstractHandler(_timer) { m_serial = new Serial(TX_GSM, RX_GSM); // create object for UART comms mode = gprs_Start; // initialise state machine m_sim900_pwr = new DigitalOut(PINPWR); // create pin out for m_sim900_on = new DigitalOut(PINONOFF); m_reqReg = 0; m_usb = _usb; m_rxBuff = new CircBuff(USB_BUFF_SIZE); m_atReq = atreq_Test; } GprsHandler::~GprsHandler() { // TODO Auto-generated destructor stub delete m_serial; delete m_rxBuff; delete m_sim900_pwr; delete m_sim900_on; } void GprsHandler::run() { switch(mode) { case gprs_Start: mode = gprs_PowerOff; break; // POWER HANDLERS case gprs_PowerOff: m_sim900_pwr->write(1); // turn power supply off m_sim900_on->write(1); m_timer->SetTimer(MyTimers::tmr_GprsPower, 500); // wait to settle mode = gprs_PowerOffWait; break; case gprs_PowerOffWait: if (!m_timer->GetTimer(MyTimers::tmr_GprsPower)) { mode = gprs_PowerSupplyOn; // timer has elapsed } break; case gprs_PowerSupplyOn: m_sim900_pwr->write(0); // turn power supply on m_sim900_on->write(0); // from the ref: "drive the PWRKEY to a low level for 1 second then release." m_timer->SetTimer(MyTimers::tmr_GprsPower, 1000); // wait for one second mode = gprs_PowerSupplyOnWait; // go to wait state break; case gprs_PowerSupplyOnWait: if (!m_timer->GetTimer(MyTimers::tmr_GprsPower)) { mode = gprs_PowerSwitchOn; // timer has elapsed } break; case gprs_PowerSwitchOn: m_sim900_on->write(1); // release power key m_timer->SetTimer(MyTimers::tmr_GprsPower, 500); // wait to settle mode = gprs_PowerSwitchOnWait; break; case gprs_PowerSwitchOnWait: if (!m_timer->GetTimer(MyTimers::tmr_GprsPower)) { mode = gprs_CheckATReqs; // timer has elapsed } break; // REQUEST HANDLERS case gprs_CheckATReqs: switch (m_atReq) { case atreq_Test: sprintf((char*)txBuf, "AT\r\n"); txBufLen = 4; mode = gprs_PostTx; break; case atreq_CheckSMS: sprintf((char*)txBuf, "AT+CMGL=\"ALL\""); txBufLen = 13; mode = gprs_PostTx; break; default: m_atReq = atreq_Test; } break; // TX/RX HANDLERS case gprs_PostTx: // use putc, other write functions in serial don't really seem to work for (int i = 0; i < txBufLen; i++) { m_serial->putc(txBuf[i]); } // make sure buffer is null terminated before printing to USB txBuf[txBufLen+1] = 0; m_usb->setRequest(UsbComms::usbreq_PrintToTerminalTimestamp, txBuf); // clear the buffer txBufLen = 0; // set timeout m_timer->SetTimer(MyTimers::tmr_GprsRxTx, SIM900_SERIAL_TIMEOUT); // wait for a response mode = gprs_WaitRx; break; case gprs_WaitRx: if (m_timer->GetTimer(MyTimers::tmr_GprsRxTx)) { // we have not timed out yet // we need a generic rx handler here. while (m_serial->readable()) { char ch = m_serial->getc(); // save this to our rx circular buffer m_rxBuff->putc(ch); mode = gprs_CheckRx; wait(0.1); } // we have not timed out, and have not got anything back yet // keep waiting in this state } else { m_usb->setRequest(UsbComms::usbreq_PrintToTerminalTimestamp, (char*)"SIM900 TIMEOUT!"); mode = gprs_RxTimeout; } break; case gprs_CheckRx: if (m_rxBuff->dataAvailable()) { // read out unsigned char s[50]; uint16_t len = m_rxBuff->read(s, 50); // write to USB m_usb->setRequest(UsbComms::usbreq_PrintToTerminalTimestamp, s); // process the reply switch(m_atReq) { case atreq_Test: // should have just gotten an ok back bool bOk = false; for (int i = 0; i < (len - 1); i++) { if ((s[i] == 'O') && (s[i+1] == 'K')) { bOk = true; } } if (bOk) { myled3 = 1; // so we know that comms are definitely OK. // now check to see what requests need to get fulfilled if (m_reqReg&REQ_SEND_SMS) { // we want to check what sms is m_atReq = atreq_SendSMS; m_reqReg &= ~REQ_SEND_SMS; } else { // no requests, but see if there are any received SMSs m_atReq = atreq_CheckSMS; } } else { // did not get the reply we were hoping for. } break; default: // todo: handle replies for checking/sending SMSs m_atReq = atreq_Test; break; } } else { } m_timer->SetTimer(MyTimers::tmr_GprsRxTx, 2000); // now that we're done here, go check what needs to get sent to the SIM900 next mode = gprs_WaitUntilNextRequest; break; case gprs_WaitUntilNextRequest: if (!m_timer->GetTimer(MyTimers::tmr_GprsRxTx)) { mode = gprs_CheckATReqs; } break; case gprs_RxTimeout: case gprs_RxError: default: mode = gprs_Start; break; } } void GprsHandler::setRequest(int request, void *data) { m_lastRequest = (request_t)request; switch(request) { case gprsreq_SmsSend: GprsRequest *req = (GprsRequest*)data; // make a copy m_lastMessage = *req; // there are strings, do i have to copy these manually? // set the request m_reqReg |= REQ_SEND_SMS; break; } } #endif