C LineFollowing

Explanation

This listing shows the code for a program that makes the O.A.R. robot follow a black line. The robot uses the O.A.R. Sensors Board and the Arduino board.

#define LMB0        16    // This is time high for Left Motor moving Backwards
#define LMB1        74    // This is time low for Left Motor moving Backwards
#define RMB0        74
#define RMB1        16
#define LMF0        74
#define LMF1        16
#define RMF0        16
#define RMF1        74
#define INVERTPORTD     PORTD = ~PORTD;
#define INVPD0        PORTD = (~PORTD & 0x01) | (PORTD & 0xfe);   // Invert port D pin 0
#define INVPC0        PORTD = (~PORTD & 0x01) | (PORTD & 0xfe);
#define INVPC1        PORTD = (~PORTD & 0x02) | (PORTD & 0xfd);
#define INVPD7        PORTD = (~PORTD & 0x80) | (PORTD & 0x7f);
#define INVPD6        PORTD = (~PORTD & 0x40) | (PORTD & 0xbf);
 
#include <avr/io.h>
#include <avr/interrupt.h>
#include <inttypes.h>
#include <avr/pgmspace.h>
 
uint8_t timeout;
uint8_t tone;
uint8_t ticks;
uint8_t dirhl;
uint8_t dirll;
uint8_t dirhr;
uint8_t dirlr;
 
void delay_ms(void){
    int i;
    for(i=880u; i != 0; i--);
}
 
void delay(uint8_t tms){
    uint8_t    i;
    for(i = tms; i != 0; i--){
        delay_ms();
    }
}
 
ISR(TIMER1_COMPA_vect){
    static uint8_t tck = 0;
    static uint8_t tck2 = 0;
    static uint8_t turn = 0;
    static uint8_t turn2 = 0;
    //static uint8_t ticks = 0;
    //static uint16_t sec = 0;
 
    cli();
    //the following code works as a multiplexer
    if (turn == 0){            //time high            
        if(tck == dirhl){
            tck = 0;
            turn = 1;
            INVPC0;
            INVPD7;
        }
        else{
            tck++;        // increment the count
        }
        if(tck2 == dirhr){
            tck2 = 0;
            turn2 = 1;
            INVPC1;
            INVPD6;
        }
        else{
            tck2++;        // increment the count
        }
 
    }        
    else if(turn == 1){        //time low    
        if(tck == dirll){
            tck = 0;
            INVPC0;
            INVPD7;
            turn = 0;
        }
        else{
            tck++;
        }
        if(tck2 == dirlr){
            tck2 = 0;
            INVPC1;
            INVPD6;
            turn2 = 0;
        }
        else{
            tck2++;
        }
 
    } 
    else{
        turn2 = 0;
        tck2 = 0;
        turn = 0;
        tck = 0;    // avoid overflow if error
    }
 
    sei();
}
 
ISR(TIMER0_OVF_vect){
    cli();
 
    if (ticks == 11){
        tone = ~tone;
        //tone++;
        //tone = tone % 2;    // tone will go from 0 to 3
    }
    else{
        ticks++;
    }
    sei();
}
 
void iniconf(void){
    cli();            // Disable interrupts
 
    /* Program timer0    */
    TCNT0 = 0x00;        // Reset timer count
    TCCR0A |= 0x00;        // Normal functioning, clk_io/1024
    TCCR0B |= 0x05;
    TIMSK0 |= _BV(TOIE0);    // Enable interrupts when overflow
 
    /* Program timer1    */
    TCNT1H = 0x00;        // Reset timer count
    TCNT1L = 0x00;
    OCR1AH = 0x01;        // Set output compare value
    OCR1AL = 0xFF;
    TCCR1A |= 0x00;        // Normal functioning, clk_io
    TCCR1B |= 0x09;
    TIMSK1 |= _BV(OCIE1A);    // Enable interrupts when overflow
 
    sei();            // Enable interrupts
 
    /* Program the ports    */
    DDRD = 0xf0;
    DDRC = 0x03;
}
 
int main(void){
    /* Initialize the system    */
    iniconf();
 
    /* Initialize goblal variables    */
    tone = 0;
    ticks = 0;
 
    while(1){
 
        //delay(0);
        //Check sensor
        if( (PIND & 0x03) == 0x00 ){
            //If both black, movr forward
            dirhl = LMF0;
            dirll = LMF1;
            dirhr = RMF0;
            dirlr = RMF1;
        }
        else if( (PIND & 0x03) == 0x02 ){
            //if left white; turn right
            dirhl = LMB0;
            dirll = LMB1;
            dirhr = RMB0;
            dirlr = RMB1;
            /*dirhl = LMB0;
            dirll = LMB1;
            dirhr = RMF0;
            dirlr = RMF1;*/
        }
        else if( (PIND & 0x03) == 0x01 ){
            //if right white; turn left
            dirhl = LMF0;
            dirll = LMF1;
            dirhr = RMB0;
            dirlr = RMB1;
        }
        else if ( (PIND & 0x03) == 0x03 ){    
                      //if both white, move backwards
            /*dirhl = LMB0;
            dirll = LMB1;
            dirhr = RMF0;
            dirlr = RMF1;*/ 
            dirhl = LMB0;
            dirll = LMB1;
            dirhr = RMB0;
            dirlr = RMB1;
        }
       }
}
page_revision: 1, last_edited: 1209615718|%e %b %Y, %H:%M %Z (%O ago)
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License