Forum: Mikrocontroller und Digitale Elektronik Nochmal Analog Comparator


von Martin Zunke (Gast)


Lesenswert?

Hi!

Ich versuche das Signal eines Ultraschallsensors mittels
Analogcomparator zu erfassen. Ich beschalte den negativen Eingang
wahlweise mit Masse oder einer Referenzspannung von 100 mV.

Eine Routine toggelt mir einen Ausgang, den ich mit einem Oszi
beobachte. Der Sensor liefert beim Empfangen eines 40 kHz Signals ab
100 mV bis hoch zu 3 Volt (dann liegt der Sender ca. 2mm vom Empfänger
entfernt, es kommt auch zu Überlagerungen).

ERST BEI 3V Amplitude des Sensorsignals (gaaaanz sauberer Sinus) kommt
ein Interrupt. Was ist das? Mache ich rein elektrisch was verkehrt,
oder ist das bei dem Comparator so? Diese Schaltschwelle erinnert aber
eher an eine ganz normalen Digitalport als an einen Analog-Eingang.

Verwirrend ist auch die Doku. Um einen Port als Eingang mit
abgeschalteten Pullups (Tri-State) zu schalten, soll ich irgendwelche
Zwischenschritte gehen. Aber ich seh nicht durch.

Hat hier einer sowas mal gemacht?
mz

von Manfred Glahe (Gast)


Lesenswert?

Hallo,
"Hat hier einer sowas mal gemacht?"
Ja, aber Du müßtest erstmal Deinen µP nennen wenn  Du Hilfe erwartest.

MfG  Manfred Glahe

von Jens Renner (Gast)


Lesenswert?

Wohl die Fortsetzung des alten Threads:
http://www.mikrocontroller.net/forum/read-1-42500.html

von Martin Zunke (Gast)


Lesenswert?

Sorry....

ATmega8535. Wenn ich ihn mit dem AIN0 an einen zweiten ATmega... hänge,
an dem ich den Pin toggle, dann hatters. Relativ gut.

Kapazitäten? Wie gesagt, die Pins sind direkt beschaltet: einer an
Masse respektive 100mV, der andere am Sensor oder am anderen
Controller.

Übrigens: das Ganze soll Kommunikation via Ultraschall werden.


Und hier der Quelltext:

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>

int i =0;

/* INTERRUPTHANDLER Analog Comparator */
SIGNAL(SIG_COMPARATOR)
{
  /* Hier toggle ich 2 Pins, einer mit LED, einer fürn Oszi*/
  sbi(PORTA,PA2);
  sbi(PORTA,PA3);
  for(i=0; i==250; i++);
  cbi(PORTA,PA2);
  cbi(PORTA,PA3);
}

void main(void)
{
  outp(0x00,DDRB); /* Port B als Eingang */
  outp(0x00,PORTB);/* switch internal pull-up's off*/

  /*outp((0<<ACME),SFIOR);*/

  outp(0xFF,DDRA); /*Port A als Ausgang*/

  /* Comparator laden und starten */

  /* IRQ disablen */
  outp((0<<ACIE),ACSR);
  /* AC ausschalten */
  outp((1<<ACD),ACSR);
  /* modus setzen (rising edge)*/
  outp((1<<ACIS0),ACSR);
  outp((1<<ACIS1),ACSR);

  /* ACI clearen */
  outp((0<<ACI),ACSR);

  /* AC anschalten */
  outp((0<<ACD),ACSR);

  /* globaler Interrupt enable */
  sei();

  /* IRQ enablen */
  outp((1<<ACIE),ACSR);

  /* neverending loop */
  for(;;);

}

von Manfred Glahe (Gast)


Lesenswert?

Hallo,
ich habe dass mit einem PIC16F84 gelöst. Das Problem dabei ist die
relativ große Schwankung der Eingangsamplitude  und die Nebengeräusche.
Deshalb habe ich das mit einem externen Komparator gelöst und nicht mit
einem anderen PIC welcher einen internen hätte. Komparator. Nach dem
Mikrofonverstärker ist ein Bandpass geschaltet welcher die
Nebengeräusche schon sehr gut dämpft. Aber eine extrem hohe Amplitude
eines Nebengeräusches in der Nähe unterdrückt auch das Filter nicht
mehr ausreichend und der Komparator schaltet. Um dies auszuschließen
habe ich die Ausgangsspannung des Mikrofonverstärkers über eine Diode
auf einen Kondensator geführt. Diese Spannung wird nun über einen
Widerstand der Schwellspannung des Komparators hinzugefügt.
Durch diese Erhöhung der Schaltschwelle können "extreme" Amplituden
nicht mehr zu Fehlschaltungen führen. Wenn Dein µP einen Eingang zur
Beeinflussung der Schwellspannung besitzt ließe sich das auch
durchführen.

