µBOT v3 – An experiment in making a small robot (part 1)

This idea of making a small robot has been knocking around my head for the past few years. Here is the original design (v1) from a few years ago:





I made a mistake when programming the “fuses” on the AVR chip which meant it was effectively bricked. For some reason I never came back to this project, until now.

The tiny stepper motors are what make this project really cool. Having a robot that small with steppers means you would have some semblance of position control which means you can do cooler stuff compared to just open loop DC motors for example.

I never actually tested the micro steppers to see what kind of torque they put out. The v2 PCB was made just to connect up the steppers and see if they could move the weight of the PCB:









It was actually kind of hard to test the torque of the motors as the weight of the wires affected things but from what I could tell the motors did indeed have enough torque to get things moving.

This brings us on to the current state of the project which is version 3. The PCB should arrive tomorrow so I will report back with the results once it’s assembled. Here is the kicad 3d model output:














The PCB is the same size as version 2. It’s got an ESP32, a lipo battery jack, a micro USB connector for charging and programming (and serial data exchange with host computer), a lipo battery charge IC to charge from USB, 2 dual H bridge motor driver ICs and a TRCT5000. The whole thing runs off a small single cell lipo.

the TRCT5000 and the microUSB are missing from the 3d view. Here is a pic of the TRCT5000 for reference:






It’s an IR emitter and receiver in one package which lets you detect the reflectivity of the surface in front of it. This sensor will be facing the ground so it could be used for line following. Not that I think of it , it would have been cool to have a front facing one also for basic obstacle detection. Will keep that in mind for v4.

The ESP8266 opens up a lot of possitibilities. I intend to flash it with micropython because I love it and it’s the best thing ever invented in my opinion. From there I can connect to wifi and do remote control from a smartphone, stream IR sensor values etc. etc.

This PCB has a fair few components and some parts I haven’t used before so the chance that I’ve ballsed something up is pretty high but I’m just glad to be making stuff again and regardless of how this version turns out it is a step in the right direction.

Stay tuned for part 2. I promise to write the blog even if it catches fire or something like that.

Here is the github repo with all design files etc.


Posted in Hardware, Ideas, PCBs | Tagged , | 1 Comment

Spooky Alexa mask documentation

Spooky Alexa

This is the animatronic mask made by Keith Colton for the 2019 Dublin Maker Faire.

This post will document the assembly and the current electronics being used. All images can be clicked on to view the full resolution image.

Mechanical Assembly:

In this photo you can see the animatronic mechanism. There are three servos in total. One for the eyes, one for the mouth and one for the neck.

Back view 1

Back view 2


This is a close up look at the eye mechanism. One servo is attached to both eyes via some metal wire. The black rectangles highlight the hinge mechanism for the eyes. Each eye has two of these nut and bolt mechanisms. The purpose of these is to allow the eye to rotate while also keeping it locked in place. If you look closely you can see that the eye is actually glued on to the nut which allows it to rotate.

Eye Mechanism


Here is a top view of the eye mechanism. The mask is divided into two seperate parts. The top part has the eyes and nose and the bottom part is the lower half of the mouth. The top part is held on by matchstick type pieces of wood and hot glue as seen here. There are two matchsticks on the top and two just underneath which are hard to see in this pic.

Eye Mechanism – matchsticks and glue


Here you can see the mouth mechanism. Basically the bottom quarter of the mask was cut off and glued back on to this piece of wood to allow it to move up and down and mimick a mouth.

Mouth Mechanism


This is the neck and mouth part of the mechanism. The neck is an upside down servo. The part of the servo that normally does the rotation is actually glued to the floor and the servo body itself rotates. The mouth servo is just above this. The metal bracket is just there for support. As the eye mechanism is in front of the neck/mouth mechanism it would not be able to stay upright without this bracket.

Neck and Eye Mechanism 1

Neck and Eye Mechanism 2



Breadboard circuit

This is the breadboard circuit used to control the mask. An Amazon Echo Dot is connected to the mask. The Echo Dot has a 3.5mm aux output. This output is fed into a circuit that amplifies the signal into a 0-5V range suitable for the ADC on an Arduino. This circuit also contains an analog envelope detector circuit. The output of the envelope detector is what gets fed into the ADC of the Arduino.

Apologies if this is a bit hard to see. The reason why there is two aux ports is because if you plug an aux cable into the echo dot it stops using its internal speaker. This is a problem for use because we want the audio to get sent to the mask but we also want to be able to hear it. So you have to split the audio. You could use an audio splitter like this to do this also. One thing to keep in mind is the aux port on the echo dot is recessed so not all aux splitters will fit (which is why I ended up making my own splitter as in the diagram).

So the audio signal from the echo dot was coming out at around 0.5 volts. This gets get into a non-inverting amplifier with a gain of around 10 or 11 ish. This amplified signal then gets put through an envelope detector. The output of the envelope detector is then connected to the ADC pin on the arduino.

One other important thing to remember is the maximum pulse lengths for the servos. Basically you could break the mechanism by driving a servo too far, there is no mechanical cut off or anything like that. The image below shows the pulse lenghts for the eyes, neck and mouth. If you go outside these you risk stripping the plastic gears in the servos.


