Skip to content

Commit 4573542

Browse files
version 2.4.2
1 parent 303cfc5 commit 4573542

19 files changed

Lines changed: 1314 additions & 509 deletions

File tree

README.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,14 @@ sudo make install
5656
* Run following command to download latest release from github.
5757

5858
```sh
59-
curl -sL https://github.com/gavinlyonsrepo/Display_Lib_RPI/archive/2.4.1.tar.gz | tar xz
59+
curl -sL https://github.com/gavinlyonsrepo/Display_Lib_RPI/archive/2.4.2.tar.gz | tar xz
6060
```
6161

6262
3. Install library : Run 'make' and 'sudo make install' to run the makefile to build and then install library.
6363
* It will be installed to usr/local/lib and usr/local/include by default.
6464

6565
```sh
66-
cd Display_Lib_RPI-2.4.1
66+
cd Display_Lib_RPI-2.4.2
6767
make
6868
sudo make install
6969
```
@@ -140,7 +140,7 @@ Library naming :
140140
5. Installed size = ~500 KiB.
141141
6. Namespaces see API.documentation.
142142

143-
Project Overview :
143+
Project class overview :
144144

145145
[![pov img](https://github.com/gavinlyonsrepo/Display_Lib_RPI/blob/main/extra/images/project.jpg)](https://github.com/gavinlyonsrepo/Display_Lib_RPI/blob/main/extra/images/project.jpg)
146146

@@ -166,8 +166,9 @@ is in the 'doc' folder [at link.](extra/doc/error_codes/README.md)
166166
A configuration file can be created which is read into program by running "rdlib_config::loadConfig()" at start of program
167167
If the file is missing it will create it at "/($HOME)/.config/rdlib_config/config.cfg".
168168
In this file logging and debug modes can be enabled they are OFF by default. A path to log file can also be
169-
set. Certain functions produce debug information to console if this setting is enabled.
170-
Some errors conditions trigger logging if it is enabled.
169+
set. Certain functions produce debug information to console if the debug setting is enabled.
170+
Some errors conditions trigger logging if the logging setting is enabled. The logging function
171+
can also be used in user applications: see file examples/misc_test/utilities_test/main.cpp.
171172

172173
Config file :
173174

examples/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,11 +115,12 @@
115115

116116
# =============== ILI9341 TFT LCD SPI ============
117117
#SRC=ili9341/hello_world
118-
#SRC=ili9341/hello_world_swspi
119118
#SRC=ili9341/bitmap_tests
120119
#SRC=ili9341/text_graphics_functions
121120
#SRC=ili9341/demos
122121
#SRC=ili9341/touch_screen
122+
#SRC=ili9341/hello_world_swspi
123+
#SRC=ili9341/read_diagnostic_swspi
123124
#=================================================
124125

125126
# =============== SSD1331 TFT LCD SPI ============

examples/gc9a01/demos/main.cpp

Lines changed: 92 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,8 @@
66
-# test 440 Round Gauge
77
-# test 441 Arc Meter
88
-# test 442 Rotary Menu Dial (Keyboard Input)
9-
-# test 443 Music Visualizer Dial
109
-# test 444 analog Clock Demo
1110
-# test 445 volume Knob Demo (Keyboard Input)
12-
@todo GC9A01 music visualize
1311
*/
1412

1513
// Section :: libraries
@@ -53,13 +51,11 @@ void drawPointerHelper(int16_t val, uint8_t x, uint8_t y, uint8_t r, uint16_t co
5351
void drawGaugeMarkers(uint8_t centerX, uint8_t centerY, uint8_t radius, int startAngle, int endAngle, float scaleFactor, uint16_t color);
5452
void drawPointer(int16_t &val, int16_t &oldVal , uint8_t x, uint8_t y, uint8_t r, uint16_t color, uint16_t bcolor);
5553
// === Demo 3 ===
56-
void rotaryMenuDemo(void) ; //demo 3
57-
int getchar_timeout(int timeout_ms); // demo 3
54+
void rotaryMenuDemo(void);
55+
int getchar_timeout(int timeout_ms);
5856
// === Demo 4 ===
59-
void musicVisualizerDialDemo(uint16_t countLimit = 50);
60-
// === Demo 5 ===
6157
void analogClockDemo(uint16_t countLimit = 50);
62-
// === Demo 6 ===
58+
// === Demo 5 ===
6359
void volumeKnobDemo(void);
6460

6561
// Section :: MAIN loop
@@ -75,25 +71,24 @@ int main()
7571
if (std::cin.fail()) {
7672
std::cin.clear(); // Clear error flag
7773
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // Discard invalid input
78-
std::cout << "Invalid input. Please enter a number between 1 and 4.\n\n";
74+
std::cout << "Invalid input. Please enter a number between 1 and 5.\n\n";
7975
continue;
8076
}
8177
switch (choice) {
8278
case 1: gaugeDemo(100); break;
8379
case 2: arcGauge(100); break;
8480
case 3: rotaryMenuDemo() ; break;
85-
case 4: musicVisualizerDialDemo(50); break;
86-
case 5: analogClockDemo(50); break;
87-
case 6: volumeKnobDemo(); break;
88-
case 7:
81+
case 4: analogClockDemo(50); break;
82+
case 5: volumeKnobDemo(); break;
83+
case 6:
8984
std::cout << "Exiting menu\n";
9085
break;
9186
default:
9287
std::cout << "Invalid choice. Please try again.\n";
9388
break;
9489
}
9590
std::cout << std::endl;
96-
} while (choice != 7);
91+
} while (choice != 6);
9792

9893
EndTests();
9994
return 0;
@@ -135,10 +130,9 @@ void displayMenu() {
135130
std::cout << "1. Round Gauge Demo\n";
136131
std::cout << "2. Arc Gauge Demo\n";
137132
std::cout << "3. Rotary Menu Demo\n";
138-
std::cout << "4. Music Visualizer Dial Demo\n";
139-
std::cout << "5. Analog Clock Demo\n";
140-
std::cout << "6. Volume Knob Demo\n";
141-
std::cout << "7. Quit\n";
133+
std::cout << "4. Analog Clock Demo\n";
134+
std::cout << "5. Volume Knob Demo\n";
135+
std::cout << "6. Quit\n";
142136
std::cout << "Enter your choice: ";
143137
}
144138

@@ -163,8 +157,8 @@ void signal_callback_handler(int signum)
163157
void gaugeDemo(uint16_t countLimit) // Demo 1
164158
{
165159
std::cout << "Gauge Demo 1 ends at seconds: " << countLimit << std::endl;
166-
int16_t currentValue = 100;
167-
int16_t oldValue = 100;
160+
int16_t currentValue = 120;
161+
int16_t oldValue = 120;
168162
myTFT.setFont(font_mega);
169163
char buffer[10];
170164
// Draw Gauge
@@ -213,7 +207,7 @@ void arcGauge(uint16_t countLimit) // demo 2
213207
// Draw Gauge
214208
uint16_t count = 1;
215209
uint16_t x = 120;
216-
uint16_t y = 120;
210+
uint16_t y =120;
217211
uint16_t radius = 90;
218212
const int16_t minValue = 1;
219213
const int16_t maxValue = 255;
@@ -250,79 +244,6 @@ void arcGauge(uint16_t countLimit) // demo 2
250244
std::cout << "Arc Gauge Demo Over" << std::endl;
251245
}
252246

253-
void rotaryMenuDemo()
254-
{
255-
std::cout << "Demo 3 Start: press a or d to move pointer , q to quit" << std::endl;
256-
myTFT.setFont(font_default);
257-
constexpr uint8_t centerX = 120;
258-
constexpr uint8_t centerY = 120;
259-
constexpr uint8_t radius = 60;
260-
constexpr uint8_t itemCount = 6;
261-
constexpr uint8_t nodeRadius = 16;
262-
struct MenuItem { const char* label; };
263-
MenuItem items[itemCount] = {
264-
{"Volts"}, {"Power"}, {"Amps"},
265-
{"Watts"}, {"System"}, {"Diode"}
266-
};
267-
268-
auto drawItem = [&](uint8_t index, bool selected) {
269-
float angle = 2.0f * std::numbers::pi * index / itemCount;
270-
int x = centerX + static_cast<int>(radius * std::cos(angle));
271-
int y = centerY + static_cast<int>(radius * std::sin(angle));
272-
273-
uint16_t color = selected ? myTFT.RDLC_RED : myTFT.RDLC_WHITE;
274-
myTFT.fillCircle(x, y, nodeRadius, color);
275-
myTFT.setTextColor(myTFT.RDLC_BLACK, color);
276-
277-
char c[2] = { items[index].label[0], '\0' };
278-
myTFT.writeCharString(x - 3, y - 4, c);
279-
};
280-
281-
auto drawPointer = [&](uint8_t index, uint16_t color) {
282-
float angle = 2.0f * std::numbers::pi * index / itemCount;
283-
constexpr uint8_t pointerLength = radius - 10;
284-
int x1 = centerX + static_cast<int>(pointerLength * std::cos(angle));
285-
int y1 = centerY + static_cast<int>(pointerLength * std::sin(angle));
286-
myTFT.drawLine(centerX, centerY, x1, y1, color);
287-
myTFT.fillCircle(centerX, centerY, 2, myTFT.RDLC_GREEN);
288-
};
289-
myTFT.fillScreen(myTFT.RDLC_BLACK);
290-
myTFT.setTextColor(myTFT.RDLC_WHITE, myTFT.RDLC_BLACK);
291-
myTFT.drawArc(centerX, centerY, radius+40, 10 ,135.0f, 45.0f, myTFT.RDLC_GREEN);
292-
for (uint8_t i = 0; i < itemCount; ++i){
293-
drawItem(i, i == 0);}
294-
uint8_t selected = 0;
295-
int8_t oldSelected = -1;
296-
drawPointer(selected, myTFT.RDLC_YELLOW);
297-
while (true) {
298-
int ch = getchar_timeout(1000);
299-
if (ch == 'q' || ch == 'Q') break;
300-
oldSelected = selected;
301-
if (ch == 'a' || ch == 'A')
302-
selected = (selected + itemCount - 1) % itemCount;
303-
if (ch == 'd' || ch == 'D')
304-
selected = (selected + 1) % itemCount;
305-
if (selected != oldSelected) {
306-
drawPointer(oldSelected, myTFT.RDLC_BLACK); // erase
307-
drawItem(oldSelected, false);
308-
drawItem(selected, true);
309-
drawPointer(selected, myTFT.RDLC_YELLOW); // draw new
310-
// label below
311-
myTFT.setFont(font_mega);
312-
myTFT.setTextColor(myTFT.RDLC_RED, myTFT.RDLC_YELLOW);
313-
myTFT.fillRect(centerX - 30, centerY + radius + 35, 80, 16, myTFT.RDLC_BLACK);
314-
char buf[20];
315-
std::strncpy(buf, items[selected].label, sizeof(buf));
316-
buf[sizeof(buf) - 1] = '\0';
317-
myTFT.writeCharString(centerX-50, centerY + radius + 35, buf);
318-
myTFT.setFont(font_default);
319-
}
320-
}
321-
myTFT.fillScreen(myTFT.RDLC_BLACK);
322-
std::cout << "Demo 3 Over" << std::endl;
323-
}
324-
325-
326247
void drawGaugeMarkers(uint8_t centerX, uint8_t centerY, uint8_t radius, int startAngle, int endAngle, float scaleFactor, uint16_t color)
327248
{
328249
float angleRad, innerX, innerY, outerX, outerY;
@@ -347,7 +268,7 @@ void drawGaugeMarkers(uint8_t centerX, uint8_t centerY, uint8_t radius, int star
347268

348269
void drawPointer(int16_t &currentValue, int16_t &oldValue, uint8_t x, uint8_t y, uint8_t r, uint16_t colour, uint16_t bcolour)
349270
{
350-
uint8_t i;
271+
uint16_t i;
351272
// If the current value is increasing
352273
if (currentValue > oldValue)
353274
{
@@ -434,67 +355,90 @@ int getchar_timeout(int timeout_ms) {
434355
return ch;
435356
}
436357

437-
/*!
438-
@brief demo 4 Music visualizer radial dial demo.
439-
@param count Duration in seconds to run the animation.
440-
@details This creates a circular music visualizer using randomized bar heights and color gradients.
441-
A pulsing center circle and a rotating rainbow arc enhance visual rhythm.
442-
Includes a simulated BPM counter for additional display dynamics.
443-
*/
444-
void musicVisualizerDialDemo(uint16_t count)
358+
void rotaryMenuDemo()
445359
{
446-
std::cout << "Music Visualizer Dial Start : Ends in Seconds : " << count << std::endl;
447-
constexpr uint16_t timeDelay = 200; // ms
360+
std::cout << "Demo 3 Start: press a or d to move pointer , q to quit" << std::endl;
361+
myTFT.setFont(font_default);
448362
constexpr uint8_t centerX = 120;
449363
constexpr uint8_t centerY = 120;
450-
constexpr uint8_t radiusInner = 20;
451-
constexpr uint8_t radiusOuter = 100;
452-
constexpr uint8_t barCount = 32;
453-
constexpr float angleStep = 2.0f * std::numbers::pi / barCount;
364+
constexpr uint8_t radius = 60;
365+
constexpr uint8_t itemCount = 6;
366+
constexpr uint8_t nodeRadius = 16;
367+
struct MenuItem { const char* label; };
368+
MenuItem items[itemCount] = {
369+
{"Volts"}, {"Power"}, {"Amps"},
370+
{"Watts"}, {"System"}, {"Diode"}
371+
};
372+
// Lambda to draw each node
373+
auto drawItem = [&](uint8_t index, bool selected) {
374+
float angle = 2.0f * std::numbers::pi * index / itemCount;
375+
int x = centerX + static_cast<int>(radius * std::cos(angle));
376+
int y = centerY + static_cast<int>(radius * std::sin(angle));
377+
uint16_t color = selected ? myTFT.RDLC_RED : myTFT.RDLC_WHITE;
378+
myTFT.fillCircle(x, y, nodeRadius, color);
379+
myTFT.setTextColor(myTFT.RDLC_BLACK, color);
380+
char c[2] = { items[index].label[0], '\0' };
381+
myTFT.writeCharString(x - 3, y - 4, c);
382+
};
383+
// Lambda to draw pointer from center to selected node
384+
auto drawPointer = [&](uint8_t index, uint16_t color) {
385+
float angle = 2.0f * std::numbers::pi * index / itemCount;
386+
constexpr uint8_t pointerLength = radius - 10;
387+
int x1 = centerX + static_cast<int>(pointerLength * std::cos(angle));
388+
int y1 = centerY + static_cast<int>(pointerLength * std::sin(angle));
389+
myTFT.drawLine(centerX, centerY, x1, y1, color);
390+
myTFT.fillCircle(centerX, centerY, 2, myTFT.RDLC_GREEN);
391+
};
454392
myTFT.fillScreen(myTFT.RDLC_BLACK);
455-
srand(time(NULL));
456-
uint8_t hueOffset = 0;
457-
458-
while (count-- > 0)
459-
{
460-
// Outer dynamic rainbow arc
461-
for (uint8_t i = 0; i < barCount; ++i) {
462-
float angleStart = i * angleStep * 180.0f / std::numbers::pi;
463-
float angleEnd = angleStart + angleStep * 180.0f / std::numbers::pi;
464-
uint16_t arcColor = rdlib_maths::generateColor((i + hueOffset) % 128);
465-
myTFT.drawSimpleArc(centerX, centerY, radiusOuter + 18, angleStart, angleEnd, arcColor);
466-
}
467-
hueOffset += 3;
468-
// Audio bars
469-
for (uint8_t i = 0; i < barCount; ++i) {
470-
float angle = i * angleStep - std::numbers::pi / 2.0f;
471-
uint8_t level = rand() % 128;
472-
uint16_t color = rdlib_maths::generateColor(level);
473-
float magnitude = static_cast<float>(level) / 127.0f;
474-
uint8_t dynamicOuter = radiusInner + static_cast<uint8_t>((radiusOuter - radiusInner) * magnitude);
475-
int16_t x0 = centerX + radiusInner * cos(angle);
476-
int16_t y0 = centerY + radiusInner * sin(angle);
477-
int16_t x1 = centerX + dynamicOuter * cos(angle);
478-
int16_t y1 = centerY + dynamicOuter * sin(angle);
479-
myTFT.drawLine(x0, y0, x1, y1, color);
393+
myTFT.setTextColor(myTFT.RDLC_WHITE, myTFT.RDLC_BLACK);
394+
myTFT.drawArc(centerX, centerY, radius + 40, 10, 135.0f, 45.0f, myTFT.RDLC_GREEN);
395+
// Draw all menu nodes, initially selecting the first
396+
for (uint8_t i = 0; i < itemCount; ++i){
397+
drawItem(i, i == 0);}
398+
uint8_t selected = 0;
399+
int8_t oldSelected = -1;
400+
// Draw pointer to initial selection
401+
drawPointer(selected, myTFT.RDLC_YELLOW);
402+
// inline label drawing
403+
myTFT.setFont(font_mega);
404+
myTFT.setTextColor(myTFT.RDLC_RED, myTFT.RDLC_YELLOW);
405+
myTFT.fillRectangle(centerX - 30, centerY + radius + 35, 80, 16, myTFT.RDLC_YELLOW);
406+
char buf[20];
407+
std::strncpy(buf, items[selected].label, sizeof(buf));
408+
buf[sizeof(buf) - 1] = '\0';
409+
myTFT.writeCharString(centerX - 50, centerY + radius + 35, buf);
410+
// --- Main input loop ---
411+
while (true) {
412+
int ch = getchar_timeout(1000);
413+
if (ch == 'q' || ch == 'Q') break;
414+
oldSelected = selected;
415+
if (ch == 'a' || ch == 'A')
416+
selected = (selected + itemCount - 1) % itemCount;
417+
if (ch == 'd' || ch == 'D')
418+
selected = (selected + 1) % itemCount;
419+
if (selected != oldSelected)
420+
{
421+
// Erase old pointer and node
422+
drawPointer(oldSelected, myTFT.RDLC_BLACK);
423+
drawItem(oldSelected, false);
424+
// Draw new pointer and node
425+
drawItem(selected, true);
426+
drawointer(selected, myTFT.RDLC_YELLOW);
427+
// Draw updated label below the new selection
428+
myTFT.setFont(font_mega);
429+
myTFT.setTextColor(myTFT.RDLC_RED, myTFT.RDLC_YELLOW);
430+
myTFT.fillRectangle(centerX - 30, centerY + radius + 35, 80, 16, myTFT.RDLC_YELLOW);
431+
std::strncpy(buf, items[selected].label, sizeof(buf));
432+
buf[sizeof(buf) - 1] = '\0';
433+
myTFT.writeCharString(centerX - 50, centerY + radius + 35, buf);
434+
myTFT.setFont(font_default);
480435
}
481-
// Center pulse
482-
uint8_t pulseRadius = 5 + (rand() % 10);
483-
uint16_t pulseColor = rdlib_maths::generateColor(rand() % 128);
484-
myTFT.fillCircle(centerX, centerY, pulseRadius, pulseColor);
485-
// Simulated BPM display
486-
//char bpmBuf[12];
487-
//snprintf(bpmBuf, sizeof(bpmBuf), "BPM %03d", 60 + rand() % 60);
488-
//std::cout << "\r" << bpmBuf << std::flush;
489-
490-
delayMilliSecRDL(timeDelay);
491-
myTFT.fillScreen(myTFT.RDLC_BLACK);
492436
}
493-
494-
std::cout << "Music Visualizer Dial end" << std::endl;
437+
myTFT.fillScreen(myTFT.RDLC_BLACK);
438+
std::cout << "Demo 3 Over" << std::endl;
495439
}
496440

497-
// Demo 5
441+
// Demo 4
498442
void analogClockDemo(uint16_t countLimit)
499443
{
500444
myTFT.fillScreen(myTFT.RDLC_BLACK);
@@ -553,7 +497,7 @@ void analogClockDemo(uint16_t countLimit)
553497
std::cout << "Clock Demo over : " <<std::endl;
554498
}
555499

556-
// Demo 6
500+
// Demo 5
557501
void volumeKnobDemo(void)
558502
{
559503
myTFT.fillScreen(myTFT.RDLC_BLACK);

0 commit comments

Comments
 (0)