Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple spi touch screen + rfid reader #420

Closed
Mechalicious opened this issue Jul 5, 2023 · 11 comments
Closed

Multiple spi touch screen + rfid reader #420

Mechalicious opened this issue Jul 5, 2023 · 11 comments

Comments

@Mechalicious
Copy link

Mechalicious commented Jul 5, 2023

Hi,

I connected both touch screen and rfid reader to an esp32
Both are working separately but i can't make them work together
I might have troubles configuring spi in lgfx
My config:

#pragma once

#define LGFX_USE_V1

#include <LovyanGFX.hpp>
#include <driver/i2c.h>
#include <SPI.h>

#define LANDSCAPE

#ifdef LANDSCAPE
extern const uint16_t screenWidth = 480;
extern const uint16_t screenHeight = 320;
#else
static const uint16_t screenWidth = 320;
static const uint16_t screenHeight = 480;
#endif

class LGFX : public lgfx::LGFX_Device
{
    lgfx::Panel_ILI9488  _panel_instance;
    lgfx::Bus_SPI       _bus_instance;
    lgfx::Light_PWM     _light_instance;
    lgfx::Touch_GT911   _touch_instance;
  public:
    LGFX(void)
    {
      {
        auto cfg = _bus_instance.config();
        cfg.spi_host         = SPI3_HOST;
        cfg.spi_mode         = 0;
        cfg.freq_write       = 40000000;
        cfg.freq_read        = 16000000;
        cfg.spi_3wire        = true;
        cfg.use_lock         = true;
        cfg.dma_channel      = SPI_DMA_CH_AUTO;
        cfg.pin_sclk         = 12;
        cfg.pin_mosi         = 11;
        cfg.pin_miso         = 13;
        cfg.pin_dc           =  16;

        _bus_instance.config(cfg);
        _panel_instance.setBus(&_bus_instance);
      }

      {
        auto cfg = _panel_instance.config();

        cfg.pin_cs           =    15;
        cfg.pin_rst          =    -1;
        cfg.pin_busy         =    -1;

        cfg.panel_width      =   320;
        cfg.panel_height     =   480;
        cfg.offset_x         =     0;
        cfg.offset_y         =     0;
        cfg.offset_rotation  =     0;
        cfg.dummy_read_pixel =     8;
        cfg.dummy_read_bits  =     1;
        cfg.readable         =  true;
        cfg.invert           = false;
        cfg.rgb_order        = false;
        cfg.dlen_16bit       = false;
        cfg.bus_shared       = false;

        _panel_instance.config(cfg);
      }

      {
        auto cfg = _light_instance.config();

        cfg.pin_bl = 21;
        cfg.invert = false;
        cfg.freq   = 44100;
        cfg.pwm_channel = 7;

        _light_instance.config(cfg);
        _panel_instance.setLight(&_light_instance);
      }

      {
        auto cfg = _touch_instance.config();
        cfg.pin_scl  = GPIO_NUM_35;
        cfg.pin_sda  = GPIO_NUM_36;
        cfg.pin_int  = GPIO_NUM_37;
        cfg.i2c_addr = 0x5D;
        cfg.i2c_port = I2C_NUM_0;
        cfg.freq     = 400000;
        cfg.x_min    =  14;
        cfg.x_max    = 310;
        cfg.y_min    =   5;
        cfg.y_max    = 448;
        cfg.offset_rotation = 0;
        cfg.bus_shared = false;

        _touch_instance.config(cfg);
        _panel_instance.setTouch(&_touch_instance);
      }

      setPanel(&_panel_instance);
    }
};

Below, in the initRfid if i uncomment SPI.Begin(); the reader works well but no more screen. The opposite happens if i comment SPI.begin();

void initRfid() {
  //SPI.begin(12, 13, 11, 5);
  rfid.PCD_Init();
   delay(4);
  rfid.PCD_DumpVersionToSerial();
  Serial.println("RFID Initialized");
}

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


// INIT LGFX

  initLvglLgfx();

  // INIT RFID
  //SPI.begin(12, 13, 11, 5);

  initRfid();
  

  Serial.println("Initialized LVGL - LGFX");

  // INIT WIFI
 // initWifi();
  // VIEW

  ESP_LOGI(TAG, "Ready to start a demo. Tap a button on screen. Reset the board with the reset button or Ctrl+T Ctrl+R to pick a new one.");
}



void loop()
{
    lv_timer_handler();
    vTaskDelay(pdMS_TO_TICKS(TASK_SLEEP_PERIOD_MS));

  unsigned long currentMillis = millis();

  unsigned long elapsedMillis = currentMillis - StartOfInterval;
  //Serial.println("elapsedmillis: " + elapsedMillis);
  if (elapsedMillis >= ResetInterval)
  {
    StartOfInterval = currentMillis;
    elapsedMillis = 0;
    rfid.PCD_Reset();
    initRfid();
    Serial.println("Resetting reader");
  }
  
  if (spiState) {
    digitalWrite(15, LOW);
    digitalWrite(5, HIGH);
    rfidCheck();
  } else {
    digitalWrite(15, HIGH);
    digitalWrite(5, LOW);
  }
  spiState = !spiState;
}

How can i configure the spi bus to make them work ?

@lovyan03
Copy link
Owner

