Code for the following project: https://www.instructables.com/id/Ultimate-Hamster-Tracker-Wheel-Featuring-Mbed-C-LC/

Dependencies:   4DGL-uLCD-SE PinDetect mbed

Files at this revision

API Documentation at this revision

Comitter:
bstrickland9
Date:
Mon Apr 03 00:24:50 2017 +0000
Commit message:
Code for the following project:; https://www.instructables.com/id/Ultimate-Hamster-Tracker-Wheel-Featuring-Mbed-C-LC/

Changed in this revision

4DGL-uLCD-SE.lib Show annotated file Show diff for this revision Revisions of this file
PinDetect.lib Show annotated file Show diff for this revision Revisions of this file
Shiftbrite.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r d0e2fe309777 4DGL-uLCD-SE.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/4DGL-uLCD-SE.lib	Mon Apr 03 00:24:50 2017 +0000
@@ -0,0 +1,1 @@
+https://mbed.org/users/4180_1/code/4DGL-uLCD-SE/#e39a44de229a
diff -r 000000000000 -r d0e2fe309777 PinDetect.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PinDetect.lib	Mon Apr 03 00:24:50 2017 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/AjK/code/PinDetect/#cb3afc45028b
diff -r 000000000000 -r d0e2fe309777 Shiftbrite.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Shiftbrite.h	Mon Apr 03 00:24:50 2017 +0000
@@ -0,0 +1,38 @@
+#include "mbed.h"
+
+//Setup a new class for a Shiftbrite RGB LED module
+class Shiftbrite
+{
+public:
+    Shiftbrite(PinName pin_e, PinName pin_l, PinName pin_do, PinName pin_di, PinName pin_clk);
+    void write(int red, int green, int blue);
+
+private:
+//class sets up the pins
+    DigitalOut _pin_e;
+    DigitalOut _pin_l;
+    SPI _spi;
+};
+
+Shiftbrite::Shiftbrite(PinName pin_e, PinName pin_l, PinName pin_do, PinName pin_di, PinName pin_clk)
+    : _pin_e(pin_e), _pin_l(pin_l), _spi(pin_do, pin_di, pin_clk)
+{
+    _spi.format(16,0);
+    _spi.frequency(500000);
+    _pin_e=0;
+    _pin_l=0;    
+}
+
+void Shiftbrite::write(int red, int green, int blue)
+{
+    _pin_e=0;
+    _pin_l=0;
+    unsigned int low_color=0;
+    unsigned int high_color=0;
+    high_color=(blue<<4)|((red&0x3C0)>>6);
+    low_color=(((red&0x3F)<<10)|(green));
+    _spi.write(high_color);
+    _spi.write(low_color);
+    _pin_l=1;
+    _pin_l=0;
+}
diff -r 000000000000 -r d0e2fe309777 main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Mon Apr 03 00:24:50 2017 +0000
@@ -0,0 +1,296 @@
+#include "mbed.h"
+#include "PinDetect.h"
+#include "uLCD_4DGL.h"
+#include "Shiftbrite.h"
+
+DigitalOut myled1(LED1);
+DigitalOut myled2(LED2);
+DigitalOut myled3(LED3);
+DigitalOut myled4(LED4);
+
+// use class to setup pushbuttons pins
+PinDetect pb1(p23);
+PinDetect pb2(p24);
+
+// use class to setup the  Color LCD
+uLCD_4DGL uLCD(p28, p27, p29); // create a global uLCD object
+
+// Global variables used in callbacks and main program
+// C variables in interrupt routines should use volatile keyword
+int volatile magnetHit=0;
+
+//timer setup
+Timer t;
+
+// Callback routine is interrupt activated by a debounced magnet hit
+void pb1_hit_callback (void)
+{
+        magnetHit=1;
+}
+
+// Callback routine is interrupt activated by a debounced magnet unhit
+void pb2_hit_callback (void)
+{
+        magnetHit=1;
+}
+
+// use class to setup Shiftbrite pins
+Shiftbrite myShiftbrite(p9, p10, p11, p12, p13);// ei li di n/c ci
+
+// init
+float circumference=0, speed=0, tempFloat=0, changePercent=0, averageBlock=0; //average is float
+int a1=10000, a2=10000, a3=10000, a4=10000, a5=10000, cumulativeDistBlock=0, recentBlock=0; //avg values assume ~7.5km
+int highestBlock=0, lowestBlock=99999999, dayCount=0;
+unsigned int myColor = 0x000000;
+unsigned int shiftR=0, shiftG=0, shiftB=0;
+bool execSpaces=0;
+
+int main() {
+    //start timer
+    t.start();
+    myled1 = 1;
+    
+    shiftR = 50;
+    myShiftbrite.write( shiftR, shiftG, shiftB);
+    
+    uLCD.color(0xff3333);
+    uLCD.locate(0,0);
+    uLCD.printf(" ...Starting...");
+    
+    // Use internal pullups/downs for the pushbutton
+    pb1.mode(PullDown); //PullUp gnd and input. PullDown vcc and input.
+    pb2.mode(PullUp);
+    // Delay for initial pullup to take effect
+    wait(.1);
+    // Setup Interrupt callback functions for a pb hit
+    //pb1.attach_deasserted(&pb1_unhit_callback);
+    pb1.attach_asserted(&pb1_hit_callback);
+    pb2.attach_deasserted(&pb2_hit_callback);
+    // Start sampling pb inputs using interrupts. leave as () default 20ms aka 20000.
+    pb1.setSampleFrequency(10000); //using 10ms aka 10000
+    pb2.setSampleFrequency(10000);
+    //setSamplesTillAssert, default is 50 continuous samples
+    pb1.setSamplesTillAssert(6);
+    pb2.setSamplesTillAssert(6);
+    
+    // Set RTC time to Wed, 28 Oct 2009 11:35:37 (January 1, 1970)
+    set_time(1);
+    //time_t mktime (tm * timeptr) //needed?
+    
+    //setup circumference
+    circumference = 3.14159*0.24; //pi * diam (m) //tweakMe was 0.254
+    
+    wait(0.4);
+    uLCD.locate(0,0);
+    uLCD.color(0x4444ff);
+    uLCD.printf(" Ultimate Hamster");
+    
+    //labels print in this color
+    uLCD.color(0x8888ff);
+    
+    // set up permanent characters on display
+        uLCD.locate(0,2);
+        uLCD.printf("Speed:       (m/s)");
+        
+        uLCD.locate(0,4);
+        uLCD.printf("Change:        (%%)");
+        
+        //optimize other labels too one day...
+        uLCD.locate(0,6);
+        uLCD.printf("Recent:        (m)");
+        uLCD.locate(0,8);
+        uLCD.printf("Average:       (m)");
+        uLCD.locate(0,10);
+        uLCD.printf("Highest:       (m)");
+        uLCD.locate(0,12);
+        uLCD.printf("Lowest:        (m)");
+        
+        uLCD.locate(0,15);
+        uLCD.printf("0 /24hr    day 0  ");
+        
+        //old debug display...
+        //uLCD.locate(0,14);
+        //uLCD.printf("Time:");
+        //uLCD.locate(0,15);
+        //uLCD.printf("Hour:");
+        
+    // end
+    
+    //numbers print in this color
+    uLCD.color(0xcccc33);
+    //if you want to change this, also change value near changePercent print!
+    
+    shiftR=0;
+    shiftG=0;
+    shiftB=50;
+    myShiftbrite.write( shiftR, shiftG, shiftB);
+    
+    
+    while(1) {
+        
+        myled1 = !myled1; // show loop is active
+        //shiftR = (rand()*40) % 40;
+        //shiftG = (rand()*40) % 40;
+        //shiftB = (rand()*40) % 40;
+        shiftR = 0;
+        shiftG = 0;
+        shiftB = 0;
+        myShiftbrite.write( shiftR, shiftG, shiftB);
+                
+        switch (magnetHit) {
+            case 0:
+                myled2 = 1; 
+                myled3 = 0;
+                break;
+            case 1:
+                
+                myled2 = 0; 
+                myled3 = 1; 
+                
+                //change title color
+                //myColor = (rand()*0xffffff) % 0xffffff;
+                
+                //change shiftbrite color
+                myShiftbrite.write( 20, 20, 20);
+                
+                //speed calc
+                //using timer t.
+                tempFloat = t.read();
+                t.reset();
+                
+                //send speed to display
+                speed = circumference / tempFloat;
+                uLCD.locate(7,2);
+                uLCD.printf("%5.2F", speed); //speed: number
+                
+                //4mph or 1.8m/s is a timer value of 0.44s per revolution
+                if (tempFloat > 0.3) { //instead use 0.3
+                    cumulativeDistBlock = cumulativeDistBlock + 1;
+                } else {
+                    //shiftbrite
+                }
+                
+                magnetHit=0; //force to zero
+                
+                myShiftbrite.write( shiftR, shiftG, shiftB);
+                
+                break;
+        }
+        
+        //for debug only
+        //uLCD.locate(0,10);
+        //uLCD.printf("t.read: %5.2F", t.read());
+        
+        //check if wheel is still for more than 5 seconds
+        //t.stop(); //line not needed if t.read() can occur without pause
+        if (t.read() > 3 && t.read() < 4) { //1 second window (24hr takes ~0.7s)
+            uLCD.locate(8,2);
+            uLCD.printf("zero"); //speed: zero
+        }
+        //t.start(); //line not needed if t.read() can occur without pause
+        
+        if (t.read() > 300) { //every 5 mins, reset speed timer
+            //prevent overflow, max value is 1800, 30 mins
+            t.reset();
+        }
+        
+        //get the current time
+        time_t seconds = time(NULL);
+        
+        uLCD.locate(0,15);
+        uLCD.printf("%u", seconds/60/60 ); //change seconds to seconds/60/60
+        
+        //time display for debug
+        //uLCD.locate(6,14);
+        //uLCD.printf("%u ", seconds );
+        //uLCD.locate(6,15);
+        //uLCD.printf("%u ", seconds/60/60 );
+        
+        //this runs every 24hr block
+        if (seconds >= 86400) { //86400 is 24hrs
+            myShiftbrite.write( 50, 0, 0);
+            
+            //compute 24hr block values
+            recentBlock = cumulativeDistBlock;
+            cumulativeDistBlock = 0; //reset
+            dayCount++; //add one to day
+            
+            //change tracking
+            changePercent = 100*(recentBlock-averageBlock) / (averageBlock); //signed float
+            
+            //shift numbers in array to delete oldest value
+            a1 = a2; //oldest 
+            a2 = a3;
+            a3 = a4;
+            a4 = a5;
+            a5 = recentBlock; //newest
+            averageBlock = (a1 + a2 + a3 + a4 + a5)/5; //int becomes float
+            
+            //check if recentBlock is new high or new low
+            if (recentBlock > highestBlock) { //new high
+                highestBlock = recentBlock;
+                //Highest (m) store max value 
+                tempFloat = highestBlock*circumference;
+                uLCD.locate(8,10);
+                uLCD.printf("%7.0F", tempFloat);
+                uLCD.locate(5,14);
+                uLCD.printf("NEW HIGH");
+                execSpaces = 1; //if no update on next round, set spaces
+            } else if (recentBlock < lowestBlock) { //new low
+                lowestBlock = recentBlock;
+                //Lowest (m) store min value
+                tempFloat = lowestBlock*circumference;
+                uLCD.locate(8,12);
+                uLCD.printf("%7.0F", tempFloat);
+                uLCD.locate(5,14);
+                uLCD.printf("NEW LOW ");
+                execSpaces = 1;
+            } else if (execSpaces == 1) {
+                uLCD.locate(5,14);
+                uLCD.printf("        ");
+                execSpaces = 0;
+            } //state machine so that spaces will not overwrite spaces every time
+            
+            //use tempFloat to convert int rotations to distance (m)
+            //use circumference float
+            //update the following on display
+            
+            //Change (%) past 24hr block vs average
+            if (changePercent > 0) {
+                //green
+                uLCD.color(0x33ff33);
+            } else if (changePercent < 0) {
+                //red
+                uLCD.color(0xff3333);
+            } else {
+                //purple, white??
+                uLCD.color(0xff33ff);
+            }
+            //tempFloat = changePercent;
+            uLCD.locate(8,4);
+            uLCD.printf("%7.0F", changePercent); //NAN and INF possible!
+            uLCD.color(0xcccc33); //reset color value!!!!! copy value from way above.
+            
+            //Recent (m) past 24hr block
+            tempFloat = recentBlock*circumference;
+            uLCD.locate(8,6);
+            uLCD.printf("%7.0F", tempFloat);
+            //Average (m) average of the past 5 24hr
+            tempFloat = averageBlock*circumference;
+            uLCD.locate(8,8);
+            uLCD.printf("%7.0F", tempFloat);
+            //print for low and high happens only when value updated
+            
+            //bottom line updates
+            uLCD.locate(0,15);
+            uLCD.printf("0 "); // remove leftover characters from XX/24hr
+            uLCD.locate(15,15); //modify this
+            uLCD.printf("%u", dayCount);
+            
+            set_time(1); //reset
+            
+            myShiftbrite.write( shiftR, shiftG, shiftB);
+        }
+        
+    } //while end
+}
diff -r 000000000000 -r d0e2fe309777 mbed.bld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Mon Apr 03 00:24:50 2017 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/faff56e089b2
\ No newline at end of file