void display_show_welcome_msg() { #if (DISPLAY_TYPE & DISPLAY_TYPE_NOKIA) || (DISPLAY_TYPE & DISPLAY_TYPE_16X2) display_show_important_info(FROM_FLASH(msg_welcome), 5); #if (DISPLAY_TYPE & DISPLAY_TYPE_NOKIA) lcd.setCursor(0, 5); const byte max_len = 12; #elif (DISPLAY_TYPE & DISPLAY_TYPE_16X2) lcd.setCursor(0, 1); const byte max_len = 14; #endif // Show total mileage (right aligned) unsigned long total_km = (odo * wheel_circumference/1000); byte number_len = calc_number_length(total_km); // Safety check if (number_len >= max_len) return; number_len = max_len - number_len; while(number_len > 1) { lcd.print(MY_F(" ")); --number_len; } lcd.print(total_km); lcd.print(MY_F(" km")); #endif }
static void display_menu() { #if (DISPLAY_TYPE & DISPLAY_TYPE_NOKIA) || (DISPLAY_TYPE & DISPLAY_TYPE_16X2) // Check if user has been idle for too long if (menu_activity_expire && millis() > menu_activity_expire) { menu_active = false; return; } if (!menu_changed) return; menu_changed = false; menu_activity_expire = millis() + menu_idle_timeout_secs * 1000; // Display the menu Menu const* menu = menu_system.get_current_menu(); MenuComponent const* selected = menu->get_selected(); lcd.clear(); // Scroll to currently selected item for long menus byte current_lcd_row = 0; byte items_to_skip = 0; #if (DISPLAY_TYPE & DISPLAY_TYPE_NOKIA) const byte num_screen_rows = 6; #elif (DISPLAY_TYPE & DISPLAY_TYPE_16X2) const byte num_screen_rows = 2; #endif if (menu->get_cur_menu_component_num() >= num_screen_rows) items_to_skip = menu->get_cur_menu_component_num() - num_screen_rows + 1; for (byte i = 0; i < menu->get_num_menu_components(); ++i) { // Handle scrolling of long menus if (items_to_skip) { --items_to_skip; continue; } lcd.setCursor(0, current_lcd_row); MenuComponent const *item = menu->get_menu_component(i); if (item == selected) lcd.print(MY_F("> ")); else lcd.print(MY_F(" ")); lcd.print(FROM_FLASH((item->get_name()))); ++current_lcd_row; if (current_lcd_row == num_screen_rows) break; } #endif }
/* Own function to display temperature / altitude on the welcome screen. If you just see "welcome" and nothing else, the I2C communication is hanging. */ void display_show_welcome_msg_temp() { #if (DISPLAY_TYPE & DISPLAY_TYPE_NOKIA) lcd.setCursor(0,0); lcd.print((int)(temperature)); lcd.print(MY_F(" C / ")); lcd.print((int)(altitude_start)); lcd.print(MY_F("m")); #endif }
static void display_16x2_view_human() { lcd.setCursor(0,0); lcd.print(MY_F("CAD: ")); if (cad<100) {lcd.print(MY_F(" "));} if (cad<10) {lcd.print(MY_F(" "));} lcd.print(cad,10); #ifdef SUPPORT_HRMI lcd.setCursor(0,1); lcd.print(MY_F("Pulse: ")); lcd.print((byte) pulse_human); lcd.print(MY_F(" ")); #endif }
static void printTime(unsigned long sec) //print time in exactly 5 characters: in the format "mm:ss" or "hh:mm", if the time is >1 hour { word hours = sec/3600UL; byte minutes = (sec/60UL) % 60UL; //numberOfMinutes(val); byte seconds = sec % 60UL; //numberOfSeconds(val); word first,second; //only 2 numbers are displayed: either hours:minutes or minutes:seconds if(hours>0) {first=hours; second=minutes;} else {first=minutes; second=seconds;} if(first<10) lcd.print(MY_F("0")); lcd.print(first); lcd.print(MY_F(":")); if(second<10) lcd.print(MY_F("0")); lcd.print(second); }
static void display_16x2_view_environment() { #if defined(SUPPORT_BMP085) || defined(SUPPORT_DSPC01) lcd.setCursor(0,0); lcd.print(MY_F("Temp: ")); lcd.print((int)temperature); lcd.print(MY_F(" C")); lcd.setCursor(0,1); // switch between altitude and slope very five seconds byte current_second = (millis() / 1000) % 60UL; if (current_second % 5 == 0) show_altitude = !show_altitude; if (show_altitude) { lcd.print(MY_F("Altitude: ")); lcd.print((int)altitude); lcd.print(MY_F("m")); lcd.print(MY_F(" ")); } else { lcd.print(MY_F("Slope: ")); lcd.print(slope,0); lcd.print(MY_F("% ")); } #endif }
static void display_16x2_view_time() { lcd.setCursor(0,0); lcd.print(MY_F("Time: ")); printTime(millis() / 1000UL); //millis can be used, because they roll over only after 50 days #ifdef SUPPORT_RTC lcd.setCursor(0,1); lcd.print("Clock: "); if (now.hh<10) lcd.print(MY_F("0")); lcd.print(now.hh); lcd.print(MY_F(":")); if (now.mm<10) lcd.print(MY_F("0")); lcd.print(now.mm); #endif }
static void display_16x2_view_main() { /* // DEBUG code spd = 25; power = 198; battery_percent_fromcapacity = 21; km = 137.8; */ lcd.setCursor(0,0); if (spd<10) {lcd.print(MY_F(" "));} lcd.print(round(spd),0); lcd.print(MY_F(" km/h ")); double power_display = power; if (power_display > 999) power_display = 999; else if (power_display < 0) power_display = 0; if (power_display<10) {lcd.print(MY_F(" "));} if (power_display<100) {lcd.print(MY_F(" "));} if (power_display < 0) lcd.print(MY_F("0")); else lcd.print(power_display,0); lcd.print(MY_F(" W ")); // Break status if(brake_stat==0) lcd.write(0x01); else lcd.print(MY_F(" ")); lcd.setCursor(0,1); // Custom battery symbol lcd.write(0x02); lcd.print(battery_percent_fromcapacity); // Note: two extra spaces to clear chars when the capacity gets lower lcd.print(MY_F("% ")); lcd.setCursor(8,1); lcd.print(km,1); lcd.print(MY_F(" km")); }
static void display_nokia_setup() //first time setup of nokia display { #if (DISPLAY_TYPE & DISPLAY_TYPE_NOKIA) lcd.begin(84, 48); lcd.createChar(0, glyph1); lcd.createChar(1, glyph2); lcd.createChar(2, glyph3); lcd.setCursor(4,0); lcd.print(MY_F("V")); lcd.setCursor(13,0); lcd.print(MY_F("%")); lcd.setCursor(3,1); lcd.print(MY_F("W")); lcd.setCursor(12,1); lcd.print(MY_F("Wh")); lcd.setCursor(0,2); lcd.print(MY_F(" SPD KM CAD")); lcd.setCursor(12,4); lcd.write(0); lcd.write(1); #endif }
static void display_16x2_view_battery() { lcd.setCursor(0,0); lcd.print(voltage_display,1); lcd.print(MY_F(" V - ")); if ((current_display<9.5)&&(current_display>0)) {lcd.print(MY_F(" "));} lcd.print(current_display,1); lcd.print(MY_F(" A ")); lcd.setCursor(0,1); lcd.print(wh,0); lcd.print(MY_F(" wh")); lcd.print(MY_F(" ")); if (km > 0.1) lcd.print(wh/km,1); else lcd.print(MY_F("---")); lcd.print(MY_F(" AVG ")); }
static void handle_command() { // sanity check if (active_serial->number_pos == 0 || active_serial->cmd_index == -1) { active_serial_port->println(MY_F("ERROR")); return; } active_serial_port->print(serial_commands[active_serial->cmd_index].mnemonic); // Info command? if (active_serial->numberstring[0] == '?') { switch(active_serial->cmd_index) { case 0: //poti_stat active_serial_port->println(poti_stat); break; case 1: //total kilometers active_serial_port->println(odo/1000.0*wheel_circumference,0); break; case 4: //hours read #ifdef SUPPORT_RTC active_serial_port->println(now.hh); #endif break; case 5: //minutes read #ifdef SUPPORT_RTC active_serial_port->println(now.mm); #endif break; case 6: //seconds read #ifdef SUPPORT_RTC active_serial_port->println(now.ss); #endif break; case 7: //charge count read #ifdef SUPPORT_BATTERY_CHARGE_COUNTER active_serial_port->println(charge_count); #endif break; } return; } // Write command? switch(active_serial->cmd_index) { case 0: //poti_stat poti_stat = min(atoi(active_serial->numberstring)*1023.0/power_poti_max,1023); break; case 1: //total kilometers odo = atoi(active_serial->numberstring)*1000.0/wheel_circumference; save_eeprom(); break; case 2: //short button press handle_switch(static_cast<switch_name>(atoi(active_serial->numberstring)), 0, PRESSED_SHORT); break; case 3: //long button press handle_switch(static_cast<switch_name>(atoi(active_serial->numberstring)), 0, PRESSED_LONG); break; case 4: //hours write #ifdef SUPPORT_RTC rtc.adjust_time(atoi(active_serial->numberstring),now.mm,now.ss); #endif break; case 5: //minutes write #ifdef SUPPORT_RTC rtc.adjust_time(now.hh,atoi(active_serial->numberstring),now.ss); #endif break; case 6: //seconds write #ifdef SUPPORT_RTC rtc.adjust_time(now.hh,now.mm,atoi(active_serial->numberstring)); #endif break; case 7: //charge count write #ifdef SUPPORT_BATTERY_CHARGE_COUNTER charge_count=atoi(active_serial->numberstring); save_eeprom(); #endif break; } active_serial_port->println(MY_F("OK")); }
void parse_serial(const char &read_c, const byte port) { if (port==0) { active_serial=&serial_port1; active_serial_port=&Serial; } #if HARDWARE_REV>=20 else { active_serial=&serial_port2; active_serial_port=&Serial1; } #endif byte i; switch(active_serial->parse_state) { case Reset: memset(active_serial->cmdbuf, 0, sizeof(active_serial->cmdbuf)); memset(active_serial->numberstring, 0, sizeof(active_serial->numberstring)); active_serial->cmd_index = -1; active_serial->number_pos = 0; active_serial->parse_state = SearchCommand; // fall through to "search command" case SearchCommand: // skip return chars if (read_c == 10 || read_c == 13) { active_serial->parse_state = Reset; break; } if (active_serial->cmdbuf[0] == 0) { // store first character active_serial->cmdbuf[0] = read_c; } else { active_serial->cmdbuf[1] = read_c; // Look for valid commands if (find_commands() == true) active_serial->parse_state = StoreNumber; else active_serial->parse_state = ErrorWaitReturn; } break; case StoreNumber: if (read_c == 10 || read_c == 13) { // User input is done handle_command(); active_serial->parse_state = Reset; } else { // Store character if (active_serial->number_pos < sizeof(active_serial->numberstring)-1) // reserve one byte for the terminating zero (atoi()) { active_serial->numberstring[active_serial->number_pos] = read_c; ++active_serial->number_pos; } } break; case ErrorWaitReturn: if (read_c == 10 || read_c == 13) { active_serial_port->println(MY_F("ERROR")); active_serial->parse_state = Reset; } break; } }
static void display_nokia_update() { #if (DISPLAY_TYPE & DISPLAY_TYPE_NOKIA) lcd.setCursor(0,0); lcd.print(voltage_display,1); lcd.setCursor(6,0); if ((current_display<9.5)&&(current_display>0)) {lcd.print(MY_F(" "));} lcd.print(current_display,1); lcd.setCursor(10,0); if (battery_percent_fromcapacity<100) {lcd.print(MY_F(" "));} if (battery_percent_fromcapacity<9.5) {lcd.print(MY_F(" "));} lcd.print(battery_percent_fromcapacity); lcd.setCursor(0,1); if (power<99.5) {lcd.print(MY_F(" "));} if (power<9.5) {lcd.print(MY_F(" "));} lcd.print(power,0); lcd.setCursor(9,1); if (wh<99.5) {lcd.print(MY_F(" "));} if (wh<9.5) {lcd.print(MY_F(" "));} lcd.print(wh,0); lcd.setCursor(0,3); if (spd<9.5) {lcd.print(MY_F(" "));} lcd.print(spd,1); lcd.setCursor(5,3); if (km<99.5) {lcd.print(MY_F(" "));} if (km<9.5) {lcd.print(MY_F(" "));} lcd.print(km,1); lcd.setCursor(11,3); if (cad<100) {lcd.print(MY_F(" "));} if (cad<10) {lcd.print(MY_F(" "));} lcd.print(cad,10); lcd.setCursor(0,4); if ( spd > 5.0) lcd.print(power/spd,1); else lcd.print(MY_F("---")); lcd.print(MY_F("/")); if ( km > 0.1) lcd.print(wh/km,1); else lcd.print(MY_F("---")); lcd.print(MY_F(" ")); lcd.setCursor(0,5); //lcd.print(millis()/60000.0,1); //uncomment this to display minutes since startup //lcd.print(" Minuten"); #if defined(SUPPORT_BMP085) || defined(SUPPORT_DSPC01) //lcd.print(temperature,1); //lcd.print(" "); lcd.print(slope,0); lcd.print(MY_F("% ")); lcd.print((int)altitude); lcd.print(MY_F(" ")); #endif #ifdef SUPPORT_HRMI lcd.print((byte) pulse_human); lcd.print(MY_F(" ")); #endif lcd.print(range,0); lcd.print(MY_F("km ")); #if HARDWARE_REV >=2 lcd.setCursor(13,5); if (digitalRead(bluetooth_pin)==1) {lcd.write(2);} else {lcd.print(MY_F(" "));} #endif #endif // (DISPLAY_TYPE & DISPLAY_TYPE_NOKIA) }
void parse_serial(const char &read_c) { byte i; switch(parse_state) { case Reset: memset(cmdbuf, 0, sizeof(cmdbuf)); memset(numberstring, 0, sizeof(numberstring)); cmd_index = -1; number_pos = 0; parse_state = SearchCommand; // fall through to "search command" case SearchCommand: // skip return chars if (read_c == 10 || read_c == 13) { parse_state = Reset; break; } if (cmdbuf[0] == 0) { // store first character cmdbuf[0] = read_c; } else { cmdbuf[1] = read_c; // Look for valid commands if (find_commands() == true) parse_state = StoreNumber; else parse_state = ErrorWaitReturn; } break; case StoreNumber: if (read_c == 10 || read_c == 13) { // User input is done handle_command(); parse_state = Reset; } else { // Store character if (number_pos < sizeof(numberstring)-1) // reserve one byte for the terminating zero (atoi()) { numberstring[number_pos] = read_c; ++number_pos; } } break; case ErrorWaitReturn: if (read_c == 10 || read_c == 13) { Serial.println(MY_F("ERROR")); parse_state = Reset; } break; } }