lovyan03 commented Jul 6, 2023

you can use SPI2_HOST.

cfg.spi_host = SPI2_HOST;

@Mechalicious
Copy link
Author

Thanks, It's "working" unfortunately i'm having trouble reading data from both spi "at the same time"
Changing the cs pin too fast in the loop doesn't work for both
It does when i put a long wait time between both periphericals but i want to use cs quite simultaneously
Would you know a better way to handle the data ?

@lovyan03
Copy link
Owner

lovyan03 commented Jul 9, 2023

Do not manipulate the CS pin outside of the library without permission.
If you do so, it is only natural that they will stop working.

@Mechalicious
Copy link
Author

How can I use digitalWrite with the lib ? i'm not finding any method or how can I use permissions

@lovyan03
Copy link
Owner

Normally, the SPI bus is released after use; assertion and deassertion of the CS pin is automatic.
All you have to do is to exclusively control multiple SPI devices so that their communication does not occur at the same time.
I don't know how the RFID library is built, but you just need to make sure that it does not communicate with the RFID during the LCD drawing operation.

@Mechalicious
Copy link
Author

How would you stop the communication with the display in lgfx in order to communicate with the RFID module ?

@lovyan03
Copy link
Owner

No communication unless drawing instructions are used.
If you are using LVGL, there should be an instruction to draw to the LCD in the drawing handler you wrote.

@Mechalicious
Copy link
Author

Mechalicious commented Jul 10, 2023

Okay thank you very much

@lovyan03
Copy link
Owner

If you are using startWrite, the SPI bus is occupied until you use endWrite.
In this case, use endWrite before communicating with RFID, and use startWrite after communicating with RFID.

@Mechalicious
Copy link
Author

Mechalicious commented Jul 17, 2023

Sorry, i'm Still having troubles making both work
Would you mind taking a look at what's wrong ?

The loop

void loop()
{
    lv_timer_handler();
    vTaskDelay(pdMS_TO_TICKS(TASK_SLEEP_PERIOD_MS));

  unsigned long currentMillis = millis();

  unsigned long elapsedMillis = currentMillis - StartOfInterval;
  if (elapsedMillis >= ResetInterval && !spiState)
  {
    StartOfInterval = currentMillis;
    elapsedMillis = 0;
    rfid.PCD_Reset();
    initRfid(); 
    Serial.println("Resetting reader");
  }
 
  if (!spiState) {
    rfidCheck();
  }

  unsigned long elapsedMillis2 = currentMillis - RfidStartOfInterval;
// 50ms 
  if (elapsedMillis2 >= ScreenRfidResetInterval) {
    elapsedMillis2 = 0;
    RfidStartOfInterval = currentMillis;
    spiState = !spiState;
  }  
}

The rfidcheck :

void rfidCheck() {
 
 if ( ! rfid.PICC_IsNewCardPresent())
    return;

  // Verify if the NUID has been readed
  if ( ! rfid.PICC_ReadCardSerial())
    return;

  Serial.print(F("PICC type: "));
  MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
  Serial.println(rfid.PICC_GetTypeName(piccType));


  if (rfid.uid.uidByte[0] != nuidPICC[0] || 
    rfid.uid.uidByte[1] != nuidPICC[1] || 
    rfid.uid.uidByte[2] != nuidPICC[2] || 
    rfid.uid.uidByte[3] != nuidPICC[3] ) {
    Serial.println(F("A new card has been detected."));


    // Store NUID into nuidPICC array
    for (byte i = 0; i < 4; i++) {
      nuidPICC[i] = rfid.uid.uidByte[i];
    }
   
    Serial.println(F("The NUID tag is:"));
    Serial.print(F("In hex: "));
    printHex(rfid.uid.uidByte, rfid.uid.size);
    Serial.println();
    Serial.print(F("In dec: "));
    printDec(rfid.uid.uidByte, rfid.uid.size);
    Serial.println();
    playSound();
  }
  else Serial.println(F("Card read previously."));

  rfid.PICC_HaltA();

  rfid.PCD_StopCrypto1();
}

The display flush:

static void display_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) {
  #ifdef DISABLE_FLUSH_DURING_BENCHMARK
  if (disable_flush) {
    lv_disp_flush_ready(disp);
    return;
  }
  #endif 

  if (spiState) {
   uint32_t w = (area->x2 - area->x1 + 1);
    uint32_t h = (area->y2 - area->y1 + 1);
    Serial.println("Calling display flush");
    display.startWrite();
    display.setAddrWindow(area->x1, area->y1, w, h);
    display.writePixels((uint16_t *)&color_p->full, w * h, true);
    display.endWrite();
  }
    lv_disp_flush_ready(disp);

}

@Mechalicious Mechalicious reopened this Aug 2, 2023
@lovyan03
Copy link
Owner

lovyan03 commented Aug 7, 2023

display_flush関数では必ずフラッシュする必要があると思いますが、
spiStateによって勝手に分岐してデータを破棄すると動作がおかしくなりませんか?

これはLGFXのバグではなくてあなたのプログラムの問題だと思います。私はあなたの便利なデバッガーではありません。
LGFXのバグだというのであれば確実に再現できるコンパクトなプログラムを用意して新しいIssueを作ってください。

@lovyan03 lovyan03 closed this as completed Aug 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants