ELM327 mit Arduino steuern

OP #4154014
Lesenswert?

Hallo,

ich versuche ein ELM327 mit einem Arduino zu steuern. Zuerst manuell 
über Hterm getestet:
1
>ATZ
2

3
ELM327 v1.3a
4

5
>atrv
6
12.6V
7

8
>atsp0
9
OK
10

11
>0100
12
SEARCHING...
13
41 00 BE 3E B8 00 
14

15
>010c
16
41 0C 00 00 
17

18
>010c
19
41 0C 12 54 
20

21
>010c
22
41 0C 11 B0 
23

24
>010c
25
41 0C 11 AC

Jetzt versuche ich das gleiche mit diesem Programm zu erreichen, was 
nicht klappt. Ich bekomme keine Werte ausgegeben. Jemand eine Idee 
warum?
1
#include <SoftwareSerial.h>
2

3
// RX, TX  --> debug
4
SoftwareSerial softwareSerial(4, 5);
5

6

7
void setup() {
8
    softwareSerial.begin(19200);
9
    Serial.begin(9600);
10
    
11
    delay(1500);
12

13
    softwareSerial.println("boot");
14

15
    //Reset the OBD-II-UART
16
    readOBDId("ATZ\r", 0);
17
    delay(5000);
18

19
    // no echo
20
    readOBDId("ATE0\r", 0);
21
    delay(1000);
22

23
    // no linefeed
24
    readOBDId("ATL0\r", 0);
25
    delay(1000);
26

27
    // auto detect protocol
28
    readOBDId("ATSP0\r", 0);
29
    delay(5000);
30

31
    // auto detect protocol
32
    readOBDId("0100\r", 0);
33
    delay(5000);
34

35
    softwareSerial.println("boot done");
36
}
37

38
// -------------------------------------------------------------------//
39
String readOBDId(String id, int numBytes){
40
    Serial.print(id);
41
    Serial.flush();
42

43
    String data = "";
44
    String result ="";
45
    char inChar;
46
    // only if there are bytes in the serial buffer execute the following code
47
    while(true) {      
48
      if(Serial.available()) {
49
  
50
          //keep reading and printing from serial untill there are bytes in the serial buffer
51
          while (Serial.available()>0){
52
              inChar = Serial.read();  //read Serial
53
              if(inChar == '\r' || inChar == '\n') {
54
                  break;
55
              }
56
              data += String(inChar);
57
              result = data;
58
          }
59
          
60
          softwareSerial.print("raw data: ");
61
          softwareSerial.println(data);
62
  
63
          if(result.length() > 4 && numBytes > 0) {
64
              int pos1 = data.indexOf(id);
65
              result = data.substring(pos1+3, pos1+(numBytes*2)+4);
66
              result.replace(" ", "");
67
          }
68

69
          softwareSerial.print("processed data: ");
70
          softwareSerial.println(result);          
71
          return result;
72
      }
73
      else {
74
        delay(20);
75
      }  
76
    }
77
}
78

79
void loop() {
80
  String rpm = readOBDId("010C\r", 2);
81
  softwareSerial.print("rpm: ");
82
  softwareSerial.println(rpm);
83

84
  delay(4000);
85
}
(Firma: matzetronics) #4154265
Lesenswert?

Das hatten wir doch gerade schon mal mit der Soft-UART beim Arduino?
Ah, ja, siehe hier:
Beitrag "GPS Sensor - UART Ausgabe"

Vllt. kannst du da Erkenntnisse draus ziehen. Nur noch mal zur Klärung: 
Am DB9 hast du dein Adapterkabel auf OBD-II und auf der 6-pol 
Stiftleiste (wo GRN und BLK dransteht) den Arduino über ein paar 
Dämpfungswiderstande auf Pin 4 und 5 des Port A?
Ziehst du die Versorgung des ELM aus der OBD Buchse oder dem Arduino?
(Firma: matzetronics) #4154289
Lesenswert?

filth schrieb:
> Mir geht es speziell um meine String readOBDId(String id, int numBytes){
>  Methode.

Das kannst du leicht über dein Startup rausfinden, du musst dir ja nur 
mal den Antwortstring auf

Filth __ schrieb:
> //Reset the OBD-II-UART
>     readOBDId("ATZ\r", 0);
>     delay(5000);

ausgeben, also
1
String result;
2
    result = readOBDId("ATZ\r",12);
3
    softwareSerial.print(result);
Frag mich nicht, ob die Syntax stimmt, ich bin Arduino Ignorant. Aber 
dann weisst du zumindest, ob die Routine richtig ist, denn der ELM muss 
ja mit der Version antworten. Vermutlich ist es auch sinnvoll, nicht auf 
eine feste Anwortlänge zu setzen, sondern die Routine entweder nach 
Timeout oder dem EOF Zeichen (CR? LF?)des ELM zu beenden.
(Firma: matzetronics) #4154309
Lesenswert?

Marc S. schrieb:
> anstatt einfach einen neuen arduino zu kaufen wäre es sinnvoller zu
> sagen was denn nicht klappt und wie du das ganze verkabelt hast.

Diese Fragen sind aber schon beantwortet:

Filth __ schrieb:
> Beispiel:
> Erwartet wird Ausgabe wie "41 0C 00 00"
> Stattdessen kommt zB "414 0C 00000" oder "C 0000 04" usw.

Filth __ schrieb:
> TX/RX/GND einfach an den uC und gib ihm ;)

