Forum: Compiler & IDEs ADC Ausgabe oder Auslese Problem


von Patrice A. (patrice_a)


Angehängte Dateien:

Lesenswert?

Hallo

als erstes will ich sagen das ich ein Neuling auf diesem Gebiet bin und 
das das ADC Auslesen/Ausgeben mein erstes "größeres" Projekt ist.

Ich verwende ein Net-IO Board mit einem Atmega32 (16Mhz).

Ich habe es am Anfang nmit Beispielen von dieser Seite hier probiert und 
es hat alles einwandfrei geklappt. Dann habe ich es ein wenig erweitert 
und "verbessert" durch Interrupts, Timer und auslesen aller Kanäle. Und 
da ist dann auch schon das Problem. Die Uart-Ausgabe funktioniert da ich 
diese vorher ohne die Interrupts schon getestet habe. Die Ausgabe von 
Hallo vor der Hauptschleife zeigt mir auch das die Ausgabe soweit 
funktioniert, aber nach dem Hallo kommt nichts mehr. Also nun weiß ich 
nicht obs am Timer liegt oder and den Interrupts oder ob ein Zähler 
nicht funktioniert.

Kann jmd vielleicht das Problem sehn?

Gruß

von Patrice A. (patrice_a)


Lesenswert?

also ich hab noch ein paar kleine änderungen reingemacht
zb ADMUX=.. über die main schleife und in den ADC interrupt unter k--

dann den ADC interrupt enable in die ADC init als ADCSRA |= (1<<ADIE)

von Patrice A. (patrice_a)


Lesenswert?

Timerinterrupt geändert in
TIMSK |= (1<<TOIE0);

interrupts sind angesprungen .. ausgabe war aber kurz und wirrwar

von Stefan E. (sternst)


Lesenswert?

adcendval wird nicht zurückgesetzt.

von Patrice A. (patrice_a)


Lesenswert?

ich werde noch einige optimierungen durchführen und mich nochma melden 
wenns dann immernoch nicht funktioniert ;)

hab selber grad noch einige fehler gefunden

von Karl H. (kbuchegg)


Lesenswert?

> Also nun weiß ich nicht obs am Timer liegt oder and den
> Interrupts oder ob ein Zähler nicht funktioniert.

Klarer Fall von: zu viele Änderungen auf einmal gemacht ohne 
zwischendurch ausgiebig zu testen.

von Patrice A. (patrice_a)


Angehängte Dateien:

Lesenswert?

Karl ich denke da hast du recht

ich hat versucht soviele zusätze wiemöglich mit einzubauen

ich habe die ganze sache nocheinmal überdacht, überarbeitet und verkürzt

Interrupts funktionieren
Ausgabe funktioniert(es wird das richtige ausgegeben)
Timer is denke ich jetzt das Problem
ich habe versucht den Timer so zu takten das ich jede sec eine 
conversion des ADC habe und diese ausgegeben wird
aber egal was ich einstelle, er schießt mir die werte in super 
geschwindigkeit entgegen
habe ich vielleicht etwas flasch gerechnet oder einen falschen PIN 
gesetzt?

am anfang wollte ich es mit millisekunden machen also im Timerinterrupt 
nach oben zählen und bei 1000 ADC_ON machen (OCR0 = 250-1)
da aber die geschwindigkeit sich nciht geändert hat habe ich es direkt 
mit sekunden veruscht aber leider auch das keine veränderung

von Stefan E. (sternst)


Lesenswert?

1
   OCR0 = 250000-1;
Und wie soll der Wert in 8 Bit passen?

1
    char mystring[4];
2
...
3
    mystring[4] = '\0';
Du schreibst hier hinter das Array.

von Patrice A. (patrice_a)


Angehängte Dateien:

Lesenswert?

hatte das mit der 250000 schon geändert und wieder die milli gemacht .. 
hmm ok dann mach ich das Array 5 lang

von Karl H. (kbuchegg)


Lesenswert?

Für meinen Geschmack immer noch zu kompliziert

> Ich habe es am Anfang nmit Beispielen von dieser Seite hier probiert
> und es hat alles einwandfrei geklappt.

