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

Revision:
2:714d63ea1eef
Parent:
1:a6fbd8341289
Child:
3:d62bb9ee0aa0
--- a/main.cpp	Sun Dec 11 17:19:29 2016 +0000
+++ b/main.cpp	Wed Dec 14 03:55:23 2016 +0000
@@ -6,7 +6,6 @@
 
 // Includes Files
 #include "mbed.h"
-#include "rtos.h"
 #include <string>
 #include "uLCD_4DGL.h"
 #include "wave_player.h"
@@ -14,33 +13,69 @@
 #include "spdomparser.hpp" /// Parseing Weather
 #include "spxmlnode.hpp" /// Parseing Weather
 #include "spxmlhandle.hpp" /// Parseing Weather
-#include <TimeUtilities.h> // Used for Clock
-
 #include "EthernetNetIf.h"
 #include "HTTPClient.h"
 #include <string>
+#include "NTPClient.h"
 
+///////////////////////
+#define TUBE_1_LED 0x00800
+#define TUBE_2_LED 0x01000
+#define TUBE_3_LED 0x02000
+#define TUBE_4_LED 0x04000
+#define TUBE_5_LED 0x08000
+#define TUBE_6_LED 0x10000
+ 
+#define TUBE_1_CATH 0x20000
+#define TUBE_2_CATH 0x40000
+#define TUBE_3_CATH 0x80000
+#define TUBE_4_CATH 0x100000
+#define TUBE_5_CATH 0x200000
+#define TUBE_6_CATH 0x400000
 
-#include "NixieTube.h"
-NixieTube test(p23,p24,p25,p26);
-/*
-int main() {
-    test.start_nixie();
-    test.update_nixie_tube(1,2);
-    test.set_dim(1.0,200);
-}
-*/
+void nixie_shiftout();
+int nixie_id_convert(int digit);
+void send_nixie_shiftreg(int cathode_id, int led_bitfield, int tube_bitfield);
+ 
+ 
+DigitalOut myled1(LED1);
+DigitalOut myled2(LED2);
+ 
+ 
+DigitalOut sdi(p24);
+DigitalOut scl(p23);
+DigitalOut rcl(p22);
+PwmOut cen(p21);
+ 
+Ticker shifter;
+ 
+int curr_tube = 1;
+ 
+volatile int digit1 = 1;
+volatile int digit2 = 2;
+volatile int digit3 = 3;
+volatile int digit4 = 4;
+ 
+ 
+uint32_t delay1 = 0.0005;
+uint32_t delay2 = 0.0045;
+ 
+float brightness = 0;
 
-
+/////////////////////////
+Serial pc(USBTX, USBRX);
 EthernetNetIf eth;
 HTTPClient http;
 HTTPResult result;
 
+NTPClient ntp;
+
+
 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(p9,p10,p11); // serial tx, serial rx, reset pin;
+uLCD_4DGL uLCD(p13,p14,p15); // serial tx, serial rx, reset pin;
 
 //LCD Files Needs to be local to the ulcd screen
 
@@ -55,29 +90,73 @@
 //      Confirm Bluetoth link? display bluetooth decal when connected? Or just Letter B in Blue just as good
     
 // Declarations 
-
+bool completed = false; // Used for HTTP Request
 bool pressPlay = false;//default on pause (song select mode)
 int volume = 0; 
 
