1+ /* *
2+ **************************************************
3+ * @file Inkplate_6_Motion_Factory_Programming.ino
4+ *
5+ * @brief File for initial testing and displaying the onboarding seqeuence of Inkplate 6 MOTION
6+ *
7+ * @note This sketch will test part of the features which need to be tested when Inkplate 6 MOTION
8+ * is assembled and in it's enclosure.
9+ *
10+ * To pass all tests:
11+ * - Edit the WiFi information below
12+ * - Follow all the test's instructions
13+ *
14+ * The other tests are done in Inkplate_6_Motion_VCOM_Set.ino
15+ *
16+ * After all tests have passed the device will showcase the Inkplate 6MOTION onboarding image sequence
17+ *
18+ *License v3.0: https://www.gnu.org/licenses/lgpl-3.0.en.html Please review the
19+ *LICENSE file included with this example. If you have any questions about
20+ *licensing, please visit https://soldered.com/contact/ Distributed as-is; no
21+ *warranty is given.
22+ *
23+ * @authors Robert @ Soldered
24+ ***************************************************/
25+
26+ // Test parameters which may be changed if required:
27+
28+ // If you want to test the device again change this
29+ // Can't be 0 as this is the default EEPROMoffset for VCOM writing
30+ int testsDoneEepromValue = 30 ; // Change this number if you want to repeat tests
31+ int testsDoneEepromOffset = 8 ; // Where in EEPROM this symbollic value is written
32+
33+ // WiFi credentials for testing
34+ char *wifiSSID = {" Soldered-testingPurposes" };
35+ char *wifiPASS = {" Testing443" };
36+
37+ // The qwiic (I2C) follower address which will be checked
38+ const uint8_t qwiicTestAddress = 0x30 ;
39+
40+ // More detailed test parameters are available to edit in InkplateTest.cpp
41+
42+ // //////////////////////////////////////////////////////////////////////////////////////////////////
43+
44+ // Next 3 lines are a precaution, you can ignore those, and the example would also work without them
45+ #if !defined(BOARD_INKPLATE6_MOTION)
46+ #error "Wrong board selection for this example, please select Inkplate 6MOTION in the boards menu."
47+ #endif
48+
49+ // Include Inkplate Motion library for STM32H743 MCU
50+ #include < InkplateMotion.h>
51+
52+ // Include Inkplate test class header file
53+ #include " InkplateTest.h"
54+
55+ // Include slideshow slides
56+ #include " slides/onboarding_00_min.h"
57+ #include " slides/onboarding_01_min.h"
58+ #include " slides/onboarding_02_min.h"
59+ #include " slides/onboarding_03_min.h"
60+ #include " slides/onboarding_04_min.h"
61+ #include " slides/onboarding_05_min.h"
62+ #include " slides/onboarding_06_min.h"
63+ #include " slides/onboarding_07_min.h"
64+ #include " slides/onboarding_initial_min.h"
65+ #include " slides/solderedLogoSmall.h"
66+
67+ // Sketch varaibles
68+ Inkplate inkplate; // Create an Inkplate Motion object.
69+ InkplateTest testClass; // The class which does all the testing
70+
71+ // This is the onboarding image sequence
72+ // Declare an array of pointers to the arrays
73+ void *onboardingSlides[9 ] = {
74+ (void *)onboarding_initial_min, (void *)onboarding_00_min, (void *)onboarding_01_min,
75+ (void *)onboarding_02_min, (void *)onboarding_03_min, (void *)onboarding_04_min,
76+ (void *)onboarding_05_min, (void *)onboarding_06_min, (void *)onboarding_07_min,
77+ };
78+ // Also know the sizes
79+ size_t slideSizes[9 ] = {
80+ sizeof (onboarding_initial_min), sizeof (onboarding_00_min), sizeof (onboarding_01_min),
81+ sizeof (onboarding_02_min), sizeof (onboarding_03_min), sizeof (onboarding_04_min),
82+ sizeof (onboarding_05_min), sizeof (onboarding_06_min), sizeof (onboarding_07_min),
83+ };
84+
85+ // Count the slides with this variable
86+ static int slideCounter = 0 ;
87+
88+ void setup ()
89+ {
90+ // Init Serial for communication
91+ Serial.begin (115200 );
92+
93+ // Set pin mode for buttons
94+ pinMode (INKPLATE_USER1, INPUT_PULLUP);
95+ pinMode (INKPLATE_USER2, INPUT_PULLUP);
96+
97+ // Init Inkplate class in 1-bit mode
98+ inkplate.begin (INKPLATE_1BW);
99+
100+ // Init Inkplate test class (this just gives it pointer to the Inkplate object and params)
101+ testClass.init (&inkplate, testsDoneEepromOffset, wifiSSID, wifiPASS, qwiicTestAddress);
102+
103+ // Check if tests have been completed with this offset
104+ if (!testClass.areTestsDone (testsDoneEepromOffset, testsDoneEepromValue))
105+ {
106+ // If tests are NOT done yet...
107+ // Perform tests in enclosure
108+ if (!testClass.testInEnclosure ())
109+ {
110+ // Fatal error happened, don't continue the test - just inform the user via Serial
111+ // Test result should also display on the e-Paper so this is just a precaution
112+ Serial.println (" Critical error: one of the tests failed!" );
113+ Serial.println (" Test stopping!" );
114+ // Go to infinite loop
115+ while (true )
116+ ;
117+ }
118+
119+ // e-Paper power supply test, VCOM set, and some other tests are done in Inkplate_6_Motion_VCOM_Set.ino
120+
121+ // We're here - tests are done, mark it in memory
122+ testClass.writeEepromValue (testsDoneEepromOffset, testsDoneEepromValue);
123+ }
124+ // Show first slide
125+ displaySlide (slideCounter);
126+ }
127+
128+ void loop ()
129+ {
130+ // Loop essentially controls the slideshow
131+
132+ // USER2 button goes to previous slide
133+ if (!digitalRead (INKPLATE_USER2))
134+ {
135+ slideCounter--;
136+ if (slideCounter < 0 )
137+ slideCounter = 8 ;
138+
139+ // Show the slide
140+ displaySlide (slideCounter);
141+
142+ // Slight debounce
143+ delay (5 );
144+ }
145+
146+ // USER1 button goes to next slide
147+ if (!digitalRead (INKPLATE_USER1))
148+ {
149+ slideCounter++;
150+ if (slideCounter > 8 )
151+ slideCounter = 0 ;
152+
153+ // Show the slide
154+ displaySlide (slideCounter);
155+
156+ // Slight debounce
157+ delay (5 );
158+ }
159+ }
160+
161+
162+ // Show a slide in the onboarding sequence
163+ void displaySlide (int _slideIndex)
164+ {
165+ // Check for range
166+ if (_slideIndex >= 10 || _slideIndex < 0 )
167+ return ;
168+
169+ // Slides 2 and 4 are in bw mode
170+ if (_slideIndex == 2 )
171+ {
172+ // Set mode to BW
173+ inkplate.selectDisplayMode (INKPLATE_BLACKWHITE);
174+ // Draw the image from memory
175+ // These are not JPG's but bitmaps
176+ inkplate.drawBitmap (0 , 0 , onboarding_01_min, SCREEN_WIDTH, SCREEN_HEIGHT, 1 );
177+ inkplate.display (); // Do full refresh with bw slides
178+ }
179+ else if (_slideIndex == 4 )
180+ {
181+ // Set mode to BW
182+ inkplate.selectDisplayMode (INKPLATE_BLACKWHITE);
183+ // Draw the image from memory
184+ inkplate.drawBitmap (0 , 0 , onboarding_03_min, SCREEN_WIDTH, SCREEN_HEIGHT, 1 );
185+ inkplate.display ();
186+ // This slide displays the animation
187+ // This function returns true if USER1 was pressed
188+ // It returns false if USER2 was pressed
189+ if (partialUpdateAnimation ())
190+ {
191+ _slideIndex++;
192+ return ;
193+ }
194+ else
195+ {
196+ _slideIndex--;
197+ return ;
198+ }
199+ }
200+ else
201+ {
202+ // Other slides are in grayscale
203+ // Set mode to Grayscale
204+ inkplate.selectDisplayMode (INKPLATE_GRAYSCALE);
205+ // Draw the image from a jpg file
206+ inkplate.image .drawFromBuffer (onboardingSlides[_slideIndex], slideSizes[_slideIndex], 0 , 0 , false , 0 ,
207+ NULL , 0 , INKPLATE_IMAGE_DECODE_FORMAT_JPG);
208+ if (_slideIndex == 0 || _slideIndex == 3 || _slideIndex == 5 )
209+ // Do full refreshes after slides 2 and 4 and on the first slide
210+ inkplate.display ();
211+ else
212+ // On other slides do partial update
213+ inkplate.partialUpdate ();
214+ }
215+ }
216+
217+ // Returns true if going to next slide, false if going to previous slide
218+ bool partialUpdateAnimation ()
219+ {
220+ // To count the number of updates
221+ int numUpdates = 0 ;
222+ // Can be pretty liberal with the number of partial updates as the affected screen area is always moving
223+ int maxPartialUpdates = 100 ;
224+
225+ // Some basic coordinations and dimensions of the animation
226+ int x = 18 ;
227+ int y = 212 ;
228+ int dx = 10 ; // Change in x direction
229+ int dy = 10 ; // Change in y direction
230+ int width = 979 ;
231+ int height = 519 ;
232+
233+ // The logo which gets bounced around is also in slide_03.h
234+ int logoWidth = 92 ;
235+ int logoHeight = 121 ;
236+
237+ while (true )
238+ {
239+ // Clear the previous position
240+ inkplate.fillRect (18 + 3 , 212 + 3 , width, height, WHITE);
241+
242+ // Update the position of the logo
243+ x += dx;
244+ y += dy;
245+
246+ // Check for button press to exit the function
247+ // A bit hacky but this is done multiple times during this while loop to increase responsiveness
248+ if (digitalRead (INKPLATE_USER1) == LOW)
249+ return true ;
250+ if (digitalRead (INKPLATE_USER2) == LOW)
251+ return false ;
252+
253+ // Check for collisions with the edges and reverse direction if necessary
254+ if (x <= 18 || x + logoWidth >= 18 + width)
255+ {
256+ dx = -dx;
257+ }
258+ if (y <= 212 || y + logoHeight >= 212 + height)
259+ {
260+ dy = -dy;
261+ }
262+
263+ if (digitalRead (INKPLATE_USER1) == LOW)
264+ return true ;
265+ if (digitalRead (INKPLATE_USER2) == LOW)
266+ return false ;
267+
268+ // Draw the logo at the new position
269+ inkplate.drawBitmap (x, y, solderedLogoSmall, logoWidth, logoHeight, BLACK);
270+ inkplate.partialUpdate (true );
271+ numUpdates++;
272+
273+ if (digitalRead (INKPLATE_USER1) == LOW)
274+ return true ;
275+ if (digitalRead (INKPLATE_USER2) == LOW)
276+ return false ;
277+
278+ if (numUpdates >= maxPartialUpdates)
279+ {
280+ numUpdates = 0 ;
281+ inkplate.display ();
282+ }
283+
284+ if (digitalRead (INKPLATE_USER1) == LOW)
285+ return true ;
286+ if (digitalRead (INKPLATE_USER2) == LOW)
287+ return false ;
288+ }
289+ }
0 commit comments