In the past I’ve used python to create small programs to interface with my hardware projects like EOGee and ShArc. I use the Matplotlib animation class to plot live data, however I’ve found this to be very slow, typically only updating a few times a second. To help remedy this I’ve begun using the Pygame library. Pygame is an open source python library for developing games – it provides a simple structure for running a main loop while drawing to the screen, and update rates of 60Hz are easily achievable.
While using the Pygame library for developing a ShArc demo, I came across a shortcoming in the function for drawing arcs, which I was using the visualise the shape of the sensor.
When drawing an arc of very large radius, I found that the arc typically would not be completely drawn. This is illustrated in the following image which shows four arcs which should be connecting to each other, however clearly there are large gaps between them. If the arc was short enough, with large enough radius, it may not be drawn at all.
In the previous article I showed my successful implementation of ShArc, a novel bend/shape sensor using capacitive sensing. My video showed that the system could track the bend shape of the sensor but it was not quantitively analysed.
To take this a little further I wanted to show the relationship between the signal that the sensor generates and the radius of curvature. To begin with I 3D printed a flexible covering for the flex using TPU filament and the modified extruder I designed to enable TPU printing on my Monoprice 3D printer.
In order to further characterise and test the EOGee prototypes, it is important to be able to inject known signals and measure the output. This is not trivial, as the devices are configured to measure micro-volts of signal and a normal signal generator cannot synthesising a signal of such small magnitude. Secondly, the device takes a differential measurement, and so a differential signal is required rather than a single-ended one, as most signal generators produce.
To fix this issue I designed FakeEyes, a PCB to take a 3.3V peak single ended signal and convert it into a 1700uV peak differential signal.
There are two main ways to program the STM32 microcontroller in the EOGlass prototypes. The first is by using a dedicated programmer/debugger (e.g. the STLink) to connect to the SWD pins of the chip and programming it directly. However this requires adding a pin header to the board to enable this connection. The second option is to use the bootloader.
The bootloader is a small program that is stored in the microcontroller flash memory that can receive a program via SPI/USB/UART etc. and program itself. In this case, we have a USB port on the board anyway, so we can use this to program the device without having to add any more connections to the board.
In order to enter the bootloader, however, it is necessary to hold the BOOT pin high while resetting the device. This is typically done using a pull-down resistor and a push button to pull the BOOT pin high when you want to enter bootloader.
Having previously improved the drift performance of EOGlass, I decided to look a little into the sources of noise. It’s pretty clear that there is a lot of noise on the signal.
It’s actually pretty tricky to know exactly what is noise, given that I don’t really know exactly what my eyes were supposed to be doing and, even if I did, the eyes often make micro-saccades that the conscious brain isn’t aware of. If I zoom into a section that looks like I was keeping my eye relatively still, the noise turns out to be about 60 ADC counts peak-to-peak. This is equivalent to approximately 21863nVpkpk, when referred to the input (ie before amplification) (12-bit ADC, 3.3V range, gain of 2211).
I wanted to know how much of this noise was coming from the hardware, and how much was coming from the user. For this I decided to analyse the noise contributions from each stage of the signal chain. Texas Instruments have a good application note on noise analysis.
In a previous article I showed how the bias current of the AD8226 amplifier was causing a 20nV current to flow through the electrodes resulting in a large voltage offset due to the impedance mismatch between the left and right electrodes. This resulted in a large drift in the signal due to changes in impedance between the user and electrodes as they moved or sweated, which often saturated the ADC. I built a test board and showed how this could be reduced by a factor of about 1000x by using the AD8220 which has a bias current of less than 10pA.
The sensor is made of two flexible circuit boards (“flexes”) stacked either side of multiple layers of polyimide material, which is the same material used for the flex substrate. Both flexes are constrained together at one end, and when the flexes are bent, they slide relative to each other. The topmost flex (TX Flex) has a series of transmit electrodes along its length, while the bottom most flex (RX Flex) has a series of corresponding receive electrodes along its length. As the two flexes slide relative to each other, the capacitance between each TX and RX electrode pair changes. By measuring this capacitance the system can infer the relative slide between the two flexes and in turn infer the bend radius.
Problem: The previous prototypes of EOGlass that I have shown use wet electrodes to make good contact to the user. This results in a reliable, low-impedance connection but is also messy and inconvenient. Recently I’ve been trying out dry electrodes for convenience, but they suffer from two main issues: drift and noise.
As part of my latest EOGee design, I have four devices on a single SPI bus – two 12-bit ADCs and two 12-bit DACs. Each of them is operating at 30kHz, which means that every 33us I have to send or receive 16-bits of data to each of them.
STMicro provide a HAL library which makes sending SPI data really simple using their commands HAL_SPI_Transmit_IT and HAL_SPI_Receive_IT.
So in theory it should be as simple as calling each of these functions four times sequentially, every 33us. With a clock speed of 10MHz, each transaction should take about 1.6us which would easily fit inside the 33us. However it turns out that the HAL library is very inefficient when it comes to small transactions.
About a year ago I decided to purchase a 3D printer. I didn’t need anything too fancy, and I didn’t want anything too big. I settled on a Monoprice MP Select Mini 3D Printer V2 which is a small desktop printer for about $200.
I’ve been very impressed with it’s reliability – it has only needed to be tuned once since I set it up, and since then it very rarely fails a print using PLA. But for an upcoming project I want to print in a flexible material, so I ordered some TPU filament from Sainsmart.