Introduction: How to Make a 3D Filament Meter

About: I love create and share for the community. The world of 3d printing opened my mind to new creations. Instagram @BJ3D

Maybe you handle several 3d filament spools and you would like to know how much you consume from each spool to have a better control of your stock. We know that approximately a 1kg coil has 330 m, so if we measure the meters we are consuming, we will be able to intuit with certain accuracy when it will be finished.

On the other hand I have also noticed that the slicer programs do not measure exactly the time nor the length consumed. For all this I decided to make a device that could measure time and meters consumed by each of my spools, I documented but did not find what I really wanted, so I made a remix of a filament meter that I found in instructables(Here de original proyect).

I have done a total redesign of the application. I have programmed a menu to choose the spools, I have added an additional optical sensor to make an encoder and to detect the direction of the filament while printing, a database on an SD card and also a filament runout sensor.

Follow me on Instagram -> @BJ3D

Step 1: What You Need

  1. Arduino board ( I used the Arduino UNO for prototyping and Arduino Pro Mini for the device)
  2. LCD 16x2 ( I used an I2C LCD because only use 4 pins, but a normal LCD it's ok)
  3. Micro SD card reader and a micro SD card.
  4. 3 switches
  5. Optical sensors (I have recycled them from an old printer, you can also buy them with cables)
  6. Resistances
    1. 2 x 1K
    2. 2 x 12K ( I used 4 x 6.8K because I didn't have more )
    3. 1 x 6.8K
    4. 1 x 480R
    5. 1 x 2.2K
  7. Perfboard
  8. Some cables

Step 2: Let's Solder the PCB!

I leave the scheme in case someone wants to do it.

- The power supply proceed of printer's electronics(5V and GND).

- To connect the runout sensor you need a pin from the MCU to control the position of the switch (exactly like a limit switch).

You have to define it in the pins_XXX.h file corresponding to the board (where XXX is your name in Marlin), assigning that pin number to the FIL_RUNOUT_PIN parameter.

Finally, you must enable the function in the Configuration.h file, in the following lines:



#define NUM_RUNOUT_SENSORS 1 // Number of sensors, up to one per extruder. Defines FIL_RUNOUT#_PIN for each.

#define FIL_RUNOUT_INVERTING false // set to true to invert the logic of the sensor.

#define FIL_RUNOUT_PULLUP // Use internal pullup for filament runout pins.



The parameters to be configured are quite evident: number of sensors (if there is more than one extruder), switch logic (as in the limit switches), enable internal pull-up resistors (in case a direct line is used) to the MCU) and the script that will be executed when the end of the filament is activated.

By default, that script is an M600 command for the filament change. You can put here the commands that you want to execute when the sensor indicates this situation.

If it is left by default, you must activate the functions ADVANCED_PAUSE_FEATURE, in the Configuration_adv.h file, so that the command M600 and NOZZLE_PARK_FEATURE are enabled, in the configuration.h file, since it is necessary for the operation of the previous one.

I have connected my sensor to pin 11 and GND, I use a mks gen v1.4. If you have the same board, choose the Ramps 1.4 in Marlin and go to the pins_Ramps.h file and change the FIL_RUNOUT_PIN from pin 4 to 11, that worked for me.

If you have a Ramps by default it uses the servo pin 3.

- I have connected the filament metter to pin D57 of my mks gen, it's an auxiliar pin, this is used for when the printing ends, send a signal to save the information on the sd card.

You must place in your slicer in the start code:

M42 P57 S0 -> puts us pin 57 in GND

and in the end code:

M42 P57 S255 -> puts pin 57 on + 5V

You can ask whatever you want.

The scheme I did in "easyeda" a free online application.

*it is better to separate the keypad, so you can make a more compact device.

Step 3: Code and Test

I will explain here important things, take a coffee.

3.1. Create a .csv file:

CSV(comma-separated values) are a type of document in a simple open format to represent data in the form of a table, in which the columns are separated by commas and the rows by line breaks.

This will be our database, we can add all the spool that we want.
I have listed the spool in this way: # 001, # 002, # 003 ... To each spool you put a sticker with that reference and you will know which one you use at each moment. To create the csv create a spreadsheet with excel, open office or google drive. Remember to write everything as plain text, since our sd card will read only plain text. Then export it as file.csv, a text file with the data separated by commas will be generated.

3.2. Configure the Arduino sketch:

Download the sketch and open it.

You will only have to change 2 variables to adapt it to your needs.
The first is num_bobinas, which indicates the number of spools you have. (Remember to add them manually in your database) The second one is an array, POSITIONS ["number of spools"] = {"Here you will put the position where the row of each spools starts, I explain it to you better*}

* Explanation -> The SD card reads our plain text file as lines of characters, each character counts as one, but apart each end of line has "\r\n" that counts as 2. For example, in the first line we have "SPOOLS,SPEND METERS,TIME PRINTED(DD:HH:MM:SS)\r\n", if we count it is 47 characters, therefore our first position where coil #001 starts will be 47.

This would be the next line "#001,000000,00:00:00:00\r\n" (25 characters), etc ...

3.3 The wheel and the encoder:

I have designed the wheel, in such a way that it has 7 teeth and 7 holes. The optical sensors must be placed in such a way that they can be covered at the same time by a tooth and also that they are free at the same time in a hole.

If they are well placed, a sequence will be formed when the wheel is rotated: HH-LH-LL-HL and repeat. When the complete sequence in the program is fulfilled, a counter will increase its value (it also decreases when it goes backwards) and then multiply it by a variable where the meters traveled are indicated, this is explained below.

One tooth has 24.2º and one hole has 27.3º.

7 * 24.2 + 27.3 * 7 = 360º

The wheel has a recycled rubber from a printer attached to it to make friction with the filament and to turn it. When I insert the filament, one complete turn of the wheel is equivalent to 5.3 cm,this may be different for you if you use another rubber diameter, I explain the calculations.

The counter increases when a tooth and a hole pass through the encoder, that is,

24.2º + 27.3º = 51.5º.


360º --------- 5.3 cm

51.5º -------- x

x = 0.76 cm = 0.0076m for each sequence for my wheel. I put this in my variable "meters" of the program and ready.

3.4 Now you can upload the code and test all:

  1. Choose your spool
  2. You can see the data of that spool
  3. Start measuring
  4. Save in the SD
  5. Check that it has been added
  6. You already have it!

Step 4: Some 3D Printing and Assembly

I have printed the pieces in PLA, 0.2 mm high layer and only the enclosure_bottom needs supports.

To assemble the electronics I used some recycled screws and glue.

The most problematic part is the wheel, you have to find the exact friction point with the filament so that the wheel turns but does not brake the filament too much. In the piece "filament guide" and in the part of the runout sensor I have put teflon tube to slide the filament.

Finally, I screw everything in my aluminum profile of the printer and I connect the power in the electronics of the printer and the runout sensor in pin D11 of my mks gene v1.4.

You have the stl, step and Fusion 360 files.

Step 5: How to Use the Metter

  1. Turn on your printer.
  2. Choose a filament.
  3. Choose your gcode and start printing.
  4. Press "start" on the meter.
  5. When the printing finishes, press "OK" and the changes will be saved in the SD.
  6. You can see the data of the spool.

Remix Contest

Participated in the
Remix Contest