Kommunikation zwischen C7 Display und Motorkontroller NCM Venice+ Das-Kit

Diskutiere Kommunikation zwischen C7 Display und Motorkontroller NCM Venice+ Das-Kit im Nabenmotoren Forum im Bereich Fertig-Pedelecs; Die Funktion Eco auf boost
M

markustoe

Dabei seit
27.06.2016
Beiträge
1.177
Punkte Reaktionen
623
Ort
LU
Details E-Antrieb
Stromer ST1X
Die Funktion Eco auf boost
 
T

Tschosef

Dabei seit
17.06.2021
Beiträge
8
Punkte Reaktionen
5
Die Funktion Eco auf boost

Halli hallo,

... verstehe ich Dich richtig, dass es kein ECO, NORMAL, BOOST mehr gibt? .....

Das ist nämlich mit ein Grund, warum ich mich mit dem Thema überhaupt beschäftige.... mein "RUNTERSCHALTEN" auf ECO (am L7 Display nach Code 8018) scheint tatsächlich keine spührbare Auswirkung zu haben, den Leon Support hab ich dazu noch nicht erreicht, daher hab ich mit Googeln angefangen und diesen Thread hier gefunden. Das hat dann dafür gesorgt dass ich das Bike behalten habe (spielte schon mit dem Gedanken es zurück zu schicken, bevor die ersten 10 km drauf sind).

Ich habe mittlerweile den ganzen Thread gründlich durchgelesen, und mir Notizen gemacht, usw. und bin am Programm-Basteln (bzw. nur nach Bedarf modifizieren)...
DENN... genau genommen ist es so, dass Töchterchen einen BAFANG Mittelmotor-Umbau hat (gedrosselt) und beim NCM ist nun Stufe 2 grad zu langsam und Stufe 3 grad zu schnell ;-) Ich möchte mir für Fahrt mit Tochter etwas feiner abgestufte Stufen erstellen (garnicht mal die Speed-Tunen wie es die meisten wollen).
Morgen kommt noch ein Logic-Analyzer, zu dem es hier im Thread einen Tipp gab... das macht dann das Leben noch ein wenig leichter.

TATSÄCHLICH ist ein Bafang-Mittelmotor-Umbau meiner Ansicht nach deutlich angenehmer zu verwenden, weil man für jede Stufe sowohl die Leistung als auch die Geschwindigkeit einstellen kann. Beim NCM Venice ist jede Stufe quasi sowas wie ein voreingestellter Tempomat, immer mit voller Power ..... das könnte ich beim Bafang auch "Simulieren" in dem ich quasi in jeder Stufe immer volle Power gebe... aber das is nix für Töchterchen ;-)

Wenn ich alleine Fahre ist das Venice für mich gut genug.... bisher hatte ich ja nur einen "voll-Eigenbau" mit einem 1000Watt Front-Motor in einem alten 26 Zoll Mountenbike von Skott, das war auch nicht schlecht, aber a) sehr unbequem, und b) irgendwie nicht so Stvo-mäßig ;-)

Viele Grüße
Erich
 
Hochsitzcola

Hochsitzcola

Dabei seit
04.09.2009
Beiträge
3.883
Punkte Reaktionen
3.754
Details E-Antrieb
Gazelle mit BionX IGH3 + OpenSource Firmware
DENN... genau genommen ist es so, dass Töchterchen einen BAFANG Mittelmotor-Umbau hat (gedrosselt) und beim NCM ist nun Stufe 2 grad zu langsam und Stufe 3 grad zu schnell ;-) Ich möchte mir für Fahrt mit Tochter etwas feiner abgestufte Stufen erstellen
Ich frage mich, warum noch kein NCM-Fahrer die offene Firmware ausprobiert hat. Die ermöglicht vollen Zugriff auf sämtliche Parameter und bietet vor allem die Möglichkeit, einen Drehmomentsensor anzuschließen, so dass man schneller wird, wenn man stärker reintritt und langsamer wird, wenn man weniger stark reintritt, wie sich das beim Fahrradfahren gehört....

Gruß
hochsitzcola
 
T

Tschosef

Dabei seit
17.06.2021
Beiträge
8
Punkte Reaktionen
5
Ich frage mich, warum ....
Halli hallo....

die Antwort ist womöglich simpel: weil es vermutlich nicht ganz so einfach durch zu führen ist, wie es nach deiner Erörterung erstmal klingt :)

Folge ich deinem Link (die Beschreibung ist von Dir, wie ich grad sehe), und lese dort schnell mal das eine oder andere durch, dann stolpere ich z.B. über folgende "Unwägbarkeiten":
1) ... das F in der Artikelnummer vom Controller.... sollte das dann auch auf einem NCM Controller zu finden sein? Woran erkenn ich ob der NCM Controller geeignet ist?
2) ... alternativ erkennbar am Prozessor, den Shunts... usw... ja das stimmt, wenn mal erstmal an den Controller rann kommt... also diese (laut diesem Thread) harte Vergussmasse muss also erstmal entsprechend entfernt werden..... hat das schon mal jemand geschafft? Hätte ich einen Controller "rumliegen"... würde ich mich da vielleicht rann trauen ;-)
3) Zitat: Bei einigen Fertigrädern hat die original Firmware einen Bootloader ..... „Unlock Controller“ darf in diesem Fall nicht geklickt werden, da sonst auch der Bootloader gelöscht wird...... ==> schön dass man das erst erkennt wenn es zu spät ist.... oder kann man das anders erkennen?
......
usw.... es wirkt auf mich (mit meinen mittel-schlechten Microcontroller-Fähigkeiten) einfach "unglaublich kompliziert" und ich habe die Vermutung, dass da die eine oder andere Falle auf mich warten würde :)
Darum mach ich das eben nicht ;-) ..... prinzipiell bin ich durchaus zufrieden, so wie das jetzt läuft.... ich bin heute gut mit dem Code weiter gekommen (dazu später mehr).

