Program that uses Adafruit FONA 800h and resistive touch uLCD display to track roommates and send and receive text messages.

Dependencies:   mbed-rtos mbed uLCD_4D_Picaso

Revision:
0:0b0487606b13
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sun May 01 21:31:25 2016 +0000
@@ -0,0 +1,478 @@
+#include "mbed.h"
+#include "uLCD_4D_Picaso.h"
+#include "Adafruit_FONA.h"
+#include "rtos.h"
+#include <string>
+#include <vector>
+#include <ctype.h>
+
+#define FONA_RST p12
+#define FONA_TX p13
+#define FONA_RX p14
+#define FONA_RI p11
+
+//using namespace std;
+Serial pcSerial(USBTX, USBRX);
+Adafruit_FONA fona(FONA_TX, FONA_RX, FONA_RST, FONA_RI);
+
+Mutex mut;
+uLCD_4D_Picaso lcd(p28, p27, p30);
+
+// this is a large buffer for replies
+char replybuffer[255];
+
+// Turn on a LED when somebody calls the FONA (we need to somehow make this apply to texts instead of call
+// Ok so this works!! just change where indicated
+DigitalOut led1(LED1);
+DigitalOut led2(LED2);
+volatile bool newText = false; 
+class FonaEventListener : public Adafruit_FONA::EventListener {
+    virtual void onRing() { //<- Upon arrival of new text here is what happens
+        //this is what should happen when a text comes in
+        
+        led1 = 1;
+        wait_ms(500);
+        led1 = 0;
+        newText = true; //global 
+    }
+    
+    virtual void onNoCarrier() {
+        led1 = 0;
+    }
+};
+FonaEventListener fonaEventListener;
+
+// Functions defined after main()
+uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout = 0);
+void flushSerial();
+char readBlocking();
+uint16_t readnumber();
+long map(long x, long in_min, long in_max, long out_min, long out_max);
+
+// I don't think this global variable is defined correctly
+volatile bool whoshome[4] = {0}; // Cole = whoshome[0], brandon = whoshome[1], George = whoshome[2], Jesse = whoshome[3]
+
+// This member function needs to run when a text message has been received by the FONA module.
+// textout() reads the phone number of the person who sent the text message from text message slot 1,
+// deletes that text message, checks the boolean array that indicates who is home and then sends out a text
+// message for each person that is home.
+
+void textout();    
+   
+// The ___home() member functions below should be called when the ____home buttons on the LCD touchscreen are pressed.
+// For example, when cole comes in the house he will push his button to indicate that he is home. This will update his
+// status from away (0) to home (1) and text everyone that is HOME the text message "Cole is home." The functionality is 
+// the same for brandonshome, georgeshome, jesseshome
+
+void coleshome();
+void brandonshome();
+void georgeshome();
+void jesseshome();
+
+// These functions should be called when one of the roommates pushes the ____away button on the lcd touchscreen.
+// For example, if Cole is leaving the house, then he would touch the COLE away box and it would change his value
+// in the boolean array whoshome from home (1) to away (0). Then, the next time the LCD DISPLAY thread is run,
+// Cole's name would disappear from the display because he is away.
+
+void colesaway(void);
+void brandonsaway(void);
+void georgesaway(void);
+void jessesaway(void);
+
+// This is the display function that updates the names based on the boolean array whoshome. Let me know if you
+// have questions about this.
+
+void update_display(){
+    mut.lock();
+    
+    //print names - if home, print name, if not, print blank spaces 
+    
+    lcd.txt_MoveCursor(4, 0);
+    lcd.txt_Attributes(Picaso::UNDERLINED);
+    
+    if (whoshome[0]) { //cole
+        lcd.putStr("Cole\r\n");
+        }
+    else lcd.putStr("       \r\n");
+    if (whoshome[1]) {  //Brandon
+        lcd.putStr("Brandon\r\n");
+        }
+    else lcd.putStr("       \r\n");
+    if (whoshome[2]) { //george
+        lcd.putStr("George\r\n");
+        }
+    else lcd.putStr("       \r\n");
+    if (whoshome[3]) { //Jesse
+        lcd.putStr("Jesse\r\n");
+        }
+    else lcd.putStr("       \r\n");
+    
+    mut.unlock();
+}
+
+void display_func(void const *args){ //this is what is going to be responsible for updating to the screen
+ 
+    // this may need to be in a separate thread, i'm not sure. we also may need to use a mutex
+    mut.lock();
+    pcSerial.printf("i'm in the display function\r\n");
+    mut.unlock();
+    int status = 0;
+    int x = 0;
+    int y = 0;
+    while (1) {
+        status = lcd.touch_Get(0);
+        if (status) {
+            mut.lock();
+            pcSerial.printf("i got touched\r\n");
+            mut.unlock();
+            x = lcd.touch_Get(1);
+            y = lcd.touch_Get(2);
+            
+                if (status == 1 && y >= 180 && y <= 240 && x >= 0 && x <= 55) {
+                    //update_display();
+                    coleshome();
+                } 
+                if (status == 1 && y >= 180 && y <= 240 && x >= 65 && x <= 115) {
+                    //update_display();
+                    brandonshome();
+                } 
+                if (status == 1 && y >= 180 && y <= 240 && x >= 125 && x <= 175) {
+                    //update_display();
+                    georgeshome();
+                } 
+                if (status == 1 && y >= 180 && y <= 240 && x >= 185 && x <= 240) {
+                    //update_display();
+                    jesseshome();
+                } 
+            
+            // AWAY
+            
+                if (status == 1 && y >= 250 && x >= 0 && x <= 55) {
+                    //update_display();
+                    colesaway();
+                } 
+                if (status == 1 && y >= 250 && x >= 65 && x <= 115) {
+                    //update_display();
+                    brandonsaway();
+                } 
+                if (status == 1 && y >= 250 && x >= 125 && x <= 175) {
+                    //update_display();
+                    georgesaway();
+                } 
+                if (status == 1 && y >= 250 && x >= 185 && x <= 240) {
+                    jessesaway();
+                    //update_display();
+                } 
+        }
+    }  
+} 
+
+void textout(void const *args){ // this is responsible for texting a list of people who are home 
+    
+    while(true) {
+        while (!newText) Thread::yield(); //GEORGE!!!
+        mut.lock();
+        pcSerial.printf("i received a text message\r\n");
+        mut.unlock();
+        newText = false; //update global variable
+        //read in txt message
+        fona.getSMSSender(1, replybuffer, 250); // store phone number in reply buffer
+        
+        fona.deleteSMS(1); // delete text message to free up sms #1
+        mut.lock();
+        pcSerial.printf("text message deleted\r\n");
+        mut.unlock();
+        //reply to number with texts of who is home
+        if (whoshome[0]) { //cole
+            fona.sendSMS(replybuffer, "Cole is home");
+            //wait_ms(250);
+        }
+        if (whoshome[1]) { //brandon
+            fona.sendSMS(replybuffer, "Brandon is home");
+            //wait_ms(250);
+        }
+        if (whoshome[2]) { //george
+            fona.sendSMS(replybuffer, "George is home");
+            //wait_ms(250);
+        }
+        if (whoshome[3]) { //jesse
+            fona.sendSMS(replybuffer, "Jesse is home");
+            //wait_ms(250);
+        }
+        if (whoshome[0] == 0 && whoshome[1] == 0 && whoshome[2] == 0 && whoshome[3] == 0) {
+            fona.sendSMS(replybuffer, "No one is home :(");
+            //wait_ms(250);
+        }
+    }
+}    
+
+void coleshome(){
+    // update bool array
+    whoshome[0] = 1;
+    update_display();
+    if (whoshome[1]) {
+        fona.sendSMS("6789936332", "Cole is home."); //text brandon
+        //wait_ms(250);
+    }
+    if (whoshome[2]) {
+        fona.sendSMS("4045189567", "Cole is home."); //text george
+        //wait_ms(250);
+    }
+    if (whoshome[3]) {
+        fona.sendSMS("7067664360", "Cole is home."); //text jesse
+        //wait_ms(250);
+    }
+}
+
+void brandonshome(){
+    // update bool array
+    whoshome[1] = 1;
+    update_display();
+    if (whoshome[0]) {
+        fona.sendSMS("8476022588", "Brandon is home."); //text cole
+        //wait_ms(250);
+    }
+    if (whoshome[2]) {
+        fona.sendSMS("4045189567", "Brandon is home."); //text george
+        //wait_ms(250);
+    }
+    if (whoshome[3]) {
+        fona.sendSMS("7067664360", "Brandon is home."); //text jesse
+        //wait_ms(250);
+    }
+}
+
+void georgeshome(){
+    // update bool array
+    whoshome[2] = 1;
+    update_display();
+    if (whoshome[0]) {
+        fona.sendSMS("8476022588", "George is home."); //text cole
+        //wait_ms(250);
+    }
+    if (whoshome[1]) {
+        fona.sendSMS("6789936332", "George is home."); //text brandon
+        //wait_ms(250);
+    }
+    if (whoshome[3]) {
+        fona.sendSMS("7067664360", "George is home."); //text jesse
+        //wait_ms(250);
+    }
+}
+
+void jesseshome(){
+    // update bool array
+    whoshome[3] = 1;
+    update_display();
+    if (whoshome[0]) {
+        fona.sendSMS("8476022588", "Jesse is home."); //text cole
+        //wait_ms(250);
+    }
+    if (whoshome[1]) {
+        fona.sendSMS("6789936332", "Jesse is home."); //text brandon
+        //wait_ms(250);
+    }
+    if (whoshome[2]) {
+        fona.sendSMS("4045189567", "Jesse is home."); //text george
+        //wait_ms(250);
+    }
+}
+
+void colesaway(){
+    whoshome[0] = 0;
+    update_display();
+}
+
+void brandonsaway(){
+    whoshome[1] = 0;
+    update_display();
+}
+
+void georgesaway(){
+    whoshome[2] = 0;
+    update_display();
+}
+
+void jessesaway(){
+    whoshome[3] = 0;
+    update_display();
+}
+
+
+void flushSerial() {
+    while (pcSerial.readable()) 
+        pcSerial.getc();
+}
+
+char readBlocking() {
+    while (!pcSerial.readable());
+    return pcSerial.getc();
+}
+
+uint16_t readnumber() {
+    uint16_t x = 0;
+    char c;
+    while (! isdigit(c = readBlocking())) {
+        //pcSerial.putc(c);
+    }
+    pcSerial.putc(c);
+    x = c - '0';
+    while (isdigit(c = readBlocking())) {
+        pcSerial.putc(c);
+        x *= 10;
+        x += c - '0';
+    }
+    return x;
+}
+  
+uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout) {
+    uint16_t buffidx = 0;
+    bool timeoutvalid = true;
+    if (timeout == 0) timeoutvalid = false;
+    
+    while (true) {
+        if (buffidx > maxbuff) {
+            //pcSerial.printf("SPACE\r\n");
+            break;
+        }
+        
+        while(pcSerial.readable()) {
+            char c =  pcSerial.getc();
+            
+            //pcSerial.printf("%02x#%c\r\n", c, c);
+            
+            if (c == '\r') continue;
+            if (c == 0xA) {
+                if (buffidx == 0)   // the first 0x0A is ignored
+                    continue;
+                
+                timeout = 0;         // the second 0x0A is the end of the line
+                timeoutvalid = true;
+                break;
+            }
+            buff[buffidx] = c;
+            buffidx++;
+        }
+        
+        if (timeoutvalid && timeout == 0) {
+            //pcSerial.printf("TIMEOUT\r\n");
+            break;
+        }
+        wait_ms(1);
+    }
+    buff[buffidx] = 0;  // null term
+    return buffidx;
+}
+
+long map(long x, long in_min, long in_max, long out_min, long out_max)
+{
+    return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
+}
+
+void initialize_everything(){
+        //initiate whatever
+   
+    // LCD touchscreen
+    lcd.setbaudWait(Picaso::BAUD_600000);
+    lcd.touch_Set(0);
+    lcd.txt_Opacity(Picaso::OPAQUE);
+    
+    //Set up header
+    
+    lcd.txt_MoveCursor(0, 6);
+    lcd.txt_Attributes(Picaso::BOLD);
+    lcd.txt_FGcolour(Picaso::RED);
+    lcd.putStr("mbed Roomate Tracker");
+    lcd.txt_MoveCursor(2, 0);
+    lcd.txt_FGcolour(Picaso::CYAN);
+    lcd.putStr("Who's home?");
+    
+    //Set up touch boxes
+    lcd.gfx_Rectangle(0, 180, 55, 240, Picaso::RED);
+    lcd.gfx_RectangleFilled(1, 181, 54, 239, Picaso::WHITE);
+    lcd.gfx_Rectangle(65, 180, 115, 240, Picaso::RED);
+    lcd.gfx_RectangleFilled(66, 181, 114, 239, Picaso::WHITE);
+    lcd.gfx_Rectangle(125, 180, 175, 240, Picaso::RED);
+    lcd.gfx_RectangleFilled(126, 181, 174, 239, Picaso::WHITE);
+    lcd.gfx_Rectangle(185, 180, 240, 240, Picaso::RED);
+    lcd.gfx_RectangleFilled(186, 181, 239, 239, Picaso::WHITE);
+    lcd.txt_MoveCursor(17, 2);
+    lcd.putStr("COLE\r\nhome");
+    lcd.txt_MoveCursor(17, 8);
+    lcd.putStr("BRANDON\r\nhome");
+    lcd.txt_MoveCursor(17, 16);
+    lcd.putStr("GEORGE\r\nhome");
+    lcd.txt_MoveCursor(17, 24);
+    lcd.putStr("JESSE\r\nhome");
+    
+    lcd.gfx_Rectangle(0, 250, 55, 310, Picaso::RED);
+    lcd.gfx_RectangleFilled(1, 251, 54, 309, Picaso::WHITE);
+    lcd.gfx_Rectangle(65, 250, 115, 310, Picaso::RED);
+    lcd.gfx_RectangleFilled(66, 251, 114, 309, Picaso::WHITE);
+    lcd.gfx_Rectangle(125, 250, 175, 310, Picaso::RED);
+    lcd.gfx_RectangleFilled(126, 251, 174, 309, Picaso::WHITE);
+    lcd.gfx_Rectangle(185, 250, 240, 310, Picaso::RED);
+    lcd.gfx_RectangleFilled(186, 251, 239, 309, Picaso::WHITE);
+    lcd.txt_FGcolour(Picaso::WHITE);
+    lcd.txt_Attributes(Picaso::UNDERLINED);
+    lcd.txt_MoveCursor(23, 2);
+    lcd.putStr("COLE\r\naway");
+    lcd.txt_MoveCursor(23, 8);
+    lcd.putStr("BRANDON\r\naway");
+    lcd.txt_MoveCursor(23, 16);
+    lcd.putStr("GEORGE\r\naway");
+    lcd.txt_MoveCursor(23, 24);
+    lcd.putStr("JESSE\r\naway");
+    
+    
+    flushSerial();
+    //FONA initialization (copied from FONA code (may only need the fona.begin(9600) but all of this stuff won't hurt to have
+    pcSerial.baud(9600);
+    wait(1);
+    mut.lock();
+    pcSerial.printf("\r\n");
+    
+    pcSerial.printf("FONA basic test\r\n");
+    pcSerial.printf("Initializing....(May take 3 seconds)\r\n");
+    wait(2);
+    // See if the FONA is responding
+    if (! fona.begin(9600)) {
+        pcSerial.printf("Couldn't find FONA\r\n");
+        while (1);
+    }
+    pcSerial.printf("Can I get an Amen\r\n");
+    fona.setEventListener(&fonaEventListener);
+    pcSerial.printf("FONA is OK\r\n");
+    for( int i = 1; i < 10; i++){
+        fona.deleteSMS(i);
+        wait_ms(10);
+    }
+    
+    // Print SIM card IMEI number.
+    char imei[15] = {0}; // MUST use a 16 character buffer for IMEI!
+    uint8_t imeiLen = fona.getIMEI(imei);
+    if (imeiLen > 0) {
+        pcSerial.printf("SIM card IMEI: %s\r\n", imei);
+    }
+    mut.unlock();
+}
+
+
+int main() {
+   
+    initialize_everything(); //does all the setup stuff
+ ///   //start threads
+    pcSerial.printf("everything is initialized\r\n");
+    Thread thread1(display_func); //this is what waits for something to touch it
+    pcSerial.printf("display thread good\r\n");
+    Thread thread2(textout);
+    pcSerial.printf("textout thread good\r\n");
+    //Thread thread3(texting);
+    while (true){
+    led2 = !led2;
+    Thread::wait(500);
+    }
+   
+    //wait
+   
+}
\ No newline at end of file