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
GprsHandler.cpp
00001 #ifdef ENABLE_GPRS_TESTING 00002 #include "GprsHandler.h" 00003 #include "mbed.h" 00004 #include "config.h" 00005 #include "UsbComms.h" 00006 #include "circbuff.h" 00007 #define TX_GSM P1_27 00008 #define RX_GSM P1_26 00009 00010 // declare led3 to display GPRS handler state 00011 extern DigitalOut myled3; 00012 00013 /* 00014 * PINPWR to low on Q10 drives 3V3 to Q7, which drives Q5 to ground, which powers VBAT_900, with 00015 * either VCC_BUCK or VCC_BAT 00016 */ 00017 #define PINPWR P1_2 00018 #define PINONOFF P1_7 00019 00020 #define REQ_SEND_SMS 0b00000001 00021 00022 #define USB_BUFF_SIZE 256 00023 00024 #define SIM900_SERIAL_TIMEOUT 10000 00025 00026 GprsHandler::GprsHandler(MyTimers * _timer, UsbComms *_usb) : AbstractHandler(_timer) 00027 { 00028 m_serial = new Serial(TX_GSM, RX_GSM); // create object for UART comms 00029 mode = gprs_Start; // initialise state machine 00030 00031 m_sim900_pwr = new DigitalOut(PINPWR); // create pin out for 00032 m_sim900_on = new DigitalOut(PINONOFF); 00033 m_reqReg = 0; 00034 00035 m_usb = _usb; 00036 m_rxBuff = new CircBuff(USB_BUFF_SIZE); 00037 00038 m_atReq = atreq_Test; 00039 } 00040 00041 GprsHandler::~GprsHandler() 00042 { 00043 // TODO Auto-generated destructor stub 00044 delete m_serial; 00045 delete m_rxBuff; 00046 delete m_sim900_pwr; 00047 delete m_sim900_on; 00048 } 00049 00050 void GprsHandler::run() 00051 { 00052 switch(mode) 00053 { 00054 case gprs_Start: 00055 00056 mode = gprs_PowerOff; 00057 break; 00058 00059 00060 // POWER HANDLERS 00061 00062 case gprs_PowerOff: 00063 m_sim900_pwr->write(1); // turn power supply off 00064 m_sim900_on->write(1); 00065 m_timer->SetTimer(MyTimers::tmr_GprsPower, 500); // wait to settle 00066 mode = gprs_PowerOffWait; 00067 break; 00068 00069 case gprs_PowerOffWait: 00070 if (!m_timer->GetTimer(MyTimers::tmr_GprsPower)) 00071 { 00072 mode = gprs_PowerSupplyOn; // timer has elapsed 00073 } 00074 break; 00075 00076 case gprs_PowerSupplyOn: 00077 m_sim900_pwr->write(0); // turn power supply on 00078 m_sim900_on->write(0); // from the ref: "drive the PWRKEY to a low level for 1 second then release." 00079 00080 00081 m_timer->SetTimer(MyTimers::tmr_GprsPower, 1000); // wait for one second 00082 mode = gprs_PowerSupplyOnWait; // go to wait state 00083 break; 00084 00085 case gprs_PowerSupplyOnWait: 00086 if (!m_timer->GetTimer(MyTimers::tmr_GprsPower)) 00087 { 00088 mode = gprs_PowerSwitchOn; // timer has elapsed 00089 } 00090 break; 00091 00092 case gprs_PowerSwitchOn: 00093 m_sim900_on->write(1); // release power key 00094 m_timer->SetTimer(MyTimers::tmr_GprsPower, 500); // wait to settle 00095 mode = gprs_PowerSwitchOnWait; 00096 break; 00097 00098 case gprs_PowerSwitchOnWait: 00099 if (!m_timer->GetTimer(MyTimers::tmr_GprsPower)) 00100 { 00101 mode = gprs_CheckATReqs; // timer has elapsed 00102 } 00103 break; 00104 00105 00106 // REQUEST HANDLERS 00107 00108 case gprs_CheckATReqs: 00109 switch (m_atReq) { 00110 case atreq_Test: 00111 sprintf((char*)txBuf, "AT\r\n"); 00112 txBufLen = 4; 00113 mode = gprs_PostTx; 00114 break; 00115 00116 case atreq_CheckSMS: 00117 sprintf((char*)txBuf, "AT+CMGL=\"ALL\""); 00118 txBufLen = 13; 00119 mode = gprs_PostTx; 00120 break; 00121 00122 default: 00123 m_atReq = atreq_Test; 00124 } 00125 break; 00126 00127 00128 // TX/RX HANDLERS 00129 00130 case gprs_PostTx: 00131 // use putc, other write functions in serial don't really seem to work 00132 for (int i = 0; i < txBufLen; i++) { 00133 m_serial->putc(txBuf[i]); 00134 } 00135 00136 // make sure buffer is null terminated before printing to USB 00137 txBuf[txBufLen+1] = 0; 00138 m_usb->setRequest(UsbComms::usbreq_PrintToTerminalTimestamp, txBuf); 00139 00140 // clear the buffer 00141 txBufLen = 0; 00142 00143 // set timeout 00144 m_timer->SetTimer(MyTimers::tmr_GprsRxTx, SIM900_SERIAL_TIMEOUT); 00145 00146 // wait for a response 00147 mode = gprs_WaitRx; 00148 break; 00149 00150 case gprs_WaitRx: 00151 if (m_timer->GetTimer(MyTimers::tmr_GprsRxTx)) 00152 { 00153 // we have not timed out yet 00154 // we need a generic rx handler here. 00155 while (m_serial->readable()) 00156 { 00157 char ch = m_serial->getc(); 00158 00159 // save this to our rx circular buffer 00160 m_rxBuff->putc(ch); 00161 00162 mode = gprs_CheckRx; 00163 wait(0.1); 00164 } 00165 // we have not timed out, and have not got anything back yet 00166 // keep waiting in this state 00167 } 00168 else { 00169 m_usb->setRequest(UsbComms::usbreq_PrintToTerminalTimestamp, (char*)"SIM900 TIMEOUT!"); 00170 mode = gprs_RxTimeout; 00171 } 00172 break; 00173 00174 case gprs_CheckRx: 00175 if (m_rxBuff->dataAvailable()) { 00176 00177 // read out 00178 unsigned char s[50]; 00179 uint16_t len = m_rxBuff->read(s, 50); 00180 00181 // write to USB 00182 m_usb->setRequest(UsbComms::usbreq_PrintToTerminalTimestamp, s); 00183 00184 // process the reply 00185 switch(m_atReq) { 00186 case atreq_Test: 00187 // should have just gotten an ok back 00188 bool bOk = false; 00189 for (int i = 0; i < (len - 1); i++) { 00190 if ((s[i] == 'O') && (s[i+1] == 'K')) { 00191 bOk = true; 00192 } 00193 } 00194 00195 if (bOk) { 00196 myled3 = 1; 00197 // so we know that comms are definitely OK. 00198 // now check to see what requests need to get fulfilled 00199 00200 if (m_reqReg&REQ_SEND_SMS) { 00201 // we want to check what sms is 00202 m_atReq = atreq_SendSMS; 00203 00204 m_reqReg &= ~REQ_SEND_SMS; 00205 } 00206 else { 00207 // no requests, but see if there are any received SMSs 00208 m_atReq = atreq_CheckSMS; 00209 } 00210 } 00211 else { 00212 // did not get the reply we were hoping for. 00213 } 00214 break; 00215 00216 default: 00217 // todo: handle replies for checking/sending SMSs 00218 m_atReq = atreq_Test; 00219 break; 00220 } 00221 } 00222 else { 00223 00224 } 00225 m_timer->SetTimer(MyTimers::tmr_GprsRxTx, 2000); 00226 // now that we're done here, go check what needs to get sent to the SIM900 next 00227 mode = gprs_WaitUntilNextRequest; 00228 break; 00229 00230 case gprs_WaitUntilNextRequest: 00231 if (!m_timer->GetTimer(MyTimers::tmr_GprsRxTx)) { 00232 mode = gprs_CheckATReqs; 00233 } 00234 break; 00235 case gprs_RxTimeout: 00236 case gprs_RxError: 00237 default: 00238 mode = gprs_Start; 00239 break; 00240 00241 00242 } 00243 } 00244 00245 void GprsHandler::setRequest(int request, void *data) 00246 { 00247 m_lastRequest = (request_t )request; 00248 switch(request) { 00249 case gprsreq_SmsSend: 00250 GprsRequest *req = (GprsRequest*)data; 00251 00252 // make a copy 00253 m_lastMessage = *req; // there are strings, do i have to copy these manually? 00254 00255 // set the request 00256 m_reqReg |= REQ_SEND_SMS; 00257 break; 00258 } 00259 } 00260 #endif
Generated on Tue Jul 12 2022 23:07:44 by 1.7.2