James Martel
Published © GPL3+

What Do I Build Next? Some Assembly Required? Part 3 of 4

The first build is done... now the BRAINS!

IntermediateFull instructions provided6 hours912
What Do I Build Next? Some Assembly Required? Part 3 of 4

Things used in this project

Hardware components

Amazon Web Services L298N Motor Driver
×1
Adafruit Raspberry Pi Zero W
×1
Adafruit Raspberry Pi Camera Module V2
×1
Adafruit Raspberry Pi Zero Camera Cable
×1
Adafruit 16-Channel 12-bit PWM/Servo Driver - I2C interface - PCA9685
×1
Battery Holder, 18650 x 2
Battery Holder, 18650 x 2
https://www.amazon.com/SACKORANGE-Plastic-Battery-Storage-Holder/dp/B06XT1DM74/ref=sr_1_4?crid=2C5BLOQZ3GXQ7&keywords=18650+battery+holder+with+leads&qid=1554767816&s=gateway&sprefix=18650+battery+holder%2Caps%2C147&sr=8-4
×1
Amazon Web Services 18650 battery
×2
Amazon Web Services 16gb SD card
×1
Tank Vehicle-Banggood
×1
Tank Vehicle-Banggood
×1
Female/Female Jumper Wires
Female/Female Jumper Wires
Amazon
×1
Adafruit Power switch-barrel
×1
Amazon Web Services Power Switch-micro usb
×1

Software apps and online services

Raspbian
Raspberry Pi Raspbian
Latest Pixel Stretch- full

Story

Read more

Schematics

Interconnect 3-3

interconnect 3-5

Code

Osoyoo PCA9685 Driver

Python
from __future__ import division
import time
#import the PCA9685 module.
import osoyoo_PCA9685
import RPi.GPIO as GPIO
speed1 = 4095  #forward/backward speed
speed2 = 2048  #turn speed
ena = 8
enb = 13
in1 = 9
in2 = 10
in3 = 11
in4 = 12
high_speed=4000
mid_speed=3000
low_speed=1200
left_light=4
right_light=3
# Initialise the PCA9685 using the default address (0x40).
pwm = osoyoo_PCA9685.PCA9685()
# Set frequency to 60hz.
pwm.set_pwm_freq(60)
#Set motor speed. speed max is 4095,min is 0 
def set_speed(lspeed,rspeed):
    pwm.set_pwm(ena,0,lspeed)
    pwm.set_pwm(enb,0,rspeed)

#Robot car forward
def go_forward():
    set_speed(high_speed,high_speed)
    pwm.set_pwm(right_light,0,0)   #right light off
    pwm.set_pwm(left_light,0,0)   #left light off
    pwm.set_pwm(in1,0,0)      #IN1
    pwm.set_pwm(in2,0,4095)   #IN2
    
    pwm.set_pwm(in3,0,0)      #IN3
    pwm.set_pwm(in4,0,4095)   #IN4

#Robot car backwards
def go_back():
    pwm.set_pwm(right_light,0,0)   #right light off
    pwm.set_pwm(left_light,0,0)   #left light off
    pwm.set_pwm(in1,0,4095)   #IN1
    pwm.set_pwm(in2,0,0)      #IN2
    
    pwm.set_pwm(in3,0,4095)   #IN3
    pwm.set_pwm(in4,0,0)      #IN4



#Robot car turn left
def turn_left():
    set_speed(mid_speed,mid_speed)
    pwm.set_pwm(left_light,0,2400)   #left light on
    pwm.set_pwm(right_light,0,0)   #right light off
    pwm.set_pwm(in1,0,4095)   #IN1
    pwm.set_pwm(in2,0,0)      #IN2
    
    pwm.set_pwm(in3,0,0)      #IN3
    pwm.set_pwm(in4,0,4095)   #IN4

#Robot turn right
def turn_right():
    set_speed(mid_speed,mid_speed)
    pwm.set_pwm(left_light,0,0)   #left light off
    pwm.set_pwm(right_light,0,2400)   #right light on
    pwm.set_pwm(in1,0,0)      #IN1
    pwm.set_pwm(in2,0,4095)   #IN2
    
    pwm.set_pwm(in3,0,4095)   #IN3
    pwm.set_pwm(in4,0,0)      #IN4

#Robot stop move
def stop():
    set_speed(0,0)

