itbrainpower.net
THE ALPHABET PROJECT - professional Arduino, BeagleBone & Raspberry PI shields



Read our last post: Modems and RaspberryPI 5. RaspberryPI OS [Debian 12 bookworm] notes.. Order u-GSM modems.

xyz-mIoT shield ILI9341 240x320 TFT and SD reader (using SPI) interfacing how to

 

About this how to

xyz-mIoT by itbrainpower.net shield shortcuts for integration with ILI9341 2.2 inch 240x320 TFT color display and/or SD card reader, using SPI, no mater what xyz-mIoT PN (with/wo LTE or GSM modem, with/wo sensors) used.

 


 

 

Shields used in this project: xyz-mIoT by itbrainpower.net + ILI9341 2.2 inch 240x320 TFT color display (having integrated TF/SD card reader) / stand alone SD card reader while label versions.

 

 

hardware integration (wiring), in a nut shell

ILI9431 TFT module wiring
ILI9341 2.2inch 240x320 TFT color wiring to xyz-mIoT
xyz-mIoT signals used for wiring ILI9341 2.2inch 240x320 TFT color


In the images up-here, notice:
a. xyz-mIoT shield powering - please refer to xyz-mIoT documentation.
b. 3.3V power supply for the TFT module is provided by xyz-mIoT shield.
c. On ILI9341 TFT module: SPI signals in GREEN, digital signal required for TFT side in BLUE and digital signals for SD/TF side in PURPLE. The 3V3 in top-right and the GNtD are used for powering inputs for both TFT and SD/TF side. The second 3V3 wire is used for TFT backlight powering.
d. If you dont intend to use the SD/TF interface, do not wire the SD card interface wires.

standalone SD/TF reader module wiring
wiring standalone SD-TF reader to xyz-mIoT

Standalone SD/TF card reader software how to

- open any of SD examples from Arduino menu, eg.: Listfiles.ino
- in setup() function, change "if (!SD.begin(4))" with "if (!SD.begin(8))" - remmember.. we wired SD chip select signal to digital port 8
- in order to use the debug functions replace ALL "Serial." with "SerialUSB." - xyz-mIoT have defined SerialUSB as debug port.
- done. Compile, upload and run the SD test code.


ILI9431 TFT module software section


We've used for this test the excellent Adafruit ILI9341 and GFX libraries. You may download them from: here
a. unzip the libraries and install both in Arduino libraries folder. Restart Arduino.
b. Make a folder named "test_ili9341_SD_xyz-mIoT".
c. Copy the code bellow, paste it one new file and save the file as "test_ili9341_SD_xyz-mIoT.ino" in the folder created in previous step. Alternate, you can download from here (right click & save as): test ILI9341 TFT +SD/TF shield with xyz-mIoT shield - Arduino main code

test_ili9341_SD_xyz-mIoT.ino

