Skip to content

Commit 17eda0e

Browse files
Added comments to example
1 parent 990dd79 commit 17eda0e

File tree

1 file changed

+85
-14
lines changed

1 file changed

+85
-14
lines changed

examples/Inkplate10/Projects/Inkplate10_Lan_Gallery/Inkplate10_Lan_Gallery.ino

Lines changed: 85 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,71 @@
1+
/*
2+
Inkplate Lan Gallery Example
3+
Compatible with Soldered Inkplate 10
4+
5+
Getting started:
6+
For this project you will need: Inkplate 10, microSD card (formatted to FAT32!)
7+
and WiFi connection.
8+
9+
Step 1: Place the formatted microSD card in onboard slot on Inkplate 10
10+
11+
Step 2: Install `AsyncTCP` and `ESPAsyncWebServer` libraries, they are available directly from
12+
Arduino Library Manager.
13+
14+
Step 3: Modify the ssid, password and IMAGE_CHANGE_INTERVAL variables. SSID and password
15+
need to be the same as the network you are trying to connect, and INTERVAL_CHANGE_TIMER
16+
changes the duration between image changes (in miliseconds, default is 30000ms or 30s)
17+
18+
Step 4: Upload the code as usual
19+
20+
Step 5: Using another device connected to the same network open a browser and
21+
go to langallery.local
22+
23+
Step 6: Press the 'Choose File' button and select a picture that you want to upload, and
24+
after that press the 'Upload' button
25+
26+
Overview:
27+
This example demonstartes how to run a webapp, handle multiple users at once, upload files
28+
to onboard SD card and display uploaded images in random order on the e-ink display. Images
29+
will be automatically resized.
30+
31+
*/
32+
33+
// Ensure corect board is selected
134
#if !defined(ARDUINO_INKPLATE10) && !defined(ARDUINO_INKPLATE10V2)
235
#error "Select 'Soldered Inkplate10' in the boards menu."
336
#endif
437

5-
#include "Inkplate.h"
38+
#include "Inkplate.h" //Inkplate library
639

40+
// Initialize Inkplate (3-bit grayscale mode)
741
Inkplate display(INKPLATE_3BIT);
842

43+
44+
// WiFi network credentials
945
const char* ssid = "YOUR_SSID";
1046
const char* password = "YOUR_PASSWORD";
1147

12-
#define IMAGE_CHANGE_INTERVAL 30000UL
48+
// Image rotation/change inteerval (milliseconds)
49+
#define IMAGE_CHANGE_INTERVAL 30000UL
50+
51+
// Linked list structure for storing image filepaths
52+
struct Node {
53+
char* path;
54+
int id;
55+
Node* next;
56+
};
1357

14-
struct Node { char* path; int id; Node* next; };
15-
Node* head = nullptr;
16-
int nodeCount = 0;
58+
Node* head = nullptr; // Pointer to the first node in circular list
59+
int nodeCount = 0; // Total number of images found
1760

18-
SemaphoreHandle_t sdMutex;
19-
SdFile* currentUploadFile = nullptr;
20-
volatile bool uploadComplete = false;
61+
SemaphoreHandle_t sdMutex; // Mutex for SD card access synchronization
62+
SdFile* currentUploadFile = nullptr; // File object for current upload
63+
volatile bool uploadComplete = false; //Flag to indicate upload completion
2164

65+
// Forward declaration
2266
void setupWebServer();
2367

