Skocz do zawartości
ewemarkam

[Arduino] Interface do SUBARU SSM-1

Pomocna odpowiedź

Witam

Mam problem. Od dłuższego czasu próbuje skomunikować się przez Arduino z moim Foresterem z 98 roku. Nie ma tam lini K ani niczego innego co by gadało z normalnymi interfajsami samochodowymi. Jest gniazdo które wygląda jak OBD ale nim nie jest. W zasadzie komunikacja działa i są programy którymi się można podłączyć, mówie tu o podłączeniu przewodem. Działa zwykly kabel na FTDI. I jest OK. Ale chciałem zrobić sobie wyświetlanie parametrów na LCD.

Mam dwa programy, jeden działa i odczytuje poprawnie TPS (położenie przepustnicy, czy też jej wychylenie. W drugim, chciałem już wyświetlać więcej parametrów, przełączając "ekrany" no i ten drugi już się nie łączy. Nie wiem co zrobiłem źle. Albo co mogę zrobić inaczej. Program pierwszy jest to modyfikacja już gdzieś znalezionego w internecie.

int led = 13;
#include <LiquidCrystal_I2C.h>
#include <SoftwareSerial.h>
#include <Wire.h>
LiquidCrystal_I2C lcd_I2C(0x27,16,2);
  
  
  void setup()  {
  byte romid[3];
  lcd_I2C.backlight(); 
  lcd_I2C.init();
  lcd_I2C.clear();
  // Устанавливаем скорость обмена
  Serial.begin(1953);
  // Включаем контроль четности: Even Parity
  UCSR0C = ( UCSR0C & ~_BV(UPM00) | _BV(UPM01) ); 

  pinMode(led, OUTPUT);

  // Зажигаем светодиод на 3 секунды
  digitalWrite(led, HIGH);
  delay(300);
  // Гасим светодиод и ждем 2 секунды
  digitalWrite(led, LOW); 
  delay(200);
  
  
  if (ECU_GetROMID(romid))  // Если ROM ID все-таки прочитали,
  {
    for (int i=0;i<3;i++) {
   
     // show_byte(romid[i]);  // То промигаем его светодиодом
    }
  }
}

void loop() {
  int retries = 0;
  while (retries<8) {
    byte romid[3]   ={0};
    int nbytes = Serial.readBytes(romid,3);
    //lcd_I2C.clear();
    lcd_I2C.setCursor(0,0);
    lcd_I2C.print(retries);
    if ((nbytes == 3) && (romid[0]!=0x00))
      break;
   // lcd_I2C.clear();
    lcd_I2C.setCursor(0,0);
    lcd_I2C.print("TPS");
    lcd_I2C.setCursor(14,0);
    //lcd_I2C.print(retries);
    lcd_I2C.setCursor(0,1);
    lcd_I2C.print(romid[0],HEX);
    lcd_I2C.setCursor(3,1);
    lcd_I2C.print(romid[1],HEX);
    lcd_I2C.setCursor(6,1);
    lcd_I2C.print(romid[2],DEC);
    float TPS = ((romid[2] *100.0)/256.0);
    lcd_I2C.setCursor(10,0);
    lcd_I2C.print(TPS,2);
    ++retries;
  }
}

void show_byte(byte b) {
  for (int i=7;i>=0;i--) {
    if (bitRead(b,i)==1) {     
      digitalWrite(led, HIGH);
      delay(1000);
      digitalWrite(led, LOW);
      delay(1000);
    } else {
      digitalWrite(led, HIGH);
      delay(300);
      digitalWrite(led, LOW);
      delay(200);
      digitalWrite(led, HIGH);
      delay(300);
      digitalWrite(led, LOW);
      delay(1200);
    }
  }
}

void ECU_Stop() {
  byte txbuf[4]={0x12,0x00,0x00,0x00};
  
  Serial.write(txbuf[0]);
  Serial.write(txbuf[1]);
  Serial.write(txbuf[2]);
  Serial.write(txbuf[3]);
  
  delay(50);
  
  Serial.flush();
}

boolean ECU_GetROMID(byte * buffer) {
  char readCmd[4] ={0x78,0x00,0x00,0x00};
  char romidCmd[4]={0x78,0x00,0x0F,0x00};
  byte romid[3]   ={0};

  ECU_Stop();

      Serial.write(readCmd[0]);
      Serial.write(readCmd[1]);
      Serial.write(readCmd[2]);
      Serial.write(readCmd[3]);
      Serial.write(romidCmd[0]);
      Serial.write(romidCmd[1]);
      Serial.write(romidCmd[2]);
      Serial.write(romidCmd[3]);
  
      int retries = 0;
      while (retries<8) {
      int nbytes = Serial.readBytes(romid,3);
   
      lcd_I2C.setCursor(0,0);
      lcd_I2C.print(retries);
      if ((nbytes == 3) && (romid[0]!=0x00))
      break;
 
    
    ++retries;
  }
 // ECU_Stop();
  
  buffer[0] = romid[0];
  buffer[1] = romid[1];
  buffer[2] = romid[2];
  
  if (romid[0] == 0x00) {
    return false;
  }
  
  return true;
}

 

I drugi ale już nie działający.

int led = 13;
#include <LiquidCrystal_I2C.h>
#include <SoftwareSerial.h>
#include <Wire.h>
LiquidCrystal_I2C lcd_I2C(0x27,16,2);
  int menu = 0;
  
  bool przycisk;
  bool OdczytV = false;
  bool OdczytT = false;
  bool OdczytAFC = false;
  bool OdczytTPS = false;
  bool OdczytWTR = false;
  bool OdczytMAP = false;
  bool OdczytRPM = false;
  bool OdczytSPD = false;

  float V = 0.0;
  float T = 0.0;
  float AFC = 0.0;
  float TPS = 0.0;
  float TPS1 = 0.0;
  float WTR = 0.0;
  float MAP = 0.0;
  float RPM = 0.0;
  float SPD = 0.0;

  byte bV[0];
  byte bT[0];
  byte bAFC[0];
  byte bTPS[0];
  byte bWTR[0];
  byte bMAP[0];
  byte bRPM[0];
  byte bSPD[0];

  char readECU[4] ={0x78,0x00,0x00,0x00};
  char stopECU[4] ={0x12,0x00,0x00,0x00};
  char V_ECU[4] ={0x78,0x00,0x07,0x00};
  char T_ECU[4] ={0x78,0x00,0x0A,0x00};
  char AFC_ECU[4] ={0x78,0x00,0x1C,0x00};
  char TPS_ECU[4] ={0x78,0x00,0x1F,0x00};
  char WTR_ECU[4] ={0x78,0x00,0x10,0x00};
  char MAP_ECU[4] ={0x78,0x00,0x20,0x00};
  char RPM_ECU[4] ={0x78,0x00,0x09,0x00};
  char SPD_ECU[4] ={0x78,0x00,0x09,0x00};
  
  void setup()  {
  pinMode(10, INPUT_PULLUP); // Button 2

    
  byte romid[3];
  lcd_I2C.backlight(); 
  lcd_I2C.init();
  lcd_I2C.clear();
  lcd_I2C.setCursor(0,0);
  lcd_I2C.print(" FORESTER 1998");
  delay(2000);
  lcd_I2C.clear();
  Serial.begin(1953);
  
  UCSR0C = ( UCSR0C & ~_BV(UPM00) | _BV(UPM01) ); 
 
  pinMode(led, OUTPUT);
  delay(300);
}

void loop() {
    przycisk = digitalRead(10);
    if(digitalRead(10) == LOW){
    menu = menu +1;
    delay(200);
    lcd_I2C.clear();
    }
    if(menu >7){menu = 0;
    }
    switch (menu){  
case 0:
    if( OdczytT == false and ECU_GetT(bT)){
      OdczytT = true;
      lcd_I2C.clear();
      }
      lcd_I2C.setCursor(0,0);
      lcd_I2C.print("Temperatura");
      lcd_I2C.setCursor(0,1);
      T = bV[2] - 50.0;
      lcd_I2C.print(T,1);
      lcd_I2C.setCursor(6,1);
      lcd_I2C.print("oC");
      OdczytT = true;
break;

case 1:
    if( OdczytV == false and ECU_GetV(bV)){
      OdczytV = true;
      lcd_I2C.clear();
      }
      lcd_I2C.setCursor(0,0);
      lcd_I2C.print("Napiecie Aku");
      lcd_I2C.setCursor(0,1);
      V = bV[2] * 0.08;
      lcd_I2C.print(V,2);
      lcd_I2C.setCursor(6,1);
      lcd_I2C.print("V");
break; 

case 2:
    if( OdczytAFC == false and ECU_GetAFC(bAFC)){
      OdczytT = true;
      lcd_I2C.clear();
      }
      lcd_I2C.setCursor(0,0);
      lcd_I2C.print("Korekta");
      lcd_I2C.setCursor(0,1);
      AFC = bAFC[2] - 128;
      lcd_I2C.print(T,1);
      lcd_I2C.setCursor(6,1);
      lcd_I2C.print("%");
break;

case 3:
    if( OdczytTPS == false and ECU_GetTPS(bTPS)){
      OdczytT = true;
      lcd_I2C.clear();
      }
      lcd_I2C.setCursor(0,0);
      lcd_I2C.print("TPS");
      lcd_I2C.setCursor(0,1);
      TPS = (bTPS[2] *100)/256;
      lcd_I2C.print(TPS,2);
      lcd_I2C.setCursor(6,1);
      lcd_I2C.print("%");
      TPS1 = (bTPS[2] * 5)/256;
      lcd_I2C.setCursor(10,1);
      lcd_I2C.print(TPS1,2);
      lcd_I2C.setCursor(15,1);
      lcd_I2C.print("V");
break;

case 4:
    if( OdczytWTR == false and ECU_GetWTR(bWTR)){
      OdczytT = true;
      lcd_I2C.clear();
      }
      lcd_I2C.setCursor(0,0);
      lcd_I2C.print("T Wtryskiwaczy");
      lcd_I2C.setCursor(0,1);
      WTR = (bV[2] * 256)/1000;
      lcd_I2C.print(WTR,1);
      lcd_I2C.setCursor(6,1);
      lcd_I2C.print("ms");
break;

case 5:
    if( OdczytMAP == false and ECU_GetMAP(bMAP)){
      OdczytT = true;
      lcd_I2C.clear();
      }
      lcd_I2C.setCursor(0,0);
      lcd_I2C.print("MAP");
      lcd_I2C.setCursor(0,1);
      MAP = (bV[2] - 128.0)/85;
      lcd_I2C.print(MAP,2);
      lcd_I2C.setCursor(6,1);
      lcd_I2C.print("bar");
break;

case 6:
    if( OdczytRPM == false and ECU_GetRPM(bRPM)){
      OdczytT = true;
      lcd_I2C.clear();
      }
      lcd_I2C.setCursor(0,0);
      lcd_I2C.print("Obroty Silnika");
      lcd_I2C.setCursor(0,1);
      RPM = bRPM[2] * 25;
      lcd_I2C.print(RPM,0);
      lcd_I2C.setCursor(6,1);
      lcd_I2C.print("obr/min");
break;

case 7:
    if( OdczytSPD == false and ECU_GetSPD(bSPD)){
      OdczytT = true;
      lcd_I2C.clear();
      }
      lcd_I2C.setCursor(0,0);
      lcd_I2C.print("Prędkosc");
      lcd_I2C.setCursor(0,1);
      SPD = bSPD[2] * 2;
      lcd_I2C.print(SPD,0);
      lcd_I2C.setCursor(6,1);
      lcd_I2C.print("km/h");
break;

  }
}




void ECU_Stop() 
{  char txbuf[4]={0x12,0x00,0x00,0x00};
  
  Serial.write(txbuf[0]);
  Serial.write(txbuf[1]);
  Serial.write(txbuf[2]);
  Serial.write(txbuf[3]);
  
  delay(50);
  
  Serial.flush();
}

 
 boolean ECU_GetTPS(byte * buffer){ 
 
      ECU_Stop();

      Serial.write(readECU[0]);
      Serial.write(readECU[1]);
      Serial.write(readECU[2]);
      Serial.write(readECU[3]);
      Serial.write(TPS_ECU[0]);
      Serial.write(TPS_ECU[1]);
      Serial.write(TPS_ECU[2]);
      Serial.write(TPS_ECU[3]);
  
    int retries = 0;
    while (retries<8) {
    int nbytes = Serial.readBytes(bTPS,3);
   
    lcd_I2C.setCursor(15,0);
    lcd_I2C.print(retries);
    if ((nbytes == 3) && (bTPS[0]!=0x00))
     break;
  
    
    ++retries;
  }
  
  buffer[0] = bTPS[0];
  buffer[1] = bTPS[1];
  buffer[2] = bTPS[2];
  
  if (bTPS[0] == 0x00) {
    return false;
  }
  
  return true;
}

 
boolean ECU_GetV(byte * buffer){
      ECU_Stop();

      Serial.write(readECU[0]);
      Serial.write(readECU[1]);
      Serial.write(readECU[2]);
      Serial.write(readECU[3]);
      Serial.write(V_ECU[0]);
      Serial.write(V_ECU[1]);
      Serial.write(V_ECU[2]);
      Serial.write(V_ECU[3]);
  
      int retries = 0;
      while (retries<8) {
      int nbytes = Serial.readBytes(bV,3);

      lcd_I2C.setCursor(15,0);
      lcd_I2C.print(retries);
      if ((nbytes == 3) && (bV[0]!=0x00))
      break;
      
      ++retries;
  }
  
  buffer[0] = bV[0];
  buffer[1] = bV[1];
  buffer[2] = bV[2];
  
  if (bV[0] == 0x00) {
    return false;
  }
  
  return true;
}

boolean ECU_GetT(byte * buffer){
      ECU_Stop();

      Serial.write(readECU[0]);
      Serial.write(readECU[1]);
      Serial.write(readECU[2]);
      Serial.write(readECU[3]);
      Serial.write(T_ECU[0]);
      Serial.write(T_ECU[1]);
      Serial.write(T_ECU[2]);
      Serial.write(T_ECU[3]);
  
      int retries = 0;
      while (retries<8) {
      int nbytes = Serial.readBytes(bT,3);

      lcd_I2C.setCursor(15,0);
      lcd_I2C.print(retries);
      if ((nbytes == 3) && (bT[0]!=0x00))
      break;
      
    
      ++retries;
  }  
  buffer[0] = bT[0];
  buffer[1] = bT[1];
  buffer[2] = bT[2];

  if (bT[0] == 0x00) {
    return false;
  }
  
  return true;
}
boolean ECU_GetAFC(byte * buffer){
      ECU_Stop();

      Serial.write(readECU[0]);
      Serial.write(readECU[1]);
      Serial.write(readECU[2]);
      Serial.write(readECU[3]);
      Serial.write(AFC_ECU[0]);
      Serial.write(AFC_ECU[1]);
      Serial.write(AFC_ECU[2]);
      Serial.write(AFC_ECU[3]);
  
      int retries = 0;
      while (retries<8) {
      int nbytes = Serial.readBytes(bAFC,3);

      lcd_I2C.setCursor(15,0);
      lcd_I2C.print(retries);
      if ((nbytes == 3) && (bAFC[0]!=0x00))
      break;
      
    
      ++retries;
  }  
  buffer[0] = bAFC[0];
  buffer[1] = bAFC[1];
  buffer[2] = bAFC[2];

  if (bAFC[0] == 0x00) {
    return false;
  }
  
  return true;
}

boolean ECU_GetWTR(byte * buffer){
      
      
      ECU_Stop();

      Serial.write(readECU[0]);
      Serial.write(readECU[1]);
      Serial.write(readECU[2]);
      Serial.write(readECU[3]);
      Serial.write(WTR_ECU[0]);
      Serial.write(WTR_ECU[1]);
      Serial.write(WTR_ECU[2]);
      Serial.write(WTR_ECU[3]);
  
      int retries = 0;
      while (retries<8) {
      int nbytes = Serial.readBytes(bWTR,3);

      lcd_I2C.setCursor(15,0);
      lcd_I2C.print(retries);
      if ((nbytes == 3) && (bWTR[0]!=0x00))
      break;
      
    
      ++retries;
  }  
  buffer[0] = bWTR[0];
  buffer[1] = bWTR[1];
  buffer[2] = bWTR[2];

  if (bWTR[0] == 0x00) {
    return false;
  }
  
  return true;
}
boolean ECU_GetMAP(byte * buffer){
      ECU_Stop();

      Serial.write(readECU[0]);
      Serial.write(readECU[1]);
      Serial.write(readECU[2]);
      Serial.write(readECU[3]);
      Serial.write(MAP_ECU[0]);
      Serial.write(MAP_ECU[1]);
      Serial.write(MAP_ECU[2]);
      Serial.write(MAP_ECU[3]);
  
      int retries = 0;
      while (retries<8) {
      int nbytes = Serial.readBytes(bMAP,3);

      lcd_I2C.setCursor(15,0);
      lcd_I2C.print(retries);
      if ((nbytes == 3) && (bMAP[0]!=0x00))
      break;
      
    
      ++retries;
  }  
  buffer[0] = bMAP[0];
  buffer[1] = bMAP[1];
  buffer[2] = bMAP[2];

  if (bMAP[0] == 0x00) {
    return false;
  }
  
  return true;
}
boolean ECU_GetRPM(byte * buffer){
      ECU_Stop();

      Serial.write(readECU[0]);
      Serial.write(readECU[1]);
      Serial.write(readECU[2]);
      Serial.write(readECU[3]);
      Serial.write(RPM_ECU[0]);
      Serial.write(RPM_ECU[1]);
      Serial.write(RPM_ECU[2]);
      Serial.write(RPM_ECU[3]);
  
      int retries = 0;
      while (retries<8) {
      int nbytes = Serial.readBytes(bRPM,3);

      lcd_I2C.setCursor(15,0);
      lcd_I2C.print(retries);
      if ((nbytes == 3) && (bRPM[0]!=0x00))
      break;
      
    
      ++retries;
  }  
  buffer[0] = bRPM[0];
  buffer[1] = bRPM[1];
  buffer[2] = bRPM[2];

  if (bRPM[0] == 0x00) {
    return false;
  }
  
  return true;
}
boolean ECU_GetSPD(byte * buffer){
      ECU_Stop();

      Serial.write(readECU[0]);
      Serial.write(readECU[1]);
      Serial.write(readECU[2]);
      Serial.write(readECU[3]);
      Serial.write(SPD_ECU[0]);
      Serial.write(SPD_ECU[1]);
      Serial.write(SPD_ECU[2]);
      Serial.write(SPD_ECU[3]);
  
      int retries = 0;
      while (retries<8) {
      int nbytes = Serial.readBytes(bSPD,3);

      lcd_I2C.setCursor(15,0);
      lcd_I2C.print(retries);
      if ((nbytes == 3) && (bSPD[0]!=0x00))
      break;
      
    
      ++retries;
  }  
  buffer[0] = bSPD[0];
  buffer[1] = bSPD[1];
  buffer[2] = bSPD[2];

  if (bSPD[0] == 0x00) {
    return false;
  }
  
  return true;
}

Różnią się w zasadzie tym że w pierwszym komunikacja jest nawiązana w setup, a w drugim dopiero w menu w petli glownej.

Udostępnij ten post


Link to post
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Gość
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.


×
×
  • Utwórz nowe...