What is this SOT-23-5 component for?
DISCLAIMER: I was not paid to write nor advertise this in any way by Bristol University or associates.
According to Bristol University electronics:
The UB20M is a sensor-driven circuit that requires no power supply (!), instead it uses power from a sensor signal to wake up. Suitable sensors are wireless antennas, infrared diodes, piezoelectric accelerometers, and other voltage-generating sensors.
So it’s basically a low power voltage sensor with pico-ampere range quiescent current draw. When I learned about it on Hackaday, I thought it would be a perfect match for lowering standby energy consumption of the PCB I was experimenting with lately: an inexpensive ESP8266+LoRa, battery powered gizmo. My idea was about detecting movement by using a piezoelectric disk and then latching the EN signal high of an AP2112 3.3V LDO.
Looking a bit further down in the Hackaday blog post, there’s an URL where I ordered a completely free sample for testing purposes, sweet.
Dave Jones on the UB20M
About two days later after receiving the free samples by snail mail, Dave Jones from EEVblog published a videblog heavily criticising the marketing machine behind the chip and rightly so IMHO.
Oh well, since I have it on my bench now, let’s see what it actually does?
The UB20M board
The board is a [convenient breakout with 3 different configurations][board datasheet] out of which I chose to test the “active-high open-drain” output since it seemed to match my target usecase, plus the other modes have an OD limit of 200mA which is unsuitable for my 600mA application:
The breadboard experimental setup looks like this in my own low tech setup:
And when connected to a piezoelectric sensor and a L6 NPN transistor that acts as a switch to the aforementioned target circuit (which for now is a simple red LED), it works as expected.
After smacking the piezoelectric component against the table and charging its associated capacitor up to ~500mV, the led turns on, turning off again when stopping the movement with the piezo, as it moves below the aforementioned threshold.
So extra circuitry and/or precious GPIO signals would be needed to latch this setup high while the main MCU wakes up and takes control of the power rail state or as stated by the Bristol team:
“Also you might need to add timing circuits on the gate lines to control turn-on and turn-off delays.”
Then looking at the whole setup and BOM required for it to integrate nicely with my PCB, MikeElectricStuff’s comments start to make a lot of sense:
Keep it simple, stupid.
Conclusion and challenge to Dave Jones
To be fair, the UB20M team has been incredibly responsive, attentive and patient to my requests and questions about the chip and board. I’m very grateful for the time and attention they have put into this experiment, specially since this kind of tinkering is not part of my day job.
Unfortunately, I don’t see the utility of this chip on my particular circuit since:
The power savings achieved are, at least, overshadowed by the quiescent current of my LDO. I’m pretty sure a simpler approach with jellybean smt parts can be put together to detect motion at low quiescent currents.
I might not have a steady supply chain for a not yet mass-produced part if I want to carry on with my design(s). I only got a board and two SOT-23-5 for tests, I’m unsure about how many more I could get in the future.
Extra PCB space to condition and properly operate the sensitive UB20M, I like my PCB boards tight and simple.
Now, what should I do with this board? Coincidentally I will be traveling to Melbourne, Australia, in a few days and had the perfect positive trolling epiphany about what to do with this board and who to send it to:
Dave, I challege you to use my UB20M board to save up a few uAmps from your micro current: pico-test your micro-current tester if you dare!
I’m a hobbyist, I don’t have the proper equipment nor money for these kind of low-amp measurements… heck, I don’t even own an oscilloscope as I’m writing this!
If you are up for it, I will send you the board by post to Sydney from Melbourne during my visit ;)
The case for local, dockerized bioinformatics
Since I started using docker on my local computer (a MacBook Air 11” at the time of writing this), I encountered issues with boot2docker+VirtualBox combo. Installing VirtualBox (plus guest additions), Docker Toolbox via Brew Casks, most of the problems stem from the volume sharing and UID/GID mappings between host and docker containers.
Then to my relief I requested access to the private Docker for Mac beta program, which uses a lightweight hypervisor and base image (hyperkit+alpine) to run containers on OSX, conveniently hiding the installation woes. This setup worked quite well and while docker on OSX does not yet support GPU passthrough processing yet (for those interested in things like Tensorflow and Keras), docker for osx is a really convenient local docker setup.
Frustratingly, my local docker setup was always accompanied by tests on our local HPC cluster that has limited docker support and a small AWS instance. Almost invariably I resumed my development efforts on the HPC/AWS setups instead, because, you know, beta.
In contrast, a large share of my colleagues
do use OSX as a
workstation mosh shell to their respective HPC clusters where they launch test runs. Why don’t we use the local CPUs a bit more for testing?
That was the state of the art with bcbio+docker+osx: not using it locally…
bcbio-nextgen and CWL
As peers in the bioinformatics community have noticed, the Common Workflow Language is getting workflow and pipeline engines migrating to CWL as their underlying workflow representation, including but not limited to Arvados, Galaxy and bcbio-nextgen.
In order to have a minimal development environment while migrating bcbio-nextgen internal logic to CWL, Brad Chapman wrapped a small demo that can launch bcbio_vm, CWL and Toil (SLURM support under Toil is a WIP right now).
So please go ahead and:
- Install Docker for Mac.
- Install Miniconda if you don’t have it already.
conda install bcbio-nextgen-vm -c bioconda.
tar xvfz test_bcbio_cwl.tar.gz&&
chmod +x run_cwltool.sh&&
Those will download a ~2GB bcbio docker image and then run a sample bioinformatics workflow under docker for OSX in your computer.
Thanks to Robin Andeer for being one of the first brave souls to test this out and please feel free to report back your experiences running this experimental setup in the comments section below!
GSoC 2016 Post-midterm ideas
After having a successful midterm evaluation for argparse2cwl where Anton Khodak successfully:
- Surveyed the python argument parsing landscape.
- Covered the argparse API with equivalent CWL terms.
- Generated CWL files out of an example bioinformatics package, CNVkit.
- Wrote tests and documentation for the above points.
- Engaging with the community through gitter, mailing list and his project blog, while getting ideas on how to improve and conduct the project in a way that is helpful to the community.
He will be tackling the next stage of this GSoC 2016 on CWL. This is a summary of the brainstorming and ideas that Anton is going to pick and undertake during the next 6 weeks.
The idea would be to have a commandline tool that:
- Queries/downloads an arbitrary pypi package specified by the user (i.e: ./pypi2cwl cnvkit).
- Checks for argparse presence in its scripts/code.
- Runs argparse2cwl against it and generates the associated CWL output files.
- Generates a pull request for review to add the templates to the CWL community repository
Building on top of the CNVkit experience that Anton has, this would be very valuable to automate the wrapping process further and potentially explore the conversion of python packages in bulk.
A desired outcome for this sub-project would be to have an output similar to that of http://pythonwheels.com, where the overall coverage and bugs can be spotted quickly.
As any conversion tool that has a “2” in the middle, isn’t it worth to flip it over? That’s what cwl2argparse would do ;)
In a future where everyone wraps their tools with CWL (ha!), one would like to be able to:
- Write a cwltool definition.
- Run cwl2argparse against you_newly_wrapped_tool.cwl.
- Generate argparse code to import into your Python program.
Since we have already generated CNVkit’s CWL, what would be the expected output of, for instance cwl2argpase tools/cnvkit-batch.cwl would generate an argparse definition that could be imported in a Python program and used, i.e:
P_batch = AP_subparsers.add_parser('batch', help=_cmd_batch.__doc__) P_batch.add_argument('bam_files', nargs='*', help="Mapped sequence reads (.bam)") P_batch.add_argument('-y', '--male-reference', action='store_true', help="""Use or assume a male reference (i.e. female samples will have +1 log-CNR of chrX; otherwise male samples would have -1 chrX).""") P_batch.add_argument('-c', '--count-reads', action='store_true', help="""Get read depths by counting read midpoints within each bin. (An alternative algorithm).""") P_batch.add_argument("--drop-low-coverage", action='store_true', help="""Drop very-low-coverage bins before segmentation to avoid false-positive deletions in poor-quality tumor samples.""") (...)
Pretty much what John Chilton does for Bash via cwl2script, Anton can try to do it for python’s argparse so that a developer only has to update their tool definition to generate argparse code for newly introduced flags. Adding in new python argparsers such as click, arg[N] or optparse
According to Anton’s first blogpost, there are a few other argument parsers that could use some CWL automation. The next on the list to implement, when accounting for packages that use it, would be python’s core argument array (arg, arg, …). On the other hand, given its free-form nature, it can be challenging to assign and transform semantics from it to CWL like the others parsers. For instance, flags, arguments and types are all well specified on click or argparse.
Or perhaps click would be more interesting to wrap given its ramping up in usage by the community? Worth exploring in any case.
Discarded idea (for now): Fuzzing support for argparse2cwl: argparse2cwl-fuzz
Last and least, after some deliberation, argparse2cwl-fuzz could be a bit too far away from this project scope and resources: writing a stub for bioinformatics fuzzing.
As pointed out in the original proposal:
(…) explore and optimize the parameter/flag space of i.e, bioinformatic aligners with Teaser.”
Instead of going all the way and create a benchmarking/validation suite and file format fuzzing, just providing some support for argparse2cwl and generating different commandline flag combinations, somewhat like biopsy and Teaser do.
Could be tackled in a future GSoC project maybe?
Should electronics be repairable?
The question seems to ask for a resounding “of course” in my mind, but today I woke up to the following video by Louis Rossman about the right to repair bill and how legislators are trying to counter trade secret lobbyists. If you care about your right to repair your electronics, either by you or a professional, take some time to hear what Louis has to say as a talented independent electronics repairman:
Rossmann mentions how stupid it would be to not be able to repair your own electronics and share how you did so with the rest of the world as he does with Apple products. That thought resonated with me, specially when I decided to look into my faulty drone as a hobby repair recently.
So if you don’t care much about that bill and you are a tech geek like me, take a look at how I fixed my ~$300 drone by fixing a software glitch in one of its motor’s microcontrollers. Then please, rethink again how that bill would affect us all and raise your voice.
One motor not responding
A couple of years ago I was showing my drone to a friend when it started to wobble mid-air and crashed. I could not get to fly it again, nothing seemed wrong with the motors or anything. When re-connecting the battery, all propellers twitched (initialization sequence) except one:
How annoying is that? Everything seems to work except one (upon visual inspection) undamaged motor? Why?
Connecting to the drone (via telnet) and seeing the logs:
0.970751 NULL 6 909390645 BLC call for motor 1 1.970768 NULL 6 909390645 BLC motor 1 flash & start FAILED 2.030722 NULL 6 909390645 BLC call for motor 2 2.142945 NULL 6 909390645 BLC motor 2 soft version 1.43, hard version 3.0, supplier 1.1, lot number 11/10, FVT1 17/11/10 2.200720 NULL 6 909390645 BLC call for motor 3 2.312925 NULL 6 909390645 BLC motor 3 soft version 1.43, hard version 3.0, supplier 1.1, lot number 11/10, FVT1 17/11/10 2.370718 NULL 6 909390645 BLC call for motor 4 2.482919 NULL 6 909390645 BLC motor 4 soft version 1.43, hard version 3.0, supplier 1.1, lot number 11/10, FVT1 17/11/10 2.510740 NULL 6 0 BLC motor 1 dead 2.510942 NULL 6 0 BLC reflash required, perform off/on cycle (...) 1.005742 NULL 6 909260344 BLC call for motor 1 1.026300 NULL 6 -1096575148 BLC start flash 1.816389 NULL 6 -1096575148 BLC flash done 1.816557 NULL 6 -1 BLC verify 1.835135 NULL 6 -1 BLC verify FAILED - page 0 (...) !!! Emergency landing from /home/aferran/[...]/version/[...]/Soft/Build/../../Soft/Toy//Os/elinux/Control/motors.c:1593. Reason is Motors have not been initialized correctly
I performed the off/on cycle by reconnecting the battery several times, no luck. Reflash required… but how? There are no instructions for doing that reflash, just power off/on cycle which clearly does not work in my case.
At this point, all the manufacturer tells you is to buy a completely new motor, worth almost $50 plus shipping:
But I insist, nothing seems wrong with the motor itself, neither the few DMC3021LSD MOSFETs that are around the motor board, so it clearly seems like a software issue… with the Atmega8A microcontroller present in each of the 4 motor boards… the microcontroller datasheet states that they should work for 20 years and withstand 100.000 programming cycles. I definitely did not use it neither for that long nor that many times, so it got me curious: what if I could just fix it myself while I still have the right to?
Not bothering opening my drone
So at this point, many people would either buy that motor or throw that dead toy to a pile of e-waste.
First, before reaching to the screwdriver, let’s learn a bit about how that gadget is built by not opening it until it’s necessary via FCCID.io. There’s a great block diagram which details all its ins an outs:
Also external and internal photos on how the different boards and components look like.
See those MISO/MOSI/SCK and RESET test points in the motor pinout? Those can be used to communicate with our confused AVR microcontroller.
Time for some wiring up a couple of motors with a Raspberry PI
Using a Raspberry Pi one’s GPIO pins acting as a microcontroller’s programmer and AVRdude running on it (just a plain
apt-get install avrdude away on a recent raspbian), we can read and write the contents of the faulty motor board:
The pinouts in AVRdude must be defined in their physical mapping. There are tons of diagrams available online on how those are distributed in the different raspberry pi versions, so pick and choose your favorite rpi GPIO pins and tell AVRdude accordingly via
programmer id = "motor_1"; desc = "Use the Linux sysfs interface to bitbang GPIO lines"; type = "linuxgpio"; reset = 25; sck = 11; mosi = 10; miso = 9; ; programmer id = "motor_2"; desc = "Use the Linux sysfs interface to bitbang GPIO lines"; type = "linuxgpio"; reset = 14; sck = 4; mosi = 3; miso = 2; ;
If all goes well and it’s properly wired, you should get this from avrdude:
$ avrdude -p m8 -C /etc/avrdude.conf -c motor_2 -v (…) avrdude: AVR device initialized and ready to accept instructions
Reading ################################################## 100% 0.00s
avrdude: Device signature = 0x1e9307 (probably m8) avrdude: safemode: hfuse reads as DC
avrdude: safemode: hfuse reads as DC avrdude: safemode: Fuses OK (E:FF, H:DC, L:E4)
avrdude done. Thank you.
Then it’s just a matter of running avrdude to read the contents of the flash, eeprom, fuse and lock bits:
# avrdude -p m8 -C /etc/avrdude.conf -c ardrone_motor_2 -U flash:r:flash.hex:i -U eeprom:r:eeprom.hex:i # avrdude -p m8 -C /etc/avrdude.conf -c ardrone_motor_2 -U lock:r:lock.hex:i -U hfuse:r:hfuse.hex:i -U lfuse:lfuse.hex:i
How can we tell the dead from the living? Using UNIX diff.
Diffing the motor’s bits
Why did I connect two motors, that is one healthy and one “dead”, instead of just the faulty one?
As I learned from bioinformatics, comparing NORMAL vs TUMOUR tissue can reveal useful insights about biology. After this really stretched yet handy analogy which I probably should be embarassed about, let’s see what I found:
$ diff -u motor1/eeprom.hex motor2/eeprom.hex --- motor2/eeprom.hex 2016-06-06 08:47:26.815120557 +0000 +++ motor1/eeprom.hex 2016-06-06 09:35:17.664976258 +0000 @@ -1,4 +1,4 @@ -:20000000AC8A0001018A0A110BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F +:20000000FF030001010B0A120B0AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 :20002000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 :20004000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 :20006000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 diff -u motor1/lock.hex motor2/lock.hex --- motor1/lock.hex 2016-06-06 10:00:38.532028704 +0000 +++ motor2/lock.hex 2016-06-06 09:09:24.738241220 +0000 @@ -1,2 +1,2 @@ -:0100000003FC +:010000002FD0 :00000001FF
So the EEPROM holds information that I have no time to reverse engineer now (motor coil timing calibration? total flight hours?… no clue).
On the other hand, the lock bits got me interested. As Alexander and Boris say in their AVR workshops: “when in doubt, look at the datasheet!”.
So the datasheet states the following about lock bits near table 86 on page 215:
The ATmega8 provides six Lock Bits which can be left unprogrammed (“1”) or can be programmed (“0”) to obtain the additional features listed in Table 86. The Lock Bits can only be erased to “1” with the Chip Erase command.
Alright, so what if we just erase the chip with
avrdude’s -e command?
avrdude -p m8 -C /etc/avrdude.conf -c motor_1 -e
And then reflash the flash back?:
avrdude -p m8 -C /etc/avrdude.conf -c motor_1 -U flash:w:flash.hex:i
To be fair, those locks might be enforced when the firmware detects that there’s a serious mechanical issue with the rotor, which defaults to cutout/shutdown if there’s something wrong with it, preventing worse damage involving burned MOSFETs, destroyed motor coils, etc…
But since there are no further specs nor documentation from the manufacturer about this topic other than
"Motors have not been initialized correctly"… how should I know if I want to?
In any case, that’s it, I just saved the environment and $50 by unlocking an incorrectly software-locked hardware!
There are a few bits missing on how I debugged this issue and saved some followup reverse engineering work Hugo Perquin did on his blog. About reverse engineering, I might present some work at the first Radare2 conference.
But anyways, I hope to have raised some awareness about the right to repair while entertaining some nerds like me ;)
Cross compiling toolchains today
When embarquing into embedded systems development to fix relatively old hardware, a need becomes clear fairly early: recompiling software on an embedded system becomes a daunting task due to too old base system or simply irritatingly slow to iterate.
That is why distributions such as Debian really shine with their support and commitment for multiple architectures. So all is fun and happy development until someone reaches out to the documentation on how to setup a cross-compiling toolchain.
But wait, there’s crosstool-ng, seems to be a wrapper that could help me cross-build my binaries…
$ ct-ng armv5-linux-gnueabi make: *** No rule to make target `armv5-linux-gnueabi'. Stop. $ ct-ng armv6-rpi-linux-gnueabi LN config MKDIR config.gen IN config.gen/arch.in IN config.gen/kernel.in IN config.gen/cc.in IN config.gen/binutils.in IN config.gen/libc.in IN config.gen/debug.in CONF config/config.in # # configuration written to .config # *********************************************************** Initially reported by: Yann E. MORIN URL: http://ymorin.is-a-geek.org/ Comment: Toolchain for the Raspberry Pi, with hard-float. ***********************************************************
So that is hard-float raspberry pi support by default, which will give me an
Invalid Instruction exception so I should activate
.config and then… sigh.
Cross compiling toolchains with DockCross
$ docker run thewtex/cross-compiler-linux-armv5 > ~/bin/dockcross $ chmod +x ~/bin/dockcross
$ dockcross --image thewtex/cross-compiler-linux-armv5 ./configure --with-compiler=armel --host=armel $ dockcross make
For an extra icing in the cake, it is worth mentioning that DockCross also supports QEMU emulation that can be used in the same container, right after your binaries are built.
Furthermore, for the cherry in the cake, have a look at TravisCI running QEMU for ARM, unbelievable.
Happy hacking and x-compiling!
QEMUlating SDL/OpenGL inside Docker for Mac?
Using Nut to spawn containers with X11 support:
$ cat nut.yml syntax_version: "6" project_name: TurboLoader macros: run: usage: xcompile and qemu TurboLoader in a docker container docker_image: aretroui privileged: true enable_gui: true security_opts: - seccomp=unconfined
$ nut run ** Test project ** ¿¿ Smoke test Lua ?? ¿¿ Startup environment ?? libGL error: No matching fbConfigs or visuals found libGL error: failed to load driver: swrast X Error of failed request: BadValue (integer parameter out of range for operation) Major opcode of failed request: 150 (GLX) Minor opcode of failed request: 3 (X_GLXCreateContext) Value in failed request: 0x0 Serial number of failed request: 82 Current serial number in output stream: 83