-/// Functions will follow here
-void display_screen_debug() {
+int weather();
+bool  gps_setup();
+void display_screen_debug(),request_callback(),parseWeather(),system_setup(),display_weather(),sound_alarm();
+
+int main() {
+    //sound_alarm(1);
+    //display_weather(0);
+     pc.baud(9600);
+    pc.printf("\r\nintializing hardware,...v14\r\n");
+    eth.init(); //Use DHCP
+sendGETRequest:
+    EthernetErr ethErr = eth.setup(60000);
+    int retry = 0;
+    if (ethErr) {
+        pc.printf("Error in setup trying again %d",retry);
+        retry++;
+        goto sendGETRequest;
     }
+    pc.printf("net ok testing weather\r\n");
+    weather();
     
-void system_setup () {
-    
-    }
-bool completed = false;
+        cen.period_us(10000);
+    cen.write(1.0);
+    shifter.attach(&nixie_shiftout, 0.001);
 
+  time_t ctTime;
+  ctTime = time(NULL);  
+
+  Host server(IpAddr(), 123, "0.us.pool.ntp.org");
+  ntp.setTime(server);
     
-void display_weather(int code){
-        uLCD.flush_media();
-        uLCD.cls();
-        uLCD.media_init();
-        //uLCD.printf("\n\nAn SD card is needed for image and video data");
-        uLCD.set_sector_address(0x0000,(code*65));
-        uLCD.display_image(0,0);
-        uLCD.cls();
-    }    
+    char hString[3];
+    char mString[3];
+    int offset = 5;
+    while(1) {
+        ctTime = time(NULL) - 3600 * offset;
+        strftime(hString, 3, "%I", localtime(&ctTime));
+        strftime(mString, 3, "%M", localtime(&ctTime));
+            
+        //pc.printf("hour: %s \n min: %s\n", hString, mString); 
+        
+        int hour = std::atoi(hString);
+        int min = std::atoi(mString);
+        
+        int digit1 = hour / 10;
+        int digit2 = hour % 10;
+        
+        int digit3 = min / 10;
+        int digit4 = min % 10;
+        
+        pc. printf("\n %d, %d, %d, %d", digit1, digit2, digit3, digit4);
+        wait(5);
+        //ctTime = time(NULL);  
+        //pc.printf("\nTime is now (UTC): %s\n", ctime(&ctTime)); 
+    }
+  
+  return 0;
+    
+    
+    
+    //eth.disconnect();   
+    }
+ // Used for obtaining weather Information
 void request_callback(HTTPResult r)
 {
     result = r;
@@ -90,220 +169,14 @@
     SP_XmlHandle handle(node);
     SP_XmlElementNode * condition = handle.getChild( "item" ).getChild("yweather:condition").toElement();
     //display Weather conditions
-    display_weather((int)condition->getAttrValue("code"));
+    pc.printf("%d:\r\n", (int)condition->getAttrValue("code"));
     // Print the name of the city
-    uLCD.locate(0,1);
-    uLCD.printf("%s:", loc);
+    pc.printf("%s:\r\n", loc);
     //Print the weather conditions
-    uLCD.locate(0,2);
-    uLCD.printf("%s",condition->getAttrValue("text"));
-    //Print the termperature (in degrees Celcius)
-    uLCD.locate(0,3);
-    uLCD.printf("%sF",condition->getAttrValue("temp"));
-}
-// Need To update so that this takes lat longitude gives it to a website to find local time and or time zone
-void parseWhereAmI(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
-    display_weather((int)condition->getAttrValue("code"));
-    // Print the name of the city
-    uLCD.locate(0,1);
-    uLCD.printf("%s:", loc);
-    //Print the weather conditions
-    uLCD.locate(0,2);
-    uLCD.printf("%s",condition->getAttrValue("text"));
+    pc.printf("%s\r\n",condition->getAttrValue("text"));
     //Print the termperature (in degrees Celcius)
-    uLCD.locate(0,3);
-    uLCD.printf("%sF",condition->getAttrValue("temp"));
-   
-}
-
-// Query Term  for Weather 
-// select+*+from+weather.forecast+where+woeid+in+(SELECT+woeid+FROM+geo.places+WHERE+text%3D%22(33.7490%2C-84.3880)%22)
-// Query Website https://developer.yahoo.com/yql/console/#h=select+*+from+weather.forecast+where+woeid+in+(SELECT+woeid+FROM+geo.places+WHERE+text%3D%22(33.7490%2C-84.3880)%22)
-//asuming that outputformat of lattitude and logitude is - for west + for east and does not use chars  for directionals as that would be dumb
-//"https://query.yahooapis.com/v1/public/yql?q=select+*+from+weather.forecast+where+woeid+in+(SELECT+woeid+FROM+geo.places+WHERE+text%3D%22(33.7490%2C-84.3880)%22)", &stream, request_callback);
-// "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(33.7490%2C-84.3880)%22)"(lat  log) &stream, request_callback)
-
-// Variable Version
-//  "https://query.yahooapis.com/v1/public/yql?q=select+*+from+weather.forecast+where+woeid+in+(SELECT+woeid+FROM+geo.places+WHERE+text%3D%22(lat%2Clong)%22)", &stream, request_callback);
-//  "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) &stream, request_callback)
-
-int weather()
-{
-    completed = false;
-    SP_XmlDomParser parser;
-    HTTPStream stream;     
-    char buffer [240];
-    int n;
-    float lat = 33.7490;
-    float log = -84.3880;
-    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};
-    uLCD.printf(buffer);
-    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(buffer, &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
-        }
-    }
-    uLCD.locate(0,6);
-    if (result == HTTP_OK) {
-        uLCD.printf("Weather complete");
-    } else {
-        uLCD. printf("Weather Error %d", result);
-        return -1;
-    }
-
-    SP_XmlHandle rootHandle( parser.getDocument()->getRootElement() );
-    SP_XmlElementNode * child2 = rootHandle.getChild( "results" ).getChild( "channel" ).toElement();
-
-    //uLCD.printf(BigBuf);
-
-    if ( child2 ) {
-        parseWeather(child2, "Atlanta"); //parses XML "current-conditions" info
-    }
-
-    if ( NULL != parser.getError() ) {
-        uLCD.printf( "\n error: %s\n", parser.getError() );
-    }
-    return 0;
+    pc.printf("%sF\r\n",condition->getAttrValue("temp"));
 }
