Mbot Joy  4409c53 (Mon Feb 4 17:15:40 2019 -0500)
Macros | Typedefs | Enumerations | Functions
/home/travis/build/larsks/avr-mbot-joy/mbot-joy.c File Reference

Control your mbot with a joystick. More...

#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

Macros

#define MAX_SPEED   200
 Normal forward speed.
 
#define MED_SPEED   127
 Slow speed when approaching an obstacle.
 
#define STOP_DISTANCE   150
 Stop when <= this distance from an obstacle.
 
#define SLOW_DISTANCE   500
 Slow down when <= this distance from an obstacle.
 
#define LEDDDR   (DDRB)
 DDR register for LED pin.
 
#define LEDPORTREG   (PORTB)
 PORT register for LED pin.
 
#define LEDPINREG   (PINB)
 PIN register for LED pin.
 
#define LEDPIN   (_BV(PORTB5))
 LED pin number.
 
#define USDDR   (DDRC)
 DDR register for ultrasonic sensor.
 
#define USPORTREG   (PORTC)
 PORT register for ultrasonic sensor.
 
#define USPINREG   (PINC)
 PIN register for ultrasonic sensor.
 
#define USPIN   (_BV(PORTC1))
 Data pin for ultrasonic sensor.
 
#define MOTORDDR   (DDRD)
 DDR register for motors.
 
#define MOTORPORT   (PORTD)
 PORT register for motors.
 
#define MLEFTDIR   (_BV(PORTD4))
 Left motor direction pin.
 
#define MLEFTPWM   (_BV(PORTD5))
 Left motor speed control.
 
#define MRIGHTDIR   (_BV(PORTD7))
 Right motor direction pin.
 
#define MRIGHTPWM   (_BV(PORTD6))
 Right motor speed control.
 
#define MLEFTOCR   (OCR0A)
 Left motor OCR register.
 
#define MRIGHTOCR   (OCR0B)
 Right motor OCR register.
 
#define JOYDDR   (DDRB)
 DDR register for joystick.
 
#define JOYPORT   (PORTB)
 PORT register for joystick.
 
#define JOYPIN   (PINB)
 PIN register for joystick.
 
#define PIN_LEFT   (_BV(PORTB1))
 Joystick left pin.
 
#define PIN_RIGHT   (_BV(PORTB2))
 Joystick right pin.
 
#define PIN_DOWN   (_BV(PORTB3))
 Joystick down (reverse) pin.
 
#define PIN_UP   (_BV(PORTB4))
 Joystick up (forward) pin.
 

Typedefs

typedef enum DIRECTION DIRECTION
 Describe motor direction.
 
typedef enum TURN TURN
 Describe current turning state.
 
typedef enum DISTANCE_STATE DISTANCE_STATE
 States in ultrasonic measurement state machine.
 

Enumerations

enum  DIRECTION { STOPPED, FORWARD, REVERSE }
 Describe motor direction. More...
 
enum  TURN { NONE, LEFT, RIGHT }
 Describe current turning state. More...
 
enum  DISTANCE_STATE { PING, WAIT_PULSE_START, WAIT_PULSE_END, INTERVAL }
 States in ultrasonic measurement state machine.
 

Functions

void setup ()
 Configure pins and pwm. More...
 
uint8_t measure_distance (uint16_t *distance)
 Handle distance measurements with the ultrasonic sensor. More...
 
int main ()
 

Detailed Description

Control your mbot with a joystick.

Connect a standard 5-pin arcade joystick to your mbot (pins GND, 9, 10, 11, 12) and control its movements. This code makes use of the ultrasonic sensor to avoid bumping into obstacles.

Enumeration Type Documentation

enum DIRECTION

Describe motor direction.

Enumerator
STOPPED 

mbot is stopped

FORWARD 

mbot is moving forward

REVERSE 

mbot is moving in reverse

enum TURN

Describe current turning state.

Enumerator
NONE 

mbot is not turning

LEFT 

mbot is turning left

RIGHT 

mbot is turning right

Function Documentation

int main ( )

handle obstacle detection

We call measure_distance every loop iteration. When there is a valid measurement available:

  • If the distance is less than or equal to STOP_DISTANCE, stop the mbot and set the obstacle flag.
  • If the distance is less than or equal to SLOW_DISTANCE, reduce mbot speed to MED_SPEED and clear the obstacle flag.
  • Otherwise, set speed to MAX_SPEED and clear the obstacle flag.

If the obstacle flag is set, turn on the built-in LED.

handle joystick

Set dir and turn based on the current joystick inputs.

Override dir to STOPPED if the obstacle flag is set.

control motors

If mbot state is STOPPED, set motor speed to 0. Otherwise, set motor speed and direction based on the current value of dir.

Next, handle turns. If the mbot is in motion, we want both motors to continue to run in the same direction, so reduce the speed on the turning side by 1/2. If the mbot is stopped, run the turning side motor in reverse and the opposite side forward.

Apply current l_speed and r_speed values to OCR* registers.

uint8_t measure_distance ( uint16_t *  distance)

Handle distance measurements with the ultrasonic sensor.

The ultrasonic sensor on the mbot is a three-pin sensor: GND, 5V, and a data pin that is used as both an input and an output. We send a 10us high pulse to the sensor to trigger a measurement. The sensor then sends out a series of ultrasonic pulses, and then reports the measurement by bringing the data line high. The duration of the high pulse corresponds to the distance.

In order to time the high pulse, we simply count loop iterations. This means that as you make changes to the code, you may need to adjust the STOP_DISTANCE and SLOW_DISTANCE settings.

void setup ( )

Configure pins and pwm.

Set up fast PWM mode with OCR output enabled on for the motor speed control pins, OC0A (PORTD6) and OC0B (PORTD5). The motor PWM frequency is 967Hz. At 16Mhz with a prescaler of clk/64, this gets us 976.5625Hz, which is apparenlty "close enough" (that's 16000000 / 64 / 255, where the final /255 is because we are using 8-bit timers). Setting OCR0A and OCR0B controls the duty cycle of the PWM output.

We need to use TIMER0 for PWM output, since this is connected to OC0A and OC0B, which are in turn connected to the motor pins.

Select clk/64 prescaler (CS = 0b011)

Configure motor pins as outputs.

An arcade joystick has a five-pin connection (ground and one pin for each direction). When you move the joystick in a given direction, it connects the appopriate pin to ground. This means we need to enable the internall pull-ups on the joystick pins.