Getting a Nucleo to work

Nucleos are very nice little dev boards for STM32 microcontrollers. I’ve been using a Nucleo-f446 for some embedded projects over the last two years, but always reluctantly because it would only work with my worst laptop which I keep around specifically for this purpose. They have integrated ST-Link programmers/debuggers which I’ve had issues using due to USB bugs. After a long time I’ve finally gotten it working.

When plugged in over USB, the Nucleo should register as both a 88k block device and as a serial console (/dev/ttyACM[0-9]). The Nucleo is programmed just by moving files onto the block device, and can be interacted with over the serial terminal. On some machines it would just show up as a block device, and on others it would not show up at all. When plugged in, the following would be outputted to dmesg:


[  555.818115] usb 5-2: new full-speed USB device number 5 using xhci_hcd
[  555.989838] usb 5-2: New USB device found, idVendor=0483, idProduct=374b
[  555.989840] usb 5-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[  555.989842] usb 5-2: Product: STM32 STLink
[  555.989844] usb 5-2: Manufacturer: STMicroelectronics
[  555.989845] usb 5-2: SerialNumber: 0669FF515056805087142030
[  555.990035] xhci_hcd 0000:0a:00.3: ERROR: unexpected command completion code 0x11.
[  555.990320] usb 5-2: can't set config #1, error -22

I initially thought the kernel was responsible with cdc-acm. I’m not going to describe all the things I’ve tried and instead skip right to the solution. The Nucleo only properly registers when I plug it into my only USB3.1 port instead of any of the USB3.0 ports.

Edit: It also appears not always enumerate unless there are no periphereals plugged into it.

Edit2: I’ve moved to using SW4STM32, and the automatic stlink firmwire update allowed me to use it with any usb plug on my desktop.

EEG part 3: Different passive electrode types

Some notes first:

See http://openeeg.sourceforge.net/doc/hw/electrodes/passive/ for inspiration. From my experience here, maintaining a good and continuous contact is more important than actual materials. A discussion of elastic bands to secure electrodes would be useful.

All of these tests were repeated with different levels of skin preparation (basically before and after rubbing sandpaper and alcohol on) and electrode jelly/saline. For a quick test, getting ECG signals while holding the electrodes between the finger and thumb of each hand is the most convenient

Electrode Tests

Initially, these tests were done with electrodes made with meter long RG58 coax soldered to ‘silver’ disks I ordered off etsy. In retrospect, they were obviously not silver. I secured the disks to the insides of my forearms with rubber bands and then typed commands while trying not to mess that up too much. This was an issue, as I would like a wearable setup and RG58 is just too thick and stiff not to shove the electrodes around causing large jumps in potential. I’ve since tried other electrode types.

Pogo Pins

Pogo pins are small, spring loaded spears with resistances of around 1 Ohm. They are used normally as surface probes for automated testing of assembled PBCs. Because they are spring loaded, I imagined the physical contact might be more secure than a flat disk on the skin.

Pogo pin electrode, no cable attached yet

I assembled the array of pogo pins by stacking layers of protoboard to keep them aligned and then soldering them in. While they worked, they did not work as well as the silver disks. The pressure it took to maintain good connections left marks.

Gold Electrodes

One point of annoyance is that chemical effects can create large potentials compared to ECG signals. For my purposes this could be filtered out with a high pass filter, but I would prefer not to do this. Being relatively chemically inert, gold is a decent material for electrodes (see Evaluation of commercially available electrodes and gels… Clinical Neurophysiology Tallgren et al 2004 for more). Sintered silver chloride is understood to be the best, see the next section for that.

Cheap gold plated electrode. The cable is very flexible which is good for preventing the tugging which causes movement artifacts.

I tried some gold plated electrodes from ebay. I would have loved to use the included cables but well shielded coax has really proved nessesary to prevent strong 60Hz interference [see footnote at end]. These are better than the silver disks, but still not ideal.

Disposable Sintered Ag|AgCl

Again off ebay I ordered electrodes, but this time disposable sintered Ag|AgCl ones.

The silver patchs on the ends of the coax are the undersides of used electrodes.

These are already coated with conductive adhesive so they stick to skin well. In an actual ECG, these are grasped with clips on the white tab, which has a conductive coating underneath it. I tried both using aligator clips on the tab and just sticking the wire underneath and the latter worked better. It is possible a different type of clip would be an improvement. This did not seem to be an improvement upon the gold electrodes, so I decided to stick with them.

*Most articles on ECG and power line noise emphasize the need for strong common mode rejection-CMRR is not the issue here. The issue is the differential signal which can be demonstrated by holding the wires out at different angles. When the wires are parallel and near to eachother, all the powerline noise is common mode and there is no 60Hz signal. When they are held out in opposite directions, the 60Hz noise is maximum, corresponding to a large differential 60Hz pickup. The obvious solution is to have wires take similar paths and only break apart at the end. I have tried this with dual conductor cables where there is only ~12″ of difference and the interference is still worse than with good coax.

