Posts

Motor drivers

I previously posted about a DRV8835 dual motor driver. In my new balancing robot, I've used a a TB6612FNG instead, basically because the board is a tiny bit bigger, so I can use PCB card guides to hold it. Pololu and Sparkfun both make carrier boards which are nearly identical. If you use the TB6612FNG like an LM293D, then it drive/breaks rather than drive/coasts. For lots of things, this works well: the relation between speed and PWM pulse width is more linear. I'm not sure how it interacts with PID though: the torque applied depends on the speed. When the speed is low, the torque is higher. That tends to happen when the bot is close to upright and balance. That sounds sub-optimal. It turns out that if you just set the PWM pins on the TB6612FNG high, it then behaves just like a DRV8835 - i.e. you can choose between drive/break, and drive/coast. You again need two PWM pins, but these STM32 boards have plenty of timers, each able to drive 4 PWM outputs, so that's fine....

ESP8266 and the balance bot

Image
I've built a new balancing robot. Unlike the last one it actually works a bit, which is nice. I've been working on it for quite a while, and neglecting to post about it, which leaves me with the dilemma of what to write about first. One of the most annoying things about the previous development experience was using Bluetooth. Specifically Linux Bluetooth support. The main reason for using a Bluetooth serial module was it's low cost. Now you can pick up a ESP8266 WiFi module for less than £2. Since WiFi is so much better supported than Bluetooth, it seems like a no-brainer. There are quite a few different formats out there, and I've bought a few different ones. At the high end are the NodeMCU boards. These include a usb serial adapter, and require the least fiddling around to get going. I recommend you get one, because what you are going to find immediately is you need to flash whatever you buy with a newer firmware. The flashing tools will just work with one of ...

Raspberry Pi PWM

There is now an accurate way to do PWM on the Raspberry PI: pi-blaster . I decided, to make things easier than using a micro controller, to use a Raspberry Pi to control my aquarium light. I've tried using a few other PWM libraries, but pi-blaster is the first one not to flicker. Here's the little python script I wrote. I should try submitting a pull request to change pi-blaster to use sockets, and conform to the LSM by putting it's socket in /var/run or similar, but the pipe interface is a good idea compared to having to have a binding to each scripting language.

Date and time

I've got a reasonably small date-time library working in Picobit. I started off with SRFI-19 , but found it's reference implementation used floating point numbers for Julian day, and used Julian day to calculate conversions between UTC and the Gregorian calendar. Trying to figure out if I could change this to integer arithmetic didn't seem that easy. Instead, I found a ground up integer method in Joda-time, and used that instead. It's calculation is incredibly easy to understand, once you get over the fact that it's pulled to pieces into several subclasses and helpers, to the extent that you wonder why everyone doesn't do it the same way. I got to simplify it even more, because Picobit gives you more latitude with arbitrary precision. The result is fairly like SRFI-19 but ignores leap seconds, and therefore the distinction between TAI and UTC , replacing them with time-real. This makes all the more sense given that most microcontroller projects will probably...

Picobit native endian

If I'd been paying attention, I'd have noticed that Picobit's memory access primitives emulate big-endian byte ordering. This sort of makes sense in the case of constants and the byte code: It makes picobit's images portable. I'm not actually interested in this, however: I build binaries for specific platforms. Even if I was, it's preferable not to do this for RAM. After a bit of hacking and debugging I've made RAM access native endian. Actually I've only tested it on little endian systems: X64 and ARM in little endian mode (which is the default for Chibios). I have a very limited performance test: 11 queens. The difference this makes varies depending on the optimisation settings. Picobit suggests -Os. I've also tried -O2. These are the results for amd64: -O2 -Os Size Time Size Time Native-endian 53040 3.119 49864 6.340 Big-endian 56848 3.733 50192 7.908 ...

Picolisp

A college pointed out Picolisp  because of my work on Picobit. The paper  mentions Picobit and discounts it because a foreign function interface would be difficult to implement. This isn't exactly true: I've been linking Picobit programs into ARM executables, and that certainly means I could link actual function addresses should I want to: I could generate C code containing a vector of the foreign function references, and link this into the resulting program. Once I have done this, I can define a foreign function primitive that uses the vector to call them. This will certainly be some work, but not as much work as writing Picolisp! That isn't what I'm currently planning to do, however. I plan to copy Unix and define a limited set of operations for IO, define device numbers and route these calls to an appropriate driver according to the device number. One of the calls will be ioctl, which will allow arbitrary scheme data structures. I could use python's approac...

Multiple return values, receive and apply

I've got multiple return values and apply working in Picobit, and that means Picobit can compile SRFI-1. This post to remind myself what I am trying to achieve, because this has been a long detour. I'm actually trying to get the time library in SRFI-19 working. It needs SRFI-6: string ports, SRFI-8: receive and by extension multiple values support. This is nothing to do with SRFI-1, other than it seemed like a good candidate for testing multiple values. My multiple values work like this: I created a 'values' type, which is just a wrapper around a list. (values ... ) returns one of these. Two primitives: (#%apply-call proc values) and (#%proc-jump proc values) apply a proc to values (jump is for tail calls). To get the two different primitives to be called in the right places, I added a new AST node type specifically for apply, and then matched it in the compilation phase. Having looked into SRFI-6, I now realise I don't have R5RS io primitives. Some of the nam...