Project tutorial
Remote Control Car w/ PocketBeagle and Arduino

Remote Control Car w/ PocketBeagle and Arduino © GPL3+

Have you ever wanted to use a PocketBeagle? And build a remote car? Well, I have! Here is how you can too!

  • 4,234 views
  • 3 comments
  • 13 respects

Components and supplies

Necessary tools and machines

09507 01
Soldering iron (generic)

Apps and online services

About this project

Introduction:

I wanted to make my own remote car where I would be able to control it from my phone. I wanted a project that would incorporate both coding and hardwarde design.

Overview:

I initially started this project thinking I would only be using a PocketBeagle, but I soon realized that I would need to use an Arduino to control my BLE module. I used the Arduino to control the BLE module because it already had a library in Arduino to control the car. The BLE module allows you to control your RC car from a phone app, Adafruit Bluefruit LE Connect, under the controller tab. After the RC car is powered by external power sources, you will be able to drive the car around using the arrow buttons.

Hardware:

As stated earlier, this RC car uses both the PocketBeagle and the Arduino to control the motion by an app on your smartphone. In addition to the two microprocessors, I used an Adafruit Bluefruit LE SPI Friend module, Dual H-Bridge Motor Driver (L293D), four 4.7k ohms resistors, four 10k ohms resistors, a 9V batter, 6x AA batteries, and a 5V external battery charger. For the car, I used a Spark-Fun Multi-Chasis 4WD kit. In this kit, I received the main frame for the car, four motors, four wheels, and battery holder.

Fritzing Diagram:

Since I was not able to find the Bluefruit LE SPI Friend Module on Frizting, here are the connections that need to be made in order for the code to align with hardware. The BLE is wired to the Arduino, since the Arduino has already been wired to the PocketBeagle.

  • SCK is connected to PIN 13
  • MISO is connected to PIN 12
  • MOSI is connected to PIN 11
  • CS is connected to PIN 8
  • IRQ is connected to PIN 7
  • RST is connected to PIN 4

