Adafruit 2.8 touchscreen breakout (2090) and Argon

Hey all!

So I’ve scoured the relevant threads here, and I have looked at the code over at https://github.com/rickkas7/Adafruit_ILI9341_RK . I feel like a rollup thread is helpful for anyone else who is doing this.

NOTE: There is still an issue with speed, and I have not yet added the capacitive touchscreen test code yet. If anyone has simple examples of that, I would be THRILLED :slight_smile:

Make sure:

  • Argon registered, operating fine
  • VS Code and particle workbench extensions up and running
  • Adafruit_ILI9341_RK, Adafruit_GFX_RK and Adafruit_STMPE610_RK loaded

The TFT is wired as follows…

(TFT -> Argon)

  • GND -> GND
  • Vin -> 3v
  • CLK -> SCK
  • M1S0 -> M1
  • M0S1 -> M0
  • CS -> D5
  • D/C -> D4

With that done, the following code will work fine.

/*
 * Project brain_main
 * Description:
 * Author:
 * Date:
 */

#include <Particle.h>
#include <SPI.h>
#include <Adafruit_GFX_RK.h>
#include <Adafruit_ILI9341_RK.h>
#include <Adafruit_STMPE610_RK.h>

#define TFT_DC   D5
#define TFT_CS   D4
#define STMPE_CS D3
#define SD_CS    D2

Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);

// setup() runs once, when the device is first turned on.
void setup() {
  // Put initialization like pinMode and begin functions here.
  delay(10);
  Serial.println("HI!");

  Serial.println("TFT BEGIN()");
  tft.begin();

  Serial.println("TFT DIAG()");
  // read diagnostics (optional but can help debug problems)
  uint8_t x = tft.readcommand8(ILI9341_RDMODE);
  Serial.print("Display Power Mode: 0x"); Serial.println(x, HEX);
  x = tft.readcommand8(ILI9341_RDMADCTL);
  Serial.print("MADCTL Mode: 0x"); Serial.println(x, HEX);
  x = tft.readcommand8(ILI9341_RDPIXFMT);
  Serial.print("Pixel Format: 0x"); Serial.println(x, HEX);
  x = tft.readcommand8(ILI9341_RDIMGFMT);
  Serial.print("Image Format: 0x"); Serial.println(x, HEX);
  x = tft.readcommand8(ILI9341_RDSELFDIAG);
  Serial.print("Self Diagnostic: 0x"); Serial.println(x, HEX); 

  Serial.println(F("Benchmark                Time (microseconds)"));
  delay(10);
  Serial.print(F("Screen fill              "));
  Serial.println(testFillScreen());
  delay(500);

  Serial.print(F("Rectangles (filled)      "));
  Serial.println(testFilledRects(ILI9341_YELLOW, ILI9341_MAGENTA));
  delay(500);
}

// loop() runs over and over again, as quickly as it can execute.
void loop() {
  // The core of your code will likely live here.

} 

unsigned long testFillScreen() {
  unsigned long start = micros();
  tft.fillScreen(ILI9341_BLACK);
  yield();
  tft.fillScreen(ILI9341_RED);
  yield();
  tft.fillScreen(ILI9341_GREEN);
  yield();
  tft.fillScreen(ILI9341_BLUE);
  yield();
  tft.fillScreen(ILI9341_BLACK);
  yield();
  return micros() - start;
}

unsigned long testFilledRects(uint16_t color1, uint16_t color2) {
  unsigned long start, t = 0;
  int           n, i, i2,
                cx = tft.width()  / 2 - 1,
                cy = tft.height() / 2 - 1;

  tft.fillScreen(ILI9341_BLACK);
  n = min(tft.width(), tft.height());
  for(i=n; i>0; i-=6) {
    i2    = i / 2;
    start = micros();
    tft.fillRect(cx-i2, cy-i2, i, i, color1);
    t    += micros() - start;
    // Outlines are not included in timing results
    tft.drawRect(cx-i2, cy-i2, i, i, color2);
    yield();
  }

  return t;
}

@samuraiken Thank you for publishing this. I haven’t had the time to explore this further but I can tell you that the touch screen controller cannot run at a clock speed faster than 1MHz and hence it sets the maximum speed that the SPI bus operates at.

My next step was to remove the touch controller object creation and initiation and jackup the speed for the ILI9341 to 16MHz - the conditional compile statements in SPITFT.cpp can be a bit tricky to follow.:wink:

Unless you are using SPI transactions which allow for differing SPI speeds for the individual slaves.

However, as I understand the board in question the touch sensor is actually connected via I2C and hence won't interfere with the screen's SPI anyway.

How did you manage to update the speed? DO you you have a simple code snippet? I'd like to add it to the example.

Adafruit_STMPE610 ts = Adafruit_STMPE610(STMPE_CS);

You are right there are various comms option available for the STMPE610 but this one uses SPI, same bus as display and SD card, obviously with its own chip select line.

You will know that the Adafruit code has been written to support many MCUs and is criss-crossed with conditional compile statements and define and undefine.

I agree that it would be possible to re-implement the different slave SPI devices to use different speeds. This one will not run faster than 1MHz and because of the way the .begin() method is coded and uses the Adafruit_SPITFT function it impacts all the slave devices.

I intend to do a strip down of the code for Gen3 devices - just haven’t had the time yet!

I have probably answered your question in reply to @ScruffR. I will post some code back when I get time to do this. You need to be using Workbench if you aren’t already.

Could it be that we are looking at a different displays?
The Adafruit item with the ID 2090 (which the OP referenced in the topic title) I found does not appear to have a dedicated CS for the touch screen (or I just can’t see it on the image nor the pinout docs)


Adafruit’s docs page also only seems to link to a library only using I2C and explicitly states
https://www.adafruit.com/product/2090

Thanks for taking the time to post that. Correct, I believe this screen uses the I2C bus for touch communication.

Thanks, I look forward to it! I didn’t see the answer in a way I recognized sorry!

I stand corrected - I have the 3.5” touch screen featherwing product:3651 which apart from screen size is he same as the 2.4” version.

Hey all, I am using the Particle Argon and I am quite a rookie when it comes to programming.

My apologies when this is a little bit off-topic but I am struggling with the slow Adafruit ILI9341 and GFX libraries and am in search of a faster solution. Would you be able to tell me about a faster solution for this? I have a 2.2" tft screen without touch functionalities.

Another question I had is: what is the difference between the Adafruit_ILI9341 and the Adafruit_ILI9341_RK?

@thomasvh, the RK version works with the latest version of the Adafruit_GFX library while the non-RK version works with the mfGFX library.

I suggest the RK version, however the display is still very, very slow. So much so that I am considering a separate small Arduino jsut for the display so I can use the much faster 8bit interface and offload the problem while preserving my data I/O.

The ILI9341 can be made much faster. There are two problems that dramatically slow it down:

  • On Gen 3, digitalWrite() is significantly slower than on Gen 2. Using pinSetFast() and pinResetFast() in the Adafruit_SPITFT code in Adafruit_GFX will significantly improve performance as this is done frequently both for SPI CS and the display DC line.
  • On Particle devices, Adafruit_SPITFT is not configured for SPI DMA. Enabling DMA would also significantly improve performance.

I’m not sure when an updated library will be available, but it’s a known issue.

I may fork and take a shot at that.

1 Like

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