Eher würde ich mir einen neuen, anderen, passenden Controller kaufen (ggf. mit Display)... wo ich dann weis, bzw. nachlesen kann, wie es läuft und funktioniert.

viele Grüße
Erich
 
T

Tschosef

Dabei seit
17.06.2021
Beiträge
8
Punkte Reaktionen
5
Halli Hallo,

Zum eigentlichen Thema wollte ich noch schreiben:
Erstmal danke für den Tip mit dem billigen 8Kanal Datenlogger... der war sehr hilfreich. Damit erkennt man recht schnell ob der Code korrekt ist (Antwort vom Motor) oder eben nicht (keine Antwort)... und wenn etwas nicht passt, lässt sich damit hervorragend rausfinden, welches Byte denn "unerwartet anders" ist... man hat damit deutlich mehr überblick. Hätt ich mir schon lange kaufen sollen. (wenn ich an meine DMX Basteleien von früher denke.... hust).

Ich habe den Code (aus Post 180 glaub ich, ich müsst gucken) mittlerweile etwas abgeändert... nämlich:
1) sobald (wie schon gehabt) das Licht an ist, kann man für jede Unterstützungsstufe eine eigene V-Max angeben, (Ich habe mir eben die ersten 4 Stufen feiner gemacht.
2) das Low- und Highbyte der Prüfsumme wird im Programm ausgerechnet (anhand der 7 relevanten Bytes die tatsächlich an den Controller gesendet wurden)... somit ist die Radgröße auch egal, und man muss nicht für jede kleine Änderung erstmal mit Tabellen rum wursteln. Auch der Mode (ECO, NORMAL oder BOOST) ist damit egal.... wobei ich, wie schon erwähnt keinen Unterschied feststellen kann.
3) ... es geht alles soweit ganz gut, auch Daumengas (das hatte ich vom Bafang Umbausatz noch übrig).... je nach Beleuchtung nur bis 6 oder eben bis zur jeweiligen Max Geschwindigkeit der aktuell gewählten Stufe.

Morgen mach ich den Code mal "Sauber".... (Mehr erörterungen, usw.... Müll weg machen...) dann kann ich diesen gerne hier teilen.

Ich betreibe den code mit dem esp8266 .... an einem NCM Venice (ohne Plus) 28 Zoll, mit einem L7 Display.
Jetzt muss ich noch ein Gehäuse basteln, das Daumengas anständig hin bauen, und dann is gut.

viele Grüße
Erich
 
T

Tschosef

Dabei seit
17.06.2021
Beiträge
8
Punkte Reaktionen
5
Guten Morgen.....


wie ich sagte.... hier der Code, wie ich ihn aktuell nutze.... der macht aktuell bis auf das Daumengas (bis V-Max) eigentlich gar kein Tuning, eher eine Drosselung der unteren Stufen ... wer will kann sich gerne eigene V-Max Werte rein schreiben. Da die Prüfsumme im Code berechnet wird, sollte der für jede Radgröße und jeden Controller gehen. ich habe den auf einem ESP8266 drauf. Ich habe ein NCM Venice 28 Zoll.... mit einem L7 Display (links am Lenker mit den eingebauten Buttons)

Viele Grüße und danke an diesen Thread und deren Teilnehmer.

Code:
/*

L7-Diplay-Kommunikation, Tschosef stand 19.07.2021
Display sendet 12 byte, Controller antwortet mit 10 bytes, Display sendet nochmal 9 bytes
ACHTUNG: bei Ausgabe auf seriellem Monitor keine Geschwindigkeitsanzeige mehr!
Mit Daumengas bis V-Max sofern Licht am Display an
Checksumme berechnet sich im Programmlauf aus b1 - b7, wird aufgeteilt in High und Low Byte. ==> Reifengröße sollte daher egal sein.

12 Bytes Display:

b0: immer "3A"
b1: immer "2C"
b2: Power Stufe.... scheint bei mir aber keine Wirkung zu haben.
b3: Fahrstufe 0-6, ohne Hintergrundbeleuchtung "40" - "46", mit Hintergrundbeleuchtung "C0" - "C6"
b4: Endgeschwindigkeit "1A", also im Gegensatz zu früher die reale Geschwindigkeit dezimal umgerechnet = 26 km/h
b5: Raddurchmesser Low Byte
b6: Raddurchmesser High Byte
b7: Funktion Daumengas: "6" bedeutet bis 6kmh, "00" bedeutet bis V-Max (aus Byte b4 ??)
b8: Prüfsumme b1 + b2 + b3 + b4 + b6 + b7 Low Byte
b9: Prüfsumme High Byte
b10: immer "D" / CR
b11: immer "A" / LF, wenn ich allerdings die Reifengröße im Untermenü (Code 8018) änder, steht hier "E1" ???

*zu Raddurchmesser:
0xF2 = 242
==>  8 * 256 + 242 = 2.290
2.290 / 3,141 / 25,4 = 28,7" -> passt!   ?? woher kommt die 25,4 ??????


9 Bytes vom Display: (in diesem Code aber aktuell irrelevant)

b0: immer "3A"
b1: immer "18"
b2: hier wird bei jedem neuen Datensatz hochgezählt
b3: immer "1"
b4: immer "B"
b5: auch hier wird hochgezählt, das Byte ist immer b2 + 36
b6: immer "0"
b7: immer "D"
b8: immer "A"

Die bytes vom Controller habe ich mir noch nicht angesehen.

*/

