Umstieg von UTFT auf eSPI mit einigen Problemen

Einen schönen Tag der Arbeit euch allen!

So ein Feiertag eignet sich immer wunderbar um ein paar Zeilen zu schreiben. Ich habe bereits mit meinem Arduino Mega 2560 R3 einen funktionierenden Mikrocomputer für mein Auto gebaut. Keine schwierigen Sachen, nur analoge Sensoren und ein bisschen I2C. Das alles war mit UTFT geschrieben.

Nun hab ich gedacht ich bau das Ganze um und integriere es in meinen Tacho. Soweit so gut. Jetzt hat mir letztens ein Kollege ein Video geschickt, der auch so etwas hat, aber bei ihm ist das viel schneller. Leider konnte er mir nicht sagen, welche Lib er verwendet. Nach ein bisschen Suchen im WWW hab ich rausgefunden, dass es mit SPI wesentlich schneller geht, als mit UTFT. Also hab ich angefangen, das alles umzubauen mit dem Grundsketch für 2 Displays von Kitecraft aus diesem Youtube Video. Leider habe ich doch einige Fehlermeldungen und komme auch nicht weiter, wie genau ich Bitmaps in der Bibliothek TFT_eSPI von Bodmer Integrieren und Aufrufen kann.

Aktuell sind die Bitmaps konvertiert mit dem Onlinekonverter von RinkyDinkElectronics und als .c Dateien. Mein Sketch bisher sieht so aus:

//copyright for the 2 screen with eSPI to Kitecraft

/*
In the TFT_ESPI user_setup.h file
be sure to comment out the line for TFT_CS
//#define TFT_CS   21  // Chip select control pin
*/

// call all your required includes
#include <Wire.h>
#include <Adafruit_BME280.h>
#include <Adafruit_Sensor.h>
#include <INA226.h>
#include <SPI.h>
#include <TFT_eSPI.h> // Hardware-specific library
#include "Arial_round_16x24.c"

// Declare which bitmaps we will be using
#include "AIR.c"
#include "BATTERY.c"
#include "FUEL.c"
#include "BMW125.c"
#include "HEIGHT.c"
#include "OIL.c"
#include "WATER.c"
#include "HUMIDITY.c"
#include "BAROMETER.c"

// define all your constant values you are using
#define ABSZERO               273.15
#define MATKONST_B            3402.26
#define MAXANALOGREAD         1024.0
#define P_SEALEVEL_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

Adafruit_BME280 bme;  // use I2C interface for BOSCH BME280
INA226 ina;           // use I2C Interface for INA226

//define CS PINS
#define firstScreenCS 21
#define secondScreenCS 22
TFT_eSPI tft = TFT_eSPI();       // Invoke custom library

/* ------------------------------------------------------------------------------------- */
// NTC temperature calculation 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);
}

