
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
Diff: main.cpp
- 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