Dependencies:   4DGL mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "TFT_4DGL.h"
00003 
00004 TFT_4DGL ecran(p13,p14,p15); // serial tx, serial rx, reset pin;
00005 CAN can(p30, p29);
00006 DigitalOut led(LED1);
00007 DigitalOut led2(LED2);
00008 DigitalOut led3(LED3);
00009 DigitalOut led4(LED4);
00010 DigitalIn switch_left(p16);
00011 DigitalIn switch_right(p17);
00012 Ticker tiktok;
00013 Ticker can_tok;
00014 Timer timer;
00015 int last_seen[10];
00016 int last_state[2];
00017 enum boards {
00018     CUTOFF,
00019     TELEMETRY,
00020     MAIN_OUTPUT,
00021     MAIN_INPUT,
00022     BPS,
00023     DATA_LOGGER,
00024     TRITIUM
00025 };
00026 enum modes {
00027     HEARTBEAT,
00028     DEMO,
00029     FULL_CAN
00030 };
00031 char mode = DEMO;
00032 int speed = 0;
00033 int percent = 0;
00034 char s[40][50];
00035 char needs_update[40];
00036 int current = 0;
00037 int j = 0;
00038 
00039 void display_can();
00040 
00041 int next() {
00042     int old = current;
00043     current = (current + 1) % 40;
00044     return old;
00045 }
00046 void demo_update() {
00047     char buffer[20];
00048     
00049     // Speed
00050     sprintf(buffer, "%02d", speed);
00051     speed = (speed + 1) % 100;
00052     ecran.text_mode(1);
00053     ecran.graphic_string(buffer, 80, 0, FONT_8X8, WHITE, 5, 5);
00054     ecran.graphic_string("Kph", 160, 0, FONT_8X8, WHITE, 2, 2);
00055     
00056     // Mode
00057     if (speed < 25)
00058         ecran.graphic_string("P", 0, 0, FONT_8X8, 0xFF0000, 5, 5);
00059     else if (speed < 50)
00060         ecran.graphic_string("N", 0, 0, FONT_8X8, 0x0000FF, 5, 5);
00061     else if (speed < 75)
00062         ecran.graphic_string("D", 0, 0, FONT_8X8, 0x00FF00, 5, 5);
00063     else
00064         ecran.graphic_string("R", 0, 0, FONT_8X8, 0xFF00FF, 5, 5);
00065     
00066     // Battery
00067     percent = (percent + 2) % 100;
00068     ecran.pen_size(0);
00069     ecran.rectangle(11, 61, (int)(percent * 2.2)+11, 79, 0xFF0000);
00070     ecran.rectangle((int)(percent * 2.2)+11, 61, 229, 79, 0x000000);
00071     ecran.graphic_string("Battery:", 10, 90, FONT_8X8, WHITE, 2, 2) ;
00072     sprintf(buffer, "%02d%%", percent);
00073     ecran.graphic_string(buffer, 140, 90, FONT_8X8, WHITE, 2, 2) ;
00074     
00075     // Logo
00076     ecran.graphic_string("CalSol GFX 2011", 110, 310, FONT_8X8, WHITE, 1, 1);
00077     
00078     // LED
00079     led = !led;
00080 }
00081 
00082 void update() {
00083     
00084     // Packets
00085     ecran.text_mode(1);
00086     for(int i = 0; i < 40; i++) {
00087         if (needs_update[i]) {
00088             needs_update[i] = 0;
00089             ecran.text_string(s[i], 0, i, FONT_8X8, WHITE);
00090         }
00091     }
00092     // LED
00093     led = !led;
00094 }
00095 void heartbeat_update() {
00096     ecran.text_mode(1);
00097     int t = timer.read_ms();
00098     char buffer[255];
00099     // Title
00100     sprintf(buffer, "Board:      Last Seen (ms)");
00101     ecran.text_string(buffer, 0, 0, FONT_8X8, WHITE);
00102     // Cutoff
00103     sprintf(buffer, "Cutoff:     %d", t - last_seen[CUTOFF]);
00104     if (t - last_seen[CUTOFF] > 1000)
00105         ecran.text_string(buffer, 0, 2, FONT_8X8, RED);
00106     else
00107         ecran.text_string(buffer, 0, 2, FONT_8X8, GREEN);
00108     // Telemetry
00109     sprintf(buffer, "Telemetry   %d", t - last_seen[TELEMETRY]);
00110     if (t - last_seen[TELEMETRY] > 1000)
00111         ecran.text_string(buffer, 0, 4, FONT_8X8, RED);
00112     else
00113         ecran.text_string(buffer, 0, 4, FONT_8X8, GREEN);
00114     // Main Output
00115     sprintf(buffer, "MainOutput  %d", t - last_seen[MAIN_OUTPUT]);
00116     if (t - last_seen[MAIN_OUTPUT] > 1000)
00117         ecran.text_string(buffer, 0, 6, FONT_8X8, RED);
00118     else
00119         ecran.text_string(buffer, 0, 6, FONT_8X8, GREEN);
00120     // Main Input
00121     sprintf(buffer, "MainInput   %d", t - last_seen[MAIN_INPUT]);
00122     if (t - last_seen[MAIN_INPUT] > 1000)
00123         ecran.text_string(buffer, 0, 8, FONT_8X8, RED);
00124     else
00125         ecran.text_string(buffer, 0, 8, FONT_8X8, GREEN);
00126     // BPS
00127     sprintf(buffer, "BPS:        %d", t - last_seen[BPS]);
00128     if (t - last_seen[BPS] > 1000)
00129         ecran.text_string(buffer, 0, 10, FONT_8X8, RED);
00130     else
00131         ecran.text_string(buffer, 0, 10, FONT_8X8, GREEN);
00132     // Data Logger
00133     sprintf(buffer, "DataLogger: %d", t - last_seen[DATA_LOGGER]);
00134     if (t - last_seen[DATA_LOGGER] > 1000)
00135         ecran.text_string(buffer, 0, 12, FONT_8X8, RED);
00136     else
00137         ecran.text_string(buffer, 0, 12, FONT_8X8, GREEN);
00138     // Tritium
00139     sprintf(buffer, "Tritium     %d", t - last_seen[TRITIUM]);
00140     if (t - last_seen[TRITIUM] > 1000)
00141         ecran.text_string(buffer, 0, 14, FONT_8X8, RED);
00142     else
00143         ecran.text_string(buffer, 0, 14, FONT_8X8, GREEN);             
00144     // LED
00145     led = !led;
00146 }
00147 
00148 void display_heartbeats();
00149 void set_demo() {
00150     ecran.cls();
00151     ecran.graphic_string("CalSol GFX 2011", 110, 310, FONT_8X8, WHITE, 1, 1);
00152     // Top bar
00153     ecran.pen_size(SOLID);
00154     ecran.rectangle(0, 40, 240, 42, 0xEEEEEE);
00155     
00156     // Battery bar
00157     ecran.pen_size(1);
00158     ecran.rectangle(10, 60, 230, 80, 0xFF0000);
00159     tiktok.detach();
00160     tiktok.attach(&demo_update, 0.5);
00161     mode = DEMO;
00162 }
00163 void set_full() {
00164     tiktok.detach();
00165     tiktok.attach(&update, 0.5);
00166     mode = FULL_CAN;
00167     ecran.cls();
00168     ecran.graphic_string("CalSol GFX 2011", 110, 310, FONT_8X8, WHITE, 1, 1);
00169 }
00170 void set_heartbeat() {
00171     tiktok.detach();
00172     tiktok.attach(&heartbeat_update, 0.5);
00173     mode = HEARTBEAT;
00174     ecran.cls();
00175     ecran.graphic_string("CalSol GFX 2011", 110, 310, FONT_8X8, WHITE, 1, 1);
00176 }
00177 
00178 int main() {
00179     can.frequency(1000000);
00180     switch_left.mode(PullUp);
00181     switch_right.mode(PullUp);
00182     for (int i = 0; i < 40; i++) {
00183         needs_update[i] = 0;
00184         s[i][0] = '\0';
00185     }
00186     ecran.baudrate(115200);
00187     timer.start();
00188     
00189     // Logo
00190     ecran.graphic_string("CalSol GFX 2011", 110, 310, FONT_8X8, WHITE, 1, 1);
00191     sprintf(s[next()], "Initializing...");
00192     
00193     tiktok.attach(&update, 0.5);
00194     CANMessage msg;    
00195     while(1) {
00196         int left = switch_left;
00197         int right = switch_right;
00198         led4 = left;
00199         led3 = right;
00200         if (last_state[0] != left) {
00201             if (left)
00202                 set_demo();
00203             else
00204                 set_heartbeat();
00205             last_state[0] = left;
00206         }
00207         if (last_state[1] != right) {
00208             if (right) 
00209                 set_demo();
00210             else
00211                 set_full();
00212             last_state[1] = right;
00213         }
00214         if (mode == FULL_CAN)
00215             display_can();
00216         else if (mode == HEARTBEAT)
00217             display_heartbeats();
00218     }
00219 }
00220 
00221 void display_heartbeats() {
00222     CANMessage msg;
00223     int t = timer.read_ms();
00224     if (can.read(msg)) {
00225         switch(msg.id) {
00226             case 0x41:
00227                 last_seen[BPS] = t;
00228                 break;
00229             case 0x42:
00230                 last_seen[CUTOFF] = t;
00231                 break;
00232             case 0x43:
00233                 last_seen[MAIN_OUTPUT] = t;
00234                 break;
00235             case 0x44:
00236                 last_seen[MAIN_INPUT] = t;
00237                 break;
00238             case 0x45:
00239                 last_seen[TELEMETRY] = t;
00240                 break;
00241             case 0x46:
00242                 last_seen[DATA_LOGGER] = t;
00243                 break;
00244             case 0x400:
00245                 last_seen[TRITIUM] = t;
00246                 break;
00247         }
00248         led2 = !led2;
00249     }
00250 }
00251 
00252 void display_can() {
00253     CANMessage msg;
00254     if (can.read(msg)) {
00255         int current_index = next();
00256         char *current_line = s[current_index];
00257         needs_update[current_index] = 1;
00258         if (((msg.id & 0x7FF) >= 0x100) && ((msg.id & 0x7FF) <= 0x12F)) {
00259             int pack_num = (msg.id & 0x30) >> 4;
00260             if ((msg.id & 0xF) <= 0xB) {
00261                 sprintf(current_line, "Volt %d/%d: %f", pack_num, (msg.id & 0xF), *((float*)msg.data));
00262             } else {
00263                 sprintf(current_line, "Temp %d/%d: %f", pack_num, (msg.id & 0xF) - 0xB, *((float*)msg.data));
00264             }
00265         } else {
00266             sprintf(current_line, "%X(%d):", msg.id & 0x7FF, msg.len);
00267             for (int i = 0; i < msg.len; i++) {
00268                 sprintf(current_line + strlen(current_line), "%2X ", msg.data[i]);
00269             }
00270         }
00271         led2 = !led2;
00272     }
00273 }