more display infos and led ring updates
This commit is contained in:
parent
14ecb8aa8f
commit
8db5cbbac9
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue