Hallo
Ein kleines Video gefällig?
Bild hier
http://www.youtube.com/watch?v=Hmy_6wn5HFg
Das einfache "links dunkler als rechts"-Programm:
Code:
// Einfaches Linienfolgen mit dem asuro-ProBot 30.8.09 mic
#include "selftest.h"
void Init(void);
void Sleep(unsigned char time36kHz);
void Msleep(int dauer);
void SerWrite(unsigned char *data,unsigned char length);
void PrintInt(int wert);
void PrintBin(char wert);
inline void StatusLED(unsigned char color);
inline void FrontLED(unsigned char status);
void BackLED(unsigned char left, unsigned char right);
inline void MotorSpeed(unsigned char left_speed, unsigned char right_speed);
inline void MotorDir(unsigned char left_dir, unsigned char right_dir);
void LineData(unsigned int *data);
inline void StatusLED(unsigned char color);
void SetLEDs(unsigned char status);
int main(void) {
unsigned int data[2];
//unsigned char i;
Init();
SerWrite("\n\rasuro-ProBot-Linienfolgen\n\r",29);
SerWrite("30.8.09 mic \n\r", 14);
DDRD |= (1<<PD2) | (1<<PD3) | (1<<PD4) | (1<<PD5) | (1<<PD6); // D12-15 und FrontLED
PORTD |= (1<<PD2) | (1<<PD3) | (1<<PD4) | (1<<PD5) | (1<<PD6); // high bedeutet LEDs aus
//PORTD &= ~((1<<PD2) | (1<<PD3) | (1<<PD4) | (1<<PD5)); // D12-15 an
//SetLEDs(0b11111); // FrontLED, D14(red), D15, D13, D12(green)
FrontLED(ON);
MotorSpeed(225,225);
while(1)
{
LineData(data);
if(data[0]<data[1]) MotorSpeed(200,250); else MotorSpeed(250,200);
/*
PrintInt(data[0]);
SerWrite("- ", 2);
PrintInt(data[1]);
SerWrite("\n\r", 2);
Msleep(100);
*/
Sleep(255);
}
return(0); // wird nie erreicht!
}
volatile unsigned char count36kHz;
volatile unsigned long timebase;
/* uses timer2 (36kHz for IR communication */
SIGNAL (SIG_OVERFLOW2)
{
TCNT2 += 0x25;
count36kHz ++;
if (!count36kHz) timebase ++;
}
void Init (void)
{
//-------- seriell interface programmed in boot routine and already running -------
// prepare 36kHz for IR - Communication
TCCR2 = (1 << WGM20) | (1 << WGM21) | (1 << COM20) | (1 << COM21) | (1 << CS20);
OCR2 = 0x91; // duty cycle for 36kHz
TIMSK |= (1 << TOIE2); // 36kHz counter for sleep
// prepare RS232
UCSRA = 0x00;
UCSRB = 0x00;
UCSRC = 0x86; // No Parity | 1 Stop Bit | 8 Data Bit
UBRRL = 0xCF; // 2400bps @ 8.00MHz
// I/O Ports
DDRB = IRTX | LEFT_DIR | PWM | GREEN_LED;
//DDRD = RIGHT_DIR | FRONT_LED | ODOMETRIE_LED | RED_LED;
// for PWM (8-Bit PWM) on OC1A & OC1B
TCCR1A = (1 << WGM10) | (1 << COM1A1) | (1 << COM1B1);
// tmr1 running on MCU clock/8
TCCR1B = (1 << CS11);
// A/D Conversion
ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1); // clk/64
ODOMETRIE_LED_OFF;
StatusLED(GREEN);
MotorDir(FWD,FWD);
MotorSpeed(0,0);
sei();
}
void Sleep(unsigned char time36kHz)
{ unsigned char ziel=(time36kHz+count36kHz) & 0x00FF;
while (count36kHz != ziel);
}
void Msleep(int dauer)
{
while(dauer--) Sleep(36);
}
void SerWrite(unsigned char *data,unsigned char length)
{
unsigned char i = 0;
UCSRB = 0x08; // enable transmitter
while (length > 0) {
if (UCSRA & 0x20) { // wait for empty transmit buffer
UDR = data[i++];
length --;
}
}
while (!(UCSRA & 0x40));
for (i = 0; i < 0xFE; i++)
for(length = 0; length < 0xFE; length++);
}
void PrintInt(int wert)
{ char text[6]=" ";
itoa(wert,text,10);
SerWrite(text,5);
}
void PrintBin(char wert)
{ char text[8]=" ";
itoa(wert,text,2);
SerWrite(text,8);
}
/* Set motor speed */
inline void MotorSpeed(unsigned char left_speed, unsigned char right_speed)
{
OCR1A = left_speed;
OCR1B = right_speed;
}
/* Set motor direction */
inline void MotorDir(unsigned char left_dir, unsigned char right_dir)
{
if(left_dir) PORTB &= ~(1 << PB5); else PORTB |= (1 << PB5);
if(right_dir) PORTB &= ~(1 << PB4); else PORTB |= (1 << PB4);
}
void LineData(unsigned int *data)
{
ADMUX = (1 << REFS0) | IR_LEFT; // AVCC reference with external capacitor
Sleep(10);
ADCSRA |= (1 << ADSC); // Start conversion
while (!(ADCSRA & (1 << ADIF))); // wait for conversion complete
ADCSRA |= (1 << ADIF); // clear ADCIF
data[0] = ADCL + (ADCH << 8);
ADMUX = (1 << REFS0) | IR_RIGHT; // AVCC reference with external capacitor
Sleep(10);
ADCSRA |= (1 << ADSC); // Start conversion
while (!(ADCSRA & (1 << ADIF))); // wait for conversion complete
ADCSRA |= (1 << ADIF); // clear ADCIF
data[1] = ADCL + (ADCH << 8);
}
inline void StatusLED(unsigned char color)
{
if (color == OFF) {GREEN_LED_OFF; RED_LED_OFF;}
if (color == GREEN) {GREEN_LED_ON; RED_LED_OFF;}
if (color == YELLOW) {GREEN_LED_ON; RED_LED_ON;}
if (color == RED) {GREEN_LED_OFF; RED_LED_ON;}
}
void SetLEDs(unsigned char status)
{
status = ~(status<<2); // LEDs sind PD2-7 gegen Vcc schaltend!
PORTD &= status; // nur gesetzte LEDs einschalten
PORTD |= status & ~3; // PD0 und PD1 nicht verändern!
}
inline void FrontLED(unsigned char status)
{
if(status) FRONT_LED_on; else FRONT_LED_off;
}
Und die Header-Datei dazu:
Code:
// Einfaches Linienfolgen mit dem asuro-ProBot 30.8.09 mic
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#define FALSE 0
#define TRUE 1
#define OFF 0
#define ON 1
#define GREEN 1
#define RED 2
#define YELLOW 3
/* --------------- INTERNAL ------------- */
#define GREEN_LED_OFF PORTD |= GREEN_LED
#define GREEN_LED_ON PORTD &= ~GREEN_LED
#define RED_LED_OFF PORTD |= RED_LED
#define RED_LED_ON PORTD &= ~RED_LED
#define FWD 0
#define RWD 1
#define BREAK 0x00
#define FREE (1 << PB4) | (1 << PB5) /* (1 << PD4) | (1 << PD5)*/
#define IRTX (1 << PB3)
#define GREEN_LED (1 << PD5)
#define RED_LED (1 << PD2)
#define PWM (1 << PB1) | (1 << PB2)
#define RIGHT_DIR (1 << PB4) | (1 << PB5)
#define LEFT_DIR (1 << PD4) | (1 << PD5)
#define BATTERIE (1 << MUX0) | (1 << MUX2) //ADC5
#define SWITCH (1 << MUX2) //ADC4
#define IR_LEFT (1 << MUX0) | (1 << MUX1) //ADC3
#define IR_RIGHT (1 << MUX1) //ADC2
#define Speaker (1 << PD5) // speaker an D14
#define Speaker_on PORTD &= ~(1<<PD5)
#define Speaker_off PORTD |= (1<<PD5)
#define FRONT_LED (1 << PD6)
#define FRONT_LED_on PORTD &= ~(1<<PD6)
#define FRONT_LED_off PORTD |= (1<<PD6)
#define ODOMETRIE_LED (1 << PD7)
#define ODOMETRIE_LED_ON PORTD |= ODOMETRIE_LED
#define ODOMETRIE_LED_OFF PORTD &= ~ODOMETRIE_LED
#define WHEEL_LEFT (1 << MUX0) //ADC1
#define WHEEL_RIGHT 0 //ADC0
#define LED12_on PORTD &= ~(1<<PD2)
#define LED13_on PORTD &= ~(1<<PD3)
#define LED14_on PORTD &= ~(1<<PD5) // Achtung Reihenfolge D14/15 getauscht!
#define LED15_on PORTD &= ~(1<<PD4)
#define LED12_off PORTD |= (1<<PD2)
#define LED13_off PORTD |= (1<<PD3)
#define LED14_off PORTD |= (1<<PD5)
#define LED15_off PORTD |= (1<<PD4)
:)
btw kann ich den Motortreiberumbau nur empfehlen.
Gruß
mic
Lesezeichen