Hello All,
I am burying my pride and posting here for some ideas/assistance. I have a student who wanted to delve into some Arduino based robotics for an end of year Capstone project. I teach industrial robotics, so i am versed in FANUC KAREL and ABB language, but have little experience coding Arduino boards. The student has a two motor tracked bot kit and associated peripherals to build the bot using an UNO as the board. The two motors will drive the tracks, and a single servo based gripper will serve as the picker. Communication is via an HC-05 board. We are using an android phone and a BTT app can connect to the HC-05, however, the app downloaded to control the bot will not connect. We are trying to modify known code that the student has found for similar bots but not having much luck. I am at my wits end. Could someone point me in the right direction so I can get the bot working with a known configuration, then wipe it and let the student figure it out? I need a sort of "instructor exam key" so I know what the correct answer is to help the student clear their hurdles. Currently it is the blind leading the slightly more blind. Many thanks!
To be able to help, we need to know the project.
So post everything you can, codes, APP, schematics (wiring), etc., to make our help work easier.
The student is using this wiring diagram, except they only have a single gripper servo.
The student is using the below website as the guide for programming.
[Bluetooth-Controlled Pick and Place Robotic Arm Car with Arduino and Smart Phone]
That code, in particular, is essential if we are to understand where you are and where you need to go.
I have compiled this, deleting SERVO 1 & 2 and leaving SERVO 3 (Gripper) all else should match the student's bot.
#include // include servo library
// Define 1 Servo
Servo myServo3; // gripper Servo
void setup() {
// Attach servos to Arduino PWM Pins
myServo3.attach(3);
myServo3.write(90);
}
void loop() {
}
#include <Servo.h>
Servo motor_3;
//#define enA 9 //Enable1 L298 Pin enA
#define in1 7 //Motor1 L298 Pin in1
#define in2 8 //Motor1 L298 Pin in1
#define in3 12 //Motor2 L298 Pin in1
#define in4 11 //Motor2 L298 Pin in1
//#define enB 9 //Enable2 L298 Pin enB
int servo3 = 90;
int bt_data;
int Speed = 130;
void setup(){
Serial.begin(9600); // initialize serial communication at 9600 bits per second:
motor_3.attach(3); // Gripper Servo
motor_3.write(servo3);
//pinMode(enA, OUTPUT); // declare as output for L298 Pin enA
pinMode(in1, OUTPUT); // declare as output for L298 Pin in1
pinMode(in2, OUTPUT); // declare as output for L298 Pin in2
pinMode(in3, OUTPUT); // declare as output for L298 Pin in3
pinMode(in4, OUTPUT); // declare as output for L298 Pin in4
//pinMode(enB, OUTPUT); // declare as output for L298 Pin enB
digitalWrite(in1, LOW); //Right Motor forword Pin
digitalWrite(in2, LOW); //Right Motor backword Pin
digitalWrite(in3, LOW); //Left Motor backword Pin
digitalWrite(in4, LOW); //Left Motor forword Pin
delay(1000);
}
void loop(){
//if some date is sent, reads it and saves in state
if(Serial.available() > 0){
bt_data = Serial.read();
Serial.println(bt_data);
if(bt_data > 20)
{Speed = bt_data;}
}
//analogWrite(enA, Speed); // Write The Duty Cycle 0 to 255 Enable Pin A for Motor1 Speed
//analogWrite(enB, Speed); // Write The Duty Cycle 0 to 255 Enable Pin B for Motor2 Speed
if(bt_data == 1)
{forword(); } // if the bt_data is '1' the DC motor will go forward
else if(bt_data == 2)
{backword();} // if the bt_data is '2' the motor will Reverse
else if(bt_data == 3)
{turnLeft();} // if the bt_data is '3' the motor will turn left
else if(bt_data == 4)
{turnRight();} // if the bt_data is '4' the motor will turn right
else if(bt_data == 5)
{Stop(); } // if the bt_data '5' the motor will Stop
}
else if (bt_data == 16){
if(servo3>60){servo3 = servo3-1;}
motor_3.write(servo3);
}
else if (bt_data == 17){
if(servo3<150){servo3 = servo3+1;}
motor_3.write(servo3);
}
delay(30);
}
void forword(){ //forword
digitalWrite(in1, HIGH); //Right Motor forword Pin
digitalWrite(in2, LOW); //Right Motor backword Pin
digitalWrite(in3, HIGH); //Left Motor forward Pin
digitalWrite(in4, LOW); //Left Motor backward Pin
}
void backword(){ //backword
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
digitalWrite(in3, LOW);
digitalWrite(in4, HIGH);
}
void turnRight(){ //turnRight
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
digitalWrite(in3, HIGH);
digitalWrite(in4, LOW);
}
void turnLeft(){ //turnLeft
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
digitalWrite(in3, LOW);
digitalWrite(in4, HIGH);
}
void Stop(){ //stop
digitalWrite(in1, LOW);
digitalWrite(in2, LOW);
digitalWrite(in3, LOW);
digitalWrite(in4, LOW);
}
-
There is only one setup( ) and loop( ) in a sketch.
-
Show us good images that expose the interconnections in the project.
Not successfully.
Obviously.
Can you assist in where I went wrong?
- remove the first 11 lines. 1 setup(), 1 loop(), no duplicate #includes
- press ctrl-T to format the code in a standard fashion
- note how, around line 78, the indentation stops. The {} pairing is messed up. Review the code to see where the structure is deficient. We can help with that.
You'll want to enable line numbering in preferences, if you haven't.
You'll want to increase the error/warning settings, so you get more info during compile.
Others can help from here, I've gotta leave now, but as Larry says, an image of how it's actually wired would help sort the wheat from the chaff.
It's wired exactly like the wiring diagram pictured, except there is only a single servo controlling a gripper.
I understand, you're a teacher and expect us to believe you, but you'd be darn surprised how often we observe things in a setup that "aren't there" according to the poster. So please.
I'll check in in a few hours.
- We need to know if there are any wiring errors.
- We need to know what jumpers are installed on the motor driver board.
- We need to see the quality of the connections.
- We really need to see good images of the hardware and wiring.
Too many people in the past often have errors in their wiring leaving volunteers spinning their wheels until they finally discover there is a wiring problem.
Okay, here is what the student has.
Here is the explanation:
12v supply to Buck Converter and Motor Controller
Motor Controller to drive motors
OUT 1 to DRIVE MOTOR 1 - Purple(+)/White(-)
OUT 2 to DRIVE MOTOR 2 - Purple(+)/White(-)
Buck Converter to UNO
UNO 5v IN - Red
UNO GND - Black
UNO to HC-05
UNO TX to HC-05 RX - Yellow
UNO RX to HC-05 TX - Green
UNO 3.3V to HC-05 VCC - Red
UNO GND to HC-05 GND - Black
UNO to Gripper
UNO 5v to Gripper VCC - Red
UNO GND to Gripper - Brown
UNO OUTPUT PIN (not yet landed or defined) to Gripper Control - Orange
I changed the code per suggestions, but my Arduino IDE preferences has no options to show line numbers. The numbers are there in my software window, but I cannot seem to include them in the copy/paste. Here is the code with the changes I made.
#include <Servo.h>
Servo myServo3;
Servo motor_3;
//#define enA 9 //Enable1 L298 Pin enA
#define in1 7 //Motor1 L298 Pin in1
#define in2 8 //Motor1 L298 Pin in1
#define in3 12 //Motor2 L298 Pin in1
#define in4 11 //Motor2 L298 Pin in1
//#define enB 9 //Enable2 L298 Pin enB
int servo3 = 90;
int bt_data;
int Speed = 130;
void setup() {
myServo3.attach(3);
myServo3.write(90);
Serial.begin(9600); // initialize serial communication at 9600 bits per second:
motor_3.attach(3); // Gripper Servo
motor_3.write(servo3);
//pinMode(enA, OUTPUT); // declare as output for L298 Pin enA
pinMode(in1, OUTPUT); // declare as output for L298 Pin in1
pinMode(in2, OUTPUT); // declare as output for L298 Pin in2
pinMode(in3, OUTPUT); // declare as output for L298 Pin in3
pinMode(in4, OUTPUT); // declare as output for L298 Pin in4
//pinMode(enB, OUTPUT); // declare as output for L298 Pin enB
digitalWrite(in1, LOW); //Right Motor forword Pin
digitalWrite(in2, LOW); //Right Motor backword Pin
digitalWrite(in3, LOW); //Left Motor backword Pin
digitalWrite(in4, LOW); //Left Motor forword Pin
delay(1000);
}
void loop() {
//if some date is sent, reads it and saves in state
if (Serial.available() > 0) {
bt_data = Serial.read();
Serial.println(bt_data);
if (bt_data > 20) { Speed = bt_data; }
}
//analogWrite(enA, Speed); // Write The Duty Cycle 0 to 255 Enable Pin A for Motor1 Speed
//analogWrite(enB, Speed); // Write The Duty Cycle 0 to 255 Enable Pin B for Motor2 Speed
if (bt_data == 1) { forword(); } // if the bt_data is '1' the DC motor will go forward
else if (bt_data == 2) {
backword();
} // if the bt_data is '2' the motor will Reverse
else if (bt_data == 3) { turnLeft(); } // if the bt_data is '3' the motor will turn left
else if (bt_data == 4) {
turnRight();
} // if the bt_data is '4' the motor will turn right
else if (bt_data == 5) { Stop(); } // if the bt_data '5' the motor will Stop
}
else if (bt_data == 16) {
if (servo3 > 60) { servo3 = servo3 - 1; }
motor_3.write(servo3);
}
else if (bt_data == 17) {
if (servo3 < 150) { servo3 = servo3 + 1; }
motor_3.write(servo3);
}
delay(30);
}
void forword() { //forword
digitalWrite(in1, HIGH); //Right Motor forword Pin
digitalWrite(in2, LOW); //Right Motor backword Pin
digitalWrite(in3, HIGH); //Left Motor forward Pin
digitalWrite(in4, LOW); //Left Motor backward Pin
}
void backword() { //backword
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
digitalWrite(in3, LOW);
digitalWrite(in4, HIGH);
}
void turnRight() { //turnRight
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
digitalWrite(in3, HIGH);
digitalWrite(in4, LOW);
}
void turnLeft() { //turnLeft
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
digitalWrite(in3, LOW);
digitalWrite(in4, HIGH);
}
void Stop() { //stop
digitalWrite(in1, LOW);
digitalWrite(in2, LOW);
digitalWrite(in3, LOW);
digitalWrite(in4, LOW);
}
- We need to know what jumpers are installed on the motor driver board.
Here is a closeup of the motor controller
Looks like that won't compile due to a misplaced bracket here:
-
It appears you are using the Arduino 5v power pin to power the servo.
Your Arduino board 5 volt supply is not adequate to power your project. If you continue to use it as such, your Arduino may/will be damaged. Also, never connect an inductive load to the Arduino 5v pin. -
This is an accident waiting to happen, do not expose the motor pins as they can/will short out.
-
Please confirm all voltages with a voltmeter.
-
The HC-05 RX needs voltage translation from 5v to 3v3.
-
Is the HC-05 receiving ”type” binary or char ?
-
Why are you sending the value back to the HC-05
bt_data = Serial.read();
Serial.println(bt_data);
Larry,
This is a student project and I am trying to unwind what they are trying to do. To answer your question, the code is being used from a project website. I nor my student wrote the code, so I cannot tell you why that value is being sent back to the HC-05. Currently, we cannot even get the HC-05 to connect to the controller app we have on the Android device. It will connect on my Alienware laptop, but then immediately show disconnected even though the LED on the HC-05 shows it to be connected. I am just not familiar with Arduino and need to help sort this end-of-year project out with my student. I apologize for not knowing more.
-
No need.
-
Do you remove the HC-05 when you upload the sketch to the UNO ?
EDIT
- you have the following, why ?:
void setup() {
myServo3.attach(3);
myServo3.write(90);
. . .
motor_3.attach(3); // Gripper Servo
motor_3.write(servo3);
Larry,
I do not remove the HC-05 during uploading.
I am not sure why I have that there. After looking at the reference website, the author has us running two codes. First they write and have us do this:
Bluetooth-Controlled Robotic Arm Car Code Explanation
The Bluetooth-controlled robotic arm Car is controlled via an Android app on Smart phone. The app has different buttons for making the Car move forward, backward, left, and right. It also controls the robotic arm waist, shoulder, and gripper movements.
The app sends signals when pressed the specific button to the servo motors in the robot, telling them how to position the arm for each type of movement.
It is important to execute this code #1 before starting the assembly stages. This code is designed to calibrate and adjust the servo motors to their correct angles. By running this code, you can ensure that the servo motors are properly functioning and positioned accurately. This will help prevent any potential issues or complications during the subsequent stages of the assembly process.
Code #1
#include <ESP32_Servo.h> // include servo library
// Define 3 Servos
Servo myServo1; // waist or base Servo
Servo myServo2; // shoulder Servo
Servo myServo3; // gripper Servo
void setup() {
- // Attach servos to Arduino PWM Pins*
- myServo1.attach(5);*
- myServo2.attach(6);*
- myServo3.attach(3);*
- myServo1.write(90);*
- myServo2.write(90);*
- myServo3.write(90);*
}
void loop() {
}
Then, after that, they have us run the second code. I am not sure how that is supposed to work however because I thought once you upload a code, it overwrites any previous code. I was trying to incorporate both procedures into one. I am sure this is incorrect and leading to even more troubles. Keep in mind, at this point we are still trying to get some code uploaded and connect to test servos and motors. The bot is not even fully constructed yet.
So second set of instructions is this:
This code #2 includes all the necessary servo motor movements to make your robot functional. Without this code, you will not be able to complete the project successfully. It is crucial for the proper operation of the robot.
This code outlines the setup and control mechanisms for a robotic arm and a 2WD Arduino car using servo motors and DC motors. It integrates Bluetooth communication to enable remote control and demonstrates how to manipulate servo angles and motor directions to achieve specific movements.
Code #2
#include <Servo.h>
*Servo motor_1; *
Servo motor_2;
Servo motor_3;
These lines include the necessary library for using servo motors and define three Servo objects (motor_1, motor_2, and motor_3) are created to control the three servos connected to pins 5, 6, and 3 respectively.
#define in1 7 //Motor1 L298 Pin in1
#define in2 8 //Motor1 L298 Pin in1
#define in3 12 //Motor2 L298 Pin in1
#define in4 11 //Motor2 L298 Pin in1
These lines define digital pins of Arduino (pin7,pin8,pin12 and pin11) for the L298N motor driver inputs to control the DC motors. The pins in1 and in2 control one motor, and the pins in3 and in4 control the other motor.
int servo1 = 90;
int servo2 = 0;
int servo3 = 90;
int bt_data;
int Speed = 130;
Initial positions (angles) for the three servos are set: servo1, servo2, and servo3. bt_data is used to store incoming Bluetooth data. Speed is initially set to 130.
void setup(){
Serial.begin(9600); // initialize serial communication at 9600 bits per second:
motor_1.attach(5); // Waist Servo
motor_2.attach(6); // Shoulder Servo
motor_3.attach(3); // Gripper Servo
motor_1.write(servo1);
motor_2.write(servo2);
motor_3.write(servo3);
//pinMode(enA, OUTPUT); // declare as output for L298 Pin enA
pinMode(in1, OUTPUT); // declare as output for L298 Pin in1
pinMode(in2, OUTPUT); // declare as output for L298 Pin in2
*pinMode(in3, OUTPUT); // declare as output for L298 Pin in3 *
pinMode(in4, OUTPUT); // declare as output for L298 Pin in4
//pinMode(enB, OUTPUT); // declare as output for L298 Pin enB
digitalWrite(in1, LOW); //Right Motor forword Pin
digitalWrite(in2, LOW); //Right Motor backword Pin
digitalWrite(in3, LOW); //Left Motor backword Pin
digitalWrite(in4, LOW); //Left Motor forword Pin
delay(1000);
}
In the setup() function, serial communication is initialized at 9600 bits per second. The servo motors are attached to specific pins, and their initial positions are set. The digital pins for motor control and the motor driver pins are set as outputs. The motor driver pins are initially set to low to ensure the motors are not moving during setup.
void loop(){
//if some date is sent, reads it and saves in state
*if(Serial.available() > 0){ *
bt_data = Serial.read();
Serial.println(bt_data);
if(bt_data > 20)
*{Speed = bt_data;} *
}
The loop function is where the main program logic runs in a continuous loop.
This code block reads incoming Bluetooth data from the serial connection. If the received data is greater than 20, it updates the Speed variable.
if(bt_data == 1)
- {forword(); } // if the bt_data is '1' the DC motor will go forward*
else if(bt_data == 2) - {backword();} // if the bt_data is '2' the motor will Reverse*
else if(bt_data == 3) - {turnLeft();} // if the bt_data is '3' the motor will turn left*
else if(bt_data == 4) - {turnRight();} // if the bt_data is '4' the motor will turn right*
else if(bt_data == 5) - {Stop(); } // if the bt_data '5' the motor will Stop*
These conditional statements check the value of bt_data and call corresponding functions (forword, backword, turnLeft, turnRight, Stop) based on the received data.
else if (bt_data == 8){
if(servo1<180){servo1 = servo1+1;}
*motor_1.write(servo1); *
}
else if (bt_data == 9){
if(servo1>0){servo1 = servo1-1;}
*motor_1.write(servo1); *
}
else if (bt_data == 10){
if(servo2>0){servo2 = servo2-1;}
motor_2.write(servo2);
}
else if (bt_data == 11){
if(servo2<180){servo2 = servo2+1;}
*motor_2.write(servo2); *
}
else if (bt_data == 16){
if(servo3>60){servo3 = servo3-1;}
motor_3.write(servo3);
}
else if (bt_data == 17){
if(servo3<150){servo3 = servo3+1;}
motor_3.write(servo3);
}
delay(30);
}
These conditional statements adjust the position of the waist servo (motor_1) based on the received Bluetooth data.
The remaining else if blocks adjust the positions of the shoulder and gripper servos (motor_2 and motor_3) similarly.
delay introduces a short pause between iterations of the loop function to prevent rapid and continuous execution.
void forword(){ //forword
digitalWrite(in1, HIGH); //Right Motor forword Pin
digitalWrite(in2, LOW); //Right Motor backword Pin
digitalWrite(in3, HIGH); //Left Motor forward Pin
digitalWrite(in4, LOW); //Left Motor backward Pin
}
void backword(){ //backword
*digitalWrite(in1, LOW); *
digitalWrite(in2, HIGH);
digitalWrite(in3, LOW);
*digitalWrite(in4, HIGH); *
}
void turnRight(){ //turnRight
*digitalWrite(in1, LOW); *
*digitalWrite(in2, HIGH); *
*digitalWrite(in3, HIGH); *
digitalWrite(in4, LOW);
}
void turnLeft(){ //turnLeft
digitalWrite(in1, HIGH);
*digitalWrite(in2, LOW); *
digitalWrite(in3, LOW);
*digitalWrite(in4, HIGH); *
}
void Stop(){ //stop
digitalWrite(in1, LOW);
*digitalWrite(in2, LOW); *
digitalWrite(in3, LOW);
digitalWrite(in4, LOW);
}
These functions (forword, backword, turnLeft, turnRight, Stop) define the movements of the robot based on the motor driver pins' states.
These functions control the direction of the motors to achieve the desired movement.
By organizing the code in this way, we can modularize the functionality and make it easier to understand and maintain. The conditional statements ensure that the appropriate movement function is executed when the corresponding condition is met based on the received data.