ESP32 QR-Code decoder TFT ST7798 Speicherzuweisung

Hallo zusammen,

leider bin ich nicht zu meinem Thema fündig geworden.
Da ich weder tiefergehnede C++ Kenntnisse habe und dies mein erstes kleines Projekt ist, bin ich mit meinem Latein am Ende. Hier erstmal ein paar hintergrund Infos: Ich möchte zwei unabhängig voneinander funktionierende Codes zusammenführen und verwenden.

Projekt:
Es soll eine Low Cost AR-Brille werden, welche mit einer Kamera einen QR-Code erkennen, decodieren und den Text auf einem Display ausgeben soll. Die Displays werden auf die Brillengläser gespiegelt.

Hardware:

  • ESP32-Cam Ai-Thinker
  • TFT ST7798
    (Arduino 1.8.18)

Code:
Ich habe einen Code, welcher den QR-Code decodieren kann und das Ergebniss im Seriellen Monitor ausgibt. Das funktioniert soweit ganz gut. QR-CodeReader

#include <Arduino.h>
#include <ESP32QRCodeReader.h>

ESP32QRCodeReader reader(CAMERA_MODEL_AI_THINKER);

void onQrCodeTask(void *pvParameters)
{
  struct QRCodeData qrCodeData;

  while (true)
  {
    if (reader.receiveQrCode(&qrCodeData, 100))
    {
      Serial.println("Found QRCode");
      if (qrCodeData.valid)
      {
        Serial.print("Payload: ");
        Serial.println((const char *)qrCodeData.payload);
      }
      else
      {
        Serial.print("Invalid: ");
        Serial.println((const char *)qrCodeData.payload);
      }
    }
    vTaskDelay(100 / portTICK_PERIOD_MS);
  }
}

void setup()
{
  Serial.begin(115200);
  Serial.println();

  reader.setup();

  Serial.println("Setup QRCode Reader");

  reader.beginOnCore(1);

  Serial.println("Begin on Core 1");

  xTaskCreate(onQrCodeTask, "onQrCode", 4 * 1024, NULL, 4, NULL);
}

void loop()
{
  delay(100);
}

Der zweite Code ist ein angepasstes Beispiel aus der TFT_eSPI library, welches auch eigenständig funktioniert:



#include <TFT_eSPI.h>
#include <SPI.h>

#define TDELAY 500

TFT_eSPI tft = TFT_eSPI(); 

void setup() {
  Serial.begin(115200);
  tft.init();
  tft.fillScreen(TFT_BLACK);
  tft.setRotation(1);

}

void loop() {

  delay(TDELAY);

  tft.setCursor(20, 80);

  tft.setTextColor(TFT_WHITE); 
  tft.setTextSize(2);

  tft.println("Hello World!");
  

}

Mein Problem ist, dass sich beim zusammenführen entweder der ESP in einem Bootloop aufhängt oder der Code in der while Schleife des QRCodeReaders befindet, jedoch keinen QR Code erkennt geschweigedenn decodiert.
Ich habe rausfinden können, dass das ganze an einer Speicherzuweisung liegen kann, hierfür fehlt mir jedoch das Know-How....

Kann mir hier jmd weiterhelfen? Falls noch weitere Informationen benötigt werden bitte einfach erfragen, Danke.

Achtung! Alle Arduino-IDE-Versionen vor 1.8.19 sind durch den log4j-Bug angreifbar.
Es ist dringend zu empfehlen auf die 1.8.19 zu updaten.

Gruß Tommy

1 Like

Du solltest mindestens angeben, welche Pins du am ESP32 mit der Cam und dem TFT belegst. Nur so können wir prüfen ob es überhaupt funktionieren kann, da die Cam selbst schon sehr viele Pins belegt.

Vielen Dank, werde ich machen.

Stimmt, danke für den Hinweis.
Die Pins der Camera gehen nicht nach außen, da diese mit einem Flachbandkabel angeschlossen ist.
Der TFT Code funktioniert ja eigenständig, dann sollte die Pin-Belegung doch passen oder?
Ich habe die Pins in der User_Setup.h Datei wie folgt angepasst:

#define TFT_MOSI 12 // In some display driver board, it might be written as "SDA" and so on.
#define TFT_SCLK 14
#define TFT_CS   15  // Chip select control pin
#define TFT_DC   16  // Data Command control pin
#define TFT_RST  2  // Reset pin (could connect to Arduino RESET pin)
//#define TFT_BL   22  // LED back-light

Danke schon mal.

Das stimmt nicht ganz, denn auch die Cam nutzt SPI (soweit mir bekannt). Und andere Pins sind durchaus auch schon belegt. Daher solltest du dir den Schaltplan oder Datenblatt dein Cam anschauen.
Wenn das TFT solo funktioniert, nur weil die Cam nicht angestruert wird.

