Bloodlight is an open-source (hardware and software) multispectral PPG research platform that Codethink is developing to research possible design improvements for medical devices.
One of the more challenging aspects of prototyping research hardware has always been the construction of plastic enclosures/cases. This is an even more fundamental issue for wearable/medical prototypes - in our example the case plays a strong role in the PPG sensor's optical properties.
Our second revision sensor was 200x more accurate than the initial prototype hardware, and this was only possible with the optical isolation that our black plastic case could provide.
Initial Case Design
We decided to design the case using OpenSCAD, primarily as we didn't have extensive experience using traditional 3D CAD modelling software. This type of software generally has a high learning curve, and OpenSCAD uses simple python-esque programmatic declarations and manipulations of 3D shapes to create models instead of manipulating them via a GUI.
The simple python-esque indications are advantageous for software engineers. It makes it easier for us as this has the familiar workflow of "type stuff, hit compile, things happen, when it's all good, commit the changes".
With OpenSCAD, it's also quick to produce something basic. However, it can be challenging to get the exact result you want. The tools available in OpenSCAD aren't as immediately powerful as those in traditional CAD programs - small tweaks can require a surprising amount of code. Inspecting the produced model can also be a little tricky - OpenSCAD provides a simple viewer, but no specific tools for measuring, etc.
Overall we think the choice of OpenSCAD still worked in our favour; we managed to get a basic case model produced reasonably quickly without having to learn unfamiliar tooling. When the responsibility for the case was given to another engineer, they were also quick to pick up and use OpenSCAD.
Case Design Workflow using OpenSCAD
Assuming the board’s design has already been finalised and is ready for a new case, this section will walk you through our process for designing a case from start to finish.
The source code for this project is available here >>, and these instructions will assume any shell commands are run from the root of this repository.
1. Export the PCB as VRML
First, open up the pcb in KiCAD by running
Once you have the board exactly as you like it, open up the PCB file:
Then click File->Export->VRML
And make sure the grid reference units are mm, and the output units are mm
2. Convert the VRML to STL
We use Blender and a script written to use Blender’s built-in python interpreter to do an automatic conversion from VRML to STL.
It’s now a simple matter of running the command-line
blender --background --python hardware/blender-wrl-to-stl.py -- hardware/bloodlight.wrl
3. View Case and Board in OpenSCAD
View the board and the case together in OpenSCAD (thanks to OpenSCAD being able to import from stl)
cd hardware/case && openscad case.scad
To see the case and the board together, call the module “render_whole_assembly()”
After you’ve made all the changes you want, edit the code, so it calls “render_top_bottom_side_by_side()” again, then renders it by clicking Design->Render or pressing F6
This will convert the case’s model from a collection of intersecting shapes into a single model. Once that has finished rendering, export the case as an STL by clicking File->Export->Export as STL…, or pressing F7.
4. Print the case
We use Prusa Slicer to convert our model to printing instructions, as it was designed for the brand of printer we use. Your printer may have its own recommended software or might be compatible with slic3r
Firstly, start your slicer software and import the STL (in PrusaSlicer, that’s File->Import->
Next, Slice the model to convert it into printing instructions.
At this point, the slicing software will warn you if there are printability issues with your model, and it should show you how it will print each part of the model.
From here, you can print the model if your computer is connected to the printer (which should take a couple of hours), or generate G-Code to send to your printer by other means.
During our experiments with putting together the board and case, we ran into some pitfalls.
Firstly, and most importantly, the 3D model produced by KiCAD had inaccurate dimensions on several components or didn't place certain parts at all. The incorrect 3D model meant "keep out" areas weren't adhered adequately to on initial case prototypes, and we only discovered this when bringing the case and board together. The first couple of revisions of the board had some issues with connector alignment, etc. That might have been easier to resolve if we had boards to hand that we could measure with callipers in an office, rather than going off 3d data. Due to COVID-19, we worked from home and had to ship the hardware back and forth to each other.
Besides, some parts of our original design pushed the limits of what a hobbyist-grade 3D printer could handle. Our original logo was an SVG of the Codethink logo, but that proved complex and fine enough that the slicer software sometimes failed to translate it into printing instructions.
Another issue that guides how the case is designed is gravity. A layer of filament can lie on the previous layer, be held up by temporary support material (this can lead to some scarring of the surface when the support is removed, so it's best supported from the inside), or being held up by tension while bridging a gap. It can't overhang the edge of the previous layer by more than a certain extent, meaning that any shallow vertical gradients must be wider at the bottom than the top. Also, using support material marks the print's surface, so it's best only to have inside/bottom faces supported in this way.
The final issue we discovered was that when using the device worn on the arm, the band exerted more pressure on the USB connector than you'd typically expect for a board that is only plugged in to charge or connect to a computer. We found that it was unfortunately relatively easy to exert enough pressure on the USB connector during measurements that the tab on the connector's back could snap rendering the connector and device unusable.
The board's micro-USB connector was likely designed for use in mobile phones, where it would be surrounded and supported by a moulded plastic, rather than being free-standing. The solution was to add support to the case's model, behind the micro-USB connector.
Finding where the support lies in the case is relatively simple, it sits in some holes drilled into the circuit board, seen as the two larger circular holes side-by-side in this picture:
Relating the position of the holes to where the back of the connector is was harder. Also, it involved deciphering which dimensions to use on the datasheet for the connector.
Unfortunately, while these measurements left enough space for the connector to fit in the case, it failed to leave enough room to slide the connector into position.
The Evolution of the Case
One of the most valuable features of using OpenSCAD to make the case is that it meshes well with version control tooling, allowing us to spin changes into different branches, and easily track what differs between versions. For example, this is what the case looked like in the first commit made public:
From there, we noticed that light was leaking into the photodiodes because the straps at the bottom pushed the case up slightly, so we moved the wings for the straps to the top of the case (see commit).
With the straps resolved, our next issue was the screws holding the case together standing out from the bottom of the case. Since the case is meant to be pressed against bare skin there, this was an irritant we wanted to remove.
Our first attempt modelled the screw as a cone and a rod and then subtracted that from the case, by using countersunk screws
The first attempt still left part of the screw sticking out of the case, which we fixed in a second attempt by modelling another cylinder at the wide end of the cone.
Designing a case design for Bloodlight was a new challenge for us. Previously our experience with case design was applying knowledge from various hobby projects. We learned that there’s no substitute for having a physical model to handle to make sure something fits together securely and comfortably.
We faced a few difficulties during the process, such as underestimating the stresses placed on the USB connector, but we could adapt and overcome them while producing a prototype.
As mentioned before, OpenSCAD is more comfortable for software engineers to use than other traditional 3D CAD modelling software. It uses simple python-esque programmatic declarations, and even though it was a first time for most engineers working with OpenSCAD, we designed a case that fit closely and comfortably on the forearm, reducing background light noise significantly.
Related blog posts:
- More about Bloodlight: Bloodlight: A Medical PPG Testbed >>
- Improving the medical industry: The Case For Open Source Software In The Medical Industry >>
- Tracking Players at the Edge: An Overview
- What is Remote Asset API?
- Running a devroom: FOSDEM 2021 Safety and Open Source
- Meet the codethings: Understanding BuildGrid and BuildBox with Beth White
- Streamlining Terraform configuration with Jsonnet
- Bloodlight: Designing a Heart Rate Sensor with STM32, LEDs and Photodiode
- Making the tech industry more inclusive for women
- Safety is a system property, not a software property
- RISC-V: Codethink's first research about the open instruction set
- Meet the Codethings: Safety-critical systems and the benefits of STPA with Shaun Mooney
- Why Project Managers are essential in an effective software consultancy
- FOSDEM 2021: Devroom for Safety and Open Source
- Meet the Codethings: Ben Dooks talks about Linux kernel and RISC-V
- Here we go 2021: 4 open source events for software engineers and project leaders
- Xmas Greetings from Codethink
- Call for Papers: FOSDEM 2021 Dev Room Safety and Open Source Software
- Building the abseil-hello Bazel project for a different architecture using a dynamically generated toolchain
- Advent of Code: programming puzzle challenges
- Improving performance on Interrogizer with the stm32
- Introducing Interrogizer: providing affordable troubleshooting
- Improving software security through input validation
- More time on top: My latest work improving Topplot
- Cycling around the world
- Orchestrating applications by (ab)using Ansible's Network XML Parser
- My experience of the MIT STAMP workshop 2020
- Red Hat announces new Flatpak Runtime for RHEL
- How to keep your staff healthy in lockdown
- Bloodlight: A Medical PPG Testbed
- Bringing Lorry into the 2020s
- How to use Tracecompass to analyse kernel traces from LTTng
- Fixing Rust's test suite on RISC-V
- The challenges behind electric vehicle infrastructure
- Investigating kernel user-space access
- Consuming BuildStream projects in Bazel: the bazelize plugin
- Improving RISC-V Linux support in Rust
- Creating a Build toolkit using the Remote Execution API
- Trusting software in a pandemic
- The Case For Open Source Software In The Medical Industry
- My experiences moving to remote working
- Impact of COVID-19 on the Medical Devices Industry
- COVID-19 (Coronavirus) and Codethink
- Codethink develops Open Source drivers for Microsoft Azure Sphere MediaTek MT3620
- Codethink partners with Wirepas
- Testing Bazel's Remote Execution API
- Passing the age of retirement: our work with Fortran and its compilers
- Sharing technical knowledge at Codethink
- Using the REAPI for Distributed Builds
- An Introduction to Remote Execution and Distributed Builds
- Gluing hardware and software: Board Support Packages (BSPs)
- Engineering's jack of all trades: an intro to FPGAs
- Bust out your pendrives: Debian 10 is out!
- Why you should attend local open source meet-ups
- Acceptance, strife, and progress in the LGBTIQ+ and open source communities
- Codethink helps York Instruments to deliver world-beating medical brain-scanner
- Codethink open sources part of staff onboarding - 'How To Git Going In FOSS'
- Getting into open source
- How to put GitOps to work for your software delivery
- Open Source Safety Requirements Analysis for Autonomous Vehicles based on STPA
- Codethink engineers develop custom debug solution for customer project
- Codethink contributes to CIP Super Long Term Kernel maintenance
- Codethink creates custom USB 3 switch to support customer's CI/CD pipeline requirements
- Codethink unlocks data analysis potential for British Cycling
- MIT Doctor delivers Manchester masterclass on innovative safety methodology
- Balance for Better: Women in Technology Codethink Interviews
- Introducing BuildGrid
- Configuring Linux to stabilise latency
- GUADEC 2018 Talks
- Hypervisor Not Required
- Full archive