Бортовой компьютер для автомобиля с 3.5 TFT дисплеем
- Войдите на сайт для отправки комментариев
Сб, 05/06/2021 - 00:33
Здравствуйте, уважаемые спецы. В общем-то все работаем, но обновление информации происходит 1 раз в 3 секунды, а хотелось бы мгновенно. С расходом тоже беда. Показывает мгновенно, а хочется за час.
Вот собственно код
#include <iarduino_RTC.h>
iarduino_RTC time(RTC_DS1307);
#include <DHT.h>
#include <DHT_U.h>
#define B 3950 // B-коэффициент
#define SERIAL_R 10000 // сопротивление последовательного резистора, 10 кОм
#define THERMISTOR_R 10000 // номинальное сопротивления термистора, 10 кОм
#define NOMINAL_T 25 // номинальная температура (при которой TR = 10 кОм)
const byte tempoPin = A12;
#define DHTTYPE DHT11
#define DHTPIN 41
DHT dht(DHTPIN, DHTTYPE);
#include <Adafruit_GFX.h> // Core graphics library
#include <SPI.h>
#include <SD.h>
#include <MCUFRIEND_kbv.h> // Hardware-specific library
#include <OneWire.h>
#include <Wire.h>
//const extern uint8_t FreeSans9pt7b
#include "Fonts/FreeSansBold24pt7b.h" // когда вам нужны другие шрифты
MCUFRIEND_kbv tft;
#define LCD_CS A3 // Chip Select goes to Analog 3
#define LCD_CD A2 // Command/Data goes to Analog 2
#define LCD_WR A1 // LCD Write goes to Analog 1
#define LCD_RD A0 // LCD Read goes to Analog 0
#define SD_CS 53 // Set the chip select line to whatever you use (10 doesnt conflict with the library)
const int tachPIN=18;// тахометр
const unsigned long sampleTime=1000;
const unsigned long sampleTime2=1000;
const unsigned long sampleTime3=1000;
const int speedPIN=19; //спидометр
////-------расход--------///
const int INJECTOR_PIN=A9;// форсунка
//------------------------------///
#define BLACK 0x0000
#define NAVY 0x000F
#define DARKGREEN 0x03E0
#define DARKCYAN 0x03EF
#define MAROON 0x7800
#define PURPLE 0x780F
#define OLIVE 0x7BE0
#define LIGHTGREY 0xC618
#define DARKGREY 0x7BEF
#define BLUE 0x001F
#define GREEN 0x07E0
#define CYAN 0x07FF
#define RED 0xF800
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF
#define ORANGE 0xFD20
#define GREENYELLOW 0xAFE5
#define PINK 0xF81F
void setup()
{
//tft.reset();
dht.begin();
time.begin();
Serial.begin(9600);
uint16_t ID = tft.readID();
Serial.println("Example: Font_simple");
Serial.print("found ID = 0x");
Serial.println(ID, HEX);
if (ID == 0xD3D3) ID = 0x9481; //force ID if write-only display
tft.begin(ID);
Wire.begin();
//tft.setTextSize(2);
//tft.fillScreen(0);
tft.setRotation(1);
if (!SD.begin(SD_CS )) {
return;
}
pinMode(tachPIN, INPUT);
digitalWrite(tachPIN, HIGH);// тахо
pinMode(speedPIN, INPUT);
digitalWrite(speedPIN, HIGH);
pinMode( tempoPin, INPUT );
//-------------расход------------//
pinMode(INJECTOR_PIN, INPUT);
digitalWrite(INJECTOR_PIN, HIGH);
//-----------------------------------//
bmpDraw("OPEL3.bmp", 0, 0);
delay(5000);
//tft.reset();
//delay(1);
tft.fillScreen( BLACK);
}
void loop()
{
//delay(2000);
float h = dht.readHumidity(); // считывание влажности
float t = dht.readTemperature(); // считывание температуры
tft.setTextColor(WHITE,BLACK);
tft.setTextSize(3);
tft.setCursor(5,270);
tft.print(h);
tft.setTextSize(3);
tft.setCursor(5,230);
tft.print(t);
tft.setCursor(105,270);
tft.print("%");
tft.setCursor(105,230);
tft.print("C");
tft.setTextColor(BLUE,BLACK);
tft.setCursor(10,185);
tft.print(utf8rus("ВНУТРИ")); // ВНУТРИ
tft.setCursor(85,52);
tft.print(utf8rus("МГ")); // РАСХОД
tft.setCursor(3,140);
//tft.print(utf8rus("Л/Ч"));
tft.setCursor(380,50);
tft.print(utf8rus("ТОСОЛ"));
tft.setTextSize(2);
tft.setCursor(380,245);
tft.print(utf8rus("За окном"));
// темп двиг (среднее от 100 замеров)
long valtemp = 0;
for (int kd=0; kd<100; ++kd) {
valtemp = valtemp + analogRead(A10);
}
valtemp = valtemp/100;
float voltemp = map(valtemp,750,0,0,1200);
voltemp = voltemp/10;
float temp3=voltemp;
int z = temp3;
tft.setTextColor(WHITE,BLACK);
tft.setTextSize(5);
tft.setCursor(375,100);
char d[5];
sprintf(d,"%3d",z);
tft.println(d);
// напряжение (среднее от 100 замеров)
long valvolt = 0;
for (int k=0; k<100; ++k) {
valvolt = valvolt + analogRead(A8); // на панели припаян
}
valvolt = valvolt/100;
float voltage = map(valvolt, 0,1725,0,150);
voltage = voltage/5;
tft.setTextColor(WHITE,BLACK);
tft.setTextSize(3);
tft.setCursor(380,215);
tft.print(voltage);
tft.setTextColor(BLUE,BLACK);
tft.setCursor(380,185);
tft.print(utf8rus("ЗАРЯД"));
tft.drawFastHLine(365,240,115,0xFFFF);
tft.drawFastHLine(0,170,480,0xFFFF);
tft.drawFastHLine(0,40,480,0xFFFF);
tft.drawLine(130,170,170,210,0xFFFF);
tft.drawLine(365,170,325,210,0xFFFF);
tft.drawFastHLine(170,210,155,0xFFFF);
tft.drawLine(130,40,130,380,0xFFFF);// верт полоска левая
tft.drawLine(365,40,365,380,0xFFFF);// верт полоска левая
float sped=getSPEED()/100;
int q = sped;
tft.setTextColor(RED,BLACK);
tft.setTextSize(13);
tft.setCursor(131,60);
char s[5];
sprintf(s,"%3d",q);
tft.println(s);
float rpm=getRPM();
int n = rpm;
tft.setTextColor(DARKGREY,BLACK);
tft.setTextSize(8);
tft.setCursor(155,225);
char o[6];
sprintf(o,"%4d",n);
tft.print(o);
// форсунки
tft.setTextColor(WHITE,BLACK);
//tft.setTextSize(5);
float fors=getFORS();
float racxod=rpm*fors/100000;
//if (racxod < 10)
//int f = fors;
tft.setTextSize(3);
tft.setCursor(0,52);
//char y[5];
//sprintf(y,"%3d",f);
tft.println(racxod);
//if (racxod >= 10)
// tft.setCursor(20,85);
//tft.println(racxod);
tft.setTextSize(5);
tft.setCursor(5,90);
tft.print("");
//tft.setCursor(20,95);
//sped = sped*100;
float sped1 = sped*sped;
float sped2 = sped*2;
float sped3 = sped1+sped2;
float rashod = (racxod/sped3)*10000;
if (rashod >= 100) rashod = 0;
float rashod2 = 0;
// расход (среднее от 10 замеров)
for (int is=0; is<100000; ++is) {
rashod2 = rashod2 + rashod; }
float rashod3 = rashod2/100000;
//if (rashod3 < 10 && sped > 5) //считаем если скорость более 5 км/ч
// tft.setCursor(20,115);
//'tft.print(rashod3);
if (rashod3 >= 10 && sped > 5)
//tft.setTextSize(5);
tft.setCursor(0,85);
tft.print(rashod3);
//tft.print("6,7");
// tft.print(fuelInHouR);
tft.setTextColor(WHITE,BLACK);
tft.setTextSize(3); // устанавливаем маленький шрифт
tft.setCursor(180,300);
tft.print("TAXOMETP");
tft.setTextColor(WHITE,BLACK);
tft.setTextSize(3); // устанавливаем маленький шрифт
tft.setCursor(180,180);
tft.print("CKOPOCTb");
tft.setCursor(15,15);
tft.print(time.gettime("d-m-Y"));
tft.setCursor(350,15);
tft.print(time.gettime("H:i"));
// наружняя температура(среднее от 1000 замеров)
int t1 = analogRead( tempoPin );
float tr = 1023.0 / t1 - 1;
tr = SERIAL_R / tr;
float steinhart;
steinhart = tr / THERMISTOR_R; // (R/Ro)
steinhart = log(steinhart); // ln(R/Ro)
steinhart /= B; // 1/B * ln(R/Ro)
steinhart += 1.0 / (NOMINAL_T + 273); // + (1/To)
steinhart = 1.0 / steinhart; // Invert
steinhart -= 273;
delay(100);
tft.setTextColor(WHITE,BLACK);
tft.setTextSize(3); // устанавливаем маленький шрифт
float tempsn;
tempsn=steinhart;
tft.setCursor(380, 280);
char m[6];
dtostrf(tempsn,5,1,m);
tft.println(m);
//tft.setCursor(380, 280);
//tft.print(steinhart-26);
}
// ----------- тахометр-------/////
int getRPM()
{
int kount=0;
boolean kflag=LOW;
unsigned long currentTime=0;
unsigned long startTime=millis();
while (currentTime<=sampleTime)
{
if (digitalRead(tachPIN)==HIGH)
{
kflag=HIGH;
}
if (digitalRead(tachPIN)==LOW && kflag==HIGH)
{
kount++;
kflag=LOW;
}
currentTime=millis()-startTime;
}
int kount2rpm = int(29400./float(sampleTime))*kount;
return kount2rpm;
}
//----------------------------////
////-------спидометр--------///
int getSPEED()
{
int kount2=0;
boolean kflag2=LOW;
unsigned long currentTime2=0;
unsigned long startTime2=millis();
while (currentTime2<=sampleTime2)
{
if (digitalRead(speedPIN)==HIGH)
{
kflag2=HIGH;
}
if (digitalRead(speedPIN)==LOW && kflag2==HIGH)
{
kount2++;
kflag2=LOW;
}
currentTime2=millis()-startTime2;
}
int kount2racxod = int(25325./float(sampleTime2))*kount2;
return kount2racxod;
}
///---------------------------------------------------////
///-------форсунки------------////
int getFORS()
{
int kount3=0;
boolean kflag3=LOW;
unsigned long currentTime3=0;
unsigned long startTime3=millis();
while (currentTime3<=sampleTime3)
{
if (digitalRead(INJECTOR_PIN)==HIGH)
{
kflag3=HIGH;
}
if (digitalRead(INJECTOR_PIN)==LOW && kflag3==HIGH)
{
kount3++;
kflag3=LOW;
}
currentTime3=millis()-startTime3;
}
int kount3racxod = int(10000./float(sampleTime3))*kount3;
return kount3racxod;
}
// This function opens a Windows Bitmap (BMP) file and
// displays it at the given coordinates. It's sped up
// by reading many pixels worth of data at a time
// (rather than pixel by pixel). Increasing the buffer
// size takes more of the Arduino's precious RAM but
// makes loading a little faster. 20 pixels seems a
// good balance.
#define BUFFPIXEL 20
void bmpDraw(char *filename, int x, int y) {
File bmpFile;
int bmpWidth, bmpHeight; // W+H in pixels
uint8_t bmpDepth; // Bit depth (currently must be 24)
uint32_t bmpImageoffset; // Start of image data in file
uint32_t rowSize; // Not always = bmpWidth; may have padding
uint8_t sdbuffer[3*BUFFPIXEL]; // pixel in buffer (R+G+B per pixel)
uint16_t lcdbuffer[BUFFPIXEL]; // pixel out buffer (16-bit per pixel)
uint8_t buffidx = sizeof(sdbuffer); // Current position in sdbuffer
boolean goodBmp = false; // Set to true on valid header parse
boolean flip = true; // BMP is stored bottom-to-top
int w, h, row, col;
uint8_t r, g, b;
uint32_t pos = 0, startTime = millis();
uint8_t lcdidx = 0;
boolean first = true;
if((x >= tft.width()) || (y >= tft.height())) return;
#ifdef DEBUG
tft.fillScreen(0);
tft.setCursor(0,0);
tft.print(F("Loading image '"));
tft.print(filename);
tft.println('\'');
#endif
// Open requested file on SD card
if ((bmpFile = SD.open(filename)) == NULL) {
#ifdef DEBUG
tft.println(F("File not found"));
#endif
return;
}
// Parse BMP header
if(read16(bmpFile) == 0x4D42) {
// BMP signature
#ifdef DEBUG
tft.println(F("File size: ")); tft.println(read32(bmpFile));
#else
read32(bmpFile);
#endif
(void)read32(bmpFile); // Read & ignore creator bytes
bmpImageoffset = read32(bmpFile); // Start of image data
#ifdef DEBUG
tft.print(F("Image Offset: ")); tft.println(bmpImageoffset, DEC);
// Read DIB header
tft.print(F("Header size: ")); tft.println(read32(bmpFile));
#else
read32(bmpFile);
#endif
bmpWidth = read32(bmpFile);
bmpHeight = read32(bmpFile);
if(read16(bmpFile) == 1) { // # planes -- must be '1'
bmpDepth = read16(bmpFile); // bits per pixel
#ifdef DEBUG
Serial.print(F("Bit Depth: ")); Serial.println(bmpDepth);
#endif
if((bmpDepth == 24) && (read32(bmpFile) == 0)) { // 0 = uncompressed
goodBmp = true; // Supported BMP format -- proceed!
#ifdef DEBUG
tft.print(F("Image size: "));
tft.print(bmpWidth);
tft.print('x');
tft.println(bmpHeight);
delay(3000);
#endif
// BMP rows are padded (if needed) to 4-byte boundary
rowSize = (bmpWidth * 3 + 3) & ~3;
// If bmpHeight is negative, image is in top-down order.
// This is not canon but has been observed in the wild.
if(bmpHeight < 0) {
bmpHeight = -bmpHeight;
flip = false;
}
// Crop area to be loaded
w = bmpWidth;
h = bmpHeight;
if((x+w-1) >= tft.width()) w = tft.width() - x;
if((y+h-1) >= tft.height()) h = tft.height() - y;
// Set TFT address window to clipped image bounds
tft.setAddrWindow(x, y, x+w-1, y+h-1);
for (row=0; row<h; row++) { // For each scanline...
// Seek to start of scan line. It might seem labor-
// intensive to be doing this on every line, but this
// method covers a lot of gritty details like cropping
// and scanline padding. Also, the seek only takes
// place if the file position actually needs to change
// (avoids a lot of cluster math in SD library).
if(flip) // Bitmap is stored bottom-to-top order (normal BMP)
pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize;
else // Bitmap is stored top-to-bottom
pos = bmpImageoffset + row * rowSize;
if(bmpFile.position() != pos) { // Need seek?
bmpFile.seek(pos);
buffidx = sizeof(sdbuffer); // Force buffer reload
}
for (col=0; col<w; col++) { // For each column...
// Time to read more pixel data?
if (buffidx >= sizeof(sdbuffer)) { // Indeed
// Push LCD buffer to the display first
if(lcdidx > 0) {
tft.pushColors(lcdbuffer, lcdidx, first);
lcdidx = 0;
first = false;
}
bmpFile.read(sdbuffer, sizeof(sdbuffer));
buffidx = 0; // Set index to beginning
}
// Convert pixel from BMP to TFT format
b = sdbuffer[buffidx++];
g = sdbuffer[buffidx++];
r = sdbuffer[buffidx++];
lcdbuffer[lcdidx++] = tft.color565(r,g,b);
} // end pixel
} // end scanline
// Write any remaining data to LCD
if(lcdidx > 0) {
tft.pushColors(lcdbuffer, lcdidx, first);
}
} // end goodBmp
}
}
bmpFile.close();
if(!goodBmp) tft.println(F("BMP format not recognized."));
}
// These read 16- and 32-bit types from the SD card file.
// BMP data is stored little-endian, Arduino is little-endian too.
// May need to reverse subscript order if porting elsewhere.
uint16_t read16(File f) {
uint16_t result;
((uint8_t *)&result)[0] = f.read(); // LSB
((uint8_t *)&result)[1] = f.read(); // MSB
return result;
}
uint32_t read32(File f) {
uint32_t result;
((uint8_t *)&result)[0] = f.read(); // LSB
((uint8_t *)&result)[1] = f.read();
((uint8_t *)&result)[2] = f.read();
((uint8_t *)&result)[3] = f.read(); // MSB
return result;
}
//Русские буквы
String utf8rus(String source)
{
int i,k;
String target;
unsigned char n;
char m[2] = { '0', '\0' };
k = source.length(); i = 0;
while (i < k) {
n = source[i]; i++;
if (n >= 0xC0) {
switch (n) {
case 0xD0: {
n = source[i]; i++;
if (n == 0x81) { n = 0xA8; break; }
if (n >= 0x90 && n <= 0xBF) n = n-1 + 0x30;
break;
}
case 0xD1: {
n = source[i]; i++;
if (n == 0x91) { n = 0xB8; break; }
if (n >= 0x80 && n <= 0x8F) n = n -1 + 0x70;
break;
}
}
}
m[0] = n; target = target + String(m);
}
return target;
}
Спасибо за информацию. Держите нас в курсе.
https://prnt.sc/142g3js
https://prnt.sc/142g9k8
В общем-то все работаем, но обновление информации происходит 1 раз в 3 секунды, а хотелось бы мгновенно.
"хотелось бы" - меняйте код.
В коде задержка 1 сек - измерение RPM, 1 секунда - замер расхода и еще 1 секунда - замер скорости. Вот и выходит, что быстрее трех секунд обновление инфы невозможно.
Да и весь код написан в абсолютно линейном последовательном стиле: - делаем первое... делаем второе... делаем третье... .... делаем тридцатое.... не код, а детский сад, пособие новичку "как не следует писать"
программы, требующие мгновенного отклика - так не пишут. Переписывайте все измерения, чтобы они выполнялись одновременно.
спс. буду изучать. Это первый серьезный проект. хоть толкнули в направлении.
ну вот например измерения оборотов, расхода и скорости в коде - три абсолютно одинаковых цикла длиной в 1 секунду, только величины разные. Самое простое - запихнуть измерение всех трех величин в один цикл, тогда хотя бы в сумме это будет занимать секунду, а не три
что это?
понял. опозорился походу спать пора
есть такая библиотека. мож через нее?
зачем? Вы без библиотеки не можете содержимое трех циклов перенести в один? Там ведь нет ОДНОВРЕМЕННЫХ процессов, для чего нужна сложная библиотека, просто у вас в цикле опрашивается пин. Сначала в первом цикле - один пин, потом во втором цикле - другой...
Что мешает прямо в первом цмкле опросить сразу три пина и посчитать все три величины? Думайте, задачка вообще элементарная...
int getRPM() { int kount=0; boolean kflag=LOW; unsigned long currentTime=0; unsigned long startTime=millis(); while (currentTime<=sampleTime) { if (digitalRead(tachPIN)==HIGH) { kflag=HIGH; } if (digitalRead(tachPIN)==LOW && kflag==HIGH) { kount++; kflag=LOW; } currentTime=millis()-startTime; } int kount2rpm = int(29400./float(sampleTime))*kount; return kount2rpm; } //----------------------------//// ////-------спидометр--------/// int getSPEED() { int kount2=0; boolean kflag2=LOW; unsigned long currentTime=0; unsigned long startTime=millis(); while (currentTime<=sampleTime) { if (digitalRead(speedPIN)==HIGH) { kflag2=HIGH; } if (digitalRead(speedPIN)==LOW && kflag2==HIGH) { kount2++; kflag2=LOW; } currentTime=millis()-startTime; } int kount2racxod = int(25325./float(sampleTime))*kount2; return kount2racxod; } ///---------------------------------------------------//// ///-------форсунки------------//// int getFORS() { int kount3=0; boolean kflag3=LOW; unsigned long currentTime=0; unsigned long startTime=millis(); while (currentTime<=sampleTime) { if (digitalRead(INJECTOR_PIN)==HIGH) { kflag3=HIGH; } if (digitalRead(INJECTOR_PIN)==LOW && kflag3==HIGH) { kount3++; kflag3=LOW; } currentTime=millis()-startTime; } int kount3racxod = int(10000./float(sampleTime))*kount3; return kount3racxod; }так?
то есть использовать толь 1 const unsigned long sampleTime=1000;
Мда.
Видимо писал не сам.
ага, списывал
ага, списывал
Шурф, при таком уровне владения языком я не в состоянии вам помочь, извините
и на том спасибо. Это первый проект, не считая включения светодиодов, ну и часов с температурой и влажностью на лсд
а , если честно, я и так рад , что смог хоть так осилить этот БК и он работает! Есть недочеты, но для первого раза - сойдет
Тут у нас регулярно появляются "борцы за правду", обвиняющие форум в нетерпимости к новичкам. Где же вы теперь, покажите свою доброту, напишите человеку код... Эдик-создатель, ты так распинался в платном разделе на днях, твой выход!
а , если честно, я и так рад , что смог хоть так осилить этот БК и он работает! Есть недочеты, но для первого раза - сойдет
надо двигаться дальше
конечно, буду изучать. Вам спасибо, в один недочет кода носом ткнули.
конечно, желание форумом пользоваться, точнее писать в нем, в ближайшее время охота отпала(
#include <iarduino_RTC.h> iarduino_RTC time(RTC_DS1307); #include <DHT.h> #include <DHT_U.h> #define B 3950 // B-коэффициент #define SERIAL_R 10000 // сопротивление последовательного резистора, 10 кОм #define THERMISTOR_R 10000 // номинальное сопротивления термистора, 10 кОм #define NOMINAL_T 25 // номинальная температура (при которой TR = 10 кОм) const byte tempoPin = A12; #define DHTTYPE DHT11 #define DHTPIN 41 DHT dht(DHTPIN, DHTTYPE); #include <Adafruit_GFX.h> // Core graphics library #include <SPI.h> #include <SD.h> #include <MCUFRIEND_kbv.h> // Hardware-specific library #include <OneWire.h> #include <Wire.h> //const extern uint8_t FreeSans9pt7b #include "Fonts/FreeSansBold24pt7b.h" // когда вам нужны другие шрифты MCUFRIEND_kbv tft; #define LCD_CS A3 // Chip Select goes to Analog 3 #define LCD_CD A2 // Command/Data goes to Analog 2 #define LCD_WR A1 // LCD Write goes to Analog 1 #define LCD_RD A0 // LCD Read goes to Analog 0 #define SD_CS 53 // Set the chip select line to whatever you use (10 doesnt conflict with the library) //------------------------------/// #define BLACK 0x0000 #define NAVY 0x000F #define DARKGREEN 0x03E0 #define DARKCYAN 0x03EF #define MAROON 0x7800 #define PURPLE 0x780F #define OLIVE 0x7BE0 #define LIGHTGREY 0xC618 #define DARKGREY 0x7BEF #define BLUE 0x001F #define GREEN 0x07E0 #define CYAN 0x07FF #define RED 0xF800 #define MAGENTA 0xF81F #define YELLOW 0xFFE0 #define WHITE 0xFFFF #define ORANGE 0xFD20 #define GREENYELLOW 0xAFE5 #define PINK 0xF81F void setup() { //tft.reset(); dht.begin(); time.begin(); Serial.begin(9600); uint16_t ID = tft.readID(); Serial.println("Example: Font_simple"); Serial.print("found ID = 0x"); Serial.println(ID, HEX); if (ID == 0xD3D3) ID = 0x9481; //force ID if write-only display tft.begin(ID); Wire.begin(); //tft.setTextSize(2); //tft.fillScreen(0); tft.setRotation(1); if (!SD.begin(SD_CS )) { return; } //-----------------------------------// bmpDraw("OPEL3.bmp", 0, 0); delay(5000); //tft.reset(); //delay(1); tft.fillScreen( BLACK); } void loop() { //delay(2000); float h = dht.readHumidity(); // считывание влажности float t = dht.readTemperature(); // считывание температуры tft.setTextColor(WHITE,BLACK); tft.setTextSize(3); tft.setCursor(5,270); tft.print(h); tft.setTextSize(3); tft.setCursor(5,230); tft.print(t); tft.setCursor(105,270); tft.print("%"); tft.setCursor(105,230); tft.print("C"); tft.setTextColor(BLUE,BLACK); tft.setCursor(10,185); tft.print(utf8rus("ВНУТРИ")); // ВНУТРИ tft.setCursor(85,52); tft.print(utf8rus("МГ")); // РАСХОД tft.setCursor(3,140); //tft.print(utf8rus("Л/Ч")); tft.setCursor(380,50); tft.print(utf8rus("ТОСОЛ")); tft.setTextSize(2); tft.setCursor(380,245); tft.print(utf8rus("За окном")); // темп двиг (среднее от 100 замеров) long valtemp = 0; for (int kd=0; kd<100; ++kd) { valtemp = valtemp + analogRead(A10); } valtemp = valtemp/100; float voltemp = map(valtemp,750,0,0,1200); voltemp = voltemp/10; float temp3=voltemp; int z = temp3; tft.setTextColor(WHITE,BLACK); tft.setTextSize(5); tft.setCursor(375,100); char d[5]; sprintf(d,"%3d",z); tft.println(d); // напряжение (среднее от 100 замеров) long valvolt = 0; for (int k=0; k<100; ++k) { valvolt = valvolt + analogRead(A8); // на панели припаян } valvolt = valvolt/100; float voltage = map(valvolt, 0,1725,0,150); voltage = voltage/5; tft.setTextColor(WHITE,BLACK); tft.setTextSize(3); tft.setCursor(380,215); tft.print(voltage); tft.setTextColor(BLUE,BLACK); tft.setCursor(380,185); tft.print(utf8rus("ЗАРЯД")); tft.drawFastHLine(365,240,115,0xFFFF); tft.drawFastHLine(0,170,480,0xFFFF); tft.drawFastHLine(0,40,480,0xFFFF); tft.drawLine(130,170,170,210,0xFFFF); tft.drawLine(365,170,325,210,0xFFFF); tft.drawFastHLine(170,210,155,0xFFFF); tft.drawLine(130,40,130,380,0xFFFF);// верт полоска левая tft.drawLine(365,40,365,380,0xFFFF);// верт полоска левая //--------скорость--------// long valsped = 0; for (int kd=0; kd<100; ++kd) { valsped = valsped + analogRead(19); } valsped = valsped/100; float volsped = map(valsped,750,0,0,1200); volsped = volsped/10; float sped=volsped; int q = sped; tft.setTextColor(RED,BLACK); tft.setTextSize(13); tft.setCursor(131,60); char s[5]; sprintf(s,"%3d",q); tft.println(s); //----------тахо---------// long valrpm = 0; for (int kd=0; kd<100; ++kd) { valrpm = valrpm + analogRead(18); } valrpm = valrpm/100; float volrpm = map(valrpm,750,0,0,1200); volrpm = volrpm/10; float rpm=volrpm; int n = rpm; tft.setTextColor(DARKGREY,BLACK); tft.setTextSize(8); tft.setCursor(155,225); char o[6]; sprintf(o,"%4d",n); tft.print(o); // форсунки tft.setTextColor(WHITE,BLACK); long valfors = 0; for (int kd=0; kd<100; ++kd) { valfors = valfors + analogRead(A9); } valfors = valfors/100; float volfors = map(valfors,750,0,0,1200); volfors = volfors/10; float fors=volfors; float racxod=rpm*fors/100000; //if (racxod < 10) //int f = fors; tft.setTextSize(3); tft.setCursor(0,52); //char y[5]; //sprintf(y,"%3d",f); tft.println(racxod); //if (racxod >= 10) // tft.setCursor(20,85); //tft.println(racxod); tft.setTextSize(5); tft.setCursor(5,90); tft.print(""); //tft.print("6,7"); // tft.print(fuelInHouR); tft.setTextColor(WHITE,BLACK); tft.setTextSize(3); // устанавливаем маленький шрифт tft.setCursor(180,300); tft.print("TAXOMETP"); tft.setTextColor(WHITE,BLACK); tft.setTextSize(3); // устанавливаем маленький шрифт tft.setCursor(180,180); tft.print("CKOPOCTb"); tft.setCursor(15,15); tft.print(time.gettime("d-m-Y")); tft.setCursor(350,15); tft.print(time.gettime("H:i")); // наружняя температура(среднее от 1000 замеров) int t1 = analogRead( tempoPin ); float tr = 1023.0 / t1 - 1; tr = SERIAL_R / tr; float steinhart; steinhart = tr / THERMISTOR_R; // (R/Ro) steinhart = log(steinhart); // ln(R/Ro) steinhart /= B; // 1/B * ln(R/Ro) steinhart += 1.0 / (NOMINAL_T + 273); // + (1/To) steinhart = 1.0 / steinhart; // Invert steinhart -= 273; delay(100); tft.setTextColor(WHITE,BLACK); tft.setTextSize(3); // устанавливаем маленький шрифт float tempsn; tempsn=steinhart; tft.setCursor(380, 280); char m[6]; dtostrf(tempsn,5,1,m); tft.println(m); //tft.setCursor(380, 280); //tft.print(steinhart-26); } // This function opens a Windows Bitmap (BMP) file and // displays it at the given coordinates. It's sped up // by reading many pixels worth of data at a time // (rather than pixel by pixel). Increasing the buffer // size takes more of the Arduino's precious RAM but // makes loading a little faster. 20 pixels seems a // good balance. #define BUFFPIXEL 20 void bmpDraw(char *filename, int x, int y) { File bmpFile; int bmpWidth, bmpHeight; // W+H in pixels uint8_t bmpDepth; // Bit depth (currently must be 24) uint32_t bmpImageoffset; // Start of image data in file uint32_t rowSize; // Not always = bmpWidth; may have padding uint8_t sdbuffer[3*BUFFPIXEL]; // pixel in buffer (R+G+B per pixel) uint16_t lcdbuffer[BUFFPIXEL]; // pixel out buffer (16-bit per pixel) uint8_t buffidx = sizeof(sdbuffer); // Current position in sdbuffer boolean goodBmp = false; // Set to true on valid header parse boolean flip = true; // BMP is stored bottom-to-top int w, h, row, col; uint8_t r, g, b; uint32_t pos = 0, startTime = millis(); uint8_t lcdidx = 0; boolean first = true; if((x >= tft.width()) || (y >= tft.height())) return; #ifdef DEBUG tft.fillScreen(0); tft.setCursor(0,0); tft.print(F("Loading image '")); tft.print(filename); tft.println('\''); #endif // Open requested file on SD card if ((bmpFile = SD.open(filename)) == NULL) { #ifdef DEBUG tft.println(F("File not found")); #endif return; } // Parse BMP header if(read16(bmpFile) == 0x4D42) { // BMP signature #ifdef DEBUG tft.println(F("File size: ")); tft.println(read32(bmpFile)); #else read32(bmpFile); #endif (void)read32(bmpFile); // Read & ignore creator bytes bmpImageoffset = read32(bmpFile); // Start of image data #ifdef DEBUG tft.print(F("Image Offset: ")); tft.println(bmpImageoffset, DEC); // Read DIB header tft.print(F("Header size: ")); tft.println(read32(bmpFile)); #else read32(bmpFile); #endif bmpWidth = read32(bmpFile); bmpHeight = read32(bmpFile); if(read16(bmpFile) == 1) { // # planes -- must be '1' bmpDepth = read16(bmpFile); // bits per pixel #ifdef DEBUG Serial.print(F("Bit Depth: ")); Serial.println(bmpDepth); #endif if((bmpDepth == 24) && (read32(bmpFile) == 0)) { // 0 = uncompressed goodBmp = true; // Supported BMP format -- proceed! #ifdef DEBUG tft.print(F("Image size: ")); tft.print(bmpWidth); tft.print('x'); tft.println(bmpHeight); delay(3000); #endif // BMP rows are padded (if needed) to 4-byte boundary rowSize = (bmpWidth * 3 + 3) & ~3; // If bmpHeight is negative, image is in top-down order. // This is not canon but has been observed in the wild. if(bmpHeight < 0) { bmpHeight = -bmpHeight; flip = false; } // Crop area to be loaded w = bmpWidth; h = bmpHeight; if((x+w-1) >= tft.width()) w = tft.width() - x; if((y+h-1) >= tft.height()) h = tft.height() - y; // Set TFT address window to clipped image bounds tft.setAddrWindow(x, y, x+w-1, y+h-1); for (row=0; row<h; row++) { // For each scanline... // Seek to start of scan line. It might seem labor- // intensive to be doing this on every line, but this // method covers a lot of gritty details like cropping // and scanline padding. Also, the seek only takes // place if the file position actually needs to change // (avoids a lot of cluster math in SD library). if(flip) // Bitmap is stored bottom-to-top order (normal BMP) pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize; else // Bitmap is stored top-to-bottom pos = bmpImageoffset + row * rowSize; if(bmpFile.position() != pos) { // Need seek? bmpFile.seek(pos); buffidx = sizeof(sdbuffer); // Force buffer reload } for (col=0; col<w; col++) { // For each column... // Time to read more pixel data? if (buffidx >= sizeof(sdbuffer)) { // Indeed // Push LCD buffer to the display first if(lcdidx > 0) { tft.pushColors(lcdbuffer, lcdidx, first); lcdidx = 0; first = false; } bmpFile.read(sdbuffer, sizeof(sdbuffer)); buffidx = 0; // Set index to beginning } // Convert pixel from BMP to TFT format b = sdbuffer[buffidx++]; g = sdbuffer[buffidx++]; r = sdbuffer[buffidx++]; lcdbuffer[lcdidx++] = tft.color565(r,g,b); } // end pixel } // end scanline // Write any remaining data to LCD if(lcdidx > 0) { tft.pushColors(lcdbuffer, lcdidx, first); } } // end goodBmp } } bmpFile.close(); if(!goodBmp) tft.println(F("BMP format not recognized.")); } // These read 16- and 32-bit types from the SD card file. // BMP data is stored little-endian, Arduino is little-endian too. // May need to reverse subscript order if porting elsewhere. uint16_t read16(File f) { uint16_t result; ((uint8_t *)&result)[0] = f.read(); // LSB ((uint8_t *)&result)[1] = f.read(); // MSB return result; } uint32_t read32(File f) { uint32_t result; ((uint8_t *)&result)[0] = f.read(); // LSB ((uint8_t *)&result)[1] = f.read(); ((uint8_t *)&result)[2] = f.read(); ((uint8_t *)&result)[3] = f.read(); // MSB return result; } //Русские буквы String utf8rus(String source) { int i,k; String target; unsigned char n; char m[2] = { '0', '\0' }; k = source.length(); i = 0; while (i < k) { n = source[i]; i++; if (n >= 0xC0) { switch (n) { case 0xD0: { n = source[i]; i++; if (n == 0x81) { n = 0xA8; break; } if (n >= 0x90 && n <= 0xBF) n = n-1 + 0x30; break; } case 0xD1: { n = source[i]; i++; if (n == 0x91) { n = 0xB8; break; } if (n >= 0x80 && n <= 0x8F) n = n -1 + 0x70; break; } } } m[0] = n; target = target + String(m); } return target; }так?