Close

2024-05-5: encountering coding difficulties

A project log for M8B 2.0

Magic 8 Ball + User Guide 2.0

nananisNananis 05/28/2024 at 14:290 Comments

Over the course of the last two weeks I struggled a lot with my arduino code.

First of all, arduino codes for an ESP32 + TFT screen or codes for ESP32 + gyroscope are practically inexistent. Most of them are designed for arduino uno.

Finding inspiration was hard...

First of all, I decided to use and old code which had been created so that when someone shakes the gyroscope, text appears on a 08x02 screen. It worked in that scenario so I thought that if I changed it for my RB-TFT1.8 screen, it would also work in this case.

What I didn't realise is that our images we wanted to display (instead of text like last semester), would have to be stored in the SD card of our screen... under bmp format.

So I changed all the images size on gimp so that they would fit perfeclty on our screen and converted them to the bmp format. I also learned that in order for our images to be displayed I would have to express their path in my code (eg: D:\Images\1.bmp)

Here are a few examples of codes I tried to modify for them to be adapted for my screen and ESP32:

Code for our screen + arduino Uno

// include TFT and SPI libraries
#include <TFT.h>  
#include <SPI.h>

// pin definition for Arduino UNO
#define cs   10
#define dc   9
#define rst  8


// create an instance of the library
TFT TFTscreen = TFT(cs, dc, rst);

void setup() {

  //initialize the library
  TFTscreen.begin();

  // clear the screen with a black background
  TFTscreen.background(0, 0, 0);
  //set the text size
  TFTscreen.setTextSize(2);
}

void loop() {

  //generate a random color
  int redRandom = random(0, 255);
  int greenRandom = random (0, 255);
  int blueRandom = random (0, 255);
  
  // set a random font color
  TFTscreen.stroke(redRandom, greenRandom, blueRandom);
  
  // print Hello, World! in the middle of the screen
  TFTscreen.text("Hello, World!", 6, 57);
  
  // wait 200 miliseconds until change to next color
  delay(200);
}"

 I tried adapting it for my ESP32:

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


TFT_eSPI tft = TFT_eSPI();

void setup() {
  
  tft.init();
  
  
  tft.fillScreen(TFT_BLACK);
  
  
  tft.setTextSize(2);
}

void loop() {
  
  uint16_t color = tft.color565(random(0, 255), random(0, 255), random(0, 255));

  
  tft.setTextColor(color);
  
  
  tft.setCursor(20, 57);  // Adjust the cursor position as needed
  tft.print("Hello, World!");

  delay(200);
}

It didn't work and after multiple attempts I just gave up, and tried to see if it would work better if I tried to insert the gyroscope as well. And after multiple changes, different codes mashed together and altering the code each time I got an error message I finally got this code which didn't displayed any error messages when I clocked in the tick button:

#include <Wire.h>
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <SPI.h>
#include <SD.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>


Adafruit_MPU6050 mpu;
const float shakeThreshold = 2.0; 


#define TFT_CS     15
#define TFT_RST    2
#define TFT_DC     17
#define SD_CS      26
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);


const char* bmpFiles[] = {
  "1.bmp",
  "2.bmp",
  "3.bmp",
  "4.bmp",
  "5.bmp",
  "6.bmp",
  "7.bmp",
  "8.bmp",
  "9.bmp",
  "10.bmp",
  "11.bmp",
  "12.bmp"
  
};
const int bmpFileCount = sizeof(bmpFiles) / sizeof(bmpFiles[0]);

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

  
  if (!mpu.begin()) {
    Serial.println("Could not find a valid MPU6050 sensor, check wiring!");
    while (1);
  }
  Serial.println("MPU6050 Found!");
  mpu.setAccelerometerRange(MPU6050_RANGE_2_G);
  mpu.setGyroRange(MPU6050_RANGE_250_DEG);
  mpu.setFilterBandwidth(MPU6050_BAND_5_HZ);

  
  tft.initR(INITR_BLACKTAB);  
  tft.fillScreen(ST7735_BLACK);

  
  if (!SD.begin(SD_CS)) {
    Serial.println("SD card initialization failed!");
    return;
  }
  Serial.println("SD card initialized.");
}


