Machine Learning Robot Driving Autonomously with Arduino and LIDAR

The first video (the one above) was quite successful and the feedback was very positive so I made another one where I cloned the robot and made them race! It’s cool and there were plenty of interesting problems that I had to solve to get it working (spoiler: in the end, it worked). Here it is:

Currently, I am doing my master’s in data science. The learning process at the university is definitely not the most interesting one, but I do enjoy new information about topics I never heard about like machine learning, data processing, classification, and so on. To put this new knowledge to the test and understand it even more (theory and boring classes will take you only so far) I decided to build my own Arduino-based robot with a LIDAR and try to train it to autonomously navigate on a race track build out of cardboard 🙂

The video linked above goes through the whole process and explains it very well but here you can find some supplementary information, code, and my data collected for training.

Before we start I would like to say thank you for reading about my projects and watching my videos! I really appreciate it as working on these projects is not easy, and takes a lot of time and money. If you would like to support my work you can do that through my merch, Patreon or Store. Thanks a lot!

Robot

The robot was built according to ORP design rules, You can read more about the project here:
https://openroboticplatform.com/

ORP parts used to build the chassis:

NameLink
160mm circular platehttps://openroboticplatform.com/part:3
160mm circular plate with wheel cutoutshttps://openroboticplatform.com/part:4
RPLIDAR holderhttps://openroboticplatform.com/part:48
Cheap yellow (TT) motor holderhttps://openroboticplatform.com/part:6
170 point breadboard holderhttps://openroboticplatform.com/part:36
SD card module holderhttps://openroboticplatform.com/part:37
L9110S motor driver holderhttps://openroboticplatform.com/part:38

That made building the robot much easier and let me reuse parts from this robot in my future projects. Parts I used are rather popular and inexpensive but also can be replaced by something you have at hand. I am positively surprised by the cheap yellow motors I used in this project. I remember facing some problems with these in my previous projects but here the experience was really smooth. Below you can find a list of all the parts used to build the robot. I used a different lidar but it’s not available anymore.

NameLink
Arduino Uno R4https://amzn.to/44OeeIA
SD card modulehttps://amzn.to/3Pw6feS
Bluetooth modulehttps://amzn.to/3sOiSZV
Motor driverhttps://amzn.to/3sUmo4U
Breadboardhttps://amzn.to/3Rh1sPZ
LIDARhttps://amzn.to/45Laj0F

Data collection:

Collecting the data was an easy step as I prepared everything earlier. With an app on my Android phone, I was able to easily send the control orders to the robot. Arduino was reading that through the serial port and driving accordingly. To simplify there are only 3 states allowed: forward, forward left, and forward right. While controlling the robot you are also allowed to stop and go back but during these maneuvers, the data is not saved on the SD card. Data is saved 5 times a second on the SD card – 240 measurements from the LIDAR and at the end there is a letter F, G or I that is the control label. Then I spent about 30 minutes on driving the robot around to collect enough data, pretty fun thing to do 🙂

All the data that was collected during this project can be found on GitHub in case you want to play around and train your own classifiers.

Feature selection:

The first step is to select the most important features present in our dataset. There are 240 points but we don’t need all of them to properly drive around, most of that data is just noise (for example all the points that are behind the robot, we don’t need them). That’s why we are going to select only the features that are the most correlated with our labels. It sounds super hard but there are ready Python functions for that inside scikit learn library.

I also modified a visualization program I created a while ago to display the data from the SD card and highlight the selected features. That way it’s super easy to visualize what exactly was selected and it really makes sense as only the points in front of the robot on the left and right were selected.

Training the classifier

When the features are selected it’s time to choose and train the classifier. I will keep it short as I am not yet that comfortable with explaining how it all works and why random forest worked the best in my case but it did and that is what I used in the end. I tried a few different classifiers but random forest performed a little bit better than the others. Training the classifier is also super easy thanks to libraries and it is not time-consuming at all, it literally takes a few seconds to do that.

Here is the code for the selection, training, and testing of the classifier.

import numpy as np
import pandas as pd
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import f_classif
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
import matplotlib.pyplot as plt
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, classification_report
from micromlgen import port

def letters_to_colors(letters):
    color_mapping = {
        'F': 'blue',
        'G': 'cyan',
        'I': 'magenta'
    }
    
    return [color_mapping.get(letter, 'black') for letter in letters]

data = pd.read_csv('I:/arduino lidar/visualizer/test4567.txt', header=None)
data.rename(columns={data.columns[-1]: 'Label'}, inplace=True)
data = data[(data['Label'] != 'L') & (data['Label'] != 'R') & (data['Label'] != 'H')]
data.reset_index(drop=True, inplace=True)
X = data.iloc[:, :-1]
y = data.iloc[:, -1]

label_encoder = LabelEncoder()
y = label_encoder.fit_transform(y)

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

k = 15
k_best = SelectKBest(score_func=f_classif, k=k)
k_best.fit(X_train, y_train)

selected_feature_indices = k_best.get_support(indices=True)
print("selected_feature_indices: ", selected_feature_indices)

plt.scatter(data.iloc[:, selected_feature_indices[0]], data.iloc[:, selected_feature_indices[9]], c = letters_to_colors(data.iloc[:, -1]), s=8)
plt.show()

clf = RandomForestClassifier(max_depth=3, random_state=42)
clf.fit(X_train.iloc[:, selected_feature_indices], y_train)

y_pred = clf.predict(X_test.iloc[:, selected_feature_indices])

accuracy = accuracy_score(y_test, y_pred)
print(f'Accuracy: {accuracy}')

class_names = label_encoder.classes_
report = classification_report(y_test, y_pred, target_names=class_names, zero_division=0)
print('Classification Report:\n', report)

arduino_code = open("arduino_random_forest3.c", mode="w+")
arduino_code.write(port(clf))

Running the machine learning classifier on the Arduino

Here is a very good and simple tutorial on how to convert the classifier from python to Arduino and most importantly it just works as you expect it to!

https://eloquentarduino.github.io/2019/11/how-to-train-a-classifier-in-scikit-learn/

