Forum: Mikrocontroller und Digitale Elektronik Animatronic Eye (mit Video): Hilfe beim Code für AtTiny13A


von Alex V. (bastel_alex) Benutzerseite


Lesenswert?

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

von Alex V. (bastel_alex) Benutzerseite


Lesenswert?

Hilfe?
Zu viel code?

von Klumpfuß Tee Feuergeschrei (Gast)


Lesenswert?

Alex v. L. schrieb:
> Hilfe?
> Zu viel code?

Alex v. L. schrieb:
> if (x>50) && (adcswitch==0))

Das geht durch den Compiler?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.