/* -------------------------------------------------------------------------------------- */
// 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(115200);
  
  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.loadFont(Arial_round_16x24);
  
  // Set both cs pins HIGH, or 'inactive'
  digitalWrite(firstScreenCS, HIGH);
  digitalWrite(secondScreenCS, HIGH);

  /*
   Update the first screen
   all 'tft.' call must be done
   after setting the cs pin low
  */
  digitalWrite(firstScreenCS, LOW);

  if (!bme.begin(0x76));
  //myGLCD1.print("Sensor BME280?", CENTER, 148);
  delay(200);

  ina.begin (0x40);
  // Configure INA226
  ina.configure(INA226_AVERAGES_1, INA226_BUS_CONV_TIME_1100US, INA226_SHUNT_CONV_TIME_1100US, INA226_MODE_SHUNT_BUS_CONT);

  // Calibrate INA226. Rshunt = 0.01 ohm, Max excepted current = 4A
  ina.calibrate(0.01, 4);
  
  // Swap the colour byte order when rendering
  tft.setSwapBytes(true);
  
  //BILDSCHIRM LINKS
  tft.setRotation(2);  
  tft.fillScreen(TFT_BLACK);
  tft.drawBitmap(57, 97, BMW125, 125, 125, TFT_BLACK, TFT_BLACK);
  tft.setCursor(0,10);
  tft.print("Hello World.\nI'm display #1");
  // set the cs pin back to HIGH when finished
  // with this particular display
  digitalWrite(firstScreenCS, HIGH);

  //BILDSCHIRM RECHTS
  digitalWrite(secondScreenCS, LOW);
  tft.setRotation(2);  
  tft.fillScreen(TFT_BLACK);
  tft.setCursor(70,100);
  tft.print("Freude");             //Schriftzug auf TFT2
  tft.setCursor(110,150);
  tft.print("am");
  tft.setCursor(70,200);
  tft.print("Fahren");
  digitalWrite(secondScreenCS, HIGH);
  delay (1500);

  //clear both screens
  digitalWrite(firstScreenCS, LOW);
  digitalWrite(secondScreenCS, LOW);
  tft.fillScreen(TFT_BLACK);
  digitalWrite(firstScreenCS, HIGH);
  digitalWrite(secondScreenCS, HIGH);

    //Display LINKS
  //SYMBOLE
  digitalWrite(firstScreenCS, LOW);
  /*tft.drawBitmap(20, 90, 24, 24, BATTERY);          //Zeile 1
  tft.drawBitmap(20, 125, 24, 24, FUEL);            //Zeile 2
  tft.drawBitmap(20, 160, 24, 24, AIR);             //Zeile 3
  tft.drawBitmap(20, 195, 24, 24, BAROMETER);       //Zeile 4
  tft.drawBitmap(20, 230, 24, 24, HEIGHT);          //Zeile 5
  tft.drawBitmap(20, 265, 24, 24, HUMIDITY);        //Zeile 6
*/
  //Textzeichen
  tft.setColor(47, 224, 0);                         //Farbe Text: GRÜN
  tft.setCursor( 180, 90);
  tft.print("V");                          //Zeile 1
  tft.setCursor(180, 125);
  tft.print("l");                         //Zeile 2
  tft.setCursor(180, 160);
  tft.print("`C");                        //Zeile 3
  tft.setCursor(180, 195);
  tft.print("hPa");                       //Zeile 4
  tft.setCursor(180, 230);
  tft.print("m");                         //Zeile 5
  tft.setCursor(80, 265);
  tft.print("%");                         //Zeile 6
  digitalWrite(firstScreenCS, HIGH);
  
  //Display RECHTS
  //Layout KÜHLWASSER
  digitalWrite(secondScreenCS, LOW);
  tft.drawBitmap(23, 25, 24, 24, WATER);            //Symbol Wasser
  tft.setColor(2, 171, 253);                        //Farbe Text: BLAU
  tft.setCursor(53, 25);
  tft.print("Kuehlwasser");                 //Kopfzeile
  tft.setCursor(23, 60);
  tft.print("Motor      `C");               //Zeile 1
  tft.setCursor(23, 95);
  tft.print("Heiss      `C");               //Zeile 2
  tft.setCursor(23, 130);
  tft.print("Kalt       `C");              //Zeile 3

  //Layout MOTORÖL
  tft.drawBitmap(35, 180, 24, 24, OIL);             //Symbol Öl
  tft.setColor(240, 213, 5);                        //Farbe Text: GELB
  tft.setCursor(70, 180);
  tft.print("Motoroel");                 //Kopfzeile
  tft.setCursor(23, 215);
  tft.print("Heiss      `C");              //Zeile 1
  tft.setCursor(23, 250);
  tft.print("Kalt       `C");              //Zeile 2
  tft.setCursor(23, 285);
  tft.print("Druck     Bar");              //Zeile 3
  digitalWrite(secondScreenCS, HIGH);
}

void loop() {
  // put your main code here, to run repeatedly:
  delay(100);
}

Meine Fehlermeldungen Aktuell sehen auf den Punbkt gebracht so aus:

/Users/gearx/Documents/Arduino/V8_Tacho_eSPI/V8_Tacho_eSPI.ino: In function 'void setup()':
V8_Tacho_eSPI:142:64: error: no matching function for call to 'TFT_eSPI::drawBitmap(int, int, const short unsigned int [15625], int, int, int, int)'
   tft.drawBitmap(57, 97, BMW125, 125, 125, TFT_BLACK, TFT_BLACK);
                                                                ^
