J1850 VPW Erfahrung?

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    Aufgrund technischer Veränderungen ist der Mailverkehr innerhalb des Forums (Private Nachrichten) nur noch eingeschränkt möglich. Die Einschränkung ist notwendig, um zusätzliche Betriebskosten für das Forum zu vermeiden. Näheres zu den Hintergründen im Thread "Aktuelles zum Forum".Wir bitten um Verständnis.

    Hinweis kann nach Kenntnisnahme deaktiviert werden!

    • J1850 VPW Erfahrung?

      Hi, Ich möchte einen J1850 Bus vom Motorrad auslesen um z.B. eine Ganganzeige oder Drehzahlmesser... zu basteln. Leider finde ich zu dem Thema und Bascom nichts.

      Ich hab mir einen OBD RS232 Adapter von Sparkfun gekauft und kann damit den Bus belauschen. Der Adapter hat einen STN1110 drauf. Leider sind die Chips (Ebenso der ELM) Mangelwahre geworden. Möglicherweise lässt sich der durch einen ATMEGA ersetzen. Im Internet hab ich einige Beispiele für Arduino gefunden. Mein Horizont bei Arduino ist jedoch sehr eingeschränkt um nicht zu sagen Null.

      Das Prinzip vom Bus hab ich verstanden jedoch hab ich keinen Plan wie es umgesetzt werden könnte. Ein paar Codeschnipsel auf die ich aufbauen könnte wären für mich sehr hilfreich. Falls Jemand welche hat oder helfen könnte wäre ich sehr dankbar.

      Gruß, Martin
    • Pac-Man wrote:

      Ich hab mir einen OBD RS232 Adapter von Sparkfun gekauft und kann damit den Bus belauschen. Der Adapter hat einen STN1110 drauf. Leider sind die Chips (Ebenso der ELM) Mangelwahre geworden.
      Na dann haste doch so einen Chip. Und am Loggen warst du ja auch schon.
      Musst ja nur den Adapter mit dem UART vom Mega verbinden und das serielle Signal (RS232) auswerten.

      Pac-Man wrote:

      Möglicherweise lässt sich der durch einen ATMEGA ersetzen.

      Wieso also den STN1110 mit einem Atmel nachbauen?
    • Mitch64 wrote:

      Wieso also den STN1110 mit einem Atmel nachbauen?
      Um nur einen MC zu haben. Zum Beispiel bei der Ganganzeige: Eine WS2812 soll durch die Farbe den Gang anzeigen. Dazu bräuchte man dann 2 ICs mit Peripherie. Das möchte ich alles mit einem IC machen. Außerdem ist der STN kaum noch erhältlich. Die meisten Funktionen die der STN bietet brauche ich auch nicht.

      Der Bus vom Motorrad ist kein richtiger OBD Bus sondern der Datenbus mit dem die ECU mit den Modulen kommuniziert. Da lässt sich nichts steuern und abfragen. Der sendet kontinuierlich Daten. Aus diesem Datenstrom brauche ich nur die jeweilige Information. Gang, RPM, Speed...
    • Bus Signal (Highpegel sind 7V) über einen Spannungsteiler einlesen hab ich mir vorgestellt. Ja, es ist VPW.

      Bit-Timing: Das VPW-Protokoll verwendet eine Bitrate von 10.4 kbps. Jedes Bit wird durch eine variable Pulsbreite dargestellt. Ein logisches ‘0’ wird durch einen 64 Mikrosekunden langen Puls dargestellt, während ein logisches ‘1’ durch einen 128 Mikrosekunden langen Puls dargestellt wird. Die Maximallänge sind 12 Bytes. Jede Übertragung startet mit einem SOF Bit welches 200 Mikrosekunden dauert. Am Ende folgt ein CRC Byte.

      Meine Überlegung war nun ein Timer der die Zeit misst. Bei <80 Mikrosekunden eine 0, bei < 140 Mikrosekunden eine 1 in ein Array schreibt. Bei 8 eingelesenen Bits das Array in ein Byte wandelt und an einen String übergibt. Bei >150 Mikrosekunden ist die Übertragung abgeschlossen und der String kann analysiert und gelöscht werden.

      Gehe ich zu naiv an die Sache ran?
    • Deine Info ist leider nicht so ganz korrekt, was das Datagramm angeht.
      Das mit den 64µs und 128µs stimmt, auch die 200µs für SOF, aber die Bits werden Alternierend übertragen.
      D.h. es wird der Puls und die Pause als Bit gewertet.

      Sieh dir mal dieses PDF im Anhang an!

      Da ist abgebildet, wie die Bits übertragen werden.

      Und hier findet man weitere Infos: Sparkfun
      Und auch hier: Sparkfun

      Im Netz habe ich Code für Arduino gefunden für CRC-Berechnung

      Aus einem anderen Link (von Github) ging hervor, dass die einen PinChange-Interrupt verwenden, um das Signal zu empfangen.
      Alternativ kann man auch einen INT1 oder INT0 nehmen.

      Beim Empfang ist der Umweg der Bits, diese zuerst in einem Array zu sammeln zu umständlich.
      Besser ist, den Bytewert * 2 zu rechnen und danach entsprechend das Bit 0 zu setzen oder nicht.
      Files
      • Lightner-183.pdf

        (956.66 kB, downloaded 14 times, last: )

      The post was edited 1 time, last by Mitch64 ().

    • Mitch64 wrote:

      aber die Bits werden Alternierend übertragen.
      D.h. es wird der Puls und die Pause als Bit gewertet.
      Ok, hab es mir jetzt genauer angeschaut. Verstehe ich dass der Pegel mit berücksichtigt werden muss? Bit=0 ist 64uS low oder 128uS high und Bit=1 ist 64uS hight und 128uS low? Würde bedeuten dass man neben der Zeit auch den Pegel abfragen muss.
    • Dachte an einen Mega8 mit 18,432 Mhz wegen Bootloader oder 20MHz. Bei 20 MHz währen die Zeiten wohl einfacher zu berechnen denke ich.

      Was meinst Du mit Aufgebaut?

      Folgende Pakete kann ich zuordnen:
      28 1B 10 02 00 00 D5 <\r> rpm
      48 29 10 02 00 00 56 <\r> speed
      A8 3B 10 03 00 00 <\r>Gear
      A8 49 10 10 34 82 <\r>Motor Temp.

      und noch einige mehr. Blinker, Kuplung, Verbrauch, Strecke...
    • Pac-Man wrote:

      Dachte an einen Mega8 mit 18,432 Mhz wegen Bootloader oder 20MHz. Bei 20 MHz
      Der Mega8 ist bis 16MHz spezifiziert. Wenn du so einen hohen Takt brauchst (weiß zwar nicht wofür), dann nimm einen Mega 168 oder 328.

      Pac-Man wrote:

      Bei 20 MHz währen die Zeiten wohl einfacher zu berechnen denke ich.
      Ob 20MHz oder 18,432MHz, das macht beim "aufgehen" der Berechnung kaum einen Unterschied.
      Wenn du noch einen UART brauchst, dann nimm den Baudquarz.

      Pac-Man wrote:

      Folgende Pakete kann ich zuordnen:
      Ja, was ich meinte, sind wie die Zahlen zu interpretieren sind.

      Pac-Man wrote:

      28 1B 10 02 00 00 D5 <\r> rpm
      Ist die 28 die PID, die Drehzahl angibt? Oder ist das ein Mode? Und die B1 sagt es kommen Drehzahldaten?
      In welchen Bytes steckt die Drehzahl und wie kodiert?
      Die D5 dürfte die CRC sein.

      Wie ist das kodiert?

      Ich finde weder die 28 noch die 1B in der Liste, die ich in Post #6 als Anhang angegeben habe.
    • Was genau die bedeuten muss ich noch raussuchen. Der Hersteller hält sich leider überhaupt nicht an irgendwelchen Standard. Die 00 00 sind in diesem Fall die Drehzahl. Der STN liefert hier zwei Hex Zahlen als ASCI (1A 3B) die dekodiert werden und durch 4 geteilt. Ich denke dass diese Daten ebenso vom Bus kommen.

      Source Code

      1. Data = Daten.Split(" ")
      2. If Daten.StartsWith("28 1B 10 02") Then
      3. lbl_rpm.Text = (Convert.ToInt32(Data(4) & Data(5), 16)) / 4
      4. Endif
      So lasse ich mir die Daten momentan in VB.Net anzeigen.
    • Mitch64 wrote:

      Wenn du so einen hohen Takt brauchst (weiß zwar nicht wofür)
      Hab jetzt einen ATMEGA328 in der Mangel. Intern mit 8Mhz getaktet weil ich mir den Platz für den Quarz sparen möchte. Ich komme mit dem Timer nicht unter 15uS. Wie soll ich dabei eine Variable alle 10uS hochzählen?

      Source Code

      1. $regfile = "m328pdef.dat"
      2. $crystal = 8000000
      3. $hwstack = 60
      4. $swstack = 60
      5. $framesize = 100
      6. $baud = 38400
      7. $loadersize = 1024
      8. Config Timer1 = Timer , Prescale = 1 , Clear Timer = 1
      9. Ocr1a = 80 - 1
      10. Enable Oc1a
      11. Enable Interrupts
      12. On Oc1a Timer_1
      13. Timer_1:
      14. Toggle Led_gruen
      15. Return
      Display All
    • Pac-Man wrote:

      Ich komme mit dem Timer nicht unter 15uS. Wie soll ich dabei eine Variable alle 10uS hochzählen?
      Wozu musst du alle 10 µs eine Variable hochzählen?
      Was ist dein Ziel?

      Zumal die LED hier nicht blinkt, da Port nicht als Ausgang konfiguriert. Und die LED versaut die Zeit eher unmerklich bis gar nicht.
      Außerdem, wenn dein Timer nur bis 80 zählt, wieso verschwendest du dann ein 16-Bit Timer?
    • Nein, aber die 110 Takte für das sichern und wiederherstellen der Registerinhalte.
      Das kann mit 'On Oc1a Timer_1 nosave' unterbunden werden. Jedoch muß man sich dann selber um das Sichern der wirklich verwendeten kümmern.
      Ist nicht 64µS die kürzeste Zeit? Schau Dir das Signal mit einem Ozzi an um zu sehen was da wirklich raus kommt. Ich traf auf eine andere Beschreibung, dort waren Pausen mit ca 40µs (als Trenner bei gleichen Bits)
    • Mitch64 wrote:

      Wozu musst du alle 10 µs eine Variable hochzählen?
      Um die Zeit zwischen den PCINTs zu messen damit ich erkennen kann welche Wertigkeit das Bit hat.

      Der Ausgang ist schon definiert und Timer1 habe ich zufällig genommen da ich noch am probieren bin. Die LED leuchtet und auf dem Oskar sehe ich den Takt.

      Pluto25 wrote:

      Ist nicht 64µS die kürzeste Zeit?
      Ja. Meinst Du damit dass ich den Timer auf 64uS einstellen sollte? Gibt es eine andere Methode so kurze Zeiten zu messen?

      Das mit der Pause (40uS) hab ich nirgendwo gefunden. Wühle nun schon eine Weile im Internet rum. Hier noch eine andere Info.
      cnblogs.com/shangdawei/p/3235907.html
    • Pac-Man wrote:

      Wie kann ich aber die Zeit auslesen wenn der Timer keine 10uS zählen kann?
      Du liest ja auch keine Zeit aus, sondern der Zählerstand.

      Dein Controller läuft mit 8 MHz und der Takt kommt über den Prescaler auf den Timer.
      Somit ist die Dauer für ein Takt am Timer = 1/ _xtal
      Oder anders gesagt, 8 Takte entsprechen 1µs.

      Wenn du also bei der Fallenden Flanke des SOF-Signals den Timer auf 0 setzt, wird bei der nächsten Flanke (steigend) der Timer ausgelesen und wieder auf 0 gesetzt.

      Der Zählerwert des Timers entspricht 1/8 µs.