Hallo
Wirklich zufällig hängt das Servo das meinen Sharp schwenkt auch an X3 :)
Code:
// Nibobee Motor- und Odometrytest 18.11.09 mic
#include <nibobee/iodefs.h>
#include <nibobee/delay.h>
#include <nibobee/analog.h>
#include <nibobee/odometry.h>
#include <nibobee/led.h>
#include <nibobee/sens.h>
#include <stdlib.h> // C standard functions (e.g. itoa...)
uint16_t nibobee_initialization; // ???
#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=0;
int main(void) {
uint8_t c;
uint16_t echo[16];
uint8_t servopos=0;
int8_t schwenk=1;
led_init();
sens_init();
analog_init();
odometry_init();
odometry_reset();
ir_init();
led_set(LED_L_YE,1);
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("Sharp-Test mit Schwenkservo\n\r");
writeString("21.11.09 mic\n\n\r");
delay(2000);
servo=108;
while(1)
{
servo=35+servopos*10;
delay(100);
echo[14-servopos]=analog_getValue(ANALOG_EXT3);
if((servopos==0) || (servopos==14))
{
for(c=0; c<15; c++)
{
writeInteger(echo[c], 10);
writeString("-");
}
writeString("\n\r");
}
servopos+=schwenk;
if(!servopos) schwenk=1; else if(servopos==14) schwenk=-1;
}
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. Zusätzlich erzeugt
// sie die Impulse für das Servo an PC3. Letztlich dekrementiert sie p solange
// bis es 0 ist
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);
}
(ungeputzer Arbeitscode)
Ein 36kHz-Takt wird mit Timer2 erzeugt:
Code:
TCCR2 = (1 << WGM21) | (1 << CS20); // CTC-Mode, no prescaling, no OC2-PIN!
OCR2 = 208; // 36kHz @15MHz
TIMSK |= (1 << OCIE2);
In der ISR wird dann das Signal ausgegeben:
Code:
ISR (TIMER2_COMP_vect)
{
...
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--;};
}
Und schließlich kann man dann die Servoposition in der Variablen servo übergeben. Mitte ist ca. 108, 0 bedeutet kein Impuls senden. Das sollte direkt so funktionieren, mein Sharp hängt auch an X3 ;)
Bild hier
http://www.youtube.com/watch?v=G836SWiYA_c
Servostecker mußte man für ADC0/1 beim RP6 auch "Umbauen".
Warum die Hersteller das Servopinout nicht übernehmen ist mir schleierhaft:
Bild hier
Gruß
mic
Lesezeichen