#include <SoftwareSerial.h>
#define BAUD_RATE 9600


SoftwareSerial swSer1(12, 13, false);        //Software Seriell 1 auf GPIO12 und 13 an Pin 13 geht data weg zum Motor an Pin 12 kommt Data vom Display  ==> auf swSer1 empfangen wir die Displaydaten und Senden sie zum Motor
SoftwareSerial swSer2(14, 15, false);        //Software Seriell 2 auf GPIO14 und 15 an pin 14 kommt data vom Motor  ==> auf swSer2 empfangen wir die Motordaten

byte ReceifedByte = 0;   //Varible für empfangenes Byte
byte ReceifedByte2 = 0;    //Variable für Empfangenes Byte vom Motor-Controller (wird aktuell nicht genutzt)
byte SendByte = 0;  // Variable für zu sendendes Byte (an Motor-Controller)
int Pruefsumme = 0;  // Variable für Prüfsumme, 16Bit
byte ByteZaehler = 0;
byte PruefSummeLowByte = 0; // Variable für LowByte der Prüfsumme
byte PruefSummeHighByte = 0; // Variable für HighByte der Prüfsumme
byte MaxSpeed = 0x10; // Variable für die MaxGeschwindigkeit für die jeweilge Stufe
boolean tune = false;  // eigentlich eine "Hilfsvariable"... true, sobald etwas an den Bytes geändert wurde
boolean PruefSummeOK = false; //Hilfsvariable.... sobald eine neue Prüfsumme berechnet wurde, wird diese True, und ersetzt dann die alte Pruefsumme

boolean SerialOutput = false;                   //bei true werden die Daten an den seriellen Monitor gesendet
boolean SerialOutput2 = false;                   //bei true werden die Daten an den seriellen Monitor gesendet

void setup() {
  Serial.begin(BAUD_RATE);
  swSer1.begin(BAUD_RATE);
  swSer2.begin(BAUD_RATE);
}

void loop() {
  if (swSer1.available())                       // wenn neue serielle Daten anliegen
            { 
            ReceifedByte = swSer1.read();                         // receive byte in ReceifedByte speichern
                      
            if (ReceifedByte ==0x3A) { // wenn das Byte das erste Byte vom Display ist, Pruefsumme = 0, Bytezähler = 0 ... das 0te Byte zählt nicht mit bei der Pruefsumme
                  Pruefsumme = 0;
                  ByteZaehler = 0;
            }
          
            /* wenn das Licht an ist.. also die Fahrstufe mit einem C begintt...  wird tune = true setzt, weil eben (später) der Datensatz verändert wird... die Variable für die Fahrsrufe wird hier (bei mir) nicht verändert, wer will kann das ja machen
            ich speichere mir hier schon mal die MaxSpeed in einer entsprechender Variable gem:
            kmh Dezimal ==> Hex .... vermutlig ist aber die Umwandlung eigentlich garnicht nötig... aber egal, jetzt stehts schon da.
            16 ==>0x10
            18 ==>0x12
            19 ==>0x13
            20 ==>0x14
            23 ==>0x17
            26 ==>0x1A*/
            if (ReceifedByte == (0xC1))                           // wenn Fahrstufe 1 aktiviert
                    {
                      SendByte = 0xC1;                              // sendbyte bleibt auf Fahrstufe 1
                      MaxSpeed = 0x10;                          // MaxSpeed setzen (gem. Tabelle oben)
                      tune = true;                            // "Tuning" ist aktiv
                    }
              else if (ReceifedByte == (0xC2))                           // wenn Fahrstufe 2 aktiviert
                    {
                      SendByte = 0xC2;                              // sendbyte auf Fahrstufe 2
                      tune = true;                                  // usw.
                      MaxSpeed = 0x12;
                      // "Tuning" ist aktiv
                    }
              else if (ReceifedByte == (0xC3))                           // wenn Fahrstufe 3 aktiviert
                    {
                      SendByte = 0xC3;                              // sendbyte auf Fahrstufe 3
                      tune = true;
                      MaxSpeed = 0x13;
                      // "Tuning" ist aktiv
                    }
              else if (ReceifedByte == (0xC4))                           // wenn Fahrstufe 4 aktiviert
                    {
                      SendByte = 0xC4;                              // sendbyte auf Fahrstufe 4
                      tune = true;
                      MaxSpeed = 0x14;
                      // "Tuning" ist aktiv
                    }
              else if (ReceifedByte == (0xC5))                           // wenn Fahrstufe 5 aktiviert
                    {
                      SendByte = 0xC5;                              // sendbyte auf Fahrstufe 5
                      tune = true;
                      MaxSpeed = 0x17;
                      // "Tuning" ist aktiv
                    }
              else if (ReceifedByte == (0xC6))                           // wenn Fahrstufe 6 aktiviert
                    {
                      SendByte = 0xC6;                              // sendbyte auf Fahrstufe 6
                      tune = true;
                      MaxSpeed = 0x1A;                              //1A entspricht den originalen 26 kmh... wer möchte kann auch 0x2D eintragen, was 45 kmh entspricht
                      // "Tuning" ist aktiv
                    }
          
              // Wenn tune = true ist (also das licht an ist)... wird hier das Daumengas auf V Max gestellt, anstatt auf 6 kmh
              else if ((ReceifedByte == (0x06)) &&  (tune == true)) // Wenn das Byte für Daumengas max 6 kmh empfangen wurde, für alle Fahrstufen auf V-Max ändern
                    {
                      SendByte = 0x00;                              // sendbyte auf alle Fahrstufe ändern
                    }
            
              // wenn tune = true ist, kann hier das Byte für die Gewschwindigkeit abgefangen (normalerweise 26 kmh?...  und dafür 45 kmh gesetzt (eben 0x2D).... ich setze die Geschw. auf den Wert der Variable MaxSpeed... wer möchte könnte sich oben die 45 kmh eintragen
              // "Original" wird hier scheinbar IMMER 1A in jeder Stufe gesendet !!!! ....
              else if ((ReceifedByte == (0x1A)) && (tune == true))  // wenn Tuning aktiv und das byte für die Maximalgeschwindigkeit kommt
                    {
                      SendByte = MaxSpeed ;          // die max. Geschwindigkeit gemäs Variable anpassen
                    }

              // neu: wenn hier PruefSummeOK = true ist, dann wurden insgesammt alle 7 notwendigen Bytes empfangen und ggf. Modifiziert. Das jetzt gerade empfangene Byte ist das originale LowByte der PruefSumme,
              // das ignorieren wir  aber jetzt, und setzen stattdessen das neue LowByte ein. Low und Highbyte wurde etwas weiter unten berechnet.
              else if ((PruefSummeOK == true) && (ByteZaehler == 8)){
                      SendByte = PruefSummeLowByte; // das neu errechnete LowByte verwenden
                      PruefSummeLowByte = 0 ;
                    }
              // gleiches Spiel mit dem Highbyte ...
              else if ((PruefSummeOK == true) && (ByteZaehler == 9)) {
                      SendByte = PruefSummeHighByte; // das neu errechnete HighByte verwenden
                      PruefSummeHighByte = 0 ;
                      PruefSummeOK = false;
                      tune = false;   //  sobald das HighByte für die Pruefsumme durch ist, wird nix mehr am Datensatz verändert
                    }
                  
              // alle anderen Bytes, die nicht bekannt/relevant oder sonstiges sind, einfach "durchreichen"
              else 
                    {
                      SendByte = ReceifedByte;
                    }

               // Berechnung der Prüfsumme .....  Byte 0 wird ignoiert, Byte 1 bis 7 aufaddiert, und dann in Low und Highbyte geteilt
               if (ByteZaehler > 0) {   //erst ab Byte 1 aufaddieren
                    Pruefsumme = Pruefsumme + SendByte;  // Wir addieren die zu sendenden Bytes
                   }
               ByteZaehler = ByteZaehler + 1; // einfach ein Zähler, zur Orientierung
                  
               if (ByteZaehler == 8) { // jetzt wurden 7+1 Bytes empfangen, für das Nächste Byte brauchen wir die  neue Pruefsumme, daraus Lowbyte und Highbyte ermitteln
                        PruefSummeLowByte = lowByte(Pruefsumme);
                        PruefSummeHighByte = highByte(Pruefsumme);
                        PruefSummeOK  = true ;  // ein Merker, der zeigt, dass die neue Prüfsumme bereit steht
                    }

          
             swSer1.write(SendByte);                           // byte an den Controller senden
        
                
              if (SerialOutput == true)
              {
                Serial.print("received: ");
                Serial.print(ReceifedByte, HEX);
                Serial.print("  new: ");
                Serial.println(SendByte, HEX);
              }

        } // Ende von if SerialData vorhanden
}
 
B

bikes0r