MfG  Manfred Glahe

von Martin Zunke (Gast)


Lesenswert?

Um es nochmal deutlich zu machen: mein Problem ist nicht, das er
schaltet, mein Problem ist, das er NICHT schaltet.

Ein AVR läßt mit 40 kHz einen Ausgang toggeln. An dem hängt ein
Ultraschallsensor. Die Empfangsseite besitzt ebenfalls einen
Ultraschallsensor. Auf der Empfangsseite ist der US mit einem Pol an
Masse, mit dem anderen am Comparator. Nimmt man das Signal am Eingang
des Comparators ab und gibt es auf das Oszi, bekommt man einen ziemlich
sauberen Sinus mit einer Amplitude zwischen 100mv und 3 V, je nach
Abstand. In einem Abstand von 5 cm habe ich eine Amplitude von fast 1
Volt, deutlich mehr als die Referenzspannung von 100 mV. Der AC müßte
also bei Modus "rising edge" im 40 kHz- Takt Interrupts werfen.

Das tut er aber nur, wenn ich statt der Sensoren ein Stück Draht
zwischen die beiden AVR's lege, d.h., das Signal ein Rechteck mit 5
Volt Amplitude ist....

Leider gibt die Doku nichts her in Sachen minimaler Pegel für den AC.
Aber 1 Volt reicht nicht ?! Wenn das so wäre, dann bräuchte Atmel den
AC gar nicht einzubauen....

...ich hoffe, jetzt ist mein Problem etwas klarer. Zur Überprüfung habe
ich jetzt ein Progrämmchen, bei dem in der AC ISR ein Zaehler
inkrementiert wird und nach Ablauf einer Torzeit (zweiter Timer) dieser
Wert ausgelesen und auf einer LED Leiste ausgegeben wird. Wenn also
irgendwas empfangen wird, dann sehe ich das.

@manfred
Durch das Bandpaßähnliche Verhalten der Sensoren und die
Referenzspannung von 100 mV habe ich das eigentlich so gemacht, wie Du
es beschreibst.

@jürgen
Das, was Du in dem anderen Thread bemerkt hast, habe ich korrigiert. Es
galt ja auch für den Quelltext, den ich hier gepostet habe.

in der hoffnung auf geistesblitze
mz

von Manfred Glahe (Gast)


Lesenswert?

@Martin,
ist die Wahl der 100mV willkürlich (ich kenne den AVR nicht) oder hast
Du das aus dem Datemnblatt? Mach doch mal folgenden Test: über einen
Widerstand ca. +3V an den Komparatoreingang legen und den
Referenzeingang zwischen 0V und +5V variieren. Wann kommt dann der
erste INT wenn Du  langsam von 0V nach +5V fährst?

MfG  Manfred Glahe

von Martin Zunke (Gast)


Lesenswert?

Die 100 mV sind nicht willkürlich, sondern zweckgebunden. Ich will ein
Signal ab 100 mV Pegel erfassen. Diesen Wert (Referenzspannung) will
ich später noch über programmierbare Widerstände variieren können (im
lfd. Programm), in diesem Kontext sozusagen "die Ohren dichtmachen",
denn wenn ich den Pegel erhöhe, muß ein Sender entsprechend näher
dransein, damit die Amplitude höher ist und der AC auslöst.

Ich stelle die Frage mal so: gibt es überhaupt ein  Datenblatt der
elektrischen Eigenschaften des AC im AVR? In der Doku steht nichts,
aber da es sich um einen analogen Eingang handelt, kann man sicher die
Daten des A/D Wandlers annehmen. Das vorallendingen deshalb, weil sich
der AC alternativ über einen Multiplexer an jeden AD-Kanal schalten
läßt (intern), sodaß jeder A/D-Kanal als positiver Eingang agieren
kann. Und für den A/D finde ich nur MAX-Werte, keine MIN..

???

von Manfred Glahe (Gast)


Lesenswert?

