Hallo
Dabei ergibt sich ein etwas seltsames Verhalten der Odometrie:
Der Motor, der sich rückwärts dreht zeigt ca. 50 Ticks. Der Motor der sich vorwärts dreht, zeigt ca. 70 Ticks. Da sich der Roboter auf der Stelle dreht, sollten beide Werte gleich sein. Wie verhalten sich eure NiboBees in der Hinsicht?
Meine Biene spinnt auch beim Drehen: Rechtsrum sind beide Zähler fast gleich, linksrum großer Unterschied. (natürlich vorzeichenlos betrachet;)
Weil ich das eher wissenschaftlicher angehen wollte, habe ich mir die Motoransteuerung mal genauer angeschaut. Sehr clever gelöst mit dem Demultiplexer :) Einzuordnen ist das wohl zwischen der voll steuerbaren H-Brücke des asuro (mit 6 Leitungen, Gas-Bremse-Freilauf) und der peinlichen Sparschaltung des Probots (mit 3 Leitungen, Gas).
Mein aktueller Sofwarestand sendet Daten per Usart und IR, steuert ein Servo an X3 und zählt die Odo-Impulse beim Schieben. Die grundsätzliche Motorsteuerung ohne PWM kennt nur Vollgas und berücksichtigt die scheinbar am Würfeltisch entworfene Richtungsansteuerung (PD6/7;):
Code:
// Nibobee Motor- und Odometrytest 18.11.09 mic
#include <nibobee/iodefs.h>
#include <nibobee/delay.h>
#include <nibobee/odometry.h>
#include <nibobee/led.h>
#include <nibobee/sens.h>
#include <stdlib.h> // C standard functions (e.g. itoa...)
#define LineLEDs_on PORTB &=~(1<<PB4)
#define LineLEDs_off PORTB |= (1<<PB4)
#define DIR_R 7
#define DIR_L 6
#define PWM_L 5
#define PWM_R 4
void ir_init(void);
void writeChar(uint8_t data );
void writeString(char *string);
void writeInteger(int16_t number, uint8_t base);
void motorDir(uint8_t dir_left, uint8_t dir_right);
void motorSpeed(uint8_t speed_left, uint8_t speed_right);
uint8_t p=0, servo=72;
int main(void) {
led_init();
sens_init();
odometry_init();
odometry_reset();
ir_init();
PORTD |=(1<<PWM_L)|(1<<PWM_R); // Pullups einschalten damit der Pegel high bleibt
DDRD |=(1<<DIR_L)|(1<<DIR_R)|(1<<PWM_L)|(1<<PWM_R);
writeString("\n\n\r");
writeString("Test der Motoransteuerung\n\r");
writeString("und der Odometry\n\r");
writeString("18.11.09 mic\n\n\r");
delay(1000);
while(1)
{
writeInteger(odometry_getLeft(0), 10);
writeString("-");
writeInteger(odometry_getRight(0), 10);
writeString("\n\r");
delay(200);
if(sens_getLeft()) odometry_getLeft(1);
if(sens_getRight()) odometry_getRight(1);
if(sens_getLeft() & sens_getRight())
{
odometry_getLeft(1);
odometry_getRight(1);
motorDir(1,1);
motorSpeed(1,1);
delay(500);
motorSpeed(0,0);
delay(50);
motorDir(0,0);
motorSpeed(1,1);
delay(500);
motorSpeed(0,0);
delay(50);
motorDir(1,0);
motorSpeed(1,1);
delay(500);
motorSpeed(0,0);
delay(50);
motorDir(0,1);
motorSpeed(1,1);
delay(500);
motorSpeed(0,0);
delay(50);
}
}
return 0;
}
// Die ISR erzeugt die 36kHz-Trägerfrequenz und "lauscht" gleichzeitig am TXD-Pin
// um die seriellen Daten auf die Trägerfrequenz zu mischen.
ISR (TIMER2_COMP_vect)
{
static uint8_t status=0;
if(PIND & 2) // Der TSOP invertiert die empfangenen Daten!
{
LineLEDs_off;
}
else
{
if(status)
{
LineLEDs_on; status=0;
}
else
{
LineLEDs_off; status=1;
}
}
static uint16_t count=1;
if(count>servo) PORTC &= ~(1<<PC3); else PORTC |= (1<<PC3);
if(count<1440) count++; else {count=1; if(p) p--;};
}
void ir_init(void)
{
#define UBRR_BAUD_2400 390 // Baudrate auf 2400 setzen
UBRRH = UBRR_BAUD_2400 >> 8;
UBRRL = (uint8_t) UBRR_BAUD_2400;
UCSRC = (1<<URSEL)|(0<<USBS)|(3<<UCSZ0); // 8, none, 1
UCSRB |= (1<<TXEN); // Senden enablen
TCCR2 = (1 << WGM21) | (1 << CS20); // CTC-Mode, no prescaling, no OC2-PIN!
OCR2 = 208; // 36kHz @15MHz
TIMSK |= (1 << OCIE2);
DDRB |= (1<<PB4); // LineLED ist ein Ausgang
LineLEDs_on; // LineLED schaltet gegen GND!
DDRD |= 2; // TXD Ausgang und low
PORTD &= ~2;
sei();
}
void writeChar(uint8_t data ) // Code aus ATMega16-Datenblatt
{
while ( !( UCSRA & (1<<UDRE)) );
UDR = data;
}
void writeString(char *string)
{
while(*string)
writeChar(*string++);
}
void writeInteger(int16_t number, uint8_t base)
{
char buffer[17];
itoa(number, &buffer[0], base);
writeString(&buffer[0]);
}
void motorDir(uint8_t dir_left, uint8_t dir_right)
{
if(dir_left) PORTD |= (1<<DIR_L); else PORTD &= ~(1<<DIR_L);
if(dir_right) PORTD &= ~(1<<DIR_R); else PORTD |= (1<<DIR_R);
}
void motorSpeed(uint8_t speed_left, uint8_t speed_right)
{
if(speed_left) PORTD &= ~(1<<PWM_L); else PORTD |= (1<<PWM_L);
if(speed_right) PORTD &= ~(1<<PWM_R); else PORTD |= (1<<PWM_R);
}
Obwohl ich inzwischen je eines der Löcher für die Fühlerlagerung auf 1,4mm aufgebohrt habe, klicken die Taster immer noch nicht richtig satt. Dafür reicht jetzt aber die Rückstellkraft von SW3 nicht mehr aus um den Fühler zurückzudrücken.
Gruß
mic
Lesezeichen