Dabei seit
13.08.2021
Beiträge
1
Punkte Reaktionen
0
Also liebe Community ich muss mich mal für diesen Thread bedanken. Habe mein Bike Moscow Plus 48V, mit circa 2000 km auf der Uhr, letztes Jahr im September nach diesem Leitfaden optimiert und bin seitdem weitere 2000 km gefahren. Vorher war es OK und hatte seine Macken, vor allem, wenn man mal schnell einen Berg runtergefahren ist und dann wieder langsamer als 25km/h geworden ist hat es teilweise ewig gedauert bis die Unterstützung wieder angesprungen ist. Manchmal ist die Geschwindigkeit unter 20km/h gefallen bis das Fahrrad sich erbarmt hat wieder zu unterstützen.
Jetzt macht es einfach nur mega viel Spaß. Der max-speed mit vollem Akku liegt so bei guten 35kmh bei lockerem Treten. Wenn man nachhilft sind auch knapp 40km/h drin.
Wenn der Akku leer wird, also so bei 50% Ladeanzeige, sind noch 30km/h mit lockerem Treten drin. Die Reichweite reicht noch locker für 50km.
 
G

Geini82

Dabei seit
27.08.2021
Beiträge
3
Punkte Reaktionen
0
Guten Morgen.....


wie ich sagte.... hier der Code, wie ich ihn aktuell nutze.... der macht aktuell bis auf das Daumengas (bis V-Max) eigentlich gar kein Tuning, eher eine Drosselung der unteren Stufen ... wer will kann sich gerne eigene V-Max Werte rein schreiben. Da die Prüfsumme im Code berechnet wird, sollte der für jede Radgröße und jeden Controller gehen. ich habe den auf einem ESP8266 drauf. Ich habe ein NCM Venice 28 Zoll.... mit einem L7 Display (links am Lenker mit den eingebauten Buttons)

Viele Grüße und danke an diesen Thread und deren Teilnehmer.
Hallo und von mir erstmal riesen Dank an alle Mitwirkenden!

Meine Frau hält mich, dank euch nun für komplett bescheuert 🙃 Jetzt steht der Kerl mit dem Laptop in der Garage und "programmiert" an seinem Fahrrad rum :LOL::X3:
Ich werkel grad an nem NCM Milano 26 Zoll 48V rum und versuch den esp8266 (D1 mini MOD 12-F) zum laufen zu kriegen.

