diff --git a/controller_teensy/include/definitions.h b/controller_teensy/include/definitions.h index b76adb5..7f97f44 100644 --- a/controller_teensy/include/definitions.h +++ b/controller_teensy/include/definitions.h @@ -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; diff --git a/controller_teensy/include/display.h b/controller_teensy/include/display.h index 3cc8ded..53b0e67 100644 --- a/controller_teensy/include/display.h +++ b/controller_teensy/include/display.h @@ -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(); diff --git a/controller_teensy/include/led.h b/controller_teensy/include/led.h index 233e688..000c67b 100644 --- a/controller_teensy/include/led.h +++ b/controller_teensy/include/led.h @@ -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 @@ -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; istrip.numPixels()){ //modulo for float + position-=strip.numPixels(); + } + for(int i=0; ithrottle_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