Accelerometer, that tiny workhorse

The accelerometer chip (1 x 1 cm)
The accelerometer chip (1 x 1 cm)

Accelerometers are wondrous little devices that offer boundless possibilities… as soon as you figure out a need for them.

For some time now, I have been thinking about a filament break detector for 3D printing. Filament comes in spools of 400m (1 kilogram) and they are usually hung on racks on which they rotate. The filament is fed to the printer via a small stepper motor turning a grooved feed wheel. If the filament breaks, or the feed wheel eats a notch into the filament, it will no longer enter the extruder, and the print fails. Usually the filament wire breaks if it has been exposed to air humidity for a long period – it is hygroscopic and becomes brittle.

The printers are not aware of the filament feed. There is no detector for smooth feed, and consequently any hitch in feed will fail the print. I have thought of making an optoelectronic feed detector that would shine a light on the filament spool and detect its movement, but that would require a striped disc to be attached to the spool, as well as the actual reading device installed on the rack. Then I thought of a mechanical device that would ride on the filament itself and detect its movement via rotating discs, but that soon turned out to be too complex.

Then I happened upon the accelerometer. In essence it is three tiny damped masses on springs, aligned along the X, Y, and Z directions. Connecting it to 3.3V, and wiring each of the axis outputs to analog inputs of the Arduino, gives you a numerical value for each axis which you can read and act on. There are countless examples of code on how to do this wiring and coding, and I managed it within 15 minutes – my soldering skills were slowing me down as you have to solder wires to the tiny holes on the accelerometer.

Arduino Nano
Arduino Nano

The idea I had for the filament movement detector is simple: build an Arduino Nano based device that monitors the values of the X, Y and Z axis at 0.5 second intervals. When all three axis report no movement, start counting. When the no-move counter exceeds 10, indicating that the spool has not budged for 5 seconds, sound an alarm.

To test this, I wrote a small program that uses the Serial Monitor feature of the Arduino to display the values. I found that the values are between 200 and 400 for each axis depending on its alignment to the ground. I was not that interested in the values as such, as I am more interested in the difference between two measurements 0.5 seconds apart. First I tested just the values, then added three variables to hold the previous value for each axis, and a delta value for the difference. The delta value is used to see the movement.

As always, I tested this idea first on an Arduino Uno, because it is much easier to try things on it with its plug-in connectors and larger size. But for the actual device, I got hold of Arduino Nano, which has the same processing power in a much smaller package. It measures only 45mm x 14mm. It can be powered with a 6V battery and housed in a small 3D printed box. After the program has been sent to the Nano, you can disconnect the USB cable, and whenever you start the Nano, it will run that program.

The parts list:

  • Arduino Nano
  • accelerometer
  • piezoelectric buzzer
  • switch
  • 6V battery
  • pieces of wire of different colors

The wiring is rather simple too: connect the +pole of the battery to the pin Vin (for Voltage in), and the -pole to the GND pin. Connect the GND of the accelerometer to the same GND on the Nano. Connect the VOD pin of the accelerometer to the 3.3V pin on the Arduino, and the X, Y and Z pins to the analog pins A0, A1, and A2 on the Arduino. The buzzer is wired to GND and digital pin 9. All connections are to be soldered so be careful not to fry the chip or the Nano with the soldering iron.

The code is as follows:

int x, y, z;                    // axis values
int xold, yold, zold = 0;       // previous axis values
int xdelta, ydelta, zdelta = 0; // difference of the two
int zerocount = 0;              // number of sero movement instances
int sensitivity = 8;            // size of delta
const int buzzer = 9;           // buzzer to arduino pin 9

void setup()
 pinMode(buzzer, OUTPUT);       // Set buzzer - pin 9 as an output

void loop()
 x = analogRead(3); // read analog input pin 0 for x axis value
 y = analogRead(4); // read analog input pin 1 for y axis value
 z = analogRead(5); // read analog input pin 1 for z axis value
 delay(500); // wait 500ms for next reading
 xdelta = x-xold; // difference between two readings
 ydelta = y-yold; // difference between two readings
 zdelta = z-zold; // difference between two readings

 if ((((abs(xdelta)<sensitivity) && ((abs(ydelta)<sensitivity) && ((abs(ydelta)<sensitivity)))))) {
 else {
 zerocount = 0;
 xold = x;
 yold = y;
 zold = z;
 if (zerocount > 10) {
 tone(buzzer, 1000); // Send 1KHz sound signal...
 delay(1000); // ...for 1 sec
 noTone(buzzer); // Stop sound...
 delay(1000); // ...for 1sec

 else {

The ABS (absolute value) function in the delta merely accounts for the fact that the X value may be smaller than the xold value, resulting in a negative value, which would have to be handled separately. Doing the ABS gives me the difference between the values in positive integers which is all I need. The Sensitivity variable allowed me to calibrate the movement detection – the smaller the Sensitivity, the smaller the movement that counts as movement. If it wasn’t there, the buzzer would never sound, since even when flat on a table the values fluctuate between -3 and 3 in successive measurements.

The zerocount variable is added to every time all three axis show movement less than the Sensitivity variable. This means the spool has to be at complete rest. In the C++ language on which the Arduino sketch language is based, the boolean AND is represented by two ampersands “&&”. Hence the comparison in the IF clause is

if ((((abs(xdelta)<sensitivity) && ((abs(ydelta)<sensitivity) && ((abs(ydelta)<sensitivity))))))

That may look complex but it is actually rather like combining IF clauses in Excel, for example. The zerocount is reset to 0 whenever one axis shows a movement.

Device assembled
Device assembled

To house the device, I printed a small box with compartments, and will add a little latch to pin this box to the rotating spool. It is normal for the spool to not rotate for 2-3 seconds when the printer is moving the print head between layers and starting points on different layers, but 5 or more seconds will indicate a problem.

I will print a cover later, but this is the essential device as it runs. See it in operation.


Leave a Reply

Your email address will not be published. Required fields are marked *


This site uses Akismet to reduce spam. Learn how your comment data is processed.