1/***************************************************
2 *  Test example for white label ILI9341 TFT + SD/TF card reader shield wired to any version of xyz-mIoT by itbrainpower.net v2.09 shield. 
3 *  Wire the boards as bellow:
4 *  
5 *  xyz-mIoT by itbrainpower.net                ILI9341 TFT + SD/TF card shield
6 *  3V3                                         VCC and LED
7 *  GND                                         GND
8 *  D2                                          D/C (TFT_DC)
9 *  D3                                          CS (TFT_CS)
10 *  D4                                          RESET (TFT_RST)
11 *  D8                                          SD_CS
12 *  MISO                                        SDO(TFT MISO) and SD_MISO
13 *  MOSI                                        SDI(TFT MOSI) and SD_MOSI
14 *  SCK                                         SCK(TFT SCK) and SD_SCK
15 *  
16 *  Examples based on Adafruit ILI9341 and GFX libraries. We've made just some surface 
17 *  adaptation in order to fix the debug port for xyz-mIoT shields and to add SD support.
18 *  
19 *  itbrainpower.net invests significant time and resources providing those how to and in design phase of our IoT products.
20 *  Support us by purchasing our worldwide best LTE CATM1, NB IoT, 2G, 3G and 4G shields:
21 *  xyz-mIoT by itbrainpower.net https://itbrainpower.net/order#xyz-mIoT
22 *  u-GSM by itbrainpower.net https://itbrainpower.net/order#u-GSM
23 *  
24 *  
25 *  We recomend you to use ILI9341 Breakout and Shield from Adafruit http://www.adafruit.com/products/1651
26 *  
27 *  
28 *  Dragos Iosub, Bucharest 2019
29 */
30/***************************************************
31  This is our GFX example for the Adafruit ILI9341 Breakout and Shield
32  ----> http://www.adafruit.com/products/1651
33
34  Check out the links above for our tutorials and wiring diagrams
35  These displays use SPI to communicate, 4 or 5 pins are required to
36  interface (RST is optional)
37  Adafruit invests time and resources providing this open source code,
38  please support Adafruit and open-source hardware by purchasing
39  products from Adafruit!
40
41  Written by Limor Fried/Ladyada for Adafruit Industries.
42  MIT license, all text above must be included in any redistribution
43 ****************************************************/
44
45
46#include "SPI.h"
47#include "Adafruit_GFX.h"
48#include "Adafruit_ILI9341.h"
49
50#include "SD.h"
51
52File root;
53
54#define TFT_DC 2
55#define TFT_CS 3
56#define TFT_RST 4
57
58#define SD_CS 8
59
60
61
62String dataString = "";
63unsigned long cycle = 0;
64
65Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
66
67void setup() {
68  delay(8000);
69  SerialUSB.begin(9600);
70
71  pinMode(SD_CS, OUTPUT);
72  digitalWrite(SD_CS, HIGH);
73
74  SerialUSB.print("Initializing SD card...");
75
76  if (!SD.begin(SD_CS)) {
77    SerialUSB.println("initialization failed!");
78  } else
79      SerialUSB.println("initialization done.");
80
81  SerialUSB.println("ILI9341 Test!"); 
82 
83  tft.begin();
84
85  // read diagnostics (optional but can help debug problems)
86  uint8_t x = tft.readcommand8(ILI9341_RDMODE);
87  SerialUSB.print("Display Power Mode: 0x"); SerialUSB.println(x, HEX);
88  x = tft.readcommand8(ILI9341_RDMADCTL);
89  SerialUSB.print("MADCTL Mode: 0x"); SerialUSB.println(x, HEX);
90  x = tft.readcommand8(ILI9341_RDPIXFMT);
91  SerialUSB.print("Pixel Format: 0x"); SerialUSB.println(x, HEX);
92  x = tft.readcommand8(ILI9341_RDIMGFMT);
93  SerialUSB.print("Image Format: 0x"); SerialUSB.println(x, HEX);
94  x = tft.readcommand8(ILI9341_RDSELFDIAG);
95  SerialUSB.print("Self Diagnostic: 0x"); SerialUSB.println(x, HEX); 
96  
97  SerialUSB.println(F("Benchmark                Time (microseconds)"));
98  delay(10);
99  SerialUSB.print(F("Screen fill              "));
100  SerialUSB.println(testFillScreen());
101  delay(500);
102
103  SerialUSB.print(F("Text                     "));
104  SerialUSB.println(testText());
105  delay(3000);
106
107  SerialUSB.print(F("Lines                    "));
108  SerialUSB.println(testLines(ILI9341_CYAN));
109  delay(500);
110
111  SerialUSB.print(F("Horiz/Vert Lines         "));
112  SerialUSB.println(testFastLines(ILI9341_RED, ILI9341_BLUE));
113  delay(500);
114
115  SerialUSB.print(F("Rectangles (outline)     "));
116  SerialUSB.println(testRects(ILI9341_GREEN));
117  delay(500);
118
119  SerialUSB.print(F("Rectangles (filled)      "));
120  SerialUSB.println(testFilledRects(ILI9341_YELLOW, ILI9341_MAGENTA));
121  delay(500);
122
123  SerialUSB.print(F("Circles (filled)         "));
124  SerialUSB.println(testFilledCircles(10, ILI9341_MAGENTA));
125
126  SerialUSB.print(F("Circles (outline)        "));
127  SerialUSB.println(testCircles(10, ILI9341_WHITE));
128  delay(500);
129
130  SerialUSB.print(F("Triangles (outline)      "));
131  SerialUSB.println(testTriangles());
132  delay(500);
133
134  SerialUSB.print(F("Triangles (filled)       "));
135  SerialUSB.println(testFilledTriangles());
136  delay(500);
137
138  SerialUSB.print(F("Rounded rects (outline)  "));
139  SerialUSB.println(testRoundRects());
140  delay(500);
141
142  SerialUSB.print(F("Rounded rects (filled)   "));
143  SerialUSB.println(testFilledRoundRects());
144  delay(500);
145
146  SerialUSB.println(F("Done!"));
147
148}
149
150
151void loop(void) {
152  for(uint8_t rotation=0; rotation<4; rotation++) {
153    tft.setRotation(rotation);
154    testText();
155    //delay(5000);
156    
157    SerialUSB.println("Test SD");
158
159    root = SD.open("/");
160  
161    printDirectory(root, 0);
162  
163    SerialUSB.println("done!");
164    delay(250);
165
166    
167
168    //bellow write log
169    dataString = String(cycle++);
170    dataString += " >> whatever we will log here <<";
171    writeToLog("datalog.txt");
172    delay(50);
173    //dump log
174    SerialUSB.println("try read the log file");
175    dumpLog("datalog.txt");
176    
177  }
178}
179
180
181void writeToLog(char* fileName){
182  File dataFile = SD.open(fileName, FILE_WRITE);
183  if (dataFile) {
184    dataFile.println(dataString);
185    dataFile.close();
186
187    SerialUSB.println(dataString);
188  }
189  else{
190    Serial.print("error opening ");
191    Serial.println(fileName);
192  }
193}
194
195void dumpLog(char* fileName){
196  File dataFile = SD.open(fileName);
197
198  if (dataFile) {
199    while (dataFile.available()) {
200      SerialUSB.write(dataFile.read());
201    }
202    dataFile.close();
203  }
204  else{
205    Serial.print("error opening ");
206    Serial.println(fileName);
207  }
208
209
210void printDirectory(File dir, int numTabs) {
211  while (true) {
212
213    File entry =  dir.openNextFile();
214    if (! entry) {
215      // no more files
216      break;
217    }
218    for (uint8_t i = 0; i < numTabs; i++) {
219      SerialUSB.print('\t');
220    }
221    SerialUSB.print(entry.name());
222    if (entry.isDirectory()) {
223      SerialUSB.println("/");
224      printDirectory(entry, numTabs + 1);
225    } else {
226      // files have sizes, directories do not
227      SerialUSB.print("\t\t");
228      SerialUSB.println(entry.size(), DEC);
229    }
230    entry.close();
231  }
232}
233
234
235unsigned long testFillScreen() {
236  unsigned long start = micros();
237  tft.fillScreen(ILI9341_BLACK);
238  yield();
239  tft.fillScreen(ILI9341_RED);
240  yield();
241  tft.fillScreen(ILI9341_GREEN);
242  yield();
243  tft.fillScreen(ILI9341_BLUE);
244  yield();
245  tft.fillScreen(ILI9341_BLACK);
246  yield();
247  return micros() - start;
248}
249
250unsigned long testText() {
251  tft.fillScreen(ILI9341_BLACK);
252  unsigned long start = micros();
253  tft.setCursor(0, 0);
254  tft.setTextColor(ILI9341_WHITE);  tft.setTextSize(1);
255  tft.println("Hello World!");
256  tft.setTextColor(ILI9341_YELLOW); tft.setTextSize(2);
257  tft.println(1234.56);
258  tft.setTextColor(ILI9341_RED);    tft.setTextSize(3);
259  tft.println(0xDEADBEEF, HEX);
260  tft.println();
261  tft.setTextColor(ILI9341_GREEN);
262  tft.setTextSize(5);
263  tft.println("Groop");
264  tft.setTextSize(2);
265  tft.println("I implore thee,");
266  tft.setTextSize(1);
267  tft.println("my foonting turlingdromes.");
268  tft.println("And hooptiously drangle me");
269  tft.println("with crinkly bindlewurdles,");
270  tft.println("Or I will rend thee");
271  tft.println("in the gobberwarts");
272  tft.println("with my blurglecruncheon,");
273  tft.println("see if I don't!");
274  return micros() - start;
275}
276
277unsigned long testLines(uint16_t color) {
278  unsigned long start, t;
279  int           x1, y1, x2, y2,
280                w = tft.width(),
281                h = tft.height();
282
283  tft.fillScreen(ILI9341_BLACK);
284  yield();
285  
286  x1 = y1 = 0;
287  y2    = h - 1;
288  start = micros();
289  for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
290  x2    = w - 1;
291  for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
292  t     = micros() - start; // fillScreen doesn't count against timing
293
294  yield();
295  tft.fillScreen(ILI9341_BLACK);
296  yield();
297
298  x1    = w - 1;
299  y1    = 0;
300  y2    = h - 1;
301  start = micros();
302  for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
303  x2    = 0;
304  for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
305  t    += micros() - start;
306
307  yield();
308  tft.fillScreen(ILI9341_BLACK);
309  yield();
310
311  x1    = 0;
312  y1    = h - 1;
313  y2    = 0;
314  start = micros();
315  for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
316  x2    = w - 1;
317  for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
318  t    += micros() - start;
319
320  yield();
321  tft.fillScreen(ILI9341_BLACK);
322  yield();
323
324  x1    = w - 1;
325  y1    = h - 1;
326  y2    = 0;
327  start = micros();
328  for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
329  x2    = 0;
330  for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
331
332  yield();
333  return micros() - start;
334}
335
336unsigned long testFastLines(uint16_t color1, uint16_t color2) {
337  unsigned long start;
338  int           x, y, w = tft.width(), h = tft.height();
339
340  tft.fillScreen(ILI9341_BLACK);
341  start = micros();
342  for(y=0; y<h; y+=5) tft.drawFastHLine(0, y, w, color1);
343  for(x=0; x<w; x+=5) tft.drawFastVLine(x, 0, h, color2);
344
345  return micros() - start;
346}
347
348unsigned long testRects(uint16_t color) {
349  unsigned long start;
350  int           n, i, i2,
351                cx = tft.width()  / 2,
352                cy = tft.height() / 2;
353
354  tft.fillScreen(ILI9341_BLACK);
355  n     = min(tft.width(), tft.height());
356  start = micros();
357  for(i=2; i<n; i+=6) {
358    i2 = i / 2;
359    tft.drawRect(cx-i2, cy-i2, i, i, color);
360  }
361
362  return micros() - start;
363}
364
365unsigned long testFilledRects(uint16_t color1, uint16_t color2) {
366  unsigned long start, t = 0;
367  int           n, i, i2,
368                cx = tft.width()  / 2 - 1,
369                cy = tft.height() / 2 - 1;
370
371  tft.fillScreen(ILI9341_BLACK);
372  n = min(tft.width(), tft.height());
373  for(i=n; i>0; i-=6) {
374    i2    = i / 2;
375    start = micros();
376    tft.fillRect(cx-i2, cy-i2, i, i, color1);
377    t    += micros() - start;
378    // Outlines are not included in timing results
379    tft.drawRect(cx-i2, cy-i2, i, i, color2);
380    yield();
381  }
382
383  return t;
384}
385
386unsigned long testFilledCircles(uint8_t radius, uint16_t color) {
387  unsigned long start;
388  int x, y, w = tft.width(), h = tft.height(), r2 = radius * 2;
389
390  tft.fillScreen(ILI9341_BLACK);
391  start = micros();
392  for(x=radius; x<w; x+=r2) {
393    for(y=radius; y<h; y+=r2) {
394      tft.fillCircle(x, y, radius, color);
395    }
396  }
397
398  return micros() - start;
399}
400
401unsigned long testCircles(uint8_t radius, uint16_t color) {
402  unsigned long start;
403  int           x, y, r2 = radius * 2,
404                w = tft.width()  + radius,
405                h = tft.height() + radius;
406
407  // Screen is not cleared for this one -- this is
408  // intentional and does not affect the reported time.
409  start = micros();
410  for(x=0; x<w; x+=r2) {
411    for(y=0; y<h; y+=r2) {
412      tft.drawCircle(x, y, radius, color);
413    }
414  }
415
416  return micros() - start;
417}
418
419unsigned long testTriangles() {
420  unsigned long start;
421  int           n, i, cx = tft.width()  / 2 - 1,
422                      cy = tft.height() / 2 - 1;
423
424  tft.fillScreen(ILI9341_BLACK);
425  n     = min(cx, cy);
426  start = micros();
427  for(i=0; i<n; i+=5) {
428    tft.drawTriangle(
429      cx    , cy - i, // peak
430      cx - i, cy + i, // bottom left
431      cx + i, cy + i, // bottom right
432      tft.color565(i, i, i));
433  }
434
435  return micros() - start;
436}
437
438unsigned long testFilledTriangles() {
439  unsigned long start, t = 0;
440  int           i, cx = tft.width()  / 2 - 1,
441                   cy = tft.height() / 2 - 1;
442
443  tft.fillScreen(ILI9341_BLACK);
444  start = micros();
445  for(i=min(cx,cy); i>10; i-=5) {
446    start = micros();
447    tft.fillTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
448      tft.color565(0, i*10, i*10));
449    t += micros() - start;
450    tft.drawTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
451      tft.color565(i*10, i*10, 0));
452    yield();
453  }
454
455  return t;
456}
457
458unsigned long testRoundRects() {
459  unsigned long start;
460  int           w, i, i2,
461                cx = tft.width()  / 2 - 1,
462                cy = tft.height() / 2 - 1;
463
464  tft.fillScreen(ILI9341_BLACK);
465  w     = min(tft.width(), tft.height());
466  start = micros();
467  for(i=0; i<w; i+=6) {
468    i2 = i / 2;
469    tft.drawRoundRect(cx-i2, cy-i2, i, i, i/8, tft.color565(i, 0, 0));
470  }
471
472  return micros() - start;
473}
474
475unsigned long testFilledRoundRects() {
476  unsigned long start;
477  int           i, i2,
478                cx = tft.width()  / 2 - 1,
479                cy = tft.height() / 2 - 1;
480
481  tft.fillScreen(ILI9341_BLACK);
482  start = micros();
483  for(i=min(tft.width(), tft.height()); i>20; i-=6) {
484    i2 = i / 2;
485    tft.fillRoundRect(cx-i2, cy-i2, i, i, i/8, tft.color565(0, i, 0));
486    yield();
487  }
488
489  return micros() - start;
490}
491



Hint:
- for other ILI9341 examples, do not forget to update the wiring pinout, the "tft" variable instantiating and to replace ALL "Serial." with "SerialUSB.".



Additional resources:

- xyz-mIoT shield pinout, port map and more pdf format or, in png format
- xyz-mIoT shield - block schematics rev 1.1



TUTORIAL PROVIDED WITHOUT ANY WARRANTY!!! USE IT AT YOUR OWN RISK!!!!

 

 

 

 

Original how to written by Dragos Iosub & itbrainpower.net team

 

 

 

 

document version 1.01 / 2019-10-12 © R&D Software Solutions srl