After uploading the code to the Arduino for the very first time I wasn’t sure what to expect but it just started working exactly as I wanted it to! So running the machine learning on the Arduino (at least the new Arduino board like Uno R4 with a more powerful microcontroller or MKR series) is not a problem.

RACING!!!

So the second video was focused on making both robots race. I wanted to teach them to avoid each other. To simplify the problem one of them was meant to drive slowly and the other fast with the aim to catch up with the first one every few laps and attempt to overtake without crashing or destroying the race track. It might sound simple but it’s not and some basic data science principles can be observed with the development of this project. In case of any questions please let me know I will extend this article!

Toroidal propellers experiments

The whole world heard about toroidal propellers when MIT published its studies (February 2023). While some similar concepts were developed earlier and they were not the only ones working on this problem they definitely got plenty of attention. People on YouTube have been testing it in various scenarios ranging from drones to PC fans. This post tries to present a different attempt and hopefully will be developed in the future to show some of the experiments performed by Nikodem Bartnik on the topic of toroidal propellers.

The idea for an experiment was first born when the concept of toroidal EDF happened to stumble across my mind. The results of the tests can be found below:

An important question should be asked, does it make any sense to make a toroidal EDF? I don’t think so. Because of how an EDF works it will not benefit a lot from a toroidal propeller. Nonetheless, I wanted to try, experiment and measure some data in order to see it on my own.

Check out my products and support my work!

The results of the fan performance regarding thrust and max wind speed can be observed on the plots below.

All the files used to print this EDF with different versions of the propeller can be found here:

https://www.thingiverse.com/thing:6111321

Parts list

The parts list for this project is rather short as you only need a motor, ESC, and an RC remote. The rest of the parts are 3D printed.

NameAmountlink
A2212 motor1https://amzn.to/3POZw0n
ESC1https://amzn.to/3rpmZes
RC remote1https://amzn.to/3O5Mp9H

if you want to perform some experiments like I did a thrust stand might be useful. I build one 5 years ago, here you can find detailed instructions on how to do it:

https://www.instructables.com/Brushless-Motor-Thrust-Stand/

This post is a work in progress and will be developed in the future. I am working on converting a $15 cooling fan to a toroidal one and will share the results of this experiment here.

DIY Mini Metal Brake

Simple metal bending tool that you can build with a drill and an angle grinder, no welding required!

Mini Metal Brake V1

When building my bachelor thesis project – the StarTrckr I noticed limitations of 3D printed parts. I couldn’t design my project how I wanted it to and still make it stiff to handle a DSLR camera. Plastic parts were completely ok for most of the project but 3D-printed arms (similar assemblies are used in camera gimbals) were flexing too much. So I decided that at some point I would upgrade parts for this project with metal parts, preferably laser-cut steel bent to 90 degrees. But the first step is always to make a prototype. I still haven’t tried machining steel with IndyMill so obviously, the prototype shall be made with aluminum, but how to bend it? I tried bending aluminum some time ago just with vice and I know how hard this process is and the results are not satisfactory for me. For that reason, I knew that to create nice prototype parts I need a metal brake (metal bender, bending machine). Tool like this seems easy to build so that’s when I decided to design it, buy the parts and just try to make it as good as I can keeping the budget low and minimal tools required.

Parts

One of the challenges was not to use welding in this project and the second one was to use only the parts available at the popular local hardware store in Poland. If you are not familiar with polish hardware stores let me tell you there is not a lot that you can buy there. For that reason project is built with few basic and hopefully easy-to-buy worldwide steel elements. Of course, this instruction is only an example of how I built it and I advise you to use it only as a reference and adjust the project to your needs. If there are other similar components you already have or can buy cheaper, feel free to do that!

NameAmount
L-shaped steel profile 35x35mm 300mm long2
L-shaped steel profile 25x25mm 200mm long1
Steel profile 20x20mm 250mm long2
hinge 40x40mm2
M8x30 screw2
M8 washer2
M5x25 screw4
M5 nut4
M4x6 screw12
M4 nut (optional)12

All elements and the dimensions I have chosen are based on my needs, I know that I am not going to bend some long materials so I preferred to keep the dimensions compact. Here are drawings of the profiles with all the dimensions just to clarify everything:

The M4 nuts mentioned in the table are optional because I tapped the threads in the holes for M4 screws and that way the nuts are not required. Keep in mind that the material that we are using is rather thin (the profiles I have used are just 2mm thick) so the threads are not super strong but so far work great and if there are any problems I can always add nuts later.

It might be hard for you to buy the same hinges that I used in this project so the holes pattern might differ. Make sure to constantly check if everything fits together as you build it and drill the holes for the hinges after checking if they fit. Also, label the holes based on hinges placement and holes pattern. If you use different components do not follow the drawings below very strictly.

NameLink
Drillhttps://amzn.to/42WeWnA
Drill press (optional)https://amzn.to/3zpx5wp
Angle grinderhttps://amzn.to/3zr6mj8
Metric tap sethttps://amzn.to/40RhbH0

The tools mentioned above are required for the project, except the drill press it’s very helpful to drill some holes but you can also easily drill them with a cordless drill. As you will see later you can even drill the holes with an old grandpas hand powered drill 🙂

Cut & drill

The drawings presented below should clarify all the holes placement and lengths of the profiles. If the images are too small you can drag and drop them to a new tab and zoom in.

We will need M4 and M8 taps to tap the holes as presented in the diagram below. The rest of the holes are simply drilled.

3 holes on each end of the profile labeled M4 shall be tapped with an M4 tap, that’s where the hinges will attach.
This is the 25x25mm L profile, holes need to be drilled at the corner of the profile. That’s where two M8 screws will be attached to clamp down the material.
5mm holes were drilled in the handles to attach them to the profile.

Unlike most designs of metal brakes, my brake attaches to the vice as it is easier and quicker to set up. For that reason, one of the 35×35 profiles (the one with holes for the handles) needs a cutout. I am using 150mm vice so that’s why my cutout is slightly bigger. Adjust this dimension to your own vice.