Wie gesagt ich arbeite nicht mit AVR's, kann dazu auch nichts sagen.
Sind die AD Eingänge auch als DIG Eingänge zu prog. (beim HC11 hatte
ich Anfangs auch nicht drauf geachtet, reagiert dann natürlich mit dem
TTL Level von 2-3V) ? Dann würde ich dort mal schauen.
Hast Du das mal mit einer Gleichspannung am Eingang ausprobiert? Nach
dem Test weißt Du ob es sich um einen DIG Eingang handelt der auf die
Komparatorschwelle garnicht achtet.

MfG  Manfred Glahe

von Martin Zunke (Gast)


Lesenswert?

Reaktivierung eines Threads ;-)

Wer hat Erfahrungen mit dem integrierten Analog-Comparator UND KLEINEN
SPANNUNGEN!! Das den irgendwer schon benutzt hat, hilft mir nicht. Es
geht konkret um KLEINE SPANNUNGEN (ab 50/100mv)

Ich habe eine Referenzspannung von ca 50 mV und ein Signal, Sinus. Das
will ich "erkennen". Es handelt sich um ein 40 kHz Signal.

Mittels Torzeitmessung erfasse ich das Signal. Das klappt auch:
manchmal. Manchmal nicht. Ohne zunächst den Quelltext zu
analysieren: gibt es Beschränkungen des AC nach unten (sicheres
Erkennen eines Signalpegels) und hinsichtlich der Frequenz?

mz

von Uwe (Gast)


Lesenswert?

Hi!
Ich überprüfe in einer PLL das Eingangssignal, das 100mV nicht
unterschreiten darf, geht ohne Probl.Proz. ist allerdings ein AT90S4433
und die Freq. dürfte bei ca. 1KHz liegen.

Die Reaktionsgeschw.des Comp.ist ja irgendwo bei 500ns @5V.
Es muss also gehen.

MFG Uwe

von Martin Zunke (Gast)


Lesenswert?

hmmmm....

habe heute den AC mittels Funktionsgenerator mit einem Rechtecksignal
gefüttert und bei jedem aufruf der ISR einen pin toggeln lassen: das
eingangssignal muß ergo als signal am pin erscheinen.

tut es auch, für eine gewisse zeit bei einem pegel des eingangssignals
von mind. 1V (!). darunter passiert nix, trotz referenzspannung 50mV
(genau: 54.4mV)(!!).

das gleiche bei referenzspannung 0 (Masse).

erst ist er noch recht empfindlich und toggelt bei knapp unter 1V mit,
dann schwimmt er und bricht schließlich ab. dreht man den pegel hoch,
macht ers wieder. das geht manchmal bis hoch auf 2.5 V. schaltet man
alles ab und wieder an, gehts von vorne los.

was um himmels willen kann das sein?!

mz

von Manfred Glahe (Gast)


Lesenswert?

"was um himmels willen kann das sein?!"
Schau Dir mal die Innereien des µP in diesem Bereich an (oder häng mal
das Datenblatt an). Sieht für mich aus als wenn der Referenzpin
(intern) nicht am Referenzpotential liegt und schwimmt. D.h. er läd
sich statisch auf mit der Zeit.

MfG  Manfred Glahe

von Martin Zunke (Gast)


Lesenswert?

Das Datenblatt ist riesig, ich mach das mal als Link:

http://www.atmel.com/dyn/resources/prod_documents/doc2502.pdf

Ich glaube, ich habe die internen Pull-Ups abgeschaltet (in meiner
Verzweiflung, als der AC überhaupt nicht reagierte). Werden diese
Register (SFIOR) beim Programmieren(und dem damit verbundenen erase)
eigentlich zurückgesetzt? Wenn nämlich nicht, dann sind die Pull-Ups
immer noch aus und könnten die statische Aufladung begünstigen, oder?!

Lange quatschen hilft nicht -- ich werde das nachher mal ausprobieren.
Aber das, was Du sagst, beschreibt exakt das Verhalten: morgens bzw.
nach langer Auszeit, ist die ganze Sache hochsensibel und funzt so, wie
ich es will. Kurze Zeit später ist Schluß und die Ergebnisse pegeln
sich wie oben dargestellt ein.

Vielleicht zur Beschaltung noch was: die Referenzspannung erzeuge ich
über einen einfachen Spannungsteiler. Vielleicht ist ja auch da der
Haken. Ich bin elektronisch nicht so die Leuchte.....



martin

von Manfred Glahe (Gast)


Lesenswert?

