Forum: Compiler & IDEs Analogwert vergleichen


von Oliver W. (soliver)


Lesenswert?

Hey,
ich habe da ein problem.
Ich versuche mit meinem ATmega88, eine analoge spannung einzulesen und 
zu vergleichen.

Die Spannung liefert eine kleine Solarzelle, (etwa 1V-2V ).
Die aufgabe des Micocontrollers soll es dabei sein die ausgegebene 
Spannung ständig zu kontrollieren und wenn ein gewisser spannungswert 
z.b.: 1,5V überschritten wird ein signal auszugeben.

Jetzt kommen meine fragen dazu:
Welche Refferenzspannung muss ich nehmen?
Funktioniert das ACO bit im ACSR register überhaupt?( es sind 
wiedersprüchliche angaben über dessen funktionsweise im Umlauf)

Ich versuche das Programm in C zu schreiben womit ich erst kürzlich 
angefangen habe.

Ich hoffe auf eure hilfe!
MFG Oliver
1
#include <avr\io.h>
2
#include <delay.h>
3
#include <stdint.h>
4
5
6
void port_init(void)
7
{
8
  DDRB = 0xff;
9
  DDRC = 0x00;
10
  DDRD= 0x00;
11
  ACSR = 0b00000000;
12
  ADCSRA = 0b11100111;
13
  DIDR1= 0xff ;
14
  ADMUX = (1<<REFS1) | (1<<REFS0);      // interne Referenzspannung nutzen
15
16
}
17
18
void AN(void) // signal geben
19
{
20
PORTB = 0x01;
21
22
}
23
24
void AUS(void) // signal stoppen
25
{
26
PORTB = 0x00;
27
28
}
29
30
int main(void)
31
{
32
  unsigned int x;
33
34
  AUS();
35
  port_init();
36
  
37
  while (1)
38
  {
39
40
  _delay_ms(1);
41
  ADCSRA |= (1<<ADSC);    //start_convertion();
42
43
44
  while (ADCSRA& (1<<ADSC));
45
46
  x= ADCL;          // wert auslesen
47
  x+= (ADCH<<8); 
48
49
        if(ACSR &(1<< 5))    // messpannung größer als refferenz /ACO bit gesetzt?
50
          {
51
            AN();      //sprung zur ausgabe  
52
          }
53
        else        // ACO nicht gesetzt
54
          {
55
            AUS();       //spannung ausstellen
56
          }
57
  _delay_ms(100);    
58
59
  }
60
}

von Karl H. (kbuchegg)


Lesenswert?

Oliver Warneke schrieb:

> Welche Refferenzspannung muss ich nehmen?

Eine die größer als deine zu messende Spannung ist und kleiner gleich 
deiner Versorgungsspannung

> Funktioniert das ACO bit im ACSR register überhaupt?( es sind
> wiedersprüchliche angaben über dessen funktionsweise im Umlauf)

Ich seh jetzt nicht ganz den Zusammenhang zwischen dem Analog Comperator 
und dem Analog/Digital Converter

> Ich versuche das Programm in C zu schreiben womit ich erst kürzlich
> angefangen habe.

Dann solltest du zuerst auf bewährte Funktionen zurückgreifen. Im 
AVR-GCC-Tutorial findet sich zb eine allgemeine ADC Routine, die auch 
funktioniert.

>   ACSR = 0b00000000;
>   ADCSRA = 0b11100111;
>   DIDR1= 0xff ;
>   ADMUX = (1<<REFS1) | (1<<REFS0);      // interne Referenzspannung


>
>   _delay_ms(1);
>   ADCSRA |= (1<<ADSC);    //start_convertion();
>
>
>   while (ADCSRA& (1<<ADSC));
>
>   x= ADCL;          // wert auslesen
>   x+= (ADCH<<8);
>
>         if(ACSR &(1<< 5))    // messpannung größer als refferenz /ACO
> bit gesetzt?


Für mich ist da der Gedankengang nicht wirklich nachvollziehbar, wie du 
aus einem ADC Wert plötzlich auf den Komperator kommst.

Du kennst deine Referenzspannung, nehmen wir an 5V (AVcc)
D.h. bei 1.5V würde der ADC einen Wert von ...

     5    .....  1023
     1.5  .....    x
   --------------------
           1.5 * 1023
     x = -------------  = 306
               5

... liefern. Daraus ergibt sich dann der Code:
1
    if( x > 306 )
2
      AN();
3
    else
4
      AUS();

Zu simpel? Oder warum meinst du, du musst da mit dem Comperator 
rummachen?