uint32_t read32(File &f) {
  uint32_t result;
  ((uint8_t *)&result)[0] = f.read(); 
  ((uint8_t *)&result)[1] = f.read();
  ((uint8_t *)&result)[2] = f.read();
  ((uint8_t *)&result)[3] = f.read(); 
  return result;
}

void loop() {
  sensors_event_t a, g, temp;
  mpu.getEvent(&a, &g, &temp);

  float magnitude = sqrt(a.acceleration.x * a.acceleration.x + a.acceleration.y * a.acceleration.y + a.acceleration.z * a.acceleration.z);

  if (magnitude > shakeThreshold) {
    Serial.println("Shake detected!");
    int randomIndex = random(0, bmpFileCount);
    displayBMP(bmpFiles[randomIndex], 0, 0);
    delay(1000); 
  }

  delay(100); 
}

void displayBMP(const char *filename, int16_t x, int16_t y) {
  File bmpFile;
  int bmpWidth, bmpHeight;
  uint8_t bmpDepth;
  uint32_t bmpImageoffset;
  uint32_t rowSize;
  uint8_t sdbuffer[3 * 20]; 
  uint8_t buffidx = sizeof(sdbuffer);
  boolean goodBmp = false;
  boolean flip = true;
  int w, h, row, col;
  uint8_t r, g, b;
  uint32_t pos = 0, startTime = millis();

  if ((x >= tft.width()) || (y >= tft.height())) return;

  Serial.println();
  Serial.print(F("Loading image '"));
  Serial.print(filename);
  Serial.println('\'');

  if ((bmpFile = SD.open(filename)) == NULL) {
    Serial.print(F("File not found"));
    return;
  }

  if (bmpFile.read() == 'B' && bmpFile.read() == 'M') {
    Serial.print(F("File size: ")); Serial.println(read32(bmpFile));
    (void)read32(bmpFile); 
    bmpImageoffset = read32(bmpFile); 
    Serial.print(F("Image Offset: ")); Serial.println(bmpImageoffset, DEC);
    
    Serial.print(F("Header size: ")); Serial.println(read32(bmpFile));
    bmpWidth  = read32(bmpFile);
    bmpHeight = read32(bmpFile);
    if (bmpFile.read() == 1) { 
      bmpDepth = bmpFile.read(); 
      Serial.print(F("Bit Depth: ")); Serial.println(bmpDepth);
      if (bmpDepth == 24 && bmpFile.read() == 0) { 
        goodBmp = true;
        Serial.print(F("Image size: "));
        Serial.print(bmpWidth);
        Serial.print('x');
        Serial.println(bmpHeight);

        rowSize = (bmpWidth * 3 + 3) & ~3; 
        if (bmpHeight < 0) { 
          bmpHeight = -bmpHeight;
          flip      = false;
        }

        w = bmpWidth;
        h = bmpHeight;
        if ((x + w - 1) >= tft.width())  w = tft.width()  - x;
        if ((y + h - 1) >= tft.height()) h = tft.height() - y;

        tft.setAddrWindow(x, y, x + w - 1, y + h - 1);

        for (row = 0; row < h; row++) { 
          
          if (flip) 
            pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize;
          else     
            pos = bmpImageoffset + row * rowSize;
          if (bmpFile.position() != pos) { 
            bmpFile.seek(pos);
            buffidx = sizeof(sdbuffer); 
          }
          for (col = 0; col < w; col++) { 
            // Time to read more pixel data?
            if (buffidx >= sizeof(sdbuffer)) { // Indeed
              bmpFile.read(sdbuffer, sizeof(sdbuffer));
              buffidx = 0; 
            }
            
            b = sdbuffer[buffidx++];
            g = sdbuffer[buffidx++];
            r = sdbuffer[buffidx++];
            tft.pushColor(tft.color565(r, g, b));
          } 
        } 
        Serial.println(F("Loaded image"));
      } 
    } 
  } 

  bmpFile.close();
}

 But my problem is that when I try to upload it the the ESP32, I get this error message: 

A fatal error occurred: Packet content transfer stopped (received 8 bytes).

I tried to check my ESP32 pins, I tried to check my wirering, I changed ESP32 and I even changed cables. But this error message keeps appearing.

Discussions