A4988, vid29-05 в качестве спидометр,тахометр

Carbontuning
Topic author
Avatar
Carbontuning
Topic author
Posts: 1
Joined: 28 Nov 2022
With us: 1 year

#1by Carbontuning » 28 Nov 2022, 17:25

Плиз не судите строго новичок в этом деле
Проект в стадии разработки.
Подскажите если не трудно где ошибка в скетче
Запускается в не той очередности как хотелось бы
Нет синхронного пуска A4988 ( AccelStepper library) и Led 1.4" запускается через шум на экране
А вышло совсем ни так https://youtube.com/shorts/v_FV08Fe8Y8?feature=share звук убавить желательно

Code: Select all

// ToyotaOBD1_Reader
// Для считывания данных с разъема OBD, короткое замыкание E1 + TE2. затем для считывания данных подключитесь к VF1.
// Обратите внимание, что выход линии передачи данных составляет 12 В - подключение его непосредственно к одному из контактов arduino может привести к повреждению (вероятно) платы
// Это сделано для diaply с OLED-дисплеем с использованием U8glib, что позволяет использовать широкий диапазон типов дисплеев с незначительными изменениями.
// Большое спасибо GadgetFreak за отличный базовый код для преобразования данных.
// Если вы хотите использовать инвертированную строку - обратите внимание на комментарии к MY_HIGH и INPUT_PULLUP в SETUP void .
////////////////////////////////////////////////////////////////////////////////////////////
// Модифицированная версия для поддержки двух дисплеев с использованием TCA 9548.
// 30 июня 2022 года от jkl
//******** Внимание!!! У меня нет возможности протестировать этот код. Как только он будет протестирован и проверен, это
//******** предупреждение может быть удалено. -jkl ******************
// 1 июля 2022 года Rev.1 добавляет включение провода.h -jkl
// Добавлена поддержка драйвера a4988 для шагового двигателя VID2905. Обеспечивает считывание показаний тахометра.
// 12 ноября 2022 года от jkl
////////////////////////////////////////////////////////////////////////////////////////////
длинный Z = 0;
длинное N = 0;
длинный неопикс = 10;
// Установка выводов
const int dirPin = 28;
const int stepPin = 26;
const int en = 30; // это соединение не требуется.
const int ступенчатая эволюция = 300;
const int dirPin1 = 50;
const int stepPin1 = 48;
const int en1 = 47; // это соединение не требуется.
const int stepsperevolution1 = 300;

#включить "U8glib.h"
//#включить "SdFat.h"
#включить <SPI.h>
#включить <Wire.h>
#включить <EEPROM.h>
#включить <MD_KeySwitch.h>
// Включить библиотеку AccelStepper
#включить <AccelStepper.h>

