// Instructables page: // Credits: Both the first half of this code which recieves the data from the app and the app itself were made thanks to Tabletop Robotics' video on YouTube // The second half of the code for calculating pwm signals to send to the motor driver were taken from How to Mechatronics' video on YouTube #define in1 5 #define in2 6 #define in3 7 #define in4 8 #define enA 9 #define enB 10 #define LEDpin 13 #define Buzzer 4 int dataIn[5] {0,0,0,0}; //Array to store all the information. 255,button,X,Y. int in_byte = 0; int array_index = 0; int xAxis, yAxis; unsigned int x = 125; unsigned int y = 125; int button = 0; int motorSpeedA = 0; // Right motor int motorSpeedB = 0; // Left motor void setup() { pinMode(enA, OUTPUT); pinMode(enB, OUTPUT); pinMode(in1, OUTPUT); pinMode(in2, OUTPUT); pinMode(in3, OUTPUT); pinMode(in4, OUTPUT); pinMode(LEDpin, OUTPUT); pinMode(Buzzer, OUTPUT); Serial.begin (9600); // starts the serial monitor at given frequency } void loop() { x = 125; y = 125; if (Serial.available() > 0) { //recieve byte from phone in_byte = Serial.read(); //store in byte into a variable if (in_byte == (255)) { // if the variable is 0 stet the array inxed to 0. this will make sure that every number goes into the correct index array_index = 0; } dataIn[array_index] = in_byte; //store number into array array_index = array_index +1; //dataIn[0] button = dataIn[1]; x = dataIn[2]; y = dataIn[3]; } // The Light & Sound buttons in the App are stored in variable called button state: // button = 0 for Off // button = 1 for Light // button = 2 for Sound if (button == 1) { tone(Buzzer, 1000); // Send 1KHz sound signal. } else if (button == 2) { digitalWrite(LEDpin, HIGH); } else { noTone(Buzzer); // Turn Buzzer off digitalWrite(LEDpin, LOW); } // You can open the app and read the X and Y position values in each direction and use their range here // Y-axis is used for forward and backward control // In the app, 125 is the middle position, the following code says if the Y value goes below 120 ( I chose 120 to avoid jitters ) // move the car forwards if (y <= 120) { // Set direction of both motors to run forwards // This sets the polarity for left motor, you can change this if your motor is running in the wrong direction digitalWrite(in1, LOW); digitalWrite(in2, HIGH); // This sets the polarity for right motor, you can change this if your motor is running in the wrong direction digitalWrite(in3, LOW); digitalWrite(in4, HIGH); // Convert the declining Y-axis readings for going forwards from 120 to 0 into 0 to 255 value for the PWM signal for increasing the motor speed motorSpeedA = map(y, 120, 0, 0, 255); motorSpeedB = map(y, 120, 0, 0, 255); } // The following code says if the Y value goes above 130 ( I chose 130 to avoid jitters ) // move the car backwards else if (y >= 130) { // Set direction of both motors to run backwards (reverse) // This sets the polarity for right motor, you can change this if your motor is running in the wrong direction digitalWrite(in1, HIGH); digitalWrite(in2, LOW); // This sets the polarity for left motor, you can change this if your motor is running in the wrong direction digitalWrite(in3, HIGH); digitalWrite(in4, LOW); // Convert the increasing Y-axis readings for going backwards from 130 to 250 into 0 to 255 value for the PWM signal for increasing the motor speed motorSpeedA = map(y, 130, 250, 0, 255); motorSpeedB = map(y, 130, 250, 0, 255); } // If joystick stays in middle the motors are not moving, turn both motors off. else { motorSpeedA = 0; motorSpeedB = 0; } // X-axis used for left and right control if (x >= 130) { // Convert the increasing X-axis readings from 130 to 250 into increasing 0 to 255 value int xMapped = map(x, 130, 250, 0, 255); // Turn right - increase left motor speed, decrease right motor speed motorSpeedA = motorSpeedA - xMapped; motorSpeedB = motorSpeedB + xMapped; // Confine the range from 0 to 255 if (motorSpeedA < 0) { motorSpeedA = 0; } if (motorSpeedB > 255) { motorSpeedB = 255; } } else if (x <= 120) { // Convert the declining X-axis readings from 120 to 0 into increasing 0 to 255 value int xMapped = map(x, 120, 0, 0, 255); // Turn left - decrease left motor speed, increase right motor speed motorSpeedA = motorSpeedA + xMapped; motorSpeedB = motorSpeedB - xMapped; // Confine the range from 0 to 255 if (motorSpeedA > 255) { motorSpeedA = 255; } if (motorSpeedB < 0) { motorSpeedB = 0; } } //Handling negative values if (motorSpeedA < 0) { motorSpeedA = 0; } if (motorSpeedB < 0) { motorSpeedB = 0; } //This is where the result of the previous calculatios are sent to the motor driver analogWrite(enA, motorSpeedA); // Send PWM signal to Right Motor analogWrite(enB, motorSpeedB); // Send PWM signal to Left Motor // This gives feedback to the Serial monitor in the app or the Arduino IDE for debugging purposes // L: Left motor speed, R: Right motor speed, X: X position recieved, Y: Y position recieved String terminal = "L:" + String(motorSpeedB) + " R:" + String(motorSpeedA) + " X:" + String(x) + " Y:" + String(y) + " B:" + String(button); Serial.println(terminal); }