Skip to content

Commit 1128ecb

Browse files
authored
Merge branch 'benjamindannegard/giga-display-shield-launch-branch' into karlsoderby/gds-prod-review
2 parents eeecaee + 82fdec8 commit 1128ecb

File tree

6 files changed

+246
-16
lines changed

6 files changed

+246
-16
lines changed

content/hardware/10.mega/shields/giga-display-shield/tutorials/draw-and-image/content.md renamed to content/hardware/10.mega/shields/giga-display-shield/tutorials/basic-draw-and-image/content.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
2-
title: Using Basic Draw Functions with the GIGA Display Shield
3-
description: 'Learn how to use basic draw functions to create images on the GIGA Display Shield.'
2+
title: Using Draw and Image Functions with the GIGA Display Shield
3+
description: 'Learn how to use basic draw functions to create and display images on the GIGA Display Shield.'
44
author: Benjamin Dannegård
55
tags: [Display, Draw]
66
---

content/hardware/10.mega/shields/giga-display-shield/tutorials/camera-tutorial/content.md

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,11 @@ The GIGA Display Shield comes with an Arducam camera connector. In this tutorial
1414
- [Arduino GIGA R1 WiFi](/hardware/giga-r1)
1515
- [Arduino GIGA Display Shield]()
1616
- [Arduino IDE](https://www.arduino.cc/en/software)
17-
- HM01B0 or HM0360 camera
18-
- [Arducam_dvp library](https://www.arduino.cc/reference/en/libraries/arducam_dvp/)
17+
- HM01B0, HM0360, GC2145 or OV7675 camera
1918

2019
## Downloading the Library and Core
2120

22-
The Arduino Mbed OS Giga Boards core contains most of the libraries you need to work with the shield's camera connector. To install the core for GIGA boards, navigate to **Tools > Board > Boards Manager** or click the Boards Manager icon in the left tab of the IDE. In the Boards Manager tab, search for giga and install the latest Arduino Mbed OS Giga Boards version, the [Arduino_H7_Video library](https://github.com/arduino/ArduinoCore-mbed/tree/main/libraries/Arduino_H7_Video) library is included in the core. Now open the library tab on the left, search for **Arducam_dvp**, and install this library.
21+
The Arduino Mbed OS Giga Boards core contains most of the libraries you need to work with the shield's camera connector. To install the core for GIGA boards, navigate to **Tools > Board > Boards Manager** or click the Boards Manager icon in the left tab of the IDE. In the Boards Manager tab, search for giga and install the latest Arduino Mbed OS Giga Boards version, the [Arduino_H7_Video library](https://github.com/arduino/ArduinoCore-mbed/tree/main/libraries/Arduino_H7_Video) library is included in the core. Now open the library tab on the left, search for [**Arducam_dvp**](https://www.arduino.cc/reference/en/libraries/arducam_dvp/), and install this library.
2322

2423
![Library tab in the Arduino IDE](assets/ide-library.svg)
2524

@@ -29,6 +28,8 @@ The GIGA Display Shield is compatible with the following cameras:
2928

3029
- [HM01B0](https://www.arducam.com/product/hm01b0-qvga-monochrome-dvp-camera-module-for-arduino-giga-r1-wifi-board/)
3130
- [HM0360](https://www.arducam.com/product/hm0360-vga-monochrome-dvp-camera-module-for-arduino-giga-r1-wifi-board/)
31+
- [GC2145](https://www.arducam.com/product/2mp-gc2145-color-dvp-camera-module-for-arduino-giga-r1-wifi-board/)
32+
- [OV7675](https://store.arduino.cc/products/arducam-camera-module?queryID=undefined)
3233

3334
Connect the camera to the connector on the front of the display shield as shown in the image below.
3435

@@ -67,13 +68,11 @@ Camera cam(himax);
6768
OV7675 ov767x;
6869
Camera cam(ov767x);
6970
#define IMAGE_MODE CAMERA_RGB565
70-
#error "Unsupported camera (at the moment :) )"
7171
#elif defined(ARDUCAM_CAMERA_GC2145)
7272
#include "GC2145/gc2145.h"
7373
GC2145 galaxyCore;
7474
Camera cam(galaxyCore);
7575
#define IMAGE_MODE CAMERA_RGB565
76-
#error "Unsupported camera (at the moment :) )"
7776
#endif
7877
7978
// The buffer used to capture the frame
@@ -108,9 +107,11 @@ void setup() {
108107
}
109108
110109
Display.begin();
111-
dsi_configueCLUT((uint32_t*)palette);
112110
113-
outfb.setBuffer((uint8_t*)SDRAM.malloc(1024*1024));
111+
if (IMAGE_MODE == CAMERA_GRAYSCALE) {
112+
dsi_configueCLUT((uint32_t*)palette);
113+
}
114+
outfb.setBuffer((uint8_t*)SDRAM.malloc(1024 * 1024));
114115
115116
// clear the display (gives a nice black background)
116117
dsi_lcdClear(0);
@@ -119,6 +120,8 @@ void setup() {
119120
dsi_drawCurrentFrameBuffer();
120121
}
121122
123+
#define HTONS(x) (((x >> 8) & 0x00FF) | ((x << 8) & 0xFF00))
124+
122125
void loop() {
123126
124127
// Grab frame and write to another framebuffer
@@ -128,13 +131,20 @@ void loop() {
128131
// this only works if the camera feed is 320x240 and the area where we want to display is 640x480
129132
for (int i = 0; i < 320; i++) {
130133
for (int j = 0; j < 240; j++) {
131-
((uint8_t*)outfb.getBuffer())[j * 2 + (i * 2) * 480] = ((uint8_t*)fb.getBuffer())[i + j * 320];
132-
((uint8_t*)outfb.getBuffer())[j * 2 + (i * 2) * 480 + 1] = ((uint8_t*)fb.getBuffer())[i + j * 320];
133-
((uint8_t*)outfb.getBuffer())[j * 2 + (i * 2 + 1) * 480] = ((uint8_t*)fb.getBuffer())[i + j * 320];
134-
((uint8_t*)outfb.getBuffer())[j * 2 + (i * 2 + 1) * 480 + 1] = ((uint8_t*)fb.getBuffer())[i + j * 320];
134+
if (IMAGE_MODE == CAMERA_GRAYSCALE) {
135+
((uint8_t*)outfb.getBuffer())[j * 2 + (i * 2) * 480] = ((uint8_t*)fb.getBuffer())[i + j * 320];
136+
((uint8_t*)outfb.getBuffer())[j * 2 + (i * 2) * 480 + 1] = ((uint8_t*)fb.getBuffer())[i + j * 320];
137+
((uint8_t*)outfb.getBuffer())[j * 2 + (i * 2 + 1) * 480] = ((uint8_t*)fb.getBuffer())[i + j * 320];
138+
((uint8_t*)outfb.getBuffer())[j * 2 + (i * 2 + 1) * 480 + 1] = ((uint8_t*)fb.getBuffer())[i + j * 320];
139+
} else {
140+
((uint16_t*)outfb.getBuffer())[j * 2 + (i * 2) * 480] = HTONS(((uint16_t*)fb.getBuffer())[i + j * 320]);
141+
((uint16_t*)outfb.getBuffer())[j * 2 + (i * 2) * 480 + 1] = HTONS(((uint16_t*)fb.getBuffer())[i + j * 320]);
142+
((uint16_t*)outfb.getBuffer())[j * 2 + (i * 2 + 1) * 480] = HTONS(((uint16_t*)fb.getBuffer())[i + j * 320]);
143+
((uint16_t*)outfb.getBuffer())[j * 2 + (i * 2 + 1) * 480 + 1] = HTONS(((uint16_t*)fb.getBuffer())[i + j * 320]);
144+
}
135145
}
136146
}
137-
dsi_lcdDrawImage((void*)outfb.getBuffer(), (void*)dsi_getCurrentFrameBuffer(), 480, 640, DMA2D_INPUT_L8);
147+
dsi_lcdDrawImage((void*)outfb.getBuffer(), (void*)dsi_getCurrentFrameBuffer(), 480, 640, IMAGE_MODE == CAMERA_GRAYSCALE ? DMA2D_INPUT_L8 : DMA2D_INPUT_RGB565);
138148
dsi_drawCurrentFrameBuffer();
139149
} else {
140150
blinkLED(20);
@@ -145,4 +155,3 @@ void loop() {
145155
## Conclusion
146156

147157
This tutorial went through how to connect a compatible camera to the shield and also how to test it out quickly with the example sketch included in the core. Now you should see a live feed from the camera on your GIGA Display Shield!
148-

content/hardware/10.mega/shields/giga-display-shield/tutorials/lvgl-guide/content.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -700,4 +700,6 @@ This guide went through the building blocks of the different components that can
700700
This example sketch will show the different components in a 2x2 grid.
701701

702702
## Next Step
703-
LVGL has a lot of customizability, if you are interested in playing around more with this, you can find many different examples on the official website for [LVGL](https://docs.lvgl.io/master/examples.html). These can easily be put in a sketch for the GIGA Display Shield just remember to use the display-specific configuration that was shown at the [start of this tutorial](#display-shield-configuration).
703+
LVGL has a lot of customizability, if you are interested in playing around more with this, you can find many different examples on the official website for [LVGL](https://docs.lvgl.io/master/examples.html). These can easily be put in a sketch for the GIGA Display Shield, just remember to use the display-specific configuration that was shown at the [start of this tutorial](#display-shield-configuration).
704+
705+
The GIGA Display Shield features some on-board sensors, like an IMU and a microphone. To see how these can be used with LVGL check out our [Orientation tutorial](/tutorials/image-orientation), which will show you how to use the on-board IMU to rotate an image. Or have a look at our [Microphone tutorial](/tutorials/microphone-tutorial), which will show you how to merge microphone readings with LVGL components.

content/hardware/10.mega/shields/giga-display-shield/tutorials/microphone-tutorial/assets/pdm-test-sketch.svg

Lines changed: 15 additions & 0 deletions
Loading
Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
---
2+
title: Microphone With LVGL Tutorial
3+
description: "Learn how to use the GIGA Display Shield's microphone together with LVGL."
4+
author: Benjamin Dannegård
5+
tags: [Display, microphone, LVGL]
6+
---
7+
8+
The GIGA Display Shield comes equipped with on-board microphone and with the help of LVGL the microphones readings can be visualized on the screen. This tutorial will show you how to create a sketch that ties together the microphones readings with visual elements on the screen.
9+
10+
## Hardware & Software Needed
11+
12+
- [Arduino GIGA R1 WiFi](/hardware/giga-r1)
13+
- [Arduino GIGA Display Shield](/hardware/giga-display-shield)
14+
- [Arduino IDE](https://www.arduino.cc/en/software)
15+
- [LVGL library](https://reference.arduino.cc/reference/en/libraries/lvgl/)
16+
17+
## Downloading the Library and Core
18+
19+
Make sure the latest GIGA core is installed in the Arduino IDE. **Tools > Board > Board Manager...**. Here you need to look for the **Arduino Mbed OS Giga Boards** and install it, the [Arduino_H7_Video library](https://github.com/arduino/ArduinoCore-mbed/tree/main/libraries/Arduino_H7_Video) and [PDM library](https://docs.arduino.cc/learn/built-in-libraries/pdm) are included in the core. Now you have to install the library needed for handling the visual component. Go to **Tools > Manage libraries..**, search for **LVGL**, and install it.
20+
21+
## Microphone Readings With The Shield
22+
23+
### Microphone Test Sketch
24+
25+
To test the microphone we can use the **PDMSerialPlotter** example sketch. This sketch can be found in **File > Examples > PDM** in the Arduino IDE. This sketch will print readings in the serial monitor. Upload the sketch and check so that readings are appearing in the serial monitor.
26+
27+
![Example sketch printing values in the serial monitor](assets/pdm-test-sketch.svg)
28+
29+
### Using the Microphone Readings
30+
31+
Now let's create a sketch that combines the microphone readings with a visual component. First, the libraries we need are, `PDM.h` which will handle the microphone readings and `lvgl.h` will handle the visual elements on the screen.
32+
33+
```arduino
34+
#include <PDM.h>
35+
#include "Arduino_H7_Video.h"
36+
#include "lvgl.h"
37+
```
38+
39+
In the `setup()` we can start the display with `Display.begin();` and the microphone with `PDM.onReceive(onPDMdata);`. This will call the `void onPDMdata()` function at the bottom of the sketch. This function handles collecting and storing the readings from the microphone.
40+
41+
```arduino
42+
void setup() {
43+
Display.begin();
44+
45+
PDM.onReceive(onPDMdata);
46+
47+
if (!PDM.begin(channels, frequency)) {
48+
Serial.println("Failed to start PDM!");
49+
while (1);
50+
}
51+
}
52+
```
53+
54+
In the `setup()` we will also create our LVGL bar and animation for that bar. Make sure you also define the `lv_obj_t * obj;` and `lv_anim_t a;` variables outside of the `setup()` function so they can be used in the `loop()` function later. Now `obj` will be the name of bar object. These next lines will set the bar's position, size and values. After that we can initialize the animation and set the time for the animation. Then we set the animation to our bar with `lv_anim_set_var(&a, obj);`.
55+
56+
```arduino
57+
// Create the bar
58+
obj = lv_bar_create(lv_scr_act());
59+
lv_obj_set_size(obj, 600, 50);
60+
lv_obj_center(obj);
61+
lv_bar_set_value(obj, 500, LV_ANIM_OFF);
62+
63+
// Create the animation for the bar
64+
lv_anim_init(&a);
65+
lv_anim_set_exec_cb(&a, set_slider_val);
66+
lv_anim_set_time(&a, 300);
67+
lv_anim_set_playback_time(&a, 300);
68+
lv_anim_set_var(&a, obj);
69+
```
70+
71+
The microphone readings will be put into a buffer, in the `loop()` we will need to go through all the samples in the buffer. We can do this with a simple `for()` loop. If you ran the previous mic test sketch you will know that the readings can get pretty high in value, to make it fit our LVGL component reduce that value. By assigning the value to our `micValue` variable we can make it fit the visual element and easily use it to set the end value of the animation with `lv_anim_set_values(&a, 0, micValue)`.
72+
73+
```arduino
74+
void loop() {
75+
76+
// Wait for samples to be read
77+
if (samplesRead) {
78+
79+
// Print samples to the serial monitor or plotter
80+
for (int i = 0; i < samplesRead; i++) {
81+
Serial.println(sampleBuffer[i]);
82+
micValue = sampleBuffer[i];
83+
micValue = micValue / 100;
84+
if (micValue > 500)
85+
{
86+
micValue = 500;
87+
}
88+
lv_anim_set_values(&a, 0, micValue);
89+
lv_anim_start(&a);
90+
}
91+
92+
// Clear the read count
93+
samplesRead = 0;
94+
delay(10);
95+
}
96+
lv_timer_handler();
97+
}
98+
```
99+
100+
In the section below you can find the full sketch. If you upload it to your GIGA Display Shield, you should see the same result as the GIF below is showing.
101+
102+
[GIF of sketch running]()
103+
104+
### Full Sketch
105+
106+
```arduino
107+
#include <PDM.h>
108+
#include "Arduino_H7_Video.h"
109+
#include "lvgl.h"
110+
111+
Arduino_H7_Video Display(800, 480, GigaDisplayShield);
112+
113+
static void set_slider_val(void * bar, int32_t val) {
114+
lv_bar_set_value((lv_obj_t *)bar, val, LV_ANIM_ON);
115+
}
116+
117+
// default number of output channels
118+
static const char channels = 1;
119+
120+
// default PCM output frequency
121+
static const int frequency = 16000;
122+
123+
// Buffer to read samples into, each sample is 16-bits
124+
short sampleBuffer[512];
125+
126+
// Number of audio samples read
127+
volatile int samplesRead;
128+
129+
lv_obj_t * obj;
130+
lv_anim_t a;
131+
int micValue;
132+
133+
void setup() {
134+
Display.begin();
135+
136+
PDM.onReceive(onPDMdata);
137+
138+
if (!PDM.begin(channels, frequency)) {
139+
Serial.println("Failed to start PDM!");
140+
while (1);
141+
}
142+
143+
// Create the bar
144+
obj = lv_bar_create(lv_scr_act());
145+
lv_obj_set_size(obj, 600, 50);
146+
lv_obj_center(obj);
147+
lv_bar_set_value(obj, 500, LV_ANIM_OFF);
148+
149+
// Create the animation for the bar
150+
lv_anim_init(&a);
151+
lv_anim_set_exec_cb(&a, set_slider_val);
152+
lv_anim_set_time(&a, 300);
153+
lv_anim_set_playback_time(&a, 300);
154+
lv_anim_set_var(&a, obj);
155+
}
156+
157+
void loop() {
158+
159+
// Wait for samples to be read
160+
if (samplesRead) {
161+
162+
// Print samples to the serial monitor or plotter
163+
for (int i = 0; i < samplesRead; i++) {
164+
Serial.println(sampleBuffer[i]);
165+
micValue = sampleBuffer[i];
166+
micValue = micValue / 100;
167+
if (micValue > 500)
168+
{
169+
micValue = 500;
170+
}
171+
lv_anim_set_values(&a, 0, micValue);
172+
lv_anim_start(&a);
173+
}
174+
175+
// Clear the read count
176+
samplesRead = 0;
177+
delay(10);
178+
}
179+
lv_timer_handler();
180+
}
181+
182+
/**
183+
* Callback function to process the data from the PDM microphone.
184+
* NOTE: This callback is executed as part of an ISR.
185+
* Therefore using `Serial` to print messages inside this function isn't supported.
186+
* */
187+
void onPDMdata() {
188+
// Query the number of available bytes
189+
int bytesAvailable = PDM.available();
190+
191+
// Read into the sample buffer
192+
PDM.read(sampleBuffer, bytesAvailable);
193+
194+
// 16-bit, 2 bytes per sample
195+
samplesRead = bytesAvailable / 2;
196+
}
197+
```
198+
199+
## Conclusion
200+
201+
Now you know how to get readings from the GIGA Display Shield's on-board microphone and how to create simple visual elements with LVGL. And lastly, how these two components could be put together in a sketch to utilize the shield's screen and on-board components.
202+
203+
## Next Step
204+
Now that you know how to use the on-board microphone, feel free to explore the shield's other features, like the IMU with our [Orientation tutorial](/tutorials/image-orientation). Or if you rather dive deeper into LVGL, take a look at our [LVGL guide](tutorials/lvgl-guide).

0 commit comments

Comments
 (0)