C
Con_Air
- Dabei seit
- 09.06.2020
- Beiträge
- 108
- Reaktionspunkte
- 42
- Ort
- Duisburg / NRW
- Details E-Antrieb
- PROPHETE GRAVELER E-MTB 27,5"
const float gauge_val_threshold = 2; // to filter jitter around 0 should it exist
const float peak_decay_timescale = 1300; //[ms] for comping the influence of the next peak on avgpeak. The higher the value, the smoother the power curve (but more delay on changes)
const unsigned long max_time_between_peaks = 700; //[ms] if peaks are further apart than this, power will start decaying inbetween
const float nachlaufzeit_max = 1800; //linearly decrease, no support left after nachlaufzeit_max
float lastgaugeval = 0.0;
unsigned long lasttimest = 0;
unsigned long timelastpeakstart = 0;
float timebetweenpeakstarts = 0; //delta t between peaks. Float, because we do multiplacation (factor <1) with this
float peaktracking = 0; //keep track of peak values
float avgpeak = 0; //smoothed average of the last few peaks
bool wasrising = false;
float last_gauge_support_level = 0;
unsigned int emptycount = 0;
float calc_gauge_support(){
float gauge_support_level = 0;
if(mybionx.gauge_queue.empty() && emptycount < 3){ //if no new value arrived, keep the old for a short while (sometimes packets don't sync perfectly)
gauge_support_level = last_gauge_support_level;
emptycount++;
}
while(!mybionx.gauge_queue.empty()){ //implemented as queue, to make sure we don't miss any measuremnts for calculation, normally this should just be one elemnt
emptycount = 0;
if(mybionx.gauge_queue.front().timestamp > lasttimest){ //skip double data
unsigned long timest = mybionx.gauge_queue.front().timestamp;
float gaugeval = mybionx.gauge_queue.front().val;
float deltat = timest - lasttimest;
bool newstart = false;
if((gaugeval > lastgaugeval) && gaugeval > gauge_val_threshold){ //gauge value currently rising -> first half of sine
peaktracking = gaugeval; //keep track of the peak values
wasrising = true; //when we stopped rising, we reached a peak. Luckily there is very little noise, so no need for fancy filtering (so far)
if(timest-timelastpeakstart > 3000){ //after 3 seconds we can assume we restart pedaling -> immidiately support
avgpeak = gaugeval;
newstart = true;
}
}else{
if(wasrising){ //gauge was still rising the measurement befor -> this is the first measurement after a peak
timebetweenpeakstarts = lasttimest - timelastpeakstart; //use the last, because the last was the peak
float timefact = min((float)1.0, timebetweenpeakstarts/peak_decay_timescale); //should always be between 0 and 1, after 1.3 sec the last peak is irrelevant
avgpeak = avgpeak*(1-timefact) + peaktracking*timefact;
timelastpeakstart = lasttimest;
}
wasrising = false;
}
if(timest-timelastpeakstart < max_time_between_peaks || newstart || wasrising){ //wasrising: bei sehr langsamer kd auch wenn der nächste sinusberg nur im onset ist noch weiter untertützen
gauge_support_level= avgpeak;
}else{
gauge_support_level = max((float)0, last_gauge_support_level-(deltat)*100/nachlaufzeit_max ); //linearly decrease, no support after nachlaufzeit_max
}
last_gauge_support_level = gauge_support_level;
lasttimest = timest;
lastgaugeval = gaugeval;
}
mybionx.gauge_queue.pop(); //delete processed value from queue
}
return gauge_support_level;
}
schön zu hören, dass noch jemand mit einem BMT unterwegs ist, dann sind wir ja schon zu dritt.Und nachdem ich schon eine erste Probefahrt machen konnte
Freut mich zu hören, dass es jetzt bei dir funktioniert. Und es freut mich auch, dass ich nicht der einzige bin, der Zweifel daran hat, dass ein einfaches Filter erster Ordnung die Lösung sein kann. Diskussionen darüber wurden bisher allerdings abgebügelt mit "wir können das besser". Den Ansatz den du da gewählt hast hätte ich auch von vornherein implementiert. Vor allem sind meines Erachtens nach gesonderte (schnellere) Zeitverläufe nach einer Pause beim Anfahren und beim Aussetzen des Tretens wie du beschrieben hast nötig.es war tatsächlich so, dass CAN high und low vertauscht waren.
Auf die Schnelle fällt mir da nur ein:Bei höheren Geschwindigkeiten (>25kmh) geht die vom Motor gelieferte Leistung (REG_MOTOR_STATUS_POWER_METER 0x14) deutlich zurück, obwohl ich per level (0x09) (fast) Maximalleistung fordere. Bei 30 km/h gibts nur noch rund 65%.
Ich habe jetzt auch meine Platine fertig gelötet, allerdings auf Basis des ESP32
Hier noch der Code zu meiner Gauge Auswertung:
Aufgebaut ist er auf Lochraster und auf Basis eines ESP32 (weil ich den da hatte, schon kenne, und er Bluetooth direkt integriert hat).Mich würde noch einiges interessieren. Wie hast du deinen BMT aufgebaut, wie hoch war gauge_gain eingestellt und wie sind deine weiteren Erfahrungen z.B. bezüglich Anfahren und Gangwechsel?
MaxSpeed steht bei mir auf 50 (km/h) und 0xd3 auf umgerechnet ca. 3 km/h, ich denke die sind es daher leider nicht...Auf die Schnelle fällt mir da nur ein:
<reg id="maxSpeed" when="motor.rev.sw >= 76" type="scalar" persistent="yes" unit="km/h" protect="yes">
<addr>0x8b</addr>
</reg>
<reg id="maxSpeedDerateDelta" when="motor.rev.sw >= 97" type="scalar" factor="9.091" persistent="yes" unit="rpm" protect="yes">
<description>Speed before maxSpeed to start derating.</description>
<addr>0xd3</addr>
</reg>
Damit wird die "Weichheit" des Abregelns gemacht. Allerdings habe ich mit dem Parameter keine praktische Erfahrung.
Eins muss man aber immer noch im Auge behalten. Der Abstand der Betriebsspannung zur EMK des Motors wird mit höheren Drehzahlen immer kleiner und somit auch die theoretisch mögliche Leistung. Ob das in diesem Bereich schon eine Rolle spielt wäre für mich aber wieder Glaskugellesen.
Ich nutze die Arduino IDE für den ESP32 (mit Platformio und VS Code).Mit welcher Toolchain arbeitest du denn? Gibt es dein Projekt auch bei github o.ä.?
Ich weiß nicht, ob @reinosmart noch welche hat.Hast du eine Platine davon?
Ich habe das Wiki gerade noch mal etwas ausführlicher gemacht. Wenn dir die Infos nicht reichen, frage einfach noch mal nach!Die Frage ist auch, welche Software genau hochgeladen werden soll und wie mit welchen Tools und Schnittstellenkabeln?
Hab noch welcheIch weiß nicht, ob @reinosmart noch welche hat.
schicke mir bitte eine PNreinosmart, Kann ich dann einen bekommen? Welcher Preis und können Sie es nach Holland schicken?
Die Werte der Widerstände sind in der BOM zu finden und das Platinenlayout, wo welcher Widerstand sitzt, ist hier.gibt es dazu vielleicht noch eine Übersicht