Differential 60Hz signal still significant fraction of the total

EEG part 2: Replacing the ADC motherboard

The motherboard which came with the ADS1263 provides power (3.3V digital, 5V analog and ground) and an ability to communicate over USB to ADC board. The ADC itself transfers data using SPI.

ADC daughterboard, raspberry pi and voltage reference with electrodes.

To replace it, I used a raspi to power (as it has both 3.3V and 5V pins) and to get data off of the daughterboard. While the ADC worked, there was a problem with this. The raspi power pins are too noisy for accurate reference. I solved this by moving to some low noise linear power supplies. An alternative might have been to ensure constant power usage for the raspi by disabling features such as SD card use or WIFI. While testing this, it was actually possible to see the power usage change by watching the rail voltage change while typing over SSH. Reading data off with SPI also added noise, so the spi program only reads when triggered on the data out pin of the ADC

You can actually see the bits for SPI on both the 5V and 3.3V rails

(see https://github.com/garthwhelan/ads1263 for the raspi and analysis programs. The raspi transfers data over netcat to the graphing computer.)

Which produces scrolling graphs like the following:

(trace from girlfriend) There’s no 60Hz EMF if you sample at 60Hz. In all of these, it should be noted that these are the best traces, there are often terrible drifts and artifacts from electrodes moving. It would be ideal to have flexible lines to the electrodes.
At 1200 Hz, coax electrodes
400Hz, coax
After applying low and high pass filters. Exact settings forgotten

To be further continued…

SMD Soldering

My brother got me a practice surface mount soldering board with parts down to 0603. I spent an hour or two getting it assembled and learned a lot about surface mount soldering while doing it.

I ended up losing an LED, so L10 isn’t on the board. Which LED is lit progresses rightward before cycling back to L1.

One of the things I learned is to be very careful with winds. Several times I exhaled strongly and blew components around. In the end, my strategy went like this:

  • Decide a number of components to do at once.
  • Apply flux to those pads
  • Set components onto them, pushing them around slowly if nessesary. Remember that the tweezers can get sticky with flux.
  • Clean soldering iron and wet it with a bit of solder. If flux has evaporated from the soldering iron tip reclean and wet again.
  • Hold components in place with downward force from tweezers and go through touching one side of each of them. I’m aware that other people deal with tombstoning in different ways.
  • Solder the other side and clean up. Components can be moved by melting solder on both sides quickly and them pushing them around. Surface tension often corrects component location when both sides are melted.

For the ICs with more pins, the lazy thing worked best.  Generously apply solder  to the legs of the peice making no effort not to bridge them and clean up with some copper wick.

Software I use

I’m a big fan of various interfaces which are meant to be exclusively keyboard driven:

urxvt – Replacement for xterm. See the stumpwm config file below to see what options I use.

sxiv – Simple lightweight image viewer with vim-like bindings

zathura – PDF/PS/DjVu viewer with vim-like bindings

emacs – my first IDE and now I’m too old to change. I’ve  used vim, but I just enjoy pressing 3 keys at once more than having modal editing. Emacs lisp sucks so I tried climacs, a common lisp emacs port, but it’s not finished yet.

qutebrowser – Internet browser in Qt with vim-like bindings. Works a ton better than pentadactyl/vimperator/tridactyl as far as being keyboard driven and not incredibly slow. Those are also very frustrating with firefox/chrome because addons break regularly. Surprisingly, given that it’s meme software, qutebrowser actually works with almost every site I’ve tried.

stumpwm – Tiling window manager, a common lisp port of ratpoison. Wastes no screen space and is entirely keyboard driven. Can also be significantly changed when running live because it’s in common lisp. Again, it works surprisingly well, I’ve done terrible terrible things and I think I’ve only had it crash once. I’ve also had weird experiences with fullscreen stuff with games or streaming sites on other linux window managers, and stumpwm has always worked how I want. Here’s my .stumpwmrc config file:

https://github.com/garthwhelan/dotfiles/blob/master/.stumpwmrc

Some excerpts:

A sys-show-info that displays ram use, battery use, sound levels, and screen brightness when invoked:


(defun sys-show-info ()
  (defparameter temp-string1 (run-shell-command "free -h | grep Mem: | sed s/' \\+'/' '/g" t))
  (defparameter positions1 (all-positions #\Space temp-string1))
  (defparameter temp-string2 (run-shell-command "acpi" t))
  (defparameter positions2 (all-positions #\Space temp-string2))
  (echo-string (current-screen) (concatenate 'string (subseq temp-string2 (caddr positions2) (- (length temp-string2) 1)) " | Volume: " (subseq (run-shell-command "amixer get Master | sed "\
s/ /\\n/g" | grep -m 1 %" t) 1 4) " | Mem: " (subseq temp-string1 (cadr positions1) (cadddr positions1)) " | " (time-format *time-format-string-default*) " | Brightness: " (subseq (run-shel\
l-command "cat /sys/class/backlight/intel_backlight/brightness" t) 0 4)))); " | " (run-shell-command "iw dev wlp1s0 link | grep SSID" ))))

(define-key *root-map* (kbd "a") "sys-info")

Taking screenshots with scrot:


(define-key *root-map* (kbd "h") "exec scrot -u /home/dont/stumpwm_screenshots/%Y-%m-%d-%T-screenshot.png")

Opening urxvt with desired options:


(define-key *root-map* (kbd "c") "exec urxvt -bg 'black' -fg 'white' +sb -sl 65535 -b 0 -w 0 -letsp -1 -fn "xft:bitstream vera sans mono:size=8:antialias=True,xft:unifont"")

You can also do stuff with ratclick to move the mouse pointer and click. I played with some stuff for that but it never worked satisfactorily. For example one thing I tried was to bring up an overlaid grid and have the pointer move to the grid depending on what button you pressed. After this finer stuff could be done with relative motion. I’m not sure if there is actually a way to completely replace the mouse in a way that I would be happy with.

Ubuntu – I worked from Ubuntu->Fedora->Arch->Gentoo and stayed there for several years before moving back. Gentoo made me learn a ton of stuff about linux, but at this point I want software to ‘just werk’ instead of needing fixes/configuration.

EEG stuff part 1

I heard about a cure for insomnia where you use biofeedback to train yourself to have more delta brainwaves, which are associated with deep sleep. This was on the Joe Rogan Experience, which means it has to be legit. Since then I’ve made some attempts at an EEG like the OpenEEG so I can play with different forms of neurobiofeedback.

There are a variety of biological electric potentials which can be measured for biofeedback. ECG signals are higher amplitude than EEG ones and can be used to measure heart rate and health. EMG is higher frequency and measures the signals causing muscle contraction. I’m starting with ECG because it has a very clear shape and large amplitude, which will help with debugging.

To make things even easier, I started by ordering a dev board for a 32bit ADC on digikey (https://www.digikey.de/en/product-highlight/t/texas-instruments/ads1262-adc).

32 bits! That gives you minimum voltage increments of less than a nV! EEG potentials are a bit less then uV so this should make it easy.

Again, just to get something easy working, I installed windows so I could use the included software. As electrodes, at first I just tried a pair of wires soldered to silver disks as leads, which had massive amounts of interference. This was measured across my chest, with professional electrode jelly. There was always a ton of 60Hz signal. Then I moved to good shielded coax and connected my right leg to the intermediate voltage (1.6V) to stay within the voltage range. Articles mentioned grounding or driving the shields, both of which made the signal quality worse.

R and T components pretty visible, some drift and plenty of 60Hz.

And it worked! I got clear ECG traces (with a decent amount of 60Hz noise) and went to get something working on linux. In the meantime I broke the motherboard for the ADC, so I had to set up something to power it and get data off of it.

To be continued…

Fanout Board

A friend of mine wanted me to design a fanout board for a very fine ribbon cable that is used with a FPGA he’s playing with.

(https://www.digikey.com/product-detail/en/molex-llc/5025985193/WM14415CT-ND/6133145)

I made sure this would work with all the cheapest options on the prototyping company I like to use. It was a bit more difficult than I expected just because of how dense the footprint of the connector is. Hopefully he gets it ordered and assembled soon so I can update this with pictures.

First Post-Light Alarm Clock

Starting with a fringe health thing that sort of works–light alarm clocks. I’ll probably post more on light later. I think I actually got seasonal affective disorder unrelated to the seasons by being a shut-in. In short, blue light suppresses melatonin production and probably wakes you up in other ways so it’s good to have some in the mornings. There are alarm clocks meant to wake you up this way, but I ended up making my own because I have some decently high powered LEDs lying around.

Say hello to my little firehazard

I did this about a year ago, so I don’t remember what the LEDs actually are. They are probably 3-5W, Chinese ones from Ebay, and all hooked up in series to a cannibalized 15W wallwart power supply with a power MOSFET that I got from a broken computer power supply as a switch. The voltage drop of the combined LEDs was just about perfect for the power supply. I had those little heatsinks lying around but they probably aren’t nessesary. This is about as bright as a normal 60W incandescent bulb when at full power. I control the brightness using PWM with a raspberry pi. See the program here (https://github.com/garthwhelan/light-alarm-clock), with instructions for use in the comments.

To tell the truth, I don’t use this any more. Even the tiny amount of light that gets past my blackout blinds signals daytime if I’m ready to get up, and I’ll stay in bed if not. What has worked is using orange safety glasses before bed, to aid in melatonin production, and a lightbox upon waking up.