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
Other
3.8k stars 1.09k forks source link

uncannyeyes - only one eye possible? #805

Closed AloisKlingler closed 4 years ago

AloisKlingler commented 4 years ago

Hi,

I have two ST7735 which I wanted to drive with a esp8266, both displays are working fine.

i tried to adapt the example eps8266_uncannyeyes like the adafruit uncannyeyes is for two displays with the for-loop:

void setup(void) {
  uint8_t e;

  Serial.begin(250000);
  randomSeed(analogRead(A0)); // Seed random() from floating analog input

  for(e=0; e<NUM_EYES; e++) {
    Serial.print("Create display #"); Serial.println(e);
  }

  eye[e].tft.init();
  eye[e].tft.fillScreen(TFT_BLACK);
  eye[e].tft.setRotation(1);

but now the esp8266 crashes with exception28:

Create display #1

--------------- CUT HERE FOR EXCEPTION DECODER ---------------

Exception (28):
epc1=0x4020dd89 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000020 depc=0x00000000

>>>stack>>>

ctx: cont
sp: 3ffffdf0 end: 3fffffc0 offset: 0190
3fffff80:  3fffdad0 3ffe861c 3ffee64c 3ffee6b8  
3fffff90:  3fffdad0 3ffe861c 3ffee624 4020107e  
3fffffa0:  feefeffe 00000000 3ffee678 40204c44  
3fffffb0:  feefeffe feefeffe 3ffe84f8 40100c39  
<<<stack<<<

--------------- CUT HERE FOR EXCEPTION DECODER ---------------

anything I can do here?

Thanks!

Best regards Alois

Bodmer commented 4 years ago

e has been increased in the for loop and this exits with e set to 2, reset e to a sensible number after the for loop!

AloisKlingler commented 4 years ago

Hello @Bodmer ,

thanks. So, the crash was a misplaced bracket. Sorry, was too late for beeing able to see this.

But, the main issue remains: Only one display is in use, it is always the one which is cabled to D8 on the nodeMCU.

I originally tought it is only necessary to initiate the second displays, that's why I placed the loop:

now the loop looks like this:

  for(e=0; e<NUM_EYES; e++) {
    Serial.print("Create display #"); Serial.println(e);
    eye[e].tft.init();
    eye[e].tft.fillScreen(TFT_BLACK);
    eye[e].tft.setRotation(1);
  }

the eye-struct:

struct {
  TFT_eSPI tft; // OLED/eye[e].tft object
  uint8_t     cs;      // Chip select pin
  eyeBlink    blink;   // Current blink state
} eye[] = { // OK to comment out one of these for single-eye display:
  TFT_eSPI(),SELECT_L_PIN,{WINK_L_PIN,NOBLINK},
  TFT_eSPI(),SELECT_R_PIN,{WINK_R_PIN,NOBLINK},
};

I can see on serial console, it entering twice the loop.

SELECT_L_PIN and SELECT_R_PIN are to D6 and D8.

The display which is connected to D8 is flickering, so it shows left and right eye. In function frame(... I placed a serial output for eyeIndex (function draweye(... is called from there), it show me swapping 0 and 1, so it tries to draw both eyes. user_setup.h is adapted according to my displays: #define ST7735_DRIVER / #define TFT_WIDTH 128 / #define TFT_HEIGHT 160 / #define ST7735_GREENTAB nothing else changed. I have also tried to comment-out there the #define TFT_CS PIN_D8 - but it did not change anything (it still compiled and installed, same eye behavior, only one display is used). user_setup_select.h is left default.

Do you have an idea what I am doing wrong?

Thanks!

Best regards Alois

AloisKlingler commented 4 years ago

I do not get why the CS-Pin is not honored.

with the following code both displays are initialized, but still they follow both D8. I have to comment-out the second eye[] struct to have it working now for two displays, but it does not look as nice as if could look, with mirrored stuff and so on...

  for(e=0; e<NUM_EYES; e++) {
    pinMode(eye[e].cs, OUTPUT);
    digitalWrite(eye[e].cs, HIGH);
  }

  for(e=0; e<NUM_EYES; e++) {
    Serial.print("Create display #"); Serial.println(e);
    digitalWrite(eye[e].cs, LOW);
    eye[e].tft.init();
    eye[e].tft.fillScreen(TFT_BLACK);
    eye[e].tft.setRotation(0);
    digitalWrite(eye[e].cs, HIGH);
  }

also I have added in the draweye function the digitalWrite(eye[e].cs, LOW); and digitalWrite(eye[e].cs, HIGH); accordingly.

Any help is appreciated.

Thanks :-)

Best regards Alois

Bodmer commented 4 years ago

When you take control of the chip select in you code you must comment out the define in the setup file otherwise TFT_eSPI will always control that pin.

AloisKlingler commented 4 years ago

I did, but it does not help. Is a special recompile necessary if the header of the lib is changed?

Bodmer commented 4 years ago

Always set the chip select to a high level when a screen update has been completed.

AloisKlingler commented 4 years ago

I do, in drawEye:

void drawEye(
...
  //eye[e].tft.setAddrWindow(319-127, 0, 319, 127);
  eye[e].tft.setAddrWindow(0, 0, 128, 128);

  digitalWrite(eye[e].cs, LOW);                       // Chip select
  digitalWrite(DISPLAY_DC, HIGH);                     // Data mode

  // Now just issue raw 16-bit values for every pixel...

  scleraXsave = scleraX; // Save initial X value to reset on each line
...
        }
      }
      *(pbuffer + pixels++) = p>>8 | p<<8;

      if (pixels >= BUFFER_SIZE) { yield(); eye[e].tft.pushColors((uint8_t*)pbuffer, pixels*2); pixels = 0;}
    }
  }

   if (pixels) { eye[e].tft.pushColors(pbuffer, pixels); pixels = 0;}

  digitalWrite(eye[e].cs, HIGH);                       // Chip unselect

}
Bodmer commented 4 years ago

D8 is the hardware chip select for the port so perhaps the SPI library has a preference to always use that pin. Try allocating the chip selects to pins other than D8. For tests I suggest GPIO D4 and D5.

AloisKlingler commented 4 years ago

sadly this does not work either. it get's better for one eye (rendered correctly now), but not for the other (still flickering as it is rendered for left and right). I tried several combinations of D2, D1 and D6. D8 is always used (as you wrote).

Thanks for your help, very appreciated.

Bodmer commented 4 years ago

Have you commented out TFT_CS completely in the setup?

Run the diagnostic "Read_User_Setup" to check no TFT_CS pin has been allocated.

Bodmer commented 4 years ago

I have added 2 new examples:

Bodmer commented 4 years ago

Info here.

AloisKlingler commented 3 years ago

Hello @Bodmer ,

sorry for late replying - thanks for your instructable project.

With your latest library and the sample 2-eye-script it works. one thing (maybe this information helps somebody): I must not use D8 (altough in User_Setup.h disabled: #define TFT_CS ) as soon as I use D8 either the display on D8 renders both eyes or stays blank. As soon as I use e.g. D1 / D2 it works perfect.

ESP8266 performance: 21fps with 80MHz, 30fps with 160MHz. Used two ST7735_GREENTAB with 160x128 in User_Setup.h

best regards Alois

InvisiKing commented 3 weeks ago

Hi @Bodmer, I am using the ESP32-C3 with the LCD screen connected directly to it, And I want to flip the Eye Eyelid from left to right, how do I go about doing that, the rotation just rotate the eye 90 degrees with each setting, but i need the eye flipped from left to right, as i am using independent ESP32-C3 with the LCD screen for each eye.