1+ /*
2+ Inkplate4TEMPERA_APDS9960 example for Soldered Inkplate 4 TEMPERA
3+ For this example you will need only a USB-C cable and Inkplate 4 TEMPERA.
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+ This example will show you how to read gestures, proximity, color and
9+ ambient light from the built-in APDS9960 sensor.
10+
11+ Want to learn more about Inkplate? Visit www.inkplate.io
12+ Looking to get support? Write on our forums: https://forum.soldered.com/
13+ 20 Nov 2023 by Soldered
14+ */
15+
16+ // Next 3 lines are a precaution, you can ignore those, and the example would also work without them
17+ #ifndef ARDUINO_INKPLATE4TEMPERA
18+ #error "Wrong board selection for this example, please select Inkplate 4 TEMPERA in the boards menu."
19+ #endif
20+
21+ #include " Inkplate.h" // Include Inkplate library to the sketch
22+ #include " background.h" // Include background image
23+
24+
25+ Inkplate display (INKPLATE_1BIT); // Create an object on Inkplate library and also set library into 1 Bit mode (BW)
26+
27+ // Display update
28+ #define NUM_UPDATES_BEFORE_FULL_REFRESH 30 // How many partial updates to do before a full refresh
29+ // Variables to help control program flow
30+ bool dataHasChanged = true ; // Set to true so initial data is shown
31+ int numUpdates = 0 ;
32+
33+ // Remember last read values from the sensor so the display can only be updated when there's new values
34+ uint8_t lastProximityMeasured = 0 ;
35+ uint16_t lastRedLightMeasured = 0 ;
36+ uint16_t lastGreenLightMeasured = 0 ;
37+ uint16_t lastBlueLightMeasured = 0 ;
38+ uint16_t lastAmbientLightMeasured = 0 ;
39+
40+ // Setup code, runs only once
41+ void setup ()
42+ {
43+ display.begin (); // Init Inkplate library (you should call this function ONLY ONCE)
44+ display.clearDisplay (); // Clear frame buffer of display
45+ display.display (); // Put clear image on display
46+ display.setTextSize (3 ); // Set text to be 3 times bigger than classic 5x7 px text
47+ display.setTextColor (BLACK);
48+
49+ // Draw the background grid from buffer
50+ display.drawImage (background, 0 , 0 , 600 , 600 , WHITE, BLACK);
51+
52+ // Let's confiugure the APDS!
53+ display.wakePeripheral (INKPLATE_APDS9960); // First, wake it from sleep
54+ // Initialize the APDS
55+ if (!display.apds9960 .init ())
56+ {
57+ // There's an error with the initialization, inform the user
58+ display.setCursor (50 , 50 );
59+ display.print (" Can't init APDS!" );
60+ display.display ();
61+
62+ // Go straight to sleep in this case
63+ esp_deep_sleep_start ();
64+ }
65+
66+ // Individual elements of the sensor have to be enabled explicitly for it to work
67+ // First, enable the proximity sensor without interrupts
68+ display.apds9960 .enableProximitySensor (false );
69+ display.apds9960 .setProximityGain (1 ); // Set gain to lower so it's less sensitive
70+ // Enable the gesture sensor as well
71+ display.apds9960 .enableGestureSensor ();
72+ display.apds9960 .setGestureGain (0 ); // Also set gain to lower so it's less sensitive
73+ // Finally, enable the light sensor
74+ display.apds9960 .enableLightSensor (false );
75+ // Config is done
76+
77+ // Show the initial picture on the display with a full refresh
78+ display.display ();
79+ }
80+
81+ // This code runs repeteadly
82+ void loop ()
83+ {
84+ // Make all the readings from the APDS in order
85+ // Review these functions for details on how it works
86+ readProximity ();
87+ detectGesture ();
88+ readColor ();
89+ readLight ();
90+
91+ // Update the display if different data was read
92+ if (dataHasChanged)
93+ {
94+ updateDisplay ();
95+ }
96+
97+ delay (250 ); // Add a small delay between readings
98+ }
99+
100+ // Detect a swiping gesture in front of the sensor
101+ void detectGesture ()
102+ {
103+ if (display.apds9960 .isGestureAvailable ())
104+ {
105+ // The sensor has detected a gesture, so it should get printed
106+
107+ dataHasChanged = true ; // Set the flag which updates the display
108+
109+ // Clear previously written data and set the cursor in the correct place
110+ display.fillRect (323 , 72 , 263 , 118 , WHITE);
111+ display.setCursor (423 , 125 );
112+ display.setTextSize (4 );
113+
114+ // Read the gesture
115+ int gesture = display.apds9960 .readGesture ();
116+ switch (gesture)
117+ {
118+ // Depending on which gesture was recorded, print different data
119+ case DIR_UP:
120+ display.print (" Up" );
121+ break ;
122+
123+ case DIR_DOWN:
124+ display.print (" Down" );
125+ break ;
126+
127+ case DIR_LEFT:
128+ display.print (" Left" );
129+ break ;
130+
131+ case DIR_RIGHT:
132+ display.print (" Right" );
133+ break ;
134+
135+ default :
136+ // Do nothing
137+ break ;
138+ }
139+ }
140+ }
141+
142+ // Get data for proximity as an 8-bit value
143+ void readProximity ()
144+ {
145+ // Get the proximity the sensor is reading at thism moment
146+ // Note the datatype is uint8_t
147+ uint8_t proximity = 0 ;
148+ display.apds9960 .readProximity (proximity);
149+
150+ // If it's different than last time, print it
151+ if (proximity != lastProximityMeasured)
152+ {
153+ dataHasChanged = true ; // Set the flag which updates the display
154+
155+ display.fillRect (21 , 72 , 249 , 118 , WHITE);
156+ display.setTextSize (4 );
157+ display.setCursor (75 , 125 );
158+ display.print (proximity);
159+ lastProximityMeasured = proximity; // Remember new data for later
160+ }
161+ }
162+
163+ // Read the red, green and blue light values
164+ void readColor ()
165+ {
166+
167+ // Same principle as readProximity, note the data type
168+ uint16_t redLight = 0 ;
169+ uint16_t greenLight = 0 ;
170+ uint16_t blueLight = 0 ;
171+ display.apds9960 .readRedLight (redLight);
172+ display.apds9960 .readGreenLight (greenLight);
173+ display.apds9960 .readBlueLight (blueLight);
174+
175+ // If any of these has changed from before, print new data
176+ if (redLight != lastRedLightMeasured || greenLight != lastGreenLightMeasured || blueLight != lastBlueLightMeasured)
177+ {
178+ dataHasChanged = true ; // Set the flag which updates the display
179+
180+ // Clear old data in the frame buffer, set the cursors in the correct place and write new data
181+ display.fillRect (21 , 409 , 249 , 126 , WHITE);
182+ display.setTextSize (3 );
183+ display.setCursor (32 , 409 );
184+ display.print (" Red: " );
185+ display.print (redLight);
186+ display.setCursor (32 , 434 );
187+ display.print (" Green: " );
188+ display.print (greenLight);
189+ display.setCursor (32 , 459 );
190+ display.print (" Blue: " );
191+ display.print (blueLight);
192+
193+ // Remember this for later so we only have to update the display when this changes
194+ lastRedLightMeasured = redLight;
195+ lastGreenLightMeasured = greenLight;
196+ lastBlueLightMeasured = blueLight;
197+ }
198+ }
199+
200+ // Read the ambient light sensor data for all light
201+ void readLight ()
202+ {
203+ // Same principle as in readColor()
204+ uint16_t ambientLight = 0 ;
205+ display.apds9960 .readAmbientLight (ambientLight);
206+
207+ // If the value has changed, print the data to the screen
208+ if (ambientLight != lastAmbientLightMeasured)
209+ {
210+ dataHasChanged = true ; // Set the flag which updates the display
211+
212+ display.fillRect (323 , 409 , 249 , 126 , WHITE); // Clear old value
213+ display.setTextSize (4 );
214+ display.setCursor (413 , 425 );
215+ display.print (ambientLight);
216+
217+ lastAmbientLightMeasured = ambientLight;
218+ }
219+ }
220+
221+ // This function updates the display with the new data in the frame buffer
222+ // It does partial updates until NUM_UPDATES_BEFORE_FULL_REFRESH is reached
223+ // Then it does a full refresh and resets the coutner
224+ void updateDisplay ()
225+ {
226+ if (numUpdates >= NUM_UPDATES_BEFORE_FULL_REFRESH)
227+ {
228+ display.display ();
229+ numUpdates = 0 ;
230+ }
231+ else
232+ {
233+ display.partialUpdate (false , true );
234+ numUpdates++;
235+ }
236+ dataHasChanged = false ;
237+ }
0 commit comments