Things used in this project

Hardware components:
A000066 iso both
Arduino UNO & Genuino UNO
×1
Texas instruments l293dne image
Texas Instruments Dual H-Bridge motor drivers L293D
(buy one with long pins, not the surface-mount version shown on the photo)
×1
12002 04
Breadboard (generic)
×1
Adafruit industries ada80 image 75px
9V to Barrel Jack Connector
×1
Lego Power Functions Extension wire (Item: 8886)
×3
Bluetooth HC-05
×1

Schematics

Github Lego-car-Arduino
Contains source code Arduino; Fritzing diagram; source code android app for upload to MIT app inventor
Fritzing diagram breadboard Lego-car-Arduino
Fritzing diagram Lego car
Lego rc car v2.fzz
Fritzing diagram schematics Lego-car-Arduino

Code

Legocar_v3_bluetoothArduino
/*
 Lego Powerfunctions car model controlled over bluetooth
 Arduino Uno controls motors and servo
 Remote controlled with android app developed with MIT App Inventor 2
 
 Circuit:
 * Serial communication   (uses Uno pin 0,1)    Bluetooth-module is attached (has to be detached when loading program over USB)
 * L293D with motor       (uses Uno digital pins 2,5,9)
 * L293D with servo       (uses Uno digital pins 6,8,3)
 
 
*/

// Used libraries:
#include <SPI.h>                             // Serial Peripheral Interface Library
#include <String.h>                          // contains function strtok: split string into tokens


// Serial buffer size: calculate based on max input size expected for one command over bluetooth serial interface
#define INPUT_SIZE 30

// Motor control digital output pins defined as global constants (4 wheel drive with 2 Lego motors):
const int controlPin1A = 2;                  // L293D driver input 1A on pin no 2  http://www.ti.com/lit/ds/symlink/l293.pdf connected to Arduino digital output pin 2
const int controlPin2A = 5;                  // L293D driver input 2A on pin no 7 connected to Arduino digital output pin 5
const int ENablePin = 9;                     // L293D ENable(1,2) input on pin no 1 connected to Arduino digital output pin 9
// Servo control digital output pins defined as global constants (Servo steering with 1 Lego servo):
const int controlPin3A = 6;                  // L293D driver input 3A on pin no 10 connected to Arduino digital output pin 6
const int controlPin4A = 8;                  // L293D driver input 4A on pin no 15 connected to Arduino digital output pin 8 
const int servoENablePin = 3;                // L293D ENable(3,4) input on pin no 9 connected to Arduino digital output pin 3
// Motor control global variables: 
int motorSpeed = 0;                          // Motor speed 0..255
int motorDirection = 1;                      // Forward (1) or reverse (0)
// Servo control global variables:
int steering = 0;                            // Servo position 0..255
int steeringDirection = 0;                   // Left (0) and Right (1)



void setup() 
{
   Serial.begin(9600);                       // initialize serial communication
   Serial.setTimeout(1000);                  // 1000 ms time out
   // Declare digital output pins:
   pinMode(controlPin1A, OUTPUT);      // 1A
   pinMode(controlPin2A, OUTPUT);      // 2A
   pinMode(ENablePin, OUTPUT);         // EN1,2
   pinMode(controlPin3A, OUTPUT);      // 3A
   pinMode(controlPin4A, OUTPUT);      // 4A
   pinMode(servoENablePin, OUTPUT);    // EN3,4
   digitalWrite(ENablePin, LOW);       // motor off
   digitalWrite(servoENablePin, LOW);  // steering centered
}


