• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
"Nakładanie" się funkcji - komunikacja przez BT
#1
Witajcie,

przygotowuję sobie urządzenie do odczytu informacji z gniazda OBDII, które gromadzi dane a w późniejszym czasie służyć będzie do analizy "stylu" jazdy kierowcy i eliminowaniu złych nawyków. Aktualnie potrzebuję danych odnośnie aktualnych obrotów silnika i aktualnej prędkości samochodu.

Do gniazda OBD wpięty jest ELM327 w wersji bluetooth. Natomiast Arduino współgra z modułem HC-05 poprzez Serial(38400). Wszystko jest zgodnie z oczekiwaniami, gdy aktywna jest tylko jedna funkcja odczytu. Natomiast, gdy uruchamiam dwie funkcje jednocześnie następuje chaos. Po kolei przedstawię jakie próby wykonałem, aby wyeliminować problem.

Wartości są wywoływane wysłaniem odpowiedniej komendy do modułu ELM327 (010C lub 010D). W odpowiedzi otrzymuję ciąg znaków (010C1410CXXXX lub 010D1410DXX). W przypadku, gdy obie funkcje są wykonywane ciągi znaków zaczynają na siebie nachodzić. Jednak czasami zdarza się, że działa to prawidłowo i odczyty są poprawne, jednak jest to mniej niż 1% odpowiedzi na zapytanie.

Próbowałem zmniejszyć częstotliwość wywoływania funkcji (kolejne zapytanie co sekundę) - bez efektów.
Utworzyłem z dwóch jedną funkcję - bez rezultatów.
W obrębie jednej funkcji wprowadziłem zmienną indeksującą, która zmieniała stan po ustaleniu wartości np. obrotów na 1, a warunek if (index==1) zezwalał na wywołanie funkcji sprawdzającej prędkość samochodu - również bez zmian.
Wywołanie przez timer funkcji pośredniej, w której szeregowo wywoływane były funkcje obliczające z użyciem delay w formie
void obd_check(){
rpm_calc();
delay(10);
velo_calc();
}
Również bez zmian.
Czy możecie naprowadzić mnie co tutaj jest nie tak i dlaczego te funkcje działą, ale w mniej niż jednym przypadku na 100 wykonań?
Czy może jest coś takiego jak wysłanie "pustego" zapytania do ELM327?

Poniżej umieszczam kod funkcji dla obrotów (kod dla prędkości jest bliźniaczy). Kod bazuje na dostępnym w internecie wzorze:
Kod:
void rpm_calc(){
 boolean prompt_rpm,valid_rpm;  
 char recvChar_rpm;
 char bufin_rpm[15];
 int i_rpm;
 //
 if (!(obd_error_flag)){                                   //if no OBD connection error
 //
   valid_rpm=false;
   prompt_rpm=false;
   blueToothSerial.print("010C1");                        //send to OBD PID command 010C is for RPM, the last 1 is for ELM to wait just for 1 respond (see ELM datasheet)
   blueToothSerial.print("\r");                           //send to OBD cariage return char
   while (blueToothSerial.available() <= 0);              //wait while no data from ELM
   i_rpm=0;
   while ((blueToothSerial.available()>0) && (!prompt_rpm)){  //if there is data from ELM and prompt is false
     recvChar_rpm = blueToothSerial.read();                   //read from ELM
     if ((i_rpm<15)&&(!(recvChar_rpm==32))) {                     //the normal respond to previus command is 010C1/r41 0C ?? ??>, so count 15 chars and ignore char 32 which is space
       bufin_rpm[i_rpm]=recvChar_rpm;                                 //put received char in bufin array
       i_rpm=i_rpm+1;                                             //increase i
     }  
   if (recvChar_rpm==62) prompt_rpm=true;                       //if received char is 62 which is '>' then prompt is true, which means that ELM response is finished
 }
   if ((bufin_rpm[6]=='4') && (bufin_rpm[7]=='1') && (bufin_rpm[8]=='0') && (bufin_rpm[9]=='C')){ //if first four chars after our command is 410C
   valid_rpm=true;                                                                  //then we have a correct RPM response
   } else {
   valid_rpm=false;                                                                 //else we dont
   }
   if (valid_rpm){                                                                    //in case of correct RPM response
     rpm_retries=0;                                                               //reset to 0 retries
     rpm_error_flag=false;                                                        //set rpm error flag to false
           //start calculation of real RPM value
           //RPM is coming from OBD in two 8bit(bytes) hex numbers for example A=0B and B=6C
           //the equation is ((A * 256) + B) / 4, so 0B=11 and 6C=108
           //so rpm=((11 * 256) + 108) / 4 = 731 a normal idle car engine rpm
     rpm=0;
     Serial.print("Bufin_RPM: ");
     Serial.println(bufin_rpm);                                                                                            
     for (i_rpm=10;i_rpm<14;i_rpm++){                              //in that 4 chars of bufin array which is the RPM value
         if ((bufin_rpm[i_rpm]>='A') && (bufin_rpm[i_rpm]<='F')){        //if char is between 'A' and 'F'
           bufin_rpm[i_rpm]-=55;                                 //'A' is int 65 minus 55 gives 10 which is int value for hex A
         }
         if ((bufin_rpm[i_rpm]>='0') && (bufin_rpm[i_rpm]<='9')){        //if char is between '0' and '9'
           bufin_rpm[i_rpm]-=48;                                 //'0' is int 48 minus 48 gives 0 same as hex
         }
         rpm=(rpm << 4) | (bufin_rpm[i_rpm] & 0xf);              //shift left rpm 4 bits and add the 4 bits of new char
     }
     rpm=rpm >> 2;                                     //finaly shift right rpm 2 bits, rpm=rpm/4
   }
   Serial.print("Obroty: ");
   Serial.println(rpm);
   //
   if (!valid_rpm){                                              //in case of incorrect RPM response
     rpm_error_flag=true;                                    //set rpm error flag to true
     rpm_retries+=1;                                         //add 1 retry
     rpm=0;                                                  //set rpm to 0
     Serial.println("RPM_ERROR");
     if (rpm_retries>=RPM_CMD_RETRIES) obd_error_flag=true;  //if retries reached RPM_CMD_RETRIES limit then set obd error flag to true
   }
 }
}
 
Odpowiedź
  


Wiadomości w tym wątku
"Nakładanie" się funkcji - komunikacja przez BT - przez Baltosz - 07-02-2018, 22:37

Skocz do:


Przeglądający: 1 gości