Project update:

Here is a video that I sent to Damon a few months ago with an update on the mask:


After that video I spent a few weeks trying to get head tracking working. The idea being that the mask could be placed in a room and if someone walked past the mask would look at them as they passed by.

The PCB design files, code for the ultrasonics sensor and code for converting the adc value to mouth movement is available in this GitHub repo.

Here is a video I made about the ultrasonic scanner:

In the end, I wasn’t able to use it for tracking people. The data was just too noisy and tracking a moving object was very difficult and I just couldn’t get it working.





Posted in Ideas, Projects, Robots | 1 Comment

OpenWave #9 : Measuring significant wave height in the frequency domain


The last post looked at two time domain measurements of significant wave height, the highest 3rd calculation and the 4 times the standard deviation measurement.

It turns out that the standard deviation measurement can also be made in the frequency domain. This is because the variance of a time domain signal is equal to the area under the power-spectral density curve.

The first step of the measurement is to start out with time domain surface elevation data:


Perform a fourier transform on the data to get the frequency content:

Then convert the FFT data to a power-spectral distribution :

The area under this PSD curve will equal the variance of the original time domain signal. Standard deviation is just the square root of the variance so signinificant wave height can easily be calculated from here. The calculation would be:

4*sqrt(area under psd curve).

An example of this calculation in Matlab is available on the OpenWave Github repo. The script is called sig_wave_ex2.m:

%Generates simulated ocean elavation data
%Calculates significant wave height in the time domain and the freq domain
%(Area under PSD curve is equal to variance of time domain signal)

num_waves = 100; %number of sine waves combined to make simulated wave data
fs = 10; %sample rate
stoptime = 40; %signal duration in seconds
sample_length = (fs*stoptime)+1;

t = (0:dt:stoptime)'; % seconds

S = oceanWaveSim(num_waves, 1, fs, stoptime); %Generate simulated ocean surface displacement data
psd_area = psd_test(S, fs); %Get area under power-spectral distribution curve

fprintf('Elevation data signal variance = %0.2f\n',var(S));
fprintf('PSD area under curve = %0.2f\n',psd_area);

fprintf('Significant wave height (time domain calc) = %0.2f\n',4*sqrt(var(S)));
fprintf('Significant wave height (freq domain calc) = %0.2f\n',4*sqrt(psd_area));

%plot time domain ocean surface displacement signal

Posted in OpenWave | Leave a comment

OpenWave #8: Calculating significant wave height

There are multiple ways of calculating significant wave height (Hs). According to wikipedia, the original definition was the average of the highest 3rd of waves. What this means is you would measure wave heights(trough to crest) for a set period, order that dataset from lowest to highest, take the top 3rd of the values and get the average of those.

The more modern definition of significant wave height is four times the standard deviation of the surface elevation or equivalently as four times the square root of the zeroth-order moment (area) of the wave spectrum. This post will just look at the standard deviation method of calculation, the calculation using the wave spectrum will be covered in a later post.

Matlab was used to test this calculation. First some simulated wave data was generated (the details of this will be covered in a later post). This simulated wave data is the vertical surface displacement over time and looks something like this:

In order to calculate significant wave height using the old definition of the highest 3rd of waves requires individual waves to be measured. This can be done in Matlab by finding the local minima and maxima using the islocalmin() and islocalmax() functions. The output of these functions just returns the index number of the dataset where the min/max is found, plotting these points over the original data looks like this:


Identifying these local extrema lets you calculate individual wave heights by calculating the difference in height between one trough and the next peak. Performing this step for the entire data set gives you a set of wave heights. Taking the highest 3rd of these values and averaging them gives the Hs measurement.

The standard deviation of the input data is calculated using the Matlab std() function. This number is then multiplied by 4 to get the significant wave height.

The difference between the highest 3rd and standard deviation calculations are shown below:



The difference between the two calculation methods varies based on the dataset used but the average difference is around 30-40%. It is proving difficult to find real world examples of calculation of significant wave height from ocean surface displacement data. Most references to the Hs measurement simply state that the highest 3rd method is roughly equivalent to the standard deviation method. The results shown here do not really match with that assertion. A 30-40% difference is quite a lot which does cast some doubt on the results shown here.

The highest 3rd calculation requires identifying the peaks in the time domain which would demand a sample rate much higher than the nyquist sample rate. This method also requires more processing power as the local extrema need to be identified, for an embedded system this would be less than ideal.

The standard deviation * 4 measurement is much easier to calculate but again, because the analysis is taking place in the time domain, a sample rate much higher than nyquist would be required in order to get an accurate picture of ocean surface displacement.

The third option mentioned above of calculating significant wave height using frequency domain data is the much more appealing option. Most other commercial wave sensors can measure  ocean waves in the range 0.05-0.67Hz (1.5 – 20 second period). This means that a 2Hz sample rate would be more than enough to satisfy nyquists theorem. This low sample rate would be an advantage on a low power embedded system.

The matlab code used in this example can be found on the github repo in the folder Matlab (script name is “gen_and_plot.m”)

Posted in OpenWave | Leave a comment