Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Buggy: better obstacle avoiding robot
/*******************************************************************************
* Pin definitions for Clicker 2 for PIC18FJ
*******************************************************************************/
// LEDs
sbit LED1 at LATD4_bit;
sbit LED2 at LATE4_bit;
sbit LED1_Direction at TRISD4_bit;
sbit LED2_Direction at TRISE4_bit;
//Switches
sbit SW1 at RD7_bit;
sbit SW2 at RH3_bit;
sbit SW1_Direction at TRISD7_bit;
sbit SW2_Direction at TRISH3_bit;
// =============================================================================
/*******************************************************************************
* Pin and function definitions for BUGGY
*******************************************************************************/
// =============================================================================
// Pin definitions for LEDS on the BUGGY
sbit Brakelights at LATJ6_bit;
sbit Headlights at LATB5_bit;
sbit SignalL at LATF5_bit;
sbit SignalR at LATJ4_bit;
sbit MainBeam at LATJ3_bit;
sbit Brake_Direction at TRISJ6_bit;
sbit Headlights_Direction at TRISB5_bit;
sbit SignalL_Direction at TRISF5_bit;
sbit SignalR_Direction at TRISJ4_bit;
sbit MainBeam_direction at TRISJ3_bit;
// =============================================================================
// BUGGY Functions
unsigned int SPEED_L;
unsigned int SPEED_R;
void Init_Buggy() {
// INIT LIGHTS
Brake_Direction = 0; //brake lights
Headlights_Direction = 0; // headlights
MainBeam_direction = 0; // main beam
SignalL_Direction = 0; // Headlights
SignalR_Direction = 0; // headlights
//PWM
SPEED_L = 0;
SPEED_R = 0;
PWM1_Init(5000);
PWM2_Init(5000); //PWM_PERIOD;
PWM5_Init(5000);
PWM3_Init(5000);
PWM1_Start(); // start PWM1
PWM2_Start(); // start PWM2
PWM3_Start(); // start PWM3
PWM5_Start(); // start PWM5
PWM1_Set_Duty(0);
PWM2_Set_Duty(0);
PWM5_Set_Duty(0);
PWM3_Set_Duty(0);
}
void Break_Buggy() {
SPEED_L = 0;
SPEED_R = 0;
PWM1_Start(); // start PWM1
PWM2_Start(); // start PWM2
PWM3_Start(); // start PWM3
PWM5_Start(); // start PWM5
PWM1_Set_Duty(0);
PWM2_Set_Duty(0);
PWM5_Set_Duty(0);
PWM3_Set_Duty(0);
}
void Drive_Buggy(unsigned int speed) {
// LEFT MOTORS
PWM1_Set_Duty(speed);
PWM2_Set_Duty(0);
// RIGHT MOTORS
PWM3_Set_Duty(speed);
PWM5_Set_Duty(0);
}
void Back_Buggy(unsigned int speed) {
PWM1_Set_Duty(0);
PWM2_Set_Duty(speed);
PWM3_Set_Duty(0);
PWM5_Set_Duty(speed);
}
void Turn_Buggy(unsigned int speed) {
PWM1_Set_Duty(0);
PWM2_Set_Duty(speed);
PWM3_Set_Duty(speed);
PWM5_Set_Duty(0);
}
/*
* Project name:
Obstacle avoiding rover: main code
* Project page https://electronza.com/buggy-better-obstacle-avoiding-robot/
* Description:
Main code for the obstacle aviding rover
* Test configuration:
MCU: PIC18F87J50
http://ww1.microchip.com/downloads/en/DeviceDoc/39775c.pdf
dev.board: Mikroe Buggy w/ Clicker2 for PIC18FJ
http://www.mikroe.com/buggy/
http://www.mikroe.com/pic/clicker-2-pic18fj/
Oscillator: HS-PLL 48.0000 MHz, 8.0000 MHz Crystal
Ext. Modules: IR Distance Click (placed in front mikroBUS sockets)
http://www.mikroe.com/click/ir-distance/
SW: mikroC PRO for PIC
http://www.mikroe.com/mikroc/pic/
*/
#include "BUGGY_PIC18_FUNCTIONS.c"
/*******************************************************************************
* Globals
*******************************************************************************/
unsigned int i;
unsigned int elapsed;
unsigned int distance;
const thresh_slow = 160;
const thresh_brake = 220;
const thresh_back = 400;
unsigned int SPEED;
//==============================================================================
void main() {
// Configure pins
TRISA2_bit = 1; // Pin RA2 is input
ANCON0 = 0x9B; // Set pin RA2 as analog input
// Initialize internal ADC module to work with RC clock.
ADC_Init(); // Initialize ADC module with default settings
LED1_Direction = 0; // Set direction for LEDs
LED2_Direction = 0;
// BUGGY SELF-TEST
// Flash the LEDS on Clicker 2 for PIC18FJ
LED1 = 1;
LED2 = 1;
Delay_ms(1000);
LED1 = 0;
LED2 = 0;
Delay_ms(500);
Init_Buggy();
Break_Buggy();
elapsed = 0;
while(1){
// Normal run
// Only headlights are on
Brakelights = 0;
Headlights = 1;
SignalL = 0;
SignalR = 0;
LED1 = 0;
LED2 = 0;
distance = ADC_Read(2);
// OBSTACLE DETECTED. APPLY BRAKES
if (distance < thresh_slow){
speed = 250;
Drive_Buggy(speed);
Brakelights = 0;
Delay_ms(50);
}
// Slow down
if ((distance >= thresh_slow) & (distance < thresh_brake)) {
speed = 125;
Drive_Buggy(speed);
Brakelights = 0;
Delay_ms(50);
}
// brake
if ((distance >= thresh_brake) & (distance < thresh_back)){
// we brake over 5 seconds; if we stop before reaching the turn back treshold
// we automatically turn back
if (elapsed <50){
LED1 = 1;
LED2 = 1;
Break_Buggy();
Brakelights = 1;
Delay_ms(50);
elapsed++;
}
if (elapsed = 50){ // elapsed waiting time, go back
LED1 = 0;
LED2 = 0;
Brakelights = 0;
speed = 200;
Back_Buggy(speed);
// go back
for (i = 0; i < 3; i++){
SignalL = 1;
SignalR = 1;
Delay_ms(500);
SignalL = 0;
SignalR = 0;
Delay_ms(500);
}
// now turn around
SignalL = 0;
speed = 200;
Turn_Buggy(speed);
for (i = 0; i < 2; i++){
SignalR = 1;
Delay_ms(600);
SignalR = 0;
Delay_ms(600);
}
elapsed = 0;
}
}
// TOO CLOSE. TURN BACK
if (distance >= thresh_back){
// slowly go back for 3 seconds while flashing all lights
Brakelights = 0;
speed = 200;
Back_Buggy(speed);
// go back
for (i = 0; i < 3; i++){
SignalL = 1;
SignalR = 1;
Delay_ms(500);
SignalL = 0;
SignalR = 0;
Delay_ms(500);
}
// now turn around
SignalL = 0;
speed = 200;
Turn_Buggy(speed);
for (i = 0; i < 2; i++){
SignalR = 1;
Delay_ms(600);
SignalR = 0;
Delay_ms(600);
}
}
}
}
/*
* Project name:
Obstacle avoiding rover: Send distances to UART code
- use this to establish the thresholds for slowing down and braking -
* Project page https://electronza.com/buggy-better-obstacle-avoiding-robot/
* Description:
This code reads the A2 A/D channel and sends the result to the PC via USB-UART
* Test configuration:
MCU: PIC18F87J50
http://ww1.microchip.com/downloads/en/DeviceDoc/39775c.pdf
dev.board: Mikroe Buggy w/ Clicker2 for PIC18FJ
http://www.mikroe.com/buggy/
http://www.mikroe.com/pic/clicker-2-pic18fj/
Oscillator: HS-PLL 48.0000 MHz, 8.0000 MHz Crystal
Ext. Modules: IR Distance Click (placed in front mikroBUS sockets)
http://www.mikroe.com/click/ir-distance/
USB UART click (placed in mikroBUS socket #2 on clicker2)
http://www.mikroe.com/click/usb-uart/
SW: mikroC PRO for PIC
http://www.mikroe.com/mikroc/pic/
*/
char ux_dist[9];
int distance;
void main() {
// On the Buggy click socket #1 uses pin RA2 for analog input
// RA2 corresponds to analog input channel AN2
// Configure pins
TRISA2_bit = 1; // Pin RA2 is input
ANCON0 = 0x9B; // Set pin RA2 as analog input
// Initialize internal ADC module to work with RC clock.
ADC_Init(); // Initialize ADC module with default settings
// If the USB-UART click is installed in mikroBUS socket #2 of the Clicker2
// then is using UART1 (pins RC6 = TX1 and RC7 = RX1)
UART1_Init(9600); // Initialize UART module at 9600 bps
Delay_ms(500); // Wait for UART module to stabilize
UART1_Write_Text("Start");
UART1_Write(13);
UART1_Write(10);
Delay_ms(1000);
while (1) { // Endless loop
// here we measure the distances from the IR distance click sensor
// and we send the result to UART
distance = ADC_Read(2);
UART1_Write_Text("Distance: ");
IntToStr(distance, ux_dist);
UART1_Write_Text(ux_dist);
UART1_Write(13);
UART1_Write(10);
Delay_ms(1000);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment