The sun emits energy over a broad spectrum of wavelengths: visible light, infrared radiation generating heat, and UV (ultraviolet) radiation hidden from our senses. Although UV radiation affects our health positively in moderation, such as instigating the production of vitamin D, sun damage is mostly engendered by overexposure to UV radiation since it has a higher frequency and lower wavelength than visible light.
The UV region covers the wavelength range of 100-400 nm and is divided into three bands:
- UVA (315-400 nm)
- UVB (280-315 nm)
- UVC (100-280 nm)
After perusing recent research papers on UV radiation, I decided to utilize UV index (UVI), temperature, pressure, and altitude measurements denoting the amount of UV radiation from the sun so as to create a budget-friendly BLE smartwatch to forecast sun damage risk levels in the hope of prewarning the user, especially risk groups, of potential sun damage risk to avert severe health conditions related to excess sun exposure, such as immune system damage and melanoma (skin cancer).
The ultraviolet index (UV index) is an international standard measurement of the strength of the sunburn-producing UV (ultraviolet) radiation. In other words, the UV index forecasts the strength of the sun’s harmful rays. Since it is designed as an open-ended linear scale, directly proportional to the intensity of UV radiation, the higher the number, the greater the chance of sun damage. An increase in the UV index value corresponds to a constant decrease in time to sunburn. Therefore, higher values represent a greater risk of sunburn and excess UV radiation exposure.
Even though UV index, temperature, pressure, and altitude measurements provide insight into detecting sun damage, it is not possible to extrapolate and construe sun damage risk levels precisely by merely employing limited data without applying complex algorithms since sun damage risk levels fluctuate according to various phenomena, some of which are not fully fathomed yet. Hence, I decided to build and train an artificial neural network model by utilizing the empirically assigned sun damage risk classes to forecast sun damage risk levels based on UV index, temperature, pressure, and altitude measurements.
Since XIAO BLE (nRF52840) is an ultra-small size Bluetooth development board that can easily collect data and run my neural netwrok model after being trained to forecast sun damage risk levels, I decided to employ XIAO BLE in this wearable smartwatch project. To obtain the required measurements to train my model, I utilized a UV sensor (Grove) and a BMP180 precision sensor. Since the XIAO expansion board provides various prototyping options and built-in peripherals such as an SSD1306 OLED display and a MicroSD card module, I use the expansion board to make rigid connections between XIAO BLE and the sensors.
Since the expansion board supports reading and writing information from/to files on an SD card, I stored the collected data in a CSV file on the SD card to create a data set. In this regard, I was able to save data packets via XIAO BLE without requiring any additional procedures.
After completing my data set, I built my artificial neural network model (ANN) with Edge Impulse to make predictions on sun damage risk levels (classes) based on UV index, temperature, pressure, and altitude measurements. Since Edge Impulse is nearly compatible with all microcontrollers and development boards, I had not encountered any issues while uploading and running my model on XIAO BLE. As labels, I employed the empirically assigned sun damage risk classes for each data record while collecting data outdoors:
- Tolerable
- Risky
- Perilous
After training and testing my neural network model, I deployed and uploaded the model on XIAO BLE. Therefore, the smartwatch is capable of detecting precise sun damage risk levels (classes) by running the model independently. Also, after running the model successfully, I employed XIAO BLE to transmit (advertise) the prediction (detection) result and the recently collected data over BLE.
Then, I developed a complementing Android application from scratch to obtain the transmitted (advertised) information over BLE from the smartwatch so as to inform the user of potential sun damage risk.
Lastly, to make the smartwatch as sturdy and robust as possible while enduring harsh conditions outdoors, I designed an Ultimatrix-inspired smartwatch case with a sliding (removable) top cover (3D printable).
So, this is my project in a nutshell 😃
In the following steps, you can find more detailed information on coding, logging data on the SD card, transmitting data packets over BLE, building a neural network model with Edge Impulse, and running it on XIAO BLE.
🎁🎨 If you want to replicate or modify this project, you can get XIAO BLE with free shipping worldwide as of now. Click here for more information.
🎁🎨 Huge thanks to Seeed Studio for sponsoring these products:
⭐ XIAO BLE nRF52840 | Inspect
⭐ XIAO Expansion Board | Inspect
⭐ Grove - UV Sensor | Inspect
🎁🎨 Also, huge thanks to Creality3D for sponsoring a Creality CR-6 SE 3D Printer.
🎁🎨 If you want to purchase some products from Creality3D, you can use my 10% discount coupon (Aktar10) even for their new and most popular printers: CR-10 Smart,CR-30 3DPrintMill,Ender-3 Pro, and Ender-3 V2. You can also use the coupon for Creality filaments.
Step 1: Designing and printing an Ultimatrix-inspired smartwatch case
Since I am a huge Ben 10 fan, I got inspired by the Ultimatrix in Ben 10: Ultimate Alien animated series to design a smartwatch case so as to create a robust and sturdy device flawlessly operating while enduring harsh conditions outdoors. To make the XIAO expansion board accessible while logging the collected data on the SD card, I added a sliding (removable) top cover. Also, I inscribed the well-known Omnitrix symbol on the top cover to emphasize the Ben 10 theme gloriously :)
I designed the smartwatch case and its sliding (removable) top cover in Autodesk Fusion 360. You can download their STL files below.
Then, I sliced 3D models (STL files) in Ultimaker Cura.
Since I wanted to create a solid structure for the smartwatch case with the sliding top cover and complement the Ben 10 theme with a unique Ultimatrix iteration, I utilized this PLA filament:
- eSilk Rainbow Multicolor
Finally, I printed all parts (models) with my Creality CR-6 SE 3D Printer. Although I am a novice in 3D printing, and it is my first FDM 3D printer, I got incredible results effortlessly with the CR-6 SE :)
Step 1.1: Assembling the smartwatch and making connections & adjustments
// Connections// XIAO BLE : // Grove - UV Sensor // A0 --------------------------- SIG // BMP180 Barometric Pressure/Temperature/Altitude Sensor // A4 --------------------------- SDA // A5 --------------------------- SCL // SSD1306 OLED Display (128x64) // A4 --------------------------- SDA // A5 --------------------------- SCL // MicroSD Card Module (Built-in on the XIAO Expansion board) // D10 --------------------------- MOSI // D9 --------------------------- MISO // D8 --------------------------- CLK (SCK) // D2 --------------------------- CS // Button (Built-in on the XIAO Expansion board) // D1 --------------------------- + // Keyes 10mm RGB LED Module (140C05) // D7 --------------------------- R // D3 --------------------------- G // D6 --------------------------- B
First of all, I soldered female pin headers to XIAO BLE in order to connect it to the XIAO expansion board. Also, I changed my 3.7V LiPo battery's pre-attached connector with a JST 2.0 standard connector so as to power the expansion board.
To collect the UV radiation and weather data, I connected the UV sensor (Grove) and the BMP180 precision sensor to XIAO BLE via the expansion board. Since the expansion board has a Grove port supporting analog sensors, I connected the UV sensor via a Grove cable.
To display and log the collected data, I utilized the built-in SSD1306 OLED screen, MicroSD card module, and button on the expansion board. Also, I added a 10mm common anode RGB LED module (Keyes) to indicate the outcomes of operating functions.
After printing all parts (models), I fastened all components except the expansion board to their corresponding slots on the smartwatch case and the sliding (removable) top cover via a hot glue gun.
To attach the expansion board to the smartwatch case, I utilized 10mm M3 male-female brass hex spacers, M3 screws, and hex nuts.
Finally, I affixed yellow rubber hook-and-loop fasteners (15mm wide Velcro) to the holes under the smartwatch case in order to wear the smartwatch effortlessly outdoors.
Step 2: Developing a BLE-enabled Android application w/ the MIT APP Inventor
To be able to obtain the transmitted (advertised) information from the smartwatch over BLE, I decided to develop an Android application from scratch with the MIT APP Inventor.
MIT App Inventor is an intuitive, visual programming environment that allows developers to build fully functional Android applications. Its blocks-based tool (drag-and-drop) facilitates the creation of complex, high-impact apps in significantly less time than the traditional programming environments.
After developing my application, named BLE UV Smartwatch, I published it on Google Play. So, you can install the BLE UV Smartwatch app on any compatible Android device via Google Play.
📲 Install BLE UV Smartwatch on Google Play
Nevertheless, if you want to replicate the BLE UV Smartwatch app on the MIT App Inventor, follow the steps below.
#️⃣ First of all, create an account on the MIT App Inventor.
#️⃣ Download the BLE UV Smartwatch app's project file in the aia format (BLE_UV_Smartwatch.aia) and import the aia file into the MIT App Inventor.
#️⃣ Since the MIT App Inventor does not support BLE connectivity by default, download the latest version of the BluetoothLE extension and import the BluetoothLE extension into the BLE UV Smartwatch project.
In this tutorial, you can get more information regarding enabling BLE connectivity on the MIT App Inventor.
#️⃣ Inspect the BLE UV Smartwatch project functions and source code in the Blocks editor.
#️⃣ After installing the BLE UV Smartwatch app on a compatible Android device, the app starts displaying the transmitted (advertised) information from the smartwatch over BLE immediately to inform the user of potential sun damage risk.
You can get more information regarding the BLE UV Smartwatch app's features in Step 8.
Step 3: Setting up XIAO BLE on the Arduino IDE
Since the XIAO expansion board supports reading and writing information from/to files on an SD card, I decided to log the collected UV radiation and weather data in a CSV file on the SD card without applying any additional procedures. Also, I employed XIAO BLE to transmit the prediction (detection) result and the recently collected data over BLE after running my neural network model.
However, before proceeding with the following steps, I needed to set up XIAO BLE on the Arduino IDE and install the required libraries for this project.
#️⃣ To add the XIAO BLE board package to the Arduino IDE, navigate to File ➡ Preferences and paste the URL below under Additional Boards Manager URLs.
https://files.seeedstudio.com/arduino/package_seeeduino_boards_index.json
#️⃣ Then, to install the required core, navigate to Tools ➡ Board ➡ Boards Manager and search for Seeed nRF52 Boards.
#️⃣ After installing the core, navigate to Tools > Board > Seeed nRF Boards and select Seeed XIAO BLE - nRF52840.
#️⃣ To transmit (advertise) data packets over BLE, download the ArduinoBLE library: Go to Sketch ➡ Include Library ➡ Manage Libraries… and search for ArduinoBLE.
#️⃣ Finally, download the required libraries for the BMP180 precision sensor and the SSD1306 OLED display:
Adafruit-BMP085-Library | Download
Adafruit_SSD1306 | Download
Adafruit-GFX-Library | Download
Step 3.1: Displaying images on the SSD1306 OLED screen
To display images (black and white) on the SSD1306 OLED screen successfully, I needed to create monochromatic bitmaps from PNG or JPG files and convert those bitmaps to data arrays.
#️⃣ First of all, download the LCD Assistant.
#️⃣ Then, upload a monochromatic bitmap and select Vertical or Horizontal depending on the screen type.
#️⃣ Convert the image (bitmap) and save the output (data array).
#️⃣ Finally, add the data array to the code and print it on the screen.
static const unsigned char PROGMEM sd [] = {0x0F, 0xFF, 0xFF, 0xFE, 0x1F, 0xFF, 0xFF, 0xFF, 0x1F, 0xFE, 0x7C, 0xFF, 0x1B, 0x36, 0x6C, 0x9B,0x19, 0x26, 0x4C, 0x93, 0x19, 0x26, 0x4C, 0x93, 0x19, 0x26, 0x4C, 0x93, 0x19, 0x26, 0x4C, 0x93,0x19, 0x26, 0x4C, 0x93, 0x19, 0x26, 0x4C, 0x93, 0x19, 0x26, 0x4C, 0x93, 0x1F, 0xFF, 0xFF, 0xFF,0x1F, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0xFF,0x3F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xC7, 0xFF, 0xFF, 0xF9, 0x41, 0xFF, 0x1F, 0xF9, 0xDD, 0xFF,0x1F, 0xFC, 0xDD, 0xFF, 0x1F, 0xFE, 0x5D, 0xFF, 0x1F, 0xF8, 0x43, 0xFF, 0x1F, 0xFD, 0xFF, 0xFF,0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE};...display.clearDisplay(); display.drawBitmap(48, 0, sd, 32, 44, SSD1306_WHITE);display.display();
Step 4: Collecting and storing UV radiation and weather data w/ XIAO BLE
Step 4.1: Logging the collected data in a CSV file on the SD card
After uploading and running the code for collecting UV radiation and weather data and for saving information to the given CSV file on the SD card on XIAO BLE:
☀️⌚ The smartwatch turns the RGB LED to blue if the sensors and the MicroSD card module connections with XIAO BLE are successful.
☀️⌚ Then, the smartwatch turns the RGB LED to magenta as the default color and displays the collected data and the selected class on the SSD1306 OLED screen:
- UV Index
- Temperature (°C)
- Pressure (Pa)
- Altitude (m)
- Selected Class
☀️⌚ If the button (built-in) is short-pressed, the smartwatch blinks the RGB LED as white and increases the class number in the range of 0-2:
- Tolerable [0]
- Risky [1]
- Perilous [2]
☀️⌚ If the button (built-in) is long-pressed, the smartwatch blinks the RGB LED as yellow and appends the recently created data record to the UV_DATA.CSV file on the SD card, including the selected sun damage risk level (class) under the risk_level data field.
☀️⌚ If the smartwatch saves the data record successfully to the given CSV file on the SD card, it blinks the RGB LED as green and displays this message on the SSD1306 OLED screen: Data saved to the SD card!
☀️⌚ If XIAO BLE throws an error while operating, the smartwatch shows the error message on the SSD1306 OLED screen, turns the RGB LED to red, and prints the error details on the serial monitor.
☀️⌚ Also, the smartwatch prints notifications and sensor measurements on the serial monitor for debugging.
After logging the collected UV radiation and weather data in the given CSV file on the SD card for 20 days outdoors in different parts of the day (early morning, late afternoon, night, etc.), I elicited my data set with eminent validity:
Since I also needed a testing data set to evaluate the accuracy of my model, I collected additional data to create a modest data set in volume under the test_UV_DATA.CSV file.
Step 5: Building a neural network model with Edge Impulse
When I completed collating my sun damage risk data set and assigning labels, I had started to work on my artificial neural network model (ANN) to make predictions on sun damage risk levels (classes) based on UV index, temperature, pressure, and altitude measurements.
Since Edge Impulse supports almost every microcontroller and development board due to its model deployment options, I decided to utilize Edge Impulse to build my artificial neural network model. Also, Edge Impulse makes scaling embedded ML applications easier and faster for edge devices such as XIAO BLE.
Even though Edge Impulse supports CSV files to upload samples, the data type should be time series to upload all data records in a single file. Therefore, I needed to follow the steps below to format my data set so as to train my model accurately:
- Data Scaling (Normalizing)
- Data Preprocessing
As explained in the previous steps, I assigned sun damage risk classes for each data record empirically while logging data outdoors with the smartwatch. Since UV radiation can impinge on our health detrimentally, it was crucial to assign insightful classes to forecast sun damage risk levels precisely with the limited data volume. Therefore, I derived my classes in reference to the UV Index Scale by EPA, conforming with international guidelines for UVI reporting established by the WHO[2].
Since the assigned classes are stored under the risk_level data field in the UV_DATA.CSV file, I preprocessed my data set effortlessly to obtain labels for each data record (sample):
- 0 — Tolerable
- 1 — Risky
- 2 — Perilous
Plausibly, Edge Impulse allows building predictive models optimized in size and accuracy automatically and deploying the trained model as an Arduino library. Therefore, after scaling (normalizing) and preprocessing my data set to create samples, I was able to build an accurate neural network model to forecast sun damage risk levels and run it on XIAO BLE effortlessly.
Since I published my Edge Impulse project, you can inspect my neural network model on Edge Impulse.
Step 5.1: Preprocessing and scaling (normalizing) the data set to create samples
Step 5.2: Uploading samples to Edge Impulse
After generating training and testing samples successfully, I uploaded them to my project on Edge Impulse.
#️⃣ First of all, sign up for Edge Impulse and create a new project.
#️⃣ Navigate to the Data acquisition page and click the Upload existing data button.
#️⃣ Then, choose the data category (training or testing) and select Infer from filename under Label to deduce labels from file names automatically.
#️⃣ Finally, select files and click the Begin upload button.
Step 5.3: Training the model on sun damage risk levels
After uploading my training and testing samples successfully, I designed an impulse and trained it on sun damage risk levels (classes).
An impulse is a custom neural network model in Edge Impulse. I created my impulse by employing the Raw Data block and the Classification learning block.
The Raw Data block generates windows from data samples without any specific signal processing.
The Classification learning block represents a Keras neural network model. Also, it lets the user change the model settings, architecture, and layers.
#️⃣ Go to the Create impulse page. Then, select the Raw Data block and the Classification learning block. Finally, click Save Impulse.
#️⃣ Before generating features for the model, go to the Raw data page and click Save parameters.
#️⃣ After saving parameters, click Generate features to apply the Raw Data block to training samples.
#️⃣ Finally, navigate to the NN Classifier page and click Start training.
I utilized the default classification model settings, architecture, and layers to build my neural network model.
After generating features and training my model with training samples, Edge Impulse evaluated the precision score (accuracy) as 100%.
The precision score is approximately 100% due to the volume and variety of training samples. In technical terms, the model overfits the training data set. Therefore, I am still collecting data to improve my training data set.
Step 5.4: Evaluating the model accuracy and deploying the model
After building and training my neural network model, I tested its accuracy and validity by utilizing testing samples.
The evaluated accuracy of the model is 90.91%.
#️⃣ To validate the trained model, go to the Model testing page and click Classify all.
After validating my neural network model, I deployed it as a fully optimized and customizable Arduino library.
#️⃣ To deploy the validated model as an Arduino library, navigate to the Deployment page and select Arduino library.
#️⃣ Then, choose the Unoptimized (float32) option to deploy the model without downsizing the accuracy.
#️⃣ Finally, click Build to download the model as an Arduino library.
Step 6: Setting up the Edge Impulse model on XIAO BLE
Inspect.
Step 7: Running the model on XIAO BLE to make predictions on sun damage risk levels
When the features array (buffer) is full with data items, my Edge Impulse neural network model predicts possibilities of labels (sun damage risk classes) for the given features buffer as an array of 3 numbers. They represent the model's "confidence" that the given features array (buffer) corresponds to each of the three different sun damage risk levels (classes) based on UV index, temperature, pressure, and altitude measurements [0 - 2], as shown in Step 5:
- 0 — Tolerable
- 1 — Risky
- 2 — Perilous
As discussed in the previous steps, I also employed XIAO BLE to transmit (advertise) the prediction (detection) result and the recently collected data over BLE.
After executing the BLE_smartwatch_run_model.ino file on XIAO BLE:
☀️⌚ The smartwatch turns the RGB LED to blue if the BLE initialization status is successful.
☀️⌚ Then, the smartwatch turns the RGB LED to magenta as the default color and displays the collected data on the SSD1306 OLED screen:
- UV Index
- Temperature (°C)
- Pressure (Pa)
- Altitude (m)
☀️⌚ The smartwatch runs inferences with the Edge Impulse model at regular intervals by filling the features buffer with the recently collected UV index, temperature, pressure, and altitude measurements.
☀️⌚ Then, the smartwatch displays the detection result, which represents the most accurate label (sun damage risk class) predicted by the model.
☀️⌚ Each sun damage risk level (class) has a unique monochrome icon to be shown on the SSD1306 OLED screen and a color code for adjusting the RGB LED when being predicted (detected) by the model:
- Tolerable ➡ Green
- Risky ➡ Yellow
- Perilous ➡ Red
☀️⌚ After running inference successfully, the smartwatch also transmits (advertises) the prediction result (class) and the recently collected data over BLE.
☀️⌚ If XIAO BLE transmits the given information over BLE successfully, the smartwatch prints this message on the screen:
BLE: Data Transmitted
☀️⌚ Also, the smartwatch prints notifications and sensor measurements on the serial monitor for debugging.
As far as my experiments go, the smartwatch operates impeccably while forecasting sun damage risk levels (classes) and transmitting (advertising) the prediction result over BLE outdoors :)
Step 8: Monitoring the model prediction result over BLE via the BLE UV Smartwatch app
As discussed in Step 2, I developed an Android application (BLE UV Smartwatch) from scratch with the MIT APP Inventor so as to obtain and display the transmitted (advertised) information from the smartwatch over BLE.
☀️⌚ If the Scan button is pressed, the application scans for compatible BLE devices and shows them as a list.
☀️⌚ If the Stop button is pressed, the application desists from scanning devices.
☀️⌚ If the Connect button is pressed, the application attempts to connect to the selected BLE device (smartwatch) over BLE.
☀️⌚ If the application connects to the smartwatch (peripheral device) as the central device successfully, the application waits for the advertised (transmitted) data packets from the smartwatch.
☀️⌚ When the application receives the advertised data packets, it shows the recently collected data by the smartwatch and the sun damage risk level (class) predicted by the Edge Impulse model.
☀️⌚ Each sun damage risk level (class) has a unique fusion state image and color code to be displayed on the screen when being received:
- Tolerable ➡ Green
- Risky ➡ Yellow
- Perilous ➡ Red
☀️⌚ If the Disconnect button is pressed, the application disconnects from the smartwatch and clears all received information.