#включить <Adafruit_NeoPixel.h>
Пиксели adafruit_neopixel_46 = пиксели Adafruit_NeoPixel(NeoPix, 46, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel пиксели_24 = Adafruit_NeoPixel(NeoPix, 24, NEO_GRB + NEO_KHZ800);

#define VREF_MEASURED 3.32      //Измеренное опорное напряжение с 3.3В стабилизатора

// выбрать один вариант логирования
#define LOGGING_MINIMAL   // Запись минимума данных
//#define LOGGING_FULL    // Запись на SD всех данных
//#define LOGGING_DEBUG   // Запись на SD всех данных + статистику расхода и пробега
//#define SECOND_O2SENS   // Включение 2го сенсора кислорода для V движков
#define DEBUG_OUTPUT false // for debug option - swith output to Serial

//DEFINE пинов под входы-выходы
#define LED_PIN         14
#define OX_PIN          0 // A0 для сенсора кислорода
#define TT_PIN 1 // A1 для сенсора ТТ АКПП
#определить ВЫВОД ENGINE_DATA_PIN 2 // ВЫВОД D2 VF1
#определить TOGGLE_BTN_PIN 7 // D7 для ввода PIN-кода
//#определить TOGGLE_BTN_PIN 5 // ВЫВОД D5 batton B
//#define INJECTOR_PIN 3 // D3 Номер ноги для форсунки
//#define SS 5 // D5 Номер ноги SS SD модуля

//DEFINE констант расходомера
#define Ls 0.055 //производительсность форсунки литров в секунду // базовый 0.004 или 240cc
#define Ncyl 4 //кол-во цилиндров

//DEFINE модуля записи на SD карту
//#define FILE_BASE_NAME "Data" //шаблон имени файла
//#define error(msg) sd.errorHalt(&Serial,F(msg)) //ошибки при работе с SD

//ОПРЕДЕЛЕНИЕ СЧИТЫВАТЕЛЯ OBD
#define MY_HIGH HIGH //LOW //Инвертировать линию Eng с помощью оптосоединителя, если у вас нет, то измените эти определения low & high на противоположные.
#define MY_LOW НИЗКИЙ //ВЫСОКИЙ
#определение TOYOTA_MAX_BYTES 24
#define OBD_INJ 1 //Injector pulse width (INJ) Длительность импульса инжектора
#define OBD_IGN 2 //Ignition timing angle (IGN) Угол опережения зажигания
#define OBD_IAC 3 //Idle Air Control (IAC) Контроль холостого хода Воздуха
#define OBD_RPM 4 //Engine speed (RPM) Частота вращения двигателя
#define OBD_MAP 5 //Manifold Absolute Pressure (MAP) Абсолютное давление в коллекторе
#define OBD_ECT 6 //Engine Coolant Temperature (ECT) Температура охлаждающей жидкости двигателя
#define OBD_TPS 7 //Throttle Position Sensor (TPS) Датчик положения дроссельной заслонки
#define OBD_SPD 8 //Speed (SPD) Скорость
#define OBD_OXSENS 9 // Лямбда 1
#ifdef СЕКУНДА_O2SENS
#define OBD_OXSENS2 10 // Лямбда 2 на V-образных движка. У меня ее нету.
#конец

// I2C адрес TCA 9548
#определить TCAADDR 0x70
// отображение каналов на TCA 9548
#определить ОТОБРАЖЕНИЕ_0 0
#определить ОТОБРАЖЕНИЕ_1 1

// Для каждого отображения создайте отдельный экземпляр.

U8GLIB_SSD1306_128X64 u8g_0(U8G_I2C_OPT_NONE); // Отображение #0
U8GLIB_SSD1306_128X64 u8g_1(U8G_I2C_OPT_NONE); // Отображение #1


// modified for tach stepper and controller модифицировано для шагового двигателя и контроллера тахометра
Ускоритель тахометра (ускоритель :: ДРАЙВЕР, шаговый, dirPin); // работает для a4988 (биполярный, постоянный ток, шаговый / направленный драйвер)
const long STEPS_PER_REVOLUTION = 315; // для шагового устройства VID2905
Ускоритель spdStepper1(ускоритель::ДРАЙВЕР, stepPin1, dirPin1);
const long STEPS_PER_REVOLUTION1 = 315;
// Установите это значение на основе конфигурации a4988.
// 1 = полный шаг, 2 = 1/2 шага, 4 = 1/4 шага, 8 = 1/8 шага
const int uSteps = 2;   // micro step rate
const int MAX_RPM_RANGE = 7000;      // Maximum RPM range to display for your car

//SdFat sd;
//SdFile file;

MD_KeySwitch S(TOGGLE_BTN_PIN, HIGH);
byte CurrentDisplayIDX = 1, TT_last = 0, TT_curr = 0;
float total_fuel_consumption = 0, trip_fuel_consumption = 0;
float trip_avg_fuel_consumption;
float cycle_obd_inj_dur = 0;
float cycle_trip = 0;
float trip_inj_dur = 0;
float total_inj_dur_ee = 0;
float current_trip = 0;
float total_trip = 0;
float all_trip_b = 0;
float all_fuel_b = 0;
float total_avg_consumption;
float total_avg_speed;
float trip_avg_speed;

unsigned long current_time = 0;
unsigned long total_time = 0;
unsigned long t;
unsigned long last_log_time = 0;
unsigned long odometer;
bool flagNulSpeed = true;
unsigned int OX, TT;

volatile uint8_t ToyotaNumBytes, ToyotaID, ToyotaData[TOYOTA_MAX_BYTES];
volatile uint16_t ToyotaFailBit = 0;
boolean LoggingOn = false; // dfeine connection flag and last success packet - for lost connection function.


void setup() {
  // privetstvie povorot
  pinMode(A12, INPUT_PULLUP);
  pinMode(A3, INPUT_PULLUP);
  pinMode(A4, INPUT_PULLUP);
  pinMode(A6, INPUT_PULLUP);
  pinMode(12, OUTPUT);
  digitalWrite(12, 0);
  pixels_46.begin();
 пиксель_24.начать();
 
//char ИМЯ_ФАЙЛА[13] = ИМЯ_ФАЙЛА_БАЗЫ_ФАЙЛА "00.csv";
// const uint8_t ИМЯ_ОСНОВЫ_РАЗМЕР = sizeof(ИМЯ_ОСНОВЫ_ФАЙЛА) - 1;
// Никаких вмешательств();
 Серийный номер.начало (115200);
 задержка (100);
 
  //EEPROM.put(200, odometer); запись значения одометра
 EEPROM.get(104, total_trip);
 EEPROM.get(108, total_time);
 EEPROM.get(200, одометр);
 EEPROM.get(204, total_inj_dur_ee);
 EEPROM.get(50, all_trip_b);
 EEPROM.get(58, all_fuel_b);
 Аналоговая ссылка (ВНЕШНЯЯ);

 // ОБРАТИТЕ ВНИМАНИЕ!!! ОЧЕНЬ ВАЖНО!!!
 // Необходимо вызвать это один раз вручную перед первым вызовом TCAselect()
 Wire.begin();
 
 // Вызовите TCAselect, чтобы установить канал.
 TCAselect(DISPLAY_0); // Канал TCA для отображения 0
 u8g_0.begin(); // использовать значения по умолчанию
 u8g_0.setFont(u8g_font_profont15r); // Я догадываюсь об этой инициализации ????!!!!!

 TCAselect(DISPLAY_1); // Канал TCA для отображения 1
 u8g_1.begin(); // использовать значения по умолчанию
 u8g_1.setFont(u8g_font_profont15r); // Я догадываюсь об этой инициализации ????!!!!!

 S.бегин();
 S.Включено двойное нажатие (true);
 S.Включить длительное нажатие (true);
 S.Включить повторное нажатие (false);
 S.Включить повторный результат(false);
 S.Установить двойное время нажатия (300);
 С.Сетлонг под давлением (2000);
  //u8g.setFont(u8g_font_profont15r);
 если (DEBUG_OUTPUT) {
 Serial.println("система запущена");
 Serial.println("Считывание с плавающей точкой из EEPROM: ");
 Серийный номер.печать ("total_trip");
 Серийный номер.println(total_trip, 3);
 Серийный номер.печать ("total_time");
 Серийный номер.println(total_time, 3);
 Серийный номер.печать ("одометр");
 Серийный номер.println(одометр, 1);
 Серийный номер.печать ("total_inj_dur_ee");
 Серийный номер.println(total_inj_dur_ee, 3);
 Серийный номер.печать("all_fuel_b");
 Serial.println(all_fuel_b, 3);
 Serial.print("all_trip_b ");
 Serial.println(all_trip_b, 3);
    }

/*
 если (!sd.begin(SS, SPI_FULL_SPEED )) {
 sd.initErrorHalt(и серийный номер);
  }
  if (BASE_NAME_SIZE > 6) {
    error("FILE_BASE_NAME too long");
  }
  if (sd.exists("Data99.csv"))                    //очистка SD карты если логов более 99 штук
  {
    u8g.setFont(u8g_font_profont15r);
    u8g.firstPage();
    do {
      u8g.drawStr( 0, 17, "WIPE DATA!" );
    } while ( u8g.nextPage() );

    if (!sd.wipe()) {
      sd.errorHalt("Wipe failed.");
    }
 если (!sd.begin(SS, SPI_FULL_SPEED )) {
 sd.Инициализация ошибок();
    }
  }

 пока (sd.существует(имя файла)) {
 если (имя файла[БАЗОВОЕ ИМЯ_РАЗМЕР + 1] != '9') {
 Имя файла[BASE_NAME_SIZE + 1]++;
 } еще, если (имя файла[БАЗОВОЕ ИМЯ_РАЗМЕРА]!= '9') {
 Имя файла[BASE_NAME_SIZE + 1] = '0';
 Имя файла[BASE_NAME_SIZE]++;
 } еще {
 ошибка ("Не удается создать имя файла");
    }
  }

если (!file.open(имя файла, O_CREAT | O_WRITE | O_EXCL)) {
ошибка ("file.open");
  }
 WriteHeader();
*/
 tachStepper.setMaxSpeed(250 * шагов); // эти значения, похоже, работают для VID2905
 Тахостепер.Настройка ускорения (250 * шагов);
 tachStepper.runToNewPosition(-300 * шагов); // переместить в нулевое положение
   //tachStepper.setCurrentPosition(0); // установить в качестве эталона 0 оборотов в минуту
   //Тахометр.выполнить новое положение (600 * шагов); // переместить иглу на полную шкалу
 Шаг тахометра.runToNewPosition(10 * шагов); // теперь переместите стрелку почти до нуля - тахометр готов к использованию.
  delay(1000);

  spdStepper1.setMaxSpeed(250 * uSteps);          // these valuses seem to work for VID2905
  spdStepper1.setAcceleration(250 * uSteps);
  spdStepper1.runToNewPosition(-300 * uSteps);    // move to zero position
   //spdStepper.setCurrentPosition(0);              // set as 0 rpm reference
   //spdStepper.runToNewPosition(600 * uSteps);     // move needle full scale
  spdStepper1.runToNewPosition(10 * uSteps);      // now move needle almost to zero  -- tach is ready to use.
  delay(1000);
 
  pinMode(ENGINE_DATA_PIN, INPUT); // VF1 PIN
  pinMode(LED_PIN, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(ENGINE_DATA_PIN), ChangeState, CHANGE); //setup Interrupt for data line  Настройка прерывания для линии передачи данных
  pinMode(TOGGLE_BTN_PIN, INPUT);           // кнопка СЛЕД. ЭКРАН
 CurrentDisplayIDX = 1; // установить для отображения 1
 drawScreenSelector();
 //Расходомер
 t = миллис();
 last_log_time = миллис();
 прерывания();
 задержка (1000);
 
} // ЗАВЕРШИТЬ НАСТРОЙКУ VOID

пустой цикл(void) {
 если (N == 0) {
 S1();
 S2();
 S3();
 N = 1;
    }
 если (digitalRead(A12) == 0) {
 S4();
 } еще {
 если (digitalRead(A3) == 0) {
 S5();
 } еще {
 если (digitalRead(A6) == 0) {
 S6();
 } еще {
 Z = Неопикс;
 для (int count = 0; count < NeoPix; count++) {
 Z = Z - 1;
 пиксели_46.Настройка яркости(30);
 pixels_46.setPixelColor(Z-1, pixels_46.Color(255,255,255));
             pixels_46.show();
             pixels_24.setBrightness(30);
             pixels_24.setPixelColor(Z-1, pixels_24.Color(255,255,255));
             pixels_24.show();
             delay(50);
          }
        }
      }
    }
  unsigned long new_t;
  unsigned int diff_t;
  switch (S.read())
  {
 случай MD_KeySwitch::KS_NULL: перерыв;
 case MD_KeySwitch::KS_PRESS: ent(); разрыв;
 случай MD_KeySwitch::KS_DPRESS:перерыв;
    //{
 // если (LoggingOn == false) LoggingOn = true; иначе LoggingOn = false;
 // } перерыв;
 дело MD_KeySwitch::KS_LONGPRESS: {
 if (CurrentDisplayIDX == 5) cleardataB(); else cleardata();
 } разрыв;
     
 дело MD_KeySwitch::KS_RPT НАЖАТЬ: перерыв;
  }

 if (ToyotaNumBytes > 0) { // если найдено байт
 new_t = миллис();
 tachStepper.moveTo((длинный)(карта(getOBDdata(OBD_RPM), 0, MAX_RPM_RANGE, 1, STEPS_PER_REVOLUTION * uSteps * 2)));
 if (new_t > t && getOBDdata(OBD_RPM) > 100 ) {// выполняем только когда на работающем двигателе
 diff_t = new_t - t;
 cycle_obd_inj_dur = getOBDdata(OBD_RPM) / 60000 * Ncyl * (float)diff_t * getOBDdata(OBD_INJ); //Время открытых форсунок за 1 такт данных. В МС
 //ОБ/М ОБ/С
 //форсунка срабатывает раз в 2 оборота КВ
 //6форсунок в с
 //время цикла мс в с. Получаем кол-во срабатываний за время цикла. Умножаем на время открытия форсунки, получаем время открытия 6 форсунок В МИЛЛИСЕКУНДАХ
       
         
      trip_inj_dur += cycle_obd_inj_dur;           //Время открытых форсунок за поездку        В МС
      total_inj_dur_ee += cycle_obd_inj_dur;       //Время открытых форсунок за все время. EEPROM    В МС

      trip_fuel_consumption = trip_inj_dur / 1000 * Ls;       //потребление топлива за поездку в литрах
      total_fuel_consumption = total_inj_dur_ee / 1000 * Ls;  //потребление топлива за все время. Из ЕЕПРОМ в литрах


      cycle_trip = (float)diff_t / 3600000 * getOBDdata(OBD_SPD);   //расстояние пройденное за такт обд данных
      current_trip += cycle_trip;  //Пройденное расстояние с момента включения. В КМ
      total_trip += cycle_trip;    //Полное пройденное расстояние. EEPROM. В КМ
 odometer += cycle_trip; //электронный одометр. Хранится в еепром и не стирается кнопкой
 current_time += diff_t; //Время в пути в миллисекундах с момента включения
 total_time += diff_t; //полное пройденное время в миллисекундах лимит ~49 суток. EEPROM

 trip_avg_speed = current_trip / (float)current_time * 3600000 ; //средняя скорость за поездку
 total_avg_speed = total_trip / (float)total_time * 3600000; // средняя скорость за все время. км\ч
 trip_avg_fuel_consumption = 100 * trip_fuel_consumption / current_trip; //средний расход за поездку
 total_avg_consumption = 100 * total_fuel_consumption / total_trip; //среднее потребление за все время - Л на 100км
     
 all_trip_b += cycle_trip ; //Полное пройденное расстояние. EEPROM. В КМ
 all_fuel_b += cycle_obd_inj_dur; //Время открытых форсунок за все время. EEPROM В МС
     
 t = new_t;//тест

 // if (LoggingOn == true) logData(); //запись в лог данных по двоному нажатию на кнопку

 updateEepromData(); //запись данных при остановке

 if (millis() - last_log_time > 180000) { //Запись данных в EEPROM каждые 3 минуты. Чтобы не потерять данные при движении на трассе
 EEPROM.put(104, total_trip);
 EEPROM.put(108, total_time);
 EEPROM.put(200, одометр);
 EEPROM.put(204, total_inj_dur_ee);
 EEPROM.put(50, all_trip_b);
 EEPROM.put(58, all_fuel_b);
       
 last_log_time = миллис();
      }
    }
 drawScreenSelector(); // рисовать экран
 ToyotaNumBytes = 0; // сбросить счетчик.
 } // завершить, если (ToyotaNumBytes > 0)
  tachStepper.run();
  spdStepper1.run();
 /* if (millis() % 50 == 0 && LoggingOn == true && CurrentDisplayIDX == 6) { //каждые 50мс, когда включено логирование и выбран экран с флагами(!)
    OX = analogRead(OX_PIN);
    if (OX < 400) { //исключаю ложные показание > ~1.3В
      file.write(';');
      file.print(((float)OX * VREF_MEASURED) / 1024, 3 );
      file.println();
    }
  }
  if (millis() % 500 == 0) {  //каждые пол секунды читаем состояние АКПП
    TT = analogRead(TT_PIN);
    TT_curr = (int)(TT * VREF_MEASURED / 1024 * 3.13 + 0.5);
 если (TT_last != TT_curr) {
 drawScreenSelector();
 TT_last = TT_curr;
    }
    //Serial.println((с плавающей точкой)TT * VREF_MEASURED / 1024 * 3.13, 3);
 // Serial.println((int)(TT * VREF_MEASURED / 1024 * 3.13+0.5 ));
  }
*/
//if (millis() % 5000 < 50) autoscreenchange(); // ротация экранов
}
 // приветственный поворот
аннулирование S1() {
 для (int count = 0; count < 2; count++) {
 для (int count = 0; count < NeoPix; count++) {
 Z = Z + 1;
 пиксели_46.Настройка яркости(30);
 pixels_46.setPixelColor(Z-1, pixels_46.Color(255,255,0));
 пиксель_46.показать();
 пиксели_24.Настройка яркости(30);
 pixels_24.setPixelColor(Z-1, pixels_24.Color(255,255,0));
 пиксель_24.показать();
 задержка (5);
    }
 задержка (200);
 Z = 0;
 для (int count = 0; count < NeoPix; count++) {
 Z = Z + 1;
 пиксели_46.Настройка яркости(30);
 pixels_46.setPixelColor(Z-1, pixels_46.Color(0,0,0));
 пиксель_46.показать();
 пиксели_24.Настройка яркости(30);
 pixels_24.setPixelColor(Z-1, pixels_24.Color(0,0,0));
 пиксель_24.показать();
       }
 Z = 0;
 задержка (200);
  }
}

пустота S2() {
 Z = NeoPix + 1;
 для (int count = 0; count < NeoPix; count++) {
 для (int count = 0; count < NeoPix; count++) {
 Z = Z - 1;
 пиксели_46.Настройка яркости(30);
 pixels_46.setPixelColor(Z-1, pixels_46.Color(51,51,51));
 пиксель_46.показать();
 пиксели_24.Настройка яркости(30);
 pixels_24.setPixelColor(Z-1, pixels_24.Color(51,51,51));
 пиксель_24.показать();
 задержка (5);
 пиксели_46.Настройка яркости(30);
 pixels_46.setPixelColor(Z-1, pixels_46.Color(0,0,0));
 пиксель_46.показать();
 пиксели_24.Настройка яркости(30);
 pixels_24.setPixelColor(Z-1, pixels_24.Color(0,0,0));
 пиксель_24.показать();
       }
 пиксели_46.Настройка яркости(30);
 pixels_46.setPixelColor(Z-1, pixels_46.Color(51,51,51));
 пиксель_46.показать();
 пиксели_24.Настройка яркости(30);
 pixels_24.setPixelColor(Z-1, pixels_24.Color(51,51,51));
 пиксель_24.показать();
 Z = Неопикс + (Z + 1);
  }
 задержка (1000);
}

аннулировать S3() {
 Z = 0;
 для (int count = 0; count < NeoPix; count++) {
 Z = Z + 1;
 пиксели_46.Настройка яркости(30);
 pixels_46.setPixelColor(Z-1, pixels_46.Color(255,255,255));
 пиксель_46.показать();
 задержка (10);
 пиксели_24.Настройка яркости(30);
 pixels_24.setPixelColor(Z-1, pixels_24.Color(51,51,51));
 пиксель_24.показать();
     }
 Z = Неопикс;
 для (int count = 0; count < NeoPix; count++) {
 Z = Z - 1;
 пиксели_24.Настройка яркости(30);
 pixels_24.setPixelColor(Z-1, pixels_24.Color(255,255,255));
 пиксель_24.показать();
 задержка (10);
  }
 Контактный режим (45, ВЫХОДНОЙ);
 Цифровая запись (45, 1);
 pinMode(31, ВЫВОД);
 Цифровая запись (31, 1);
}

аннулировать S4() {
 для (int count = 0; count < 2; count++) {
 для (int count = 0; count < NeoPix; count++) {
 Z = Z + 1;
 пиксели_46.Настройка яркости(30);
 pixels_46.setPixelColor(Z-1, pixels_46.Color(255,255,0));
 пиксель_46.показать();
 задержка (5);
    }
    delay(200);
    Z = 0;
    for (int count = 0; count < NeoPix; count++) {
      Z = Z + 1;
      pixels_46.setBrightness(30);
       pixels_46.setPixelColor(Z-1, pixels_46.Color(0,0,0));
       pixels_46.show();
       }
    Z = 0;
    delay(200);
  }
}
void S5() {
  for (int count = 0; count < 2; count++) {
    for (int count = 0; count < NeoPix; count++) {
      Z = Z + 1;
      pixels_24.setBrightness(30);
       pixels_24.setPixelColor(Z-1, pixels_24.Color(255,255,0));
 пиксель_24.показать();
 задержка (5);
    }
 задержка (200);
 Z = 0;
 для (int count = 0; count < NeoPix; count++) {
 Z = Z + 1;
 пиксели_24.Настройка яркости(30);
 pixels_24.setPixelColor(Z-1, pixels_24.Color(0,0,0));
 пиксель_24.показать();
       }
 Z = 0;
 задержка (200);
  }
}
аннулировать S6() {
 для (int count = 0; count < 2; count++) {
 для (int count = 0; count < NeoPix; count++) {
 Z = Z + 1;
 пиксели_46.Настройка яркости(30);
 pixels_46.setPixelColor(Z-1, pixels_46.Color(255,255,0));
 пиксель_46.показать();
 пиксели_24.Настройка яркости(30);
 pixels_24.setPixelColor(Z-1, pixels_24.Color(255,255,0));
 пиксель_24.показать();
 задержка (5);
    }
 задержка (200);
 Z = 0;
 для (int count = 0; count < NeoPix; count++) {
 Z = Z + 1;
 пиксели_46.Настройка яркости(30);
 pixels_46.setPixelColor(Z-1, pixels_46.Color(0,0,0));
 пиксель_46.показать();
 пиксели_24.Настройка яркости(30);
 pixels_24.setPixelColor(Z-1, pixels_24.Color(0,0,0));
 пиксель_24.показать();
       }
 Z = 0;
 задержка (200);
  }
}
void updateEepromData() {
  if (getOBDdata(OBD_SPD) == 0 && flagNulSpeed == false)  {   //Запись данных в еепром когда остановка авто
    EEPROM.put(104, total_trip);
    EEPROM.put(108, total_time);
    EEPROM.put(200, odometer);
    EEPROM.put(204, total_inj_dur_ee);
    EEPROM.put(50, all_trip_b);
    EEPROM.put(58, all_fuel_b);
    flagNulSpeed = true;                                  //запрет повторной записи
    last_log_time = millis();                             //чтобы не писать лишний раз
  }
  if (getOBDdata(OBD_SPD) != 0) flagNulSpeed = false;     //начали двигаться - разрешаем запись
}

void cleardata() {
  int i;
  for (i = 104; i <= 112; i++) {
  EEPROM.update(i, 0);
  }
  for (i = 200; i <= 208; i++) {
  EEPROM.update(i, 0);
  }
  EEPROM.get(104, total_trip);
  EEPROM.get(108, total_time);
  EEPROM.get(204, total_inj_dur_ee);

}

void cleardataB () {
  int i;
  for (i = 50; i <= 62; i++) {
  EEPROM.update(i, 0);
  }

 EEPROM.get(50, all_trip_b);
 EEPROM.get(58, all_fuel_b);
 
}

/*аннулировать WriteHeader() {
#ifdef_заполнение РЕГИСТРАЦИИ
 file.print(F("; OX_RAW;ВРЕМЯ INJ; IGN; IAC; ОБОРОТЫ в МИНУТУ; КАРТА; ECT; TPS; SPD; VF1; OX; ASE; ХОЛОДНЫЙ; ДЕТОНАЦИЯ; РАЗОМКНУТЫЙ КОНТУР; Ускорение обогащения; СТАРТЕР; ХОЛОСТОЙ ХОД; КОНДИЦИОНЕР; НЕЙТРАЛЬ; СРЕДНЕЕ ЗНАЧЕНИЕ SPD; LPK_OBD; LPH_OBD;TOTAL_OBD;AVG_OBD;CURR_OBD;CURR_RUN;total_trip"));
#конец
#ошибка ВХОДА В СИСТЕМУ IFDEF_DEBUG
 file.print(F(";OX_RAW;INJ TIME;IGN;IAC; RPM; MAP; ECT; TPS; SPD; VF1; OX; СРЕДНЕЕ ЗНАЧЕНИЕ SPD;LPK_OBD;LPH_OBD;TOTAL_OBD;AVG_OBD;CURR_OBD;CURR_RUN;total_trip"));
#конец
#регистрация IFDEF_MINIMAL
 file.print(F(";OX_RAW;INJ TIME;IGN;IAC; RPM;MAP; ECT;TPS;SPD;VF1;OX;LPH_OBD"));
#конец
 файл.println();
 файл.синхронизация();
}
*/
//обнуление данных


/*аннулировать логданные() {
 файл.печать(с плавающей точкой(миллис()) / 60000, 3); файл.записать(';') ; файл.написать(';');
 file.print(getOBDdata(OBD_INJ)); файл.написать(';'); file.print(getOBDdata(OBD_IGN)); файл.написать(';'); file.print(getOBDdata(OBD_IAC)); файл.написать(';');
  file.print(getOBDdata(OBD_RPM)); file.write(';'); file.print(getOBDdata(OBD_MAP));  file.write(';'); file.print(getOBDdata(OBD_ECT));  file.write(';');
  file.print(getOBDdata(OBD_TPS)); file.write(';');  file.print(getOBDdata(OBD_SPD));  file.write(';'); file.print(getOBDdata(OBD_OXSENS)); file.write(';'); file.print(getOBDdata(20)); file.write(';');
#ifdef LOGGING_FULL
  file.print(getOBDdata(11)); file.write(';'); file.print(getOBDdata(12)); file.write(';'); file.print(getOBDdata(13)); file.write(';'); file.print(getOBDdata(14)); file.write(';');
  file.print(getOBDdata(15)); file.write(';'); file.print(getOBDdata(16)); file.write(';'); file.print(getOBDdata(17)); file.write(';'); file.print(getOBDdata(18)); file.write(';');
  file.print(getOBDdata(19)); file.write(';');
#endif
#ifdef  LOGGING_DEBUG
  // file.print(total_avg_speed); file.write(';');                                                                   //AVG_SPD       ok
  // file.print(100 / getOBDdata(OBD_SPD) * (getOBDdata(OBD_INJ) * getOBDdata(OBD_RPM)*Ls * 0.18)); file.write(';');  //LPK_OBD      ok
#endif
  file.print(getOBDdata(OBD_INJ) * getOBDdata(OBD_RPM)*Ls * 0.18); file.write(';');                                //LPH_OBD    ok
#ifdef LOGGING_DEBUG
  //file.print(total_fuel_consumption); file.write(';');   //TOTAL_OBD     ok
  //file.print(trip_avg_fuel_consumption); file.write(';');   //!AVG_OBD
  //file.print(trip_fuel_consumption); file.write(';');  //!CURR_OBD
  //file.print(current_trip);   file.write(';');    //CURR_RUN ok
  //file.print(total_trip); file.write(';');//RUN_TOTAL      ok
#endif
  file.println();
  file.sync();
}
*/
void drawScreenSelector(void) {
  if (CurrentDisplayIDX == 1) DrawCurrentFuelConsuption();
 иначе, если (CurrentDisplayIDX == 2) drawTripTimeDistance();
 иначе, если (CurrentDisplayIDX == 3) drawTimeDistance();
 в противном случае, если (CurrentDisplayIDX == 4) DrawTotalFuelConsuption();
 иначе, если (CurrentDisplayIDX == 5) Нарисовать итоговый результат();
 иначе, если (CurrentDisplayIDX == 6) Нарисовать все данные();
 иначе, если (CurrentDisplayIDX == 7) drawExtraData();
} // завершите drawScreenSelector()

недействительный расход текущего топлива(недействительный) {
 TCAselect(DISPLAY_0); // это будет отображаться на дисплее 0
 u8g_0.Установить шрифт(u8g_font_profont15r);
 u8g_0.Первая страница();
 делать {
 u8g_0.Установить шрифт(u8g_font_profont15r);
 u8g_0.drawStr(0, 15, "ОТКЛЮЧЕНИЕ");
 u8g_0.drawStr(74, 15, "L");
 u8g_0.setPrintPos(35, 15) ;
 u8g_0.печать(trip_fuel_consumption, 1);
 если (LoggingOn == true) u8g_0.нариСУйте линию (20, 24, 88);
 // u8g.setPrintPos(90, 20) ;
 // u8g.print((с плавающей точкой)TT * VREF_MEASURED / 1024 * 3.13, 2);
/*
 u8g.setFont(u8g_font_profont22r);
 switch (TT_curr) { //для делителя 10k + 4.7k
 случай 0: u8g.drawStr( 95, 20, "1" ); перерыв;
 случай 2: u8g.drawStr( 95, 20, "2" ); перерыв;
 случай 4: u8g.drawStr( 95, 20, "3" ); перерыв;
 случай 5: u8g.drawStr(95, 20, "3L"); разрыв;
 случай 6: u8g.drawStr( 95, 20, "4" ); перерыв;
 случай 7: u8g.drawStr(95, 20, "4L"); разрыв;
    }*/
 если (getOBDdata(OBD_SPD) > 1)
    {
 u8g_0.Установить шрифт(u8g_font_profont15r);
      u8g_0.drawStr( 0, 42, "L/100Km" );
      u8g_0.setFont(u8g_font_profont22r);
 u8g_0.setPrintPos(0, 60) ;
 // u8g.print( 100 / getOBDdata(OBD_SPD) * (getOBDdata(OBD_INJ) * getOBDdata(OBD_RPM)* Ls * 0.18), 1);
 u8g_0.print( 100 / getOBDdata(OBD_SPD) * (getOBDdata(OBD_INJ)/1000 * Ls*4* getOBDdata(OBD_RPM)*60), 1);
 } еще {
 u8g_0.Установить шрифт(u8g_font_profont15r);
 u8g_0.drawStr(0, 42, "Л/час");
 u8g_0.Установить шрифт(u8g_font_profont22r);
 u8g_0.setPrintPos(0, 60) ;
 // u8g.print(getOBDdata(OBD_INJ) * getOBDdata(OBD_RPM)* Ls * 0.18, 1);
 u8g_0.print(getOBDdata(OBD_INJ)/1000 * Ls*4* getOBDdata(OBD_RPM)*60, 1);
    }
 u8g_0.Установить шрифт(u8g_font_profont15r);
 u8g_0.drawStr(60, 42, "Среднее");
 u8g_0.Установить шрифт(u8g_font_profont22r);
 u8g_0.setPrintPos(60, 60) ;
 если (trip_avg_fuel_consumption < 100)
 u8g_0.печать(trip_avg_fuel_consumption, 1);
 иначе u8g_0.drawStr( 60, 60, "---" );
  }
 в то время как ( u8g_0.nextPage() );
}

недействительный расход топлива (недействительный) {
 TCAselect(DISPLAY_1); // это будет отображаться на дисплее 1
 u8g_1.Установить шрифт(u8g_font_profont15r);
 u8g_1.Первая страница();
 делать {
 u8g_1.Установить шрифт(u8g_font_profont15r);
 u8g_1.drawStr(0, 15, "ВСЕГО");
    // u8g.drawStr( 74, 15, "L" );
    u8g_1.drawStr( 42, 15, "Liters" );
   
  //  u8g.setPrintPos(42, 15) ;
  //  u8g.print(total_fuel_consumption, 1);
    if (LoggingOn == true)  u8g_1.drawHLine(20, 24, 88);
    // u8g.setFont(u8g_font_profont22r);
    // switch (TT_curr) { //для делителя 10k + 4.7k
    // case 0: u8g.drawStr( 95, 20, "1" ); break;
    // case 2: u8g.drawStr( 95, 20, "2" ); break;
    // case 4: u8g.drawStr( 95, 20, "3" ); break;
    // case 5: u8g.drawStr( 95, 20, "3L" ); break;
    // case 6: u8g.drawStr( 95, 20, "4" ); break;
    // case 7: u8g.drawStr( 95, 20, "4L" ); break;
    // }
   
   // if (getOBDdata(OBD_SPD) > 1)
   // {
      u8g_1.setFont(u8g_font_profont15r);
    //  u8g.drawStr( 0, 42, "L/100Km" );
      u8g_1.drawStr( 0, 42, "All" );
      u8g_1.setFont(u8g_font_profont22r);
      u8g_1.setPrintPos(0, 60) ;
    u8g_1.print(total_fuel_consumption, 1);
     // u8g.print( 100 / getOBDdata(OBD_SPD) * (getOBDdata(OBD_INJ) * getOBDdata(OBD_RPM)*Ls * 0.18), 1);
     // u8g.print( 100 / getOBDdata(OBD_SPD) * (getOBDdata(OBD_INJ) *Ls*4* getOBDdata(OBD_RPM)*60), 1);
     // } else {
     // u8g.setFont(u8g_font_profont15r);
     // u8g.drawStr( 0, 42, "L/Hour" );
     // u8g.setFont(u8g_font_profont22r);
     // u8g.setPrintPos(0, 60) ;
     // u8g.print(getOBDdata(OBD_INJ) * getOBDdata(OBD_RPM)*Ls * 0.18, 1);
     // u8g.print(getOBDdata(OBD_INJ) *Ls*4* getOBDdata(OBD_RPM)*60, 1);
     // }
   
    u8g_1.setFont(u8g_font_profont15r);
    u8g_1.drawStr( 60, 42, "Average" );
    u8g_1.setFont(u8g_font_profont22r);
    u8g_1.setPrintPos(60, 60) ;
    if (total_avg_consumption < 100)
    u8g_1.print( total_avg_consumption, 1);
    else u8g_1.drawStr( 60, 60, "---" );
  }
  while ( u8g_1.nextPage() );
}

void drawTimeDistance(void) {
  TCAselect(DISPLAY_0);   // this will be displayed on display 0
  u8g_0.setFont(u8g_font_profont15r);
  u8g_0.firstPage();
  do {
    u8g_0.setFont(u8g_font_profont15r);
    u8g_0.drawStr( 0, 15, "TOTAL" );
    u8g_0.drawStr( 90, 15, "KM" );
    u8g_0.setPrintPos(44, 15) ;
    u8g_0.print(total_trip, 1);
    if (LoggingOn == true)  u8g_0.drawHLine(20, 24, 88);
    u8g_0.setFont(u8g_font_profont22r);
   //  switch (TT_curr) { //для делителя 10k + 4.7k
   //  case 0: u8g.drawStr( 95, 20, "1" ); break;
   //  case 2: u8g.drawStr( 95, 20, "2" ); break;
   //  case 4: u8g.drawStr( 95, 20, "3" ); break;
   //  case 5: u8g.drawStr( 95, 20, "3L" ); break;
   //  case 6: u8g.drawStr( 95, 20, "4" ); break;
   //  case 7: u8g.drawStr( 95, 20, "4L" ); break;
   // }
    u8g_0.setFont(u8g_font_profont15r);
    u8g_0.drawStr( 0, 42, "Avg SPD" );
    u8g_0.setFont(u8g_font_profont22r);
    u8g_0.setPrintPos(0, 60) ;
    u8g_0.print(total_avg_speed, 1);
    u8g_0.setFont(u8g_font_profont15r);
    u8g_0.drawStr( 60, 42, "Time (M)" );
    u8g_0.setFont(u8g_font_profont22r);
    u8g_0.setPrintPos(60, 60) ;
    u8g_0.print( float(total_time) / 60000, 1);
  }
  while ( u8g_0.nextPage() );
}

void drawTripTimeDistance(void) {
  TCAselect(DISPLAY_0);   // this will be displayed on display 0
  u8g_0.setFont(u8g_font_profont15r);
  u8g_0.firstPage();
  do {
 u8g_0.Установить шрифт(u8g_font_profont15r);
 u8g_0.drawStr(0, 15, "ОТКЛЮЧЕНИЕ");
 u8g_0.Протяженность (90, 15, "КМ");
 u8g_0.setPrintPos(44, 15) ;
 u8g_0.печать(current_trip, 1);
 если (LoggingOn == true) u8g_0.нариСУйте линию (20, 24, 88);
 u8g_0.Установить шрифт(u8g_font_profont22r);
 // switch (TT_curr) { //для делителя 10k + 4.7k
 // случай 0: u8g.drawStr( 95, 20, "1" ); перерыв;
 // случай 2: u8g.drawStr( 95, 20, "2" ); перерыв;
 // случай 4: u8g.drawStr( 95, 20, "3" ); перерыв;
 // случай 5: u8g.drawStr(95, 20, "3L"); разрыв;
 // случай 6: u8g.drawStr( 95, 20, "4" ); перерыв;
 // случай 7: u8g.drawStr(95, 20, "4L"); разрыв;
   //  }
 u8g_0.Установить шрифт(u8g_font_profont15r);
 u8g_0.drawStr(0, 42, "Среднее значение SPD");
 u8g_0.Установить шрифт(u8g_font_profont22r);
 u8g_0.setPrintPos(0, 60) ;
 u8g_0.печать(trip_avg_speed, 1);
 u8g_0.Установить шрифт(u8g_font_profont15r);
 u8g_0.drawStr(60, 42, "Время (М)");
 u8g_0.Установить шрифт(u8g_font_profont22r);
 u8g_0.setPrintPos(60, 60) ;
 u8g_0.print(с плавающей точкой(current_time) / 60000, 1);
  }
 в то время как ( u8g_0.nextPage() );
}

недействительный drawTotalFuelDistanceB(недействительный) //-------------------------------------------- ПОЕЗДКА В
{
  TCAselect(DISPLAY_0);   // this will be displayed on display 0
  u8g_0.setFont(u8g_font_profont15r);
  u8g_0.firstPage();
  do {
  u8g_0.setFont(u8g_font_profont15r);
  //u8g.drawStr( 0, 6, "TOTAL" );
  //u8g.drawStr( 74, 15, "L" );
  //u8g.drawStr( 20, 15, "All Trip B" );
   
 
    if (LoggingOn == true)  u8g_0.drawHLine(20, 24, 88);
 
    u8g_0.setFont(u8g_font_profont15r);
    u8g_0.drawStr( 0, 47, "Km" );
    u8g_0.setFont(u8g_font_profont15r);
    u8g_0.setPrintPos(40, 47) ;
    u8g_0.print(all_trip_b, 1);
   
    u8g_0.setFont(u8g_font_profont15r);
    u8g_0.drawStr( 0, 63, "Lit" );
    u8g_0.setFont(u8g_font_profont15r);
    u8g_0.setPrintPos(40, 63) ;
    u8g_0.print( all_fuel_b/ 1000 * Ls, 1);
   
    u8g_0.setFont(u8g_font_profont15r);
    u8g_0.drawStr( 0, 30, "L/100" );
    u8g_0.setFont(u8g_font_profont15r);
    u8g_0.setPrintPos(40, 30) ;
    u8g_0.print(  all_fuel_b / 1000 * Ls * 100 / all_trip_b , 1);
  }
  while ( u8g_0.nextPage() );
}
//}


void drawAllData(void) {
  // graphic commands to redraw the complete screen should be placed here
  TCAselect(DISPLAY_0);   // this will be displayed on display 0
  u8g_0.setFont(u8g_font_profont15r);
  u8g_0.firstPage();
  do {
    u8g_0.drawStr( 0, 17, "INJ" );
    u8g_0.setPrintPos(25, 17) ;
    u8g_0.print(getOBDdata(OBD_INJ));

    u8g_0.drawStr( 0, 32, "IGN");
    u8g_0.setPrintPos(25, 32) ;
    u8g_0.print( int(getOBDdata(OBD_IGN)));

    u8g_0.drawStr( 0, 47, "IAC");
    u8g_0.setPrintPos(25, 47) ;
    u8g_0.print( int(getOBDdata(OBD_IAC)));

    u8g_0.drawStr( 0, 62, "RPM");
    u8g_0.setPrintPos(25, 62) ;
    u8g_0.print( int(getOBDdata(OBD_RPM)));

    u8g_0.drawStr( 65, 17, "MAP" );
    u8g_0.setPrintPos(92, 17) ;
    u8g_0.print( int(getOBDdata(OBD_MAP)));

    u8g_0.drawStr( 65, 32, "ECT");
    u8g_0.setPrintPos(92, 32) ;
    u8g_0.print( int(getOBDdata(OBD_ECT)));

    u8g_0.drawStr( 65, 47, "TPS");
    u8g_0.setPrintPos(92, 47) ;
    u8g_0.print( int(getOBDdata(OBD_TPS)));

    u8g_0.drawStr( 65, 62, "SPD");
    u8g_0.setPrintPos(92, 62) ;
    u8g_0.print( int(getOBDdata(OBD_SPD)));

    u8g_0.drawVLine(63, 0, 64);
  } while ( u8g_0.nextPage() ); // end picture loop
} // end void drawalldata

void autoscreenchange() {
  CurrentDisplayIDX++;
  if (CurrentDisplayIDX > 3) CurrentDisplayIDX = 1;
  drawScreenSelector();
}
void ent() {//ПЕРЕКЛЮЧЕНИЕ ЭКРАНОВ
  CurrentDisplayIDX++;
  if (CurrentDisplayIDX > 7) CurrentDisplayIDX = 1;
  drawScreenSelector();
}

float getOBDdata(byte OBDdataIDX) {
  float returnValue;
  switch (OBDdataIDX) {
    case 0:// UNKNOWN
      returnValue = ToyotaData[0];
      break;
    case OBD_INJ: //  Время впрыска форсунок  =X*0.125 (мс) (x / 8)
      returnValue = ToyotaData[OBD_INJ] / 8 ;  //* 0.125; //Время впрыска форсунок x/10
      break;
    case OBD_IGN: // Угол опережения зажигания X*0.47-30 (град)
      returnValue = ToyotaData[OBD_IGN] * 0.47 - 30;
      break;
    case OBD_IAC: //  Состояние клапана ХХ Для разных типов КХХ разные формулы: X/255*100 (%)
      //  X (шаг)
      returnValue = ToyotaData[OBD_IAC] * 0.39215; ///optimize divide
      break;
    case OBD_RPM: //Частота вращения коленвала X*25(об/мин)
      returnValue = ToyotaData[OBD_RPM] * 25;
      break;
    case OBD_MAP: //Расходомер воздуха (MAP/MAF)
      //  X*0.6515 (кПа)
      //  X*4.886 (мм.ртут.столба)
      //  X*0.97 (кПа) (для турбомоторов)
      //  X*7.732 (мм.рт.ст) (для турбомоторов)
      //  x*2(гр/сек) (данная формула для MAF так и не найдена)
      //  X/255*5 (Вольт) (напряжение на расходомере)
      returnValue = ToyotaData[OBD_MAP] * 4.886; //MAF
      break;
    case OBD_ECT: // Температура двигателя (ECT)
      // В зависимости от величины Х разные формулы:
      // 0..14:          =(Х-5)*2-60
      // 15..38:        =(Х-15)*0.83-40
      // 39..81:        =(Х-39)*0.47-20
      // 82..134:      =(Х-82)*0.38
      // 135..179:    =(Х-135)*0.44+20
      // 180..209:    =(Х-180)*0.67+40
      // 210..227:    =(Х-210)*1.11+60
      // 228..236:    =(Х-228)*2.11+80
      // 237..242:    =(Х-237)*3.83+99
      // 243..255:    =(Х-243)*9.8+122
      // Температура в градусах цельсия.
      if (ToyotaData[OBD_ECT] >= 243)
        returnValue = ((float)(ToyotaData[OBD_ECT] - 243) * 9.8) + 122;
      else if (ToyotaData[OBD_ECT] >= 237)
        returnValue = ((float)(ToyotaData[OBD_ECT] - 237) * 3.83) + 99;
      else if (ToyotaData[OBD_ECT] >= 228)
        returnValue = ((float)(ToyotaData[OBD_ECT] - 228) * 2.11) + 80.0;
      else if (ToyotaData[OBD_ECT] >= 210)
        returnValue = ((float)(ToyotaData[OBD_ECT] - 210) * 1.11) + 60.0;
      else if (ToyotaData[OBD_ECT] >= 180)
        returnValue = ((float)(ToyotaData[OBD_ECT] - 180) * 0.67) + 40.0;
      else if (ToyotaData[OBD_ECT] >= 135)
        returnValue = ((float)(ToyotaData[OBD_ECT] - 135) * 0.44) + 20.0;
      else if (ToyotaData[OBD_ECT] >= 82)
        returnValue = ((float)(ToyotaData[OBD_ECT] - 82) * 0.38);
      else if (ToyotaData[OBD_ECT] >= 39)
        returnValue = ((float)(ToyotaData[OBD_ECT] - 39) * 0.47) - 20.0;
      else if (ToyotaData[OBD_ECT] >= 15)
        returnValue = ((float)(ToyotaData[OBD_ECT] - 15) * 0.83) - 40.0;
      else
        returnValue = ((float)(ToyotaData[OBD_ECT] - 15) * 2.0) - 60.0;
      break;
    case OBD_TPS: // Положение дроссельной заслонки
      // X/2(градусы)
      // X/1.8(%)
      returnValue = ToyotaData[OBD_TPS] / 1.8;
      break;
    case OBD_SPD: // Скорость автомобиля (км/час)
      returnValue = ToyotaData[OBD_SPD];
      break;
    //  Коррекция для рядных/ коррекция первой половины
    case OBD_OXSENS:
      returnValue = (float)ToyotaData[OBD_OXSENS] * 0.01953125;
      break;

#ifdef SECOND_O2SENS
    case OBD_OXSENS2:// Lambda2 tst
      returnValue = (float)ToyotaData[OBD_OXSENS2] * 0.01953125;
      break;
#endif

    //  читаем Байты флагов побитно
    case 11:
      returnValue = bitRead(ToyotaData[11], 0); //Переобогащение после запуска 1-Вкл
      break;
    case 12:
      returnValue = bitRead(ToyotaData[11], 1); //Холодный двигатель 1-Да
      break;
    case 13:
      returnValue = bitRead(ToyotaData[11], 4); //Детонация 1-Да
      break;
    case 14:
      returnValue = bitRead(ToyotaData[11], 5); //Обратная связь по лямбда зонду 1-Да
      break;
    case 15:
      returnValue = bitRead(ToyotaData[11], 6); //Дополнительное обогащение 1-Да
      break;
    case 16:
      returnValue = bitRead(ToyotaData[12], 0); //Стартер 1-Да
      break;
    case 17:
      returnValue = bitRead(ToyotaData[12], 1); //Признак ХХ (Дроссельная заслонка) 1-Да(Закрыта)
      break;
    case 18:
      returnValue = bitRead(ToyotaData[12], 2); //Кондиционер 1-Да
      break;
    case 19:
      returnValue = bitRead(ToyotaData[12], 3); //Нейтраль 1-Да
      break;
    case 20:
      returnValue = bitRead(ToyotaData[12], 4); //Смесь  первой половины 1-Богатая, 0-Бедная
      break;

#ifdef SECOND_O2SENS //Вторая лябмда для Vобразных движков
    case 21:
      returnValue = bitRead(ToyotaData[12], 5); //Смесь второй половины 1-Богатая, 0-Бедная
 перерыв;
#конец

 по умолчанию: // РЕГИСТР ПО УМОЛЧАНИЮ (не соответствует номеру)
 // отправить значение "ошибка"
 Возвращаемое значение = 9999,99;
 } // конечный выключатель
 // отправить значение обратно
 вернуть возвращаемое значение;
} // end аннулирует getOBDdata


аннулировать изменение состояния() {
 статический идентификатор uint8_t, EData[TOYOTA_MAX_BYTES];
 статический логический входной пакет = false;
 статические беззнаковые длинные StartMS;
 статическое значение uint16_t BitCount;
 состояние ввода = digitalRead(ENGINE_DATA_PIN);
 Цифровая запись (LED_PIN, состояние);
 если (InPacket == false) {
 если (состояние == MY_HIGH) {
 StartMS = миллис();
 } else { // else, если (состояние == MY_HIGH)
 если ((миллис() - начальные значения) > (15 * 8)) {
 StartMS = миллис();
 Входящий пакет = true;
 Количество битов = 0;
 } // завершить, если ((миллис() - StartMS) > (15 * 8))
 } // конец, если (состояние == MY_HIGH)
 } else { // else, если (InPacket == false)
 uint16_t бит = ((millis() - StartMS) + 1 ) / 8; // +1 - это справиться с небольшими временными ошибками
    StartMS = millis();
    // process bits
    while (bits > 0)  {
    if (BitCount < 4)  {
    if (BitCount == 0)
          ID = 0;
        ID >>= 1;
    if (state == MY_LOW)  // inverse state as we are detecting the change!
          ID |= 0x08;
      }   else    { // else    if (BitCount < 4)
        uint16_t bitpos = (BitCount - 4) % 11;
        uint16_t bytepos = (BitCount - 4) / 11;
    if (bitpos == 0)      {
          // Start bit, should be LOW
    if ((BitCount > 4) && (state != MY_HIGH))  { // inverse state as we are detecting the change!
            ToyotaFailBit = BitCount;
            InPacket = false;
            break;
          } // end if ((BitCount > 4) && (state != MY_HIGH))
        }  else if (bitpos < 9)  { //else TO  if (bitpos == 0)
          EData[bytepos] >>= 1;
    if (state == MY_LOW)  // inverse state as we are detecting the change!
            EData[bytepos] |= 0x80;
        } else { // else if (bitpos == 0)
          // Stop bits, should be HIGH
    if (state != MY_LOW)  { // inverse state as we are detecting the change!
            ToyotaFailBit = BitCount;
            InPacket = false;
            break;
 } // завершить, если (указать != MY_LOW)
 если ( (битпос == 10) && ((бит> 1) || (байтпос == (TOYOTA_MAX_BYTES - 1))) ) {
 ToyotaNumBytes = 0;
 ToyotaID = ИДЕНТИФИКАТОР;
 для (uint16_t i = 0; i <= байтовое значение; i++)
 ToyotaData[i] = EData[i];
 ToyotaNumBytes = байтовые данные + 1;
 if (bits> = 16) // Стоп-биты последнего байта были равны 1, поэтому определите преамбулу для следующего пакета
 Количество битов = 0;
 остальное {
 ToyotaFailBit = количество бит;
 Входящий пакет = false;
            }
 перерыв;
          }
        }
      }
 ++Количество битов;
 --биты;
 } // завершить, пока
 } // конец (InPacket == false)
} // завершить недействительное изменение

аннулировать drawExtraData(аннулировать) {
 TCAselect(DISPLAY_0); // это будет отображаться на дисплее 0
 u8g_0.Установить шрифт(u8g_font_profont15r);
 u8g_0.Первая страница();
 делать {
 u8g_0.drawStr(0, 15, "VF");
 u8g_0.setPrintPos(25, 15) ;
 u8g_0.print(getOBDdata(OBD_OXSENS), 1);
    if (int(getOBDdata(11)) == 1) {
    u8g_0.drawStr( 0, 30, "ASE");
    }
 если (int(getOBDdata(12)) == 1) {
 u8g_0.drawStr(0, 45, "CLD");
    }
 если (int(getOBDdata(13)) == 1) {
 u8g_0.drawStr(0, 60, "KNK");
    }
 если (int(getOBDdata(14)) == 1) {
 u8g_0.drawStr(40, 30, "OL");
    }
 если (int(getOBDdata(15)) == 1) {
 u8g_0.drawStr(40, 45, "AE");
    }
 если (int(getOBDdata(16)) == 1) {
 u8g_0.drawStr(40, 60, "STA");
    }
 если (int(getOBDdata(17)) == 1) {
 u8g_0.drawStr(70, 30, "IDL");
    }
 если (int(getOBDdata(18)) == 1) {
 u8g_0.drawStr(70, 45, "A/C");
    }
 если (int(getOBDdata(19)) == 1) {
 u8g_0.Ничья (70, 60, "Новый Южный Уэльс");
    }
 если (int(getOBDdata(20)) == 0) {
 u8g_0.drawStr(70, 15, "ХУДОЙ");
 } еще {
 u8g_0.drawStr(70, 15, "БОГАТЫЙ");
    }
  }
 в то время как ( u8g_0.nextPage() );
}


// Вспомогательная функция для изменения выходного канала TCA
// Вызывайте эту функцию при смене дисплеев.
аннулировать TCAselect(канал uint8_t) {
 если (канал > 7) возврат;
 Проводная передача.Начало передачи (TCAADDR);
 Провод.запись (1 << канал);
 Проводная.Конечная передача();
}
где пытался запустить чтоб начинало с запуска ws2812 ,а потом уже запуск 2 vi2905 синхронно и самих OLeD


Return to “Программирование”

Who is online (over the past 5 minutes)

Users browsing this forum: 1 guest