Software apps and online services
Hand tools and fabrication machines
I've always wanted to tinker with a RISC-V device, so one day I was visiting my go to place to buy electronics components (LCSC) and saw this banner on the front page.
I knew WCH did USB to UART modules for the Arduino clone boards, but what took me by surprise is that now they were fabricating their own RISCV MCUs.
Needles to say I got pretty exited and I signed up for this challenge.Overview.
My main goal for this "SmartWatch" project was to learn a RTOS (such as RT-Thread) and make a functional clock with at least one feature involving Bluetooth low energy (BLE).
My strategy here was to develop more features once I had the minimum working prototype, I'm glad I did this because you'll see that a lot of participants (myself included) had a bunch of issues during the time-lapse of the challenge.Part 1: Initial Setup
I based my design on "easy to get"/"easy to use" modules such as an MPU-6050 for an accelerometer, a BLE to Serial module and an ST7789 screen. Once our delayed boards and chips got delivered I quickly connected all the parts to their corresponding GPIOs and started writing some code.
I first started writing the drivers of all my modules separately, I wanted to use RT-Thread device frameworks but they ended up with a lot of bugs and issues (specially with the SPI device), in the end here is a list of the baremetal drivers and RT-thread device drivers I ended up using.
For the baremetal drivers I used the examples of the CH32V307 github page: https://github.com/openwch/ch32v307
The only one I modified was SPI, because I didn't like their "send data" API.
void SPI_I2S_SendData(SPI_TypeDef *SPIx, uint16_t Data)
SPIx->DATAR = Data;
/******* Blocking call - Blocking API *******/
void SPI_SendData(SPI_TypeDef *SPIx, uint8_t *pTxBuffer, uint8_t Len)
// loop until the Len is 0
while(Len > 0)
// Wait until TXE is set (page 303 ref manual)
//while(! (SPIx->STATR & (1 << 1)) );
while (SPI_I2S_GetFlagStatus(SPIx, SPI_TXE_FLAG) == RESET);
// Check the DFF bit in CR1
if( (SPIx->CTLR1 & (1 << SPI_CTLR1_DFF)) )
//16 bit DFF
//Load the data into the DR (turn 8 bit to 16 bit data pointer)
SPIx->DATAR = *((uint16_t*)pTxBuffer);
//8 bit DFF
SPIx->DATAR = *pTxBuffer;
I actually found a very useful Gitee page that had an example code for the CH32V307 using the MPU-6050
Once I had all the drivers working I structured my threads the simplest way possible, my objective here was to use 2 Thread synchronization methods and 3 threads.
You can see the rest of the code on my GitHub page.Part 3: Hardware (PCB)
One advantage of having all the project modules on a bread board is that schematic design gets a lot easier because you have all the connections ready and verified, that's why I did the initial code first; because I wanted to make sure my connections would work.
The layout got a little cramped but I ended up with a very acceptable size for a smartwatch. I had to use 4 layers though.
Once I had my PCB I soldered the components and programmed the chip using the DIO and CLK pins on the CH32V307V-R1 board.
Once I had all the components working, I designed a simple case on FreeCAD and started testing all the features.
- BLE (Change Theme)
- Step counter
- Change Time
Due to the time constrains and issues presented on this challenge I couldn't implement some features I wanted, I'm definitely going to re-take this project and add:
- Low power capabilities
- Better debouncing for the push buttons
- Create an app (Flutter or MIT app creator)
- Add more BLE features
- LVGL (Originally planned to have, but removed due to time and memory constrains)
For now I'm satisfied with what I have, this experience made me learn a lot of new skills and was a lot of fun, I would definitely recommend a maker or a tinkerer to enter to these kinds of challenges because its a completely new way of handling a project,