more display infos and led ring updates

This commit is contained in:
interfisch 2023-06-03 12:21:40 +02:00
parent 14ecb8aa8f
commit 8db5cbbac9
4 changed files with 143 additions and 51 deletions

View File

@ -75,8 +75,8 @@ int16_t max_acceleration_rate=NORMAL_MAX_ACCELERATION_RATE; //maximum cmd send i
//Driving parameters
int16_t minimum_constant_cmd_reduce=1; //reduce cmd every loop by this constant amount when freewheeling/braking
int16_t brake_cmdreduce_proportional=500; //cmd gets reduced by an amount proportional to brake position (ignores freewheeling). cmd_new-=brake_cmdreduce_proportional / second @ full brake. with BREAK_CMDREDUCE_CONSTANT=1000 car would stop with full brake at least after a second (ignoring influence of brake current control/freewheeling)
float startbrakecurrent=3; //Ampere. "targeted brake current @full brake". at what point to start apply brake proportional to brake_pos. for everything above that cmd is reduced by freewheel_break_factor
float startbrakecurrent_offset=0.07; //offset start point for breaking, because of reading fluctuations around 0A. set this slightly above idle current reading
float startbrakecurrent=2; //Ampere. "targeted brake current @full brake". at what point to start apply brake proportional to brake_pos. for everything above that cmd is reduced by freewheel_break_factor
float startbrakecurrent_offset=0.15; //offset start point for breaking, because of reading fluctuations around 0A. set this slightly above idle current reading
bool reverse_enabled=false;
unsigned long last_notidle=0; //not rolling to fast, no pedal pressed
@ -96,6 +96,13 @@ unsigned long last_notidle=0; //not rolling to fast, no pedal pressed
float filtered_currentAll=0;
//Statistics values
float max_filtered_currentAll;
float min_filtered_currentAll;
float max_meanSpeed;
int16_t cmd_send=0;
int16_t last_cmd_send=0;

View File