#define CAMERA_MODEL_AI_THINKER \
  {                             \
    .PWDN_GPIO_NUM = 32,        \
    .RESET_GPIO_NUM = -1,       \
    .XCLK_GPIO_NUM = 0,         \
    .SIOD_GPIO_NUM = 26,        \
    .SIOC_GPIO_NUM = 27,        \
    .Y9_GPIO_NUM = 35,          \
    .Y8_GPIO_NUM = 34,          \
    .Y7_GPIO_NUM = 39,          \
    .Y6_GPIO_NUM = 36,          \
    .Y5_GPIO_NUM = 21,          \
    .Y4_GPIO_NUM = 19,          \
    .Y3_GPIO_NUM = 18,          \
    .Y2_GPIO_NUM = 5,           \
    .VSYNC_GPIO_NUM = 25,       \
    .HREF_GPIO_NUM = 23,        \
    .PCLK_GPIO_NUM = 22,        \
  }

Ok, ich konnte keine Probleme erkennen, sollte eigentlich funktionieren.
Ich habe mal bei Google geschaut und Dies hier gefunden.
Da sollte es funktionieren, evtl. hilft dir das weiter.

Soweit mir bekannt gilt das bei ESP32-Cam-Modulen für den eingebauten SD-Card-Reader. Solange man den nicht benutzt kann es wohl klappen.

richtig, es wird jedoch keine SD Karte verwendet.

Ja, stimmt. Es werden die I2C Pins genutzt. Aber ob wirklich mit I2C k.A.

Hast du dir das Beispiel mal angeschaut ?

Ja, dort werden jedoch andere libraries verwendet.
Kann natürlich jetzt nicht sagen, ob das an meinem Problem etwas ändert, da die Ursache unklar ist.

Aus meiner Sicht ist es doch eine einfache Lösung, wenn etwas nicht funktioniert, dies mit einer anderen Library zu testen. Wenn es dann geht ist doch gut, oder man probiert es dann noch mal mit der ersten Library.
Im übrigen sind beide Libraries sehr ähnlich aufgebaut. Ich habe einige meiner Sketche von der Adafruit auf die TFT_eSPI umgebaut und konnte die meisten Anweisungen direkt übernehmen.

1 Like

Wie bereits erwähnt, vermute ich, dass es etwas mit dem verfügbaren Speicher bzw dessen zuteilung zu tun hat.
Dass je nachdem was ich zuerst aufrufe (tft oder qr code) nur das Erste funktioniert.

Rein von der Logik sind das doch 2 BlackBoxen.
QR Code decodieren (funktioniert), Text auf TFT ausgeben (funktioniert)

  1. Camera erkennt QR Code (ja/nein)
  2. QR Code wird decodiert und in
(const char *)qrCodeData.payload)

gespeichert.
3. Dieser Codeabschnitt somit fertig.
4. Jetzt findet die Kommunikation zum TFT statt,

tft.println((const char *)qrCodeData.payload))
  1. anschließend wieder bei 1. beginnen...

Das klingt so leicht, aber irgendwas habe ich nicht beachtet, meine vermutung eben, dass die libraries irgendwo gleichzeitig zugreifen wollen, was bereits von einem genutzt wird...

Kannst du denn schreieben, wieviel Speicher (Flash und Ram) nach dem Flashen des kompletten Sketch noch frei ist ?

Kann ich machen, sobald ich meine Hardware wieder habe, dann werde ich auch die ardafruit library mal testen, anstelle der eSPI

Das war mein letzter Fehler:

assert failed: heap_caps_free heap_caps.c:381 (heap != NULL && "free() target pointer is outside heap areas")

In ESP32QRCodeReader.h befindet sich folgender Code, wird hier eventuell zu viel Speicher reserviert?

#ifndef ESP32_QR_CODE_ARDUINO_H_
#define ESP32_QR_CODE_ARDUINO_H_

#include "Arduino.h"
#include "ESP32CameraPins.h"
#include "esp_camera.h"

#ifndef QR_CODE_READER_STACK_SIZE
#define QR_CODE_READER_STACK_SIZE 40 * 1024       //Ist das zu viel?? kann ich nicht einschätzen
#endif

#ifndef QR_CODE_READER_TASK_PRIORITY
#define QR_CODE_READER_TASK_PRIORITY 5
#endif

enum QRCodeReaderSetupErr
{
  SETUP_OK,
  SETUP_NO_PSRAM_ERROR,
  SETUP_CAMERA_INIT_ERROR,
};

/* This structure holds the decoded QR-code data */
struct QRCodeData
{
  bool valid;
  int dataType;
  uint8_t payload[1024];
  int payloadLen;
};

class ESP32QRCodeReader
{
private:
  TaskHandle_t qrCodeTaskHandler;
  CameraPins pins;
  framesize_t frameSize;

public:
  camera_config_t cameraConfig;
  QueueHandle_t qrCodeQueue;
  bool begun = false;
  bool debug = false;

  // Constructor
  ESP32QRCodeReader();
  ESP32QRCodeReader(CameraPins pins);
  ESP32QRCodeReader(CameraPins pins, framesize_t frameSize);
  ESP32QRCodeReader(framesize_t frameSize);
  ~ESP32QRCodeReader();

  // Setup camera
  QRCodeReaderSetupErr setup();

  void begin();
  void beginOnCore(BaseType_t core);
  bool receiveQrCode(struct QRCodeData *qrCodeData, long timeoutMs);
  void end();

  void setDebug(bool);
};

#endif // ESP32_QR_CODE_ARDUINO_H_

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.