Forum: Compiler & IDEs Power-down mit Taster


von Bastler (Gast)


Lesenswert?

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.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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.

von Bastler (Gast)


Angehängte Dateien:

Lesenswert?

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!

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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.

von Falk B. (falk)


Lesenswert?

Siehe Sleep Mode

von Bastler (Gast)


Lesenswert?

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);
        }
  }
}

von Peter D. (peda)


Lesenswert?

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

von Bastler (Gast)


Lesenswert?

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.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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.

von Bastler (Gast)


Lesenswert?

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.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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.

von Bastler (Gast)


Angehängte Dateien:

Lesenswert?

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?

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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...

von Stefan B. (stefan) Benutzerseite


Lesenswert?

> 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

von Bastler (Gast)


Lesenswert?

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.

von Bastler (Gast)


Angehängte Dateien:

Lesenswert?

Hier mein Quellcode nochmal in .c Format. Hoffe das passt so.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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.

von Bastler (Gast)


Lesenswert?

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.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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?

von Bastler (Gast)


Lesenswert?

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.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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!

von Peter D. (peda)


Lesenswert?

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

von Bastler (Gast)


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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

von Bastler (Gast)


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.

von Bastler (Gast)


Lesenswert?

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

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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!

von Bastler (Gast)


Lesenswert?

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.

von Bastler (Gast)


Lesenswert?

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?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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!

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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.

von Bastler (Gast)


Lesenswert?

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.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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. ;-)

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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

von Bastler (Gast)


Angehängte Dateien:

Lesenswert?

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

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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.

von Bastler (Gast)


Lesenswert?

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?

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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.

von Bastler (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.)

von Peter D. (peda)


Lesenswert?

Wenn man einen Spannungsteiler mißt, kann man ruhig die unstabile VCC 
als Referenz nehmen, die kürzt sich komplett raus.


Peter

von Karl H. (kbuchegg)


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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

von Peter D. (peda)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.

von Bastler (Gast)


Lesenswert?

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.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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).

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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

von Bastler (Gast)


Lesenswert?

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

von Peter D. (peda)


Lesenswert?

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

von Bastler (Gast)


Lesenswert?

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

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.

von Bastler (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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?

von Karl H. (kbuchegg)


Lesenswert?

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.

von Bastler (Gast)


Angehängte Dateien:

Lesenswert?

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

von Peter D. (peda)


Lesenswert?

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

von Bastler (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Bastler (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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?

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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
}

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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!

von Bastler (Gast)


Angehängte Dateien:

Lesenswert?

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
Noch kein Account? Hier anmelden.