Forum: Mikrocontroller und Digitale Elektronik Atmega8, ADC und der GP2D12


von Toby (Gast)


Lesenswert?

Hi Leute!
Ich hab gerade eine Test-Schaltung mit dem GP2D12 und dem Atmega 
aufgebaut..

Der Sensor wird mit 5V versorgt, die gelbe (Mess-)Leitung an PC0 vom 
Atmega.
Ich bekomme auch Werte, aber leider bewegen die sich alle zwischen 40 
und 60..

Habe die Schaltung einmal mit Widerstand (200 Ohm versucht, hab kein 
Gerät da, um den Widerstand vom Sensor zu messen) gegen GND 
angeschlossen, wie im Tutorial beschrieben, und einmal ohne, aber viel 
verändert hat sich nicht..

Hier mal mein Code-Schnipsel:

    int sample,i,value, count1, count2;
    ADMUX=0xC0;
    ADCSRA=0x80;
    count1 = 0;
    count2 = 0;
    while(1){
      sample=0;
      for(i=0;i<32;i++){
        ADCSRA |= (1 << 6);
        _delay_ms(60);
        sample+=ADCW;
      }
      value=sample/32;

      {
        char buffer[20];
        lcd_clear;
        set_cursor(0,2);
        itoa(value, buffer, 10);
        lcd_string( buffer );
      }

      wait_ms(10);
    }

Wäre echt dankbar, wenn mir jmd. Helfen kann, auch die Kenntnis des 
richtigen Widerstandes vom Sensor würde mich wohl schon weiterbringen..
Wahrscheinlich hab ich aber auch einfach nen Fehler in der Messung und 
komme nicht drauf. Hab bisher auch noch keine Erfahrung mit dem 
ADC-Wandler des Atmega..

P.S.: Ich weiss, Code normalerweise als Anhang, aber ist ja nur ein 
Schnipsel, bitte verzeiht mir!

von Johannes M. (johnny-m)


Lesenswert?

Toby wrote:
> Habe die Schaltung einmal mit Widerstand (200 Ohm versucht, hab kein
> Gerät da, um den Widerstand vom Sensor zu messen) gegen GND
> angeschlossen, wie im Tutorial beschrieben, und einmal ohne, aber viel
> verändert hat sich nicht..
Verstehe ich nicht, was Du da mit nem Widerstand machst. Der Sensor 
liefert doch schon ne Spannung, die muss nur an den entsprechenden 
ADC-Pin angeschlossen werden...

>         ADCSRA |= (1 << 6);
>         _delay_ms(60);
Das ist Murks. Ich weiß nicht, welches Tutorial Du gelesen hast, aber 
mit ner _delay_XX-Funktion auf das Ende der Wandlung zu warten ist 
kriminell. Entweder Du fragst das ADSC oder das ADIF ab. Im 
AVR-GCC-Tutorial steht wie's geht...

Und je nachdem, was für eine Taktfrequenz der µC hat, sind 60 ms auch 
schon zu viel für _delay_ms.

Die erste Wandlung nach Aktivieren des ADC kannste übrigens i.d.R. 
wegschmeißen. Die liefert meist keinen brauchbaren Wert.

> Wäre echt dankbar, wenn mir jmd. Helfen kann, auch die Kenntnis des
> richtigen Widerstandes vom Sensor würde mich wohl schon weiterbringen..
Wozu? Einfach Ausgang des Sensors an den µC.

Und bitte keine Codeschnipsel, sondern ein vollständiges, am besten 
compilierbares Programm posten!

von Toby (Gast)


Lesenswert?

mhm, im avr-tutorial steht doch, dass man sensor-ausgänge noch mit einem 
widerstand gegen GND beschalten soll, bevor man sie an den ADC 
anschliesst?

stimmt, das delay könnte evt. ein prob sein, aber im Datenblatt stand, 
dass der GP2D12 ca. 50ms für eine Messung braucht, da dachte ich, dass 
60ms ne gute Wahl wären..

bin erstmal arbeiten, ich kümmer mich heut nacht nochmal drum,
erstmal danke!!

von Thorsten Pusch (Gast)


Lesenswert?

Hallo,

du bekommst am GP2D12 aber an seinem Ausgang keinen Widerstandswert, 
sondern bereits eine Spannung, welche direkt auf den ADC des Controllers 
gegeben werden kann. Du musst nur sicher stellen, dass die Spannung 
nicht zu groß wird.
Ich verwende als Referenzspannung meist die Versorgungsspannung von 5V 
und betreibe den GP2D12 ebenfalls mit 5V. Der liefert dann Spannungen 
<5V.
Das klappt sehr schön.

Gruß,
Thorsten

von Johannes M. (johnny-m)


Lesenswert?

