2023-03-02 21:05:48 +00:00
|
|
|
#ifndef _DISPLAY_H_
|
|
|
|
#define _DISPLAY_H_
|
|
|
|
|
|
|
|
#include <Wire.h>
|
|
|
|
#include <Adafruit_GFX.h>
|
|
|
|
#include <Adafruit_SSD1306.h>
|
2023-05-23 21:57:22 +00:00
|
|
|
#include <Fonts/FreeMonoBold18pt7b.h>
|
|
|
|
#include <Fonts/FreeSansBold9pt7b.h>
|
|
|
|
|
|
|
|
|
2023-03-02 21:05:48 +00:00
|
|
|
#define SCREEN_WIDTH 128 // OLED display width, in pixels
|
|
|
|
#define SCREEN_HEIGHT 32 // OLED display height, in pixels
|
|
|
|
|
|
|
|
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
|
|
|
|
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
|
|
|
|
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
|
|
|
|
|
2023-05-23 19:46:34 +00:00
|
|
|
bool display_init();
|
2023-06-02 17:18:21 +00:00
|
|
|
void display_update(ESCSerialComm& escFront, ESCSerialComm& escRear);
|
|
|
|
void display_drivingDisplay(ESCSerialComm& escFront, ESCSerialComm& escRear);
|
|
|
|
void display_standingDisplay(ESCSerialComm& escFront, ESCSerialComm& escRear);
|
2023-06-03 10:21:40 +00:00
|
|
|
void display_standingDisarmedDisplay(ESCSerialComm& escFront, ESCSerialComm& escRear);
|
2023-03-02 21:05:48 +00:00
|
|
|
|
2023-06-02 19:10:45 +00:00
|
|
|
void display_debugDisplay(ESCSerialComm& escFront, ESCSerialComm& escRear);
|
|
|
|
|
2023-05-23 21:57:22 +00:00
|
|
|
|
2023-05-23 19:46:34 +00:00
|
|
|
bool display_init(){
|
2023-03-02 21:05:48 +00:00
|
|
|
if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
|
|
|
|
Serial.println(F("SSD1306 allocation failed"));
|
2023-05-23 19:46:34 +00:00
|
|
|
return false;
|
2023-03-02 21:05:48 +00:00
|
|
|
}
|
|
|
|
display.clearDisplay();
|
2023-04-15 22:13:02 +00:00
|
|
|
display.setTextSize(1); // Normal 1:1 pixel scale
|
|
|
|
display.setTextColor(SSD1306_WHITE); // Draw white text
|
|
|
|
display.setCursor(0,0); // Start at top-left corner
|
2023-03-02 21:05:48 +00:00
|
|
|
display.display();
|
2023-05-23 19:46:34 +00:00
|
|
|
return true;
|
2023-03-02 21:05:48 +00:00
|
|
|
}
|
|
|
|
|
2023-05-23 20:01:07 +00:00
|
|
|
void display_update(ESCSerialComm& escFront, ESCSerialComm& escRear){
|
2023-03-02 21:05:48 +00:00
|
|
|
display.clearDisplay();
|
2023-05-23 21:57:22 +00:00
|
|
|
/*
|
2023-03-02 21:05:48 +00:00
|
|
|
display.setTextSize(1); // Normal 1:1 pixel scale
|
|
|
|
display.setTextColor(SSD1306_WHITE); // Draw white text
|
|
|
|
display.setCursor(0,0); // Start at top-left corner
|
2023-05-23 20:01:07 +00:00
|
|
|
display.print(F("Speed : ")); display.println((escFront.getMeanSpeed()+escRear.getMeanSpeed())/2.0);
|
2023-05-23 21:57:22 +00:00
|
|
|
display.print(F("Thr: ")); display.print(throttle_pos);
|
|
|
|
display.print(F(" Brk : ")); display.println(brake_pos);
|
2023-04-15 22:13:02 +00:00
|
|
|
display.print(F("Current : ")); display.println(filtered_currentAll);
|
2023-05-23 20:01:07 +00:00
|
|
|
display.print(F("Vbat : ")); display.print(escFront.getFeedback_batVoltage());
|
|
|
|
display.print(F(" / ")); display.println(escRear.getFeedback_batVoltage());
|
2023-05-23 21:57:22 +00:00
|
|
|
*/
|
|
|
|
|
2023-09-15 22:15:32 +00:00
|
|
|
if ( (error_brake_outofrange || error_throttle_outofrange || error_throttle_difftoohigh || error_ads_max_read_interval || error_sdfile_unavailable) && ((loopmillis/2000)%2==0)) {
|
2023-06-03 10:21:40 +00:00
|
|
|
//Error Messages
|
2023-06-02 17:18:21 +00:00
|
|
|
|
2023-06-03 10:21:40 +00:00
|
|
|
display.setFont();
|
|
|
|
display.setTextSize(1); // Normal 1:1 pixel scale
|
|
|
|
display.setTextColor(SSD1306_WHITE); // Draw white text
|
|
|
|
display.setCursor(0,0); // Start at top-left corner
|
|
|
|
display.print(F("Error!"));
|
|
|
|
display.println();
|
|
|
|
|
|
|
|
String errorstring="";
|
|
|
|
if (error_brake_outofrange) {
|
|
|
|
errorstring+="brake_outofrange\n";
|
|
|
|
}
|
|
|
|
if (error_throttle_outofrange) {
|
|
|
|
errorstring+="throttle_outofrange\n";
|
|
|
|
}
|
2023-09-15 22:15:32 +00:00
|
|
|
if (error_throttle_difftoohigh) {
|
|
|
|
errorstring+="throttle_difftoohigh\n";
|
|
|
|
}
|
2023-06-03 10:21:40 +00:00
|
|
|
if (error_ads_max_read_interval) {
|
|
|
|
errorstring+="ads_max_read_interval\n";
|
2023-07-10 14:25:19 +00:00
|
|
|
}if (error_sdfile_unavailable) {
|
|
|
|
errorstring+="error_sdfile_unavailable\n";
|
2023-06-03 10:21:40 +00:00
|
|
|
}
|
|
|
|
display.print(errorstring);
|
|
|
|
|
2023-06-02 17:18:21 +00:00
|
|
|
}else{
|
2023-06-03 10:21:40 +00:00
|
|
|
//Normal Display Routinges here
|
|
|
|
|
|
|
|
if (armed) {
|
|
|
|
if (loopmillis-last_notidle>5000) {
|
|
|
|
display_standingDisplay(escFront,escRear);
|
|
|
|
}else{
|
|
|
|
display_drivingDisplay(escFront,escRear);
|
|
|
|
//display_debugDisplay(escFront,escRear);
|
|
|
|
}
|
|
|
|
|
|
|
|
}else{
|
|
|
|
display_standingDisarmedDisplay(escFront,escRear);
|
|
|
|
}
|
2023-07-10 14:25:19 +00:00
|
|
|
|
2023-06-02 17:18:21 +00:00
|
|
|
}
|
|
|
|
|
2023-06-02 19:10:45 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
2023-06-02 17:18:21 +00:00
|
|
|
display.display();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void display_drivingDisplay(ESCSerialComm& escFront, ESCSerialComm& escRear) {
|
2023-06-02 19:10:45 +00:00
|
|
|
|
2023-06-02 17:18:21 +00:00
|
|
|
//## Km/h Display
|
2023-05-23 21:57:22 +00:00
|
|
|
display.setFont(&FreeMonoBold18pt7b);
|
|
|
|
display.setTextSize(1); // Normal 1:1 pixel scale
|
|
|
|
display.setTextColor(SSD1306_WHITE); // Draw white text
|
2023-06-02 17:18:21 +00:00
|
|
|
display.setCursor(0,SCREEN_HEIGHT-(SCREEN_HEIGHT-18)/2 - 3); // Start at top-left corner
|
2023-05-23 21:57:22 +00:00
|
|
|
|
2023-06-18 00:12:10 +00:00
|
|
|
//float _speeddisplay=(escFront.getMeanSpeed()+escRear.getMeanSpeed())/2.0*3.6;
|
|
|
|
float _speeddisplay=minSpeedms*3.6;
|
|
|
|
|
2023-05-23 21:57:22 +00:00
|
|
|
//_speeddisplay=(millis()/1000)%21; //debugging
|
|
|
|
char buf[8];
|
|
|
|
dtostrf(_speeddisplay,1,1,buf);
|
|
|
|
String strbuf=buf;
|
2023-05-23 20:01:07 +00:00
|
|
|
|
2023-05-23 21:57:22 +00:00
|
|
|
if (strbuf.length()<4) { //pad spaces on the left
|
|
|
|
strbuf=" "+strbuf;
|
|
|
|
}
|
|
|
|
display.print(strbuf);
|
2023-04-15 22:13:02 +00:00
|
|
|
|
2023-05-23 21:57:22 +00:00
|
|
|
display.setFont();
|
2023-06-02 17:18:21 +00:00
|
|
|
display.setCursor(SCREEN_WIDTH-25,SCREEN_HEIGHT-16);
|
2023-05-23 21:57:22 +00:00
|
|
|
display.print("km/h");
|
2023-06-02 17:18:21 +00:00
|
|
|
|
2023-06-03 10:50:29 +00:00
|
|
|
//A
|
2023-06-04 12:12:49 +00:00
|
|
|
display.setCursor(SCREEN_WIDTH-37,1);
|
2023-06-03 10:50:29 +00:00
|
|
|
static float averaged_filtered_currentAll;
|
2023-06-03 10:59:26 +00:00
|
|
|
#define CURRENT_FILTER 0.8
|
2023-06-03 10:50:29 +00:00
|
|
|
averaged_filtered_currentAll=averaged_filtered_currentAll*CURRENT_FILTER+(1-CURRENT_FILTER)*filtered_currentAll; //filter over time
|
2023-07-10 13:43:01 +00:00
|
|
|
float averaged_filtered_wattAll=averaged_filtered_currentAll*(escFront.getFeedback_batVoltage()+escRear.getFeedback_batVoltage())/2.0;
|
|
|
|
//dtostrf(averaged_filtered_currentAll,1,2,buf);
|
|
|
|
dtostrf(averaged_filtered_wattAll,1,0,buf);
|
2023-06-03 10:50:29 +00:00
|
|
|
strbuf=buf;
|
|
|
|
if (strbuf.length()<5) { //pad spaces on the left
|
|
|
|
strbuf=" "+strbuf;
|
|
|
|
}
|
|
|
|
display.print(strbuf);
|
2023-07-10 13:43:01 +00:00
|
|
|
//display.print("A");
|
|
|
|
display.print("W");
|
2023-06-03 10:50:29 +00:00
|
|
|
|
2023-06-02 17:18:21 +00:00
|
|
|
|
|
|
|
//## Trip / Current Consumed Display
|
|
|
|
display.setCursor(1,SCREEN_HEIGHT-7);
|
2023-06-02 19:10:45 +00:00
|
|
|
|
2023-06-02 17:18:21 +00:00
|
|
|
if (((millis()/2500)%2)==0) {
|
2023-06-04 12:12:49 +00:00
|
|
|
//## Speed statistic
|
|
|
|
display.print("max: ");
|
2023-06-03 10:21:40 +00:00
|
|
|
dtostrf(max_meanSpeed*3.6,1,0,buf);
|
2023-06-02 17:18:21 +00:00
|
|
|
display.print((String)buf);
|
2023-06-03 10:21:40 +00:00
|
|
|
display.print("km/h");
|
2023-06-02 17:18:21 +00:00
|
|
|
}else{
|
|
|
|
//## Current Consumed
|
2023-07-10 13:43:01 +00:00
|
|
|
/*
|
2023-06-03 10:21:40 +00:00
|
|
|
dtostrf(min_filtered_currentAll,1,1,buf);
|
2023-06-04 12:12:49 +00:00
|
|
|
display.print("min:");
|
2023-06-02 17:18:21 +00:00
|
|
|
display.print((String)buf);
|
2023-06-04 12:12:49 +00:00
|
|
|
display.print("A max:");
|
2023-06-02 17:18:21 +00:00
|
|
|
|
2023-06-03 10:21:40 +00:00
|
|
|
dtostrf(max_filtered_currentAll,1,1,buf);
|
2023-06-02 17:18:21 +00:00
|
|
|
display.print((String)buf);
|
2023-06-03 10:21:40 +00:00
|
|
|
display.print("A");
|
2023-07-10 13:43:01 +00:00
|
|
|
*/
|
|
|
|
//## Watt Hours Consumed
|
|
|
|
dtostrf(min_filtered_wattAll,1,0,buf);
|
|
|
|
display.print("min:");
|
|
|
|
display.print((String)buf);
|
|
|
|
display.print("W max:");
|
|
|
|
|
|
|
|
dtostrf(max_filtered_wattAll,1,0,buf);
|
|
|
|
display.print((String)buf);
|
|
|
|
display.print("W");
|
2023-06-02 17:18:21 +00:00
|
|
|
}
|
2023-06-02 19:10:45 +00:00
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void display_debugDisplay(ESCSerialComm& escFront, ESCSerialComm& escRear) {
|
|
|
|
//Debug
|
|
|
|
display.setTextSize(1); // Normal 1:1 pixel scale
|
|
|
|
display.setFont();
|
|
|
|
display.setTextColor(SSD1306_WHITE); // Draw white text
|
|
|
|
char buf[8];
|
|
|
|
|
|
|
|
display.setCursor(1,0);
|
|
|
|
dtostrf(filtered_currentAll,1,3,buf);
|
|
|
|
display.print((String)buf);
|
|
|
|
display.print(" A > ");
|
|
|
|
|
2023-06-02 17:18:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void display_standingDisplay(ESCSerialComm& escFront, ESCSerialComm& escRear) {
|
2023-06-18 00:12:10 +00:00
|
|
|
double _displaytrip=trip;
|
2023-07-10 13:43:01 +00:00
|
|
|
//double _displaycurrent=currentConsumed;
|
|
|
|
double _displaywatthours=watthoursConsumed;
|
2023-06-18 00:12:10 +00:00
|
|
|
bool _displayOverall= ((millis()/3000)%2==0);
|
|
|
|
if (_displayOverall) { //alternate between this trip and overall trip
|
|
|
|
_displaytrip=overallTrip;
|
2023-07-10 13:43:01 +00:00
|
|
|
//_displaycurrent=overallCurrentConsumed;
|
|
|
|
_displaywatthours=overallWatthoursConsumed;
|
2023-06-18 00:12:10 +00:00
|
|
|
}
|
|
|
|
|
2023-06-02 17:18:21 +00:00
|
|
|
char buf[8];
|
|
|
|
display.setFont();
|
|
|
|
display.setCursor(0,0);
|
|
|
|
|
2023-06-04 12:12:49 +00:00
|
|
|
display.print(F("Vbat:")); display.print(escFront.getFeedback_batVoltage());
|
2023-06-02 19:10:45 +00:00
|
|
|
display.print(F("/")); display.print(escRear.getFeedback_batVoltage());
|
2023-06-02 17:18:21 +00:00
|
|
|
display.print(" V");
|
|
|
|
display.println();
|
|
|
|
|
2023-06-13 21:45:17 +00:00
|
|
|
//display.print(F("Temp:")); display.print(escFront.getFeedback_boardTemp());
|
|
|
|
//display.print(F("/")); display.print(escRear.getFeedback_boardTemp());
|
|
|
|
display.print(F("T:")); display.print(temp_ESCFront,0);
|
|
|
|
display.print(F("/")); display.print(temp_ESCRear,0);
|
|
|
|
display.print(F("/")); display.print(temp_Air,0);
|
2023-06-03 10:21:40 +00:00
|
|
|
display.print(" C");
|
|
|
|
display.println();
|
|
|
|
|
2023-06-04 12:12:49 +00:00
|
|
|
display.print(F("Trip:"));
|
2023-06-18 00:12:10 +00:00
|
|
|
dtostrf(_displaytrip,1,0,buf);
|
2023-06-02 17:18:21 +00:00
|
|
|
display.print((String)buf);
|
2023-07-18 19:01:07 +00:00
|
|
|
display.print("m ");
|
2023-07-10 13:43:01 +00:00
|
|
|
//dtostrf(_displaycurrent,1,2,buf);
|
|
|
|
dtostrf(_displaywatthours,1,2,buf);
|
2023-06-02 17:18:21 +00:00
|
|
|
display.print((String)buf);
|
2023-07-10 13:43:01 +00:00
|
|
|
//display.print(" Ah");
|
2023-07-18 19:01:07 +00:00
|
|
|
display.print("Wh");
|
2023-06-02 17:18:21 +00:00
|
|
|
display.println();
|
|
|
|
|
2023-07-18 19:01:07 +00:00
|
|
|
display.print(F(""));
|
2023-07-10 13:43:01 +00:00
|
|
|
//dtostrf( _displaytrip/1000/_displaycurrent ,1,2,buf);
|
2023-07-18 19:01:07 +00:00
|
|
|
dtostrf( _displaywatthours/_displaytrip*100,1,2,buf);
|
2023-06-02 17:18:21 +00:00
|
|
|
display.print((String)buf);
|
2023-07-10 13:43:01 +00:00
|
|
|
//display.print(" km/Ah");
|
2023-07-18 19:01:07 +00:00
|
|
|
display.print(" kWh/100km");
|
2023-06-04 12:12:49 +00:00
|
|
|
|
2023-06-18 00:12:10 +00:00
|
|
|
if (_displayOverall){
|
|
|
|
display.print(" sum");
|
|
|
|
}
|
|
|
|
|
2023-06-04 12:12:49 +00:00
|
|
|
|
2023-06-02 17:18:21 +00:00
|
|
|
display.println();
|
2023-06-03 10:21:40 +00:00
|
|
|
|
2023-03-02 21:05:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-06-03 10:21:40 +00:00
|
|
|
void display_standingDisarmedDisplay(ESCSerialComm& escFront, ESCSerialComm& escRear) {
|
2023-06-02 17:18:21 +00:00
|
|
|
//Displayed stuff here when escs are powered off / disconnected
|
|
|
|
char buf[8];
|
|
|
|
display.setFont();
|
|
|
|
display.setCursor(0,0);
|
|
|
|
|
|
|
|
display.print(getLogFilename());
|
|
|
|
|
|
|
|
display.print(F(" ")); display.print(loopmillis/1000);
|
|
|
|
display.print(F("s"));
|
|
|
|
display.println();
|
|
|
|
|
|
|
|
display.print(F("ESC F="));
|
|
|
|
display.print(escFront.getControllerConnected());
|
|
|
|
display.print(F(" R="));
|
|
|
|
display.print(escRear.getControllerConnected());
|
|
|
|
display.println();
|
|
|
|
|
|
|
|
|
|
|
|
display.print("throttle=");
|
|
|
|
dtostrf(ads_throttle_A_raw,1,0,buf);
|
|
|
|
display.print((String)buf);
|
|
|
|
display.print("/");
|
|
|
|
dtostrf(ads_throttle_B_raw,1,0,buf);
|
|
|
|
display.print((String)buf);
|
|
|
|
display.println();
|
|
|
|
|
|
|
|
display.print("brake=");
|
|
|
|
dtostrf(ads_brake_raw,1,0,buf);
|
|
|
|
display.print((String)buf);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2023-03-02 21:05:48 +00:00
|
|
|
#endif
|