1
+ /* **************************************************
2
+ This is our touchscreen painting example for the Adafruit TFT FeatherWing
3
+ ----> http://www.adafruit.com/products/3315
4
+
5
+ Check out the links above for our tutorials and wiring diagrams
6
+
7
+ Adafruit invests time and resources providing this open source code,
8
+ please support Adafruit and open-source hardware by purchasing
9
+ products from Adafruit!
10
+
11
+ Written by Limor Fried/Ladyada for Adafruit Industries.
12
+ MIT license, all text above must be included in any redistribution
13
+ ****************************************************/
14
+
15
+ #include < SPI.h>
16
+ #include < Wire.h> // this is needed even tho we aren't using it
17
+
18
+ #include < Adafruit_GFX.h> // Core graphics library
19
+ #include < Adafruit_ILI9341.h> // Hardware-specific library
20
+ #include < SD.h>
21
+ #include < Adafruit_STMPE610.h>
22
+
23
+ #ifdef ESP8266
24
+ #define STMPE_CS 16
25
+ #define TFT_CS 0
26
+ #define TFT_DC 15
27
+ #define SD_CS 2
28
+ #endif
29
+ #ifdef __AVR_ATmega32U4__
30
+ #define STMPE_CS 6
31
+ #define TFT_CS 9
32
+ #define TFT_DC 10
33
+ #define SD_CS 5
34
+ #endif
35
+ #ifdef ARDUINO_SAMD_FEATHER_M0
36
+ #define STMPE_CS 6
37
+ #define TFT_CS 9
38
+ #define TFT_DC 10
39
+ #define SD_CS 5
40
+ #endif
41
+ #ifdef TEENSYDUINO
42
+ #define TFT_DC 10
43
+ #define TFT_CS 4
44
+ #define STMPE_CS 3
45
+ #define SD_CS 8
46
+ #endif
47
+ #ifdef ARDUINO_STM32_FEATHER
48
+ #define TFT_DC PB4
49
+ #define TFT_CS PA15
50
+ #define STMPE_CS PC7
51
+ #define SD_CS PC5
52
+ #endif
53
+
54
+ Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
55
+ Adafruit_STMPE610 ts = Adafruit_STMPE610(STMPE_CS);
56
+
57
+
58
+ // This is calibration data for the raw touch data to the screen coordinates
59
+ #define TS_MINX 3800
60
+ #define TS_MAXX 100
61
+ #define TS_MINY 100
62
+ #define TS_MAXY 3750
63
+
64
+ #define PENRADIUS 3
65
+
66
+ void setup (void ) {
67
+ Serial.begin (115200 );
68
+
69
+ delay (10 );
70
+ Serial.println (" FeatherWing TFT" );
71
+ if (!ts.begin ()) {
72
+ Serial.println (" Couldn't start touchscreen controller" );
73
+ while (1 );
74
+ }
75
+ Serial.println (" Touchscreen started" );
76
+
77
+ tft.begin ();
78
+ tft.fillScreen (ILI9341_BLUE);
79
+
80
+ yield ();
81
+
82
+ Serial.print (" Initializing SD card..." );
83
+ if (!SD.begin (SD_CS)) {
84
+ Serial.println (" failed!" );
85
+ }
86
+ Serial.println (" OK!" );
87
+
88
+ bmpDraw (" purple.bmp" , 0 , 0 );
89
+ }
90
+
91
+ void loop () {
92
+ // Retrieve a point
93
+ TS_Point p = ts.getPoint ();
94
+
95
+ Serial.print (" X = " ); Serial.print (p.x );
96
+ Serial.print (" \t Y = " ); Serial.print (p.y );
97
+ Serial.print (" \t Pressure = " ); Serial.println (p.z );
98
+
99
+
100
+ // Scale from ~0->4000 to tft.width using the calibration #'s
101
+ p.x = map (p.x , TS_MINX, TS_MAXX, 0 , tft.width ());
102
+ p.y = map (p.y , TS_MINY, TS_MAXY, 0 , tft.height ());
103
+
104
+ if (((p.y -PENRADIUS) > 0 ) && ((p.y +PENRADIUS) < tft.height ())) {
105
+ tft.fillCircle (p.x , p.y , PENRADIUS, ILI9341_RED);
106
+ }
107
+ }
108
+
109
+ // This function opens a Windows Bitmap (BMP) file and
110
+ // displays it at the given coordinates. It's sped up
111
+ // by reading many pixels worth of data at a time
112
+ // (rather than pixel by pixel). Increasing the buffer
113
+ // size takes more of the Arduino's precious RAM but
114
+ // makes loading a little faster. 20 pixels seems a
115
+ // good balance.
116
+
117
+ #define BUFFPIXEL 20
118
+
119
+ void bmpDraw (char *filename, uint8_t x, uint16_t y) {
120
+
121
+ File bmpFile;
122
+ int bmpWidth, bmpHeight; // W+H in pixels
123
+ uint8_t bmpDepth; // Bit depth (currently must be 24)
124
+ uint32_t bmpImageoffset; // Start of image data in file
125
+ uint32_t rowSize; // Not always = bmpWidth; may have padding
126
+ uint8_t sdbuffer[3 *BUFFPIXEL]; // pixel buffer (R+G+B per pixel)
127
+ uint8_t buffidx = sizeof (sdbuffer); // Current position in sdbuffer
128
+ boolean goodBmp = false ; // Set to true on valid header parse
129
+ boolean flip = true ; // BMP is stored bottom-to-top
130
+ int w, h, row, col;
131
+ uint8_t r, g, b;
132
+ uint32_t pos = 0 , startTime = millis ();
133
+
134
+ if ((x >= tft.width ()) || (y >= tft.height ())) return ;
135
+
136
+ Serial.println ();
137
+ Serial.print (F (" Loading image '" ));
138
+ Serial.print (filename);
139
+ Serial.println (' \' ' );
140
+
141
+ // Open requested file on SD card
142
+ if ((bmpFile = SD.open (filename)) == NULL ) {
143
+ Serial.print (F (" File not found" ));
144
+ return ;
145
+ }
146
+
147
+ // Parse BMP header
148
+ if (read16 (bmpFile) == 0x4D42 ) { // BMP signature
149
+ Serial.print (F (" File size: " )); Serial.println (read32 (bmpFile));
150
+ (void )read32 (bmpFile); // Read & ignore creator bytes
151
+ bmpImageoffset = read32 (bmpFile); // Start of image data
152
+ Serial.print (F (" Image Offset: " )); Serial.println (bmpImageoffset, DEC);
153
+ // Read DIB header
154
+ Serial.print (F (" Header size: " )); Serial.println (read32 (bmpFile));
155
+ bmpWidth = read32 (bmpFile);
156
+ bmpHeight = read32 (bmpFile);
157
+ if (read16 (bmpFile) == 1 ) { // # planes -- must be '1'
158
+ bmpDepth = read16 (bmpFile); // bits per pixel
159
+ Serial.print (F (" Bit Depth: " )); Serial.println (bmpDepth);
160
+ if ((bmpDepth == 24 ) && (read32 (bmpFile) == 0 )) { // 0 = uncompressed
161
+
162
+ goodBmp = true ; // Supported BMP format -- proceed!
163
+ Serial.print (F (" Image size: " ));
164
+ Serial.print (bmpWidth);
165
+ Serial.print (' x' );
166
+ Serial.println (bmpHeight);
167
+
168
+ // BMP rows are padded (if needed) to 4-byte boundary
169
+ rowSize = (bmpWidth * 3 + 3 ) & ~3 ;
170
+
171
+ // If bmpHeight is negative, image is in top-down order.
172
+ // This is not canon but has been observed in the wild.
173
+ if (bmpHeight < 0 ) {
174
+ bmpHeight = -bmpHeight;
175
+ flip = false ;
176
+ }
177
+
178
+ // Crop area to be loaded
179
+ w = bmpWidth;
180
+ h = bmpHeight;
181
+ if ((x+w-1 ) >= tft.width ()) w = tft.width () - x;
182
+ if ((y+h-1 ) >= tft.height ()) h = tft.height () - y;
183
+
184
+ // Set TFT address window to clipped image bounds
185
+ tft.setAddrWindow (x, y, x+w-1 , y+h-1 );
186
+
187
+ for (row=0 ; row<h; row++) { // For each scanline...
188
+
189
+ // Seek to start of scan line. It might seem labor-
190
+ // intensive to be doing this on every line, but this
191
+ // method covers a lot of gritty details like cropping
192
+ // and scanline padding. Also, the seek only takes
193
+ // place if the file position actually needs to change
194
+ // (avoids a lot of cluster math in SD library).
195
+ if (flip) // Bitmap is stored bottom-to-top order (normal BMP)
196
+ pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize;
197
+ else // Bitmap is stored top-to-bottom
198
+ pos = bmpImageoffset + row * rowSize;
199
+ if (bmpFile.position () != pos) { // Need seek?
200
+ bmpFile.seek (pos);
201
+ buffidx = sizeof (sdbuffer); // Force buffer reload
202
+ }
203
+
204
+ for (col=0 ; col<w; col++) { // For each pixel...
205
+ // Time to read more pixel data?
206
+ if (buffidx >= sizeof (sdbuffer)) { // Indeed
207
+ bmpFile.read (sdbuffer, sizeof (sdbuffer));
208
+ buffidx = 0 ; // Set index to beginning
209
+ }
210
+
211
+ // Convert pixel from BMP to TFT format, push to display
212
+ b = sdbuffer[buffidx++];
213
+ g = sdbuffer[buffidx++];
214
+ r = sdbuffer[buffidx++];
215
+ tft.pushColor (tft.color565 (r,g,b));
216
+ } // end pixel
217
+ } // end scanline
218
+ Serial.print (F (" Loaded in " ));
219
+ Serial.print (millis () - startTime);
220
+ Serial.println (" ms" );
221
+ } // end goodBmp
222
+ }
223
+ }
224
+
225
+ bmpFile.close ();
226
+ if (!goodBmp) Serial.println (F (" BMP format not recognized." ));
227
+ }
228
+
229
+ // These read 16- and 32-bit types from the SD card file.
230
+ // BMP data is stored little-endian, Arduino is little-endian too.
231
+ // May need to reverse subscript order if porting elsewhere.
232
+
233
+ uint16_t read16 (File &f) {
234
+ uint16_t result;
235
+ ((uint8_t *)&result)[0 ] = f.read (); // LSB
236
+ ((uint8_t *)&result)[1 ] = f.read (); // MSB
237
+ return result;
238
+ }
239
+
240
+ uint32_t read32 (File &f) {
241
+ uint32_t result;
242
+ ((uint8_t *)&result)[0 ] = f.read (); // LSB
243
+ ((uint8_t *)&result)[1 ] = f.read ();
244
+ ((uint8_t *)&result)[2 ] = f.read ();
245
+ ((uint8_t *)&result)[3 ] = f.read (); // MSB
246
+ return result;
247
+ }
0 commit comments