Guten Tag, ich habe in letzter Zeit ein paar Experimente an einem Attiny85 gemacht. Mein Plan ist, dass ich Feuchtigkeitswerte von meinen Pflanzen übertrage mittels einen RF433 MHZ Sender. Zudem soll noch der Akkuwert und der Temperaturwert (jeweils 10 Bit Werte) übertragen werden. So, das ganze funktioniert auch schon mit den übertragen und empfangen der Werte. Nur ich bin mir nicht sicher, ob mein Schaltplan "ausgereift" ist. Zudem soll es auch Stromgünstig laufen (Knopfzelle im Blumentopf von 3V nur ~1x im Jahr wechseln). Ich bräuchte ein paar Experten, die über meinen Schaltplan gucken. Kurze Erklärung: - PC0 ist ein Ausgang, der alle ca. 10 Min aktiv ist. Gibt 3V aus, wartet ca 200ms und sendet die Werte über das 433MHZ Modul. - PB1 ist der digitale Ausgang für das 433MHZ Modul - PB2 ist mein "roher" 10Bit Temperaturwert. Wird beim Empfangen des Wertes umgerechnet. - PB3 ist mein Feuchtigketiswert (10 Bit). Ein Wiederstand geht auf GND und zwei Drähte werden in der Erde einen bestimmten Widerstand haben. - PB4 ist mein Akkuwert - da bin ich mir unschlüssig, ob das so gemacht wird. Code usw. werde ich später auf mein Blog dafür auch veröffentlichen. Ich bin nämlich kein Elektrioniker sondern Informatiker. Daher weiß ich, dass der Code richtig sein sollte ;-) Danke und viele Grüße!
funktioniert das Messen der Akkuspannung so wirklich? Ich denke da fehlt ein Widerstand für einen Spannungsteiler. Wenn du den ADC so einstellst das Vref=VCC ist dann misst du immer 100 %. Die Referenz sollte also auf 2,56 V oder sogar 1,1 V eingestellt werden und der Spannungsteiler so berechnet werden das die max. Eingangsspannung unter der Ref liegt. Dann findest du hier im Forum noch einen alternativen Feuchtesensor der kapazitiv arbeitet, halt also den Vorteil das da keine Kontakte korrodieren können. In deinem Schaltplan fehlt sonst nur noch ein 100 nF Keramikkondensator zwischen VCC und GND.
Hallo, beim Akkuwert habe ich auch noch Probleme. Wie kann ich die Referenzspannung denn für den IC einstellen? Bekommt er seine Referenzspannung von NRES? Oder vom 3V (von PB0) ein Widerstand nach PB4? Den Kondensator könnte ich noch einbauen. Danke. Werde mir noch den kapazitiven Sensor hier im Forum angucken. Am Strom kann man nicht sparen, wenn man beim Attiny85 auf "internal 1MHZ Clock" programmiert und dann ca. alle 10min oder mehr, oder? Oder wäre ein Zeitgeber IC, wie der NE555 noch Stromgünstiger? Gruß
:
Bearbeitet durch User
Hi Da der Sensor mit Gleichspannung läuft ist (auf Dauer) mit Elektrolyse zu rechnen. MfG Spess
jup, darum auch den Tip von Jojo.. Kapazitiven Sensor
Hallo, wäre es vielleicht möglich mal in den Code reinzuschauen? Schlagen uns seit Wochen damit rum einen Funkschalter zu bauen mit jeweils einem Attiny85 an jedem Ende. Das Ganze soll einen Code senden und am anderen Ende empfangen. Wenn der Code mit dem einprogrammierten übereinstimmt soll der Schalter ausgelöst werden. Sowas gibts auch schon massig, aber alles für Arduino. Hatten bisher keinen Erfolg was umzuschreiben und unsere eigenen mühsamen Versuche hatten nur eine geringe Erfolgsrate von 10% oder so. Wäre wirklich hilfreich da mal was funktionierendes zu sehen. :) MFG D.S.
MoinMoin, Daniel Gronewold schrieb: > beim Akkuwert habe ich auch noch Probleme. > ...zum Thema messen der Akku-Spannung schaue dir mal das Manual der MCU an. Auch bei einem Attiny85 sollte es funktionieren, dass man die Höhe der Versorgungsspannung indirekt über die Bandgap-Spannung ermitteln kann. Ich habe dieses Verfahren auch für eine meiner Funkbrücken verwendet: http://bralug.de/wiki/RFM12-Funkbr%C3%BCcke#Versorgungsspannung_Sender_ermitteln Grüße Uwe
Hallo, ich habe die Arduino-Software genommen. Du brauchst das Board dazu nicht! Die Software lässt sich leicht installieren (bei mir Win7 x86). Spielt aber keine Rolle, da es für fast alle Betriebssysteme ein Treiber gibt. Das AMTEL Studio war mir zu aufgeblasen. Ich wollte ja nur den Attiny programmieren. Schritte: - Software herunterladen (momentan 1.0.6): http://arduino.cc/en/Main/Software - Treiber (Jungo-USB) installieren für das Programmierboard (Bei mir Diamex All-AVR Programmer / ERFOS-ISP-2): http://sourceforge.net/projects/libusb-win32/ - Nun nur noch den verwendeten Microkontroller raussuchen (bei Arduino unter Tools -> Board) auswählbar: http://highlowtech.org/?p=1695 (Anleitung befolgen) fertig! Hier mein Code:
1 | #include <avr/sleep.h> |
2 | |
3 | //clear bit macro
|
4 | #ifndef cbi
|
5 | #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
|
6 | #endif
|
7 | |
8 | //set bit macro
|
9 | #ifndef sbi
|
10 | #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
|
11 | #endif
|
12 | |
13 | int groni_code = 817; // Buchstaben 'HAG' |
14 | int nPulseLength = 101; // Definiert von DG |
15 | unsigned long m_w = 1; |
16 | unsigned long m_z = 2; |
17 | |
18 | int watchdog_counter = 10; // hauptsache hoch, damit beim ersten mal ausgeführt wird |
19 | int first_wait = 0; |
20 | |
21 | #define PIN_STROM 0
|
22 | #define PIN_SEND 1
|
23 | |
24 | |
25 | #define PIN_FEUCHT 3
|
26 | #define ANALOG_FEUCHT 3
|
27 | |
28 | #define PIN_TEMP 2
|
29 | #define ANALOG_TEMP 1
|
30 | |
31 | #define PIN_AKKU 4
|
32 | #define ANALOG_AKKU 2
|
33 | |
34 | |
35 | #define IC_CODE 255 // 0-FF -> 255 ICs möglich!
|
36 | #define WAIT_TO_SEND 600 // in Sekunden
|
37 | #define WAIT_DELAY_FIRST 50 // in ms
|
38 | #define WAIT_DELAY_END 20 // in ms
|
39 | |
40 | |
41 | void transmit(int nHighPulses, int nLowPulses) { |
42 | digitalWrite(PIN_SEND, HIGH); |
43 | delayMicroseconds(nPulseLength * nHighPulses); |
44 | digitalWrite(PIN_SEND, LOW); |
45 | delayMicroseconds(nPulseLength * nLowPulses); |
46 | }
|
47 | |
48 | |
49 | unsigned long getRandom() |
50 | {
|
51 | m_z = 36969L * (m_z & 65535L) + (m_z >> 16); |
52 | m_w = 18000L * (m_w & 65535L) + (m_w >> 16); |
53 | return (m_z << 16) + m_w; /* 32-bit result */ |
54 | }
|
55 | |
56 | void setup() { |
57 | // Set up FAST PWM
|
58 | TCCR0A = 2<<COM0A0 | 2<<COM0B0 | 3<<WGM00; // Set control register A for Timer 0 |
59 | TCCR0B = 0<<WGM02 | 1<<CS00; // Set control register B for Timer 0 |
60 | TCCR1 = 0<<PWM1A | 0<<COM1A0 | 1<<CS10; // Set control register for Timer 1 |
61 | GTCCR = 1<<PWM1B | 2<<COM1B0; // General control register for Timer 1 |
62 | |
63 | pinMode(PIN_STROM, OUTPUT); |
64 | pinMode(PIN_AKKU, INPUT); |
65 | pinMode(PIN_TEMP, INPUT); |
66 | pinMode(PIN_FEUCHT, INPUT); |
67 | pinMode(PIN_SEND, OUTPUT); |
68 | |
69 | setup_watchdog(6); // approximately 1 seconds sleep |
70 | }
|
71 | |
72 | void system_sleep() { |
73 | cbi(ADCSRA,ADEN); // switch Analog to Digitalconverter OFF |
74 | set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here |
75 | sleep_enable(); |
76 | sleep_mode(); // System actually sleeps here |
77 | sleep_disable(); // System continues execution here when watchdog timed out |
78 | sbi(ADCSRA,ADEN); // switch Analog to Digitalconverter ON |
79 | |
80 | |
81 | }
|
82 | |
83 | void loop() { |
84 | int wait_send; |
85 | int fs_in = 0; |
86 | int temp_in = 0; |
87 | int paritaet = 0; |
88 | int akku_in = 0; |
89 | int i = 0; |
90 | |
91 | // wenn man den Akku reinsteckt, soll der Attiny für 1min in 10 Sekunden schritten senden
|
92 | // danach normal
|
93 | if(first_wait < 7) { |
94 | wait_send = 10; // alle 10 sekunden; |
95 | } else { |
96 | wait_send = WAIT_TO_SEND; |
97 | }
|
98 | |
99 | if(watchdog_counter >= wait_send) { |
100 | |
101 | digitalWrite(PIN_STROM, HIGH); // Spannung an |
102 | delay(WAIT_DELAY_FIRST); // - danach ein Delay zum einpendeln |
103 | |
104 | akku_in = analogRead(ANALOG_AKKU); |
105 | temp_in = analogRead(ANALOG_TEMP); |
106 | fs_in = analogRead(ANALOG_FEUCHT); |
107 | |
108 | transmit(1, 0); // Start |
109 | |
110 | transmit(1, 3); // Damit der Receiver weiß, wie lang eine '0' ist |
111 | transmit(3, 1); // Damit der Receiver weiß, wie lang eine '1' ist |
112 | |
113 | for(i = 9; i >= 0; i--) { // 9 Bits takes the 'groni_code' |
114 | if(((groni_code >> i) & 1)) { |
115 | transmit(3, 1); |
116 | paritaet = (paritaet+1) % 2; // Parität ausrechnen.. Im Anschluss mitsenden |
117 | } else { |
118 | transmit(1, 3); |
119 | }
|
120 | }
|
121 | |
122 | if(paritaet) { |
123 | transmit(3, 1); |
124 | } else { |
125 | transmit(1, 3); |
126 | }
|
127 | paritaet = 0; |
128 | |
129 | for(i = 7; i >= 0; i--) { // 8 Bits takes the 'ic-code' |
130 | if(((IC_CODE >> i) & 1)) { |
131 | transmit(3, 1); |
132 | paritaet = (paritaet+1) % 2; |
133 | } else { |
134 | transmit(1, 3); |
135 | }
|
136 | |
137 | }
|
138 | |
139 | if(paritaet) { |
140 | transmit(3, 1); |
141 | } else { |
142 | transmit(1, 3); |
143 | }
|
144 | paritaet = 0; |
145 | |
146 | for(i = 9; i >= 0; i--) { // 10 Bits takes the 'feucht_sensor' |
147 | if(((fs_in >> i) & 1)) { |
148 | transmit(3, 1); |
149 | paritaet = (paritaet+1) % 2; |
150 | } else { |
151 | transmit(1, 3); |
152 | }
|
153 | }
|
154 | |
155 | if(paritaet) { |
156 | transmit(3, 1); |
157 | } else { |
158 | transmit(1, 3); |
159 | }
|
160 | paritaet = 0; |
161 | |
162 | for(i = 9; i >= 0; i--) { // 10 Bits takes the 'tempeartatur_sensor' |
163 | if(((temp_in >> i) & 1)) { |
164 | transmit(3, 1); |
165 | paritaet = (paritaet+1) % 2; |
166 | } else { |
167 | transmit(1, 3); |
168 | }
|
169 | }
|
170 | |
171 | if(paritaet) { |
172 | transmit(3, 1); |
173 | } else { |
174 | transmit(1, 3); |
175 | }
|
176 | paritaet = 0; |
177 | |
178 | |
179 | for(i = 9; i >= 0; i--) { // 10 Bits takes the 'akku_sensor' |
180 | if(((akku_in >> i) & 1)) { |
181 | transmit(3, 1); |
182 | paritaet = (paritaet+1) % 2; |
183 | } else { |
184 | transmit(1, 3); |
185 | }
|
186 | }
|
187 | |
188 | if(paritaet) { |
189 | transmit(3, 1); |
190 | } else { |
191 | transmit(1, 3); |
192 | }
|
193 | paritaet = 0; |
194 | //transmit(0,99); // sendSync muss ungerade sein!
|
195 | |
196 | |
197 | delay(WAIT_DELAY_END); // - danach ein Delay, falls er nochwas macht |
198 | digitalWrite(PIN_STROM, LOW); // Spannung aus |
199 | |
200 | watchdog_counter = 0; |
201 | first_wait++; |
202 | |
203 | }
|
204 | //delay(WAIT_TO_SEND+((int)getRandom()%100)); // falls 2 ICs gleichzeitig senden.. Das muss nicht sein
|
205 | system_sleep(); |
206 | |
207 | }
|
208 | |
209 | // 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms
|
210 | // 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
|
211 | void setup_watchdog(int ii) { |
212 | |
213 | byte bb; |
214 | int ww; |
215 | if (ii > 9 ) ii=9; |
216 | bb=ii & 7; |
217 | if (ii > 7) bb|= (1<<5); |
218 | bb|= (1<<WDCE); |
219 | ww=bb; |
220 | |
221 | MCUSR &= ~(1<<WDRF); |
222 | // start timed sequence
|
223 | WDTCR |= (1<<WDCE) | (1<<WDE); |
224 | // set new watchdog timeout value
|
225 | WDTCR = bb; |
226 | WDTCR |= _BV(WDIE); |
227 | }
|
228 | |
229 | ISR(WDT_vect) { |
230 | watchdog_counter++; |
231 | }
|
Ich werde aber eventuell die Ansteuerung mit VirtuelWire.h machen, da es anscheinend zuverlässiger funktioniert. Gruß!
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.