Lass den Free Running Mode Free Running Mode sein. Nimm die ADC Funktion 
aus dem Tutorial. Die macht 1 Messung bei jedem Funktionsaufruf. Dessen 
Ergebnis vergleichst du mit 306 (oder dem entsprechenden Wert für die 
dich interessierende Voltzahl) und gut ists.

von Mike (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Karl heinz

Karl heinz Buchegger schrieb:
> ... liefern. Daraus ergibt sich dann der Code:
>
>     if( x > 306 )
>
>       AN();
>
>     else
>
>       AUS();

Ich bin leider noch totaler Anfänger.
Und auf der suche nach einer ähnlichen Sache, nur ich möchte einen Text 
in der Webpage anzeigen lassen.

Diesen teil habe ich nun hin bekommen aber es wird kein Text ausgegeben.

[c]
      unsigned char Stufe
      #if USE_ADC
      //Visualisierung ADC3
      if(var_array[6] == 0)
      Stufe=("Anlage aus");
      if((var_array[6] >= 375) && (var_array[6] <= 385))
      Stufe="Stufe 1 =  44 % ~ 132 m³/h";
      if((var_array[6] >= 590) && (var_array[6] <= 610))
      Stufe="Stufe 2 =  76 % ~ 228 m³/h";
      if((var_array[6] >= 676) && (var_array[6] <= 686))
         Stufe="Stufe 3 =  100 % ~ 300 m³/h";
      #endif
[/c}

Was mache ich da Falsch und was muß ich ändern?
Ich habe die C Datei mit Angehangen und dieser Code steht ab Zeile 844.

Bitte helft mir damit ich das Projekt Fertig stellen kann.

Gruß Mike

von Floh (Gast)


Lesenswert?

Mike schrieb:
> unsigned char Stufe
; Strichpunkt, und warum eigentlich unsigned?
>       #if USE_ADC
>       //Visualisierung ADC3
>       if(var_array[6] == 0)
>       Stufe=("Anlage aus");

das geht so nicht! Stufe ist char, nimmt also genau ein (1) Zeichen auf.
-> C-Buch

>       if((var_array[6] >= 375) && (var_array[6] <= 385))
>       Stufe="Stufe 1 =  44 % ~ 132 m³/h";
s.o.
>       if((var_array[6] >= 590) && (var_array[6] <= 610))
>       Stufe="Stufe 2 =  76 % ~ 228 m³/h";
s.o.
>       if((var_array[6] >= 676) && (var_array[6] <= 686))
>          Stufe="Stufe 3 =  100 % ~ 300 m³/h";
s.o.

von Karl H. (kbuchegg)


Lesenswert?

Mike schrieb:

> Was mache ich da Falsch und was muß ich ändern?

So ziemlich alles.
Selbst dann, wenn man das von Floh gesagte berücksichtigt ... ist das 
immer noch Unsinn.

> aber es wird kein Text ausgegeben.

Logo.
Nur weil du eine Variable definierst, heißt das noch lange nicht, dass 
der Text dann irgendwie magisch auf der Web-Seite landet.

> Bitte helft mir damit ich das Projekt Fertig stellen kann.

Du musst erst mal C lernen, ehe du dich an so etwas wie einen 
vorhandenen Web-Server zu modifizieren wagst.

von Oliver W. (soliver)


Lesenswert?

Danke für die schnelle Antwort!
Durch den beitrag hab ich nun endgültig den unterscheid zwischen dem 
Comperator und dem ADC verstanden.

Es gibt allerdings noch einen Fehler in dem Programm.
Der Simulator kehrt nach der initialisierung des ADC´s nicht in die Main 
schleife zurück. Ich bin wie gesagt erst kürzlich mit der C 
Programierung angefangen und kann den Fehler nicht entdecken.

Die Funktion des Microcontrollers soll sein, einen Analog wert zu 
vergleichen und sobald dieser 1V überschritten hat ein Signal 
auszugeben.

Mein Programm sieht nun wie folgt aus.

#include <avr/io.h>
#include <util/delay.h>
#include <stdint.h>

/* Ports initialisieren */
void port_init(void)
  {
    DDRB = 0xff;
    DDRC = 0x00;
    DDRD = 0x00;
  }

/* ADC initialisieren */
void ADC_Init(void)
  {

    uint16_t result;

    ADMUX = (1<<REFS1) | (1<<REFS0);      // interne Referenzspannung 
nutzen
    ADCSRA = (1<<ADPS1) | (1<<ADPS0);     // Frequenzvorteiler
    ADCSRA |= (1<<ADEN);

    ADCSRA |= (1<<ADSC);                  // eine ADC-Wandlung
    while (ADCSRA & (1<<ADSC) );          // auf Abschluss der 
Konvertierung warten

    result = ADCW;
  }

    /* ADC Einzelmessung */
    uint16_t ADC_Read(uint8_t channel)
  {
      ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F);
      ADCSRA |= (1<<ADSC);
      while (ADCSRA & (1<<ADSC) )
        ;
      return ADCW  ;
  }