In file included from /Users/gearx/Documents/Arduino/V8_Tacho_eSPI/V8_Tacho_eSPI.ino:15:0:
/Users/gearx/Documents/Arduino/libraries/TFT_eSPI/TFT_eSPI.h:457:12: note: candidate: void TFT_eSPI::drawBitmap(int16_t, int16_t, const uint8_t*, int16_t, int16_t, uint16_t)
   void     drawBitmap( int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t fgcolor),
            ^~~~~~~~~~
/Users/gearx/Documents/Arduino/libraries/TFT_eSPI/TFT_eSPI.h:457:12: note:   candidate expects 6 arguments, 5 provided
/Users/gearx/Documents/Arduino/libraries/TFT_eSPI/TFT_eSPI.h:458:12: note: candidate: void TFT_eSPI::drawBitmap(int16_t, int16_t, const uint8_t*, int16_t, int16_t, uint16_t, uint16_t)
            drawBitmap( int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t fgcolor, uint16_t bgcolor),
            ^~~~~~~~~~
exit status 1
no matching function for call to 'TFT_eSPI::drawBitmap(int, int, const short unsigned int [15625], int, int, int, int)'

Das Problem ist jetzt, dass egal ob ich "drawBitmap" oder "push
Image" verwende, immer die selbe Fehlermeldung bekomme. Kann mir da jemand unter die Arme greifen?

Vielen Dank euch.

Hast du denn vorher mal getestet, ob dein Display mit der gewählten Ansteuerung und einem einfachen Testsketch auch funktioniert ?

Hallo HotSystems,

getestet nein. Muss aber, da in dem Beispielvideo von Kitecraft 3 unterschiedliche Displays verwendet werden mit dem selben Chip (ILI9341), den meine beiden Displays auch verwenden.

Na dann.....ich habe schon viele Displays eingesetzt.
Jedoch teste ich andere, neuere immer vorher mit einem Testsketch, damit ich sicher bin, dass dies auch funktioniert.

Sich auf andere Tutorials zu verlassen, ist immer ein Problem.

Die Sache geht jeder anders an. Dein Posting ist jedoch total offtopic. Ich brauche Unterstützung beim Fehlercode, da ich auch aus der cpp Datei der Library nicht schlauer werde.

Wieso ist das offtopic ?
Wenn du das nicht verstehen willst ist es deine Sache.
Aber systematisch an ein Problem ran gehen, ist wohl nicht so dein Ding.

Ich kann auflösen: Es liegt an diesem einen Bild, das ich einbinden möchte. Die anderen Grafiken funktionieren.

Warum dein Posting OffTopic ist kann dir mal ein Mod erklären. Wenn ich dich nach dem Wetter frag, interessiert mich die Uhrzeit ja schließlich auch nicht.

Hallo,
keine passende Funktion zum Aufruf von 'TFT_eSPI::drawBitmap(int, int....
" ```
V8_Tacho_eSPI

ist nicht im deinem Programm
Grüsse
Bernhard

Was für TFT ist das ?
möglich gibt es andere Bibliotek

Was glaubst du eigentlich, warum dieses Forum so erfolgreich ist.
Sicher nicht nur, weil immer versucht wird einfach nur auf Fragen zu antworten.
Sonder weil auch Probleme hinterfragt werden.
Aber wenn dir das nicht gefällt, musst du hier keine Fragen stellen.

Na ja er ist beleidigt und weg vo fenster

Warum sollte er ?
Weil es nicht nach seiner Nase geht ?

Beide Falsch. Ich war fleißig und es läuft jetzt. Zwar noch nicht mit meinem Wunsch-font, und ich hab noch ein Problem mit dem tft.pushImage Befehl, aber es läuft.

Konkret würde ich gern am zweiten Problem arbeiten. Die Schriftart ist weniger schlimm.