Since the car has four possible directions/movements, I had the Arduino connect using four gpio pins, where it is in an input onto the PocketBeagle. In order to accomplish this project, I had to use an existent library: Adafruit Bluefruit LE nRF51 (https://github.com/adafruit/Adafruit_BluefruitLE_nRF51). Inside that folder, I use the controller library; the only changes I made to the library is adding the connections to the PocketBeagle.

In the setup part of the Arduino Code in Controller, I added the pins that control the movement and designated them as outputs because they will be inputs on the PocketBeagle. They are also initially set as LOW, and will be HIGH when the button on the app is pressed.

In the loop, I set the pin values as HIGH.

This is the section of the code that will set the pin as a HIGH or LOW based on if the buttons are pressed.

Case 1, which is the number 1 on the button, is the fail safe stop; therefore, if the button 1 is pressed, all pins are set to a value of LOW.

Case 2, 3, and 4 do not have an if statement because those buttons are not being used.

Case 5 is the up arrow, meaning if pressed, the RC car will move forward and pin 6 will be set on HIGH.

Case 6 controls the down arrow, which means that the car will move backwards.

Case 7 and 8 control the direction of the RC car to the right or left, respectively.

GAME PLAY:

In order to control the RC car, you need to download the app and connect to the Adafruit Bluefruit. By connecting to the Bluefruit, you will then be able to select Controller as the tab to enter, where you will end up with a screen similar to the Figure above titled TheControlButtons. From here, it is very similar to controlling other RC cars.

Directions:

The Up Arrow allows for forward motion; the Down Arrow allows backward motion. The arrow pointing to the right, changes the direction of the car to the right; the arrow pointing to the left, changes the direction of the car to the left.

Future Upgrades:

In the future, I hope to use buttons 2, 3, and 4 for varying speeds and controls. In addition to enabling those buttons, I need to make a contained for all the breadboards and wiring that will make the RC car more user-friendly. With more time, a library for the BLE module may be made that will allow it to connect to the PocketBeagle directly rather than using an Arduino.

Code

Cloud 9: Python RC_carPython
import time
import random

# ------------------------------------------------------------------------
# Constants
# ------------------------------------------------------------------------

# Peripheral path
GPIO_BASE_PATH               = "/sys/class/gpio"
ADC_BASE_PATH                = "/sys/bus/iio/devices/iio:device0"

# GPIO direction (if it is outputting or inputting a signal to the GPIO)
IN                           = True
OUT                          = False

# GPIO output state
LOW                          = "0"
HIGH                         = "1"

#Motor 1 
motor_1_ln1 				 = (0,30) #gpio30 P2_P5
motor_1_ln2					 = (0,31) #gpio31 P2_P7
motor_1_en1  				 = (1,28) #gpio60 P2_P8

#Motor 2
motor_2_ln4					 = (1,25) #gpio57 P2_P6
motor_2_ln3					 = (1,26) #gpio58 P2_P4
motor_2_en3					 = (1,27) #gpio59 P2_P2

#Motor 3
motor_3_ln1					 = (1,10) #gpio42 P1_P32
motor_3_ln2					 = (1,11) #gpio43 P1_P30
motor_3_en1					 = (0,26) #gpio26 P1_34

#Motor4
motor_4_ln4					 = (3,15) #gpio111 P1_33
motor_4_ln3					 = (2,24) #gpio88 P1_35
motor_4_en3					 = (3,14) #gpio110 P1_36

ard1                        =(3,20) #going to ard6
ard2                        =(3,17) #going to ard5
ard3                        =(3,16) #going to ard3
ard4                        =(3,19) #going to ard2


motor1						 = (motor_1_ln1, motor_1_ln2, motor_1_en1)
motor2						 = (motor_2_ln3, motor_2_ln4, motor_2_en3)
motor3						 = (motor_3_ln1, motor_3_ln2, motor_3_en1)
motor4						 = (motor_4_ln3, motor_4_ln4, motor_4_en3)


# ------------------------------------------------------------------------
# Global variables
# ------------------------------------------------------------------------

start_time                    = 30.0              # Start time (in seconds)


# ------------------------------------------------------------------------
# GPIO / ADC access library
# ------------------------------------------------------------------------
import os

def gpio_setup(gpio, direction, default_value=False):
    """Setup GPIO pin
    
      * Test if GPIO exists; if not create it
      * Set direction
      * Set default value
    """
    gpio_number = str((gpio[0] * 32) + gpio[1])
    path        = "{0}/gpio{1}".format(GPIO_BASE_PATH, gpio_number)
    
    if not os.path.exists(path):
        # "echo {gpio_number} > {GPIO_BASE_PATH}/export"
        print("Create GPIO: {0}".format(gpio_number))
        with open("{0}/export".format(GPIO_BASE_PATH), 'w') as f:
            f.write(gpio_number)
    
    if direction:
        # "echo in > {path}/direction"
        with open("{0}/direction".format(path), 'w') as f:
            f.write("in")
    else:
        # "echo out > {path}/direction"
        with open("{0}/direction".format(path), 'w') as f:
            f.write("out")
        
    if default_value:
        # "echo {default_value} > {path}/value"
        with open("{0}/value".format(path), 'w') as f:
            f.write(default_value)
    
# End def


def gpio_set(gpio, value):
    """Set GPIO ouptut value."""
    gpio_number = str((gpio[0] * 32) + gpio[1])
    path        = "{0}/gpio{1}".format(GPIO_BASE_PATH, gpio_number)
    
    # "echo {value} > {path}/value"
    with open("{0}/value".format(path), 'w') as f:
        f.write(value)

# End def


def gpio_get(gpio):
    """Get GPIO input value."""
    gpio_number = str((gpio[0] * 32) + gpio[1])
    path        = "{0}/gpio{1}".format(GPIO_BASE_PATH, gpio_number)
    
    # "cat {path}/value"
    with open("{0}/value".format(path), 'r') as f:
        out = f.read()
    
    return float(out)

# End def

    
def setforward(motor):
	gpio_set(motor[0],HIGH)
	gpio_set(motor[1],LOW)
	
#End def
def setbackward(motor):
	gpio_set(motor[0],LOW)
	gpio_set(motor[1],HIGH)
	
#End def

	
def move():
	gpio_set(motor1[2],HIGH)
	gpio_set(motor2[2],HIGH)
	gpio_set(motor3[2],HIGH)
	gpio_set(motor4[2],HIGH)

#End def
	
def stop():
	gpio_set(motor1[2],LOW)
	gpio_set(motor2[2],LOW)
	gpio_set(motor3[2],LOW)
	gpio_set(motor4[2],LOW)

#End def

def setleft():

	"""move the left wheels forward"""
	setforward(motor1)
	setforward(motor3)
	
	"""move the right wheels backward"""
	setbackward(motor2)
	setbackward(motor4)
	
#End def

def setright():
	"""move the left wheels backward"""
	
	setbackward(motor1)
	setbackward(motor3)
	
	"""move the right wheels forward"""
	setforward(motor2)
	setforward(motor4)

#End def


def setupcar():
	"""Setup gpio"""
	gpio_setup(motor_1_ln1, OUT, LOW)
	gpio_setup(motor_1_ln2, OUT, LOW)
	gpio_setup(motor_1_en1, OUT, LOW)

	"""motor 2"""
	gpio_setup(motor_2_ln3, OUT, LOW)
	gpio_setup(motor_2_ln4, OUT, LOW)
	gpio_setup(motor_2_en3, OUT, LOW)
	
	"""motor 3"""
	gpio_setup(motor_3_ln1, OUT, LOW)
	gpio_setup(motor_3_ln2, OUT, LOW)
	gpio_setup(motor_3_en1, OUT, LOW)
	
	"""motor 4"""
	gpio_setup(motor_4_ln3, OUT, LOW)
	gpio_setup(motor_4_ln4, OUT, LOW)
	gpio_setup(motor_4_en3, OUT, LOW)
	
	gpio_setup(ard1, IN)
	gpio_setup(ard2, IN)
	gpio_setup(ard3, IN)
	gpio_setup(ard4, IN)
	
#End def

def drive_forward(drivetime):
    setforward(motor1)
    setforward(motor2)
    setforward(motor3)
    setforward(motor4)
    move()
    time.sleep(drivetime)
    stop()
  	
#End def

def drive_backward(drivetime):
    setbackward(motor1)
    setbackward(motor2)
    setbackward(motor3)
    setbackward(motor4)
    move()
    time.sleep(drivetime)
    stop()
  	
#End def
  	
def drive_right(drivetime):
    setright()
    move()
    time.sleep(drivetime)
    stop()
#End def

def drive_left(drivetime):
    setleft()
    move()
    time.sleep(drivetime)
    stop()
#End def

# ------------------------------------------------------------------------
# Main script
# ------------------------------------------------------------------------

if __name__ == '__main__':
    setupcar()
    while (True):
        if gpio_get(ard1):
           # print("Forward")
            drive_forward(0.5)
        if gpio_get(ard2):
            #print("Backward")
            drive_backward(0.5)
        if gpio_get(ard3):
            #print("Right")
            drive_right(0.5)
        if gpio_get(ard4):
           # print("Left")
            drive_left(0.5)
    


  	
Cloud9: Config PinsPython
#!/bin/bash
# --------------------------------------------------------------------------
# Motion Detection Demo Pin Configuration
# --------------------------------------------------------------------------
# Copyright 2017-18 Octavo Systems LLC
# Redistribution and use in source and binary forms, with or without modification, 
# are permitted provided that the following conditions are met:

# 1. Redistributions of source code must retain the above copyright notice, this 
   # list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice, 
   # this list of conditions and the following disclaimer in the documentation and/or 
   # other materials provided with the distribution.
# 3. Neither the name of the copyright holder nor the names of its contributors may be
   # used to endorse or promote products derived from this software without specific 
   # prior written permission.

   # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
   # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
   # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
   # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
   # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
   # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
   # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
   # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
   # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
   # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

# 
# --------------------------------------------------------------------------
# Auto-run script
#
# Add to crontab:
#   - In code directory <code>
#     1) mkdir logs
#     2) sudo crontab -e
#     3) @reboot sh <code>/run_motion_demo.sh > <code>/logs/cronlog 2>&1
#
# Reboot the PocketBeagle to then auto-run the program
#
# --------------------------------------------------------------------------

/var/lib/cloud9/RCCar/config_pins.sh
python /var/lib/cloud9/RCCar/remotecontrolcar.py

Schematics

Fritzing Diagram
rccar_hackter_jkPG0yiYLr.fzz

Comments

Similar projects you might like

Servo Control with TV Remote Control

Project showcase by eldo85

  • 5,591 views
  • 5 comments
  • 17 respects

Turn your RC Car to Bluetooth RC car

Project tutorial by Prajjwal Nag

  • 11,971 views
  • 1 comment
  • 11 respects

Control an LED with the Remote Control

Project showcase by Nicholas_N

  • 3,194 views
  • 2 comments
  • 9 respects

Hacking A RC Car To Control It Using An Android Device

Project tutorial by MJRoBot

  • 21,012 views
  • 0 comments
  • 39 respects

Control Your Computer With A Remote Control

Project tutorial by Arduino_Scuola

  • 5,942 views
  • 1 comment
  • 8 respects
Add projectSign up / Login