- LiFePO4 Speicher Test         
Ergebnis 1 bis 10 von 15

Thema: Atmega8 ADC \ eeprom

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    12.08.2014
    Beiträge
    11
    Ziel wäre es einen Drucksensor anzuschließen und dessen wert einzulesen (ergibt 4-20mA aus)
    Ich habe mich jetzt nur mal auf das einlesen des ADC konzentriert, bei mir wären 5V = 1023

    Mein aktuelles Problem ist das der ADC wert > 205 und < 409 ist und das Immer sogar wenn nichts angeschlossen ist ?
    Ich konnte den Fehler noch nicht finden, daher ich noch kein Poti habe verwende ich verschiedene widerstände.

    Code:
    #include <avr/io.h>
    #include <util/delay.h>
    #include <avr/eeprom.h>
    
    uint16_t lastValue = 0;
    uint16_t ADC_Read(uint8_t channel);
    
    int main()
    {
      // Set PORTD as Output
      DDRD = (1<<PD7)| (1<<PD6)|(1<<PD5) | (1<<PD4) | (1<<PD3) | (1<<PD2)| (1<<PD1)| (1<<PD0);
      PORTD |= ((1 << PD7) | (1 << PD6) |(1<<PD5) | (1<<PD4) | (1<<PD3) | (1<<PD2)| (1<<PD1)| (1<<PD0));
    
      ADC_init();
    
      while (1)
      {
        //0V = 0
        //1V = 205
        //2V = 409
        //3V = 614
        //4V = 816
        //5V = 1023
        //Vgemessen=lastValue*5/1024;
    
        lastValue = ADC_Read(0);
        if (lastValue = 0) {
           PORTD = 0b11111111;
        }
        else if (lastValue > 205) {
           PORTD = 0b11111110;
        }
        else if (lastValue < 409) {
          PORTD = 0b11111100;
        }
        else if (lastValue > 614) {
           PORTD = 0b11111000;
        }
        else if (lastValue > 816) {
          PORTD = 0b11110000;
        }
        else if (lastValue > 1023) {
          PORTD = 0b11100000;
        }
        }
    }
    
    /* ADC initialisieren */
    void ADC_init(void) {
        // die Versorgungsspannung AVcc als Refernz wählen:
        ADMUX = (1<<REFS0);
        // oder interne Referenzspannung als Referenz für den ADC wählen:
        //ADMUX = (1<<REFS1) | (1<<REFS0);
        // Bit ADFR ("free running") in ADCSRA steht beim Einschalten
        // schon auf 0, also single conversion
        ADCSRA = (1<<ADPS1) | (1<<ADPS0);     // Frequenzvorteiler
        ADCSRA |= (1<<ADEN);                  // ADC aktivieren
    
        /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest
         also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */
    
    
        ADCSRA |= (1<<ADSC);                  // eine ADC-Wandlung
        while (ADCSRA & (1<<ADSC) ) {         // auf Abschluss der Konvertierung warten
        }
    
        /* ADCW muss einmal gelesen werden, sonst wird Ergebnis der nächsten
         Wandlung nicht übernommen. */
        (void) ADCW;
    }
    
    /* ADC Einzelmessung */
    uint16_t ADC_Read(uint8_t channel)
    {
        // Kanal waehlen, ohne andere Bits zu beeinflußen
        ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F);
        ADCSRA |= (1<<ADSC);            // eine Wandlung "single conversion"
        while (ADCSRA & (1<<ADSC) ) {   // auf Abschluss der Konvertierung warten
        }
        return ADCW;                    // ADC auslesen und zurückgeben
    }
    Klicke auf die Grafik für eine größere Ansicht