@ -19,7 +19,7 @@ bool display_init();
void display_update(ESCSerialComm& escFront, ESCSerialComm& escRear);
void display_drivingDisplay(ESCSerialComm& escFront, ESCSerialComm& escRear);
void display_standingDisplay(ESCSerialComm& escFront, ESCSerialComm& escRear);
void display_standingOffDisplay(ESCSerialComm& escFront, ESCSerialComm& escRear);
void display_standingDisarmedDisplay(ESCSerialComm& escFront, ESCSerialComm& escRear);
void display_debugDisplay(ESCSerialComm& escFront, ESCSerialComm& escRear);
@ -51,17 +51,42 @@ void display_update(ESCSerialComm& escFront, ESCSerialComm& escRear){
display.print(F(" / ")); display.println(escRear.getFeedback_batVoltage());
*/
if (escFront.getControllerConnected() && escRear.getControllerConnected()) {
if (loopmillis-last_notidle>5000) {
display_standingDisplay(escFront,escRear);
}else{
display_drivingDisplay(escFront,escRear);
//display_debugDisplay(escFront,escRear);
}
if ( (error_brake_outofrange || error_throttle_outofrange || error_ads_max_read_interval ) && ((loopmillis/2000)%2==0)) {
//Error Messages
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";
}
if (error_ads_max_read_interval) {
errorstring+="ads_max_read_interval\n";
}
display.print(errorstring);
}else{
display_standingOffDisplay(escFront,escRear);
//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);
}
}
@ -100,22 +125,19 @@ void display_drivingDisplay(ESCSerialComm& escFront, ESCSerialComm& escRear) {
if (((millis()/2500)%2)==0) {
//## Trip
dtostrf(escFront.getTrip(),1,0,buf);
display.print((String)buf);
display.print("m + ");
dtostrf(escRear.getTrip(),1,0,buf);
dtostrf(max_meanSpeed*3.6,1,0,buf);
display.print((String)buf);
display.print("m");
display.print("km/h");
}else{
//## Current Consumed
dtostrf(escFront.getCurrentConsumed(),1,1,buf);
dtostrf(min_filtered_currentAll,1,1,buf);
display.print((String)buf);
display.print("Ah + ");
display.print("A / ");
dtostrf(escRear.getCurrentConsumed(),1,1,buf);
dtostrf(max_filtered_currentAll,1,1,buf);
display.print((String)buf);
display.print("Ah");
display.print("A");
}
@ -145,6 +167,11 @@ void display_standingDisplay(ESCSerialComm& escFront, ESCSerialComm& escRear) {
display.print(" V");
display.println();
display.print(F("Temp: ")); display.print(escFront.getFeedback_boardTemp());
display.print(F("/")); display.print(escRear.getFeedback_boardTemp());
display.print(" C");
display.println();
display.print(F("Trip: "));
dtostrf(escFront.getTrip(),1,0,buf);
display.print((String)buf);
@ -155,18 +182,14 @@ void display_standingDisplay(ESCSerialComm& escFront, ESCSerialComm& escRear) {
display.println();
display.print(F("Cons. "));
dtostrf(escFront.getCurrentConsumed(),1,2,buf);
dtostrf(escFront.getCurrentConsumed()+escRear.getCurrentConsumed(),1,2,buf);
display.print((String)buf);
display.print("/");
dtostrf(escRear.getCurrentConsumed(),1,2,buf);
display.print((String)buf);
display.print(" Ah");
display.println();
}
void display_standingOffDisplay(ESCSerialComm& escFront, ESCSerialComm& escRear) {
void display_standingDisarmedDisplay(ESCSerialComm& escFront, ESCSerialComm& escRear) {
//Displayed stuff here when escs are powered off / disconnected
char buf[8];
display.setFont();

View File

@ -2,6 +2,18 @@
#define _LED_H_
//LED Ring Positions
/*
3 2 1
4 0
5 15
6 14
7 13
8 12
9 10 11
*/
#include <Adafruit_NeoPixel.h>
@ -20,7 +32,7 @@ unsigned long last_ledupdate=0;
uint8_t led_errorcount=0; //count led progress errors. used for delay at end if any errors occured
void led_dotcircle(unsigned long loopmillis);
void led_voltage(unsigned long loopmillis,float vbat,float vbat_min,float vbat_max);
void led_gauge(unsigned long loopmillis,float value,float value_min,float value_max,uint32_t colorGauge,uint32_t colorBG);
void init_led() {
strip.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
@ -89,39 +101,73 @@ void led_update(unsigned long loopmillis,ESCSerialComm& escFront, ESCSerialComm&
if (loopmillis>last_ledupdate+LEDUPDATEINTERVAL) {
last_ledupdate=loopmillis;
float vbat=min(escRear.getFeedback_batVoltage(),escFront.getFeedback_batVoltage());
if (error_brake_outofrange || error_throttle_outofrange || error_ads_max_read_interval) {
//Error
}else{
if (armed) {
if (loopmillis-last_notidle>5000) {
//Standing
float vbat=min(escRear.getFeedback_batVoltage(),escFront.getFeedback_batVoltage());
led_gauge(loopmillis,vbat,3*12,4.2*12,strip.Color(0, 255, 0, 0),strip.Color(100, 0, 0, 0));
}else{
//Driving
float currentMean=escRear.getFiltered_curL()+escRear.getFiltered_curR()+escFront.getFiltered_curL()+escFront.getFiltered_curR();
led_gauge(loopmillis,currentMean,0,16.0,strip.Color(0, 0, 0, 255),strip.Color(0, 0, 20, 0));
}
}else{
//Disarmed
led_dotcircle(loopmillis); //fill background with animation
uint32_t colorConnected=strip.Color(0, 255, 0, 0);
if (escFront.getControllerConnected()) {
for(int i=1; i<=3; i++) {
strip.setPixelColor(i, colorConnected);
}
}
if (escRear.getControllerConnected()) {
for(int i=1+8; i<=3+8; i++) {
strip.setPixelColor(i, colorConnected);
}
}
}
}
//led_dotcircle(loopmillis);
led_voltage(loopmillis,vbat,3*12,4.2*12);
strip.show(); // Update strip to match
}
}
void led_voltage(unsigned long loopmillis,float vbat,float vbat_min,float vbat_max) {
uint32_t colorBG=strip.Color(0, 255, 0, 0);
uint32_t colorEmpty=strip.Color(255, 0, 0, 0);
uint8_t position=map( max(min(vbat,vbat_max),vbat_min) ,vbat_min,vbat_max, 0,strip.numPixels()+1);
void led_gauge(unsigned long loopmillis,float value,float value_min,float value_max,uint32_t colorGauge,uint32_t colorBG) {
uint8_t position=map( max(min(value,value_max),value_min) ,value_min,value_max, 0,strip.numPixels()+1);
for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
uint8_t pp=(strip.numPixels()-i-1 + 10 )%strip.numPixels(); //Offset and invert
if (i<position) {
strip.setPixelColor(pp, colorBG); // Set pixel's color (in RAM)
strip.setPixelColor(pp, colorGauge); // Set pixel's color (in RAM)
}else{
strip.setPixelColor(pp, colorEmpty); // Set pixel's color (in RAM)
strip.setPixelColor(pp, colorBG); // Set pixel's color (in RAM)
}
}
}
void led_dotcircle(unsigned long loopmillis) {
uint32_t color=strip.Color(0, 0, 0, 255);
uint32_t colorOff=strip.Color(30, 0, 0, 0);
uint8_t position=(loopmillis/100)%strip.numPixels();
float position=(loopmillis/1000.0*strip.numPixels()/10.0);
while (position>strip.numPixels()){ //modulo for float
position-=strip.numPixels();
}
for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
if (i==position) {
strip.setPixelColor(i, color); // Set pixel's color (in RAM)
}else{
strip.setPixelColor(i, colorOff); // Set pixel's color (in RAM)
}
float _bright=min(abs(i-position),strip.numPixels()-abs(i-position));
_bright/=strip.numPixels()/2.0; //1 if position is at i, 0 if position is oposite of i in circle
_bright=pow(_bright,2);
uint32_t color=strip.Color(0, 0, 0, _bright*255);
strip.setPixelColor(i, color); // Set pixel's color (in RAM)
}
}

View File

@ -225,6 +225,17 @@ void loop() {
unsigned long _timediff=loopmillis-last_calculateSetSpeed;
last_calculateSetSpeed=loopmillis;
calculateSetSpeed(_timediff);
//Update Statistics
max_filtered_currentAll=max(max_filtered_currentAll,filtered_currentAll);
min_filtered_currentAll=min(min_filtered_currentAll,filtered_currentAll);
max_meanSpeed=max(max_meanSpeed,(escFront.getMeanSpeed()+escRear.getMeanSpeed())/2);
if (!armed) { //reset statistics if disarmed
max_filtered_currentAll=0;
min_filtered_currentAll=0;
max_meanSpeed=0;
}
}
escFront.update(loopmillis);
@ -399,8 +410,7 @@ void failChecks() {
if (loopmillis>throttle_ok_time+ADC_OUTOFRANGE_TIME) { //not ok for too long
if (!error_throttle_outofrange) {
error_throttle_outofrange=true;
writeLogComment(loopmillis, "Error Throttle ADC Out of Range");
writeLogComment(loopmillis, "Error Throttle ADC Out of Range");
}
//Serial.print("Error Throttle ADC Out of Range="); Serial.println(throttle_raw);
}
@ -445,7 +455,8 @@ void calculateSetSpeed(unsigned long timediff){
float filtered_currentFront=max(escFront.getFiltered_curL(),escFront.getFiltered_curR());
float filtered_currentRear=max(escRear.getFiltered_curL(),escRear.getFiltered_curR());
filtered_currentAll=max(filtered_currentFront,filtered_currentRear); //positive value is current Drawn from battery. negative value is braking current
filtered_currentAll=filtered_currentFront+filtered_currentRear; //positive value is current Drawn from battery. negative value is braking current
if (throttle_pos>=last_cmd_send) { //accelerating
cmd_send += constrain(throttle_pos-cmd_send,0,(int16_t)(max_acceleration_rate*(timediff/1000.0)) ); //if throttle higher than last applied value, apply throttle directly
@ -633,8 +644,13 @@ void readButtons() {
writeLogComment(loopmillis, "Disarmed by button");
}
if (button_start_longpress_flag) {
armed=true; //arm if button pressed long enough
writeLogComment(loopmillis, "Armed by button");
if (escFront.getControllerConnected() && escRear.getControllerConnected()) {
armed=true; //arm if button pressed long enough
writeLogComment(loopmillis, "Armed by button");
}else{
writeLogComment(loopmillis, "Unable to arm");
}
}
/* TODO: if works, remove this