самое верное решение уже давно раньше звучало. Взять вторую ардуину и наделить её обязанностью обмениваться по к-лайн, а основной ардуине, она 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; . извени. не внимательность
К сожалению не помогает
маловероятно что поможет
да ты прав не помогло
ладно позже попробую алгоритм поменять
ок. спсибо
короче сделал по старой схеме
ща испытаю
#define debugGAUGE
#define debugPCM
и на экране нет данных
Ну так и думал что одно заработает, а другое сломается
самое верное решение уже давно раньше звучало. Взять вторую ардуину и наделить её обязанностью обмениваться по к-лайн, а основной ардуине, она 4 готовых байта будет передавать, без всяких инитов и прочей херни.
понимаю, это мне нужно было делать с самого начала, когда ты это говорил, в разработке. теперь уже это не для меня. да и все таки же работало 2 года на одной..... и без проблем, если бы не экран, то так бы и работало.
убрал автоматическое переподключение к панели. Сделал опрос данных щитка приборов раз в полминуты, чтобы не мешать обмену с PCM
вроде заработало. и данные вроде корекны, 40 литров показывает как в баке и есть. машина была заведенная, были данные, не глуша я подключил к компу чтобы заглянуть в терминал, бортовик перезагрузился и данные уже не появились и в терменале тишина. сново выключить и включить зажигание, есть данные. debugPCM не работает, хотел туда тоже заглянуть
Строка 225 можешь 60000 поставить (обновление топлива раз в минуту) ну или даже больше. Потому как в этот момент данные кратковременно на бортовике не обновляются, по идее должны замерзать цифры не на долго
Хотя вообще то км должны чаще обновляться. Оставь полминуты
А че debug pcm не работает не понятно
неа. ща еще раз проверю. все норм работает
Ладно тестируй, потом добавлю датчик t
А ты узнай его адрес, примером из библиотеки onewire
ок. температура в нутри и влага, и наружняя температура не работают, я видел что не прописаны библиотеки. ок буду пока тестить. я ща пробую добавить все что было раньше на них, но чета не показывает
раньше было так
вообщем пока так, ниже скетя, внутреннюю температуру и влагу не показывает, на ружнюю показывает но не обновляется. как тольлко чтото сую в луп
это Temperature ();
или по отдельности или вместе это
h = dht.readHumidity();
t = dht.readTemperature();
sensors.requestTemperatures();
чтобы обновлялись, все зависает.
скетч для определения адреса ds18b20
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.
Ты гений, показывает обе температуры и влагу, я домой, завтра скажу как себя вел бортовик, спасибо
в итоговом скетче комментируй обе отладки
Поздно сказал :). Уже так залил. Есть косяки, завтра напишу
Макс вообщем хаус. поездка 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 параметра и переподключение решить, мне больше ничего не нужно, я буду счастлив. вот скетч
Спасибо
Сколько памяти свободно остаётся во флеше без красивого шрифта ? Можно свой шрифт организовать по типу обычного (по крайней мере для тех символов, которыми отображаются динамические данные)!
Сколько памяти свободно остаётся во флеше без красивого шрифта ? Можно свой шрифт организовать по типу обычного (по крайней мере для тех символов, которыми отображаются динамические данные)!
привет мужики, что-то после отпуска сюда не заглядывал. Как, удалось тогда победить моргание на пропорциональных шрифтах, или забили и "пошли другим путем" ?
Командир, завтра скажу сколько памяти. Я уже думал ковырять стандартный шрифт, сделать его хотя-бы вытянутой а не квадратным
B707. Победить то победили, но вот то что он сильно тормозит все, может у меня экран слабый.
"экран слабый" быть не может. Если тормозит, то причины м.б. только две - либо код не оптимальный, либо проц слабый (то есть вместо ардуины надо брать СТМ, к примеру)
Хз. На прошлом экране все было гуд. Сменил экран и пошли тормоза. Так что ардуина не при чем. Сам устал бороться, и ребят уже замучал
прошлый экран был такого же размера разве?
Для обновления картинки 240Х320 нужно примерно в 10 раз больше времени, чем, например, 128х64. И никакой "слабый экран" тут не при чем - это просто ардуина слабая для этого экрана, вот и все.
Поставил стандартный шрифт и все пошло. Думаю стандартный ковырять так как размер 2 маловат а 3 за большой и квадратные они, мне бы вытянутые, уродливый но мать его за лапу, какой есть. Именно при добавлении стороннего шрифта начининаются тормоза.
Был такой же размер
также попробуй 1929 без использования шрифта , чтобы экран не тормозил
Я вышел на отличный результат со стандартным шрифтом. И мой старый и твой новый работают быстро. В старом только косяк в четырёх данных. В твоём новом хаус в расчётах. Но оба работают очень быстро со стандартным. Плевать уже на красоту.
Ок. На этой неделе не работаю что будет, не смогу. Через неделю продолжу ковырять.
ты пробуй не последний а 1929
Ок, через неделю. Мог бы дома, но в ноуте батарея сдохла, с 4 этажа кабель не кинешь :)
viki13viki Привет. Мне кажется или ты решил отказаться от проверки выводимых данных на изменения (ака last...)? Или вы скрещиваете не с крайним скетчем !!! Я бы еще даже не сами значения сравнивал, а данные из буфера, что бы не производить вычисления, если данные для конкретного параметра не изменились (особенно если в вычислении есть деление/умножение).
На следующей недели продолжу. Я сейчас использую старый скетчь на стандартном шрифты без Last. Но и последний со стандартным шрифтом с Last летает, но хаус в расчётах, и проблема в выводимых данных. При переходе на страницы прорисовывается только часть данных, renew тыкал везде, как в верху так и в низу на каждой страницы так и для всех страниц один renew внизу. Проверю 1229 о котором выше говорил Макс, тока на стандартном шрифты. Но уже в понедельник
Отчет по 1929 . Вроде все данные показываетю. Косяки: 1. TempAir показывает 36 ( через 5 мин после второй прошивки показал 44 градуса, что уже не коректно, должно быть где-то 14-16 примерно(но это нужно проверять когда подключится наружняя температура) тогда скажу точно, я их сравниваю. 2. при переходах на страницы не всегда прорисовывает часы.(но это пока не важно) добавил в низу в Watch это reNew = 1;, не помогло. Остальное нужно на ходу проверять. Работет мгновенно, прорисовка мгновенно.
вот скетч чтобы далеко не бегать
Переставь вызовы Watch сразу после reNew = 1;