Habe derzeit den Code von Tschosef (#206) drauf, aber ich kriege den V-Max und die Fahrstufen nicht geändert.
Geschwindigkeit und Akku werden angezeigt, sonst bislang auch nix ungewöhnliches bemerkt.

Hier der Auszug aus dem Serial Monitor
16:38:35.885 -> received: 3A new: 3A
16:38:35.885 -> received: 2C new: 2C
16:38:35.931 -> received: B new: B
16:38:35.931 -> received: C6 new: C6
16:38:35.931 -> received: 1A new: 2D
16:38:35.978 -> received: A8 new: A8
16:38:36.025 -> received: 7 new: 7
16:38:36.025 -> received: 6 new: 0
16:38:36.025 -> received: CC new: D9
16:38:36.072 -> received: 1 new: 1
16:38:36.072 -> received: D new: D
16:38:36.119 -> received: A new: A
Wenn ich das richtig sehe, ist die Prüfsumme auch richtig berechnet:
Fahrstufe 6+Licht @45kmh
Jedenfalls, wenn ich das mit der Berechung richtig verstanden hatte und mich die Tabelle aus #93 nicht noch mehr verwirrt hat :unsure:

Ich hab zwar das Gefühl, dass er mit Tuning (Licht) besser anzieht.. aber das kann auch Einbildung sein..
Aber ich hatte Testweise auch mal Stufe 1-5, mit 16-20Kmh belegt, und das hat er auch nicht genommen (waren immernoch die Standard Stufen)

Was kann ich denn jetzt machen, um das Problem zu identifizieren?
(Ich habe zwar ein Paar codes ausprobiert, aber das war dann nur wilde rumprobiererei ohne wirklichen Sinn und Verstand - Aber selbes Ergebniss)

Wenn ich die Tage die Zeit finde, werd ich auch noch mal einen der frühere Codes Probieren, die Checksum errechnen und händisch eintragen..

Hier nochmal den Code, den ich jetzt letztendlich benutzt hatte:
Code:
/*

L7-Diplay-Kommunikation, Tschosef stand 19.07.2021
Display sendet 12 byte, Controller antwortet mit 10 bytes, Display sendet nochmal 9 bytes
ACHTUNG: bei Ausgabe auf seriellem Monitor keine Geschwindigkeitsanzeige mehr!
Mit Daumengas bis V-Max sofern Licht am Display an
Checksumme berechnet sich im Programmlauf aus b1 - b7, wird aufgeteilt in High und Low Byte. ==> Reifengröße sollte daher egal sein.

12 Bytes Display:

b0: immer "3A"
b1: immer "2C"
b2: Power Stufe.... scheint bei mir aber keine Wirkung zu haben.
b3: Fahrstufe 0-6, ohne Hintergrundbeleuchtung "40" - "46", mit Hintergrundbeleuchtung "C0" - "C6"
b4: Endgeschwindigkeit "1A", also im Gegensatz zu früher die reale Geschwindigkeit dezimal umgerechnet = 26 km/h
b5: Raddurchmesser Low Byte
b6: Raddurchmesser High Byte
b7: Funktion Daumengas: "6" bedeutet bis 6kmh, "00" bedeutet bis V-Max (aus Byte b4 ??)
b8: Prüfsumme b1 + b2 + b3 + b4 + b6 + b7 Low Byte
b9: Prüfsumme High Byte
b10: immer "D" / CR
b11: immer "A" / LF, wenn ich allerdings die Reifengröße im Untermenü (Code 8018) änder, steht hier "E1" ???

*zu Raddurchmesser:
0xF2 = 242
==>  8 * 256 + 242 = 2.290
2.290 / 3,141 / 25,4 = 28,7" -> passt!   ?? woher kommt die 25,4 ??????


9 Bytes vom Display: (in diesem Code aber aktuell irrelevant)

b0: immer "3A"
b1: immer "18"
b2: hier wird bei jedem neuen Datensatz hochgezählt
b3: immer "1"
b4: immer "B"
b5: auch hier wird hochgezählt, das Byte ist immer b2 + 36
b6: immer "0"
b7: immer "D"
b8: immer "A"

Die bytes vom Controller habe ich mir noch nicht angesehen.

*/

#include <SoftwareSerial.h>
#define BAUD_RATE 9600


SoftwareSerial swSer1(12, 13, false);        //Software Seriell 1 auf GPIO12 und 13 an Pin 13 geht data weg zum Motor an Pin 12 kommt Data vom Display  ==> auf swSer1 empfangen wir die Displaydaten und Senden sie zum Motor
SoftwareSerial swSer2(14, 15, false);        //Software Seriell 2 auf GPIO14 und 15 an pin 14 kommt data vom Motor  ==> auf swSer2 empfangen wir die Motordaten

byte ReceifedByte = 0;   //Varible für empfangenes Byte
byte ReceifedByte2 = 0;    //Variable für Empfangenes Byte vom Motor-Controller (wird aktuell nicht genutzt)
byte SendByte = 0;  // Variable für zu sendendes Byte (an Motor-Controller)
int Pruefsumme = 0;  // Variable für Prüfsumme, 16Bit
byte ByteZaehler = 0;
byte PruefSummeLowByte = 0; // Variable für LowByte der Prüfsumme
byte PruefSummeHighByte = 0; // Variable für HighByte der Prüfsumme
byte MaxSpeed = 0x2D; // Variable für die MaxGeschwindigkeit für die jeweilge Stufe
boolean tune = false;  // eigentlich eine "Hilfsvariable"... true, sobald etwas an den Bytes geändert wurde
boolean PruefSummeOK = false; //Hilfsvariable.... sobald eine neue Prüfsumme berechnet wurde, wird diese True, und ersetzt dann die alte Pruefsumme

boolean SerialOutput = false;                   //bei true werden die Daten an den seriellen Monitor gesendet
// boolean SerialOutput2 = false;                   //bei true werden die Daten an den seriellen Monitor gesendet

void setup() 
{
  Serial.begin(BAUD_RATE);
  swSer1.begin(BAUD_RATE);
  swSer2.begin(BAUD_RATE);
}

void loop() 
{
    if (swSer1.available())                     // wenn neue serielle Daten anliegen
    { 
        ReceifedByte = swSer1.read();           // receive byte in ReceifedByte speichern
                  
        if (ReceifedByte ==0x3A)                  // wenn das Byte das erste Byte vom Display ist, Pruefsumme = 0, Bytezähler = 0 ... das 0te Byte zählt nicht mit bei der Pruefsumme
        {
            Pruefsumme = 0;
            ByteZaehler = 0;
        }
      
            /* 
            wenn das Licht an ist.. also die Fahrstufe mit einem C begintt...  wird tune = true setzt, weil eben (später) der Datensatz verändert wird... die Variable 'MaxSpeed' für die Fahrsrufe kann hier angepasst werden!
            ich speichere mir hier schon mal die MaxSpeed in einer entsprechender Variable gem:
            kmh Dezimal ==> Hex .... vermutlig ist aber die Umwandlung eigentlich garnicht nötig... aber egal, jetzt stehts schon da.
            16 ==>0x10
            18 ==>0x12
            19 ==>0x13
            20 ==>0x14
            23 ==>0x17
            26 ==>0x1A
            */
        
        if (ReceifedByte == (0xC1))                            // wenn Fahrstufe 1 aktiviert + Licht an ('C')
        {
            SendByte = 0xC1;                                      // sendbyte bleibt auf Fahrstufe 1
            tune = true;                                        // "Tuning" ist aktiv
            MaxSpeed = 0x10;                                      // MaxSpeed setzen (gem. Tabelle oben)
        }
        else if (ReceifedByte == (0xC2))                       // wenn Fahrstufe 2 aktiviert + Licht an ('C')
        {
            SendByte = 0xC2;                                      // sendbyte auf Fahrstufe 2
            tune = true;                                        // "Tuning" ist aktiv
            MaxSpeed = 0x12;                                    // MaxSpeed setzen (gem. Tabelle oben)
        }
        else if (ReceifedByte == (0xC3))                    // wenn Fahrstufe 3 aktiviert + Licht an ('C')
        {
            SendByte = 0xC3;                                      // sendbyte auf Fahrstufe 3
            tune = true;                                        // "Tuning" ist aktiv
            MaxSpeed = 0x13;                                    // MaxSpeed setzen (gem. Tabelle oben)
        }
        else if (ReceifedByte == (0xC4))                    // wenn Fahrstufe 4 aktiviert + Licht an ('C')
        {
            SendByte = 0xC4;                                      // sendbyte auf Fahrstufe 4
            tune = true;                                        // "Tuning" ist aktiv
            MaxSpeed = 0x14;                                    // MaxSpeed setzen (gem. Tabelle oben)
        }
        else if (ReceifedByte == (0xC5))                    // wenn Fahrstufe 5 aktiviert + Licht an ('C')
        {
            SendByte = 0xC5;                                      // sendbyte auf Fahrstufe 5
            tune = true;                                        // "Tuning" ist aktiv
            MaxSpeed = 0x17;                                    // MaxSpeed setzen (gem. Tabelle oben)
        }
        else if (ReceifedByte == (0xC6))                    // wenn Fahrstufe 6 aktiviert + Licht an ('C')
        {
            SendByte = 0xC6;                                      // sendbyte auf Fahrstufe 6
            tune = true;                                        // "Tuning" ist aktiv
            MaxSpeed = 0x2D;                                     // 19 = 25 kmh, 1A = 26 kmh, 36 = 24 kmh, 2D = 45 kmh
        }
      
        // Wenn tune = true ist (also das licht an ist)... wird hier das Daumengas auf V Max gestellt, anstatt auf 6 kmh
        else if ((ReceifedByte == (0x06)) &&  (tune == true)) // Wenn das Byte für Daumengas max 6 kmh empfangen wurde, für alle Fahrstufen auf V-Max ändern
        {
            SendByte = 0x00;                              // sendbyte auf alle Fahrstufe ändern
        }
    
        // wenn tune = true ist, kann hier das Byte für die Gewschwindigkeit abgefangen (25 oder 26 Km/h)  und dafür 45 kmh gesetzt (eben 0x2D).... ich setze die Geschw. auf den Wert der Variable MaxSpeed... wer möchte könnte sich oben die 45 kmh eintragen
        else if ( ( (ReceifedByte == (0x1A)) || (ReceifedByte == (0x19)) ) && (tune == true) )  // wenn Tuning aktiv und das byte für die Maximalgeschwindigkeit kommt
        {
            SendByte = MaxSpeed;          // die max. Geschwindigkeit gemäs Variable anpassen
        }
        
        
        // das gleiche nochmal, nur mit 25Km/h Seriengeschwindigkeit
        //else if ((ReceifedByte == (0x19)) && (tune == true))  // wenn Tuning aktiv und das byte für die Maximalgeschwindigkeit kommt
        //{
        //    SendByte = MaxSpeed;          // die max. Geschwindigkeit gemäs Variable anpassen
        //}

        
        // neu: wenn hier PruefSummeOK = true ist, dann wurden insgesammt alle 7 notwendigen Bytes empfangen und ggf. Modifiziert. Das jetzt gerade empfangene Byte ist das originale LowByte der PruefSumme,
        // das ignorieren wir  aber jetzt, und setzen stattdessen das neue LowByte ein. Low und Highbyte wurde etwas weiter unten berechnet.
        else if ((PruefSummeOK == true) && (ByteZaehler == 8))
        {
            SendByte = PruefSummeLowByte; // das neu errechnete LowByte verwenden
            PruefSummeLowByte = 0;
        }
        // gleiches Spiel mit dem Highbyte ...
        else if ((PruefSummeOK == true) && (ByteZaehler == 9)) 
        {
            SendByte = PruefSummeHighByte; // das neu errechnete HighByte verwenden
            PruefSummeHighByte = 0;
            PruefSummeOK = false;
            tune = false;   //  sobald das HighByte für die Pruefsumme durch ist, wird nix mehr am Datensatz verändert
        }
          
        // alle anderen Bytes, die nicht bekannt/relevant oder sonstiges sind, einfach "durchreichen"
        else 
        {
            SendByte = ReceifedByte;
        }

        // Berechnung der Prüfsumme .....  Byte 0 wird ignoiert, Byte 1 bis 7 aufaddiert, und dann in Low und Highbyte geteilt
        if (ByteZaehler > 0)    //erst ab Byte 1 aufaddieren
        {
            Pruefsumme = Pruefsumme + SendByte;  // Wir addieren die zu sendenden Bytes
        }
        
        ByteZaehler = ByteZaehler + 1; // einfach ein Zähler, zur Orientierung
          
        if (ByteZaehler == 8)  // jetzt wurden 7+1 Bytes empfangen, für das Nächste Byte brauchen wir die  neue Pruefsumme, daraus Lowbyte und Highbyte ermitteln
        {
            PruefSummeLowByte = lowByte(Pruefsumme);
            PruefSummeHighByte = highByte(Pruefsumme);
            PruefSummeOK  = true;  // ein Merker, der zeigt, dass die neue Prüfsumme bereit steht
        }

  
        swSer1.write(SendByte);                           // byte an den Controller senden

        
        if (SerialOutput == true)
        {
            Serial.print("received: ");
            Serial.print(ReceifedByte, HEX);
            Serial.print("  new: ");
            Serial.println(SendByte, HEX);
        }

    } // Ende von if SerialData vorhanden
}
Hatte dort auch nochmal die Seriengeschwindigkeitserkennung um die (alten?) 25Km/h erweitert (ja.. ich habs vorher auch schon getestet und da lief es auch nicht 😜 )


Ich hoffe, es kann mir hier noch jemand helfen, bevor ich verzweifel und mich meine Frau vollends für Verrückt erklärt, weil ich noch zig Stunden mit dem Laptop am Fahrrad hänge 🤣
So'n kleiner Wink mit dem Zaunpfahl würde sicher reichen ^^ jedenfalls n Tipp wo und wie ich was kontrollieren könnte (den Analyzer hab ich leider (noch) nicht)..

Gruß,
der Geini
 
G

Geini82

Dabei seit
27.08.2021
Beiträge
3
Punkte Reaktionen
0
Habe derzeit den Code von Tschosef (#206) drauf, aber ich kriege den V-Max und die Fahrstufen nicht geändert.
Geschwindigkeit und Akku werden angezeigt, sonst bislang auch nix ungewöhnliches bemerkt.
....

Hallo nochmal...

Ich glaube ich muss mich korrigieren. Habe gerade nochmal den Code auf den ESP gejagt.. angeschlossen und Probefahrt gemacht.
Hatte jetzt dummerweise die Fahrstufen auf Standard Kmh gelassen :rolleyes:

Aber, mit aktiviertem Tuning:
besseres Ansprechverhalten
Über 26/27kmh kommt er auch..

aber da jetzt mal die Frage, wie es sein sollte:
er zieht mit voller Power auf ~27Kmh und danach gehts nur noch mit "2 Balken" weiter.. soll das so? 😅
aber auf meiner kurzen Testfahrt kam er auf ca. 30Kmh, nur mit lockerem Pedale bewegen ^^

Mal gucken, wie es aussieht, wenn das Daumengas da ist.. wenn das alles funzt, bin ich zufrieden.


BTW:
falls jemand interesse an ner STL für ein Gehäuse hat, einfach mal melden..
Ich hatte mir n Gehäuse für den Wemos D1 Mini entsprechend abgeändert, dass das Gehäuse geschlossen ist und oberhalb, genug platz für die angelöteten Kabel und 2 Ausparungen um die Kabel raus zu führen. USB-Port dabei immer erreichbar. (Wenn alles fertig, n bissle Heißkleber und dann kann nix mehr passieren ^^ )
Muss nur mal gucken, ob ich das Kabel für das Daumengas da noch reingequetscht bekomme, oder ich das dafür nochmal abändern muss..

aber wie gesagt, falls jemand interesse hat, lad ich es mal hoch und mach dazu mal 1-2 Fotos.



Also nochmals vielen Dank an alle hier!!!
 
J

Jokerrr

Dabei seit
12.09.2021
Beiträge
2
Punkte Reaktionen
0
Hallo :) Hat jemand Bilder von seinem Gerät und der Verkabelung aus der Nähe, damit ich eine gute Vorstellung davon bekomme, wie man dieses Projekt macht?
Danke schön!
 
G

Geini82

Dabei seit
27.08.2021
Beiträge
3
Punkte Reaktionen
0
Ich hab grad noch einen gemacht und ein Paar Fotos davon erstellt...
Hoffe, das reicht dir als Inspiration ;-)