Name:	Drawing1.jpg
Hits:	10
Größe:	51,9 KB
ID:	28892

  2. #2
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.220
    Nur ein Hinweis.
    Du kannst Probleme bekommen wenn du AREF mit AVCC verbindest. An AREF gehört ein 100n Kondensator nach GND.
    Wenn du, wie in deinem Fall einmal die interne Referenz verwenden willst, fließt ein Ausgleichsstrom in AREF.
    Grüsse Hubert
    ____________

    Meine Projekte findet ihr auf schorsch.at

  3. #3
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.694
    ... aktuelles Problem ... ADC wert > 205 und < 409 ... Immer sogar wenn nichts angeschlossen ist ...

    Code:
    ...
    /* ADC Einzelmessung */
    uint16_t ADC_Read(uint8_t channel)
    {
        // Kanal waehlen, ohne andere Bits zu beeinflußen
        ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F);
        ADCSRA |= (1<<ADSC);            // eine Wandlung "single conversion"
        while (ADCSRA & (1<<ADSC) ) {   // auf Abschluss der Konvertierung warten
        }
        return ADCW;                    // ADC auslesen und zurückgeben
    }
    Wenn das Ergebnis gleich ist - egal ob am ADC eine Spannung anliegt oder der Pinn in der Luft hängt - dann klingt das doch danach, dass der ADC "nichts" misst. Jedenfalls nichts Sinnvolles. Oder?

    Rechne mal bitte: Dein Vorteiler ist clock/8. WENN Du den Controller mit 8 MHz fährst (ist ja nicht unüblich, Du gibst hier leider nix an) dann bekommst Du eine ADC-Frequenz von 1 MHz. Dieser Takt ist die Stoppuhr für die Abläufe des ADC - der zählt die Takte und bemisst damit seine Samplezeit, seine Wandlungszeit und so.
    Zitat Zitat von Atmel-Datasheet 8271E–AVR–07/2012
    ... By default, the successive approximation circuitry requires an input clock frequency between 50kHz and 200kHz to get maximum resolution. If a lower resolution than 10 bits is needed, the input clock frequency to the ADC can be higher than 200kHz to get a higher sample rate...
    Nun siehts also so aus, als sei Dein ADC-Takt zu hoch >>WENN<< meine Annahme mit den 8 MHz stimmt. Musst halt rechnen.

    Verdächtig erscheint mir auch Dein Kanalwechsel bei Deiner ADC_Read-Funktion mit der unmittelbar folgenden Leseaktion. Lies Dir dazu mal das Datenblatt durch, Abschnitt Changing Channel oder so, dort ist ausgeführt wie glaubhaft der erste Wert nach dem Kanalwechsel ist. Und ein Kanalwechsel erfolgt (meines Wissens nach) auch dann, wenn durch den Befehl derselbe Kanal wie vorher ausgewählt wird . . .

    Und Huberts Hinweis ist ja auch im Datenblatt (... Analog Input Circuitry ...) näher erläutert *gg*
    Ciao sagt der JoeamBerg

  4. #4
    Neuer Benutzer Öfters hier
    Registriert seit
    12.08.2014
    Beiträge
    11
    ja der Controller läuft mit 8Mhz...

    Wenn ich das richtig verstehe das ist mein Teilungsfaktor falsch...
    Nach dieser Rechnung müsste ich den Faktor 64 Nehmen und nich 8 ist das so korrekt von mir ?

    TFmin=CLK/200kHz=8000000/200000=40
    TFmax=CLK/50kHz=8000000/50000=160
    ADCSRA = (1<<ADPS1) | (0<<ADPS0); // Teilungsfaktor (64)

  5. #5
    Erfahrener Benutzer Roboter Genie Avatar von HeXPloreR
    Registriert seit
    08.07.2008
    Ort
    Soltau - Niedersachsen
    Alter
    46
    Beiträge
    1.369
    Hallo,

    zusätzlich, und nicht ganz unwichtig, finde ich es auch zu sagen das ein Analogsensor meist einen Spannungswert (V) aus gibt. Mir ist bisher kein Drucksesnor begegnet/bekannt der das nicht tut - mal abgesehen von I²C und PWM und so weiter, wo also der Sensor die Spannungswerte selbst vorverarbeitete und als "Datenpaket" verschickt. Bist Du denn sicher das dein Sensor mA(mpere) ausgibt? Welcher Sensor ist das genau? Oder sind es doch eher mV?

    Um das Problem mit der ADC-Grundbeschaltung zu lösen würde ich mir persönlich den Schaltplan der RN-Control diesbezüglich rein tun. Diese ist aber dann definitiv nur für Spanungen (V) am ADC gedacht. Ob man dazu einen Shunt aufbauen muss damit man Ampere erhält .... hab ich mich noch nicht ausreichen damit beschäftigt deswegen bleibt diese Antwort von mir offen.

    Blöd wäre es ja nur wenn der Sensor sowieso schon "wirklich" einen mA-Wert als verkappten "Spannungswert" liefert ... frage mich grade ob man an so einem Wert überhaupt dann noch was umrechnen muss, wenn es schon der gesuchte Wert ist?

    Das Problem bei Deiner ersten Rechnung oben wird sein, das Du nur *5,0 rechnest. Dadurch ist eine 10 Bit-Wert schon mit dem kleinsten Messwert von 1 Bit auf 5. Und das sagt ja quasi garnichts aus ebensowenig wie 5115 bei max wert - es sei denn man rechnet sich das auch wieder umständlich um... dieser wert müsste also noch durch 1023 (10Bit) geteilt werden U = ADC-bit * Ref (5V) /1023-bit. Daraus kann man eine Konstante erstellen = Ref(5V)/1023 mit der dann der ADC-Wert nur noch multupliziert werden muss um die korrekte Spannung angegeben zu bekommen.

    Hüstel: und der Sensor sollte natürlich im angegeben Spannungsbereich (etwa 3,3 - 5V) funktionieren.

    Hüstel nochmal: Du solltest mal schauen ob in Deinem zweiten Programm Dein "Vgemessen" ggf nicht in einem Kommentar stehen sollte. Und ob es gut ist "LastValue" zu prüfen obwohl Du "Vgemessen" vergleichen möchtest, oder?
    Wenn Du vermutlich eine Art Bargraph Anzeige realisieren möchtest dann sollte auch nicht nur der Wert für den 409er Vergleich auf kleiner (<) geprüft werden sondern Alle. Ggf machte es auch Sinn bei dieser Art des Vergleichs die Reihenfolge umzudrehen, also erst auf den größten ADC-Wert zuerst zu prüfen. Denn dann sind es weniger Vergleiche wenn man davon ausgeht das eher eine hohe Spannung anliegt als eine niedrige. 1023 als Vergleichswert könnte man vernachlässigen...


    Viele Grüße
    Jörg
    Geändert von HeXPloreR (13.08.2014 um 19:20 Uhr)

  6. #6
    Neuer Benutzer Öfters hier
    Registriert seit
    12.08.2014
    Beiträge
    11
    Ok, ich weiß nicht wie ich auf mA komme aber gemeint wäre so einer:
    http://www.conrad.at/ce/de/product/1...omSuggest=true

    Gibt es eigentlich eine möglich keit die Ports vom µC zu Testen bzw. den Controller selbst ich hab die vermutung das ich das ding zerstört habe, per PC kann ich noch Programmer draufbrennen.
    Geändert von live5 (14.08.2014 um 10:39 Uhr)

  7. #7
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    01.03.2008
    Ort
    Niederlanden
    Beiträge
    1.170
    Zitat Zitat von live5 Beitrag anzeigen
    Ok, ich weiß nicht wie ich auf mA komme aber gemeint wäre so einer:
    http://www.conrad.at/ce/de/product/1...omSuggest=true
    Dan brachst du sicher eine weitere Widerstand und den beiden als ein Spannungsteiler zu schalten.

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    12.08.2014
    Beiträge
    11
    ja das hab ich auch schon gelesen zum Testen hab ich das ganze so aufgebaut, jetzt müsste ich eigenltich am PC0 ca 3.2V haben aber was mir eigentartig erscheint ist das meine LED leuchtet wenn ich das so verbinde^^
    Als würde mein eingang durchschalten deshalb die Frage ob ich eventuell einen Funktionstest machen kann mit dem controller.

    5V
    |
    |
    |
    |
    ----
    | |
    | |
    | | R = 56 Ohm
    | |
    ----
    |
    |
    |
    -----------|LED|---- PC0

  9. #9
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    01.03.2008
    Ort
    Niederlanden
    Beiträge
    1.170
    Die pin hoch schalten. Oder als Eingang schalten. Und auch auf die polaritat der led achten. Wie man die pins in zbs C Schalten muss steht in dem Atmel datasheet der mikrocontroller

Ähnliche Themen

  1. ATMega32, Werte vom ADC ins EEPROM
    Von Spessi im Forum C - Programmierung (GCC u.a.)
    Antworten: 9
    Letzter Beitrag: 12.11.2008, 23:12
  2. ATMega8 + EEPROM
    Von Bumbum im Forum C - Programmierung (GCC u.a.)
    Antworten: 6
    Letzter Beitrag: 14.06.2008, 22:00
  3. I2C-EEprom an ATMega8
    Von .Johannes. im Forum AVR Hardwarethemen
    Antworten: 1
    Letzter Beitrag: 08.06.2006, 13:42
  4. ATmega8 aus dem EEPROM lesen und ins EEPROM Schreiben
    Von melowtrax im Forum AVR Hardwarethemen
    Antworten: 6
    Letzter Beitrag: 20.02.2006, 22:32
  5. Messwerte aus ADC in internem EEPROM vom ATMega8 abspeichern
    Von RalfP im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 5
    Letzter Beitrag: 28.10.2005, 16:43

Stichworte

Berechtigungen

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

Solar Speicher und Akkus Tests