Skip to content

Commit 94a597c

Browse files
committed
Added example and fixed APDS for Tempera
1 parent 9a8769d commit 94a597c

File tree

18 files changed

+3038
-1020
lines changed

18 files changed

+3038
-1020
lines changed

examples/Inkplate10/Projects/Inkplate10_Image_Frame_From_SD/Inkplate10_Image_Frame_From_SD.ino

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ void loop()
8686
lastImageIndex = file.dirIndex();
8787

8888
// Skip hidden files and subdirectories
89-
skipHiden();
89+
skipHidden();
9090

9191
// Get name of the pucture, create path and draw image on the screen
9292
if (!displayImage())
@@ -241,7 +241,7 @@ bool displayImage()
241241
/**
242242
* @brief Skip hidden files and subdirectories.
243243
*/
244-
void skipHiden()
244+
void skipHidden()
245245
{
246246
while (file.isHidden() || file.isSubDir())
247247
{
Lines changed: 332 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,332 @@
1+
/*
2+
Inkplate4TEMPERA_Image_Frame_Gesture example for Soldered Inkplate 4 TEMPERA
3+
For this example you will need a USB-C cable, Inkplate 4TEMPERA and a SD card loaded with images.
4+
Select "Soldered Inkplate 4 TEMPERA" from Tools -> Board menu.
5+
Don't have "Soldered Inkplate 4 TEMPERA" option? Follow our tutorial and add it:
6+
https://soldered.com/learn/add-inkplate-6-board-definition-to-arduino-ide/
7+
8+
You can open .bmp, .jpeg, or .png files that have a color depth of 1-bit (BW bitmap), 4-bit, 8-bit and
9+
24 bit, but there are some limitations of the library. It will skip images that can't be drawn.
10+
Make sure that the image has a resolution smaller than 600x600 or otherwise it won't fit on the screen.
11+
Format your SD card in standard FAT file format.
12+
13+
NOTE: the maximum number of images on the SD card is 512 due to the limitations of the RTC memory.
14+
15+
This example will show you how you can make slideshow images from an SD card. Put your images on
16+
the SD card in a file and specify the file path in the sketch. Images will cycle on gestures
17+
LEFT and RIGHT on the APDS9960 gesture sensor, and the rest of the time, Inkplate will be in deep sleep,
18+
making this example battery-friendly.
19+
20+
Want to learn more about Inkplate? Visit www.inkplate.io
21+
Looking to get support? Write on our forums: https://forum.soldered.com/
22+
2 Oct 2023 by Soldered
23+
*/
24+
25+
// Next 3 lines are a precaution, you can ignore those, and the example would also work without them
26+
#ifndef ARDUINO_INKPLATE4TEMPERA
27+
#error "Wrong board selection for this example, please select Inkplate 4 TEMPERA in the boards menu."
28+
#endif
29+
30+
/******************CHANGE HERE***********************/
31+
32+
// Path to the folder with pictures (e.g. there is a folder called images on the SD card)
33+
const char folderPath[] = "/images/"; // NOTE: Must end with /
34+
35+
/****************************************************/
36+
37+
#include "Inkplate.h" // Include Inkplate library to the sketch
38+
Inkplate display(INKPLATE_3BIT); // Create an object on Inkplate library and also set library into 3 Bit mode
39+
SdFile folder, file; // Create SdFile objects used for accessing files on SD card
40+
41+
// These variables are stored in RTC's memory, so they stay alive even if Inkplate goes to deep sleep
42+
43+
// Remember if we completed the first boot process
44+
// The reason for this is that the APDS needs to only be configured once, as it stays on during sleep
45+
RTC_DATA_ATTR bool firstBootcompleted = false;
46+
47+
// A flag to see if a gesture woke up Inkplate which wasn't left or right
48+
RTC_DATA_ATTR bool skip = false;
49+
50+
// Last image index stored in RTC RAM that stores variable even if deep sleep is used
51+
RTC_DATA_ATTR uint16_t lastImageIndex = 0;
52+
// Dir indexes of all the images which are in the given folder
53+
RTC_DATA_ATTR uint16_t imageIndexes[512];
54+
// How many images are there in total
55+
RTC_DATA_ATTR int numFiles = 0;
56+
// Which file in imageIndexes are we currently observing
57+
RTC_DATA_ATTR int currentImageIndex = 0;
58+
59+
void setup()
60+
{
61+
display.begin(); // Init Inkplate library (you should call this function ONLY ONCE)
62+
display.clearDisplay(); // Clear frame buffer of display
63+
display.setCursor(30, 30); // Set the cursor a bit further from the corner so the text is visible
64+
display.setTextColor(BLACK); // Set text color to black
65+
display.setTextSize(5); // Scale text to be five times bigger then original (5x7 px)
66+
67+
// Init SD card
68+
if (!display.sdCardInit())
69+
{
70+
// If the SD card init is not successful, display an error on the screen
71+
display.println("SD Card error!");
72+
display.display();
73+
74+
// Go to deep sleep and do nothing
75+
deepSleep();
76+
}
77+
78+
if (!firstBootcompleted)
79+
{
80+
// If this is the first boot...
81+
82+
// Init APDS and enable the gesture sensor
83+
display.apds9960.init();
84+
display.apds9960.enableGestureSensor(true); // Setting 'true' here enables interrupts
85+
86+
// Make sure gesture is at lowest sensitivity so it doesn't accidentially get triggered
87+
display.apds9960.setGestureGain(0);
88+
89+
// Get the file count and file dir indexes and save them to RTC memory
90+
getFileCount();
91+
92+
// Remember that this config was completed
93+
firstBootcompleted = true;
94+
}
95+
else
96+
{
97+
// This happens from the second boot onwards
98+
// This must mean Inkplate was woken up by an interrupt from the APDS
99+
// Let's read which gesture woke it up
100+
if (display.apds9960.isGestureAvailable())
101+
{
102+
// Read the gesture and act accordingly
103+
switch (display.apds9960.readGesture())
104+
{
105+
case DIR_LEFT:
106+
skip = false; // Picture should be changed
107+
currentImageIndex++; // Go to next picture
108+
// Reset counter if it overflowed
109+
if (currentImageIndex > numFiles - 1)
110+
currentImageIndex = 0;
111+
break;
112+
case DIR_RIGHT:
113+
skip = false; // Picture should be changed
114+
currentImageIndex--; // Go to previous picture
115+
// Loop back counter if it went below 0
116+
if (currentImageIndex < 0)
117+
currentImageIndex = numFiles - 1;
118+
break;
119+
default:
120+
// If it's not a left or right gesture, do nothing
121+
skip = true;
122+
}
123+
}
124+
}
125+
}
126+
127+
void loop()
128+
{
129+
// If the gesture was either left or right
130+
if (!skip)
131+
{
132+
// Open the folder with pictures
133+
if (folder.open(folderPath))
134+
{
135+
// Open the according file
136+
if (!file.open(&folder, imageIndexes[currentImageIndex], O_READ))
137+
{
138+
// If it can't open the next file, there is an end of the file so set the index of the last file to 0
139+
// because it's used later for restart
140+
lastImageIndex = 0;
141+
}
142+
else
143+
{
144+
// The file was opened successfully!
145+
// Save the index of the last opened file
146+
lastImageIndex = file.dirIndex();
147+
148+
// Skip hidden files and subdirectories
149+
skipHidden();
150+
151+
// Get name of the picture, create path and draw image on the screen
152+
if (!displayImage())
153+
{
154+
// Reset the loop if there is an error displaying the image
155+
return;
156+
}
157+
158+
// Close the file
159+
file.close();
160+
}
161+
// Close the folder
162+
folder.close();
163+
164+
// That's it, go to sleep!
165+
deepSleep();
166+
}
167+
else
168+
{
169+
display.printf(
170+
"Error opening folder! Make sure \nthat you have entered the proper \nname and add / to the end "
171+
"of the \npath");
172+
display.display();
173+
deepSleep();
174+
}
175+
176+
// If the index is equal to 0, it is the end of the file so repeat the code in loop again
177+
// If not, go into a deep sleep and wait for displaying next image
178+
if (lastImageIndex != 0)
179+
{
180+
// Go to deep sleep
181+
deepSleep();
182+
}
183+
}
184+
else
185+
{
186+
// If a gesture was made which isn't left or right, just go to sleep
187+
deepSleep();
188+
}
189+
}
190+
191+
/**
192+
* @brief Activate the SD card and count the files in the folder. Close the folder and file and return the number of
193+
* files
194+
*/
195+
void getFileCount()
196+
{
197+
// Open the folder
198+
if (folder.open(folderPath))
199+
{
200+
// Opening the next file until it reaches the end
201+
while (file.openNext(&folder, O_READ))
202+
{
203+
// If the file is not hidden, increase the counter
204+
if (!file.isHidden())
205+
{
206+
imageIndexes[numFiles] = file.dirIndex();
207+
Serial.println("just added to image indexes: ");
208+
Serial.println(imageIndexes[numFiles]);
209+
numFiles++;
210+
}
211+
212+
// Close the file
213+
file.close();
214+
}
215+
// Close the folder
216+
folder.close();
217+
218+
Serial.print("just counted the files, there are : ");
219+
Serial.println(numFiles);
220+
}
221+
else
222+
{
223+
display.println("The folder doesn't exist");
224+
display.display();
225+
deepSleep();
226+
}
227+
}
228+
229+
/**
230+
* @brief Go to deep sleep and enable wakeup on the wake button.
231+
*/
232+
void deepSleep()
233+
{
234+
// Turn off the power supply for the SD card
235+
display.sdCardSleep();
236+
237+
// First, configure the interrupt from APDS to the GPIO expander
238+
display.pinModeIO(9, INPUT_PULLUP, IO_INT_ADDR);
239+
display.setIntPin(9, IO_INT_ADDR);
240+
241+
// Now, the internal GPIO expander will fire an interrupt on it's INT pin
242+
// On pin change of pin 9
243+
244+
// Now, configure the interrupt from the GPIO expander to ESP32
245+
// Set it as an input
246+
pinMode(GPIO_NUM_34, INPUT);
247+
// Enable wakeup from deep sleep on GPIO 34 when it goes LOW
248+
esp_sleep_enable_ext0_wakeup(GPIO_NUM_34, LOW);
249+
250+
// Just in case, wait until the APDS interrupt clears
251+
while (!display.digitalReadIO(9, IO_INT_ADDR))
252+
{
253+
delay(10);
254+
}
255+
256+
// Finally, put ESP32 into deep sleep (low power mode)
257+
esp_deep_sleep_start();
258+
}
259+
260+
/**
261+
* @brief If it's the first file, the file open at index 0 won't work so skip this for the index zero (first file
262+
* because the index is declared as 0).
263+
*/
264+
void openLastFile()
265+
{
266+
if (lastImageIndex != 0)
267+
{
268+
if (file.open(&folder, lastImageIndex, O_READ))
269+
{
270+
// Close the file so the code below can open the next one
271+
file.close();
272+
}
273+
}
274+
}
275+
276+
/**
277+
* @brief Get name of the pucture, create path and draw image on the screen.
278+
*
279+
* @return 0 if there is an error, 1 if the image is drawn.
280+
*/
281+
bool displayImage()
282+
{
283+
// Get the name of the picture
284+
int maxCharacters = 100;
285+
char pictureName[maxCharacters];
286+
file.getName(pictureName, maxCharacters);
287+
288+
// Copy of the folder path just for creating path for the image
289+
char path[maxCharacters];
290+
strcpy(path, folderPath);
291+
292+
// Create picture path (folder path + picture name)
293+
char *picturePath = strcat(path, pictureName);
294+
295+
// Draw the image on the screen
296+
if (!display.drawImage(picturePath, 0, 0, 1, 0))
297+
{
298+
// Close folder and file
299+
file.close();
300+
folder.close();
301+
302+
// Return 0 to signalize an error
303+
return 0;
304+
}
305+
306+
// Display the picture on the screen
307+
display.display();
308+
return 1;
309+
}
310+
311+
/**
312+
* @brief Skip hidden files and subdirectories.
313+
*/
314+
void skipHidden()
315+
{
316+
while (file.isHidden() || file.isSubDir())
317+
{
318+
file.close();
319+
320+
// Opening the next file while the file is hidden or the file is the directory
321+
if (!file.openNext(&folder, O_RDONLY))
322+
{
323+
// It is end of file
324+
lastImageIndex = 0;
325+
}
326+
else
327+
{
328+
// Save the index of the last opened file
329+
lastImageIndex = file.dirIndex();
330+
}
331+
}
332+
}

examples/Inkplate4TEMPERA/Projects/Inkplate4TEMPERA_Image_frame_From_SD/Inkplate4TEMPERA_Image_frame_From_SD.ino

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ void loop()
8484
lastImageIndex = file.dirIndex();
8585

8686
// Skip hidden files and subdirectories
87-
skipHiden();
87+
skipHidden();
8888

8989
// Get name of the pucture, create path and draw image on the screen
9090
if (!displayImage())
@@ -239,7 +239,7 @@ bool displayImage()
239239
/**
240240
* @brief Skip hidden files and subdirectories.
241241
*/
242-
void skipHiden()
242+
void skipHidden()
243243
{
244244
while (file.isHidden() || file.isSubDir())
245245
{

examples/Inkplate6/Projects/Inkplate6_Image_Frame_From_SD/Inkplate6_Image_Frame_From_SD.ino

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ void loop()
8686
lastImageIndex = file.dirIndex();
8787

8888
// Skip hidden files and subdirectories
89-
skipHiden();
89+
skipHidden();
9090

9191
// Get name of the pucture, create path and draw image on the screen
9292
if (!displayImage())
@@ -241,7 +241,7 @@ bool displayImage()
241241
/**
242242
* @brief Skip hidden files and subdirectories.
243243
*/
244-
void skipHiden()
244+
void skipHidden()
245245
{
246246
while (file.isHidden() || file.isSubDir())
247247
{

0 commit comments

Comments
 (0)