@Martin

Die Referenzspannungserzeugung, so wie Du sie beschrieben hast, ist
absolut NICHT die Ursache. Das kann Dir höchstens später die
Genauigkeit/Reproduzierbarkeit verderben, aber nicht diesen Fehler
hervorrufen.
Wie gesagt, ich kenne den µP nicht und werde mir die Sektion mal
anschauen (kann aber etwas dauern bis zur Antwort).

MfG  Manfred Glahe

von Manfred Glahe (Gast)


Lesenswert?

@Martin

Ich habe mir das mal angeschaut und würde mal tippen, daß Du den
falschen Analogeingang für die Referenz ausgewählt hast (der währe dann
unbeschaltet und den Fehlerzustand erklären. Schalte doch mal alle
Analogeingänge auf die Referenz, dann müßte es eigentlich laufen.
Wie sehen die Inhalte von SFIOR und ACSR aus?
Datenblatt Seite 201, enthält die Tabelle welcher Eingang wann usw...
Am Besten poste mal den relevanten Code Schnipsel.

MfG  Manfred Glahe

von Martin Zunke (Gast)


Lesenswert?

Initialisierung:

/* Analogcomparator initialisieren */
void init_ac(void)
{
  /* Alles mit set- und clear-Bit, zur Sicherheit */
  /* Interrupt disablen, dann stoppen */
  cbi(ACSR,ACIE);
  sbi(ACSR,ACD);

  /* modus setzen rising edge (11) */
  sbi(ACSR,ACIS0);
  sbi(ACSR,ACIS1);

  /* ACI clearen (zur Sicherheit) */
  cbi(ACSR,ACI);

  /* anschalten, dann Interrupt enablen */
  cbi(ACSR,ACD);
  sbi(ACSR,ACIE);

}

ISR:

/* INTERRUPTHANDLER Analog Comparator */
SIGNAL(SIG_COMPARATOR)
{
  if(bit_is_set(PORTC,PC2)) cbi(PORTC,PC2);
  else sbi(PORTC,PC2);
}

In der main dann sei() und Endlosschleife.

von postmen (Gast)


Lesenswert?

@martin:

setzt du die beiden flags ACME und ADEN auf '1' um AIN1 als negativen
input auszuwaehlen?

just my .02
andi

von postmen (Gast)


Lesenswert?

nachtrag.. bzw. brauchst du nur ACME loeschen, dann ist automatisch AIN1
selected.

andi

von Gerhard Schmidt (Gast)


Lesenswert?

Ich habe mit dem Analogkomparator und einem PWM-Kanal einen AD-Wandler
mit sukzessiver Approximation gebaut:

http://www.avr-asm-tutorial.net/avr_de/avr_adc500.html

Funktioniert in allen Spannungsbereichen zwischen 0 und 5 Volt. Nur
ganz oben (ab 4,9 Volt) nimmt der Fehler überproportional zu, was auch
kein Wunder ist.

Allerdings alles in asm.

MfG
Gerd

von Martin Zunke (Gast)


Lesenswert?

ACME habe ich gelöscht, der richtige Eingang ist das schon.

Ach, sch...

Ausserdem toggelt der bezeichnete Ausgang mit 15 kHz (wenn ich das
Messsignal direkt anlege, Amplitude min. 1V). Da ich ja steigende
Flanken registriere, müßte sich alle 2 Perioden der Pegel des Ausgangs
ändern: 40kHz/2 == 20kHz..... Liegt vielleicht daran, daß ich die
Taktfrequenz noch als Werkseinstellung habe: 1MHz. Ich versuche das mal
hochzusetzen....

Durch das direkte Anlegen des Signals umgehe ich inzwischen alles, was
auf der Schaltung sonst noch existiert. Am Referenzeingang liegen
definitiv 50mV (ich messe das jedesmal nach, bevor ich Euch
schreibe...), das Signal ist definitiv ein Rechtecksignal mit 40 kHz
und einer Amplitude zwischen 1....2.5 Volt.

....und zwischen 0.05 und 1 Volt will ich eine Reaktion des AC.

ich wein' gleich...;-)
mz

von postmen (Gast)


Lesenswert?

sorry, dass ich dir nicht helfen kann, ich kenne das gefuehl, man denkt
es ist alles richtig und doch geht es nicht.. ich versuche seit wochen
den hardware twi (externes eeprom) zum laufen zu bringen, ich bekomme
alle errorcodes richtig zurueck, aber trotzdem lese ich nichts aus dem
eeprom aus.. und der errorcode ist dann auch falsch..

dirbeisteh
andi

von Martin Zunke (Gast)


Lesenswert?

....so, nun müßte aber eigentlich alles stimmen. Ich hatte noch
vergessen, die Pins als Eingang mit ausgeschalteten Pull-Ups zu
betreiben:

/* Analogcomparator initialisieren */
void init_ac(void)
{
  /* GLOBALE PORTSETTINGS
     ==================== */

  /* PORT B, Pin 3 und 4 (Bit 2 und 3) als Eingang (AIN= und AIN1) */
  cbi(DDRB,PB2);
  cbi(DDRB,PB3);

  /* Massebezug (Portc, Pin 2) für Sensor einschalten: Output, "0"*/
  sbi(DDRC,PC1);
  cbi(PORTC,PC1);


  /* SPEZIELLE SETTINGS FÜR ANALOG COMPARATOR
     ======================================== */

  /* Register SFIOR
     -------------- */
  /* ACME clearen, AIN als negativer Eingang */
  cbi(SFIOR,ACME);
  /* PUD setzen, interne Pull-ups disablen */
  sbi(SFIOR,PUD);

  /* Register ACSR
     ------------- */
  /* Interrupt disablen, dann stoppen */
  cbi(ACSR,ACIE);
  sbi(ACSR,ACD);

  /* modus setzen rising edge (11) */
  sbi(ACSR,ACIS0);
  sbi(ACSR,ACIS1);

  /* ACI clearen (zur Sicherheit) */
  cbi(ACSR,ACI);

  /* anschalten, dann Interrupt enablen */
  cbi(ACSR,ACD);
  sbi(ACSR,ACIE);

}

Es ist faszinierend: nach neuproggen und aus/anschalten reagiert er
jetzt bei ca 0.4 V. Eine Weile. Dann wird das Signal am Oszi
verschwommen, d.h., er erkennt nicht mehr alle Flanken. Drehe ich den
Signalpegel hoch, habe ich wieder ein sauberes Rechtecksignal. Das
Spiel geht solange, bis die Amplitude des Eingangssignals bei 2.5 Volt
ist.

Nochmal zur Erinnerung: ich toggele in der ISR einen Pin bei jeder
steigenden Flanke. Da ich nur steigende Flanken registriere, müßte ein
Signal von 20 kHz entstehen. Es sind aber tatsächlich nur 15 kHz.

Ich glaub, da ist ganz kräftig der Wurm drin...

@andi schluchzendindiearmefall

von Johannes (Gast)


Lesenswert?

Ohne mich mit Deinem Problem näher Beschäftigt zu haben ....
und ohne "Fachmann" zu sein:
Hatte ein ähnlilches Ptroblem bei der Beschaltung eines
Operationsverstärkers als Subtrahierer (Bestandteil Messverstärkers).
Nachdem ich einen weiteren OP als Impedanzwandler hinzugefügt habe lief
alles. In Deinem Fall könnte dies bedeuten durch eine Stromverstärkung
Erfolg zu haben.
-> OP: Rail to Rail z.B. LTC 1152 als Impedanzwandler beschaltet

mfg jan

von Uwe (Gast)


Lesenswert?

Hi!
Ich werde nicht ganz schlau draus. Haste mal nen anderen Proz.
genommen? (alter spinnt??????)

MFG Uwe

von Martin Zunke (Gast)


Lesenswert?

...das letzte habe ich inzwischen auch in Betracht gezogen und neue
bestellt. Nachdem ich nun die Referenzspannung über eine
Spannungsquelle variiert und dabei festgestellt habe, das das Signal
bei 1.65 V Referenzspannung erkannt wird, aber nicht mehr, wenn ich sie
RUNTER regele, da habe ich angefangen an Geister zu glauben. Auch eine
Vertauschung von Referenz und Eingangsignal habe ich in Betracht
gezogen (wegen möglichem Druckfehler im Manual). Das gleiche...

Dann habe ich mal die Frequenz geändert. Und festgestellt, das ab 35
kHz sich nichts mehr ändert. D.h., die Interrupts kommen ab 35 kHz im
Takt von 15 kHz. Nur unterhalb 35 kHz verändert sich was.

Wir lassen das hier vieleicht mal ruhen, bis ich die neuen Proz. habe.

danke trotzdem
mz

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.