Da der TE auch Zeichen bekommt, ist die Verkabelung (bis auf die o.a. 
Dämpfungswiderstände) funktionsfähig.
#4154327
Lesenswert?

Matthias Sch. schrieb:
> Marc S. schrieb:
>> anstatt einfach einen neuen arduino zu kaufen wäre es sinnvoller zu
>> sagen was denn nicht klappt und wie du das ganze verkabelt hast.
>
> Diese Fragen sind aber schon beantwortet:
>
> Filth __ schrieb:
>> Beispiel:
>> Erwartet wird Ausgabe wie "41 0C 00 00"
>> Stattdessen kommt zB "414 0C 00000" oder "C 0000 04" usw.

das hab ich glatt überlesen.

ich würde noch probieren den software serial langsamer zu machen.
Gast #4155618
Lesenswert?

Ich habe die software Serial nun auf einen "richtigen" Pin gelegt und 
den Code verändert. Es kommen keine "kaputten" Ausgaben mehr, aber es 
gibt noch ein Problem:


Serielle Ausgabe:
Start...
[STOPPED]
[ELM327 v1.3a]
[>ATE0]
[>OK]
[>OK]
[>SEARCHING...41 0C 00441 441441 0C 00 00 ]
[441 0C 41 441 0441 0441 0C 00 00 ]
[>41 0C 00 00 ]
[>41 0C 00 00 ]
[>41 0C 00 00 ]
[>41 0C 00 00 ]
[>41 0C 00 00 ]
[>41 0C 00 00 ]
[>41 0C 00 00 ]
[>4141 0C 00 00 ]
[441 0C 00 00 ]
[441 0C 00 00 ]
[441 0C 00 00 ]
[441 0C 00 00 ]
[>4141 0C 00 00 ]
[441 0C 00 00 ]
[441 0C 00 00 ]
[441 0C 00 00 ]
[441 0C 00 00 ]
[>4141 0C 00 00 ]

Also eigentlich recht gut, nur nach ein paar Ausgaben, ist immer die 5te 
Zeile eingerückt und eine "41" zu viel. Hat jemand eine Idee warum?
1
#include <Arduino.h>
2
#include <Wire.h>
3
#include <SoftwareSerial.h>
4

5
String inputString = "";         // a string to hold incoming data
6
SoftwareSerial softwareSerial(8, 9);
7

8

9
int  serIn;
10
char serInString[100];  // array that will hold the different bytes  100=100characters;
11
                        // -> you must state how long the array will be else it won't work.
12
int  serInIndx  = 0;    // index of serInString[] in which to insert the next incoming byte
13
int  serOutIndx = 0;    // index of the outgoing serInString[] array;
14

15
//This is a character buffer that will store the data from the serial port
16
char rxData[20];
17
char rxIndex=0;
18

19
//Variables to hold the speed and RPM data.
20
int vehicleSpeed=0;
21
int vehicleRPM=0;
22

23
void setup()
24
{
25
  Serial.begin(9600);
26
  softwareSerial.begin(19200); 
27

28
  softwareSerial.println("Start...");
29
  delay(1000);
30
  
31
  Serial.flush();
32
  Serial.println("ATZ");
33
  delay(1000);
34
  Serial.print("ATZ\r");
35
  delay(5000);
36
  
37
  Serial.print("ATE0\r");
38
  delay(1000);
39
  
40
  Serial.print("ATL0\r");
41
  delay(1000);
42
  
43
  Serial.print("ATSP0\r");
44
  delay(1000);
45

46
  Serial.print("0100\r");
47
  delay(5000);  
48
}
49

50

51
void readOBD() {
52
     char inChar;
53
  String rec = "[";
54
 // only if there are bytes in the serial buffer execute the following code
55
  if(Serial.available()) {    
56
       
57
    //keep reading and printing from serial untill there are bytes in the serial buffer
58
     while (Serial.available()>0){
59
        inChar = Serial.read();  //read Serial        
60
         if(inChar == '\r' || inChar == '\n') break;
61
        rec += String(inChar);
62
     }
63
     rec += "]";
64
     if(rec.length() > 4) 
65
     {
66
       softwareSerial.println(rec);
67
     }
68
     else {
69
       rec = "";
70
     }
71
  }
72
}
73

74
void loop()
75
{
76
  Serial.println("010C");
77
  readOBD();
78

79
  delay(200);
80
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren