Final Project for 4180 Nixie Tube IoT Clock
Dependencies: 4DGL-uLCD-SE NixieTube MBed_Adafruit-GPS-Library NetServices wave_player mbed spxml
Final Project for ECE 4180
main.cpp
- Committer:
- fischk08
- Date:
- 2016-12-15
- Revision:
- 4:9651e706b36f
- Parent:
- 3:d62bb9ee0aa0
File content as of revision 4:9651e706b36f:
// Notes https://developer.mbed.org/users/edodm85/notebook/HC-05-bluetooth/ // https://developer.mbed.org/cookbook/Bluetooth-Android-Controlled-MBED // https://developer.mbed.org/users/mlee350/notebook/adafruit-ultimate-gps-breakout-board/ // https://developer.mbed.org/users/4180_1/notebook/ulcd-144-g2-128-by-128-color-lcd/ // https://developer.mbed.org/handbook/LocalFileSystem // Includes Files #include "mbed.h" #include <string> #include "uLCD_4DGL.h" #include "wave_player.h" #include "MBed_Adafruit_GPS.h" // GPS Unit #include "spdomparser.hpp" /// Parseing Weather #include "spxmlnode.hpp" /// Parseing Weather #include "spxmlhandle.hpp" /// Parseing Weather #include "EthernetNetIf.h" #include "HTTPClient.h" #include <string> #include "NTPClient.h" #include "NixieTube.h" Serial pc(USBTX, USBRX); NixieTube Ntube(p24,p23,p22,p21); ///////////////////////// EthernetNetIf eth; HTTPClient http; HTTPResult result; //////////////////////// NTPClient ntp; // Used for Clock //////////////////////////////// LocalFileSystem local("local"); // Create the local filesystem under the name "local" AnalogOut DACout(p18); // DAC for producing sound wave_player waver(&DACout); // wavplayer object Serial * gps_Serial; // GPS Interface uLCD_4DGL uLCD(p13,p14,p15); // serial tx, serial rx, reset pin; AnalogIn photocell(p19); Serial bt(p28, p27); // Bluetooth //LCD Files Needs to be local to the ulcd screen // Declarations bool completed = false; // Used for HTTP Request bool pressPlay = false; // Default on pause (song select mode) int volume = 0; volatile float lattitude = 33.7490; volatile float longitude = -84.3880; bool gps_setup(); void display_screen_debug(),request_callback(),parseWeather(),system_setup(),display_weather(int),sound_alarm(float),ethernet_setup(); // Used for obtaining weather Information void request_callback(HTTPResult r){ result = r; completed = true; } void display_weather(int code){ uLCD.flush_media(); uLCD.cls(); uLCD.media_init(); uLCD.set_sector_address(0x0000,(code*65)); uLCD.display_control(3); uLCD.display_image(0,0); } void parseWeather(SP_XmlElementNode *node, string loc){ //extracts current weather XML data fields for LCD SP_XmlHandle handle(node); SP_XmlElementNode * condition = handle.getChild( "item" ).getChild("yweather:condition").toElement(); //display Weather conditions // Print the name of the city pc.printf("%s:", loc); //Print the weather conditions pc.printf("%s",condition->getAttrValue("text")); //Print the termperature (in degrees Celcius) pc.printf("%sF",condition->getAttrValue("temp")); display_weather(atoi(condition->getAttrValue("code"))); } int weather(){ retryweather: completed = false; SP_XmlDomParser parser; HTTPStream stream; char buffer3 [200]; wait(1); pc.printf("%.6f:",lattitude); pc.printf("%.6f:",longitude); int n2; char post[] = "https://query.yahooapis.com/v1/public/yql?q=select+item.condition+from+weather.forecast+where+woeid+in+(SELECT+woeid+FROM+geo.places+WHERE+text='("; char msg[10] = ")')"; n2 = sprintf(buffer3, "%.6f,%.6f", lattitude, longitude); char* temppostRequest = strcat(post,buffer3); char* postRequest = strcat(temppostRequest,msg); pc.printf(post); pc.printf(msg); pc.printf(temppostRequest); pc.printf("Reading\r\n"); pc.printf(postRequest); wait(1); //n=sprintf(buffer, "https://query.yahooapis.com/v1/public/yql?q=select%20item.condition%20from%20weather.forecast%20where%20woeid%20in%20%28SELECT%20woeid%20FROM%20geo.places%20WHERE%20text%3D%22(%.6f%2C%.6f)%22)", lat, log); char BigBuf[512 + 1] = {0}; wait(1); stream.readNext((byte*)BigBuf, 512); //Point to buffer for the first read //Yahoo! weather API for selected city - get XML document for parsing //HTTPResult r = http.get("https://query.yahooapis.com/v1/public/yql?q=select+item.condition+from+weather.forecast+where+woeid+in+(SELECT+woeid+FROM+geo.places+WHERE+text='(33.7490,-84.3880)')", &stream, request_callback); HTTPResult r = http.get(postRequest, &stream, request_callback); // This is wehre the http query for the local weather occurs while (!completed) { Net::poll(); //Polls the Networking stack if (stream.readable()) { BigBuf[stream.readLen()] = 0; //Transform this buffer in a zero-terminated char* string parser.append( BigBuf, strlen(BigBuf)); // stream current buffer data to the XML parser stream.readNext((byte*)BigBuf, 512); //Buffer has been read, now we can put more data in it } } if (result == HTTP_OK) { pc.printf("Weather complete"); } else { pc. printf("Weather Error %d", result); goto retryweather; return -1; } SP_XmlHandle rootHandle( parser.getDocument()->getRootElement() ); SP_XmlElementNode * child2 = rootHandle.getChild( "results" ).getChild( "channel" ).toElement(); //pc.printf(BigBuf); if ( child2 ) { parseWeather(child2, "Atlanta"); //parses XML "current-conditions" info } if ( NULL != parser.getError() ) { pc.printf( "\n error: %s\n", parser.getError() ); } return 0; } // Need to update so that if it failes to get a GPS fix after say 10 tries it defaults lat and longitude values and time is found thought another method. bool gps_setup(){ Timer refresh_Timer; //sets up a timer for use in loop; how often do we print GPS info? const int refresh_Time = 2000; //refresh time in ms bool gps_off = true; char c; gps_Serial = new Serial(p9,p10); //serial object for use w/ GPS tx rx Adafruit_GPS myGPS(gps_Serial); //object of Adafruit's GPS class myGPS.begin(9600); //sets baud rate for GPS communication; note this may be changed via Adafruit_GPS::sendCommand(char *) myGPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA); //these commands are defined in MBed_Adafruit_GPS.h; a link is provided there for command creation myGPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ); myGPS.sendCommand(PGCMD_ANTENNA); refresh_Timer.start(); //starts the clock on the timer uLCD.text_width(1); //4X size text uLCD.text_height(1); uLCD.printf("Starting Up\n"); while(gps_off){ uLCD.cls(); c = myGPS.read(); //queries the GPS if (c) { uLCD.printf("%c", c); } //this line will echo the GPS data if not paused //check if we recieved a new message from GPS, if so, attempt to parse it, if ( myGPS.newNMEAreceived() ) { if ( !myGPS.parse(myGPS.lastNMEA()) ) { continue; } } //check if enough time has passed to warrant printing GPS info to screen //note if refresh_Time is too low or pc.baud is too low, GPS data may be lost during printing if (refresh_Timer.read_ms() >= refresh_Time) { refresh_Timer.reset(); uLCD.printf("Fix: %d\n", (int) myGPS.fix); uLCD.printf("Quality: %d\n", (int) myGPS.fixquality); if (myGPS.fix) { uLCD.printf("Time: %d:%d:%d.%u\n", myGPS.hour, myGPS.minute, myGPS.seconds, myGPS.milliseconds); uLCD.printf("Date: %d/%d/20%d\n", myGPS.day, myGPS.month, myGPS.year); uLCD.printf("Location: %5.2f%c, %5.2f%c\n", myGPS.latitude, myGPS.lat, myGPS.longitude, myGPS.lon); uLCD.printf("Speed: %5.2f knots\n", myGPS.speed); uLCD.printf("Angle: %5.2f\n", myGPS.angle); uLCD.printf("Altitude: %5.2f\n", myGPS.altitude); uLCD.printf("Satellites: %d\n", myGPS.satellites); gps_off = false; lattitude = myGPS.latitude; longitude = myGPS.longitude; } } } return true; } void sound_alarm() { pressPlay = true; FILE *wave_file = fopen("/local/alarm.wav","r"); waver.play(wave_file); //play(FILE *wavefile,bool *pressPlay, int *volume); pressPlay = false; wait(10); fclose(wave_file); } int main() { unsigned char rx; bt.baud(9600); char alarm[6] = "02:14"; pc.baud(9600); pc.printf("\r\nintializing hardware,...v15\r\n"); eth.init(); //Use DHCP int retry = 0; sendGETRequest: EthernetErr ethErr = eth.setup(60000); if (ethErr) { pc.printf("Error in setup trying again %d",retry); retry++; goto sendGETRequest; } pc.printf("net ok testing weather\r\n"); weather(); weather(); time_t ctTime; ctTime = time(NULL); Host server(IpAddr(), 123, "0.us.pool.ntp.org"); ntp.setTime(server); char hString[3]; char mString[3]; char alarmCompare[5]; int offset = 5; int old_min2 = 0; int reset = 0; char ch; while(1) { int x = 0; if(bt.readable()) { //pc.printf("device readable"); ch=bt.getc(); //alarm[x] = ch; pc.printf("%c",ch); bt.printf("%c",ch); //x++ } //pc.printf("%f", photocell.read() ); if (photocell < .3) { Ntube.set_dim(0.2); } else { Ntube.set_dim(0.5); } ctTime = time(NULL) - 3600 * offset; strftime(hString, 3, "%I", localtime(&ctTime)); strftime(mString, 3, "%M", localtime(&ctTime)); strftime(alarmCompare, 6, "%I:%M", localtime(&ctTime)); if (strcmp(alarm, alarmCompare) == 0) { pc.printf("ALARM\r\n"); sound_alarm(); wait(10); } int hour = std::atoi(hString); int min = std::atoi(mString); int hour1 = hour / 10; int hour2 = hour % 10; int min1 = min / 10; int min2 = min % 10; if (min2!=old_min2) { old_min2=min2; pc. printf("\n %d, %d, %d, %d\r\n", hour1, hour2, min1, min2); Ntube.update_all_nixie_tube(hour1, hour2, min1, min2); reset++; } if (reset>14){ reset = 0; weather(); weather(); } wait(0.3); } }