def test():
    #forward-->2s
    go_forward()
    time.sleep(2)
    #backward-->2s
    go_back()
    time.sleep(2)
    #turn left-->2s
    turn_left()
    time.sleep(2)
    #turn right-->2s
    turn_right()
    time.sleep(2)
    #stop
    stop()
    
#Reset PCA9685's all channels    
def destroy():
    pwm.set_all_pwm(0,0)
if __name__ == '__main__':
    try:
	#forward-->backward-->turn left-->turn right-->stop
        test()
    except KeyboardInterrupt:
	#robot car stop
        destroy()

Osoyoo PCA9685 Python Driver

Python
from __future__ import division
import logging
import time
import math


# Registers/etc:
PCA9685_ADDRESS    = 0x40
MODE1              = 0x00
MODE2              = 0x01
SUBADR1            = 0x02
SUBADR2            = 0x03
SUBADR3            = 0x04
PRESCALE           = 0xFE
LED0_ON_L          = 0x06
LED0_ON_H          = 0x07
LED0_OFF_L         = 0x08
LED0_OFF_H         = 0x09
ALL_LED_ON_L       = 0xFA
ALL_LED_ON_H       = 0xFB
ALL_LED_OFF_L      = 0xFC
ALL_LED_OFF_H      = 0xFD

# Bits:
RESTART            = 0x80
SLEEP              = 0x10
ALLCALL            = 0x01
INVRT              = 0x10
OUTDRV             = 0x04


logger = logging.getLogger(__name__)

def software_reset(i2c=None, **kwargs):
    """Sends a software reset (SWRST) command to all servo drivers on the bus."""
    # Setup I2C interface for device 0x00 to talk to all of them.
    self._device = i2c.get_i2c_device(0x00, **kwargs)
    self._device.writeRaw8(0x06)  # SWRST

class PCA9685(object):
    """PCA9685 PWM LED/servo controller."""

    def __init__(self, address=PCA9685_ADDRESS, i2c=None, **kwargs):
        """Initialize the PCA9685."""
        # Setup I2C interface for the device.
        if i2c is None:
            import Adafruit_GPIO.I2C as I2C
            i2c = I2C
        self._device = i2c.get_i2c_device(address, **kwargs)
        self.set_all_pwm(0, 0)
        self._device.write8(MODE2, OUTDRV)
        self._device.write8(MODE1, ALLCALL)
        time.sleep(0.005)  # wait for oscillator
        mode1 = self._device.readU8(MODE1)
        mode1 = mode1 & ~SLEEP  # wake up (reset sleep)
        self._device.write8(MODE1, mode1)
        time.sleep(0.005)  # wait for oscillator

    def set_pwm_freq(self, freq_hz):
        """Set the PWM frequency to the provided value in hertz."""
        prescaleval = 25000000.0    # 25MHz
        prescaleval /= 4096.0       # 12-bit
        prescaleval /= float(freq_hz)
        prescaleval -= 1.0
        logger.debug('Setting PWM frequency to {0} Hz'.format(freq_hz))
        logger.debug('Estimated pre-scale: {0}'.format(prescaleval))
        prescale = int(math.floor(prescaleval + 0.5))
        logger.debug('Final pre-scale: {0}'.format(prescale))
        oldmode = self._device.readU8(MODE1);
        newmode = (oldmode & 0x7F) | 0x10    # sleep
        self._device.write8(MODE1, newmode)  # go to sleep
        self._device.write8(PRESCALE, prescale)
        self._device.write8(MODE1, oldmode)
        time.sleep(0.005)
        self._device.write8(MODE1, oldmode | 0x80)

    def set_pwm(self, channel, on, off):
        """Sets a single PWM channel."""
        self._device.write8(LED0_ON_L+4*channel, on & 0xFF)
        self._device.write8(LED0_ON_H+4*channel, on >> 8)
        self._device.write8(LED0_OFF_L+4*channel, off & 0xFF)
        self._device.write8(LED0_OFF_H+4*channel, off >> 8)

    def set_all_pwm(self, on, off):
        """Sets all PWM channels."""
        self._device.write8(ALL_LED_ON_L, on & 0xFF)
        self._device.write8(ALL_LED_ON_H, on >> 8)
        self._device.write8(ALL_LED_OFF_L, off & 0xFF)
        self._device.write8(ALL_LED_OFF_H, off >> 8)

osoyoo PCA9685 C

Python
No preview (download only).

Credits

James Martel

James Martel

47 projects • 59 followers
Self taught Robotics platform developer with electronics background

Comments