mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik AtMega8 - Funktioniert das so?


Autor: Nico (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Ich möchte mir für eine Vitrine mit Pflanzen eine Anzeige basteln, die 
wesentliche Eigenschaften anzeigt (Luftfeuchte, Bodenfeuchte, 
Temperatur, Helligkeit). Dazu wollte ich den Zustand der resistiven 
Sensoren über einen AtMega8 auf Bargraphs anzeigen. Das ist dann 
zugleich mein "Debüt" mit µCs.
Ich habe auch schon Schaltplan und Programm fertig und mit Proteus Isis 
simuliert. Scheint alles zu laufen.
Da ich die Bauteile bestellen muss und nicht zweimal Porto bezahlen 
will, wäre es schön, wenn sich jemand das ganze mal ansehen und einen 
Kommentar abgeben könnte.
Zum Schaltplan im Anhang:
Ich bin mir nicht wirklich sicher, ob Proteus die Schaltzeichen für die 
Bargraphs kennt. Jedenfalls sollen das die Dinger ganz rechts sein.
Unten links sind die resistiven Sensoren als Potentiometer angedeutet.
Der ISP soll an die COM-Schnittstelle des Computers angeschlossen 
werden.
Das ganze funktioniert über Multiplexing. Port D und zwei Pins von Port 
C geben die Daten aus und 4 Pins von Port B schalten die entsprechenden 
Transistoren.
Ich denke, der Rest erklärt sich von alleine.
Und jetzt der Quelltext (zwei Anhänge gibt es hier nicht, oder?):
#include <avr/io.h>
#include <math.h>

// Anzahl der LEDs
volatile unsigned char LFeuchte;
volatile unsigned char BFeuchte;
volatile unsigned char Licht;
volatile unsigned char Temp;

volatile unsigned char count;
volatile unsigned char count2;

void Zeige(unsigned int LED, int n)
{
  if(n<0) n=0;
  PORTB=0x0;
  PORTD=0x0;
  PORTC=0x0;
  if(n>=1) PORTD |= 0x1;
  if(n>=2) PORTD |= 0x2;
  if(n>=3) PORTD |= 0x4;
  if(n>=4) PORTD |= 0x8;
  if(n>=5) PORTD |= 0x10;
  if(n>=6) PORTD |= 0x20;
  if(n>=7) PORTD |= 0x40;
  if(n>=8) PORTD |= 0x80;
  if(n>=9) PORTC |= 0x10;
  if(n>=10) PORTC |= 0x20;
  PORTB=LED;
}

void ActivateNext()
{
  switch(PORTB)
  {
    case 0x40: case 0x00:
      Zeige(0x01,LFeuchte);
      break;
    case 0x01:
      Zeige(0x02,BFeuchte);
      break;
    case 0x02:
      Zeige(0x04,Licht);
      break;
    case 0x04:
      Zeige(0x40,Temp);
      break;
  }
}

void Messen()
{
  volatile unsigned int U;
  ADMUX = 0x00;
  ADCSRA |= (1<<ADSC); //Single-Conversion
  while (ADCSRA & (1<<ADSC)); // Auf Abschluss warten
  U=ADCL;
  U+=(ADCH<<8);
  //SHS-A2
  if (U<=174) LFeuchte=0; //<50%
  if (U<=250 && U>174) LFeuchte=1; //50 - 55%
  if (U<=345 && U>250) LFeuchte=2; //55 - 60%
  if (U<=455 && U>345) LFeuchte=3; //60 - 65%
  if (U<=571 && U>455) LFeuchte=4; //65 - 70%
  if (U<=681 && U>571) LFeuchte=5; //70 - 75%
  if (U<=776 && U>681) LFeuchte=6; //75 - 80%
  if (U<=851 && U>776) LFeuchte=7; //80 - 85%
  if (U<=907 && U>851) LFeuchte=8; //85 - 90%
  if (U<=946 && U>907) LFeuchte=9; //90 - 95%
  if (U>=946) LFeuchte=10; //>95%

  ADMUX = 0x01;
  ADCSRA |= (1<<ADSC); //Single-Conversion
  while (ADCSRA & (1<<ADSC)); // Auf Abschluss warten
  U=ADCL;
  U+=(ADCH<<8);
  if (U>877) BFeuchte=0; //60 kR
  if (U<=877 && U>866) BFeuchte=1; //60-55 kR
  if (U<=866 && U>853) BFeuchte=2; //55-50 kR
  if (U<=853 && U>837) BFeuchte=3;
  if (U<=837 && U>818) BFeuchte=4;
  if (U<=818 && U>796) BFeuchte=5;
  if (U<=796 && U>767) BFeuchte=6;
  if (U<=767 && U>731) BFeuchte=7;
  if (U<=731 && U>682) BFeuchte=8;
  if (U<=682 && U>614) BFeuchte=9;
  if (U<=614) BFeuchte=10;
  

  ADMUX = 0x02;
  ADCSRA |= (1<<ADSC); //Single-Conversion
  while (ADCSRA & (1<<ADSC)); // Auf Abschluss warten
  U=ADCL;
  U+=(ADCH<<8);
  //Die folgenden Werte sind noch nicht angepasst
  if (U>877) Licht=0;
  if (U<=877 && U>866) Licht=1;
  if (U<=866 && U>853) Licht=2;
  if (U<=853 && U>837) Licht=3;
  if (U<=837 && U>818) Licht=4;
  if (U<=818 && U>796) Licht=5;
  if (U<=796 && U>767) Licht=6;
  if (U<=767 && U>731) Licht=7;
  if (U<=731 && U>682) Licht=8;
  if (U<=682 && U>614) Licht=9;
  if (U<=614) Licht=10;

  ADMUX = 0x03;
  ADCSRA |= (1<<ADSC); //Single-Conversion
  while (ADCSRA & (1<<ADSC)); // Auf Abschluss warten
  U=ADCL;
  U+=(ADCH<<8);
  if (U>630) Temp=0; //kleiner 15 Grad
  if (U<=630 && U>619) Temp=1; // 15 bis 16 Grad
  if (U<=619 && U>608) Temp=2; // 16 bis 17 Grad
  if (U<=608 && U>597) Temp=3; // 17 bis 18 Grad
  if (U<=597 && U>585) Temp=4; // 18 bis 19 Grad
  if (U<=585 && U>574) Temp=5; // 19 bis 20 Grad
  if (U<=574 && U>562) Temp=6; // 20 bis 21 Grad
  if (U<=562 && U>551) Temp=7; // 21 bis 22 Grad
  if (U<=551 && U>539) Temp=8; // 22 bis 23 Grad
  if (U<=539 && U>528) Temp=9; // 23 bis 24 Grad
  if (U<=528) Temp=10; // über 24 Grad
}

int main (void) {  
  DDRD  = 0xff;
  DDRB = 0x47; //01000111
  DDRC = 0x30; //00110000
  ADCSRA = 0xc7; //11000111, ADC aktivieren

  TCCR0 = (1<<CS00)|(1<<CS02);    //Prescaler 1024
 
  while(1) 
  {
    if(TCNT0 == 0xff) // alle 1.024 ms
    {
      count++;
      if(count==4) //getestet mit count == 50
      {
        count2++;
        ActivateNext();
        count = 0;
      }
      if(count2==200) //getestet mit count2 == 1
      {
        Messen();
        count2=0;
      }
    }
  }                         

  return 0;                 
}
Also in der Hauptschleife werden zum einen die Anzeigen aktualisiert 
(ca. 60 Hz pro Anzeige). Und zum anderen werden in regelmäßigen 
Abständen (ca. 1 s) neue Messungen durchgeführt.
Da bei der Simulation die CPU ziemlich belastet wird, habe ich nicht mit 
voller Geschwindigkeit getestet, sondern mit den in den Kommentaren 
angegebenen Werten ("getestet mit...").
Vielleicht findet ja jemand ein paar Minuten Zeit, sich die ganze Sache 
mal anzusehen.
Danke schonmal im Voraus.

Nico

Autor: Michael U. (amiga)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

hab nur kurz auf den Schaltplan geschaut...

Wenn die Bargraphs grüne LED haben, dürfte der LED-Strom bei mindestens 
20mA liegen. Dann überschreitest Du die maximal zulässigen 200mA des 
Mega8.

Die 100n an den Spannugsanschlüssen zwischen VCC/GND und AVCC/AGND 
fehlen.
AREF gehört über 100n an GND, nicht an AVCC.

AVCC sollte über eine Drossel entkoppelt werden wenn man den ADC 
benutzt.

An den ADC-Eingängen sind vermutlich auch noch ca. 100n Kondensatoren 
gegen GND als Tiefpass gegen Störungen auf den Leitungen zu den Sensoren 
nötig.

Was sind das für Sensoren? Speziell Luftfeuchte als Widerstandssensor 
kenne ich im Moment nicht.

C3 würde ich eher 220-470µ nehmen, die LEDs erzeugen merkliche 
Lastwechsel, hängt aber auch vom Netzteil ab.

Q1 am Reset gibt einen netten Verstärker für Störungen ab wenn nichts 
angeschlossen ist. Besser noch 47-100n am Reset gegen GND.

Gruß aus Berlin
Michael

Autor: Nico (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke, fürs Ansehen.
Wenn die Bargraphs grüne LED haben, dürfte der LED-Strom bei mindestens
20mA liegen. Dann überschreitest Du die maximal zulässigen 200mA des
Mega8.
Ich weiß jetzt gar nicht mehr, warum ich bei den Bargraphs 100R 
Vorwiderstand genommen habe. Wenn ich da 500R nehme, wären das ja 
I=U/R=5 V / 500 R=10 mA. Wären insgesamt höchstens hundert mA. Wäre das 
dann zu verkraften?
Die 100n an den Spannugsanschlüssen zwischen VCC/GND und AVCC/AGND
fehlen.
Da hatte ich eigentlich die Kondensatoren oben links vor und hinter dem 
Spannungswandler vorgesehen. Reichen die nicht aus oder müssen woanders 
noch welche hin?
AREF gehört über 100n an GND, nicht an AVCC.
Also lieber die interne Referenzspannung benutzen?
An den ADC-Eingängen sind vermutlich auch noch ca. 100n Kondensatoren
gegen GND als Tiefpass gegen Störungen auf den Leitungen zu den Sensoren
nötig.
Gut. Das werde ich noch einbauen.
Was sind das für Sensoren? Speziell Luftfeuchte als Widerstandssensor
kenne ich im Moment nicht.
Bei Conrad gibt es da zum Beispiel den SHS A2, den ich verwenden will.
C3 würde ich eher 220-470µ nehmen, die LEDs erzeugen merkliche
Lastwechsel, hängt aber auch vom Netzteil ab.
Gut. Werde ich auch noch ändern. Gibt es ein Problem, wenn eine Batterie 
genutzt werden soll?
Q1 am Reset gibt einen netten Verstärker für Störungen ab wenn nichts
angeschlossen ist. Besser noch 47-100n am Reset gegen GND.
Ändere ich auch noch.

Danke für die Mühe.

Nico

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Gut. Werde ich auch noch ändern. Gibt es ein Problem, wenn eine Batterie
>genutzt werden soll?

Eine 9V Blockbatterie? Jo, dann läuft das ganze
vieleicht 10 Minuten.

Autor: roman (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
irgendwie begreiff ich nicht wiso alle die led's direkt vom avr 
treiben... meine ein uln dazwischen kostet nix und entlastat die 
schaltung... zudem hat man die möglichkeit den strom so zu variieren wie 
man möchte...

Autor: Michael U. (amiga)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Nico wrote:

> Ich weiß jetzt gar nicht mehr, warum ich bei den Bargraphs 100R
> Vorwiderstand genommen habe. Wenn ich da 500R nehme, wären das ja
> I=U/R=5 V / 500 R=10 mA. Wären insgesamt höchstens hundert mA. Wäre das
> dann zu verkraften?
Deine Rechnung stimmt nicht. I = (5V - Uled - Ul_out)/R
Uled steht in deren Datenblatt, bei roten ca. 1,6V, bei grünen ca. 2V.
Ul_out ist die Spannung am AVR-Pin bei L-Pegel und dem fließenden Strom.
Gibt es im AVR-Datenblatt Diagramme zu. Bei 10mA wohl um 0,2V.

Umgestellt zum Widerstand also 5V - 2V - 0,2V = 2,8V / 10mA = 280 Ohm.
Allerdings machst Du ja einen 1:4 Multiplex, also sollte der Strom schon 
höher sein, er fließt ja nur 1/4 der Zeit und die LED sind evtl. zu 
dunkel.

Der Maximalstrom eines Portpins ist zwar 40mA, allerdings darf der Strom 
über Vcc bzw. GND des AVR 200mA nicht übersteigen (Datenblatt).

> Da hatte ich eigentlich die Kondensatoren oben links vor und hinter dem
> Spannungswandler vorgesehen. Reichen die nicht aus oder müssen woanders
> noch welche hin?
Siehe Stützkondensatoren/Abblockkondensatoren oder wie es auch gerade 
heißt. Alle ICs müssen dicht an ihren Vcc/GND-Anschlüssen einen 100n 
Kondensator bekommen.
Beim Umschalten treten im ns-Bereich Stromspitzen auf, die von diesen 
Kondensatoren gepuffert werden sollen. Da jeder mm Leiterbahn/Draht eine 
kleine Induktivität darstellt, verlieren die ihre Wirkung, wenn sie zu 
weite weg sind.
>
>
AREF gehört über 100n an GND, nicht an AVCC.
> Also lieber die interne Referenzspannung benutzen?
Nein. Man kann auch AVCC als Referenz intern einschalten. Wenn aber AREF 
an AVCC angeschlossen ist und Du programmierst dann die interne 
Referenzspannug, dann liegt die an dem Pin. Ob das den FET, der die 
2,56V dann gegen die 5V schalten soll, so gefällt?

>
Was sind das für Sensoren? Speziell Luftfeuchte als
> Widerstandssensor
> kenne ich im Moment nicht.
> Bei Conrad gibt es da zum Beispiel den SHS A2, den ich verwenden will.

Naja, das ist ein Betauungssensor, ob man den sinnvoll zur relativen 
Feuchtemessung nutzen kann?
Ich kenne sowas aus alten Camcordern, wenn da Kondeswasser auftrat, weil 
man von kalten ins warme gekommen ist, dann haben die das Einschalten 
verhindert, damit das Band nicht an der Kopftrommel kleben bleibt.

>
C3 würde ich eher 220-470µ nehmen, die LEDs erzeugen merkliche
> Lastwechsel, hängt aber auch vom Netzteil ab.
> Gut. Werde ich auch noch ändern. Gibt es ein Problem, wenn eine Batterie
> genutzt werden soll?
Nein, macht keine Probleme, im Gegenteil.

Gruß aus Berlin
Michael

Autor: Klaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Für Feuchtigkeits- und Temperatur messungen empfehle ich den Sensor 
SHT11 der Firmal Sensirion.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.