Also ich habe ein JPG mit dem Onlinekonverter zu einer ".c" Datei konvertiert und in einen Tab in meinem Sketch gezogen.
Der Include sieht dazu so aus:
#include "BMW125.c"
Und im Setup (weil es nur ein einziges Mal beim Start gezeigt werden soll:
tft.pushImage(57, 97, 125, 125, "BMW125");

So. Normalerweise sollte hier ein BMW Logo in 125x125 Pixel zu sehen sein. Leider sieht man aber nur Pixelbrei. Hat da jemand ne Ahnung, was los ist?

Das kann man aus der Ferne nur schwer ermessen.

Da scheint mir ein offensichtlicher Fehler im letzten Parameter des pushImage-Aufrufs vorzuliegen:
Da soll man wohl eher nicht den Namen des Bildes, sondern den Namen des Daten-Arrays angeben, in den das Bild konvertiert wurde. Jedenfalls habe ich hier keine Signatur gefunden, die eine Zeichenkette als letzten Parameter erwartet.

Danke für deine Antwort. Also ich habe die includes mal ausgeklammert und das ändert tatsächlich garnichts. finde ich ziemlich seltsam wenn ich ehrlich bin. Woher weiß der compiler denn dann, welche Bilddateien alle da sind?
Ich verstehe auch noch nicht genau, was du mit Datenarray meinst.

Nee, nee - den include für die Bilddatei musst Du schon drinlassen. Da drin steht ja die Bilddaten.
Ich nehme an, dass Du diesen Konverter benutzt hast. Richtig?
Das habe ich auch mal gemacht mit einem Bild namens "testBild.png". Ergebnis (nur der Anfang):

// Generated by   : ImageConverter 565 Online
// Generated from : testBild.png
// Time generated : Tue, 04 May 21 18:40:41 +0200  (Server timezone: CET)
// Image Size     : 125x125 pixels
// Memory usage   : 31250 bytes


#if defined(__AVR__)
    #include <avr/pgmspace.h>
#elif defined(__PIC32MX__)
    #define PROGMEM
#elif defined(__arm__)
    #define PROGMEM
#endif

const unsigned short testBild[15625] PROGMEM={
0xEF1A, 0xEF18, 0xDDF3, 0x6B2A, 0x738C, 0x7BEE, 0x948F, 0xA4F0, 0x6309, 0x6309, 0x7C0E, 0x944D, 0x942C, 0x730A, 0x6B4A, 0x846E,   // 0x0010 (16) pixels

Und der Name, der hinter dem const unsigned short steht ist der gesuchte - hier testBild.
Dann würde - vorausgesetzt das Format, in dem die Daten gespeichert wurden passt zu Deiner Library - der Aufruf so heißen müssen:

tft.pushImage(57, 97, 125, 125, testBild);

Jetzt musst Du nur noch in Deinem BMW125.c nachsehen wie der Name dort ist.

Edit: Ich habe das Testbild mal angehangen. Es ist auch 125x125 und ein Fahrzeug aus Bayern.
testBild.zip (31,1 KB)

Den Konverter, den du verlinkt hast, hab ich benutzt, das stimmt.

So sieht der Code in dem entsprechenden Tab aus:

// Generated by   : ImageConverter 565 Online
 // Generated from : BMW125.jpg
 // Time generated : Mon, 29 Jun 20 21:42:02 +0200  (Server timezone: CET)
 // Image Size     : 125x125 pixels
 // Memory usage   : 31250 bytes
 
 
 #if defined(__AVR__)
     #include <avr/pgmspace.h>
 #elif defined(__PIC32MX__)
     #define PROGMEM
 #elif defined(__arm__)
     #define PROGMEM
#endif

const unsigned short BMW125[15625] PROGMEM={

Und so der Code vor dem Setup:

#include "BMW125.c"

Und dann im Setup:

tft.pushImage(57, 97, 125, 125, "BMW125[15625]");

Das funktioniert leider genauso wenig wie

tft.pushImage(57, 97, 125, 125, "BMW125");

Oder

  tft.pushImage(57, 97, 125, 125, "BMW125.c");

Auch nicht funktionieren will (Ohne die Hochkommata):

  tft.pushImage(57, 97, 125, 125, BMW125);

Da kommt die Fehlermeldung:

/Users/gearx/Documents/Arduino/V8_Tacho_eSPI/V8_Tacho_eSPI.ino: In function 'void setup()':
V8_Tacho_eSPI:151:41: error: no matching function for call to 'pushImage(int, int, int, int, const short unsigned int [15625])'
   tft.pushImage(57, 97, 125, 125, BMW125);
                                                                         ^

Das Problem habe ich auch mit allen anderen Grafiken.

Ohne die Hochkommata ist richtig.

Kannst Du alles vor setup() und die Funktion selbst posten?
Und ein Link auf die tatsächlich verwendete TFT-Library wäre auch hilfreich.

Der Teil vor dem Setup:

//copyright for the 2 screen with eSPI to Kitecraft

/*
In the TFT_ESPI user_setup.h file
be sure to comment out the line for TFT_CS
//#define TFT_CS   21  // Chip select control pin
*/

// call all your required includes
#include <Wire.h>
#include <Adafruit_BME280.h>
#include <Adafruit_Sensor.h>
#include <INA226.h>
#include <SPI.h>
#include <TFT_eSPI.h> // Hardware-specific library
#include "Free_Fonts.h"

// 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 all your constant values you are using
#define ABSZERO               273.15
#define MATKONST_B            3402.26
#define MAXANALOGREAD         1024.0
#define P_SEALEVEL_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

Adafruit_BME280 bme;  // use I2C interface for BOSCH BME280
INA226 ina;           // use I2C Interface for INA226

//define PINS
#define firstScreenCS 3
#define secondScreenCS 4
/*#define TFT_MISO 50
#define TFT_MOSI 51
#define TFT_SCLK 52
#define TFT_DC    2  // Data Command control pin
#define TFT_RST  -1  // Set TFT_RST to -1 if display RESET is connected to ESP32 board RST
*/
TFT_eSPI tft = TFT_eSPI();       // Invoke custom library

/* ------------------------------------------------------------------------------------- */
// NTC temperature calculation 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);
}

/* -------------------------------------------------------------------------------------- */
// 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);
}

Dann kommt hier die Funktion im Setup:

  //Serial.begin(115200);
  
  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();
  
  // Swap the colour byte order when rendering
  tft.setSwapBytes(false);
  tft.setFreeFont(FSS12);
  
  // Set both cs pins HIGH, or 'inactive'
  digitalWrite(firstScreenCS, HIGH);
  digitalWrite(secondScreenCS, HIGH);

  /*
   Update the first screen
   all 'tft.' call must be done
   after setting the cs pin low
  */
  digitalWrite(firstScreenCS, LOW);

  if (!bme.begin(0x76));
  tft.print("Sensor BME280?");
  delay(200);

  ina.begin (0x40);
  // Configure INA226
  ina.configure(INA226_AVERAGES_1, INA226_BUS_CONV_TIME_1100US, INA226_SHUNT_CONV_TIME_1100US, INA226_MODE_SHUNT_BUS_CONT);

  // Calibrate INA226. Rshunt = 0.01 ohm, Max excepted current = 4A
  ina.calibrate(0.01, 4);
  
  //BILDSCHIRM LINKS
  tft.setRotation(2);  
  tft.fillScreen(TFT_BLACK);
  tft.pushImage(57, 97, 125, 125, BMW125);
  digitalWrite(firstScreenCS, HIGH);

Und zu guter Letzt die Library die benutzt wird: GitHub - Bodmer/TFT_eSPI: Arduino and PlatformIO IDE compatible TFT library optimised for the Raspberry Pi Pico (RP2040), STM32, ESP8266 and ESP32 that supports different driver chips

Uii - da machst du ja ein Faß auf mit den zwei Displays.

Eine tft-Instanz für beide wird vermutlich nicht funktionieren. Und was ganz gewiss nicht geht ist die Initialisierung mit beiden CS gleichzeitig aktiv.
Kommentier mal testweise die Benutzung des anderen Displays ("nicht BMW") raus.

Das erklärt aber die Fehlermeldung von oben noch nicht; muss ich später mal nachsehen.