Toby wrote:
> mhm, im avr-tutorial steht doch, dass man sensor-ausgänge noch mit einem
> widerstand gegen GND beschalten soll, bevor man sie an den ADC
> anschliesst?
Sensor ist nicht gleich Sensor! Es gibt solche und solche. Du hast einen 
Abstandssensor mit integrierter Elektronik, und das ist was ganz anderes 
als ein nackter temperatur-, licht oder irgendwasanderesabhängiger 
Widerstand, den man in einem Spannungsteiler oder einer Brücke betreiben 
muss.

Dass der Sensor bei schnellen Änderungen der Messgröße 50 ms braucht, um 
das Ausgangssignal sauber zu liefern, ist eine Sache, die bei einer 
Mittelwertbildung eigentlich keine Rolle spielen sollte. Wenn Du 
unbedingt warten willst, dann tu das, nachdem Du festgestellt hast, 
dass der ADC fertig ist mit seiner Wandlung. Also erst Flag abfragen und 
dann warten. Und wenn die delay-Funktionen für Deine Zwecke nicht 
ausreichen, dann schreib Dir eine Wartefunktion, die zyklisch z.B. ein 
_delay_ms(1) aufruft, und das ganze 60 mal hintereinander. Oder besser 
gleich nen Timer nehmen. BTW: Was ist eigentlich wait_ms()?

von Toby (Gast)


Lesenswert?

wait_ms() war meine eigene Funktion, die eben die von dir vorgeschlagene 
_delay_ms mehrmals aufruft..

alles klar, werds direkt morgen nochmal versuchen, und gegebenenfalls 
nochmal hier posten :-)

wie genau kann ich warten, bis die Messung fertig ist?

von STK500-Besitzer (Gast)


Lesenswert?

>wie genau kann ich warten, bis die Messung fertig ist?

Warte ab, bis ADSC durch die Hardware zurückgestzt wurde.
Siehe auch Datenblatt Mega8 Complete Seite 195

von Toby (Gast)


Angehängte Dateien:

Lesenswert?

sooo..

Im Moment erhalte ich Werte, die zumindest einigermassen Sinn machen
(Program im Anhang).

also, ich habe den GP2D12 an der gleichen Spannungsversorgung wie den 
Atmega8, mit 100nF und 100uF zwischen + und -, kurz vor dem Sensor..

Die Werte sind jetzt soweit auch relativ stabil, aber sehr ungenau..
Ich benutze als REF die interne Referenz-Spannung von 2,56V..

Ich erhalte folgende Werte für value=sample/32:

39-40 - kein Hindernis
41-43 - Hindernis in ca. 70-80cm
...
...
47-50 - Hindernis in 10cm Entfernung..

Die Werte schwanken immer noch um ca. 1-2, aber mich stört, dass die 
Messung so ungenau ist. Der Wandler hat doch 10 bit, also eigentlich 
1024 Schritte, die sich dann zwischen 0(GND) und 2,56(REF) aufteilen 
müssten, oder?

Der Sensor bringt doch auch nur Ausgangs-Spannungen zwischen 2,5 und 0V, 
oder?

von Johannes M. (johnny-m)


Lesenswert?

Toby wrote:
> Der Sensor bringt doch auch nur Ausgangs-Spannungen zwischen 2,5 und 0V,
> oder?
Afair geht der Sensor nicht auf 0 V runter, sondern bleibt deutlich 
drüber. Aber eine so geringe Auflösung wie von Dir beschrieben sollte 
nicht rauskommen...

EDIT:
Du musst Deine Analog-Eingänge auch als Eingang konfigurieren (DDRx.n 
= 0). In Deinem Programm ist der komplette Port C als Ausgang 
eingestellt! Das kann nicht funktionieren!

von Johannes M. (johnny-m)


Lesenswert?

Noch was: Während einer Wandlung sollten am Port C keine Schaltvorgänge 
durchgeführt werden. Und denk dran: Am Analog-Eingang Pull-Up 
ausschalten!

von Toby (Gast)


Lesenswert?

ich bin ja so ein Trottel :-) sitze seit ner Woche dran und komm nicht 
drauf, was ich falsch gemacht hab...
Ja, jetzt, wo ichs als Eingang definiert hab funktioniert es natürlich 
genauso wie es soll :-)
Ich danke dir vielmals!!

von Johannes M. (johnny-m)


Lesenswert?

...und nächstes Mal schickste gleich am Anfang den kompletten Code und 
nicht nur ein nichtssagendes Schnipselchen...

von Toby (Gast)


Lesenswert?

Danke an alle, die geholfen haben :-)
Hier mal ein kleines Vid, hab den Sensor jetzt auf nen servo-gesteuerten 
Hals gebaut meines Robos gebaut, funktioniert schon relativ gut,
bis auf einige Spannungsspitzen solange die Motoren laufen..Die habe ich 
selbst mit den vorgeschlagenen Kondensatoren 100nF und 100uf zwischen + 
und - nicht rausbekommen, und die Werte sind schon gemittelt..Naja, wie 
man sieht funktioniert es dennoch ganz akzeptabel, selbst ohne 
Kalibrierung und "feinere" Programmierung:

http://www.infolexikon.de/blog/er-lebt/

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.