void AN(void) // signal geben
  {
    PORTB = 0x00;
  }

void AUS(void) // signal stoppen
  {
    PORTB = 0xFF;
  }

int main(void)
  {
    uint16_t x;

    port_init();         //Ports initialisieren
    ADC_Init();          //ADC  initialisieren

      while(1);        //Messschleife
    {
      _delay_ms(1000);    //Jede Sekunde Aktualisieren
      x = ADC_Read(1);     //Einzelmessung
        if( x > 306 )
            AN();
            else
            AUS();
    }
  }



Vielen Dank für die Hilfe!
MFG Oliver

von Semikolon (Gast)


Lesenswert?

Oliver W. schrieb:
> while(1);        //Messschleife
          |
          DA ist der Wurm!

von Mike (Gast)


Lesenswert?

Karl heinz Buchegger schrieb:
> Autor: Karl heinz Buchegger (kbuchegg) (Moderator)
>
> Datum: 19.08.2010 19:46
>
> Mike schrieb:
>
>
>> Was mache ich da Falsch und was muß ich ändern?
>
> So ziemlich alles.
>
> Selbst dann, wenn man das von Floh gesagte berücksichtigt ... ist das
>
> immer noch Unsinn.
>
>> aber es wird kein Text ausgegeben.
>
> Logo.
>
> Nur weil du eine Variable definierst, heißt das noch lange nicht, dass
>
> der Text dann irgendwie magisch auf der Web-Seite landet.
>
>> Bitte helft mir damit ich das Projekt Fertig stellen kann.
>
> Du musst erst mal C lernen, ehe du dich an so etwas wie einen
>
> vorhandenen Web-Server zu modifizieren wagst.

Danke erstmal für den guten Tip ;-)

Habe auch ein Buch (ISBN 978-3-7723-7350-3)vor mir, nur Hilft es mir 
nicht viel.

Bitte entschuldigt das ich mit so "einfachen" Fragen das Forum 
belästige.

von Karl H. (kbuchegg)


Lesenswert?

Mike schrieb:

> Bitte entschuldigt das ich mit so "einfachen" Fragen das Forum
> belästige.

Das hat mit einfach nichts zu tun.
In der Tat ist Strinverarbeitung in C gar nicht mal eine besonders 
einfache Sache, sondern eine der ersten größeren Hürden, mit der sich 
ein Einsteiger konfrontiert sieht.

Dein Problem: Du übernimmst dich mit deiner Aufgabenstellung als 
Anfänger.
Wenn ich in meinem ganzen Leben noch nie auf einen Berg gestiegen bin, 
dann nehm ich als ersten Berg nicht den Mont Blanc, sondern einen 
kleinen Hügel im Voralpenland.

Genauso bei dir: Du versuchst mindestens 2 bis 3 Monate Programmierung 
(auf einem PC wegen der besseren Entwicklungsumgebung) zu überspringen. 
Und daher kommst du nicht weiter. Ein Buch hilft dir nur dann, wenn du 
es von vorne beginnend durcharbeitest und auch die im Buch angegebenen 
Übungen machst, bzw. dir selber Übungen ausdenkst. Nach 2 oder 3 Wochen 
bist du dann im Buch bei Stringverarbeitung angelangt (moderate 
Lernzeiten eingeräumt). Nach ein paar weiteren Stunden hast du dann die 
Stringverarbeitung soweit verinnerlicht, dass dir die simpelsten 
Basis-Fehler in der Stringverarbeitung nicht mehr passieren.
Dann könnte man sich diesen Code weiter vornehmen.
Das Problem dabei: Du versuchst ein nicht gerade triviales Programm zu 
modifizieren. D.h. du musst vorher Programmanalyse betreiben um zu 
verstehen, wie und wo du eingreifen musst. Aber auch da fehlt dir die 
Erfahrung, die sich erst im Laufe der Zeit und mit fleissigem Üben 
einstellt. Unter anderem bekommst du sie, indem du bei deinen Übungen 
Fehler machst, deren Suchen und Beseitigen dir eine Menge Erfahrung 
vermittelt.

Und bei der Art und Weise, wie du die Modifikation versuchst, ist dieses 
Defizit ziemlich klar zu sehen. In ähnlicher Weise wie auch die 
Bergwacht auf der Zugspitze den Flachlandtiroler untrüglich an seinen 
Sandalen und nicht bergtauglicher Kleidung erkennt.

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.