Empowering Today’s Learners to Become Tomorrow’s Leaders
Before we start driving the car around, let’s start off with a very basic example, just to get familiar with the Mixly programming environment. The most simple Arduino program is probably the blinking LED. An Arduino typically has a built in LED which can be used for this purpose, so we do not have to add any parts to make this work. The left LED is connected to pin 13, the right LED to pin 12. In this example we will make the left LED blink with a delay time of one second.
From the In/Out section you can drag a digitalwrite command into the work area. Then indicate pin 13 should be High, which means the LED connected to pin 13 is turned ON. Next, drag a delay command from the Control section and set it to the desired value, in this case 1000 milliseconds. It is possible to copy and paste the commands with Ctrl+C and Ctrl+V. Attach them to the string of commands and change the second command for the LED to LOW. Now simply press Upload. The Mixly software will compile the program and send it over to the AI starter over the USB interface.
void setup()
{
pinMode(13, OUTPUT);
}
void loop()
{
digitalWrite(13,HIGH);
delay(1000);
digitalWrite(13,LOW);
delay(1000);
}
This is all that is needed to make this program run on the AI starter. It is possible to make much more sophisticated programs for the AI starter without ever seeing any line of code.
For a typical Arduino program to achieve this you would have to write the code as shown to left, which may be much more difficult to teach, especially in schools. With a graphical programming interface the user can just focus on the logic of the program and doesn’t have to worry about the correct syntax of a specific command.
The Mixly environment has an even simpler way of blinking the LEDs, with a dedicated command that you can use anywhere in your program. Just drag the LED command onto the working area and select blink.This is really as simple as it gets.
#include <AIStarter.h>
void setup()
{
AIStarter_SmartBotInit();
}
void loop()
{
AIStarter_SmartBotSetLED(LED1,BLINK);
AIStarter_SmartBotSetLED(LED2,BLINK);
}
In the code that this generates, we can see it just uses a function from a specific AI starter library, which is a nice solution, because you don’t have to set a delay yourself and also you do not even need to know the pin number the LED is connected to.
There is an array of infrared sensors mounted to the front of the AI starter, which are intended for line tracking. The Kit comes with a foldable track. On the left and right side there are markers added to the track. If the car drives over these markers, all sensors are triggered simultaneously. This can be used to stop the car and perform an action. One of the stop markers has a red field in front of it and the other a green field.
In order to try out the line tracking capabilities I used an included demo file, this time in the Arduino IDE. The program lets the AI starter follow a line and halts at every stop marker that it finds. At the red marker it beeps 3 times and at the green marker it beeps once. The line tracking works very well. The only issue I came across was that the unit sometimes skipped the green stop marker, while it always found the red one. The user manual states that the infrared line tracking sensors can be adjusted for detection distance, which might fix the issue. Or maybe the folds in the paper caused this behavior, I am not sure at this point. If there are any updates on this item I will update the article. The line tracking function gives you a nice possibility to play around with PID controller parameters. The AI starter uses only the Proportional and Integral action, making it a PI controller, which is a popular choice for speed controllers. The demo program shows some optimal settings for several speed settings. You can start with the suggested settings, but you can also play around with the kp and ki parameters and see how the car reacts to the changes parameters. With some settings there are large overshoots and with other settings it follows the line very tightly. You can adjust the settings to you personal preference or based on what is needed for your project.
Below is an example of the default kp and ki variables for a specific speed setting, in this case 70:
And finally an example with sensor readout and some driving action. Again, a very basic example just to show the concept. This uses an IF loop from the control section. The IF-statement needs a part to verify and if the statement is true it will execute whatever you put in the “do-section”. In this case we will place a statement verifying if the front ultrasonic sensors detected an obstacle. In the Do-section it is specified that the car has to move back, with a speed setting of 100, for a time period of 0.5 seconds.
#include <AIStarter.h>
void setup()
{
AIStarter_SmartBotInit();
}
void loop()
{
if (AIStarter_SmartBotGetBarrier(SONAR3)) {
AIStarter_SmartBotSetMovmentTime(BACK,100,0.5);
}
}
A benefit of this type of visual programming is that it is very easy to read back the program to see if it meets your needs. Just for good measure, the C++ code as generated by the Mixly software below:
There are many different commands included in the specific AI starter section, which I think address most, if not all of the functionality of the sensors and other hardware.
If the color sensor does not return 255 255 255 on white, white balance operation is required at this time.
There is no need to do white balance every time, only when the data is inaccurate.
The operation steps of AI-Starter white balance calibration are as follows:
Place the AI-Starter on white A4 paper
Compile the white balance program
Upload white balance program to AI-Starter
After the program runs normally, remove the AI-Starter
Since this platform lends itself perfectly for some experimentation, I thought it would be nice to expand the functionality of the AI starter by adding a tipping bucket. I believe Dobot actually uses a similar tipping bucket for school learning material and programming challenges, but instead of trying to get one from them I thought it would be more fun to design one myself and hopefully learn something new while doing so.
As I usually do when designing a part that has to fit some existing geometry, I imported a picture into Fusion 360. I found that, especially with larger parts tilt is very critical, so I made sure to take a picture from straight above.
The design is printable as a single part, including the hinge. To tilt the tipping bucket I used a small SG90 hobby servo, which has enough torque to lift the bucket including the items inside it as long as they are not too heavy. My first design was a bit rushed, which lead to a couple of issues. The first one was that the geometry of the hinge did not allow the bucket to fully open. Looking at the hinge in CAD it was actually quite obvious that this wouldn’t work, but sometimes I don’t take the time to check everything in detail, assuming that I will have to make another prototype anyway. So that is more of an iterative approach. In this case it might have been better to take more time on the first try since it is quite a long print. The second issue was that the hinge was moving with a lot of friction, which meant I did not use enough clearance. For the next iteration I increased the diameter gap between the pin and the hole from 0.15 to 0.25 mm. Also I removed some material where bridging was taking place, to allow for some sagging, since at these points the material is printed in mid-air.
This time I took a smarter approach and printed only a section of the print that contained the hinge, so I could quickly check if it was now okay, before committing to another 6 hours of print time for the entire part. In Prusa Slicer you can cut away unwanted sections of your part, which is very helpful, since you don’t have to cut up your native model in your CAD software. The printed section showed that the hinge now worked fine, so I started up another print. This time for the entire bucket.
I also found that printing such a part on the Prusa Mini without a brim does not work. The very first part I printed actually warped so much that it came loose and fell over. I am still in the process of figuring out what type of parts I can print without a brim on this printer, but for larger parts like these it is typically best to play it safe and use a brim.
The standard servo arm was a bit too short for this application, so I looked up a customizable model on thingiverse and found a model by “Oregondesign”. https://www.thingiverse.com/thing:2737914. I selected the servo type (Futaba 2F-21T) and entered an arm length of 25 mm. The print came out very nicely and even more important, the fit on the servo motor was spot on.
I used the built in function for a tipping bucket in the Mixly software. This basically drives a servo motor, which is in this case connected to pin 7. The Ai starter has a connector at the back called Servo1, which can be used for this purpose. If you look closely at the text on the print board, you can see the function of each pin. For the Servo we need Ground, 5Volts and a digital outputpin for setting the angle of the servo, which is in this case pin 7.
For the initial test I just pushed some dupont connectors onto the pins and this actually works fine. However to clean things up a bit I ended up using a JST connector, but especially for experiments this is not really necessary.
I made a test program that adds some basic autonomy to the AIstarter. It will keep driving around and avoid obstacles and walls until it finds a blue area. If it drives over a blue surface it will back up, turn by roughly 180 degrees and dump the parts on the blue location.
Click the picture below to open a PDF file in the browser or press te button to down load the file:
Creating the program in Mixly was easy and very intuitive. I did go through several iterations before I had something that worked as intended. Modifications to the program can be made and uploaded very quickly, which makes it suitable for doing multiple quick iterations to get to your end goal.