SourceCode für die Programmierung von ALAN

verwendet die OpenSource-Entwicklungsumgebung AVR-GCC für Atmel AVR-Mikrocontroller
(Alan verwendet den AT8515 AVR)

Mehr Infos zu AVR's und Firmware-Programmierung

Download Source + Makefile

/*
ALAN
Serving and Collecting - Robot

SHIFZ - Abtlg. f. Robotik
2002, 2003
*/


#include <io.h>
#include <interrupt.h>
#include <sig-avr.h>
#include <ina90.h>

#define bin8const(d7,d6,d5,d4,d3,d2,d1,d0) ((d7<<7)+(d6<<6)+(d5<<5)+(d4<<4)+(d3<<3)+(d2<<2)+(d1<<1)+d0)

#define r1_go sbi(PORTA,PA0)
#define r1_stop cbi(PORTA,PA0)
#define r2_go sbi(PORTA,PA1)
#define r2_stop cbi(PORTA,PA1)
#define r3_go sbi(PORTA,PA2)
#define r3_stop cbi(PORTA,PA2)
#define r4_go sbi(PORTA,PA3)
#define r4_stop cbi(PORTA,PA3)

#define q4 bit_is_set(PINA, PA4)
#define q3 bit_is_set(PINA, PA5)
#define q2 bit_is_set(PINA, PA6)
#define q1 bit_is_set(PINA, PA7)

#define mp3_stop_on sbi(PORTC,PC0)
#define mp3_stop_off cbi(PORTC,PC0)
#define mp3_play_on sbi(PORTC,PC1)
#define mp3_play_off cbi(PORTC,PC1)
#define mp3_next_on sbi(PORTC,PC2)
#define mp3_next_off cbi(PORTC,PC2)
#define mp3_prev_on sbi(PORTC,PC3)
#define mp3_prev_off cbi(PORTC,PC3)

#define bump_left bit_is_clear(PINC, PC4)
#define bump_right bit_is_clear(PINC, PC5)

#define PIR bit_is_clear(PINC, PC6)

#define SERVO_on sbi(PORTC,PC7)
#define SERVO_off cbi(PORTC,PC7)

#define SERVO_2_on sbi(PORTB,PB1)
#define SERVO_2_off cbi(PORTB,PB1)

#define SERVO_3_on sbi(PORTB,PB2)
#define SERVO_3_off cbi(PORTB,PB2)
#define std bit_is_set(PINB, PB3)

#define led_on cbi(PORTD,PD4)
#define led_off sbi(PORTD,PD4)

#define bump_rear bit_is_clear(PIND, PD5)
#define bump_front bit_is_clear(PIND, PD6)
#define bump_revers bit_is_clear(PIND, PD7)

#define CAM_LEFT 320
#define CAM_RIGHT 130
#define CAM2_MIDDLE 230

#define CAM_UP 340
#define CAM_DOWN 200
#define CAM1_MIDDLE 280 // 300
#define CAM1_DRIVE 290 // 220

#define CAM_ACTIVATION 500

#define AUTO_ACTIVATION 100
#define BACKGROUND_ACTIVATION 2000
#define INTERSOUND_PAUSE 400
#define OVERRIDEACTION_TIME 250

#define BAG_OPENED 200
#define BAG_CLOSED 80


#define WAIT1 40
#define WAIT2 40

volatile uint16_t timevar;
volatile uint8_t actsong;
volatile uint8_t mp3_go_prev;
volatile uint8_t mp3_go_next;
volatile uint16_t playtime;
volatile uint16_t nextbutton;
volatile uint16_t mp3_active;
volatile uint8_t song_playing;
volatile uint16_t seed=11;
volatile uint8_t action;
volatile uint8_t autonom=0;
volatile uint8_t valid_tone=15;
volatile uint16_t open_bag=0;
volatile uint16_t bgsound_time=0;
volatile uint16_t bagpos=105;
volatile uint16_t campos1=250;
volatile uint16_t campos2=250;
volatile uint16_t camtarget1=CAM1_MIDDLE;
volatile uint16_t camtarget2=CAM2_MIDDLE;
volatile int16_t cam_time=0;
volatile uint16_t ovr=0;
volatile uint8_t idle=1;
volatile uint16_t idle_time=AUTO_ACTIVATION;
volatile uint8_t undo=0;
volatile uint8_t ui=0;
volatile uint8_t working=0;

volatile uint16_t duration=0;
volatile uint8_t lightmode=0;
volatile uint16_t song_time=0;
volatile uint16_t led_time=0;
volatile uint16_t led_ontime=30;
volatile uint16_t led_offtime=50;

#define SOUNDS 8


uint16_t songtimes[SOUNDS+1]={

0, // 0: 20secpause
500, // 1: hallo
500, // 2: cocktails
300, // 3: splendid
550, // 4: cocktails
550, // 5: nüsse
300, // 6: pfiff
350, // 7: schuss
9000, // 8: sounds
};


void init_ports(void)
{
//---initialize DataDirection ( 1=Input, 0=Output )
outp((uint8_t)(~ bin8const(1,1,1,0,0,0,0,0)) ,DDRD);
outp((uint8_t)(~ bin8const(0,0,0,0,1,0,0,0)) ,DDRB);
outp((uint8_t)(~ bin8const(1,1,1,1,0,0,0,0)) ,DDRA);
outp((uint8_t)(~ bin8const(0,1,1,1,0,0,0,0)) ,DDRC);

//---initialize Portpins (for output)/weak pullups(for inputs)
outp(0xf0,PORTA);
outp(0x70,PORTC);
outp(0x08,PORTB);
outp(0xf0,PORTD);
}

void init_timer(void)
{
outp((1<<TOIE0), TIMSK); // enables the T/C0 overflow interrupt in T/C interrupt mask register
outp(0, TCNT0); // start value of T/C0
outp(5, TCCR0); // prescale ck/1024
timevar=0;
sei(); // set global interrupt enable
}


void delay(uint16_t t)
{
uint16_t i,j,k;

for (k=0;k<t;k++)
for (i=0; i<7000; i++)
for(j=0; j<870;j++) ;
}


uint16_t random(uint8_t range)
{
uint16_t newbit;
uint8_t i,ret;
if (range==0) return(0);
for (i=1;i<=7;i++)
{
newbit=((seed>>15)&1) ^
((seed>>1)&1) ^
((seed )&1);
seed=(seed<<1)|newbit;
}
ret=seed&127;
while (ret>range) ret=ret-range;
return (ret);
}


void stop_motors(void)
{ r1_stop;r3_stop;r2_stop;r4_stop;}


void go_back(void)
{
r2_go;r1_stop;
r4_go;r3_stop;
}
void go_fwd(void)
{
r1_go;r2_stop;
r3_go;r4_stop;
}
void go_right(void)
{
r1_go;r2_stop;
r4_go;r3_stop;
}
void go_left(void)
{
r2_go;r1_stop;
r3_go;r4_stop;
}


void mp3_player_on(void)
{
mp3_stop_on;delay(70);mp3_stop_off;delay(100);
mp3_stop_on;delay(70);mp3_stop_off;delay(100);
mp3_play_on;delay(70);mp3_play_off;delay(1300);
mp3_next_on;delay(50);mp3_next_off;delay(50);
mp3_go_prev=0;actsong=0;playtime=0;nextbutton=0;mp3_active=0;
}

void mp3_play_song(uint8_t num)
{

if ((mp3_active==0) && ((song_playing==0)||(actsong==SOUNDS)))
{

cli();
mp3_active=1;
if (num>actsong)
mp3_go_next=num-actsong;

else

mp3_go_prev=actsong-num+1;

actsong=num;playtime=songtimes[actsong];
mp3_active=1;timevar=0;song_playing=1;nextbutton=0;
sei();
}
}

void mp3_reset(void)
{
cli();
mp3_stop_on;delay(70);mp3_stop_off;delay(200);
mp3_stop_on;delay(70);mp3_stop_off;delay(110);
mp3_stop_on;delay(70);mp3_stop_off;delay(110);
mp3_play_on;delay(70);mp3_play_off;delay(1300);
mp3_next_on;delay(45);mp3_next_off;delay(50);

mp3_go_prev=0;mp3_go_next=0;
actsong=0;playtime=0;nextbutton=0;mp3_active=0;
song_time=0;
sei();
}

uint8_t gettone(void)
{
uint8_t c;

if (std)
{
c=0; if (q4) c=c+8; if (q3) c=c+4; if(q2) c=c+2; if(q1) c=c+1;
valid_tone=c;
}
else valid_tone=15;
return(valid_tone);
}

