Hallo zusammen,
Habe einen mittlweile recht umfangreichen Sketch auf meinem Arduino am Laufen. Dieser dient als Bordcomputer in meinem Auto. Seit langem hab ich jetzt mal die IDE wieder gestartet und etwas angepasst, da der Drucksensor von VDO keine plausiblen Werte angezeigt hat. Die Berechnung für Temperatur und Drucksensorik stammt von "jurs" hier aus dem Forum. Die Anzeige der Temperaturen hat jetzt auch 4 Jahre lang gut gepasst - seit dem Update stimmt das gar nicht mehr!
Am Sketch hab ich -zumindest an der Berechnung und Anzeige der Temperatur- nichts geändert. Nur den Teil für den Drucksensor. Trotzdem habe ich jetzt ein recht interessantes Phänomen. Mein Arduino wird über den Rundstecker von einem 12V/5V DCDC Wandler versorgt. An diesem Wandler hängen auch die Displays und die Sensorik. Der Arduino Mega muss also keine Peripherie mit Spannung versorgen. Meine angezeigten Werte für die Temperatur sind wie festgenagelt bei 5°C. Dieser Wert stellt einen Ersatzwert dar für alles, was unterhalb oder gleich der 5°C ist. Erst wenn das Kühlmittel ca 45°C erreicht, gehen die angezeigten Werte langsam nach oben. Jetzt der clou: versorge ich den Arduino zusätzlich über den USB Anschluss mit 5V, dann stimmen die angezeigten Temperaturen von Anfang an. Einzig die Bordspannung wird dann nicht mehr richtig angezeigt.
Der Sketch schaut so aus:
// call all your required includes
#include <Wire.h>
#include <Adafruit_BME280.h>
#include <Adafruit_Sensor.h>
#include <SPI.h>
#include <TFT_eSPI.h> // Hardware-specific library
#include "Free_Fonts.h"
Adafruit_BME280 bme; // use I2C interface
// Declare which bitmaps we will be using
#include "AIR.c"
#include "BAROMETER.c"
#include "BATTERY.c"
#include "BMW125.c"
#include "FUEL.c"
#include "HEIGHT.c"
#include "OIL.c"
#include "HUMIDITY.c"
#include "WATER.c"
//#define TFT_RGB_ORDER TFT_RGB // Colour order Red-Green-Blue
//#define TFT_RGB_ORDER TFT_BGR // Colour order Blue-Green-Red
// define all your constant values you are using
#define ABSZERO 273.15
#define MATKONST_B 3994.92
#define MAXANALOGREAD 1023.0
#define SEALEVELPRESSURE_HPA 1013.25
// define all your analog input channels you are using
#define T_OEL_1 A0
#define T_OEL_2 A1
#define T_KUEHLW_1 A2
#define T_KUEHLW_2 A3
#define T_KUEHLW_3 A4
#define P_OEL_1 A5
#define L_TANK1 A6
#define L_TANK2 A7
#define V_BATT A8
//Voltage Control SPANNUNGSANZEIGE!!!
//Floats for ADC & input voltage
float adc_voltage = 0.0;
float in_voltage = 0.0;
//floats for resistor values in divider (ohms)
float R1 = 30000.0;
float R2 = 7500.0;
//float for reference voltage
float ref_voltage = 3.2;
//integer for adc value
int adc_value = 0;
//define PINS
#define firstScreenCS 3
#define secondScreenCS 2
TFT_eSPI tft = TFT_eSPI(); // Invoke custom library
/* ------------------------------------------------------------------------------------- */
//Temperature sensor code by 'jurs' for German Arduino Forum
float temperature_NTCB(float T0, float R0, float B, float RV, float VA_VB, float fCorr)
{
// Ermittlung der Temperatur mittels NTC-Widerstand
// Version der Funktion bei gegebener Materialkonstante B
// Erklärung der Parameter:
// T0 : Nenntemperatur des NTC-Widerstands in °C
// R0 : Nennwiderstand des NTC-Sensors in Ohm
// B : Materialkonstante B
// Vorwiderstand: Vorwiderstand in Ohm
// VA_VB : Spannungsverhältnis "Spannung am NTC zu Betriebsspannung"
// Rückgabewert : Temperatur
T0 += ABSZERO; // umwandeln Celsius in absolute Temperatur
float RN = RV * VA_VB / (1 - VA_VB); // aktueller Widerstand des NTC
return (T0 * B / (B + T0 * log(RN / R0)) - ABSZERO + fCorr);
}
/*
//Temperature sensor code by 'jurs' for German Arduino Forum
float temperature_NTC(float T0, float R0, float T1, float R1, float RV, float VA_VB)
// Ermittlung der Temperatur mittels NTC-Widerstand
// Version der Funktion bei unbekannter Materialkonstante B
// Erklärung der Parameter:
// T0 : Nenntemperatur des NTC-Widerstands in °C
// R0 : Nennwiderstand des NTC-Sensors in Ohm
// T1 : erhöhte Temperatur des NTC-Widerstands in °C
// R1 : Widerstand des NTC-Sensors bei erhöhter Temperatur in Ohm
// Vorwiderstand: Vorwiderstand in Ohm
// VA_VB : Spannungsverhältnis "Spannung am NTC zu Betriebsspannung"
// Rückgabewert : Temperatur
{
T0+=ABSZERO; // umwandeln Celsius in absolute Temperatur
T1+=ABSZERO; // umwandeln Celsius in absolute Temperatur
float B= (T0 * T1)/ (T1-T0) * log(R0/R1); // Materialkonstante B
float RN=RV*VA_VB / (1-VA_VB); // aktueller Widerstand des NTC
return T0 * B / (B + T0 * log(RN / R0))-ABSZERO;
}
*/
/* -------------------------------------------------------------------------------------- */
// VDO pressure sensor code by 'jurs' for German Arduino Forum
float pressure_VDO_10bar(float RV, float VA_VB, float fCorr)
// Ermittlung des Drucks mit einem VDO Öldruckgeber 10bar
// Erklärung der Parameter:
// RV : Vorwiderstand in Ohm
// VA_VB : Spannungsverhältnis "Spannung am NTC zu Betriebsspannung"
// Rückgabewert : Öldruck - wegen 10 bar Messbereich ist der maximale Rückgabewert 11,1 bar.
//
// Info: http://forum.arduino.cc/index.php?topic=155733.0
// https://forum.arduino.cc/index.php?topic=155733.15
// http://forum.arduino.cc/index.php?topic=152024
{
float a = 8.37e-8;
float b = 0.000054058;
float c = 0.0439893708;
float d = -0.4453831665;
float RN = RV * VA_VB / (1 - VA_VB); // aktueller Widerstand des NTC
float pressure = (((a * RN * RN * RN) + (b * RN * RN) + (c * RN) + d) * fCorr);
if (pressure < 0) pressure = 0; // Begrenzung nach unten, keine negativen Werte extrapolieren
if (pressure > 11.1) pressure = 11.1; // Willkürlich gewählte Begrenzung nach oben
return (pressure);
}
void setup()
{
Serial.begin(9600);
Wire.begin();
pinMode(firstScreenCS, OUTPUT);
digitalWrite(firstScreenCS, HIGH);
pinMode(secondScreenCS, OUTPUT);
digitalWrite(secondScreenCS, HIGH);
// We need to 'init' both displays at the same time. so set both cs pins low
digitalWrite(firstScreenCS, LOW);
digitalWrite(secondScreenCS, LOW);
tft.init();
tft.begin();
unsigned status;
status = bme.begin(0x77);
// Swap the colour byte order when rendering
tft.setSwapBytes(true);
//tft.setFreeFont(FSS12);
tft.setFreeFont(FSS12);
//tft.setTextSize(2);
// Set both cs pins HIGH, or 'inactive'
//digitalWrite(firstScreenCS, HIGH);
//digitalWrite(secondScreenCS, HIGH);
//initial screen clearing
digitalWrite(firstScreenCS, LOW);
digitalWrite(secondScreenCS, LOW);
tft.setRotation(2); //Bildschirmausrichtung definieren
tft.fillScreen(TFT_BLACK); //Bildschirme schwärzen
digitalWrite(firstScreenCS, HIGH);
digitalWrite(secondScreenCS, HIGH);
//BILDSCHIRM LINKS
digitalWrite(firstScreenCS, LOW);
//tft.setRotation(2);
//tft.fillScreen(TFT_BLACK);
tft.pushImage(48, 97, 125, 125, BMW125);
digitalWrite(firstScreenCS, HIGH);
//BILDSCHIRM RECHTS
digitalWrite(secondScreenCS, LOW);
//tft.setRotation(2);
//tft.fillScreen(TFT_BLACK);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.setCursor(90,130);
tft.print("Freude"); //Schriftzug auf TFT2
tft.setCursor(110,180);
tft.print("am");
tft.setCursor(90,230);
tft.print("Fahren");
digitalWrite(secondScreenCS, HIGH);
delay (2000);
//clear both screens
digitalWrite(firstScreenCS, LOW);
digitalWrite(secondScreenCS, LOW);
tft.fillScreen(TFT_BLACK);
digitalWrite(firstScreenCS, HIGH);
//tft.fillScreen(TFT_BLACK);
digitalWrite(secondScreenCS, HIGH);
//Display LINKS
//SYMBOLE
digitalWrite(firstScreenCS, LOW);
tft.setTextColor(TFT_WHITE, TFT_BLACK); //Farbe Text: Weiß
tft.setCursor( 70, 50);
tft.print("Alpina V8"); //Kopfzeile
tft.pushImage(20, 80, 24, 24, BATTERY); //Zeile 1
tft.pushImage(20, 115, 24, 24, FUEL); //Zeile 2
tft.pushImage(20, 150, 24, 24, AIR); //Zeile 3
tft.pushImage(20, 185, 24, 24, BAROMETER); //Zeile 4
tft.pushImage(20, 220, 24, 24, HEIGHT); //Zeile 5
tft.pushImage(20, 255, 24, 24, HUMIDITY); //Zeile 6
//Textzeichen
tft.setTextColor(TFT_WHITE, TFT_BLACK); //Farbe Text: Weiß
tft.setCursor( 170, 100);
tft.print("V"); //Zeile 1
tft.setCursor(170, 135);
tft.print("l"); //Zeile 2
tft.setCursor(170, 170);
tft.print("°C"); //Zeile 3
tft.setCursor(170, 205);
tft.print("hPa"); //Zeile 4
tft.setCursor(170, 240);
tft.print("m"); //Zeile 5
tft.setCursor(170, 275);
tft.print("%"); //Zeile 6
digitalWrite(firstScreenCS, HIGH);
//Display RECHTS
//Layout KÜHLWASSER
digitalWrite(secondScreenCS, LOW);
tft.pushImage(40, 25, 24, 24, WATER); //Symbol Wasser
tft.setTextColor(TFT_CYAN, TFT_BLACK); //Farbe Text: Weiß
tft.setCursor(75, 45);
tft.print("Kuehlwasser"); //Kopfzeile
tft.setCursor(40, 75);
tft.print("Motor °C"); //Zeile 1
tft.setCursor(40, 110);
tft.print("Heiss °C"); //Zeile 2
tft.setCursor(40, 145);
tft.print("Kalt °C"); //Zeile 3
//Layout MOTORÖL
tft.pushImage(52, 160, 40, 18, OIL); //Symbol Öl
tft.setTextColor(TFT_GOLD, TFT_BLACK); //Farbe Text: Weiß
tft.setCursor(110, 180);
tft.print("Motoroel"); //Kopfzeile
tft.setCursor(40, 215);
tft.print("Heiss °C"); //Zeile 1
//tft.setCursor(40, 250);
//tft.print("Kalt °C"); //Zeile 2
tft.setCursor(40, 285);
tft.print("Druck Bar"); //Zeile 3
digitalWrite(secondScreenCS, HIGH);
}
void loop()
{
// KÜHLWASSER Temperatur berechnen
float fT0 = 40; // Nenntemperatur des NTC-Widerstands in °C
float fR0 = 843; // Nennwiderstand des NTC-Sensors in Ohm
float fT1 = 100; // erhöhte Temperatur des NTC-Widerstands in °C
float fR1 = 108; // Widerstand des NTC-Sensors bei erhöhter Temperatur in Ohm
float fVorwiderstand = 100; // Vorwiderstand in Ohm
float fTemp3, fTemp4, fTemp5;
int iTemp3 = analogRead(T_KUEHLW_1); //Zeile 1
int iTemp4 = analogRead(T_KUEHLW_2); //Zeile 2
int iTemp5 = analogRead(T_KUEHLW_3); //Zeile 3
// fTemp3 = temperature_NTC(fT0, fR0, fT1, fR1, fVorwiderstand, iTemp3 / MAXANALOGREAD);
fTemp3 = temperature_NTCB(fT0, fR0, MATKONST_B, fVorwiderstand, iTemp3 / MAXANALOGREAD, 0.0);
if (fTemp3 < 5) fTemp3 = 5; // Begrenzung nach unten
fTemp4 = temperature_NTCB(fT0, fR0, MATKONST_B, fVorwiderstand, iTemp4 / MAXANALOGREAD, 0.0);
if (fTemp4 < 5) fTemp4 = 5; // Begrenzung nach unten
fTemp5 = temperature_NTCB(fT0, fR0, MATKONST_B, fVorwiderstand, iTemp5 / MAXANALOGREAD, 0.0);
if (fTemp5 < 5) fTemp5 = 5; // Begrenzung nach unten
// MOTORÖL Temperatur berechnen
float fVorwiderstand1 = 100; // Vorwiderstand in Ohm
float fPress1, fTemp1, fTemp2;
int iTemp1 = analogRead(T_OEL_2);
int iTemp2 = analogRead(T_OEL_1);
fTemp1 = temperature_NTCB(fT0, fR0, MATKONST_B, fVorwiderstand1, iTemp1 / MAXANALOGREAD, 0.0);
if (fTemp1 < 5) fTemp1 = 5; // Begrenzung nach unten
fTemp2 = temperature_NTCB(fT0, fR0, MATKONST_B, fVorwiderstand1, iTemp2 / MAXANALOGREAD, 0.0);
if (fTemp2 < 5) fTemp2 = 5; // Begrenzung nach unten
//MOTORÖL Druck berechnen
float pressure;
float fvorWiderstand = 25; // Hier Vorwiderstand in Ohm angeben!
int iPress1 = analogRead(P_OEL_1); // Hier wird gemessen!
//for (iPress1=0;iPress1<1024;iPress1++)
fPress1 = pressure_VDO_10bar(fvorWiderstand, iPress1 / 1023.0, 0.5); // Hier wird gerechnet!
//WERTE Bildschirm Links
digitalWrite(firstScreenCS, LOW);
//tft.fillRect(80, 80, 80, 220, TFT_BLACK); //alte Anzeigewerte löschen
tft.setTextColor(TFT_WHITE, TFT_BLACK); //Farbe Text: WEISS
tft.setCursor(80,100);
adc_value = analogRead(V_BATT); //determine voltage at adc input
adc_voltage = (adc_value * ref_voltage) / 1023.0; //calc voltage at divider input
in_voltage = adc_voltage / (R2/(R1+R2));
tft.drawFloat((in_voltage), 1, 80, 80); //Zeile 1 Bordspannung
adc_value = analogRead(L_TANK1);
int iTank1 = (map(adc_value, 40, 530, 63, 0));
adc_value = analogRead(L_TANK2);
int iTank2 = (map(adc_value, 90, 480, 63, 0));
float fTank = ((iTank1 + iTank2)/ 1.85);
tft.drawFloat(fTank, 0, 80, 118); //Zeile 2 Tankinhalt
tft.drawFloat(bme.readTemperature(), 0, 80, 153); //Zeile 3 Außentemperatur
tft.drawFloat(bme.readPressure() / 100.0F, 0, 80, 190); //Zeile 4 Luftdruck
tft.drawFloat(bme.readAltitude(SEALEVELPRESSURE_HPA), 0, 80, 225); //Zeile 5 Höhe über NN
tft.drawFloat(bme.readHumidity(), 0, 80, 260); //Zeile 6 Luftfeuchtigkeit
digitalWrite(firstScreenCS, HIGH);
//WERTE KÜHLWASSER
digitalWrite(secondScreenCS, LOW);
tft.setTextColor(TFT_CYAN, TFT_BLACK); //Farbe Text: blau
tft.drawFloat(fTemp4, 0, 125, 58); //Zeile 1 Wassertemp Thermostat
tft.drawFloat(fTemp3, 0, 125, 93); //Zeile 2 Wassertemp vor Kühler
tft.drawFloat(fTemp5, 0, 125, 129); //Zeile 3 Wassertemp im V
//WERTE MOTORÖL
tft.setTextColor(TFT_GOLD, TFT_BLACK); //Farbe Text: gold
tft.drawFloat(fTemp1, 0, 120, 198); //Zeile 1 Öltemp vor Kühler
// tft.drawFloat(fTemp2, 0, 120, 234); //Zeile 2 Öltemp nach Kühler
tft.drawFloat(fPress1, 1, 120, 268); //Zeile 3 Öldruck
digitalWrite(secondScreenCS, HIGH);
delay(1000);
}
Und so schaut das Ganze aus. Einmal nur über den Rundstecker mit 5V versorgt:
Und einmal mit doppelter Spannungsversorgung:
Kann sich das Mal jemand anschauen und mir sagen, was ich verbockt hab? Oder soll ich mal eine Spannungsversorgung basteln, die nur über den USB Anschluss läuft?