Hallo! Ich möchte mir für eine Vitrine mit Pflanzen eine Anzeige basteln, die wesentliche Eigenschaften anzeigt (Luftfeuchte, Bodenfeuchte, Temperatur, Helligkeit). Dazu wollte ich den Zustand der resistiven Sensoren über einen AtMega8 auf Bargraphs anzeigen. Das ist dann zugleich mein "Debüt" mit µCs. Ich habe auch schon Schaltplan und Programm fertig und mit Proteus Isis simuliert. Scheint alles zu laufen. Da ich die Bauteile bestellen muss und nicht zweimal Porto bezahlen will, wäre es schön, wenn sich jemand das ganze mal ansehen und einen Kommentar abgeben könnte. Zum Schaltplan im Anhang: Ich bin mir nicht wirklich sicher, ob Proteus die Schaltzeichen für die Bargraphs kennt. Jedenfalls sollen das die Dinger ganz rechts sein. Unten links sind die resistiven Sensoren als Potentiometer angedeutet. Der ISP soll an die COM-Schnittstelle des Computers angeschlossen werden. Das ganze funktioniert über Multiplexing. Port D und zwei Pins von Port C geben die Daten aus und 4 Pins von Port B schalten die entsprechenden Transistoren. Ich denke, der Rest erklärt sich von alleine. Und jetzt der Quelltext (zwei Anhänge gibt es hier nicht, oder?):
1 | #include <avr/io.h> |
2 | #include <math.h> |
3 | |
4 | // Anzahl der LEDs
|
5 | volatile unsigned char LFeuchte; |
6 | volatile unsigned char BFeuchte; |
7 | volatile unsigned char Licht; |
8 | volatile unsigned char Temp; |
9 | |
10 | volatile unsigned char count; |
11 | volatile unsigned char count2; |
12 | |
13 | void Zeige(unsigned int LED, int n) |
14 | {
|
15 | if(n<0) n=0; |
16 | PORTB=0x0; |
17 | PORTD=0x0; |
18 | PORTC=0x0; |
19 | if(n>=1) PORTD |= 0x1; |
20 | if(n>=2) PORTD |= 0x2; |
21 | if(n>=3) PORTD |= 0x4; |
22 | if(n>=4) PORTD |= 0x8; |
23 | if(n>=5) PORTD |= 0x10; |
24 | if(n>=6) PORTD |= 0x20; |
25 | if(n>=7) PORTD |= 0x40; |
26 | if(n>=8) PORTD |= 0x80; |
27 | if(n>=9) PORTC |= 0x10; |
28 | if(n>=10) PORTC |= 0x20; |
29 | PORTB=LED; |
30 | }
|
31 | |
32 | void ActivateNext() |
33 | {
|
34 | switch(PORTB) |
35 | {
|
36 | case 0x40: case 0x00: |
37 | Zeige(0x01,LFeuchte); |
38 | break; |
39 | case 0x01: |
40 | Zeige(0x02,BFeuchte); |
41 | break; |
42 | case 0x02: |
43 | Zeige(0x04,Licht); |
44 | break; |
45 | case 0x04: |
46 | Zeige(0x40,Temp); |
47 | break; |
48 | }
|
49 | }
|
50 | |
51 | void Messen() |
52 | {
|
53 | volatile unsigned int U; |
54 | ADMUX = 0x00; |
55 | ADCSRA |= (1<<ADSC); //Single-Conversion |
56 | while (ADCSRA & (1<<ADSC)); // Auf Abschluss warten |
57 | U=ADCL; |
58 | U+=(ADCH<<8); |
59 | //SHS-A2
|
60 | if (U<=174) LFeuchte=0; //<50% |
61 | if (U<=250 && U>174) LFeuchte=1; //50 - 55% |
62 | if (U<=345 && U>250) LFeuchte=2; //55 - 60% |
63 | if (U<=455 && U>345) LFeuchte=3; //60 - 65% |
64 | if (U<=571 && U>455) LFeuchte=4; //65 - 70% |
65 | if (U<=681 && U>571) LFeuchte=5; //70 - 75% |
66 | if (U<=776 && U>681) LFeuchte=6; //75 - 80% |
67 | if (U<=851 && U>776) LFeuchte=7; //80 - 85% |
68 | if (U<=907 && U>851) LFeuchte=8; //85 - 90% |
69 | if (U<=946 && U>907) LFeuchte=9; //90 - 95% |
70 | if (U>=946) LFeuchte=10; //>95% |
71 | |
72 | ADMUX = 0x01; |
73 | ADCSRA |= (1<<ADSC); //Single-Conversion |
74 | while (ADCSRA & (1<<ADSC)); // Auf Abschluss warten |
75 | U=ADCL; |
76 | U+=(ADCH<<8); |
77 | if (U>877) BFeuchte=0; //60 kR |
78 | if (U<=877 && U>866) BFeuchte=1; //60-55 kR |
79 | if (U<=866 && U>853) BFeuchte=2; //55-50 kR |
80 | if (U<=853 && U>837) BFeuchte=3; |
81 | if (U<=837 && U>818) BFeuchte=4; |
82 | if (U<=818 && U>796) BFeuchte=5; |
83 | if (U<=796 && U>767) BFeuchte=6; |
84 | if (U<=767 && U>731) BFeuchte=7; |
85 | if (U<=731 && U>682) BFeuchte=8; |
86 | if (U<=682 && U>614) BFeuchte=9; |
87 | if (U<=614) BFeuchte=10; |
88 | |
89 | |
90 | ADMUX = 0x02; |
91 | ADCSRA |= (1<<ADSC); //Single-Conversion |
92 | while (ADCSRA & (1<<ADSC)); // Auf Abschluss warten |
93 | U=ADCL; |
94 | U+=(ADCH<<8); |
95 | //Die folgenden Werte sind noch nicht angepasst
|
96 | if (U>877) Licht=0; |
97 | if (U<=877 && U>866) Licht=1; |
98 | if (U<=866 && U>853) Licht=2; |
99 | if (U<=853 && U>837) Licht=3; |
100 | if (U<=837 && U>818) Licht=4; |
101 | if (U<=818 && U>796) Licht=5; |
102 | if (U<=796 && U>767) Licht=6; |
103 | if (U<=767 && U>731) Licht=7; |
104 | if (U<=731 && U>682) Licht=8; |
105 | if (U<=682 && U>614) Licht=9; |
106 | if (U<=614) Licht=10; |
107 | |
108 | ADMUX = 0x03; |
109 | ADCSRA |= (1<<ADSC); //Single-Conversion |
110 | while (ADCSRA & (1<<ADSC)); // Auf Abschluss warten |
111 | U=ADCL; |
112 | U+=(ADCH<<8); |
113 | if (U>630) Temp=0; //kleiner 15 Grad |
114 | if (U<=630 && U>619) Temp=1; // 15 bis 16 Grad |
115 | if (U<=619 && U>608) Temp=2; // 16 bis 17 Grad |
116 | if (U<=608 && U>597) Temp=3; // 17 bis 18 Grad |
117 | if (U<=597 && U>585) Temp=4; // 18 bis 19 Grad |
118 | if (U<=585 && U>574) Temp=5; // 19 bis 20 Grad |
119 | if (U<=574 && U>562) Temp=6; // 20 bis 21 Grad |
120 | if (U<=562 && U>551) Temp=7; // 21 bis 22 Grad |
121 | if (U<=551 && U>539) Temp=8; // 22 bis 23 Grad |
122 | if (U<=539 && U>528) Temp=9; // 23 bis 24 Grad |
123 | if (U<=528) Temp=10; // über 24 Grad |
124 | }
|
125 | |
126 | int main (void) { |
127 | DDRD = 0xff; |
128 | DDRB = 0x47; //01000111 |
129 | DDRC = 0x30; //00110000 |
130 | ADCSRA = 0xc7; //11000111, ADC aktivieren |
131 | |
132 | TCCR0 = (1<<CS00)|(1<<CS02); //Prescaler 1024 |
133 | |
134 | while(1) |
135 | {
|
136 | if(TCNT0 == 0xff) // alle 1.024 ms |
137 | {
|
138 | count++; |
139 | if(count==4) //getestet mit count == 50 |
140 | {
|
141 | count2++; |
142 | ActivateNext(); |
143 | count = 0; |
144 | }
|
145 | if(count2==200) //getestet mit count2 == 1 |
146 | {
|
147 | Messen(); |
148 | count2=0; |
149 | }
|
150 | }
|
151 | }
|
152 | |
153 | return 0; |
154 | }
|
Also in der Hauptschleife werden zum einen die Anzeigen aktualisiert (ca. 60 Hz pro Anzeige). Und zum anderen werden in regelmäßigen Abständen (ca. 1 s) neue Messungen durchgeführt. Da bei der Simulation die CPU ziemlich belastet wird, habe ich nicht mit voller Geschwindigkeit getestet, sondern mit den in den Kommentaren angegebenen Werten ("getestet mit..."). Vielleicht findet ja jemand ein paar Minuten Zeit, sich die ganze Sache mal anzusehen. Danke schonmal im Voraus. Nico