SMS message display on LED Matrix board with printer option
Dependencies: AdafruitThermalPrinter HT1632_LedMatrix VodafoneUSBModem mbed-rtos mbed
Revision 0:9d29b886d41b, committed 2013-01-18
- Comitter:
- SomeRandomBloke
- Date:
- Fri Jan 18 08:41:20 2013 +0000
- Child:
- 1:243371cb92c8
- Commit message:
- Library updates
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/AdafruitThermalPrinter.lib Fri Jan 18 08:41:20 2013 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/SomeRandomBloke/code/AdafruitThermalPrinter/#871ca02007be
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HT1632_LedMatrix.lib Fri Jan 18 08:41:20 2013 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/SomeRandomBloke/code/HT1632_LedMatrix/#0fac71b7ec1d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/VodafoneUSBModem.lib Fri Jan 18 08:41:20 2013 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/VodafoneUSBModem/#07ac4e1ea5b0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Fri Jan 18 08:41:20 2013 +0000
@@ -0,0 +1,468 @@
+/**
+ * Mbed SMS to Printer and LED Matrix Displays
+ * Based on SMS example from VodafoneUSBModem library and
+ * 3GReceiptPrinter app from Ashley Mills.
+ *
+ * Requires libraries:
+ * AdafruitThermalPrinter - Port of Arduino library by Ashley Mills
+ * VodafoneUSBModem - Driver for Vodafone K3370 Mobile Broadband dongle
+ * HT1632_LedMatrix - LED Matrix library by Andrew Lindsay, port of Arduino library by Andrew Lindsay
+ *
+ * @author Andrew Lindsay
+ *
+ * @section LICENSE
+ *
+ * Copyright (c) 2012 Andrew Lindsay (andrew [at] thiseldo [dot] co [dot] uk)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @section DESCRIPTION
+ * Display received SMS on scrolling LED matrix with optional output to thermal printer.
+ *
+ * TODO: Still have issue with restarts when using printer.
+ * mbed-rtos and serial problem?
+ *
+ */
+
+#define USE_LED
+#define USE_PRINTER
+
+#include <ctype.h>
+
+#include "mbed.h"
+#include "VodafoneUSBModem.h"
+//#include <LinkMonitor.h>
+
+#ifdef USE_LED
+#include "HT1632_LedMatrix.h"
+#endif
+#ifdef USE_PRINTER
+#include "AdafruitThermal.h"
+//#include "test.h"
+#endif
+
+#define DEBUG 1
+
+#ifdef USE_LED
+// Cound try to get own number usine USSD request
+#define INFO_MSG " Send a message to 07765946942 "
+#endif
+
+// Vodafone USSD commands
+#define USSD_COMMAND_OWN_NUMBER "*#100#"
+#define USSD_COMMAND_BALANCE "*#134#"
+#define USSD_COMMAND_TIME "*#103#"
+
+
+#ifdef DEBUG
+//Serial pc(USBTX, USBRX); // tx, rx
+//Serial debug_pc(p13,p14); // tx, rx
+Serial debug_pc(USBTX, USBRX); // tx, rx
+#endif
+
+#ifdef USE_PRINTER
+AdafruitThermal printer(p28,p27); // setup printer
+#endif
+// Define a maximum size for storage arrays, is 160 (SMS size) + a bit more.
+#define MAX_MSG_LENGTH 192
+
+// Month list used in converting to integer for set_time
+char months[12][4] = {"JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC" };
+
+#ifdef USE_LED
+
+#define LED_MAX_DISPLAY_X 4
+#define LED_MAX_DISPLAY_Y 1
+
+// create object to control the LED Matrix
+HT1632_LedMatrix led = HT1632_LedMatrix();
+#define DISPDELAY 90
+#endif
+
+// Message buffers. New message waiting to be displayed and current message being displayed
+static char cmdBuf[12];
+static char newMsgBuf[MAX_MSG_LENGTH];
+static char msgBuf[MAX_MSG_LENGTH];
+
+#ifdef USE_LED
+int crtPos = 0;
+int msgx = 1; // position on message screen of current character, set to 1 to allow for first scroll
+bool resetMessage = false;
+
+void matrixDemo( void );
+#endif
+
+// Define the onboard LEDs to use as status indicators
+DigitalOut led1(LED1); // Activity
+DigitalOut led2(LED2); // Activity, alternates with led2
+DigitalOut led3(LED3); // SMS received, turns off after processed
+DigitalOut led4(LED4); // USSD requested
+
+int threadRestartCount = 0;
+
+// Convert string buffer to upper case, is destructive. Buffer will be changed.
+char* stoupper( char* s )
+{
+ char* p = s;
+ while (*p = toupper( *p )) p++;
+ return s;
+}
+
+
+#ifdef USE_PRINTER
+void timestampMessage( char *msg )
+{
+ char timebuf[50];
+ // Print date/time, then message
+ time_t seconds = time(NULL);
+ strftime(timebuf, 50, "%d/%m/%Y %X\n", localtime(&seconds));
+ printer.print(timebuf);
+ printer.print(msg);
+ // linefeed a couple of times
+ printer.feed(3);
+}
+#endif
+
+#ifdef USE_LED
+// Load a new message
+void setNewMessage( char *newMsgStart )
+{
+ strncpy( newMsgBuf, newMsgStart, MAX_MSG_LENGTH );
+ resetMessage = true;
+}
+#endif
+
+void sendUSSDCommand( VodafoneUSBModem *_modem, char *ussdCommand, bool setScrolling )
+{
+ led4 = 1;
+#ifdef DEBUG
+ debug_pc.printf("Sending %s on USSD channel\n", ussdCommand);
+#endif
+ int ret = _modem->sendUSSD(ussdCommand, newMsgBuf, MAX_MSG_LENGTH);
+ // Check for correct response
+ if(ret) {
+ // Non 0 value indicates an error??
+#ifdef DEBUG
+ debug_pc.printf("Send USSD command returned %d\n", ret);
+#endif
+ led4 = 0;
+ return;
+ }
+
+ // Should only display message if one has been received.
+#ifdef DEBUG
+ debug_pc.printf("Result of command: %s\n", newMsgBuf);
+#endif
+
+ led4 = 0;
+
+#ifdef USE_LED
+ resetMessage = setScrolling;
+#endif
+}
+
+void setTime(VodafoneUSBModem *_modem )
+{
+ char numBuf[10];
+ // Set RTC using received message, format is DD-MMM-YYYY HH:MM
+ // Month is in text name, e.g. NOV, time is using 24 hour clock.
+ struct tm t;
+ int retryCount = 3;
+
+ while( retryCount ) {
+ sendUSSDCommand( _modem, USSD_COMMAND_TIME, false );
+
+#ifdef DEBUG
+ debug_pc.printf("Time received is %s\n", newMsgBuf);
+#endif
+
+ t.tm_sec = 0; // 0-59
+ strncpy(numBuf, &newMsgBuf[15], 2 );
+ t.tm_min = atoi(numBuf); // 0-59
+ strncpy(numBuf, &newMsgBuf[12], 2 );
+ t.tm_hour = atoi(numBuf); // 0-23
+ strncpy(numBuf, &newMsgBuf[0], 2 );
+ t.tm_mday = atoi(numBuf); // 1-31
+ strncpy(numBuf, &newMsgBuf[3], 3 );
+ t.tm_mon = 0; // 0-11
+ for( int i=0; i<12; i++ ) {
+ if( strncmp( months[i], numBuf, 3 ) == 0 ) {
+ t.tm_mon = i; // 0-11
+ break;
+ }
+ }
+ strncpy(numBuf, &newMsgBuf[9], 2 );
+ t.tm_year = 100 + atoi( numBuf ); // year since 1900
+
+ if( t.tm_year >110 ) {
+ // convert to timestamp and display
+ time_t seconds = mktime(&t);
+ set_time( seconds );
+ retryCount = 0; // No more retries, terminate while
+ } else {
+ // Failed to set time, decrement tries
+ retryCount--;
+ }
+ }
+}
+
+
+void receiveSMS(void const*)
+{
+ VodafoneUSBModem modem;
+ time_t seconds = time(NULL);
+
+ threadRestartCount++;
+
+// int pRssi = 0;
+// setNewMessage( "Starting" );
+
+
+// LinkMonitor::REGISTRATION_STATE pRegistrationState;
+// LinkMonitor::BEARER pBearer;
+
+// modem.getLinkState( &pRssi,&pRegistrationState, &pBearer);
+#ifdef DEBUG
+// debug_pc.printf("Link state Rssi: %d, Registration state %x Bearer %x\n",pRssi,pRegistrationState, pBearer);
+#endif
+
+// sprintf(msgBuf, "Link state Rssi: %d, Registration state %x Bearer %x ",pRssi,pRegistrationState, pBearer);
+#ifdef USE_PRINTER
+ // Check if time already set, if not then get it. Use year = 0 as test
+ struct tm *t = localtime(&seconds);
+ if( t->tm_year == 0 ) {
+ setTime( &modem );
+ }
+
+ sprintf(newMsgBuf, "Thread Start %d\r\n", threadRestartCount );
+ timestampMessage( newMsgBuf );
+#endif
+#ifdef USE_LED
+ //strcpy( msgBuf, INFO_MSG );
+ setNewMessage( INFO_MSG );
+
+ led.displayOn();
+#endif
+ char num[17];
+ size_t smsCount;
+
+ while(true) {
+ if( modem.getSMCount(&smsCount) ==OK ) {
+ if( smsCount > 0) {
+ led3 = 1;
+#ifdef DEBUG
+ debug_pc.printf("%d SMS to read\n", smsCount);
+#endif
+ if( modem.getSM(num, newMsgBuf, MAX_MSG_LENGTH) == OK ) {
+
+#ifdef DEBUG
+ debug_pc.printf("%s : %s\n", num, newMsgBuf);
+#endif
+#ifdef USE_PRINTER
+// Print date/time, then message
+ timestampMessage( newMsgBuf );
+#endif
+#ifdef USE_LED
+ resetMessage = true;
+#endif
+ strncpy( cmdBuf, newMsgBuf, 10 );
+ stoupper( cmdBuf ); // This is a destructive function, original characters are uppercased
+ if( strncmp( cmdBuf, "BALANCE", 7 ) == 0 ) {
+ sendUSSDCommand( &modem, USSD_COMMAND_BALANCE, true );
+#ifdef USE_PRINTER
+ timestampMessage( newMsgBuf );
+#endif
+#ifdef USE_LED
+ resetMessage = true;
+ } else if ( strncmp( cmdBuf, "INFO", 4 ) == 0 ) {
+ setNewMessage( INFO_MSG );
+#endif
+// } else if ( strncmp( cmdBuf, "DEMO", 4 ) == 0 ) {
+// matrixDemo();
+// setNewMessage( INFO_MSG );
+#ifdef USE_LED
+ } else if ( strncmp( cmdBuf, "CLEAR", 5 ) == 0 ) {
+ setNewMessage( " " );
+#endif
+ }
+ }
+ }
+ }
+ Thread::wait(3000);
+ led3 = 0;
+ }
+}
+
+#ifdef USE_LED
+void displayScrollingLine(void const*)
+{
+ int y,xmax,ymax;
+ led.getXYMax(&xmax,&ymax);
+
+ while(true) {
+ // shift the whole screen 6 times, one column at a time; making 1 character
+ if( strlen( msgBuf ) > 10 ) {
+ for (int x=0; x < 6; x++) {
+ led.scrollLeft(1, 1);
+ msgx--;
+ // fit as much as we can on the available display space
+
+ while (!led.putChar(msgx,0,msgBuf[crtPos])) { // zero return if it all fitted
+ led.getXY(&msgx,&y);
+ crtPos++; // we got all of the character on!!
+ if (crtPos >= strlen(msgBuf)) {
+ crtPos = 0;
+ }
+ }
+ led.putShadowRam();
+ Thread::wait(DISPDELAY);
+ }
+ }
+ // Look for a new message being available
+ // TODO add minimum interval between message changes, e.g. 60s
+ if( resetMessage ) {
+ led.clear();
+ crtPos = 0;
+ msgx = 1;
+ strncpy( msgBuf, newMsgBuf, MAX_MSG_LENGTH );
+ if( strlen( msgBuf ) > 10 ) {
+ strcat( msgBuf, " ");
+ } else {
+ led.putString(0,0, msgBuf);
+ }
+ resetMessage = false;
+ }
+ }
+}
+
+
+void matrixDemo( void )
+{
+ int xmax,ymax;
+ led.getXYMax(&xmax,&ymax);
+ led.clear();
+ for( int n=0; n<3; n++ ) {
+ for( int i=0; i<8; i++ ) {
+ led.drawRectangle(i,i,xmax-i,ymax-i, 1);
+ wait(0.05);
+ }
+ for( int i=7; i>=0; i-- ) {
+ led.drawRectangle(i,i,xmax-i,ymax-i, 0);
+ wait(0.05);
+ }
+ }
+ led.clear();
+ for( int n=0; n<3; n++ ) {
+ for(int i=0; i<(xmax/2); i++) {
+ led.drawCircle((xmax/2), 7, i, 1 );
+ wait( 0.05 );
+ }
+ for(int i=(xmax/2); i>=0; i--) {
+ led.drawCircle((xmax/2), 7, i, 0 );
+ wait( 0.05 );
+ }
+ }
+ wait(2);
+
+ led.clear();
+ led.init(2,1); // Use displays 1 and 2 as 64x8 display
+}
+
+
+void showTime()
+{
+ time_t seconds = time(NULL);
+ char timebuf[20];
+ strftime(timebuf, 20, "%X ", localtime(&seconds));
+ led.putString(12,8, timebuf );
+}
+
+void showDate()
+{
+ time_t seconds = time(NULL);
+ char timebuf[20];
+ strftime(timebuf, 20, "%d/%m/%Y ", localtime(&seconds));
+ led.putString(4,8, timebuf );
+}
+#endif
+
+
+int main()
+{
+#ifdef DEBUG
+ debug_pc.baud(57600);
+#ifdef USE_LED
+ debug_pc.printf("SMS to LED Matrix display\n");
+#endif
+#ifdef USE_PRINTER
+ printer.begin();
+ debug_pc.printf("SMS To Printer\n");
+ timestampMessage("SMS To Printer Starting");
+#endif
+#endif
+#ifdef USE_LED
+ int displayCount = 10;
+ bool displayTime = true;
+
+ led.init(LED_MAX_DISPLAY_X,LED_MAX_DISPLAY_Y); // Use displays 1 and 2 as 64x8 display
+ led.clear();
+ led.setBrightness(2);
+ //led.displayOff(); // Turn off display for now until receiver tast has started
+ bool twoLineDisplay = (LED_MAX_DISPLAY_X > 1);
+ led.putString( 0, 0, "SMS to LED Display" );
+
+ Thread::wait(3000); // Wait for display to initialise after power up
+#endif
+
+ // Set initial blank message
+ strcpy( msgBuf, " " );
+
+ Thread receiveTask(receiveSMS, NULL, osPriorityNormal, 1024 * 8); // try 6 next
+#ifdef USE_LED
+ Thread displayTask(displayScrollingLine, NULL, osPriorityNormal, 1024 * 4);
+#endif
+
+ // Show we are still working by alternitively flashing LED1 adn LED2, once a second
+ led1 = 0; // Working
+ led2 = 1; // Alternate with led1
+ led3 = 0; // Received and processign SMS
+ led4 = 0; // Processing USSD message queue
+ while(1) {
+#ifdef USE_LED
+ // Only display date/time is we have a 2 row display
+ if( twoLineDisplay ) {
+ if( --displayCount <= 0 ) {
+ displayTime = !displayTime;
+ displayCount = 10;
+ led.putString(0,8, " " );
+ }
+ if( displayTime ) {
+ showTime();
+ } else {
+ showDate();
+ }
+ }
+#endif
+ led1=!led1;
+ led2=!led2;
+ Thread::wait(1000);
+ }
+
+ return 0;
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-rtos.lib Fri Jan 18 08:41:20 2013 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed-rtos/#88a1a9c26ae3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Fri Jan 18 08:41:20 2013 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/3753e96f3c8b \ No newline at end of file