- Akku Tests und Balkonkraftwerk Speicher         
Ergebnis 1 bis 10 von 10

Thema: Hilfe! Ich will an den ADC Port ...

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    26.04.2009
    Ort
    Singen - Rostock
    Alter
    39
    Beiträge
    159

    Hilfe! Ich will an den ADC Port ...

    Anzeige

    Praxistest und DIY Projekte
    Servus,

    hab vor zwei Tagen mein Pollin Board zusammen gelötet und will mich jetzt mit voller Wucht ins AVR getümmel werfen
    Jetzt steh ich jedoch vor ein paar kleinen Problemen

    Hab momentan nen ATMega 32 drauf.

    Will mit meinem Labornetzteil mal auf die ADC Eingänge gehen und da gehts schon los ...

    - Der Pluspol kommt doch auf z.B. PC0 und der Minus vom Netzteil auf GND vom AVR?
    - Ich will intern den AVCC auf AREF schalten, hab bei meinem Board auf AVCC 5V anliegen, das bedeutet das ich theoretisch auch mit meinem Labornetzteil auf max. 5V gehen darf oder?
    - Muss zu Testzwecken der 10nF Kondensator zum glätten dazwischen geschaltet werden oder kann man den auch mal weg lassen?

    Hab vor ersteinmal dieses C-Programm aufzuspielen um das ganze zu testen:

    #include <avr/io.h>
    #include <inttypes.h>

    uint16_t readADC(uint8_t channel) {
    uint8_t i;
    uint16_t result = 0;

    // Den ADC aktivieren und Teilungsfaktor auf 64 stellen
    ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1);

    // Kanal des Multiplexers waehlen
    // Interne Referenzspannung verwenden (also 2,56 V)
    ADMUX = channel | (1<<REFS1) | (1<<REFS0);

    // Den ADC initialisieren und einen sog. Dummyreadout machen
    ADCSRA |= (1<<ADSC);
    while(ADCSRA & (1<<ADSC));

    // Jetzt 3x die analoge Spannung and Kanal channel auslesen
    // und dann Durchschnittswert ausrechnen.
    for(i=0; i<3; i++) {
    // Eine Wandlung
    ADCSRA |= (1<<ADSC);
    // Auf Ergebnis warten...
    while(ADCSRA & (1<<ADSC));

    result += ADCW;
    }

    // ADC wieder deaktivieren
    ADCSRA &= ~(1<<ADEN);

    result /= 3;

    return result;
    }

    int main(void) {
    uint16_t result = readADC(0); //Auslesen der analogen Spannungen an Pin 0,
    // also ADC0. In result steht das Ergebnis.
    return 0;
    }

    Kenn mich noch nicht so gut in C aus von daher noch meine letzte wirklich dumme Frage...

    - Ich wandel das C-Prog in AVRStudio in ne Hex. um und übertrage das ganze dann mit PonyProg, wie kann ich da ein Result sehen? Wenn dies nicht möglich ist, ab welchem Teil des Programms kann ich z.B. Leuchtdioden leuchten lassen wenn eine bestimmte Spannung erreicht ist? Normalerweise nach "int main (void)" so das ich z.b. eine LED anschalte wenn der wert 512 erricht ist alsp bei 2,5V.

    Ich danke euch allen schon mal im vorraus, ich weiß das sind echt blöde fragen aber ich hab die letzten Tage ein Lauflicht mit delay geschrieben und will jetzt auch mal was aufregenderes machen.

    Gruß Andi

  2. #2
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Mit einem externen Netzgerät an den AD-eingang gehen ist nicht unbedingt besonders sicher. Da geht schnell mal was kaputt. Besser wäre ein Poti (z.B. 10 K) zwischen Vcc und GND von der µC-Platine.

    Den Kondensator an AREF muß man nicht unbedingt haben, man kriegt damit aber weniger Rauschen hin.

    Damit die LED auf den ADC reagiert, und das nicht nur einmal, braucht man eine Endlosschleife. Dadrin denn den ADC auslesen, dann Vergleichen und entspechend was ausgeben.

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    26.04.2009
    Ort
    Singen - Rostock
    Alter
    39
    Beiträge
    159
    Will den ADC nutzen um damit zu einem späteren Zeitpunkt die Spannung meines Netzgerätes über den AVR auf ein Display auszugeben. Ist das machbar? Deshalb wollte ich auch mit dem Netzgerät auf PC0 und GND gehen.

  4. #4
    Erfahrener Benutzer Roboter Genie Avatar von BMS
    Registriert seit
    21.06.2006
    Ort
    TT,KA
    Alter
    33
    Beiträge
    1.192
    Hallo,

    so könnte das Programm aussehen, um den Wert des Analogeingangs mit einer Zahl zu vergleichen, und die LED zu schalten:
    Code:
    int main(void)
    {
     //Endlosschleife
     while(1)
     {
      uint16_t result = readADC(0); //Auslesen der analogen Spannungen an Pin 0,
      // also ADC0. In result steht das Ergebnis.
    
      if(result>512)
      {
       //LED an
       //musst du noch vervollständigen
      }
      else
      {
       //LED aus
       //musst du noch vervollständigen
      }
    
     } //Endlosschleife bis hier
    
     //an diese Stelle wird das Programm wegen der Endlosschleife nicht mehr gelangen,
     //außer du verlässt die while-Schleife mit einem break;
    
      return 0;
    }
    Du möchtest den Inhalt von "result" auf dem PC sehen? Funktioniert gut über das sog. UART und einem Terminal-Programm auf dem PC.
    Dazu brauchst du auf jeden Fall eine kleine Zusatzschaltung mit MAX232 und 4 Elkos und kannst dann über eine serielle Schnittstelle (RS232) mit dem PC kommunizieren. Es gibt auch USB-Seriell Adapter ( die heutigen PCs werden wohl kaum noch eine serielle Schnittstelle haben).
    Damit kannst du recht einfach von PC zu Mikrocontroller und umgekehrt Daten übertragen.
    Siehe auch:
    Daten und Texte zum PC übertragen

    Alternativ: ein Display anschließen (braucht aber einen größeren Brocken Software, gibts zum Glück im Internet)

    Könnte auch noch Programmschnipsel für UART-Übertragung und einen Link zu einem vernünftigen Terminal nachliefern - falls erwünscht

    Grüße,
    Bernhard

    EDIT: Du kannst die Spannung des Netzgeräts schon messen. Wenn es maximal 5 V liefern kann und damit deine Vref nicht überschreitet, könntest du es direkt an den Analogeingang anschließen.
    Ansonsten muss da noch ein Spannungsteiler dazwischen !!
    Welche Spannung liefert das Netzteil maximal ?
    Der Wert im Programm lässt sich dann auch relativ einfach wieder in den Spannungswert umrechnen.

    PS: PC0 ist kein analoger Eingang! Beim Atmega32 sind die alle am PORT A !!!

  5. #5
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    26.04.2009
    Ort
    Singen - Rostock
    Alter
    39
    Beiträge
    159
    Ja gerne mein Board hat einen Com Ausgang wäre echt super nett von dir.

  6. #6
    Erfahrener Benutzer Roboter Genie Avatar von BMS
    Registriert seit
    21.06.2006
    Ort
    TT,KA
    Alter
    33
    Beiträge
    1.192
    gut
    Als Terminal verwende ich das von Burkhard Kainka:
    Hier ist es
    Damit funktionieren auch die USB-auf-seriell-Adapter problemlos (habs selber ausprobiert).

    Erst mal musst du den ganzen UART-Kram aktivieren und konfigurieren:
    Code:
    //Die Zahlenwerte hier sind für eine Baudrate von 9600 bei Verwendung eines 16Mhz-Quarzes gewählt
    UBRRH=0;				//Baudrate
    UBRRL=103;				//Baudrate
    UCSRB=0b00011000;		//internen UART einschalten
    UCSRC=0b10000110;		//Datenformat: 8 Datenbits, no Parity, 1 Stopbit
    Die Werte für UBRRH und UBRRL geben die Übertragungsgeschwindigkeit an. Die Zahlenwerte dafür musst du im Datenblatt vom Atmega32 ab Seite 163 in der Tabelle - abhängig von Taktfrequenz und Baudrate ablesen.

    Funktion, um ein Byte zu senden:
    Code:
    void serial_sendbyte(unsigned char i)
    {
     while( !(UCSRA & 32) );
     //senden
     UDR=i;
    }
    Funktion, um zu prüfen, ob der PC Daten gesendet hat (wenn ja, dann liefert diese Funktion "true"):
    Code:
    bool serial_available()
    {
     if(UCSRA & 128){return true;}
     return false;
    }
    Funktion, um das empfangene Byte zu lesen
    Code:
    unsigned char serial_receive()
    {
     //bis Daten empfangen
     while( !(UCSRA & 128) );
     //einlesen
     return UDR;
    }
    Die Funktionen senden nur Bytes. Das Terminal zeigt sie sowohl als Dezimalzahlen als auch als Text an (ASCII Tabelle sagt dir vielleicht was)

    Grüße,
    Bernhard

  7. #7
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    26.04.2009
    Ort
    Singen - Rostock
    Alter
    39
    Beiträge
    159
    Vielen Dank,

    das ist echt super von dir, hast mir wirklich enorm geholfen. Werde es gleich morgen mal ausprobieren.

    Gruß Andi

  8. #8
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    26.04.2009
    Ort
    Singen - Rostock
    Alter
    39
    Beiträge
    159
    So habs jetzt mal versucht, klappt leider noch nicht, hab ich da irgendwo noch nen fehler drin?
    Hab ein 10k Poti zwischen VCC und GND geklemmt und den Abgang auf Port C.0 gesetzt. Hab zwischen VCC und GND 5V und kann das Poti auch bis 5V hochdrehen. Hab in nem Tutorial was von 2,56V gelesen am ADC Eingang...


    #include <avr/io.h>
    #include <inttypes.h>

    uint16_t readADC(uint8_t channel) {
    uint8_t i;
    uint16_t result = 0;

    // Den ADC aktivieren und Teilungsfaktor auf 64 stellen
    ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1);

    // Kanal des Multiplexers waehlen
    // Interne Referenzspannung verwenden (also 2,56 V)
    ADMUX = channel | (1<<REFS1) | (1<<REFS0);

    // Den ADC initialisieren und einen sog. Dummyreadout machen
    ADCSRA |= (1<<ADSC);
    while(ADCSRA & (1<<ADSC));

    // Jetzt 3x die analoge Spannung and Kanal channel auslesen
    // und dann Durchschnittswert ausrechnen.
    for(i=0; i<3; i++) {
    // Eine Wandlung
    ADCSRA |= (1<<ADSC);
    // Auf Ergebnis warten...
    while(ADCSRA & (1<<ADSC));

    result += ADCW;
    }

    // ADC wieder deaktivieren
    ADCSRA &= ~(1<<ADEN);

    result /= 3;

    return result;
    }

    int main(void)
    {
    //Endlosschleife
    while(1)
    {
    uint16_t result = readADC(0); //Auslesen der analogen Spannungen an Pin 0,
    // also ADC0. In result steht das Ergebnis.

    if(result>12
    {
    //LED an
    PORTA = 0x01;
    //Setze PinA.0 auf 1
    }
    else
    {
    //LED aus
    PORTA = 0x00;
    //Setze PinA.0 auf 0
    }

    } //Endlosschleife bis hier

    //an diese Stelle wird das Programm wegen der Endlosschleife nicht mehr gelangen,
    //außer du verlässt die while-Schleife mit einem break;

    return 0;
    }

  9. #9
    Erfahrener Benutzer Roboter Genie Avatar von BMS
    Registriert seit
    21.06.2006
    Ort
    TT,KA
    Alter
    33
    Beiträge
    1.192
    Du musst den Anschluss A0 erst mal auf Ausgang schalten, sonst geht das nicht.
    Code:
    ...
    int main(void)
    {
    
     DDRA=0x01;   //Diese Zeile muss noch rein
    
     //Endlosschleife
     while(1)
      {
    ...

  10. #10
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    26.04.2009
    Ort
    Singen - Rostock
    Alter
    39
    Beiträge
    159
    Vielen Dank, hatte ich vergessen. Werds nachher gleich mal probieren

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad