COCKBOT I - Firmware-Source Code
Cockbot verwendet einen Atmel AT8515 AVR-Mikrocontroller, der mithilfe der Open-Source-Entwicklungsumgebung AVR-GCC programmiert werden kann.
Mehr
Infos zu AVR's und Firmware-Programmierung
Download Cockbot Source + Makefile
#include <io.h>
#include <interrupt.h>
#include <sig-avr.h>
#include <ina90.h>
#define DEMO 1
#define DEMOSOUND 11
#define COINS 2
#define SOUNDS 4
/*
1. 1e: 2 euro
2. 2e: noch 2 euro
3. 3e: wählen
4. 5e: fertig
5. eis: eis nachfüllen
6. err: error
7. glenn1
8. glenn2
9. glenn3
10. glenn4
11. glenndemo
*/
#define set_start 21 // codes dimmersteuerung
#define set_end 36
#define set_speed 2
#define act_more 59
#define act_less 58
#define cmd_up 68
#define SGAP 40
#define binconst(d7,d6,d5,d4,d3,d2,d1,d0) ((d7<<7)+(d6<<6)+(d5<<5)+(d4<<4)+(d3<<3)+(d2<<2)+(d1<<1)+d0)
#define led_ein sbi(PORTB,PB1) // led
#define led_aus cbi(PORTB,PB1)
#define flaschen_ein sbi(PORTB,PB2) // flaschen
#define flaschen_aus cbi(PORTB,PB2)
#define eis_rauf_ein sbi(PORTB,PB3) // eisaufzug rauf
#define eis_rauf_aus cbi(PORTB,PB3)
#define eis_runter_ein sbi(PORTB,PB0) // eisaufzug runter
#define eis_runter_aus cbi(PORTB,PB0)
#define spiegel_ein sbi(PORTB,PB4) // gläser
#define spiegel_aus cbi(PORTB,PB4)
#define glasband_ein sbi(PORTD,PD0) // spielgel
#define glasband_aus cbi(PORTD,PD0)
#define hebel_rauf_ein sbi(PORTD,PD1) // hebel rauf
#define hebel_rauf_aus cbi(PORTD,PD1)
#define hebel_runter_ein sbi(PORTD,PD2) // hebel runter
#define hebel_runter_aus cbi(PORTD,PD2)
#define high_send sbi(PORTD,PD3) // lichtcode
#define low_send cbi(PORTD,PD3)
#define play_on sbi(PORTC,PC1) // mp3 play
#define play_off cbi(PORTC,PC1)
#define stop_on sbi(PORTC,PC0) // mp3 stop
#define stop_off cbi(PORTC,PC0)
#define prev_on sbi(PORTC,PC3) // mp3 prev
#define prev_off cbi(PORTC,PC3)
#define next_on sbi(PORTC,PC2) // mp3 next
#define next_off cbi(PORTC,PC2)
#define hebel bit_is_clear(PINA, PA7) // hebel
#define juice_pos bit_is_clear(PINC, PC7) // juices
#define coin bit_is_clear(PINA, PA6) // münze
#define select_3 bit_is_clear(PINA, PA5) // cocktail3
#define select_1 bit_is_clear(PINA, PA4) // cocktail1
#define select_2 bit_is_clear(PINA, PA3) // cocktail2
#define glas_pos bit_is_clear(PINA, PA2) // glaspos
#define eis_leer bit_is_clear(PINA, PA1) // eis_leer
#define eis_ok bit_is_clear(PINA, PA0) // eis_ok
#define SURE 20
volatile uint16_t i;
volatile uint8_t actsound;
volatile uint8_t x;
volatile uint16_t c;
volatile uint8_t l;
volatile uint8_t no_glass;
volatile uint16_t cin,cin2;
volatile uint16_t last;
volatile uint16_t juice1;
volatile uint16_t juice2;
volatile uint16_t juice3;
volatile uint16_t juice4;
volatile uint16_t juice5;
volatile uint16_t act_pos;
volatile uint16_t amount;
volatile uint8_t led;
volatile uint8_t prev_flag;
volatile uint16_t seed;
void cocktail1(void)
{ // screwdriver
juice1=20000;
juice2=0;
juice3=0;
juice4=35000;
juice5=0;
last=4;
i=1;
}
void cocktail2(void)
{ // Daiquiri
juice1=0;
juice2=25000;
juice3=0;
juice4=0;
juice5=35000;
last=5;
i=1;
}
void cocktail3(void)
{ // Campari Orange
juice1=0;
juice2=0;
juice3=20000;
juice4=35000;
juice5=0;
last=3;
i=1;
}
void delay(uint16_t duration)
{
uint16_t w1;
uint16_t w2;
uint16_t w3;
for(w1=0;w1<duration;w1++) { for (w2=0;w2<100;w2++) { for (w3=0;w3<20;w3++)
w3++;} }
}
void s_delay(uint16_t duration)
{
uint16_t w1;
for(w1=0;w1<duration*120;) { w1++; }
}
void do_random(void)
{
uint16_t newbit;
uint8_t i;
for (i=1;i<=7;i++)
{
newbit=((seed>>15)&1) ^
((seed>>1)&1) ^
((seed )&1);
seed=(seed<<1)|newbit;
}
}
uint16_t random(uint8_t range)
{
uint8_t ret;
if (range==0) return(0);
ret=seed&127;
while (ret>range) ret=ret-range;
return (ret);
}
void play_track(uint8_t num)
{
uint8_t t;
play_on;delay(500); play_off;delay(800);
for (t=1;t< num;t++) {next_on;delay(400);next_off;delay(400);}
}
void player_off (void)
{
stop_on; delay(250);stop_off;delay(350);stop_on;delay(250);stop_off;delay(350);
}
void com_wait(int8_t s)
{
switch (s)
{
case -1: s_delay(SGAP); break;
case 0: s_delay(1); break;
default: s_delay(2); break;
}
}
void send_dimmer (uint8_t light_cmd)
{
high_send;
com_wait(light_cmd&127);
low_send;
com_wait(light_cmd&64);
high_send;
com_wait(light_cmd&32);
low_send;
com_wait(light_cmd&16);
high_send;
com_wait(light_cmd&8);
low_send;
com_wait(light_cmd&4);
high_send;
com_wait(light_cmd&2);
low_send;
com_wait(light_cmd&1);
high_send;
com_wait(light_cmd&1);
low_send;
com_wait(light_cmd&1);
high_send;
com_wait(light_cmd&1);
low_send;
com_wait(light_cmd&1);
high_send;
com_wait(light_cmd&1);
low_send;
com_wait(light_cmd&1);
high_send;
com_wait(light_cmd&1);
low_send;
com_wait(light_cmd&1);
low_send;
com_wait(-1);
}
void get_the_ice(void)
{
uint16_t dircnt,t;
dircnt=0;
delay(200);
cin=0;cin2=0;
eis_rauf_ein;
while ((cin<7) && (cin2<SURE))
{
for (t=0;t<=7;t++) {
if (eis_ok) cin++; else cin=0;
if (eis_leer) cin2++; else cin2=0;
}
dircnt++;
if (dircnt==1) eis_rauf_ein;
if (dircnt==15000) eis_rauf_aus;
if (dircnt==30000) dircnt=0;
}
eis_runter_aus;eis_rauf_aus;
cin2=1;
for (t=0;t<=SURE;t++)
{
if (eis_leer) cin2++; else cin2=0; delay(1);
}
if (cin2>=SURE)
{
cin2=0;
player_off();delay(200);play_track(5);
while (!select_3)
{
if (select_1) {eis_rauf_aus;delay(100);eis_runter_ein;}
if (select_2) {eis_runter_aus;delay(100);//eis_rauf_ein;
}
cin2++; if (cin2==6000) {cin2=0;prev_on;delay(40);prev_off;delay(40);}
if (cin2<3000) led_ein; else led_aus;
delay(2);
}
eis_runter_aus;delay(100);
next_on;delay(300);next_off;delay(300);
next_on;delay(300);next_off;delay(300);
eis_rauf_ein;
cin=0;cin2=0;dircnt=0;
while ((cin<7) && (cin2<SURE))
{
for (t=0;t<=7;t++) {
if (eis_ok) cin++; else cin=0;
if (eis_leer) cin2++; else cin2=0;
}
dircnt++;
if (dircnt==1) eis_rauf_ein;
if (dircnt==15000) eis_rauf_aus;
if (dircnt==30000) dircnt=0;
}
eis_runter_aus;eis_rauf_aus;
}
delay(2000);
eis_runter_ein;
delay(7000);
eis_runter_aus;
}
void find_next_juice(void)
{
float s;
flaschen_ein;
delay(5);
cin=0;s=0.0f;
while ((cin<SURE)&&(s<20000.0f))
{ if (!juice_pos) cin++; else cin=0;
s++;
}
delay(200);
cin=0;s=0.0f;
while ((cin<SURE)&&(s<20000.0f))
{ if (juice_pos) cin++; else cin=0;
s++;
}
flaschen_aus;
}
void get_the_juice(void)
{
if (amount!=0)
{
if (!DEMO)
{
hebel_runter_ein;
cin=0;
while (cin<SURE)
{
if (hebel) cin++; else cin=0;
}
hebel_runter_aus;
delay(amount);
hebel_rauf_ein;
delay(1000);
hebel_rauf_aus;
} else delay(10000);
}
}
void next_glass_pos(void)
{
cin=0;
while (cin<SURE)
{
if (glas_pos) cin++; else cin=0;
}
}
void leave_glass_pos(void)
{
cin=0;
while (cin<SURE)
{
if (!glas_pos) cin++; else cin=0;
}
}
void return_the_glass(void)
{
spiegel_ein;
leave_glass_pos();
delay(200);
next_glass_pos();
spiegel_aus;
for (i=1;i<3;i++)
{
led_ein;
delay(200);
led_aus;
delay(200);
}
}
void inserted(void)
{
for (x=1;x<4;x++)
{
led_ein;
delay(50);
led_aus;
delay(50);
}
}
void cocktail_loop(void)
{
uint16_t ptime,stime;
seed=11;
while (1)
{
send_dimmer(set_speed + 4);
send_dimmer(set_start);
no_glass=0;
if (select_1)
{
while(!select_3)
{
if (select_1) eis_runter_ein; else eis_runter_aus;
if (select_2) eis_rauf_ein; else eis_rauf_aus;
}
}
led=1;
act_pos = 0;
c=0;
led_ein;
if (!DEMO) play_track(1);
ptime=0;i=0;stime=14;prev_flag=0;
while ((c<COINS)&&(!DEMO))
{
for (i=1;i<20000; i++)
{
if ((coin)||(select_2))
{
inserted();
prev_off;
delay(300);
next_on; delay(300); next_off;
c=c+1;if (c==COINS) i=20000;
stime=7;
}
do_random();
}
if (led==0) {led=1; led_ein;} else {led=0;led_aus;}
stime--;
if (prev_flag==1) {prev_off;prev_flag=0;}
if (stime==0)
{
prev_on; prev_flag=1;
if (c==0) stime=14; else stime=7;
}
}
delay(300);
// next_on;delay(40);next_off;delay(40);
led_ein;
i=0;ptime=0;
while (i==0)
{
if (select_1) cocktail1();
if (select_2) cocktail2();
if (select_3) cocktail3();
delay(1);ptime++;
if ((ptime==10000)&&(!DEMO)){ptime=0;prev_on;delay(40);prev_off;delay(40);}
}
send_dimmer(cmd_up);
delay(260);
led_ein;
if (!DEMO)
{for (actsound=1; actsound<=(3+random(SOUNDS)); actsound++) {next_on;delay(300);next_off;delay(300);}}
else { spiegel_ein;
actsound=DEMOSOUND; play_track(DEMOSOUND); spiegel_aus;}
if (!DEMO)
{
glasband_ein;
next_glass_pos();
delay(20);
leave_glass_pos();
spiegel_ein;
delay(1500);
glasband_aus;
}
else { delay(1000); spiegel_ein;}
send_dimmer(cmd_up);
next_glass_pos();
delay(850);
spiegel_aus;
if (!DEMO) get_the_ice(); else delay(12000);
spiegel_ein;
leave_glass_pos();
delay(200);
next_glass_pos();
spiegel_aus;
delay(7500);
spiegel_ein;
leave_glass_pos();
send_dimmer(cmd_up);
next_glass_pos();
delay(1500);
spiegel_aus;
for (act_pos=0;act_pos<=4;act_pos++)
{
find_next_juice();
switch (act_pos)
{
case 0: amount=juice1;break;
case 1: amount=juice2;break;
case 2: amount=juice3;break;
case 3: amount=juice4;break;
case 4: amount=juice5;break;
}
delay(200);
get_the_juice();
}
flaschen_ein;
delay(5);
cin=0;
while (cin<SURE)
{ if (!juice_pos) cin++; else cin=0;
}
delay(100);
flaschen_aus;
send_dimmer(cmd_up);
return_the_glass();
for (;actsound>3; actsound--) {prev_on;delay(300);prev_off;delay(300);}
delay(11000);
player_off();
if (eis_ok)
{
delay(1000);
play_track(6);
while (eis_ok) { delay (10000); prev_on; delay(40); prev_off; delay(40); }
player_off();
}
send_dimmer(cmd_up);
// if (DEMO) return_the_glass();
}
}
void init_ports(void)
{
//---initialize DataDirection
outp((uint8_t)(~ binconst(0,0,0,0,0,0,0,0)) ,DDRD); // 1=Input, 0=Output
outp((uint8_t)(~ binconst(0,0,0,0,0,0,0,0)) ,DDRB);
outp((uint8_t)(~ binconst(1,1,1,1,1,1,1,1)) ,DDRA);
outp((uint8_t)(~ binconst(1,0,0,0,0,0,0,0)) ,DDRC);
//---initialize Portpins (for output)/weak pullups(for inputs)
outp(0xFF,PORTA);
outp(0x80,PORTC);
outp(0x00,PORTB);
outp(0x00,PORTD);
player_off();
low_send;
delay(200);
send_dimmer(set_speed + 4);
send_dimmer(set_start);
}
int main( void )
{
init_ports();
cocktail_loop();
return(0);
}