SIGNAL (SIG_OVERFLOW0)
{
uint16_t d,i;

cli();

if ((mp3_go_prev==0)&&(mp3_go_next==0)&&(playtime>0))
{ if (timevar==240) mp3_active=0; else timevar++;
if (--playtime==0) {mp3_go_prev=actsong+1;mp3_active=1;nextbutton=0;}

}
else
{
if (mp3_go_prev>0)
{ switch (++nextbutton) {
case 1: mp3_prev_on;duration=200;break;
case 25: mp3_prev_off;break;
case 50: nextbutton=0;mp3_go_prev--;
if (mp3_go_prev==0) led_on; break;
}
}
else
{
if (mp3_go_next>0)
{ switch (++nextbutton) {
case 1: mp3_next_on;duration=200;break;
case 25: mp3_next_off;break;
case 50: nextbutton=0;mp3_go_next--;
if (mp3_go_next==0) led_on;break;
}
}
else
{
switch (++nextbutton) {
case 1: mp3_active=0;actsong=0;song_playing=0;break;
case 800: mp3_active=1;mp3_prev_on;break;
case 825: mp3_prev_off;break;
case 850: nextbutton=0;break;
}
}
}

}

if (lightmode==1)
{

led_time++;
if (led_time==led_ontime) led_off;
if (led_time==(led_ontime+led_offtime)) {led_on; led_time=0;}
}
else
{

if (song_time>0) song_time--;
if (PIR)
{
led_on;
if ((song_time==0)&&(mp3_active==0))
{
mp3_play_song(random(7));
if ((actsong>=1)&&(actsong<=4)) open_bag=700;

song_time=songtimes[actsong]+INTERSOUND_PAUSE;
camtarget2=230;camtarget1=300;cam_time= - 500;
}
}
else
{
led_off;
if (idle) cam_time++; else cam_time=0;
if (cam_time>=CAM_ACTIVATION)
{
cam_time=0;
camtarget1=200+random(110);
camtarget2=150+random(160);

if ((action==5) || (action==15))
{
ovr=OVERRIDEACTION_TIME;
undo=0;
// action=random(3); if (action==2) action=4;
}

}
}

if (actsong==0) bgsound_time++; else bgsound_time=0;


if ((bgsound_time>=BACKGROUND_ACTIVATION)&&(mp3_active==0))
{ bgsound_time=0; mp3_play_song(SOUNDS); }
}

if (open_bag==-1) bagpos=BAG_CLOSED+10;
if (open_bag==0) {if (bagpos>BAG_CLOSED+7) bagpos--; else open_bag=-1;}
if ((open_bag>0)&&(open_bag!=-1)) {open_bag--; if (bagpos<BAG_OPENED) bagpos++;}
if (bagpos!=BAG_CLOSED+10) led_on;

if (campos1<camtarget1) campos1++;
if (campos1>camtarget1) campos1--;
if (campos2<camtarget2) campos2++;
if (campos2>camtarget2) campos2--;

SERVO_on; SERVO_2_on; SERVO_3_on;

for (d=0;d<360;d++)
{ for (i=0;i<1200;i++) ;
if (d==bagpos) SERVO_off;
if (d==campos1) SERVO_2_off;
if (d==campos2) SERVO_3_off;
}


if (idle)
{
if (idle_time<AUTO_ACTIVATION) idle_time++;
else lightmode=0;
}
else {idle_time=0; lightmode=1; open_bag=0;}

if (ovr) ovr--;
outp(112,TCNT0); // timer 50 millisec
}


int main( void )
{

init_ports();


action=gettone();led_on;
mp3_player_on();led_off;

init_timer();
delay(400);


mp3_play_song(SOUNDS);


while (1)
{
// undo=0;

if (((bump_front)||(bump_left)||(bump_right)||(bump_rear))&&(!working))
{ working=1;
ovr=50;
if (undo)
{
action=action+undo;
}
else
{
ui=0;
if (bump_rear) action=1;
if (bump_front) action=2;
if (bump_left) action=4;
if (bump_right) action=3;
}
}

if (ovr==0) { ui=1; action=gettone();working=0; }
switch (action) {

case 1: go_fwd(); camtarget1=CAM1_DRIVE; camtarget2=CAM2_MIDDLE;if (ui) undo= 1; idle=0; break;
case 2: go_back(); camtarget1=CAM1_DRIVE; camtarget2=CAM2_MIDDLE; if (ui) undo=-1; idle=0; break;
case 4: go_left(); camtarget1=CAM1_DRIVE; camtarget2=CAM2_MIDDLE; if (ui) undo= 1; idle=0; break;
case 3: go_right(); camtarget1=CAM1_DRIVE; camtarget2=CAM2_MIDDLE; if (ui) undo=-1; idle=0; break;

case 5: undo=0; stop_motors();
if (!ovr) { camtarget1=campos1;camtarget2=campos2; }
idle=1;break;

case 6: camtarget1=CAM_DOWN; cam_time=0; break;
case 7: camtarget1=CAM_UP; cam_time=0; break;
case 8: camtarget2=CAM_RIGHT; cam_time=0; break;
case 9: camtarget2=CAM_LEFT; cam_time=0; break;

case 11: open_bag=400; break;
case 12: mp3_reset(); break;

case 15: undo=0; stop_motors();
idle=1;break;
default: break;
}

}

return(0);
}