-
-
-// 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.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;
-            }
-        }
-    }
-    return true;
-}    
-
-void sound_alarm(int volume) {
-        pressPlay = true;
-        FILE *wave_file = fopen("/local/alarm.wav","r");
-        waver.play(wave_file,&pressPlay, &volume); //play(FILE *wavefile,bool *pressPlay, int *volume);
-        pressPlay = false;
-        fclose(wave_file); 
-        }
-        
-RealTimeClock rtc;
- 
- void main_test() {
-     bool success;
-     char TimeTest[] = "05/29/2011 14:15:18 (-6:00)";
-     char buf[50];
-     success = rtc.SetTime(TimeTest);
-     rtc.GetTimeString(buf);
-     uLCD.printf("success: %i, time: %s\n", success, buf);
- }       
-        
-int main() {
-    //sound_alarm(1);
-    //display_weather(0);
-    
-    
-    }
-    
-    
-    
-    ////////////////////////////////////////////////
-    
-    #include "mbed.h"
-#include "EthernetNetIf.h"
-#include "HTTPClient.h"
-#include "spdomparser.hpp"
-#include "spxmlnode.hpp"
-#include "spxmlhandle.hpp"
-#include <string>
-EthernetNetIf eth;
-Serial pc(USBTX, USBRX);
-HTTPClient http;
-HTTPResult result;
-
-bool completed = false;
-void request_callback(HTTPResult r)
-{
-    result = r;
-    completed = true;
-}
-
-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
-    pc.printf("%d:", (int)condition->getAttrValue("code"));
-    // 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"));
-}
-// Need To update so that this takes lat longitude gives it to a website to find local time and or time zone
-void parseWhereAmI(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
-    pc.printf("%d:", (int)condition->getAttrValue("code"));
-    // 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"));
-   
-}
-
 // Query Term  for Weather 
 // select+*+from+weather.forecast+where+woeid+in+(SELECT+woeid+FROM+geo.places+WHERE+text%3D%22(33.7490%2C-84.3880)%22)
 // Query Website https://developer.yahoo.com/yql/console/#h=select+*+from+weather.forecast+where+woeid+in+(SELECT+woeid+FROM+geo.places+WHERE+text%3D%22(33.7490%2C-84.3880)%22)
@@ -376,23 +249,127 @@
 }
 
 
-int main()
-{
-     pc.baud(9600);
-    pc.printf("\r\nintializing hardware,...v14\r\n");
-    eth.init(); //Use DHCP
-sendGETRequest:
-    EthernetErr ethErr = eth.setup(60000);
-    int retry = 0;
-    if (ethErr) {
-        pc.printf("Error in setup trying again %d",retry);
-        retry++;
-        goto sendGETRequest;
+
+/// Functions will follow here
+void display_screen_debug() {
+    }
+    
+void system_setup () {
+    
+    }
+    
+void display_weather(int code){
+        uLCD.flush_media();
+        uLCD.cls();
+        uLCD.media_init();
+        //uLCD.printf("\n\nAn SD card is needed for image and video data");
+        uLCD.set_sector_address(0x0000,(code*65));
+        uLCD.display_image(0,0);
+        uLCD.cls();
+    }    
+
+// 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.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;
+            }
+        }
     }
-    pc.printf("net ok testing weather\r\n");
-    weather();
-    //eth.disconnect();
+    return true;
+}    
+
+void sound_alarm(int volume) {
+        pressPlay = true;
+        FILE *wave_file = fopen("/local/alarm.wav","r");
+        waver.play(wave_file,&pressPlay, &volume); //play(FILE *wavefile,bool *pressPlay, int *volume);
+        pressPlay = false;
+        fclose(wave_file); 
+        }
 
+void nixie_shiftout() {
+       
+       
+        switch (curr_tube) {
+            case 1:
+                send_nixie_shiftreg(nixie_id_convert(digit1), 0, TUBE_1_CATH);
+                break;
+            case 2:
+                send_nixie_shiftreg(nixie_id_convert(digit2), 0, TUBE_2_CATH);
+                break;
+            case 3:
+                send_nixie_shiftreg(nixie_id_convert(digit3), 0, TUBE_3_CATH);
+                break;
+            case 4:
+                send_nixie_shiftreg(nixie_id_convert(digit4), 0, TUBE_4_CATH);
+                break;
+            default:
+                curr_tube = 1;
+        }
+        curr_tube++;
+        if (curr_tube == 5) {
+            curr_tube = 1;
+        }
 }
-
-
+ 
+int nixie_id_convert(int digit) {
+    if (digit == 0 || digit == -1) {
+        return digit + 1;  
+    }
+    if (digit < 10) {
+        return 11 - digit;
+    }
+    if (digit == 10) {
+        return 11;
+    }
+    return 0;
+}
+ 
+void send_nixie_shiftreg(int cathode_id, int led_bitfield, int tube_bitfield) {
+ 
+    int buffer = 0;
+    buffer = 1 << (cathode_id-1) | led_bitfield | tube_bitfield;
+ 
+    for (int i=23; i >= 0; i--) {
+        sdi = buffer & (1 << i);
+        scl = 1;
+        scl = 0;
+    }
+    rcl = 1;
+    rcl = 0;
+ 
+}