Dann fang nochmal auf dieser Ebene an.
Bring diese Beispiele noch einmal zum Laufen (vergewissere dich auch 
dass sie das sicher tun) und dann fängst du an sie zu modifizieren. Aber 
immer nur eine kleine Änderung nach der anderen. Nach jeder Änderung 
vergewisserst du dich, dass das was du geändert hast auch wirklich noch 
funktioniert!



> ADMUX = 0;

Wie ist der AREF Pin auf dem Net-IO beschaltet?
Du wählst hier "externe Referenzspannung" aus.
Ist das wirklich das, was du willst?

von Patrice A. (patrice_a)


Angehängte Dateien:

Lesenswert?

AREF Jumper ist auf intern .. ich nehm also die 5V als Referenz da das 
Ziel ist 3,3V zu messen



also ok der reihe nach:

uart initialisieren

ausgabe initialisieren

Test der Ausagbe mit printf ... funktioniert

ADC initialisieren .. ADMUX auf AREF 5V
                   .. Frequenzvorteiler auf 128
                   .. Start ADC
                   .. ADC Interrupt erlauben
                   .. eine Single Conversion
                   .. Freerunning Mode
                   .. An ADC2 auslesen (Hardware Check .. ja liegt an)

Timer initialisieren .. Prescaler /64 .. Timer0 Start
                     .. CTC starten
                     .. OCR0 Register initialisieren (nachrechnen .. 
16MHz .. 16000000/64 = 250000 .. 1s=250000 Takte .. 1ms=250 Takte .. 
Interrupt nach 250 Takten .. stimmt)
                     .. Interrupt starten
                     .. Timer in anderen Programm getestet .. alles 
funktioniert

Globale Interrupts erlauben

Interrupt Routinen prüfen .. ISR(TIMER0_COMP_vect) .. stimmt
                          .. milli hochzählen bis 1000 .. 
milli=uint=65.535 .. stimmt
                          .. if abfrage .. milli zuruecksetzen .. if 
abfrage zur sicherheit .. Aufruf Makro (dasgleiche wie bei ADC_Init)
                          .. wenn ADC aus dann Ausgabe starten
                          .. ADCW-Wert wird übergeben als uint16_t 
adcval
                          .. umrechnen .. in String schreiben
                          .. String ausgeben

                          .. Freerunning bis ADC Interrupt ausgelöst 
wird

                          .. ISR(ADC_vect) .. sollte stimmen .. Makro 
aufruf (ADC stoppt) .. hm sollte auch stimmen

MAIN loop  .. nichts

so hat ich dann hier und da was verändert und es funktioniert ;)

hm ich weiß das die Ausgabe nicht ganz optimal da vielleicht ein wenig 
viel für einen interrupt .. aber davon mal abgesehen finde ich keinen 
Fehler

ich meine es ist ja nicht wirklich kompliziert
aber nun möchte ich die 4 ADC Pins am Net-IO Board auslesen (4-7 am 
Atmega 32) .. darum auch das k bei der Kanalausgabe
und ich möchte 5 mal den Wert eines Kanals lesen(Mittelwert) und dann 
erst ausgeben(wegen genauigkeit) .. hier steh ich total aufm Schlauch .. 
keine Ahnung wo ich das Einbauen soll

bei dem Kanal wollte ich es so machen das ich nach der Ausgabe das k 
hochzähle .. desweiteren muss k1-k4 mit einem Befehl zum ADMUX verbunden 
werden .. zb if k=1 dann a=5 und dann das a in den ADMUX schmeißen .. 
aber wo und wie ich das genau mache weiß ich nicht ..

hat jmd eine Idee oder einen genialen besseren Vorschlag? ;)

Gruss

von Patrice A. (patrice_a)


Lesenswert?

1
  if(ADCSRA==0)
2
      {
3
        adc_ausgabe(ADCW);
4
        k++;
5
        if(k==8)
6
        {
7
          k=4;
8
        }
9
        ADMUX = (ADMUX & ~(0x1f))|(k & 0x1F);
10
        ADC_ON;
11
      }

ich hab das mit dem Kanal jetzt so probiert .. aber das is immermehr in 
dem Interrupt .. soll ich da eine flag setzen und das ganze im main loop 
machen lassen oder is das noch ok für die performance? .. bei der Kanal 
ausgabe habe ich einfach den Wert Minus 3 damit der richtige Kanal 
dasteht

von Patrice A. (patrice_a)


Lesenswert?

Problem hier soweit gelöst .. ganz alleine ;)

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.