void loop() 
{
   // Get next command from serial bluetooth (add 1 byte for final 0)
   char input[INPUT_SIZE + 1];                  // array of type char (C-string) with null-termination (https://www.arduino.cc/en/Reference/String)
   byte size = Serial.readBytesUntil('\n', input, INPUT_SIZE);   //read Serial until new line or buffer full or time out
   // Add the final 0 to end the C-string
   input[size] = 0;

   // Read command which is a C-string of the form:  "RC,RCsteering,RCspeed,\n\0"  (ends with a new line character and a null)
   char* command = strtok(input, ",");          // ignore command for now (RC for Remote Control is the only command sent by the app for the time being)    
   char* RCsteering = strtok(NULL, ",");        // next comes RCsteering which is in the Range: -100 (left).. 0 .. 100 (right)
   char* RCspeed = strtok(NULL, ",");           // next comes RCspeed which is in the Range: -100 (full speed reverse).. 0 .. 100 (full speed forward)
   int iRCsteering = atoi(RCsteering);          // convert string RCsteering into integer iRCsteering
   int iRCspeed = atoi(RCspeed);                // convert string RCspeed into integer iRCspeed
   
   // Set motor and servo control variables
   if (iRCsteering > 0) steeringDirection = 1;   // turn right if iRCsteering = 1..100
   else steeringDirection = 0;                   // turn left  if iRCsteering = -100..0
   steering = int(2.55*abs(iRCsteering));        // Servo position 0..255 based on command 0..100
   if (iRCspeed > 0) motorDirection = 1;         // Set car in forward if iRCspeed = 1..100
   else motorDirection = 0;                      // Set car in reverse if iRCspeed = -100..0
   motorSpeed = int(2.55*abs(iRCspeed));         // Set speed 0..255 based on command 0..100
   
   SetMotorControl();                            // adjust motor direction and speed 
}




void SetMotorControl()
/*
L293 logic:    EN1,2   1A    2A
               H       H     L    Motor turns left  (Forward; motorDirection == 1)
               H       L     H    Motor turns right (Reverse; motorDirection == 0)
               
               EN3,4   3A    4A
               H       H     L    Servo turns left  (steeringDirection == 0)
               H       L     H    Servo turns right (steeringDirection == 1)

Motor speed:   PWM signal on EN1,2 (490 Hz; digital output value 0..255 for motorSpeed)
Servo position:PWM signal on EN3,4 (490 Hz; digital output value 0..255 for position; 0 is straight ahead)
*/
{
  if (motorDirection == 1)               //Forward
    {
       digitalWrite(controlPin1A, HIGH);
       digitalWrite(controlPin2A, LOW);
    }
  else                                   //Reverse
    {
       digitalWrite(controlPin1A, LOW);
       digitalWrite(controlPin2A, HIGH);
    } 
  analogWrite(ENablePin, motorSpeed);    //Speed
    
  if (steeringDirection == 0)            //Left
    {
       digitalWrite(controlPin3A, HIGH);
       digitalWrite(controlPin4A, LOW);
    }
  else                                   //Right
    {
       digitalWrite(controlPin3A, LOW);
       digitalWrite(controlPin4A, HIGH);
    } 
  analogWrite(servoENablePin, steering); //Servo position

}
Github Lego-car-Arduino
Contains source code Arduino; Fritzing diagram; source code android app for uploading to MIT app inventor

Credits

7efc6ed6f199f9501d2a40097ed50e30
Patrick Müller

Hobbyist, mechanical engineer and father of curious children

Contact

Replications

Did you replicate this project? Share it!

I made one

Love this project? Think it could be improved? Tell us what you think!

Give feedback

Comments

Similar projects you might like

I Keep my Cucumber Growing Conditions Moist - Part 2
Easy
  • 196
  • 4

Full instructions

This is the next step with an Ultrasonic HC-SR04 Echo and LCD 1602.

Laser Stuff
Easy
  • 511
  • 3

A laser module that makes light patterns.

LEDog Collar
Easy
  • 897
  • 10

Full instructions

The LEDog collar lights up when it gets dark, helping you locate your dog from far away.

Handheld Infinity Kaleidoscope Group Kit
Easy
  • 2,619
  • 30

Full instructions

Use the orientation sensor in your Arduino 101 to control a cool Petri dish infinity-mirror illusion. This project is great for groups.

Arduino 101 BLE RGB Lamp
Easy
  • 538
  • 7

Full instructions

Create your own RGB controlled lamp with Arduino 101 using BLE.

SECURITY SYSTEM AND ACCESs CONTROL WITH ARDUINO AND RFID
Easy
  • 666
  • 8

Full instructions

To enter passwords and to allow access to a door or to drive an electronic device, now we will use a RFID device

ProjectsCommunitiesTopicsContestsLiveAppsBetaFree StoreBlogAdd projectSign up / Login
Feedback