Hallo Community,
ich habe vor kurzem eine kleine Bastelei mechanisch fertiggestellt, die
ich nun über die Ostertage gemütlich ausprogrammieren wollte. Es handelt
sich um ein Animatronisches Auge, das in eine Maske eingebaut werden
soll. Die Mechanik (zum Zeitpunkt des Videos ist die µC-schaltung noch
nicht angebracht) kann man hier sehen:
http://www.youtube.com/watch?v=ASYXJcNJUEI&feature=youtu.be
Nun Ist in der applikation oben links und oben rechts je ein mini
kondensatormikrophon angebracht. Die idee ist simpel: Wenn aus einer der
beiden Richtungen ein Lautstärkepegel überschritten wird, soll das Auge
in diese Richtung schauen.
Die schaltung etc. ist fertig und funktioniert soweit (das auge bewegt
sich super wenn ich es stur nach code auslenke). Blos bei der Umsetzung
der zwei ADWandler als Trigger habe ich derzeit Probleme. Vielleicht
liegt das an meiner Nutzung der _delay_ms utility in verbindung mit
Interrupts?
Im Folgenden ist mein Code, wie er bisher steht und NICHT funktioniert.
So geflasht wie es unten steht, kommt es zu keiner Auslenkung. Falls
jemand von euch drüberschauen könnte und mir tips oder
umstrukturierungshilfen geben könnte, würde ich mich sehr freuen!
Zum Logischen Aufbau - Ich hatte mit das so überlegt:
Es werden über die variable "adcswitch" und die mir ihr verbundene
switch-case-anweisung abwechselnd beide ADWandler ausgelesen.
Wenn das Mic, das aktuell am ADWandler-MUX hängt (initialisiert habe ich
das Mic und den ADwandler für "links") einen Pegel überschreitet, wird
eine von beiden Triggervariable (triggerleft oder triggerright)
aktiviert, die in der mainschleife dann abgefragt werden soll. Alles
weitere hier:
1 | /*************************************************************************
|
2 |
|
3 | Hardware
|
4 |
|
5 | prozessor: ATtiny13A
|
6 | clock: 9.6Mhz internal RC oscillator
|
7 |
|
8 | PIN1 RESET
|
9 | PIN2 PORTB3/ADC3 MIC1
|
10 | PIN3 PORTB4/ADC2 Eye left
|
11 | PIN4 GND
|
12 |
|
13 | PIN5 PORTB0/OC10 Eye right
|
14 | PIN6 PORTB1 Eyelid
|
15 | PIN7 PORTB2/ADC1 MIC2
|
16 | PIN8 VCC
|
17 |
|
18 | *************************************************************************/
|
19 | #include <avr/io.h>
|
20 | #include <avr/interrupt.h>
|
21 | #include <stdlib.h>
|
22 | #include <util/delay.h>
|
23 |
|
24 | // sampling frequency
|
25 |
|
26 | #define F_CPU 9.6E6
|
27 |
|
28 | static volatile uint8_t adcswitch = 0;
|
29 | static volatile uint8_t triggerleft = 0;
|
30 | static volatile uint8_t triggerright = 0;
|
31 |
|
32 | void eye_left()
|
33 | {
|
34 | PORTB &= ~(1<<PINB0);
|
35 | PORTB |= (1<<PINB4);
|
36 |
|
37 | }
|
38 |
|
39 | void eye_right()
|
40 | {
|
41 | PORTB &= ~(1<<PINB4);
|
42 | PORTB |= (1<<PINB0);
|
43 |
|
44 | }
|
45 |
|
46 | void kill_eye()
|
47 | {
|
48 | PORTB &= ~(1<<PINB4);
|
49 | PORTB &= ~(1<<PINB0);
|
50 | }
|
51 |
|
52 | void eye_lid()
|
53 | {
|
54 | PORTB |= (1<<PINB1);
|
55 | }
|
56 |
|
57 | void kill_lid()
|
58 | {
|
59 | PORTB &= ~(1<<PINB1);
|
60 | }
|
61 |
|
62 | /*************************************************************************
|
63 | adc interrupt
|
64 | *************************************************************************/
|
65 |
|
66 | SIGNAL (TIM0_OVF_vect)
|
67 | {
|
68 | uint16_t x;
|
69 |
|
70 | // read ADC
|
71 | x = ADCL;
|
72 | x += (ADCH << 8);
|
73 | x=x>>2; // ADC result with 8 bit resolution
|
74 |
|
75 | if (x>50) && (adcswitch==0))
|
76 | {
|
77 | triggerleft = 1;
|
78 | }
|
79 | if ((x>50) && (adcswitch==1))
|
80 | {
|
81 | triggerright = 1;
|
82 | }
|
83 |
|
84 |
|
85 | switch (adcswitch)
|
86 | {
|
87 | case 0:
|
88 | {
|
89 | ADMUX= (1<<MUX1); // ADC3 aktivieren
|
90 | adcswitch = 1;
|
91 | break;
|
92 | }
|
93 | case 1:
|
94 | {
|
95 | ADMUX= (0<<MUX1); // ADC1 aktivieren
|
96 | adcswitch = 0;
|
97 | break;
|
98 | }
|
99 | }
|
100 |
|
101 | }
|
102 | /*************************************************************************
|
103 | main
|
104 | *************************************************************************/
|
105 | int main(void)
|
106 | {
|
107 | //************** init Timer ************************************
|
108 |
|
109 | TCCR0B=(1<<CS01) | (1<<CS00) ; // Prescaling = 64,
|
110 |
|
111 | //interrupt mask register: enable timer1 overflow
|
112 | TIMSK0 |= (1 << TOIE0);
|
113 | sei();
|
114 |
|
115 | // Ports
|
116 |
|
117 | DDRB=(1<<PINB0) | (1<<PINB1) | (1<<PINB4); // Pin 0,1,4 as output
|
118 | DDRB=(0<<PINB2) | (0<<PINB2); // Pin 2,3 as input (MIC)
|
119 |
|
120 | // ADC_Clk=F_CPU/128 ==> fs~75kHz, free runing mode
|
121 | ADCSRA = (1<<ADEN) | (1<<ADATE) |(1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);
|
122 |
|
123 | // VCC as reference and ADC1 as input
|
124 | ADMUX=(0<<REFS0) | (0<<MUX1) | (1<<MUX0);
|
125 |
|
126 | //timer0 overflow as adc trigger
|
127 | ADCSRB |= (1 << ADTS2 );
|
128 |
|
129 | // clear interrupt flag and start first conversion
|
130 | ADCSRA |= (1 << ADIF) | (1<<ADSC);
|
131 |
|
132 | while(1)
|
133 | {
|
134 |
|
135 | if (triggerleft == 1)
|
136 | {
|
137 | eye_left();
|
138 | _delay_ms(500);
|
139 | eye_lid();
|
140 | _delay_ms(50);
|
141 | kill_lid();
|
142 | _delay_ms(500);
|
143 | kill_eye();
|
144 | _delay_ms(500);
|
145 |
|
146 | triggerleft =0;
|
147 | }
|
148 |
|
149 |
|
150 |
|
151 | }
|
152 | }
|
Kann mir da jemand helfen - es läuft nicht?
Viele Grüße
Alex