James Martel
Published © GPL3+

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

The Second Build is Done..Now for the BRAINS

IntermediateFull instructions provided6 hours1,144
What Do I Build Next? Some Assembly Required? Part 4 of 4

Things used in this project

Hardware components

Raspberry Pi 3 Model B+
Raspberry Pi 3 Model B+
I purchased a Model 3A+
×1
12 Wheeled Robot Tank Chassis
×1
PCA9685 Generic
×1
Amazon Web Services L298N Motor Controller- Generic
×1
12 vdc battery 4800maH- Linksprite
×1
Battery Holder, 18650 x 2
Battery Holder, 18650 x 2
×1
Amazon Web Services 18650 battery
×2
Amazon Web Services Male-Female power plug connectors
×1
Amazon Web Services 16 gb SD card-Generic
×1
Camera Module
Raspberry Pi Camera Module
×1
Ultrasonic Sensor - HC-SR04 (Generic)
Ultrasonic Sensor - HC-SR04 (Generic)
×1
Amazon Web Services HC-SR04 mounting bracket
×1
Standoff, nylon-Adafruit
×1

Software apps and online services

Raspbian
Raspberry Pi Raspbian
WEBIOPI-Osoyoo customized
WebStreamer-Osoyoo Customized
Robot Tank Controller-Osoyoo customized
Adafruit PCA9685 I2C PWM Module

Story

Read more

Schematics

Interconnect 3-3

interconnect 3-5

Code

http://osoyoo.com/driver/motor-test-tank.tar.gz

Python
Demo L298N/PCA9685 Motor code
No preview (download only).

Osoyoo PCA9685 Python Code

Python
Testing Initial software
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 Driver

Python
keep in same folder
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)

PCA9685 Osoyoo C

Python
PCA9685 Python
No preview (download only).

Credits

James Martel

James Martel

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

Comments