Skocz do zawartości

[Arduino] Interface do SUBARU SSM-1


ewemarkam

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.

Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.