File content as of revision 0:dbe4ead20087:
#include "mbed.h"
#include "TFT_4DGL.h"
TFT_4DGL ecran(p13,p14,p15); // serial tx, serial rx, reset pin;
CAN can(p30, p29);
DigitalOut led(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
DigitalOut led4(LED4);
DigitalIn switch_left(p16);
DigitalIn switch_right(p17);
Ticker tiktok;
Ticker can_tok;
Timer timer;
int last_seen[10];
int last_state[2];
enum boards {
CUTOFF,
TELEMETRY,
MAIN_OUTPUT,
MAIN_INPUT,
BPS,
DATA_LOGGER,
TRITIUM
};
enum modes {
HEARTBEAT,
DEMO,
FULL_CAN
};
char mode = DEMO;
int speed = 0;
int percent = 0;
char s[40][50];
char needs_update[40];
int current = 0;
int j = 0;
void display_can();
int next() {
int old = current;
current = (current + 1) % 40;
return old;
}
void demo_update() {
char buffer[20];
// Speed
sprintf(buffer, "%02d", speed);
speed = (speed + 1) % 100;
ecran.text_mode(1);
ecran.graphic_string(buffer, 80, 0, FONT_8X8, WHITE, 5, 5);
ecran.graphic_string("Kph", 160, 0, FONT_8X8, WHITE, 2, 2);
// Mode
if (speed < 25)
ecran.graphic_string("P", 0, 0, FONT_8X8, 0xFF0000, 5, 5);
else if (speed < 50)
ecran.graphic_string("N", 0, 0, FONT_8X8, 0x0000FF, 5, 5);
else if (speed < 75)
ecran.graphic_string("D", 0, 0, FONT_8X8, 0x00FF00, 5, 5);
else
ecran.graphic_string("R", 0, 0, FONT_8X8, 0xFF00FF, 5, 5);
// Battery
percent = (percent + 2) % 100;
ecran.pen_size(0);
ecran.rectangle(11, 61, (int)(percent * 2.2)+11, 79, 0xFF0000);
ecran.rectangle((int)(percent * 2.2)+11, 61, 229, 79, 0x000000);
ecran.graphic_string("Battery:", 10, 90, FONT_8X8, WHITE, 2, 2) ;
sprintf(buffer, "%02d%%", percent);
ecran.graphic_string(buffer, 140, 90, FONT_8X8, WHITE, 2, 2) ;
// Logo
ecran.graphic_string("CalSol GFX 2011", 110, 310, FONT_8X8, WHITE, 1, 1);
// LED
led = !led;
}
void update() {
// Packets
ecran.text_mode(1);
for(int i = 0; i < 40; i++) {
if (needs_update[i]) {
needs_update[i] = 0;
ecran.text_string(s[i], 0, i, FONT_8X8, WHITE);
}
}
// LED
led = !led;
}
void heartbeat_update() {
ecran.text_mode(1);
int t = timer.read_ms();
char buffer[255];
// Title
sprintf(buffer, "Board: Last Seen (ms)");
ecran.text_string(buffer, 0, 0, FONT_8X8, WHITE);
// Cutoff
sprintf(buffer, "Cutoff: %d", t - last_seen[CUTOFF]);
if (t - last_seen[CUTOFF] > 1000)
ecran.text_string(buffer, 0, 2, FONT_8X8, RED);
else
ecran.text_string(buffer, 0, 2, FONT_8X8, GREEN);
// Telemetry
sprintf(buffer, "Telemetry %d", t - last_seen[TELEMETRY]);
if (t - last_seen[TELEMETRY] > 1000)
ecran.text_string(buffer, 0, 4, FONT_8X8, RED);
else
ecran.text_string(buffer, 0, 4, FONT_8X8, GREEN);
// Main Output
sprintf(buffer, "MainOutput %d", t - last_seen[MAIN_OUTPUT]);
if (t - last_seen[MAIN_OUTPUT] > 1000)
ecran.text_string(buffer, 0, 6, FONT_8X8, RED);
else
ecran.text_string(buffer, 0, 6, FONT_8X8, GREEN);
// Main Input
sprintf(buffer, "MainInput %d", t - last_seen[MAIN_INPUT]);
if (t - last_seen[MAIN_INPUT] > 1000)
ecran.text_string(buffer, 0, 8, FONT_8X8, RED);
else
ecran.text_string(buffer, 0, 8, FONT_8X8, GREEN);
// BPS
sprintf(buffer, "BPS: %d", t - last_seen[BPS]);
if (t - last_seen[BPS] > 1000)
ecran.text_string(buffer, 0, 10, FONT_8X8, RED);
else
ecran.text_string(buffer, 0, 10, FONT_8X8, GREEN);
// Data Logger
sprintf(buffer, "DataLogger: %d", t - last_seen[DATA_LOGGER]);
if (t - last_seen[DATA_LOGGER] > 1000)
ecran.text_string(buffer, 0, 12, FONT_8X8, RED);
else
ecran.text_string(buffer, 0, 12, FONT_8X8, GREEN);
// Tritium
sprintf(buffer, "Tritium %d", t - last_seen[TRITIUM]);
if (t - last_seen[TRITIUM] > 1000)
ecran.text_string(buffer, 0, 14, FONT_8X8, RED);
else
ecran.text_string(buffer, 0, 14, FONT_8X8, GREEN);
// LED
led = !led;
}
void display_heartbeats();
void set_demo() {
ecran.cls();
ecran.graphic_string("CalSol GFX 2011", 110, 310, FONT_8X8, WHITE, 1, 1);
// Top bar
ecran.pen_size(SOLID);
ecran.rectangle(0, 40, 240, 42, 0xEEEEEE);
// Battery bar
ecran.pen_size(1);
ecran.rectangle(10, 60, 230, 80, 0xFF0000);
tiktok.detach();
tiktok.attach(&demo_update, 0.5);
mode = DEMO;
}
void set_full() {
tiktok.detach();
tiktok.attach(&update, 0.5);
mode = FULL_CAN;
ecran.cls();
ecran.graphic_string("CalSol GFX 2011", 110, 310, FONT_8X8, WHITE, 1, 1);
}
void set_heartbeat() {
tiktok.detach();
tiktok.attach(&heartbeat_update, 0.5);
mode = HEARTBEAT;
ecran.cls();
ecran.graphic_string("CalSol GFX 2011", 110, 310, FONT_8X8, WHITE, 1, 1);
}
int main() {
can.frequency(1000000);
switch_left.mode(PullUp);
switch_right.mode(PullUp);
for (int i = 0; i < 40; i++) {
needs_update[i] = 0;
s[i][0] = '\0';
}
ecran.baudrate(115200);
timer.start();
// Logo
ecran.graphic_string("CalSol GFX 2011", 110, 310, FONT_8X8, WHITE, 1, 1);
sprintf(s[next()], "Initializing...");
tiktok.attach(&update, 0.5);
CANMessage msg;
while(1) {
int left = switch_left;
int right = switch_right;
led4 = left;
led3 = right;
if (last_state[0] != left) {
if (left)
set_demo();
else
set_heartbeat();
last_state[0] = left;
}
if (last_state[1] != right) {
if (right)
set_demo();
else
set_full();
last_state[1] = right;
}
if (mode == FULL_CAN)
display_can();
else if (mode == HEARTBEAT)
display_heartbeats();
}
}
void display_heartbeats() {
CANMessage msg;
int t = timer.read_ms();
if (can.read(msg)) {
switch(msg.id) {
case 0x41:
last_seen[BPS] = t;
break;
case 0x42:
last_seen[CUTOFF] = t;
break;
case 0x43:
last_seen[MAIN_OUTPUT] = t;
break;
case 0x44:
last_seen[MAIN_INPUT] = t;
break;
case 0x45:
last_seen[TELEMETRY] = t;
break;
case 0x46:
last_seen[DATA_LOGGER] = t;
break;
case 0x400:
last_seen[TRITIUM] = t;
break;
}
led2 = !led2;
}
}
void display_can() {
CANMessage msg;
if (can.read(msg)) {
int current_index = next();
char *current_line = s[current_index];
needs_update[current_index] = 1;
if (((msg.id & 0x7FF) >= 0x100) && ((msg.id & 0x7FF) <= 0x12F)) {
int pack_num = (msg.id & 0x30) >> 4;
if ((msg.id & 0xF) <= 0xB) {
sprintf(current_line, "Volt %d/%d: %f", pack_num, (msg.id & 0xF), *((float*)msg.data));
} else {
sprintf(current_line, "Temp %d/%d: %f", pack_num, (msg.id & 0xF) - 0xB, *((float*)msg.data));
}
} else {
sprintf(current_line, "%X(%d):", msg.id & 0x7FF, msg.len);
for (int i = 0; i < msg.len; i++) {
sprintf(current_line + strlen(current_line), "%2X ", msg.data[i]);
}
}
led2 = !led2;
}
}