Hallo zusammen! Ich bin Anfänger auf dem Gebiet der Programmierung. Ich habe eine Schaltung die Feuchte misst. Das geschieht in einer Endlosschleife wo je nach ADC Wert ein rotes, gelbes oder grünes LED leuchtet oder auch blinkt. Ich möchte ganze Sache jetzt mit einem Taster an- und ausschalten da die Schaltung durch eine 3 V Batterie versorgt wird. Ich dachte dabei an Power-Down. Dazu habe ich einen Taster an meinen ATtiny 24V angeschlossen. Er geht von PB2-Pin (INT0) auf Ground. Ebenso habe ich den Pin auf Eingang gesetzt und mit einem Pull-Up Widerstand auf High gelegt (DDRB |= (0 << PB2); PORTB |= (1 << PB2);). Ich muss ja als nächstes Eingriffe auf meine Register machen, Interrupts zulassen und das Sleep oben includen. Dann werde ich ja auch die Interruptserviceroutine ISR(INT0_vect) benötigen. Was muss ich beim MCUCR Register für Einstellungen vornehmen? BODS und BODSE?? Brown out detection. Muss ich da was auf 1 setzen? Sleep enable auf 1 ist klar und die Bits für Power-down auch. ISC01 und 00 werde ich wohl auf falling edge einstellen da mein Taster einen Ground Impuls gibt. In GIMSK muss ich für INT0 ne 1 setzen und wohl auch für Pin change Interrupt 1. Also die Pins PCINT11...8 (INT0 = PCINT10). In GIFR werde ich wohl auch INTF0 und PCIF1 auf eins setzen. Wie bringe ich das dann alles so in den code ein oder ist das alles wesentlich schwieriger als ich mir das vorstelle. Bei einem Tastendruck muss ich den Controller ja schlafen legen aber dazu wieder INT0 scharfmachen irgendwie. Wenn dann wieder gedrückt wird muss er wieder aufwachen. Danke für eure Hilfe im voraus! Gruß Th.
Bastler schrieb: > ISC01 und 00 werde ich wohl auf *falling* > edge einstellen da mein Taster einen Ground Impuls gibt. Dann wacht der schlafende Attiny nicht auf Tastendruck auf. In dem anderen Thread von dir hatte ich darauf hingewiesen, dass für das Aufwecken bestimmte Voraussetzungen an den External Interrupt gestellt werden. Der Interrupt löst bei einem LOW oder HIGH Level am Pin aus, nicht bei einer Flanke.
Stefan B. schrieb: > Der Interrupt löst bei einem LOW oder HIGH Level am Pin aus, > nicht bei einer Flanke. Korrektur: Nur bei LOW! In meinem Suppentimer habe ich einmal falling edge benutzt. Das ist aber die Codevariante SLEEP_CODE 2, d.h. Simulation, bei der der µC nicht tatsächlich in den Sleep Modus versetzt wird und bei der das Aufwecken mit einem Tastendruck und externem Interrupt getestet wird.
Ja aber zum einschlafen müßte das mit Falling Edge ja funktionieren. Zum Aufwachen ist klar da braucht er den Low Level. Ich habe mal versucht ein Programm einzugeben. Ich denke mal das ist noch nicht komplett aber vielleicht mal ein Anfang!
Versuche das schrittweise anzugehen. Zuerst ein Progrämmchen bei dem du siehst, ob der µC läuft. So wie mein Blinky Programm. Dann eine Tasterabfrage mit Pollen. So wie mein Tasty oder Zähler Programm. Dabei kannst du anschliessend ein Schlafen/Wecken simulieren. Damit bekommst du ein Gefühl, was Programmzustände sind und wie du definiert immer von einem Zustand zum nächsten kommst. Dann die Tastenabfrage statt mit Pollen mit externem Interrupt machen, so wie beim Suppentimer bei SLEEP_CODE 2. Damit bekommst du ein Gefühl für parallel stattfindene Prozesse also Userprogramm/Interruptroutine und Interrupts überhaupt. Dann den Sleepmodus verwenden.
Ich habe schon bei einem Programm ein Problem das den Schalter abfragt damit die LED leuchtet. Das müßte doch den Schalter abfragen ob 0 anliegt. #include <avr/io.h> #include <avr/interrupt.h> #include <avr/wdt.h> #include <stdint.h> #include <avr/sleep.h> int main(void) { DDRB |= (1 << PB1); PORTB |= (1 << PB1); DDRB |= (0 << PB2); PORTB |= (1 << PB2); CLKPR = 0x83; wdt_disable(); sei(); while(1) { if(!(PINB & (0 << PINB2)) { PORTB |= (0 << PB1); } } }
Das mit dem Taster und Power-Down geht prima. Allerdings ist nicht das Power-Down das Hauptproblem. Das A und O ist erstmal eine einwandfrei funktionierende Entprellroutine! Dann muß man nur noch das Sleep als Aktion auf den Tastendruck hinzufügen. Natürlich erst, nachdem "Taste losgelassen" festgestellt wurde. Hier mal ein Beispiel: Beitrag "Re: attiny13 aufwecken aus power down modus" Peter
Das sieht schon extrem lang aus dieses Programm. Läßt sich auch wohl nicht einfacher abarbeiten befürchte ich. Das ist natürlich jetzt erst mal nur sehr schwer zu verstehen für mich. Das mit dem Entprellen sieht mir schon fast am schwierigsten aus.
Tip: Gewöhn dir Kommentare in deinem Programm an, besonders wenn du "exotische" Sachen machst.
1 | #include <avr/io.h> |
2 | #include <avr/interrupt.h> |
3 | #include <avr/wdt.h> |
4 | #include <stdint.h> |
5 | #include <avr/sleep.h> |
6 | |
7 | int main(void) |
8 | {
|
9 | /*
|
10 | The ATtiny24/44/84 system clock can be divided by setting the
|
11 | “CLKPR – Clock Prescale Register”. This feature can be used to
|
12 | decrease power consumption when the requirement for processing
|
13 | power is low.
|
14 | |
15 | (1<<CLKPS1) | (1<<CLKPS0): Clock Division Factor 8
|
16 | |
17 | Beispiel:
|
18 | Interner RC Oszillator 8 MHz
|
19 | CKDIV8 Fuse ab Werk programmiert: 8 MHz / 8 = 1 MHz
|
20 | CLKPR wie unten gesetzt: 1 MHz / 8 = 125 kHz
|
21 | */
|
22 | CLKPR = (1<<CLKPCE) | (1<<CLKPS1) | (1<<CLKPS0); // 0x83 |
23 | |
24 | // Hardware: Active-low geschaltete LED inkl. Vorwiderstand
|
25 | // zwischen PB1 und Vcc
|
26 | DDRB |= (1 << PB1); // Bit setzen: Pin PB1 als Ausgang |
27 | PORTB |= (1 << PB1); // Bit setzen: Ausgabe HIGH: LED aus (active-low) |
28 | |
29 | // Hardware: Im Ruhezustand offener Taster zwischen PB2 und GND
|
30 | DDRB &= ~(1 << PB2); // Bit löschen: Pin PB2 als Eingang |
31 | PORTB |= (1 << PB2); // Interner Pullup eingeschaltet |
32 | |
33 | // Sehe keinen Sinn in diesen Anweisungen in diesem Programm
|
34 | // wdt_disable();
|
35 | // sei();
|
36 | |
37 | while(1) |
38 | {
|
39 | if(!(PINB & (1 << PINB2)) // gedrückt? |
40 | {
|
41 | // ja => Bit löschen: Ausgabe LOW: LED an (active-low)
|
42 | PORTB &= ~(1 << PB1); |
43 | }
|
44 | else
|
45 | {
|
46 | // nein => Bit setzen: Ausgabe HIGH: LED aus (active-low)
|
47 | PORTB |= (1 << PB1); |
48 | }
|
49 | }
|
50 | }
|
Die nächsten Aufgaben sind: 1. Abfrage des Tasters in eine Funktion packen. Später kann man dann die Funktion durch ein anderes Verfahren austauschen oder erweitern (Entorellung!) und das getestete Hauptprogramm in Ruhe lassen. 2. Den Zustand der Taste merken und somit die Funktion eines Tasters in die Funktion eines Schalters ändern. Das Drücken ändert dann den Schaltzustand. Du wirst beim Spielen damit merken, dass Tasterprellen dein Programm stört. 3. Deswegen: In den Code mit der Tasterfunktion eine Entprellung einbauen. Das einfachste Verfahren ist ein Warteschleifenverfahren wie im Artikel Entprellung. Später wenn du sowieso Interrupts laufen hast, solltest du vom Warteschleifenverfahren zur Entprellung im Timerinterrupt wechseln.
Danke für diese Hilfe. Heißt das, dass ich meinen ATtiny im Moment auf 125 kHz getaktet habe??? Das verstehe ich jetzt nicht ganz?! Nach einiger Überlegung habe ich jetzt geschafft dass mein LED aufleuchtet wenn mein Taster gedrückt ist. Das ist schon mal wunderbar. Als nächstes soll ich die Abfrage des Tasters in eine Funktion packen. Das heißt dass in meinem Sensorprogramm dann nur noch ein Funktionsaufruf steht und nicht mehr der ganze Code. Die Tatsache dass erst das Auslassen des Tasters zu einer Änderung führt gehört schon zum Entprellen oder??? Gruß Th.
Bastler schrieb: > Danke für diese Hilfe. Heißt das, dass ich meinen ATtiny im Moment auf > 125 kHz getaktet habe??? Das verstehe ich jetzt nicht ganz?! Für mich sieht der Code so aus. Ich kannte die Zeile CLKPR = 0x83; nicht und habe mir den Kommentar oben im Datenblatt zusammengesucht. > Die Tatsache dass > erst das Auslassen des Tasters zu einer Änderung führt gehört schon zum > Entprellen oder??? Genaugenommen noch nicht. Ich hole etwas aus... Wenn du den Taster zum Schalter machen willst, ist die Arbeitsweise ja so. Du drückst den Taster und lässt ihn los. Beim 1. Mal entspricht das dem Befehl Einschalten. Dann die gleiche Tasterbetätigung nochmal und dann entspricht das der Arbeitsweise Ausschalten, weil das System ja vorher eingeschaltet war. Usw. Ohne eine Behandlung der prellenden Taste wirst du mit obigem Verfahren rasch sehen, dass du wild die EIN/AUS Zustände wechselst wo du es nicht willst. Die federnden Tastekontakte bringen beim Drücken und beim Loslassen rasch hintereinander Kontakt/Kein Kontakt und der Schaltzustand springt wild um. Das Entprellen kannst du aber in die zu schreibende Funktion einbauen. Z.B. indem du nach einem vermuteten Ereignis (z.B. LOW an PB2) eine Zeit (paar zig Millisekunden) wartest und dann prüfst ob das Ereignis tatsächlich noch anliegt. Hier liegt auch die Vorteile, die Tastenabfrage in eine zentrale Funktion zu packen: Du hast den Entprellcode einmal zentral bei der Abfrage an sich und nicht kompliziert in einem if-Fall oder sogar an mehreren Stellen in der Arbeitsschleife (while(1)...) verstreut.
Danke! 3 hex heißt für mich hald 0011. Darum dachte ich ok der Teiler 8 ist aktiviert. Defaultmäßig ist der Controller ja mit 8 MHZ getaktet. Bit 7 muss auch auf eins sein da die Teiler sonst überhaupt nicht aktiv sind. Daher der Code 0x83. Ich habe jetzt einfach mal versucht einen Code zu schreiben. In meinen Augen müßte mein Taster jetzt wie ein Schalt arbeiten. Leider ist noch ein Fehler in meinem Programm: ../Schalter.c:47: error: expected declaration or statement at end of input make: *** [Schalter.o] Error 1 Ich weiss dass ich das Entprellen noch gar nicht berücksichtigt habe. Wollte einfach nur mal schaun dass ich so weit komme. Wie ich das mit der Funktion schaffe in meiner eigentlichen Main weiss ich noch nicht. Habe ja bei meinem ATtiny 24V das Problem dass ich nicht direkt debuggen kann. Kann es ja nur über den Simulator vom AVR Studio testen. DA haben schon einige gesagt dass sowas nicht ideal ist aber es geht nicht mehr anders. Noch eine andere Sache. Ich wollte bei meiner Schaltung ja einen Batteriewächter realisieren. Das ist ja leider etwas komplexer. Über einen Spannungsteiler auf den AD Wandler geht leider schwer. Z-Diode und dann Komperator ist auch blöd. Über diesen Reset Controller weiss ich rein gar nichts. Es gibt doch solche Bausteine die Bandgap reference device oder so heißen. Die bringen mir ja wenn ich sie mit 3V Batteriespannung versorge stabil z.B. 2 V. Sprich da könnte ich dann mit einem Komperator arbeiten. Allerdings muss ich natürlich auch stark Strom sparen. Ist das empfehlenswert?
Bastler schrieb: > Danke! > 3 hex heißt für mich hald 0011. Darum dachte ich ok der Teiler 8 ist > aktiviert. Defaultmäßig ist der Controller ja mit 8 MHZ getaktet. Bit 7 > muss auch auf eins sein da die Teiler sonst überhaupt nicht aktiv sind. > Daher der Code 0x83. Lies mal was im Datenblatt zur CKDIV8 Fuse steht und lies den Zustand bei deinem Attiny mal aus...
> Schalter.txt
Quellcode hängt man nie als .txt an. Wenn man Quellcode als .c
(C-Source) anhängt, bekommt man eine schöne, übersichtliche Formatierung
Da hast du wohl recht. Bei CKDIV8 ist ein Häkchen drin. Das heißt der 8er Teiler ist wohl wirklich schon ausgewählt und das Ding läuft auf 1 MHz. Wenn man das so richtig interpretiert.
Die Fehlermeldung ist wahrscheinlich die fehlende } vom while. Das sind aber Fehler, die man auch als Anfänger selbst suchen und finden sollte ;-) Ich meinte die Auslagerung in eine Funktion so:
1 | #include <avr/io.h> |
2 | |
3 | #define NIX 2
|
4 | #define EIN 1
|
5 | #define AUS 0
|
6 | |
7 | #define LED_EIN() (PORTB &= ~(1 << PB1))
|
8 | #define LED_AUS() (PORTB |= (1 << PB1))
|
9 | |
10 | |
11 | unsigned char taster_abfrage(void) |
12 | {
|
13 | static unsigned char zustand = AUS; |
14 | unsigned char ret = NIX; |
15 | |
16 | // Eingabe holen
|
17 | if((!(PINB & (1 << PINB2))) |
18 | {
|
19 | // auf das Loslassen warten
|
20 | while(!(PINB & (1 << PINB2))); |
21 | |
22 | // Verarbeiten
|
23 | if (zustand == EIN) |
24 | zustand = AUS; |
25 | else
|
26 | zustand = EIN; |
27 | |
28 | ret = zustand; |
29 | }
|
30 | |
31 | return ret; |
32 | }
|
33 | |
34 | |
35 | int main(void) |
36 | {
|
37 | DDRB |= (1 << PB1); // LED von VCC auf Portpin; low-active |
38 | PORTB |= (1 << PB1); // PB1 auf Ausgang |
39 | DDRB &= ~(1 << PB2); // Bit loeschen; damit PB2 Eingang |
40 | PORTB |= (1 << PB2); // Taster an PB2 mit internem Pull-up (auf GND) |
41 | |
42 | while(1) |
43 | {
|
44 | unsigned char schalter = taster_abfrage(); |
45 | |
46 | switch(schalter) |
47 | {
|
48 | case EIN: |
49 | LED_EIN(); |
50 | break; |
51 | case AUS: |
52 | LED_AUS(); |
53 | break; |
54 | case NIX: |
55 | default:
|
56 | break; |
57 | }
|
58 | }
|
59 | |
60 | return 0; |
61 | }
|
Die Arbeitsschleife wird dadurch etwas übersichtlicher.
Bastler schrieb: > Noch eine andere Sache. Ich wollte bei meiner Schaltung ja einen > Batteriewächter realisieren. Das ist ja leider etwas komplexer. Über > einen Spannungsteiler auf den AD Wandler geht leider schwer. Z-Diode und > dann Komperator ist auch blöd. Über diesen Reset Controller weiss ich > rein gar nichts. Es gibt doch solche Bausteine die Bandgap reference > device oder so heißen. Die bringen mir ja wenn ich sie mit 3V > Batteriespannung versorge stabil z.B. 2 V. Sprich da könnte ich dann mit > einem Komperator arbeiten. Allerdings muss ich natürlich auch stark > Strom sparen. Ist das empfehlenswert? Du meinst sowas? http://www.elektronik-kompendium.de/public/schaerer/u_supvis.htm Battery monitor ist das engl. Stichwort Hier ist eine Schaltung für 3V Versorgung, 2,4V Schaltschwelle mit 1 µA (inaktiv) bzw. 20 µA (LED blinkt): http://www.discovercircuits.com/DJ-Circuits/undervol.htm Das wäre eine vollkommen vom µC unabhängige Lösung. Dein Gerät mit dem µC könnte "Durchschlafen" und dieser unabhängige Schaltkreis überwacht währenddessen die Batterie. Wenn du den ADC vom µC mitnutzen willst: http://www.edn.com/article/CA6495298.html?spacedesc=designideas&industryid=44217 Bei dieser Lösung müsste der µC (kann auf Attiny umgestellt werden) regelmäßig aufgeweckt werden, dann die Batterie checken und dann wieder pennen bzw. Alarm geben. Mir persönlich würde von der Bedienung und vom Stromverbrauch her die 1. Lösung mehr zusagen.
Guten Morgen!! Ich bin wirklich begeistert von diesem Forum. Man bekommt hier ja wirklich tolle Unterstützung als Anfänger. Also dieses Ding von Panasonic würde mir schon genügen glaube ich. MN13811-G oder wie das heißt. Datenblatt habe ich jetzt auf die Schnelle leider keines gefunden. Wäre hald schön wenn man diese Dinge bei Fa. Conrad oder Reichelt bestellen könnte. Wegen der weiteren Arbeiten ist es auch zwingend nötig, dass es sich um einen SMD Baustein handelt. Dumme Frage wie heißt dieses Bauteil denn eigentlich?? Ich kenne Spannungswandler aber die würden ja auch mehr Strom ziehn. Mit meinem Power-Down Modus habe ich jetzt eh schon wieder ein Problem. Das Datenblatt sagt dass VCC da 3 V sein sollte. Was ist aber wenn meine Batterie sagen wir mal nur noch 2,7 V hat???? Geht das dann noch oder ist das VCC 3V nur irgendein Vorschlag?? Das habe ich nicht verstanden. Dachte nicht dass es da zu sovielen Unklarheiten kommen könnte! Gruß Th.
Bastler schrieb: > Ich bin wirklich begeistert von diesem Forum. Man bekommt hier ja > wirklich tolle Unterstützung als Anfänger. Also dieses Ding von > Panasonic würde mir schon genügen glaube ich. MN13811-G oder wie das > heißt. Datenblatt habe ich jetzt auf die Schnelle leider keines > gefunden. http://www.alldatasheet.com/view.jsp?Searchword=MN13811-G > Wäre hald schön wenn man diese Dinge bei Fa. Conrad oder > Reichelt bestellen könnte. Da habe ich diesen IC noch nicht gesehen. Digikey hat ihn im Angebot. Also vielleicht an eine Monatssammelbestellung anhängen... oder einen Ersatz heraussuchen. > Wegen der weiteren Arbeiten ist es auch > zwingend nötig, dass es sich um einen SMD Baustein handelt. Dumme Frage > wie heißt dieses Bauteil denn eigentlich?? Ich kenne Spannungswandler > aber die würden ja auch mehr Strom ziehn. (low) voltage detector ic oder reset ic > Mit meinem Power-Down Modus habe ich jetzt eh schon wieder ein Problem. > Das Datenblatt sagt dass VCC da 3 V sein sollte. Was ist aber wenn meine > Batterie sagen wir mal nur noch 2,7 V hat???? Geht das dann noch oder > ist das VCC 3V nur irgendein Vorschlag?? Das habe ich nicht verstanden. > Dachte nicht dass es da zu sovielen Unklarheiten kommen könnte! Auf welche Stelle im Datenblatt beziehst du dich?
Ok das Datenblatt habe ich mir angeschaut. Für meine Verwendung würde ich dann eh diesen Baustein in einem SMD Gehäuse nehmen. Dann heißt er ja glaube ich MN 13821. Sind auch große Mengen die man hier abnehmen muss. Was gibt der Baustein eigentlich aus wenn die Spannung auf 2,4 V abgesunken ist. Ich vermute mal soetwas wie einen High-Impuls damit ein Transistor oder so angesteuert werden kann. Brauche ja keinen Reset oder so sondern nur eine Information jetzt soll die LED leuchten. Man muss davon ja auch recht große Mengen abnehmen. Texas Instruments und MAXIM haben doch wohl ähnliches denke ich. Ich beziehe mich auf Seite 176 des Datenblatts. Power-down-mode, VCC = 3V. Warum braucht er da plötzlich 3 V. LIegt das daran dass er sonst nicht mehr aufwacht?? Würde das Teil ja gerne mit 1 MHz laufen lassen was es ja wohl auch schon tut. Und da heißt es oben VCC = 2V. Was hat das auf sich??? Gruß Th.
Bastler schrieb: > Ok das Datenblatt habe ich mir angeschaut. Für meine Verwendung würde > ich dann eh diesen Baustein in einem SMD Gehäuse nehmen. Dann heißt er > ja glaube ich MN 13821. Sind auch große Mengen die man hier abnehmen > muss. > Was gibt der Baustein eigentlich aus wenn die Spannung auf 2,4 V > abgesunken ist. Ich vermute mal soetwas wie einen High-Impuls damit ein > Transistor oder so angesteuert werden kann. Brauche ja keinen Reset oder > so sondern nur eine Information jetzt soll die LED leuchten. Kein Impuls sondern Dauersignal. Ist die zu überwachende Spannung oberhalb Schaltschwelle V_DL 2,4V dann ist die Ausgabe V_OH = 0,8*V_DD bis V_DD. Ist die zu überwachende Spannung unterhalb Schaltschwelle V_DL 2,4V dann ist die Ausgabe V_OH = V_SS bis 0,4V > Man muss > davon ja auch recht große Mengen abnehmen. Texas Instruments und MAXIM > haben doch wohl ähnliches denke ich. Denke ich auch. Seiko, Rohm etc. haben vielleicht auch so was. > Ich beziehe mich auf Seite 176 des Datenblatts. Power-down-mode, VCC = > 3V. Warum braucht er da plötzlich 3 V. LIegt das daran dass er sonst > nicht mehr aufwacht?? Würde das Teil ja gerne mit 1 MHz laufen lassen > was es ja wohl auch schon tut. Und da heißt es oben VCC = 2V. Was hat > das auf sich??? Die Messwerte für den Strom in der Tabelle mit den elektrischen Kennwerten sind von der Vcc abhängig. Deswegen ist in der Tabelle angegeben bei welcher Vcc gemessen wurde. Gängige Werte sind 2V, 3V und 5V - z.B. um verschiedene µC bei gleicher Vcc vergleichbar zu machen. Das bedeutet nicht, dass Power-Down nur bei Vcc 3V geht oder 1 MHz nur bei Vcc 2V!
Wenn es nicht auf absolut extremstes Stromsparen ankommt (Batterie mit 1mAh Kapazität), dann brauchst Du keine exotischen Spezial-ICs. Der AVR kann mit VCC als Referenz seine interne Bandgap messen. Dabei gibt es nur eine leider nicht dokumentierte Fallgrube. Nach Auswahl der Bandgap als Input sind die ersten Messungen ungültig. Daher entweder eine Wartezeit (~1ms) einfügen oder die ersten 16 Messungen wegschmeißen und nur die 17. verwenden. Damit klappt die Unterspannungserkennung zuverlässig. Peter
Moment. Langsam. Heißt das jetzt ich brauche kein externes Bauelement sondern das geht genauso auch intern??!! Wie groß ist dabei der Programmieraufwand. Hat das irgendwas mit der Brown-Out-Detection zu tun? Das habe ich so nämlich noch nicht ganz verstanden.
Bastler schrieb: > Moment. Langsam. Heißt das jetzt ich brauche kein externes Bauelement > sondern das geht genauso auch intern??!! Wie groß ist dabei der > Programmieraufwand. Der ist gering: - ADC-MUX auswählen - dann 17-mal: - Messung starten - warten bis Messung beendet - Wert auslesen und mit berechneter Schwelle vergleichen. Aber Du solltest Dich nicht verzetteln und alles Schritt für Schritt tun. Also 1. Entprellen (LED zuverlässig an/aus), 2. Power down, 3. Unterspannung Und solange ein Schritt noch nicht klappt, ist es sinnlos, den nächsten zu tun. Peter
Guten Morgen! Oje da wäre ich wohl hoffnungslos überfordert als Anfänger. Das mit dem Taster ist ja schon sehr schwer für mich. Wenn ich das jetzt richtig verstanden habe dann wird da neben der AD Wandlung für meinen Sensor auch noch diese voltage detection gemacht. Passiert das über die Comperator Funktion irgendwie. Demnach wären also keine Bauteile nötig ausser der LED die dann leuchten soll wenn die Spannung z.B. unter 2,4 V abfällt. Einfacher erscheint mir da natürlich die Sache mit dem diskreten voltage detector. Da wäre wohl keinerlei Programmieraufwand nötig. Allerdings würde hier ein ständiger Stromverbrauch von 1 µA vorliegen. Die Sache das über den Controller zu machen ist ja auch im Power-Down-Mode deaktiviert. Nur verstehe ich nicht wie man hier das mit der Referenz einstellen kann. Gruß Th.
Bastler schrieb: > Oje da wäre ich wohl hoffnungslos überfordert als Anfänger. Wir waren alle mal Anfänger. Ich denke, daß man hier bei konkreten Fragen gute Unterstützung bekommt. > Das mit dem > Taster ist ja schon sehr schwer für mich. Da mußte durch. Für private Anwendungen könnte man tolerieren, daß man die Taste manchmal öfters drücken muß, aber elegant ist was anderes. > Wenn ich das jetzt richtig verstanden habe dann wird da neben der AD > Wandlung für meinen Sensor auch noch diese voltage detection gemacht. Das sollte kein Problem sein, Du brauchst ja für den Sensor bestimmt nicht die volle ADC-Samplerate. Du kannst also bequem den Muxer umschalten und verschiedene Eingänge nacheinander einlesen. > Einfacher erscheint mir da natürlich > die Sache mit dem diskreten voltage detector. Nur, wenn Du überhaupt nicht programmieren (lernen) willst. > Die Sache das über den Controller zu > machen ist ja auch im Power-Down-Mode deaktiviert. Dann solltest Du Dir erstmal nen Programmablaufplan machen. Wann soll überhaupt die Unterspannungserkennung gemacht werden? Erst bei Tastendruck (Aufwachen) oder zyklisch z.B. alle 10min per Aufwachen über Watchdoginterrupt. > Nur verstehe ich > nicht wie man hier das mit der Referenz einstellen kann. Dann hast Du aber nicht im Datenblatt den Abschnitt ADC angeschaut. Peter
Peter Dannegger schrieb: > Dabei gibt es nur eine leider nicht dokumentierte Fallgrube. Nach > Auswahl der Bandgap als Input sind die ersten Messungen ungültig. Dokumentiert sind 125 µs. Allerdings dürfte sich diese Zeit ggf. um die Zeit verlängern, die ein externer Abblockkondensator an AREF benötigt, um sein Potenzial zu stabilisieren. Da diese Zeit aber vom konkreten Wert des Kondensators abhängt, kann die dir das Datenblatt nicht nennen.
Jörg Wunsch schrieb: > Dokumentiert sind 125 µs. Allerdings dürfte sich diese Zeit ggf. > um die Zeit verlängern, die ein externer Abblockkondensator an > AREF benötigt, um sein Potenzial zu stabilisieren. ??? Und was hat das mit dem Messen der Bandgap zu tun? Die UREF muß dabei VCC sein, denn Du willst ja VCC ermitteln. Außerdem, einen Kondensator kannst Du beim ATtiny24 garnicht anschließen, der Pin ist nur als externer Referenzeingang benutzbar. Hier mal eine Messung am Bandgap-Eingang: http://wap.taur.dk/bandgap.png und der Thread dazu: http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=587074#587074 Peter
Peter Dannegger schrieb: > Jörg Wunsch schrieb: >> Dokumentiert sind 125 µs. Allerdings dürfte sich diese Zeit ggf. >> um die Zeit verlängern, die ein externer Abblockkondensator an >> AREF benötigt, um sein Potenzial zu stabilisieren. > Und was hat das mit dem Messen der Bandgap zu tun? > Die UREF muß dabei VCC sein, denn Du willst ja VCC ermitteln. Könnte trotzdem sein, dass der AREF-Kondensator umgeladen werden muss (wenn du die Referenz intern auf Vcc schaltest, also nicht extern an AREF anlegst). Die 125 µs sind allein die interne Umschaltzeit. > Außerdem, einen Kondensator kannst Du beim ATtiny24 garnicht > anschließen, der Pin ist nur als externer Referenzeingang benutzbar. Ja, dort ist das anders. Hatte mir den konkreten Controller hier nicht angeguckt. > Hier mal eine Messung am Bandgap-Eingang: > > http://wap.taur.dk/bandgap.png Ja, interessant. Interessant vor allem, dass man durch vorheriges Auswählen von GND die Annäherung beschleunigen kann. Ich hatte das Verhalten auch schon mal beobachtet, allerdings dann nur empirisch geguckt, wie lange ich warten muss, bis ich eine korrekte Messung erhalte. Bei mir sind das 100 µs (für einen ATmega324P), das passt eigentlich recht gut zu den im Datenblatt genannten 125 µs.
Also so wirklich verstanden habe ich die Sache immer noch nicht. Beim ATtiny 24V ist ja die Referenz des AD-Wandlers gleich VCC. Zumindest bei mir ist es so. Ich habe schon gesehen dass am Pin PA0 AREF steht. Das heißt wohl für eine externe Spannung. Nur wenn ich als Schwelle 2,4 V haben möchte dann muss ich ja auch wieder über eine Z-Diode oder so meine 2,4 V stabil abgreifen. Und wenn ich keine externe Referenz habe bringt es mir ja auch nicht viel. Wenn meine Batterie 3V Spannung hat anfangs dann wird bei diesem Wert die 3 V geteilt durch 1024 Stufen gerechnet (10 Bit AD Wandler). Ich könnte also jetzt sagen welche Stufe dann 2,4 V entspricht. Allerdings wenn meine VCC auf 2,4 V geschrumpt ist verändert sich ja auch die Spannung von einer Stufe. Sprich er löst dann nicht mehr bei 2,4 V aus sondern wegen mir bei 2,1 V. Wo liegt bei mir da der Denkfehler. Ich meine eigentlich das Datenblatt mit dem ADC durchgelesen zu haben! ;-) Ihr werdet ja auf diese Referenzspannung anspielen. So wollte ich es ja auch ursprünglich lösen. Ein Spannungsteiler mit zwei 100 kOhm Widerständen. Der Pin dazwischen auf einen ADC Pin. Nur das geht ja nicht so einfach dann! Gruß Thomas
Bastler schrieb: > Also so wirklich verstanden habe ich die Sache immer noch nicht. Beim > ATtiny 24V ist ja die Referenz des AD-Wandlers gleich VCC. Nein, laut Datenblatt kann man aus drei Referenzspannungen auswählen: 16.6.2 ADC Voltage Reference The reference voltage for the ADC (VREF) indicates the conversion range for the ADC. Single ended channels that exceed VREF will result in codes close to 0x3FF. VREF can be selected as either VCC, or internal 1.1V reference, or external AREF pin. Für die Überwachung der Vcc ist der Fall "internal 1.1V reference" interessant. Jetzt liegt aber deine 2.4V über der Vref 1.1V und du bekommst als Ergebnis für Vcc >1.1V immer codes close to 0x3FF. Das kannst du aber mit einem Spannungsteiler beheben. Der muss so dimensioniert werden, dass bei Vcc 2.4V eine Spannung von max. 1.1V an dem ADC-Messeingang anliegt. Wenn deine Spannungswächterroutine dann einen ADC Wert < 0x3FF misst (nach entsprechender Wartezeit nach dem Aufwecken, s. Diskussion oben!), ist die Vcc kleiner 2.4V.
Bastler schrieb: > Nur wenn ich als Schwelle 2,4 V > haben möchte dann muss ich ja auch wieder über eine Z-Diode oder so > meine 2,4 V stabil abgreifen. Nein. Schau mal ins Datenblatt Table 16-4. Dort steht beim MUX5..0 = 100001 als Eingang 1,1V, das ist die Bandgap Referenz. Und nun rechne einfach mal die Formel für die AD-Wandlung für verschiedene VCC als UREF aus: ADC_Wert = 1024 * 1.1V / VCC Z.B.: 5,0V: ADC = 225 4,9V: ADC = 229 4,8V: ADC = 234 usw. Für die Schwelle VCC = 2,4V mußt Du also mit 469 vergleichen. Ist der Wert größer, dann ist die VCC zu klein. Peter
Stefan B. schrieb:
> Das kannst du aber mit einem Spannungsteiler beheben.
Der braucht aber permanenten Querstrom. Daher ist die Lösung, Vcc
als Referenz zu nehmen und die Bandgap als Messquelle, die bessere
Wahl. Kalibrieren muss man ohnehin beides, da die Exemplarstreuung
der Bandgap zu groß ist, und das bisschen Reziprok-Rechnerei macht
das Kraut nicht fett. Man muss die Batteriespannung ja nicht 100x
in der Sekunde überwachen.
Jörg Wunsch schrieb: > Stefan B. schrieb: > >> Das kannst du aber mit einem Spannungsteiler beheben. > > Der braucht aber permanenten Querstrom. Daher ist die Lösung, Vcc > als Referenz zu nehmen und die Bandgap als Messquelle, die bessere > Wahl. Heh, ihr seid aber pfiffige Füchse. Diese Variante begreife ich erst jetzt. Wieder was gelernt, danke!
Ok!!! Also das war jetzt schon mal wieder verständlich. Den Spannungsteiler werde ich natürlich relativ hochohmig machen damit ich einen geringen Stromfluss habe. Habe jetzt mal 120 zu 100 kOhm gewählt. Dann wird am Abgriff bei VCC 2,42 V die 1,1 V erreicht. Das bedeutet bei drei Volt fließen 14 µA. Das muss meine Batterie verkraften. Dachte hald nur immer Spannungsteiler sind stetige Stromfresser aber irgendwo muss man einfach mal Kompromisse machen. Ich könnte die 1,1 V dann bei ADC7 (PA7) in den Controller einführen. Ich muss mir jetzt also was einfallen lassen dass er wegen mir alle halbe Sekunde des eine misst und ale halbe Sekunde wieder des andere. Multiplexen hald. Was mache ich aber mit den Lämpchen die ja aufleuchten wenn der Sensor einen bestimmten Wert hat. Wenn da zwischendrin eine Messung kommt von meiner VCC würden die ja urplötzlich undefiniert aufleuchten. Ich könnte natürlich auch sagen dass die Messung der Batteriespannung anfangs erfolgen soll und in meiner while Schleife vom Sensor kann er dann seinen Sensor ausmessen. Das müßte ja wohl gehen. Muss ja auch beim ADMUX andere Bits setzen und löschen. Sprich dann bräuchte ich wohl gar nicht multiplexen. Ist das richtig? Gruß Th.
Wie meint ihr das mit der Messquelle??? Ich habe ja für meinen Betauungssensor VCC als Referenz. Wie soll ich jetzt die 1,1 V als Messquelle nehmen?
Bastler schrieb: > Wie meint ihr das mit der Messquelle??? Ich habe ja für meinen > Betauungssensor VCC als Referenz. Wie soll ich jetzt die 1,1 V als > Messquelle nehmen? Mann, bist du schwer von Begriff! Indem du den ADMUX auf 0b100001 einstellst. Guck doch einfach mal ins <censored> Datenblatt!
Bastler schrieb: > Wie meint ihr das mit der Messquelle??? Ich habe ja für meinen > Betauungssensor VCC als Referenz. Wie soll ich jetzt die 1,1 V als > Messquelle nehmen? Du hast zwei Messaufgaben: 1. Messung der Spannung vom Betauungssensor 2. Messung der Batteriespannung Der Bedarf für 2. sagt schon, dass du keine konstante Batteriespannung hast, die du ohne weiteres als Referenz einsetzen könntest. Dein unveränderlicher Maßstab kann also nur die interne 1.1V Referenz sein. Man könnte die interne 1.1V Referenz als Vref einstellen, müsste aber dann zu messende Spannungen oberhalb 1.1V runterteilen, damit sie in den Meßbereich passen. Das Runterteilen frisst aber kostbare Batterieenergie (Dauerstrom durch Spannungsteiler) und sollte vermieden werden. Der pfiffige Clou von Peter und Jörg ist, dass man die Meßanordnung umdreht: Die unbekannte Batteriespannung nimmt man als (ungenaue) Vref und misst damit die bekannte interne 1.1V Spannung. Damit bekommt man die Batteriespannung raus! Die internen 1.1V leitet man über die MUX5:0: Analog Channel and Gain Selection Bits des ADMUX – ADC Multiplexer Selection Registers an den ADC. Wenn du die Batteriespannung Vcc bestimmt hast, ist Fall 2. bereits gelöst. Anschliessend kannst du mit der gemessenen Batteriespannung Vcc als genaue Vref die Messung 1. durchführen.
Ok ich habe da wohl inzwischen schon so viele Informationen bekommen dass sich die eine um die andere dreht. Die allereinfachste Möglichkeit wäre aber doch wenn ich das mit dem Spannungsteiler mache. Natürlich auch schaun dass kein hoher Strom fließt. Die Abfrage meines Betauungssensors findet ja in einer while(1) Schleife statt. Wenn ich jetzt bei jedem Einschalten am Anfang des Programms eine Messung der Batteriespannung mache sollte des ja auch funktionieren. Zumindest könnte ich das eher nachvollziehen. Ich brauche dann ja meinen ADMUX nur auf den Eingang PA7 ausrichten und die interne 1,1 V Referenz anwählen. Dann kann ich mit einer if Schleife abfragen ob die 1,1 V gleich den 1,1 V vom Spannungsteiler ist. Dann kann ich meinen Port Pin auf 0 ziehen und mein LED leuchtet solange die Sache eingeschaltet ist. Dann schreibe ich meinen ADMUX wieder um für die AD-wandlung des Betauungssensors. Für mich stellt sich dann nur noch die Frage wie kann ich abfragen ob die beiden Spannungen gleich sind. Wie spreche ich die interne Referenz an. Die schreibt ja ihren Wert in ADC. Wird das dann nicht überschrieben von dem eingelesenen Wert? Das andere kann ich im Moment nicht nachvollziehen. Da fehlt mir wohl die Erfahrung. Ich verstehe das mit der Referenz fürn AD-Wandler. Ich dachte hald immer dass man dafür normal VCC verwendet weil es dann einfacher ist. Theoretisch würden sogar die 1,1 V ausreichen da mein Betauungssensor eh nur mit max. 0,8 V DC belegt werden soll. Soll das heißen ich gehe nicht mehr von VCC auf den ersten Widerstand des Spannungsteilers sondern mit den 1,1 V. Ich habe sowas noch nie gemacht darum tu ich mich da auch so schwer. Auch im Datenblatt ist es ja teilweise schwer die Umstände zu verstehen. Trotzdem danke für eure Geduld! Gruß Th.
Bastler schrieb: > Die allereinfachste Möglichkeit wäre aber doch wenn ich das mit dem > Spannungsteiler mache. Inwiefern ist das einfacher als die andere Variante? Es benötigt sogar noch zwei Bauteile mehr, und Software zum Auswerten musst du so oder so schreiben. Kalibrieren musst du auch beide. Faulheit, über ein bestimmtes Detail (das dir ja nun schon mit Formeln und Registerwerten bis zum Kleinsten dargelegt worden ist) nachzudenken lässt sich nicht unbedingt als ,,am allereinfachsten'' abtun. ;-)
Bastler schrieb: > Ok ich habe da wohl inzwischen schon so viele Informationen bekommen > dass sich die eine um die andere dreht. Kann passieren ;-) > Die allereinfachste Möglichkeit wäre aber doch wenn ich das mit dem > Spannungsteiler mache. Natürlich auch schaun dass kein hoher Strom > fließt. Die Abfrage meines Betauungssensors findet ja in einer while(1) > Schleife statt. Wenn ich jetzt bei jedem Einschalten am Anfang des > Programms eine Messung der Batteriespannung mache sollte des ja auch > funktionieren. Zumindest könnte ich das eher nachvollziehen. Mache es mal. Du lernst auf jeden Fall was. Spiele mal mit verschiedenen Vcc und beobachte den ADC-Wert vom Betauungssensor bei sonst gleicher Umgebung... In der Praxis ist es schade um den verlorenen Batteriesaft. > Ich brauche > dann ja meinen ADMUX nur auf den Eingang PA7 ausrichten und die interne > 1,1 V Referenz anwählen. Dann kann ich mit einer if Schleife abfragen ob > die 1,1 V gleich den 1,1 V vom Spannungsteiler ist. Dann kann ich meinen > Port Pin auf 0 ziehen und mein LED leuchtet solange die Sache > eingeschaltet ist. Dann schreibe ich meinen ADMUX wieder um für die > AD-wandlung des Betauungssensors. Hört sich plausibel an. > Für mich stellt sich dann nur noch die > Frage wie kann ich abfragen ob die beiden Spannungen gleich sind. Wie > spreche ich die interne Referenz an. Die schreibt ja ihren Wert in ADC. > Wird das dann nicht überschrieben von dem eingelesenen Wert? Das nicht ;-) Das gesamte Prinzip der ADC Messung ist im Wiki als Tutorial erklärt. > Das andere kann ich im Moment nicht nachvollziehen. Da fehlt mir wohl > die Erfahrung. Ich verstehe das mit der Referenz fürn AD-Wandler. Ich > dachte hald immer dass man dafür normal VCC verwendet weil es dann > einfacher ist. Wenn du ein konstantes Vcc hast, ja. Hast du aber nicht, weil du mit Batterie arbeitest (Stichwort Entladungskurve) und bisher nichts über einen Spannungsstabilisator geschrieben hast. Also musst du zuerst dein Vcc bestimmen, um dann damit in einem kleinen Zeitraum als annäherend konstante Referenz arbeiten zu können. > Theoretisch würden sogar die 1,1 V ausreichen da mein > Betauungssensor eh nur mit max. 0,8 V DC belegt werden soll. Soll das > heißen ich gehe nicht mehr von VCC auf den ersten Widerstand des > Spannungsteilers sondern mit den 1,1 V. Das wäre dann eine weitere Lösung für Messaufgabe 1, die dir die Messung der Batteriespannung vor der Messung der Spannung vom Betauungssensor erspart. Vielleicht legst du dein System so aus: 1. Messung der Spannung vom Betauungssensor mit Vref=interne 1.1V. Das geht ohne Spannungsteiler, wenn Vunbek. max. Vref. (1.1V). 2. Messung der Batteriespannung mit Vref=Vcc und Messung der bekannten 1.1V und Berechnung von Vcc. Das geht ohne Spannungsteiler
Ok klar dass ich den Spgteiler zur Batterieüberwachung brauchen würde ist ein Nachteil. Ich verstehe hald nur nicht wie ihr das von der Verdrahtung her realisieren wollt. Wie soll ich meinen Sensor mit den 1,1 V durchmessen? Etwa so wie in meiner kurzen Zeichnung im Anhang. Ich kann ja wohl auf einem Pin diese 1,1 V ausgeben vermute ich oder kann ich die 1,1 V nur als Hexzahl in mein ADC Register schreiben. Ohne Spannungsteiler wüßte ich nicht wie man das machen sollte. So wie in meiner Zeichnung wäre es relativ logisch. Da mein Sensor eh nur 0,8 V Spannung abbekommen soll müßten also am R minimal 0,3 V abfallen. Und das muss ich dann wieder messen wie bisher. Für die Messung der Batteriespannung muss ich da einen weiteren Pin am Controller vorsehen oder geht das über VCC?? Das verstehe ich auch noch nicht. Ich würde es ja gerne programmieren können. Nur fehlt mir einfach die Vorstellung was ihr meint. Gruß Thomas
Bastler schrieb: > Ich verstehe hald nur nicht wie ihr das von der > Verdrahtung her realisieren wollt. >> Die internen 1.1V leitet man über die MUX5:0: >> Analog Channel and Gain Selection Bits des ADMUX – ADC Multiplexer >> Selection Registers an den ADC. Durch diese Einstellung (MUX5..0 100001) wird im Attiny24V Inneren eine "Weiche" gestellt, die die internen 1.1V an den ADC Eingang führt. Aussen wird da nix zusätzlich verdrahtet und die 1.1V werden auch nicht nach aussen ausgegeben! Wenn du dann den Sensor messen willst, musst du den ADC Eingang über die MUX5..0 Bits wieder zurückstellen z.B. auf ADC7 (PA7) 000111 > Für die Messung der Batteriespannung muss ich da einen weiteren Pin am > Controller vorsehen oder geht das über VCC?? Nein musst du nicht. Vcc ist sowieso am µC angeschlossen und kann intern als Vref für den ADC ausgewählt werden. Und die 1.1V werden wie oben intern an den ADC Eingang geleitet.
Ok wieder ein Schritt mehr. Sprich mit der Einstellung MUX5...0: 100001b schreibt er den Hex-Wert der Stufe (also praktisch Stufe 1023d entspricht 3FFh) von 1,1 V in meinen ADC. Schön und gut. Ist dann praktisch ein ständiges Umstellen von MUX? Oder geb ich ihm nur am Anfang in der Initialisierung kurz die 1,1 V (3FFh) damit er weiss das ist die Referenz und dann liefert mein Sensor die jeweiligen Werte zurück. Wie wird aber dann der Sensor angeschlossen. Ich kann ihn doch nicht einfach ohne Spgteiler von ADC0 auf GND hängen. Und an VCC geht ja auch nicht. Der muss doch eine Spgversorgung bekommen. Wie man VCC intern als Referenz wählt ist mir dann auch klar. Ich stelle das mit den BITs 6 und 7 von ADMUX auf Vcc used as analog reference. Das funktioniert dann ja so wie ich anfangs geschrieben habe. Sprich mit jedem einschalten mißt er ob die Spg. 1,1 V + 1,3 V (natürlich in Stufen bzw. in HEX) ist. Wenn ja kann er mein LED ansteuern wenn nein richter er sich den ADC auf 1,1 V interne Ref ein und macht in seiner Endlosschleife die Wandlung für den Betauungssensor. Ist das von der Überlegung her einigermaßen korrekt?
Die Qualität/Verständlichkeit der Frage lässt im Moment stark nach. Vorschlag: Drucke dir den Thread aus und lese ihn mehrmals durch. Bastler schrieb: > Ok wieder ein Schritt mehr. Sprich mit der Einstellung MUX5...0: 100001b > schreibt er den Hex-Wert der Stufe (also praktisch Stufe 1023d > entspricht 3FFh) von 1,1 V in meinen ADC. Schön und gut. Mit der Einstellung MUX5...0: 100001b wird die 1.1V an den Eingang des ADC geleitet. Was dort digitalisiert wird ist von der eingestellten Referenzspannung Vref abhängig. Wenn du Vcc als Vref auswählst, wird irgendein Wert als Ergebnis rauskommen. Einen Hinweis welcher Wert bei welcher Vcc rauskommt hat Peter gegeben. > Ist dann > praktisch ein ständiges Umstellen von MUX? Der ADC muss von dir per Programm umgestellt werden, abhängig davon welche Messung du machen willst. Einmal willst du die internen 1.1V am ADC Eingang haben, um die Batteriespannung Vcc zu bestimmen Und einmal willst du dein Eingangssignal/deine Spannung vom Sensor z.B. ADC0 Eingangspin haben, um den Betauungsmesswert zu bestimmen. > Oder geb ich ihm nur am > Anfang in der Initialisierung kurz die 1,1 V (3FFh) damit er weiss das > ist die Referenz und dann liefert mein Sensor die jeweiligen Werte > zurück. Von welcher Messung redest du? Es gibt mehrere Varianten: >> 1a. Messung der Spannung vom Betauungssensor mit Vref=interne 1.1V. Das >> geht ohne Spannungsteiler, NUR wenn Vunbek. max. Vref. (1.1V). 1b. Messung der Spannung vom Betauungssensor mit Vref=genaue Vcc. Das geht ohne Spannungsteiler. >> 2. Messung der Batteriespannung mit Vref=Vcc und Messung der bekannten >> 1.1V und Berechnung der genauen Vcc. Das geht ohne Spannungsteiler 3. Deine Variante(n) mit Spannungsteiler? > Wie wird aber dann der Sensor angeschlossen. Ich kann ihn doch > nicht einfach ohne Spgteiler von ADC0 auf GND hängen. Und an VCC geht ja > auch nicht. Der muss doch eine Spgversorgung bekommen. Der Anschluß eines solchen Sensors ist sicher in dessen Datenblatt erklärt. Ich kenne weder Typ noch Datenblatt deines Sensors. Oft haben solche Sensoren drei Beinchen: GND, Vcc und Vout. Vout würde dann an den ADC0 Pin kommen.
Guten Morgen! Ja ich gebe zu es wird langsam sehr komplex. Zu meinem Sensor kann ich folgendes sagen. Es ist der Sensor SHS-A2. Er besitzt nur zwei Anschlüsse. Ist also ein veränderbarer Widerstand. Es wird zwar immer von Impedanzen geschrieben im Datenblatt ich kann das Teil aber laut Auskunft der Firma mit DC 0,8 V betreiben. Das ist für mich das entscheidende. Sprich ich will das Teil wie einen PTC oder was auch immer betreiben. Also es kommt dann auf jeden Fall ein Pin des Sensors auf Masse und einer an den ADC0 Pin. Das kann aber doch noch nicht alles gewesen sein. Ich muss doch noch irgendwo eine Spannung dran geben. Das ist mein eigentliches Problem bei euren Beiträgen. Die 1,1 V Referenz ist mir ja klar. Wobei das wäre mir nur klar wenn ich diese 1,1 V an einem anderen Pin nach aussen führe und über einen Vorwiderstand auf ADC0 gebe. Dann hätte ich praktisch auch wieder einen Spg.teiler der aber nicht von VCC weggeht sondern von einem Pin. Nur das widerspricht sich ja wieder mit eurer Aussage dass die 1,1 V nicht an einem I-O Pin erscheinen. Kann mir diesbezüglich noch jemand helfen? Die Referenz von 1,1 V wird dann praktisch durch die 1024 geteilt und ich habe den Spannungswert pro Stufe. Je nach Widerstand des Sensors hätte ich dann einen dementsprechenden Stufenwert und könnte ihn mit den 1,1 V vergleichen. Für die Sensormessung müßte ich also nach meiner These ständig beim MUX umschalten. Einmal dass er den Wert von meinem Sensor in den ADC einließt und die zweite dass er es mit den 3FFh vergleicht. Ist das so richtig? Ich denke mal nicht weil ihr das ganze ja ohne Spannungsteiler lösen wollt. Meine Schaltung ist ja schon aufgebaut. Mit VCC als VREF. Das funktioniert. Normal müßte das ja auch mit fallender Batteriespannung noch gehen da sich die Stufen ja proportional verändern. Sprich wenn ich nur noch 2,7 V habe dann geschieht die Teilung ja durch 2,7 V und nicht mehr durch 3 V. Dadurch müßte das mit den Stufen ja wieder passen. Ich stimme euch aber zu dass 1,1 V besser wäre weil am Sensor eh nur 0,8 V anliegen sollen. Allerdings habe ich die Info dass diese einzelnen "Stufen" nicht zu klein sein sollten. Also 3 V geteilt durch 1024 ist knapp 3 mV. Ist das dann bei 1,1 V ein Problem dass des zu empfindlich wird??? Man kann den ADC ja auch als 8 Bit Wandler umstellen. Gruß Thomas
Bastler schrieb: > Zu meinem Sensor kann ich folgendes sagen. Es ist der Sensor SHS-A2. Er > besitzt nur zwei Anschlüsse. Ist also ein veränderbarer Widerstand. Es > wird zwar immer von Impedanzen geschrieben im Datenblatt ich kann das > Teil aber laut Auskunft der Firma mit DC 0,8 V betreiben. Das ist für > mich das entscheidende. Sprich ich will das Teil wie einen PTC oder was > auch immer betreiben. Gut. Du benutzt also einen Widerstand, der zusammen mit dem Sensor einen Spannungsteiler bildet. Soweit so gut. > Also es kommt dann auf jeden Fall ein Pin des Sensors auf Masse und > einer an den ADC0 Pin. Das kann aber doch noch nicht alles gewesen sein. Ist es auch nicht. Vom ADC0 Pin muss noch ein Widerstand nach ARef, damit dieser Widerstand zusammen mit dem Sensor einen Spannungsteiler bildet. (An ARef liegt die stabilisierte Referenzspannung, die du per Programm ausgewählt hast) > weggeht sondern von einem Pin. Nur das widerspricht sich ja wieder mit > eurer Aussage dass die 1,1 V nicht an einem I-O Pin erscheinen. Moment. Wir reden von 2 verschiedenen Dingen Das eine ist deine Messspannung die du vom Betauungssensor erhältst. Da führt kein Weg drann vorbei. Das must du mit dem Spannungsteiler arbeiten. Das ist ein stink normaler Aufbau und du brauchst dort auch keine 1.1V oder sowas. Such dir eine Referenzspannung aus, stell sie ein, miss den ADC Wert, umrechnen in einen vernünftigen, anzeigbaren Wert. Fertig. Alles ganz normales Standardvorgehen. Eine ganz andere Geschichte ist aber die Messung der Batteriespannung. Der Clou an der ganzen Geschichte ist es ja gerade, dass du dafür keinerlei externe Beschaltung brauchst. Das kannst du alles erledigen, indem du die ADC Einheit während der Messung der Batteriespannung umkonfigurierst. Da man aber diese Batterieüberwachung ja nicht ständig macht, ist das auch kein Problem.
BETAUUNGSSENSOR SHS-A2 PDF: http://www.bmcm.de/pdf-misc/sensors/shs_a2.pdf Grundschaltung ist IMHO ein Spannungsteiler aus SHS-A2 und R: Vcc----+-----------Vcc vom µC | SHS-A2 | +-----------ADC0 | R | GND----+-----------GND vom µC R wird so bemessen, dass (Vcc-VADC0) <= 0,8V ist. Nachteil: Es fliesst ein Dauerstrom durch den Spannungsteiler und die Batterie wird leer gesuckelt. Als Abhilfe könnte ich mir vorstellen, dass der µC selbst benutzt wird um die Messspannung auszugeben. also in der Art: +-----------I/O-Pin1 vom µC | SHS-A2 | +-----------ADC0 | R | +-----------GND vom µC Wenn keine Messung gemacht wird, ist I/O-Pin1 als Eingang ohne Pullup geschaltet. Wenn eine Messung gemacht wird, wird I/O-Pin1 auf Ausgang HIGH geschaltet. Für die Messung muss man wissen mit welcher Spannung SHS-A2 versorgt wird. Der Pegel wird sich bei ändernder Vcc ebenfalls ändern. Dazu fällt mir spontan nur die Lösung ein, diesen Pegel zu messen: +------+----I/O-Pin1 vom µC | | SHS-A2 R2 | | | +----ADC1 | +-----------ADC0 | R1 | +-----------I/O-Pin2 vom µC Messung Voh: I/O-Pin1 Ausgabe HIGH, I/O-Pin2 Eingang ohne Pullup, ADC0 Eingang ohne Pullup. ADC1 messen. Vref=genaue Vcc Messung VSHS-A2: I/O-Pin1 Ausgabe HIGH, I/O-Pin2 Ausgang LOW, ADC1 Eingang ohne Pullup. ADC0 messen. Vref=genaue Vcc Das Diagramm Feuchte gegen Impedanz im Datenblatt ist eine stark nichtlineare Kurve, so dass du auf jeden Fall eine Kalibrierung vornehmen musst ("Wo sollen die Schaltschwellen liegen"). Teste mal, ob sich deine Schaltschwelle bei verschiedenen Vcc stark ändert. Vielleicht kannst du die Messung der Voh einsparen.
Stefan B. schrieb: > Als Abhilfe könnte ich mir vorstellen, dass der µC selbst benutzt wird > um die Messspannung auszugeben. also in der Art: > > +-----------I/O-Pin1 vom µC > | > SHS-A2 > | > +-----------ADC0 > | > R > | > +-----------GND vom µC > > Wenn keine Messung gemacht wird, ist I/O-Pin1 als Eingang ohne Pullup > geschaltet. Wenn eine Messung gemacht wird, wird I/O-Pin1 auf Ausgang > HIGH geschaltet. Ich denke, die Impendanz ist hoch genug, dass der ARef Ausgang den Strom durch den Spannungsteiler schon verkraftet. In Messpausen wird ARef einfach auf externe Referenz gestellt und dann sollte eigentlich kein Strom mehr durch den Spg-Teiler fliessen. > Für die Messung muss man wissen mit welcher Spannung SHS-A2 versorgt > wird. Der Pegel wird sich bei ändernder Vcc ebenfalls ändern. Damit würde sich dann auch dieses Problem in Luft auflösen.
Karl heinz Buchegger schrieb: > Ich denke, die Impendanz ist hoch genug, dass der ARef Ausgang den Strom > durch den Spannungsteiler schon verkraftet. In Messpausen wird ARef > einfach auf externe Referenz gestellt und dann sollte eigentlich kein > Strom mehr durch den Spg-Teiler fliessen. "Mein" I/O-Pin1 wäre dann Aref. Das ist noch geschickter! Über Schaltung #3 (Messung von Voh) braucht man dann tatsächlich nicht nachzudenken. Die an Aref ausgegebene Vcc (die Batteriespannung) kann man ja intern messen.
Karl heinz Buchegger schrieb: > Ich denke, die Impendanz ist hoch genug, dass der ARef Ausgang den Strom > durch den Spannungsteiler schon verkraftet. Der ATtiny24 kann das leider nicht. Dort gibt es den AREF-Pin nur als Eingang, d. h. wenn man die ADC-Referenz nicht auf externe Referenz gestellt hat, dann ist der entsprechende Pin ein ganz normaler Portpin. Daher sollte man wohl einfach einen normalen Portpin als Spannungs- quelle benutzen und ratiometrisch gegen Vcc messen. Wenn man ganz genau sein will, misst man den Ausgangspin selbst zuerst noch als ADC-Pin wieder ein (also mit der Belastung durch den Sensor) und erst danach den eigentlichen Sensor. Dafür muss der Ausgangspin, der den Sensor versorgt, am Port A liegen, denn PA0 bis PA7 sind allesamt potenzielle ADC-Eingänge. (Das entspricht Stefans Vorschlag mit dem Unterschied, dass der Pin zugleich Ausgang zur Versorgung des Sensors und Eingang zum ADC ist.)
Wenn man einen Spannungsteiler mißt, kann man ruhig die unstabile VCC als Referenz nehmen, die kürzt sich komplett raus. Peter
Jörg Wunsch schrieb: > Karl heinz Buchegger schrieb: > >> Ich denke, die Impendanz ist hoch genug, dass der ARef Ausgang den Strom >> durch den Spannungsteiler schon verkraftet. > > Der ATtiny24 kann das leider nicht. Schade. Ich hab nicht im Datenblatt nachgesehen und ging davon aus, dass alle AVR dieses können. Wieder was gelernt. > Daher sollte man wohl einfach einen normalen Portpin als Spannungs- > quelle benutzen und ratiometrisch gegen Vcc messen. Dann gehts wohl wirklich nicht anders.
Bastler schrieb: > Für die Sensormessung müßte ich also nach meiner These ständig beim MUX > umschalten. Und was ist daran ein Problem? Du hast mehrere Meßaufgaben, also führst Du sie nacheinander aus. Und für jede Meßaufgabe stellst Du den AD-Wandler entsprechend ein, startest die Messung, wartest auf das Wandlungsende und liest den Wert aus. Fertsch. Der AD-Wandler ist für Deine Aufgabe (Ansteuerung von LEDs) mindestens 10000-mal schneller als nötig. Er könnte also theoretisch 10000 Sensoren auslesen und 10000 LEDs schalten (wenn er soviel Pinne hätte). Peter
Karl heinz Buchegger schrieb: > Schade. Ich hab nicht im Datenblatt nachgesehen und ging davon aus, dass > alle AVR dieses können. Wieder was gelernt. Nochmal, das ist völlig unnötig, VCC kürzt sich raus >> Daher sollte man wohl einfach einen normalen Portpin als Spannungs- >> quelle benutzen und ratiometrisch gegen Vcc messen. Auch das ist völlig unnötig. VCC muß nur für die Meßzeit stabil sein (etwa 20µs). Peter
Peter Dannegger schrieb: > Karl heinz Buchegger schrieb: >> Schade. Ich hab nicht im Datenblatt nachgesehen und ging davon aus, dass >> alle AVR dieses können. Wieder was gelernt. > > Nochmal, das ist völlig unnötig, VCC kürzt sich raus Ja, ich weiß. Ich hab nur ein gewisses Unbehagen einen normalen Portpin als 'Referenz' zu benutzen.
Peter Dannegger schrieb: >>> Daher sollte man wohl einfach einen normalen Portpin als Spannungs- >>> quelle benutzen und ratiometrisch gegen Vcc messen. > > Auch das ist völlig unnötig. Sender Jerewan: Im Prinzip ja. Für die Messung allein ist es nicht notwendig, den an einen Portpin zu klemmen. Zum Stromsparen ist es aber sinnvoll. Da der Portpin aber wiederum einen endlich kleinen Kanalwiderstand im p-Kanal-FET hat, der in die Messung dann mit eingeht, ist es halt auch sinnvoll, den Pin selbst gleich noch mit zu vermessen.
Erst mal Danke für die Hilfe. Also wenn ich das jetzt richtig zusammenfasse dann heißt das ich soll einen Spannungsteiler verwenden. Nur dass ich mit dem "Vorwiderstand" nicht auf VCC gehe sondern auf einen Portpin. In meinem Fall wäre PB0 noch frei oder auch PA7. Mit dem "Vorwiderstand" auf ADC0 und von dort mit dem Sensor auf GND. Ich kann den Sensor ja auch auf GND schalten oder? So hab ich es im Moment gemacht. Wenn ich PB0 (oder PA7) dann auf Ausgang und High ziehe müßte ich doch aber auch wieder die VCC als Spannung daran haben?! Es ist ja auch so dass ADC0 und AREF am gleichen Pin sind. Also den Gedanken meine Spannung vom AREF zu entnehmen kann ich verwerfen. Also für mich sieht des so aus als hätte ich alles wie bisher. Nur ich würde hald jetzt Strom sparen weil ich vom Portpin rausgehe und nicht von VCC weg. Aber damit ist meine VREF ja die Spannung die vom Portpin rausgeht also wohl auch wieder VCC. Ihr meint also der Strom ist ausreichend aus dem Portpin. Schaltschwellen habe ich mir noch nicht überlegt wenn ich ehrlich bin. Im Moment habe ich den Sensor auch nur angehaucht. Dann geht hald nach einer Zeit das gelbe LED an und am Schluss blinkt das rote. Also ganz einfach. Eine "Genauigkeit" kann man in dem Sinne auch nicht reinbringen. Mann kann sagen ok wenn gelb an ist sind es wegen mir zwischen 75 und 93 Prozent relative Feuchte. Ist natürlich auch wieder mit Vorsicht zu genießen weil Betauung ja was anderes ist wie Nässe. Gruß Th.
Bastler schrieb: > Wenn ich PB0 (oder PA7) dann auf Ausgang und High ziehe müßte ich doch > aber auch wieder die VCC als Spannung daran haben?! Nicht exakt Vcc sondern etwas weniger. Siehe Datenblatt Abschnitt DC Characteristics und dort die Zeile mit der Output High-Voltage. Die Spannung Output Voltage ist auch vom entnommenen Strom, Vcc und der Temperatur abhängig (s. Figure 21-22 und 21-23 I/O Pin Output Voltage vs. Source Current).
PB0 kannst du für diesen Zweck nicht benutzen, sondern du benutzt PA7. Diesen schaltest du zwar als Ausgang, aber da er zugleich ein möglicher Eingang für den ADC ist, kannst du anschließend die dort tatsächlich anliegende Spannung messen. Die misst du gegen Vcc als Referenz. Danach misst du deinen eigentlichen Sensor (wohl an ADC0, wenn ich dich richtig verstehe). Referenz ist in beiden Fällen Vcc. Danach vergleichst du die Messung von ADC0 gegen die von ADC7, damit hast du dein Spannungsteilerverhältnis. Direkt vergleichen könntest du nur, indem du sie als float/double umrechnest und dividierst, aber das dürfte das Fassungsvermögen deines ATtiny24 übersteigen. Du musst also den Wert von ADC0 passend skalieren und danach durch den von ADC7 dividieren.
Jörg Wunsch schrieb: > PB0 kannst du für diesen Zweck nicht benutzen, sondern du benutzt > PA7. Diesen schaltest du zwar als Ausgang, aber da er zugleich ein > möglicher Eingang für den ADC ist, kannst du anschließend die dort > tatsächlich anliegende Spannung messen. Man sollte aber berücksichtigen, daß er nur ne LED bei ner Schwelle schalten will. D.h. da wird man eh ne Hysterese einbauen müssen, damit die LED nicht flackert. Und warscheinlich wird der Spannungsteiler nicht so niederohmig sein, daß da viele mA durchfließen und nen großen Spannungsabfall verursachen. Man muß also nicht unbedingt Berechnungen für Präzisionsmessungen einsetzen. Die Annahme, der eingeschaltete Portpin liefert (genau genug) VCC, sollte hier vollkommen ausreichen. Peter
Guten Morgen!! Also unter DC Characteristics kann ich lesen, dass bei VCC = 3V um die 2,5 V am High Pin anliegen. Nach dem letzten Beitrag kann ich also sagen, der Ausgang des Portpins liefert VCC. Ich kann dann also meinen Portpin gleich Anfangs der while(1) Schleife aktivieren. Demnach bräuchte ich dann ja auch wohl die Referenz Messung nicht wenn ich ohnehin davon ausgehe dass meine Spg. gegen VCC geht. Was verändert sich dann unterm Strich in meiner Software? Dass ich beim ADMUX Register die Bits REFS1 und REFS0 umändern muss. Diese sind ja derzeit auf 00 damit die VCC benützt wird. Naja für mich hätte ohnehin erst mal die Batterieüberwachung und die Sache mit Power-Down oberste Priorität da mein Sensor ja funktioniert. Das kann man dann natürlich immer noch verfeinern. Habe immer noch mit der Batterieüberwachung zu kämpfen, weil ich da einfach ein Denkproblem habe. Ich weiss dass ich keine weiteren Bauteile benötige. Ich weiss dass ich meine 1,1 V Referenz benutze. Ich weiss dass ich diese Sache immer einmal nach dem Einschalten machen möchte. Dann also nicht mehr. Sprich meine while(1) Schleife vom Sensor bleibt völlig unberührt. Ich weiss dass ich beim MUX5:0 auf 100001 programmieren muss. Das dürften also alles in allem 3-4 Zeilen Programmcode sein incl. einer if-Abfrage. Wird das Programm eigentlich nach dem Aufwachen aus dem Power-Down Mode völlig neu gestartet. Also bin ich da auf der sicheren Seite dass die Batteriemessung durchgeführt wird? Gruß Thomas
Bastler schrieb: > Ich weiss dass ich diese Sache > immer einmal nach dem Einschalten machen möchte. Dann also nicht mehr. > Sprich meine while(1) Schleife vom Sensor bleibt völlig unberührt. Versuch uns mal zu erklären, wie Du bloß darauf kommst, daß man in der Mainloop nur ausschließlich eine Sache machen darf. > Wird das Programm eigentlich nach dem Aufwachen aus dem Power-Down Mode > völlig neu gestartet. Natürlich nicht. Es geht nach dem SLEEP weiter. Ansonsten hätte man ziemliche Probleme, ein vernünftiges Programm zu schreiben. Peter
Naja ich dachte hald die Sache mit der Batterieüberwachung macht man ganz am Anfang. Aber das hat sich mit der Tatsache ja schon erledigt dass es nach dem aufwachen nicht mehr aufgerufen werden würde. Das Einschlafen und Aufwachen des Controllers ist ja praktisch mein on/off Zustand. In meiner Mainloop würde die Abfrage ja wohl auch dauernd passieren wie die Abfrage des Sensors. Das möchte ich ja nicht. Nach jedem aufwachen soll er einmal messen ob meine Spg. 2,4V ist. Wenn ja Warn LED an. Dass die Unterbrechung des ganzen in der Mainloop sein muss ist mir ja auch klar weil er aus der while(1) Schleife ohne Interrupt nicht mehr rauskommmt. Ok aber das ist dann noch die zweite Baustelle mit dem Taster... Also der sleep Befehl muss ja in der Endlosschleife stehen oder eben mit der Unterfunktion. Dann muss diese Unterfunktion in der Mainloop aufgerufen werden. Diese Info habe ich ja bereits bekommen mit der Unterfunktion. Und die Interrupt Service Routine steht dann ja auch noch irgendwo. Gruß Thomas
Bastler schrieb: > Also unter DC Characteristics kann ich lesen, dass bei VCC = 3V um die > 2,5 V am High Pin anliegen. Sinnvoller ist es hier, unter den `Typical Characteristics' die `Pin driver strenght'-Werte anzusehen. Das sind FETs im Ausgang, da hast du ohne Last die volle Vcc am durchgeschalteten Ausgang liegen, mit Last verhält sich der Kanal eines FETs anfangs wie ein Widerstand, wenn er in die Sättigung gerät, verhält er sich wie eine Konstantstromquelle. Deren Strom ist allerdings von der Gatespannung (und damit indirekt von der Höhe von Vcc) abhängig, das lässt sich vor allem bei den Kurven für kleines Vcc gut erkennen. Ob du mit dem Fehler leben kannst, die Ausgangsspannung des Portpins als Vcc anzunehmen, oder ob du sie lieber nachmessen und heraus rechnen willst, musst du selbst einschätzen.
Ich denke mal ich kann damit leben da ich ja die relative Feuchte Werte ohnehin nur ungefähr sagen kann. Das wird eh schwer genug zu sagen bei der anliegenden Spg. hat der Sensor den Widerstand und damit die relative Feuchte. Ich werde mich jetzt aber mehr darauf konzentrieren dass die Batterieüberwachung klappt. Da werde ich sicher nochmal eure Hilfe brauchen. Bei der Sache mit dem Taster sowieso. Das scheint mir irgendwie das kompliziertere. Kann ich eigentlich um das Prellen zu verhindern oder zumindest zu vermindern einen Kondensator (z.B. 100 nF) parallel zum Taster auf GND legen. Das müßte doch auch klappen. Gruß Thomas
Bastler schrieb: > Zustand. In meiner Mainloop würde die Abfrage ja wohl auch dauernd > passieren wie die Abfrage des Sensors. Das möchte ich ja nicht. Warum nicht? Irgendwie hab ich das Gefühl wir reden aneinander vorbei > Nach > jedem aufwachen soll er einmal messen ob meine Spg. 2,4V ist. Wenn ja > Warn LED an. Ja. Wo ist das Problem? > Dass die Unterbrechung des ganzen in der Mainloop sein muss > ist mir ja auch klar weil er aus der while(1) Schleife ohne Interrupt > nicht mehr rauskommmt. Ok aber das ist dann noch die zweite Baustelle > mit dem Taster... Also der sleep Befehl muss ja in der Endlosschleife > stehen oder eben mit der Unterfunktion. Dann muss diese Unterfunktion in > der Mainloop aufgerufen werden. Diese Info habe ich ja bereits bekommen > mit der Unterfunktion. Und die Interrupt Service Routine steht dann ja > auch noch irgendwo. Auch hier wieder? Wo ist das Problem?
Bastler schrieb: > brauchen. Bei der Sache mit dem Taster sowieso. Das scheint mir > irgendwie das kompliziertere. Ähm. Ich würde mal vorschlagen. Kümmere dich um alles andere zuerst. Wenn dir Tasterentprellen noch Schwierigkeiten macht, dann solltest du erst mal anfangen kleinere Brötchen zu backen. Ich hab das Gefühl du führst zur Zeit einen 5-Fronten Krieg, weißt nicht wo du anfangen sollst. Mach eines nach dem anderen. Sieh zu dass du ein Teilproblem nach dem anderen in den Griff kriegst. Es ist auch sinnvoll für einzelne Teilprobleme erst mal einzelne Spielprogramme zu machen. Und erst dann, wenn du für jeden Teilbereich funktionierende Programme und Lösungen hast, dann (Überraschung!) fang ein neues Programm an, in dem du die Einzelteile zusammenführst. Dein Erstentwurf eines funktionierenden Gesamtprogramms wird wahrscheinlich sowieso nicht funktionieren und du musst damit rechnen den ein zweites mal zu machen. Erst mal Erfahrung mit den Einzelteilen sammeln. Wie macht man Tasterabfrage Wie macht man Sensorauswertung Wie funktioniert Versorgungsspannungsmessung Wie funktioniert sleep Erst wenn du diese Teilbereiche in jeweils einem eigenen Teilprogramm studiert und abgehandelt und ein wenig damit rumgespielt hast um Erfahrung zu bekommen, erst dann bist du soweit, mit deinem eigentlichen Komplettprogramm zu beginnen. Im Moment verzettelst du dich, indem du 25 Teilprobleme gleichzeitig angehst und zu lösen versuchst und dabei den Überblick verlierst. Und nochwas: Rechne auf jeden Fall damit, dass du dein eigentliches Programm mindestens 2 mal schreibst.
Nachdem mir im anderen Thread nahegelegt wurde dass ich meinen gesamten Code mal zur Verfügung stellen soll werde ich das jetzt tun. Zur Information: Der Spg.teiler hängt noch an VCC. Hier habe ich jetzt nur versucht den Code so übersichtlich wie nur irgendwie möglich zu machen. Außerdem habe ich versucht den Code für die Batterieüberwachung einzufügen. Natürlich ist es so dass das ganze nicht funktioniert. Die Sensormessung ist nach wie vor i.O.. Allerdings leuchtet die Lampe für Batterieüberwachung dauerhaft. Könnt ihr mir bitte einen Tip geben wo genau der Fehler liegt. Außerdem würde mich interessieren ob die Batterieüberwachung und der Aufruf für den Power-Down Taster in der Mainloop an der richtigen Stelle liegen. Gruß Thomas
Bastler schrieb: > Außerdem habe ich versucht den Code für die Batterieüberwachung > einzufügen. Natürlich ist es so dass das ganze nicht funktioniert. Du scheinst eine besondere Leseabneigung zu haben, was den ADC betrifft: Beitrag "Re: Power-down mit Taster" Peter
Diese Antwort kann ich nicht nachvollziehen. Ich habe ja in dem anderen Beitrag auch reingeschrieben. Dann hieß es ich soll meinen Code in eine Form bringen die jeder schnell lesen kann. Was meinst du mit Leseabneigung?? Ich habe mir das jetzt schon paarmal durchgelesen. Auch im Datenblatt. Im Moment lese ich auch im Tutorial. Manche Sachen verstehe ich ehrlich gesagt nicht. Da mach ich das hald so wie ich es mir denke. Bleibt mir ja nichts anderes übrig. Wenn du darauf anspielst dass ich immer noch VCC als Referenz nehme dann muss ich sagen: 1. Habe ich das in paar Beiträgen zur VCC Messung auch so gelesen. 2. erscheint es mir unlogisch als Referenz 1,1 V zu haben aber damit 2,4 V messen zu wollen! Ich weiss ja dass da irgendwo der Haken liegt. Einerseits MUX5..0 die 1,1 V ansprechen andererseits VCC als Referenz. Das wird ja auch wohl das Problem sein.
Den Free Running Mode würde ich gar nicht verwenden. Es reicht nämlich nicht, einfach nur den Multiplexer zu setzen und im nächsten Takt schon zu erwarten, dass ein Ergebnis vom ADC da ist. Ich würde es so machen: Ich würd mir aus dem Tutorial die ADC Routine rauskopieren, so wie sie ist! Die übernehme ich in mein Projekt, so wie sie ist. Anstelle des ganzen gefrieckels in der main() rufe ich einfach die Funktion auf und kriege ein Messergebnis zurück. Super. Dann gehe ich her und untersuche, wie in der ADC Routine die Referenzspannung gesetzt wird. Da bau ich mir in diese Routine noch einen zusätzlichen Parameter ein, so dass ich der Funktion auch noch den Code für die Referenzspannung mit übergeben kann. Dann ruf ich in der Hauptschleife die ADC-Funktion zweimal auf. Einmal für Batteriespannung mit 1.1V als Referenz Einmal für das ineterssierende Messergebnis.
Achso. Das ist jetz mal wieder ein sehr interessanter Tip. Ich habe dir Free Running Option gewählt weil ich mir dachte ich möchte ja eine Dauerwandlung. Bei Single Shot muss ich das ganze ja erst wieder anstoßen. Das mit der Unterfunktion für die Sensorwandlung kann ich nachvollziehen. Für die Sache mit dem Taster wurde mir ja auch schon gesagt eigene Funktion. Die Interruptserviceroutine für den externen Interrupt ist ja quasi auch eine "eigene" Funktion. Also sie hat ja auch die geschweiften Klammern und steht nicht in Main. Im Tutorial sehe ich ein Programm das den internen ADC betriff mit der Überschrift "Aktivieren des ADC". Allerdings geht es da ja auch um eine Mittelwertbildung und so. Also eigentlich etwas anderes als ich brauche. Ich muss auch sagen dass ich da so manche Zeile nicht nachvollziehen kann. Das liegt natürlich auch daran dass des ein andere Controller ist. Zu der ADC Wandlung muss ich sagen dass mein Sensor ja ausgewertet wird. Den Tip es so machen habe ich von Studienkollegen bekommen. Keiner hat da Erfahrung mit Atmel controllern. Eher mit Texas Instruments oder 8051 und so. Darum war ich im guten Glauben dass ich das so realisieren kann. Die letzten beiden Absätze verstehe ich nicht. Zusätzlicher Parameter für Code der REferenzspannung??????????? Ich habe ja auch erwähnt dass ich keinerlei Erfahrung im programmieren habe. Es würde auch zu lange dauern zu erklären warum ich in dieses Gebiet reinblicke. Die Hauptarbeit betrifft eine ganz bestimmte Technologie. Darum ist es mir auch nicht möglich beim programmieren viel Zeit zu investieren. Ich weiss von Studienkollegen "learning by doing"! Nur ich habe diese Monate derzeit leider nicht. Diese Monate kann ich frühestens nächstes Jahr investieren um darin Erfahrung zu sammeln. Es gab ja auch Aussagen ich soll mir den Code im Internet zusammenstückeln und bissl anpassen. So einfach geht das ohnehin leider nicht. Jedenfalls ist das alles nicht so einfach wenn man die Zusammenhänge dahinter nicht versteht. Ich kann inzwischen meinen Code nachvollziehen. Mir ist auch klar dass Leute die das professionel machen ganz anders an die Sache gehen würden. Ich kann das hald nur im Rahmen meiner sehr beschränkten Möglichkeiten tun. Ich werde mir mal überlegen wie ich aus der Sensorauswertung eine eigene Funktion mache. Das werde ich schon irgendwie schaffen. Für mich ist hald auch schwer ein Gefühl dafür zu entwickeln was gehört wo hin und an welche Stelle.
Bastler schrieb: > Achso. Das ist jetz mal wieder ein sehr interessanter Tip. Ich habe dir > Free Running Option gewählt weil ich mir dachte ich möchte ja eine > Dauerwandlung. Bei Single Shot muss ich das ganze ja erst wieder > anstoßen. Ja und? Dein µC hat doch Zeit genug! Oder ist es unbedingt notwendig, dass du 3000 Wandlungen in der Sekunde machst?
1 | #include <avr/io.h> |
2 | #include <inttypes.h> |
3 | |
4 | uint16_t adcmessung(uint8_t ref_und_mux) |
5 | {
|
6 | uint16_t messwert; |
7 | uint8_t i; |
8 | |
9 | ADMUX = ref_und_mux; |
10 | ADCSRA = (1<<ADEN); |
11 | |
12 | /*
|
13 | Nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen,
|
14 | man liest also einen Wert und verwirft diesen, um den ADC
|
15 | "warmlaufen zu lassen"
|
16 | */
|
17 | ADCSRA |= (1<<ADSC); // eine ADC-Wandlung |
18 | while ( ADCSRA & (1<<ADSC) ) |
19 | {
|
20 | ; // auf Abschluss der Konvertierung warten |
21 | }
|
22 | messwert = ADCW; // Auslesen (Pflicht!) |
23 | |
24 | /*
|
25 | Eigentliche Messung: Mittelwert aus 4 Wandlungen
|
26 | */
|
27 | messwert = 0; |
28 | for( i=0; i<4; i++ ) |
29 | {
|
30 | ADCSRA |= (1<<ADSC); // eine Wandlung "single conversion" |
31 | while ( ADCSRA & (1<<ADSC) ) |
32 | {
|
33 | ; // auf Abschluss der Konvertierung warten |
34 | }
|
35 | messwert += ADCW; // Wandlungsergebnisse aufaddieren |
36 | }
|
37 | |
38 | ADCSRA &= ~(1<<ADEN); // ADC disable (Stromsparen) |
39 | messwert /= 4; // Summe durch vier teilen = arithm. Mittelwert |
40 | return messwert; |
41 | }
|
42 | |
43 | |
44 | /*
|
45 | Spannungsmessung zur Batterieueberwachung
|
46 | MUX5...0 1,1 V (interne Referenz) auf ADC geben
|
47 | und mit Referenzspg. = VCC messen.
|
48 | */
|
49 | void batterieueberwachung(void) |
50 | {
|
51 | uint16_t messwert; |
52 | |
53 | messwert = adcmessung((0<<REFS1)|(0<<REFS0)|(1<<MUX5)|(1<<MUX0)); |
54 | |
55 | /*
|
56 | 1D6h = 470d; bei VCC 2,4V entspricht 1,1V der
|
57 | externen Referenz 470 "Stufen" im 10Bit ADC
|
58 | ADCW = 1024 * 1.1 / Vcc
|
59 | */
|
60 | if(messwert <= ((1024*11)/24)) |
61 | {
|
62 | PORTB &= ~(1<<PB1); // Batterie-LED an (low-active) |
63 | }
|
64 | }
|
65 | |
66 | |
67 | void feuchtemessung(void) |
68 | {
|
69 | uint16_t messwert; |
70 | |
71 | messwert = adcmessung((0<<REFS1)|(0<<REFS0)|(0<<MUX5)|(0<<MUX0)); |
72 | |
73 | if(messwert >= 0x96) |
74 | {
|
75 | PORTA ^= (1<<PA1); // rote LED toggeln |
76 | PORTA = (1<<PA2)|(1<<PA3); // restl. LEDs aus |
77 | }
|
78 | else if((messwert > 0x32) && (messwert < 0x96)) |
79 | {
|
80 | PORTA ^= (1<<PA2); // gelbe LED toggeln |
81 | PORTA = (1<<PA1)|(1<<PA3); // restl. LEDs aus |
82 | }
|
83 | else if(messwert <= 0x32) |
84 | {
|
85 | PORTA ^= (1<<PA3); // gruene LED toggeln |
86 | PORTA = (1<<PA1)|(1<<PA2); // restl. LEDs aus |
87 | }
|
88 | }
|
89 | |
90 | |
91 | int main(void) |
92 | {
|
93 | uint8_t trigger = 0; |
94 | |
95 | /* Initialisierung PortA */
|
96 | DDRA = (1<<PA1)|(1<<PA2)|(1<<PA3); // PA1, PA2, PA3 = Ausgang |
97 | PORTA = (1<<PA1)|(1<<PA2)|(1<<PA3); // alle LEDs aus |
98 | |
99 | /* Initialisierung PortB */
|
100 | DDRB |= (1<<PB1); // PB1 LED fuer Batterieueberwachung |
101 | DDRB &= ~(1<<PB2); // PB2 Taster Eingang (low-active) |
102 | PORTB = (1<<PB1)|(1<<PB2); // Taster an PB2 mit int. Pull-UP, Bat-LED aus |
103 | |
104 | while(1) |
105 | {
|
106 | // z.B. jedes 256.te Mal
|
107 | if (trigger == 0) |
108 | batterieueberwachung(); |
109 | |
110 | // z.B. jedes 16. Mal
|
111 | if ((trigger & 16) == 0) |
112 | feuchtemessung(); |
113 | |
114 | /* uint8_t */ trigger++; |
115 | }
|
116 | }
|
Da er schon über power-down nachdenkt, wäre es natürlich naheliegend, die Messungen jeweils über einen Timerinterrupt bspw. alle 100 ms anzuwerfen und zwischendurch den Prozessor schlafen zu legen.
Karl heinz Buchegger schrieb:
> Den Free Running Mode würde ich gar nicht verwenden.
Stimmt, der geht nicht, wenn man vereschiedene Quellen wandeln muß.
Bzw. nur, wenn man es im Interrupthandler macht.
Ansonsten hat man keine Chance, zu erkennen, wann welche Wandlung fertig
ist.
Aber egal, welcher Mode, das Ergebnis ist nie direkt nach dem MUX
umschalten da.
Ne ADC-Funktion zu schreiben, ist generell ne gute Idee.
Man übergibt ihr den gewünschte Input-Kanal und sie liefert das
Ergebnis, d.h. macht alle notwendigen Zwischenschritte.
Peter
Bastler schrieb: >Allerdings leuchtet die Lampe für Batterieüberwachung dauerhaft. Stefan schrieb: > if(messwert <= ((1024*11)/24)) Da habe ich das Original nicht kontrolliert und das <= einfach übernommen. Es muss aber if(messwert >= ((1024*11)/24)) heissen, wenn die Batterie-LED nur bei Unterspannung (<=2,4V) leuchten soll. Vcc Vmess ADC (messwert) ========================== 5,0 1,1 225 2,5 1,1 450 2,4 1,1 469 2,3 1,1 489
Korrektur: Statt
1 | PORTA = (1<<PA2)|(1<<PA3); // restl. LEDs aus |
2 | PORTA = (1<<PA1)|(1<<PA3); // restl. LEDs aus |
3 | PORTA = (1<<PA1)|(1<<PA2); // restl. LEDs aus |
muss
1 | PORTA |= (1<<PA2)|(1<<PA3); // restl. LEDs aus |
2 | PORTA |= (1<<PA1)|(1<<PA3); // restl. LEDs aus |
3 | PORTA |= (1<<PA1)|(1<<PA2); // restl. LEDs aus |
sonst ist das Toggeln die Zeile davor für die Katz!
Hallo! Nochmal danke für euere Hilfe. Ich komme jetzt erst wieder dazu mich um meine Software zu kümmern, weil ich Prüfungszeit hatte. Die Batterieüberwachung scheint auch zu funktionieren. Ich wollte jetzt auch noch das Blinken der roten Lampe mit rein nehmen wie in meinem ursprünglichen Programm. Das hat leider dazu geführt dass die rote LED gar nicht mehr angeht und nur noch maximal die gelbe LED leuchtet. Ich habe es in diesem Textbeispiel auskommentiert. Siehe Anhang! Für die Power-Down Funktion muss ich dann also nochmal so eine Unterfunktion schreiben die dann auch wieder im Main aufgerufen wird oder? Wie kann ich das verstehen mit den Aufrufen: jedes 256. Mal bzw jedes 16. Mal? Gruß Thomas
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.