Additionally having the brake attached to a vice solves one additional problem and that is all the screws that stick out from the bottom of the other profile that make it impossible to attach to a flat surface. This problem can be solved by adding a piece of wood to the bottom but I am not a fan of this option.

Vice cutout.

After cutting & drilling you might want to check if everything fits together nicely. Before final assembly it’s a good idea to paint your project to give it a professional look 🙂

Painting – powder coating

I like adding a professional touch to my projects and making them as cool as I can. Also, additional protection from corrosion is helpful so that it lasts longer. For that reason, after a test fit I disassembled the whole project including the hinges and powder-coated everything blue and black.

But how did I do that? I have my own cheap and simple powder coating setup. But wait, there is more! You can buy the same powder coating gun that I am using from my store:

This is a very simple-to-use gun perfect for a small project like this one or even small-scale manufacturing because I am also using it to paint parts that I sell for my IndyMill CNC machine. All you need in addition to the powder coating gun is an air compressor and an oven, that’s it. Powder coating is not only simple but also efficient, inexpensive and fast as you don’t have to wait for the paint to dry, it just has to cool down.

That’s me powder coating the parts, the booth is something I have to work on and improve as well as creating a better filtration system.

Your safety is very important when powder coating so you need a filtration system (don’t look at mine, it’s not good enough), a very good mask (I am using a 3M mask and it’s perfect), goggles, and gloves.
Parts drying after powder coating. The whole process takes about 30 minutes. 5 minutes painting, 15 minutes in the oven, and 10 minutes cooling down.
Parts after homemade powder coating.

There is one thing I should mention, tapping the holes and then painting is not the best idea because the paint will get inside the threads and you will need to retap them, otherwise driving screws will be hard. I tapped the holes before painting for a reason – I wanted to assemble everything before painting to test if it works ok or still require some refinement.

Assembly

Once the MiniMetalBrake was painted to your favorite colors it’s time to assemble it according to the drawings presented below. Those are pretty self-explanatory so I will only point out the most important steps there.

When joining together two L profiles make sure that the top surfaces are perfectly parallel and flat. It’s a good idea to clamp them in a vice together and then join with hinges (actually I used the same technique when drilling holes for the hinges).

Two 35x35mm L profiles.
Hinges attached to the profiles with M4 nuts.

The following step is optional. I tapped the holes with M4 tap and it works ok so I didn’t use nuts but I added it there just to show you that it’s a possibility.

Optional M4 nuts.

Here I want to mention one possible improvement that is super easy to implement. Springs. Adding springs on the screws is a great improvement in user experience as the profile that clamps down the material will rise on its own. I had no such springs around so that’s something I will add in the future.

M8x30 screws are attached with washers through a 25x25mm profile that clamps down the material.
Handles are attached with M5 screws and nuts.
Wireframe view of the completed MiniMetalBrake.
Render view of the MiniMetalBrake.

What can you bend?

There was one goal as I mentioned in the beginning and that was to create metal arms for the star tracker so the first thing I made was exactly that. I designed an arm with sheet metal tools in Fusion360, machined the aluminum piece with IndyMill, and bent it with a MiniMetalBrake. Later the piece was powder-coated black to make it look professional and match with other parts in the StarTrckr.

Unfortunately, I had to cheat a bit when bending this piece and add additional support. The steel profile was bending a lot when I tried to bend this 3mm thick aluminum. So one future upgrade would be to add some flat pieces of steel attached to the handles to support the part more and reduce the flexing in the steel profile.

3mm thick aluminum machine on IndyMill, bent with MiniMetalBrake and powder-coated black. Amazing result and improved stiffness. There are 2 more arms to be replaced in the StarTrckr.

And then I wanted to try something more complicated so I designed a one pice phone holder. It is also made out of aluminum with IndyMill, and the material thickness is 1.5mm.
This time machining was hard, I have no idea what kind of aluminum was that but milling it was almost impossible. At the end after a lof of sanding, I got it to look somehow decent and after powder coating, most imperfections are not visible anymore.

Simple one-piece phone holder.

The small size makes it easy to store for example on your tool wall. Attaches quickly to the vice and hopefully will be often used in future projects. Machining aluminum with DIY CNC is cool but combined with a metal brake it literally adds another dimension to your parts.

MiniMetalBrake is easy to store, for example on your tool wall.

Thanks for reading through the whole project! I hope you liked it and that maybe one-day MiniMetalBrake will show up in your workshop too! I am thinking about redesigning the machine to laser cut the parts out of thicker steel and improve some of its weak points and offer a kit for it in my store. Are you interested? Send me an email: nikodem@indystry.cc

Screw Counting Machine

Since I started offering the parts to build an IndyMill I have been looking at various ways to optimize the process of preparing, packing, and branding. I think some of the things I am doing might be interesting for some of you as I am always trying to find the most DIY, easy and eco-friendly solutions. I will share more details about different methods and projects I created at Indystry.cc but in this project, I would like to focus on the most time-consuming problem – counting the screws.

To illustrate how big of a problem that was let me tell you more about the set of screws for IndyMill. There are 13 different types of screws and nuts, in total 255 screws. So far every single screw had to be manually counted. I took great care when packing the screws and usually double-counted everything to make sure that each set was perfect.

There are also bearings in the kit, only 10 of them so that’s easy to count. It takes about 8 hours to create 20 sets with all the components, considering I am not selling the parts at a huge volume it wasn’t a big problem but still there is plenty of room for improvement. The goal for this project was easy – building a machine that is able to easily, quickly, and accurately count screws.

While the goal was pretty well defined getting all 3 subgoals at once is not easy at all and most likely will take at least a few iterations. For that reason from the beginning, I decided to treat this project as a prototype that lets me verify the idea and its feasibility. To test the idea and build a prototype we usually don’t need a lot and for that reason, I used cheap components, 3D printed parts, and thin plywood.

Design

Design

Parts and files

You can find all the files required to build this project on my GitHub:

OpenScrewCounter
GitHub repository for open-source machine for precise and reliable screw counting. Designed with 3D printed and laser cut parts as well as Pi Pico based electronics.

And here is a list of parts I used for this project with links to some of them. Keep in mind that as I mentioned this is a prototype of a new machine I would like to build in the future. There are a lot of things that could be upgraded to make the machine more reliable and in general better.

NameAmountLink
Raspberry Pi Pico1https://amzn.to/3FnSxVT
DC motor1https://amzn.to/405kJVr
7 segment display1https://bit.ly/40bwYQB
Buttons3https://amzn.to/3yK9nul
6804 Bearing1https://amzn.to/40ppZDR
Some screwsa lothttps://amzn.to/3leCWBm

This is not a complete list of parts as there are a lot of small electronic components and also most likely you will have to adapt the project to your needs.

Manufacturing

There are some 3D-printed parts you have to print on your own. It really doesn’t matter that much whether you use PLA or PETG, any material will do. Personally, I used PLA for this project. There are also plywood parts that I cut with a CO2 laser. Those parts can be easily replaced with 3D printed parts in case you don’t have an access to a laser cutter. Another alternative is to machine them with a CNC machine.

For printing, I used my slightly modified Ender3 printer. When I think about it now, this printer is already 4 years old and the only thing I replaced is the motherboard (I wanted to have silent TMC drivers, the original was perfectly fine and there was no reason to replace it), build plate (I broke the original one and adhesion on this golden powder plate is better) and plenty of nozzles. Everything else is as it originally was on the ender.

As a laser, I used my Epilog Zing 16. It is a really cool, professional and unfortunately pricey laser cutter. This cutter is a prize I won during one of the contests organized by Instructables, you should check them out! A cheaper alternative that require some upgrades out of the box to turn it into a usable and capable laser is a K40 laser like this one.

All the files are in the GitHub repository linked above.

Assembly

Assembly is so straightforward that I am not going to explain it in detail there. You need some M3 and M5 screws, wood glue might be useful to join plywood parts. In my video you can see some clips from the assembly but keep in mind I assembled the machine at 5 different stages of the design there and the final one differs a bit.

Problems

Instead of listing the problems let’s focus on the solutions:

  • Bigger drum – this is the element that holds the screws. It’s not big enough to hold a lot of screws. For my use case, it’s just a bit slow but I could easily use it as it is. But because I always want my projects to be appealing to a large audience I know a bigger drum may be beneficial.
  • Better motor with an encoder – I used a very cheap motor, like a very very cheap motor, you can buy it for about a dollar. The next version should incorporate a more powerful motor capable of turning at slower and higher speeds depending on the need. Additionally, an encoder shall be used to allow for stall detection.
  • More accurate laser sensor – using an LED and a photoresist is a decent solution but not accurate enough. Implementing two of these sensors to really make sure that the screws are properly counted is also to be considered.
  • Bigger display with button/encoder – to control all the settings
  • External communication interface – SPI, I2C or CAN to integrate the machine with other machines. For example a rotary table with containers of screws to allow for continuous counting.

I am pretty sure there is a lot more to upgrade, if you have any ideas and want to share them, feel free to send me an email.

Electronics, breadboard, CNC machining a PCB

Starting with a breadboard prototype where modifying anything is really easy is always a good idea. So I started by connecting Pi Pico with 7 segment display to check if everything work as intended. The simple circuit assembled on the breadboard is presented in the image below.

And after that, I moved to KiCAD to design the schematic and PCB layout. My plan was to make the PCB on my own with a modified CNC machine that I made just for PCB machining. And the result of that process you can see on the image above as well as in the video. PCB files are available in the GitHub repository as well.

Programming

Pi Pico or RP2040 can be programmed in Python and since I tried using this microcontroller I completely fell in love with it. Python is definitely my favorite programming language and as I am studying data science now for my master’s degree I am using it quite often for university projects.

The fun part while programming was using ChatGPT to write a function for controlling the 7-segment display. It wasn’t perfect it wasn’t working straight from the chat but the errors were easy to spot and fix. So definitely using this cool AI technology saved me some time for this project.

Other than that firmware for the project is rather simple. You can upload it to the pico with Thonny a simple IDE.

Final thoughts

Honestly, unfortunately, it’s not yet “production ready” I am not going to use it to pack the screws as I can’t trust it. The counting process is not reliable enough. I can use it as a machine that assists me during counting but to be 100% sure I have to count it manually too. So what’s next? Second better, bigger and more expensive version. Not a prototype but a production-ready unit. Follow my YouTube channel and Instagram to be notified when the project is ready, you can also support my work on Patreon:

DIY Solar Powered Garden Watering System

Automating every day tasks are the best projects for so many reasons. You can find a real problem and take it as a challenge to automate it. In the end you will end up with plenty of new knowledge, practical experience with problem solving and more time for new projects because a new project will take care of the every day task. Simple and really rewarding project of this kind is an automated watering system add to that solar power and you have a perfect solution!

To learn more about the project, how I built it, problems I faced and how it works take a look at this video:

Parts

Here is a list of parts you will need to build a Pico watering system. You cna find all the files for both systems on my GitHub, links at the end of this page.

NameAmazonAliexpress
Raspberry Pi Picohttps://amzn.to/3O2GBdGhttps://bit.ly/3c9K7FP
Solar panel and chargerhttps://amzn.to/3PqgpLphttps://bit.ly/3yDzbIe
Garden irrigation systemhttps://amzn.to/3uLS3DLhttps://bit.ly/3c9sE0m
Pumphttps://amzn.to/3O74vF0https://bit.ly/3z0th5v
Water level sensorhttps://amzn.to/3z16nL9https://bit.ly/3nVWZSD
IRFZ44Nhttps://amzn.to/3O1NyvJhttps://bit.ly/3aG8udU
LEDshttps://amzn.to/3yxl1Zjhttps://bit.ly/3NZ0nXz
Buttonshttps://amzn.to/3z0r75Thttps://bit.ly/3yD8UtK
Batteryhttps://amzn.to/3ceAIx6

Links above are affiliate so by using them you support my work at no extra cost. If you would like to support me in a different way you can check out my store or my Patreon:

Become a Patron!

Two systems

My plan was to build a watering system with a few sensors just for fun. While building it I started adding more and more sensors and ended up with a pretty sophisticated system. Also I wanted to make this project in a good old DIY fashion to make it easy for everyone to replicate. In the end I wasn’t quite happy with the system as it was too complicated, there was too many cables everywhere and it wasn’t simple enough to be elegant.

Ad

It’s important to mention that this first system was working great for 11 days and was perfectly watering my garden. Unfortunately the power consumption was pretty high because of many LEDs I had there so it would only work for a few more cloudy days before running out of battery. My DIY soil moisture sensors weren’t working reliably and after creating the plots all the sensors weren’t really needed anymore. All I needed was a simple watering system.

My DIY soil moisture sensor

It obviously wasn’t a waste of time because I learned a lot while making this first version of the system and I used that experience while making the second one. Also with the data collected over 11 days I made some cool looking plots. There is a vertical line every 86 milion milliseconds (that’s 24 hours) so we can see that we have data from almost full 11 days. It was collected during a heatwave in Poland (that was quite fortunate because the system was able to charge fully during the day to survive the night).

Ground and air temperature plots over 11 days of the test

Here we can see sudden drops in the data from ground moisture sensors, unfortunately it is caused by a voltage drop on the battery when turning on the pump. Based on these plots we can conclude that these sensors weren’t working properly. I hope to try to build my own capacitive moisture sensor soon.

Ground moisture data from DIY resistive sensors that unfortunately weren’t working properly
Sunlight data

Here we can see nice correlation between the plots above and below. It’s also visible that the solar charging system wasn’t big enough and wasn’t able to charge the battery on a cloudy day and it got discharged significantly. That’s why reducing power consumption in such systems is really important.

Voltage on a battery

For that reason I decided to start all over again and design a new simple system with only necessary components that consumes less current, is easier to build and more elegant. This time instead of using Arduino (Arduino is great and I still love it but sometimes it’s nice to experiment and try something new) I used Raspberry Pi Pico a microcontroller based board from Raspberry Pi based on RP2040 chip. It’s incredibly chip for what it can offer and is programmed in Python. It’s not the best choice for extreme low power solutions but I am using here a 12V 4Ah battery with a 10W solar panel so that’s not the most important factor for me. RP2040 chip itself is low cost compared to other solutions and what’s really important these days (July 2022) is available. Adding to that a 7805 voltage regulator, IRFZ44N MOSFETs, buttons and a few LEDs I designed a simple single sided PCB – single sided means easy to make at home. To make it I used a $200 CNC machine.

Machining a PCB on a $200 CNC machine with a really nice result
Ad
Final PCB for Pico watering system

There is two of everything on the PCB so you can run two separate systems for different parts of the garden (it’s not yet implemented in the program). With two buttons and 8 LEDs you can easily set number of watering cycles per day (between 1 and 4) and watering cycle time (you can choose from 2, 4, 6 and 8 minutes per cycle) of course that can be also adjusted in the program depending on what you need in your garden. Settign are stored in the flash memory of the Pico, it’s amazing that you can simply safe a file there as you would in a normal Python running on your computer!

Simple LED and buttons make can make a great user interface

Case was 3D printed with PETG on Ender3 and additionally closed in a 2l food container together with the battery to protect it. I also used cable gland to go with the cables through the container. In the end everything was attached to a a wooden pole and solar panel got pointed south for maximum efficiency. I used a 150l water reservoir that honestly after testing it for two weeks is a bit small and something closer to 300l would be great. Also a rain water collection system could help here significantly.

Files

You can find all the files for this project on my GitHub:

Here is a link to the Pico watering system:
https://github.com/NikodemBartnik/Pico-Watering-System

And here is a link to the WDCS (Watering and Data Collection System):
https://github.com/NikodemBartnik/WDCS

Feel free to ask any questions, share the video and contribute to the open source project!

Happy making and have a nice day!

3D Printed duct fan

This is a 3D printed duct fan that can be used with a 775 motor or a popular BLDC (for example 2212). It can obviously also be adapted to any other motor. It’s an open-source project so below you can find STL files and .F3D files of a project so that you can easily modify and adapt it to your needs.

Consider supporting my work:

Become a Patron!

Files

Below you can download ZIP with all the STL and F3D files of the duct fan, fans, and air filter attachments that I designed. You can also find here the PDF with all of my measurements and plots. Feel free to print, modify and share with others.

Tests and measurments

In the beginning, there was just an idea for a simple duct fan but later I thought that I can optimize it and design a better fan. In order to do that I experimented a lot and measure the performance of each fan while noting everything in a spreadsheet. Later I made a lot of plots to show how each fun perform and you can see all of that here:

https://docs.google.com/spreadsheets/d/1bWz74lslCTUJS_hIYJnpoS_NEaYTMo8m/edit?usp=sharing&ouid=113317919185968062988&rtpof=true&sd=true

You can also find a PDF version of that in the ZIP above.

Here you have 6 most interesting plots where you can observe the difference between performance of each fan and how the measuring method influences the end result.

How to build a robot?

Robots are cool, I think we all agree on that. Right here I would like to give you a short introduction to all the topics that you will most likely face while building your first robot. In the beginning, I just wanted to say no worries, building simple robots is not hard at all, most of it doesn’t even require any soldering (sometimes you may need to solder cables to motors, but for simple robots that’s the only soldering required).

I also wanted to point out the difference between a robot and not a robot. Some tutorials refer to an RC car as a robot but in reality robot is a device that can work on it’s own. At the same time it’s not about fancy futuristic artificial intelligence or humanoid robots, it’s about simple tasks that are solved by the robot completely without human interaction. So a line follower or an obstacle avoiding robot are great examples of ROBOTS while a “robot” and a human with a remote next to it is not a robot.

Keep in mind that this is not a complete tutorial with code, schematic and DIY instruction. It’s meant as introduction to all the topics you should know about in order to even start and understand some of the robotics tutorials so that instead of mindlessly following those you understand what’s going on.

If you want to start easily with a kit, you can check out something like this with all the parts, chassis, motors, sensors, and Arduino. If you prefer to buy components individually check out the list below.

Here you can see a short one minute introduction video, and to learn more about all the topics continue reading:

