Hallo zusammen, ich habe durch einen Optokoppler der mit 230V beschaltet wird (SFH628 mit zwei antiparallelen Dioden) am Eingang meines AVR eine "gepulste" Gleichspannung. kann ich diese durch Software in eine glatte "1" oder "0" verwandeln. Mit meinen bisherigen Versuchen hatte ich immer einen mehr oder weniger Zufallstreffer.
:
Bearbeitet durch User
Hallo! Dann ist es wie eine prellende Taste zu behandeln - mit Software oder in diesem Fall auch gern mit Hardware. Also ganz ganz einfach.
einfach wäre schön ;-) Mein Vorgehen war es die eingänge (ich habe das ganze an jedem Pin von Port E) 10x (Tests auch mit 40x -200x) mit einander zu verodern um ein Ergebnis zu bekommen. Hat leider nicht funktioniert.
Christoph P. schrieb: > einfach wäre schön ;-) > > Mein Vorgehen war es die eingänge (ich habe das ganze an jedem Pin von > Port E) 10x (Tests auch mit 40x -200x) mit einander zu verodern um ein > Ergebnis zu bekommen. > Hat leider nicht funktioniert. Du musst die Eingänge verUNDen und zwischen jeder Abfrage eine Pause von wenigen Millisekunden machen.
In Hardware: Hüllkurvendemodulator (Diode und Kondensator sowie Entladewiderstand) In Software: dauerhafte Abtastung mit mindestens 200Hz und dann DSV (FIR oder IIR Tiefpass, danach Grenzwert per if). Software alternativ: Missing Pulse Detector. Beispielsweise indem man die Spannung auf nen Pin gibt und danach dann 10ms wartet. Dann muss da wieder ne Spannung anliegen.
ich glaube das mit den verodern habe ich ein wenig falsch formuliert. hier mein code
1 | for(x=0;x<90;x++) |
2 | {
|
3 | eingange |= PINE; |
4 | |
5 | }
|
Ziel ist es, dass die Variable "eingange" den tatsächlichen Zustand wiederspiegelt. Und leider kann ich an der Hardware nichts mehr machen.
Wie oft fragst Du den Pin ab? Wenn es jede z.B. ms ist, dann geht sowas:
1 | static int cnt; /* Zwischenspeicher zum überbrücken einer halben Periode (5ms) + ein wenig Reserve */ |
2 | static int on; /* boolscher Zustand An oder AUS */ |
3 | |
4 | |
5 | if(PinX==0) |
6 | {
|
7 | cnt = 15; |
8 | }
|
9 | |
10 | if(cnt) |
11 | {
|
12 | cnt--; |
13 | on = 1; |
14 | }
|
15 | else
|
16 | {
|
17 | on = 0; |
18 | }
|
Wenn Du weniger als alle 2ms abfragst, dann brauchst Du einen Kondensator am µC-Pin. Mit einem Tau von z.B. 10ms;
Christoph P. schrieb: > for(x=0;x<90;x++) > { > eingange |= PINE; > > } 1) Du musst über eine komplette Halbwelle messen. Also 10ms. Dauert die Schleife so lange? 2) Wenn Strom, dann ist Dein Port-Pin 0. Daher musst Du verunden oder vorher Invertieren (wie hier) eingange |= !PINE;
Achim S. schrieb: > 1) Du musst über eine komplette Halbwelle messen. Also 10ms. Dauert die > Schleife so lange? Das Ziel ist nicht, den Netzsinus zu rekonstruieren, das Ziel ist festzustellen, ob er vorhanden ist. Es reicht also völlig, sich nen Pinchange-Interrupt zu machen und von da an nen 15ms langen Watchdog-Timer loslaufen zu lassen. Bei jedem Pinchange Interrupt wird der auf 0 gesetzt, wenn er überläuft weiss man dass die Spannung gefehlt hat.
THOR schrieb: > Es reicht also völlig, sich nen Pinchange-Interrupt zu machen und von da > an nen 15ms langen Watchdog-Timer loslaufen zu lassen. ich mach mir die Welt, widevidewie sie mir gefällt .... Christoph P. schrieb: > Und leider kann ich an der Hardware nichts mehr machen. Wenn Du also weisst, dass "PINE" ein Interrupt-Pin ist, dann schreibe das dem TO.
Christoph P. schrieb: > Ziel ist es, dass die Variable "eingange" den tatsächlichen Zustand > wiederspiegelt. > > einfach wäre schön ;-)
1 | eingange = PINE; |
2 | _delay_ms(5); |
3 | eingange &= PINE; |
Selbst wenn eine Abfrage den Nulldurchgang (=H-Pegel am Eingang) erwischt, liegt die zweite garantiert außerhalb und durch das UND setzt sich der L-Pegel (=Netzspannung vorhanden) durch.
Was soll das eigentlich werden? Willst du wissen ob generell Netzspannung da ist bzw ob da etwas eingeschaltet ist? Oder willst du irgendetwas anderes damit abfragen oder genauere Informationen darüber auslesen?
Christoph P. schrieb: > kann ich diese durch Software in eine glatte "1" oder "0" verwandeln. Sicher.
1 | eingange = 0; |
Was war jetzt dein Problem ? > Mit meinen bisherigen Versuchen hatte ich immer einen mehr oder weniger > Zufallstreffer. Was erwartest du bei Wechselspannung ? Klar ist die mal höher und mal niedriger, und manchmal sogar aus. Dein eingange wird das exakt wiedergeben. Christoph P. schrieb: > for(x=0;x<90;x++) > { > eingange |= PINE; > > } > > Ziel ist es, dass die Variable "eingange" den tatsächlichen Zustand > wiederspiegelt. Dann sollte man wohl besser
1 | eingange = PINE; |
schreiben. Offenbar willst du gar nicht wissen, dass es Wechselspannung ist. Dich interessieren die Pausen und Nulldurchgänge nicht. Du wilkst nur wissen, ob es innerhalb der letzten 50tel Sekunde mal an war. Da du offenbar keine Programmhauptschleife hast, zumindest zeigst du sie nicht, vielleicht ja aus Faulheit, ist sicher der Vorschlag von THOR angemessen: PinChangeInterrupt und Reset durch Watchdog, also Zeitgeber (Timer). Ob dein Port E überhaupt pin change interrupts kann, wissen wir nicht, da du zu faul warst den verwendeten Microcontroller zu nennen. Als AVR vermutlich ja.
Christoph P. schrieb: > ich habe durch einen Optokoppler der mit 230V beschaltet wird (SFH628 > mit zwei antiparallelen Dioden) am Eingang meines AVR eine "gepulste" > Gleichspannung. > kann ich diese durch Software in eine glatte "1" oder "0" verwandeln. Per Hardware reicht vermutlich schon ein kleiner Elko zwischen Emitter und Kollektor. Grösse müsste man ausprobieren.
Harald W. schrieb: > Per Hardware reicht vermutlich schon ein kleiner Elko zwischen > Emitter und Kollektor. Das wird anscheinend schwierig. Christoph P. schrieb: > Und leider kann ich an der Hardware nichts mehr machen.
Hi Somit bleibt nur die Software (wie bereits zu Beginn erwähnt). Der Vorschlag per PCINT und WDT klingt in sich schlüssig und sollte funktionieren. MfG
Der Ausgangspegel des Optokopplers zeigt SO ETWA an, ob gerade eine positive, oder negative Halbwelle der Wechselspannung vorliegt. Im Übergangsbereich werden Werte zwischen den von Digital- schaltungen benötigten High- und Low-Pegeln ausgegeben, die auch noch durch höherfrequente Störspannungen auf der Wechselspannung überlagert sein können. Prinzipiell wird auch die positive Halbwelle am Eingang kürzer, als die negative Halbwelle ausgegeben, weil die Eingangs-LED erst oberhalb von 1,5...2 V zu leuchten beginnt. Ganz sichere ist: Das ist KEIN Nulldurchgangsdetektor! Was willst du mit dem Optokopplersignal erreichen? Nur wenn das bekannt ist, kann es auch zielführende Tipps geben. Mit Spekulation erreicht man NIX.
ich habe jeweils an einem Port die oben gezeigte Schaltung (insg 8x). Und möchte feststellen, ob L1 anliegt oder nicht (und natürlich will ich auch wissen an welchem Port.
Christoph P. schrieb: > Und leider kann ich an der Hardware nichts mehr machen. Das ist schlecht, denn besser wäre folgende Schaltung: https://www.mikrocontroller.net/articles/230V#Galvanisch_getrenntes_Abfragen_von_230V_Wechselspannung Ohmscher Vorwiderstand bedeutet ca. 2 Watt Verlustleistung :-(
Christoph P. schrieb: > Und leider kann ich an der Hardware nichts mehr machen. Ist das Ding denn ein Serienprodukt, oder Einzelstück? Ein Kondensator parallel zum Transistor (C-E) um die Nulldurchgangs-Zeit zu überbrücken würde helfen. Und den sollte man ja wirklich irgendwie noch draufpatchen können. Welchen Wert hat denn der unbeschriftete Pull-Up?
:
Bearbeitet durch User
Guten morgen. Erstmal vielen Dank für die vielen Vorschläge. Meine Lösung sieht nun so aus :
1 | |
2 | int x=0,y=0 ; |
3 | int eingange; |
4 | for(x=0;x<20;x++) |
5 | {
|
6 | y|=~PINE; |
7 | delayms(3); |
8 | }
|
9 | eingange =~y; |
mit einem logischen NOT hat es nicht geklappt. Gesucht war tatsächlich nur eine Softwarelösung. Den Kondensator(330nF) parallel zum Ausgang des OK habe ich nicht erwähnt da er keinen Einfluss auf das wackeln am Ausgang hat. Der Vorwiderstand ist so gewählt das kaum Strom fließt und ist in der Realität auf mehrere Widerstände aufgeteilt. Die Verlustleistung beträgt ca 1/4W. Das Arbeiten mit Interrupts ist prinzipiell eine gute Sache in die ich mich weiter reinarbeiten muss. Die von mir vorgestellte Lösung ist quick and dirty und eigenet sich nur solange es keine Störungen gibt, die zwischendurch einen unbeschalteten Eingang auf Masse zieht. Nochmal vielen Dank für die zahlreichen Vorschläge und Ideen.
Christoph P. schrieb: > Den Kondensator(330nF) parallel zum Ausgang des OK habe ich nicht > erwähnt da er keinen Einfluss auf das wackeln am Ausgang hat. Zu klein.
Christoph P. schrieb: > Den Kondensator(330nF) parallel zum Ausgang des OK habe ich nicht > erwähnt da er keinen Einfluss auf das wackeln am Ausgang hat. Na ist doch prima, dass da schonmal ein Kondensator da ist. Wenn du jetzt noch den Wert des Pullups (der Widerstand zwische uC-Pin und 5V) verraten würdest... Der ist vermutlich zu niederohmig gewählt. Bei 330nF würde ich es mal mit 47K versuchen. Christoph P. schrieb: > Der Vorwiderstand ist so gewählt das kaum Strom fließt und ist in der > Realität auf mehrere Widerstände aufgeteilt. Die Verlustleistung beträgt > ca 1/4W. Wenn schon wenig Strom durch die LED fließt, ist es um so wichtiger, dass der Pullup am Ausgang nicht zu niederohmig ist.
Christoph P. schrieb: > Und möchte feststellen, ob L1 anliegt oder nicht Damit ist die Sache doch sehr eindeutig. Idealisiert bedeutet es: Strom aus = immer 0 Strom an = überwiegend 1 mit zyklisch wiederkehrenden Nullen alle 10 Millisekunden (eine Halbwelle) Zuzüglich gelegentlicher Störungen. Das kann man genauso handhaben wie das Entprellen eines Tasters. Will man abfragen oder kontinuierlich überwachen? Einer der einfachsten Varianten bei festgelegter Hardware dürfte es sein, den Port per Timer im Millisekundentakt abzufragen. Waren 5 oder mehr der letzen 10(eine Halbwelle) Messungen eine 1, so liegt Spannung an. Waren es weniger.... Nun ja, die 5 ist nicht festgetackert und kann angepaßt werden. Damit wären Nulldurchgang und Störungen zugleich behandelt. Det Takt ist fast willkürlich. Er ist schnell genug um oft genug abzutasten, aber auch nicht zu hoch und mit den Timern ist es meist leicht einen Takt in der Größenordnung hinzubekommen. Der exakte Wert ist nicht kritisch.
:
Bearbeitet durch User
Christoph P. schrieb: > Der Vorwiderstand ist so gewählt das kaum Strom fließt > und ist in der Realität auf mehrere Widerstände aufgeteilt. > Die Verlustleistung beträgt ca 1/4W. Also hast Du im Mittel 1mA für den Optokoppler, ganz schön knapp. Ich vermute mal, dass Dein Ausgangssignal damit unnötig kurz wird, weil der erst bei recht hoher Spannung schaltet. Ich würde statt des Widerstandes einen Kondensator 0,1µF X2 und einen Angstwiderstand um 5kOhm verwenden. Dann schaltet er früher durch und Dein Zeitfenster am Ausgang wird größer.
Manfred schrieb: > Dann schaltet er früher durch und > Dein Zeitfenster am Ausgang wird größer. Man möchte am Ausgang eigentlich überhaupt kein "Fenster" sondern ein High oder Low. Daher ist ja da schon ein Kondensator. Aber die Grenzfrequenz des durch den Pullup und Kondensator gebildeten Tiefpasses scheint eben zu hoch geraten zu sein. Wenn der richtig dimensioniert ist, kann die Nulldurchgangsphase sogar 10% der Gesamtzeit sein, und es würde immer noch ein ziemlich eindeutiges und dauerhaftes LOW nach dem Tiefpass entstehen.
Joe F. schrieb: > Manfred schrieb: >> Dann schaltet er früher durch und >> Dein Zeitfenster am Ausgang wird größer. > > Man möchte am Ausgang eigentlich überhaupt kein "Fenster" sondern ein > High oder Low. Ja! > Daher ist ja da schon ein Kondensator. Macht man ihn größer, wird er vermutlich nicht geladen. Bei > Die Verlustleistung beträgt ca 1/4W. dürfte er 220k als Vorwiderstand haben. Über den Sinus betrachtet zwischen 0 und 1,5mA Strom durch die LEDs, was soll da hinten noch kommen - aus dem Gefühl heraus 3..5ms aktiv? Ob da genug Strom ist, einen C zu laden, bezweifele ich - von daher meine Idee, primärseitig anzufassen.
Manfred schrieb: >> Daher ist ja da schon ein Kondensator. > Macht man ihn größer, wird er vermutlich nicht geladen. Bei deswegen sage ich ja, Kondensator so lassen, und Pull-Up möglichst hochohmig. 47K / 330n kommen schon hin. Das wären 10 Hz Grenzfrequenz. >> Die Verlustleistung beträgt ca 1/4W. > dürfte er 220k als Vorwiderstand haben. > > Über den Sinus betrachtet zwischen 0 und 1,5mA Strom durch die LEDs, was > soll da hinten noch kommen - aus dem Gefühl heraus 3..5ms aktiv? Ob da > genug Strom ist, einen C zu laden, bezweifele ich - von daher meine > Idee, primärseitig anzufassen. Ja, das mit dem geringen Strom am Transistor sehe ich auch so, daher: hochohmiger am Ausgang. Der Kondensator muss über den Transistor übrigens entladen werden. Ob das sauber funktioniert, sieht man am besten, wenn man mal ein Oszilloskop an das Signal hält... Wenn der Transistor den Pegel schon gar nicht auf 0V runterzieht, oder nur extrem langsam, dann ist zu wenig Strom an der LED.
Christoph P. schrieb: > y|=~PINE; > ... > eingange =~y; > mit einem logischen NOT hat es nicht geklappt. Ich dachte, PINE sei ein Pin gewesen. Mir war nicht klar, dass Du einen ganzen Port parallel auswertest. Das logische NOT geht natürlich nur bei einem binären Signal (nur 0 oder 1, nicht 0x40 oder so)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.