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