Microcontroller

Microcontroller is a brain of the robot, all the logic, conditions and calculations are performed in here. To simplify it we can say that microcontroller is just a very very simplified computer, the internal structure is more or less similar. There is no screen or keyboard, just a chip with pins. By writing the program you can read pin states set conditions (if statements for example) do some math and set output pins conditions or communicate with other modules, sensors etc.

There are a lot of different types of microcontrollers but if you are just starting you should take a look at Arduino UNO (which is actually more than just a microcontroller, it uses Atmega328 as a microcontroller but Arduino is rather an ecosystem and collection of development boards). Any Arduino board is very easy to start with and Arduino UNO is additionally quite affordable (Original boards start at 23 USD or you can buy a Chinese Arduino clone for 5 USD). With UNO you can build blinking LEDs, learn electronics and programming, simple robots, home automation, measuring devices and even CNC machines! If you need more pins (trust me if you are just starting you don’t need more pins) you can buy Arduino Mega.

NameStore 1Store 2
Original Arduino UNOhttps://bit.ly/2MuCKMwhttps://bit.ly/3ormF7N
Clone Arduino UNOhttps://bit.ly/3t5gk59https://bit.ly/3osuWIi
Original Arduino Megahttps://bit.ly/2YnfYsQhttps://bit.ly/3pt5vro
Clone Arduino Megahttps://bit.ly/3aqqXHBhttps://bit.ly/2M3BsZf

Of course Arduino is not the only way to go. You can read about programming STM microcontrollers, AVR, or lately released Raspberry Pi Pico (programmed with C++ or Python). There are some more advanced boards like Maix Sipeed with an integrated screen and camera programmed with Python. You can also take a look at single-board computers like Raspberry Pi 4B or BeagleBone Black. But all of those examples are probably not the best for beginners.

Sensors

In order to build a robot (not an RC car) we need sensors. Sensors are devices that measure physical things and transform those readings into electrical signals so that we can read those with microcontroller. For example, to build object avoiding robot we need an ultrasonic sensor that will measure the distance between a robot and an obstacle. This distance or actually two-way time of travel of sound that is processed into the distance can further be processed to decide if the obstacle is close enough to stop the robot or turn. With 2 conditional statements (if(…){}) you can write a simple program for such a robot.

Another popular sensor for simple robots is a line sensor that can be used to build a line follower, that is a robot that follows the black line. By using three of those sensors at the front of the robot you can write a simple program that will drive forward when the line is detected by the sensor in the middle, if the line is detected by the right sensor it should turn right, and if the left sensor detects line you need to turn left. This is a simple example of a not really efficient program for a line follower but it works really well 🙂

There are other types of sensors, there is a sensor to measure everything you can think of air quality, pressure, soil pH sensor, LIDARs, movements sensors etc. Once you get more familiar with basic sensors you can start playing with those a bit more advanced. Ultrasonic sensor and line sensor are probably the easiest to start with and pretty straight forward to use.

NameStore 1Store 2
Line Sensorhttps://bit.ly/39q4qLxhttps://bit.ly/2MxQTbW
Ultrasonic Sensorhttps://bit.ly/3t1Quz7https://bit.ly/2YjCqTD
Sensor Kithttps://bit.ly/3aqzXfRhttps://bit.ly/39rnmJT

Motors

There is many options when it comes to motors for robotics but because this is an introduction I will focus only on simple and cheap motors. You should pay attention to the rated voltage and current of the motors. Usually, you should look for motors with voltage of about 5 to 12V. There should be a way to mount wheels or you will have to look for a DIY solution. In order to increase the torque and lower the RPM motor should have a built-in gearbox. To start I recommend those plastic yellow motors, those are not great and you wouldn’t build the most amazing robot ever with those but to start those are great!

NameStore 1Store 2
Yellow Motorshttps://bit.ly/3orwWknhttps://bit.ly/3pseObk
Small Motorshttps://bit.ly/3oqqgTmhttps://bit.ly/3adWmMX
Bigger Motorshttps://bit.ly/3qZZVxbhttps://bit.ly/3pthhSC

Motor driver (H Bridge)

There is no way to drive a motor directly with an Arduino, don’t even try because you will break it. In order to control the motors we need a motor driver also called H bridge. Again there is a lot of options and most of them are very similar. Main differences are max voltage and current that can be handled by a driver or some additional features. Some simple and popular drivers are listed below.

NameStore 1Store 2
L298https://bit.ly/36h9IH5https://bit.ly/3cgeLvq
L9110Shttps://bit.ly/3acjcVlhttps://bit.ly/3qYZyTI

Cables, Breadboards

Obviously, you will need some cables and a breadboard to connect everything together. They’re nothing complicated, buy some female-female, female-male, male-male cables. When it comes to breadboard use a bigger one for bigger projects and a smaller one for smaller projects, usually power rails on the sides are very useful.

NameStore 1Store 2
Cableshttps://bit.ly/2L20vLGhttps://bit.ly/2M2yGDx
Breadboardhttps://bit.ly/3cj6t67https://bit.ly/3t3MGgP

Chassis

In order to attach everything together, you will need a chassis. You can buy a set with chassis, motors and wheels or you can try to find your own DIY solution and make a chassis out of plastic or even cardboard (that’s how I built my first robot).

NameStore 1Store 2
Chassis 1https://bit.ly/3t3LJF7https://bit.ly/3cfuaw1
Chassis 2https://bit.ly/3a9Ebbmhttps://bit.ly/3cnsX5N

Batteries

The battery is always a really problematic part of building robots. The most common choice is a LiPo battery but it’s a little bit dangerous, you have to take care of it and be careful because discharging the cells under 3.2V may damage the battery. Those batteries are sold as 1S, 2S, 3S and so on which means one, two or three cells because each cell has a nominal voltage of 3.7V a two-cell battery has a nominal voltage of 7.4V (and a max voltage of 8.4V). Batteries vary with capacity, the bigger the capacity the longer you can power the robot. There is also max current that can be drawn from a battery this is labeled as for example 10C and it means that capacity multiplied by 10 will give the max amperage that you can draw from a battery.

Another (probably safer) way to go is to use protected 18650 batteries. It’s also more complicated because you need to create a battery pack on your own and combine a few of those batteries in parallel or in series. Professionally those batteries are spot welded together but you can just easily use a battery box to keep them together.

I don’t recommend going with AA or AAA batteries as you will need to recharge or replace those very often (it’s not good for the climate and your wallet) and the max current of those isn’t enough for some motors.

NameStore 1Store 2
2S LiPohttps://bit.ly/3iUpE7qhttps://bit.ly/2M2ILAn
3S LiPohttps://bit.ly/3qX8sRwhttps://bit.ly/2M2ILAn
4S LiPohttps://bit.ly/3iWMQSkhttps://bit.ly/2M2ILAn
18650 Batteryhttps://bit.ly/3a4ys6whttps://bit.ly/3orRskO
18650 Boxhttps://bit.ly/3a9hIv7https://bit.ly/36jr8Dh

Programming

A lot of people are scarred by programming, I am not really sure why. Programming is easy, you don’t need math to create simple robots! If you have any experience with C++ or similar programming languages you can start programming Arduino right now. If you don’t no worries, there is a lot of great tutorials and examples online. Once you start and try to write your own programs you will realize that it’s not that hard.

You can find some cool tutorials on official arduino website:

https://www.arduino.cc/en/Tutorial/HomePage

Or just type “Arduino tutorial” into YouTube and you will find thousands if videos on this topic!

I hope this article helped you a bit with your robotics journey! If so don’t forget to share with friends and share you progress on Instagram by tagging me: @nikodembartnik and @indystry

Have a nice day!

Arduino Based Air Quality Monitor

The air quality is a pretty big problem in my city. We have a monitoring station but it’s quite far from where I live so I decided to build myself a local, simple and nice-looking air quality monitor. You can learn more about the whole project and how I made it in this video:

Below you can find all the files and code for the project. And here are the parts that I used:

PartLink
Arduino Nanohttps://bit.ly/32xGF06
Air Quality Sensorhttps://bit.ly/36jWXLj
NeoPixel Ringhttps://bit.ly/3lhRM4O

Code

#include <Adafruit_NeoPixel.h>
#include <SoftwareSerial.h>

#define LED_PIN 6 
#define SLEEP_PIN 5
#define MAX_PM1_LEVEL 50
#define MAX_PM25_LEVEL 30
#define MAX_PM10_LEVEL 40
#define NUMPIXELS 24 
Adafruit_NeoPixel pixels(NUMPIXELS, LED_PIN, NEO_GRB + NEO_KHZ800);

// 0 - green, 1 - blue, 2- orange, 3 - red
int last_color = 5;

#define LENG 31   //0x42 + 31 bytes equal to 32 bytes
unsigned char buf[LENG];

SoftwareSerial SoftSerial(10, 11); // RX, TX


void setup() {
  SoftSerial.begin(9600);
  Serial.begin(9600);
  pixels.begin(); 
  pinMode(5, OUTPUT);
}

void loop() {

digitalWrite(SLEEP_PIN, HIGH);
delay(1000L * 60L);
int pm01_level = 0;
int pm25_level = 0;
int pm10_level = 0;

int air_quality[3];

CheckAirQuality(air_quality);

pm01_level = air_quality[0];
pm25_level = air_quality[1];
pm10_level = air_quality[2];


if(pm01_level < MAX_PM1_LEVEL && pm25_level < MAX_PM25_LEVEL && pm10_level < MAX_PM10_LEVEL){
  if(last_color != 0){
  SetColor(0,30,0);
  }
  last_color = 0;
}else if((pm01_level > MAX_PM1_LEVEL && pm25_level < MAX_PM25_LEVEL && pm10_level < MAX_PM10_LEVEL) || (pm01_level < MAX_PM1_LEVEL && pm25_level > MAX_PM25_LEVEL && pm10_level < MAX_PM10_LEVEL) || (pm01_level < MAX_PM1_LEVEL && pm25_level < MAX_PM25_LEVEL && pm10_level > MAX_PM10_LEVEL)){
  if(last_color != 1){
  SetColor(0,0,30);
  }
  last_color = 1;
}else if((pm01_level > MAX_PM1_LEVEL && pm25_level > MAX_PM25_LEVEL && pm10_level < MAX_PM10_LEVEL) || (pm01_level > MAX_PM1_LEVEL && pm25_level < MAX_PM25_LEVEL && pm10_level > MAX_PM10_LEVEL) || (pm01_level < MAX_PM1_LEVEL && pm25_level > MAX_PM25_LEVEL && pm10_level > MAX_PM10_LEVEL)){
  if(last_color != 2){
  SetColor(30,10,0);
  }
  last_color = 2;
}else if(pm01_level > MAX_PM1_LEVEL && pm25_level > MAX_PM25_LEVEL && pm10_level > MAX_PM10_LEVEL){
  if(last_color != 3){
  SetColor(30,0,0);
  }
  last_color = 3;
}
Serial.print("PM01: ");
Serial.println(pm01_level);
Serial.print("PM2.5: ");
Serial.println(pm25_level);
Serial.print("PM10: ");
Serial.println(pm10_level);

digitalWrite(SLEEP_PIN, LOW);
delay(1000L * 60L * 3L);

}


void SetColor(int r, int g, int b){
  
  for(int a = 255; a > 0; a--){
    pixels.setBrightness(a);
    pixels.show();
    delay(20);
  }
pixels.clear();
pixels.setBrightness(255);
pixels.show();
  for(int i = 0; i < NUMPIXELS; i++) { 
    pixels.setPixelColor(i, pixels.Color(r, g, b)); 
    pixels.show();   
    delay(50); 
  }
  
  

}

void CheckAirQuality(int* air_quality){
  if(SoftSerial.find(0x42)){    //start to read when detect 0x42
    SoftSerial.readBytes(buf,LENG);

    if(buf[0] == 0x4d){
      if(checkValue(buf,LENG)){
        air_quality[0] = transmitPM01(buf); //count PM1.0 value of the air detector module
        air_quality[1] = transmitPM2_5(buf);//count PM2.5 value of the air detector module
        air_quality[2] = transmitPM10(buf); //count PM10 value of the air detector module
      }
    }
  }
}


