SMS message display on LED Matrix board with printer option

Dependencies:   AdafruitThermalPrinter HT1632_LedMatrix VodafoneUSBModem mbed-rtos mbed

Committer:
SomeRandomBloke
Date:
Mon Jul 29 21:16:33 2013 +0000
Revision:
8:401c7a593dd0
Parent:
7:b46d5d98434a
nightly commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
SomeRandomBloke 0:9d29b886d41b 1 /**
SomeRandomBloke 0:9d29b886d41b 2 * Mbed SMS to Printer and LED Matrix Displays
SomeRandomBloke 0:9d29b886d41b 3 * Based on SMS example from VodafoneUSBModem library and
SomeRandomBloke 0:9d29b886d41b 4 * 3GReceiptPrinter app from Ashley Mills.
SomeRandomBloke 0:9d29b886d41b 5 *
SomeRandomBloke 0:9d29b886d41b 6 * Requires libraries:
SomeRandomBloke 0:9d29b886d41b 7 * AdafruitThermalPrinter - Port of Arduino library by Ashley Mills
SomeRandomBloke 0:9d29b886d41b 8 * VodafoneUSBModem - Driver for Vodafone K3370 Mobile Broadband dongle
SomeRandomBloke 0:9d29b886d41b 9 * HT1632_LedMatrix - LED Matrix library by Andrew Lindsay, port of Arduino library by Andrew Lindsay
SomeRandomBloke 0:9d29b886d41b 10 *
SomeRandomBloke 0:9d29b886d41b 11 * @author Andrew Lindsay
SomeRandomBloke 0:9d29b886d41b 12 *
SomeRandomBloke 0:9d29b886d41b 13 * @section LICENSE
SomeRandomBloke 0:9d29b886d41b 14 *
SomeRandomBloke 0:9d29b886d41b 15 * Copyright (c) 2012 Andrew Lindsay (andrew [at] thiseldo [dot] co [dot] uk)
SomeRandomBloke 0:9d29b886d41b 16 *
SomeRandomBloke 0:9d29b886d41b 17 * Permission is hereby granted, free of charge, to any person obtaining a copy
SomeRandomBloke 0:9d29b886d41b 18 * of this software and associated documentation files (the "Software"), to deal
SomeRandomBloke 0:9d29b886d41b 19 * in the Software without restriction, including without limitation the rights
SomeRandomBloke 0:9d29b886d41b 20 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
SomeRandomBloke 0:9d29b886d41b 21 * copies of the Software, and to permit persons to whom the Software is
SomeRandomBloke 0:9d29b886d41b 22 * furnished to do so, subject to the following conditions:
SomeRandomBloke 0:9d29b886d41b 23
SomeRandomBloke 0:9d29b886d41b 24 * The above copyright notice and this permission notice shall be included in
SomeRandomBloke 0:9d29b886d41b 25 * all copies or substantial portions of the Software.
SomeRandomBloke 0:9d29b886d41b 26 *
SomeRandomBloke 0:9d29b886d41b 27 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
SomeRandomBloke 0:9d29b886d41b 28 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
SomeRandomBloke 0:9d29b886d41b 29 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
SomeRandomBloke 0:9d29b886d41b 30 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
SomeRandomBloke 0:9d29b886d41b 31 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
SomeRandomBloke 0:9d29b886d41b 32 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
SomeRandomBloke 0:9d29b886d41b 33 * THE SOFTWARE.
SomeRandomBloke 0:9d29b886d41b 34 *
SomeRandomBloke 0:9d29b886d41b 35 * @section DESCRIPTION
SomeRandomBloke 0:9d29b886d41b 36 * Display received SMS on scrolling LED matrix with optional output to thermal printer.
SomeRandomBloke 0:9d29b886d41b 37 *
SomeRandomBloke 0:9d29b886d41b 38 * TODO: Still have issue with restarts when using printer.
SomeRandomBloke 0:9d29b886d41b 39 * mbed-rtos and serial problem?
SomeRandomBloke 2:787cbb491f8f 40 * Incoming queue for multiple messages, give each at least 60 to be displayed
SomeRandomBloke 0:9d29b886d41b 41 *
SomeRandomBloke 0:9d29b886d41b 42 */
SomeRandomBloke 0:9d29b886d41b 43
SomeRandomBloke 0:9d29b886d41b 44 #define USE_LED
SomeRandomBloke 2:787cbb491f8f 45 #undef USE_PRINTER
SomeRandomBloke 0:9d29b886d41b 46
SomeRandomBloke 0:9d29b886d41b 47 #include <ctype.h>
SomeRandomBloke 0:9d29b886d41b 48
SomeRandomBloke 0:9d29b886d41b 49 #include "mbed.h"
SomeRandomBloke 7:b46d5d98434a 50 //#include "beep.h"
SomeRandomBloke 0:9d29b886d41b 51 #include "VodafoneUSBModem.h"
SomeRandomBloke 7:b46d5d98434a 52 //#include "LinkMonitor.h"
SomeRandomBloke 0:9d29b886d41b 53
SomeRandomBloke 0:9d29b886d41b 54 #ifdef USE_LED
SomeRandomBloke 0:9d29b886d41b 55 #include "HT1632_LedMatrix.h"
SomeRandomBloke 0:9d29b886d41b 56 #endif
SomeRandomBloke 0:9d29b886d41b 57 #ifdef USE_PRINTER
SomeRandomBloke 0:9d29b886d41b 58 #include "AdafruitThermal.h"
SomeRandomBloke 0:9d29b886d41b 59 #endif
SomeRandomBloke 0:9d29b886d41b 60
SomeRandomBloke 7:b46d5d98434a 61 //#define DEBUG 1
SomeRandomBloke 0:9d29b886d41b 62
SomeRandomBloke 0:9d29b886d41b 63 #ifdef USE_LED
SomeRandomBloke 3:59038ad536ac 64 // Default scrolling message includes own number obtained using USSD request
SomeRandomBloke 1:243371cb92c8 65 #define INFO_MSG " Send a message to "
SomeRandomBloke 7:b46d5d98434a 66 //#define INFO_MSG " Welcome to the IoT London Showcase. Send a message to "
SomeRandomBloke 7:b46d5d98434a 67 //#define INFO_MSG " Welcome to the Reading Geek Night. Send a message to "
SomeRandomBloke 0:9d29b886d41b 68 #endif
SomeRandomBloke 0:9d29b886d41b 69
SomeRandomBloke 7:b46d5d98434a 70 #define BRIGHTNESS 10
SomeRandomBloke 7:b46d5d98434a 71
SomeRandomBloke 0:9d29b886d41b 72 // Vodafone USSD commands
SomeRandomBloke 0:9d29b886d41b 73 #define USSD_COMMAND_OWN_NUMBER "*#100#"
SomeRandomBloke 0:9d29b886d41b 74 #define USSD_COMMAND_BALANCE "*#134#"
SomeRandomBloke 0:9d29b886d41b 75 #define USSD_COMMAND_TIME "*#103#"
SomeRandomBloke 0:9d29b886d41b 76
SomeRandomBloke 0:9d29b886d41b 77 #ifdef DEBUG
SomeRandomBloke 0:9d29b886d41b 78 Serial debug_pc(USBTX, USBRX); // tx, rx
SomeRandomBloke 0:9d29b886d41b 79 #endif
SomeRandomBloke 0:9d29b886d41b 80
SomeRandomBloke 0:9d29b886d41b 81 #ifdef USE_PRINTER
SomeRandomBloke 0:9d29b886d41b 82 AdafruitThermal printer(p28,p27); // setup printer
SomeRandomBloke 0:9d29b886d41b 83 #endif
SomeRandomBloke 0:9d29b886d41b 84 // Define a maximum size for storage arrays, is 160 (SMS size) + a bit more.
SomeRandomBloke 0:9d29b886d41b 85 #define MAX_MSG_LENGTH 192
SomeRandomBloke 0:9d29b886d41b 86
SomeRandomBloke 0:9d29b886d41b 87 // Month list used in converting to integer for set_time
SomeRandomBloke 0:9d29b886d41b 88 char months[12][4] = {"JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC" };
SomeRandomBloke 0:9d29b886d41b 89
SomeRandomBloke 0:9d29b886d41b 90 #ifdef USE_LED
SomeRandomBloke 0:9d29b886d41b 91
SomeRandomBloke 0:9d29b886d41b 92 #define LED_MAX_DISPLAY_X 4
SomeRandomBloke 0:9d29b886d41b 93 #define LED_MAX_DISPLAY_Y 1
SomeRandomBloke 0:9d29b886d41b 94
SomeRandomBloke 7:b46d5d98434a 95
SomeRandomBloke 0:9d29b886d41b 96 // create object to control the LED Matrix
SomeRandomBloke 7:b46d5d98434a 97 HT1632_LedMatrix led = HT1632_LedMatrix(p7, p5, p19, p17, p18, p20); //, LED_MAX_DISPLAY_X,LED_MAX_DISPLAY_Y );
SomeRandomBloke 7:b46d5d98434a 98 //HT1632_LedMatrix led = HT1632_LedMatrix(p7, p5, p17, p18, p19, p20); //, LED_MAX_DISPLAY_X,LED_MAX_DISPLAY_Y );
SomeRandomBloke 0:9d29b886d41b 99 #define DISPDELAY 90
SomeRandomBloke 0:9d29b886d41b 100 #endif
SomeRandomBloke 0:9d29b886d41b 101
SomeRandomBloke 0:9d29b886d41b 102 // Message buffers. New message waiting to be displayed and current message being displayed
SomeRandomBloke 4:a364da55b42e 103 //#define MAX_NUM_MSGS 10
SomeRandomBloke 0:9d29b886d41b 104 static char cmdBuf[12];
SomeRandomBloke 0:9d29b886d41b 105 static char newMsgBuf[MAX_MSG_LENGTH];
SomeRandomBloke 4:a364da55b42e 106 static char msgBuf[MAX_MSG_LENGTH];
SomeRandomBloke 4:a364da55b42e 107 //static int currentMsg = 0;
SomeRandomBloke 4:a364da55b42e 108 //static int numberOfMsgs = 0;
SomeRandomBloke 4:a364da55b42e 109 static bool getNextMessage = true;
SomeRandomBloke 0:9d29b886d41b 110
SomeRandomBloke 0:9d29b886d41b 111 #ifdef USE_LED
SomeRandomBloke 1:243371cb92c8 112 static char ownNumber[20];
SomeRandomBloke 1:243371cb92c8 113
SomeRandomBloke 0:9d29b886d41b 114 int crtPos = 0;
SomeRandomBloke 0:9d29b886d41b 115 int msgx = 1; // position on message screen of current character, set to 1 to allow for first scroll
SomeRandomBloke 0:9d29b886d41b 116 bool resetMessage = false;
SomeRandomBloke 0:9d29b886d41b 117
SomeRandomBloke 0:9d29b886d41b 118 void matrixDemo( void );
SomeRandomBloke 0:9d29b886d41b 119 #endif
SomeRandomBloke 0:9d29b886d41b 120
SomeRandomBloke 7:b46d5d98434a 121 // Define object for buzzer to signal new message received
SomeRandomBloke 7:b46d5d98434a 122 //Beep buzzer(p21);
SomeRandomBloke 7:b46d5d98434a 123
SomeRandomBloke 0:9d29b886d41b 124 // Define the onboard LEDs to use as status indicators
SomeRandomBloke 0:9d29b886d41b 125 DigitalOut led1(LED1); // Activity
SomeRandomBloke 0:9d29b886d41b 126 DigitalOut led2(LED2); // Activity, alternates with led2
SomeRandomBloke 0:9d29b886d41b 127 DigitalOut led3(LED3); // SMS received, turns off after processed
SomeRandomBloke 2:787cbb491f8f 128 DigitalOut led4(LED4); // USSD request in progress
SomeRandomBloke 0:9d29b886d41b 129
SomeRandomBloke 0:9d29b886d41b 130 int threadRestartCount = 0;
SomeRandomBloke 0:9d29b886d41b 131
SomeRandomBloke 0:9d29b886d41b 132 // Convert string buffer to upper case, is destructive. Buffer will be changed.
SomeRandomBloke 0:9d29b886d41b 133 char* stoupper( char* s )
SomeRandomBloke 0:9d29b886d41b 134 {
SomeRandomBloke 0:9d29b886d41b 135 char* p = s;
SomeRandomBloke 0:9d29b886d41b 136 while (*p = toupper( *p )) p++;
SomeRandomBloke 0:9d29b886d41b 137 return s;
SomeRandomBloke 0:9d29b886d41b 138 }
SomeRandomBloke 0:9d29b886d41b 139
SomeRandomBloke 0:9d29b886d41b 140
SomeRandomBloke 0:9d29b886d41b 141 #ifdef USE_PRINTER
SomeRandomBloke 0:9d29b886d41b 142 void timestampMessage( char *msg )
SomeRandomBloke 0:9d29b886d41b 143 {
SomeRandomBloke 0:9d29b886d41b 144 char timebuf[50];
SomeRandomBloke 0:9d29b886d41b 145 // Print date/time, then message
SomeRandomBloke 0:9d29b886d41b 146 time_t seconds = time(NULL);
SomeRandomBloke 0:9d29b886d41b 147 strftime(timebuf, 50, "%d/%m/%Y %X\n", localtime(&seconds));
SomeRandomBloke 0:9d29b886d41b 148 printer.print(timebuf);
SomeRandomBloke 0:9d29b886d41b 149 printer.print(msg);
SomeRandomBloke 0:9d29b886d41b 150 // linefeed a couple of times
SomeRandomBloke 0:9d29b886d41b 151 printer.feed(3);
SomeRandomBloke 0:9d29b886d41b 152 }
SomeRandomBloke 0:9d29b886d41b 153 #endif
SomeRandomBloke 0:9d29b886d41b 154
SomeRandomBloke 0:9d29b886d41b 155 #ifdef USE_LED
SomeRandomBloke 0:9d29b886d41b 156 // Load a new message
SomeRandomBloke 4:a364da55b42e 157
SomeRandomBloke 4:a364da55b42e 158 void setNewMessage( char *newMsgStart )
SomeRandomBloke 0:9d29b886d41b 159 {
SomeRandomBloke 0:9d29b886d41b 160 strncpy( newMsgBuf, newMsgStart, MAX_MSG_LENGTH );
SomeRandomBloke 0:9d29b886d41b 161 resetMessage = true;
SomeRandomBloke 7:b46d5d98434a 162 // buzzer.beep(1000,0.5);
SomeRandomBloke 0:9d29b886d41b 163 }
SomeRandomBloke 2:787cbb491f8f 164
SomeRandomBloke 2:787cbb491f8f 165
SomeRandomBloke 2:787cbb491f8f 166 void resetMessageBuffers( )
SomeRandomBloke 2:787cbb491f8f 167 {
SomeRandomBloke 4:a364da55b42e 168 strcpy( msgBuf, " " );
SomeRandomBloke 4:a364da55b42e 169 newMsgBuf[0] = '\0';
SomeRandomBloke 2:787cbb491f8f 170 }
SomeRandomBloke 0:9d29b886d41b 171 #endif
SomeRandomBloke 0:9d29b886d41b 172
SomeRandomBloke 0:9d29b886d41b 173 void sendUSSDCommand( VodafoneUSBModem *_modem, char *ussdCommand, bool setScrolling )
SomeRandomBloke 0:9d29b886d41b 174 {
SomeRandomBloke 0:9d29b886d41b 175 led4 = 1;
SomeRandomBloke 0:9d29b886d41b 176 #ifdef DEBUG
SomeRandomBloke 0:9d29b886d41b 177 debug_pc.printf("Sending %s on USSD channel\n", ussdCommand);
SomeRandomBloke 0:9d29b886d41b 178 #endif
SomeRandomBloke 0:9d29b886d41b 179 int ret = _modem->sendUSSD(ussdCommand, newMsgBuf, MAX_MSG_LENGTH);
SomeRandomBloke 0:9d29b886d41b 180 // Check for correct response
SomeRandomBloke 0:9d29b886d41b 181 if(ret) {
SomeRandomBloke 0:9d29b886d41b 182 // Non 0 value indicates an error??
SomeRandomBloke 0:9d29b886d41b 183 #ifdef DEBUG
SomeRandomBloke 0:9d29b886d41b 184 debug_pc.printf("Send USSD command returned %d\n", ret);
SomeRandomBloke 0:9d29b886d41b 185 #endif
SomeRandomBloke 0:9d29b886d41b 186 led4 = 0;
SomeRandomBloke 0:9d29b886d41b 187 return;
SomeRandomBloke 0:9d29b886d41b 188 }
SomeRandomBloke 0:9d29b886d41b 189
SomeRandomBloke 0:9d29b886d41b 190 // Should only display message if one has been received.
SomeRandomBloke 0:9d29b886d41b 191 #ifdef DEBUG
SomeRandomBloke 0:9d29b886d41b 192 debug_pc.printf("Result of command: %s\n", newMsgBuf);
SomeRandomBloke 0:9d29b886d41b 193 #endif
SomeRandomBloke 0:9d29b886d41b 194
SomeRandomBloke 0:9d29b886d41b 195 led4 = 0;
SomeRandomBloke 0:9d29b886d41b 196
SomeRandomBloke 0:9d29b886d41b 197 #ifdef USE_LED
SomeRandomBloke 0:9d29b886d41b 198 resetMessage = setScrolling;
SomeRandomBloke 0:9d29b886d41b 199 #endif
SomeRandomBloke 0:9d29b886d41b 200 }
SomeRandomBloke 0:9d29b886d41b 201
SomeRandomBloke 0:9d29b886d41b 202 void setTime(VodafoneUSBModem *_modem )
SomeRandomBloke 0:9d29b886d41b 203 {
SomeRandomBloke 0:9d29b886d41b 204 char numBuf[10];
SomeRandomBloke 0:9d29b886d41b 205 // Set RTC using received message, format is DD-MMM-YYYY HH:MM
SomeRandomBloke 0:9d29b886d41b 206 // Month is in text name, e.g. NOV, time is using 24 hour clock.
SomeRandomBloke 0:9d29b886d41b 207 struct tm t;
SomeRandomBloke 0:9d29b886d41b 208 int retryCount = 3;
SomeRandomBloke 0:9d29b886d41b 209
SomeRandomBloke 0:9d29b886d41b 210 while( retryCount ) {
SomeRandomBloke 0:9d29b886d41b 211 sendUSSDCommand( _modem, USSD_COMMAND_TIME, false );
SomeRandomBloke 0:9d29b886d41b 212
SomeRandomBloke 0:9d29b886d41b 213 #ifdef DEBUG
SomeRandomBloke 0:9d29b886d41b 214 debug_pc.printf("Time received is %s\n", newMsgBuf);
SomeRandomBloke 0:9d29b886d41b 215 #endif
SomeRandomBloke 0:9d29b886d41b 216
SomeRandomBloke 0:9d29b886d41b 217 t.tm_sec = 0; // 0-59
SomeRandomBloke 0:9d29b886d41b 218 strncpy(numBuf, &newMsgBuf[15], 2 );
SomeRandomBloke 0:9d29b886d41b 219 t.tm_min = atoi(numBuf); // 0-59
SomeRandomBloke 0:9d29b886d41b 220 strncpy(numBuf, &newMsgBuf[12], 2 );
SomeRandomBloke 0:9d29b886d41b 221 t.tm_hour = atoi(numBuf); // 0-23
SomeRandomBloke 0:9d29b886d41b 222 strncpy(numBuf, &newMsgBuf[0], 2 );
SomeRandomBloke 0:9d29b886d41b 223 t.tm_mday = atoi(numBuf); // 1-31
SomeRandomBloke 0:9d29b886d41b 224 strncpy(numBuf, &newMsgBuf[3], 3 );
SomeRandomBloke 0:9d29b886d41b 225 t.tm_mon = 0; // 0-11
SomeRandomBloke 0:9d29b886d41b 226 for( int i=0; i<12; i++ ) {
SomeRandomBloke 0:9d29b886d41b 227 if( strncmp( months[i], numBuf, 3 ) == 0 ) {
SomeRandomBloke 0:9d29b886d41b 228 t.tm_mon = i; // 0-11
SomeRandomBloke 0:9d29b886d41b 229 break;
SomeRandomBloke 0:9d29b886d41b 230 }
SomeRandomBloke 0:9d29b886d41b 231 }
SomeRandomBloke 0:9d29b886d41b 232 strncpy(numBuf, &newMsgBuf[9], 2 );
SomeRandomBloke 0:9d29b886d41b 233 t.tm_year = 100 + atoi( numBuf ); // year since 1900
SomeRandomBloke 0:9d29b886d41b 234
SomeRandomBloke 0:9d29b886d41b 235 if( t.tm_year >110 ) {
SomeRandomBloke 0:9d29b886d41b 236 // convert to timestamp and display
SomeRandomBloke 0:9d29b886d41b 237 time_t seconds = mktime(&t);
SomeRandomBloke 0:9d29b886d41b 238 set_time( seconds );
SomeRandomBloke 0:9d29b886d41b 239 retryCount = 0; // No more retries, terminate while
SomeRandomBloke 0:9d29b886d41b 240 } else {
SomeRandomBloke 0:9d29b886d41b 241 // Failed to set time, decrement tries
SomeRandomBloke 0:9d29b886d41b 242 retryCount--;
SomeRandomBloke 0:9d29b886d41b 243 }
SomeRandomBloke 0:9d29b886d41b 244 }
SomeRandomBloke 0:9d29b886d41b 245 }
SomeRandomBloke 0:9d29b886d41b 246
SomeRandomBloke 1:243371cb92c8 247 void getOwnNumber(VodafoneUSBModem *_modem, char *numPtr )
SomeRandomBloke 1:243371cb92c8 248 {
SomeRandomBloke 1:243371cb92c8 249 int retryCount = 3;
SomeRandomBloke 1:243371cb92c8 250
SomeRandomBloke 1:243371cb92c8 251 while( retryCount ) {
SomeRandomBloke 1:243371cb92c8 252 sendUSSDCommand( _modem, USSD_COMMAND_OWN_NUMBER, false );
SomeRandomBloke 1:243371cb92c8 253
SomeRandomBloke 1:243371cb92c8 254 #ifdef DEBUG
SomeRandomBloke 1:243371cb92c8 255 debug_pc.printf("Own Number received %s\n", newMsgBuf);
SomeRandomBloke 1:243371cb92c8 256 #endif
SomeRandomBloke 2:787cbb491f8f 257 if( strlen(newMsgBuf) > 0 ) {
SomeRandomBloke 2:787cbb491f8f 258 // Save number in array pointed to be numPtr
SomeRandomBloke 2:787cbb491f8f 259 strncpy(ownNumber, newMsgBuf, strlen(newMsgBuf) );
SomeRandomBloke 2:787cbb491f8f 260 retryCount = 0;
SomeRandomBloke 2:787cbb491f8f 261 } else
SomeRandomBloke 1:243371cb92c8 262 retryCount--;
SomeRandomBloke 1:243371cb92c8 263 }
SomeRandomBloke 1:243371cb92c8 264 }
SomeRandomBloke 3:59038ad536ac 265
SomeRandomBloke 1:243371cb92c8 266
SomeRandomBloke 2:787cbb491f8f 267 char linkStateStr[6][13] = { "Unknown ", "Registering ", "Denied ", "No Signal ", "Home Network", "Roaming " };
SomeRandomBloke 2:787cbb491f8f 268 char bearerStr[6][5] = {"Unkn", "GSM ", "EDGE", "3G ", "HSPA", "LTE " };
SomeRandomBloke 0:9d29b886d41b 269
SomeRandomBloke 0:9d29b886d41b 270 void receiveSMS(void const*)
SomeRandomBloke 0:9d29b886d41b 271 {
SomeRandomBloke 0:9d29b886d41b 272 VodafoneUSBModem modem;
SomeRandomBloke 0:9d29b886d41b 273 time_t seconds = time(NULL);
SomeRandomBloke 3:59038ad536ac 274 int pRssi = 0;
SomeRandomBloke 3:59038ad536ac 275 LinkMonitor::REGISTRATION_STATE pRegistrationState;
SomeRandomBloke 3:59038ad536ac 276 LinkMonitor::BEARER pBearer;
SomeRandomBloke 0:9d29b886d41b 277
SomeRandomBloke 0:9d29b886d41b 278 threadRestartCount++;
SomeRandomBloke 0:9d29b886d41b 279
SomeRandomBloke 3:59038ad536ac 280 // Getting the link state seems to speed up startup of the library
SomeRandomBloke 7:b46d5d98434a 281 // Sometimes startup doesnt happen - need way to retry this
SomeRandomBloke 2:787cbb491f8f 282 modem.getLinkState( &pRssi,&pRegistrationState, &pBearer);
SomeRandomBloke 2:787cbb491f8f 283 #ifdef DEBUG
SomeRandomBloke 2:787cbb491f8f 284 debug_pc.printf("Link state Rssi: %d, Registration state %x Bearer %x\n",pRssi,pRegistrationState, pBearer);
SomeRandomBloke 2:787cbb491f8f 285 #endif
SomeRandomBloke 2:787cbb491f8f 286 sprintf(newMsgBuf, "Link State: %s on %s ", linkStateStr[pRegistrationState], bearerStr[pBearer] );
SomeRandomBloke 3:59038ad536ac 287
SomeRandomBloke 3:59038ad536ac 288 #ifdef USE_LED
SomeRandomBloke 4:a364da55b42e 289 setNewMessage( newMsgBuf );
SomeRandomBloke 3:59038ad536ac 290 #endif
SomeRandomBloke 3:59038ad536ac 291 #ifdef USE_PRINTER
SomeRandomBloke 3:59038ad536ac 292 timestampMessage( newMsgBuf );
SomeRandomBloke 3:59038ad536ac 293 #endif
SomeRandomBloke 0:9d29b886d41b 294
SomeRandomBloke 2:787cbb491f8f 295 Thread::wait(3000);
SomeRandomBloke 0:9d29b886d41b 296
SomeRandomBloke 3:59038ad536ac 297 // Get own number from the network
SomeRandomBloke 3:59038ad536ac 298 getOwnNumber( &modem, ownNumber );
SomeRandomBloke 1:243371cb92c8 299 #ifdef USE_LED
SomeRandomBloke 3:59038ad536ac 300 sprintf(newMsgBuf, "Own number %s", ownNumber );
SomeRandomBloke 4:a364da55b42e 301 setNewMessage( newMsgBuf );
SomeRandomBloke 1:243371cb92c8 302 #endif
SomeRandomBloke 1:243371cb92c8 303
SomeRandomBloke 0:9d29b886d41b 304 #ifdef USE_PRINTER
SomeRandomBloke 0:9d29b886d41b 305 // Check if time already set, if not then get it. Use year = 0 as test
SomeRandomBloke 0:9d29b886d41b 306 struct tm *t = localtime(&seconds);
SomeRandomBloke 3:59038ad536ac 307 if( t->tm_year == 0 )
SomeRandomBloke 0:9d29b886d41b 308 setTime( &modem );
SomeRandomBloke 0:9d29b886d41b 309
SomeRandomBloke 0:9d29b886d41b 310 sprintf(newMsgBuf, "Thread Start %d\r\n", threadRestartCount );
SomeRandomBloke 0:9d29b886d41b 311 timestampMessage( newMsgBuf );
SomeRandomBloke 0:9d29b886d41b 312 #endif
SomeRandomBloke 0:9d29b886d41b 313 #ifdef USE_LED
SomeRandomBloke 2:787cbb491f8f 314 //strcpy( &msgBuf[currentMsg][0], INFO_MSG );
SomeRandomBloke 1:243371cb92c8 315 sprintf(newMsgBuf, "%s %s ", INFO_MSG, ownNumber );
SomeRandomBloke 4:a364da55b42e 316 setNewMessage( newMsgBuf );
SomeRandomBloke 2:787cbb491f8f 317
SomeRandomBloke 0:9d29b886d41b 318 led.displayOn();
SomeRandomBloke 0:9d29b886d41b 319 #endif
SomeRandomBloke 0:9d29b886d41b 320 char num[17];
SomeRandomBloke 3:59038ad536ac 321 size_t smsCount;
SomeRandomBloke 3:59038ad536ac 322 getNextMessage = true;
SomeRandomBloke 0:9d29b886d41b 323
SomeRandomBloke 0:9d29b886d41b 324 while(true) {
SomeRandomBloke 3:59038ad536ac 325 if( modem.getSMCount(&smsCount) == OK ) {
SomeRandomBloke 3:59038ad536ac 326 if( smsCount > 0 && getNextMessage ) {
SomeRandomBloke 0:9d29b886d41b 327 led3 = 1;
SomeRandomBloke 3:59038ad536ac 328 getNextMessage = false;
SomeRandomBloke 0:9d29b886d41b 329 #ifdef DEBUG
SomeRandomBloke 0:9d29b886d41b 330 debug_pc.printf("%d SMS to read\n", smsCount);
SomeRandomBloke 0:9d29b886d41b 331 #endif
SomeRandomBloke 0:9d29b886d41b 332 if( modem.getSM(num, newMsgBuf, MAX_MSG_LENGTH) == OK ) {
SomeRandomBloke 0:9d29b886d41b 333 #ifdef DEBUG
SomeRandomBloke 0:9d29b886d41b 334 debug_pc.printf("%s : %s\n", num, newMsgBuf);
SomeRandomBloke 0:9d29b886d41b 335 #endif
SomeRandomBloke 0:9d29b886d41b 336 #ifdef USE_PRINTER
SomeRandomBloke 0:9d29b886d41b 337 // Print date/time, then message
SomeRandomBloke 0:9d29b886d41b 338 timestampMessage( newMsgBuf );
SomeRandomBloke 3:59038ad536ac 339 #ifndef USE_LED
SomeRandomBloke 3:59038ad536ac 340 // Force processing of next messages if only printer being used
SomeRandomBloke 3:59038ad536ac 341 // If LED display then update when displayed once
SomeRandomBloke 3:59038ad536ac 342 getNextMessage = true;
SomeRandomBloke 3:59038ad536ac 343 #endif
SomeRandomBloke 0:9d29b886d41b 344 #endif
SomeRandomBloke 0:9d29b886d41b 345 #ifdef USE_LED
SomeRandomBloke 0:9d29b886d41b 346 resetMessage = true;
SomeRandomBloke 0:9d29b886d41b 347 #endif
SomeRandomBloke 0:9d29b886d41b 348 strncpy( cmdBuf, newMsgBuf, 10 );
SomeRandomBloke 0:9d29b886d41b 349 stoupper( cmdBuf ); // This is a destructive function, original characters are uppercased
SomeRandomBloke 0:9d29b886d41b 350 if( strncmp( cmdBuf, "BALANCE", 7 ) == 0 ) {
SomeRandomBloke 0:9d29b886d41b 351 sendUSSDCommand( &modem, USSD_COMMAND_BALANCE, true );
SomeRandomBloke 0:9d29b886d41b 352 #ifdef USE_PRINTER
SomeRandomBloke 0:9d29b886d41b 353 timestampMessage( newMsgBuf );
SomeRandomBloke 0:9d29b886d41b 354 #endif
SomeRandomBloke 0:9d29b886d41b 355 #ifdef USE_LED
SomeRandomBloke 0:9d29b886d41b 356 resetMessage = true;
SomeRandomBloke 0:9d29b886d41b 357 } else if ( strncmp( cmdBuf, "INFO", 4 ) == 0 ) {
SomeRandomBloke 1:243371cb92c8 358 sprintf(newMsgBuf, "%s %s ", INFO_MSG, ownNumber );
SomeRandomBloke 4:a364da55b42e 359 setNewMessage( newMsgBuf );
SomeRandomBloke 0:9d29b886d41b 360 #endif
SomeRandomBloke 0:9d29b886d41b 361 // } else if ( strncmp( cmdBuf, "DEMO", 4 ) == 0 ) {
SomeRandomBloke 1:243371cb92c8 362 // matrixDemo();
SomeRandomBloke 1:243371cb92c8 363 // sprintf(newMsgBuf, "%s %s ", INFO_MSG, ownNumber );
SomeRandomBloke 4:a364da55b42e 364 // setNewMessage( newMsgBuf );
SomeRandomBloke 0:9d29b886d41b 365 #ifdef USE_LED
SomeRandomBloke 0:9d29b886d41b 366 } else if ( strncmp( cmdBuf, "CLEAR", 5 ) == 0 ) {
SomeRandomBloke 4:a364da55b42e 367 setNewMessage( " " );
SomeRandomBloke 0:9d29b886d41b 368 #endif
SomeRandomBloke 0:9d29b886d41b 369 }
SomeRandomBloke 0:9d29b886d41b 370 }
SomeRandomBloke 0:9d29b886d41b 371 }
SomeRandomBloke 0:9d29b886d41b 372 }
SomeRandomBloke 0:9d29b886d41b 373 Thread::wait(3000);
SomeRandomBloke 0:9d29b886d41b 374 led3 = 0;
SomeRandomBloke 0:9d29b886d41b 375 }
SomeRandomBloke 0:9d29b886d41b 376 }
SomeRandomBloke 0:9d29b886d41b 377
SomeRandomBloke 0:9d29b886d41b 378 #ifdef USE_LED
SomeRandomBloke 0:9d29b886d41b 379 void displayScrollingLine(void const*)
SomeRandomBloke 0:9d29b886d41b 380 {
SomeRandomBloke 0:9d29b886d41b 381 int y,xmax,ymax;
SomeRandomBloke 0:9d29b886d41b 382 led.getXYMax(&xmax,&ymax);
SomeRandomBloke 4:a364da55b42e 383 bool msgFinished = true;
SomeRandomBloke 0:9d29b886d41b 384
SomeRandomBloke 0:9d29b886d41b 385 while(true) {
SomeRandomBloke 0:9d29b886d41b 386 // shift the whole screen 6 times, one column at a time; making 1 character
SomeRandomBloke 4:a364da55b42e 387 if( strlen( &msgBuf[0] ) > 10 ) {
SomeRandomBloke 0:9d29b886d41b 388 for (int x=0; x < 6; x++) {
SomeRandomBloke 0:9d29b886d41b 389 led.scrollLeft(1, 1);
SomeRandomBloke 0:9d29b886d41b 390 msgx--;
SomeRandomBloke 3:59038ad536ac 391 if( msgx <= 0 ) {
SomeRandomBloke 3:59038ad536ac 392 msgFinished = true;
SomeRandomBloke 3:59038ad536ac 393 getNextMessage = true;
SomeRandomBloke 3:59038ad536ac 394 }
SomeRandomBloke 3:59038ad536ac 395
SomeRandomBloke 0:9d29b886d41b 396 // fit as much as we can on the available display space
SomeRandomBloke 0:9d29b886d41b 397
SomeRandomBloke 4:a364da55b42e 398 while (!led.putChar(msgx,0,msgBuf[crtPos])) { // zero return if it all fitted
SomeRandomBloke 0:9d29b886d41b 399 led.getXY(&msgx,&y);
SomeRandomBloke 0:9d29b886d41b 400 crtPos++; // we got all of the character on!!
SomeRandomBloke 4:a364da55b42e 401 if (crtPos >= strlen(msgBuf)) {
SomeRandomBloke 0:9d29b886d41b 402 crtPos = 0;
SomeRandomBloke 0:9d29b886d41b 403 }
SomeRandomBloke 0:9d29b886d41b 404 }
SomeRandomBloke 0:9d29b886d41b 405 led.putShadowRam();
SomeRandomBloke 0:9d29b886d41b 406 Thread::wait(DISPDELAY);
SomeRandomBloke 0:9d29b886d41b 407 }
SomeRandomBloke 5:a2c0e95f9a0b 408 } else {
SomeRandomBloke 5:a2c0e95f9a0b 409 getNextMessage = true;
SomeRandomBloke 5:a2c0e95f9a0b 410 msgFinished = true;
SomeRandomBloke 0:9d29b886d41b 411 }
SomeRandomBloke 3:59038ad536ac 412 // Look for a new message being available and current message has been displayed
SomeRandomBloke 3:59038ad536ac 413
SomeRandomBloke 0:9d29b886d41b 414 // TODO add minimum interval between message changes, e.g. 60s
SomeRandomBloke 3:59038ad536ac 415 if( resetMessage && msgFinished ) {
SomeRandomBloke 0:9d29b886d41b 416 led.clear();
SomeRandomBloke 7:b46d5d98434a 417 led.setBrightness(BRIGHTNESS);
SomeRandomBloke 0:9d29b886d41b 418 crtPos = 0;
SomeRandomBloke 0:9d29b886d41b 419 msgx = 1;
SomeRandomBloke 3:59038ad536ac 420 msgFinished = false;
SomeRandomBloke 2:787cbb491f8f 421
SomeRandomBloke 4:a364da55b42e 422 strncpy( msgBuf, newMsgBuf, MAX_MSG_LENGTH );
SomeRandomBloke 4:a364da55b42e 423 if( strlen( msgBuf ) > 10 ) {
SomeRandomBloke 4:a364da55b42e 424 strcat( msgBuf, " ");
SomeRandomBloke 0:9d29b886d41b 425 } else {
SomeRandomBloke 4:a364da55b42e 426 led.putString(0,0, msgBuf);
SomeRandomBloke 0:9d29b886d41b 427 }
SomeRandomBloke 0:9d29b886d41b 428 resetMessage = false;
SomeRandomBloke 0:9d29b886d41b 429 }
SomeRandomBloke 0:9d29b886d41b 430 }
SomeRandomBloke 0:9d29b886d41b 431 }
SomeRandomBloke 0:9d29b886d41b 432
SomeRandomBloke 0:9d29b886d41b 433
SomeRandomBloke 3:59038ad536ac 434 /*
SomeRandomBloke 0:9d29b886d41b 435 void matrixDemo( void )
SomeRandomBloke 0:9d29b886d41b 436 {
SomeRandomBloke 0:9d29b886d41b 437 int xmax,ymax;
SomeRandomBloke 0:9d29b886d41b 438 led.getXYMax(&xmax,&ymax);
SomeRandomBloke 0:9d29b886d41b 439 led.clear();
SomeRandomBloke 0:9d29b886d41b 440 for( int n=0; n<3; n++ ) {
SomeRandomBloke 0:9d29b886d41b 441 for( int i=0; i<8; i++ ) {
SomeRandomBloke 0:9d29b886d41b 442 led.drawRectangle(i,i,xmax-i,ymax-i, 1);
SomeRandomBloke 0:9d29b886d41b 443 wait(0.05);
SomeRandomBloke 0:9d29b886d41b 444 }
SomeRandomBloke 0:9d29b886d41b 445 for( int i=7; i>=0; i-- ) {
SomeRandomBloke 0:9d29b886d41b 446 led.drawRectangle(i,i,xmax-i,ymax-i, 0);
SomeRandomBloke 0:9d29b886d41b 447 wait(0.05);
SomeRandomBloke 0:9d29b886d41b 448 }
SomeRandomBloke 0:9d29b886d41b 449 }
SomeRandomBloke 0:9d29b886d41b 450 led.clear();
SomeRandomBloke 0:9d29b886d41b 451 for( int n=0; n<3; n++ ) {
SomeRandomBloke 0:9d29b886d41b 452 for(int i=0; i<(xmax/2); i++) {
SomeRandomBloke 0:9d29b886d41b 453 led.drawCircle((xmax/2), 7, i, 1 );
SomeRandomBloke 0:9d29b886d41b 454 wait( 0.05 );
SomeRandomBloke 0:9d29b886d41b 455 }
SomeRandomBloke 0:9d29b886d41b 456 for(int i=(xmax/2); i>=0; i--) {
SomeRandomBloke 0:9d29b886d41b 457 led.drawCircle((xmax/2), 7, i, 0 );
SomeRandomBloke 0:9d29b886d41b 458 wait( 0.05 );
SomeRandomBloke 0:9d29b886d41b 459 }
SomeRandomBloke 0:9d29b886d41b 460 }
SomeRandomBloke 0:9d29b886d41b 461 wait(2);
SomeRandomBloke 0:9d29b886d41b 462
SomeRandomBloke 0:9d29b886d41b 463 led.clear();
SomeRandomBloke 2:787cbb491f8f 464 led.init(LED_MAX_DISPLAY_X,LED_MAX_DISPLAY_Y);
SomeRandomBloke 0:9d29b886d41b 465 }
SomeRandomBloke 3:59038ad536ac 466 */
SomeRandomBloke 0:9d29b886d41b 467
SomeRandomBloke 0:9d29b886d41b 468 void showTime()
SomeRandomBloke 0:9d29b886d41b 469 {
SomeRandomBloke 0:9d29b886d41b 470 time_t seconds = time(NULL);
SomeRandomBloke 0:9d29b886d41b 471 char timebuf[20];
SomeRandomBloke 0:9d29b886d41b 472 strftime(timebuf, 20, "%X ", localtime(&seconds));
SomeRandomBloke 0:9d29b886d41b 473 led.putString(12,8, timebuf );
SomeRandomBloke 0:9d29b886d41b 474 }
SomeRandomBloke 0:9d29b886d41b 475
SomeRandomBloke 0:9d29b886d41b 476 void showDate()
SomeRandomBloke 0:9d29b886d41b 477 {
SomeRandomBloke 0:9d29b886d41b 478 time_t seconds = time(NULL);
SomeRandomBloke 0:9d29b886d41b 479 char timebuf[20];
SomeRandomBloke 0:9d29b886d41b 480 strftime(timebuf, 20, "%d/%m/%Y ", localtime(&seconds));
SomeRandomBloke 0:9d29b886d41b 481 led.putString(4,8, timebuf );
SomeRandomBloke 0:9d29b886d41b 482 }
SomeRandomBloke 0:9d29b886d41b 483 #endif
SomeRandomBloke 0:9d29b886d41b 484
SomeRandomBloke 0:9d29b886d41b 485
SomeRandomBloke 0:9d29b886d41b 486 int main()
SomeRandomBloke 0:9d29b886d41b 487 {
SomeRandomBloke 0:9d29b886d41b 488 #ifdef DEBUG
SomeRandomBloke 0:9d29b886d41b 489 debug_pc.baud(57600);
SomeRandomBloke 0:9d29b886d41b 490 #ifdef USE_LED
SomeRandomBloke 0:9d29b886d41b 491 debug_pc.printf("SMS to LED Matrix display\n");
SomeRandomBloke 0:9d29b886d41b 492 #endif
SomeRandomBloke 0:9d29b886d41b 493 #ifdef USE_PRINTER
SomeRandomBloke 0:9d29b886d41b 494 printer.begin();
SomeRandomBloke 0:9d29b886d41b 495 debug_pc.printf("SMS To Printer\n");
SomeRandomBloke 0:9d29b886d41b 496 timestampMessage("SMS To Printer Starting");
SomeRandomBloke 0:9d29b886d41b 497 #endif
SomeRandomBloke 0:9d29b886d41b 498 #endif
SomeRandomBloke 0:9d29b886d41b 499 #ifdef USE_LED
SomeRandomBloke 0:9d29b886d41b 500 int displayCount = 10;
SomeRandomBloke 0:9d29b886d41b 501 bool displayTime = true;
SomeRandomBloke 0:9d29b886d41b 502
SomeRandomBloke 2:787cbb491f8f 503 led.init(LED_MAX_DISPLAY_X,LED_MAX_DISPLAY_Y); // Use all displays as 128x8 display
SomeRandomBloke 0:9d29b886d41b 504 led.clear();
SomeRandomBloke 7:b46d5d98434a 505 led.setBrightness(BRIGHTNESS);
SomeRandomBloke 3:59038ad536ac 506 //led.displayOff(); // Turn off display for now until receiver task has started
SomeRandomBloke 0:9d29b886d41b 507 bool twoLineDisplay = (LED_MAX_DISPLAY_X > 1);
SomeRandomBloke 0:9d29b886d41b 508 led.putString( 0, 0, "SMS to LED Display" );
SomeRandomBloke 0:9d29b886d41b 509
SomeRandomBloke 7:b46d5d98434a 510 // Thread::wait(3000); // Wait for display to initialise after power up
SomeRandomBloke 0:9d29b886d41b 511 #endif
SomeRandomBloke 0:9d29b886d41b 512
SomeRandomBloke 7:b46d5d98434a 513 // Startup beep
SomeRandomBloke 7:b46d5d98434a 514 // buzzer.beep(1000,0.5);
SomeRandomBloke 7:b46d5d98434a 515
SomeRandomBloke 7:b46d5d98434a 516 Thread::wait(30000); // Wait for bit longer to ensure dongle powers up
SomeRandomBloke 7:b46d5d98434a 517
SomeRandomBloke 0:9d29b886d41b 518 // Set initial blank message
SomeRandomBloke 2:787cbb491f8f 519 resetMessageBuffers();
SomeRandomBloke 0:9d29b886d41b 520
SomeRandomBloke 0:9d29b886d41b 521 Thread receiveTask(receiveSMS, NULL, osPriorityNormal, 1024 * 8); // try 6 next
SomeRandomBloke 0:9d29b886d41b 522 #ifdef USE_LED
SomeRandomBloke 0:9d29b886d41b 523 Thread displayTask(displayScrollingLine, NULL, osPriorityNormal, 1024 * 4);
SomeRandomBloke 0:9d29b886d41b 524 #endif
SomeRandomBloke 0:9d29b886d41b 525
SomeRandomBloke 7:b46d5d98434a 526 // Show we are still working by alternitively flashing LED1 and LED2, once a second
SomeRandomBloke 0:9d29b886d41b 527 led1 = 0; // Working
SomeRandomBloke 0:9d29b886d41b 528 led2 = 1; // Alternate with led1
SomeRandomBloke 3:59038ad536ac 529 led3 = 0; // Received and processing SMS
SomeRandomBloke 0:9d29b886d41b 530 led4 = 0; // Processing USSD message queue
SomeRandomBloke 0:9d29b886d41b 531 while(1) {
SomeRandomBloke 0:9d29b886d41b 532 #ifdef USE_LED
SomeRandomBloke 0:9d29b886d41b 533 // Only display date/time is we have a 2 row display
SomeRandomBloke 0:9d29b886d41b 534 if( twoLineDisplay ) {
SomeRandomBloke 0:9d29b886d41b 535 if( --displayCount <= 0 ) {
SomeRandomBloke 0:9d29b886d41b 536 displayTime = !displayTime;
SomeRandomBloke 0:9d29b886d41b 537 displayCount = 10;
SomeRandomBloke 0:9d29b886d41b 538 led.putString(0,8, " " );
SomeRandomBloke 0:9d29b886d41b 539 }
SomeRandomBloke 0:9d29b886d41b 540 if( displayTime ) {
SomeRandomBloke 0:9d29b886d41b 541 showTime();
SomeRandomBloke 0:9d29b886d41b 542 } else {
SomeRandomBloke 0:9d29b886d41b 543 showDate();
SomeRandomBloke 0:9d29b886d41b 544 }
SomeRandomBloke 0:9d29b886d41b 545 }
SomeRandomBloke 0:9d29b886d41b 546 #endif
SomeRandomBloke 0:9d29b886d41b 547 led1=!led1;
SomeRandomBloke 0:9d29b886d41b 548 led2=!led2;
SomeRandomBloke 0:9d29b886d41b 549 Thread::wait(1000);
SomeRandomBloke 0:9d29b886d41b 550 }
SomeRandomBloke 0:9d29b886d41b 551 }