Elegoo, a manufacturer of Arduino-clone electronics and kits based in Shenzhen, China, approached me to do review their new Arduino-powered Smart Robot Car Kit. It’s a neat little kit–something fun to put together on a weekend and mess around with.
As for the meat-and-potatoes, it’s got a few bugs to work out. The car runs great with the included IR remote control, and can easily be programmed to use various sensors or just traverse pre-programmed missions (a la the classic Big Trak toy from Milton Bradley). The ultrasonic obstacle detection/avoidance mode also works like a champ. However, I couldn’t get the Bluetooth functionality working. It may be that the included Bluetooth module is not compatible with the latest versions of Android (as my cursory research and troubleshooting has led me to believe) due to updates in security protocols with Oreo and Pie. Your mileage may vary, though. Also of note was the line-tracking module which had a faulty LED and would only allow the car to spin in circles.
My contact at Elegoo was polite and provided me with some generic troubleshooting information, but they were unwilling to replace the faulty parts. If they’re not going to do it for the review, I would assume that they would be unwilling to do it for the consumer as well, so please take note. That being said, this is the first time that I have had as much trouble with an Elegoo-branded product, as I have used their Arduino clones and passive components in the past with no issue. I hope that this experience was a fluke, but only time will tell. I do want to emphasize that these sorts of problems can and do happen with any distributor, so it is not a mark against their quality per se.
At the end of the day, I’ll likely use these parts for some other projects (the geared motors and control boards may come in quite handy later), and have no real qualms about purchasing through Amazon as you’re protected by their returns policy (provided you purchase from the listing “fulfilled by Amazon”). So, give it a try. It’s a lot of fun to build, and makes a great transition from static Lego kits to full-fledged electronics hackery!
Building on our last project, we’re going to find a new way to control our piezo buzzer. Rather than using buttons, we’re going to use the variable resistance of a photoresistor to create different tones–a sort of light-activated Theremin. A photoresistor is an element that changes resistance based on the amount of light it detects. The more light, the less resistance. This device will convert those resistance values into various tones for our Theremin.
The Circuit:
Connect a jumper wire from +5V and GND to their respective busses on the breadboard. Connect a jumper from the +5V bus rail to one side of the photoresistor. This part is not polarized, so it doesn’t matter which side. Connect the opposite side of the photoresistor to GND via a 10K resistor and to A0 via another jumper.
Connect D8 to the positive leg of the piezo via a jumper and connect the ground leg of the piezo to GND.The Sketch:
int sensorValue;
// variable to calibrate low value
int sensorLow = 1023;
// variable to calibrate high value
int sensorHigh = 0;
// LED pin
const int ledPin = 13;
void setup() {
// Make the LED pin an output and turn it on
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, HIGH);
// calibrate for the first five seconds after program runs
while (millis() < 5000) { // save the maximum sensor value sensorValue = analogRead(A0); if (sensorValue > sensorHigh) {
sensorHigh = sensorValue;
}
// save the minimum sensor value
if (sensorValue < sensorLow) {
sensorLow = sensorValue;
}
}
//turn the LED off, signaling the end of the calibration
digitalWrite(ledPin, LOW);
}
void loop() {
//read the input from A0 and store it in a variable
sensorValue=analogRead(A0);
// map the sensor values to a wide range of pitches
int pitch=map(sensorValue, sensorLow, sensorHigh, 50, 4000);
// play the tone for 20 ms on pin 8
tone(8, pitch, 20);
// wait for 10ms
delay(10);
}
The Arduino, despite its simplicity, is a very powerful electronics platform and it can do so much more than blink LEDs or make noises with a buzzer. In this project, we’re going to connect a simple character LCD to the Arduino and use it to display some randomly selected custom text.
The Circuit:
Start by connecting +5V and GND to their respective busses on the breadboard. Use a jumpers to connect one side of a tactile switch to +5V and the other side to D8. Also connect a 10KR resistor to GND to act as a pull-down and prevent the pin from floating.
Connect a 10KR rotary potentiometer’s + and – pins to +5V and GND respectively while connecting the drain pin to pin 3 on the LCD. Finally, connect the LCD pins as shown in the schematic below:
The Sketch:
#include
LiquidCrystal lcd(12,11,5,4,3,2); // generates an instance in the lcd
const int switchPin = 6;
int switchState = 0;
int prevSwitchState = 0;
int reply;
void setup() {
lcd.begin(16,2);
pinMode(switchPin, INPUT);
lcd.print("I AM THE GREAT");
lcd.setCursor(0,1); // changes the Cursor to continue writing in the second row
lcd.print("ZOLDUINO");
}
void loop() {
switchState=digitalRead(switchPin);
if (switchState != prevSwitchState) {
if (switchState == LOW) {
reply = random(8);
lcd.clear(); // clears the screen
lcd.setCursor(0,1);
switch(reply){ // the program will enter the case
assigned to the switch
case 0:
lcd.print("Si");
break;
case 1:
lcd.print("It's probable");
break;
case 2:
lcd.print("It is certain");
break;
case 3:
lcd.print("Outlook good");
break;
case 4:
lcd.print("It is unclear");
break;
case 5:
lcd.print("Ask again");
break;
case 6:
lcd.print("I have no idea");
break;
case 7:
lcd.print("No");
break;
}
}
}
Now that we’ve learned the basics of digital and analog signalling on an Arduino, let’s start exploring with different kinds of sensors. The ultrasonic sensor module is a rudimentary SONAR device that emits and detects a particular high-frequency sound pulse. We can use this pulse to determine the location and relative position of objects.
The Circuit:
Using jumpers, connect +5V on the Arduino to VCC on the sensor and GND to GND. Connect the sensor’s Trigger and Echo pins to the Arduino at D2 and D4 respectively.
As we’ve learned throughout this series, a microcontroller like the one on the Arduino is basically a rudimentary computer that can execute instruction sets very quickly because it doesn’t have to load all those pesky applications and operating systems. What better capstone for this basic course than to combine everything that we’ve learned so far and build our own rudimentary mathematical computation device: a simple calculator!
For this calculator, we’re going to use a basic 4×4 matrix keypad and attach it to the Arduino in such a way that we only need to use 8 pins to cover the functions of 16 individual switches!
The Circuit:
Connect the character LCD and potentiometer as we learned in the Liquid Crystal Ball project, using the Arduino pins shown in the diagram. You can use a breadboard to create busses for +5V and GND.
Connect the pins of the keypad to pins D0-D8 on the Arduino as shown.
The Sketch:
#include //Header file for LCD from https://www.arduino.cc/en/Reference/LiquidCrystal
#include //Header file for Keypad from https://github.com/Chris--A/Keypad
const byte ROWS = 4; // Four rows
const byte COLS = 4; // Three columns
// Define the Keymap
char keys[ROWS][COLS] = {
{'7','8','9','D'},
{'4','5','6','C'},
{'1','2','3','B'},
{'','0','#','A'}
};
byte rowPins[ROWS] = { 0, 1, 2, 3 };// Connect keypad ROW0, ROW1, ROW2 and ROW3 to these Arduino pins.
byte colPins[COLS] = { 4, 5, 6, 7 }; // Connect keypad COL0, COL1 and COL2 to these Arduino pins.
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); // Create the Keypad
const int rs = 8, en = 9, d4 = 10, d5 = 11, d6 = 12, d7 = 13; //Pins to which LCD is connected
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
long Num1,Num2,Number;
char key,action;
boolean result = false;
void setup() {
lcd.begin(16, 2); //We are using a 162 LCD display
lcd.print("DIY Calculator"); //Display a intro message
lcd.setCursor(0, 1); // set the cursor to column 0, line 1
lcd.print("-CircuitDigest"); //Display a intro message
delay(2000); //Wait for display to show info
lcd.clear(); //Then clean it
}
void loop() {
key = kpd.getKey(); //storing pressed key value in a char
if (key!=NO_KEY)
DetectButtons();
if (result==true)
CalculateResult();
DisplayResult();
}
void DetectButtons()
{
lcd.clear(); //Then clean it
if (key=='') //If cancel Button is pressed
{Serial.println ("Button Cancel"); Number=Num1=Num2=0; result=false;}
if (key == '1') //If Button 1 is pressed
{Serial.println ("Button 1");
if (Number==0)
Number=1;
else
Number = (Number10) + 1; //Pressed twice
}
if (key == '4') //If Button 4 is pressed
{Serial.println ("Button 4");
if (Number==0)
Number=4;
else
Number = (Number10) + 4; //Pressed twice
}
if (key == '7') //If Button 7 is pressed
{Serial.println ("Button 7");
if (Number==0)
Number=7;
else
Number = (Number10) + 7; //Pressed twice
}
if (key == '0')
{Serial.println ("Button 0"); //Button 0 is Pressed
if (Number==0)
Number=0;
else
Number = (Number10) + 0; //Pressed twice
}
if (key == '2') //Button 2 is Pressed
{Serial.println ("Button 2");
if (Number==0)
Number=2;
else
Number = (Number10) + 2; //Pressed twice
}
if (key == '5')
{Serial.println ("Button 5");
if (Number==0)
Number=5;
else
Number = (Number10) + 5; //Pressed twice
}
if (key == '8')
{Serial.println ("Button 8");
if (Number==0)
Number=8;
else
Number = (Number10) + 8; //Pressed twice
}
if (key == '#')
{Serial.println ("Button Equal");
Num2=Number;
result = true;
}
if (key == '3')
{Serial.println ("Button 3");
if (Number==0)
Number=3;
else
Number = (Number10) + 3; //Pressed twice
}
if (key == '6')
{Serial.println ("Button 6");
if (Number==0)
Number=6;
else
Number = (Number10) + 6; //Pressed twice
}
if (key == '9')
{Serial.println ("Button 9");
if (Number==0)
Number=9;
else
Number = (Number10) + 9; //Pressed twice
}
if (key == 'A' || key == 'B' || key == 'C' || key == 'D') //Detecting Buttons on Column 4
{
Num1 = Number;
Number =0;
if (key == 'A')
{Serial.println ("Addition"); action = '+';}
if (key == 'B')
{Serial.println ("Subtraction"); action = '-'; }
if (key == 'C')
{Serial.println ("Multiplication"); action = '';}
if (key == 'D')
{Serial.println ("Devesion"); action = '/';}
delay(100);
}
}
void CalculateResult()
{
if (action=='+')
Number = Num1+Num2;
if (action=='-')
Number = Num1-Num2;
if (action=='')
Number = Num1Num2;
if (action=='/')
Number = Num1/Num2;
}
void DisplayResult()
{
lcd.setCursor(0, 0); // set the cursor to column 0, line 1
lcd.print(Num1); lcd.print(action); lcd.print(Num2);
if (result==true)
{lcd.print(" ="); lcd.print(Number);} //Display the result
lcd.setCursor(0, 1); // set the cursor to column 0, line 1
lcd.print(Number); //Display the result
}
Congratulations!
If you have completed all 9 lessons in this course, then you have completed the Arduino for Kooks basic-level course! You have learned most of the wiring and programming rudiments necessary to go on and build your very own projects with the Arduino platform!
As a reward for your efforts, I have designed a “merit badge” that you can attach to your EDC, patch wall, or a sweet hacker jacket. You’ve worked hard to achieve it, so show off your new skill set!
Congratulations on completing the Arduino for Kooks course in Arduino basics! As a reward for your efforts, you are eligible to wear this exclusive merit badge to show off your achievement and new skill set! This design is based on the Arduino Community Logo as I am not affiliated with Arduino the company. It’s going to be a hexagonal design so you can wear it with future badges in a sweet honeycomb design, but it looks just as good paired with other organizations’ badges, too!
The badge isn’t ready yet, but it will be soon! I’m working through the manufacturing process, and I will let you know once they’re ready! They’re going to measure about 1.5-2 inches across, and I’m looking to have the price point somewhere around $3US plus shipping, so let me know if you are interested in nabbing one of the first! You can check up on the progress via Instagram @theairbornesurfer
[yikes-mailchimp form=”1″ description=”1″ submit=”Let me know!”]
I’m a bit of a sucker for retro electronic novelties, and one of the most prolific is the “love tester” device that–in various forms–hearkens back to the early 20th century and the heyday of the penny arcade. These were often an electromechanical device that used some algorithm (or even just a random number generator) to ring bells, flash lights, and indicate either a fortune or–more often–a rating of one’s romantic prowess. In the 1960s, Nintendo released their first (in what would prove to be quite a long line) of electronic toys which gave a love rating based on the electrodermal activity between two people. In this video, part of a series building a project for element14 Presents, I’ll walk through using an Arduino to replicate the Nintendo Love Tester so you can build your own meter for your Valentine.
Inspired by scouting merit badges, Atari decides to start a tile wall to celebrate his achievements. To celebrate building his first online course (Arduino For Kooks), he’s going to design a tile based on the Arduino Community Logo–a frenetic jumble of multicolored shapes forming the Arduino “infinity” logo. Since his 3D printer only has one extruder, he decides to paint and assemble the differently colored pieces for a nice, lo-fi aesthetic.
Clocks are a rite of passage for hardware hackers, and with this video you can start working on your DIY Clock merit badge using the Arduino platform to build a basic Arduino clock. This project builds on the Arduino Fortune Teller project from the “Arduino For Kooks” basic series and teaches programming concepts like timing and actively updating a display, so you can use it as a springboard for many more complicated projects!
Connect the LCD module as described in the Liquid Crystal Ball project. You can use the breadboard to create buses for +5V and GND. Connect one side of one tactile switch to D8 and the other to a 10K resistor to ground. Connect one side of the other tactile switch to D9 and the other side to a 10K resistor to ground.
Previously, we looked at how to build a simple DIY Arduino clock. Unfortunately, if power to the clock is disconnected, the whole thing has to be reset. To solve that problem, we’re going to add an Arduino battery backup real time clock module based on the DS1307 RTC package. Instead of purchasing a pre-made part, we’ll walk through how to build a DIY Arduino RTC module from scratch and add it to our clock project.
//RealTimeClock RTC;//=new RealTimeClock();
#define Display_Clock_Every_N_Seconds 10 // n.secs to show date/time
#define Display_ShortHelp_Every_N_Seconds 60 // n.secs to show hint for help
//#define TEST_Squarewave
//#define TEST_StopStart
//#define TEST_1224Switch
int count=0;
char formatted[] = "00-00-00 00:00:00x";
void setup() {
// Wire.begin();
Serial.begin(9600);
pinMode(A3, OUTPUT); //*** pin 16 (Analog pin 2) as OUTPUT ***
digitalWrite(A3, HIGH); //*** pin 16 (Analog pin 2) set to LOW ***
pinMode(A2, OUTPUT); //*** pin 17 (Analog pin 3) as OUTPUT ***
digitalWrite(A2, LOW); //*** pin 17 (Analog pin 3) set to HIGH ***
//*** Analog Pin settings to power RTC module ***
}
void processCommand() {
if(!Serial.available()) { return; }
char command = Serial.read();
int in,in2;
switch(command)
{
case 'H':
case 'h':
in=SerialReadPosInt();
RTC.setHours(in);
RTC.setClock();
Serial.print("Setting hours to ");
Serial.println(in);
break;
case 'I':
case 'i':
in=SerialReadPosInt();
RTC.setMinutes(in);
RTC.setClock();
Serial.print("Setting minutes to ");
Serial.println(in);
break;
case 'S':
case 's':
in=SerialReadPosInt();
RTC.setSeconds(in);
RTC.setClock();
Serial.print("Setting seconds to ");
Serial.println(in);
break;
case 'Y':
case 'y':
in=SerialReadPosInt();
RTC.setYear(in);
RTC.setClock();
Serial.print("Setting year to ");
Serial.println(in);
break;
case 'M':
case 'm':
in=SerialReadPosInt();
RTC.setMonth(in);
RTC.setClock();
Serial.print("Setting month to ");
Serial.println(in);
break;
case 'D':
case 'd':
in=SerialReadPosInt();
RTC.setDate(in);
RTC.setClock();
Serial.print("Setting date to ");
Serial.println(in);
break;
case 'W':
Serial.print("Day of week is ");
Serial.println((int) RTC.getDayOfWeek());
break;
case 'w':
in=SerialReadPosInt();
RTC.setDayOfWeek(in);
RTC.setClock();
Serial.print("Setting day of week to ");
Serial.println(in);
break;
case 't':
case 'T':
if(RTC.is12hour()) {
RTC.switchTo24h();
Serial.println("Switching to 24-hour clock.");
} else {
RTC.switchTo12h();
Serial.println("Switching to 12-hour clock.");
}
RTC.setClock();
break;
case 'A':
case 'a':
if(RTC.is12hour()) {
RTC.setAM();
RTC.setClock();
Serial.println("Set AM.");
} else {
Serial.println("(Set hours only in 24-hour mode.)");
}
break;
case 'P':
case 'p':
if(RTC.is12hour()) {
RTC.setPM();
RTC.setClock();
Serial.println("Set PM.");
} else {
Serial.println("(Set hours only in 24-hour mode.)");
}
break;
case 'q':
RTC.sqwEnable(RTC.SQW_1Hz);
Serial.println("Square wave output set to 1Hz");
break;
case 'Q':
RTC.sqwDisable(0);
Serial.println("Square wave output disabled (low)");
break;
case 'z':
RTC.start();
Serial.println("Clock oscillator started.");
break;
case 'Z':
RTC.stop();
Serial.println("Clock oscillator stopped.");
break;
case '>':
in=SerialReadPosInt();
in2=SerialReadPosInt();
RTC.writeData(in, in2);
Serial.print("Write to register ");
Serial.print(in);
Serial.print(" the value ");
Serial.println(in2);
break;
case '<':
in=SerialReadPosInt();
in2=RTC.readData(in);
Serial.print("Read from register ");
Serial.print(in);
Serial.print(" the value ");
Serial.println(in2);
break;
default:
Serial.println("Unknown command. Try these:");
Serial.println(" h## - set Hours [range 1..12 or 0..24]");
Serial.println(" i## - set mInutes [range 0..59]");
Serial.println(" s## - set Seconds [range 0..59]");
Serial.println(" d## - set Date [range 1..31]");
Serial.println(" m## - set Month [range 1..12]");
Serial.println(" y## - set Year [range 0..99]");
Serial.println(" w## - set arbitrary day of Week [range 1..7]");
Serial.println(" t - toggle 24-hour mode");
Serial.println(" a - set AM p - set PM");
Serial.println();
Serial.println(" z - start clock Z - stop clock");
Serial.println(" q - SQW/OUT = 1Hz Q - stop SQW/OUT");
Serial.println();
Serial.println(" >##,### - write to register ## the value ###");
Serial.println(" <## - read the value in register ##");
}//switch on command
}
//read in numeric characters until something else
//or no more data is available on serial.
int SerialReadPosInt() {
int i = 0;
boolean done=false;
while(Serial.available() && !done)
{
char c = Serial.read();
if (c >= '0' && c <='9')
{
i = i * 10 + (c-'0');
}
else
{
done = true;
}
}
return i;
}