char checkValue(unsigned char *thebuf, char leng)
{
  char receiveflag=0;
  int receiveSum=0;

  for(int i=0; i<(leng-2); i++){
  receiveSum=receiveSum+thebuf[i];
  }
  receiveSum=receiveSum + 0x42;

  if(receiveSum == ((thebuf[leng-2]<<8)+thebuf[leng-1]))  //check the serial data
  {
    receiveSum = 0;
    receiveflag = 1;
  }
  return receiveflag;
}

int transmitPM01(unsigned char *thebuf)
{
  int PM01Val;
  PM01Val=((thebuf[3]<<8) + thebuf[4]); //count PM1.0 value of the air detector module
  return PM01Val;
}

//transmit PM Value to PC
int transmitPM2_5(unsigned char *thebuf)
{
  int PM2_5Val;
  PM2_5Val=((thebuf[5]<<8) + thebuf[6]);//count PM2.5 value of the air detector module
  return PM2_5Val;
  }

//transmit PM Value to PC
int transmitPM10(unsigned char *thebuf)
{
  int PM10Val;
  PM10Val=((thebuf[7]<<8) + thebuf[8]); //count PM10 value of the air detector module
  return PM10Val;
}

It’s hard to create a nice schematic for this project as there is no Fritzing library for PM2.5 sensor, and I have no idea how to create one 🙂 That’s why below you can find a text only explanation on connection, definitely not a perfect option but at the same time better than nothing:

DevicesArduino
Air Sensor RXPIN 10
Air Sensor TXPIN 11
Air Sensor 5V5V
Air Sensor GNDGND
Air Sensor SLEEPPIN 5
LED Ring DIPIN 6
LED Ring 5V3.3V
LED Ring GNDGND

As you can see in the table above I connected LED ring 5V to the 3.3V on the Arduino, that’s because there is only one 5V pin on Arduino Nano and it has to be used for Air quality sensor because it doesn’t work with 3.3V.

Thanks a lot for reading and happy making! I hope my air quality sensor will serve you well! And don’t forget to check out my other projects:

Object Tracking Robot – FollowBot V2

This is a second version of original FollowBot made in 2015. This one uses Maix Sipeed board with a camera and LCD screen. With 2 micro servo motors I made a small pan-tilt mechanism. Here you can read some more about how I made this project.

I decided to use new Maix Sipeed board, it’s quite powerful, has build in camera and you can program that in python so I though it should be quite easy to make such project with this board. I was right. If you have at least a little bit of experience with Python and electronics you can do some really cool stuff.

Firstly I had to develop a simple program for tracking red objects. I started by using blob detection algorithm. Basically it searches for all red blobs on the image and store that in a table. Then I had to find the biggest blob as that’s most likely what I want to track (simple for loop with one if statement and one variable can do it). And that’s it, within 40 lines of code you can detect simple single color objects. You can read more about that and find some examples here:

https://maixpy.sipeed.com/en/libs/machine_vision/image.html

https://github.com/sipeed/MaixPy_scripts

Parts

PartLink
Maix Sipeedhttps://bit.ly/31BwNCA
Robot Chassishttps://bit.ly/31zBVXK
Motor Driverhttps://bit.ly/31yPs1V
Servohttps://bit.ly/2EqHQ96
Batteryhttps://bit.ly/3jrPVJr

There is no servo library for this board so that’s a downside because you need to figure out on your own how to control a servo (later I noticed that there is a servo example on github linked above). Servo is controlled with 50Hz PWM signal, high signal should be between 1 ms – 2 ms so that’s a duty of 5-10% (5% * 1/50s = 1 ms, 10%*1/50s = 2 ms). With a timer I was able to set up such PWM signal, a simple servo example can be found in all of the files (you can download them at the bottom of the page).

I also designed my own minimal pan and tilt mechanism in Fusion360. STL files are also at the bottom of this page.

I made my own functions to control DC motor driver but that was obviously very easy. Here is how I connected the motor driver and servos to the board.

Connection

Maix SipeedDC Motor Driver/Servo
PIN 0Pan Servo Signal
PIN 1Tilt Servo Signal
PIN 9Motor Driver ENA
PIN 10Motor Driver IN1
PIN 11Motor Driver IN2
PIN 12Motor Driver IN3
PIN 13Motor Driver IN4
PIN 14Motor Driver ENB
GNDMotor Driver and Servo GND
5VMotor Driver and Servo 5V

After that I simply connected all small programs that I wrote and put everything on my robot chassis. And it was time for the final test that you can see on the video below.

Here you can find a ZIP archive with all the files including my small subprograms, main followbot.py and all STL files that you can print. Feel free to edit those and customize this project to make it work for you. Don’t forget to share your work with others and link to my project 🙂

Thanks for reading this short project description, it’s definitely not a full tutorial but I hope it will be helpful for some of you!

How to build 3D printed Dremel CNC?

Try typing Dremel CNC to Google or Youtube, the internet is filled with my videos and tutorials about building 3D printed Dremel CNC. I kind of feel just like repeating over and over the same content and that is creatively hard for me because I like creating new stuff the most and not focusing on past projects.

At the same time, I understand that a lot of people want to build DIY Dremel CNC because it’s simple, cheap, and inexpensive, totally understandable! A CNC machine that can be easily 3D printed and assembled with easy to buy components, that was the goal of this project, and looking at reviews of hundreds of makers all around the world I think the project turned out perfectly! I am more than happy that such a simple idea of mine can help so many makers, businesses and people. As you may know, I am working on a new bigger CNC machine called IndyMill, that’s why I created this website to share all the info about this machine, release files, and maybe even create a small business out of that! But I don’t want to forget about Dremel CNC and I know there is still a lot of people that want to build it but don’t know where to start. That’s why I made this post, actually, the first one on indystry.cc, I hope to make some more in the near future 🙂 Let’s start!

Continue reading “How to build 3D printed Dremel CNC?”