Hier ist auch mein Gehäuse zu sehen.. nichts dolles, aber reicht für mich..


Mit dem code, werd ich aber noch ein wenig rumspielen müssen da das Daumengas immer Vollgas gibt, bei tuning (schön wäre der Stufe angepasst).

IMG_20210918_002848.jpg
IMG_20210918_002948_2.jpg

IMG_20210918_003221_2.jpg
IMG_20210918_003335.jpg
 
J

Jokerrr

Dabei seit
12.09.2021
Beiträge
2
Punkte Reaktionen
0
Ich hab grad noch einen gemacht und ein Paar Fotos davon erstellt...
Hoffe, das reicht dir als Inspiration ;-)

Hier ist auch mein Gehäuse zu sehen.. nichts dolles, aber reicht für mich..


Mit dem code, werd ich aber noch ein wenig rumspielen müssen da das Daumengas immer Vollgas gibt, bei tuning (schön wäre der Stufe angepasst).

Anhang anzeigen 411248Anhang anzeigen 411249
Anhang anzeigen 411250Anhang anzeigen 411251
Das ist perfekt, vielen Dank! :) Macht jetzt viel mehr Sinn
 
Thema:

Kommunikation zwischen C7 Display und Motorkontroller NCM Venice+ Das-Kit

Kommunikation zwischen C7 Display und Motorkontroller NCM Venice+ Das-Kit - Ähnliche Themen

Extern Balancer für 10S selber bauen?: Hi, ich habe das hier ins Auge gefast: TP4056 Platine Chip Datasheet Meine Cellen Technische Daten (kurzfassung)...
Haibike Yamaha: Reverse-Engineering: Hallo, nachdem ich zusammen mit dem Nutzer @hErMeS den Yamaha Thread mit dem Akku-protokoll vollgequatscht hatte, haben wir uns über die...
Oben