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

Committer:
Joseph Radford
Date:
Sun Apr 10 15:47:33 2016 +1000
Revision:
0:2df78a4443cd
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Joseph Radford 0:2df78a4443cd 1 #ifdef ENABLE_GPRS_TESTING
Joseph Radford 0:2df78a4443cd 2 #include "GprsHandler.h"
Joseph Radford 0:2df78a4443cd 3 #include "mbed.h"
Joseph Radford 0:2df78a4443cd 4 #include "config.h"
Joseph Radford 0:2df78a4443cd 5 #include "UsbComms.h"
Joseph Radford 0:2df78a4443cd 6 #include "circbuff.h"
Joseph Radford 0:2df78a4443cd 7 #define TX_GSM P1_27
Joseph Radford 0:2df78a4443cd 8 #define RX_GSM P1_26
Joseph Radford 0:2df78a4443cd 9
Joseph Radford 0:2df78a4443cd 10 // declare led3 to display GPRS handler state
Joseph Radford 0:2df78a4443cd 11 extern DigitalOut myled3;
Joseph Radford 0:2df78a4443cd 12
Joseph Radford 0:2df78a4443cd 13 /*
Joseph Radford 0:2df78a4443cd 14 * PINPWR to low on Q10 drives 3V3 to Q7, which drives Q5 to ground, which powers VBAT_900, with
Joseph Radford 0:2df78a4443cd 15 * either VCC_BUCK or VCC_BAT
Joseph Radford 0:2df78a4443cd 16 */
Joseph Radford 0:2df78a4443cd 17 #define PINPWR P1_2
Joseph Radford 0:2df78a4443cd 18 #define PINONOFF P1_7
Joseph Radford 0:2df78a4443cd 19
Joseph Radford 0:2df78a4443cd 20 #define REQ_SEND_SMS 0b00000001
Joseph Radford 0:2df78a4443cd 21
Joseph Radford 0:2df78a4443cd 22 #define USB_BUFF_SIZE 256
Joseph Radford 0:2df78a4443cd 23
Joseph Radford 0:2df78a4443cd 24 #define SIM900_SERIAL_TIMEOUT 10000
Joseph Radford 0:2df78a4443cd 25
Joseph Radford 0:2df78a4443cd 26 GprsHandler::GprsHandler(MyTimers * _timer, UsbComms *_usb) : AbstractHandler(_timer)
Joseph Radford 0:2df78a4443cd 27 {
Joseph Radford 0:2df78a4443cd 28 m_serial = new Serial(TX_GSM, RX_GSM); // create object for UART comms
Joseph Radford 0:2df78a4443cd 29 mode = gprs_Start; // initialise state machine
Joseph Radford 0:2df78a4443cd 30
Joseph Radford 0:2df78a4443cd 31 m_sim900_pwr = new DigitalOut(PINPWR); // create pin out for
Joseph Radford 0:2df78a4443cd 32 m_sim900_on = new DigitalOut(PINONOFF);
Joseph Radford 0:2df78a4443cd 33 m_reqReg = 0;
Joseph Radford 0:2df78a4443cd 34
Joseph Radford 0:2df78a4443cd 35 m_usb = _usb;
Joseph Radford 0:2df78a4443cd 36 m_rxBuff = new CircBuff(USB_BUFF_SIZE);
Joseph Radford 0:2df78a4443cd 37
Joseph Radford 0:2df78a4443cd 38 m_atReq = atreq_Test;
Joseph Radford 0:2df78a4443cd 39 }
Joseph Radford 0:2df78a4443cd 40
Joseph Radford 0:2df78a4443cd 41 GprsHandler::~GprsHandler()
Joseph Radford 0:2df78a4443cd 42 {
Joseph Radford 0:2df78a4443cd 43 // TODO Auto-generated destructor stub
Joseph Radford 0:2df78a4443cd 44 delete m_serial;
Joseph Radford 0:2df78a4443cd 45 delete m_rxBuff;
Joseph Radford 0:2df78a4443cd 46 delete m_sim900_pwr;
Joseph Radford 0:2df78a4443cd 47 delete m_sim900_on;
Joseph Radford 0:2df78a4443cd 48 }
Joseph Radford 0:2df78a4443cd 49
Joseph Radford 0:2df78a4443cd 50 void GprsHandler::run()
Joseph Radford 0:2df78a4443cd 51 {
Joseph Radford 0:2df78a4443cd 52 switch(mode)
Joseph Radford 0:2df78a4443cd 53 {
Joseph Radford 0:2df78a4443cd 54 case gprs_Start:
Joseph Radford 0:2df78a4443cd 55
Joseph Radford 0:2df78a4443cd 56 mode = gprs_PowerOff;
Joseph Radford 0:2df78a4443cd 57 break;
Joseph Radford 0:2df78a4443cd 58
Joseph Radford 0:2df78a4443cd 59
Joseph Radford 0:2df78a4443cd 60 // POWER HANDLERS
Joseph Radford 0:2df78a4443cd 61
Joseph Radford 0:2df78a4443cd 62 case gprs_PowerOff:
Joseph Radford 0:2df78a4443cd 63 m_sim900_pwr->write(1); // turn power supply off
Joseph Radford 0:2df78a4443cd 64 m_sim900_on->write(1);
Joseph Radford 0:2df78a4443cd 65 m_timer->SetTimer(MyTimers::tmr_GprsPower, 500); // wait to settle
Joseph Radford 0:2df78a4443cd 66 mode = gprs_PowerOffWait;
Joseph Radford 0:2df78a4443cd 67 break;
Joseph Radford 0:2df78a4443cd 68
Joseph Radford 0:2df78a4443cd 69 case gprs_PowerOffWait:
Joseph Radford 0:2df78a4443cd 70 if (!m_timer->GetTimer(MyTimers::tmr_GprsPower))
Joseph Radford 0:2df78a4443cd 71 {
Joseph Radford 0:2df78a4443cd 72 mode = gprs_PowerSupplyOn; // timer has elapsed
Joseph Radford 0:2df78a4443cd 73 }
Joseph Radford 0:2df78a4443cd 74 break;
Joseph Radford 0:2df78a4443cd 75
Joseph Radford 0:2df78a4443cd 76 case gprs_PowerSupplyOn:
Joseph Radford 0:2df78a4443cd 77 m_sim900_pwr->write(0); // turn power supply on
Joseph Radford 0:2df78a4443cd 78 m_sim900_on->write(0); // from the ref: "drive the PWRKEY to a low level for 1 second then release."
Joseph Radford 0:2df78a4443cd 79
Joseph Radford 0:2df78a4443cd 80
Joseph Radford 0:2df78a4443cd 81 m_timer->SetTimer(MyTimers::tmr_GprsPower, 1000); // wait for one second
Joseph Radford 0:2df78a4443cd 82 mode = gprs_PowerSupplyOnWait; // go to wait state
Joseph Radford 0:2df78a4443cd 83 break;
Joseph Radford 0:2df78a4443cd 84
Joseph Radford 0:2df78a4443cd 85 case gprs_PowerSupplyOnWait:
Joseph Radford 0:2df78a4443cd 86 if (!m_timer->GetTimer(MyTimers::tmr_GprsPower))
Joseph Radford 0:2df78a4443cd 87 {
Joseph Radford 0:2df78a4443cd 88 mode = gprs_PowerSwitchOn; // timer has elapsed
Joseph Radford 0:2df78a4443cd 89 }
Joseph Radford 0:2df78a4443cd 90 break;
Joseph Radford 0:2df78a4443cd 91
Joseph Radford 0:2df78a4443cd 92 case gprs_PowerSwitchOn:
Joseph Radford 0:2df78a4443cd 93 m_sim900_on->write(1); // release power key
Joseph Radford 0:2df78a4443cd 94 m_timer->SetTimer(MyTimers::tmr_GprsPower, 500); // wait to settle
Joseph Radford 0:2df78a4443cd 95 mode = gprs_PowerSwitchOnWait;
Joseph Radford 0:2df78a4443cd 96 break;
Joseph Radford 0:2df78a4443cd 97
Joseph Radford 0:2df78a4443cd 98 case gprs_PowerSwitchOnWait:
Joseph Radford 0:2df78a4443cd 99 if (!m_timer->GetTimer(MyTimers::tmr_GprsPower))
Joseph Radford 0:2df78a4443cd 100 {
Joseph Radford 0:2df78a4443cd 101 mode = gprs_CheckATReqs; // timer has elapsed
Joseph Radford 0:2df78a4443cd 102 }
Joseph Radford 0:2df78a4443cd 103 break;
Joseph Radford 0:2df78a4443cd 104
Joseph Radford 0:2df78a4443cd 105
Joseph Radford 0:2df78a4443cd 106 // REQUEST HANDLERS
Joseph Radford 0:2df78a4443cd 107
Joseph Radford 0:2df78a4443cd 108 case gprs_CheckATReqs:
Joseph Radford 0:2df78a4443cd 109 switch (m_atReq) {
Joseph Radford 0:2df78a4443cd 110 case atreq_Test:
Joseph Radford 0:2df78a4443cd 111 sprintf((char*)txBuf, "AT\r\n");
Joseph Radford 0:2df78a4443cd 112 txBufLen = 4;
Joseph Radford 0:2df78a4443cd 113 mode = gprs_PostTx;
Joseph Radford 0:2df78a4443cd 114 break;
Joseph Radford 0:2df78a4443cd 115
Joseph Radford 0:2df78a4443cd 116 case atreq_CheckSMS:
Joseph Radford 0:2df78a4443cd 117 sprintf((char*)txBuf, "AT+CMGL=\"ALL\"");
Joseph Radford 0:2df78a4443cd 118 txBufLen = 13;
Joseph Radford 0:2df78a4443cd 119 mode = gprs_PostTx;
Joseph Radford 0:2df78a4443cd 120 break;
Joseph Radford 0:2df78a4443cd 121
Joseph Radford 0:2df78a4443cd 122 default:
Joseph Radford 0:2df78a4443cd 123 m_atReq = atreq_Test;
Joseph Radford 0:2df78a4443cd 124 }
Joseph Radford 0:2df78a4443cd 125 break;
Joseph Radford 0:2df78a4443cd 126
Joseph Radford 0:2df78a4443cd 127
Joseph Radford 0:2df78a4443cd 128 // TX/RX HANDLERS
Joseph Radford 0:2df78a4443cd 129
Joseph Radford 0:2df78a4443cd 130 case gprs_PostTx:
Joseph Radford 0:2df78a4443cd 131 // use putc, other write functions in serial don't really seem to work
Joseph Radford 0:2df78a4443cd 132 for (int i = 0; i < txBufLen; i++) {
Joseph Radford 0:2df78a4443cd 133 m_serial->putc(txBuf[i]);
Joseph Radford 0:2df78a4443cd 134 }
Joseph Radford 0:2df78a4443cd 135
Joseph Radford 0:2df78a4443cd 136 // make sure buffer is null terminated before printing to USB
Joseph Radford 0:2df78a4443cd 137 txBuf[txBufLen+1] = 0;
Joseph Radford 0:2df78a4443cd 138 m_usb->setRequest(UsbComms::usbreq_PrintToTerminalTimestamp, txBuf);
Joseph Radford 0:2df78a4443cd 139
Joseph Radford 0:2df78a4443cd 140 // clear the buffer
Joseph Radford 0:2df78a4443cd 141 txBufLen = 0;
Joseph Radford 0:2df78a4443cd 142
Joseph Radford 0:2df78a4443cd 143 // set timeout
Joseph Radford 0:2df78a4443cd 144 m_timer->SetTimer(MyTimers::tmr_GprsRxTx, SIM900_SERIAL_TIMEOUT);
Joseph Radford 0:2df78a4443cd 145
Joseph Radford 0:2df78a4443cd 146 // wait for a response
Joseph Radford 0:2df78a4443cd 147 mode = gprs_WaitRx;
Joseph Radford 0:2df78a4443cd 148 break;
Joseph Radford 0:2df78a4443cd 149
Joseph Radford 0:2df78a4443cd 150 case gprs_WaitRx:
Joseph Radford 0:2df78a4443cd 151 if (m_timer->GetTimer(MyTimers::tmr_GprsRxTx))
Joseph Radford 0:2df78a4443cd 152 {
Joseph Radford 0:2df78a4443cd 153 // we have not timed out yet
Joseph Radford 0:2df78a4443cd 154 // we need a generic rx handler here.
Joseph Radford 0:2df78a4443cd 155 while (m_serial->readable())
Joseph Radford 0:2df78a4443cd 156 {
Joseph Radford 0:2df78a4443cd 157 char ch = m_serial->getc();
Joseph Radford 0:2df78a4443cd 158
Joseph Radford 0:2df78a4443cd 159 // save this to our rx circular buffer
Joseph Radford 0:2df78a4443cd 160 m_rxBuff->putc(ch);
Joseph Radford 0:2df78a4443cd 161
Joseph Radford 0:2df78a4443cd 162 mode = gprs_CheckRx;
Joseph Radford 0:2df78a4443cd 163 wait(0.1);
Joseph Radford 0:2df78a4443cd 164 }
Joseph Radford 0:2df78a4443cd 165 // we have not timed out, and have not got anything back yet
Joseph Radford 0:2df78a4443cd 166 // keep waiting in this state
Joseph Radford 0:2df78a4443cd 167 }
Joseph Radford 0:2df78a4443cd 168 else {
Joseph Radford 0:2df78a4443cd 169 m_usb->setRequest(UsbComms::usbreq_PrintToTerminalTimestamp, (char*)"SIM900 TIMEOUT!");
Joseph Radford 0:2df78a4443cd 170 mode = gprs_RxTimeout;
Joseph Radford 0:2df78a4443cd 171 }
Joseph Radford 0:2df78a4443cd 172 break;
Joseph Radford 0:2df78a4443cd 173
Joseph Radford 0:2df78a4443cd 174 case gprs_CheckRx:
Joseph Radford 0:2df78a4443cd 175 if (m_rxBuff->dataAvailable()) {
Joseph Radford 0:2df78a4443cd 176
Joseph Radford 0:2df78a4443cd 177 // read out
Joseph Radford 0:2df78a4443cd 178 unsigned char s[50];
Joseph Radford 0:2df78a4443cd 179 uint16_t len = m_rxBuff->read(s, 50);
Joseph Radford 0:2df78a4443cd 180
Joseph Radford 0:2df78a4443cd 181 // write to USB
Joseph Radford 0:2df78a4443cd 182 m_usb->setRequest(UsbComms::usbreq_PrintToTerminalTimestamp, s);
Joseph Radford 0:2df78a4443cd 183
Joseph Radford 0:2df78a4443cd 184 // process the reply
Joseph Radford 0:2df78a4443cd 185 switch(m_atReq) {
Joseph Radford 0:2df78a4443cd 186 case atreq_Test:
Joseph Radford 0:2df78a4443cd 187 // should have just gotten an ok back
Joseph Radford 0:2df78a4443cd 188 bool bOk = false;
Joseph Radford 0:2df78a4443cd 189 for (int i = 0; i < (len - 1); i++) {
Joseph Radford 0:2df78a4443cd 190 if ((s[i] == 'O') && (s[i+1] == 'K')) {
Joseph Radford 0:2df78a4443cd 191 bOk = true;
Joseph Radford 0:2df78a4443cd 192 }
Joseph Radford 0:2df78a4443cd 193 }
Joseph Radford 0:2df78a4443cd 194
Joseph Radford 0:2df78a4443cd 195 if (bOk) {
Joseph Radford 0:2df78a4443cd 196 myled3 = 1;
Joseph Radford 0:2df78a4443cd 197 // so we know that comms are definitely OK.
Joseph Radford 0:2df78a4443cd 198 // now check to see what requests need to get fulfilled
Joseph Radford 0:2df78a4443cd 199
Joseph Radford 0:2df78a4443cd 200 if (m_reqReg&REQ_SEND_SMS) {
Joseph Radford 0:2df78a4443cd 201 // we want to check what sms is
Joseph Radford 0:2df78a4443cd 202 m_atReq = atreq_SendSMS;
Joseph Radford 0:2df78a4443cd 203
Joseph Radford 0:2df78a4443cd 204 m_reqReg &= ~REQ_SEND_SMS;
Joseph Radford 0:2df78a4443cd 205 }
Joseph Radford 0:2df78a4443cd 206 else {
Joseph Radford 0:2df78a4443cd 207 // no requests, but see if there are any received SMSs
Joseph Radford 0:2df78a4443cd 208 m_atReq = atreq_CheckSMS;
Joseph Radford 0:2df78a4443cd 209 }
Joseph Radford 0:2df78a4443cd 210 }
Joseph Radford 0:2df78a4443cd 211 else {
Joseph Radford 0:2df78a4443cd 212 // did not get the reply we were hoping for.
Joseph Radford 0:2df78a4443cd 213 }
Joseph Radford 0:2df78a4443cd 214 break;
Joseph Radford 0:2df78a4443cd 215
Joseph Radford 0:2df78a4443cd 216 default:
Joseph Radford 0:2df78a4443cd 217 // todo: handle replies for checking/sending SMSs
Joseph Radford 0:2df78a4443cd 218 m_atReq = atreq_Test;
Joseph Radford 0:2df78a4443cd 219 break;
Joseph Radford 0:2df78a4443cd 220 }
Joseph Radford 0:2df78a4443cd 221 }
Joseph Radford 0:2df78a4443cd 222 else {
Joseph Radford 0:2df78a4443cd 223
Joseph Radford 0:2df78a4443cd 224 }
Joseph Radford 0:2df78a4443cd 225 m_timer->SetTimer(MyTimers::tmr_GprsRxTx, 2000);
Joseph Radford 0:2df78a4443cd 226 // now that we're done here, go check what needs to get sent to the SIM900 next
Joseph Radford 0:2df78a4443cd 227 mode = gprs_WaitUntilNextRequest;
Joseph Radford 0:2df78a4443cd 228 break;
Joseph Radford 0:2df78a4443cd 229
Joseph Radford 0:2df78a4443cd 230 case gprs_WaitUntilNextRequest:
Joseph Radford 0:2df78a4443cd 231 if (!m_timer->GetTimer(MyTimers::tmr_GprsRxTx)) {
Joseph Radford 0:2df78a4443cd 232 mode = gprs_CheckATReqs;
Joseph Radford 0:2df78a4443cd 233 }
Joseph Radford 0:2df78a4443cd 234 break;
Joseph Radford 0:2df78a4443cd 235 case gprs_RxTimeout:
Joseph Radford 0:2df78a4443cd 236 case gprs_RxError:
Joseph Radford 0:2df78a4443cd 237 default:
Joseph Radford 0:2df78a4443cd 238 mode = gprs_Start;
Joseph Radford 0:2df78a4443cd 239 break;
Joseph Radford 0:2df78a4443cd 240
Joseph Radford 0:2df78a4443cd 241
Joseph Radford 0:2df78a4443cd 242 }
Joseph Radford 0:2df78a4443cd 243 }
Joseph Radford 0:2df78a4443cd 244
Joseph Radford 0:2df78a4443cd 245 void GprsHandler::setRequest(int request, void *data)
Joseph Radford 0:2df78a4443cd 246 {
Joseph Radford 0:2df78a4443cd 247 m_lastRequest = (request_t)request;
Joseph Radford 0:2df78a4443cd 248 switch(request) {
Joseph Radford 0:2df78a4443cd 249 case gprsreq_SmsSend:
Joseph Radford 0:2df78a4443cd 250 GprsRequest *req = (GprsRequest*)data;
Joseph Radford 0:2df78a4443cd 251
Joseph Radford 0:2df78a4443cd 252 // make a copy
Joseph Radford 0:2df78a4443cd 253 m_lastMessage = *req; // there are strings, do i have to copy these manually?
Joseph Radford 0:2df78a4443cd 254
Joseph Radford 0:2df78a4443cd 255 // set the request
Joseph Radford 0:2df78a4443cd 256 m_reqReg |= REQ_SEND_SMS;
Joseph Radford 0:2df78a4443cd 257 break;
Joseph Radford 0:2df78a4443cd 258 }
Joseph Radford 0:2df78a4443cd 259 }
Joseph Radford 0:2df78a4443cd 260 #endif