Ticker

6/recent/ticker-posts

Microchip Xpress board: Obstacle avoiding robot with XC8 code

 


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
The breadboard robot with Xpress Demo board installed

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!

Post a Comment

0 Comments