Zephyr is tough, video is out eventually here.
Hardware pitch"Explore opportunities where navigation, mobility, and communication can be made more efficient or provide assistance to the elderly, disabled, or children."
This simple sentence in contest overview was the main source of inspiration for my project idea and hardware application for "Make it Matter!". One major shared issue unites two of the three target populations: loneliness.
Social isolation is now well-known to significantly increase a person's risk of premature death from all causes. What is worse, loneliness disproportionately affects elderly people and those living with disabilities - the very individuals that may struggle to combat loneliness without external help.
Loneliness is a tough problem to solve. People across the globe have tried numerous approaches, including some ingenious robots and AI-driven gadgets to substitute for human connections. However, I believe nothing can replace interactions with those you love and care about. Instead of looking for a complex solution, I pitched a simple concept that does not re-invent the wheel - it simply reminds you to push it.
nRF7002 DK is the brain of this project. It's role is simple - to be as invisible as possible. Connected to some environmental sensors, it is given a very simple role - to monitor the environment and look for important cues in an elderly or disabled person's home. The information will be converted and sent to the carer, highlighting some crucial information about their dependant's wellbeing and giving a reason or two to get in touch and check-up on them.
Long story short, this seemingly simple solution to a complex problem was one of the 100 pitches that got awarded free hardware. After receiving an SMS from DHL, I couldn't wait to get my hands on the nRF7002 DK, and in a few hours I was setting up my IDE.
Zephyr applications are complexThe first few steps are easy. nRF Connect SDK Fundamentals guides you through VSC plugin installation and shows how to run some simple examples. Blinky and Matter Lightbulb samples all work like a charm, giving you a false impression that the rest of this journey will be smoother than your speedometer arrow going up on an autobahn.
Disillusionment caught up with me the moment I tried interfacing external modules with my new nRF7002 DK. Before digging out my ST7735r display and some jumper wires, I opened the display driver sample, hit the "Build" button... and got a build error. After a few hours on Google and kind help from contest's Discord channel, I realised two crucial things:
1. Any hardware you use has to be defined in a separate Devicetree overlay file, including most of the on-board hardware.
2. There is little-to-no guidance online that shows what exactly this overlay file should include.
In contrast with convenient and simple #include from Arduino IDE, overlay files can require fairly specific detail that you need to dig out of 150-page product manuals (or said Arduino libraries, if you are lazy like me). Overlays can also end up rather complex, with no clear way of understanding which of the variables you find in Zephyr docs need definitions, unless you are lucky enough to find one of the scarce examples online or have support from an expert.
Here is the final overlay for my display that resulted in a successful build with display sample. The overlay file needs to be placed in a /boards folder inside your application (/display/boards). Its name has to be identical to the name of the board in build configuration, e.g. nrf7002dk_nrf5340_cpuapp.overlay:
// Display sample overlay for st7735r
&spi2 {
status = "okay";
pinctrl-0 = <&spi2_default>;
pinctrl-names = "default";
cs-gpios = <&gpio0 18 GPIO_ACTIVE_LOW>;
st7735r: st7735r@0 {
compatible = "sitronix,st7735r";
spi-max-frequency = <20000000>;
reg = <0>;
cmd-data-gpios = <&gpio0 19 GPIO_ACTIVE_LOW>;
reset-gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
width = <160>;
height = <128>;
x-offset = <0>;
y-offset = <0>;
madctl = <0x60>;
colmod = <0x55>;
vmctr1 = <0x0e>;
pwctr1 = [a2 02 84];
pwctr2 = [c5];
pwctr3 = [0a 00];
pwctr4 = [8a 2a];
pwctr5 = [8a ee];
frmctr1 = [01 2c 2d];
frmctr2 = [01 2c 2d];
frmctr3 = [01 2c 2d 01 2c 2d];
gamctrp1 = [02 1c 07 12 37 32 29 2d 29 25 2b 39 00 01 03 10];
gamctrn1 = [03 1d 07 06 2e 2c 29 2d 2e 2e 37 3f 00 00 02 10];
};
};
// Define pins used for SPI
&pinctrl {
spi2_default: spi2_default {
group1 {
psels = <NRF_PSEL(SPIM_SCK, 0, 17)>,
<NRF_PSEL(SPIM_MOSI, 0, 13)>,
<NRF_PSEL(SPIM_MISO, 0, 14)>;
};
};
};
/ {
chosen {
zephyr,display = &st7735r;
};
};
Invisible modulesSuccessful is, however, a relative term. After I flashed the build and connected the wires, my display did absolutely nothing. Well, technically, the backlight did light up when connected to 5V, but that does not need a microcontroller. The script successfully fetched my device from the device tree, but the board simply did not establish a connection with the display.
After checking my pin assignment and wiring, I decided to change my strategy and try something less complex. DHT temperature sensor sample looked simple enough. I wired my DHT11 module in, loaded the sample, tweaked the overlay, and... nothing!
// DHT sample overlay for DHT11
/ {
dht11 {
compatible = "aosong,dht";
status = "okay";
label = "DHT11";
dio-gpios = <&gpio0 27 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
};
};
Adding an insult to the injury, it took me less than 10 minutes to run an equivalent example on an ESP8266-based board. But, after a quick vent on Discord, I found a new hope: logic level shifters.
Episode IV: Logic LevelsnRF7002 DK runs on 1.8V logic. Both ST7735r display and DHT11 temperature sensor run on 3-5.5V, which means that they may not be getting enough "juice" to run properly. With elevated spirits, I added some 4-channel logic level converters to my cart and reached out for my debit card.
A couple of days later my parcel arrives. I try connecting DHT11 via the logic level shifter, and... nothing. It is still as invisible as before. The same goes for the ST7735r display. This is the part where I would love to shift the narrative and uncover the obvious rookie mistake that prevented everything from working. Unfortunately, at the time of this write-up, I still have no clue.
If you are a Zephyr pro, please share your wisdom in the comments - I still hope to finish this project and use nRF7002 DK for future Matter ideas.
Stage 5: AcceptanceWhile I was waiting on my level shifters parcel, I also found an online example of using lvgl with an SSD1306 display, and decided to quickly appropriate it to my needs. With a few tweaks to the sample overlay file (see attachments), I uploaded it to my nRF7002 DK and started wiring the SDA and SCL lines.
To my surprise, it failed in a completely new and exciting way:
Now, this is something completely new. Obviously, logic level shifter did not magically fix this problem either. However, after an hour or two online, I did find the culprit - memory allocation. This time, a third file is introduced into the mix: proj.config. After allocating additional memory inside the configuration file (CONFIG_HEAP_MEM_POOL_SIZE=16384
& CONFIG_MAIN_STACK_SIZE=4096
), magic almost happened but in a fairly bugged way.
CONFIG_I2C=y
CONFIG_SSD1306=y
CONFIG_SSD1306_SH1106_COMPATIBLE=n
CONFIG_STDOUT_CONSOLE=y
CONFIG_BOOT_BANNER=n
CONFIG_HEAP_MEM_POOL_SIZE=16384
CONFIG_MAIN_STACK_SIZE=4096
CONFIG_BT_RX_STACK_SIZE=4096
CONFIG_DISPLAY=y
CONFIG_CHARACTER_FRAMEBUFFER=y
CONFIG_SHELL=y
CONFIG_CHARACTER_FRAMEBUFFER_SHELL=y
CONFIG_LOG=y
CONFIG_CFB_LOG_LEVEL_DBG=y
CONFIG_LVGL=y
Unfortunately, I did not have time to properly troubleshoot this last issue before the contest deadline. Once again, any advice and hints on what went wrong are highly appreciated!
In the meantime, I will go brew myself a coffee, recover my morale, and try again.
Thanks for giving this a read and stay nerdy.
Seeya!
Comments