самое верное решение уже давно раньше звучало. Взять вторую ардуину и наделить её обязанностью обмениваться по к-лайн, а основной ардуине, она 4 готовых байта будет передавать, без всяких инитов и прочей херни.
понимаю, это мне нужно было делать с самого начала, когда ты это говорил, в разработке. теперь уже это не для меня. да и все таки же работало 2 года на одной..... и без проблем, если бы не экран, то так бы и работало.
вроде заработало. и данные вроде корекны, 40 литров показывает как в баке и есть. машина была заведенная, были данные, не глуша я подключил к компу чтобы заглянуть в терминал, бортовик перезагрузился и данные уже не появились и в терменале тишина. сново выключить и включить зажигание, есть данные. debugPCM не работает, хотел туда тоже заглянуть
Строка 225 можешь 60000 поставить (обновление топлива раз в минуту) ну или даже больше. Потому как в этот момент данные кратковременно на бортовике не обновляются, по идее должны замерзать цифры не на долго
ок. температура в нутри и влага, и наружняя температура не работают, я видел что не прописаны библиотеки. ок буду пока тестить. я ща пробую добавить все что было раньше на них, но чета не показывает
раньше было так
библиотеки
//датчик наружней температуры
#include <OneWire.h>
#define ONE_WIRE_BUS 22
OneWire oneWire(ONE_WIRE_BUS);
#include <DallasTemperature.h>
DallasTemperature sensors(&oneWire);
//датчик внутринней температуры и влаги
#include "DHT.h"
#define DHTPIN 26
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
в сетупе
Wire.begin();
rtc.begin();
dht.begin();
sensors.begin();
в лупе
if (millis() - prevTemperature > 60000) { Temperature (); prevTemperature = millis();}
на странице хоме
myGLCD.printNumI(sensors.getTempCByIndex(0), 415, 145 , 3);
этот пока так и остается
myGLCD.printNumI(t, 415, 180, 3);
сейчас так if ((t != t_last) || reNew) {myGLCD.printNumI(t, 415, 180, 3); t_last=t;}
на странице инф1
myGLCD.printNumF(h, 1, 418, 215); }
сейчас так if ((h != h_last) || reNew) {myGLCD.printNumF(h, 1, 430, 215, 3); h_last=h;}
и в конце скетча
void Temperature (){
h = dht.readHumidity();
t = dht.readTemperature();
sensors.requestTemperatures();
}
вообщем пока так, ниже скетя, внутреннюю температуру и влагу не показывает, на ружнюю показывает но не обновляется. как тольлко чтото сую в луп
это Temperature ();
или по отдельности или вместе это
h = dht.readHumidity();
t = dht.readTemperature();
sensors.requestTemperatures();
чтобы обновлялись, все зависает.
//------------все для связи по K-line (тут настраиваем UARTы к-лайников, адреса блоков, скорость инита и отладку)
#include <SoftwareSerial.h>
#define TX_PCM 13
SoftwareSerial K_LINE_PCM (12, TX_PCM); //RХ,TХ //UART на котором висит K_line к PCM
#define K_LINE_GAUGE Serial2 //UART на котором висит K_line к приборке
#define TX_gauge 16 //TX UARTa на котором висит K_line к приборке
#define PCM_address 0x11 // адрес PCM
#define DIAG_address 0xF1 // адрес диагностики
const byte BAUD=200; // init baudrate - скорость инита при подключении к приборке
const byte addressGUAGE = 0xB8;// init GAUGE address - адрес щитка приборов при ините (установке связи)
#define debugPCM // раскомментировать эту строку для отладки в Serial порту обмена с PCM
//#define debugGAUGE // раскомментировать эту строку для отладки в Serial порту обмена co щитком приборов
uint32_t curmillis = 0; // снимок текущего времени
//------------------------------------------переменные для организации протокола связи с PCM
uint32_t prevRequest = 0; // таймер периодических запосов на PCM
uint16_t RequestPeriod = 3500; // периодичность запросов на PCM
uint32_t prevRESETheader=0; // таймер сброса сообщения, если данные оборвались посередине сообщения
bool RESETheader_timer; // таймер сброса сообщения, если данные оборвались посередине сообщения
uint32_t prev_NOanswer=0; // таймер контроля неответов от ЭБУ после подачи запросов
bool NOanswer_timer = 0; // таймер контроля неответов от ЭБУ после подачи запросов
byte noanswers = 0; // количество подряд неответов от ЭБУ
uint32_t timerdelay = 0; // таймер ожидания байт (для успевания появления данных в буфере UART)
bool Delay = 0; // таймер ожидания байт (для успевания появления данных в буфере UART)
byte waitbyte_RX = 1; // задержка, мс для успевания появления данных в буфере RX
// (подрегулировать в зависимости от уровня жизнидеятельности на Марсе)
#define TIMER_DELAY Delay = 0; timerdelay = curmillis // включение этого таймера
byte delaybyte_TX = 1; // задержка между отправкой байт в запросах, мс
byte header = 0; // состояние заголовка
byte message_size = 0; // размер тела сообщения
byte j = 3; // инкремент
byte n = 3; // количество старт байт
const byte bufsize = 150; // размер буфера принятого сообщения
byte MessageRx_PCM [bufsize] = {0}; // буфер принятого сообщения
byte crc =0; // байт контрольной суммы
// возможные варианты запросов на ЭБУ:
enum REQUEST {INIT, PID, DTCERASE, DTCREAD, PRESENT,};
// текстовки запросов для отладки
char* textRequest[] = {"INIT", "PID_2101", "DTC_ERASE", "DTC_READ", "PRESENT",} ;
// сами запросы
byte PCM_Message_TX[][5] = {
{1, 0x81, 0,0,0}, // запрос инициализации
{2, 0x21,0x01, 0,0}, // запрос пид 2101
{3, 0x14,0xFF,0x00, 0}, // запрос на стирание ошибок
{4, 0x18,0x00,0xFF,0x00 }, // запрос на чтение ошибок
{1, 0x3E, 0,0,0}, // запрос присутствия
};
byte request = INIT; // переменная, показывающая какой запрос будем делать
//------------------------------------------ переменные для организации протокола связи со щитком приборов
uint32_t prevNoconnect = 0; // таймер периодической проверки наличия связи со щитком приборов
uint32_t prevInitbusGauge = 0; // таймер для инита щитка приборов
byte NoconnectsGAUGE = 0 ; // счетчик неответов от щитка приборов
byte InitGauge = 0; // автомат состояния инита щитка приборов
int waitbyte_gauge = 4;
byte MessageRxGauge[60] = {0}; // массив байтов принимаемого сообщения от щитка приборов
byte PIDgauge[] = {0x02,0x11,0x00,0x13}; // запрос параметоров щитка приборов
bool flagneedGAUGE = 1;
//-------------------------------------------переменные бортовика
float L100M = 0; float L100M_last = 1; //расход на 100 км измеренный за поездку
float L100 = 0; float L100_last = 1; //мгновенный расход литров на 100км
float LHor = 0; float LHor_last = 1; //мгновенный расход топлива литров в час
float L100SR = 0; //расход литров на 100км измеренный раз в интервал kmL
float L100SR_TFT = 0; float L100SR_TFT_last = 1; // самый средний из расходов на 100км, он выводится на экран
int L100_Eeprom[11]= {10,10,10,10,10,10,10,10,10,10,10};
int FuelZamer[10]= {0}; // массив для измерения уровня (количества) топлива
int ZamerNumber = 0; // номер замера уровня (количества) топлива
int n_eeprom = 0; // текущий адрес ячейки еепром для записи расхода
int MAF = 0; int MAF_last = 1; //26,27 байты Sensor de flujo de aire en masa
float BoostPres = 0; float BoostPres_last = 1; //28,29 байты Presión de refuerzo
int RPM = 0; int RPM_last = 1; //32,33 байты Velocidad del motor
int EGRmg = 0; int EGRmg_last = 1; //34,35 байты Comando EGR (Comando de recirculación de gases de escape)
float BoostPresCom = 0; float BoostPresCom_last = 1;//38,39 байты Comando de presión de refuerzo
int Speed = 0; int Speed_last = 1; //44,45 байты Velocidad del vehículo
float DesaInjQua = 0; float DesaInjQua_last = 1; //50,51 байты Cantidad de inyección deseada
float InjQua = 0; float InjQua_last = 1; //52,53 байты Cantidad de la inyección
float StaDaliv = 0; float StaDaliv_last = 1; //54,55 байты Inicio de la entrega
int PumpRPM = 0; int PumpRPM_last = 1; //56,57 байты Velocidad de la bomba
float EGRPul = 0; float EGRPul_last = 1; //62,63 байты Relación de impulsos EGR (recirculación de gases de escape
float SolenPul = 0; float SolenPul_last = 1; //64,65 байты Velocidad de solenoide de control de nivel de remolino Relación de impulsos
float SolenPre = 0; float SolenPre_last = 1; //70,71 байты Relación de impulsos Presión Electroválvula de presión
float DesInj = 0; float DesInj_last = 1; //72,73 байты Inyección deseada Inicio
float ActInj = 0; float ActInj_last = 1; //16,17 байты Inicio de la inyección real
int TempAir = 0; int TempAir_last = 1; //74,75 байты Temperatura del aire de admisión
int Temp = 0; int Temp_last = 1; //14,15 байты Temperatura del refrigerante
int TempOil = 0; int TempOil_last = 1; //18,19 байты Temperatura del aceite del motor
int TempFuel = 0; int TempFuel_last = 1; //58,59 байты Temperatura del combustible
//все что касается топлива
float Fuel = 0; //остаток топлива
float Fuel2 = 0; float Fuel2_last = 1; //остаток мгновенного топлива байт 16 , датчика в баке
int FuelIGN = 0; // количество топлвива в баке на момент включения зажигания
int Fuel_last = 0; // для формул
bool flagFuelIGN = 0; // флаг записан ли остаток топлива в момент вкл. зажигания
float FuelTrip = 0; float FuelTrip_last = 1; // количество литров топлива, израсходованное за один цикл включения зажигания
//все что касается километража
float kmAge = 0; //пробег, полученный со щитка приборов
int kmAgeIGN = 0; //пробег который был в момент включения зажигания
int kmAge_last = 0; // для формул
bool flagkmAgeIGN = 0; //флаг записан ли пробег в момент вкл. зажигания
float kmTrip = 0; float kmTrip_last = 1; //пробег за один цикл включения зажигания
int kmL = 10; // интервал, через который будет происходить обновление среднего расхода на 100км
int km = 0; // переменная для расчетов
int kmeeprom = 10; // интервал, через который будет происходить подсчет среднеарифмитического расхода L100SR_TFT
int kmTFT = 0; // переменная для расчетов периодического подсчета среднеарифмитического расхода топлива L100SR_TFT
int kmREFUELING = 0; int kmREFUELING_last = 1; // пробег до заправки на остатке топлива
unsigned long prevWatch = 0;
unsigned long prevDvoet = 0;
unsigned long prevData = 0;
uint32_t prevGauge = 0;
//----------------------------------------------для экрана
#include <Adafruit_GFX.h>
#include <MCUFRIEND_kbv.h>
#include <UTFTGLUE.h>//use GLUE class and constructor
#include "TouchScreen.h"
#include <stdint.h>
#include <SPI.h>
#include <EEPROM.h>
//MCUFRIEND_kbv tft;
#include "Fonts/Chosence_Bold16pt7b.h";
#define MINPRESSURE 200
#define MAXPRESSURE 1000
//pin 20 SCL , 21 SDA датчик реального времени
#include <Wire.h>
#include "RTClib.h"
RTC_DS3231 rtc;
//датчик наружней температуры
#include <OneWire.h>
#define ONE_WIRE_BUS 22
OneWire oneWire(ONE_WIRE_BUS);
#include <DallasTemperature.h>
DallasTemperature sensors(&oneWire);
//датчик внутринней температуры и влаги
#include "DHT.h"
#define DHTPIN 26
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
UTFTGLUE myGLCD(0x1581,A2,A1,A3,A4,A0); //all dummy args
const int XP = 6, XM = A2, YP = A1, YM = 7;
const int TS_LEFT = 136, TS_RT = 907, TS_TOP = 139, TS_BOT = 942;
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
uint16_t ID;
int x, y;
char currentPage;
float h; int h_last = 1;
float t; int t_last = 1;
bool Dvoet = 0;
bool reNew = 0;
#define BLACK 0x0000
#define WHITE 0xFFFF
#define RED 0xF800
#define GREEN 0x07E0
void setup() {
uint16_t ID = myGLCD.readID();
if (ID == 0xD3D3) ID = 0x1581; // write-only shield
myGLCD.begin(ID);
myGLCD.InitLCD(3);
myGLCD.clrScr();
myGLCD.setFont(&Chosence_Bold16pt7b);
//myGLCD.fillScreen(WHITE);
//myGLCD.setTextColor(WHITE, BLACK);
//myGLCD.setBackColor(BLACK);
Wire.begin();
rtc.begin();
dht.begin();
sensors.begin();
//загрузка стартовой страницы
currentPage = '0';
drawHomeScreen();
//подсчет среднеарифметического усредненного расхода
for (int i = 0; i < 11; i++) L100_Eeprom [i]= EEPROM.read(i);
for (int i = 0; i < 11; i++) L100SR_TFT = L100SR_TFT + L100_Eeprom [i];
L100SR_TFT = (float)L100SR_TFT/110.0;
if (L100SR_TFT<0) L100SR_TFT = 0;
if (L100SR_TFT>99) L100SR_TFT = 99;
// строка ниже используется для настройки даты и времени часов
// раскомментировать, выставить времая и дату, залить в ардуино. в скетче закомментировать
// обратно и залить еще раз, иначе каждый раз будет по новой выствлятся это же время и дата
// (год, месяц, день, часы, минуты, секунды)
//rtc.adjust(DateTime(2019, 7, 2, 10, 48, 0));
#if defined debugPCM or defined debugGAUGE
Serial.begin(115200);
#endif
K_LINE_PCM.begin(10400);
pinMode(TX_PCM, OUTPUT);
}
void loop()
{
curmillis = millis(); // снимок текущего времени
if (curmillis - prevRequest > RequestPeriod && header == 0 && !flagneedGAUGE)
{
if (request == INIT) fastinit(); // при необходимости делаем переподключение к PCM
else {sendMessagePCM(request); // отправляем на PCM текущий запрос
if (request == PID) RequestPeriod = 600;
if (request == DTCERASE || request == DTCREAD) RequestPeriod = 2500;}
prevRequest = curmillis;
}
if (!flagneedGAUGE) {receivePCM ();} // приём сообщений от PCM
receiveGAUGE (); // приём сообщений от щитка приборов
if (header == 0) {Menu ();}
if (curmillis - prevWatch > 4000) { Watch (); prevWatch = curmillis; Trip ();}
//if (millis() - prevTemperature > 60000) { Temperature (); prevTemperature = millis();}
if (millis() - prevDvoet > 500) { if (!Dvoet) {myGLCD.print(":", 290, 5);} else {myGLCD.print(" ", 290, 5);} prevDvoet = millis(); Dvoet=!Dvoet;}
if (curmillis - prevGauge > 30000UL) {flagneedGAUGE = 1;prevGauge = curmillis;}
}// end loop
void Trip () {
if (flagkmAgeIGN){
FuelTrip = FuelIGN - Fuel;
if (kmAge>kmAgeIGN) kmTrip = kmAge - kmAgeIGN;
if (kmAge<kmAgeIGN) kmTrip = 2000 - (kmAgeIGN - kmAge); // 2000 это через сколько км у тебя суточный пробег сбрасывается на ноль, поменяй если другое число
if (kmAge==kmAgeIGN) kmTrip = 0;
//подсчет расхода на 100км за поездку
L100M = ((float)FuelTrip*100.00)/(float)kmTrip;
if (L100M<0) L100M = 0;
if (L100M>99) L100M = 99;
// ниже цикл считает среднеарифметический расход из еепром раз в пробег, указанный в переменной kmeeprom
if (kmTrip-kmTFT>kmeeprom) {kmTFT = kmTrip;
// тут считаем среднеарифметический усредненного расход из ячеек еепром
for (int i = 0; i < 11; i++) L100_Eeprom [i]= EEPROM.read(i);
for (int i = 0; i < 11; i++) L100SR_TFT = L100SR_TFT + L100_Eeprom [i];
L100SR_TFT = (float)L100SR_TFT/110.00;
if (L100SR_TFT<0) L100SR_TFT = 0;
if (L100SR_TFT>99) L100SR_TFT = 99;}
// ниже цикл считает расход топлива за пробег, указанный в переменной kmL, здесь же запись в ячейки еепром
if (kmTrip-km>kmL) {km=kmTrip;
L100SR = ((float)(Fuel_last-Fuel)*100.00)/(float)kmL; // расход/100км - обновляется раз в 10км, меняется км в int kmL = 10;
Fuel_last = Fuel; // сохранение параметров с последнего измерениея
if (L100SR<0) L100SR = 0;
if (L100SR>99) L100SR = 99;
//расчет остатка километров в баке
if (L100SR>0) kmREFUELING=((float)Fuel*100.0)/(float)L100SR; //если средний расход больше нуля, то расчитывать км в баке из него
else kmREFUELING=((float)Fuel*100.00)/(float)L100SR_TFT; //если ноль или ментше то расчитывать км в баке с устредненного расхода
// тут записываем L100SR последовательно в одну из 11 ячеек еепром
//EEPROM.write (12,n_eeprom); // ЗДЕСЬ ВНИМАТЕЛЬНО. ЗАГРУЗИТЬ ПРОШИВКУ С ЭТОЙ СТРОКОЙ ОДИН РАЗ, ПОТОМ ЗАКОМЕНТИРОВАТЬ И ЕЩЁ РАЗ ЗАГРУЗИТЬ
n_eeprom = EEPROM.read (12); // в ячейке 12 хранится № текущей ячейки для записи расхода, чтобы где остановился при выкл питания, от туда и продолжил
EEPROM.write(n_eeprom, L100SR*10);
n_eeprom++; if (n_eeprom>10) n_eeprom=0;
EEPROM.write (12,n_eeprom); }}}
void fastinit() {
digitalWrite (TX_PCM, HIGH); // bus idle
delay(1500);
digitalWrite (TX_PCM, LOW); // first part fastinit (25 ms LOW)
delay(25);
digitalWrite (TX_PCM, HIGH); // second part fastinit (25 ms HIGH)
delay(25);
K_LINE_PCM.begin(10400);
sendMessagePCM(INIT); // send start communication message
}
void receivePCM () {
if (K_LINE_PCM.available() ){
// первый старт байт
if (header == 0 && Delay){TIMER_DELAY ; MessageRx_PCM[0]=K_LINE_PCM.read();
if (MessageRx_PCM[0]!=0xFF && bitRead (MessageRx_PCM[0],7)){header = 1; RESETheader_timer = 1; prevRESETheader = curmillis;
#ifdef debugPCM
Serial.print (F("Receive PCM: ")); printDebugRX(MessageRx_PCM[0]);
#endif
}
}
// второй старт байт
if (header == 1 && Delay){TIMER_DELAY ; MessageRx_PCM[1]=K_LINE_PCM.read();
#ifdef debugPCM
printDebugRX (MessageRx_PCM[1]);
#endif
if (MessageRx_PCM[1]==DIAG_address){ header = 2;}
else {
#ifdef debugPCM
Serial.println(F(" PCM Message fail address"));
#endif
header = 0; RESETheader_timer = 0;}}
// третий старт байт
if (header == 2 && Delay){
TIMER_DELAY ;
MessageRx_PCM[2]=K_LINE_PCM.read();
#ifdef debugPCM
printDebugRX (MessageRx_PCM[2]);
#endif
if (MessageRx_PCM[2]==PCM_address){ message_size = MessageRx_PCM[0]; prevRESETheader = curmillis;
if (MessageRx_PCM[0] !=0x80) {header = 4; bitWrite (message_size, 7 , 0);j=3;n=3;}
else {header = 3; j=4;n=4;}
if (message_size > bufsize) message_size = bufsize; crc = 0;}
else {header = 0;
#ifdef debugPCM
Serial.println(F("PCM Message fail address"));
#endif
RESETheader_timer = 0;}
}
// если размер сообщения указан в дополнительном байте (нулевой байт 0x80) читаем этот дополнительный байт:
if (header == 3 && Delay){
TIMER_DELAY ; prevRESETheader = curmillis;
MessageRx_PCM[3]=K_LINE_PCM.read();
#ifdef debugPCM
printDebugRX(MessageRx_PCM[3]);
#endif
message_size = MessageRx_PCM[3];
if (message_size > bufsize) message_size = bufsize;
crc = 0; header = 4;
}
// пишем тело сообщения
if (header == 4 && Delay && j< message_size+n+1) {
MessageRx_PCM[j] = K_LINE_PCM.read(); prevRESETheader = curmillis;
if (j<message_size+n) crc+= MessageRx_PCM[j]; // подсчёт КС
if (j==message_size+n) header = 5;
TIMER_DELAY ;
#ifdef debugPCM
printDebugRX(MessageRx_PCM[j]);
#endif
j++; }
}
// сообщение приняли, действуем
if (header == 5) {TIMER_DELAY ;
#ifdef debugPCM
Serial.println();
#endif
NOanswer_timer = 0; noanswers = 0; // сбрасываем таймер контроля неответов
for(byte i = 0; i<n; i++) crc+=MessageRx_PCM[i]; // прибавляем к контрольной сумме старт байты
// если контрольная сумма верна:
if ( crc == MessageRx_PCM[message_size+n])
{
#ifdef debugPCM
Serial.print (F("Received message is OK! Checksum is correct!")); Serial.print (F(" ")); Serial.println (millis()); // Если КС совпала, тут чёнибудь нужное делаем
printDebugRX_CSgood();
#endif
if (MessageRx_PCM[n]==0xC1 && MessageRx_PCM[n+1]==0x6B && MessageRx_PCM[n+2]==0x8F) {
if (currentPage!=3) {request = PID; RequestPeriod = 70;} else request = PRESENT, RequestPeriod = 4000; prevRequest = curmillis; // receive good INIT
}
else if (MessageRx_PCM[n]==0x58) Troublecodes (); // DTC
else if (MessageRx_PCM[n]==0x54 && MessageRx_PCM[n+1]==0xFF && MessageRx_PCM[n+2]==0x00){ request = PRESENT; RequestPeriod = 4000; prevRequest = curmillis;} // DTC are cleared
else if (MessageRx_PCM[n]==0x61 && MessageRx_PCM[n+1]==0x01) {dataVars() ; RequestPeriod = 70; prevRequest = curmillis; } // receive DataStream
}
// если контрольная сумма не совпала:
#ifdef debugPCM
else Serial.println("CRC fail!!!" );
#endif
message_size = 0; header=0; RESETheader_timer = 0; j=3; crc = 0;
}
// таймер ожидания байт (для успевания появления данных в буфере UART)
if (!Delay && curmillis - timerdelay > waitbyte_RX) Delay = 1;
// таймер сброса целостности сообщения (если данные оборвались посередине сообщения)
if (RESETheader_timer && curmillis - prevRESETheader > 200) {
#ifdef debugPCM
Serial.println(F("Message fail timeout"));
#endif
RESETheader_timer = 0; header = 0;}
// если нет ответа после запроса: +1 к счетчику неответов. Если накопилось 6 и более: делаем реинит.
if (request!=INIT && NOanswer_timer && curmillis - prev_NOanswer > RequestPeriod - RequestPeriod/10)
{
NOanswer_timer = 0; noanswers++;
if (noanswers>=6) { noanswers = 0; request = INIT; RequestPeriod = 3500;}
}
}// end receivePCM
void Troublecodes ()
{
if (MessageRx_PCM[n]==0x58 && MessageRx_PCM[n+1]==0x00){
myGLCD.clrScr();
drawscreen_three();
myGLCD.print("NO DTC", 180, 145);
}
// при получении сообщения о наличии ошибок DTC разберем сообщение выведем на экран ошибки
if (MessageRx_PCM[n]==0x58 && MessageRx_PCM[n+1]>0){
myGLCD.clrScr();
drawscreen_three();
for (int i=0; i<MessageRx_PCM[n+8-7]; i++ ) {
int y = i*35;
bool nolA=0; bool nolB =0;
if (!bitRead(MessageRx_PCM[n+11-7+(i*3)],6) && bitRead(MessageRx_PCM[n+11-7+(i*3)],7)){ myGLCD.setTextColor(GREEN, BLACK);
myGLCD.print(" -Passive-", 300, (75+y));} // если DTC пасивныый делаем цвет зеленый
if (bitRead(MessageRx_PCM[n+11-7+(i*3)],7) && bitRead(MessageRx_PCM[n+11-7+(i*3)],6)) { myGLCD.setTextColor(RED, BLACK);
myGLCD.print(" -Active-", 300, (75+y));} // если DTC активный, делаем цвет красный
myGLCD.print("ERROR ", 50, (75+y));
myGLCD.printNumI((i+1), 150, (75+y));
if (!bitRead(MessageRx_PCM[n+9-7+(i*3)],6) && !bitRead(MessageRx_PCM[n+9-7+(i*3)],7)) myGLCD.print(": P", 170, (75+y));
if (bitRead(MessageRx_PCM[n+9-7+(i*3)],6) && !bitRead(MessageRx_PCM[n+9-7+(i*3)],7)) myGLCD.print(": C", 170, (75+y));
if (!bitRead(MessageRx_PCM[n+9-7+(i*3)],6) && bitRead(MessageRx_PCM[n+9-7+(i*3)],7)) myGLCD.print(": B", 170, (75+y));
if (bitRead(MessageRx_PCM[n+9-7+(i*3)],6) && bitRead(MessageRx_PCM[n+9-7+(i*3)],7)) myGLCD.print(": U", 170, (75+y));
if (MessageRx_PCM[n+9-7+(i*3)]==0x00) {myGLCD.print("00", 230, (75+y)); nolA = 1;}
if (MessageRx_PCM[n+9-7+(i*3)]<=0x0F&&MessageRx_PCM[n+9-7+(i*3)]!=0) {myGLCD.print("0", 230, (75+y)); nolA = 1;}
if (nolA)myGLCD.print(String (MessageRx_PCM[n+9-7+(i*3)],HEX), 246, (75+y));
else myGLCD.print(String (MessageRx_PCM[n+9-7+(i*3)],HEX), 230, (75+y));
if (MessageRx_PCM[n+10-7+(i*3)]==0x00) {myGLCD.print("00", 262, (75+y)); nolB = 1;}
if (MessageRx_PCM[n+10-7+(i*3)]<=0x0F&&MessageRx_PCM[n+10-7+(i*3)]!=0) {myGLCD.print("0", 262, (75+y)); nolB = 1;}
if (nolB)myGLCD.print(String (MessageRx_PCM[n+10-7+(i*3)]),HEX, 278, (75+y));
else myGLCD.print(String (MessageRx_PCM[n+10-7+(i*3)],HEX), 262, (75+y));}}
request = PRESENT; RequestPeriod = 4000; prevRequest = curmillis;
}
void dataVars()
{
//Barom = MessageRx_PCM[39];
L100 = (float)LHor*100.0/(float)Speed;
LHor = (float)RPM* (float)InjQua*2.00/1000.0*60.00/1000.0/0.85;
MAF = ((MessageRx_PCM[n+22]*256)+MessageRx_PCM[n+23])/10;
BoostPres = ((MessageRx_PCM[n+24]*256)+MessageRx_PCM[n+25])/1000.0;
RPM = (MessageRx_PCM[n+35-7]*256)+MessageRx_PCM[n+36-7];
EGRmg = ((MessageRx_PCM[n+37-7]*256)+MessageRx_PCM[n+38-7])/10.0;
BoostPresCom = ((MessageRx_PCM[n+41-7]*256)+MessageRx_PCM[n+42-7])/1000.0;
Speed = ((MessageRx_PCM[n+47-7]*256)+MessageRx_PCM[n+48-7])/100;
DesaInjQua = ((MessageRx_PCM[n+53-7]*256)+MessageRx_PCM[n+54-7])/100.0;
InjQua = ((MessageRx_PCM[n+55-7]*256)+MessageRx_PCM[n+56-7])/100.0;
StaDaliv = ((MessageRx_PCM[n+57-7]*256)+MessageRx_PCM[n+58-7])/100.0;
PumpRPM = (MessageRx_PCM[n+59-7]*256)+MessageRx_PCM[n+60-7];
EGRPul = ((MessageRx_PCM[n+65-7]*256)+MessageRx_PCM[n+66-7])/100.0;
SolenPul = ((MessageRx_PCM[n+67-7]*256)+MessageRx_PCM[n+68-7])/100.0;
SolenPre = ((MessageRx_PCM[n+73-7]*256)+MessageRx_PCM[n+74-7])/100.0;
DesInj = ((MessageRx_PCM[n+75-7]*3)+(MessageRx_PCM[n+76-7])/100.0)+0.3;
ActInj = ((MessageRx_PCM[n+19-7]*3)+(MessageRx_PCM[n+20-7])/100.0)+0.3;
//TempAir = ((MessageRx_PCM[n+77-7]*26)-278)+MessageRx_PCM[n+78-7]/10.0;
//Temp = ((MessageRx_PCM[n+17-7]*26)-278)+MessageRx_PCM[n+18-7]/10.0;
//TempOil = ((MessageRx_PCM[n+21-7]*26)-278)+MessageRx_PCM[n+22-7]/10.0;
//TempFuel = ((MessageRx_PCM[n+61-7]*26)-278)+MessageRx_PCM[n+62-7]/10.0;
//ниже идут расчетные формулы более точные чем те что закоментированы выше
int A = 0;
if (MessageRx_PCM[n+77-7]<=0x0A) A = 277;
if (MessageRx_PCM[n+77-7]==0x0B || MessageRx_PCM[n+77-7]==0x0C) A = 278;
if (MessageRx_PCM[n+77-7]>=0x0D) A = 279;
double B = MessageRx_PCM[n+78-7]/10.0;
double cel , drob ;
drob = modf(B, &cel);
if (drob>0.6) cel++;
TempAir = ((MessageRx_PCM[n+77-7]*26)-A)+cel;
if (MessageRx_PCM[n+17-7]<=0x0A) A = 277;
if (MessageRx_PCM[n+17-7]==0x0B || MessageRx_PCM[n+17-7]==0x0C) A = 278;
if (MessageRx_PCM[n+17-7]>=0x0D) A = 279;
B = MessageRx_PCM[n+18-7]/10.0;
drob = modf(B, &cel);
if (drob>0.6) cel++;
Temp = ((MessageRx_PCM[n+17-7]*26)-A)+cel;
if (MessageRx_PCM[n+21-7]<=0x0A) A = 277;
if (MessageRx_PCM[n+21-7]==0x0B || MessageRx_PCM[n+21-7]==0x0C) A = 278;
if (MessageRx_PCM[n+21-7]>=0x0D) A = 279;
B = MessageRx_PCM[n+22-7]/10.0;
drob = modf(B, &cel);
if (drob>0.6) cel++;
TempOil = ((MessageRx_PCM[n+21-7]*26)-A)+cel;
if (MessageRx_PCM[n+61-7]<=0x0A) A = 277;
if (MessageRx_PCM[n+61-7]==0x0B || MessageRx_PCM[n+61-7]==0x0C) A = 278;
if (MessageRx_PCM[n+61-7]>=0x0D) A = 279;
B = MessageRx_PCM[n+62-7]/10.0;
drob = modf(B, &cel);
if (drob>0.6) cel++;
TempFuel = ((MessageRx_PCM[n+61-7]*26)-A)+cel;
//----------------------------------------------------------
//страниц HOME
//----------------------------------------------------------
//myGLCD.setBackColor(RED);
myGLCD.setTextColor(WHITE, BLACK);
//myGLCD.setBackColor(RED);
if ((Speed != Speed_last) || reNew) {myGLCD.printNumI(Speed, 360, 7, 3); Speed_last=Speed;}
if (currentPage == '0') {
if ((LHor != LHor_last) || reNew) {myGLCD.printNumF(LHor, 1, 75, 40, '.',4); LHor_last=LHor;}
if ((L100 != L100_last) || reNew) {myGLCD.printNumF(L100, 1, 225, 40,'.',4 ); L100_last=L100;}
if ((L100M != L100M_last) || reNew) {myGLCD.printNumF(L100M, 1, 75, 75,'.',4 ); L100M_last=L100M;}
if ((L100SR_TFT != L100SR_TFT_last) || reNew) {myGLCD.printNumF(L100SR_TFT, 1, 225, 75,'.',4 ); L100SR_TFT_last=L100SR_TFT;}
if ((kmREFUELING != kmREFUELING_last) || reNew) {myGLCD.printNumI(kmREFUELING, 90, 110,3 ); kmREFUELING_last=kmREFUELING;}
//if (Fuel<53)
if ((Fuel != Fuel_last) || reNew) {myGLCD.printNumF(Fuel, 1, 225, 110,'.',4); Fuel_last=Fuel;}
//else myGLCD.print("MAX", 210, 110);
if ((kmTrip != kmTrip_last) || reNew) {myGLCD.printNumF(kmTrip, 1, 60, 145,'.',5); kmTrip_last=kmTrip;}
if ((FuelTrip != FuelTrip_last) || reNew) {myGLCD.printNumF(FuelTrip, 1, 210, 145,'.',5); FuelTrip_last=FuelTrip;}
if ((PumpRPM != PumpRPM_last) || reNew) {myGLCD.printNumI(PumpRPM, 230, 180,4); PumpRPM_last=PumpRPM;}
if ((RPM != RPM_last) || reNew) {myGLCD.printNumI(RPM, 230, 215,4); RPM_last=RPM;}
if ((Fuel2 != Fuel2_last) || reNew) {myGLCD.printNumF(Fuel2, 1, 10, 215,'.',4); Fuel2_last=Fuel2;}
if ((Temp != Temp_last) || reNew) {myGLCD.printNumI(Temp, 415, 40, 3); Temp_last=Temp;}
if ((TempOil != TempOil_last) || reNew) {myGLCD.printNumI(TempOil, 415, 75, 3); TempOil_last=TempOil;}
if ((TempFuel != TempFuel_last) || reNew) {myGLCD.printNumI(TempFuel, 415, 110,3); TempFuel_last=TempFuel;}
myGLCD.printNumI(sensors.getTempCByIndex(0), 415, 145 , 3);
if ((t != t_last) || reNew) {myGLCD.printNumI(t, 415, 180, 3); t_last=t;}
if ((TempAir != TempAir_last) || reNew) {myGLCD.printNumI(TempAir, 415, 215, 3); TempAir_last=TempAir;}
reNew = 0;
}
//----------------------------------------------------------
//страниц INF1
//----------------------------------------------------------
if (currentPage == '1') {
if ((StaDaliv != StaDaliv_last) || reNew) {myGLCD.printNumF(StaDaliv,1, 385, 40,'.', 4); StaDaliv_last=StaDaliv;}
if ((DesInj != DesInj_last) || reNew) {myGLCD.printNumF(DesInj,1, 385, 75, '.', 4); DesInj_last=DesInj;}
if ((ActInj != ActInj_last) || reNew) {myGLCD.printNumF(ActInj,1, 385, 110,'.', 4); ActInj_last=ActInj;}
if ((DesaInjQua != DesaInjQua_last) || reNew) {myGLCD.printNumF(DesaInjQua,1, 385, 145,'.', 4);DesaInjQua_last=DesaInjQua;}
if ((InjQua != InjQua_last) || reNew) {myGLCD.printNumF(InjQua,1, 385, 180,'.', 4); InjQua_last=InjQua;}
if ((MAF != MAF_last) || reNew) {myGLCD.printNumI(MAF, 170, 215, 4); MAF_last=MAF;}
if ((h != h_last) || reNew) {myGLCD.printNumF(h, 1, 430, 215, 3); h_last=h;}
reNew = 0;
}
//----------------------------------------------------------
//страниц INF2
//----------------------------------------------------------
if (currentPage == '2') {
if ((BoostPres != BoostPres_last) || reNew) {myGLCD.printNumF(BoostPres,1, 400, 40,'.', 4); BoostPres_last=BoostPres;}
if ((BoostPresCom != BoostPresCom_last) || reNew) {myGLCD.printNumF(BoostPresCom,1, 400, 75,'.', 4); BoostPresCom_last=BoostPresCom;}
if ((EGRmg != EGRmg_last) || reNew) {myGLCD.printNumI(EGRmg, 400, 110, 4); EGRmg_last=EGRmg;}
if ((EGRPul != EGRPul_last) || reNew) {myGLCD.printNumF(EGRPul,1, 400, 145,'.', 4); EGRPul_last=EGRPul;}
if ((SolenPul != SolenPul_last) || reNew) {myGLCD.printNumF(SolenPul, 1, 400, 180,'.', 4); SolenPul_last=SolenPul;}
if ((SolenPre != SolenPre_last) || reNew) {myGLCD.printNumF(SolenPre, 0, 400, 215,'.', 4); SolenPre_last=SolenPre;}
reNew = 0;
}
//reNew = 0;
}
void sendMessagePCM(const byte &command)
{
#ifdef debugPCM
Serial.print (F("Send request ")); Serial.print (textRequest[command]); Serial.print (F(" to PCM ")); Serial.println (millis());
#endif
if (command != INIT) {NOanswer_timer = 1; prev_NOanswer = curmillis;} //т.к. сейчас будем делать запрос, то запускаем таймер контроля неответов
byte size = PCM_Message_TX[command][0];
const byte siZe = size+4;
byte Mes[siZe];
byte Checksum = 0;
for(byte i=0; i<siZe; i++) {
if (i==0) {Mes[i]=size; bitWrite(Mes[i], 7 , 1);}
if (i==1) Mes[i] = PCM_address;
if (i==2) Mes[i] = DIAG_address;
if (i==3) {for (byte t=1; t<size+1; t++ ) {
Mes[i]=PCM_Message_TX [command][t];
Checksum+=Mes[i] ;
K_LINE_PCM.write (Mes[i]);
if (command == INIT) delay (5); else delay (delaybyte_TX);
K_LINE_PCM.read();
i++;}}
if (i!=siZe-1) Checksum+=Mes[i];
else Mes[i] = Checksum;
K_LINE_PCM.write (Mes[i]);
if (command == INIT) delay (5); else delay (delaybyte_TX);
K_LINE_PCM.read();
}
}// end sendMessagePCM
void receiveGAUGE () {
while(InitGauge==1){
if (K_LINE_GAUGE.available()) {
byte inByte = K_LINE_GAUGE.read();
#ifdef debugGAUGE
Serial.print(" ");
Serial.print(inByte,HEX);
#endif
if (inByte==0x80) {K_LINE_GAUGE.write (0x7F); delay (1);}
if (inByte==0xF0) {
for (byte i=0; i<sizeof(PIDgauge); i++) { K_LINE_GAUGE.write (PIDgauge[i]); delay (1);}
InitGauge=2; NoconnectsGAUGE = 0;}}}
bool MessageParse = 0;
bool dataMessageEND = 0;
bool dataMessageOK = 0;
byte headerGAUGE = 0;
byte numberbyte = 0;
while (InitGauge==2 && !MessageParse && flagneedGAUGE) {
if (!dataMessageOK) {
if (K_LINE_GAUGE.read() == 0x23 && headerGAUGE ==0) {headerGAUGE=1; delay (waitbyte_gauge); }
if (K_LINE_GAUGE.read() == 0xA1 && headerGAUGE ==1) {headerGAUGE=2; delay (waitbyte_gauge);}
else {headerGAUGE =0;}
if (K_LINE_GAUGE.read() == 0x04 && headerGAUGE ==2) {headerGAUGE=3; delay (waitbyte_gauge);}
else {headerGAUGE =0;}
if (headerGAUGE ==3) {dataMessageOK = 1; headerGAUGE =0;}
numberbyte=0;}
else { if (K_LINE_GAUGE.available()>0) { MessageRxGauge[numberbyte] = K_LINE_GAUGE.read(); numberbyte++; delayMicroseconds (250);}
if (numberbyte==34) {dataMessageEND = 1; dataMessageOK = 0; }}
if (dataMessageEND) {
int crc = ( ( unsigned int )MessageRxGauge[32] << 8 ) | MessageRxGauge[33]; // парсинг контрольной суммы из 2 последних байт
int CRC =200;
for (int i = 0; i < 32; i++) CRC = CRC + MessageRxGauge[i]; // подсчет контрольной суммы байт от 0 до 31
#ifdef debugGAUGE
Serial.print (" ReceiveGauge: ");
for (int i = 0; i < 34; i++) {
Serial.print(MessageRxGauge[i],HEX); Serial.print (" ");}
#endif
//при получении сообщения БЕЗ ошибок с данными от панели приборов, запишем в переменные остаток топлива и пробег
if (CRC==crc) {
#ifdef debugGAUGE
Serial.println (" OK!!!");
#endif
flagneedGAUGE = 0;
Fuel2 = MessageRxGauge[16]/2.0;
if (!flagFuelIGN) { Fuel = MessageRxGauge[16]/2.00; kmREFUELING=((float)Fuel*100.00)/(float)L100SR_TFT;} //стартовая запись литров в баке для подсчета затраченных литро
else Fuel = MessageRxGauge[17]/2.0; //для устреднения болтания в баке закоментировать эту строку, а раскоментировать ниже
//для усреднения болтания топлива в баке, раскоментировать, высчитывает среднее
/*else { FuelZamer[ZamerNumber] = MessageRxGauge[17]/2.00;
if (ZamerNumber==9) {
Fuel = 0 ;
for (int i = 0; i < 10; i++) Fuel = Fuel + FuelZamer[i];
Fuel = (float)Fuel/10.0;}
ZamerNumber++; if (ZamerNumber>9) ZamerNumber = 0;}
*/
kmAge = (MessageRxGauge[23]+(MessageRxGauge[24]*256))/10.0; //суточный пробег с панели приборов
//бак у меня на 59 литров, а датчик показывает максимально 53 литра. для этого эта формула
//если у вас тоже датчик имеет лимит то подправте 53 на свой лимит.
//если ваш датчик показывает одинаково с полным баком то закоментировать три нижние строки.
if (Fuel<53){
if (!flagkmAgeIGN) { kmAgeIGN = kmAge; flagkmAgeIGN =1;}
if (!flagFuelIGN) { FuelIGN = Fuel; Fuel_last = Fuel; flagFuelIGN = 1; }}}
#ifdef debugGAUGE
else Serial.println (" ERROR!!!");
#endif
dataMessageEND = 0; MessageParse = 1;
NoconnectsGAUGE = 0;}}
// if (curmillis - prevNoconnect > 500) {NoconnectsGAUGE ++ ; if (NoconnectsGAUGE>=10){
// #ifdef debugGAUGE
// Serial.println (F(" Connect GAUGE failed!!! ")) ;
// #endif
// NoconnectsGAUGE = 0 ;InitGauge = 0 ; } prevNoconnect = curmillis; }
InitBusGAUGE ();
}// end receiveGAUGE
void InitBusGAUGE ()
{
if (InitGauge == 0){
#ifdef debugGAUGE
Serial.println ("Send startsession - address Gauge");
#endif
K_LINE_GAUGE.end();
pinMode(TX_gauge, OUTPUT);
digitalWrite (TX_gauge, HIGH); // BUS IDLE
InitGauge = 5; prevInitbusGauge = curmillis;
}
if (InitGauge == 5 && curmillis - prevInitbusGauge>1500) {InitGauge = 6;} // BUS IDLE
if (InitGauge == 6)
{
byte boudrate = 1000/BAUD;
digitalWrite (TX_gauge, LOW); delay (boudrate); // старт бит
for (byte i=0; i<8; i++){digitalWrite (TX_gauge, bitRead(addressGUAGE, i)); delay (boudrate);} // биты тела адреса
digitalWrite (TX_gauge, HIGH); delay (boudrate); // стоп бит
K_LINE_GAUGE.begin(9600);
InitGauge = 1;
}
}
#if defined debugPCM or defined debugGAUGE
void printDebugRX (const byte &inbyte) {if (inbyte<=15) Serial.print(F("0")); Serial.print (inbyte, HEX); Serial.print (F(" "));}
#endif
#ifdef debugPCM
void printDebugRX_CSgood(){
if (MessageRx_PCM[n]==0xC1 && MessageRx_PCM[n+1]==0x6B && MessageRx_PCM[n+2]==0x8F) {Serial.println (F(" Initialization OK!!!!")); }
else if (MessageRx_PCM[n]==0x58 && MessageRx_PCM[n+1]==0x00) {Serial.println (F(" NO DTC "));}
else if (MessageRx_PCM[n]==0x58 && MessageRx_PCM[n+1] >0x00) {Serial.println (F(" DTC is found!"));}
else if (MessageRx_PCM[n]==0x54 && MessageRx_PCM[n+1]==0xFF && MessageRx_PCM[n+2]==0x00){Serial.println (F(" DTC CLEARED "));}
else if (MessageRx_PCM[n]==0x61 && MessageRx_PCM[n+1]==0x01) {Serial.println (F(" Receive PCM DATAstream"));}}
#endif
void Menu () {
TouchHOME();
if (currentPage == '0') {
TouchINF1();
TouchINF2();
TouchCHECK(); }
if (currentPage == '1') {
TouchINF2();
TouchCHECK(); }
if (currentPage == '2') {
TouchINF1();
TouchCHECK(); }
if (currentPage == '3') {
TouchREAD();
TouchERASE(); }}
void drawHomeScreen() {
line() ;
Watch ();
//myGLCD.print(":", 290, 5);
myGLCD.print("/", 115, 7);
myGLCD.print("/", 160, 7);
myGLCD.setTextColor(RED, BLACK); // цвет линии и текста красный
myGLCD.drawLine(295,35,295,248); // линия вертикальная
myGLCD.drawLine(145,35,145,178); // линия вертикальная
myGLCD.drawLine(80,178,80,247); // линия вертикальная
myGLCD.print("L/H", 10, 40);
myGLCD.print("L/A", 148, 40);
myGLCD.print("L/V", 10, 75);
myGLCD.print("L/M", 148, 75);
myGLCD.print("D/K", 10, 110);
myGLCD.print("D/L", 148, 110);
myGLCD.print("V/K", 10, 145);
myGLCD.print("V/L", 148, 145);
myGLCD.print("PUMP RPM", 82, 180);
myGLCD.print("ENGI RPM", 82, 215);
myGLCD.print("D/L/A", 10, 180);
myGLCD.print("Motor C", 300, 40);
myGLCD.print("OIL C", 300, 75);
myGLCD.print("FUEL C", 300, 110);
myGLCD.print("INTER C", 300, 145);
myGLCD.print("EXTER C", 300, 180);
myGLCD.print("INTAIR C", 300, 215);
//myGLCD.setTextColor(RED);
myGLCD.drawRoundRect (15, 255, 145, 310);
myGLCD.print("INF 1", 55, 270);
myGLCD.drawRoundRect (175, 255, 305, 310);
myGLCD.print("INF 2", 215, 270);
myGLCD.drawRoundRect (335, 255, 465, 310);
myGLCD.print("CHECK", 365, 270);
myGLCD.drawRoundRect (1, 1, 77, 37);
myGLCD.print("HOME", 10, 7);
myGLCD.print("Km/h", 410, 7);
reNew = 1;
}
//-------------------------------------------------
void drawscreen_one() {
line() ;
Watch ();
//myGLCD.print(":", 290, 5);
myGLCD.print("/", 115, 7);
myGLCD.print("/", 160, 7);
myGLCD.setTextColor(RED, BLACK); // цвет линии и текста красный
myGLCD.print("Start of Delivery *CA:", 10, 40);
myGLCD.print("Desir inject Start *CA:", 10, 75);
myGLCD.print("Actua Inject Start *CA:", 10, 110);
myGLCD.print("Desir Inject Quan mg/s:", 10, 145);
myGLCD.print("Actu Inject Quant mg/s:", 10, 180);
myGLCD.print("MAF mg/s:", 10, 215);
myGLCD.print("Humedad %:", 255, 215);
//myGLCD.setTextColor(RED);
myGLCD.drawRoundRect (175, 255, 305, 310);
myGLCD.print("INF 2", 215, 270);
myGLCD.drawRoundRect (335, 255, 465, 310);
myGLCD.print("CHECK", 365, 270);
myGLCD.drawRoundRect (1, 1, 77, 37);
myGLCD.print("HOME", 10, 7);
myGLCD.print("Km/h", 410, 7);
reNew = 1;
}
//-------------------------------------------------
void drawscreen_two() {
line() ;
Watch ();
//myGLCD.print(":", 290, 5);
myGLCD.print("/", 115, 7);
myGLCD.print("/", 160, 7);
myGLCD.setTextColor(RED, BLACK); // цвет линии и текста красный
myGLCD.print("Boost Press Bar:", 10, 40);
myGLCD.print("Boost Press Com Bar:", 10, 75);
myGLCD.print("EGR command mg/s:", 10, 110);
myGLCD.print("EGR Pulse Ratio %:", 10, 145);
myGLCD.print("Solenoide Pulse %:", 10, 180);
myGLCD.print("Solenoide Boost %:", 10, 215);
//myGLCD.setColor(RED);
myGLCD.drawRoundRect (15, 255, 145, 310);
myGLCD.print("INF 1", 55, 270);
myGLCD.drawRoundRect (335, 255, 465, 310);
myGLCD.print("CHECK", 365, 270);
myGLCD.drawRoundRect (1, 1, 77, 37);
myGLCD.print("HOME", 10, 7);
myGLCD.print("Km/h", 410, 7);
reNew = 1;
}
//----------------------------------------------------------------------------
void drawscreen_three() {
Watch ();
//myGLCD.print(":", 290, 5);
myGLCD.print("/", 115, 7);
myGLCD.print("/", 160, 7);
myGLCD.setTextColor(RED, BLACK); // цвет линии красный
myGLCD.drawLine(1,35,479,35); // линия горизонтальная
myGLCD.drawLine(1,248,479,248); // линия горизонтальная
//myGLCD.setTextColor(RED);
myGLCD.drawRoundRect (15, 255, 145, 310);
myGLCD.print("ERASE", 55, 270);
myGLCD.drawRoundRect (335, 255, 465, 310);
myGLCD.print("READ", 365, 270);
myGLCD.drawRoundRect (1, 1, 77, 37);
myGLCD.print("HOME", 10, 5);
reNew = 1;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//кнопки тач . координаты и переходы
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void TouchHOME(){
TSPoint p = ts.getPoint();
pinMode(XM, OUTPUT);
pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
{if (p.x > 140 && p.x < 320 && p.y > 140 && p.y < 260 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
{ myGLCD.drawRoundRect (1, 1, 77, 37);
currentPage = '0';
request = PID; RequestPeriod = 10; prevRequest = curmillis; // на PCM в этом окне посылается запрос текущих параметров
myGLCD.clrScr();
drawHomeScreen();
x = 0;
y = 0;
p.z = 0;}}}
void TouchINF1(){
TSPoint p = ts.getPoint();
pinMode(XM, OUTPUT);
pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
{
if (p.x > 150 && p.x < 450 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
{ myGLCD.drawRoundRect (15, 255, 145, 310);
currentPage = '1';
request = PID; RequestPeriod = 10; prevRequest = curmillis; // на PCM в этом окне посылается запрос текущих параметров
myGLCD.clrScr();
drawscreen_one();
x = 0;
y = 0;
p.z = 0;}}}
void TouchINF2(){
TSPoint p = ts.getPoint();
pinMode(XM, OUTPUT);
pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
{
if (p.x > 450 && p.x < 680 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
{ myGLCD.drawRoundRect (175, 255, 305, 310);
currentPage = '2';
request = PID; RequestPeriod = 600; prevRequest = curmillis; // на PCM в этом окне посылается запрос текущих параметров
myGLCD.clrScr();
drawscreen_two();
x = 0;
y = 0;
p.z = 0;}}}
void TouchCHECK(){
TSPoint p = ts.getPoint();
pinMode(XM, OUTPUT);
pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
{
if (p.x > 690 && p.x < 950 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
{ myGLCD.drawRoundRect (335, 255, 465, 310);
currentPage = '3';
// request = DTCREAD; RequestPeriod = 10; prevRequest = curmillis; // на PCM в этом окне посылается запрос чтения ошибок
myGLCD.clrScr();
drawscreen_three();
x = 0;
y = 0;
p.z = 0;}}}
void TouchREAD(){
TSPoint p = ts.getPoint();
pinMode(XM, OUTPUT);
pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
{
if (p.x > 690 && p.x < 950 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
{ myGLCD.drawRoundRect (335, 255, 465, 310);
request = DTCREAD; RequestPeriod = 300; prevRequest = curmillis; // на PCM при нажатии этой кнопки посылается запрос чтения ошибок
x = 0;
y = 0;
p.z = 0;}}}
void TouchERASE(){
TSPoint p = ts.getPoint();
pinMode(XM, OUTPUT);
pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
{
if (p.x > 150 && p.x < 450 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
{myGLCD.drawRoundRect (15, 255, 145, 310);
request = DTCERASE; RequestPeriod = 300; prevRequest = curmillis; // на PCM при нажатии этой кнопки посылается запрос удаления ошибок
myGLCD.clrScr();
drawscreen_three();
myGLCD.print("DTC BORRADO", 180, 145);
x = 0;
y = 0;
p.z = 0;}}}
////////////////////////////////////////////////////////////////////////////////////////
//прорисовка линий
///////////////////////////////////////////////////////////////////////////////////////
void line() {
//myGLCD.setTextColor(RED); // цвет линии красный
myGLCD.drawLine(1,35,479,35); // линия горизонтальная
myGLCD.drawLine(1,73,479,73); // линия горизонтальная
myGLCD.drawLine(1,108,479,108); // линия горизонтальная
myGLCD.drawLine(1,143,479,143); // линия горизонтальная
myGLCD.drawLine(1,178,479,178); // линия горизонтальная
myGLCD.drawLine(1,212,479,212); // линия горизонтальная
myGLCD.drawLine(1,248,479,248); // линия горизонтальная
}
void Watch (){
DateTime now = rtc.now();
int minut = now.minute();
int hour = now.hour();
int mon = now.month();
int date = now.day();
int Year = now.year();
static int minut_last;
static int hour_last;
static int mon_last;
static int date_last;
static int Year_last;
myGLCD.setTextColor(WHITE, BLACK); //белый цвет цифры
if (date != date_last || reNew){ myGLCD.printNumI(date, 85, 7, 2, '0'); date_last = date; }
if (mon!=mon_last || reNew){myGLCD.printNumI(mon, 130, 7, 2, '0'); mon_last = mon; }
if (Year!=Year_last || reNew) { myGLCD.printNumI(Year, 175, 7); Year_last = Year; }
if (hour!=hour_last || reNew){ myGLCD.printNumI(hour, 255, 7, 2, '0'); hour_last = hour; }
if (minut!=minut_last || reNew ){ myGLCD.printNumI(minut, 300, 7, 2, '0'); minut_last = minut; }
}
void Temperature (){
h = dht.readHumidity();
t = dht.readTemperature();
sensors.requestTemperatures();
}
#include <OneWire.h>
OneWire ds(22); // on pin 10 (a 4.7K resistor is necessary)
void setup(void) {
Serial.begin(115200);
}
void loop(void) {
byte i;
byte present = 0;
byte type_s;
byte data[12];
byte addr[8];
float celsius, fahrenheit;
if ( !ds.search(addr)) {
Serial.println("No more addresses.");
Serial.println();
ds.reset_search();
delay(250);
return;
}
Serial.print("ROM =");
for( i = 0; i < 8; i++) {
Serial.write(' ');
Serial.print(addr[i], HEX);
}
if (OneWire::crc8(addr, 7) != addr[7]) {
Serial.println("CRC is not valid!");
return;
}
Serial.println();
// the first ROM byte indicates which chip
switch (addr[0]) {
case 0x10:
Serial.println(" Chip = DS18S20"); // or old DS1820
type_s = 1;
break;
case 0x28:
Serial.println(" Chip = DS18B20");
type_s = 0;
break;
case 0x22:
Serial.println(" Chip = DS1822");
type_s = 0;
break;
default:
Serial.println("Device is not a DS18x20 family device.");
return;
}
ds.reset();
ds.select(addr);
ds.write(0x44, 1); // start conversion, with parasite power on at the end
delay(1000); // maybe 750ms is enough, maybe not
// we might do a ds.depower() here, but the reset will take care of it.
present = ds.reset();
ds.select(addr);
ds.write(0xBE); // Read Scratchpad
Serial.print(" Data = ");
Serial.print(present, HEX);
Serial.print(" ");
for ( i = 0; i < 9; i++) { // we need 9 bytes
data[i] = ds.read();
Serial.print(data[i], HEX);
Serial.print(" ");
}
Serial.print(" CRC=");
Serial.print(OneWire::crc8(data, 8), HEX);
Serial.println();
// Convert the data to actual temperature
// because the result is a 16 bit signed integer, it should
// be stored to an "int16_t" type, which is always 16 bits
// even when compiled on a 32 bit processor.
int16_t raw = (data[1] << 8) | data[0];
if (type_s) {
raw = raw << 3; // 9 bit resolution default
if (data[7] == 0x10) {
// "count remain" gives full 12 bit resolution
raw = (raw & 0xFFF0) + 12 - data[6];
}
} else {
byte cfg = (data[4] & 0x60);
// at lower res, the low bits are undefined, so let's zero them
if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms
else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
//// default is 12 bit resolution, 750 ms conversion time
}
celsius = (float)raw / 16.0;
fahrenheit = celsius * 1.8 + 32.0;
Serial.print(" Temperature = ");
Serial.print(celsius);
Serial.print(" Celsius, ");
Serial.print(fahrenheit);
Serial.println(" Fahrenheit");
}
Макс вообщем хаус. поездка 30 км. средний расход за поездку стартует с 99.0л/100 закончил где то 13л/100. самый средний расход висит восновном на 0.9 иногда может быть 2.5 или 3.5. Внутрення температура у меня дошла до 63 градуса. Наружняя тоже чето не то, обычно интактаире и наружняя различаются в 2 градуса, а вчера была разнится в 10 градусов. актуальный расход у меня никогда не прыгал выше 14л/100 под нагрузкой, сейчас проскакивали цыфры и 35л/100. Остаток в баке на километры тоже не верно отображает, меньше, вроде как. А так же актуальный остаток в баке очень разнится от среднего остатак, и из за этого больше висит расход за поездку в минусе, иногда может быть и в плусе, редко, наверно как расчет поподет, когда они оба примерно одинаковы или очень разные. Километры за поездку тоже, выехал с дома, 100 метров проехал показывает уже 200, проехал еще 200 уже показало 1 км 200 м, но иногда правильно показывает но отстает сильно от реальных, иногда вроде уравнивается. Был включен #define debugGAUGE, думаешь это могло так мешать? Не уверен но это моя мысль.... Возможно изза большой задержки в 30 секунд, когда идет запись то в этот момент чтото уже обновилось а чтото еще не успело..... вот и происходит не верные запись и подсчеты. Не уверен, это просто мысль. Примерно так,
дебаг не причем. Возможно номера байтов как то сбились, поэтому неправильные данные от панели ловит, ну или ,действительно, из за того, что редко обновляется - раз в 30 сек. Может в какой то момент просто перестали данные от панели поступать, как вариант. Поведение программы вообще не удивительно, т.к. весь проект получился в итоге на костылях, начиная от библы экрана, тача, заканчивая организацией протоколов обмена с блоками. Даже не знаю что тут и предложить, честно.
Мои новые подходы к чтению блоков не проканали в реальных условиях (работают только если в программе ничего другого нет). Хотя может эти алгоритмы и работали бы нормально, если бы это всё остальное в программе не тормозило последнюю. Но по идее на такой случай они и писались, х.з. почему не работают - байты куда-то теряются, хотя должны спокойно храниться в буфере, пока их от туда не вычитаешь. Можно было бы предположить, как говорил Komandir, что дело в библиотеке Softserial , дак ведь когда заморочились с панелью, косяки проявлялись такие же (стоило немного притормозить луп и байты стали теряться), но она то висит на хардсериале, так что алгоритм гавно, получается, а не хард или софтсериал.
дак ты же как то срастил старый скетч с новым экраном? Где он там у тебя. Бери щас да пользуй, коль выяснили, что подтормаживала библиотека экрана , но ты её щас то уже поправил.
Короче, Макс. Как ни рути всему виной шрифт, он все тормозит и даже при шрифте перестает идти запрос на ебу, идет только панель. Оставил стандартный шриф 2го размера, маловат, нужно присматриватся когда едешь, а 3й за большой. но, все работает мгновенно. Прорисовка меню и данных мгновенная, обновление данных быстрое. Это о моем старом скетче. Твой новый тоже рботает так же но, хаус с расчетами остался. Последняя прозьба, в старом скетче почемуто перестали работать 4 параметра, это странно так как раньше они работали, это
TempAir показывает( - 277) , EGRPul показывает (0.0), SolenPul показывает (0.0) и SolenPre показывает (0).
а, заливаю твой последний усовершенствованый, все параметры работают.
глянь когда сможешь, и если не сложно и не долго и если это возможно, добавть в этот скетч переподключение если будет сбой.
если эти две проблемки : не работающие 4 параметра и переподключение решить, мне больше ничего не нужно, я буду счастлив. вот скетч
/////////////////////////////////////////////////////////////////////////////////////////
//библиотеки
///////////////////////////////////////////////////////////////////////////////////////////
#include <Adafruit_GFX.h>
//#include <MCUFRIEND_kbv.h>
#include <UTFTGLUE.h>//use GLUE class and constructor
#include "TouchScreen.h"
#include <stdint.h>
#include <SPI.h>
#include <EEPROM.h>
#include "Fonts/Chosence_Bold16pt7b.h";
#define MINPRESSURE 200
#define MAXPRESSURE 1000
//pin 20 SCL , 21 SDA датчик реального времени
#include <Wire.h>
#include "RTClib.h"
RTC_DS3231 rtc;
//датчик наружней температуры
#include <OneWire.h>
#define ONE_WIRE_BUS 22
OneWire oneWire(ONE_WIRE_BUS);
#include <DallasTemperature.h>
DallasTemperature sensors(&oneWire);
//датчик внутринней температуры и влаги
#include "DHT.h"
#define DHTPIN 26
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
///////////////////////////////////////////////////////////////////////////////////
//пины экрана и тача
///////////////////////////////////////////////////////////////////////////////////
UTFTGLUE myGLCD(0x1581,A2,A1,A3,A4,A0);
const int XP = 6, XM = A2, YP = A1, YM = 7;
const int TS_LEFT = 136, TS_RT = 907, TS_TOP = 139, TS_BOT = 942;
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
uint16_t ID;
int x, y;
char currentPage;
float h;
float t;
bool Dvoet = 0;
#define BLACK 0x0000
#define WHITE 0xFFFF
#define RED 0xF800
#define GREEN 0x07E0
//////////////////////////////////////////////////////////////////////////////
//все что касается OBD2
///////////////////////////////////////////////////////////////////////////////
#include <SoftwareSerial.h>
#define mySerial_gauge Serial2
#define TX_gauge 16
#define TX 13
SoftwareSerial mySerial (12, 13); //RХ,TХ
int length5 = 5;
int length6 = 6;
int length8 = 8;
int length7 = 7;
bool Init = 0;
bool InitGauge = 0;
bool dataMessageOK=0;
bool dataMessageEND = 0;
bool MessageParse = 0;
bool byte0 = 0;
bool byte1 = 0;
bool byte2 = 0;
int numberbyte = 0;
int PIDTime = 120; // задержка ожидания запроса следующего pid 2101, мс
int PresTime = 8000; // задержка между посылками запросов присутствия, мс
int waitbyte = 1; // задержка между отправкой байт в сообщении, мс
int waitbyte_gauge = 4;
int Datadelay = 50; // задержка между отрисовкой данных на LCD, мс
float L100M = 0; //расход на 100 км измеренный за поездку
float L100 = 0; //мгновенный расход литров на 100км
float LHor = 0; //мгновенный расход топлива литров в час
float L100SR = 0; //расход литров на 100км измеренный раз в интервал kmL
float L100SR_TFT = 0; // самый средний из расходов на 100км, он выводится на экран
int L100_Eeprom[11]= {10,10,10,10,10,10,10,10,10,10,10};
int FuelZamer[10]= {0}; // массив для измерения уровня (количества) топлива
int ZamerNumber = 0; // номер замера уровня (количества) топлива
int n_eeprom = 0; // текущий адрес ячейки еепром для записи расхода
int MAF = 0; //26,27 байты Sensor de flujo de aire en masa
float BoostPres = 0; //28,29 байты Presión de refuerzo
int RPM = 0; //32,33 байты Velocidad del motor
int EGRmg = 0; //34,35 байты Comando EGR (Comando de recirculación de gases de escape)
float BoostPresCom = 0; //38,39 байты Comando de presión de refuerzo
int Speed = 0; //44,45 байты Velocidad del vehículo
float DesaInjQua = 0; //50,51 байты Cantidad de inyección deseada
float InjQua = 0; //52,53 байты Cantidad de la inyección
float StaDaliv = 0; //54,55 байты Inicio de la entrega
int PumpRPM = 0; //56,57 байты Velocidad de la bomba
float EGRPul = 0; //62,63 байты Relación de impulsos EGR (recirculación de gases de escape
float SolenPul = 0; //64,65 байты Velocidad de solenoide de control de nivel de remolino Relación de impulsos
float SolenPre = 0; //70,71 байты Relación de impulsos Presión Electroválvula de presión
float DesInj = 0; //72,73 байты Inyección deseada Inicio
float ActInj = 0; //16,17 байты Inicio de la inyección real
int TempAir = 0; //74,75 байты Temperatura del aire de admisión
int Temp = 0; //14,15 байты Temperatura del refrigerante
int TempOil = 0; //18,19 байты Temperatura del aceite del motor
int TempFuel = 0; //58,59 байты Temperatura del combustible
//все что касается топлива
float Fuel = 0; //остаток топлива
float Fuel2 = 0; //остаток мгновенного топлива байт 16 , датчика в баке
int FuelIGN = 0; // количество топлвива в баке на момент включения зажигания
int Fuel_last = 0; // для формул
bool flagFuelIGN = 0; // флаг записан ли остаток топлива в момент вкл. зажигания
float FuelTrip = 0; // количество литров топлива, израсходованное за один цикл включения зажигания
//все что касается километража
float kmAge = 0; //пробег, полученный со щитка приборов
int kmAgeIGN = 0; //пробег который был в момент включения зажигания
int kmAge_last = 0; // для формул
bool flagkmAgeIGN = 0; //флаг записан ли пробег в момент вкл. зажигания
float kmTrip = 0; //пробег за один цикл включения зажигания
int kmL = 10; // интервал, через который будет происходить обновление среднего расхода на 100км
int km = 0; // переменная для расчетов
int kmeeprom = 10; // интервал, через который будет происходить подсчет среднеарифмитического расхода L100SR_TFT
int kmTFT = 0; // переменная для расчетов периодического подсчета среднеарифмитического расхода топлива L100SR_TFT
int kmREFUELING = 0; // пробег до заправки на остатке топлива
int colerror = 0; //количество ошибок в правом верхнем углу третьего экрана
//float Barom = 0; // барометр
byte MessageRx[110] = {0}; // массив байтов принимаемого сообщения
byte MessageRxGauge[60] = {0}; // массив байтов принимаемого сообщения от щитка приборов
byte messageInit[5] = {0x81, 0x11, 0xF1, 0x81, 0x04}; // запрос инициализации
byte messagePresent[5] = {0x81,0x11,0xF1,0x3E,0xC1}; // запрос присутствия
byte messagePids[6] = {0x82,0x11,0xF1,0x21,0x01,0xA6}; // запрос пид 2101
byte messageREAD[8] = {0x84,0x11,0xF1,0x18,0x00,0xFF,0x00,0x9D}; // запрос ошибок
byte messageERASE[7] = {0x83,0x11,0xF1,0x14,0xFF,0x00,0x98}; // стирание ошибок
unsigned long prevPID = 0;
unsigned long prevPIDgauge = 0;
unsigned long prevTemperature = 0;
unsigned long prevpres = 0;
unsigned long prevWatch = 0;
unsigned long prevDvoet = 0;
unsigned long prevData = 0;
unsigned long TimewaitPID, timerwaitPID = 0;
bool timerenabledPID = 0;
#define TIMEREXPIRED_PID (TimewaitPID - timerwaitPID)> 200 // здесь задержка на ожидание правильного ответа пидов, мс
unsigned long TimewaitInit, timerwaitInit = 0;
bool timerenabledInit = 0;
#define TIMEREXPIRED_Init (TimewaitInit - timerwaitInit)> 500 // здесь задержка на ожидание ответа об удачной инициализации, мс
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//SETUP
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup() {
uint16_t ID = myGLCD.readID();
if (ID == 0xD3D3) ID = 0x1581;
myGLCD.begin(ID);
myGLCD.InitLCD(3);
Serial.begin(115200);
mySerial.begin(10400);
Wire.begin();
rtc.begin();
dht.begin();
sensors.begin();
myGLCD.clrScr();
myGLCD.setTextSize(2);
//myGLCD.setFont(&Chosence_Bold16pt7b);
//загрузка стартовой страницы
currentPage = '0';
drawHomeScreen();
//подсчет среднеарифметического усредненного расхода
for (int i = 0; i < 11; i++) L100_Eeprom [i]= EEPROM.read(i);
for (int i = 0; i < 11; i++) L100SR_TFT = L100SR_TFT + L100_Eeprom [i];
L100SR_TFT = (float)L100SR_TFT/110.0;
if (L100SR_TFT<0) L100SR_TFT = 0;
if (L100SR_TFT>99) L100SR_TFT = 99;
// строка ниже используется для настройки даты и времени часов
// раскоментировать, выставить времая и дату, залить в ардуино. в скетче закоментировать
// обратно и залить еще раз, иначе каждый раз будет по новой выствлятся это же время и дата
// (год, месяц, день, часы, минуты, секунды)
//rtc.adjust(DateTime(2017, 7, 21, 13, 57, 0));
Temperature ();
pinMode(TX, OUTPUT);
pinMode(TX_gauge, OUTPUT);
fastinit();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//SETUP FIN
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//LOOP
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void loop() {
TimewaitPID = millis ();
TimewaitInit = millis ();
if (!Init) { if (!timerenabledInit){ timerwaitInit=TimewaitInit; timerenabledInit=1; initialization(); }
else if (TIMEREXPIRED_Init) timerenabledInit=0;}
else { if (currentPage != '3'){ // если открыта страница 0,1 или 2 шлем запрос пид2101, если страница 3 - шлем запрос присутствия
if (millis() - prevPID > PIDTime) { PIDs(); prevPID = millis(); }}
else if (millis() - prevpres > PresTime) {present(); prevpres = millis();}}
if (!InitGauge) {Serial.println ("Otpravil zapros adress Gauge");
digitalWrite (TX_gauge, HIGH); delay (500);
digitalWrite (TX_gauge, LOW); delay (20);
digitalWrite (TX_gauge, HIGH ); delay (15);
digitalWrite (TX_gauge, LOW); delay (5);
digitalWrite (TX_gauge, HIGH); delay (5);
mySerial_gauge.begin(9600);}
receive ();
if (millis() - prevWatch > 3000) { Watch (); prevWatch = millis(); Trip ();}
if (millis() - prevTemperature > 60000) { Temperature (); prevTemperature = millis();}
if (millis() - prevDvoet > 500) { if (!Dvoet) {myGLCD.print(":", 285, 10);} else {myGLCD.print(" ", 285, 10);} prevDvoet = millis(); Dvoet=!Dvoet;}
Menu();
LCDDataPrint();}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
//BOID TRIP//////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
void Trip () {
if (flagkmAgeIGN){
FuelTrip = FuelIGN - Fuel;
if (kmAge>kmAgeIGN) kmTrip = kmAge - kmAgeIGN;
if (kmAge<kmAgeIGN) kmTrip = 2000 - (kmAgeIGN - kmAge); // 2000 это через сколько км у тебя суточный пробег сбрасывается на ноль, поменяй если другое число
if (kmAge==kmAgeIGN) kmTrip = 0;
//подсчет расхода на 100км за поездку
L100M = ((float)FuelTrip*100.00)/(float)kmTrip;
if (L100M<0) L100M = 0;
if (L100M>99) L100M = 99;
// ниже цикл считает среднеарифметический расход из еепром раз в пробег, указанный в переменной kmeeprom
if (kmTrip-kmTFT>kmeeprom) {kmTFT = kmTrip;
// тут считаем среднеарифметический усредненного расход из ячеек еепром
for (int i = 0; i < 11; i++) L100_Eeprom [i]= EEPROM.read(i);
for (int i = 0; i < 11; i++) L100SR_TFT = L100SR_TFT + L100_Eeprom [i];
L100SR_TFT = (float)L100SR_TFT/110.00;
if (L100SR_TFT<0) L100SR_TFT = 0;
if (L100SR_TFT>99) L100SR_TFT = 99;}
// ниже цикл считает расход топлива за пробег, указанный в переменной kmL, здесь же запись в ячейки еепром
if (kmTrip-km>kmL) {km=kmTrip;
L100SR = ((float)(Fuel_last-Fuel)*100.00)/(float)kmL; // расход/100км - обновляется раз в 10км, меняется км в int kmL = 10;
Fuel_last = Fuel; // сохранение параметров с последнего измерениея
if (L100SR<0) L100SR = 0;
if (L100SR>99) L100SR = 99;
//расчет остатка километров в баке
if (L100SR>0) kmREFUELING=((float)Fuel*100.0)/(float)L100SR; //если средний расход больше нуля, то расчитывать км в баке из него
else kmREFUELING=((float)Fuel*100.00)/(float)L100SR_TFT; //если ноль или ментше то расчитывать км в баке с устредненного расхода
// тут записываем L100SR последовательно в одну из 11 ячеек еепром
//EEPROM.write (12,n_eeprom); // ЗДЕСЬ ВНИМАТЕЛЬНО. ЗАГРУЗИТЬ ПРОШИВКУ С ЭТОЙ СТРОКОЙ ОДИН РАЗ, ПОТОМ ЗАКОМЕНТИРОВАТЬ И ЕЩЁ РАЗ ЗАГРУЗИТЬ
n_eeprom = EEPROM.read (12); // в ячейке 12 хранится № текущей ячейки для записи расхода, чтобы где остановился при выкл питания, от туда и продолжил
EEPROM.write(n_eeprom, L100SR*10);
n_eeprom++; if (n_eeprom>10) n_eeprom=0;
EEPROM.write (12,n_eeprom); }}}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
//BOID LCDDATAPRINT. прописываем данные и их расположение и цвет/////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
void LCDDataPrint(){
unsigned long curData = millis();
if (millis() - prevData > Datadelay){
myGLCD.setTextColor(WHITE, BLACK); //цвет текста
myGLCD.printNumI(Speed, 365, 10, 3);
//----------------------------------------------------------
//страниц HOME
//----------------------------------------------------------
if (currentPage == '0') {
myGLCD.printNumF(LHor, 1, 90, 50, '.',4);
myGLCD.printNumF(L100, 1, 240, 50,'.',4 );
myGLCD.printNumF(L100M, 1, 90, 85,'.',4 );
myGLCD.printNumF(L100SR_TFT, 1, 240, 85,'.',4 );
myGLCD.printNumI(kmREFUELING, 80, 120,5 );
//if (Fuel<53)
myGLCD.printNumF(Fuel, 1, 240, 120,'.',4);
//else myGLCD.print("MAX", 240, 120);
myGLCD.printNumF(kmTrip, 1, 90, 155,'.',4);
myGLCD.printNumF(FuelTrip, 1, 240, 155,'.',4);
myGLCD.printNumI(PumpRPM, 230, 190,4);
myGLCD.printNumI(RPM, 230, 225,4);
myGLCD.printNumF(Fuel2, 1, 15, 225,'.',4);
myGLCD.printNumI(Temp, 415, 50, 3);
myGLCD.printNumI(TempOil, 415, 85, 3);
myGLCD.printNumI(TempFuel, 415, 120,3);
myGLCD.printNumI(sensors.getTempCByIndex(0), 415, 155 , 3);
myGLCD.printNumI(t, 415, 190, 3);
myGLCD.printNumI(TempAir, 415, 225, 3); }
//----------------------------------------------------------
//страниц INF1
//----------------------------------------------------------
if (currentPage == '1') {
myGLCD.printNumF(StaDaliv,1, 360, 50,'.', 3);
myGLCD.printNumF(DesInj,1, 360, 85, '.', 4);
myGLCD.printNumF(ActInj,1, 360, 120,'.', 4);
myGLCD.printNumF(DesaInjQua,1, 360, 155,'.', 4);
myGLCD.printNumF(InjQua,1, 360, 190,'.', 4);
myGLCD.printNumI(MAF, 160, 225, 4);
myGLCD.printNumF(h, 1, 400, 225); }
//----------------------------------------------------------
//страниц INF2
//----------------------------------------------------------
if (currentPage == '2') {
myGLCD.printNumF(BoostPres,1, 385, 50,'.', 3);
myGLCD.printNumF(BoostPresCom,1, 385, 85,'.', 3);
myGLCD.printNumI(EGRmg, 375, 120, 4);
myGLCD.printNumF(EGRPul,1, 375, 155,'.', 4);
myGLCD.printNumF(SolenPul, 1, 375, 190,'.', 4);
myGLCD.printNumF(SolenPre, 0, 375, 225,'.', 4); }
prevData = millis(); }}
///////////////////////////////////////////////////////////////////////////
//BOID PIDs//отправка запроса пид 2101/////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
void PIDs() {
Serial.println ("Otpravil zapros 21 01");
for (int i = 0; i < length6; i++) {
mySerial.write(messagePids[i]);
delay (waitbyte); }}
///////////////////////////////////////////////////////////////////////////
//BOID PIDsGAUGR//отправка запроса на панель приборов//////////////////////
///////////////////////////////////////////////////////////////////////////
void PIDsGauge() {
Serial.println (" Otpravil zapros 02 11 na panel");
mySerial_gauge.write (0x02); delay (1);
mySerial_gauge.write (0x11); delay (1);
mySerial_gauge.write(byte(0)); delay (1);
mySerial_gauge.write (0x13); }
///////////////////////////////////////////////////////////////////////////
//BOID PIDsGAUGR//отправка запроса присутствия/////////////////////////////
///////////////////////////////////////////////////////////////////////////
void present() {
Serial.println ("Otpravil zapros Present");
for (int i = 0; i < length5; i++) {
mySerial.write(messagePresent[i]);
delay (waitbyte); }}
/////////////////////////////////////////////////////////////////////////////////////////////
//получение данных от ЭБУ, разборка входящих сообщений
/////////////////////////////////////////////////////////////////////////////////////////////
void receive () {
///////////////////////////////////////////////////////////////////////
////////////////// работа с К-Line софт сериал 16-17 (12 контакт ОБД)
///////////////////////////////////////////////////////////////////////
while(!InitGauge){
if (mySerial_gauge.available()) {
byte inByte = mySerial_gauge.read();
Serial.print(" ");
Serial.print(inByte,HEX);
if (inByte==0x80) {mySerial_gauge.write (0x7F); delay (1);}
if (inByte==0xF0) {
mySerial_gauge.write (0x02); delay (1);
mySerial_gauge.write (0x11); delay (1);
mySerial_gauge.write (0x00); delay (1);
mySerial_gauge.write (0x13); delay (1); InitGauge=1; }}}
MessageParse = 0;
while (InitGauge && !MessageParse) {
if (!dataMessageOK) {
if (mySerial_gauge.read() == 0x23) {byte0=1; delay (waitbyte_gauge); }
if (mySerial_gauge.read() == 0xA1 && byte0) {byte1=1; delay (waitbyte_gauge);}
else byte0=0;
if (mySerial_gauge.read() == 0x04 && byte0 && byte1) {byte2=1; delay (waitbyte_gauge);}
else {byte0=0; byte1=0;}
if (byte0 && byte1 && byte2) {dataMessageOK = 1; byte0=0; byte1=0; byte2=0;}
numberbyte=0;}
else { if (mySerial_gauge.available()>0) { MessageRxGauge[numberbyte] = mySerial_gauge.read(); numberbyte++; delayMicroseconds (250);}
if (numberbyte==34) {dataMessageEND = 1; dataMessageOK = 0; }}
if (dataMessageEND) {
int crc = ( ( unsigned int )MessageRxGauge[32] << 8 ) | MessageRxGauge[33]; // парсинг контрольной суммы из 2 последних байт
int CRC =200;
for (int i = 0; i < 32; i++) CRC = CRC + MessageRxGauge[i]; // подсчет контрольной суммы байт от 0 до 31
Serial.print (" ReceiveGauge: ");
for (int i = 0; i < 34; i++) {
Serial.print(MessageRxGauge[i],HEX); Serial.print (" ");}
//при получении сообщения БЕЗ ошибок с данными от панели приборов, запишем в переменные остаток топлива и пробег
if (CRC==crc) {Serial.println (" OK!!!");
Fuel2 = MessageRxGauge[16]/2.0;
if (!flagFuelIGN) { Fuel = MessageRxGauge[16]/2.00; kmREFUELING=((float)Fuel*100.00)/(float)L100SR_TFT;} //стартовая запись литров в баке для подсчета затраченных литро
else Fuel = MessageRxGauge[17]/2.0; //для устреднения болтания в баке закоментировать эту строку, а раскоментировать ниже
//для усреднения болтания топлива в баке, раскоментировать, высчитывает среднее
/*else { FuelZamer[ZamerNumber] = MessageRxGauge[17]/2.00;
if (ZamerNumber==9) {
Fuel = 0 ;
for (int i = 0; i < 10; i++) Fuel = Fuel + FuelZamer[i];
Fuel = (float)Fuel/10.0;}
ZamerNumber++; if (ZamerNumber>9) ZamerNumber = 0;}
*/
kmAge = (MessageRxGauge[23]+(MessageRxGauge[24]*256))/10.0; //суточный пробег с панели приборов
//бак у меня на 59 литров, а датчик показывает максимально 53 литра. для этого эта формула
//если у вас тоже датчик имеет лимит то подправте 53 на свой лимит.
//если ваш датчик показывает одинаково с полным баком то закоментировать три нижние строки.
if (Fuel<53){
if (!flagkmAgeIGN) { kmAgeIGN = kmAge; flagkmAgeIGN =1;}
if (!flagFuelIGN) { FuelIGN = Fuel; Fuel_last = Fuel; flagFuelIGN = 1; }}}
else Serial.println (" ERROR!!!");
dataMessageEND = 0; MessageParse = 1; //mySerial_gauge.flush();
for (int i = 0; i < 34; i++) MessageRxGauge[i]=0; }} // очистка байтов массива
////////////////////////////////////////////////////////////////////
////////////////// работа с К-Line софт сериал 12-13 (7 контакт ОБД)
////////////////////////////////////////////////////////////////////
if (mySerial.available()) {
delay(195);
int k=0;
byte inbyte=0;
while( mySerial.available() && k < 110) {
inbyte = mySerial.read();
MessageRx[k] = inbyte;
k++; }
Serial.print ("Receive: ");
for (int i = 0; i < k; i++) {
Serial.print(MessageRx[i],HEX); Serial.print (" ");}
Serial.println ("");
if (MessageRx[2]==0x83 && MessageRx[3]==0xF1 && MessageRx[4]==0x11 && MessageRx[5]==0xC1 && MessageRx[6]==0x6B && MessageRx[7]==0x8F && MessageRx[8]==0x40) {Init=1;
timerenabledInit=0;
Serial.println (" Initialization OK!!!!: "); }
if (currentPage == '3'){
///////////////////////////////////////////////////////////////////////////////////////////////////
//Чтение и стирание ошибок
///////////////////////////////////////////////////////////////////////////////////////////////////
//при получении этого сообщения выдавать на третий экран "NO ERROR"
if (MessageRx[4]==0x82 && MessageRx[5]==0xF1 && MessageRx[6]==0x11 && MessageRx[7]==0x58 && MessageRx[8]==0x00 && MessageRx[9]==0xDC){
myGLCD.clrScr();
drawscreen_three();
myGLCD.print("NO DTC", 200, 145);
Serial.println (" NO DTC "); }
//при получении этого сообщения выдавать на третий экран "DTC BORRADO"
if (MessageRx[3]==0x83 && MessageRx[4]==0xF1 && MessageRx[5]==0x11 && MessageRx[6]==0x54 && MessageRx[7]==0xFF && MessageRx[8]==0x00 && MessageRx[9]==0xD8){
myGLCD.clrScr();
drawscreen_three();
myGLCD.print("DTC BORRADO", 175, 145);
Serial.println (" DTC BORRADO "); }
// при получении сообщения о наличии ошибок DTC разберем сообщение выведем на экран ошибки
if (MessageRx[5]==0xF1 && MessageRx[6]==0x11 && MessageRx[7]==0x58 && MessageRx[8]>0){
Serial.println ("DTC is found!");
myGLCD.clrScr();
drawscreen_three();
for (int i=0; i<MessageRx[8]; i++ ) {
int y = i*35;
bool nolA=0; bool nolB =0;
if (!bitRead(MessageRx[11+(i*3)],6) && bitRead(MessageRx[11+(i*3)],7)){ myGLCD.setTextColor(GREEN, BLACK);
myGLCD.print(" -Passive-", 300, (75+y));} // если DTC пасивныый делаем цвет зеленый
if (bitRead(MessageRx[11+(i*3)],7) && bitRead(MessageRx[11+(i*3)],6)) {myGLCD.setTextColor(RED, BLACK);
myGLCD.print(" -Active-", 300, (75+y));} // если DTC активный, делаем цвет красный
myGLCD.print("ERROR ", 50, (75+y));
myGLCD.printNumI((i+1), 150, (75+y));
if (!bitRead(MessageRx[9+(i*3)],6) && !bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": P", 170, (75+y));
if (bitRead(MessageRx[9+(i*3)],6) && !bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": C", 170, (75+y));
if (!bitRead(MessageRx[9+(i*3)],6) && bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": B", 170, (75+y));
if (bitRead(MessageRx[9+(i*3)],6) && bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": U", 170, (75+y));
if (MessageRx[9+(i*3)]==0x00) {myGLCD.print("00", 230, (75+y)); nolA = 1;}
if (MessageRx[9+(i*3)]<=0x0F&&MessageRx[9+(i*3)]!=0) {myGLCD.print("0", 230, (75+y)); nolA = 1;}
if (nolA)myGLCD.print(String (MessageRx[9+(i*3)],HEX), 246, (75+y));
else myGLCD.print(String (MessageRx[9+(i*3)],HEX), 230, (75+y));
if (MessageRx[10+(i*3)]==0x00) {myGLCD.print("00", 262, (75+y)); nolB = 1;}
if (MessageRx[10+(i*3)]<=0x0F&&MessageRx[10+(i*3)]!=0) {myGLCD.print("0", 262, (75+y)); nolB = 1;}
if (nolB)myGLCD.print(String (MessageRx[10+(i*3)]),HEX, 278, (75+y));
else myGLCD.print(String (MessageRx[10+(i*3)],HEX), 262, (75+y));}}}
///////////////////////////////////////////////////////////////////////////////////////////////////////////
//прописываем формулы к данным ///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////
else if (MessageRx[3]==0x80 && MessageRx[4]==0xF1 && MessageRx[5]==0x11 && MessageRx[6]==0x4C && MessageRx[7]==0x61 && MessageRx[8]==0x01) {
//Barom = MessageRx[39];
L100 = (float)LHor*100.0/(float)Speed;
LHor = (float)RPM* (float)InjQua*2.00/1000.0*60.00/1000.0/0.85;
MAF = ((MessageRx[29]*256)+MessageRx[30])/10;
BoostPres = ((MessageRx[31]*256)+MessageRx[32])/1000.0;
RPM = (MessageRx[35]*256)+MessageRx[36];
EGRmg = ((MessageRx[37]*256)+MessageRx[38])/10.0;
BoostPresCom = ((MessageRx[41]*256)+MessageRx[42])/1000.0;
Speed = ((MessageRx[47]*256)+MessageRx[48])/100;
DesaInjQua = ((MessageRx[53]*256)+MessageRx[54])/100.0;
InjQua = ((MessageRx[55]*256)+MessageRx[56])/100.0;
StaDaliv = ((MessageRx[57]*256)+MessageRx[58])/100.0;
PumpRPM = (MessageRx[59]*256)+MessageRx[60];
EGRPul = ((MessageRx[65]*256)+MessageRx[66])/100.0;
SolenPul = ((MessageRx[67]*256)+MessageRx[68])/100.0;
SolenPre = ((MessageRx[73]*256)+MessageRx[74])/100.0;
DesInj = ((MessageRx[75]*3)+(MessageRx[76])/100.0)+0.3;
ActInj = ((MessageRx[19]*3)+(MessageRx[20])/100.0)+0.3;
//TempAir = ((MessageRx[77]*26)-278)+MessageRx[78]/10.0;
//Temp = ((MessageRx[17]*26)-278)+MessageRx[18]/10.0;
//TempOil = ((MessageRx[21]*26)-278)+MessageRx[22]/10.0;
//TempFuel = ((MessageRx[61]*26)-278)+MessageRx[62]/10.0;
//ниже идут расчетные формулы более точные чем те что закоментированы выше
int A = 0;
if (MessageRx[77]<=0x0A) A = 277;
if (MessageRx[77]==0x0B || MessageRx[77]==0x0C) A = 278;
if (MessageRx[77]>=0x0D) A = 279;
double B = MessageRx[78]/10.0;
double cel , drob ;
drob = modf(B, &cel);
if (drob>0.6) cel++;
TempAir = ((MessageRx[77]*26)-A)+cel;
if (MessageRx[17]<=0x0A) A = 277;
if (MessageRx[17]==0x0B || MessageRx[77]==0x0C) A = 278;
if (MessageRx[17]>=0x0D) A = 279;
B = MessageRx[18]/10.0;
drob = modf(B, &cel);
if (drob>0.6) cel++;
Temp = ((MessageRx[17]*26)-A)+cel;
if (MessageRx[21]<=0x0A) A = 277;
if (MessageRx[21]==0x0B || MessageRx[77]==0x0C) A = 278;
if (MessageRx[21]>=0x0D) A = 279;
B = MessageRx[22]/10.0;
drob = modf(B, &cel);
if (drob>0.6) cel++;
TempOil = ((MessageRx[21]*26)-A)+cel;
if (MessageRx[61]<=0x0A) A = 277;
if (MessageRx[61]==0x0B || MessageRx[77]==0x0C) A = 278;
if (MessageRx[61]>=0x0D) A = 279;
B = MessageRx[62]/10.0;
drob = modf(B, &cel);
if (drob>0.6) cel++;
TempFuel = ((MessageRx[61]*26)-A)+cel;
timerenabledPID=0; }
for (int i = 0; i < 110; i++) MessageRx[i]=0; }} // очистка байтов массива
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//отправка запроса на диагностическое соединение
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void initialization() {
Serial.println ("Otpravil zapros Init");
for (int i = 0; i < length5; i++) {
mySerial.write(messageInit[i]);
delay (5); }
delay (55); }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//стартовая инициализация 7 пина ОБД
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void fastinit() {
digitalWrite (TX, HIGH); // makes K-line high 3
delay(360); // wait for K-line to be clear 3
digitalWrite (TX, LOW); // makes K-line low 3
delay(25);
digitalWrite (TX, HIGH); // makes K-line high 3
delay(25); //last delay before first message
mySerial.begin(10400); } // baud rate of the OBD
///////////////////////////////////////////////////////////////////////////////////////////////////////
//запрос чтения и стирания ошибок
///////////////////////////////////////////////////////////////////////////////////////////////////////
void Read() {
Serial.println ("Zapros error; ");
for (int i = 0; i < length8; i++) {
mySerial.write(messageREAD[i]);
delay (waitbyte); }}
void Erase() {
Serial.println ("Zapros erase; ");
for (int i = 0; i < length7; i++) {
mySerial.write(messageERASE[i]);
delay (waitbyte); }}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//прорисовка тач кнопок
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Menu () {
if (currentPage == '0') {
TouchHOME();
TouchINF1();
TouchINF2();
TouchCHECK(); }
if (currentPage == '1') {
TouchHOME();
TouchINF2();
TouchCHECK(); }
if (currentPage == '2') {
TouchHOME();
TouchINF1();
TouchCHECK(); }
if (currentPage == '3') {
TouchHOME();
TouchREAD();
TouchERASE(); }}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//прописывает заголовки и кнопки на страницах
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void drawHomeScreen() {
line() ;
Watch ();
myGLCD.setTextColor(RED, BLACK); // цвет линии и текста красный
myGLCD.drawLine(295,35,295,248); // линия вертикальная
myGLCD.drawLine(145,35,145,178); // линия вертикальная
myGLCD.drawLine(80,178,80,247); // линия вертикальная
myGLCD.print("L/Hor", 10, 50);
myGLCD.print("100/Ac", 148, 50);
myGLCD.print("100/V", 10, 85);
myGLCD.print("100/M", 148, 85);
myGLCD.print("De/Km", 10, 120);
myGLCD.print("De/Li", 148, 120);
myGLCD.print("Vi/Km", 10, 155);
myGLCD.print("Vi/Li", 148, 155);
myGLCD.print("BOMBA RPM", 82, 190);
myGLCD.print("MOTOR RPM", 82, 225);
myGLCD.print("D/L/A", 10, 190);
myGLCD.print("MOTOR C", 300, 50);
myGLCD.print("OIL C", 300, 85);
myGLCD.print("FUEL C", 300, 120);
myGLCD.print("DENTR C", 300, 155);
myGLCD.print("FUERA C", 300, 190);
myGLCD.print("INTAIR C", 300, 225);
myGLCD.drawRoundRect (15, 255, 145, 310);
myGLCD.print("INF 1", 55, 280);
myGLCD.drawRoundRect (175, 255, 305, 310);
myGLCD.print("INF 2", 215, 280);
myGLCD.drawRoundRect (335, 255, 465, 310);
myGLCD.print("CHECK", 365, 280);
myGLCD.drawRoundRect (1, 1, 77, 37);
myGLCD.print("HOME", 20, 10);
myGLCD.print("Km/h", 410, 10);
}
//-------------------------------------------------
void drawscreen_one() {
line() ;
Watch ();
myGLCD.setTextColor(RED, BLACK); // цвет линии и текста красный
myGLCD.print("Start of Delivery *CA:", 10, 50);
myGLCD.print("Desir inject Start *CA:", 10, 85);
myGLCD.print("Actua Inject Start *CA:", 10, 120);
myGLCD.print("Desir Inject Quan mg/s:", 10, 155);
myGLCD.print("Actu Inject Quant mg/s:", 10, 190);
myGLCD.print("MAF mg/s:", 10, 225);
myGLCD.print("Humedad %:", 255, 225);
myGLCD.drawRoundRect (175, 255, 305, 310);
myGLCD.print("INF 2", 215, 280);
myGLCD.drawRoundRect (335, 255, 465, 310);
myGLCD.print("CHECK", 365, 280);
myGLCD.drawRoundRect (1, 1, 77, 37);
myGLCD.print("HOME", 10, 10);
myGLCD.print("Km/h", 410, 10);
}
//-------------------------------------------------
void drawscreen_two() {
line() ;
Watch ();
myGLCD.setTextColor(RED, BLACK); // цвет линии и текста красный
myGLCD.print("Boost Press Bar:", 10, 50);
myGLCD.print("Boost Press Com Bar:", 10, 85);
myGLCD.print("EGR command mg/s:", 10, 120);
myGLCD.print("EGR Pulse Ratio %:", 10, 155);
myGLCD.print("Solenoide Pulse %:", 10, 190);
myGLCD.print("Solenoide Boost %:", 10, 225);
myGLCD.drawRoundRect (15, 255, 145, 310);
myGLCD.print("INF 1", 55, 280);
myGLCD.drawRoundRect (335, 255, 465, 310);
myGLCD.print("CHECK", 365, 280);
myGLCD.drawRoundRect (1, 1, 77, 37);
myGLCD.print("HOME", 20, 10);
myGLCD.print("Km/h", 410, 10);
}
//----------------------------------------------------------------------------
void drawscreen_three() {
Watch ();
myGLCD.setTextColor(RED, BLACK); // цвет линии красный
myGLCD.drawLine(1,35,479,35); // линия горизонтальная
myGLCD.drawLine(1,248,479,248); // линия горизонтальная
myGLCD.drawRoundRect (15, 255, 145, 310);
myGLCD.print("ERASE", 55, 280);
myGLCD.drawRoundRect (335, 255, 465, 310);
myGLCD.print("READ", 365, 280);
myGLCD.drawRoundRect (1, 1, 77, 37);
myGLCD.print("HOME", 20, 10);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//кнопки тач . координаты и переходы
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void TouchHOME(){
TSPoint p = ts.getPoint();
pinMode(XM, OUTPUT);
pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
{if (p.x > 140 && p.x < 320 && p.y > 140 && p.y < 260 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
{ myGLCD.drawRoundRect (1, 1, 77, 37);
currentPage = '0';
myGLCD.clrScr();
drawHomeScreen();
x = 0;
y = 0;
p.z = 0;}}}
void TouchINF1(){
TSPoint p = ts.getPoint();
pinMode(XM, OUTPUT);
pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
{
if (p.x > 150 && p.x < 450 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
{ myGLCD.drawRoundRect (15, 255, 145, 310);
currentPage = '1';
myGLCD.clrScr();
drawscreen_one();
x = 0;
y = 0;
p.z = 0;}}}
void TouchINF2(){
TSPoint p = ts.getPoint();
pinMode(XM, OUTPUT);
pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
{
if (p.x > 450 && p.x < 680 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
{ myGLCD.drawRoundRect (175, 255, 305, 310);
currentPage = '2';
myGLCD.clrScr();
drawscreen_two();
x = 0;
y = 0;
p.z = 0;}}}
void TouchCHECK(){
TSPoint p = ts.getPoint();
pinMode(XM, OUTPUT);
pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
{
if (p.x > 690 && p.x < 950 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
{ myGLCD.drawRoundRect (335, 255, 465, 310);
currentPage = '3';
myGLCD.clrScr();
drawscreen_three();
x = 0;
y = 0;
p.z = 0;}}}
void TouchREAD(){
TSPoint p = ts.getPoint();
pinMode(XM, OUTPUT);
pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
{
if (p.x > 690 && p.x < 950 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
{ myGLCD.drawRoundRect (335, 255, 465, 310);
Read();
x = 0;
y = 0;
p.z = 0;}}}
void TouchERASE(){
TSPoint p = ts.getPoint();
pinMode(XM, OUTPUT);
pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
{
if (p.x > 150 && p.x < 450 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
{ myGLCD.drawRoundRect (15, 255, 145, 310);
Erase();
x = 0;
y = 0;
p.z = 0;}}}
////////////////////////////////////////////////////////////////////////////////////////
//прорисовка линий
///////////////////////////////////////////////////////////////////////////////////////
void line() {
myGLCD.setColor(255, 0, 0); // цвет линии красный
myGLCD.drawLine(1,35,479,35); // линия горизонтальная
myGLCD.drawLine(1,73,479,73); // линия горизонтальная
myGLCD.drawLine(1,108,479,108); // линия горизонтальная
myGLCD.drawLine(1,143,479,143); // линия горизонтальная
myGLCD.drawLine(1,178,479,178); // линия горизонтальная
myGLCD.drawLine(1,212,479,212); // линия горизонтальная
myGLCD.drawLine(1,248,479,248); }// линия горизонтальная
/////////////////////////////////////////////////////////////////////////////////////////////
//верхняя часть экрана часы и дата отображается на всех экранах
/////////////////////////////////////////////////////////////////////////////////////////////
void Watch (){
DateTime now = rtc.now();
int m = now.minute();
int hour = now.hour();
int mon = now.month();
int date = now.day();
myGLCD.setTextColor(WHITE, BLACK); //белый цвет цифры
if (date<10) {
myGLCD.print("0", 85, 10);
myGLCD.printNumI(now.day(), 100, 10); }
else if (date >=10) {
myGLCD.printNumI(now.day(), 85, 10); }
myGLCD.print("/", 115, 10);
if ( mon<10) {
myGLCD.print("0", 130, 10);
myGLCD.printNumI(now.month(), 145, 10);}
else if (mon >=10) {
myGLCD.printNumI(now.month(), 130, 10);}
myGLCD.print("/", 160, 7);
myGLCD.printNumI(now.year(), 175, 10);
if (hour<10) {
myGLCD.print("0",255, 7);
myGLCD.printNumI(now.hour(), 270, 10); }
else if(hour>=10){
myGLCD.printNumI(now.hour(), 255, 10); }
if (m<10) {
myGLCD.print("0",300, 10);
myGLCD.printNumI(now.minute(), 315, 10); }
else if (m>=10){
myGLCD.printNumI(now.minute(), 300, 10); }
}
void Temperature (){
h = dht.readHumidity();
t = dht.readTemperature();
sensors.requestTemperatures();
}
Сколько памяти свободно остаётся во флеше без красивого шрифта ? Можно свой шрифт организовать по типу обычного (по крайней мере для тех символов, которыми отображаются динамические данные)!
Сколько памяти свободно остаётся во флеше без красивого шрифта ? Можно свой шрифт организовать по типу обычного (по крайней мере для тех символов, которыми отображаются динамические данные)!
привет мужики, что-то после отпуска сюда не заглядывал. Как, удалось тогда победить моргание на пропорциональных шрифтах, или забили и "пошли другим путем" ?
Командир, завтра скажу сколько памяти. Я уже думал ковырять стандартный шрифт, сделать его хотя-бы вытянутой а не квадратным
B707. Победить то победили, но вот то что он сильно тормозит все, может у меня экран слабый.
B707. Победить то победили, но вот то что он сильно тормозит все, может у меня экран слабый.
"экран слабый" быть не может. Если тормозит, то причины м.б. только две - либо код не оптимальный, либо проц слабый (то есть вместо ардуины надо брать СТМ, к примеру)
Хз. На прошлом экране все было гуд. Сменил экран и пошли тормоза. Так что ардуина не при чем.
прошлый экран был такого же размера разве?
Для обновления картинки 240Х320 нужно примерно в 10 раз больше времени, чем, например, 128х64. И никакой "слабый экран" тут не при чем - это просто ардуина слабая для этого экрана, вот и все.
Поставил стандартный шрифт и все пошло. Думаю стандартный ковырять так как размер 2 маловат а 3 за большой и квадратные они, мне бы вытянутые, уродливый но мать его за лапу, какой есть. Именно при добавлении стороннего шрифта начининаются тормоза.
Был такой же размер
Я вышел на отличный результат со стандартным шрифтом. И мой старый и твой новый работают быстро. В старом только косяк в четырёх данных. В твоём новом хаус в расчётах. Но оба работают очень быстро со стандартным. Плевать уже на красоту.
viki13viki Привет. Мне кажется или ты решил отказаться от проверки выводимых данных на изменения (ака last...)? Или вы скрещиваете не с крайним скетчем !!! Я бы еще даже не сами значения сравнивал, а данные из буфера, что бы не производить вычисления, если данные для конкретного параметра не изменились (особенно если в вычислении есть деление/умножение).
На следующей недели продолжу. Я сейчас использую старый скетчь на стандартном шрифты без Last. Но и последний со стандартным шрифтом с Last летает, но хаус в расчётах, и проблема в выводимых данных. При переходе на страницы прорисовывается только часть данных, renew тыкал везде, как в верху так и в низу на каждой страницы так и для всех страниц один renew внизу. Проверю 1229 о котором выше говорил Макс, тока на стандартном шрифты. Но уже в понедельник
Отчет по 1929 . Вроде все данные показываетю. Косяки: 1. TempAir показывает 36 ( через 5 мин после второй прошивки показал 44 градуса, что уже не коректно, должно быть где-то 14-16 примерно(но это нужно проверять когда подключится наружняя температура) тогда скажу точно, я их сравниваю. 2. при переходах на страницы не всегда прорисовывает часы.(но это пока не важно) добавил в низу в Watch это reNew = 1;, не помогло. Остальное нужно на ходу проверять. Работет мгновенно, прорисовка мгновенно.
вот скетч чтобы далеко не бегать
//------------все для связи по K-line (тут настраиваем UARTы к-лайников, адреса блоков, скорость инита и отладку)
#include <SoftwareSerial.h>
#define TX_PCM 13
SoftwareSerial K_LINE_PCM (12, TX_PCM); //RХ,TХ //UART на котором висит K_line к PCM
#define K_LINE_GAUGE Serial2 //UART на котором висит K_line к приборке
#define TX_gauge 16 //TX UARTa на котором висит K_line к приборке
#define PCM_address 0x11 // адрес PCM
#define DIAG_address 0xF1 // адрес диагностики
const byte BAUD=200; // init baudrate - скорость инита при подключении к приборке
const byte addressGUAGE = 0xB8;// init GAUGE address - адрес щитка приборов при ините (установке связи)
//#define debugPCM // раскоментировать эту строку для отладки в Serial порту обмена с PCM
#define debugGAUGE // раскоментировать эту строку для отладки в Serial порту обмена co щитком приборов
uint32_t curmillis = 0; // снимок текущего времени
//------------------------------------------переменные для организации протокола связи с PCM
uint32_t prevRequest = 0; // таймер периодических запосов на PCM
uint16_t RequestPeriod = 3500; // периодичность запросов на PCM
uint32_t prevRESETheader=0; // таймер сброса сообщения, если данные оборвались посередине сообщения
bool RESETheader_timer; // таймер сброса сообщения, если данные оборвались посередине сообщения
uint32_t prev_NOanswer=0; // таймер контроля неответов от ЭБУ после подачи запросов
bool NOanswer_timer = 0; // таймер контроля неответов от ЭБУ после подачи запросов
byte noanswers = 0; // количество подряд неответов от ЭБУ
uint32_t timerdelay = 0; // таймер ожидания байт (для успевания появления данных в буфере UART)
bool Delay = 0; // таймер ожидания байт (для успевания появления данных в буфере UART)
byte waitbyte_RX = 1; // задержка, мс для успевания появления данных в буфере RX
// (подрегулировать в зависимости от уровня жизнидеятельности на Марсе)
#define TIMER_DELAY Delay = 0; timerdelay = curmillis // включение этого таймера
byte delaybyte_TX = 1; // задержка между отправкой байт в запросах, мс
byte header = 0; // состояние заголовка
byte message_size = 0; // размер тела сообщения
byte j = 3; // инкремент
byte n = 3; // количество старт байт
const byte bufsize = 150; // размер буфера принятого сообщения
byte MessageRx_PCM [bufsize] = {0}; // буфер принятого сообщения
byte crc =0; // байт контрольной суммы
// возможные варианты запросов на ЭБУ:
enum REQUEST {INIT, PID, DTCERASE, DTCREAD, PRESENT,};
// текстовки запросов для отладки
char* textRequest[] = {"INIT", "PID_2101", "DTC_ERASE", "DTC_READ", "PRESENT",} ;
// сами запросы
byte PCM_Message_TX[][5] = {
{1, 0x81, 0,0,0}, // запрос инициализации
{2, 0x21,0x01, 0,0}, // запрос пид 2101
{3, 0x14,0xFF,0x00, 0}, // запрос на стирание ошибок
{4, 0x18,0x00,0xFF,0x00 }, // запрос на чтение ошибок
{1, 0x3E, 0,0,0}, // запрос присутствия
};
byte request = INIT; // переменная, показывающая какой запрос будем делать
//------------------------------------------ переменные для организации протокола связи со щитком приборов
uint32_t prevRESETheaderGAUGE=0; // таймер сброса сообщения, если данные оборвались посередине сообщения
bool RESETheader_timerGAUGE; // таймер сброса сообщения, если данные оборвались посередине сообщения
uint32_t timerdelayGAUGE = 0; // таймер ожидания байт (для успевания появления данных в буфере UART)
bool DelayGAUGE = 0; // таймер ожидания байт (для успевания появления данных в буфере UART)
uint32_t prevNoconnect = 0; // таймер периодической проверки наличия связи со щитком приборов
byte waitbyte_RX_GAUGE = 1; // задержка, мс для успевания появления данных в буфере RX
// (подрегулировать в зависимости от уровня жизнидеятельности на Марсе)
#define TIMER_DELAYGAUGE DelayGAUGE = 0; timerdelayGAUGE = curmillis // включение этого таймера
uint32_t prevInitbusGauge = 0; // таймер для инита щитка приборов
byte NoconnectsGAUGE = 0 ; // счетчик неответов от щитка приборов
byte headerGAUGE = 0; // состояние заголовка
byte message_sizeGAUGE = 0; // размер тела сообщения
byte jGAUGE = 3; // инкремент
byte nGAUGE = 3; // количество старт байт
int ChecksumGAUGE =0; // байт контрольной суммы
byte InitGauge = 0; // автомат состояния инита щитка приборов
const byte bufsizeG = 150; // размер буфера принятого сообщения
byte MessageRx_GAUGE [bufsizeG] = {0}; // буфер принятого сообщения
byte PIDgauge[] = {0x02,0x11,0x00,0x13}; // запрос параметоров щитка приборов
//-------------------------------------------переменные бортовика
float L100M = 0; float L100M_last = 1; //расход на 100 км измеренный за поездку
float L100 = 0; float L100_last = 1; //мгновенный расход литров на 100км
float LHor = 0; float LHor_last = 1; //мгновенный расход топлива литров в час
float L100SR = 0; //расход литров на 100км измеренный раз в интервал kmL
float L100SR_TFT = 0; float L100SR_TFT_last = 1; // самый средний из расходов на 100км, он выводится на экран
int L100_Eeprom[11]= {10,10,10,10,10,10,10,10,10,10,10};
int FuelZamer[10]= {0}; // массив для измерения уровня (количества) топлива
int ZamerNumber = 0; // номер замера уровня (количества) топлива
int n_eeprom = 0; // текущий адрес ячейки еепром для записи расхода
int MAF = 0; int MAF_last = 1; //26,27 байты Sensor de flujo de aire en masa
float BoostPres = 0; float BoostPres_last = 1; //28,29 байты Presión de refuerzo
int RPM = 0; int RPM_last = 1; //32,33 байты Velocidad del motor
int EGRmg = 0; int EGRmg_last = 1; //34,35 байты Comando EGR (Comando de recirculación de gases de escape)
float BoostPresCom = 0; float BoostPresCom_last = 1;//38,39 байты Comando de presión de refuerzo
int Speed = 0; int Speed_last = 1; //44,45 байты Velocidad del vehículo
float DesaInjQua = 0; float DesaInjQua_last = 1; //50,51 байты Cantidad de inyección deseada
float InjQua = 0; float InjQua_last = 1; //52,53 байты Cantidad de la inyección
float StaDaliv = 0; float StaDaliv_last = 1; //54,55 байты Inicio de la entrega
int PumpRPM = 0; int PumpRPM_last = 1; //56,57 байты Velocidad de la bomba
float EGRPul = 0; float EGRPul_last = 1; //62,63 байты Relación de impulsos EGR (recirculación de gases de escape
float SolenPul = 0; float SolenPul_last = 1; //64,65 байты Velocidad de solenoide de control de nivel de remolino Relación de impulsos
float SolenPre = 0; float SolenPre_last = 1; //70,71 байты Relación de impulsos Presión Electroválvula de presión
float DesInj = 0; float DesInj_last = 1; //72,73 байты Inyección deseada Inicio
float ActInj = 0; float ActInj_last = 1; //16,17 байты Inicio de la inyección real
int TempAir = 0; int TempAir_last = 1; //74,75 байты Temperatura del aire de admisión
int Temp = 0; int Temp_last = 1; //14,15 байты Temperatura del refrigerante
int TempOil = 0; int TempOil_last = 1; //18,19 байты Temperatura del aceite del motor
int TempFuel = 0; int TempFuel_last = 1; //58,59 байты Temperatura del combustible
//все что касается топлива
float Fuel = 0; //остаток топлива
float Fuel2 = 0; float Fuel2_last = 1; //остаток мгновенного топлива байт 16 , датчика в баке
int FuelIGN = 0; // количество топлвива в баке на момент включения зажигания
int Fuel_last = 0; // для формул
bool flagFuelIGN = 0; // флаг записан ли остаток топлива в момент вкл. зажигания
float FuelTrip = 0; float FuelTrip_last = 1; // количество литров топлива, израсходованное за один цикл включения зажигания
//все что касается километража
float kmAge = 0; //пробег, полученный со щитка приборов
int kmAgeIGN = 0; //пробег который был в момент включения зажигания
int kmAge_last = 0; // для формул
bool flagkmAgeIGN = 0; //флаг записан ли пробег в момент вкл. зажигания
float kmTrip = 0; float kmTrip_last = 1; //пробег за один цикл включения зажигания
int kmL = 10; // интервал, через который будет происходить обновление среднего расхода на 100км
int km = 0; // переменная для расчетов
int kmeeprom = 10; // интервал, через который будет происходить подсчет среднеарифмитического расхода L100SR_TFT
int kmTFT = 0; // переменная для расчетов периодического подсчета среднеарифмитического расхода топлива L100SR_TFT
int kmREFUELING = 0; int kmREFUELING_last = 1; // пробег до заправки на остатке топлива
unsigned long prevWatch = 0;
unsigned long prevDvoet = 0;
unsigned long prevData = 0;
//----------------------------------------------для экрана
#include <Adafruit_GFX.h>
#include <MCUFRIEND_kbv.h>
#include <UTFTGLUE.h>//use GLUE class and constructor
#include "TouchScreen.h"
#include <stdint.h>
#include <SPI.h>
#include <EEPROM.h>
//#include "Fonts/Chosence_Bold16pt7b.h";
#define MINPRESSURE 200
#define MAXPRESSURE 1000
//pin 20 SCL , 21 SDA датчик реального времени
#include <Wire.h>
#include "RTClib.h"
RTC_DS3231 rtc;
UTFTGLUE myGLCD(0x1581,A2,A1,A3,A4,A0); //all dummy args
const int XP = 6, XM = A2, YP = A1, YM = 7;
const int TS_LEFT = 136, TS_RT = 907, TS_TOP = 139, TS_BOT = 942;
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
uint16_t ID;
int x, y;
char currentPage;
float h; int h_last = 1;
float t; int t_last = 1;
bool Dvoet = 0;
bool reNew = 0;
#define BLACK 0x0000
#define WHITE 0xFFFF
#define RED 0xF800
#define GREEN 0x07E0
void setup() {
uint16_t ID = myGLCD.readID();
if (ID == 0xD3D3) ID = 0x1581; // write-only shield
myGLCD.begin(ID);
myGLCD.InitLCD(3);
myGLCD.clrScr();
myGLCD.setTextSize(2);
//myGLCD.setFont(&Chosence_Bold16pt7b);
Wire.begin();
rtc.begin();
//загрузка стартовой страницы
currentPage = '0';
drawHomeScreen();
//подсчет среднеарифметического усредненного расхода
for (int i = 0; i < 11; i++) L100_Eeprom [i]= EEPROM.read(i);
for (int i = 0; i < 11; i++) L100SR_TFT = L100SR_TFT + L100_Eeprom [i];
L100SR_TFT = (float)L100SR_TFT/110.0;
if (L100SR_TFT<0) L100SR_TFT = 0;
if (L100SR_TFT>99) L100SR_TFT = 99;
// строка ниже используется для настройки даты и времени часов
// раскоментировать, выставить времая и дату, залить в ардуино. в скетче закоментировать
// обратно и залить еще раз, иначе каждый раз будет по новой выствлятся это же время и дата
// (год, месяц, день, часы, минуты, секунды)
//rtc.adjust(DateTime(2019, 7, 2, 10, 48, 0));
#if defined debugPCM or defined debugGAUGE
Serial.begin(115200);
#endif
K_LINE_PCM.begin(10400);
pinMode(TX_PCM, OUTPUT);
}
void loop()
{
curmillis = millis(); // снимок текущего времени
if (curmillis - prevRequest > RequestPeriod && header == 0 )
{
if (request == INIT) fastinit(); // при необходимости делаем переподключение к PCM
else {sendMessagePCM(request); // отправляем на PCM текущий запрос
if (request == PID) RequestPeriod = 600;
if (request == DTCERASE || request == DTCREAD) RequestPeriod = 2500;}
prevRequest = curmillis;
}
receivePCM (); // приём сообщений от PCM
receiveGAUGE (); // приём сообщений от щитка приборов
if (header == 0) {Menu ();}
if (curmillis - prevWatch > 4000) { Watch (); prevWatch = curmillis; Trip ();}
//if (curmillis - prevDvoet > 500) { if (!Dvoet) {myGLCD.setTextColor(WHITE); } else {myGLCD.setTextColor(BLACK); } myGLCD.print(":", 290, 5); prevDvoet = curmillis; Dvoet=!Dvoet;}
if (millis() - prevDvoet > 500) { if (!Dvoet) {myGLCD.print(":", 290, 5);} else {myGLCD.print(" ", 290, 5);} prevDvoet = millis(); Dvoet=!Dvoet;}
}// end loop
void Trip () {
if (flagkmAgeIGN){
FuelTrip = FuelIGN - Fuel;
if (kmAge>kmAgeIGN) kmTrip = kmAge - kmAgeIGN;
if (kmAge<kmAgeIGN) kmTrip = 2000 - (kmAgeIGN - kmAge); // 2000 это через сколько км у тебя суточный пробег сбрасывается на ноль, поменяй если другое число
if (kmAge==kmAgeIGN) kmTrip = 0;
//подсчет расхода на 100км за поездку
L100M = ((float)FuelTrip*100.00)/(float)kmTrip;
if (L100M<0) L100M = 0;
if (L100M>99) L100M = 99;
// ниже цикл считает среднеарифметический расход из еепром раз в пробег, указанный в переменной kmeeprom
if (kmTrip-kmTFT>kmeeprom) {kmTFT = kmTrip;
// тут считаем среднеарифметический усредненного расход из ячеек еепром
for (int i = 0; i < 11; i++) L100_Eeprom [i]= EEPROM.read(i);
for (int i = 0; i < 11; i++) L100SR_TFT = L100SR_TFT + L100_Eeprom [i];
L100SR_TFT = (float)L100SR_TFT/110.00;
if (L100SR_TFT<0) L100SR_TFT = 0;
if (L100SR_TFT>99) L100SR_TFT = 99;}
// ниже цикл считает расход топлива за пробег, указанный в переменной kmL, здесь же запись в ячейки еепром
if (kmTrip-km>kmL) {km=kmTrip;
L100SR = ((float)(Fuel_last-Fuel)*100.00)/(float)kmL; // расход/100км - обновляется раз в 10км, меняется км в int kmL = 10;
Fuel_last = Fuel; // сохранение параметров с последнего измерениея
if (L100SR<0) L100SR = 0;
if (L100SR>99) L100SR = 99;
//расчет остатка километров в баке
if (L100SR>0) kmREFUELING=((float)Fuel*100.0)/(float)L100SR; //если средний расход больше нуля, то расчитывать км в баке из него
else kmREFUELING=((float)Fuel*100.00)/(float)L100SR_TFT; //если ноль или ментше то расчитывать км в баке с устредненного расхода
// тут записываем L100SR последовательно в одну из 11 ячеек еепром
//EEPROM.write (12,n_eeprom); // ЗДЕСЬ ВНИМАТЕЛЬНО. ЗАГРУЗИТЬ ПРОШИВКУ С ЭТОЙ СТРОКОЙ ОДИН РАЗ, ПОТОМ ЗАКОМЕНТИРОВАТЬ И ЕЩЁ РАЗ ЗАГРУЗИТЬ
n_eeprom = EEPROM.read (12); // в ячейке 12 хранится № текущей ячейки для записи расхода, чтобы где остановился при выкл питания, от туда и продолжил
EEPROM.write(n_eeprom, L100SR*10);
n_eeprom++; if (n_eeprom>10) n_eeprom=0;
EEPROM.write (12,n_eeprom); }}}
void fastinit() {
digitalWrite (TX_PCM, HIGH); // bus idle
delay(1500);
digitalWrite (TX_PCM, LOW); // first part fastinit (25 ms LOW)
delay(25);
digitalWrite (TX_PCM, HIGH); // second part fastinit (25 ms HIGH)
delay(25);
K_LINE_PCM.begin(10400);
sendMessagePCM(INIT); // send start communication message
}
void receivePCM () {
if (K_LINE_PCM.available() ){
// первый старт байт
if (header == 0 && Delay){TIMER_DELAY ; MessageRx_PCM[0]=K_LINE_PCM.read();
if (MessageRx_PCM[0]!=0xFF && bitRead (MessageRx_PCM[0],7)){header = 1; RESETheader_timer = 1; prevRESETheader = curmillis;
#ifdef debugPCM
Serial.print (F("Receive PCM: ")); printDebugRX(MessageRx_PCM[0]);
#endif
}
}
// второй старт байт
if (header == 1 && Delay){TIMER_DELAY ; MessageRx_PCM[1]=K_LINE_PCM.read();
#ifdef debugPCM
printDebugRX (MessageRx_PCM[1]);
#endif
if (MessageRx_PCM[1]==DIAG_address){ header = 2;}
else {
#ifdef debugPCM
Serial.println(F(" PCM Message fail address"));
#endif
header = 0; RESETheader_timer = 0;}}
// третий старт байт
if (header == 2 && Delay){
TIMER_DELAY ;
MessageRx_PCM[2]=K_LINE_PCM.read();
#ifdef debugPCM
printDebugRX (MessageRx_PCM[2]);
#endif
if (MessageRx_PCM[2]==PCM_address){ message_size = MessageRx_PCM[0]; prevRESETheader = curmillis;
if (MessageRx_PCM[0] !=0x80) {header = 4; bitWrite (message_size, 7 , 0);j=3;n=3;}
else {header = 3; j=4;n=4;}
if (message_size > bufsize) message_size = bufsize; crc = 0;}
else {header = 0;
#ifdef debugPCM
Serial.println(F("PCM Message fail address"));
#endif
RESETheader_timer = 0;}
}
// если размер сообщения указан в дополнительном байте (нулевой байт 0x80) читаем этот дополнительный байт:
if (header == 3 && Delay){
TIMER_DELAY ; prevRESETheader = curmillis;
MessageRx_PCM[3]=K_LINE_PCM.read();
#ifdef debugPCM
printDebugRX(MessageRx_PCM[3]);
#endif
message_size = MessageRx_PCM[3];
if (message_size > bufsize) message_size = bufsize;
crc = 0; header = 4;
}
// пишем тело сообщения
if (header == 4 && Delay && j< message_size+n+1) {
MessageRx_PCM[j] = K_LINE_PCM.read(); prevRESETheader = curmillis;
if (j<message_size+n) crc+= MessageRx_PCM[j]; // подсчёт КС
if (j==message_size+n) header = 5;
TIMER_DELAY ;
#ifdef debugPCM
printDebugRX(MessageRx_PCM[j]);
#endif
j++; }
}
// сообщение приняли, действуем
if (header == 5) {TIMER_DELAY ;
#ifdef debugPCM
Serial.println();
#endif
NOanswer_timer = 0; noanswers = 0; // сбрасываем таймер контроля неответов
for(byte i = 0; i<n; i++) crc+=MessageRx_PCM[i]; // прибавляем к контрольной сумме старт байты
// если контрольная сумма верна:
if ( crc == MessageRx_PCM[message_size+n])
{
#ifdef debugPCM
Serial.print (F("Received message is OK! Checksum is correct!")); Serial.print (F(" ")); Serial.println (millis()); // Если КС совпала, тут чёнибудь нужное делаем
printDebugRX_CSgood();
#endif
if (MessageRx_PCM[n]==0xC1 && MessageRx_PCM[n+1]==0x6B && MessageRx_PCM[n+2]==0x8F) {
if (currentPage!=3) {request = PID; RequestPeriod = 70;} else request = PRESENT, RequestPeriod = 4000; prevRequest = curmillis; // receive good INIT
}
else if (MessageRx_PCM[n]==0x58) Troublecodes (); // DTC
else if (MessageRx_PCM[n]==0x54 && MessageRx_PCM[n+1]==0xFF && MessageRx_PCM[n+2]==0x00){ request = PRESENT; RequestPeriod = 4000; prevRequest = curmillis;} // DTC are cleared
else if (MessageRx_PCM[n]==0x61 && MessageRx_PCM[n+1]==0x01) {dataVars() ; RequestPeriod = 70; prevRequest = curmillis; } // receive DataStream
}
// если контрольная сумма не совпала:
#ifdef debugPCM
else Serial.println("CRC fail!!!" );
#endif
message_size = 0; header=0; RESETheader_timer = 0; j=3; crc = 0;
}
// таймер ожидания байт (для успевания появления данных в буфере UART)
if (!Delay && curmillis - timerdelay > waitbyte_RX) Delay = 1;
// таймер сброса целостности сообщения (если данные оборвались посередине сообщения)
if (RESETheader_timer && curmillis - prevRESETheader > 200) {
#ifdef debugPCM
Serial.println(F("Message fail timeout"));
#endif
RESETheader_timer = 0; header = 0;}
// если нет ответа после запроса: +1 к счетчику неответов. Если накопилось 6 и более: делаем реинит.
if (request!=INIT && NOanswer_timer && curmillis - prev_NOanswer > RequestPeriod - RequestPeriod/10)
{
NOanswer_timer = 0; noanswers++;
if (noanswers>=6) { noanswers = 0; request = INIT; RequestPeriod = 3500;}
}
}// end receivePCM
void Troublecodes ()
{
if (MessageRx_PCM[n]==0x58 && MessageRx_PCM[n+1]==0x00){
myGLCD.clrScr();
drawscreen_three();
myGLCD.print("NO DTC", 180, 145);
}
// при получении сообщения о наличии ошибок DTC разберем сообщение выведем на экран ошибки
if (MessageRx_PCM[n]==0x58 && MessageRx_PCM[n+1]>0){
myGLCD.clrScr();
drawscreen_three();
for (int i=0; i<MessageRx_PCM[n+8-7]; i++ ) {
int y = i*35;
bool nolA=0; bool nolB =0;
if (!bitRead(MessageRx_PCM[n+11-7+(i*3)],6) && bitRead(MessageRx_PCM[n+11-7+(i*3)],7)){ myGLCD.setTextColor(GREEN, BLACK);
myGLCD.print(" -Passive-", 300, (75+y));} // если DTC пасивныый делаем цвет зеленый
if (bitRead(MessageRx_PCM[n+11-7+(i*3)],7) && bitRead(MessageRx_PCM[n+11-7+(i*3)],6)) { myGLCD.setTextColor(RED, BLACK);
myGLCD.print(" -Active-", 300, (75+y));} // если DTC активный, делаем цвет красный
myGLCD.print("ERROR ", 50, (75+y));
myGLCD.printNumI((i+1), 150, (75+y));
if (!bitRead(MessageRx_PCM[n+9-7+(i*3)],6) && !bitRead(MessageRx_PCM[n+9-7+(i*3)],7)) myGLCD.print(": P", 170, (75+y));
if (bitRead(MessageRx_PCM[n+9-7+(i*3)],6) && !bitRead(MessageRx_PCM[n+9-7+(i*3)],7)) myGLCD.print(": C", 170, (75+y));
if (!bitRead(MessageRx_PCM[n+9-7+(i*3)],6) && bitRead(MessageRx_PCM[n+9-7+(i*3)],7)) myGLCD.print(": B", 170, (75+y));
if (bitRead(MessageRx_PCM[n+9-7+(i*3)],6) && bitRead(MessageRx_PCM[n+9-7+(i*3)],7)) myGLCD.print(": U", 170, (75+y));
if (MessageRx_PCM[n+9-7+(i*3)]==0x00) {myGLCD.print("00", 230, (75+y)); nolA = 1;}
if (MessageRx_PCM[n+9-7+(i*3)]<=0x0F&&MessageRx_PCM[n+9-7+(i*3)]!=0) {myGLCD.print("0", 230, (75+y)); nolA = 1;}
if (nolA)myGLCD.print(String (MessageRx_PCM[n+9-7+(i*3)],HEX), 246, (75+y));
else myGLCD.print(String (MessageRx_PCM[n+9-7+(i*3)],HEX), 230, (75+y));
if (MessageRx_PCM[n+10-7+(i*3)]==0x00) {myGLCD.print("00", 262, (75+y)); nolB = 1;}
if (MessageRx_PCM[n+10-7+(i*3)]<=0x0F&&MessageRx_PCM[n+10-7+(i*3)]!=0) {myGLCD.print("0", 262, (75+y)); nolB = 1;}
if (nolB)myGLCD.print(String (MessageRx_PCM[n+10-7+(i*3)]),HEX, 278, (75+y));
else myGLCD.print(String (MessageRx_PCM[n+10-7+(i*3)],HEX), 262, (75+y));}}
request = PRESENT; RequestPeriod = 4000; prevRequest = curmillis;
}
void dataVars()
{
//Barom = MessageRx_PCM[39];
L100 = (float)LHor*100.0/(float)Speed;
LHor = (float)RPM* (float)InjQua*2.00/1000.0*60.00/1000.0/0.85;
MAF = ((MessageRx_PCM[n+22]*256)+MessageRx_PCM[n+23])/10;
BoostPres = ((MessageRx_PCM[n+24]*256)+MessageRx_PCM[n+25])/1000.0;
RPM = (MessageRx_PCM[n+35-7]*256)+MessageRx_PCM[n+36-7];
EGRmg = ((MessageRx_PCM[n+37-7]*256)+MessageRx_PCM[n+38-7])/10.0;
BoostPresCom = ((MessageRx_PCM[n+41-7]*256)+MessageRx_PCM[n+42-7])/1000.0;
Speed = ((MessageRx_PCM[n+47-7]*256)+MessageRx_PCM[n+48-7])/100;
DesaInjQua = ((MessageRx_PCM[n+53-7]*256)+MessageRx_PCM[n+54-7])/100.0;
InjQua = ((MessageRx_PCM[n+55-7]*256)+MessageRx_PCM[n+56-7])/100.0;
StaDaliv = ((MessageRx_PCM[n+57-7]*256)+MessageRx_PCM[n+58-7])/100.0;
PumpRPM = (MessageRx_PCM[n+59-7]*256)+MessageRx_PCM[n+60-7];
EGRPul = ((MessageRx_PCM[n+65-7]*256)+MessageRx_PCM[n+66-7])/100.0;
SolenPul = ((MessageRx_PCM[n+67-7]*256)+MessageRx_PCM[n+68-7])/100.0;
SolenPre = ((MessageRx_PCM[n+73-7]*256)+MessageRx_PCM[n+74-7])/100.0;
DesInj = ((MessageRx_PCM[n+75-7]*3)+(MessageRx_PCM[n+76-7])/100.0)+0.3;
ActInj = ((MessageRx_PCM[n+19-7]*3)+(MessageRx_PCM[n+20-7])/100.0)+0.3;
//TempAir = ((MessageRx_PCM[n+77-7]*26)-278)+MessageRx_PCM[n+78-7]/10.0;
//Temp = ((MessageRx_PCM[n+17-7]*26)-278)+MessageRx_PCM[n+18-7]/10.0;
//TempOil = ((MessageRx_PCM[n+21-7]*26)-278)+MessageRx_PCM[n+22-7]/10.0;
//TempFuel = ((MessageRx_PCM[n+61-7]*26)-278)+MessageRx_PCM[n+62-7]/10.0;
//ниже идут расчетные формулы более точные чем те что закоментированы выше
int A = 0;
if (MessageRx_PCM[n+77-7]<=0x0A) A = 277;
if (MessageRx_PCM[n+77-7]==0x0B || MessageRx_PCM[n+77-7]==0x0C) A = 278;
if (MessageRx_PCM[n+77-7]>=0x0D) A = 279;
double B = MessageRx_PCM[n+78-7]/10.0;
double cel , drob ;
drob = modf(B, &cel);
if (drob>0.6) cel++;
TempAir = ((MessageRx_PCM[n+77-7]*26)-A)+cel;
if (MessageRx_PCM[n+17-7]<=0x0A) A = 277;
if (MessageRx_PCM[n+17-7]==0x0B || MessageRx_PCM[n+17-7]==0x0C) A = 278;
if (MessageRx_PCM[n+17-7]>=0x0D) A = 279;
B = MessageRx_PCM[n+18-7]/10.0;
drob = modf(B, &cel);
if (drob>0.6) cel++;
Temp = ((MessageRx_PCM[n+17-7]*26)-A)+cel;
if (MessageRx_PCM[n+21-7]<=0x0A) A = 277;
if (MessageRx_PCM[n+21-7]==0x0B || MessageRx_PCM[n+21-7]==0x0C) A = 278;
if (MessageRx_PCM[n+21-7]>=0x0D) A = 279;
B = MessageRx_PCM[n+22-7]/10.0;
drob = modf(B, &cel);
if (drob>0.6) cel++;
TempOil = ((MessageRx_PCM[n+21-7]*26)-A)+cel;
if (MessageRx_PCM[n+61-7]<=0x0A) A = 277;
if (MessageRx_PCM[n+61-7]==0x0B || MessageRx_PCM[n+61-7]==0x0C) A = 278;
if (MessageRx_PCM[n+61-7]>=0x0D) A = 279;
B = MessageRx_PCM[n+62-7]/10.0;
drob = modf(B, &cel);
if (drob>0.6) cel++;
TempFuel = ((MessageRx_PCM[n+61-7]*26)-A)+cel;
//----------------------------------------------------------
//страниц HOME
//----------------------------------------------------------
//myGLCD.setBackColor(RED);
myGLCD.setTextColor(WHITE, BLACK);
//myGLCD.setBackColor(RED);
if ((Speed != Speed_last) || reNew) {myGLCD.printNumI(Speed, 360, 7, 3); Speed_last=Speed;}
if (currentPage == '0') {
if ((LHor != LHor_last) || reNew) {myGLCD.printNumF(LHor, 1, 75, 40, '.',4); LHor_last=LHor;}
if ((L100 != L100_last) || reNew) {myGLCD.printNumF(L100, 1, 225, 40,'.',4 ); L100_last=L100;}
if ((L100M != L100M_last) || reNew) {myGLCD.printNumF(L100M, 1, 75, 75,'.',4 ); L100M_last=L100M;}
if ((L100SR_TFT != L100SR_TFT_last) || reNew) {myGLCD.printNumF(L100SR_TFT, 1, 225, 75,'.',4 ); L100SR_TFT_last=L100SR_TFT;}
if ((kmREFUELING != kmREFUELING_last) || reNew) {myGLCD.printNumI(kmREFUELING, 90, 110,3 ); kmREFUELING_last=kmREFUELING;}
//if (Fuel<53)
if ((Fuel != Fuel_last) || reNew) {myGLCD.printNumF(Fuel, 1, 225, 110,'.',4); Fuel_last=Fuel;}
//else myGLCD.print("MAX", 210, 110);
if ((kmTrip != kmTrip_last) || reNew) {myGLCD.printNumF(kmTrip, 1, 60, 145,'.',5); kmTrip_last=kmTrip;}
if ((FuelTrip != FuelTrip_last) || reNew) {myGLCD.printNumF(FuelTrip, 1, 210, 145,'.',5); FuelTrip_last=FuelTrip;}
if ((PumpRPM != PumpRPM_last) || reNew) {myGLCD.printNumI(PumpRPM, 230, 180,4); PumpRPM_last=PumpRPM;}
if ((RPM != RPM_last) || reNew) {myGLCD.printNumI(RPM, 230, 215,4); RPM_last=RPM;}
if ((Fuel2 != Fuel2_last) || reNew) {myGLCD.printNumF(Fuel2, 1, 10, 215,'.',4); Fuel2_last=Fuel2;}
if ((Temp != Temp_last) || reNew) {myGLCD.printNumI(Temp, 415, 40, 3); Temp_last=Temp;}
if ((TempOil != TempOil_last) || reNew) {myGLCD.printNumI(TempOil, 415, 75, 3); TempOil_last=TempOil;}
if ((TempFuel != TempFuel_last) || reNew) {myGLCD.printNumI(TempFuel, 415, 110,3); TempFuel_last=TempFuel;}
//myGLCD.printNumI(sensors.getTempCByIndex(0), 415, 145 , 3);
if ((t != t_last) || reNew) {myGLCD.printNumI(t, 415, 180, 3); t_last=t;}
if ((TempAir != TempAir_last) || reNew) {myGLCD.printNumI(TempAir, 415, 215, 3); TempAir_last=TempAir;}
reNew = 0;
}
//----------------------------------------------------------
//страниц INF1
//----------------------------------------------------------
if (currentPage == '1') {
if ((StaDaliv != StaDaliv_last) || reNew) {myGLCD.printNumF(StaDaliv,1, 385, 40,'.', 4); StaDaliv_last=StaDaliv;}
if ((DesInj != DesInj_last) || reNew) {myGLCD.printNumF(DesInj,1, 385, 75, '.', 4); DesInj_last=DesInj;}
if ((ActInj != ActInj_last) || reNew) {myGLCD.printNumF(ActInj,1, 385, 110,'.', 4); ActInj_last=ActInj;}
if ((DesaInjQua != DesaInjQua_last) || reNew) {myGLCD.printNumF(DesaInjQua,1, 385, 145,'.', 4);DesaInjQua_last=DesaInjQua;}
if ((InjQua != InjQua_last) || reNew) {myGLCD.printNumF(InjQua,1, 385, 180,'.', 4); InjQua_last=InjQua;}
if ((MAF != MAF_last) || reNew) {myGLCD.printNumI(MAF, 170, 215, 4); MAF_last=MAF;}
if ((h != h_last) || reNew) {myGLCD.printNumF(h, 1, 430, 215, 3); h_last=h;}
reNew = 0;
}
//----------------------------------------------------------
//страниц INF2
//----------------------------------------------------------
if (currentPage == '2') {
if ((BoostPres != BoostPres_last) || reNew) {myGLCD.printNumF(BoostPres,1, 400, 40,'.', 4); BoostPres_last=BoostPres;}
if ((BoostPresCom != BoostPresCom_last) || reNew) {myGLCD.printNumF(BoostPresCom,1, 400, 75,'.', 4); BoostPresCom_last=BoostPresCom;}
if ((EGRmg != EGRmg_last) || reNew) {myGLCD.printNumI(EGRmg, 400, 110, 4); EGRmg_last=EGRmg;}
if ((EGRPul != EGRPul_last) || reNew) {myGLCD.printNumF(EGRPul,1, 400, 145,'.', 4); EGRPul_last=EGRPul;}
if ((SolenPul != SolenPul_last) || reNew) {myGLCD.printNumF(SolenPul, 1, 400, 180,'.', 4); SolenPul_last=SolenPul;}
if ((SolenPre != SolenPre_last) || reNew) {myGLCD.printNumF(SolenPre, 0, 400, 215,'.', 4); SolenPre_last=SolenPre;}
reNew = 0;
}
//reNew = 0;
}
void sendMessagePCM(const byte &command)
{
#ifdef debugPCM
Serial.print (F("Send request ")); Serial.print (textRequest[command]); Serial.print (F(" to PCM ")); Serial.println (millis());
#endif
if (command != INIT) {NOanswer_timer = 1; prev_NOanswer = curmillis;} //т.к. сейчас будем делать запрос, то запускаем таймер контроля неответов
byte size = PCM_Message_TX[command][0];
const byte siZe = size+4;
byte Mes[siZe];
byte Checksum = 0;
for(byte i=0; i<siZe; i++) {
if (i==0) {Mes[i]=size; bitWrite(Mes[i], 7 , 1);}
if (i==1) Mes[i] = PCM_address;
if (i==2) Mes[i] = DIAG_address;
if (i==3) {for (byte t=1; t<size+1; t++ ) {
Mes[i]=PCM_Message_TX [command][t];
Checksum+=Mes[i] ;
K_LINE_PCM.write (Mes[i]);
if (command == INIT) delay (5); else delay (delaybyte_TX);
K_LINE_PCM.read();
i++;}}
if (i!=siZe-1) Checksum+=Mes[i];
else Mes[i] = Checksum;
K_LINE_PCM.write (Mes[i]);
if (command == INIT) delay (5); else delay (delaybyte_TX);
K_LINE_PCM.read();
}
}// end sendMessagePCM
void receiveGAUGE () {
if (K_LINE_GAUGE.available() ){
// первый старт байт
if (headerGAUGE == 0 && DelayGAUGE){TIMER_DELAYGAUGE ; MessageRx_GAUGE[0]=K_LINE_GAUGE.read();
if ((InitGauge ==1 && MessageRx_GAUGE[0]==0x55) || (InitGauge ==2 && MessageRx_GAUGE[0]!=0xFF && MessageRx_GAUGE[0]!=0x7F)
|| (InitGauge ==3 && MessageRx_GAUGE[0]!=0xFF && MessageRx_GAUGE[0]!=0x7F)
)
{headerGAUGE = 1; RESETheader_timerGAUGE = 1; prevRESETheaderGAUGE = curmillis;
#ifdef debugGAUGE
Serial.print (F("Receive GAUGE: ")); printDebugRX(MessageRx_GAUGE[0]);
#endif
}
}
// второй старт байт
if (headerGAUGE == 1 && DelayGAUGE){TIMER_DELAYGAUGE ; MessageRx_GAUGE[1]=K_LINE_GAUGE.read();
#ifdef debugGAUGE
printDebugRX (MessageRx_GAUGE[1]);
#endif
if ( (InitGauge ==1 && MessageRx_GAUGE[1]==0x52) || (InitGauge ==2 && (MessageRx_GAUGE[1]==0xA0 || MessageRx_GAUGE[1]==0xF0))
|| (InitGauge == 3 && MessageRx_GAUGE[1]==0xA1)){ headerGAUGE = 2;}
else {
#ifdef debugGAUGE
Serial.println(F(" GAUGE Message fail address"));
#endif
headerGAUGE = 0; RESETheader_timerGAUGE = 0;}}
// третий старт байт
if (headerGAUGE == 2 && DelayGAUGE){
TIMER_DELAYGAUGE ;
MessageRx_GAUGE[2]=K_LINE_GAUGE.read();
#ifdef debugGAUGE
printDebugRX (MessageRx_GAUGE[2]);
#endif
if ((InitGauge ==2 && (MessageRx_GAUGE[2]==0x48 || MessageRx_GAUGE[2]==0x55 || MessageRx_GAUGE[2]==0xAA)) || (InitGauge == 3 && MessageRx_GAUGE[2]==0x04)){ message_sizeGAUGE = MessageRx_GAUGE[0]-2; prevRESETheaderGAUGE = curmillis;
headerGAUGE = 4; jGAUGE=3; nGAUGE=3;
if (message_sizeGAUGE > bufsizeG) message_sizeGAUGE = bufsizeG; ChecksumGAUGE = 0;}
else if (InitGauge ==1 && MessageRx_GAUGE[2]==0x80) {InitGauge = 2; K_LINE_GAUGE.write(0x7F); delay (2); K_LINE_GAUGE.read(); headerGAUGE = 0; RESETheader_timerGAUGE = 0;
#ifdef debugGAUGE
Serial.println ("Gauge INIT is good!");
#endif
}
else {headerGAUGE = 0;
#ifdef debugGAUGE
Serial.println(F("GAUGE Message fail address"));
#endif
RESETheader_timerGAUGE = 0;}
}
// пишем тело сообщения
if (headerGAUGE == 4 && DelayGAUGE && jGAUGE< message_sizeGAUGE+nGAUGE+1) {
MessageRx_GAUGE[jGAUGE] = K_LINE_GAUGE.read(); prevRESETheaderGAUGE = curmillis;
if (jGAUGE<message_sizeGAUGE+nGAUGE-1) ChecksumGAUGE+= MessageRx_GAUGE[jGAUGE]; // подсчёт КС
if (jGAUGE==message_sizeGAUGE+nGAUGE) headerGAUGE = 5;
TIMER_DELAYGAUGE ;
#ifdef debugGAUGE
printDebugRX(MessageRx_GAUGE[jGAUGE]);
#endif
jGAUGE++; }
}
// сообщение приняли, действуем
if (headerGAUGE == 5) {TIMER_DELAYGAUGE ;
#ifdef debugGAUGE
Serial.println();
#endif
for(byte i = 0; i<nGAUGE; i++) ChecksumGAUGE+=MessageRx_GAUGE[i]; // прибавляем к контрольной сумме старт байты
int ChecksumG = ( ( unsigned int )MessageRx_GAUGE[message_sizeGAUGE+nGAUGE-1] << 8 ) | MessageRx_GAUGE[message_sizeGAUGE+nGAUGE]; // парсинг контрольной суммы из 2 последних байт
// если контрольная сумма верна:
if ( ChecksumGAUGE == ChecksumG)
{ NoconnectsGAUGE = 0; // сбрасываем на 0 отсутствие связи с панелью
#ifdef debugGAUGE
Serial.print (F("Received message is OK! Checksum is correct!")); Serial.print (F(" ")); Serial.println (millis()); // Если КС совпала, тут чёнибудь нужное делаем
#endif
if (MessageRx_GAUGE[1]== 0xA0 && MessageRx_GAUGE[2]== 0x48) {
#ifdef debugGAUGE
Serial.println ("ID panel receive! Send request PIDGauge");
#endif
InitGauge = 3;
for (byte i=0; i<sizeof(PIDgauge); i++) { K_LINE_GAUGE.write (PIDgauge[i]); delay (1); K_LINE_GAUGE.read();}
}
if (MessageRx_GAUGE[1]== 0xF0 && (MessageRx_GAUGE[2]== 0xAA || MessageRx_GAUGE[2]== 0x55)) {
#ifdef debugGAUGE
Serial.println ("receive present from Gauge. I send PID to Gauge");
#endif
InitGauge = 3;
for (byte i=0; i<sizeof(PIDgauge); i++) { K_LINE_GAUGE.write (PIDgauge[i]); delay (1); K_LINE_GAUGE.read();}
}
if (MessageRx_GAUGE[1]== 0xA1 && MessageRx_GAUGE[2]== 0x04) {
#ifdef debugGAUGE
Serial.println (" receive Datastream Gauge!");
#endif
Fuel2 = MessageRx_GAUGE[nGAUGE + 16]/2.0;
if (!flagFuelIGN) { Fuel = MessageRx_GAUGE[nGAUGE + 16]/2.0; kmREFUELING=((float)Fuel*100.00)/(float)L100SR_TFT;} //стартовая запись литров в баке для подсчета затраченных литро
else Fuel = MessageRx_GAUGE[nGAUGE + 17]/2.0; //для усреднения болтания в баке закоментировать эту строку, а раскоментировать ниже
//для усреднения болтания топлива в баке, раскоментировать, высчитывает среднее
/*else { FuelZamer[ZamerNumber] = MessageRxGauge[17]/2.00;
if (ZamerNumber==9) {
Fuel = 0 ;
for (int i = 0; i < 10; i++) Fuel = Fuel + FuelZamer[i];
Fuel = (float)Fuel/10.0;}
ZamerNumber++; if (ZamerNumber>9) ZamerNumber = 0;}
*/
kmAge = (MessageRx_GAUGE[nGAUGE + 23]+(MessageRx_GAUGE[nGAUGE + 24]*256))/10.0; //суточный пробег с панели приборов
//бак у меня на 59 литров, а датчик показывает максимально 53 литра. для этого эта формула
//если у вас тоже датчик имеет лимит то подправте 53 на свой лимит.
//если ваш датчик показывает одинаково с полным баком то закоментировать три нижние строки.
if (Fuel<53){
if (!flagkmAgeIGN) { kmAgeIGN = kmAge; flagkmAgeIGN =1;}
if (!flagFuelIGN) { FuelIGN = Fuel; Fuel_last = Fuel; flagFuelIGN = 1;}}
}
}
// если контрольная сумма не совпала:
#ifdef debugGAUGE
else Serial.println("CRC fail!!!" );
#endif
message_sizeGAUGE = 0; headerGAUGE=0; RESETheader_timerGAUGE = 0; jGAUGE=3; ChecksumGAUGE = 0;
}
// таймер ожидания байт (для успевания появления данных в буфере UART)
if (!DelayGAUGE && curmillis - timerdelayGAUGE > waitbyte_RX_GAUGE) DelayGAUGE = 1;
// таймер сброса целостности сообщения (если данные оборвались посередине сообщения)
if (RESETheader_timerGAUGE && curmillis - prevRESETheaderGAUGE > 1000) {
#ifdef debugGAUGE
Serial.println(F("Message fail timeout"));
#endif
RESETheader_timerGAUGE = 0; headerGAUGE = 0;}
if (curmillis - prevNoconnect > 500) {NoconnectsGAUGE ++ ; if (NoconnectsGAUGE>=8){
#ifdef debugGAUGE
Serial.println (F(" Connect GAUGE failed!!! ")) ;
#endif
NoconnectsGAUGE = 0 ;InitGauge = 0 ; } prevNoconnect = curmillis; }
InitBusGAUGE ();
}// end receiveGAUGE
void InitBusGAUGE ()
{
if (InitGauge == 0){
#ifdef debugGAUGE
Serial.println ("Send startsession - address Gauge");
#endif
K_LINE_GAUGE.end();
pinMode(TX_gauge, OUTPUT);
digitalWrite (TX_gauge, HIGH); // BUS IDLE
InitGauge = 5; prevInitbusGauge = curmillis;
}
if (InitGauge == 5 && curmillis - prevInitbusGauge>1500) {InitGauge = 6;} // BUS IDLE
if (InitGauge == 6)
{
byte boudrate = 1000/BAUD;
digitalWrite (TX_gauge, LOW); delay (boudrate); // старт бит
for (byte i=0; i<8; i++){digitalWrite (TX_gauge, bitRead(addressGUAGE, i)); delay (boudrate);} // биты тела адреса
digitalWrite (TX_gauge, HIGH); delay (boudrate); // стоп бит
K_LINE_GAUGE.begin(9600);
InitGauge = 1;
}
}
#if defined debugPCM or defined debugGAUGE
void printDebugRX (const byte &inbyte) {if (inbyte<=15) Serial.print(F("0")); Serial.print (inbyte, HEX); Serial.print (F(" "));}
#endif
#ifdef debugPCM
void printDebugRX_CSgood(){
if (MessageRx_PCM[n]==0xC1 && MessageRx_PCM[n+1]==0x6B && MessageRx_PCM[n+2]==0x8F) {Serial.println (F(" Initialization OK!!!!")); }
else if (MessageRx_PCM[n]==0x58 && MessageRx_PCM[n+1]==0x00) {Serial.println (F(" NO DTC "));}
else if (MessageRx_PCM[n]==0x58 && MessageRx_PCM[n+1] >0x00) {Serial.println (F(" DTC is found!"));}
else if (MessageRx_PCM[n]==0x54 && MessageRx_PCM[n+1]==0xFF && MessageRx_PCM[n+2]==0x00){Serial.println (F(" DTC CLEARED "));}
else if (MessageRx_PCM[n]==0x61 && MessageRx_PCM[n+1]==0x01) {Serial.println (F(" Receive PCM DATAstream"));}}
#endif
void Menu () {
TouchHOME();
if (currentPage == '0') {
TouchINF1();
TouchINF2();
TouchCHECK(); }
if (currentPage == '1') {
TouchINF2();
TouchCHECK(); }
if (currentPage == '2') {
TouchINF1();
TouchCHECK(); }
if (currentPage == '3') {
TouchREAD();
TouchERASE(); }}
void drawHomeScreen() {
line() ;
Watch ();
//myGLCD.print(":", 290, 5);
myGLCD.print("/", 115, 7);
myGLCD.print("/", 160, 7);
myGLCD.setTextColor(RED, BLACK); // цвет линии и текста красный
myGLCD.drawLine(295,35,295,248); // линия вертикальная
myGLCD.drawLine(145,35,145,178); // линия вертикальная
myGLCD.drawLine(80,178,80,247); // линия вертикальная
myGLCD.print("L/H", 10, 40);
myGLCD.print("L/A", 148, 40);
myGLCD.print("L/V", 10, 75);
myGLCD.print("L/M", 148, 75);
myGLCD.print("D/K", 10, 110);
myGLCD.print("D/L", 148, 110);
myGLCD.print("V/K", 10, 145);
myGLCD.print("V/L", 148, 145);
myGLCD.print("PUMP RPM", 82, 180);
myGLCD.print("ENGI RPM", 82, 215);
myGLCD.print("D/L/A", 10, 180);
myGLCD.print("Motor C", 300, 40);
myGLCD.print("OIL C", 300, 75);
myGLCD.print("FUEL C", 300, 110);
myGLCD.print("INTER C", 300, 145);
myGLCD.print("EXTER C", 300, 180);
myGLCD.print("INTAIR C", 300, 215);
//myGLCD.setTextColor(RED);
myGLCD.drawRoundRect (15, 255, 145, 310);
myGLCD.print("INF 1", 55, 270);
myGLCD.drawRoundRect (175, 255, 305, 310);
myGLCD.print("INF 2", 215, 270);
myGLCD.drawRoundRect (335, 255, 465, 310);
myGLCD.print("CHECK", 365, 270);
myGLCD.drawRoundRect (1, 1, 77, 37);
myGLCD.print("HOME", 10, 7);
myGLCD.print("Km/h", 410, 7);
reNew = 1;
}
//-------------------------------------------------
void drawscreen_one() {
line() ;
Watch ();
//myGLCD.print(":", 290, 5);
myGLCD.print("/", 115, 7);
myGLCD.print("/", 160, 7);
myGLCD.setTextColor(RED, BLACK); // цвет линии и текста красный
myGLCD.print("Start of Delivery *CA:", 10, 40);
myGLCD.print("Desir inject Start *CA:", 10, 75);
myGLCD.print("Actua Inject Start *CA:", 10, 110);
myGLCD.print("Desir Inject Quan mg/s:", 10, 145);
myGLCD.print("Actu Inject Quant mg/s:", 10, 180);
myGLCD.print("MAF mg/s:", 10, 215);
myGLCD.print("Humedad %:", 255, 215);
//myGLCD.setTextColor(RED);
myGLCD.drawRoundRect (175, 255, 305, 310);
myGLCD.print("INF 2", 215, 270);
myGLCD.drawRoundRect (335, 255, 465, 310);
myGLCD.print("CHECK", 365, 270);
myGLCD.drawRoundRect (1, 1, 77, 37);
myGLCD.print("HOME", 10, 7);
myGLCD.print("Km/h", 410, 7);
reNew = 1;
}
//-------------------------------------------------
void drawscreen_two() {
line() ;
Watch ();
//myGLCD.print(":", 290, 5);
myGLCD.print("/", 115, 7);
myGLCD.print("/", 160, 7);
myGLCD.setTextColor(RED, BLACK); // цвет линии и текста красный
myGLCD.print("Boost Press Bar:", 10, 40);
myGLCD.print("Boost Press Com Bar:", 10, 75);
myGLCD.print("EGR command mg/s:", 10, 110);
myGLCD.print("EGR Pulse Ratio %:", 10, 145);
myGLCD.print("Solenoide Pulse %:", 10, 180);
myGLCD.print("Solenoide Boost %:", 10, 215);
//myGLCD.setColor(RED);
myGLCD.drawRoundRect (15, 255, 145, 310);
myGLCD.print("INF 1", 55, 270);
myGLCD.drawRoundRect (335, 255, 465, 310);
myGLCD.print("CHECK", 365, 270);
myGLCD.drawRoundRect (1, 1, 77, 37);
myGLCD.print("HOME", 10, 7);
myGLCD.print("Km/h", 410, 7);
reNew = 1;
}
//----------------------------------------------------------------------------
void drawscreen_three() {
Watch ();
//myGLCD.print(":", 290, 5);
myGLCD.print("/", 115, 7);
myGLCD.print("/", 160, 7);
myGLCD.setTextColor(RED, BLACK); // цвет линии красный
myGLCD.drawLine(1,35,479,35); // линия горизонтальная
myGLCD.drawLine(1,248,479,248); // линия горизонтальная
//myGLCD.setTextColor(RED);
myGLCD.drawRoundRect (15, 255, 145, 310);
myGLCD.print("ERASE", 55, 270);
myGLCD.drawRoundRect (335, 255, 465, 310);
myGLCD.print("READ", 365, 270);
myGLCD.drawRoundRect (1, 1, 77, 37);
myGLCD.print("HOME", 10, 5);
reNew = 1;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//кнопки тач . координаты и переходы
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void TouchHOME(){
TSPoint p = ts.getPoint();
pinMode(XM, OUTPUT);
pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
{if (p.x > 140 && p.x < 320 && p.y > 140 && p.y < 260 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
{ myGLCD.drawRoundRect (1, 1, 77, 37);
currentPage = '0';
request = PID; RequestPeriod = 10; prevRequest = curmillis; // на PCM в этом окне посылается запрос текущих параметров
myGLCD.clrScr();
drawHomeScreen();
x = 0;
y = 0;
p.z = 0;}}}
void TouchINF1(){
TSPoint p = ts.getPoint();
pinMode(XM, OUTPUT);
pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
{
if (p.x > 150 && p.x < 450 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
{ myGLCD.drawRoundRect (15, 255, 145, 310);
currentPage = '1';
request = PID; RequestPeriod = 10; prevRequest = curmillis; // на PCM в этом окне посылается запрос текущих параметров
myGLCD.clrScr();
drawscreen_one();
x = 0;
y = 0;
p.z = 0;}}}
void TouchINF2(){
TSPoint p = ts.getPoint();
pinMode(XM, OUTPUT);
pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
{
if (p.x > 450 && p.x < 680 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
{ myGLCD.drawRoundRect (175, 255, 305, 310);
currentPage = '2';
request = PID; RequestPeriod = 600; prevRequest = curmillis; // на PCM в этом окне посылается запрос текущих параметров
myGLCD.clrScr();
drawscreen_two();
x = 0;
y = 0;
p.z = 0;}}}
void TouchCHECK(){
TSPoint p = ts.getPoint();
pinMode(XM, OUTPUT);
pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
{
if (p.x > 690 && p.x < 950 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
{ myGLCD.drawRoundRect (335, 255, 465, 310);
currentPage = '3';
// request = DTCREAD; RequestPeriod = 10; prevRequest = curmillis; // на PCM в этом окне посылается запрос чтения ошибок
myGLCD.clrScr();
drawscreen_three();
x = 0;
y = 0;
p.z = 0;}}}
void TouchREAD(){
TSPoint p = ts.getPoint();
pinMode(XM, OUTPUT);
pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
{
if (p.x > 690 && p.x < 950 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
{ myGLCD.drawRoundRect (335, 255, 465, 310);
request = DTCREAD; RequestPeriod = 300; prevRequest = curmillis; // на PCM при нажатии этой кнопки посылается запрос чтения ошибок
x = 0;
y = 0;
p.z = 0;}}}
void TouchERASE(){
TSPoint p = ts.getPoint();
pinMode(XM, OUTPUT);
pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
{
if (p.x > 150 && p.x < 450 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
{myGLCD.drawRoundRect (15, 255, 145, 310);
request = DTCERASE; RequestPeriod = 300; prevRequest = curmillis; // на PCM при нажатии этой кнопки посылается запрос удаления ошибок
myGLCD.clrScr();
drawscreen_three();
myGLCD.print("DTC BORRADO", 180, 145);
x = 0;
y = 0;
p.z = 0;}}}
////////////////////////////////////////////////////////////////////////////////////////
//прорисовка линий
///////////////////////////////////////////////////////////////////////////////////////
void line() {
//myGLCD.setTextColor(RED); // цвет линии красный
myGLCD.drawLine(1,35,479,35); // линия горизонтальная
myGLCD.drawLine(1,73,479,73); // линия горизонтальная
myGLCD.drawLine(1,108,479,108); // линия горизонтальная
myGLCD.drawLine(1,143,479,143); // линия горизонтальная
myGLCD.drawLine(1,178,479,178); // линия горизонтальная
myGLCD.drawLine(1,212,479,212); // линия горизонтальная
myGLCD.drawLine(1,248,479,248); // линия горизонтальная
}
void Watch (){
DateTime now = rtc.now();
int minut = now.minute();
int hour = now.hour();
int mon = now.month();
int date = now.day();
int Year = now.year();
static int minut_last;
static int hour_last;
static int mon_last;
static int date_last;
static int Year_last;
myGLCD.setTextColor(WHITE, BLACK); //белый цвет цифры
if (date != date_last || reNew){ myGLCD.printNumI(date, 85, 7, 2, '0'); date_last = date; }
if (mon!=mon_last || reNew){myGLCD.printNumI(mon, 130, 7, 2, '0'); mon_last = mon; }
if (Year!=Year_last || reNew) { myGLCD.printNumI(Year, 175, 7); Year_last = Year; }
if (hour!=hour_last || reNew){ myGLCD.printNumI(hour, 255, 7, 2, '0'); hour_last = hour; }
if (minut!=minut_last || reNew ){ myGLCD.printNumI(minut, 300, 7, 2, '0'); minut_last = minut; }
reNew = 1; }
не ругайся я менял мс в byte waitbyte_RX = 1; ща здесь поменяю byte waitbyte_RX_GAUGE = 1; . извени. не внимательность
К сожалению не помогает
маловероятно что поможет
да ты прав не помогло
ладно позже попробую алгоритм поменять
ок. спсибо
короче сделал по старой схеме
//------------все для связи по K-line (тут настраиваем UARTы к-лайников, адреса блоков, скорость инита и отладку) #include <SoftwareSerial.h> #define TX_PCM 13 SoftwareSerial K_LINE_PCM (12, TX_PCM); //RХ,TХ //UART на котором висит K_line к PCM #define K_LINE_GAUGE Serial2 //UART на котором висит K_line к приборке #define TX_gauge 16 //TX UARTa на котором висит K_line к приборке #define PCM_address 0x11 // адрес PCM #define DIAG_address 0xF1 // адрес диагностики const byte BAUD=200; // init baudrate - скорость инита при подключении к приборке const byte addressGUAGE = 0xB8;// init GAUGE address - адрес щитка приборов при ините (установке связи) //#define debugPCM // раскомментировать эту строку для отладки в Serial порту обмена с PCM #define debugGAUGE // раскомментировать эту строку для отладки в Serial порту обмена co щитком приборов uint32_t curmillis = 0; // снимок текущего времени //------------------------------------------переменные для организации протокола связи с PCM uint32_t prevRequest = 0; // таймер периодических запосов на PCM uint16_t RequestPeriod = 3500; // периодичность запросов на PCM uint32_t prevRESETheader=0; // таймер сброса сообщения, если данные оборвались посередине сообщения bool RESETheader_timer; // таймер сброса сообщения, если данные оборвались посередине сообщения uint32_t prev_NOanswer=0; // таймер контроля неответов от ЭБУ после подачи запросов bool NOanswer_timer = 0; // таймер контроля неответов от ЭБУ после подачи запросов byte noanswers = 0; // количество подряд неответов от ЭБУ uint32_t timerdelay = 0; // таймер ожидания байт (для успевания появления данных в буфере UART) bool Delay = 0; // таймер ожидания байт (для успевания появления данных в буфере UART) byte waitbyte_RX = 1; // задержка, мс для успевания появления данных в буфере RX // (подрегулировать в зависимости от уровня жизнидеятельности на Марсе) #define TIMER_DELAY Delay = 0; timerdelay = curmillis // включение этого таймера byte delaybyte_TX = 1; // задержка между отправкой байт в запросах, мс byte header = 0; // состояние заголовка byte message_size = 0; // размер тела сообщения byte j = 3; // инкремент byte n = 3; // количество старт байт const byte bufsize = 150; // размер буфера принятого сообщения byte MessageRx_PCM [bufsize] = {0}; // буфер принятого сообщения byte crc =0; // байт контрольной суммы // возможные варианты запросов на ЭБУ: enum REQUEST {INIT, PID, DTCERASE, DTCREAD, PRESENT,}; // текстовки запросов для отладки char* textRequest[] = {"INIT", "PID_2101", "DTC_ERASE", "DTC_READ", "PRESENT",} ; // сами запросы byte PCM_Message_TX[][5] = { {1, 0x81, 0,0,0}, // запрос инициализации {2, 0x21,0x01, 0,0}, // запрос пид 2101 {3, 0x14,0xFF,0x00, 0}, // запрос на стирание ошибок {4, 0x18,0x00,0xFF,0x00 }, // запрос на чтение ошибок {1, 0x3E, 0,0,0}, // запрос присутствия }; byte request = INIT; // переменная, показывающая какой запрос будем делать //------------------------------------------ переменные для организации протокола связи со щитком приборов uint32_t prevNoconnect = 0; // таймер периодической проверки наличия связи со щитком приборов uint32_t prevInitbusGauge = 0; // таймер для инита щитка приборов byte NoconnectsGAUGE = 0 ; // счетчик неответов от щитка приборов byte InitGauge = 0; // автомат состояния инита щитка приборов int waitbyte_gauge = 4; byte MessageRxGauge[60] = {0}; // массив байтов принимаемого сообщения от щитка приборов byte PIDgauge[] = {0x02,0x11,0x00,0x13}; // запрос параметоров щитка приборов //-------------------------------------------переменные бортовика float L100M = 0; float L100M_last = 1; //расход на 100 км измеренный за поездку float L100 = 0; float L100_last = 1; //мгновенный расход литров на 100км float LHor = 0; float LHor_last = 1; //мгновенный расход топлива литров в час float L100SR = 0; //расход литров на 100км измеренный раз в интервал kmL float L100SR_TFT = 0; float L100SR_TFT_last = 1; // самый средний из расходов на 100км, он выводится на экран int L100_Eeprom[11]= {10,10,10,10,10,10,10,10,10,10,10}; int FuelZamer[10]= {0}; // массив для измерения уровня (количества) топлива int ZamerNumber = 0; // номер замера уровня (количества) топлива int n_eeprom = 0; // текущий адрес ячейки еепром для записи расхода int MAF = 0; int MAF_last = 1; //26,27 байты Sensor de flujo de aire en masa float BoostPres = 0; float BoostPres_last = 1; //28,29 байты Presión de refuerzo int RPM = 0; int RPM_last = 1; //32,33 байты Velocidad del motor int EGRmg = 0; int EGRmg_last = 1; //34,35 байты Comando EGR (Comando de recirculación de gases de escape) float BoostPresCom = 0; float BoostPresCom_last = 1;//38,39 байты Comando de presión de refuerzo int Speed = 0; int Speed_last = 1; //44,45 байты Velocidad del vehículo float DesaInjQua = 0; float DesaInjQua_last = 1; //50,51 байты Cantidad de inyección deseada float InjQua = 0; float InjQua_last = 1; //52,53 байты Cantidad de la inyección float StaDaliv = 0; float StaDaliv_last = 1; //54,55 байты Inicio de la entrega int PumpRPM = 0; int PumpRPM_last = 1; //56,57 байты Velocidad de la bomba float EGRPul = 0; float EGRPul_last = 1; //62,63 байты Relación de impulsos EGR (recirculación de gases de escape float SolenPul = 0; float SolenPul_last = 1; //64,65 байты Velocidad de solenoide de control de nivel de remolino Relación de impulsos float SolenPre = 0; float SolenPre_last = 1; //70,71 байты Relación de impulsos Presión Electroválvula de presión float DesInj = 0; float DesInj_last = 1; //72,73 байты Inyección deseada Inicio float ActInj = 0; float ActInj_last = 1; //16,17 байты Inicio de la inyección real int TempAir = 0; int TempAir_last = 1; //74,75 байты Temperatura del aire de admisión int Temp = 0; int Temp_last = 1; //14,15 байты Temperatura del refrigerante int TempOil = 0; int TempOil_last = 1; //18,19 байты Temperatura del aceite del motor int TempFuel = 0; int TempFuel_last = 1; //58,59 байты Temperatura del combustible //все что касается топлива float Fuel = 0; //остаток топлива float Fuel2 = 0; float Fuel2_last = 1; //остаток мгновенного топлива байт 16 , датчика в баке int FuelIGN = 0; // количество топлвива в баке на момент включения зажигания int Fuel_last = 0; // для формул bool flagFuelIGN = 0; // флаг записан ли остаток топлива в момент вкл. зажигания float FuelTrip = 0; float FuelTrip_last = 1; // количество литров топлива, израсходованное за один цикл включения зажигания //все что касается километража float kmAge = 0; //пробег, полученный со щитка приборов int kmAgeIGN = 0; //пробег который был в момент включения зажигания int kmAge_last = 0; // для формул bool flagkmAgeIGN = 0; //флаг записан ли пробег в момент вкл. зажигания float kmTrip = 0; float kmTrip_last = 1; //пробег за один цикл включения зажигания int kmL = 10; // интервал, через который будет происходить обновление среднего расхода на 100км int km = 0; // переменная для расчетов int kmeeprom = 10; // интервал, через который будет происходить подсчет среднеарифмитического расхода L100SR_TFT int kmTFT = 0; // переменная для расчетов периодического подсчета среднеарифмитического расхода топлива L100SR_TFT int kmREFUELING = 0; int kmREFUELING_last = 1; // пробег до заправки на остатке топлива unsigned long prevWatch = 0; unsigned long prevDvoet = 0; unsigned long prevData = 0; //----------------------------------------------для экрана #include <Adafruit_GFX.h> #include <MCUFRIEND_kbv.h> #include <UTFTGLUE.h>//use GLUE class and constructor #include "TouchScreen.h" #include <stdint.h> #include <SPI.h> #include <EEPROM.h> //MCUFRIEND_kbv tft; #include "Fonts/Chosence_Bold16pt7b.h"; #define MINPRESSURE 200 #define MAXPRESSURE 1000 //pin 20 SCL , 21 SDA датчик реального времени #include <Wire.h> #include "RTClib.h" RTC_DS3231 rtc; UTFTGLUE myGLCD(0x1581,A2,A1,A3,A4,A0); //all dummy args const int XP = 6, XM = A2, YP = A1, YM = 7; const int TS_LEFT = 136, TS_RT = 907, TS_TOP = 139, TS_BOT = 942; TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300); uint16_t ID; int x, y; char currentPage; float h; int h_last = 1; float t; int t_last = 1; bool Dvoet = 0; bool reNew = 0; #define BLACK 0x0000 #define WHITE 0xFFFF #define RED 0xF800 #define GREEN 0x07E0 void setup() { uint16_t ID = myGLCD.readID(); if (ID == 0xD3D3) ID = 0x1581; // write-only shield myGLCD.begin(ID); myGLCD.InitLCD(3); myGLCD.clrScr(); myGLCD.setFont(&Chosence_Bold16pt7b); //myGLCD.fillScreen(WHITE); //myGLCD.setTextColor(WHITE, BLACK); //myGLCD.setBackColor(BLACK); Wire.begin(); rtc.begin(); //загрузка стартовой страницы currentPage = '0'; drawHomeScreen(); //подсчет среднеарифметического усредненного расхода for (int i = 0; i < 11; i++) L100_Eeprom [i]= EEPROM.read(i); for (int i = 0; i < 11; i++) L100SR_TFT = L100SR_TFT + L100_Eeprom [i]; L100SR_TFT = (float)L100SR_TFT/110.0; if (L100SR_TFT<0) L100SR_TFT = 0; if (L100SR_TFT>99) L100SR_TFT = 99; // строка ниже используется для настройки даты и времени часов // раскомментировать, выставить времая и дату, залить в ардуино. в скетче закомментировать // обратно и залить еще раз, иначе каждый раз будет по новой выствлятся это же время и дата // (год, месяц, день, часы, минуты, секунды) //rtc.adjust(DateTime(2019, 7, 2, 10, 48, 0)); #if defined debugPCM or defined debugGAUGE Serial.begin(115200); #endif K_LINE_PCM.begin(10400); pinMode(TX_PCM, OUTPUT); } void loop() { curmillis = millis(); // снимок текущего времени if (curmillis - prevRequest > RequestPeriod && header == 0 ) { if (request == INIT) fastinit(); // при необходимости делаем переподключение к PCM else {sendMessagePCM(request); // отправляем на PCM текущий запрос if (request == PID) RequestPeriod = 600; if (request == DTCERASE || request == DTCREAD) RequestPeriod = 2500;} prevRequest = curmillis; } receivePCM (); // приём сообщений от PCM receiveGAUGE (); // приём сообщений от щитка приборов if (header == 0) {Menu ();} if (curmillis - prevWatch > 4000) { Watch (); prevWatch = curmillis; Trip ();} //if (curmillis - prevDvoet > 500) { if (!Dvoet) {myGLCD.setTextColor(WHITE); } else {myGLCD.setTextColor(BLACK); } myGLCD.print(":", 290, 5); prevDvoet = curmillis; Dvoet=!Dvoet;} if (millis() - prevDvoet > 500) { if (!Dvoet) {myGLCD.print(":", 290, 5);} else {myGLCD.print(" ", 290, 5);} prevDvoet = millis(); Dvoet=!Dvoet;} }// end loop void Trip () { if (flagkmAgeIGN){ FuelTrip = FuelIGN - Fuel; if (kmAge>kmAgeIGN) kmTrip = kmAge - kmAgeIGN; if (kmAge<kmAgeIGN) kmTrip = 2000 - (kmAgeIGN - kmAge); // 2000 это через сколько км у тебя суточный пробег сбрасывается на ноль, поменяй если другое число if (kmAge==kmAgeIGN) kmTrip = 0; //подсчет расхода на 100км за поездку L100M = ((float)FuelTrip*100.00)/(float)kmTrip; if (L100M<0) L100M = 0; if (L100M>99) L100M = 99; // ниже цикл считает среднеарифметический расход из еепром раз в пробег, указанный в переменной kmeeprom if (kmTrip-kmTFT>kmeeprom) {kmTFT = kmTrip; // тут считаем среднеарифметический усредненного расход из ячеек еепром for (int i = 0; i < 11; i++) L100_Eeprom [i]= EEPROM.read(i); for (int i = 0; i < 11; i++) L100SR_TFT = L100SR_TFT + L100_Eeprom [i]; L100SR_TFT = (float)L100SR_TFT/110.00; if (L100SR_TFT<0) L100SR_TFT = 0; if (L100SR_TFT>99) L100SR_TFT = 99;} // ниже цикл считает расход топлива за пробег, указанный в переменной kmL, здесь же запись в ячейки еепром if (kmTrip-km>kmL) {km=kmTrip; L100SR = ((float)(Fuel_last-Fuel)*100.00)/(float)kmL; // расход/100км - обновляется раз в 10км, меняется км в int kmL = 10; Fuel_last = Fuel; // сохранение параметров с последнего измерениея if (L100SR<0) L100SR = 0; if (L100SR>99) L100SR = 99; //расчет остатка километров в баке if (L100SR>0) kmREFUELING=((float)Fuel*100.0)/(float)L100SR; //если средний расход больше нуля, то расчитывать км в баке из него else kmREFUELING=((float)Fuel*100.00)/(float)L100SR_TFT; //если ноль или ментше то расчитывать км в баке с устредненного расхода // тут записываем L100SR последовательно в одну из 11 ячеек еепром //EEPROM.write (12,n_eeprom); // ЗДЕСЬ ВНИМАТЕЛЬНО. ЗАГРУЗИТЬ ПРОШИВКУ С ЭТОЙ СТРОКОЙ ОДИН РАЗ, ПОТОМ ЗАКОМЕНТИРОВАТЬ И ЕЩЁ РАЗ ЗАГРУЗИТЬ n_eeprom = EEPROM.read (12); // в ячейке 12 хранится № текущей ячейки для записи расхода, чтобы где остановился при выкл питания, от туда и продолжил EEPROM.write(n_eeprom, L100SR*10); n_eeprom++; if (n_eeprom>10) n_eeprom=0; EEPROM.write (12,n_eeprom); }}} void fastinit() { digitalWrite (TX_PCM, HIGH); // bus idle delay(1500); digitalWrite (TX_PCM, LOW); // first part fastinit (25 ms LOW) delay(25); digitalWrite (TX_PCM, HIGH); // second part fastinit (25 ms HIGH) delay(25); K_LINE_PCM.begin(10400); sendMessagePCM(INIT); // send start communication message } void receivePCM () { if (K_LINE_PCM.available() ){ // первый старт байт if (header == 0 && Delay){TIMER_DELAY ; MessageRx_PCM[0]=K_LINE_PCM.read(); if (MessageRx_PCM[0]!=0xFF && bitRead (MessageRx_PCM[0],7)){header = 1; RESETheader_timer = 1; prevRESETheader = curmillis; #ifdef debugPCM Serial.print (F("Receive PCM: ")); printDebugRX(MessageRx_PCM[0]); #endif } } // второй старт байт if (header == 1 && Delay){TIMER_DELAY ; MessageRx_PCM[1]=K_LINE_PCM.read(); #ifdef debugPCM printDebugRX (MessageRx_PCM[1]); #endif if (MessageRx_PCM[1]==DIAG_address){ header = 2;} else { #ifdef debugPCM Serial.println(F(" PCM Message fail address")); #endif header = 0; RESETheader_timer = 0;}} // третий старт байт if (header == 2 && Delay){ TIMER_DELAY ; MessageRx_PCM[2]=K_LINE_PCM.read(); #ifdef debugPCM printDebugRX (MessageRx_PCM[2]); #endif if (MessageRx_PCM[2]==PCM_address){ message_size = MessageRx_PCM[0]; prevRESETheader = curmillis; if (MessageRx_PCM[0] !=0x80) {header = 4; bitWrite (message_size, 7 , 0);j=3;n=3;} else {header = 3; j=4;n=4;} if (message_size > bufsize) message_size = bufsize; crc = 0;} else {header = 0; #ifdef debugPCM Serial.println(F("PCM Message fail address")); #endif RESETheader_timer = 0;} } // если размер сообщения указан в дополнительном байте (нулевой байт 0x80) читаем этот дополнительный байт: if (header == 3 && Delay){ TIMER_DELAY ; prevRESETheader = curmillis; MessageRx_PCM[3]=K_LINE_PCM.read(); #ifdef debugPCM printDebugRX(MessageRx_PCM[3]); #endif message_size = MessageRx_PCM[3]; if (message_size > bufsize) message_size = bufsize; crc = 0; header = 4; } // пишем тело сообщения if (header == 4 && Delay && j< message_size+n+1) { MessageRx_PCM[j] = K_LINE_PCM.read(); prevRESETheader = curmillis; if (j<message_size+n) crc+= MessageRx_PCM[j]; // подсчёт КС if (j==message_size+n) header = 5; TIMER_DELAY ; #ifdef debugPCM printDebugRX(MessageRx_PCM[j]); #endif j++; } } // сообщение приняли, действуем if (header == 5) {TIMER_DELAY ; #ifdef debugPCM Serial.println(); #endif NOanswer_timer = 0; noanswers = 0; // сбрасываем таймер контроля неответов for(byte i = 0; i<n; i++) crc+=MessageRx_PCM[i]; // прибавляем к контрольной сумме старт байты // если контрольная сумма верна: if ( crc == MessageRx_PCM[message_size+n]) { #ifdef debugPCM Serial.print (F("Received message is OK! Checksum is correct!")); Serial.print (F(" ")); Serial.println (millis()); // Если КС совпала, тут чёнибудь нужное делаем printDebugRX_CSgood(); #endif if (MessageRx_PCM[n]==0xC1 && MessageRx_PCM[n+1]==0x6B && MessageRx_PCM[n+2]==0x8F) { if (currentPage!=3) {request = PID; RequestPeriod = 70;} else request = PRESENT, RequestPeriod = 4000; prevRequest = curmillis; // receive good INIT } else if (MessageRx_PCM[n]==0x58) Troublecodes (); // DTC else if (MessageRx_PCM[n]==0x54 && MessageRx_PCM[n+1]==0xFF && MessageRx_PCM[n+2]==0x00){ request = PRESENT; RequestPeriod = 4000; prevRequest = curmillis;} // DTC are cleared else if (MessageRx_PCM[n]==0x61 && MessageRx_PCM[n+1]==0x01) {dataVars() ; RequestPeriod = 70; prevRequest = curmillis; } // receive DataStream } // если контрольная сумма не совпала: #ifdef debugPCM else Serial.println("CRC fail!!!" ); #endif message_size = 0; header=0; RESETheader_timer = 0; j=3; crc = 0; } // таймер ожидания байт (для успевания появления данных в буфере UART) if (!Delay && curmillis - timerdelay > waitbyte_RX) Delay = 1; // таймер сброса целостности сообщения (если данные оборвались посередине сообщения) if (RESETheader_timer && curmillis - prevRESETheader > 200) { #ifdef debugPCM Serial.println(F("Message fail timeout")); #endif RESETheader_timer = 0; header = 0;} // если нет ответа после запроса: +1 к счетчику неответов. Если накопилось 6 и более: делаем реинит. if (request!=INIT && NOanswer_timer && curmillis - prev_NOanswer > RequestPeriod - RequestPeriod/10) { NOanswer_timer = 0; noanswers++; if (noanswers>=6) { noanswers = 0; request = INIT; RequestPeriod = 3500;} } }// end receivePCM void Troublecodes () { if (MessageRx_PCM[n]==0x58 && MessageRx_PCM[n+1]==0x00){ myGLCD.clrScr(); drawscreen_three(); myGLCD.print("NO DTC", 180, 145); } // при получении сообщения о наличии ошибок DTC разберем сообщение выведем на экран ошибки if (MessageRx_PCM[n]==0x58 && MessageRx_PCM[n+1]>0){ myGLCD.clrScr(); drawscreen_three(); for (int i=0; i<MessageRx_PCM[n+8-7]; i++ ) { int y = i*35; bool nolA=0; bool nolB =0; if (!bitRead(MessageRx_PCM[n+11-7+(i*3)],6) && bitRead(MessageRx_PCM[n+11-7+(i*3)],7)){ myGLCD.setTextColor(GREEN, BLACK); myGLCD.print(" -Passive-", 300, (75+y));} // если DTC пасивныый делаем цвет зеленый if (bitRead(MessageRx_PCM[n+11-7+(i*3)],7) && bitRead(MessageRx_PCM[n+11-7+(i*3)],6)) { myGLCD.setTextColor(RED, BLACK); myGLCD.print(" -Active-", 300, (75+y));} // если DTC активный, делаем цвет красный myGLCD.print("ERROR ", 50, (75+y)); myGLCD.printNumI((i+1), 150, (75+y)); if (!bitRead(MessageRx_PCM[n+9-7+(i*3)],6) && !bitRead(MessageRx_PCM[n+9-7+(i*3)],7)) myGLCD.print(": P", 170, (75+y)); if (bitRead(MessageRx_PCM[n+9-7+(i*3)],6) && !bitRead(MessageRx_PCM[n+9-7+(i*3)],7)) myGLCD.print(": C", 170, (75+y)); if (!bitRead(MessageRx_PCM[n+9-7+(i*3)],6) && bitRead(MessageRx_PCM[n+9-7+(i*3)],7)) myGLCD.print(": B", 170, (75+y)); if (bitRead(MessageRx_PCM[n+9-7+(i*3)],6) && bitRead(MessageRx_PCM[n+9-7+(i*3)],7)) myGLCD.print(": U", 170, (75+y)); if (MessageRx_PCM[n+9-7+(i*3)]==0x00) {myGLCD.print("00", 230, (75+y)); nolA = 1;} if (MessageRx_PCM[n+9-7+(i*3)]<=0x0F&&MessageRx_PCM[n+9-7+(i*3)]!=0) {myGLCD.print("0", 230, (75+y)); nolA = 1;} if (nolA)myGLCD.print(String (MessageRx_PCM[n+9-7+(i*3)],HEX), 246, (75+y)); else myGLCD.print(String (MessageRx_PCM[n+9-7+(i*3)],HEX), 230, (75+y)); if (MessageRx_PCM[n+10-7+(i*3)]==0x00) {myGLCD.print("00", 262, (75+y)); nolB = 1;} if (MessageRx_PCM[n+10-7+(i*3)]<=0x0F&&MessageRx_PCM[n+10-7+(i*3)]!=0) {myGLCD.print("0", 262, (75+y)); nolB = 1;} if (nolB)myGLCD.print(String (MessageRx_PCM[n+10-7+(i*3)]),HEX, 278, (75+y)); else myGLCD.print(String (MessageRx_PCM[n+10-7+(i*3)],HEX), 262, (75+y));}} request = PRESENT; RequestPeriod = 4000; prevRequest = curmillis; } void dataVars() { //Barom = MessageRx_PCM[39]; L100 = (float)LHor*100.0/(float)Speed; LHor = (float)RPM* (float)InjQua*2.00/1000.0*60.00/1000.0/0.85; MAF = ((MessageRx_PCM[n+22]*256)+MessageRx_PCM[n+23])/10; BoostPres = ((MessageRx_PCM[n+24]*256)+MessageRx_PCM[n+25])/1000.0; RPM = (MessageRx_PCM[n+35-7]*256)+MessageRx_PCM[n+36-7]; EGRmg = ((MessageRx_PCM[n+37-7]*256)+MessageRx_PCM[n+38-7])/10.0; BoostPresCom = ((MessageRx_PCM[n+41-7]*256)+MessageRx_PCM[n+42-7])/1000.0; Speed = ((MessageRx_PCM[n+47-7]*256)+MessageRx_PCM[n+48-7])/100; DesaInjQua = ((MessageRx_PCM[n+53-7]*256)+MessageRx_PCM[n+54-7])/100.0; InjQua = ((MessageRx_PCM[n+55-7]*256)+MessageRx_PCM[n+56-7])/100.0; StaDaliv = ((MessageRx_PCM[n+57-7]*256)+MessageRx_PCM[n+58-7])/100.0; PumpRPM = (MessageRx_PCM[n+59-7]*256)+MessageRx_PCM[n+60-7]; EGRPul = ((MessageRx_PCM[n+65-7]*256)+MessageRx_PCM[n+66-7])/100.0; SolenPul = ((MessageRx_PCM[n+67-7]*256)+MessageRx_PCM[n+68-7])/100.0; SolenPre = ((MessageRx_PCM[n+73-7]*256)+MessageRx_PCM[n+74-7])/100.0; DesInj = ((MessageRx_PCM[n+75-7]*3)+(MessageRx_PCM[n+76-7])/100.0)+0.3; ActInj = ((MessageRx_PCM[n+19-7]*3)+(MessageRx_PCM[n+20-7])/100.0)+0.3; //TempAir = ((MessageRx_PCM[n+77-7]*26)-278)+MessageRx_PCM[n+78-7]/10.0; //Temp = ((MessageRx_PCM[n+17-7]*26)-278)+MessageRx_PCM[n+18-7]/10.0; //TempOil = ((MessageRx_PCM[n+21-7]*26)-278)+MessageRx_PCM[n+22-7]/10.0; //TempFuel = ((MessageRx_PCM[n+61-7]*26)-278)+MessageRx_PCM[n+62-7]/10.0; //ниже идут расчетные формулы более точные чем те что закоментированы выше int A = 0; if (MessageRx_PCM[n+77-7]<=0x0A) A = 277; if (MessageRx_PCM[n+77-7]==0x0B || MessageRx_PCM[n+77-7]==0x0C) A = 278; if (MessageRx_PCM[n+77-7]>=0x0D) A = 279; double B = MessageRx_PCM[n+78-7]/10.0; double cel , drob ; drob = modf(B, &cel); if (drob>0.6) cel++; TempAir = ((MessageRx_PCM[n+77-7]*26)-A)+cel; if (MessageRx_PCM[n+17-7]<=0x0A) A = 277; if (MessageRx_PCM[n+17-7]==0x0B || MessageRx_PCM[n+17-7]==0x0C) A = 278; if (MessageRx_PCM[n+17-7]>=0x0D) A = 279; B = MessageRx_PCM[n+18-7]/10.0; drob = modf(B, &cel); if (drob>0.6) cel++; Temp = ((MessageRx_PCM[n+17-7]*26)-A)+cel; if (MessageRx_PCM[n+21-7]<=0x0A) A = 277; if (MessageRx_PCM[n+21-7]==0x0B || MessageRx_PCM[n+21-7]==0x0C) A = 278; if (MessageRx_PCM[n+21-7]>=0x0D) A = 279; B = MessageRx_PCM[n+22-7]/10.0; drob = modf(B, &cel); if (drob>0.6) cel++; TempOil = ((MessageRx_PCM[n+21-7]*26)-A)+cel; if (MessageRx_PCM[n+61-7]<=0x0A) A = 277; if (MessageRx_PCM[n+61-7]==0x0B || MessageRx_PCM[n+61-7]==0x0C) A = 278; if (MessageRx_PCM[n+61-7]>=0x0D) A = 279; B = MessageRx_PCM[n+62-7]/10.0; drob = modf(B, &cel); if (drob>0.6) cel++; TempFuel = ((MessageRx_PCM[n+61-7]*26)-A)+cel; //---------------------------------------------------------- //страниц HOME //---------------------------------------------------------- //myGLCD.setBackColor(RED); myGLCD.setTextColor(WHITE, BLACK); //myGLCD.setBackColor(RED); if ((Speed != Speed_last) || reNew) {myGLCD.printNumI(Speed, 360, 7, 3); Speed_last=Speed;} if (currentPage == '0') { if ((LHor != LHor_last) || reNew) {myGLCD.printNumF(LHor, 1, 75, 40, '.',4); LHor_last=LHor;} if ((L100 != L100_last) || reNew) {myGLCD.printNumF(L100, 1, 225, 40,'.',4 ); L100_last=L100;} if ((L100M != L100M_last) || reNew) {myGLCD.printNumF(L100M, 1, 75, 75,'.',4 ); L100M_last=L100M;} if ((L100SR_TFT != L100SR_TFT_last) || reNew) {myGLCD.printNumF(L100SR_TFT, 1, 225, 75,'.',4 ); L100SR_TFT_last=L100SR_TFT;} if ((kmREFUELING != kmREFUELING_last) || reNew) {myGLCD.printNumI(kmREFUELING, 90, 110,3 ); kmREFUELING_last=kmREFUELING;} //if (Fuel<53) if ((Fuel != Fuel_last) || reNew) {myGLCD.printNumF(Fuel, 1, 225, 110,'.',4); Fuel_last=Fuel;} //else myGLCD.print("MAX", 210, 110); if ((kmTrip != kmTrip_last) || reNew) {myGLCD.printNumF(kmTrip, 1, 60, 145,'.',5); kmTrip_last=kmTrip;} if ((FuelTrip != FuelTrip_last) || reNew) {myGLCD.printNumF(FuelTrip, 1, 210, 145,'.',5); FuelTrip_last=FuelTrip;} if ((PumpRPM != PumpRPM_last) || reNew) {myGLCD.printNumI(PumpRPM, 230, 180,4); PumpRPM_last=PumpRPM;} if ((RPM != RPM_last) || reNew) {myGLCD.printNumI(RPM, 230, 215,4); RPM_last=RPM;} if ((Fuel2 != Fuel2_last) || reNew) {myGLCD.printNumF(Fuel2, 1, 10, 215,'.',4); Fuel2_last=Fuel2;} if ((Temp != Temp_last) || reNew) {myGLCD.printNumI(Temp, 415, 40, 3); Temp_last=Temp;} if ((TempOil != TempOil_last) || reNew) {myGLCD.printNumI(TempOil, 415, 75, 3); TempOil_last=TempOil;} if ((TempFuel != TempFuel_last) || reNew) {myGLCD.printNumI(TempFuel, 415, 110,3); TempFuel_last=TempFuel;} //myGLCD.printNumI(sensors.getTempCByIndex(0), 415, 145 , 3); if ((t != t_last) || reNew) {myGLCD.printNumI(t, 415, 180, 3); t_last=t;} if ((TempAir != TempAir_last) || reNew) {myGLCD.printNumI(TempAir, 415, 215, 3); TempAir_last=TempAir;} reNew = 0; } //---------------------------------------------------------- //страниц INF1 //---------------------------------------------------------- if (currentPage == '1') { if ((StaDaliv != StaDaliv_last) || reNew) {myGLCD.printNumF(StaDaliv,1, 385, 40,'.', 4); StaDaliv_last=StaDaliv;} if ((DesInj != DesInj_last) || reNew) {myGLCD.printNumF(DesInj,1, 385, 75, '.', 4); DesInj_last=DesInj;} if ((ActInj != ActInj_last) || reNew) {myGLCD.printNumF(ActInj,1, 385, 110,'.', 4); ActInj_last=ActInj;} if ((DesaInjQua != DesaInjQua_last) || reNew) {myGLCD.printNumF(DesaInjQua,1, 385, 145,'.', 4);DesaInjQua_last=DesaInjQua;} if ((InjQua != InjQua_last) || reNew) {myGLCD.printNumF(InjQua,1, 385, 180,'.', 4); InjQua_last=InjQua;} if ((MAF != MAF_last) || reNew) {myGLCD.printNumI(MAF, 170, 215, 4); MAF_last=MAF;} if ((h != h_last) || reNew) {myGLCD.printNumF(h, 1, 430, 215, 3); h_last=h;} reNew = 0; } //---------------------------------------------------------- //страниц INF2 //---------------------------------------------------------- if (currentPage == '2') { if ((BoostPres != BoostPres_last) || reNew) {myGLCD.printNumF(BoostPres,1, 400, 40,'.', 4); BoostPres_last=BoostPres;} if ((BoostPresCom != BoostPresCom_last) || reNew) {myGLCD.printNumF(BoostPresCom,1, 400, 75,'.', 4); BoostPresCom_last=BoostPresCom;} if ((EGRmg != EGRmg_last) || reNew) {myGLCD.printNumI(EGRmg, 400, 110, 4); EGRmg_last=EGRmg;} if ((EGRPul != EGRPul_last) || reNew) {myGLCD.printNumF(EGRPul,1, 400, 145,'.', 4); EGRPul_last=EGRPul;} if ((SolenPul != SolenPul_last) || reNew) {myGLCD.printNumF(SolenPul, 1, 400, 180,'.', 4); SolenPul_last=SolenPul;} if ((SolenPre != SolenPre_last) || reNew) {myGLCD.printNumF(SolenPre, 0, 400, 215,'.', 4); SolenPre_last=SolenPre;} reNew = 0; } //reNew = 0; } void sendMessagePCM(const byte &command) { #ifdef debugPCM Serial.print (F("Send request ")); Serial.print (textRequest[command]); Serial.print (F(" to PCM ")); Serial.println (millis()); #endif if (command != INIT) {NOanswer_timer = 1; prev_NOanswer = curmillis;} //т.к. сейчас будем делать запрос, то запускаем таймер контроля неответов byte size = PCM_Message_TX[command][0]; const byte siZe = size+4; byte Mes[siZe]; byte Checksum = 0; for(byte i=0; i<siZe; i++) { if (i==0) {Mes[i]=size; bitWrite(Mes[i], 7 , 1);} if (i==1) Mes[i] = PCM_address; if (i==2) Mes[i] = DIAG_address; if (i==3) {for (byte t=1; t<size+1; t++ ) { Mes[i]=PCM_Message_TX [command][t]; Checksum+=Mes[i] ; K_LINE_PCM.write (Mes[i]); if (command == INIT) delay (5); else delay (delaybyte_TX); K_LINE_PCM.read(); i++;}} if (i!=siZe-1) Checksum+=Mes[i]; else Mes[i] = Checksum; K_LINE_PCM.write (Mes[i]); if (command == INIT) delay (5); else delay (delaybyte_TX); K_LINE_PCM.read(); } }// end sendMessagePCM void receiveGAUGE () { while(InitGauge==1){ if (K_LINE_GAUGE.available()) { byte inByte = K_LINE_GAUGE.read(); #ifdef debugGAUGE Serial.print(" "); Serial.print(inByte,HEX); #endif if (inByte==0x80) {K_LINE_GAUGE.write (0x7F); delay (1);} if (inByte==0xF0) { for (byte i=0; i<sizeof(PIDgauge); i++) { K_LINE_GAUGE.write (PIDgauge[i]); delay (1);} InitGauge=2; NoconnectsGAUGE = 0;}}} bool MessageParse = 0; bool dataMessageEND = 0; bool dataMessageOK = 0; byte headerGAUGE = 0; byte numberbyte = 0; while (InitGauge==2 && !MessageParse) { if (!dataMessageOK) { if (K_LINE_GAUGE.read() == 0x23 && headerGAUGE ==0) {headerGAUGE=1; delay (waitbyte_gauge); } if (K_LINE_GAUGE.read() == 0xA1 && headerGAUGE ==1) {headerGAUGE=2; delay (waitbyte_gauge);} else {headerGAUGE =0;} if (K_LINE_GAUGE.read() == 0x04 && headerGAUGE ==2) {headerGAUGE=3; delay (waitbyte_gauge);} else {headerGAUGE =0;} if (headerGAUGE ==3) {dataMessageOK = 1; headerGAUGE =0;} numberbyte=0;} else { if (K_LINE_GAUGE.available()>0) { MessageRxGauge[numberbyte] = K_LINE_GAUGE.read(); numberbyte++; delayMicroseconds (250);} if (numberbyte==34) {dataMessageEND = 1; dataMessageOK = 0; }} if (dataMessageEND) { int crc = ( ( unsigned int )MessageRxGauge[32] << 8 ) | MessageRxGauge[33]; // парсинг контрольной суммы из 2 последних байт int CRC =200; for (int i = 0; i < 32; i++) CRC = CRC + MessageRxGauge[i]; // подсчет контрольной суммы байт от 0 до 31 #ifdef debugGAUGE Serial.print (" ReceiveGauge: "); for (int i = 0; i < 34; i++) { Serial.print(MessageRxGauge[i],HEX); Serial.print (" ");} #endif //при получении сообщения БЕЗ ошибок с данными от панели приборов, запишем в переменные остаток топлива и пробег if (CRC==crc) { #ifdef debugGAUGE Serial.println (" OK!!!"); #endif Fuel2 = MessageRxGauge[16]/2.0; if (!flagFuelIGN) { Fuel = MessageRxGauge[16]/2.00; kmREFUELING=((float)Fuel*100.00)/(float)L100SR_TFT;} //стартовая запись литров в баке для подсчета затраченных литро else Fuel = MessageRxGauge[17]/2.0; //для устреднения болтания в баке закоментировать эту строку, а раскоментировать ниже //для усреднения болтания топлива в баке, раскоментировать, высчитывает среднее /*else { FuelZamer[ZamerNumber] = MessageRxGauge[17]/2.00; if (ZamerNumber==9) { Fuel = 0 ; for (int i = 0; i < 10; i++) Fuel = Fuel + FuelZamer[i]; Fuel = (float)Fuel/10.0;} ZamerNumber++; if (ZamerNumber>9) ZamerNumber = 0;} */ kmAge = (MessageRxGauge[23]+(MessageRxGauge[24]*256))/10.0; //суточный пробег с панели приборов //бак у меня на 59 литров, а датчик показывает максимально 53 литра. для этого эта формула //если у вас тоже датчик имеет лимит то подправте 53 на свой лимит. //если ваш датчик показывает одинаково с полным баком то закоментировать три нижние строки. if (Fuel<53){ if (!flagkmAgeIGN) { kmAgeIGN = kmAge; flagkmAgeIGN =1;} if (!flagFuelIGN) { FuelIGN = Fuel; Fuel_last = Fuel; flagFuelIGN = 1; }}} #ifdef debugGAUGE else Serial.println (" ERROR!!!"); #endif dataMessageEND = 0; MessageParse = 1; //K_LINE_GAUGE.flush(); for (int i = 0; i < 34; i++) MessageRxGauge[i]=0; NoconnectsGAUGE = 0;}} // очистка байтов массива if (curmillis - prevNoconnect > 500) {NoconnectsGAUGE ++ ; if (NoconnectsGAUGE>=10){ #ifdef debugGAUGE Serial.println (F(" Connect GAUGE failed!!! ")) ; #endif NoconnectsGAUGE = 0 ;InitGauge = 0 ; } prevNoconnect = curmillis; } InitBusGAUGE (); }// end receiveGAUGE void InitBusGAUGE () { if (InitGauge == 0){ #ifdef debugGAUGE Serial.println ("Send startsession - address Gauge"); #endif K_LINE_GAUGE.end(); pinMode(TX_gauge, OUTPUT); digitalWrite (TX_gauge, HIGH); // BUS IDLE InitGauge = 5; prevInitbusGauge = curmillis; } if (InitGauge == 5 && curmillis - prevInitbusGauge>1500) {InitGauge = 6;} // BUS IDLE if (InitGauge == 6) { byte boudrate = 1000/BAUD; digitalWrite (TX_gauge, LOW); delay (boudrate); // старт бит for (byte i=0; i<8; i++){digitalWrite (TX_gauge, bitRead(addressGUAGE, i)); delay (boudrate);} // биты тела адреса digitalWrite (TX_gauge, HIGH); delay (boudrate); // стоп бит K_LINE_GAUGE.begin(9600); InitGauge = 1; } } #if defined debugPCM or defined debugGAUGE void printDebugRX (const byte &inbyte) {if (inbyte<=15) Serial.print(F("0")); Serial.print (inbyte, HEX); Serial.print (F(" "));} #endif #ifdef debugPCM void printDebugRX_CSgood(){ if (MessageRx_PCM[n]==0xC1 && MessageRx_PCM[n+1]==0x6B && MessageRx_PCM[n+2]==0x8F) {Serial.println (F(" Initialization OK!!!!")); } else if (MessageRx_PCM[n]==0x58 && MessageRx_PCM[n+1]==0x00) {Serial.println (F(" NO DTC "));} else if (MessageRx_PCM[n]==0x58 && MessageRx_PCM[n+1] >0x00) {Serial.println (F(" DTC is found!"));} else if (MessageRx_PCM[n]==0x54 && MessageRx_PCM[n+1]==0xFF && MessageRx_PCM[n+2]==0x00){Serial.println (F(" DTC CLEARED "));} else if (MessageRx_PCM[n]==0x61 && MessageRx_PCM[n+1]==0x01) {Serial.println (F(" Receive PCM DATAstream"));}} #endif void Menu () { TouchHOME(); if (currentPage == '0') { TouchINF1(); TouchINF2(); TouchCHECK(); } if (currentPage == '1') { TouchINF2(); TouchCHECK(); } if (currentPage == '2') { TouchINF1(); TouchCHECK(); } if (currentPage == '3') { TouchREAD(); TouchERASE(); }} void drawHomeScreen() { line() ; Watch (); //myGLCD.print(":", 290, 5); myGLCD.print("/", 115, 7); myGLCD.print("/", 160, 7); myGLCD.setTextColor(RED, BLACK); // цвет линии и текста красный myGLCD.drawLine(295,35,295,248); // линия вертикальная myGLCD.drawLine(145,35,145,178); // линия вертикальная myGLCD.drawLine(80,178,80,247); // линия вертикальная myGLCD.print("L/H", 10, 40); myGLCD.print("L/A", 148, 40); myGLCD.print("L/V", 10, 75); myGLCD.print("L/M", 148, 75); myGLCD.print("D/K", 10, 110); myGLCD.print("D/L", 148, 110); myGLCD.print("V/K", 10, 145); myGLCD.print("V/L", 148, 145); myGLCD.print("PUMP RPM", 82, 180); myGLCD.print("ENGI RPM", 82, 215); myGLCD.print("D/L/A", 10, 180); myGLCD.print("Motor C", 300, 40); myGLCD.print("OIL C", 300, 75); myGLCD.print("FUEL C", 300, 110); myGLCD.print("INTER C", 300, 145); myGLCD.print("EXTER C", 300, 180); myGLCD.print("INTAIR C", 300, 215); //myGLCD.setTextColor(RED); myGLCD.drawRoundRect (15, 255, 145, 310); myGLCD.print("INF 1", 55, 270); myGLCD.drawRoundRect (175, 255, 305, 310); myGLCD.print("INF 2", 215, 270); myGLCD.drawRoundRect (335, 255, 465, 310); myGLCD.print("CHECK", 365, 270); myGLCD.drawRoundRect (1, 1, 77, 37); myGLCD.print("HOME", 10, 7); myGLCD.print("Km/h", 410, 7); reNew = 1; } //------------------------------------------------- void drawscreen_one() { line() ; Watch (); //myGLCD.print(":", 290, 5); myGLCD.print("/", 115, 7); myGLCD.print("/", 160, 7); myGLCD.setTextColor(RED, BLACK); // цвет линии и текста красный myGLCD.print("Start of Delivery *CA:", 10, 40); myGLCD.print("Desir inject Start *CA:", 10, 75); myGLCD.print("Actua Inject Start *CA:", 10, 110); myGLCD.print("Desir Inject Quan mg/s:", 10, 145); myGLCD.print("Actu Inject Quant mg/s:", 10, 180); myGLCD.print("MAF mg/s:", 10, 215); myGLCD.print("Humedad %:", 255, 215); //myGLCD.setTextColor(RED); myGLCD.drawRoundRect (175, 255, 305, 310); myGLCD.print("INF 2", 215, 270); myGLCD.drawRoundRect (335, 255, 465, 310); myGLCD.print("CHECK", 365, 270); myGLCD.drawRoundRect (1, 1, 77, 37); myGLCD.print("HOME", 10, 7); myGLCD.print("Km/h", 410, 7); reNew = 1; } //------------------------------------------------- void drawscreen_two() { line() ; Watch (); //myGLCD.print(":", 290, 5); myGLCD.print("/", 115, 7); myGLCD.print("/", 160, 7); myGLCD.setTextColor(RED, BLACK); // цвет линии и текста красный myGLCD.print("Boost Press Bar:", 10, 40); myGLCD.print("Boost Press Com Bar:", 10, 75); myGLCD.print("EGR command mg/s:", 10, 110); myGLCD.print("EGR Pulse Ratio %:", 10, 145); myGLCD.print("Solenoide Pulse %:", 10, 180); myGLCD.print("Solenoide Boost %:", 10, 215); //myGLCD.setColor(RED); myGLCD.drawRoundRect (15, 255, 145, 310); myGLCD.print("INF 1", 55, 270); myGLCD.drawRoundRect (335, 255, 465, 310); myGLCD.print("CHECK", 365, 270); myGLCD.drawRoundRect (1, 1, 77, 37); myGLCD.print("HOME", 10, 7); myGLCD.print("Km/h", 410, 7); reNew = 1; } //---------------------------------------------------------------------------- void drawscreen_three() { Watch (); //myGLCD.print(":", 290, 5); myGLCD.print("/", 115, 7); myGLCD.print("/", 160, 7); myGLCD.setTextColor(RED, BLACK); // цвет линии красный myGLCD.drawLine(1,35,479,35); // линия горизонтальная myGLCD.drawLine(1,248,479,248); // линия горизонтальная //myGLCD.setTextColor(RED); myGLCD.drawRoundRect (15, 255, 145, 310); myGLCD.print("ERASE", 55, 270); myGLCD.drawRoundRect (335, 255, 465, 310); myGLCD.print("READ", 365, 270); myGLCD.drawRoundRect (1, 1, 77, 37); myGLCD.print("HOME", 10, 5); reNew = 1; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //кнопки тач . координаты и переходы ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void TouchHOME(){ TSPoint p = ts.getPoint(); pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); if (p.z > 10 && p.z < 1000) {if (p.x > 140 && p.x < 320 && p.y > 140 && p.y < 260 && p.z > MINPRESSURE && p.z < MAXPRESSURE) { myGLCD.drawRoundRect (1, 1, 77, 37); currentPage = '0'; request = PID; RequestPeriod = 10; prevRequest = curmillis; // на PCM в этом окне посылается запрос текущих параметров myGLCD.clrScr(); drawHomeScreen(); x = 0; y = 0; p.z = 0;}}} void TouchINF1(){ TSPoint p = ts.getPoint(); pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); if (p.z > 10 && p.z < 1000) { if (p.x > 150 && p.x < 450 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE) { myGLCD.drawRoundRect (15, 255, 145, 310); currentPage = '1'; request = PID; RequestPeriod = 10; prevRequest = curmillis; // на PCM в этом окне посылается запрос текущих параметров myGLCD.clrScr(); drawscreen_one(); x = 0; y = 0; p.z = 0;}}} void TouchINF2(){ TSPoint p = ts.getPoint(); pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); if (p.z > 10 && p.z < 1000) { if (p.x > 450 && p.x < 680 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE) { myGLCD.drawRoundRect (175, 255, 305, 310); currentPage = '2'; request = PID; RequestPeriod = 600; prevRequest = curmillis; // на PCM в этом окне посылается запрос текущих параметров myGLCD.clrScr(); drawscreen_two(); x = 0; y = 0; p.z = 0;}}} void TouchCHECK(){ TSPoint p = ts.getPoint(); pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); if (p.z > 10 && p.z < 1000) { if (p.x > 690 && p.x < 950 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE) { myGLCD.drawRoundRect (335, 255, 465, 310); currentPage = '3'; // request = DTCREAD; RequestPeriod = 10; prevRequest = curmillis; // на PCM в этом окне посылается запрос чтения ошибок myGLCD.clrScr(); drawscreen_three(); x = 0; y = 0; p.z = 0;}}} void TouchREAD(){ TSPoint p = ts.getPoint(); pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); if (p.z > 10 && p.z < 1000) { if (p.x > 690 && p.x < 950 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE) { myGLCD.drawRoundRect (335, 255, 465, 310); request = DTCREAD; RequestPeriod = 300; prevRequest = curmillis; // на PCM при нажатии этой кнопки посылается запрос чтения ошибок x = 0; y = 0; p.z = 0;}}} void TouchERASE(){ TSPoint p = ts.getPoint(); pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); if (p.z > 10 && p.z < 1000) { if (p.x > 150 && p.x < 450 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE) {myGLCD.drawRoundRect (15, 255, 145, 310); request = DTCERASE; RequestPeriod = 300; prevRequest = curmillis; // на PCM при нажатии этой кнопки посылается запрос удаления ошибок myGLCD.clrScr(); drawscreen_three(); myGLCD.print("DTC BORRADO", 180, 145); x = 0; y = 0; p.z = 0;}}} //////////////////////////////////////////////////////////////////////////////////////// //прорисовка линий /////////////////////////////////////////////////////////////////////////////////////// void line() { //myGLCD.setTextColor(RED); // цвет линии красный myGLCD.drawLine(1,35,479,35); // линия горизонтальная myGLCD.drawLine(1,73,479,73); // линия горизонтальная myGLCD.drawLine(1,108,479,108); // линия горизонтальная myGLCD.drawLine(1,143,479,143); // линия горизонтальная myGLCD.drawLine(1,178,479,178); // линия горизонтальная myGLCD.drawLine(1,212,479,212); // линия горизонтальная myGLCD.drawLine(1,248,479,248); // линия горизонтальная } void Watch (){ DateTime now = rtc.now(); int minut = now.minute(); int hour = now.hour(); int mon = now.month(); int date = now.day(); int Year = now.year(); static int minut_last; static int hour_last; static int mon_last; static int date_last; static int Year_last; myGLCD.setTextColor(WHITE, BLACK); //белый цвет цифры if (date != date_last || reNew){ myGLCD.printNumI(date, 85, 7, 2, '0'); date_last = date; } if (mon!=mon_last || reNew){myGLCD.printNumI(mon, 130, 7, 2, '0'); mon_last = mon; } if (Year!=Year_last || reNew) { myGLCD.printNumI(Year, 175, 7); Year_last = Year; } if (hour!=hour_last || reNew){ myGLCD.printNumI(hour, 255, 7, 2, '0'); hour_last = hour; } if (minut!=minut_last || reNew ){ myGLCD.printNumI(minut, 300, 7, 2, '0'); minut_last = minut; } }ща испытаю
#define debugGAUGE
Send startsession - address Gauge 55 52 80 7F 2D A0 48 54 20 32 34 34 31 39 35 36 30 20 31 34 30 30 20 34 31 39 39 20 31 33 30 31 20 30 34 32 20 31 20 30 30 30 30 30 30 30 30 30 30 8 F0 ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B3 0 FF 50 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F1 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B4 0 FF 4F 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F1 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B4 0 FF 4E 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F0 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B4 0 FF 4E 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F0 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B2 0 FF 4F 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 EF OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B4 0 FF 4F 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F1 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B1 0 FF 4F 50 4F 1A 47 0 0 0 23 4 0 0 0 0 0 0 0 0 4 ERROR!!! ReceiveGauge: 23 A1 4 0 0 0 0 0 0 0 0 0 0 4 10 B5 0 FF 4F 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 ERROR!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B3 0 FF 4F 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F0 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B5 0 FF 4E 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F1 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B2 0 FF 50 4F 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 EF OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B2 0 FF 4F 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 EF OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B5 0 FF 4F 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F2 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B5 0 FF 4E 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F1 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B2 0 FF 50 4F 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 EF OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B5 0 FF 4E 50 4F 1A 47 0 0 0 23 4 0 0 0 0 0 0 0 0 4 ERROR!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B2 0 FF 4F 4F 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 EE OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B2 0 FF 50 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F0 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B5 0 FF 4F 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F2 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B3 0 FF 50 50 4F 1A 47 0 0 0 13 0 5 23 A1 4 0 0 0 0 0 ERROR!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B5 0 FF 51 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F4 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 51 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F6 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B5 0 FF 51 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F4 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 51 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F6 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 51 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F6 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 51 50 4F 1A 47 0 0 0 23 A1 4 0 0 0 0 0 0 0 0 ERROR!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 51 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F8 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B6 0 FF 51 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F5 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B6 0 FF 51 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F5 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 51 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F8 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B6 0 FF 51 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F5 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 51 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F8 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B6 0 FF 51 50 4F 1A 47 0 0 0 8C 13 0 5 F7 23 A1 4 0 0 0 ERROR!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 51 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F7 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B6 0 FF 52 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F6 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 51 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F8 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 51 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F8 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B6 0 FF 51 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F5 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 51 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F8 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 50 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F7 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B6 0 FF 52 4F 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F5 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 52 4F 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F7 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B6 0 FF 52 50 4F 1A 47 0 0 0 8C 13 0 5 F8 23 A1 4 0 0 0 ERROR!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 BA 0 FF 51 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F9 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 51 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F8 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 BA 0 FF 51 4F 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F8 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 51 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F6 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 52 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F7 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 BA 0 FF 51 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F9 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 51 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F8 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 BA 0 FF 51 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F9 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 52 50 4F 1A 47 0 0 0 A1 0 0 0 0 0 0 0 0 4 10 ERROR!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 BA 0 FF 51 4F 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F8 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 51 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F7 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 52 4F 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F8 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 51 4F 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F5 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 51 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F6 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 BA 0 FF 52 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 FA OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 BA 0 FF 52 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 FA OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 52 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F9 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 BA 0 FF 51 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F9 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 51 50 4F 1A 47 0 0 0 23 A1 4 0 0 0 0 0 0 0 0 ERROR!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 51 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F8 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 51 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F7 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 51 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F6 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 BA 0 FF 51 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F9 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 51 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F7 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 BA 0 FF 51 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F9 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 BA 0 FF 51 50 4F 1A 47 0 0 0 0 10 0 51 50 4F 1A 47 0 0 0 ERROR!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 52 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F9 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 51 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F8 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 BA 0 FF 51 4F 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F8 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 52 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F7 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 BA 0 FF 51 50 4F 1A 47 0 0 0 23 A1 4 0 0 0 0 0 0 0 0 ERROR!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 52 4F 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F6 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 52 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F7 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 52 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F8 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 BA 0 FF 51 4F 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F8 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 52 50 4F 1A 47 0 0 0 A1 0 0 0 0 0 0 0 0 4 10 ERROR!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 BA 0 FF 51 4F 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F8 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 BA 0 FF 51 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F9 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 BA 0 FF 51 50 4F 1A 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F9 OK!!!#define debugPCM
и на экране нет данных
Ну так и думал что одно заработает, а другое сломается
самое верное решение уже давно раньше звучало. Взять вторую ардуину и наделить её обязанностью обмениваться по к-лайн, а основной ардуине, она 4 готовых байта будет передавать, без всяких инитов и прочей херни.
понимаю, это мне нужно было делать с самого начала, когда ты это говорил, в разработке. теперь уже это не для меня. да и все таки же работало 2 года на одной..... и без проблем, если бы не экран, то так бы и работало.
убрал автоматическое переподключение к панели. Сделал опрос данных щитка приборов раз в полминуты, чтобы не мешать обмену с PCM
//------------все для связи по K-line (тут настраиваем UARTы к-лайников, адреса блоков, скорость инита и отладку) #include <SoftwareSerial.h> #define TX_PCM 13 SoftwareSerial K_LINE_PCM (12, TX_PCM); //RХ,TХ //UART на котором висит K_line к PCM #define K_LINE_GAUGE Serial2 //UART на котором висит K_line к приборке #define TX_gauge 16 //TX UARTa на котором висит K_line к приборке #define PCM_address 0x11 // адрес PCM #define DIAG_address 0xF1 // адрес диагностики const byte BAUD=200; // init baudrate - скорость инита при подключении к приборке const byte addressGUAGE = 0xB8;// init GAUGE address - адрес щитка приборов при ините (установке связи) //#define debugPCM // раскомментировать эту строку для отладки в Serial порту обмена с PCM #define debugGAUGE // раскомментировать эту строку для отладки в Serial порту обмена co щитком приборов uint32_t curmillis = 0; // снимок текущего времени //------------------------------------------переменные для организации протокола связи с PCM uint32_t prevRequest = 0; // таймер периодических запосов на PCM uint16_t RequestPeriod = 3500; // периодичность запросов на PCM uint32_t prevRESETheader=0; // таймер сброса сообщения, если данные оборвались посередине сообщения bool RESETheader_timer; // таймер сброса сообщения, если данные оборвались посередине сообщения uint32_t prev_NOanswer=0; // таймер контроля неответов от ЭБУ после подачи запросов bool NOanswer_timer = 0; // таймер контроля неответов от ЭБУ после подачи запросов byte noanswers = 0; // количество подряд неответов от ЭБУ uint32_t timerdelay = 0; // таймер ожидания байт (для успевания появления данных в буфере UART) bool Delay = 0; // таймер ожидания байт (для успевания появления данных в буфере UART) byte waitbyte_RX = 1; // задержка, мс для успевания появления данных в буфере RX // (подрегулировать в зависимости от уровня жизнидеятельности на Марсе) #define TIMER_DELAY Delay = 0; timerdelay = curmillis // включение этого таймера byte delaybyte_TX = 1; // задержка между отправкой байт в запросах, мс byte header = 0; // состояние заголовка byte message_size = 0; // размер тела сообщения byte j = 3; // инкремент byte n = 3; // количество старт байт const byte bufsize = 150; // размер буфера принятого сообщения byte MessageRx_PCM [bufsize] = {0}; // буфер принятого сообщения byte crc =0; // байт контрольной суммы // возможные варианты запросов на ЭБУ: enum REQUEST {INIT, PID, DTCERASE, DTCREAD, PRESENT,}; // текстовки запросов для отладки char* textRequest[] = {"INIT", "PID_2101", "DTC_ERASE", "DTC_READ", "PRESENT",} ; // сами запросы byte PCM_Message_TX[][5] = { {1, 0x81, 0,0,0}, // запрос инициализации {2, 0x21,0x01, 0,0}, // запрос пид 2101 {3, 0x14,0xFF,0x00, 0}, // запрос на стирание ошибок {4, 0x18,0x00,0xFF,0x00 }, // запрос на чтение ошибок {1, 0x3E, 0,0,0}, // запрос присутствия }; byte request = INIT; // переменная, показывающая какой запрос будем делать //------------------------------------------ переменные для организации протокола связи со щитком приборов uint32_t prevNoconnect = 0; // таймер периодической проверки наличия связи со щитком приборов uint32_t prevInitbusGauge = 0; // таймер для инита щитка приборов byte NoconnectsGAUGE = 0 ; // счетчик неответов от щитка приборов byte InitGauge = 0; // автомат состояния инита щитка приборов int waitbyte_gauge = 4; byte MessageRxGauge[60] = {0}; // массив байтов принимаемого сообщения от щитка приборов byte PIDgauge[] = {0x02,0x11,0x00,0x13}; // запрос параметоров щитка приборов bool flagneedGAUGE = 1; //-------------------------------------------переменные бортовика float L100M = 0; float L100M_last = 1; //расход на 100 км измеренный за поездку float L100 = 0; float L100_last = 1; //мгновенный расход литров на 100км float LHor = 0; float LHor_last = 1; //мгновенный расход топлива литров в час float L100SR = 0; //расход литров на 100км измеренный раз в интервал kmL float L100SR_TFT = 0; float L100SR_TFT_last = 1; // самый средний из расходов на 100км, он выводится на экран int L100_Eeprom[11]= {10,10,10,10,10,10,10,10,10,10,10}; int FuelZamer[10]= {0}; // массив для измерения уровня (количества) топлива int ZamerNumber = 0; // номер замера уровня (количества) топлива int n_eeprom = 0; // текущий адрес ячейки еепром для записи расхода int MAF = 0; int MAF_last = 1; //26,27 байты Sensor de flujo de aire en masa float BoostPres = 0; float BoostPres_last = 1; //28,29 байты Presión de refuerzo int RPM = 0; int RPM_last = 1; //32,33 байты Velocidad del motor int EGRmg = 0; int EGRmg_last = 1; //34,35 байты Comando EGR (Comando de recirculación de gases de escape) float BoostPresCom = 0; float BoostPresCom_last = 1;//38,39 байты Comando de presión de refuerzo int Speed = 0; int Speed_last = 1; //44,45 байты Velocidad del vehículo float DesaInjQua = 0; float DesaInjQua_last = 1; //50,51 байты Cantidad de inyección deseada float InjQua = 0; float InjQua_last = 1; //52,53 байты Cantidad de la inyección float StaDaliv = 0; float StaDaliv_last = 1; //54,55 байты Inicio de la entrega int PumpRPM = 0; int PumpRPM_last = 1; //56,57 байты Velocidad de la bomba float EGRPul = 0; float EGRPul_last = 1; //62,63 байты Relación de impulsos EGR (recirculación de gases de escape float SolenPul = 0; float SolenPul_last = 1; //64,65 байты Velocidad de solenoide de control de nivel de remolino Relación de impulsos float SolenPre = 0; float SolenPre_last = 1; //70,71 байты Relación de impulsos Presión Electroválvula de presión float DesInj = 0; float DesInj_last = 1; //72,73 байты Inyección deseada Inicio float ActInj = 0; float ActInj_last = 1; //16,17 байты Inicio de la inyección real int TempAir = 0; int TempAir_last = 1; //74,75 байты Temperatura del aire de admisión int Temp = 0; int Temp_last = 1; //14,15 байты Temperatura del refrigerante int TempOil = 0; int TempOil_last = 1; //18,19 байты Temperatura del aceite del motor int TempFuel = 0; int TempFuel_last = 1; //58,59 байты Temperatura del combustible //все что касается топлива float Fuel = 0; //остаток топлива float Fuel2 = 0; float Fuel2_last = 1; //остаток мгновенного топлива байт 16 , датчика в баке int FuelIGN = 0; // количество топлвива в баке на момент включения зажигания int Fuel_last = 0; // для формул bool flagFuelIGN = 0; // флаг записан ли остаток топлива в момент вкл. зажигания float FuelTrip = 0; float FuelTrip_last = 1; // количество литров топлива, израсходованное за один цикл включения зажигания //все что касается километража float kmAge = 0; //пробег, полученный со щитка приборов int kmAgeIGN = 0; //пробег который был в момент включения зажигания int kmAge_last = 0; // для формул bool flagkmAgeIGN = 0; //флаг записан ли пробег в момент вкл. зажигания float kmTrip = 0; float kmTrip_last = 1; //пробег за один цикл включения зажигания int kmL = 10; // интервал, через который будет происходить обновление среднего расхода на 100км int km = 0; // переменная для расчетов int kmeeprom = 10; // интервал, через который будет происходить подсчет среднеарифмитического расхода L100SR_TFT int kmTFT = 0; // переменная для расчетов периодического подсчета среднеарифмитического расхода топлива L100SR_TFT int kmREFUELING = 0; int kmREFUELING_last = 1; // пробег до заправки на остатке топлива unsigned long prevWatch = 0; unsigned long prevDvoet = 0; unsigned long prevData = 0; uint32_t prevGauge = 0; //----------------------------------------------для экрана #include <Adafruit_GFX.h> #include <MCUFRIEND_kbv.h> #include <UTFTGLUE.h>//use GLUE class and constructor #include "TouchScreen.h" #include <stdint.h> #include <SPI.h> #include <EEPROM.h> //MCUFRIEND_kbv tft; #include "Fonts/Chosence_Bold16pt7b.h"; #define MINPRESSURE 200 #define MAXPRESSURE 1000 //pin 20 SCL , 21 SDA датчик реального времени #include <Wire.h> #include "RTClib.h" RTC_DS3231 rtc; UTFTGLUE myGLCD(0x1581,A2,A1,A3,A4,A0); //all dummy args const int XP = 6, XM = A2, YP = A1, YM = 7; const int TS_LEFT = 136, TS_RT = 907, TS_TOP = 139, TS_BOT = 942; TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300); uint16_t ID; int x, y; char currentPage; float h; int h_last = 1; float t; int t_last = 1; bool Dvoet = 0; bool reNew = 0; #define BLACK 0x0000 #define WHITE 0xFFFF #define RED 0xF800 #define GREEN 0x07E0 void setup() { uint16_t ID = myGLCD.readID(); if (ID == 0xD3D3) ID = 0x1581; // write-only shield myGLCD.begin(ID); myGLCD.InitLCD(3); myGLCD.clrScr(); myGLCD.setFont(&Chosence_Bold16pt7b); //myGLCD.fillScreen(WHITE); //myGLCD.setTextColor(WHITE, BLACK); //myGLCD.setBackColor(BLACK); Wire.begin(); rtc.begin(); //загрузка стартовой страницы currentPage = '0'; drawHomeScreen(); //подсчет среднеарифметического усредненного расхода for (int i = 0; i < 11; i++) L100_Eeprom [i]= EEPROM.read(i); for (int i = 0; i < 11; i++) L100SR_TFT = L100SR_TFT + L100_Eeprom [i]; L100SR_TFT = (float)L100SR_TFT/110.0; if (L100SR_TFT<0) L100SR_TFT = 0; if (L100SR_TFT>99) L100SR_TFT = 99; // строка ниже используется для настройки даты и времени часов // раскомментировать, выставить времая и дату, залить в ардуино. в скетче закомментировать // обратно и залить еще раз, иначе каждый раз будет по новой выствлятся это же время и дата // (год, месяц, день, часы, минуты, секунды) //rtc.adjust(DateTime(2019, 7, 2, 10, 48, 0)); #if defined debugPCM or defined debugGAUGE Serial.begin(115200); #endif K_LINE_PCM.begin(10400); pinMode(TX_PCM, OUTPUT); } void loop() { curmillis = millis(); // снимок текущего времени if (curmillis - prevRequest > RequestPeriod && header == 0 && !flagneedGAUGE) { if (request == INIT) fastinit(); // при необходимости делаем переподключение к PCM else {sendMessagePCM(request); // отправляем на PCM текущий запрос if (request == PID) RequestPeriod = 600; if (request == DTCERASE || request == DTCREAD) RequestPeriod = 2500;} prevRequest = curmillis; } if (!flagneedGAUGE) {receivePCM ();} // приём сообщений от PCM receiveGAUGE (); // приём сообщений от щитка приборов if (header == 0) {Menu ();} if (curmillis - prevWatch > 4000) { Watch (); prevWatch = curmillis; Trip ();} //if (curmillis - prevDvoet > 500) { if (!Dvoet) {myGLCD.setTextColor(WHITE); } else {myGLCD.setTextColor(BLACK); } myGLCD.print(":", 290, 5); prevDvoet = curmillis; Dvoet=!Dvoet;} if (millis() - prevDvoet > 500) { if (!Dvoet) {myGLCD.print(":", 290, 5);} else {myGLCD.print(" ", 290, 5);} prevDvoet = millis(); Dvoet=!Dvoet;} if (curmillis - prevGauge > 30000UL) {flagneedGAUGE = 1;prevGauge = curmillis;} }// end loop void Trip () { if (flagkmAgeIGN){ FuelTrip = FuelIGN - Fuel; if (kmAge>kmAgeIGN) kmTrip = kmAge - kmAgeIGN; if (kmAge<kmAgeIGN) kmTrip = 2000 - (kmAgeIGN - kmAge); // 2000 это через сколько км у тебя суточный пробег сбрасывается на ноль, поменяй если другое число if (kmAge==kmAgeIGN) kmTrip = 0; //подсчет расхода на 100км за поездку L100M = ((float)FuelTrip*100.00)/(float)kmTrip; if (L100M<0) L100M = 0; if (L100M>99) L100M = 99; // ниже цикл считает среднеарифметический расход из еепром раз в пробег, указанный в переменной kmeeprom if (kmTrip-kmTFT>kmeeprom) {kmTFT = kmTrip; // тут считаем среднеарифметический усредненного расход из ячеек еепром for (int i = 0; i < 11; i++) L100_Eeprom [i]= EEPROM.read(i); for (int i = 0; i < 11; i++) L100SR_TFT = L100SR_TFT + L100_Eeprom [i]; L100SR_TFT = (float)L100SR_TFT/110.00; if (L100SR_TFT<0) L100SR_TFT = 0; if (L100SR_TFT>99) L100SR_TFT = 99;} // ниже цикл считает расход топлива за пробег, указанный в переменной kmL, здесь же запись в ячейки еепром if (kmTrip-km>kmL) {km=kmTrip; L100SR = ((float)(Fuel_last-Fuel)*100.00)/(float)kmL; // расход/100км - обновляется раз в 10км, меняется км в int kmL = 10; Fuel_last = Fuel; // сохранение параметров с последнего измерениея if (L100SR<0) L100SR = 0; if (L100SR>99) L100SR = 99; //расчет остатка километров в баке if (L100SR>0) kmREFUELING=((float)Fuel*100.0)/(float)L100SR; //если средний расход больше нуля, то расчитывать км в баке из него else kmREFUELING=((float)Fuel*100.00)/(float)L100SR_TFT; //если ноль или ментше то расчитывать км в баке с устредненного расхода // тут записываем L100SR последовательно в одну из 11 ячеек еепром //EEPROM.write (12,n_eeprom); // ЗДЕСЬ ВНИМАТЕЛЬНО. ЗАГРУЗИТЬ ПРОШИВКУ С ЭТОЙ СТРОКОЙ ОДИН РАЗ, ПОТОМ ЗАКОМЕНТИРОВАТЬ И ЕЩЁ РАЗ ЗАГРУЗИТЬ n_eeprom = EEPROM.read (12); // в ячейке 12 хранится № текущей ячейки для записи расхода, чтобы где остановился при выкл питания, от туда и продолжил EEPROM.write(n_eeprom, L100SR*10); n_eeprom++; if (n_eeprom>10) n_eeprom=0; EEPROM.write (12,n_eeprom); }}} void fastinit() { digitalWrite (TX_PCM, HIGH); // bus idle delay(1500); digitalWrite (TX_PCM, LOW); // first part fastinit (25 ms LOW) delay(25); digitalWrite (TX_PCM, HIGH); // second part fastinit (25 ms HIGH) delay(25); K_LINE_PCM.begin(10400); sendMessagePCM(INIT); // send start communication message } void receivePCM () { if (K_LINE_PCM.available() ){ // первый старт байт if (header == 0 && Delay){TIMER_DELAY ; MessageRx_PCM[0]=K_LINE_PCM.read(); if (MessageRx_PCM[0]!=0xFF && bitRead (MessageRx_PCM[0],7)){header = 1; RESETheader_timer = 1; prevRESETheader = curmillis; #ifdef debugPCM Serial.print (F("Receive PCM: ")); printDebugRX(MessageRx_PCM[0]); #endif } } // второй старт байт if (header == 1 && Delay){TIMER_DELAY ; MessageRx_PCM[1]=K_LINE_PCM.read(); #ifdef debugPCM printDebugRX (MessageRx_PCM[1]); #endif if (MessageRx_PCM[1]==DIAG_address){ header = 2;} else { #ifdef debugPCM Serial.println(F(" PCM Message fail address")); #endif header = 0; RESETheader_timer = 0;}} // третий старт байт if (header == 2 && Delay){ TIMER_DELAY ; MessageRx_PCM[2]=K_LINE_PCM.read(); #ifdef debugPCM printDebugRX (MessageRx_PCM[2]); #endif if (MessageRx_PCM[2]==PCM_address){ message_size = MessageRx_PCM[0]; prevRESETheader = curmillis; if (MessageRx_PCM[0] !=0x80) {header = 4; bitWrite (message_size, 7 , 0);j=3;n=3;} else {header = 3; j=4;n=4;} if (message_size > bufsize) message_size = bufsize; crc = 0;} else {header = 0; #ifdef debugPCM Serial.println(F("PCM Message fail address")); #endif RESETheader_timer = 0;} } // если размер сообщения указан в дополнительном байте (нулевой байт 0x80) читаем этот дополнительный байт: if (header == 3 && Delay){ TIMER_DELAY ; prevRESETheader = curmillis; MessageRx_PCM[3]=K_LINE_PCM.read(); #ifdef debugPCM printDebugRX(MessageRx_PCM[3]); #endif message_size = MessageRx_PCM[3]; if (message_size > bufsize) message_size = bufsize; crc = 0; header = 4; } // пишем тело сообщения if (header == 4 && Delay && j< message_size+n+1) { MessageRx_PCM[j] = K_LINE_PCM.read(); prevRESETheader = curmillis; if (j<message_size+n) crc+= MessageRx_PCM[j]; // подсчёт КС if (j==message_size+n) header = 5; TIMER_DELAY ; #ifdef debugPCM printDebugRX(MessageRx_PCM[j]); #endif j++; } } // сообщение приняли, действуем if (header == 5) {TIMER_DELAY ; #ifdef debugPCM Serial.println(); #endif NOanswer_timer = 0; noanswers = 0; // сбрасываем таймер контроля неответов for(byte i = 0; i<n; i++) crc+=MessageRx_PCM[i]; // прибавляем к контрольной сумме старт байты // если контрольная сумма верна: if ( crc == MessageRx_PCM[message_size+n]) { #ifdef debugPCM Serial.print (F("Received message is OK! Checksum is correct!")); Serial.print (F(" ")); Serial.println (millis()); // Если КС совпала, тут чёнибудь нужное делаем printDebugRX_CSgood(); #endif if (MessageRx_PCM[n]==0xC1 && MessageRx_PCM[n+1]==0x6B && MessageRx_PCM[n+2]==0x8F) { if (currentPage!=3) {request = PID; RequestPeriod = 70;} else request = PRESENT, RequestPeriod = 4000; prevRequest = curmillis; // receive good INIT } else if (MessageRx_PCM[n]==0x58) Troublecodes (); // DTC else if (MessageRx_PCM[n]==0x54 && MessageRx_PCM[n+1]==0xFF && MessageRx_PCM[n+2]==0x00){ request = PRESENT; RequestPeriod = 4000; prevRequest = curmillis;} // DTC are cleared else if (MessageRx_PCM[n]==0x61 && MessageRx_PCM[n+1]==0x01) {dataVars() ; RequestPeriod = 70; prevRequest = curmillis; } // receive DataStream } // если контрольная сумма не совпала: #ifdef debugPCM else Serial.println("CRC fail!!!" ); #endif message_size = 0; header=0; RESETheader_timer = 0; j=3; crc = 0; } // таймер ожидания байт (для успевания появления данных в буфере UART) if (!Delay && curmillis - timerdelay > waitbyte_RX) Delay = 1; // таймер сброса целостности сообщения (если данные оборвались посередине сообщения) if (RESETheader_timer && curmillis - prevRESETheader > 200) { #ifdef debugPCM Serial.println(F("Message fail timeout")); #endif RESETheader_timer = 0; header = 0;} // если нет ответа после запроса: +1 к счетчику неответов. Если накопилось 6 и более: делаем реинит. if (request!=INIT && NOanswer_timer && curmillis - prev_NOanswer > RequestPeriod - RequestPeriod/10) { NOanswer_timer = 0; noanswers++; if (noanswers>=6) { noanswers = 0; request = INIT; RequestPeriod = 3500;} } }// end receivePCM void Troublecodes () { if (MessageRx_PCM[n]==0x58 && MessageRx_PCM[n+1]==0x00){ myGLCD.clrScr(); drawscreen_three(); myGLCD.print("NO DTC", 180, 145); } // при получении сообщения о наличии ошибок DTC разберем сообщение выведем на экран ошибки if (MessageRx_PCM[n]==0x58 && MessageRx_PCM[n+1]>0){ myGLCD.clrScr(); drawscreen_three(); for (int i=0; i<MessageRx_PCM[n+8-7]; i++ ) { int y = i*35; bool nolA=0; bool nolB =0; if (!bitRead(MessageRx_PCM[n+11-7+(i*3)],6) && bitRead(MessageRx_PCM[n+11-7+(i*3)],7)){ myGLCD.setTextColor(GREEN, BLACK); myGLCD.print(" -Passive-", 300, (75+y));} // если DTC пасивныый делаем цвет зеленый if (bitRead(MessageRx_PCM[n+11-7+(i*3)],7) && bitRead(MessageRx_PCM[n+11-7+(i*3)],6)) { myGLCD.setTextColor(RED, BLACK); myGLCD.print(" -Active-", 300, (75+y));} // если DTC активный, делаем цвет красный myGLCD.print("ERROR ", 50, (75+y)); myGLCD.printNumI((i+1), 150, (75+y)); if (!bitRead(MessageRx_PCM[n+9-7+(i*3)],6) && !bitRead(MessageRx_PCM[n+9-7+(i*3)],7)) myGLCD.print(": P", 170, (75+y)); if (bitRead(MessageRx_PCM[n+9-7+(i*3)],6) && !bitRead(MessageRx_PCM[n+9-7+(i*3)],7)) myGLCD.print(": C", 170, (75+y)); if (!bitRead(MessageRx_PCM[n+9-7+(i*3)],6) && bitRead(MessageRx_PCM[n+9-7+(i*3)],7)) myGLCD.print(": B", 170, (75+y)); if (bitRead(MessageRx_PCM[n+9-7+(i*3)],6) && bitRead(MessageRx_PCM[n+9-7+(i*3)],7)) myGLCD.print(": U", 170, (75+y)); if (MessageRx_PCM[n+9-7+(i*3)]==0x00) {myGLCD.print("00", 230, (75+y)); nolA = 1;} if (MessageRx_PCM[n+9-7+(i*3)]<=0x0F&&MessageRx_PCM[n+9-7+(i*3)]!=0) {myGLCD.print("0", 230, (75+y)); nolA = 1;} if (nolA)myGLCD.print(String (MessageRx_PCM[n+9-7+(i*3)],HEX), 246, (75+y)); else myGLCD.print(String (MessageRx_PCM[n+9-7+(i*3)],HEX), 230, (75+y)); if (MessageRx_PCM[n+10-7+(i*3)]==0x00) {myGLCD.print("00", 262, (75+y)); nolB = 1;} if (MessageRx_PCM[n+10-7+(i*3)]<=0x0F&&MessageRx_PCM[n+10-7+(i*3)]!=0) {myGLCD.print("0", 262, (75+y)); nolB = 1;} if (nolB)myGLCD.print(String (MessageRx_PCM[n+10-7+(i*3)]),HEX, 278, (75+y)); else myGLCD.print(String (MessageRx_PCM[n+10-7+(i*3)],HEX), 262, (75+y));}} request = PRESENT; RequestPeriod = 4000; prevRequest = curmillis; } void dataVars() { //Barom = MessageRx_PCM[39]; L100 = (float)LHor*100.0/(float)Speed; LHor = (float)RPM* (float)InjQua*2.00/1000.0*60.00/1000.0/0.85; MAF = ((MessageRx_PCM[n+22]*256)+MessageRx_PCM[n+23])/10; BoostPres = ((MessageRx_PCM[n+24]*256)+MessageRx_PCM[n+25])/1000.0; RPM = (MessageRx_PCM[n+35-7]*256)+MessageRx_PCM[n+36-7]; EGRmg = ((MessageRx_PCM[n+37-7]*256)+MessageRx_PCM[n+38-7])/10.0; BoostPresCom = ((MessageRx_PCM[n+41-7]*256)+MessageRx_PCM[n+42-7])/1000.0; Speed = ((MessageRx_PCM[n+47-7]*256)+MessageRx_PCM[n+48-7])/100; DesaInjQua = ((MessageRx_PCM[n+53-7]*256)+MessageRx_PCM[n+54-7])/100.0; InjQua = ((MessageRx_PCM[n+55-7]*256)+MessageRx_PCM[n+56-7])/100.0; StaDaliv = ((MessageRx_PCM[n+57-7]*256)+MessageRx_PCM[n+58-7])/100.0; PumpRPM = (MessageRx_PCM[n+59-7]*256)+MessageRx_PCM[n+60-7]; EGRPul = ((MessageRx_PCM[n+65-7]*256)+MessageRx_PCM[n+66-7])/100.0; SolenPul = ((MessageRx_PCM[n+67-7]*256)+MessageRx_PCM[n+68-7])/100.0; SolenPre = ((MessageRx_PCM[n+73-7]*256)+MessageRx_PCM[n+74-7])/100.0; DesInj = ((MessageRx_PCM[n+75-7]*3)+(MessageRx_PCM[n+76-7])/100.0)+0.3; ActInj = ((MessageRx_PCM[n+19-7]*3)+(MessageRx_PCM[n+20-7])/100.0)+0.3; //TempAir = ((MessageRx_PCM[n+77-7]*26)-278)+MessageRx_PCM[n+78-7]/10.0; //Temp = ((MessageRx_PCM[n+17-7]*26)-278)+MessageRx_PCM[n+18-7]/10.0; //TempOil = ((MessageRx_PCM[n+21-7]*26)-278)+MessageRx_PCM[n+22-7]/10.0; //TempFuel = ((MessageRx_PCM[n+61-7]*26)-278)+MessageRx_PCM[n+62-7]/10.0; //ниже идут расчетные формулы более точные чем те что закоментированы выше int A = 0; if (MessageRx_PCM[n+77-7]<=0x0A) A = 277; if (MessageRx_PCM[n+77-7]==0x0B || MessageRx_PCM[n+77-7]==0x0C) A = 278; if (MessageRx_PCM[n+77-7]>=0x0D) A = 279; double B = MessageRx_PCM[n+78-7]/10.0; double cel , drob ; drob = modf(B, &cel); if (drob>0.6) cel++; TempAir = ((MessageRx_PCM[n+77-7]*26)-A)+cel; if (MessageRx_PCM[n+17-7]<=0x0A) A = 277; if (MessageRx_PCM[n+17-7]==0x0B || MessageRx_PCM[n+17-7]==0x0C) A = 278; if (MessageRx_PCM[n+17-7]>=0x0D) A = 279; B = MessageRx_PCM[n+18-7]/10.0; drob = modf(B, &cel); if (drob>0.6) cel++; Temp = ((MessageRx_PCM[n+17-7]*26)-A)+cel; if (MessageRx_PCM[n+21-7]<=0x0A) A = 277; if (MessageRx_PCM[n+21-7]==0x0B || MessageRx_PCM[n+21-7]==0x0C) A = 278; if (MessageRx_PCM[n+21-7]>=0x0D) A = 279; B = MessageRx_PCM[n+22-7]/10.0; drob = modf(B, &cel); if (drob>0.6) cel++; TempOil = ((MessageRx_PCM[n+21-7]*26)-A)+cel; if (MessageRx_PCM[n+61-7]<=0x0A) A = 277; if (MessageRx_PCM[n+61-7]==0x0B || MessageRx_PCM[n+61-7]==0x0C) A = 278; if (MessageRx_PCM[n+61-7]>=0x0D) A = 279; B = MessageRx_PCM[n+62-7]/10.0; drob = modf(B, &cel); if (drob>0.6) cel++; TempFuel = ((MessageRx_PCM[n+61-7]*26)-A)+cel; //---------------------------------------------------------- //страниц HOME //---------------------------------------------------------- //myGLCD.setBackColor(RED); myGLCD.setTextColor(WHITE, BLACK); //myGLCD.setBackColor(RED); if ((Speed != Speed_last) || reNew) {myGLCD.printNumI(Speed, 360, 7, 3); Speed_last=Speed;} if (currentPage == '0') { if ((LHor != LHor_last) || reNew) {myGLCD.printNumF(LHor, 1, 75, 40, '.',4); LHor_last=LHor;} if ((L100 != L100_last) || reNew) {myGLCD.printNumF(L100, 1, 225, 40,'.',4 ); L100_last=L100;} if ((L100M != L100M_last) || reNew) {myGLCD.printNumF(L100M, 1, 75, 75,'.',4 ); L100M_last=L100M;} if ((L100SR_TFT != L100SR_TFT_last) || reNew) {myGLCD.printNumF(L100SR_TFT, 1, 225, 75,'.',4 ); L100SR_TFT_last=L100SR_TFT;} if ((kmREFUELING != kmREFUELING_last) || reNew) {myGLCD.printNumI(kmREFUELING, 90, 110,3 ); kmREFUELING_last=kmREFUELING;} //if (Fuel<53) if ((Fuel != Fuel_last) || reNew) {myGLCD.printNumF(Fuel, 1, 225, 110,'.',4); Fuel_last=Fuel;} //else myGLCD.print("MAX", 210, 110); if ((kmTrip != kmTrip_last) || reNew) {myGLCD.printNumF(kmTrip, 1, 60, 145,'.',5); kmTrip_last=kmTrip;} if ((FuelTrip != FuelTrip_last) || reNew) {myGLCD.printNumF(FuelTrip, 1, 210, 145,'.',5); FuelTrip_last=FuelTrip;} if ((PumpRPM != PumpRPM_last) || reNew) {myGLCD.printNumI(PumpRPM, 230, 180,4); PumpRPM_last=PumpRPM;} if ((RPM != RPM_last) || reNew) {myGLCD.printNumI(RPM, 230, 215,4); RPM_last=RPM;} if ((Fuel2 != Fuel2_last) || reNew) {myGLCD.printNumF(Fuel2, 1, 10, 215,'.',4); Fuel2_last=Fuel2;} if ((Temp != Temp_last) || reNew) {myGLCD.printNumI(Temp, 415, 40, 3); Temp_last=Temp;} if ((TempOil != TempOil_last) || reNew) {myGLCD.printNumI(TempOil, 415, 75, 3); TempOil_last=TempOil;} if ((TempFuel != TempFuel_last) || reNew) {myGLCD.printNumI(TempFuel, 415, 110,3); TempFuel_last=TempFuel;} //myGLCD.printNumI(sensors.getTempCByIndex(0), 415, 145 , 3); if ((t != t_last) || reNew) {myGLCD.printNumI(t, 415, 180, 3); t_last=t;} if ((TempAir != TempAir_last) || reNew) {myGLCD.printNumI(TempAir, 415, 215, 3); TempAir_last=TempAir;} reNew = 0; } //---------------------------------------------------------- //страниц INF1 //---------------------------------------------------------- if (currentPage == '1') { if ((StaDaliv != StaDaliv_last) || reNew) {myGLCD.printNumF(StaDaliv,1, 385, 40,'.', 4); StaDaliv_last=StaDaliv;} if ((DesInj != DesInj_last) || reNew) {myGLCD.printNumF(DesInj,1, 385, 75, '.', 4); DesInj_last=DesInj;} if ((ActInj != ActInj_last) || reNew) {myGLCD.printNumF(ActInj,1, 385, 110,'.', 4); ActInj_last=ActInj;} if ((DesaInjQua != DesaInjQua_last) || reNew) {myGLCD.printNumF(DesaInjQua,1, 385, 145,'.', 4);DesaInjQua_last=DesaInjQua;} if ((InjQua != InjQua_last) || reNew) {myGLCD.printNumF(InjQua,1, 385, 180,'.', 4); InjQua_last=InjQua;} if ((MAF != MAF_last) || reNew) {myGLCD.printNumI(MAF, 170, 215, 4); MAF_last=MAF;} if ((h != h_last) || reNew) {myGLCD.printNumF(h, 1, 430, 215, 3); h_last=h;} reNew = 0; } //---------------------------------------------------------- //страниц INF2 //---------------------------------------------------------- if (currentPage == '2') { if ((BoostPres != BoostPres_last) || reNew) {myGLCD.printNumF(BoostPres,1, 400, 40,'.', 4); BoostPres_last=BoostPres;} if ((BoostPresCom != BoostPresCom_last) || reNew) {myGLCD.printNumF(BoostPresCom,1, 400, 75,'.', 4); BoostPresCom_last=BoostPresCom;} if ((EGRmg != EGRmg_last) || reNew) {myGLCD.printNumI(EGRmg, 400, 110, 4); EGRmg_last=EGRmg;} if ((EGRPul != EGRPul_last) || reNew) {myGLCD.printNumF(EGRPul,1, 400, 145,'.', 4); EGRPul_last=EGRPul;} if ((SolenPul != SolenPul_last) || reNew) {myGLCD.printNumF(SolenPul, 1, 400, 180,'.', 4); SolenPul_last=SolenPul;} if ((SolenPre != SolenPre_last) || reNew) {myGLCD.printNumF(SolenPre, 0, 400, 215,'.', 4); SolenPre_last=SolenPre;} reNew = 0; } //reNew = 0; } void sendMessagePCM(const byte &command) { #ifdef debugPCM Serial.print (F("Send request ")); Serial.print (textRequest[command]); Serial.print (F(" to PCM ")); Serial.println (millis()); #endif if (command != INIT) {NOanswer_timer = 1; prev_NOanswer = curmillis;} //т.к. сейчас будем делать запрос, то запускаем таймер контроля неответов byte size = PCM_Message_TX[command][0]; const byte siZe = size+4; byte Mes[siZe]; byte Checksum = 0; for(byte i=0; i<siZe; i++) { if (i==0) {Mes[i]=size; bitWrite(Mes[i], 7 , 1);} if (i==1) Mes[i] = PCM_address; if (i==2) Mes[i] = DIAG_address; if (i==3) {for (byte t=1; t<size+1; t++ ) { Mes[i]=PCM_Message_TX [command][t]; Checksum+=Mes[i] ; K_LINE_PCM.write (Mes[i]); if (command == INIT) delay (5); else delay (delaybyte_TX); K_LINE_PCM.read(); i++;}} if (i!=siZe-1) Checksum+=Mes[i]; else Mes[i] = Checksum; K_LINE_PCM.write (Mes[i]); if (command == INIT) delay (5); else delay (delaybyte_TX); K_LINE_PCM.read(); } }// end sendMessagePCM void receiveGAUGE () { while(InitGauge==1){ if (K_LINE_GAUGE.available()) { byte inByte = K_LINE_GAUGE.read(); #ifdef debugGAUGE Serial.print(" "); Serial.print(inByte,HEX); #endif if (inByte==0x80) {K_LINE_GAUGE.write (0x7F); delay (1);} if (inByte==0xF0) { for (byte i=0; i<sizeof(PIDgauge); i++) { K_LINE_GAUGE.write (PIDgauge[i]); delay (1);} InitGauge=2; NoconnectsGAUGE = 0;}}} bool MessageParse = 0; bool dataMessageEND = 0; bool dataMessageOK = 0; byte headerGAUGE = 0; byte numberbyte = 0; while (InitGauge==2 && !MessageParse && flagneedGAUGE) { if (!dataMessageOK) { if (K_LINE_GAUGE.read() == 0x23 && headerGAUGE ==0) {headerGAUGE=1; delay (waitbyte_gauge); } if (K_LINE_GAUGE.read() == 0xA1 && headerGAUGE ==1) {headerGAUGE=2; delay (waitbyte_gauge);} else {headerGAUGE =0;} if (K_LINE_GAUGE.read() == 0x04 && headerGAUGE ==2) {headerGAUGE=3; delay (waitbyte_gauge);} else {headerGAUGE =0;} if (headerGAUGE ==3) {dataMessageOK = 1; headerGAUGE =0;} numberbyte=0;} else { if (K_LINE_GAUGE.available()>0) { MessageRxGauge[numberbyte] = K_LINE_GAUGE.read(); numberbyte++; delayMicroseconds (250);} if (numberbyte==34) {dataMessageEND = 1; dataMessageOK = 0; }} if (dataMessageEND) { int crc = ( ( unsigned int )MessageRxGauge[32] << 8 ) | MessageRxGauge[33]; // парсинг контрольной суммы из 2 последних байт int CRC =200; for (int i = 0; i < 32; i++) CRC = CRC + MessageRxGauge[i]; // подсчет контрольной суммы байт от 0 до 31 #ifdef debugGAUGE Serial.print (" ReceiveGauge: "); for (int i = 0; i < 34; i++) { Serial.print(MessageRxGauge[i],HEX); Serial.print (" ");} #endif //при получении сообщения БЕЗ ошибок с данными от панели приборов, запишем в переменные остаток топлива и пробег if (CRC==crc) { #ifdef debugGAUGE Serial.println (" OK!!!"); #endif flagneedGAUGE = 0; Fuel2 = MessageRxGauge[16]/2.0; if (!flagFuelIGN) { Fuel = MessageRxGauge[16]/2.00; kmREFUELING=((float)Fuel*100.00)/(float)L100SR_TFT;} //стартовая запись литров в баке для подсчета затраченных литро else Fuel = MessageRxGauge[17]/2.0; //для устреднения болтания в баке закоментировать эту строку, а раскоментировать ниже //для усреднения болтания топлива в баке, раскоментировать, высчитывает среднее /*else { FuelZamer[ZamerNumber] = MessageRxGauge[17]/2.00; if (ZamerNumber==9) { Fuel = 0 ; for (int i = 0; i < 10; i++) Fuel = Fuel + FuelZamer[i]; Fuel = (float)Fuel/10.0;} ZamerNumber++; if (ZamerNumber>9) ZamerNumber = 0;} */ kmAge = (MessageRxGauge[23]+(MessageRxGauge[24]*256))/10.0; //суточный пробег с панели приборов //бак у меня на 59 литров, а датчик показывает максимально 53 литра. для этого эта формула //если у вас тоже датчик имеет лимит то подправте 53 на свой лимит. //если ваш датчик показывает одинаково с полным баком то закоментировать три нижние строки. if (Fuel<53){ if (!flagkmAgeIGN) { kmAgeIGN = kmAge; flagkmAgeIGN =1;} if (!flagFuelIGN) { FuelIGN = Fuel; Fuel_last = Fuel; flagFuelIGN = 1; }}} #ifdef debugGAUGE else Serial.println (" ERROR!!!"); #endif dataMessageEND = 0; MessageParse = 1; NoconnectsGAUGE = 0;}} // if (curmillis - prevNoconnect > 500) {NoconnectsGAUGE ++ ; if (NoconnectsGAUGE>=10){ // #ifdef debugGAUGE // Serial.println (F(" Connect GAUGE failed!!! ")) ; // #endif // NoconnectsGAUGE = 0 ;InitGauge = 0 ; } prevNoconnect = curmillis; } InitBusGAUGE (); }// end receiveGAUGE void InitBusGAUGE () { if (InitGauge == 0){ #ifdef debugGAUGE Serial.println ("Send startsession - address Gauge"); #endif K_LINE_GAUGE.end(); pinMode(TX_gauge, OUTPUT); digitalWrite (TX_gauge, HIGH); // BUS IDLE InitGauge = 5; prevInitbusGauge = curmillis; } if (InitGauge == 5 && curmillis - prevInitbusGauge>1500) {InitGauge = 6;} // BUS IDLE if (InitGauge == 6) { byte boudrate = 1000/BAUD; digitalWrite (TX_gauge, LOW); delay (boudrate); // старт бит for (byte i=0; i<8; i++){digitalWrite (TX_gauge, bitRead(addressGUAGE, i)); delay (boudrate);} // биты тела адреса digitalWrite (TX_gauge, HIGH); delay (boudrate); // стоп бит K_LINE_GAUGE.begin(9600); InitGauge = 1; } } #if defined debugPCM or defined debugGAUGE void printDebugRX (const byte &inbyte) {if (inbyte<=15) Serial.print(F("0")); Serial.print (inbyte, HEX); Serial.print (F(" "));} #endif #ifdef debugPCM void printDebugRX_CSgood(){ if (MessageRx_PCM[n]==0xC1 && MessageRx_PCM[n+1]==0x6B && MessageRx_PCM[n+2]==0x8F) {Serial.println (F(" Initialization OK!!!!")); } else if (MessageRx_PCM[n]==0x58 && MessageRx_PCM[n+1]==0x00) {Serial.println (F(" NO DTC "));} else if (MessageRx_PCM[n]==0x58 && MessageRx_PCM[n+1] >0x00) {Serial.println (F(" DTC is found!"));} else if (MessageRx_PCM[n]==0x54 && MessageRx_PCM[n+1]==0xFF && MessageRx_PCM[n+2]==0x00){Serial.println (F(" DTC CLEARED "));} else if (MessageRx_PCM[n]==0x61 && MessageRx_PCM[n+1]==0x01) {Serial.println (F(" Receive PCM DATAstream"));}} #endif void Menu () { TouchHOME(); if (currentPage == '0') { TouchINF1(); TouchINF2(); TouchCHECK(); } if (currentPage == '1') { TouchINF2(); TouchCHECK(); } if (currentPage == '2') { TouchINF1(); TouchCHECK(); } if (currentPage == '3') { TouchREAD(); TouchERASE(); }} void drawHomeScreen() { line() ; Watch (); //myGLCD.print(":", 290, 5); myGLCD.print("/", 115, 7); myGLCD.print("/", 160, 7); myGLCD.setTextColor(RED, BLACK); // цвет линии и текста красный myGLCD.drawLine(295,35,295,248); // линия вертикальная myGLCD.drawLine(145,35,145,178); // линия вертикальная myGLCD.drawLine(80,178,80,247); // линия вертикальная myGLCD.print("L/H", 10, 40); myGLCD.print("L/A", 148, 40); myGLCD.print("L/V", 10, 75); myGLCD.print("L/M", 148, 75); myGLCD.print("D/K", 10, 110); myGLCD.print("D/L", 148, 110); myGLCD.print("V/K", 10, 145); myGLCD.print("V/L", 148, 145); myGLCD.print("PUMP RPM", 82, 180); myGLCD.print("ENGI RPM", 82, 215); myGLCD.print("D/L/A", 10, 180); myGLCD.print("Motor C", 300, 40); myGLCD.print("OIL C", 300, 75); myGLCD.print("FUEL C", 300, 110); myGLCD.print("INTER C", 300, 145); myGLCD.print("EXTER C", 300, 180); myGLCD.print("INTAIR C", 300, 215); //myGLCD.setTextColor(RED); myGLCD.drawRoundRect (15, 255, 145, 310); myGLCD.print("INF 1", 55, 270); myGLCD.drawRoundRect (175, 255, 305, 310); myGLCD.print("INF 2", 215, 270); myGLCD.drawRoundRect (335, 255, 465, 310); myGLCD.print("CHECK", 365, 270); myGLCD.drawRoundRect (1, 1, 77, 37); myGLCD.print("HOME", 10, 7); myGLCD.print("Km/h", 410, 7); reNew = 1; } //------------------------------------------------- void drawscreen_one() { line() ; Watch (); //myGLCD.print(":", 290, 5); myGLCD.print("/", 115, 7); myGLCD.print("/", 160, 7); myGLCD.setTextColor(RED, BLACK); // цвет линии и текста красный myGLCD.print("Start of Delivery *CA:", 10, 40); myGLCD.print("Desir inject Start *CA:", 10, 75); myGLCD.print("Actua Inject Start *CA:", 10, 110); myGLCD.print("Desir Inject Quan mg/s:", 10, 145); myGLCD.print("Actu Inject Quant mg/s:", 10, 180); myGLCD.print("MAF mg/s:", 10, 215); myGLCD.print("Humedad %:", 255, 215); //myGLCD.setTextColor(RED); myGLCD.drawRoundRect (175, 255, 305, 310); myGLCD.print("INF 2", 215, 270); myGLCD.drawRoundRect (335, 255, 465, 310); myGLCD.print("CHECK", 365, 270); myGLCD.drawRoundRect (1, 1, 77, 37); myGLCD.print("HOME", 10, 7); myGLCD.print("Km/h", 410, 7); reNew = 1; } //------------------------------------------------- void drawscreen_two() { line() ; Watch (); //myGLCD.print(":", 290, 5); myGLCD.print("/", 115, 7); myGLCD.print("/", 160, 7); myGLCD.setTextColor(RED, BLACK); // цвет линии и текста красный myGLCD.print("Boost Press Bar:", 10, 40); myGLCD.print("Boost Press Com Bar:", 10, 75); myGLCD.print("EGR command mg/s:", 10, 110); myGLCD.print("EGR Pulse Ratio %:", 10, 145); myGLCD.print("Solenoide Pulse %:", 10, 180); myGLCD.print("Solenoide Boost %:", 10, 215); //myGLCD.setColor(RED); myGLCD.drawRoundRect (15, 255, 145, 310); myGLCD.print("INF 1", 55, 270); myGLCD.drawRoundRect (335, 255, 465, 310); myGLCD.print("CHECK", 365, 270); myGLCD.drawRoundRect (1, 1, 77, 37); myGLCD.print("HOME", 10, 7); myGLCD.print("Km/h", 410, 7); reNew = 1; } //---------------------------------------------------------------------------- void drawscreen_three() { Watch (); //myGLCD.print(":", 290, 5); myGLCD.print("/", 115, 7); myGLCD.print("/", 160, 7); myGLCD.setTextColor(RED, BLACK); // цвет линии красный myGLCD.drawLine(1,35,479,35); // линия горизонтальная myGLCD.drawLine(1,248,479,248); // линия горизонтальная //myGLCD.setTextColor(RED); myGLCD.drawRoundRect (15, 255, 145, 310); myGLCD.print("ERASE", 55, 270); myGLCD.drawRoundRect (335, 255, 465, 310); myGLCD.print("READ", 365, 270); myGLCD.drawRoundRect (1, 1, 77, 37); myGLCD.print("HOME", 10, 5); reNew = 1; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //кнопки тач . координаты и переходы ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void TouchHOME(){ TSPoint p = ts.getPoint(); pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); if (p.z > 10 && p.z < 1000) {if (p.x > 140 && p.x < 320 && p.y > 140 && p.y < 260 && p.z > MINPRESSURE && p.z < MAXPRESSURE) { myGLCD.drawRoundRect (1, 1, 77, 37); currentPage = '0'; request = PID; RequestPeriod = 10; prevRequest = curmillis; // на PCM в этом окне посылается запрос текущих параметров myGLCD.clrScr(); drawHomeScreen(); x = 0; y = 0; p.z = 0;}}} void TouchINF1(){ TSPoint p = ts.getPoint(); pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); if (p.z > 10 && p.z < 1000) { if (p.x > 150 && p.x < 450 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE) { myGLCD.drawRoundRect (15, 255, 145, 310); currentPage = '1'; request = PID; RequestPeriod = 10; prevRequest = curmillis; // на PCM в этом окне посылается запрос текущих параметров myGLCD.clrScr(); drawscreen_one(); x = 0; y = 0; p.z = 0;}}} void TouchINF2(){ TSPoint p = ts.getPoint(); pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); if (p.z > 10 && p.z < 1000) { if (p.x > 450 && p.x < 680 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE) { myGLCD.drawRoundRect (175, 255, 305, 310); currentPage = '2'; request = PID; RequestPeriod = 600; prevRequest = curmillis; // на PCM в этом окне посылается запрос текущих параметров myGLCD.clrScr(); drawscreen_two(); x = 0; y = 0; p.z = 0;}}} void TouchCHECK(){ TSPoint p = ts.getPoint(); pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); if (p.z > 10 && p.z < 1000) { if (p.x > 690 && p.x < 950 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE) { myGLCD.drawRoundRect (335, 255, 465, 310); currentPage = '3'; // request = DTCREAD; RequestPeriod = 10; prevRequest = curmillis; // на PCM в этом окне посылается запрос чтения ошибок myGLCD.clrScr(); drawscreen_three(); x = 0; y = 0; p.z = 0;}}} void TouchREAD(){ TSPoint p = ts.getPoint(); pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); if (p.z > 10 && p.z < 1000) { if (p.x > 690 && p.x < 950 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE) { myGLCD.drawRoundRect (335, 255, 465, 310); request = DTCREAD; RequestPeriod = 300; prevRequest = curmillis; // на PCM при нажатии этой кнопки посылается запрос чтения ошибок x = 0; y = 0; p.z = 0;}}} void TouchERASE(){ TSPoint p = ts.getPoint(); pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); if (p.z > 10 && p.z < 1000) { if (p.x > 150 && p.x < 450 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE) {myGLCD.drawRoundRect (15, 255, 145, 310); request = DTCERASE; RequestPeriod = 300; prevRequest = curmillis; // на PCM при нажатии этой кнопки посылается запрос удаления ошибок myGLCD.clrScr(); drawscreen_three(); myGLCD.print("DTC BORRADO", 180, 145); x = 0; y = 0; p.z = 0;}}} //////////////////////////////////////////////////////////////////////////////////////// //прорисовка линий /////////////////////////////////////////////////////////////////////////////////////// void line() { //myGLCD.setTextColor(RED); // цвет линии красный myGLCD.drawLine(1,35,479,35); // линия горизонтальная myGLCD.drawLine(1,73,479,73); // линия горизонтальная myGLCD.drawLine(1,108,479,108); // линия горизонтальная myGLCD.drawLine(1,143,479,143); // линия горизонтальная myGLCD.drawLine(1,178,479,178); // линия горизонтальная myGLCD.drawLine(1,212,479,212); // линия горизонтальная myGLCD.drawLine(1,248,479,248); // линия горизонтальная } void Watch (){ DateTime now = rtc.now(); int minut = now.minute(); int hour = now.hour(); int mon = now.month(); int date = now.day(); int Year = now.year(); static int minut_last; static int hour_last; static int mon_last; static int date_last; static int Year_last; myGLCD.setTextColor(WHITE, BLACK); //белый цвет цифры if (date != date_last || reNew){ myGLCD.printNumI(date, 85, 7, 2, '0'); date_last = date; } if (mon!=mon_last || reNew){myGLCD.printNumI(mon, 130, 7, 2, '0'); mon_last = mon; } if (Year!=Year_last || reNew) { myGLCD.printNumI(Year, 175, 7); Year_last = Year; } if (hour!=hour_last || reNew){ myGLCD.printNumI(hour, 255, 7, 2, '0'); hour_last = hour; } if (minut!=minut_last || reNew ){ myGLCD.printNumI(minut, 300, 7, 2, '0'); minut_last = minut; } }Send startsession - address Gauge 55 52 80 7F 2D A0 48 54 20 32 34 34 31 39 35 36 30 20 31 34 30 30 20 34 31 39 39 20 31 33 30 31 20 30 34 32 20 31 20 30 30 30 30 30 30 30 30 30 30 8 F0 ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 52 50 4F 19 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F7 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 BA 0 FF 52 50 4F 19 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F9 OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 BA 0 FF 52 50 4F 19 47 0 0 0 0 0 0 0 0 0 4 10 BE 0 FF ERROR!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 BD 0 FF 52 50 4F 19 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 FC OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 BC 0 FF 53 50 4F 19 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 FC OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 BC 0 FF 53 50 4F 19 47 0 0 0 23 A1 4 0 0 0 0 0 0 0 0 ERROR!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 BB 0 FF 52 50 4F 19 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 FA OK!!! ReceiveGauge: 0 0 0 0 0 0 0 0 0 0 4 10 BA 0 FF 52 50 4F 19 47 0 0 0 95 7 CD 8C 4 13 7 0 0 5 F9 OK!!!вроде заработало. и данные вроде корекны, 40 литров показывает как в баке и есть. машина была заведенная, были данные, не глуша я подключил к компу чтобы заглянуть в терминал, бортовик перезагрузился и данные уже не появились и в терменале тишина. сново выключить и включить зажигание, есть данные. debugPCM не работает, хотел туда тоже заглянуть
Строка 225 можешь 60000 поставить (обновление топлива раз в минуту) ну или даже больше. Потому как в этот момент данные кратковременно на бортовике не обновляются, по идее должны замерзать цифры не на долго
Хотя вообще то км должны чаще обновляться. Оставь полминуты
А че debug pcm не работает не понятно
неа. ща еще раз проверю. все норм работает
Send request INIT to PCM 12758 Receive PCM: 83 F1 11 C1 6B 8F 40 Received message is OK! Checksum is correct! 12857 Initialization OK!!!! Send request PID_2101 to PCM 12929 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CD 00 00 02 4E 00 00 00 00 04 37 00 00 00 00 32 C8 03 A4 04 29 03 3F E5 62 00 00 00 00 0B 11 00 00 00 00 09 35 00 00 0B F1 A0 00 01 90 00 00 A5 08 01 21 00 00 01 B9 0B DB 03 A3 00 02 Message fail timeout Send request PID_2101 to PCM 13816 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CD 00 00 02 4E 00 00 00 00 04 3E 00 00 00 00 32 C8 03 A4 04 29 03 3E E5 62 00 00 00 00 0B 13 00 00 00 00 09 35 00 00 0B F1 A0 00 01 90 00 00 A5 08 01 21 00 00 01 B9 0B DC 03 A3 00 02 9B Received message is OK! Checksum is correct! 14027 Receive PCM DATAstream Send request PID_2101 to PCM 17220 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CD 00 00 02 4F 00 00 00 00 04 3A 00 00 00 00 32 C8 03 A3 04 29 03 3E E5 62 00 00 00 00 0B 11 00 00 00 00 09 35 00 00 0B F1 A0 00 01 90 00 00 A1 08 01 21 00 00 01 B9 0B DE 03 A3 00 02 93 Received message is OK! Checksum is correct! 17436 Receive PCM DATAstream Send request PID_2101 to PCM 17652 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CD 00 00 02 4F 00 00 00 00 04 3A 00 00 00 00 32 C8 03 A3 04 29 03 3F E5 62 00 00 00 00 0B 55 00 00 00 00 09 35 00 00 0B F1 A0 00 01 90 00 00 A5 08 01 21 00 00 01 B9 0B DC 03 A3 00 02 DA Received message is OK! Checksum is correct! 17918 Receive PCM DATAstream Send request PID_2101 to PCM 18135 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CE 00 00 02 4F 00 00 00 00 04 3A 00 00 00 00 32 C8 03 A3 04 29 03 3E E5 62 00 00 00 00 0B 14 00 00 00 00 09 35 00 00 0B F1 A0 00 01 90 00 00 A1 08 01 21 00 00 01 B9 0B DE 03 A4 00 02 98 Received message is OK! Checksum is correct! 18428 Receive PCM DATAstream Send request PID_2101 to PCM 18803 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CD 00 00 02 58 00 00 00 00 04 3E 00 00 00 00 32 C8 03 A3 04 29 03 3E E5 62 00 00 00 00 0B 16 00 00 00 00 09 35 00 00 0B F1 A0 00 01 90 00 00 A9 08 01 20 00 00 01 B9 0B DE 03 A3 00 02 AC Received message is OK! Checksum is correct! 19044 Receive PCM DATAstream Send request PID_2101 to PCM 19469 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CD 00 00 02 5B 00 00 00 00 04 3C 00 00 00 00 32 C8 03 A4 04 29 03 3E E5 62 00 00 00 00 0B 16 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 AD 08 01 20 00 00 01 BA 0B DC 03 A3 00 02 B4 Received message is OK! Checksum is correct! 19674 Receive PCM DATAstream Send request PID_2101 to PCM 19890 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CD 00 00 02 5B 00 00 00 00 04 3A 00 00 00 00 32 C8 03 A3 04 29 03 3E E5 62 00 00 00 00 0B 16 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 AD 08 01 20 00 00 01 BA 0B DE 03 A3 00 02 B3 Received message is OK! Checksum is correct! 20147 Receive PCM DATAstream Send request PID_2101 to PCM 20363 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CB 00 00 02 5C 00 00 00 00 04 3E 00 00 00 00 32 C8 03 A4 04 29 03 3E E5 62 00 00 00 00 0B 16 00 00 00 00 09 35 00 00 0B F1 A0 00 01 90 00 00 AD 08 01 20 00 00 01 B9 0B DE 03 A3 00 02 B3 Received message is OK! Checksum is correct! 20653 Receive PCM DATAstream Send request PID_2101 to PCM 20869 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CD 00 00 02 5C 00 00 00 00 04 37 00 00 00 00 32 C8 03 A4 04 29 03 3E E5 62 00 00 00 00 0B 16 00 00 00 00 09 35 00 00 0B F1 A0 00 01 90 00 00 A9 08 01 20 00 00 01 B9 0B DE 03 A4 00 02 AB Received message is OK! Checksum is correct! 21075 Receive PCM DATAstream Send request PID_2101 to PCM 21315 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CD 00 00 02 5C 00 00 00 00 04 3F 00 00 00 00 32 C8 03 A4 04 29 03 3F E5 62 00 00 00 00 0B 16 00 00 00 00 09 35 00 00 0B F1 A0 00 01 90 00 00 A9 08 01 20 00 00 01 B9 0B DE 03 A3 00 02 B3 Received message is OK! Checksum is correct! 21528 Receive PCM DATAstream Send request PID_2101 to PCM 21744 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CD 00 00 02 5D 00 00 00 00 04 3A 00 00 00 00 32 C8 03 A4 04 29 03 3E E5 62 00 00 00 00 0B 16 00 00 00 00 09 35 00 00 0B F1 A0 00 01 90 00 00 A9 08 01 20 00 00 01 B9 0B DE 03 A4 00 02 AF Received message is OK! Checksum is correct! 22044 Receive PCM DATAstream Send request PID_2101 to PCM 22260 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CD 00 00 02 5D 00 00 00 00 04 3E 00 00 00 00 32 C8 03 A3 04 29 03 3E E5 62 00 00 00 00 0B 18 00 00 00 00 09 35 00 00 0B F1 A0 00 01 90 00 00 A9 08 01 20 00 00 01 B9 0B DE 03 A3 00 02 B3 Received message is OK! Checksum is correct! 22516 Receive PCM DATAstream Send request PID_2101 to PCM 22732 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CD 00 00 02 5E 00 00 00 00 04 3A 00 00 00 00 32 C8 03 A4 04 29 03 3E E5 62 00 00 00 00 0B 16 00 00 00 00 09 35 00 00 0B F1 A0 00 01 90 00 00 A9 08 01 20 00 00 01 B9 0B DE 03 A3 00 02 AF Received message is OK! Checksum is correct! 22936 Receive PCM DATAstream Send request PID_2101 to PCM 23198 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CD 00 00 02 5E 00 00 00 00 04 3A 00 00 00 00 32 C8 03 A3 04 29 03 3E E5 62 00 00 00 00 0B 18 00 00 00 00 09 35 00 00 0B F1 A0 00 01 90 00 00 A9 08 01 20 00 00 01 B9 0B DE 03 A3 00 02 B0 Received message is OK! Checksum is correct! 23408 Receive PCM DATAstream Send request PID_2101 to PCM 23624 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CB 00 00 02 5E 00 00 00 00 04 3E 00 00 00 00 32 C8 03 A3 04 29 03 3E E5 62 00 00 00 00 0B 18 00 00 00 00 09 35 00 00 0B F1 A0 00 01 90 00 00 A9 08 01 20 00 00 01 B9 0B DC 03 A3 00 02 B0 Received message is OK! Checksum is correct! 23881 Receive PCM DATAstream Send request PID_2101 to PCM 24097 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CD 00 00 02 5E 00 00 00 00 04 3A 00 00 00 00 32 C8 03 A3 04 29 03 3E E5 62 00 00 00 00 0B 58 00 00 00 00 09 35 00 00 0B F1 A0 00 01 90 00 00 A9 08 01 20 00 00 01 B9 0B DE 03 A4 00 02 F1 Received message is OK! Checksum is correct! 24391 Receive PCM DATAstream Send request PID_2101 to PCM 24607 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CD 00 00 02 5F 00 00 00 00 04 3A 00 00 00 00 32 C8 03 A4 04 29 03 3F E5 62 00 00 00 00 0B 18 00 00 00 00 09 35 00 00 0B F1 A0 00 01 90 00 00 A9 08 01 20 00 00 01 B9 0B DE 03 A4 00 02 B4 Received message is OK! Checksum is correct! 24814 Receive PCM DATAstream Send request PID_2101 to PCM 25054 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CD 00 00 02 5F 00 00 00 00 04 3F 00 00 00 00 32 C8 03 A3 04 29 03 3E E5 62 00 00 00 00 0B 16 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 A9 08 01 20 00 00 01 BA 0B DE 03 A3 00 02 B8 Received message is OK! Checksum is correct! 25261 Receive PCM DATAstream Send request PID_2101 to PCM 25477 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CD 00 00 02 5E 00 00 00 00 04 3F 00 00 00 00 32 C8 03 A4 04 29 03 3F E5 62 00 00 00 00 0B 18 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 A9 08 01 20 00 00 01 BA 0B DE 03 A3 00 02 BB Received message is OK! Checksum is correct! 25764 Receive PCM DATAstream Send request PID_2101 to PCM 25980 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CD 00 00 02 5E 00 00 00 00 04 39 00 00 00 00 32 C8 03 A3 04 29 03 3E E5 62 00 00 00 00 0B 5A 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 AD 08 01 20 00 00 01 BA 0B DE 03 A4 00 02 FA Received message is OK! Checksum is correct! 26234 Receive PCM DATAstream Send request PID_2101 to PCM 26450 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CD 00 00 02 5F 00 00 00 00 04 3E 00 00 00 00 32 C8 03 A3 04 29 03 3E E5 62 00 00 00 00 0B 16 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 A9 08 01 20 00 00 01 BA 0B DE 03 A4 00 02 B8 Received message is OK! Checksum is correct! 26664 Receive PCM DATAstream Send request PID_2101 to PCM 26927 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FE 00 00 0B CD 00 00 02 5F 00 00 00 00 04 3A 00 00 00 00 32 C8 03 A4 04 29 03 3F E5 62 00 00 00 00 0B 16 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 AD 08 01 20 00 00 01 BA 0B DE 03 A3 00 02 B8 Received message is OK! Checksum is correct! 27142 Receive PCM DATAstream Send request PID_2101 to PCM 27358 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CD 00 00 02 5F 00 00 00 00 04 39 00 00 00 00 32 C8 03 A3 04 29 03 3E E5 62 00 00 00 00 0B 16 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 A9 08 01 20 00 00 01 BA 0B DE 03 A4 00 02 B3 Received message is OK! Checksum is correct! 27618 Receive PCM DATAstream Send request PID_2101 to PCM 27834 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CD 00 00 02 5F 00 00 00 00 04 3A 00 00 00 00 32 C8 03 A4 04 29 03 3F E5 62 00 00 00 00 0B 16 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 A9 08 01 20 00 00 01 BA 0B DF 03 A3 00 02 B6 Received message is OK! Checksum is correct! 28134 Receive PCM DATAstream Send request PID_2101 to PCM 28350 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CD 00 00 02 5F 00 00 00 00 04 3A 00 00 00 00 32 C8 03 A3 04 29 03 3F E5 62 00 00 00 00 0B 18 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 A9 08 00 20 00 00 01 BA 0B DE 03 A3 00 02 B5 Received message is OK! Checksum is correct! 28593 Receive PCM DATAstream Send request PID_2101 to PCM 28809 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CD 00 00 02 5F 00 00 00 00 04 39 00 00 00 00 32 C8 03 A3 04 29 03 3E E5 62 00 00 00 00 0B 16 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 A9 08 00 20 00 00 01 BA 0B DE 03 A4 00 02 B2 Received message is OK! Checksum is correct! 29022 Receive PCM DATAstream Send request PID_2101 to PCM 29284 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CD 00 00 02 5F 00 00 00 00 04 3A 00 00 00 00 32 C8 03 A4 04 29 03 3E E5 62 00 00 00 00 0B 16 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 A9 08 00 20 00 00 01 BA 0B DE 03 A3 00 02 B3 Received message is OK! Checksum is correct! 29495 Receive PCM DATAstream Send request PID_2101 to PCM 29711 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CD 00 00 02 5F 00 00 00 00 04 39 00 00 00 00 32 C8 03 A3 04 29 03 3E E5 62 00 00 00 00 0B 18 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 A9 08 00 20 00 00 01 BA 0B DF 03 A4 00 02 B5 Received message is OK! Checksum is correct! 29970 Receive PCM DATAstream Send request PID_2101 to PCM 30186 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FE 00 00 0B CD 00 00 02 60 00 00 00 00 04 3E 00 00 00 00 32 C8 03 A4 04 29 03 3F E5 62 00 00 00 00 0B 19 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 29 08 00 20 00 00 00 Message fail timeout Send request PID_2101 to PCM 30790 Send request PID_2101 to PCM 31391 Send request PID_2101 to PCM 31992 Send request PID_2101 to PCM 32593 Send request PID_2101 to PCM 33198 Send request INIT to PCM 38250 Receive PCM: 83 F1 11 C1 6B 8F 40 Received message is OK! Checksum is correct! 38347 Initialization OK!!!! Send request PID_2101 to PCM 38419 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CD 00 00 02 4D 00 00 00 00 04 3A 00 00 00 00 32 C8 03 A3 04 29 03 3E E5 62 00 00 00 00 0B 16 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 A1 08 01 21 00 00 01 BA 0B DF 03 A4 00 02 9C Received message is OK! Checksum is correct! 38624 Receive PCM DATAstream Send request PID_2101 to PCM 39464 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CB 00 00 02 4E 00 00 00 00 04 41 00 00 00 00 32 C8 03 A4 04 29 03 3E E5 62 00 00 00 00 0B 13 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 A1 08 01 21 00 00 01 BA 0B DF 03 A3 00 02 9F Received message is OK! Checksum is correct! 39670 Receive PCM DATAstream Send request PID_2101 to PCM 40119 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CD 00 00 02 4E 00 00 00 00 04 3E 00 00 00 00 32 C8 03 A4 04 29 03 3F E5 62 00 00 00 00 0B 14 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 A1 08 01 21 00 00 01 BA 0B DF 03 A3 00 02 A0 Received message is OK! Checksum is correct! 40324 Receive PCM DATAstream Send request PID_2101 to PCM 40750 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CD 00 00 02 4F 00 00 00 00 04 3A 00 00 00 00 32 C8 03 A3 04 29 03 3F E5 62 00 00 00 00 0B 11 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 A1 08 01 21 00 00 01 BA 0B DF 03 A3 00 02 99 Received message is OK! Checksum is correct! 40960 Receive PCM DATAstream Send request PID_2101 to PCM 41408 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FE 00 00 0B CD 00 00 02 4E 00 00 00 00 04 3A 00 00 00 00 32 C8 03 A3 04 29 03 3E E5 62 00 00 00 00 0B 55 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 A1 08 01 21 00 00 01 BA 0B DF 03 A4 00 02 DB Received message is OK! Checksum is correct! 41610 Receive PCM DATAstream Send request PID_2101 to PCM 42036 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CD 00 00 02 4E 00 00 00 00 04 3A 00 00 00 00 32 C8 03 A4 04 29 03 3E E5 62 00 00 00 00 0B 11 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 A1 08 01 21 00 00 01 BA 0B DF 03 A4 00 02 99 Received message is OK! Checksum is correct! 42246 Receive PCM DATAstream Send request PID_2101 to PCM 42694 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FE 00 00 0B CD 00 00 02 4F 00 00 00 00 04 3A 00 00 00 00 32 C8 03 A3 04 29 03 3E E5 62 00 00 00 00 0B 11 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 A1 08 01 21 00 00 01 BA 0B DF 03 A3 00 02 97 Received message is OK! Checksum is correct! 42900 Receive PCM DATAstream Send request PID_2101 to PCM 43326 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CB 00 00 02 4F 00 00 00 00 04 3A 00 00 00 00 32 C8 03 A3 04 29 03 3F E5 62 00 00 00 00 0B 11 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 A1 08 01 21 00 00 01 BA 0B DE 03 A3 00 02 96 Received message is OK! Checksum is correct! 43536 Receive PCM DATAstream Send request PID_2101 to PCM 43984 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CD 00 00 02 4E 00 00 00 00 04 3A 00 00 00 00 32 C8 03 A3 04 29 03 3F E5 62 00 00 00 00 0B 13 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 A5 08 01 21 00 00 01 BA 0B E0 03 A3 00 02 9F Received message is OK! Checksum is correct! 44190 Receive PCM DATAstream Send request PID_2101 to PCM 44616 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CD 00 00 02 4F 00 00 00 00 04 3A 00 00 00 00 32 C8 03 A4 04 29 03 3F E5 62 00 00 00 00 0B 13 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 A1 08 01 21 00 00 01 BA 0B E0 03 A3 00 02 9D Received message is OK! Checksum is correct! 44824 Receive PCM DATAstream Send request PID_2101 to PCM 45273 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CD 00 00 02 4F 00 00 00 00 04 3E 00 00 00 00 32 C8 03 A3 04 29 03 3E E5 62 00 00 00 00 0B 13 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 A5 08 01 21 00 00 01 BA 0B E0 03 A3 00 02 A3 Received message is OK! Checksum is correct! 45474 Receive PCM DATAstream Send request PID_2101 to PCM 45900 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CB 00 00 02 4F 00 00 00 00 04 3A 00 00 00 00 32 C8 03 A3 04 29 03 3E E5 62 00 00 00 00 0B 13 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 A1 08 01 21 00 00 01 BA 0B DF 03 A3 00 02 98 Received message is OK! Checksum is correct! 46106 Receive PCM DATAstream Send request PID_2101 to PCM 46555 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CD 00 00 02 4F 00 00 00 00 04 3A 00 00 00 00 32 C8 03 A3 04 29 03 3F E5 62 00 00 00 00 0B 13 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 A5 08 01 21 00 00 01 BA 0B DF 03 A3 00 02 9F Received message is OK! Checksum is correct! 46760 Receive PCM DATAstream Send request PID_2101 to PCM 47186 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CB 00 00 02 4F 00 00 00 00 04 3A 00 00 00 00 32 C8 03 A4 04 29 03 3E E5 62 00 00 00 00 0B 53 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 A1 08 01 21 00 00 01 BA 0B E0 03 A3 00 02 DA Received message is OK! Checksum is correct! 47396 Receive PCM DATAstream Send request PID_2101 to PCM 47845 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FE 00 00 0B CD 00 00 02 4F 00 00 00 00 04 3C 00 00 00 00 32 C8 03 A3 04 29 03 3F E5 62 00 00 00 00 0B 14 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 A5 08 01 21 00 00 01 BA 0B E0 03 A3 00 02 A2 Received message is OK! Checksum is correct! 48047 Receive PCM DATAstream Send request PID_2101 to PCM 48473 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FE 00 00 0B CD 00 00 02 4F 00 00 00 00 04 3E 00 00 00 00 32 C8 03 A3 04 29 03 3E E5 62 00 00 00 00 0B 55 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 A1 08 01 21 00 00 01 BA 0B E0 03 A3 00 02 E0 Received message is OK! Checksum is correct! 48678 Receive PCM DATAstream Send request PID_2101 to PCM 49127 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CD 00 00 02 4F 00 00 00 00 04 3A 00 00 00 00 32 C8 03 A3 04 29 03 3F E5 62 00 00 00 00 0B 55 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 A5 08 01 21 00 00 01 BA 0B E0 03 A3 00 02 E2 Received message is OK! Checksum is correct! 49331 Receive PCM DATAstream Send request PID_2101 to PCM 49757 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FE 00 00 0B CD 00 00 02 4F 00 00 00 00 04 3A 00 00 00 00 32 C8 03 A3 04 29 03 3E E5 62 00 00 00 00 0B 11 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 A1 08 01 21 00 00 01 BA 0B E0 03 A3 00 02 98 Received message is OK! Checksum is correct! 49965 Receive PCM DATAstream Send request PID_2101 to PCM 50413 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FE 00 00 0B CD 00 00 02 4F 00 00 00 00 04 3E 00 00 00 00 32 C8 03 A3 04 29 03 3F E5 62 00 00 00 00 0B 14 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 A1 08 01 21 00 00 01 BA 0B DF 03 A3 00 02 9F Received message is OK! Checksum is correct! 50623 Receive PCM DATAstream Send request PID_2101 to PCM 51049 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CB 00 00 02 50 00 00 00 00 04 3A 00 00 00 00 32 C8 03 A3 04 29 03 3E E5 62 00 00 00 00 0B 14 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 A1 08 01 21 00 00 01 BA 0B DF 03 A3 00 02 9A Received message is OK! Checksum is correct! 51253 Receive PCM DATAstream Send request PID_2101 to PCM 51701 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CD 00 00 02 4F 00 00 00 00 04 3A 00 00 00 00 32 C8 03 A4 04 29 03 3F E5 62 00 00 00 00 0B 14 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 A1 08 01 21 00 00 01 BA 0B E0 03 A3 00 02 9E Received message is OK! Checksum is correct! 51905 Receive PCM DATAstream Send request PID_2101 to PCM 52331 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CD 00 00 02 4F 00 00 00 00 04 3E 00 00 00 00 32 C8 03 A4 04 29 03 3F E5 62 00 00 00 00 0B 55 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 A1 08 01 21 00 00 01 BA 0B E0 03 A3 00 02 E3 Received message is OK! Checksum is correct! 52539 Receive PCM DATAstream Send request PID_2101 to PCM 52987 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CD 00 00 02 4F 00 00 00 00 04 37 00 00 00 00 32 C8 03 A3 04 29 03 3F E5 62 00 00 00 00 0B 11 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 A1 08 01 21 00 00 01 BA 0B DF 03 A3 00 02 96 Received message is OK! Checksum is correct! 53195 Receive PCM DATAstream Send request PID_2101 to PCM 53621 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CD 00 00 02 5A 00 00 00 00 04 39 00 00 00 00 32 C8 03 A3 04 29 03 3E E5 62 00 00 00 00 0B 58 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 A9 08 01 20 00 00 01 BA 0B E0 03 A4 00 02 F2 Received message is OK! Checksum is correct! 53831 Receive PCM DATAstream Send request PID_2101 to PCM 54280 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FE 00 00 0B CD 00 00 02 5B 00 00 00 00 04 3E 00 00 00 00 32 C8 03 A3 04 29 03 3E E5 62 00 00 00 00 0B 16 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 A9 08 01 20 00 00 01 BA 0B E0 03 A3 00 02 B4 Received message is OK! Checksum is correct! 54481 Receive PCM DATAstream Send request PID_2101 to PCM 54907 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CB 00 00 02 5B 00 00 00 00 04 3A 00 00 00 00 32 C8 03 A3 04 29 03 3E E5 62 00 00 00 00 0B 16 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 AD 08 01 20 00 00 01 BA 0B E0 03 A3 00 02 B3 Received message is OK! Checksum is correct! 55113 Receive PCM DATAstream Send request PID_2101 to PCM 55562 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FE 00 00 0B CE 00 00 02 5C 00 00 00 00 04 3C 00 00 00 00 32 C8 03 A4 04 29 03 3E E5 62 00 00 00 00 0B 16 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 A9 08 01 20 00 00 01 BA 0B E0 03 A3 00 02 B5 Received message is OK! Checksum is correct! 55766 Receive PCM DATAstream Send request PID_2101 to PCM 56349 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FE 00 00 0B CD 00 00 02 5D 00 00 00 00 04 3A 00 00 00 00 32 C8 03 A3 04 29 03 3E E5 62 00 00 00 00 0B 16 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 A9 08 01 20 00 00 01 BA 0B E0 03 A3 00 02 B2 Received message is OK! Checksum is correct! 56562 Receive PCM DATAstream Send request PID_2101 to PCM 57172 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FE 00 00 0B CD 00 00 02 5D 00 00 00 00 04 37 00 00 00 00 32 C8 03 A3 04 29 03 3E E5 62 00 00 00 00 0B 16 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 A9 08 01 20 00 00 01 BA 0B E1 03 A4 00 02 B1 Received message is OK! Checksum is correct! 57374 Receive PCM DATAstream Send request PID_2101 to PCM 57800 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FE 00 00 0B CD 00 00 02 5E 00 00 00 00 04 3E 00 00 00 00 32 C8 03 A3 04 29 03 3F E5 62 00 00 00 00 0B 16 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 A9 08 01 20 00 00 01 BA 0B E1 03 A3 00 02 B9 Received message is OK! Checksum is correct! 58006 Receive PCM DATAstream Send request PID_2101 to PCM 58455 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FE 00 00 0B CD 00 00 02 5E 00 00 00 00 04 3A 00 00 00 00 32 C8 03 A3 04 29 03 3F E5 62 00 00 00 00 0B 16 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 A9 08 01 20 00 00 01 BA 0B E0 03 A3 00 02 B4 Received message is OK! Checksum is correct! 58656 Receive PCM DATAstream Send request PID_2101 to PCM 59082 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CB 00 00 02 5E 00 00 00 00 04 3E 00 00 00 00 32 C8 03 A4 04 29 03 3E E5 62 00 00 00 00 0B 16 00 00 00 00 09 36 00 00 0B F3 A0 00 01 00 02 B8 Message fail timeout Send request PID_2101 to PCM 59685 Receive PCM: 80 F1 11 4C 61 01 00 00 00 00 00 00 00 00 0B FF 00 00 0B CE 00 00 02 5E 00 00 00 00 04 3E 00 00 00 00 32 C8 03 A3 04 29 03 3E E5 62 00 00 00 00 0B 16 00 00 00 00 09 36 00 00 0B F3 A0 00 01 90 00 00 AD 08 01 20 00 00 01 BA 0B E0 03 A3 00 02 BD Received message is OK! Checksum is correct! 59888 Receive PCM DATAstream Send request PID_2101 to PCM 60472Ладно тестируй, потом добавлю датчик t
А ты узнай его адрес, примером из библиотеки onewire
ок. температура в нутри и влага, и наружняя температура не работают, я видел что не прописаны библиотеки. ок буду пока тестить. я ща пробую добавить все что было раньше на них, но чета не показывает
раньше было так
библиотеки //датчик наружней температуры #include <OneWire.h> #define ONE_WIRE_BUS 22 OneWire oneWire(ONE_WIRE_BUS); #include <DallasTemperature.h> DallasTemperature sensors(&oneWire); //датчик внутринней температуры и влаги #include "DHT.h" #define DHTPIN 26 #define DHTTYPE DHT22 DHT dht(DHTPIN, DHTTYPE); в сетупе Wire.begin(); rtc.begin(); dht.begin(); sensors.begin(); в лупе if (millis() - prevTemperature > 60000) { Temperature (); prevTemperature = millis();} на странице хоме myGLCD.printNumI(sensors.getTempCByIndex(0), 415, 145 , 3); этот пока так и остается myGLCD.printNumI(t, 415, 180, 3); сейчас так if ((t != t_last) || reNew) {myGLCD.printNumI(t, 415, 180, 3); t_last=t;} на странице инф1 myGLCD.printNumF(h, 1, 418, 215); } сейчас так if ((h != h_last) || reNew) {myGLCD.printNumF(h, 1, 430, 215, 3); h_last=h;} и в конце скетча void Temperature (){ h = dht.readHumidity(); t = dht.readTemperature(); sensors.requestTemperatures(); }вообщем пока так, ниже скетя, внутреннюю температуру и влагу не показывает, на ружнюю показывает но не обновляется. как тольлко чтото сую в луп
это Temperature ();
или по отдельности или вместе это
h = dht.readHumidity();
t = dht.readTemperature();
sensors.requestTemperatures();
чтобы обновлялись, все зависает.
//------------все для связи по K-line (тут настраиваем UARTы к-лайников, адреса блоков, скорость инита и отладку) #include <SoftwareSerial.h> #define TX_PCM 13 SoftwareSerial K_LINE_PCM (12, TX_PCM); //RХ,TХ //UART на котором висит K_line к PCM #define K_LINE_GAUGE Serial2 //UART на котором висит K_line к приборке #define TX_gauge 16 //TX UARTa на котором висит K_line к приборке #define PCM_address 0x11 // адрес PCM #define DIAG_address 0xF1 // адрес диагностики const byte BAUD=200; // init baudrate - скорость инита при подключении к приборке const byte addressGUAGE = 0xB8;// init GAUGE address - адрес щитка приборов при ините (установке связи) #define debugPCM // раскомментировать эту строку для отладки в Serial порту обмена с PCM //#define debugGAUGE // раскомментировать эту строку для отладки в Serial порту обмена co щитком приборов uint32_t curmillis = 0; // снимок текущего времени //------------------------------------------переменные для организации протокола связи с PCM uint32_t prevRequest = 0; // таймер периодических запосов на PCM uint16_t RequestPeriod = 3500; // периодичность запросов на PCM uint32_t prevRESETheader=0; // таймер сброса сообщения, если данные оборвались посередине сообщения bool RESETheader_timer; // таймер сброса сообщения, если данные оборвались посередине сообщения uint32_t prev_NOanswer=0; // таймер контроля неответов от ЭБУ после подачи запросов bool NOanswer_timer = 0; // таймер контроля неответов от ЭБУ после подачи запросов byte noanswers = 0; // количество подряд неответов от ЭБУ uint32_t timerdelay = 0; // таймер ожидания байт (для успевания появления данных в буфере UART) bool Delay = 0; // таймер ожидания байт (для успевания появления данных в буфере UART) byte waitbyte_RX = 1; // задержка, мс для успевания появления данных в буфере RX // (подрегулировать в зависимости от уровня жизнидеятельности на Марсе) #define TIMER_DELAY Delay = 0; timerdelay = curmillis // включение этого таймера byte delaybyte_TX = 1; // задержка между отправкой байт в запросах, мс byte header = 0; // состояние заголовка byte message_size = 0; // размер тела сообщения byte j = 3; // инкремент byte n = 3; // количество старт байт const byte bufsize = 150; // размер буфера принятого сообщения byte MessageRx_PCM [bufsize] = {0}; // буфер принятого сообщения byte crc =0; // байт контрольной суммы // возможные варианты запросов на ЭБУ: enum REQUEST {INIT, PID, DTCERASE, DTCREAD, PRESENT,}; // текстовки запросов для отладки char* textRequest[] = {"INIT", "PID_2101", "DTC_ERASE", "DTC_READ", "PRESENT",} ; // сами запросы byte PCM_Message_TX[][5] = { {1, 0x81, 0,0,0}, // запрос инициализации {2, 0x21,0x01, 0,0}, // запрос пид 2101 {3, 0x14,0xFF,0x00, 0}, // запрос на стирание ошибок {4, 0x18,0x00,0xFF,0x00 }, // запрос на чтение ошибок {1, 0x3E, 0,0,0}, // запрос присутствия }; byte request = INIT; // переменная, показывающая какой запрос будем делать //------------------------------------------ переменные для организации протокола связи со щитком приборов uint32_t prevNoconnect = 0; // таймер периодической проверки наличия связи со щитком приборов uint32_t prevInitbusGauge = 0; // таймер для инита щитка приборов byte NoconnectsGAUGE = 0 ; // счетчик неответов от щитка приборов byte InitGauge = 0; // автомат состояния инита щитка приборов int waitbyte_gauge = 4; byte MessageRxGauge[60] = {0}; // массив байтов принимаемого сообщения от щитка приборов byte PIDgauge[] = {0x02,0x11,0x00,0x13}; // запрос параметоров щитка приборов bool flagneedGAUGE = 1; //-------------------------------------------переменные бортовика float L100M = 0; float L100M_last = 1; //расход на 100 км измеренный за поездку float L100 = 0; float L100_last = 1; //мгновенный расход литров на 100км float LHor = 0; float LHor_last = 1; //мгновенный расход топлива литров в час float L100SR = 0; //расход литров на 100км измеренный раз в интервал kmL float L100SR_TFT = 0; float L100SR_TFT_last = 1; // самый средний из расходов на 100км, он выводится на экран int L100_Eeprom[11]= {10,10,10,10,10,10,10,10,10,10,10}; int FuelZamer[10]= {0}; // массив для измерения уровня (количества) топлива int ZamerNumber = 0; // номер замера уровня (количества) топлива int n_eeprom = 0; // текущий адрес ячейки еепром для записи расхода int MAF = 0; int MAF_last = 1; //26,27 байты Sensor de flujo de aire en masa float BoostPres = 0; float BoostPres_last = 1; //28,29 байты Presión de refuerzo int RPM = 0; int RPM_last = 1; //32,33 байты Velocidad del motor int EGRmg = 0; int EGRmg_last = 1; //34,35 байты Comando EGR (Comando de recirculación de gases de escape) float BoostPresCom = 0; float BoostPresCom_last = 1;//38,39 байты Comando de presión de refuerzo int Speed = 0; int Speed_last = 1; //44,45 байты Velocidad del vehículo float DesaInjQua = 0; float DesaInjQua_last = 1; //50,51 байты Cantidad de inyección deseada float InjQua = 0; float InjQua_last = 1; //52,53 байты Cantidad de la inyección float StaDaliv = 0; float StaDaliv_last = 1; //54,55 байты Inicio de la entrega int PumpRPM = 0; int PumpRPM_last = 1; //56,57 байты Velocidad de la bomba float EGRPul = 0; float EGRPul_last = 1; //62,63 байты Relación de impulsos EGR (recirculación de gases de escape float SolenPul = 0; float SolenPul_last = 1; //64,65 байты Velocidad de solenoide de control de nivel de remolino Relación de impulsos float SolenPre = 0; float SolenPre_last = 1; //70,71 байты Relación de impulsos Presión Electroválvula de presión float DesInj = 0; float DesInj_last = 1; //72,73 байты Inyección deseada Inicio float ActInj = 0; float ActInj_last = 1; //16,17 байты Inicio de la inyección real int TempAir = 0; int TempAir_last = 1; //74,75 байты Temperatura del aire de admisión int Temp = 0; int Temp_last = 1; //14,15 байты Temperatura del refrigerante int TempOil = 0; int TempOil_last = 1; //18,19 байты Temperatura del aceite del motor int TempFuel = 0; int TempFuel_last = 1; //58,59 байты Temperatura del combustible //все что касается топлива float Fuel = 0; //остаток топлива float Fuel2 = 0; float Fuel2_last = 1; //остаток мгновенного топлива байт 16 , датчика в баке int FuelIGN = 0; // количество топлвива в баке на момент включения зажигания int Fuel_last = 0; // для формул bool flagFuelIGN = 0; // флаг записан ли остаток топлива в момент вкл. зажигания float FuelTrip = 0; float FuelTrip_last = 1; // количество литров топлива, израсходованное за один цикл включения зажигания //все что касается километража float kmAge = 0; //пробег, полученный со щитка приборов int kmAgeIGN = 0; //пробег который был в момент включения зажигания int kmAge_last = 0; // для формул bool flagkmAgeIGN = 0; //флаг записан ли пробег в момент вкл. зажигания float kmTrip = 0; float kmTrip_last = 1; //пробег за один цикл включения зажигания int kmL = 10; // интервал, через который будет происходить обновление среднего расхода на 100км int km = 0; // переменная для расчетов int kmeeprom = 10; // интервал, через который будет происходить подсчет среднеарифмитического расхода L100SR_TFT int kmTFT = 0; // переменная для расчетов периодического подсчета среднеарифмитического расхода топлива L100SR_TFT int kmREFUELING = 0; int kmREFUELING_last = 1; // пробег до заправки на остатке топлива unsigned long prevWatch = 0; unsigned long prevDvoet = 0; unsigned long prevData = 0; uint32_t prevGauge = 0; //----------------------------------------------для экрана #include <Adafruit_GFX.h> #include <MCUFRIEND_kbv.h> #include <UTFTGLUE.h>//use GLUE class and constructor #include "TouchScreen.h" #include <stdint.h> #include <SPI.h> #include <EEPROM.h> //MCUFRIEND_kbv tft; #include "Fonts/Chosence_Bold16pt7b.h"; #define MINPRESSURE 200 #define MAXPRESSURE 1000 //pin 20 SCL , 21 SDA датчик реального времени #include <Wire.h> #include "RTClib.h" RTC_DS3231 rtc; //датчик наружней температуры #include <OneWire.h> #define ONE_WIRE_BUS 22 OneWire oneWire(ONE_WIRE_BUS); #include <DallasTemperature.h> DallasTemperature sensors(&oneWire); //датчик внутринней температуры и влаги #include "DHT.h" #define DHTPIN 26 #define DHTTYPE DHT22 DHT dht(DHTPIN, DHTTYPE); UTFTGLUE myGLCD(0x1581,A2,A1,A3,A4,A0); //all dummy args const int XP = 6, XM = A2, YP = A1, YM = 7; const int TS_LEFT = 136, TS_RT = 907, TS_TOP = 139, TS_BOT = 942; TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300); uint16_t ID; int x, y; char currentPage; float h; int h_last = 1; float t; int t_last = 1; bool Dvoet = 0; bool reNew = 0; #define BLACK 0x0000 #define WHITE 0xFFFF #define RED 0xF800 #define GREEN 0x07E0 void setup() { uint16_t ID = myGLCD.readID(); if (ID == 0xD3D3) ID = 0x1581; // write-only shield myGLCD.begin(ID); myGLCD.InitLCD(3); myGLCD.clrScr(); myGLCD.setFont(&Chosence_Bold16pt7b); //myGLCD.fillScreen(WHITE); //myGLCD.setTextColor(WHITE, BLACK); //myGLCD.setBackColor(BLACK); Wire.begin(); rtc.begin(); dht.begin(); sensors.begin(); //загрузка стартовой страницы currentPage = '0'; drawHomeScreen(); //подсчет среднеарифметического усредненного расхода for (int i = 0; i < 11; i++) L100_Eeprom [i]= EEPROM.read(i); for (int i = 0; i < 11; i++) L100SR_TFT = L100SR_TFT + L100_Eeprom [i]; L100SR_TFT = (float)L100SR_TFT/110.0; if (L100SR_TFT<0) L100SR_TFT = 0; if (L100SR_TFT>99) L100SR_TFT = 99; // строка ниже используется для настройки даты и времени часов // раскомментировать, выставить времая и дату, залить в ардуино. в скетче закомментировать // обратно и залить еще раз, иначе каждый раз будет по новой выствлятся это же время и дата // (год, месяц, день, часы, минуты, секунды) //rtc.adjust(DateTime(2019, 7, 2, 10, 48, 0)); #if defined debugPCM or defined debugGAUGE Serial.begin(115200); #endif K_LINE_PCM.begin(10400); pinMode(TX_PCM, OUTPUT); } void loop() { curmillis = millis(); // снимок текущего времени if (curmillis - prevRequest > RequestPeriod && header == 0 && !flagneedGAUGE) { if (request == INIT) fastinit(); // при необходимости делаем переподключение к PCM else {sendMessagePCM(request); // отправляем на PCM текущий запрос if (request == PID) RequestPeriod = 600; if (request == DTCERASE || request == DTCREAD) RequestPeriod = 2500;} prevRequest = curmillis; } if (!flagneedGAUGE) {receivePCM ();} // приём сообщений от PCM receiveGAUGE (); // приём сообщений от щитка приборов if (header == 0) {Menu ();} if (curmillis - prevWatch > 4000) { Watch (); prevWatch = curmillis; Trip ();} //if (millis() - prevTemperature > 60000) { Temperature (); prevTemperature = millis();} if (millis() - prevDvoet > 500) { if (!Dvoet) {myGLCD.print(":", 290, 5);} else {myGLCD.print(" ", 290, 5);} prevDvoet = millis(); Dvoet=!Dvoet;} if (curmillis - prevGauge > 30000UL) {flagneedGAUGE = 1;prevGauge = curmillis;} }// end loop void Trip () { if (flagkmAgeIGN){ FuelTrip = FuelIGN - Fuel; if (kmAge>kmAgeIGN) kmTrip = kmAge - kmAgeIGN; if (kmAge<kmAgeIGN) kmTrip = 2000 - (kmAgeIGN - kmAge); // 2000 это через сколько км у тебя суточный пробег сбрасывается на ноль, поменяй если другое число if (kmAge==kmAgeIGN) kmTrip = 0; //подсчет расхода на 100км за поездку L100M = ((float)FuelTrip*100.00)/(float)kmTrip; if (L100M<0) L100M = 0; if (L100M>99) L100M = 99; // ниже цикл считает среднеарифметический расход из еепром раз в пробег, указанный в переменной kmeeprom if (kmTrip-kmTFT>kmeeprom) {kmTFT = kmTrip; // тут считаем среднеарифметический усредненного расход из ячеек еепром for (int i = 0; i < 11; i++) L100_Eeprom [i]= EEPROM.read(i); for (int i = 0; i < 11; i++) L100SR_TFT = L100SR_TFT + L100_Eeprom [i]; L100SR_TFT = (float)L100SR_TFT/110.00; if (L100SR_TFT<0) L100SR_TFT = 0; if (L100SR_TFT>99) L100SR_TFT = 99;} // ниже цикл считает расход топлива за пробег, указанный в переменной kmL, здесь же запись в ячейки еепром if (kmTrip-km>kmL) {km=kmTrip; L100SR = ((float)(Fuel_last-Fuel)*100.00)/(float)kmL; // расход/100км - обновляется раз в 10км, меняется км в int kmL = 10; Fuel_last = Fuel; // сохранение параметров с последнего измерениея if (L100SR<0) L100SR = 0; if (L100SR>99) L100SR = 99; //расчет остатка километров в баке if (L100SR>0) kmREFUELING=((float)Fuel*100.0)/(float)L100SR; //если средний расход больше нуля, то расчитывать км в баке из него else kmREFUELING=((float)Fuel*100.00)/(float)L100SR_TFT; //если ноль или ментше то расчитывать км в баке с устредненного расхода // тут записываем L100SR последовательно в одну из 11 ячеек еепром //EEPROM.write (12,n_eeprom); // ЗДЕСЬ ВНИМАТЕЛЬНО. ЗАГРУЗИТЬ ПРОШИВКУ С ЭТОЙ СТРОКОЙ ОДИН РАЗ, ПОТОМ ЗАКОМЕНТИРОВАТЬ И ЕЩЁ РАЗ ЗАГРУЗИТЬ n_eeprom = EEPROM.read (12); // в ячейке 12 хранится № текущей ячейки для записи расхода, чтобы где остановился при выкл питания, от туда и продолжил EEPROM.write(n_eeprom, L100SR*10); n_eeprom++; if (n_eeprom>10) n_eeprom=0; EEPROM.write (12,n_eeprom); }}} void fastinit() { digitalWrite (TX_PCM, HIGH); // bus idle delay(1500); digitalWrite (TX_PCM, LOW); // first part fastinit (25 ms LOW) delay(25); digitalWrite (TX_PCM, HIGH); // second part fastinit (25 ms HIGH) delay(25); K_LINE_PCM.begin(10400); sendMessagePCM(INIT); // send start communication message } void receivePCM () { if (K_LINE_PCM.available() ){ // первый старт байт if (header == 0 && Delay){TIMER_DELAY ; MessageRx_PCM[0]=K_LINE_PCM.read(); if (MessageRx_PCM[0]!=0xFF && bitRead (MessageRx_PCM[0],7)){header = 1; RESETheader_timer = 1; prevRESETheader = curmillis; #ifdef debugPCM Serial.print (F("Receive PCM: ")); printDebugRX(MessageRx_PCM[0]); #endif } } // второй старт байт if (header == 1 && Delay){TIMER_DELAY ; MessageRx_PCM[1]=K_LINE_PCM.read(); #ifdef debugPCM printDebugRX (MessageRx_PCM[1]); #endif if (MessageRx_PCM[1]==DIAG_address){ header = 2;} else { #ifdef debugPCM Serial.println(F(" PCM Message fail address")); #endif header = 0; RESETheader_timer = 0;}} // третий старт байт if (header == 2 && Delay){ TIMER_DELAY ; MessageRx_PCM[2]=K_LINE_PCM.read(); #ifdef debugPCM printDebugRX (MessageRx_PCM[2]); #endif if (MessageRx_PCM[2]==PCM_address){ message_size = MessageRx_PCM[0]; prevRESETheader = curmillis; if (MessageRx_PCM[0] !=0x80) {header = 4; bitWrite (message_size, 7 , 0);j=3;n=3;} else {header = 3; j=4;n=4;} if (message_size > bufsize) message_size = bufsize; crc = 0;} else {header = 0; #ifdef debugPCM Serial.println(F("PCM Message fail address")); #endif RESETheader_timer = 0;} } // если размер сообщения указан в дополнительном байте (нулевой байт 0x80) читаем этот дополнительный байт: if (header == 3 && Delay){ TIMER_DELAY ; prevRESETheader = curmillis; MessageRx_PCM[3]=K_LINE_PCM.read(); #ifdef debugPCM printDebugRX(MessageRx_PCM[3]); #endif message_size = MessageRx_PCM[3]; if (message_size > bufsize) message_size = bufsize; crc = 0; header = 4; } // пишем тело сообщения if (header == 4 && Delay && j< message_size+n+1) { MessageRx_PCM[j] = K_LINE_PCM.read(); prevRESETheader = curmillis; if (j<message_size+n) crc+= MessageRx_PCM[j]; // подсчёт КС if (j==message_size+n) header = 5; TIMER_DELAY ; #ifdef debugPCM printDebugRX(MessageRx_PCM[j]); #endif j++; } } // сообщение приняли, действуем if (header == 5) {TIMER_DELAY ; #ifdef debugPCM Serial.println(); #endif NOanswer_timer = 0; noanswers = 0; // сбрасываем таймер контроля неответов for(byte i = 0; i<n; i++) crc+=MessageRx_PCM[i]; // прибавляем к контрольной сумме старт байты // если контрольная сумма верна: if ( crc == MessageRx_PCM[message_size+n]) { #ifdef debugPCM Serial.print (F("Received message is OK! Checksum is correct!")); Serial.print (F(" ")); Serial.println (millis()); // Если КС совпала, тут чёнибудь нужное делаем printDebugRX_CSgood(); #endif if (MessageRx_PCM[n]==0xC1 && MessageRx_PCM[n+1]==0x6B && MessageRx_PCM[n+2]==0x8F) { if (currentPage!=3) {request = PID; RequestPeriod = 70;} else request = PRESENT, RequestPeriod = 4000; prevRequest = curmillis; // receive good INIT } else if (MessageRx_PCM[n]==0x58) Troublecodes (); // DTC else if (MessageRx_PCM[n]==0x54 && MessageRx_PCM[n+1]==0xFF && MessageRx_PCM[n+2]==0x00){ request = PRESENT; RequestPeriod = 4000; prevRequest = curmillis;} // DTC are cleared else if (MessageRx_PCM[n]==0x61 && MessageRx_PCM[n+1]==0x01) {dataVars() ; RequestPeriod = 70; prevRequest = curmillis; } // receive DataStream } // если контрольная сумма не совпала: #ifdef debugPCM else Serial.println("CRC fail!!!" ); #endif message_size = 0; header=0; RESETheader_timer = 0; j=3; crc = 0; } // таймер ожидания байт (для успевания появления данных в буфере UART) if (!Delay && curmillis - timerdelay > waitbyte_RX) Delay = 1; // таймер сброса целостности сообщения (если данные оборвались посередине сообщения) if (RESETheader_timer && curmillis - prevRESETheader > 200) { #ifdef debugPCM Serial.println(F("Message fail timeout")); #endif RESETheader_timer = 0; header = 0;} // если нет ответа после запроса: +1 к счетчику неответов. Если накопилось 6 и более: делаем реинит. if (request!=INIT && NOanswer_timer && curmillis - prev_NOanswer > RequestPeriod - RequestPeriod/10) { NOanswer_timer = 0; noanswers++; if (noanswers>=6) { noanswers = 0; request = INIT; RequestPeriod = 3500;} } }// end receivePCM void Troublecodes () { if (MessageRx_PCM[n]==0x58 && MessageRx_PCM[n+1]==0x00){ myGLCD.clrScr(); drawscreen_three(); myGLCD.print("NO DTC", 180, 145); } // при получении сообщения о наличии ошибок DTC разберем сообщение выведем на экран ошибки if (MessageRx_PCM[n]==0x58 && MessageRx_PCM[n+1]>0){ myGLCD.clrScr(); drawscreen_three(); for (int i=0; i<MessageRx_PCM[n+8-7]; i++ ) { int y = i*35; bool nolA=0; bool nolB =0; if (!bitRead(MessageRx_PCM[n+11-7+(i*3)],6) && bitRead(MessageRx_PCM[n+11-7+(i*3)],7)){ myGLCD.setTextColor(GREEN, BLACK); myGLCD.print(" -Passive-", 300, (75+y));} // если DTC пасивныый делаем цвет зеленый if (bitRead(MessageRx_PCM[n+11-7+(i*3)],7) && bitRead(MessageRx_PCM[n+11-7+(i*3)],6)) { myGLCD.setTextColor(RED, BLACK); myGLCD.print(" -Active-", 300, (75+y));} // если DTC активный, делаем цвет красный myGLCD.print("ERROR ", 50, (75+y)); myGLCD.printNumI((i+1), 150, (75+y)); if (!bitRead(MessageRx_PCM[n+9-7+(i*3)],6) && !bitRead(MessageRx_PCM[n+9-7+(i*3)],7)) myGLCD.print(": P", 170, (75+y)); if (bitRead(MessageRx_PCM[n+9-7+(i*3)],6) && !bitRead(MessageRx_PCM[n+9-7+(i*3)],7)) myGLCD.print(": C", 170, (75+y)); if (!bitRead(MessageRx_PCM[n+9-7+(i*3)],6) && bitRead(MessageRx_PCM[n+9-7+(i*3)],7)) myGLCD.print(": B", 170, (75+y)); if (bitRead(MessageRx_PCM[n+9-7+(i*3)],6) && bitRead(MessageRx_PCM[n+9-7+(i*3)],7)) myGLCD.print(": U", 170, (75+y)); if (MessageRx_PCM[n+9-7+(i*3)]==0x00) {myGLCD.print("00", 230, (75+y)); nolA = 1;} if (MessageRx_PCM[n+9-7+(i*3)]<=0x0F&&MessageRx_PCM[n+9-7+(i*3)]!=0) {myGLCD.print("0", 230, (75+y)); nolA = 1;} if (nolA)myGLCD.print(String (MessageRx_PCM[n+9-7+(i*3)],HEX), 246, (75+y)); else myGLCD.print(String (MessageRx_PCM[n+9-7+(i*3)],HEX), 230, (75+y)); if (MessageRx_PCM[n+10-7+(i*3)]==0x00) {myGLCD.print("00", 262, (75+y)); nolB = 1;} if (MessageRx_PCM[n+10-7+(i*3)]<=0x0F&&MessageRx_PCM[n+10-7+(i*3)]!=0) {myGLCD.print("0", 262, (75+y)); nolB = 1;} if (nolB)myGLCD.print(String (MessageRx_PCM[n+10-7+(i*3)]),HEX, 278, (75+y)); else myGLCD.print(String (MessageRx_PCM[n+10-7+(i*3)],HEX), 262, (75+y));}} request = PRESENT; RequestPeriod = 4000; prevRequest = curmillis; } void dataVars() { //Barom = MessageRx_PCM[39]; L100 = (float)LHor*100.0/(float)Speed; LHor = (float)RPM* (float)InjQua*2.00/1000.0*60.00/1000.0/0.85; MAF = ((MessageRx_PCM[n+22]*256)+MessageRx_PCM[n+23])/10; BoostPres = ((MessageRx_PCM[n+24]*256)+MessageRx_PCM[n+25])/1000.0; RPM = (MessageRx_PCM[n+35-7]*256)+MessageRx_PCM[n+36-7]; EGRmg = ((MessageRx_PCM[n+37-7]*256)+MessageRx_PCM[n+38-7])/10.0; BoostPresCom = ((MessageRx_PCM[n+41-7]*256)+MessageRx_PCM[n+42-7])/1000.0; Speed = ((MessageRx_PCM[n+47-7]*256)+MessageRx_PCM[n+48-7])/100; DesaInjQua = ((MessageRx_PCM[n+53-7]*256)+MessageRx_PCM[n+54-7])/100.0; InjQua = ((MessageRx_PCM[n+55-7]*256)+MessageRx_PCM[n+56-7])/100.0; StaDaliv = ((MessageRx_PCM[n+57-7]*256)+MessageRx_PCM[n+58-7])/100.0; PumpRPM = (MessageRx_PCM[n+59-7]*256)+MessageRx_PCM[n+60-7]; EGRPul = ((MessageRx_PCM[n+65-7]*256)+MessageRx_PCM[n+66-7])/100.0; SolenPul = ((MessageRx_PCM[n+67-7]*256)+MessageRx_PCM[n+68-7])/100.0; SolenPre = ((MessageRx_PCM[n+73-7]*256)+MessageRx_PCM[n+74-7])/100.0; DesInj = ((MessageRx_PCM[n+75-7]*3)+(MessageRx_PCM[n+76-7])/100.0)+0.3; ActInj = ((MessageRx_PCM[n+19-7]*3)+(MessageRx_PCM[n+20-7])/100.0)+0.3; //TempAir = ((MessageRx_PCM[n+77-7]*26)-278)+MessageRx_PCM[n+78-7]/10.0; //Temp = ((MessageRx_PCM[n+17-7]*26)-278)+MessageRx_PCM[n+18-7]/10.0; //TempOil = ((MessageRx_PCM[n+21-7]*26)-278)+MessageRx_PCM[n+22-7]/10.0; //TempFuel = ((MessageRx_PCM[n+61-7]*26)-278)+MessageRx_PCM[n+62-7]/10.0; //ниже идут расчетные формулы более точные чем те что закоментированы выше int A = 0; if (MessageRx_PCM[n+77-7]<=0x0A) A = 277; if (MessageRx_PCM[n+77-7]==0x0B || MessageRx_PCM[n+77-7]==0x0C) A = 278; if (MessageRx_PCM[n+77-7]>=0x0D) A = 279; double B = MessageRx_PCM[n+78-7]/10.0; double cel , drob ; drob = modf(B, &cel); if (drob>0.6) cel++; TempAir = ((MessageRx_PCM[n+77-7]*26)-A)+cel; if (MessageRx_PCM[n+17-7]<=0x0A) A = 277; if (MessageRx_PCM[n+17-7]==0x0B || MessageRx_PCM[n+17-7]==0x0C) A = 278; if (MessageRx_PCM[n+17-7]>=0x0D) A = 279; B = MessageRx_PCM[n+18-7]/10.0; drob = modf(B, &cel); if (drob>0.6) cel++; Temp = ((MessageRx_PCM[n+17-7]*26)-A)+cel; if (MessageRx_PCM[n+21-7]<=0x0A) A = 277; if (MessageRx_PCM[n+21-7]==0x0B || MessageRx_PCM[n+21-7]==0x0C) A = 278; if (MessageRx_PCM[n+21-7]>=0x0D) A = 279; B = MessageRx_PCM[n+22-7]/10.0; drob = modf(B, &cel); if (drob>0.6) cel++; TempOil = ((MessageRx_PCM[n+21-7]*26)-A)+cel; if (MessageRx_PCM[n+61-7]<=0x0A) A = 277; if (MessageRx_PCM[n+61-7]==0x0B || MessageRx_PCM[n+61-7]==0x0C) A = 278; if (MessageRx_PCM[n+61-7]>=0x0D) A = 279; B = MessageRx_PCM[n+62-7]/10.0; drob = modf(B, &cel); if (drob>0.6) cel++; TempFuel = ((MessageRx_PCM[n+61-7]*26)-A)+cel; //---------------------------------------------------------- //страниц HOME //---------------------------------------------------------- //myGLCD.setBackColor(RED); myGLCD.setTextColor(WHITE, BLACK); //myGLCD.setBackColor(RED); if ((Speed != Speed_last) || reNew) {myGLCD.printNumI(Speed, 360, 7, 3); Speed_last=Speed;} if (currentPage == '0') { if ((LHor != LHor_last) || reNew) {myGLCD.printNumF(LHor, 1, 75, 40, '.',4); LHor_last=LHor;} if ((L100 != L100_last) || reNew) {myGLCD.printNumF(L100, 1, 225, 40,'.',4 ); L100_last=L100;} if ((L100M != L100M_last) || reNew) {myGLCD.printNumF(L100M, 1, 75, 75,'.',4 ); L100M_last=L100M;} if ((L100SR_TFT != L100SR_TFT_last) || reNew) {myGLCD.printNumF(L100SR_TFT, 1, 225, 75,'.',4 ); L100SR_TFT_last=L100SR_TFT;} if ((kmREFUELING != kmREFUELING_last) || reNew) {myGLCD.printNumI(kmREFUELING, 90, 110,3 ); kmREFUELING_last=kmREFUELING;} //if (Fuel<53) if ((Fuel != Fuel_last) || reNew) {myGLCD.printNumF(Fuel, 1, 225, 110,'.',4); Fuel_last=Fuel;} //else myGLCD.print("MAX", 210, 110); if ((kmTrip != kmTrip_last) || reNew) {myGLCD.printNumF(kmTrip, 1, 60, 145,'.',5); kmTrip_last=kmTrip;} if ((FuelTrip != FuelTrip_last) || reNew) {myGLCD.printNumF(FuelTrip, 1, 210, 145,'.',5); FuelTrip_last=FuelTrip;} if ((PumpRPM != PumpRPM_last) || reNew) {myGLCD.printNumI(PumpRPM, 230, 180,4); PumpRPM_last=PumpRPM;} if ((RPM != RPM_last) || reNew) {myGLCD.printNumI(RPM, 230, 215,4); RPM_last=RPM;} if ((Fuel2 != Fuel2_last) || reNew) {myGLCD.printNumF(Fuel2, 1, 10, 215,'.',4); Fuel2_last=Fuel2;} if ((Temp != Temp_last) || reNew) {myGLCD.printNumI(Temp, 415, 40, 3); Temp_last=Temp;} if ((TempOil != TempOil_last) || reNew) {myGLCD.printNumI(TempOil, 415, 75, 3); TempOil_last=TempOil;} if ((TempFuel != TempFuel_last) || reNew) {myGLCD.printNumI(TempFuel, 415, 110,3); TempFuel_last=TempFuel;} myGLCD.printNumI(sensors.getTempCByIndex(0), 415, 145 , 3); if ((t != t_last) || reNew) {myGLCD.printNumI(t, 415, 180, 3); t_last=t;} if ((TempAir != TempAir_last) || reNew) {myGLCD.printNumI(TempAir, 415, 215, 3); TempAir_last=TempAir;} reNew = 0; } //---------------------------------------------------------- //страниц INF1 //---------------------------------------------------------- if (currentPage == '1') { if ((StaDaliv != StaDaliv_last) || reNew) {myGLCD.printNumF(StaDaliv,1, 385, 40,'.', 4); StaDaliv_last=StaDaliv;} if ((DesInj != DesInj_last) || reNew) {myGLCD.printNumF(DesInj,1, 385, 75, '.', 4); DesInj_last=DesInj;} if ((ActInj != ActInj_last) || reNew) {myGLCD.printNumF(ActInj,1, 385, 110,'.', 4); ActInj_last=ActInj;} if ((DesaInjQua != DesaInjQua_last) || reNew) {myGLCD.printNumF(DesaInjQua,1, 385, 145,'.', 4);DesaInjQua_last=DesaInjQua;} if ((InjQua != InjQua_last) || reNew) {myGLCD.printNumF(InjQua,1, 385, 180,'.', 4); InjQua_last=InjQua;} if ((MAF != MAF_last) || reNew) {myGLCD.printNumI(MAF, 170, 215, 4); MAF_last=MAF;} if ((h != h_last) || reNew) {myGLCD.printNumF(h, 1, 430, 215, 3); h_last=h;} reNew = 0; } //---------------------------------------------------------- //страниц INF2 //---------------------------------------------------------- if (currentPage == '2') { if ((BoostPres != BoostPres_last) || reNew) {myGLCD.printNumF(BoostPres,1, 400, 40,'.', 4); BoostPres_last=BoostPres;} if ((BoostPresCom != BoostPresCom_last) || reNew) {myGLCD.printNumF(BoostPresCom,1, 400, 75,'.', 4); BoostPresCom_last=BoostPresCom;} if ((EGRmg != EGRmg_last) || reNew) {myGLCD.printNumI(EGRmg, 400, 110, 4); EGRmg_last=EGRmg;} if ((EGRPul != EGRPul_last) || reNew) {myGLCD.printNumF(EGRPul,1, 400, 145,'.', 4); EGRPul_last=EGRPul;} if ((SolenPul != SolenPul_last) || reNew) {myGLCD.printNumF(SolenPul, 1, 400, 180,'.', 4); SolenPul_last=SolenPul;} if ((SolenPre != SolenPre_last) || reNew) {myGLCD.printNumF(SolenPre, 0, 400, 215,'.', 4); SolenPre_last=SolenPre;} reNew = 0; } //reNew = 0; } void sendMessagePCM(const byte &command) { #ifdef debugPCM Serial.print (F("Send request ")); Serial.print (textRequest[command]); Serial.print (F(" to PCM ")); Serial.println (millis()); #endif if (command != INIT) {NOanswer_timer = 1; prev_NOanswer = curmillis;} //т.к. сейчас будем делать запрос, то запускаем таймер контроля неответов byte size = PCM_Message_TX[command][0]; const byte siZe = size+4; byte Mes[siZe]; byte Checksum = 0; for(byte i=0; i<siZe; i++) { if (i==0) {Mes[i]=size; bitWrite(Mes[i], 7 , 1);} if (i==1) Mes[i] = PCM_address; if (i==2) Mes[i] = DIAG_address; if (i==3) {for (byte t=1; t<size+1; t++ ) { Mes[i]=PCM_Message_TX [command][t]; Checksum+=Mes[i] ; K_LINE_PCM.write (Mes[i]); if (command == INIT) delay (5); else delay (delaybyte_TX); K_LINE_PCM.read(); i++;}} if (i!=siZe-1) Checksum+=Mes[i]; else Mes[i] = Checksum; K_LINE_PCM.write (Mes[i]); if (command == INIT) delay (5); else delay (delaybyte_TX); K_LINE_PCM.read(); } }// end sendMessagePCM void receiveGAUGE () { while(InitGauge==1){ if (K_LINE_GAUGE.available()) { byte inByte = K_LINE_GAUGE.read(); #ifdef debugGAUGE Serial.print(" "); Serial.print(inByte,HEX); #endif if (inByte==0x80) {K_LINE_GAUGE.write (0x7F); delay (1);} if (inByte==0xF0) { for (byte i=0; i<sizeof(PIDgauge); i++) { K_LINE_GAUGE.write (PIDgauge[i]); delay (1);} InitGauge=2; NoconnectsGAUGE = 0;}}} bool MessageParse = 0; bool dataMessageEND = 0; bool dataMessageOK = 0; byte headerGAUGE = 0; byte numberbyte = 0; while (InitGauge==2 && !MessageParse && flagneedGAUGE) { if (!dataMessageOK) { if (K_LINE_GAUGE.read() == 0x23 && headerGAUGE ==0) {headerGAUGE=1; delay (waitbyte_gauge); } if (K_LINE_GAUGE.read() == 0xA1 && headerGAUGE ==1) {headerGAUGE=2; delay (waitbyte_gauge);} else {headerGAUGE =0;} if (K_LINE_GAUGE.read() == 0x04 && headerGAUGE ==2) {headerGAUGE=3; delay (waitbyte_gauge);} else {headerGAUGE =0;} if (headerGAUGE ==3) {dataMessageOK = 1; headerGAUGE =0;} numberbyte=0;} else { if (K_LINE_GAUGE.available()>0) { MessageRxGauge[numberbyte] = K_LINE_GAUGE.read(); numberbyte++; delayMicroseconds (250);} if (numberbyte==34) {dataMessageEND = 1; dataMessageOK = 0; }} if (dataMessageEND) { int crc = ( ( unsigned int )MessageRxGauge[32] << 8 ) | MessageRxGauge[33]; // парсинг контрольной суммы из 2 последних байт int CRC =200; for (int i = 0; i < 32; i++) CRC = CRC + MessageRxGauge[i]; // подсчет контрольной суммы байт от 0 до 31 #ifdef debugGAUGE Serial.print (" ReceiveGauge: "); for (int i = 0; i < 34; i++) { Serial.print(MessageRxGauge[i],HEX); Serial.print (" ");} #endif //при получении сообщения БЕЗ ошибок с данными от панели приборов, запишем в переменные остаток топлива и пробег if (CRC==crc) { #ifdef debugGAUGE Serial.println (" OK!!!"); #endif flagneedGAUGE = 0; Fuel2 = MessageRxGauge[16]/2.0; if (!flagFuelIGN) { Fuel = MessageRxGauge[16]/2.00; kmREFUELING=((float)Fuel*100.00)/(float)L100SR_TFT;} //стартовая запись литров в баке для подсчета затраченных литро else Fuel = MessageRxGauge[17]/2.0; //для устреднения болтания в баке закоментировать эту строку, а раскоментировать ниже //для усреднения болтания топлива в баке, раскоментировать, высчитывает среднее /*else { FuelZamer[ZamerNumber] = MessageRxGauge[17]/2.00; if (ZamerNumber==9) { Fuel = 0 ; for (int i = 0; i < 10; i++) Fuel = Fuel + FuelZamer[i]; Fuel = (float)Fuel/10.0;} ZamerNumber++; if (ZamerNumber>9) ZamerNumber = 0;} */ kmAge = (MessageRxGauge[23]+(MessageRxGauge[24]*256))/10.0; //суточный пробег с панели приборов //бак у меня на 59 литров, а датчик показывает максимально 53 литра. для этого эта формула //если у вас тоже датчик имеет лимит то подправте 53 на свой лимит. //если ваш датчик показывает одинаково с полным баком то закоментировать три нижние строки. if (Fuel<53){ if (!flagkmAgeIGN) { kmAgeIGN = kmAge; flagkmAgeIGN =1;} if (!flagFuelIGN) { FuelIGN = Fuel; Fuel_last = Fuel; flagFuelIGN = 1; }}} #ifdef debugGAUGE else Serial.println (" ERROR!!!"); #endif dataMessageEND = 0; MessageParse = 1; NoconnectsGAUGE = 0;}} // if (curmillis - prevNoconnect > 500) {NoconnectsGAUGE ++ ; if (NoconnectsGAUGE>=10){ // #ifdef debugGAUGE // Serial.println (F(" Connect GAUGE failed!!! ")) ; // #endif // NoconnectsGAUGE = 0 ;InitGauge = 0 ; } prevNoconnect = curmillis; } InitBusGAUGE (); }// end receiveGAUGE void InitBusGAUGE () { if (InitGauge == 0){ #ifdef debugGAUGE Serial.println ("Send startsession - address Gauge"); #endif K_LINE_GAUGE.end(); pinMode(TX_gauge, OUTPUT); digitalWrite (TX_gauge, HIGH); // BUS IDLE InitGauge = 5; prevInitbusGauge = curmillis; } if (InitGauge == 5 && curmillis - prevInitbusGauge>1500) {InitGauge = 6;} // BUS IDLE if (InitGauge == 6) { byte boudrate = 1000/BAUD; digitalWrite (TX_gauge, LOW); delay (boudrate); // старт бит for (byte i=0; i<8; i++){digitalWrite (TX_gauge, bitRead(addressGUAGE, i)); delay (boudrate);} // биты тела адреса digitalWrite (TX_gauge, HIGH); delay (boudrate); // стоп бит K_LINE_GAUGE.begin(9600); InitGauge = 1; } } #if defined debugPCM or defined debugGAUGE void printDebugRX (const byte &inbyte) {if (inbyte<=15) Serial.print(F("0")); Serial.print (inbyte, HEX); Serial.print (F(" "));} #endif #ifdef debugPCM void printDebugRX_CSgood(){ if (MessageRx_PCM[n]==0xC1 && MessageRx_PCM[n+1]==0x6B && MessageRx_PCM[n+2]==0x8F) {Serial.println (F(" Initialization OK!!!!")); } else if (MessageRx_PCM[n]==0x58 && MessageRx_PCM[n+1]==0x00) {Serial.println (F(" NO DTC "));} else if (MessageRx_PCM[n]==0x58 && MessageRx_PCM[n+1] >0x00) {Serial.println (F(" DTC is found!"));} else if (MessageRx_PCM[n]==0x54 && MessageRx_PCM[n+1]==0xFF && MessageRx_PCM[n+2]==0x00){Serial.println (F(" DTC CLEARED "));} else if (MessageRx_PCM[n]==0x61 && MessageRx_PCM[n+1]==0x01) {Serial.println (F(" Receive PCM DATAstream"));}} #endif void Menu () { TouchHOME(); if (currentPage == '0') { TouchINF1(); TouchINF2(); TouchCHECK(); } if (currentPage == '1') { TouchINF2(); TouchCHECK(); } if (currentPage == '2') { TouchINF1(); TouchCHECK(); } if (currentPage == '3') { TouchREAD(); TouchERASE(); }} void drawHomeScreen() { line() ; Watch (); //myGLCD.print(":", 290, 5); myGLCD.print("/", 115, 7); myGLCD.print("/", 160, 7); myGLCD.setTextColor(RED, BLACK); // цвет линии и текста красный myGLCD.drawLine(295,35,295,248); // линия вертикальная myGLCD.drawLine(145,35,145,178); // линия вертикальная myGLCD.drawLine(80,178,80,247); // линия вертикальная myGLCD.print("L/H", 10, 40); myGLCD.print("L/A", 148, 40); myGLCD.print("L/V", 10, 75); myGLCD.print("L/M", 148, 75); myGLCD.print("D/K", 10, 110); myGLCD.print("D/L", 148, 110); myGLCD.print("V/K", 10, 145); myGLCD.print("V/L", 148, 145); myGLCD.print("PUMP RPM", 82, 180); myGLCD.print("ENGI RPM", 82, 215); myGLCD.print("D/L/A", 10, 180); myGLCD.print("Motor C", 300, 40); myGLCD.print("OIL C", 300, 75); myGLCD.print("FUEL C", 300, 110); myGLCD.print("INTER C", 300, 145); myGLCD.print("EXTER C", 300, 180); myGLCD.print("INTAIR C", 300, 215); //myGLCD.setTextColor(RED); myGLCD.drawRoundRect (15, 255, 145, 310); myGLCD.print("INF 1", 55, 270); myGLCD.drawRoundRect (175, 255, 305, 310); myGLCD.print("INF 2", 215, 270); myGLCD.drawRoundRect (335, 255, 465, 310); myGLCD.print("CHECK", 365, 270); myGLCD.drawRoundRect (1, 1, 77, 37); myGLCD.print("HOME", 10, 7); myGLCD.print("Km/h", 410, 7); reNew = 1; } //------------------------------------------------- void drawscreen_one() { line() ; Watch (); //myGLCD.print(":", 290, 5); myGLCD.print("/", 115, 7); myGLCD.print("/", 160, 7); myGLCD.setTextColor(RED, BLACK); // цвет линии и текста красный myGLCD.print("Start of Delivery *CA:", 10, 40); myGLCD.print("Desir inject Start *CA:", 10, 75); myGLCD.print("Actua Inject Start *CA:", 10, 110); myGLCD.print("Desir Inject Quan mg/s:", 10, 145); myGLCD.print("Actu Inject Quant mg/s:", 10, 180); myGLCD.print("MAF mg/s:", 10, 215); myGLCD.print("Humedad %:", 255, 215); //myGLCD.setTextColor(RED); myGLCD.drawRoundRect (175, 255, 305, 310); myGLCD.print("INF 2", 215, 270); myGLCD.drawRoundRect (335, 255, 465, 310); myGLCD.print("CHECK", 365, 270); myGLCD.drawRoundRect (1, 1, 77, 37); myGLCD.print("HOME", 10, 7); myGLCD.print("Km/h", 410, 7); reNew = 1; } //------------------------------------------------- void drawscreen_two() { line() ; Watch (); //myGLCD.print(":", 290, 5); myGLCD.print("/", 115, 7); myGLCD.print("/", 160, 7); myGLCD.setTextColor(RED, BLACK); // цвет линии и текста красный myGLCD.print("Boost Press Bar:", 10, 40); myGLCD.print("Boost Press Com Bar:", 10, 75); myGLCD.print("EGR command mg/s:", 10, 110); myGLCD.print("EGR Pulse Ratio %:", 10, 145); myGLCD.print("Solenoide Pulse %:", 10, 180); myGLCD.print("Solenoide Boost %:", 10, 215); //myGLCD.setColor(RED); myGLCD.drawRoundRect (15, 255, 145, 310); myGLCD.print("INF 1", 55, 270); myGLCD.drawRoundRect (335, 255, 465, 310); myGLCD.print("CHECK", 365, 270); myGLCD.drawRoundRect (1, 1, 77, 37); myGLCD.print("HOME", 10, 7); myGLCD.print("Km/h", 410, 7); reNew = 1; } //---------------------------------------------------------------------------- void drawscreen_three() { Watch (); //myGLCD.print(":", 290, 5); myGLCD.print("/", 115, 7); myGLCD.print("/", 160, 7); myGLCD.setTextColor(RED, BLACK); // цвет линии красный myGLCD.drawLine(1,35,479,35); // линия горизонтальная myGLCD.drawLine(1,248,479,248); // линия горизонтальная //myGLCD.setTextColor(RED); myGLCD.drawRoundRect (15, 255, 145, 310); myGLCD.print("ERASE", 55, 270); myGLCD.drawRoundRect (335, 255, 465, 310); myGLCD.print("READ", 365, 270); myGLCD.drawRoundRect (1, 1, 77, 37); myGLCD.print("HOME", 10, 5); reNew = 1; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //кнопки тач . координаты и переходы ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void TouchHOME(){ TSPoint p = ts.getPoint(); pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); if (p.z > 10 && p.z < 1000) {if (p.x > 140 && p.x < 320 && p.y > 140 && p.y < 260 && p.z > MINPRESSURE && p.z < MAXPRESSURE) { myGLCD.drawRoundRect (1, 1, 77, 37); currentPage = '0'; request = PID; RequestPeriod = 10; prevRequest = curmillis; // на PCM в этом окне посылается запрос текущих параметров myGLCD.clrScr(); drawHomeScreen(); x = 0; y = 0; p.z = 0;}}} void TouchINF1(){ TSPoint p = ts.getPoint(); pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); if (p.z > 10 && p.z < 1000) { if (p.x > 150 && p.x < 450 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE) { myGLCD.drawRoundRect (15, 255, 145, 310); currentPage = '1'; request = PID; RequestPeriod = 10; prevRequest = curmillis; // на PCM в этом окне посылается запрос текущих параметров myGLCD.clrScr(); drawscreen_one(); x = 0; y = 0; p.z = 0;}}} void TouchINF2(){ TSPoint p = ts.getPoint(); pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); if (p.z > 10 && p.z < 1000) { if (p.x > 450 && p.x < 680 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE) { myGLCD.drawRoundRect (175, 255, 305, 310); currentPage = '2'; request = PID; RequestPeriod = 600; prevRequest = curmillis; // на PCM в этом окне посылается запрос текущих параметров myGLCD.clrScr(); drawscreen_two(); x = 0; y = 0; p.z = 0;}}} void TouchCHECK(){ TSPoint p = ts.getPoint(); pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); if (p.z > 10 && p.z < 1000) { if (p.x > 690 && p.x < 950 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE) { myGLCD.drawRoundRect (335, 255, 465, 310); currentPage = '3'; // request = DTCREAD; RequestPeriod = 10; prevRequest = curmillis; // на PCM в этом окне посылается запрос чтения ошибок myGLCD.clrScr(); drawscreen_three(); x = 0; y = 0; p.z = 0;}}} void TouchREAD(){ TSPoint p = ts.getPoint(); pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); if (p.z > 10 && p.z < 1000) { if (p.x > 690 && p.x < 950 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE) { myGLCD.drawRoundRect (335, 255, 465, 310); request = DTCREAD; RequestPeriod = 300; prevRequest = curmillis; // на PCM при нажатии этой кнопки посылается запрос чтения ошибок x = 0; y = 0; p.z = 0;}}} void TouchERASE(){ TSPoint p = ts.getPoint(); pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); if (p.z > 10 && p.z < 1000) { if (p.x > 150 && p.x < 450 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE) {myGLCD.drawRoundRect (15, 255, 145, 310); request = DTCERASE; RequestPeriod = 300; prevRequest = curmillis; // на PCM при нажатии этой кнопки посылается запрос удаления ошибок myGLCD.clrScr(); drawscreen_three(); myGLCD.print("DTC BORRADO", 180, 145); x = 0; y = 0; p.z = 0;}}} //////////////////////////////////////////////////////////////////////////////////////// //прорисовка линий /////////////////////////////////////////////////////////////////////////////////////// void line() { //myGLCD.setTextColor(RED); // цвет линии красный myGLCD.drawLine(1,35,479,35); // линия горизонтальная myGLCD.drawLine(1,73,479,73); // линия горизонтальная myGLCD.drawLine(1,108,479,108); // линия горизонтальная myGLCD.drawLine(1,143,479,143); // линия горизонтальная myGLCD.drawLine(1,178,479,178); // линия горизонтальная myGLCD.drawLine(1,212,479,212); // линия горизонтальная myGLCD.drawLine(1,248,479,248); // линия горизонтальная } void Watch (){ DateTime now = rtc.now(); int minut = now.minute(); int hour = now.hour(); int mon = now.month(); int date = now.day(); int Year = now.year(); static int minut_last; static int hour_last; static int mon_last; static int date_last; static int Year_last; myGLCD.setTextColor(WHITE, BLACK); //белый цвет цифры if (date != date_last || reNew){ myGLCD.printNumI(date, 85, 7, 2, '0'); date_last = date; } if (mon!=mon_last || reNew){myGLCD.printNumI(mon, 130, 7, 2, '0'); mon_last = mon; } if (Year!=Year_last || reNew) { myGLCD.printNumI(Year, 175, 7); Year_last = Year; } if (hour!=hour_last || reNew){ myGLCD.printNumI(hour, 255, 7, 2, '0'); hour_last = hour; } if (minut!=minut_last || reNew ){ myGLCD.printNumI(minut, 300, 7, 2, '0'); minut_last = minut; } } void Temperature (){ h = dht.readHumidity(); t = dht.readTemperature(); sensors.requestTemperatures(); }скетч для определения адреса ds18b20
#include <OneWire.h> OneWire ds(22); // on pin 10 (a 4.7K resistor is necessary) void setup(void) { Serial.begin(115200); } void loop(void) { byte i; byte present = 0; byte type_s; byte data[12]; byte addr[8]; float celsius, fahrenheit; if ( !ds.search(addr)) { Serial.println("No more addresses."); Serial.println(); ds.reset_search(); delay(250); return; } Serial.print("ROM ="); for( i = 0; i < 8; i++) { Serial.write(' '); Serial.print(addr[i], HEX); } if (OneWire::crc8(addr, 7) != addr[7]) { Serial.println("CRC is not valid!"); return; } Serial.println(); // the first ROM byte indicates which chip switch (addr[0]) { case 0x10: Serial.println(" Chip = DS18S20"); // or old DS1820 type_s = 1; break; case 0x28: Serial.println(" Chip = DS18B20"); type_s = 0; break; case 0x22: Serial.println(" Chip = DS1822"); type_s = 0; break; default: Serial.println("Device is not a DS18x20 family device."); return; } ds.reset(); ds.select(addr); ds.write(0x44, 1); // start conversion, with parasite power on at the end delay(1000); // maybe 750ms is enough, maybe not // we might do a ds.depower() here, but the reset will take care of it. present = ds.reset(); ds.select(addr); ds.write(0xBE); // Read Scratchpad Serial.print(" Data = "); Serial.print(present, HEX); Serial.print(" "); for ( i = 0; i < 9; i++) { // we need 9 bytes data[i] = ds.read(); Serial.print(data[i], HEX); Serial.print(" "); } Serial.print(" CRC="); Serial.print(OneWire::crc8(data, 8), HEX); Serial.println(); // Convert the data to actual temperature // because the result is a 16 bit signed integer, it should // be stored to an "int16_t" type, which is always 16 bits // even when compiled on a 32 bit processor. int16_t raw = (data[1] << 8) | data[0]; if (type_s) { raw = raw << 3; // 9 bit resolution default if (data[7] == 0x10) { // "count remain" gives full 12 bit resolution raw = (raw & 0xFFF0) + 12 - data[6]; } } else { byte cfg = (data[4] & 0x60); // at lower res, the low bits are undefined, so let's zero them if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms //// default is 12 bit resolution, 750 ms conversion time } celsius = (float)raw / 16.0; fahrenheit = celsius * 1.8 + 32.0; Serial.print(" Temperature = "); Serial.print(celsius); Serial.print(" Celsius, "); Serial.print(fahrenheit); Serial.println(" Fahrenheit"); }Chip = DS18B20
Data = 1 89 1 4B 46 7F FF C 10 E CRC=E
Temperature = 24.56 Celsius, 76.21 Fahrenheit
No more addresses.
в верху добавил глянь
щас добавлю t. а где адрес то? ROM =
ROM = 28 FF A6 19 A8 15 1 D2
Chip = DS18B20
Data = 1 7E 1 4B 46 7F FF C 10 F9 CRC=F9
Temperature = 23.87 Celsius, 74.97 Fahrenheit
No more addresses.
//------------все для связи по K-line (тут настраиваем UARTы к-лайников, адреса блоков, скорость инита и отладку) #include <SoftwareSerial.h> #define TX_PCM 13 SoftwareSerial K_LINE_PCM (12, TX_PCM); //RХ,TХ //UART на котором висит K_line к PCM #define K_LINE_GAUGE Serial2 //UART на котором висит K_line к приборке #define TX_gauge 16 //TX UARTa на котором висит K_line к приборке #define PCM_address 0x11 // адрес PCM #define DIAG_address 0xF1 // адрес диагностики const byte BAUD=200; // init baudrate - скорость инита при подключении к приборке const byte addressGUAGE = 0xB8;// init GAUGE address - адрес щитка приборов при ините (установке связи) //#define debugPCM // раскомментировать эту строку для отладки в Serial порту обмена с PCM #define debugGAUGE // раскомментировать эту строку для отладки в Serial порту обмена co щитком приборов uint32_t curmillis = 0; // снимок текущего времени //------------------------------------------переменные для организации протокола связи с PCM uint32_t prevRequest = 0; // таймер периодических запосов на PCM uint16_t RequestPeriod = 3500; // периодичность запросов на PCM uint32_t prevRESETheader=0; // таймер сброса сообщения, если данные оборвались посередине сообщения bool RESETheader_timer; // таймер сброса сообщения, если данные оборвались посередине сообщения uint32_t prev_NOanswer=0; // таймер контроля неответов от ЭБУ после подачи запросов bool NOanswer_timer = 0; // таймер контроля неответов от ЭБУ после подачи запросов byte noanswers = 0; // количество подряд неответов от ЭБУ uint32_t timerdelay = 0; // таймер ожидания байт (для успевания появления данных в буфере UART) bool Delay = 0; // таймер ожидания байт (для успевания появления данных в буфере UART) byte waitbyte_RX = 1; // задержка, мс для успевания появления данных в буфере RX // (подрегулировать в зависимости от уровня жизнидеятельности на Марсе) #define TIMER_DELAY Delay = 0; timerdelay = curmillis // включение этого таймера byte delaybyte_TX = 1; // задержка между отправкой байт в запросах, мс byte header = 0; // состояние заголовка byte message_size = 0; // размер тела сообщения byte j = 3; // инкремент byte n = 3; // количество старт байт const byte bufsize = 150; // размер буфера принятого сообщения byte MessageRx_PCM [bufsize] = {0}; // буфер принятого сообщения byte crc =0; // байт контрольной суммы // возможные варианты запросов на ЭБУ: enum REQUEST {INIT, PID, DTCERASE, DTCREAD, PRESENT,}; // текстовки запросов для отладки char* textRequest[] = {"INIT", "PID_2101", "DTC_ERASE", "DTC_READ", "PRESENT",} ; // сами запросы byte PCM_Message_TX[][5] = { {1, 0x81, 0,0,0}, // запрос инициализации {2, 0x21,0x01, 0,0}, // запрос пид 2101 {3, 0x14,0xFF,0x00, 0}, // запрос на стирание ошибок {4, 0x18,0x00,0xFF,0x00 }, // запрос на чтение ошибок {1, 0x3E, 0,0,0}, // запрос присутствия }; byte request = INIT; // переменная, показывающая какой запрос будем делать //------------------------------------------ переменные для организации протокола связи со щитком приборов uint32_t prevNoconnect = 0; // таймер периодической проверки наличия связи со щитком приборов uint32_t prevInitbusGauge = 0; // таймер для инита щитка приборов byte NoconnectsGAUGE = 0 ; // счетчик неответов от щитка приборов byte InitGauge = 0; // автомат состояния инита щитка приборов int waitbyte_gauge = 4; byte MessageRxGauge[60] = {0}; // массив байтов принимаемого сообщения от щитка приборов byte PIDgauge[] = {0x02,0x11,0x00,0x13}; // запрос параметоров щитка приборов bool flagneedGAUGE = 1; //-------------------------------------------переменные бортовика float L100M = 0; float L100M_last = 1; //расход на 100 км измеренный за поездку float L100 = 0; float L100_last = 1; //мгновенный расход литров на 100км float LHor = 0; float LHor_last = 1; //мгновенный расход топлива литров в час float L100SR = 0; //расход литров на 100км измеренный раз в интервал kmL float L100SR_TFT = 0; float L100SR_TFT_last = 1; // самый средний из расходов на 100км, он выводится на экран int L100_Eeprom[11]= {10,10,10,10,10,10,10,10,10,10,10}; int FuelZamer[10]= {0}; // массив для измерения уровня (количества) топлива int ZamerNumber = 0; // номер замера уровня (количества) топлива int n_eeprom = 0; // текущий адрес ячейки еепром для записи расхода int MAF = 0; int MAF_last = 1; //26,27 байты Sensor de flujo de aire en masa float BoostPres = 0; float BoostPres_last = 1; //28,29 байты Presión de refuerzo int RPM = 0; int RPM_last = 1; //32,33 байты Velocidad del motor int EGRmg = 0; int EGRmg_last = 1; //34,35 байты Comando EGR (Comando de recirculación de gases de escape) float BoostPresCom = 0; float BoostPresCom_last = 1;//38,39 байты Comando de presión de refuerzo int Speed = 0; int Speed_last = 1; //44,45 байты Velocidad del vehículo float DesaInjQua = 0; float DesaInjQua_last = 1; //50,51 байты Cantidad de inyección deseada float InjQua = 0; float InjQua_last = 1; //52,53 байты Cantidad de la inyección float StaDaliv = 0; float StaDaliv_last = 1; //54,55 байты Inicio de la entrega int PumpRPM = 0; int PumpRPM_last = 1; //56,57 байты Velocidad de la bomba float EGRPul = 0; float EGRPul_last = 1; //62,63 байты Relación de impulsos EGR (recirculación de gases de escape float SolenPul = 0; float SolenPul_last = 1; //64,65 байты Velocidad de solenoide de control de nivel de remolino Relación de impulsos float SolenPre = 0; float SolenPre_last = 1; //70,71 байты Relación de impulsos Presión Electroválvula de presión float DesInj = 0; float DesInj_last = 1; //72,73 байты Inyección deseada Inicio float ActInj = 0; float ActInj_last = 1; //16,17 байты Inicio de la inyección real int TempAir = 0; int TempAir_last = 1; //74,75 байты Temperatura del aire de admisión int Temp = 0; int Temp_last = 1; //14,15 байты Temperatura del refrigerante int TempOil = 0; int TempOil_last = 1; //18,19 байты Temperatura del aceite del motor int TempFuel = 0; int TempFuel_last = 1; //58,59 байты Temperatura del combustible int IntTemp = 0; int IntTemp_last = 1; //Температура улицы //все что касается топлива float Fuel = 0; //остаток топлива float Fuel2 = 0; float Fuel2_last = 1; //остаток мгновенного топлива байт 16 , датчика в баке int FuelIGN = 0; // количество топлвива в баке на момент включения зажигания int Fuel_last = 0; // для формул bool flagFuelIGN = 0; // флаг записан ли остаток топлива в момент вкл. зажигания float FuelTrip = 0; float FuelTrip_last = 1; // количество литров топлива, израсходованное за один цикл включения зажигания //все что касается километража float kmAge = 0; //пробег, полученный со щитка приборов int kmAgeIGN = 0; //пробег который был в момент включения зажигания int kmAge_last = 0; // для формул bool flagkmAgeIGN = 0; //флаг записан ли пробег в момент вкл. зажигания float kmTrip = 0; float kmTrip_last = 1; //пробег за один цикл включения зажигания int kmL = 10; // интервал, через который будет происходить обновление среднего расхода на 100км int km = 0; // переменная для расчетов int kmeeprom = 10; // интервал, через который будет происходить подсчет среднеарифмитического расхода L100SR_TFT int kmTFT = 0; // переменная для расчетов периодического подсчета среднеарифмитического расхода топлива L100SR_TFT int kmREFUELING = 0; int kmREFUELING_last = 1; // пробег до заправки на остатке топлива unsigned long prevWatch = 0; unsigned long prevDvoet = 0; unsigned long prevData = 0; uint32_t prevGauge = 0; //----------------------------------------------для экрана #include <Adafruit_GFX.h> #include <MCUFRIEND_kbv.h> #include <UTFTGLUE.h>//use GLUE class and constructor #include "TouchScreen.h" #include <stdint.h> #include <SPI.h> #include <EEPROM.h> //MCUFRIEND_kbv tft; #include "Fonts/Chosence_Bold16pt7b.h"; #define MINPRESSURE 200 #define MAXPRESSURE 1000 //pin 20 SCL , 21 SDA датчик реального времени #include <Wire.h> #include "RTClib.h" RTC_DS3231 rtc; UTFTGLUE myGLCD(0x1581,A2,A1,A3,A4,A0); //all dummy args const int XP = 6, XM = A2, YP = A1, YM = 7; const int TS_LEFT = 136, TS_RT = 907, TS_TOP = 139, TS_BOT = 942; TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300); uint16_t ID; int x, y; char currentPage; float h; int h_last = 1; float t; int t_last = 1; bool Dvoet = 0; bool reNew = 0; #define BLACK 0x0000 #define WHITE 0xFFFF #define RED 0xF800 #define GREEN 0x07E0 //--------------------------------------датчики t byte DSaddress[] = {0x28, 0xFF, 0xA6, 0x19, 0xA8, 0x15, 0x01, 0xD2}; //датчик внутринней температуры и влаги #include "DHT.h" #define DHTPIN 26 #define DHTTYPE DHT22 DHT dht(DHTPIN, DHTTYPE); #include <OneWire.h> #define ONE_WIRE_BUS 22 OneWire ds(ONE_WIRE_BUS); void setup() { uint16_t ID = myGLCD.readID(); if (ID == 0xD3D3) ID = 0x1581; // write-only shield myGLCD.begin(ID); myGLCD.InitLCD(3); myGLCD.clrScr(); myGLCD.setFont(&Chosence_Bold16pt7b); //myGLCD.fillScreen(WHITE); //myGLCD.setTextColor(WHITE, BLACK); //myGLCD.setBackColor(BLACK); Wire.begin(); rtc.begin(); dht.begin(); //загрузка стартовой страницы currentPage = '0'; drawHomeScreen(); //подсчет среднеарифметического усредненного расхода for (int i = 0; i < 11; i++) L100_Eeprom [i]= EEPROM.read(i); for (int i = 0; i < 11; i++) L100SR_TFT = L100SR_TFT + L100_Eeprom [i]; L100SR_TFT = (float)L100SR_TFT/110.0; if (L100SR_TFT<0) L100SR_TFT = 0; if (L100SR_TFT>99) L100SR_TFT = 99; // строка ниже используется для настройки даты и времени часов // раскомментировать, выставить времая и дату, залить в ардуино. в скетче закомментировать // обратно и залить еще раз, иначе каждый раз будет по новой выствлятся это же время и дата // (год, месяц, день, часы, минуты, секунды) //rtc.adjust(DateTime(2019, 7, 2, 10, 48, 0)); #if defined debugPCM or defined debugGAUGE Serial.begin(115200); #endif K_LINE_PCM.begin(10400); pinMode(TX_PCM, OUTPUT); } void loop() { curmillis = millis(); // снимок текущего времени if (curmillis - prevRequest > RequestPeriod && header == 0 && !flagneedGAUGE) { if (request == INIT) fastinit(); // при необходимости делаем переподключение к PCM else {sendMessagePCM(request); // отправляем на PCM текущий запрос if (request == PID) RequestPeriod = 600; if (request == DTCERASE || request == DTCREAD) RequestPeriod = 2500;} prevRequest = curmillis; } if (!flagneedGAUGE) {receivePCM ();} // приём сообщений от PCM receiveGAUGE (); // приём сообщений от щитка приборов if (header == 0) {Menu ();} if (curmillis - prevWatch > 4000) { Watch (); prevWatch = curmillis; Trip (); Temperature();} //if (curmillis - prevDvoet > 500) { if (!Dvoet) {myGLCD.setTextColor(WHITE); } else {myGLCD.setTextColor(BLACK); } myGLCD.print(":", 290, 5); prevDvoet = curmillis; Dvoet=!Dvoet;} if (millis() - prevDvoet > 500) { if (!Dvoet) {myGLCD.print(":", 290, 5);} else {myGLCD.print(" ", 290, 5);} prevDvoet = millis(); Dvoet=!Dvoet;} if (curmillis - prevGauge > 30000UL) {flagneedGAUGE = 1;prevGauge = curmillis; h = dht.readHumidity(); t = dht.readTemperature();} }// end loop void Trip () { if (flagkmAgeIGN){ FuelTrip = FuelIGN - Fuel; if (kmAge>kmAgeIGN) kmTrip = kmAge - kmAgeIGN; if (kmAge<kmAgeIGN) kmTrip = 2000 - (kmAgeIGN - kmAge); // 2000 это через сколько км у тебя суточный пробег сбрасывается на ноль, поменяй если другое число if (kmAge==kmAgeIGN) kmTrip = 0; //подсчет расхода на 100км за поездку L100M = ((float)FuelTrip*100.00)/(float)kmTrip; if (L100M<0) L100M = 0; if (L100M>99) L100M = 99; // ниже цикл считает среднеарифметический расход из еепром раз в пробег, указанный в переменной kmeeprom if (kmTrip-kmTFT>kmeeprom) {kmTFT = kmTrip; // тут считаем среднеарифметический усредненного расход из ячеек еепром for (int i = 0; i < 11; i++) L100_Eeprom [i]= EEPROM.read(i); for (int i = 0; i < 11; i++) L100SR_TFT = L100SR_TFT + L100_Eeprom [i]; L100SR_TFT = (float)L100SR_TFT/110.00; if (L100SR_TFT<0) L100SR_TFT = 0; if (L100SR_TFT>99) L100SR_TFT = 99;} // ниже цикл считает расход топлива за пробег, указанный в переменной kmL, здесь же запись в ячейки еепром if (kmTrip-km>kmL) {km=kmTrip; L100SR = ((float)(Fuel_last-Fuel)*100.00)/(float)kmL; // расход/100км - обновляется раз в 10км, меняется км в int kmL = 10; Fuel_last = Fuel; // сохранение параметров с последнего измерениея if (L100SR<0) L100SR = 0; if (L100SR>99) L100SR = 99; //расчет остатка километров в баке if (L100SR>0) kmREFUELING=((float)Fuel*100.0)/(float)L100SR; //если средний расход больше нуля, то расчитывать км в баке из него else kmREFUELING=((float)Fuel*100.00)/(float)L100SR_TFT; //если ноль или ментше то расчитывать км в баке с устредненного расхода // тут записываем L100SR последовательно в одну из 11 ячеек еепром //EEPROM.write (12,n_eeprom); // ЗДЕСЬ ВНИМАТЕЛЬНО. ЗАГРУЗИТЬ ПРОШИВКУ С ЭТОЙ СТРОКОЙ ОДИН РАЗ, ПОТОМ ЗАКОМЕНТИРОВАТЬ И ЕЩЁ РАЗ ЗАГРУЗИТЬ n_eeprom = EEPROM.read (12); // в ячейке 12 хранится № текущей ячейки для записи расхода, чтобы где остановился при выкл питания, от туда и продолжил EEPROM.write(n_eeprom, L100SR*10); n_eeprom++; if (n_eeprom>10) n_eeprom=0; EEPROM.write (12,n_eeprom); }}} void fastinit() { digitalWrite (TX_PCM, HIGH); // bus idle delay(1500); digitalWrite (TX_PCM, LOW); // first part fastinit (25 ms LOW) delay(25); digitalWrite (TX_PCM, HIGH); // second part fastinit (25 ms HIGH) delay(25); K_LINE_PCM.begin(10400); sendMessagePCM(INIT); // send start communication message } void receivePCM () { if (K_LINE_PCM.available() ){ // первый старт байт if (header == 0 && Delay){TIMER_DELAY ; MessageRx_PCM[0]=K_LINE_PCM.read(); if (MessageRx_PCM[0]!=0xFF && bitRead (MessageRx_PCM[0],7)){header = 1; RESETheader_timer = 1; prevRESETheader = curmillis; #ifdef debugPCM Serial.print (F("Receive PCM: ")); printDebugRX(MessageRx_PCM[0]); #endif } } // второй старт байт if (header == 1 && Delay){TIMER_DELAY ; MessageRx_PCM[1]=K_LINE_PCM.read(); #ifdef debugPCM printDebugRX (MessageRx_PCM[1]); #endif if (MessageRx_PCM[1]==DIAG_address){ header = 2;} else { #ifdef debugPCM Serial.println(F(" PCM Message fail address")); #endif header = 0; RESETheader_timer = 0;}} // третий старт байт if (header == 2 && Delay){ TIMER_DELAY ; MessageRx_PCM[2]=K_LINE_PCM.read(); #ifdef debugPCM printDebugRX (MessageRx_PCM[2]); #endif if (MessageRx_PCM[2]==PCM_address){ message_size = MessageRx_PCM[0]; prevRESETheader = curmillis; if (MessageRx_PCM[0] !=0x80) {header = 4; bitWrite (message_size, 7 , 0);j=3;n=3;} else {header = 3; j=4;n=4;} if (message_size > bufsize) message_size = bufsize; crc = 0;} else {header = 0; #ifdef debugPCM Serial.println(F("PCM Message fail address")); #endif RESETheader_timer = 0;} } // если размер сообщения указан в дополнительном байте (нулевой байт 0x80) читаем этот дополнительный байт: if (header == 3 && Delay){ TIMER_DELAY ; prevRESETheader = curmillis; MessageRx_PCM[3]=K_LINE_PCM.read(); #ifdef debugPCM printDebugRX(MessageRx_PCM[3]); #endif message_size = MessageRx_PCM[3]; if (message_size > bufsize) message_size = bufsize; crc = 0; header = 4; } // пишем тело сообщения if (header == 4 && Delay && j< message_size+n+1) { MessageRx_PCM[j] = K_LINE_PCM.read(); prevRESETheader = curmillis; if (j<message_size+n) crc+= MessageRx_PCM[j]; // подсчёт КС if (j==message_size+n) header = 5; TIMER_DELAY ; #ifdef debugPCM printDebugRX(MessageRx_PCM[j]); #endif j++; } } // сообщение приняли, действуем if (header == 5) {TIMER_DELAY ; #ifdef debugPCM Serial.println(); #endif NOanswer_timer = 0; noanswers = 0; // сбрасываем таймер контроля неответов for(byte i = 0; i<n; i++) crc+=MessageRx_PCM[i]; // прибавляем к контрольной сумме старт байты // если контрольная сумма верна: if ( crc == MessageRx_PCM[message_size+n]) { #ifdef debugPCM Serial.print (F("Received message is OK! Checksum is correct!")); Serial.print (F(" ")); Serial.println (millis()); // Если КС совпала, тут чёнибудь нужное делаем printDebugRX_CSgood(); #endif if (MessageRx_PCM[n]==0xC1 && MessageRx_PCM[n+1]==0x6B && MessageRx_PCM[n+2]==0x8F) { if (currentPage!=3) {request = PID; RequestPeriod = 70;} else request = PRESENT, RequestPeriod = 4000; prevRequest = curmillis; // receive good INIT } else if (MessageRx_PCM[n]==0x58) Troublecodes (); // DTC else if (MessageRx_PCM[n]==0x54 && MessageRx_PCM[n+1]==0xFF && MessageRx_PCM[n+2]==0x00){ request = PRESENT; RequestPeriod = 4000; prevRequest = curmillis;} // DTC are cleared else if (MessageRx_PCM[n]==0x61 && MessageRx_PCM[n+1]==0x01) {dataVars() ; RequestPeriod = 70; prevRequest = curmillis; } // receive DataStream } // если контрольная сумма не совпала: #ifdef debugPCM else Serial.println("CRC fail!!!" ); #endif message_size = 0; header=0; RESETheader_timer = 0; j=3; crc = 0; } // таймер ожидания байт (для успевания появления данных в буфере UART) if (!Delay && curmillis - timerdelay > waitbyte_RX) Delay = 1; // таймер сброса целостности сообщения (если данные оборвались посередине сообщения) if (RESETheader_timer && curmillis - prevRESETheader > 200) { #ifdef debugPCM Serial.println(F("Message fail timeout")); #endif RESETheader_timer = 0; header = 0;} // если нет ответа после запроса: +1 к счетчику неответов. Если накопилось 6 и более: делаем реинит. if (request!=INIT && NOanswer_timer && curmillis - prev_NOanswer > RequestPeriod - RequestPeriod/10) { NOanswer_timer = 0; noanswers++; if (noanswers>=6) { noanswers = 0; request = INIT; RequestPeriod = 3500;} } }// end receivePCM void Troublecodes () { if (MessageRx_PCM[n]==0x58 && MessageRx_PCM[n+1]==0x00){ myGLCD.clrScr(); drawscreen_three(); myGLCD.print("NO DTC", 180, 145); } // при получении сообщения о наличии ошибок DTC разберем сообщение выведем на экран ошибки if (MessageRx_PCM[n]==0x58 && MessageRx_PCM[n+1]>0){ myGLCD.clrScr(); drawscreen_three(); for (int i=0; i<MessageRx_PCM[n+8-7]; i++ ) { int y = i*35; bool nolA=0; bool nolB =0; if (!bitRead(MessageRx_PCM[n+11-7+(i*3)],6) && bitRead(MessageRx_PCM[n+11-7+(i*3)],7)){ myGLCD.setTextColor(GREEN, BLACK); myGLCD.print(" -Passive-", 300, (75+y));} // если DTC пасивныый делаем цвет зеленый if (bitRead(MessageRx_PCM[n+11-7+(i*3)],7) && bitRead(MessageRx_PCM[n+11-7+(i*3)],6)) { myGLCD.setTextColor(RED, BLACK); myGLCD.print(" -Active-", 300, (75+y));} // если DTC активный, делаем цвет красный myGLCD.print("ERROR ", 50, (75+y)); myGLCD.printNumI((i+1), 150, (75+y)); if (!bitRead(MessageRx_PCM[n+9-7+(i*3)],6) && !bitRead(MessageRx_PCM[n+9-7+(i*3)],7)) myGLCD.print(": P", 170, (75+y)); if (bitRead(MessageRx_PCM[n+9-7+(i*3)],6) && !bitRead(MessageRx_PCM[n+9-7+(i*3)],7)) myGLCD.print(": C", 170, (75+y)); if (!bitRead(MessageRx_PCM[n+9-7+(i*3)],6) && bitRead(MessageRx_PCM[n+9-7+(i*3)],7)) myGLCD.print(": B", 170, (75+y)); if (bitRead(MessageRx_PCM[n+9-7+(i*3)],6) && bitRead(MessageRx_PCM[n+9-7+(i*3)],7)) myGLCD.print(": U", 170, (75+y)); if (MessageRx_PCM[n+9-7+(i*3)]==0x00) {myGLCD.print("00", 230, (75+y)); nolA = 1;} if (MessageRx_PCM[n+9-7+(i*3)]<=0x0F&&MessageRx_PCM[n+9-7+(i*3)]!=0) {myGLCD.print("0", 230, (75+y)); nolA = 1;} if (nolA)myGLCD.print(String (MessageRx_PCM[n+9-7+(i*3)],HEX), 246, (75+y)); else myGLCD.print(String (MessageRx_PCM[n+9-7+(i*3)],HEX), 230, (75+y)); if (MessageRx_PCM[n+10-7+(i*3)]==0x00) {myGLCD.print("00", 262, (75+y)); nolB = 1;} if (MessageRx_PCM[n+10-7+(i*3)]<=0x0F&&MessageRx_PCM[n+10-7+(i*3)]!=0) {myGLCD.print("0", 262, (75+y)); nolB = 1;} if (nolB)myGLCD.print(String (MessageRx_PCM[n+10-7+(i*3)]),HEX, 278, (75+y)); else myGLCD.print(String (MessageRx_PCM[n+10-7+(i*3)],HEX), 262, (75+y));}} request = PRESENT; RequestPeriod = 4000; prevRequest = curmillis; } void dataVars() { //Barom = MessageRx_PCM[39]; L100 = (float)LHor*100.0/(float)Speed; LHor = (float)RPM* (float)InjQua*2.00/1000.0*60.00/1000.0/0.85; MAF = ((MessageRx_PCM[n+22]*256)+MessageRx_PCM[n+23])/10; BoostPres = ((MessageRx_PCM[n+24]*256)+MessageRx_PCM[n+25])/1000.0; RPM = (MessageRx_PCM[n+35-7]*256)+MessageRx_PCM[n+36-7]; EGRmg = ((MessageRx_PCM[n+37-7]*256)+MessageRx_PCM[n+38-7])/10.0; BoostPresCom = ((MessageRx_PCM[n+41-7]*256)+MessageRx_PCM[n+42-7])/1000.0; Speed = ((MessageRx_PCM[n+47-7]*256)+MessageRx_PCM[n+48-7])/100; DesaInjQua = ((MessageRx_PCM[n+53-7]*256)+MessageRx_PCM[n+54-7])/100.0; InjQua = ((MessageRx_PCM[n+55-7]*256)+MessageRx_PCM[n+56-7])/100.0; StaDaliv = ((MessageRx_PCM[n+57-7]*256)+MessageRx_PCM[n+58-7])/100.0; PumpRPM = (MessageRx_PCM[n+59-7]*256)+MessageRx_PCM[n+60-7]; EGRPul = ((MessageRx_PCM[n+65-7]*256)+MessageRx_PCM[n+66-7])/100.0; SolenPul = ((MessageRx_PCM[n+67-7]*256)+MessageRx_PCM[n+68-7])/100.0; SolenPre = ((MessageRx_PCM[n+73-7]*256)+MessageRx_PCM[n+74-7])/100.0; DesInj = ((MessageRx_PCM[n+75-7]*3)+(MessageRx_PCM[n+76-7])/100.0)+0.3; ActInj = ((MessageRx_PCM[n+19-7]*3)+(MessageRx_PCM[n+20-7])/100.0)+0.3; //TempAir = ((MessageRx_PCM[n+77-7]*26)-278)+MessageRx_PCM[n+78-7]/10.0; //Temp = ((MessageRx_PCM[n+17-7]*26)-278)+MessageRx_PCM[n+18-7]/10.0; //TempOil = ((MessageRx_PCM[n+21-7]*26)-278)+MessageRx_PCM[n+22-7]/10.0; //TempFuel = ((MessageRx_PCM[n+61-7]*26)-278)+MessageRx_PCM[n+62-7]/10.0; //ниже идут расчетные формулы более точные чем те что закоментированы выше int A = 0; if (MessageRx_PCM[n+77-7]<=0x0A) A = 277; if (MessageRx_PCM[n+77-7]==0x0B || MessageRx_PCM[n+77-7]==0x0C) A = 278; if (MessageRx_PCM[n+77-7]>=0x0D) A = 279; double B = MessageRx_PCM[n+78-7]/10.0; double cel , drob ; drob = modf(B, &cel); if (drob>0.6) cel++; TempAir = ((MessageRx_PCM[n+77-7]*26)-A)+cel; if (MessageRx_PCM[n+17-7]<=0x0A) A = 277; if (MessageRx_PCM[n+17-7]==0x0B || MessageRx_PCM[n+17-7]==0x0C) A = 278; if (MessageRx_PCM[n+17-7]>=0x0D) A = 279; B = MessageRx_PCM[n+18-7]/10.0; drob = modf(B, &cel); if (drob>0.6) cel++; Temp = ((MessageRx_PCM[n+17-7]*26)-A)+cel; if (MessageRx_PCM[n+21-7]<=0x0A) A = 277; if (MessageRx_PCM[n+21-7]==0x0B || MessageRx_PCM[n+21-7]==0x0C) A = 278; if (MessageRx_PCM[n+21-7]>=0x0D) A = 279; B = MessageRx_PCM[n+22-7]/10.0; drob = modf(B, &cel); if (drob>0.6) cel++; TempOil = ((MessageRx_PCM[n+21-7]*26)-A)+cel; if (MessageRx_PCM[n+61-7]<=0x0A) A = 277; if (MessageRx_PCM[n+61-7]==0x0B || MessageRx_PCM[n+61-7]==0x0C) A = 278; if (MessageRx_PCM[n+61-7]>=0x0D) A = 279; B = MessageRx_PCM[n+62-7]/10.0; drob = modf(B, &cel); if (drob>0.6) cel++; TempFuel = ((MessageRx_PCM[n+61-7]*26)-A)+cel; //---------------------------------------------------------- //страниц HOME //---------------------------------------------------------- //myGLCD.setBackColor(RED); myGLCD.setTextColor(WHITE, BLACK); //myGLCD.setBackColor(RED); if ((Speed != Speed_last) || reNew) {myGLCD.printNumI(Speed, 360, 7, 3); Speed_last=Speed;} if (currentPage == '0') { if ((LHor != LHor_last) || reNew) {myGLCD.printNumF(LHor, 1, 75, 40, '.',4); LHor_last=LHor;} if ((L100 != L100_last) || reNew) {myGLCD.printNumF(L100, 1, 225, 40,'.',4 ); L100_last=L100;} if ((L100M != L100M_last) || reNew) {myGLCD.printNumF(L100M, 1, 75, 75,'.',4 ); L100M_last=L100M;} if ((L100SR_TFT != L100SR_TFT_last) || reNew) {myGLCD.printNumF(L100SR_TFT, 1, 225, 75,'.',4 ); L100SR_TFT_last=L100SR_TFT;} if ((kmREFUELING != kmREFUELING_last) || reNew) {myGLCD.printNumI(kmREFUELING, 90, 110,3 ); kmREFUELING_last=kmREFUELING;} //if (Fuel<53) if ((Fuel != Fuel_last) || reNew) {myGLCD.printNumF(Fuel, 1, 225, 110,'.',4); Fuel_last=Fuel;} //else myGLCD.print("MAX", 210, 110); if ((kmTrip != kmTrip_last) || reNew) {myGLCD.printNumF(kmTrip, 1, 60, 145,'.',5); kmTrip_last=kmTrip;} if ((FuelTrip != FuelTrip_last) || reNew) {myGLCD.printNumF(FuelTrip, 1, 210, 145,'.',5); FuelTrip_last=FuelTrip;} if ((PumpRPM != PumpRPM_last) || reNew) {myGLCD.printNumI(PumpRPM, 230, 180,4); PumpRPM_last=PumpRPM;} if ((RPM != RPM_last) || reNew) {myGLCD.printNumI(RPM, 230, 215,4); RPM_last=RPM;} if ((Fuel2 != Fuel2_last) || reNew) {myGLCD.printNumF(Fuel2, 1, 10, 215,'.',4); Fuel2_last=Fuel2;} if ((Temp != Temp_last) || reNew) {myGLCD.printNumI(Temp, 415, 40, 3); Temp_last=Temp;} if ((TempOil != TempOil_last) || reNew) {myGLCD.printNumI(TempOil, 415, 75, 3); TempOil_last=TempOil;} if ((TempFuel != TempFuel_last) || reNew) {myGLCD.printNumI(TempFuel, 415, 110,3); TempFuel_last=TempFuel;} if ((IntTemp != IntTemp_last) || reNew) {myGLCD.printNumI(TempFuel, 415, 145 , 3); IntTemp_last=IntTemp;} if ((t != t_last) || reNew) {myGLCD.printNumI(t, 415, 180, 3); t_last=t;} if ((TempAir != TempAir_last) || reNew) {myGLCD.printNumI(TempAir, 415, 215, 3); TempAir_last=TempAir;} reNew = 0; } //---------------------------------------------------------- //страниц INF1 //---------------------------------------------------------- if (currentPage == '1') { if ((StaDaliv != StaDaliv_last) || reNew) {myGLCD.printNumF(StaDaliv,1, 385, 40,'.', 4); StaDaliv_last=StaDaliv;} if ((DesInj != DesInj_last) || reNew) {myGLCD.printNumF(DesInj,1, 385, 75, '.', 4); DesInj_last=DesInj;} if ((ActInj != ActInj_last) || reNew) {myGLCD.printNumF(ActInj,1, 385, 110,'.', 4); ActInj_last=ActInj;} if ((DesaInjQua != DesaInjQua_last) || reNew) {myGLCD.printNumF(DesaInjQua,1, 385, 145,'.', 4);DesaInjQua_last=DesaInjQua;} if ((InjQua != InjQua_last) || reNew) {myGLCD.printNumF(InjQua,1, 385, 180,'.', 4); InjQua_last=InjQua;} if ((MAF != MAF_last) || reNew) {myGLCD.printNumI(MAF, 170, 215, 4); MAF_last=MAF;} if ((h != h_last) || reNew) {myGLCD.printNumF(h, 1, 430, 215, 3); h_last=h;} reNew = 0; } //---------------------------------------------------------- //страниц INF2 //---------------------------------------------------------- if (currentPage == '2') { if ((BoostPres != BoostPres_last) || reNew) {myGLCD.printNumF(BoostPres,1, 400, 40,'.', 4); BoostPres_last=BoostPres;} if ((BoostPresCom != BoostPresCom_last) || reNew) {myGLCD.printNumF(BoostPresCom,1, 400, 75,'.', 4); BoostPresCom_last=BoostPresCom;} if ((EGRmg != EGRmg_last) || reNew) {myGLCD.printNumI(EGRmg, 400, 110, 4); EGRmg_last=EGRmg;} if ((EGRPul != EGRPul_last) || reNew) {myGLCD.printNumF(EGRPul,1, 400, 145,'.', 4); EGRPul_last=EGRPul;} if ((SolenPul != SolenPul_last) || reNew) {myGLCD.printNumF(SolenPul, 1, 400, 180,'.', 4); SolenPul_last=SolenPul;} if ((SolenPre != SolenPre_last) || reNew) {myGLCD.printNumF(SolenPre, 0, 400, 215,'.', 4); SolenPre_last=SolenPre;} reNew = 0; } //reNew = 0; } void sendMessagePCM(const byte &command) { #ifdef debugPCM Serial.print (F("Send request ")); Serial.print (textRequest[command]); Serial.print (F(" to PCM ")); Serial.println (millis()); #endif if (command != INIT) {NOanswer_timer = 1; prev_NOanswer = curmillis;} //т.к. сейчас будем делать запрос, то запускаем таймер контроля неответов byte size = PCM_Message_TX[command][0]; const byte siZe = size+4; byte Mes[siZe]; byte Checksum = 0; for(byte i=0; i<siZe; i++) { if (i==0) {Mes[i]=size; bitWrite(Mes[i], 7 , 1);} if (i==1) Mes[i] = PCM_address; if (i==2) Mes[i] = DIAG_address; if (i==3) {for (byte t=1; t<size+1; t++ ) { Mes[i]=PCM_Message_TX [command][t]; Checksum+=Mes[i] ; K_LINE_PCM.write (Mes[i]); if (command == INIT) delay (5); else delay (delaybyte_TX); K_LINE_PCM.read(); i++;}} if (i!=siZe-1) Checksum+=Mes[i]; else Mes[i] = Checksum; K_LINE_PCM.write (Mes[i]); if (command == INIT) delay (5); else delay (delaybyte_TX); K_LINE_PCM.read(); } }// end sendMessagePCM void receiveGAUGE () { while(InitGauge==1){ if (K_LINE_GAUGE.available()) { byte inByte = K_LINE_GAUGE.read(); #ifdef debugGAUGE Serial.print(" "); Serial.print(inByte,HEX); #endif if (inByte==0x80) {K_LINE_GAUGE.write (0x7F); delay (1);} if (inByte==0xF0) { for (byte i=0; i<sizeof(PIDgauge); i++) { K_LINE_GAUGE.write (PIDgauge[i]); delay (1);} InitGauge=2; NoconnectsGAUGE = 0;}}} bool MessageParse = 0; bool dataMessageEND = 0; bool dataMessageOK = 0; byte headerGAUGE = 0; byte numberbyte = 0; while (InitGauge==2 && !MessageParse && flagneedGAUGE) { if (!dataMessageOK) { if (K_LINE_GAUGE.read() == 0x23 && headerGAUGE ==0) {headerGAUGE=1; delay (waitbyte_gauge); } if (K_LINE_GAUGE.read() == 0xA1 && headerGAUGE ==1) {headerGAUGE=2; delay (waitbyte_gauge);} else {headerGAUGE =0;} if (K_LINE_GAUGE.read() == 0x04 && headerGAUGE ==2) {headerGAUGE=3; delay (waitbyte_gauge);} else {headerGAUGE =0;} if (headerGAUGE ==3) {dataMessageOK = 1; headerGAUGE =0;} numberbyte=0;} else { if (K_LINE_GAUGE.available()>0) { MessageRxGauge[numberbyte] = K_LINE_GAUGE.read(); numberbyte++; delayMicroseconds (250);} if (numberbyte==34) {dataMessageEND = 1; dataMessageOK = 0; }} if (dataMessageEND) { int crc = ( ( unsigned int )MessageRxGauge[32] << 8 ) | MessageRxGauge[33]; // парсинг контрольной суммы из 2 последних байт int CRC =200; for (int i = 0; i < 32; i++) CRC = CRC + MessageRxGauge[i]; // подсчет контрольной суммы байт от 0 до 31 #ifdef debugGAUGE Serial.print (" ReceiveGauge: "); for (int i = 0; i < 34; i++) { Serial.print(MessageRxGauge[i],HEX); Serial.print (" ");} #endif //при получении сообщения БЕЗ ошибок с данными от панели приборов, запишем в переменные остаток топлива и пробег if (CRC==crc) { #ifdef debugGAUGE Serial.println (" OK!!!"); #endif flagneedGAUGE = 0; Fuel2 = MessageRxGauge[16]/2.0; if (!flagFuelIGN) { Fuel = MessageRxGauge[16]/2.00; kmREFUELING=((float)Fuel*100.00)/(float)L100SR_TFT;} //стартовая запись литров в баке для подсчета затраченных литро else Fuel = MessageRxGauge[17]/2.0; //для устреднения болтания в баке закоментировать эту строку, а раскоментировать ниже //для усреднения болтания топлива в баке, раскоментировать, высчитывает среднее /*else { FuelZamer[ZamerNumber] = MessageRxGauge[17]/2.00; if (ZamerNumber==9) { Fuel = 0 ; for (int i = 0; i < 10; i++) Fuel = Fuel + FuelZamer[i]; Fuel = (float)Fuel/10.0;} ZamerNumber++; if (ZamerNumber>9) ZamerNumber = 0;} */ kmAge = (MessageRxGauge[23]+(MessageRxGauge[24]*256))/10.0; //суточный пробег с панели приборов //бак у меня на 59 литров, а датчик показывает максимально 53 литра. для этого эта формула //если у вас тоже датчик имеет лимит то подправте 53 на свой лимит. //если ваш датчик показывает одинаково с полным баком то закоментировать три нижние строки. if (Fuel<53){ if (!flagkmAgeIGN) { kmAgeIGN = kmAge; flagkmAgeIGN =1;} if (!flagFuelIGN) { FuelIGN = Fuel; Fuel_last = Fuel; flagFuelIGN = 1; }}} #ifdef debugGAUGE else Serial.println (" ERROR!!!"); #endif dataMessageEND = 0; MessageParse = 1; NoconnectsGAUGE = 0;}} // if (curmillis - prevNoconnect > 500) {NoconnectsGAUGE ++ ; if (NoconnectsGAUGE>=10){ // #ifdef debugGAUGE // Serial.println (F(" Connect GAUGE failed!!! ")) ; // #endif // NoconnectsGAUGE = 0 ;InitGauge = 0 ; } prevNoconnect = curmillis; } InitBusGAUGE (); }// end receiveGAUGE void InitBusGAUGE () { if (InitGauge == 0){ #ifdef debugGAUGE Serial.println ("Send startsession - address Gauge"); #endif K_LINE_GAUGE.end(); pinMode(TX_gauge, OUTPUT); digitalWrite (TX_gauge, HIGH); // BUS IDLE InitGauge = 5; prevInitbusGauge = curmillis; } if (InitGauge == 5 && curmillis - prevInitbusGauge>1500) {InitGauge = 6;} // BUS IDLE if (InitGauge == 6) { byte boudrate = 1000/BAUD; digitalWrite (TX_gauge, LOW); delay (boudrate); // старт бит for (byte i=0; i<8; i++){digitalWrite (TX_gauge, bitRead(addressGUAGE, i)); delay (boudrate);} // биты тела адреса digitalWrite (TX_gauge, HIGH); delay (boudrate); // стоп бит K_LINE_GAUGE.begin(9600); InitGauge = 1; } } #if defined debugPCM or defined debugGAUGE void printDebugRX (const byte &inbyte) {if (inbyte<=15) Serial.print(F("0")); Serial.print (inbyte, HEX); Serial.print (F(" "));} #endif #ifdef debugPCM void printDebugRX_CSgood(){ if (MessageRx_PCM[n]==0xC1 && MessageRx_PCM[n+1]==0x6B && MessageRx_PCM[n+2]==0x8F) {Serial.println (F(" Initialization OK!!!!")); } else if (MessageRx_PCM[n]==0x58 && MessageRx_PCM[n+1]==0x00) {Serial.println (F(" NO DTC "));} else if (MessageRx_PCM[n]==0x58 && MessageRx_PCM[n+1] >0x00) {Serial.println (F(" DTC is found!"));} else if (MessageRx_PCM[n]==0x54 && MessageRx_PCM[n+1]==0xFF && MessageRx_PCM[n+2]==0x00){Serial.println (F(" DTC CLEARED "));} else if (MessageRx_PCM[n]==0x61 && MessageRx_PCM[n+1]==0x01) {Serial.println (F(" Receive PCM DATAstream"));}} #endif void Menu () { TouchHOME(); if (currentPage == '0') { TouchINF1(); TouchINF2(); TouchCHECK(); } if (currentPage == '1') { TouchINF2(); TouchCHECK(); } if (currentPage == '2') { TouchINF1(); TouchCHECK(); } if (currentPage == '3') { TouchREAD(); TouchERASE(); }} void drawHomeScreen() { line() ; Watch (); //myGLCD.print(":", 290, 5); myGLCD.print("/", 115, 7); myGLCD.print("/", 160, 7); myGLCD.setTextColor(RED, BLACK); // цвет линии и текста красный myGLCD.drawLine(295,35,295,248); // линия вертикальная myGLCD.drawLine(145,35,145,178); // линия вертикальная myGLCD.drawLine(80,178,80,247); // линия вертикальная myGLCD.print("L/H", 10, 40); myGLCD.print("L/A", 148, 40); myGLCD.print("L/V", 10, 75); myGLCD.print("L/M", 148, 75); myGLCD.print("D/K", 10, 110); myGLCD.print("D/L", 148, 110); myGLCD.print("V/K", 10, 145); myGLCD.print("V/L", 148, 145); myGLCD.print("PUMP RPM", 82, 180); myGLCD.print("ENGI RPM", 82, 215); myGLCD.print("D/L/A", 10, 180); myGLCD.print("Motor C", 300, 40); myGLCD.print("OIL C", 300, 75); myGLCD.print("FUEL C", 300, 110); myGLCD.print("INTER C", 300, 145); myGLCD.print("EXTER C", 300, 180); myGLCD.print("INTAIR C", 300, 215); //myGLCD.setTextColor(RED); myGLCD.drawRoundRect (15, 255, 145, 310); myGLCD.print("INF 1", 55, 270); myGLCD.drawRoundRect (175, 255, 305, 310); myGLCD.print("INF 2", 215, 270); myGLCD.drawRoundRect (335, 255, 465, 310); myGLCD.print("CHECK", 365, 270); myGLCD.drawRoundRect (1, 1, 77, 37); myGLCD.print("HOME", 10, 7); myGLCD.print("Km/h", 410, 7); reNew = 1; } //------------------------------------------------- void drawscreen_one() { line() ; Watch (); //myGLCD.print(":", 290, 5); myGLCD.print("/", 115, 7); myGLCD.print("/", 160, 7); myGLCD.setTextColor(RED, BLACK); // цвет линии и текста красный myGLCD.print("Start of Delivery *CA:", 10, 40); myGLCD.print("Desir inject Start *CA:", 10, 75); myGLCD.print("Actua Inject Start *CA:", 10, 110); myGLCD.print("Desir Inject Quan mg/s:", 10, 145); myGLCD.print("Actu Inject Quant mg/s:", 10, 180); myGLCD.print("MAF mg/s:", 10, 215); myGLCD.print("Humedad %:", 255, 215); //myGLCD.setTextColor(RED); myGLCD.drawRoundRect (175, 255, 305, 310); myGLCD.print("INF 2", 215, 270); myGLCD.drawRoundRect (335, 255, 465, 310); myGLCD.print("CHECK", 365, 270); myGLCD.drawRoundRect (1, 1, 77, 37); myGLCD.print("HOME", 10, 7); myGLCD.print("Km/h", 410, 7); reNew = 1; } //------------------------------------------------- void drawscreen_two() { line() ; Watch (); //myGLCD.print(":", 290, 5); myGLCD.print("/", 115, 7); myGLCD.print("/", 160, 7); myGLCD.setTextColor(RED, BLACK); // цвет линии и текста красный myGLCD.print("Boost Press Bar:", 10, 40); myGLCD.print("Boost Press Com Bar:", 10, 75); myGLCD.print("EGR command mg/s:", 10, 110); myGLCD.print("EGR Pulse Ratio %:", 10, 145); myGLCD.print("Solenoide Pulse %:", 10, 180); myGLCD.print("Solenoide Boost %:", 10, 215); //myGLCD.setColor(RED); myGLCD.drawRoundRect (15, 255, 145, 310); myGLCD.print("INF 1", 55, 270); myGLCD.drawRoundRect (335, 255, 465, 310); myGLCD.print("CHECK", 365, 270); myGLCD.drawRoundRect (1, 1, 77, 37); myGLCD.print("HOME", 10, 7); myGLCD.print("Km/h", 410, 7); reNew = 1; } //---------------------------------------------------------------------------- void drawscreen_three() { Watch (); //myGLCD.print(":", 290, 5); myGLCD.print("/", 115, 7); myGLCD.print("/", 160, 7); myGLCD.setTextColor(RED, BLACK); // цвет линии красный myGLCD.drawLine(1,35,479,35); // линия горизонтальная myGLCD.drawLine(1,248,479,248); // линия горизонтальная //myGLCD.setTextColor(RED); myGLCD.drawRoundRect (15, 255, 145, 310); myGLCD.print("ERASE", 55, 270); myGLCD.drawRoundRect (335, 255, 465, 310); myGLCD.print("READ", 365, 270); myGLCD.drawRoundRect (1, 1, 77, 37); myGLCD.print("HOME", 10, 5); reNew = 1; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //кнопки тач . координаты и переходы ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void TouchHOME(){ TSPoint p = ts.getPoint(); pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); if (p.z > 10 && p.z < 1000) {if (p.x > 140 && p.x < 320 && p.y > 140 && p.y < 260 && p.z > MINPRESSURE && p.z < MAXPRESSURE) { myGLCD.drawRoundRect (1, 1, 77, 37); currentPage = '0'; request = PID; RequestPeriod = 10; prevRequest = curmillis; // на PCM в этом окне посылается запрос текущих параметров myGLCD.clrScr(); drawHomeScreen(); x = 0; y = 0; p.z = 0;}}} void TouchINF1(){ TSPoint p = ts.getPoint(); pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); if (p.z > 10 && p.z < 1000) { if (p.x > 150 && p.x < 450 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE) { myGLCD.drawRoundRect (15, 255, 145, 310); currentPage = '1'; request = PID; RequestPeriod = 10; prevRequest = curmillis; // на PCM в этом окне посылается запрос текущих параметров myGLCD.clrScr(); drawscreen_one(); x = 0; y = 0; p.z = 0;}}} void TouchINF2(){ TSPoint p = ts.getPoint(); pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); if (p.z > 10 && p.z < 1000) { if (p.x > 450 && p.x < 680 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE) { myGLCD.drawRoundRect (175, 255, 305, 310); currentPage = '2'; request = PID; RequestPeriod = 600; prevRequest = curmillis; // на PCM в этом окне посылается запрос текущих параметров myGLCD.clrScr(); drawscreen_two(); x = 0; y = 0; p.z = 0;}}} void TouchCHECK(){ TSPoint p = ts.getPoint(); pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); if (p.z > 10 && p.z < 1000) { if (p.x > 690 && p.x < 950 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE) { myGLCD.drawRoundRect (335, 255, 465, 310); currentPage = '3'; // request = DTCREAD; RequestPeriod = 10; prevRequest = curmillis; // на PCM в этом окне посылается запрос чтения ошибок myGLCD.clrScr(); drawscreen_three(); x = 0; y = 0; p.z = 0;}}} void TouchREAD(){ TSPoint p = ts.getPoint(); pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); if (p.z > 10 && p.z < 1000) { if (p.x > 690 && p.x < 950 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE) { myGLCD.drawRoundRect (335, 255, 465, 310); request = DTCREAD; RequestPeriod = 300; prevRequest = curmillis; // на PCM при нажатии этой кнопки посылается запрос чтения ошибок x = 0; y = 0; p.z = 0;}}} void TouchERASE(){ TSPoint p = ts.getPoint(); pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); if (p.z > 10 && p.z < 1000) { if (p.x > 150 && p.x < 450 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE) {myGLCD.drawRoundRect (15, 255, 145, 310); request = DTCERASE; RequestPeriod = 300; prevRequest = curmillis; // на PCM при нажатии этой кнопки посылается запрос удаления ошибок myGLCD.clrScr(); drawscreen_three(); myGLCD.print("DTC BORRADO", 180, 145); x = 0; y = 0; p.z = 0;}}} //////////////////////////////////////////////////////////////////////////////////////// //прорисовка линий /////////////////////////////////////////////////////////////////////////////////////// void line() { //myGLCD.setTextColor(RED); // цвет линии красный myGLCD.drawLine(1,35,479,35); // линия горизонтальная myGLCD.drawLine(1,73,479,73); // линия горизонтальная myGLCD.drawLine(1,108,479,108); // линия горизонтальная myGLCD.drawLine(1,143,479,143); // линия горизонтальная myGLCD.drawLine(1,178,479,178); // линия горизонтальная myGLCD.drawLine(1,212,479,212); // линия горизонтальная myGLCD.drawLine(1,248,479,248); // линия горизонтальная } void Watch (){ DateTime now = rtc.now(); int minut = now.minute(); int hour = now.hour(); int mon = now.month(); int date = now.day(); int Year = now.year(); static int minut_last; static int hour_last; static int mon_last; static int date_last; static int Year_last; myGLCD.setTextColor(WHITE, BLACK); //белый цвет цифры if (date != date_last || reNew){ myGLCD.printNumI(date, 85, 7, 2, '0'); date_last = date; } if (mon!=mon_last || reNew){myGLCD.printNumI(mon, 130, 7, 2, '0'); mon_last = mon; } if (Year!=Year_last || reNew) { myGLCD.printNumI(Year, 175, 7); Year_last = Year; } if (hour!=hour_last || reNew){ myGLCD.printNumI(hour, 255, 7, 2, '0'); hour_last = hour; } if (minut!=minut_last || reNew ){ myGLCD.printNumI(minut, 300, 7, 2, '0'); minut_last = minut; } } void Temperature () { static boolean p=0; // флаг работы: запрос температуры или её чтение p=!p; if (p) {ds.reset(); // сброс шины ds.write(0xCC); // обращение ко всем датчикам ds.write(0x44); // начать преобразование (без паразитного питания) } else { int Temper_= 20; byte buff[9]; ds.reset(); ds.select(DSaddress); ds.write(0xBE); // Read Scratchpad (чтение регистров) for (byte j = 0; j<9; j++) buff[j]= ds.read(); //читаем все 9 байт от датчика ds.reset(); if (OneWire::crc8(buff, 8) == buff[8]){ // если контрольная сумма совпадает Temper_ = buff[0] | (buff[1]<<8); // читаем температуру из первых двух байт (остальные были нужны для проверки CRC) Temper_ = Temper_ / 16; if (Temper_ < 150 && Temper_ > -50 && Temper_ !=85 && Temper_!=-127) IntTemp = Temper_; } } }Ты гений, показывает обе температуры и влагу, я домой, завтра скажу как себя вел бортовик, спасибо
в итоговом скетче комментируй обе отладки
Поздно сказал :). Уже так залил. Есть косяки, завтра напишу
Макс вообщем хаус. поездка 30 км. средний расход за поездку стартует с 99.0л/100 закончил где то 13л/100. самый средний расход висит восновном на 0.9 иногда может быть 2.5 или 3.5. Внутрення температура у меня дошла до 63 градуса. Наружняя тоже чето не то, обычно интактаире и наружняя различаются в 2 градуса, а вчера была разнится в 10 градусов. актуальный расход у меня никогда не прыгал выше 14л/100 под нагрузкой, сейчас проскакивали цыфры и 35л/100. Остаток в баке на километры тоже не верно отображает, меньше, вроде как. А так же актуальный остаток в баке очень разнится от среднего остатак, и из за этого больше висит расход за поездку в минусе, иногда может быть и в плусе, редко, наверно как расчет поподет, когда они оба примерно одинаковы или очень разные. Километры за поездку тоже, выехал с дома, 100 метров проехал показывает уже 200, проехал еще 200 уже показало 1 км 200 м, но иногда правильно показывает но отстает сильно от реальных, иногда вроде уравнивается. Был включен #define debugGAUGE, думаешь это могло так мешать? Не уверен но это моя мысль.... Возможно изза большой задержки в 30 секунд, когда идет запись то в этот момент чтото уже обновилось а чтото еще не успело..... вот и происходит не верные запись и подсчеты. Не уверен, это просто мысль. Примерно так,
дебаг не причем. Возможно номера байтов как то сбились, поэтому неправильные данные от панели ловит, ну или ,действительно, из за того, что редко обновляется - раз в 30 сек. Может в какой то момент просто перестали данные от панели поступать, как вариант. Поведение программы вообще не удивительно, т.к. весь проект получился в итоге на костылях, начиная от библы экрана, тача, заканчивая организацией протоколов обмена с блоками. Даже не знаю что тут и предложить, честно.
Мои новые подходы к чтению блоков не проканали в реальных условиях (работают только если в программе ничего другого нет). Хотя может эти алгоритмы и работали бы нормально, если бы это всё остальное в программе не тормозило последнюю. Но по идее на такой случай они и писались, х.з. почему не работают - байты куда-то теряются, хотя должны спокойно храниться в буфере, пока их от туда не вычитаешь. Можно было бы предположить, как говорил Komandir, что дело в библиотеке Softserial , дак ведь когда заморочились с панелью, косяки проявлялись такие же (стоило немного притормозить луп и байты стали теряться), но она то висит на хардсериале, так что алгоритм гавно, получается, а не хард или софтсериал.
ясно. а по старой схеме не получится, по старым алгоритмам?
дак ты же как то срастил старый скетч с новым экраном? Где он там у тебя. Бери щас да пользуй, коль выяснили, что подтормаживала библиотека экрана , но ты её щас то уже поправил.
ок. буду эксперементировать, спасибо за помощь и терпение
Короче, Макс. Как ни рути всему виной шрифт, он все тормозит и даже при шрифте перестает идти запрос на ебу, идет только панель. Оставил стандартный шриф 2го размера, маловат, нужно присматриватся когда едешь, а 3й за большой. но, все работает мгновенно. Прорисовка меню и данных мгновенная, обновление данных быстрое. Это о моем старом скетче. Твой новый тоже рботает так же но, хаус с расчетами остался. Последняя прозьба, в старом скетче почемуто перестали работать 4 параметра, это странно так как раньше они работали, это
TempAir показывает( - 277) , EGRPul показывает (0.0), SolenPul показывает (0.0) и SolenPre показывает (0).
а, заливаю твой последний усовершенствованый, все параметры работают.
глянь когда сможешь, и если не сложно и не долго и если это возможно, добавть в этот скетч переподключение если будет сбой.
если эти две проблемки : не работающие 4 параметра и переподключение решить, мне больше ничего не нужно, я буду счастлив. вот скетч
///////////////////////////////////////////////////////////////////////////////////////// //библиотеки /////////////////////////////////////////////////////////////////////////////////////////// #include <Adafruit_GFX.h> //#include <MCUFRIEND_kbv.h> #include <UTFTGLUE.h>//use GLUE class and constructor #include "TouchScreen.h" #include <stdint.h> #include <SPI.h> #include <EEPROM.h> #include "Fonts/Chosence_Bold16pt7b.h"; #define MINPRESSURE 200 #define MAXPRESSURE 1000 //pin 20 SCL , 21 SDA датчик реального времени #include <Wire.h> #include "RTClib.h" RTC_DS3231 rtc; //датчик наружней температуры #include <OneWire.h> #define ONE_WIRE_BUS 22 OneWire oneWire(ONE_WIRE_BUS); #include <DallasTemperature.h> DallasTemperature sensors(&oneWire); //датчик внутринней температуры и влаги #include "DHT.h" #define DHTPIN 26 #define DHTTYPE DHT22 DHT dht(DHTPIN, DHTTYPE); /////////////////////////////////////////////////////////////////////////////////// //пины экрана и тача /////////////////////////////////////////////////////////////////////////////////// UTFTGLUE myGLCD(0x1581,A2,A1,A3,A4,A0); const int XP = 6, XM = A2, YP = A1, YM = 7; const int TS_LEFT = 136, TS_RT = 907, TS_TOP = 139, TS_BOT = 942; TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300); uint16_t ID; int x, y; char currentPage; float h; float t; bool Dvoet = 0; #define BLACK 0x0000 #define WHITE 0xFFFF #define RED 0xF800 #define GREEN 0x07E0 ////////////////////////////////////////////////////////////////////////////// //все что касается OBD2 /////////////////////////////////////////////////////////////////////////////// #include <SoftwareSerial.h> #define mySerial_gauge Serial2 #define TX_gauge 16 #define TX 13 SoftwareSerial mySerial (12, 13); //RХ,TХ int length5 = 5; int length6 = 6; int length8 = 8; int length7 = 7; bool Init = 0; bool InitGauge = 0; bool dataMessageOK=0; bool dataMessageEND = 0; bool MessageParse = 0; bool byte0 = 0; bool byte1 = 0; bool byte2 = 0; int numberbyte = 0; int PIDTime = 120; // задержка ожидания запроса следующего pid 2101, мс int PresTime = 8000; // задержка между посылками запросов присутствия, мс int waitbyte = 1; // задержка между отправкой байт в сообщении, мс int waitbyte_gauge = 4; int Datadelay = 50; // задержка между отрисовкой данных на LCD, мс float L100M = 0; //расход на 100 км измеренный за поездку float L100 = 0; //мгновенный расход литров на 100км float LHor = 0; //мгновенный расход топлива литров в час float L100SR = 0; //расход литров на 100км измеренный раз в интервал kmL float L100SR_TFT = 0; // самый средний из расходов на 100км, он выводится на экран int L100_Eeprom[11]= {10,10,10,10,10,10,10,10,10,10,10}; int FuelZamer[10]= {0}; // массив для измерения уровня (количества) топлива int ZamerNumber = 0; // номер замера уровня (количества) топлива int n_eeprom = 0; // текущий адрес ячейки еепром для записи расхода int MAF = 0; //26,27 байты Sensor de flujo de aire en masa float BoostPres = 0; //28,29 байты Presión de refuerzo int RPM = 0; //32,33 байты Velocidad del motor int EGRmg = 0; //34,35 байты Comando EGR (Comando de recirculación de gases de escape) float BoostPresCom = 0; //38,39 байты Comando de presión de refuerzo int Speed = 0; //44,45 байты Velocidad del vehículo float DesaInjQua = 0; //50,51 байты Cantidad de inyección deseada float InjQua = 0; //52,53 байты Cantidad de la inyección float StaDaliv = 0; //54,55 байты Inicio de la entrega int PumpRPM = 0; //56,57 байты Velocidad de la bomba float EGRPul = 0; //62,63 байты Relación de impulsos EGR (recirculación de gases de escape float SolenPul = 0; //64,65 байты Velocidad de solenoide de control de nivel de remolino Relación de impulsos float SolenPre = 0; //70,71 байты Relación de impulsos Presión Electroválvula de presión float DesInj = 0; //72,73 байты Inyección deseada Inicio float ActInj = 0; //16,17 байты Inicio de la inyección real int TempAir = 0; //74,75 байты Temperatura del aire de admisión int Temp = 0; //14,15 байты Temperatura del refrigerante int TempOil = 0; //18,19 байты Temperatura del aceite del motor int TempFuel = 0; //58,59 байты Temperatura del combustible //все что касается топлива float Fuel = 0; //остаток топлива float Fuel2 = 0; //остаток мгновенного топлива байт 16 , датчика в баке int FuelIGN = 0; // количество топлвива в баке на момент включения зажигания int Fuel_last = 0; // для формул bool flagFuelIGN = 0; // флаг записан ли остаток топлива в момент вкл. зажигания float FuelTrip = 0; // количество литров топлива, израсходованное за один цикл включения зажигания //все что касается километража float kmAge = 0; //пробег, полученный со щитка приборов int kmAgeIGN = 0; //пробег который был в момент включения зажигания int kmAge_last = 0; // для формул bool flagkmAgeIGN = 0; //флаг записан ли пробег в момент вкл. зажигания float kmTrip = 0; //пробег за один цикл включения зажигания int kmL = 10; // интервал, через который будет происходить обновление среднего расхода на 100км int km = 0; // переменная для расчетов int kmeeprom = 10; // интервал, через который будет происходить подсчет среднеарифмитического расхода L100SR_TFT int kmTFT = 0; // переменная для расчетов периодического подсчета среднеарифмитического расхода топлива L100SR_TFT int kmREFUELING = 0; // пробег до заправки на остатке топлива int colerror = 0; //количество ошибок в правом верхнем углу третьего экрана //float Barom = 0; // барометр byte MessageRx[110] = {0}; // массив байтов принимаемого сообщения byte MessageRxGauge[60] = {0}; // массив байтов принимаемого сообщения от щитка приборов byte messageInit[5] = {0x81, 0x11, 0xF1, 0x81, 0x04}; // запрос инициализации byte messagePresent[5] = {0x81,0x11,0xF1,0x3E,0xC1}; // запрос присутствия byte messagePids[6] = {0x82,0x11,0xF1,0x21,0x01,0xA6}; // запрос пид 2101 byte messageREAD[8] = {0x84,0x11,0xF1,0x18,0x00,0xFF,0x00,0x9D}; // запрос ошибок byte messageERASE[7] = {0x83,0x11,0xF1,0x14,0xFF,0x00,0x98}; // стирание ошибок unsigned long prevPID = 0; unsigned long prevPIDgauge = 0; unsigned long prevTemperature = 0; unsigned long prevpres = 0; unsigned long prevWatch = 0; unsigned long prevDvoet = 0; unsigned long prevData = 0; unsigned long TimewaitPID, timerwaitPID = 0; bool timerenabledPID = 0; #define TIMEREXPIRED_PID (TimewaitPID - timerwaitPID)> 200 // здесь задержка на ожидание правильного ответа пидов, мс unsigned long TimewaitInit, timerwaitInit = 0; bool timerenabledInit = 0; #define TIMEREXPIRED_Init (TimewaitInit - timerwaitInit)> 500 // здесь задержка на ожидание ответа об удачной инициализации, мс ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //SETUP ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void setup() { uint16_t ID = myGLCD.readID(); if (ID == 0xD3D3) ID = 0x1581; myGLCD.begin(ID); myGLCD.InitLCD(3); Serial.begin(115200); mySerial.begin(10400); Wire.begin(); rtc.begin(); dht.begin(); sensors.begin(); myGLCD.clrScr(); myGLCD.setTextSize(2); //myGLCD.setFont(&Chosence_Bold16pt7b); //загрузка стартовой страницы currentPage = '0'; drawHomeScreen(); //подсчет среднеарифметического усредненного расхода for (int i = 0; i < 11; i++) L100_Eeprom [i]= EEPROM.read(i); for (int i = 0; i < 11; i++) L100SR_TFT = L100SR_TFT + L100_Eeprom [i]; L100SR_TFT = (float)L100SR_TFT/110.0; if (L100SR_TFT<0) L100SR_TFT = 0; if (L100SR_TFT>99) L100SR_TFT = 99; // строка ниже используется для настройки даты и времени часов // раскоментировать, выставить времая и дату, залить в ардуино. в скетче закоментировать // обратно и залить еще раз, иначе каждый раз будет по новой выствлятся это же время и дата // (год, месяц, день, часы, минуты, секунды) //rtc.adjust(DateTime(2017, 7, 21, 13, 57, 0)); Temperature (); pinMode(TX, OUTPUT); pinMode(TX_gauge, OUTPUT); fastinit(); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //SETUP FIN ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //LOOP ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void loop() { TimewaitPID = millis (); TimewaitInit = millis (); if (!Init) { if (!timerenabledInit){ timerwaitInit=TimewaitInit; timerenabledInit=1; initialization(); } else if (TIMEREXPIRED_Init) timerenabledInit=0;} else { if (currentPage != '3'){ // если открыта страница 0,1 или 2 шлем запрос пид2101, если страница 3 - шлем запрос присутствия if (millis() - prevPID > PIDTime) { PIDs(); prevPID = millis(); }} else if (millis() - prevpres > PresTime) {present(); prevpres = millis();}} if (!InitGauge) {Serial.println ("Otpravil zapros adress Gauge"); digitalWrite (TX_gauge, HIGH); delay (500); digitalWrite (TX_gauge, LOW); delay (20); digitalWrite (TX_gauge, HIGH ); delay (15); digitalWrite (TX_gauge, LOW); delay (5); digitalWrite (TX_gauge, HIGH); delay (5); mySerial_gauge.begin(9600);} receive (); if (millis() - prevWatch > 3000) { Watch (); prevWatch = millis(); Trip ();} if (millis() - prevTemperature > 60000) { Temperature (); prevTemperature = millis();} if (millis() - prevDvoet > 500) { if (!Dvoet) {myGLCD.print(":", 285, 10);} else {myGLCD.print(" ", 285, 10);} prevDvoet = millis(); Dvoet=!Dvoet;} Menu(); LCDDataPrint();} ///////////////////////////////////////////////////////////////////////////////////////////////////////// //BOID TRIP////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////// void Trip () { if (flagkmAgeIGN){ FuelTrip = FuelIGN - Fuel; if (kmAge>kmAgeIGN) kmTrip = kmAge - kmAgeIGN; if (kmAge<kmAgeIGN) kmTrip = 2000 - (kmAgeIGN - kmAge); // 2000 это через сколько км у тебя суточный пробег сбрасывается на ноль, поменяй если другое число if (kmAge==kmAgeIGN) kmTrip = 0; //подсчет расхода на 100км за поездку L100M = ((float)FuelTrip*100.00)/(float)kmTrip; if (L100M<0) L100M = 0; if (L100M>99) L100M = 99; // ниже цикл считает среднеарифметический расход из еепром раз в пробег, указанный в переменной kmeeprom if (kmTrip-kmTFT>kmeeprom) {kmTFT = kmTrip; // тут считаем среднеарифметический усредненного расход из ячеек еепром for (int i = 0; i < 11; i++) L100_Eeprom [i]= EEPROM.read(i); for (int i = 0; i < 11; i++) L100SR_TFT = L100SR_TFT + L100_Eeprom [i]; L100SR_TFT = (float)L100SR_TFT/110.00; if (L100SR_TFT<0) L100SR_TFT = 0; if (L100SR_TFT>99) L100SR_TFT = 99;} // ниже цикл считает расход топлива за пробег, указанный в переменной kmL, здесь же запись в ячейки еепром if (kmTrip-km>kmL) {km=kmTrip; L100SR = ((float)(Fuel_last-Fuel)*100.00)/(float)kmL; // расход/100км - обновляется раз в 10км, меняется км в int kmL = 10; Fuel_last = Fuel; // сохранение параметров с последнего измерениея if (L100SR<0) L100SR = 0; if (L100SR>99) L100SR = 99; //расчет остатка километров в баке if (L100SR>0) kmREFUELING=((float)Fuel*100.0)/(float)L100SR; //если средний расход больше нуля, то расчитывать км в баке из него else kmREFUELING=((float)Fuel*100.00)/(float)L100SR_TFT; //если ноль или ментше то расчитывать км в баке с устредненного расхода // тут записываем L100SR последовательно в одну из 11 ячеек еепром //EEPROM.write (12,n_eeprom); // ЗДЕСЬ ВНИМАТЕЛЬНО. ЗАГРУЗИТЬ ПРОШИВКУ С ЭТОЙ СТРОКОЙ ОДИН РАЗ, ПОТОМ ЗАКОМЕНТИРОВАТЬ И ЕЩЁ РАЗ ЗАГРУЗИТЬ n_eeprom = EEPROM.read (12); // в ячейке 12 хранится № текущей ячейки для записи расхода, чтобы где остановился при выкл питания, от туда и продолжил EEPROM.write(n_eeprom, L100SR*10); n_eeprom++; if (n_eeprom>10) n_eeprom=0; EEPROM.write (12,n_eeprom); }}} ///////////////////////////////////////////////////////////////////////////////////////////////////////// //BOID LCDDATAPRINT. прописываем данные и их расположение и цвет///////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////// void LCDDataPrint(){ unsigned long curData = millis(); if (millis() - prevData > Datadelay){ myGLCD.setTextColor(WHITE, BLACK); //цвет текста myGLCD.printNumI(Speed, 365, 10, 3); //---------------------------------------------------------- //страниц HOME //---------------------------------------------------------- if (currentPage == '0') { myGLCD.printNumF(LHor, 1, 90, 50, '.',4); myGLCD.printNumF(L100, 1, 240, 50,'.',4 ); myGLCD.printNumF(L100M, 1, 90, 85,'.',4 ); myGLCD.printNumF(L100SR_TFT, 1, 240, 85,'.',4 ); myGLCD.printNumI(kmREFUELING, 80, 120,5 ); //if (Fuel<53) myGLCD.printNumF(Fuel, 1, 240, 120,'.',4); //else myGLCD.print("MAX", 240, 120); myGLCD.printNumF(kmTrip, 1, 90, 155,'.',4); myGLCD.printNumF(FuelTrip, 1, 240, 155,'.',4); myGLCD.printNumI(PumpRPM, 230, 190,4); myGLCD.printNumI(RPM, 230, 225,4); myGLCD.printNumF(Fuel2, 1, 15, 225,'.',4); myGLCD.printNumI(Temp, 415, 50, 3); myGLCD.printNumI(TempOil, 415, 85, 3); myGLCD.printNumI(TempFuel, 415, 120,3); myGLCD.printNumI(sensors.getTempCByIndex(0), 415, 155 , 3); myGLCD.printNumI(t, 415, 190, 3); myGLCD.printNumI(TempAir, 415, 225, 3); } //---------------------------------------------------------- //страниц INF1 //---------------------------------------------------------- if (currentPage == '1') { myGLCD.printNumF(StaDaliv,1, 360, 50,'.', 3); myGLCD.printNumF(DesInj,1, 360, 85, '.', 4); myGLCD.printNumF(ActInj,1, 360, 120,'.', 4); myGLCD.printNumF(DesaInjQua,1, 360, 155,'.', 4); myGLCD.printNumF(InjQua,1, 360, 190,'.', 4); myGLCD.printNumI(MAF, 160, 225, 4); myGLCD.printNumF(h, 1, 400, 225); } //---------------------------------------------------------- //страниц INF2 //---------------------------------------------------------- if (currentPage == '2') { myGLCD.printNumF(BoostPres,1, 385, 50,'.', 3); myGLCD.printNumF(BoostPresCom,1, 385, 85,'.', 3); myGLCD.printNumI(EGRmg, 375, 120, 4); myGLCD.printNumF(EGRPul,1, 375, 155,'.', 4); myGLCD.printNumF(SolenPul, 1, 375, 190,'.', 4); myGLCD.printNumF(SolenPre, 0, 375, 225,'.', 4); } prevData = millis(); }} /////////////////////////////////////////////////////////////////////////// //BOID PIDs//отправка запроса пид 2101///////////////////////////////////// /////////////////////////////////////////////////////////////////////////// void PIDs() { Serial.println ("Otpravil zapros 21 01"); for (int i = 0; i < length6; i++) { mySerial.write(messagePids[i]); delay (waitbyte); }} /////////////////////////////////////////////////////////////////////////// //BOID PIDsGAUGR//отправка запроса на панель приборов////////////////////// /////////////////////////////////////////////////////////////////////////// void PIDsGauge() { Serial.println (" Otpravil zapros 02 11 na panel"); mySerial_gauge.write (0x02); delay (1); mySerial_gauge.write (0x11); delay (1); mySerial_gauge.write(byte(0)); delay (1); mySerial_gauge.write (0x13); } /////////////////////////////////////////////////////////////////////////// //BOID PIDsGAUGR//отправка запроса присутствия///////////////////////////// /////////////////////////////////////////////////////////////////////////// void present() { Serial.println ("Otpravil zapros Present"); for (int i = 0; i < length5; i++) { mySerial.write(messagePresent[i]); delay (waitbyte); }} ///////////////////////////////////////////////////////////////////////////////////////////// //получение данных от ЭБУ, разборка входящих сообщений ///////////////////////////////////////////////////////////////////////////////////////////// void receive () { /////////////////////////////////////////////////////////////////////// ////////////////// работа с К-Line софт сериал 16-17 (12 контакт ОБД) /////////////////////////////////////////////////////////////////////// while(!InitGauge){ if (mySerial_gauge.available()) { byte inByte = mySerial_gauge.read(); Serial.print(" "); Serial.print(inByte,HEX); if (inByte==0x80) {mySerial_gauge.write (0x7F); delay (1);} if (inByte==0xF0) { mySerial_gauge.write (0x02); delay (1); mySerial_gauge.write (0x11); delay (1); mySerial_gauge.write (0x00); delay (1); mySerial_gauge.write (0x13); delay (1); InitGauge=1; }}} MessageParse = 0; while (InitGauge && !MessageParse) { if (!dataMessageOK) { if (mySerial_gauge.read() == 0x23) {byte0=1; delay (waitbyte_gauge); } if (mySerial_gauge.read() == 0xA1 && byte0) {byte1=1; delay (waitbyte_gauge);} else byte0=0; if (mySerial_gauge.read() == 0x04 && byte0 && byte1) {byte2=1; delay (waitbyte_gauge);} else {byte0=0; byte1=0;} if (byte0 && byte1 && byte2) {dataMessageOK = 1; byte0=0; byte1=0; byte2=0;} numberbyte=0;} else { if (mySerial_gauge.available()>0) { MessageRxGauge[numberbyte] = mySerial_gauge.read(); numberbyte++; delayMicroseconds (250);} if (numberbyte==34) {dataMessageEND = 1; dataMessageOK = 0; }} if (dataMessageEND) { int crc = ( ( unsigned int )MessageRxGauge[32] << 8 ) | MessageRxGauge[33]; // парсинг контрольной суммы из 2 последних байт int CRC =200; for (int i = 0; i < 32; i++) CRC = CRC + MessageRxGauge[i]; // подсчет контрольной суммы байт от 0 до 31 Serial.print (" ReceiveGauge: "); for (int i = 0; i < 34; i++) { Serial.print(MessageRxGauge[i],HEX); Serial.print (" ");} //при получении сообщения БЕЗ ошибок с данными от панели приборов, запишем в переменные остаток топлива и пробег if (CRC==crc) {Serial.println (" OK!!!"); Fuel2 = MessageRxGauge[16]/2.0; if (!flagFuelIGN) { Fuel = MessageRxGauge[16]/2.00; kmREFUELING=((float)Fuel*100.00)/(float)L100SR_TFT;} //стартовая запись литров в баке для подсчета затраченных литро else Fuel = MessageRxGauge[17]/2.0; //для устреднения болтания в баке закоментировать эту строку, а раскоментировать ниже //для усреднения болтания топлива в баке, раскоментировать, высчитывает среднее /*else { FuelZamer[ZamerNumber] = MessageRxGauge[17]/2.00; if (ZamerNumber==9) { Fuel = 0 ; for (int i = 0; i < 10; i++) Fuel = Fuel + FuelZamer[i]; Fuel = (float)Fuel/10.0;} ZamerNumber++; if (ZamerNumber>9) ZamerNumber = 0;} */ kmAge = (MessageRxGauge[23]+(MessageRxGauge[24]*256))/10.0; //суточный пробег с панели приборов //бак у меня на 59 литров, а датчик показывает максимально 53 литра. для этого эта формула //если у вас тоже датчик имеет лимит то подправте 53 на свой лимит. //если ваш датчик показывает одинаково с полным баком то закоментировать три нижние строки. if (Fuel<53){ if (!flagkmAgeIGN) { kmAgeIGN = kmAge; flagkmAgeIGN =1;} if (!flagFuelIGN) { FuelIGN = Fuel; Fuel_last = Fuel; flagFuelIGN = 1; }}} else Serial.println (" ERROR!!!"); dataMessageEND = 0; MessageParse = 1; //mySerial_gauge.flush(); for (int i = 0; i < 34; i++) MessageRxGauge[i]=0; }} // очистка байтов массива //////////////////////////////////////////////////////////////////// ////////////////// работа с К-Line софт сериал 12-13 (7 контакт ОБД) //////////////////////////////////////////////////////////////////// if (mySerial.available()) { delay(195); int k=0; byte inbyte=0; while( mySerial.available() && k < 110) { inbyte = mySerial.read(); MessageRx[k] = inbyte; k++; } Serial.print ("Receive: "); for (int i = 0; i < k; i++) { Serial.print(MessageRx[i],HEX); Serial.print (" ");} Serial.println (""); if (MessageRx[2]==0x83 && MessageRx[3]==0xF1 && MessageRx[4]==0x11 && MessageRx[5]==0xC1 && MessageRx[6]==0x6B && MessageRx[7]==0x8F && MessageRx[8]==0x40) {Init=1; timerenabledInit=0; Serial.println (" Initialization OK!!!!: "); } if (currentPage == '3'){ /////////////////////////////////////////////////////////////////////////////////////////////////// //Чтение и стирание ошибок /////////////////////////////////////////////////////////////////////////////////////////////////// //при получении этого сообщения выдавать на третий экран "NO ERROR" if (MessageRx[4]==0x82 && MessageRx[5]==0xF1 && MessageRx[6]==0x11 && MessageRx[7]==0x58 && MessageRx[8]==0x00 && MessageRx[9]==0xDC){ myGLCD.clrScr(); drawscreen_three(); myGLCD.print("NO DTC", 200, 145); Serial.println (" NO DTC "); } //при получении этого сообщения выдавать на третий экран "DTC BORRADO" if (MessageRx[3]==0x83 && MessageRx[4]==0xF1 && MessageRx[5]==0x11 && MessageRx[6]==0x54 && MessageRx[7]==0xFF && MessageRx[8]==0x00 && MessageRx[9]==0xD8){ myGLCD.clrScr(); drawscreen_three(); myGLCD.print("DTC BORRADO", 175, 145); Serial.println (" DTC BORRADO "); } // при получении сообщения о наличии ошибок DTC разберем сообщение выведем на экран ошибки if (MessageRx[5]==0xF1 && MessageRx[6]==0x11 && MessageRx[7]==0x58 && MessageRx[8]>0){ Serial.println ("DTC is found!"); myGLCD.clrScr(); drawscreen_three(); for (int i=0; i<MessageRx[8]; i++ ) { int y = i*35; bool nolA=0; bool nolB =0; if (!bitRead(MessageRx[11+(i*3)],6) && bitRead(MessageRx[11+(i*3)],7)){ myGLCD.setTextColor(GREEN, BLACK); myGLCD.print(" -Passive-", 300, (75+y));} // если DTC пасивныый делаем цвет зеленый if (bitRead(MessageRx[11+(i*3)],7) && bitRead(MessageRx[11+(i*3)],6)) {myGLCD.setTextColor(RED, BLACK); myGLCD.print(" -Active-", 300, (75+y));} // если DTC активный, делаем цвет красный myGLCD.print("ERROR ", 50, (75+y)); myGLCD.printNumI((i+1), 150, (75+y)); if (!bitRead(MessageRx[9+(i*3)],6) && !bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": P", 170, (75+y)); if (bitRead(MessageRx[9+(i*3)],6) && !bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": C", 170, (75+y)); if (!bitRead(MessageRx[9+(i*3)],6) && bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": B", 170, (75+y)); if (bitRead(MessageRx[9+(i*3)],6) && bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": U", 170, (75+y)); if (MessageRx[9+(i*3)]==0x00) {myGLCD.print("00", 230, (75+y)); nolA = 1;} if (MessageRx[9+(i*3)]<=0x0F&&MessageRx[9+(i*3)]!=0) {myGLCD.print("0", 230, (75+y)); nolA = 1;} if (nolA)myGLCD.print(String (MessageRx[9+(i*3)],HEX), 246, (75+y)); else myGLCD.print(String (MessageRx[9+(i*3)],HEX), 230, (75+y)); if (MessageRx[10+(i*3)]==0x00) {myGLCD.print("00", 262, (75+y)); nolB = 1;} if (MessageRx[10+(i*3)]<=0x0F&&MessageRx[10+(i*3)]!=0) {myGLCD.print("0", 262, (75+y)); nolB = 1;} if (nolB)myGLCD.print(String (MessageRx[10+(i*3)]),HEX, 278, (75+y)); else myGLCD.print(String (MessageRx[10+(i*3)],HEX), 262, (75+y));}}} /////////////////////////////////////////////////////////////////////////////////////////////////////////// //прописываем формулы к данным /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////// else if (MessageRx[3]==0x80 && MessageRx[4]==0xF1 && MessageRx[5]==0x11 && MessageRx[6]==0x4C && MessageRx[7]==0x61 && MessageRx[8]==0x01) { //Barom = MessageRx[39]; L100 = (float)LHor*100.0/(float)Speed; LHor = (float)RPM* (float)InjQua*2.00/1000.0*60.00/1000.0/0.85; MAF = ((MessageRx[29]*256)+MessageRx[30])/10; BoostPres = ((MessageRx[31]*256)+MessageRx[32])/1000.0; RPM = (MessageRx[35]*256)+MessageRx[36]; EGRmg = ((MessageRx[37]*256)+MessageRx[38])/10.0; BoostPresCom = ((MessageRx[41]*256)+MessageRx[42])/1000.0; Speed = ((MessageRx[47]*256)+MessageRx[48])/100; DesaInjQua = ((MessageRx[53]*256)+MessageRx[54])/100.0; InjQua = ((MessageRx[55]*256)+MessageRx[56])/100.0; StaDaliv = ((MessageRx[57]*256)+MessageRx[58])/100.0; PumpRPM = (MessageRx[59]*256)+MessageRx[60]; EGRPul = ((MessageRx[65]*256)+MessageRx[66])/100.0; SolenPul = ((MessageRx[67]*256)+MessageRx[68])/100.0; SolenPre = ((MessageRx[73]*256)+MessageRx[74])/100.0; DesInj = ((MessageRx[75]*3)+(MessageRx[76])/100.0)+0.3; ActInj = ((MessageRx[19]*3)+(MessageRx[20])/100.0)+0.3; //TempAir = ((MessageRx[77]*26)-278)+MessageRx[78]/10.0; //Temp = ((MessageRx[17]*26)-278)+MessageRx[18]/10.0; //TempOil = ((MessageRx[21]*26)-278)+MessageRx[22]/10.0; //TempFuel = ((MessageRx[61]*26)-278)+MessageRx[62]/10.0; //ниже идут расчетные формулы более точные чем те что закоментированы выше int A = 0; if (MessageRx[77]<=0x0A) A = 277; if (MessageRx[77]==0x0B || MessageRx[77]==0x0C) A = 278; if (MessageRx[77]>=0x0D) A = 279; double B = MessageRx[78]/10.0; double cel , drob ; drob = modf(B, &cel); if (drob>0.6) cel++; TempAir = ((MessageRx[77]*26)-A)+cel; if (MessageRx[17]<=0x0A) A = 277; if (MessageRx[17]==0x0B || MessageRx[77]==0x0C) A = 278; if (MessageRx[17]>=0x0D) A = 279; B = MessageRx[18]/10.0; drob = modf(B, &cel); if (drob>0.6) cel++; Temp = ((MessageRx[17]*26)-A)+cel; if (MessageRx[21]<=0x0A) A = 277; if (MessageRx[21]==0x0B || MessageRx[77]==0x0C) A = 278; if (MessageRx[21]>=0x0D) A = 279; B = MessageRx[22]/10.0; drob = modf(B, &cel); if (drob>0.6) cel++; TempOil = ((MessageRx[21]*26)-A)+cel; if (MessageRx[61]<=0x0A) A = 277; if (MessageRx[61]==0x0B || MessageRx[77]==0x0C) A = 278; if (MessageRx[61]>=0x0D) A = 279; B = MessageRx[62]/10.0; drob = modf(B, &cel); if (drob>0.6) cel++; TempFuel = ((MessageRx[61]*26)-A)+cel; timerenabledPID=0; } for (int i = 0; i < 110; i++) MessageRx[i]=0; }} // очистка байтов массива /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //отправка запроса на диагностическое соединение /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void initialization() { Serial.println ("Otpravil zapros Init"); for (int i = 0; i < length5; i++) { mySerial.write(messageInit[i]); delay (5); } delay (55); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //стартовая инициализация 7 пина ОБД //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void fastinit() { digitalWrite (TX, HIGH); // makes K-line high 3 delay(360); // wait for K-line to be clear 3 digitalWrite (TX, LOW); // makes K-line low 3 delay(25); digitalWrite (TX, HIGH); // makes K-line high 3 delay(25); //last delay before first message mySerial.begin(10400); } // baud rate of the OBD /////////////////////////////////////////////////////////////////////////////////////////////////////// //запрос чтения и стирания ошибок /////////////////////////////////////////////////////////////////////////////////////////////////////// void Read() { Serial.println ("Zapros error; "); for (int i = 0; i < length8; i++) { mySerial.write(messageREAD[i]); delay (waitbyte); }} void Erase() { Serial.println ("Zapros erase; "); for (int i = 0; i < length7; i++) { mySerial.write(messageERASE[i]); delay (waitbyte); }} ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //прорисовка тач кнопок /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Menu () { if (currentPage == '0') { TouchHOME(); TouchINF1(); TouchINF2(); TouchCHECK(); } if (currentPage == '1') { TouchHOME(); TouchINF2(); TouchCHECK(); } if (currentPage == '2') { TouchHOME(); TouchINF1(); TouchCHECK(); } if (currentPage == '3') { TouchHOME(); TouchREAD(); TouchERASE(); }} /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //прописывает заголовки и кнопки на страницах /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void drawHomeScreen() { line() ; Watch (); myGLCD.setTextColor(RED, BLACK); // цвет линии и текста красный myGLCD.drawLine(295,35,295,248); // линия вертикальная myGLCD.drawLine(145,35,145,178); // линия вертикальная myGLCD.drawLine(80,178,80,247); // линия вертикальная myGLCD.print("L/Hor", 10, 50); myGLCD.print("100/Ac", 148, 50); myGLCD.print("100/V", 10, 85); myGLCD.print("100/M", 148, 85); myGLCD.print("De/Km", 10, 120); myGLCD.print("De/Li", 148, 120); myGLCD.print("Vi/Km", 10, 155); myGLCD.print("Vi/Li", 148, 155); myGLCD.print("BOMBA RPM", 82, 190); myGLCD.print("MOTOR RPM", 82, 225); myGLCD.print("D/L/A", 10, 190); myGLCD.print("MOTOR C", 300, 50); myGLCD.print("OIL C", 300, 85); myGLCD.print("FUEL C", 300, 120); myGLCD.print("DENTR C", 300, 155); myGLCD.print("FUERA C", 300, 190); myGLCD.print("INTAIR C", 300, 225); myGLCD.drawRoundRect (15, 255, 145, 310); myGLCD.print("INF 1", 55, 280); myGLCD.drawRoundRect (175, 255, 305, 310); myGLCD.print("INF 2", 215, 280); myGLCD.drawRoundRect (335, 255, 465, 310); myGLCD.print("CHECK", 365, 280); myGLCD.drawRoundRect (1, 1, 77, 37); myGLCD.print("HOME", 20, 10); myGLCD.print("Km/h", 410, 10); } //------------------------------------------------- void drawscreen_one() { line() ; Watch (); myGLCD.setTextColor(RED, BLACK); // цвет линии и текста красный myGLCD.print("Start of Delivery *CA:", 10, 50); myGLCD.print("Desir inject Start *CA:", 10, 85); myGLCD.print("Actua Inject Start *CA:", 10, 120); myGLCD.print("Desir Inject Quan mg/s:", 10, 155); myGLCD.print("Actu Inject Quant mg/s:", 10, 190); myGLCD.print("MAF mg/s:", 10, 225); myGLCD.print("Humedad %:", 255, 225); myGLCD.drawRoundRect (175, 255, 305, 310); myGLCD.print("INF 2", 215, 280); myGLCD.drawRoundRect (335, 255, 465, 310); myGLCD.print("CHECK", 365, 280); myGLCD.drawRoundRect (1, 1, 77, 37); myGLCD.print("HOME", 10, 10); myGLCD.print("Km/h", 410, 10); } //------------------------------------------------- void drawscreen_two() { line() ; Watch (); myGLCD.setTextColor(RED, BLACK); // цвет линии и текста красный myGLCD.print("Boost Press Bar:", 10, 50); myGLCD.print("Boost Press Com Bar:", 10, 85); myGLCD.print("EGR command mg/s:", 10, 120); myGLCD.print("EGR Pulse Ratio %:", 10, 155); myGLCD.print("Solenoide Pulse %:", 10, 190); myGLCD.print("Solenoide Boost %:", 10, 225); myGLCD.drawRoundRect (15, 255, 145, 310); myGLCD.print("INF 1", 55, 280); myGLCD.drawRoundRect (335, 255, 465, 310); myGLCD.print("CHECK", 365, 280); myGLCD.drawRoundRect (1, 1, 77, 37); myGLCD.print("HOME", 20, 10); myGLCD.print("Km/h", 410, 10); } //---------------------------------------------------------------------------- void drawscreen_three() { Watch (); myGLCD.setTextColor(RED, BLACK); // цвет линии красный myGLCD.drawLine(1,35,479,35); // линия горизонтальная myGLCD.drawLine(1,248,479,248); // линия горизонтальная myGLCD.drawRoundRect (15, 255, 145, 310); myGLCD.print("ERASE", 55, 280); myGLCD.drawRoundRect (335, 255, 465, 310); myGLCD.print("READ", 365, 280); myGLCD.drawRoundRect (1, 1, 77, 37); myGLCD.print("HOME", 20, 10); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //кнопки тач . координаты и переходы ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void TouchHOME(){ TSPoint p = ts.getPoint(); pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); if (p.z > 10 && p.z < 1000) {if (p.x > 140 && p.x < 320 && p.y > 140 && p.y < 260 && p.z > MINPRESSURE && p.z < MAXPRESSURE) { myGLCD.drawRoundRect (1, 1, 77, 37); currentPage = '0'; myGLCD.clrScr(); drawHomeScreen(); x = 0; y = 0; p.z = 0;}}} void TouchINF1(){ TSPoint p = ts.getPoint(); pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); if (p.z > 10 && p.z < 1000) { if (p.x > 150 && p.x < 450 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE) { myGLCD.drawRoundRect (15, 255, 145, 310); currentPage = '1'; myGLCD.clrScr(); drawscreen_one(); x = 0; y = 0; p.z = 0;}}} void TouchINF2(){ TSPoint p = ts.getPoint(); pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); if (p.z > 10 && p.z < 1000) { if (p.x > 450 && p.x < 680 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE) { myGLCD.drawRoundRect (175, 255, 305, 310); currentPage = '2'; myGLCD.clrScr(); drawscreen_two(); x = 0; y = 0; p.z = 0;}}} void TouchCHECK(){ TSPoint p = ts.getPoint(); pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); if (p.z > 10 && p.z < 1000) { if (p.x > 690 && p.x < 950 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE) { myGLCD.drawRoundRect (335, 255, 465, 310); currentPage = '3'; myGLCD.clrScr(); drawscreen_three(); x = 0; y = 0; p.z = 0;}}} void TouchREAD(){ TSPoint p = ts.getPoint(); pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); if (p.z > 10 && p.z < 1000) { if (p.x > 690 && p.x < 950 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE) { myGLCD.drawRoundRect (335, 255, 465, 310); Read(); x = 0; y = 0; p.z = 0;}}} void TouchERASE(){ TSPoint p = ts.getPoint(); pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); if (p.z > 10 && p.z < 1000) { if (p.x > 150 && p.x < 450 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE) { myGLCD.drawRoundRect (15, 255, 145, 310); Erase(); x = 0; y = 0; p.z = 0;}}} //////////////////////////////////////////////////////////////////////////////////////// //прорисовка линий /////////////////////////////////////////////////////////////////////////////////////// void line() { myGLCD.setColor(255, 0, 0); // цвет линии красный myGLCD.drawLine(1,35,479,35); // линия горизонтальная myGLCD.drawLine(1,73,479,73); // линия горизонтальная myGLCD.drawLine(1,108,479,108); // линия горизонтальная myGLCD.drawLine(1,143,479,143); // линия горизонтальная myGLCD.drawLine(1,178,479,178); // линия горизонтальная myGLCD.drawLine(1,212,479,212); // линия горизонтальная myGLCD.drawLine(1,248,479,248); }// линия горизонтальная ///////////////////////////////////////////////////////////////////////////////////////////// //верхняя часть экрана часы и дата отображается на всех экранах ///////////////////////////////////////////////////////////////////////////////////////////// void Watch (){ DateTime now = rtc.now(); int m = now.minute(); int hour = now.hour(); int mon = now.month(); int date = now.day(); myGLCD.setTextColor(WHITE, BLACK); //белый цвет цифры if (date<10) { myGLCD.print("0", 85, 10); myGLCD.printNumI(now.day(), 100, 10); } else if (date >=10) { myGLCD.printNumI(now.day(), 85, 10); } myGLCD.print("/", 115, 10); if ( mon<10) { myGLCD.print("0", 130, 10); myGLCD.printNumI(now.month(), 145, 10);} else if (mon >=10) { myGLCD.printNumI(now.month(), 130, 10);} myGLCD.print("/", 160, 7); myGLCD.printNumI(now.year(), 175, 10); if (hour<10) { myGLCD.print("0",255, 7); myGLCD.printNumI(now.hour(), 270, 10); } else if(hour>=10){ myGLCD.printNumI(now.hour(), 255, 10); } if (m<10) { myGLCD.print("0",300, 10); myGLCD.printNumI(now.minute(), 315, 10); } else if (m>=10){ myGLCD.printNumI(now.minute(), 300, 10); } } void Temperature (){ h = dht.readHumidity(); t = dht.readTemperature(); sensors.requestTemperatures(); }Спасибо
Сколько памяти свободно остаётся во флеше без красивого шрифта ? Можно свой шрифт организовать по типу обычного (по крайней мере для тех символов, которыми отображаются динамические данные)!
Сколько памяти свободно остаётся во флеше без красивого шрифта ? Можно свой шрифт организовать по типу обычного (по крайней мере для тех символов, которыми отображаются динамические данные)!
привет мужики, что-то после отпуска сюда не заглядывал. Как, удалось тогда победить моргание на пропорциональных шрифтах, или забили и "пошли другим путем" ?
Командир, завтра скажу сколько памяти. Я уже думал ковырять стандартный шрифт, сделать его хотя-бы вытянутой а не квадратным
B707. Победить то победили, но вот то что он сильно тормозит все, может у меня экран слабый.
"экран слабый" быть не может. Если тормозит, то причины м.б. только две - либо код не оптимальный, либо проц слабый (то есть вместо ардуины надо брать СТМ, к примеру)
Хз. На прошлом экране все было гуд. Сменил экран и пошли тормоза. Так что ардуина не при чем. Сам устал бороться, и ребят уже замучал
прошлый экран был такого же размера разве?
Для обновления картинки 240Х320 нужно примерно в 10 раз больше времени, чем, например, 128х64. И никакой "слабый экран" тут не при чем - это просто ардуина слабая для этого экрана, вот и все.
Поставил стандартный шрифт и все пошло. Думаю стандартный ковырять так как размер 2 маловат а 3 за большой и квадратные они, мне бы вытянутые, уродливый но мать его за лапу, какой есть. Именно при добавлении стороннего шрифта начининаются тормоза.
Был такой же размер
#define K_LINE_GAUGE Serial2 //UART на котором висит K_line к приборке #define TX_gauge 16 //TX UARTa на котором висит K_line к приборке const byte BAUD=200; // init baudrate - скорость инита при подключении к приборке const byte addressGUAGE = 0xB8; // init GAUGE address - адрес щитка приборов при ините (установке связи) //#define debugPCM // раскоментировать эту строку для отладки в Serial порту обмена с PCM #define debugGAUGE // раскоментировать эту строку для отладки в Serial порту обмена co щитком приборов uint32_t curmillis = 0; // снимок текущего времени const byte waitbyte_RX_GAUGE = 0; // задержка, мс для успевания появления данных в буфере RX byte InitGauge = 0; // автомат состояния инита щитка приборов const byte bufsizeG = 150; // размер буфера принятого сообщения byte MessageRx_GAUGE [bufsizeG] = {0}; // буфер принятого сообщения byte PIDgauge[] = {0x02,0x11,0x00,0x13}; // запрос параметоров щитка приборов void setup() { #if defined debugPCM or defined debugGAUGE Serial.begin (115200); #endif } void loop() { curmillis = millis(); // снимок текущего времени receiveGAUGE (); // приём сообщений от приборки } void receiveGAUGE () { static uint32_t prevRESETheaderGAUGE = 0;// таймер сброса сообщения, если данные оборвались посередине сообщения static bool RESETheader_timerGAUGE = 0; // таймер сброса сообщения, если данные оборвались посередине сообщения static uint32_t timerdelayGAUGE = 0; // таймер ожидания байт (для успевания появления данных в буфере UART) static bool DelayGAUGE = 1; // таймер ожидания байт (для успевания появления данных в буфере UART) static uint32_t prevNoconnect = 0; // таймер периодической проверки наличия связи со щитком приборов static byte NoconnectsGAUGE = 0 ; // счетчик неответов от щитка приборов static byte headerGAUGE = 0; // состояние заголовка static byte message_sizeGAUGE = 0; // размер тела сообщения static byte jGAUGE = 3; // инкремент static byte nGAUGE = 3; // количество старт байт static int ChecksumGAUGE = 0; // байт контрольной суммы if (K_LINE_GAUGE.available() ){ // первый старт байт if (headerGAUGE == 0 && DelayGAUGE){DelayGAUGE = 0; timerdelayGAUGE = curmillis; MessageRx_GAUGE[0]=K_LINE_GAUGE.read(); if ((InitGauge ==1 && MessageRx_GAUGE[0]==0x55) || InitGauge ==2 && MessageRx_GAUGE[0]!=0xFF && MessageRx_GAUGE[0]!=0x7F) {headerGAUGE = 1; RESETheader_timerGAUGE = 1; prevRESETheaderGAUGE = curmillis; #ifdef debugGAUGE Serial.print (F("Receive GAUGE: ")); printDebugRX(MessageRx_GAUGE[0]); #endif } } // второй старт байт if (headerGAUGE == 1 && DelayGAUGE){DelayGAUGE = 0; timerdelayGAUGE = curmillis; MessageRx_GAUGE[1]=K_LINE_GAUGE.read(); #ifdef debugGAUGE printDebugRX (MessageRx_GAUGE[1]); #endif if ( (InitGauge ==1 && MessageRx_GAUGE[1]==0x52) || (InitGauge ==2 && (MessageRx_GAUGE[1]==0xA0 || MessageRx_GAUGE[1]==0xA1))){ headerGAUGE = 2;} else { #ifdef debugGAUGE Serial.println(F(" GAUGE Message fail address")); #endif headerGAUGE = 0; RESETheader_timerGAUGE = 0;}} // третий старт байт if (headerGAUGE == 2 && DelayGAUGE){ DelayGAUGE = 0; timerdelayGAUGE = curmillis; MessageRx_GAUGE[2]=K_LINE_GAUGE.read(); #ifdef debugGAUGE printDebugRX (MessageRx_GAUGE[2]); #endif if (InitGauge ==2 && (MessageRx_GAUGE[2]==0x48 || MessageRx_GAUGE[2]==0x04)){ message_sizeGAUGE = MessageRx_GAUGE[0]-2; prevRESETheaderGAUGE = curmillis; headerGAUGE = 4; jGAUGE=3; nGAUGE=3; if (message_sizeGAUGE > bufsizeG) message_sizeGAUGE = bufsizeG; ChecksumGAUGE = 0;} else if (InitGauge ==1 && MessageRx_GAUGE[2]==0x80) {InitGauge = 2; K_LINE_GAUGE.write(0x7F); delay (2); K_LINE_GAUGE.read(); headerGAUGE = 0; RESETheader_timerGAUGE = 0; #ifdef debugGAUGE Serial.println ("Gauge INIT is good!"); #endif } else {headerGAUGE = 0; #ifdef debugGAUGE Serial.println(F("GAUGE Message fail address")); #endif RESETheader_timerGAUGE = 0;} } // пишем тело сообщения if (headerGAUGE == 4 && DelayGAUGE && jGAUGE< message_sizeGAUGE+nGAUGE+1) { MessageRx_GAUGE[jGAUGE] = K_LINE_GAUGE.read(); prevRESETheaderGAUGE = curmillis; if (jGAUGE<message_sizeGAUGE+nGAUGE-1) ChecksumGAUGE+= MessageRx_GAUGE[jGAUGE]; // подсчёт КС if (jGAUGE==message_sizeGAUGE+nGAUGE) headerGAUGE = 5; DelayGAUGE = 0; timerdelayGAUGE = curmillis ; #ifdef debugGAUGE printDebugRX(MessageRx_GAUGE[jGAUGE]); #endif jGAUGE++; } } // сообщение приняли, действуем if (headerGAUGE == 5) {DelayGAUGE = 0; timerdelayGAUGE = curmillis ; #ifdef debugGAUGE Serial.println(); #endif for(byte i = 0; i<nGAUGE; i++) ChecksumGAUGE+=MessageRx_GAUGE[i]; // прибавляем к контрольной сумме старт байты int ChecksumG = ( ( unsigned int )MessageRx_GAUGE[message_sizeGAUGE+nGAUGE-1] << 8 ) | MessageRx_GAUGE[message_sizeGAUGE+nGAUGE]; // парсинг контрольной суммы из 2 последних байт // если контрольная сумма верна: if ( ChecksumGAUGE == ChecksumG) { NoconnectsGAUGE = 0; // сбрасываем на 0 отсутствие связи с панелью #ifdef debugGAUGE Serial.print (F("Received message is OK! Checksum is correct!")); Serial.print (F(" ")); Serial.println (millis()); // Если КС совпала, тут чёнибудь нужное делаем #endif if (MessageRx_GAUGE[1]== 0xA0 && MessageRx_GAUGE[2]== 0x48) { #ifdef debugGAUGE Serial.println ("ID panel receive! Send request PIDGauge"); #endif for (byte i=0; i<sizeof(PIDgauge); i++) { K_LINE_GAUGE.write (PIDgauge[i]); delay (2); K_LINE_GAUGE.read();} } if (MessageRx_GAUGE[1]== 0xA1 && MessageRx_GAUGE[2]== 0x04) { byte Fuel = 0; int kmAge = 0; kmAge = (MessageRx_GAUGE[nGAUGE+23]+(MessageRx_GAUGE[nGAUGE+24]*256))/10.0; Fuel = MessageRx_GAUGE[nGAUGE+16]/2.00; #ifdef debugGAUGE // Serial.println (" receive Datastream Gauge!"); Serial.print ("Fuel = "); Serial.print (Fuel); Serial.print (" Odometer = "); Serial.println (kmAge) ; #endif } } // если контрольная сумма не совпала: #ifdef debugGAUGE else Serial.println("CRC fail!!!" ); #endif message_sizeGAUGE = 0; headerGAUGE=0; RESETheader_timerGAUGE = 0; jGAUGE=3; ChecksumGAUGE = 0; } // таймер ожидания байт (для успевания появления данных в буфере UART) if (!DelayGAUGE && curmillis - timerdelayGAUGE > waitbyte_RX_GAUGE) DelayGAUGE = 1; // таймер сброса целостности сообщения (если данные оборвались посередине сообщения) if (RESETheader_timerGAUGE && curmillis - prevRESETheaderGAUGE > 1000) { #ifdef debugGAUGE Serial.println(F("Message fail timeout")); #endif RESETheader_timerGAUGE = 0; headerGAUGE = 0;} if (curmillis - prevNoconnect > 500) {NoconnectsGAUGE ++ ; if (NoconnectsGAUGE>=12){ #ifdef debugGAUGE Serial.println (F(" Connect GAUGE failed!!! ")) ; #endif NoconnectsGAUGE = 0 ;InitGauge = 0 ; } prevNoconnect = curmillis; } InitBusGAUGE (); }// end receiveGAUGE void printDebugRX (const byte &inbyte) {if (inbyte<=15) Serial.print(F("0")); Serial.print (inbyte, HEX); Serial.print (F(" "));} void InitBusGAUGE () { static uint32_t prevInitbusGauge; // таймер для инита щитка приборов if (InitGauge == 0){ #ifdef debugGAUGE Serial.println ("Send startsession - address Gauge"); #endif K_LINE_GAUGE.end(); pinMode(TX_gauge, OUTPUT); digitalWrite (TX_gauge, HIGH); // BUS IDLE InitGauge = 5; prevInitbusGauge = curmillis; } if (InitGauge == 5 && curmillis - prevInitbusGauge>1500) {InitGauge = 6;} // BUS IDLE if (InitGauge == 6) { byte boudrate = 1000/BAUD; digitalWrite (TX_gauge, LOW); delay (boudrate); // старт бит for (byte i=0; i<8; i++){digitalWrite (TX_gauge, bitRead(addressGUAGE, i)); delay (boudrate);} // биты тела адреса digitalWrite (TX_gauge, HIGH); delay (boudrate); // стоп бит K_LINE_GAUGE.begin(9600); InitGauge = 1; } }также попробуй 1929 без использования шрифта , чтобы экран не тормозил
Я вышел на отличный результат со стандартным шрифтом. И мой старый и твой новый работают быстро. В старом только косяк в четырёх данных. В твоём новом хаус в расчётах. Но оба работают очень быстро со стандартным. Плевать уже на красоту.
Ок. На этой неделе не работаю что будет, не смогу. Через неделю продолжу ковырять.
ты пробуй не последний а 1929
Ок, через неделю. Мог бы дома, но в ноуте батарея сдохла, с 4 этажа кабель не кинешь :)
viki13viki Привет. Мне кажется или ты решил отказаться от проверки выводимых данных на изменения (ака last...)? Или вы скрещиваете не с крайним скетчем !!! Я бы еще даже не сами значения сравнивал, а данные из буфера, что бы не производить вычисления, если данные для конкретного параметра не изменились (особенно если в вычислении есть деление/умножение).
На следующей недели продолжу. Я сейчас использую старый скетчь на стандартном шрифты без Last. Но и последний со стандартным шрифтом с Last летает, но хаус в расчётах, и проблема в выводимых данных. При переходе на страницы прорисовывается только часть данных, renew тыкал везде, как в верху так и в низу на каждой страницы так и для всех страниц один renew внизу. Проверю 1229 о котором выше говорил Макс, тока на стандартном шрифты. Но уже в понедельник
Отчет по 1929 . Вроде все данные показываетю. Косяки: 1. TempAir показывает 36 ( через 5 мин после второй прошивки показал 44 градуса, что уже не коректно, должно быть где-то 14-16 примерно(но это нужно проверять когда подключится наружняя температура) тогда скажу точно, я их сравниваю. 2. при переходах на страницы не всегда прорисовывает часы.(но это пока не важно) добавил в низу в Watch это reNew = 1;, не помогло. Остальное нужно на ходу проверять. Работет мгновенно, прорисовка мгновенно.
вот скетч чтобы далеко не бегать
//------------все для связи по K-line (тут настраиваем UARTы к-лайников, адреса блоков, скорость инита и отладку) #include <SoftwareSerial.h> #define TX_PCM 13 SoftwareSerial K_LINE_PCM (12, TX_PCM); //RХ,TХ //UART на котором висит K_line к PCM #define K_LINE_GAUGE Serial2 //UART на котором висит K_line к приборке #define TX_gauge 16 //TX UARTa на котором висит K_line к приборке #define PCM_address 0x11 // адрес PCM #define DIAG_address 0xF1 // адрес диагностики const byte BAUD=200; // init baudrate - скорость инита при подключении к приборке const byte addressGUAGE = 0xB8;// init GAUGE address - адрес щитка приборов при ините (установке связи) //#define debugPCM // раскоментировать эту строку для отладки в Serial порту обмена с PCM #define debugGAUGE // раскоментировать эту строку для отладки в Serial порту обмена co щитком приборов uint32_t curmillis = 0; // снимок текущего времени //------------------------------------------переменные для организации протокола связи с PCM uint32_t prevRequest = 0; // таймер периодических запосов на PCM uint16_t RequestPeriod = 3500; // периодичность запросов на PCM uint32_t prevRESETheader=0; // таймер сброса сообщения, если данные оборвались посередине сообщения bool RESETheader_timer; // таймер сброса сообщения, если данные оборвались посередине сообщения uint32_t prev_NOanswer=0; // таймер контроля неответов от ЭБУ после подачи запросов bool NOanswer_timer = 0; // таймер контроля неответов от ЭБУ после подачи запросов byte noanswers = 0; // количество подряд неответов от ЭБУ uint32_t timerdelay = 0; // таймер ожидания байт (для успевания появления данных в буфере UART) bool Delay = 0; // таймер ожидания байт (для успевания появления данных в буфере UART) byte waitbyte_RX = 1; // задержка, мс для успевания появления данных в буфере RX // (подрегулировать в зависимости от уровня жизнидеятельности на Марсе) #define TIMER_DELAY Delay = 0; timerdelay = curmillis // включение этого таймера byte delaybyte_TX = 1; // задержка между отправкой байт в запросах, мс byte header = 0; // состояние заголовка byte message_size = 0; // размер тела сообщения byte j = 3; // инкремент byte n = 3; // количество старт байт const byte bufsize = 150; // размер буфера принятого сообщения byte MessageRx_PCM [bufsize] = {0}; // буфер принятого сообщения byte crc =0; // байт контрольной суммы // возможные варианты запросов на ЭБУ: enum REQUEST {INIT, PID, DTCERASE, DTCREAD, PRESENT,}; // текстовки запросов для отладки char* textRequest[] = {"INIT", "PID_2101", "DTC_ERASE", "DTC_READ", "PRESENT",} ; // сами запросы byte PCM_Message_TX[][5] = { {1, 0x81, 0,0,0}, // запрос инициализации {2, 0x21,0x01, 0,0}, // запрос пид 2101 {3, 0x14,0xFF,0x00, 0}, // запрос на стирание ошибок {4, 0x18,0x00,0xFF,0x00 }, // запрос на чтение ошибок {1, 0x3E, 0,0,0}, // запрос присутствия }; byte request = INIT; // переменная, показывающая какой запрос будем делать //------------------------------------------ переменные для организации протокола связи со щитком приборов uint32_t prevRESETheaderGAUGE=0; // таймер сброса сообщения, если данные оборвались посередине сообщения bool RESETheader_timerGAUGE; // таймер сброса сообщения, если данные оборвались посередине сообщения uint32_t timerdelayGAUGE = 0; // таймер ожидания байт (для успевания появления данных в буфере UART) bool DelayGAUGE = 0; // таймер ожидания байт (для успевания появления данных в буфере UART) uint32_t prevNoconnect = 0; // таймер периодической проверки наличия связи со щитком приборов byte waitbyte_RX_GAUGE = 1; // задержка, мс для успевания появления данных в буфере RX // (подрегулировать в зависимости от уровня жизнидеятельности на Марсе) #define TIMER_DELAYGAUGE DelayGAUGE = 0; timerdelayGAUGE = curmillis // включение этого таймера uint32_t prevInitbusGauge = 0; // таймер для инита щитка приборов byte NoconnectsGAUGE = 0 ; // счетчик неответов от щитка приборов byte headerGAUGE = 0; // состояние заголовка byte message_sizeGAUGE = 0; // размер тела сообщения byte jGAUGE = 3; // инкремент byte nGAUGE = 3; // количество старт байт int ChecksumGAUGE =0; // байт контрольной суммы byte InitGauge = 0; // автомат состояния инита щитка приборов const byte bufsizeG = 150; // размер буфера принятого сообщения byte MessageRx_GAUGE [bufsizeG] = {0}; // буфер принятого сообщения byte PIDgauge[] = {0x02,0x11,0x00,0x13}; // запрос параметоров щитка приборов //-------------------------------------------переменные бортовика float L100M = 0; float L100M_last = 1; //расход на 100 км измеренный за поездку float L100 = 0; float L100_last = 1; //мгновенный расход литров на 100км float LHor = 0; float LHor_last = 1; //мгновенный расход топлива литров в час float L100SR = 0; //расход литров на 100км измеренный раз в интервал kmL float L100SR_TFT = 0; float L100SR_TFT_last = 1; // самый средний из расходов на 100км, он выводится на экран int L100_Eeprom[11]= {10,10,10,10,10,10,10,10,10,10,10}; int FuelZamer[10]= {0}; // массив для измерения уровня (количества) топлива int ZamerNumber = 0; // номер замера уровня (количества) топлива int n_eeprom = 0; // текущий адрес ячейки еепром для записи расхода int MAF = 0; int MAF_last = 1; //26,27 байты Sensor de flujo de aire en masa float BoostPres = 0; float BoostPres_last = 1; //28,29 байты Presión de refuerzo int RPM = 0; int RPM_last = 1; //32,33 байты Velocidad del motor int EGRmg = 0; int EGRmg_last = 1; //34,35 байты Comando EGR (Comando de recirculación de gases de escape) float BoostPresCom = 0; float BoostPresCom_last = 1;//38,39 байты Comando de presión de refuerzo int Speed = 0; int Speed_last = 1; //44,45 байты Velocidad del vehículo float DesaInjQua = 0; float DesaInjQua_last = 1; //50,51 байты Cantidad de inyección deseada float InjQua = 0; float InjQua_last = 1; //52,53 байты Cantidad de la inyección float StaDaliv = 0; float StaDaliv_last = 1; //54,55 байты Inicio de la entrega int PumpRPM = 0; int PumpRPM_last = 1; //56,57 байты Velocidad de la bomba float EGRPul = 0; float EGRPul_last = 1; //62,63 байты Relación de impulsos EGR (recirculación de gases de escape float SolenPul = 0; float SolenPul_last = 1; //64,65 байты Velocidad de solenoide de control de nivel de remolino Relación de impulsos float SolenPre = 0; float SolenPre_last = 1; //70,71 байты Relación de impulsos Presión Electroválvula de presión float DesInj = 0; float DesInj_last = 1; //72,73 байты Inyección deseada Inicio float ActInj = 0; float ActInj_last = 1; //16,17 байты Inicio de la inyección real int TempAir = 0; int TempAir_last = 1; //74,75 байты Temperatura del aire de admisión int Temp = 0; int Temp_last = 1; //14,15 байты Temperatura del refrigerante int TempOil = 0; int TempOil_last = 1; //18,19 байты Temperatura del aceite del motor int TempFuel = 0; int TempFuel_last = 1; //58,59 байты Temperatura del combustible //все что касается топлива float Fuel = 0; //остаток топлива float Fuel2 = 0; float Fuel2_last = 1; //остаток мгновенного топлива байт 16 , датчика в баке int FuelIGN = 0; // количество топлвива в баке на момент включения зажигания int Fuel_last = 0; // для формул bool flagFuelIGN = 0; // флаг записан ли остаток топлива в момент вкл. зажигания float FuelTrip = 0; float FuelTrip_last = 1; // количество литров топлива, израсходованное за один цикл включения зажигания //все что касается километража float kmAge = 0; //пробег, полученный со щитка приборов int kmAgeIGN = 0; //пробег который был в момент включения зажигания int kmAge_last = 0; // для формул bool flagkmAgeIGN = 0; //флаг записан ли пробег в момент вкл. зажигания float kmTrip = 0; float kmTrip_last = 1; //пробег за один цикл включения зажигания int kmL = 10; // интервал, через который будет происходить обновление среднего расхода на 100км int km = 0; // переменная для расчетов int kmeeprom = 10; // интервал, через который будет происходить подсчет среднеарифмитического расхода L100SR_TFT int kmTFT = 0; // переменная для расчетов периодического подсчета среднеарифмитического расхода топлива L100SR_TFT int kmREFUELING = 0; int kmREFUELING_last = 1; // пробег до заправки на остатке топлива unsigned long prevWatch = 0; unsigned long prevDvoet = 0; unsigned long prevData = 0; //----------------------------------------------для экрана #include <Adafruit_GFX.h> #include <MCUFRIEND_kbv.h> #include <UTFTGLUE.h>//use GLUE class and constructor #include "TouchScreen.h" #include <stdint.h> #include <SPI.h> #include <EEPROM.h> //#include "Fonts/Chosence_Bold16pt7b.h"; #define MINPRESSURE 200 #define MAXPRESSURE 1000 //pin 20 SCL , 21 SDA датчик реального времени #include <Wire.h> #include "RTClib.h" RTC_DS3231 rtc; UTFTGLUE myGLCD(0x1581,A2,A1,A3,A4,A0); //all dummy args const int XP = 6, XM = A2, YP = A1, YM = 7; const int TS_LEFT = 136, TS_RT = 907, TS_TOP = 139, TS_BOT = 942; TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300); uint16_t ID; int x, y; char currentPage; float h; int h_last = 1; float t; int t_last = 1; bool Dvoet = 0; bool reNew = 0; #define BLACK 0x0000 #define WHITE 0xFFFF #define RED 0xF800 #define GREEN 0x07E0 void setup() { uint16_t ID = myGLCD.readID(); if (ID == 0xD3D3) ID = 0x1581; // write-only shield myGLCD.begin(ID); myGLCD.InitLCD(3); myGLCD.clrScr(); myGLCD.setTextSize(2); //myGLCD.setFont(&Chosence_Bold16pt7b); Wire.begin(); rtc.begin(); //загрузка стартовой страницы currentPage = '0'; drawHomeScreen(); //подсчет среднеарифметического усредненного расхода for (int i = 0; i < 11; i++) L100_Eeprom [i]= EEPROM.read(i); for (int i = 0; i < 11; i++) L100SR_TFT = L100SR_TFT + L100_Eeprom [i]; L100SR_TFT = (float)L100SR_TFT/110.0; if (L100SR_TFT<0) L100SR_TFT = 0; if (L100SR_TFT>99) L100SR_TFT = 99; // строка ниже используется для настройки даты и времени часов // раскоментировать, выставить времая и дату, залить в ардуино. в скетче закоментировать // обратно и залить еще раз, иначе каждый раз будет по новой выствлятся это же время и дата // (год, месяц, день, часы, минуты, секунды) //rtc.adjust(DateTime(2019, 7, 2, 10, 48, 0)); #if defined debugPCM or defined debugGAUGE Serial.begin(115200); #endif K_LINE_PCM.begin(10400); pinMode(TX_PCM, OUTPUT); } void loop() { curmillis = millis(); // снимок текущего времени if (curmillis - prevRequest > RequestPeriod && header == 0 ) { if (request == INIT) fastinit(); // при необходимости делаем переподключение к PCM else {sendMessagePCM(request); // отправляем на PCM текущий запрос if (request == PID) RequestPeriod = 600; if (request == DTCERASE || request == DTCREAD) RequestPeriod = 2500;} prevRequest = curmillis; } receivePCM (); // приём сообщений от PCM receiveGAUGE (); // приём сообщений от щитка приборов if (header == 0) {Menu ();} if (curmillis - prevWatch > 4000) { Watch (); prevWatch = curmillis; Trip ();} //if (curmillis - prevDvoet > 500) { if (!Dvoet) {myGLCD.setTextColor(WHITE); } else {myGLCD.setTextColor(BLACK); } myGLCD.print(":", 290, 5); prevDvoet = curmillis; Dvoet=!Dvoet;} if (millis() - prevDvoet > 500) { if (!Dvoet) {myGLCD.print(":", 290, 5);} else {myGLCD.print(" ", 290, 5);} prevDvoet = millis(); Dvoet=!Dvoet;} }// end loop void Trip () { if (flagkmAgeIGN){ FuelTrip = FuelIGN - Fuel; if (kmAge>kmAgeIGN) kmTrip = kmAge - kmAgeIGN; if (kmAge<kmAgeIGN) kmTrip = 2000 - (kmAgeIGN - kmAge); // 2000 это через сколько км у тебя суточный пробег сбрасывается на ноль, поменяй если другое число if (kmAge==kmAgeIGN) kmTrip = 0; //подсчет расхода на 100км за поездку L100M = ((float)FuelTrip*100.00)/(float)kmTrip; if (L100M<0) L100M = 0; if (L100M>99) L100M = 99; // ниже цикл считает среднеарифметический расход из еепром раз в пробег, указанный в переменной kmeeprom if (kmTrip-kmTFT>kmeeprom) {kmTFT = kmTrip; // тут считаем среднеарифметический усредненного расход из ячеек еепром for (int i = 0; i < 11; i++) L100_Eeprom [i]= EEPROM.read(i); for (int i = 0; i < 11; i++) L100SR_TFT = L100SR_TFT + L100_Eeprom [i]; L100SR_TFT = (float)L100SR_TFT/110.00; if (L100SR_TFT<0) L100SR_TFT = 0; if (L100SR_TFT>99) L100SR_TFT = 99;} // ниже цикл считает расход топлива за пробег, указанный в переменной kmL, здесь же запись в ячейки еепром if (kmTrip-km>kmL) {km=kmTrip; L100SR = ((float)(Fuel_last-Fuel)*100.00)/(float)kmL; // расход/100км - обновляется раз в 10км, меняется км в int kmL = 10; Fuel_last = Fuel; // сохранение параметров с последнего измерениея if (L100SR<0) L100SR = 0; if (L100SR>99) L100SR = 99; //расчет остатка километров в баке if (L100SR>0) kmREFUELING=((float)Fuel*100.0)/(float)L100SR; //если средний расход больше нуля, то расчитывать км в баке из него else kmREFUELING=((float)Fuel*100.00)/(float)L100SR_TFT; //если ноль или ментше то расчитывать км в баке с устредненного расхода // тут записываем L100SR последовательно в одну из 11 ячеек еепром //EEPROM.write (12,n_eeprom); // ЗДЕСЬ ВНИМАТЕЛЬНО. ЗАГРУЗИТЬ ПРОШИВКУ С ЭТОЙ СТРОКОЙ ОДИН РАЗ, ПОТОМ ЗАКОМЕНТИРОВАТЬ И ЕЩЁ РАЗ ЗАГРУЗИТЬ n_eeprom = EEPROM.read (12); // в ячейке 12 хранится № текущей ячейки для записи расхода, чтобы где остановился при выкл питания, от туда и продолжил EEPROM.write(n_eeprom, L100SR*10); n_eeprom++; if (n_eeprom>10) n_eeprom=0; EEPROM.write (12,n_eeprom); }}} void fastinit() { digitalWrite (TX_PCM, HIGH); // bus idle delay(1500); digitalWrite (TX_PCM, LOW); // first part fastinit (25 ms LOW) delay(25); digitalWrite (TX_PCM, HIGH); // second part fastinit (25 ms HIGH) delay(25); K_LINE_PCM.begin(10400); sendMessagePCM(INIT); // send start communication message } void receivePCM () { if (K_LINE_PCM.available() ){ // первый старт байт if (header == 0 && Delay){TIMER_DELAY ; MessageRx_PCM[0]=K_LINE_PCM.read(); if (MessageRx_PCM[0]!=0xFF && bitRead (MessageRx_PCM[0],7)){header = 1; RESETheader_timer = 1; prevRESETheader = curmillis; #ifdef debugPCM Serial.print (F("Receive PCM: ")); printDebugRX(MessageRx_PCM[0]); #endif } } // второй старт байт if (header == 1 && Delay){TIMER_DELAY ; MessageRx_PCM[1]=K_LINE_PCM.read(); #ifdef debugPCM printDebugRX (MessageRx_PCM[1]); #endif if (MessageRx_PCM[1]==DIAG_address){ header = 2;} else { #ifdef debugPCM Serial.println(F(" PCM Message fail address")); #endif header = 0; RESETheader_timer = 0;}} // третий старт байт if (header == 2 && Delay){ TIMER_DELAY ; MessageRx_PCM[2]=K_LINE_PCM.read(); #ifdef debugPCM printDebugRX (MessageRx_PCM[2]); #endif if (MessageRx_PCM[2]==PCM_address){ message_size = MessageRx_PCM[0]; prevRESETheader = curmillis; if (MessageRx_PCM[0] !=0x80) {header = 4; bitWrite (message_size, 7 , 0);j=3;n=3;} else {header = 3; j=4;n=4;} if (message_size > bufsize) message_size = bufsize; crc = 0;} else {header = 0; #ifdef debugPCM Serial.println(F("PCM Message fail address")); #endif RESETheader_timer = 0;} } // если размер сообщения указан в дополнительном байте (нулевой байт 0x80) читаем этот дополнительный байт: if (header == 3 && Delay){ TIMER_DELAY ; prevRESETheader = curmillis; MessageRx_PCM[3]=K_LINE_PCM.read(); #ifdef debugPCM printDebugRX(MessageRx_PCM[3]); #endif message_size = MessageRx_PCM[3]; if (message_size > bufsize) message_size = bufsize; crc = 0; header = 4; } // пишем тело сообщения if (header == 4 && Delay && j< message_size+n+1) { MessageRx_PCM[j] = K_LINE_PCM.read(); prevRESETheader = curmillis; if (j<message_size+n) crc+= MessageRx_PCM[j]; // подсчёт КС if (j==message_size+n) header = 5; TIMER_DELAY ; #ifdef debugPCM printDebugRX(MessageRx_PCM[j]); #endif j++; } } // сообщение приняли, действуем if (header == 5) {TIMER_DELAY ; #ifdef debugPCM Serial.println(); #endif NOanswer_timer = 0; noanswers = 0; // сбрасываем таймер контроля неответов for(byte i = 0; i<n; i++) crc+=MessageRx_PCM[i]; // прибавляем к контрольной сумме старт байты // если контрольная сумма верна: if ( crc == MessageRx_PCM[message_size+n]) { #ifdef debugPCM Serial.print (F("Received message is OK! Checksum is correct!")); Serial.print (F(" ")); Serial.println (millis()); // Если КС совпала, тут чёнибудь нужное делаем printDebugRX_CSgood(); #endif if (MessageRx_PCM[n]==0xC1 && MessageRx_PCM[n+1]==0x6B && MessageRx_PCM[n+2]==0x8F) { if (currentPage!=3) {request = PID; RequestPeriod = 70;} else request = PRESENT, RequestPeriod = 4000; prevRequest = curmillis; // receive good INIT } else if (MessageRx_PCM[n]==0x58) Troublecodes (); // DTC else if (MessageRx_PCM[n]==0x54 && MessageRx_PCM[n+1]==0xFF && MessageRx_PCM[n+2]==0x00){ request = PRESENT; RequestPeriod = 4000; prevRequest = curmillis;} // DTC are cleared else if (MessageRx_PCM[n]==0x61 && MessageRx_PCM[n+1]==0x01) {dataVars() ; RequestPeriod = 70; prevRequest = curmillis; } // receive DataStream } // если контрольная сумма не совпала: #ifdef debugPCM else Serial.println("CRC fail!!!" ); #endif message_size = 0; header=0; RESETheader_timer = 0; j=3; crc = 0; } // таймер ожидания байт (для успевания появления данных в буфере UART) if (!Delay && curmillis - timerdelay > waitbyte_RX) Delay = 1; // таймер сброса целостности сообщения (если данные оборвались посередине сообщения) if (RESETheader_timer && curmillis - prevRESETheader > 200) { #ifdef debugPCM Serial.println(F("Message fail timeout")); #endif RESETheader_timer = 0; header = 0;} // если нет ответа после запроса: +1 к счетчику неответов. Если накопилось 6 и более: делаем реинит. if (request!=INIT && NOanswer_timer && curmillis - prev_NOanswer > RequestPeriod - RequestPeriod/10) { NOanswer_timer = 0; noanswers++; if (noanswers>=6) { noanswers = 0; request = INIT; RequestPeriod = 3500;} } }// end receivePCM void Troublecodes () { if (MessageRx_PCM[n]==0x58 && MessageRx_PCM[n+1]==0x00){ myGLCD.clrScr(); drawscreen_three(); myGLCD.print("NO DTC", 180, 145); } // при получении сообщения о наличии ошибок DTC разберем сообщение выведем на экран ошибки if (MessageRx_PCM[n]==0x58 && MessageRx_PCM[n+1]>0){ myGLCD.clrScr(); drawscreen_three(); for (int i=0; i<MessageRx_PCM[n+8-7]; i++ ) { int y = i*35; bool nolA=0; bool nolB =0; if (!bitRead(MessageRx_PCM[n+11-7+(i*3)],6) && bitRead(MessageRx_PCM[n+11-7+(i*3)],7)){ myGLCD.setTextColor(GREEN, BLACK); myGLCD.print(" -Passive-", 300, (75+y));} // если DTC пасивныый делаем цвет зеленый if (bitRead(MessageRx_PCM[n+11-7+(i*3)],7) && bitRead(MessageRx_PCM[n+11-7+(i*3)],6)) { myGLCD.setTextColor(RED, BLACK); myGLCD.print(" -Active-", 300, (75+y));} // если DTC активный, делаем цвет красный myGLCD.print("ERROR ", 50, (75+y)); myGLCD.printNumI((i+1), 150, (75+y)); if (!bitRead(MessageRx_PCM[n+9-7+(i*3)],6) && !bitRead(MessageRx_PCM[n+9-7+(i*3)],7)) myGLCD.print(": P", 170, (75+y)); if (bitRead(MessageRx_PCM[n+9-7+(i*3)],6) && !bitRead(MessageRx_PCM[n+9-7+(i*3)],7)) myGLCD.print(": C", 170, (75+y)); if (!bitRead(MessageRx_PCM[n+9-7+(i*3)],6) && bitRead(MessageRx_PCM[n+9-7+(i*3)],7)) myGLCD.print(": B", 170, (75+y)); if (bitRead(MessageRx_PCM[n+9-7+(i*3)],6) && bitRead(MessageRx_PCM[n+9-7+(i*3)],7)) myGLCD.print(": U", 170, (75+y)); if (MessageRx_PCM[n+9-7+(i*3)]==0x00) {myGLCD.print("00", 230, (75+y)); nolA = 1;} if (MessageRx_PCM[n+9-7+(i*3)]<=0x0F&&MessageRx_PCM[n+9-7+(i*3)]!=0) {myGLCD.print("0", 230, (75+y)); nolA = 1;} if (nolA)myGLCD.print(String (MessageRx_PCM[n+9-7+(i*3)],HEX), 246, (75+y)); else myGLCD.print(String (MessageRx_PCM[n+9-7+(i*3)],HEX), 230, (75+y)); if (MessageRx_PCM[n+10-7+(i*3)]==0x00) {myGLCD.print("00", 262, (75+y)); nolB = 1;} if (MessageRx_PCM[n+10-7+(i*3)]<=0x0F&&MessageRx_PCM[n+10-7+(i*3)]!=0) {myGLCD.print("0", 262, (75+y)); nolB = 1;} if (nolB)myGLCD.print(String (MessageRx_PCM[n+10-7+(i*3)]),HEX, 278, (75+y)); else myGLCD.print(String (MessageRx_PCM[n+10-7+(i*3)],HEX), 262, (75+y));}} request = PRESENT; RequestPeriod = 4000; prevRequest = curmillis; } void dataVars() { //Barom = MessageRx_PCM[39]; L100 = (float)LHor*100.0/(float)Speed; LHor = (float)RPM* (float)InjQua*2.00/1000.0*60.00/1000.0/0.85; MAF = ((MessageRx_PCM[n+22]*256)+MessageRx_PCM[n+23])/10; BoostPres = ((MessageRx_PCM[n+24]*256)+MessageRx_PCM[n+25])/1000.0; RPM = (MessageRx_PCM[n+35-7]*256)+MessageRx_PCM[n+36-7]; EGRmg = ((MessageRx_PCM[n+37-7]*256)+MessageRx_PCM[n+38-7])/10.0; BoostPresCom = ((MessageRx_PCM[n+41-7]*256)+MessageRx_PCM[n+42-7])/1000.0; Speed = ((MessageRx_PCM[n+47-7]*256)+MessageRx_PCM[n+48-7])/100; DesaInjQua = ((MessageRx_PCM[n+53-7]*256)+MessageRx_PCM[n+54-7])/100.0; InjQua = ((MessageRx_PCM[n+55-7]*256)+MessageRx_PCM[n+56-7])/100.0; StaDaliv = ((MessageRx_PCM[n+57-7]*256)+MessageRx_PCM[n+58-7])/100.0; PumpRPM = (MessageRx_PCM[n+59-7]*256)+MessageRx_PCM[n+60-7]; EGRPul = ((MessageRx_PCM[n+65-7]*256)+MessageRx_PCM[n+66-7])/100.0; SolenPul = ((MessageRx_PCM[n+67-7]*256)+MessageRx_PCM[n+68-7])/100.0; SolenPre = ((MessageRx_PCM[n+73-7]*256)+MessageRx_PCM[n+74-7])/100.0; DesInj = ((MessageRx_PCM[n+75-7]*3)+(MessageRx_PCM[n+76-7])/100.0)+0.3; ActInj = ((MessageRx_PCM[n+19-7]*3)+(MessageRx_PCM[n+20-7])/100.0)+0.3; //TempAir = ((MessageRx_PCM[n+77-7]*26)-278)+MessageRx_PCM[n+78-7]/10.0; //Temp = ((MessageRx_PCM[n+17-7]*26)-278)+MessageRx_PCM[n+18-7]/10.0; //TempOil = ((MessageRx_PCM[n+21-7]*26)-278)+MessageRx_PCM[n+22-7]/10.0; //TempFuel = ((MessageRx_PCM[n+61-7]*26)-278)+MessageRx_PCM[n+62-7]/10.0; //ниже идут расчетные формулы более точные чем те что закоментированы выше int A = 0; if (MessageRx_PCM[n+77-7]<=0x0A) A = 277; if (MessageRx_PCM[n+77-7]==0x0B || MessageRx_PCM[n+77-7]==0x0C) A = 278; if (MessageRx_PCM[n+77-7]>=0x0D) A = 279; double B = MessageRx_PCM[n+78-7]/10.0; double cel , drob ; drob = modf(B, &cel); if (drob>0.6) cel++; TempAir = ((MessageRx_PCM[n+77-7]*26)-A)+cel; if (MessageRx_PCM[n+17-7]<=0x0A) A = 277; if (MessageRx_PCM[n+17-7]==0x0B || MessageRx_PCM[n+17-7]==0x0C) A = 278; if (MessageRx_PCM[n+17-7]>=0x0D) A = 279; B = MessageRx_PCM[n+18-7]/10.0; drob = modf(B, &cel); if (drob>0.6) cel++; Temp = ((MessageRx_PCM[n+17-7]*26)-A)+cel; if (MessageRx_PCM[n+21-7]<=0x0A) A = 277; if (MessageRx_PCM[n+21-7]==0x0B || MessageRx_PCM[n+21-7]==0x0C) A = 278; if (MessageRx_PCM[n+21-7]>=0x0D) A = 279; B = MessageRx_PCM[n+22-7]/10.0; drob = modf(B, &cel); if (drob>0.6) cel++; TempOil = ((MessageRx_PCM[n+21-7]*26)-A)+cel; if (MessageRx_PCM[n+61-7]<=0x0A) A = 277; if (MessageRx_PCM[n+61-7]==0x0B || MessageRx_PCM[n+61-7]==0x0C) A = 278; if (MessageRx_PCM[n+61-7]>=0x0D) A = 279; B = MessageRx_PCM[n+62-7]/10.0; drob = modf(B, &cel); if (drob>0.6) cel++; TempFuel = ((MessageRx_PCM[n+61-7]*26)-A)+cel; //---------------------------------------------------------- //страниц HOME //---------------------------------------------------------- //myGLCD.setBackColor(RED); myGLCD.setTextColor(WHITE, BLACK); //myGLCD.setBackColor(RED); if ((Speed != Speed_last) || reNew) {myGLCD.printNumI(Speed, 360, 7, 3); Speed_last=Speed;} if (currentPage == '0') { if ((LHor != LHor_last) || reNew) {myGLCD.printNumF(LHor, 1, 75, 40, '.',4); LHor_last=LHor;} if ((L100 != L100_last) || reNew) {myGLCD.printNumF(L100, 1, 225, 40,'.',4 ); L100_last=L100;} if ((L100M != L100M_last) || reNew) {myGLCD.printNumF(L100M, 1, 75, 75,'.',4 ); L100M_last=L100M;} if ((L100SR_TFT != L100SR_TFT_last) || reNew) {myGLCD.printNumF(L100SR_TFT, 1, 225, 75,'.',4 ); L100SR_TFT_last=L100SR_TFT;} if ((kmREFUELING != kmREFUELING_last) || reNew) {myGLCD.printNumI(kmREFUELING, 90, 110,3 ); kmREFUELING_last=kmREFUELING;} //if (Fuel<53) if ((Fuel != Fuel_last) || reNew) {myGLCD.printNumF(Fuel, 1, 225, 110,'.',4); Fuel_last=Fuel;} //else myGLCD.print("MAX", 210, 110); if ((kmTrip != kmTrip_last) || reNew) {myGLCD.printNumF(kmTrip, 1, 60, 145,'.',5); kmTrip_last=kmTrip;} if ((FuelTrip != FuelTrip_last) || reNew) {myGLCD.printNumF(FuelTrip, 1, 210, 145,'.',5); FuelTrip_last=FuelTrip;} if ((PumpRPM != PumpRPM_last) || reNew) {myGLCD.printNumI(PumpRPM, 230, 180,4); PumpRPM_last=PumpRPM;} if ((RPM != RPM_last) || reNew) {myGLCD.printNumI(RPM, 230, 215,4); RPM_last=RPM;} if ((Fuel2 != Fuel2_last) || reNew) {myGLCD.printNumF(Fuel2, 1, 10, 215,'.',4); Fuel2_last=Fuel2;} if ((Temp != Temp_last) || reNew) {myGLCD.printNumI(Temp, 415, 40, 3); Temp_last=Temp;} if ((TempOil != TempOil_last) || reNew) {myGLCD.printNumI(TempOil, 415, 75, 3); TempOil_last=TempOil;} if ((TempFuel != TempFuel_last) || reNew) {myGLCD.printNumI(TempFuel, 415, 110,3); TempFuel_last=TempFuel;} //myGLCD.printNumI(sensors.getTempCByIndex(0), 415, 145 , 3); if ((t != t_last) || reNew) {myGLCD.printNumI(t, 415, 180, 3); t_last=t;} if ((TempAir != TempAir_last) || reNew) {myGLCD.printNumI(TempAir, 415, 215, 3); TempAir_last=TempAir;} reNew = 0; } //---------------------------------------------------------- //страниц INF1 //---------------------------------------------------------- if (currentPage == '1') { if ((StaDaliv != StaDaliv_last) || reNew) {myGLCD.printNumF(StaDaliv,1, 385, 40,'.', 4); StaDaliv_last=StaDaliv;} if ((DesInj != DesInj_last) || reNew) {myGLCD.printNumF(DesInj,1, 385, 75, '.', 4); DesInj_last=DesInj;} if ((ActInj != ActInj_last) || reNew) {myGLCD.printNumF(ActInj,1, 385, 110,'.', 4); ActInj_last=ActInj;} if ((DesaInjQua != DesaInjQua_last) || reNew) {myGLCD.printNumF(DesaInjQua,1, 385, 145,'.', 4);DesaInjQua_last=DesaInjQua;} if ((InjQua != InjQua_last) || reNew) {myGLCD.printNumF(InjQua,1, 385, 180,'.', 4); InjQua_last=InjQua;} if ((MAF != MAF_last) || reNew) {myGLCD.printNumI(MAF, 170, 215, 4); MAF_last=MAF;} if ((h != h_last) || reNew) {myGLCD.printNumF(h, 1, 430, 215, 3); h_last=h;} reNew = 0; } //---------------------------------------------------------- //страниц INF2 //---------------------------------------------------------- if (currentPage == '2') { if ((BoostPres != BoostPres_last) || reNew) {myGLCD.printNumF(BoostPres,1, 400, 40,'.', 4); BoostPres_last=BoostPres;} if ((BoostPresCom != BoostPresCom_last) || reNew) {myGLCD.printNumF(BoostPresCom,1, 400, 75,'.', 4); BoostPresCom_last=BoostPresCom;} if ((EGRmg != EGRmg_last) || reNew) {myGLCD.printNumI(EGRmg, 400, 110, 4); EGRmg_last=EGRmg;} if ((EGRPul != EGRPul_last) || reNew) {myGLCD.printNumF(EGRPul,1, 400, 145,'.', 4); EGRPul_last=EGRPul;} if ((SolenPul != SolenPul_last) || reNew) {myGLCD.printNumF(SolenPul, 1, 400, 180,'.', 4); SolenPul_last=SolenPul;} if ((SolenPre != SolenPre_last) || reNew) {myGLCD.printNumF(SolenPre, 0, 400, 215,'.', 4); SolenPre_last=SolenPre;} reNew = 0; } //reNew = 0; } void sendMessagePCM(const byte &command) { #ifdef debugPCM Serial.print (F("Send request ")); Serial.print (textRequest[command]); Serial.print (F(" to PCM ")); Serial.println (millis()); #endif if (command != INIT) {NOanswer_timer = 1; prev_NOanswer = curmillis;} //т.к. сейчас будем делать запрос, то запускаем таймер контроля неответов byte size = PCM_Message_TX[command][0]; const byte siZe = size+4; byte Mes[siZe]; byte Checksum = 0; for(byte i=0; i<siZe; i++) { if (i==0) {Mes[i]=size; bitWrite(Mes[i], 7 , 1);} if (i==1) Mes[i] = PCM_address; if (i==2) Mes[i] = DIAG_address; if (i==3) {for (byte t=1; t<size+1; t++ ) { Mes[i]=PCM_Message_TX [command][t]; Checksum+=Mes[i] ; K_LINE_PCM.write (Mes[i]); if (command == INIT) delay (5); else delay (delaybyte_TX); K_LINE_PCM.read(); i++;}} if (i!=siZe-1) Checksum+=Mes[i]; else Mes[i] = Checksum; K_LINE_PCM.write (Mes[i]); if (command == INIT) delay (5); else delay (delaybyte_TX); K_LINE_PCM.read(); } }// end sendMessagePCM void receiveGAUGE () { if (K_LINE_GAUGE.available() ){ // первый старт байт if (headerGAUGE == 0 && DelayGAUGE){TIMER_DELAYGAUGE ; MessageRx_GAUGE[0]=K_LINE_GAUGE.read(); if ((InitGauge ==1 && MessageRx_GAUGE[0]==0x55) || (InitGauge ==2 && MessageRx_GAUGE[0]!=0xFF && MessageRx_GAUGE[0]!=0x7F) || (InitGauge ==3 && MessageRx_GAUGE[0]!=0xFF && MessageRx_GAUGE[0]!=0x7F) ) {headerGAUGE = 1; RESETheader_timerGAUGE = 1; prevRESETheaderGAUGE = curmillis; #ifdef debugGAUGE Serial.print (F("Receive GAUGE: ")); printDebugRX(MessageRx_GAUGE[0]); #endif } } // второй старт байт if (headerGAUGE == 1 && DelayGAUGE){TIMER_DELAYGAUGE ; MessageRx_GAUGE[1]=K_LINE_GAUGE.read(); #ifdef debugGAUGE printDebugRX (MessageRx_GAUGE[1]); #endif if ( (InitGauge ==1 && MessageRx_GAUGE[1]==0x52) || (InitGauge ==2 && (MessageRx_GAUGE[1]==0xA0 || MessageRx_GAUGE[1]==0xF0)) || (InitGauge == 3 && MessageRx_GAUGE[1]==0xA1)){ headerGAUGE = 2;} else { #ifdef debugGAUGE Serial.println(F(" GAUGE Message fail address")); #endif headerGAUGE = 0; RESETheader_timerGAUGE = 0;}} // третий старт байт if (headerGAUGE == 2 && DelayGAUGE){ TIMER_DELAYGAUGE ; MessageRx_GAUGE[2]=K_LINE_GAUGE.read(); #ifdef debugGAUGE printDebugRX (MessageRx_GAUGE[2]); #endif if ((InitGauge ==2 && (MessageRx_GAUGE[2]==0x48 || MessageRx_GAUGE[2]==0x55 || MessageRx_GAUGE[2]==0xAA)) || (InitGauge == 3 && MessageRx_GAUGE[2]==0x04)){ message_sizeGAUGE = MessageRx_GAUGE[0]-2; prevRESETheaderGAUGE = curmillis; headerGAUGE = 4; jGAUGE=3; nGAUGE=3; if (message_sizeGAUGE > bufsizeG) message_sizeGAUGE = bufsizeG; ChecksumGAUGE = 0;} else if (InitGauge ==1 && MessageRx_GAUGE[2]==0x80) {InitGauge = 2; K_LINE_GAUGE.write(0x7F); delay (2); K_LINE_GAUGE.read(); headerGAUGE = 0; RESETheader_timerGAUGE = 0; #ifdef debugGAUGE Serial.println ("Gauge INIT is good!"); #endif } else {headerGAUGE = 0; #ifdef debugGAUGE Serial.println(F("GAUGE Message fail address")); #endif RESETheader_timerGAUGE = 0;} } // пишем тело сообщения if (headerGAUGE == 4 && DelayGAUGE && jGAUGE< message_sizeGAUGE+nGAUGE+1) { MessageRx_GAUGE[jGAUGE] = K_LINE_GAUGE.read(); prevRESETheaderGAUGE = curmillis; if (jGAUGE<message_sizeGAUGE+nGAUGE-1) ChecksumGAUGE+= MessageRx_GAUGE[jGAUGE]; // подсчёт КС if (jGAUGE==message_sizeGAUGE+nGAUGE) headerGAUGE = 5; TIMER_DELAYGAUGE ; #ifdef debugGAUGE printDebugRX(MessageRx_GAUGE[jGAUGE]); #endif jGAUGE++; } } // сообщение приняли, действуем if (headerGAUGE == 5) {TIMER_DELAYGAUGE ; #ifdef debugGAUGE Serial.println(); #endif for(byte i = 0; i<nGAUGE; i++) ChecksumGAUGE+=MessageRx_GAUGE[i]; // прибавляем к контрольной сумме старт байты int ChecksumG = ( ( unsigned int )MessageRx_GAUGE[message_sizeGAUGE+nGAUGE-1] << 8 ) | MessageRx_GAUGE[message_sizeGAUGE+nGAUGE]; // парсинг контрольной суммы из 2 последних байт // если контрольная сумма верна: if ( ChecksumGAUGE == ChecksumG) { NoconnectsGAUGE = 0; // сбрасываем на 0 отсутствие связи с панелью #ifdef debugGAUGE Serial.print (F("Received message is OK! Checksum is correct!")); Serial.print (F(" ")); Serial.println (millis()); // Если КС совпала, тут чёнибудь нужное делаем #endif if (MessageRx_GAUGE[1]== 0xA0 && MessageRx_GAUGE[2]== 0x48) { #ifdef debugGAUGE Serial.println ("ID panel receive! Send request PIDGauge"); #endif InitGauge = 3; for (byte i=0; i<sizeof(PIDgauge); i++) { K_LINE_GAUGE.write (PIDgauge[i]); delay (1); K_LINE_GAUGE.read();} } if (MessageRx_GAUGE[1]== 0xF0 && (MessageRx_GAUGE[2]== 0xAA || MessageRx_GAUGE[2]== 0x55)) { #ifdef debugGAUGE Serial.println ("receive present from Gauge. I send PID to Gauge"); #endif InitGauge = 3; for (byte i=0; i<sizeof(PIDgauge); i++) { K_LINE_GAUGE.write (PIDgauge[i]); delay (1); K_LINE_GAUGE.read();} } if (MessageRx_GAUGE[1]== 0xA1 && MessageRx_GAUGE[2]== 0x04) { #ifdef debugGAUGE Serial.println (" receive Datastream Gauge!"); #endif Fuel2 = MessageRx_GAUGE[nGAUGE + 16]/2.0; if (!flagFuelIGN) { Fuel = MessageRx_GAUGE[nGAUGE + 16]/2.0; kmREFUELING=((float)Fuel*100.00)/(float)L100SR_TFT;} //стартовая запись литров в баке для подсчета затраченных литро else Fuel = MessageRx_GAUGE[nGAUGE + 17]/2.0; //для усреднения болтания в баке закоментировать эту строку, а раскоментировать ниже //для усреднения болтания топлива в баке, раскоментировать, высчитывает среднее /*else { FuelZamer[ZamerNumber] = MessageRxGauge[17]/2.00; if (ZamerNumber==9) { Fuel = 0 ; for (int i = 0; i < 10; i++) Fuel = Fuel + FuelZamer[i]; Fuel = (float)Fuel/10.0;} ZamerNumber++; if (ZamerNumber>9) ZamerNumber = 0;} */ kmAge = (MessageRx_GAUGE[nGAUGE + 23]+(MessageRx_GAUGE[nGAUGE + 24]*256))/10.0; //суточный пробег с панели приборов //бак у меня на 59 литров, а датчик показывает максимально 53 литра. для этого эта формула //если у вас тоже датчик имеет лимит то подправте 53 на свой лимит. //если ваш датчик показывает одинаково с полным баком то закоментировать три нижние строки. if (Fuel<53){ if (!flagkmAgeIGN) { kmAgeIGN = kmAge; flagkmAgeIGN =1;} if (!flagFuelIGN) { FuelIGN = Fuel; Fuel_last = Fuel; flagFuelIGN = 1;}} } } // если контрольная сумма не совпала: #ifdef debugGAUGE else Serial.println("CRC fail!!!" ); #endif message_sizeGAUGE = 0; headerGAUGE=0; RESETheader_timerGAUGE = 0; jGAUGE=3; ChecksumGAUGE = 0; } // таймер ожидания байт (для успевания появления данных в буфере UART) if (!DelayGAUGE && curmillis - timerdelayGAUGE > waitbyte_RX_GAUGE) DelayGAUGE = 1; // таймер сброса целостности сообщения (если данные оборвались посередине сообщения) if (RESETheader_timerGAUGE && curmillis - prevRESETheaderGAUGE > 1000) { #ifdef debugGAUGE Serial.println(F("Message fail timeout")); #endif RESETheader_timerGAUGE = 0; headerGAUGE = 0;} if (curmillis - prevNoconnect > 500) {NoconnectsGAUGE ++ ; if (NoconnectsGAUGE>=8){ #ifdef debugGAUGE Serial.println (F(" Connect GAUGE failed!!! ")) ; #endif NoconnectsGAUGE = 0 ;InitGauge = 0 ; } prevNoconnect = curmillis; } InitBusGAUGE (); }// end receiveGAUGE void InitBusGAUGE () { if (InitGauge == 0){ #ifdef debugGAUGE Serial.println ("Send startsession - address Gauge"); #endif K_LINE_GAUGE.end(); pinMode(TX_gauge, OUTPUT); digitalWrite (TX_gauge, HIGH); // BUS IDLE InitGauge = 5; prevInitbusGauge = curmillis; } if (InitGauge == 5 && curmillis - prevInitbusGauge>1500) {InitGauge = 6;} // BUS IDLE if (InitGauge == 6) { byte boudrate = 1000/BAUD; digitalWrite (TX_gauge, LOW); delay (boudrate); // старт бит for (byte i=0; i<8; i++){digitalWrite (TX_gauge, bitRead(addressGUAGE, i)); delay (boudrate);} // биты тела адреса digitalWrite (TX_gauge, HIGH); delay (boudrate); // стоп бит K_LINE_GAUGE.begin(9600); InitGauge = 1; } } #if defined debugPCM or defined debugGAUGE void printDebugRX (const byte &inbyte) {if (inbyte<=15) Serial.print(F("0")); Serial.print (inbyte, HEX); Serial.print (F(" "));} #endif #ifdef debugPCM void printDebugRX_CSgood(){ if (MessageRx_PCM[n]==0xC1 && MessageRx_PCM[n+1]==0x6B && MessageRx_PCM[n+2]==0x8F) {Serial.println (F(" Initialization OK!!!!")); } else if (MessageRx_PCM[n]==0x58 && MessageRx_PCM[n+1]==0x00) {Serial.println (F(" NO DTC "));} else if (MessageRx_PCM[n]==0x58 && MessageRx_PCM[n+1] >0x00) {Serial.println (F(" DTC is found!"));} else if (MessageRx_PCM[n]==0x54 && MessageRx_PCM[n+1]==0xFF && MessageRx_PCM[n+2]==0x00){Serial.println (F(" DTC CLEARED "));} else if (MessageRx_PCM[n]==0x61 && MessageRx_PCM[n+1]==0x01) {Serial.println (F(" Receive PCM DATAstream"));}} #endif void Menu () { TouchHOME(); if (currentPage == '0') { TouchINF1(); TouchINF2(); TouchCHECK(); } if (currentPage == '1') { TouchINF2(); TouchCHECK(); } if (currentPage == '2') { TouchINF1(); TouchCHECK(); } if (currentPage == '3') { TouchREAD(); TouchERASE(); }} void drawHomeScreen() { line() ; Watch (); //myGLCD.print(":", 290, 5); myGLCD.print("/", 115, 7); myGLCD.print("/", 160, 7); myGLCD.setTextColor(RED, BLACK); // цвет линии и текста красный myGLCD.drawLine(295,35,295,248); // линия вертикальная myGLCD.drawLine(145,35,145,178); // линия вертикальная myGLCD.drawLine(80,178,80,247); // линия вертикальная myGLCD.print("L/H", 10, 40); myGLCD.print("L/A", 148, 40); myGLCD.print("L/V", 10, 75); myGLCD.print("L/M", 148, 75); myGLCD.print("D/K", 10, 110); myGLCD.print("D/L", 148, 110); myGLCD.print("V/K", 10, 145); myGLCD.print("V/L", 148, 145); myGLCD.print("PUMP RPM", 82, 180); myGLCD.print("ENGI RPM", 82, 215); myGLCD.print("D/L/A", 10, 180); myGLCD.print("Motor C", 300, 40); myGLCD.print("OIL C", 300, 75); myGLCD.print("FUEL C", 300, 110); myGLCD.print("INTER C", 300, 145); myGLCD.print("EXTER C", 300, 180); myGLCD.print("INTAIR C", 300, 215); //myGLCD.setTextColor(RED); myGLCD.drawRoundRect (15, 255, 145, 310); myGLCD.print("INF 1", 55, 270); myGLCD.drawRoundRect (175, 255, 305, 310); myGLCD.print("INF 2", 215, 270); myGLCD.drawRoundRect (335, 255, 465, 310); myGLCD.print("CHECK", 365, 270); myGLCD.drawRoundRect (1, 1, 77, 37); myGLCD.print("HOME", 10, 7); myGLCD.print("Km/h", 410, 7); reNew = 1; } //------------------------------------------------- void drawscreen_one() { line() ; Watch (); //myGLCD.print(":", 290, 5); myGLCD.print("/", 115, 7); myGLCD.print("/", 160, 7); myGLCD.setTextColor(RED, BLACK); // цвет линии и текста красный myGLCD.print("Start of Delivery *CA:", 10, 40); myGLCD.print("Desir inject Start *CA:", 10, 75); myGLCD.print("Actua Inject Start *CA:", 10, 110); myGLCD.print("Desir Inject Quan mg/s:", 10, 145); myGLCD.print("Actu Inject Quant mg/s:", 10, 180); myGLCD.print("MAF mg/s:", 10, 215); myGLCD.print("Humedad %:", 255, 215); //myGLCD.setTextColor(RED); myGLCD.drawRoundRect (175, 255, 305, 310); myGLCD.print("INF 2", 215, 270); myGLCD.drawRoundRect (335, 255, 465, 310); myGLCD.print("CHECK", 365, 270); myGLCD.drawRoundRect (1, 1, 77, 37); myGLCD.print("HOME", 10, 7); myGLCD.print("Km/h", 410, 7); reNew = 1; } //------------------------------------------------- void drawscreen_two() { line() ; Watch (); //myGLCD.print(":", 290, 5); myGLCD.print("/", 115, 7); myGLCD.print("/", 160, 7); myGLCD.setTextColor(RED, BLACK); // цвет линии и текста красный myGLCD.print("Boost Press Bar:", 10, 40); myGLCD.print("Boost Press Com Bar:", 10, 75); myGLCD.print("EGR command mg/s:", 10, 110); myGLCD.print("EGR Pulse Ratio %:", 10, 145); myGLCD.print("Solenoide Pulse %:", 10, 180); myGLCD.print("Solenoide Boost %:", 10, 215); //myGLCD.setColor(RED); myGLCD.drawRoundRect (15, 255, 145, 310); myGLCD.print("INF 1", 55, 270); myGLCD.drawRoundRect (335, 255, 465, 310); myGLCD.print("CHECK", 365, 270); myGLCD.drawRoundRect (1, 1, 77, 37); myGLCD.print("HOME", 10, 7); myGLCD.print("Km/h", 410, 7); reNew = 1; } //---------------------------------------------------------------------------- void drawscreen_three() { Watch (); //myGLCD.print(":", 290, 5); myGLCD.print("/", 115, 7); myGLCD.print("/", 160, 7); myGLCD.setTextColor(RED, BLACK); // цвет линии красный myGLCD.drawLine(1,35,479,35); // линия горизонтальная myGLCD.drawLine(1,248,479,248); // линия горизонтальная //myGLCD.setTextColor(RED); myGLCD.drawRoundRect (15, 255, 145, 310); myGLCD.print("ERASE", 55, 270); myGLCD.drawRoundRect (335, 255, 465, 310); myGLCD.print("READ", 365, 270); myGLCD.drawRoundRect (1, 1, 77, 37); myGLCD.print("HOME", 10, 5); reNew = 1; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //кнопки тач . координаты и переходы ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void TouchHOME(){ TSPoint p = ts.getPoint(); pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); if (p.z > 10 && p.z < 1000) {if (p.x > 140 && p.x < 320 && p.y > 140 && p.y < 260 && p.z > MINPRESSURE && p.z < MAXPRESSURE) { myGLCD.drawRoundRect (1, 1, 77, 37); currentPage = '0'; request = PID; RequestPeriod = 10; prevRequest = curmillis; // на PCM в этом окне посылается запрос текущих параметров myGLCD.clrScr(); drawHomeScreen(); x = 0; y = 0; p.z = 0;}}} void TouchINF1(){ TSPoint p = ts.getPoint(); pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); if (p.z > 10 && p.z < 1000) { if (p.x > 150 && p.x < 450 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE) { myGLCD.drawRoundRect (15, 255, 145, 310); currentPage = '1'; request = PID; RequestPeriod = 10; prevRequest = curmillis; // на PCM в этом окне посылается запрос текущих параметров myGLCD.clrScr(); drawscreen_one(); x = 0; y = 0; p.z = 0;}}} void TouchINF2(){ TSPoint p = ts.getPoint(); pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); if (p.z > 10 && p.z < 1000) { if (p.x > 450 && p.x < 680 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE) { myGLCD.drawRoundRect (175, 255, 305, 310); currentPage = '2'; request = PID; RequestPeriod = 600; prevRequest = curmillis; // на PCM в этом окне посылается запрос текущих параметров myGLCD.clrScr(); drawscreen_two(); x = 0; y = 0; p.z = 0;}}} void TouchCHECK(){ TSPoint p = ts.getPoint(); pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); if (p.z > 10 && p.z < 1000) { if (p.x > 690 && p.x < 950 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE) { myGLCD.drawRoundRect (335, 255, 465, 310); currentPage = '3'; // request = DTCREAD; RequestPeriod = 10; prevRequest = curmillis; // на PCM в этом окне посылается запрос чтения ошибок myGLCD.clrScr(); drawscreen_three(); x = 0; y = 0; p.z = 0;}}} void TouchREAD(){ TSPoint p = ts.getPoint(); pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); if (p.z > 10 && p.z < 1000) { if (p.x > 690 && p.x < 950 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE) { myGLCD.drawRoundRect (335, 255, 465, 310); request = DTCREAD; RequestPeriod = 300; prevRequest = curmillis; // на PCM при нажатии этой кнопки посылается запрос чтения ошибок x = 0; y = 0; p.z = 0;}}} void TouchERASE(){ TSPoint p = ts.getPoint(); pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); if (p.z > 10 && p.z < 1000) { if (p.x > 150 && p.x < 450 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE) {myGLCD.drawRoundRect (15, 255, 145, 310); request = DTCERASE; RequestPeriod = 300; prevRequest = curmillis; // на PCM при нажатии этой кнопки посылается запрос удаления ошибок myGLCD.clrScr(); drawscreen_three(); myGLCD.print("DTC BORRADO", 180, 145); x = 0; y = 0; p.z = 0;}}} //////////////////////////////////////////////////////////////////////////////////////// //прорисовка линий /////////////////////////////////////////////////////////////////////////////////////// void line() { //myGLCD.setTextColor(RED); // цвет линии красный myGLCD.drawLine(1,35,479,35); // линия горизонтальная myGLCD.drawLine(1,73,479,73); // линия горизонтальная myGLCD.drawLine(1,108,479,108); // линия горизонтальная myGLCD.drawLine(1,143,479,143); // линия горизонтальная myGLCD.drawLine(1,178,479,178); // линия горизонтальная myGLCD.drawLine(1,212,479,212); // линия горизонтальная myGLCD.drawLine(1,248,479,248); // линия горизонтальная } void Watch (){ DateTime now = rtc.now(); int minut = now.minute(); int hour = now.hour(); int mon = now.month(); int date = now.day(); int Year = now.year(); static int minut_last; static int hour_last; static int mon_last; static int date_last; static int Year_last; myGLCD.setTextColor(WHITE, BLACK); //белый цвет цифры if (date != date_last || reNew){ myGLCD.printNumI(date, 85, 7, 2, '0'); date_last = date; } if (mon!=mon_last || reNew){myGLCD.printNumI(mon, 130, 7, 2, '0'); mon_last = mon; } if (Year!=Year_last || reNew) { myGLCD.printNumI(Year, 175, 7); Year_last = Year; } if (hour!=hour_last || reNew){ myGLCD.printNumI(hour, 255, 7, 2, '0'); hour_last = hour; } if (minut!=minut_last || reNew ){ myGLCD.printNumI(minut, 300, 7, 2, '0'); minut_last = minut; } reNew = 1; }Переставь вызовы Watch сразу после reNew = 1;