All the projects I made until now using the Microchip Xpress Demo board were stationary projects. Those were projects in which the Xpress board was connected to the PC via USB cable, with one MikroElektronika click board performing various functions. But it doesn’t have to be this way. One can use the Xpress Evaluation board in more creative ways…
Today I will show you how to use the Xpress board to make an obstacle avoiding robot, using one breadboard as robot chassis, and components that are available worldwide. As such, it should be easy for anybody to replicate this project.
The hardware
This robot uses a more exotic approach: a WB-104-3 breadboard is used as chassis, with motors, trailing ball, batteries and a click board socket being fixed right on the breadboard base. The breadboard itself is 220 x 120 x 31 mm, with a 1.2 mm aluminum plate base and it weighs about 0.4 kg. Breadboard area comprises one distribution strip with 100 distribution holes and two terminal strips, with a total of 1280 terminal holes.
As the breadboard is quite heavy, I needed some motors that are able to develop enough torque to set the whole thing in motion. My choice went to Pololu micro-motors, for their small footprint and the ease of fixing them to the breadboard. Having a matching trailing ball in my parts inventory also contributed to this choice.
Pololu micromotors
Pololu manufactures a huge range of micro-motors, all with the same size of 10 × 12 x 26 mm. The wheel shaft adds an extra 9 mm to the 26 mm length. There is also a version with a longer 14mm shaft, which allows the use of an encoder.
Several motors are available:
- 12V HPCB (High Power Carbon Brushes), with a stall current of 600mA
- 6V HP (High Power) with 1600mA stall current
- 6V HPCB with 1600mA stall current
- 6V MP (Medium power), with 700mA stall current
- 6V LP (Low power), with 360mA stall current
Stalling the motors should be avoided as this can damage both the motor and the gearbox. Pololu’s general recommendation for brushed DC motor operation is 25% or less of the stall current.
Each of the above motors can be matched with one of the eleven gearboxes, with gear ratios ranging from 1:5 to 1:1000. A low gear ratio means higher speed, but lower torque. Higher gear ratios sacrifice speed to gain higher torque values.
The breadboard I used in this project is quite heavy, and I also had to consider the weight of added components, batteries and stuff. As such I have chosen one 6V HP motor with a 1:250 gearbox. The item number from Pololu is 995. The maximum stall current of this motor is 1600mA, the no-load speed is 120 RPM, and the stall torque is approximately 0.4Nm.
The motors were fixed to the breadboard using a pair of Pololu Micro Metal Gearmotor Brackets in black color, having the Pololu item# 989. Wheels are also from Pololu, they are 32×7 mm in size, with item# 1087 for the black version. To run the cables I drilled two 5mm holes, in which I’ve put FIX-GR-15 rubber grommets.
The breadboard robot uses Pololu HP micromotor |
The breadboard robot motor detail |
Considering the max RPM and the wheel size we can compute the maximum speed in cm/s:
The wheel circumference is: C = π · wheeldiameter = π · 3.2 = 10.05 cm
In a minute the robot can go for a distance: D = maxRPM · C = 120 · 10.05 = 1206 cm
This corresponds to a theoretical no-load speed of about 20 cm/s. In practice, due to the weight of the robot, it will move much slower, I think somewhere less than half of this. I also noticed that due to the high gear ratio the motor is unlikely to stall. On most surfaces the wheels will lose traction and will begin to spin freely rather than having the motors stop.
Motor drivers
Now that we have the motors, we have to choose the motor driver. The motor driver should meet a number of constraints:
- it has to handle the stall current of the motors, so it won’t get damaged if motor stalls
- it has to work with 6V power, as I will use four AAA batteries to power my robot
- as the PIC16F18855 has only two PWM pins, the motor driver must be able to work with those
- it must fit onto the breadboard
My driver of choice is DVR8835 from Texas Instruments, a motor drivers containing two full-bridges, with a maximum peak current of 1.5A. It also embeds a lot of protection circuits, so it’s extremely hard to damage. As for the voltage, it can work between 2 and 11V, more than enough for my robot implementation. This particular motor driver has two user selectable working modes, one of the working modes requiring one PWM line and one direction pin per bridge – so it matches the PIC16F18855 capabilities. To fit on the breadboard I used a Pololu 2135 dual motor driver carrier, which is a breadboard-compatible breakout board for the DRV8835.
Pololu 2135 - DRV8835 Dual Motor Driver Carrier |
The Vcc pin must be connected to the logic voltage, in our case this being 3.3V provided by the regulator onboard the DM164140 Xpress board. Vin is connected to the battery voltage. To run this motor with only two PWM lines the MODE pin must be held high, connected to Vcc.
The left motor is connected to channel A (pins O2 and O1). To drive this motor PWM should be applied to pin (A) IN2-EN, direction being set by pin (A) IN1-PH.
The right motor is connected to channel B (pins O2 and O1). To drive this motor PWM should be applied to pin (B) IN2-EN, direction being set by pin (B) IN1-PH.
Trailing wheel
The robot runs in a trailing wheel configuration, with motors being fixed on about 1/3 of the whole length, and a ball caster in the rear. The ball caster is Pololu item# 953.
This is a decent compromise between maneuverability and the number of parts used in the driving train. Obviously, different motor configurations can be used, and it’s fun to observe how motor placement affects the overall performance.
The breadboard robot: trailing end ball caster |
Front click socket
As I plan to use the same IR distance click featured in the Buggy obstacle avoiding project, I need one front click socket. For this I made one click adapter from one Proto click, which I have fixed onto the breadboard base using a pair of PMB-1 mounting couplers. I’ve installed header sockets on both sides of the Proto click, so it acts like an adapter. The only thing to consider is that the Proto click is facing down, so take care when wiring your project.
The breadboard robot: universal rover platform, with front mikroBUS socket |
Batteries
I used one battery holder for 4 AAA batteries, mounted underneath the breadboard with double-sided tape. As it is, it allows for enough ground clearance so this robot will run fine on flat surfaces.
The breadboard robot, with front mikroBUS socket and battery holder |
Xpress board
To install the Xpress board onto the breadboard I first soldered header pins underneath the Xpress board. For easy access to the pins I also installed some jumper wires, as in the pictures below:
The breadboard robot: preparing the XPRESS board |
A screw terminal was also installed on the Xpress board power header, so I can power it from the breadboard. The Xpress board has only a power regulator for the 3.3 voltage. If powered this way the battery power will also be present on the 5V pin in the click socket, so don’t use click boards that require 5V.
Wiring the robot
We come here to the final stage, wiring the robot. First we connect the motor drivers and the power for the Xpress board, as shown below. Channel A uses pin RC2 for PWM and RC7 for direction, while channel B uses pin RC4 for PWM and RC5 for direction.
Wiring the motor driver: power and mode |
Connecting the battery |
Motor driver: connecting motors |
Motor driver: control pins |
Then we connect the IR distance click. For this we need only three wires: Vcc, GND and the AN analog output is wired to pin RB0, same as if it was installed directly on the Xpress board.
Wiring the IR distance click |
Connecting the distance sensor |
With this the hardware side is complete and we can start writing the code.
XC8 code for the obstacle avoiding robot
The code for the robot is written using MPLAB Xpress IDE and XC8 compiler, with the PIC16F18855 being configured using Microchip Code Configurator. Then, the main code relies on functions generated by MCC.
The following configuration settings were done using Microchip Code Configurator:
- Clock source HFINTOSC, clock frequency 4MHz, clock divider set to 1. This leads to a main clock frequency of 4MHZ.
- Timer4 is used for PWM6, Timer6 is used for PWM7. Note that these two timers are identical, so we make the same settings for both timers
- Timer settings:
- Clock source FOSC/4
- Prescaler 1:1
- Postscaler 1:1
- Period 1:250 us
- Ext reset source T4CKIPPS pin
- PWM settings
- PWM duty 0%
- PWM polarity: active high
- PWM resolution is 9 bits given the current main clock / timer settings
- A/D convertor is set to operate in basic mode
- Clock source is FRC
- Alignment right
- Positive reference Vdd
- Negative reference Vss
- “Enable continuous operation” is unchecked
- Pin module
- PIN RB0 is set as ANx (analog input)
- Pins RC5 and RC7 are set as outputs (they will control the direction of the motors)
- Pins RC2 and RC4 are set as PWM
Below there are some screen captures from MCC:
Clock settings |
PWM settings |
Timer settings |
ADC settings |
Pin settings |
Please observe that PWM resolution is 9 bits, so valid settings for the duty cycle are between 0x00 and 0x01FF.
The code
Main code is as follows:
/**
Generated Main Source File
Company:
Microchip Technology Inc.
File Name:
main.c
Summary:
This is the main file generated using MPLAB(c) Code Configurator
Description:
This header file provides implementations for driver APIs for all modules selected in the GUI.
Generation Information :
Product Revision : MPLAB(c) Code Configurator - 3.15.0
Device : PIC16F18855
Driver Version : 2.00
The generated drivers are tested against the following:
Compiler : XC8 1.35
MPLAB : MPLAB X 3.20
*/
/*
(c) 2016 Microchip Technology Inc. and its subsidiaries. You may use this
software and any derivatives exclusively with Microchip products.
THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER
EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A
PARTICULAR PURPOSE, OR ITS INTERACTION WITH MICROCHIP PRODUCTS, COMBINATION
WITH ANY OTHER PRODUCTS, OR USE IN ANY APPLICATION.
IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE,
INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND
WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS
BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE
FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN
ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
MICROCHIP PROVIDES THIS SOFTWARE CONDITIONALLY UPON YOUR ACCEPTANCE OF THESE
TERMS.
*/
#include "mcc_generated_files/mcc.h"
/*
Main application
*/
uint16_t distance;
uint16_t too_close = 350;
void main(void)
{
// initialize the device
SYSTEM_Initialize();
// When using interrupts, you need to set the Global and Peripheral Interrupt Enable bits
// Use the following macros to:
// Enable the Global Interrupts
//INTERRUPT_GlobalInterruptEnable();
// Enable the Peripheral Interrupts
//INTERRUPT_PeripheralInterruptEnable();
// Disable the Global Interrupts
//INTERRUPT_GlobalInterruptDisable();
// Disable the Peripheral Interrupts
//INTERRUPT_PeripheralInterruptDisable();
// Set direction to forward
PIN_MANAGER_Initialize ();
IO_RC5_SetHigh();
IO_RC7_SetHigh();
// Initialize ADC, conversion by request
ADCC_Initialize();
ADCC_DisableContinuousConversion();
// Initialize PWMs and set them to 0
PWM6_Initialize();
PWM6_LoadDutyValue(0x00);
PWM6_Initialize();
PWM6_LoadDutyValue(0x00);
// Start forward
// PWM is 9 bits resolution
PWM6_LoadDutyValue(0x01FF);
PWM7_LoadDutyValue(0x01FF);
while (1)
{
// Add your application code
// Read ADC value, RB0 is channel ANB0
distance = ADCC_GetSingleConversion(channel_ANB0);
if ( distance > too_close ){
// stop
PWM6_LoadDutyValue(0x00);
PWM7_LoadDutyValue(0x00);
// wait a bit
__delay_ms(500);
// turn back
IO_RC5_SetLow();
IO_RC7_SetLow();
PWM6_LoadDutyValue(0x01FF);
PWM7_LoadDutyValue(0x01FF);
// run backwards fro some time
__delay_ms(5000);
// stop
PWM6_LoadDutyValue(0x00);
PWM7_LoadDutyValue(0x00);
// wait a bit
__delay_ms(500);
// Turn slowly
IO_RC5_SetHigh();
IO_RC7_SetLow();
PWM6_LoadDutyValue(0x00FF);
PWM7_LoadDutyValue(0x00FF);
// The delay controls how much we turn
__delay_ms(2000);
// stop
PWM6_LoadDutyValue(0x00);
PWM7_LoadDutyValue(0x00);
// wait a bit
__delay_ms(500);
// resume going forward
IO_RC5_SetHigh();
IO_RC7_SetHigh();
PWM6_LoadDutyValue(0x01FF);
PWM7_LoadDutyValue(0x01FF);
}
}
}
/**
End of File
*/
Note: if the robot first moves backwards you just have to reverse the output pins on the DRV8835.
And.. action!
0 Comments