zetgun
13.07.2010, 21:36
Hi,
ich habe das Gefühl ich sehe wieder den Wald vor lauter Bäumen nicht. Ich hab nun schon mehrmals über den Code geschaut, mehrere Pausen gemacht...aber ich blicks nicht.
Aber wozu gibts eine nette Community :)
Ich habe eine Nibobee welche zwei Antriebsmotoren hat und an jedem einen Odometrysensor, welcher über Interrupts eine Variable hoch bzw. runter zählt.
Dies wollte ich nun ausnutzen um beide Motoren mit der selben Drezahl drehen zu lassen. Sprich gleich viele Impulse pro bestimmter Zeit. Hier 10 Impulse pro 100ms (14 Impluse pro 100ms entsprechen ca. 100% PWM).
Um die 100ms zu erreichen habe ich einen Timer, der jede ms "time_odo" incrementiert. Wenn dieser >=100 (falls die 100 verpasst) werden die Impulse vom rechten und linken Sensor eingelesen und mit der Vorgabe abgeglichen und dann das Motor-PWM incrementiert oder decrementiert. Zur Kontrolle noch ein paar LEDs ansteuern, timer_odo wieder auf 0 und fertig.
Leider habe ich aber nun da Problem das, dass rechte Rad sich langsamer dreht als das Linke und ich nicht verstehe warum.
Leider habe ich auch noch kein Display / UART und kann mir somit die Werte nicht rausgeben. (Ist aber bestellt)
#include <avr/io.h>
#include <stdint.h>
#include <avr/interrupt.h>
#include <nibobee/motpwm.h>
#include <nibobee/odometry.h>
#include <nibobee/sens.h>
#include <nibobee/delay.h>
#include <nibobee/iodefs.h>
// Prototypen
void LED_init(void);
void LED_set(int8_t led0, int8_t led1, int8_t led2, int8_t led3);
void Timer0_init(void);
// globale Variable
volatile uint16_t time_odo = 0;
/*************
Main
**************/
int main(void)
{
// IO's init
sens_init();
Timer0_init();
LED_init();
odometry_init();
motpwm_init();
// Variable
int8_t odo_tick_l = 10; // 14Ticks in 100ms => 90% PWM
int8_t odo_tick_r = 10;
int16_t odo_left = 0;
int16_t odo_right = 0;
int16_t speed_l = 0;
int16_t speed_r = 0;
// Interrupts aktivieren
sei();
delay(500);
odometry_reset();
while(1)
{
if(time_odo >=100) // Alle 100ms
{
cli(); // Odo-Sensoren einlesen, damit right nicht weiterzählt => Interrupts aus
odo_left = odometry_getLeft(1); // Linker Sensor in "odo_left" und dann reset des Senors
odo_right = odometry_getRight(1); // Rechter Sensor in "odo_right" und dann reset des Senors
sei(); // Interrupts wieder an
// Left
if(odo_left < odo_tick_l)
{
speed_l +=5;
LED_set(0,1,2,2);
}
else if(odo_left > odo_tick_l)
{
speed_l -=5;
LED_set(1,0,2,2);
}
else LED_set(1,1,2,2);
// Right
if(odo_right < odo_tick_r)
{
speed_r +=5;
LED_set(2,2,1,0);
}
else if(odo_right > odo_tick_r)
{
speed_r -=5;
LED_set(2,2,0,1);
}
else LED_set(2,2,1,1);
time_odo =0;
}
// Motoren mit PWM-Werten füttern
motpwm_setLeft(speed_l);
motpwm_setRight(speed_r);
}
return 0;
}
/*************
Funktionen
*************/
// *** LED ***
void LED_init(void)
{
DDRB |= (1<<PB0) | (1<<PB1) | (1<<PB2) | (1<<PB3);
}
void LED_set(int8_t led0, int8_t led1, int8_t led2, int8_t led3)
{
// Hier steht die LED ansteuerung, wird aber nicht gebraucht zum Code verstehen
}
// *** Timer0 ***
void Timer0_init(void)
{
TCCR0 = (1<<WGM01); // Timer im CTC-Modus
TCCR0 |= (1<<CS00) | (1<<CS01); // Prescaler auf 64
OCR0 = 234; // um ca. 1ms zu erreichen
TIMSK |= (1<<OCIE0); // Interrupt "TIMER0_COMP_vect" aktivieren
}
/*************
Interrupts
*************/
ISR (TIMER0_COMP_vect)
{
time_odo++;
}
Ich hoffe ihr könnt einen Fehler entdecken...Ich seh das Problem leider nicht.
greez
ich habe das Gefühl ich sehe wieder den Wald vor lauter Bäumen nicht. Ich hab nun schon mehrmals über den Code geschaut, mehrere Pausen gemacht...aber ich blicks nicht.
Aber wozu gibts eine nette Community :)
Ich habe eine Nibobee welche zwei Antriebsmotoren hat und an jedem einen Odometrysensor, welcher über Interrupts eine Variable hoch bzw. runter zählt.
Dies wollte ich nun ausnutzen um beide Motoren mit der selben Drezahl drehen zu lassen. Sprich gleich viele Impulse pro bestimmter Zeit. Hier 10 Impulse pro 100ms (14 Impluse pro 100ms entsprechen ca. 100% PWM).
Um die 100ms zu erreichen habe ich einen Timer, der jede ms "time_odo" incrementiert. Wenn dieser >=100 (falls die 100 verpasst) werden die Impulse vom rechten und linken Sensor eingelesen und mit der Vorgabe abgeglichen und dann das Motor-PWM incrementiert oder decrementiert. Zur Kontrolle noch ein paar LEDs ansteuern, timer_odo wieder auf 0 und fertig.
Leider habe ich aber nun da Problem das, dass rechte Rad sich langsamer dreht als das Linke und ich nicht verstehe warum.
Leider habe ich auch noch kein Display / UART und kann mir somit die Werte nicht rausgeben. (Ist aber bestellt)
#include <avr/io.h>
#include <stdint.h>
#include <avr/interrupt.h>
#include <nibobee/motpwm.h>
#include <nibobee/odometry.h>
#include <nibobee/sens.h>
#include <nibobee/delay.h>
#include <nibobee/iodefs.h>
// Prototypen
void LED_init(void);
void LED_set(int8_t led0, int8_t led1, int8_t led2, int8_t led3);
void Timer0_init(void);
// globale Variable
volatile uint16_t time_odo = 0;
/*************
Main
**************/
int main(void)
{
// IO's init
sens_init();
Timer0_init();
LED_init();
odometry_init();
motpwm_init();
// Variable
int8_t odo_tick_l = 10; // 14Ticks in 100ms => 90% PWM
int8_t odo_tick_r = 10;
int16_t odo_left = 0;
int16_t odo_right = 0;
int16_t speed_l = 0;
int16_t speed_r = 0;
// Interrupts aktivieren
sei();
delay(500);
odometry_reset();
while(1)
{
if(time_odo >=100) // Alle 100ms
{
cli(); // Odo-Sensoren einlesen, damit right nicht weiterzählt => Interrupts aus
odo_left = odometry_getLeft(1); // Linker Sensor in "odo_left" und dann reset des Senors
odo_right = odometry_getRight(1); // Rechter Sensor in "odo_right" und dann reset des Senors
sei(); // Interrupts wieder an
// Left
if(odo_left < odo_tick_l)
{
speed_l +=5;
LED_set(0,1,2,2);
}
else if(odo_left > odo_tick_l)
{
speed_l -=5;
LED_set(1,0,2,2);
}
else LED_set(1,1,2,2);
// Right
if(odo_right < odo_tick_r)
{
speed_r +=5;
LED_set(2,2,1,0);
}
else if(odo_right > odo_tick_r)
{
speed_r -=5;
LED_set(2,2,0,1);
}
else LED_set(2,2,1,1);
time_odo =0;
}
// Motoren mit PWM-Werten füttern
motpwm_setLeft(speed_l);
motpwm_setRight(speed_r);
}
return 0;
}
/*************
Funktionen
*************/
// *** LED ***
void LED_init(void)
{
DDRB |= (1<<PB0) | (1<<PB1) | (1<<PB2) | (1<<PB3);
}
void LED_set(int8_t led0, int8_t led1, int8_t led2, int8_t led3)
{
// Hier steht die LED ansteuerung, wird aber nicht gebraucht zum Code verstehen
}
// *** Timer0 ***
void Timer0_init(void)
{
TCCR0 = (1<<WGM01); // Timer im CTC-Modus
TCCR0 |= (1<<CS00) | (1<<CS01); // Prescaler auf 64
OCR0 = 234; // um ca. 1ms zu erreichen
TIMSK |= (1<<OCIE0); // Interrupt "TIMER0_COMP_vect" aktivieren
}
/*************
Interrupts
*************/
ISR (TIMER0_COMP_vect)
{
time_odo++;
}
Ich hoffe ihr könnt einen Fehler entdecken...Ich seh das Problem leider nicht.
greez