68+
// Add a new image node to the linked list
2469
void addNode(const char* p, int id) {
2570
Node* n = (Node*)malloc(sizeof(Node));
2671
if (!n) return;
@@ -38,10 +83,13 @@ void addNode(const char* p, int id) {
3883
nodeCount++;
3984
}
4085

86+
// Build a list of all image files found on the SD card
4187
bool buildImageList() {
4288
Serial.println("Building image list...");
4389
if (!display.sdCardInit()) {
44-
Serial.println("SD Card init failed!");
90+
display.clearDisplay();
91+
display.print("SD Card init failed!");
92+
display.display();
4593
return false;
4694
}
4795
SdFile root;
@@ -50,6 +98,7 @@ bool buildImageList() {
5098
return false;
5199
}
52100

101+
// Free any existing list before rebuilding
53102
if (head) {
54103
Node* current = head;
55104
Node* first = head;
@@ -63,6 +112,7 @@ bool buildImageList() {
63112
}
64113
nodeCount = 0;
65114

115+
// Iterate through SD card root directory and find image files
66116
SdFile e;
67117
while (e.openNext(&root, O_RDONLY)) {
68118
char name[64];
@@ -80,6 +130,7 @@ bool buildImageList() {
80130
return nodeCount > 0;
81131
}
82132

133+
// Pick a random image node from the list
83134
Node* pickRandomNode() {
84135
if (!head) return nullptr;
85136
int id = random(nodeCount);
@@ -88,6 +139,7 @@ Node* pickRandomNode() {
88139
return t;
89140
}
90141

142+
//read BMP image dimensions directly from SD card
91143
static bool readBmpSize_SdFat(const char* path, int &w, int &h) {
92144
w = h = 0;
93145
SdFile f;
@@ -107,6 +159,7 @@ static bool readBmpSize_SdFat(const char* path, int &w, int &h) {
107159
return true;
108160
}
109161

162+
// Read JPEG image dimensions directly from SD card
110163
static bool readJpegSize_SdFat(const char* path, int &w, int &h) {
111164
w = h = 0;
112165
SdFile f;
@@ -135,6 +188,7 @@ static bool readJpegSize_SdFat(const char* path, int &w, int &h) {
135188
return true;
136189
};
137190

191+
// Parse JPEG markers until SOF segment found
138192
while (true) {
139193
uint8_t markerPrefix;
140194
do {
@@ -176,6 +230,7 @@ static bool readJpegSize_SdFat(const char* path, int &w, int &h) {
176230
return false;
177231
}
178232

233+
// Detect image type and get its width and height
179234
static bool getImageWH_SdFat(const char* path, int &w, int &h) {
180235
const char *ext = strrchr(path, '.');
181236
if (ext) {
@@ -189,14 +244,21 @@ static bool getImageWH_SdFat(const char* path, int &w, int &h) {
189244
if (readJpegSize_SdFat(path, w, h)) return true;
190245
}
191246
}
192-
w = 800; h = 600;
247+
// Fallback default size if detection fails
248+
w = 800;
249+
h = 600;
193250
return false;
194251
}
195252

253+
// Display selected image file on the e-ink screen
196254
void showImage(const char* path) {
197255
Serial.printf("Displaying: %s\n", path);
198256
display.clearDisplay();
199-
display.sdCardInit();
257+
if(!display.sdCardInit()){
258+
display.clearDisplay();
259+
display.print("SD Card Init() failed!");
260+
display.display();
261+
}
200262

201263
int imgW = 0, imgH = 0;
202264
bool okSize = getImageWH_SdFat(path, imgW, imgH);
@@ -213,13 +275,14 @@ void showImage(const char* path) {
213275

214276
Serial.printf("Draw at x=%d, y=%d (disp=%dx%d)\n", x, y, dispW, dispH);
215277

278+
// Draw image fron SD card
216279
if (!display.drawImage(path, x, y, 3)) {
217280
display.setTextSize(2);
218281
display.setCursor(100, 300);
219282
display.println("Image load failed!");
220283
}
221284

222-
// Overlay text (white on black background)
285+
// Overlay footer text (white on black background)
223286
const char* overlayText = "Inkplate LAN Gallery on langallery.local";
224287
display.setTextSize(1);
225288

@@ -243,6 +306,7 @@ void showImage(const char* path) {
243306
display.display();
244307
}
245308

309+
// Start receiving file data for upload
246310
void startFileUpload(const char* filename) {
247311
if (xSemaphoreTake(sdMutex, portMAX_DELAY)) {
248312
display.sdCardInit();
@@ -257,6 +321,7 @@ void startFileUpload(const char* filename) {
257321
}
258322
}
259323

324+
// Write incoming file data chunks to SD card
260325
void writeFileData(uint8_t* data, size_t len) {
261326
if (xSemaphoreTake(sdMutex, portMAX_DELAY)) {
262327
if (currentUploadFile && currentUploadFile->isOpen()) {
@@ -269,6 +334,7 @@ void writeFileData(uint8_t* data, size_t len) {
269334
}
270335
}
271336

337+
// Finish file upload and close the file
272338
void finishFileUpload() {
273339
if (xSemaphoreTake(sdMutex, portMAX_DELAY)) {
274340
if (currentUploadFile) {
@@ -288,6 +354,7 @@ void finishFileUpload() {
288354
void setup() {
289355
Serial.begin(115200);
290356
display.begin();
357+
display.setTextColor(BLACK);
291358
randomSeed(analogRead(0));
292359
sdMutex = xSemaphoreCreateMutex();
293360

@@ -297,15 +364,18 @@ void setup() {
297364
display.println("Connecting Wi-Fi...");
298365
display.display();
299366

367+
// Connect to existing WiFi network
300368
WiFi.begin(ssid, password);
301369
while (WiFi.status() != WL_CONNECTED) {
302370
delay(500);
303371
Serial.print(".");
304372
}
305373
Serial.printf("\nConnected! IP: %s\n", WiFi.localIP().toString().c_str());
306374

375+
// Start local web server fro uploads
307376
setupWebServer();
308377

378+
// Build image list and show a random one at startup
309379
if (buildImageList()) {
310380
Node* n = pickRandomNode();
311381
if (n) showImage(n->path);
@@ -318,7 +388,7 @@ void setup() {
318388
}
319389
}
320390

321-
unsigned long lastImageChange = 0;
391+
unsigned long lastImageChange = 0; // track last displayed image time
322392

323393
void loop() {
324394
if (uploadComplete) {
@@ -339,6 +409,7 @@ void loop() {
339409
lastImageChange = millis();
340410
}
341411

412+
// Automatically change image after the set interval
342413
if (millis() - lastImageChange >= IMAGE_CHANGE_INTERVAL) {
343414
if (xSemaphoreTake(sdMutex, portMAX_DELAY)) {
344415
if (buildImageList()) {
@@ -350,5 +421,5 @@ void loop() {
350421
lastImageChange = millis();
351422
}
352423

353-
delay(10);
424+
delay(10); // small delay for task scheduling
354425
}

0 commit comments

Comments
 (0)