Hallo, möchte einen Elektrozaun darauf überprüfen, ob Spannung anliegt. Dies wollte ich eigentlich über einen Spannunsteiler und evtl. Optokoppler realisieren. Falls der gemessene ADC Wert 5s lang unter 2000V fällt, soll eine Signalleuchte über ein Relais eingeschalten werden. Optional ist im Betrieb eine Spannungsanzeige auf LCD vorgesehen, vorerst aber nicht so wichtig. Mir geht es vor allem um die Benutzung des ADC im geplanten ATMega8. Bin blutiger AVR Anfänger, hab mir bisher aber einiges angelesen. Wie kann ich denn in der for-Zählschleife eine Messung von 5s realisieren, also wieviele Messungen muss ich entsprechend dem CPU Takt ausführen lassen ?
der ansatz ist gut. Bedenke aber, dass dein Spannugsteiler ziemlich hochohmig sein muss, damit die Spule im Gerät nicht zu schnell leer wird. du kannst auch einen interrupt werfen lassen, wenn die spannung unter 2kV fällt und nur dann 5sek lang messen, ob die spannung wieder ansteigt. Könnte vielleicht Strom sparen? Kenn mich aber nicht gut genug aus. Vereinfachen kannst du das Ganze natürlich, indem du ohne uC arbeitest und das Licht einfach immer dann anmachst, wenn die Spannung zu niedrig ist. Über die Schwelle stellst du dann ein, dass die Leuchte nicht ständig blinkt beim be- und entladen. Müsste man mal versuchen (oder rechnen, falls genügend Daten übers Gerät vorhanden sind).
Danke für die Antwort Armin, du hast natürlich Recht, dass dies auch mit Analogtechnik möglich ist. Erste Testschaltungen in MultiSim sind auch gelaufen, allerdings reizt mich die Herausforderung, das mit einem uC umzusetzen ... zumal man damit wesentlich flexibler ist und die Zaunspannung bei Bedarf auch über ein LCD anzeigen lassen kann.
Kann sich evtl. mal jemand in den Code reinschaun, ob ich da gröbere Fehler gemacht habe ... wie gesagt, bin Anfänger.
Hallo, ich habe mal kurz den Code überflogen. Dabei fand ich die folgende Zeile: > while(ADCSRA & (1<<ADIF)); Das ADIF abzufragen, ist falsch. Das wird nach der ersten Wandlung gesetzt und BLEIBT GESETZT, bis die ISR aufgerufen wird oder man es von Hand löscht. Stattdessen nimmt man dafür folgenden Code: while (ADCSRA & (1<<ADSC)); (siehe dazu auch AVR GCC Tutorial: ADC) Weiterhin wird bei jedem Aufruf von "messung()" der ADC eingeschaltet, eine Dummy-Wandlung durchgeführt, dann 1000 Werte genommen und vor Verlassen der Funktion der ADC wieder abgeschaltet. Normalerweise wird der ADC nicht abgeschaltet. Dann wird auch die Dummy-Wandlung überflüssig, und der ADC ist sofort bereit für Wandlungen. Der ADC steht auf "externe Referenzspannung an AREF". Ist das korrekt? Hängt an AREF tatsächlich eine passende Referenzspannung? Der ADC im Mega8 hat 10bit Auflösung; er liefert also Werte zwischen 0 und 1023. Daher solltest du die zugewiesenen Werte der Variablen "maximum" und "minimum" überprüfen; diese sind grösser als der maximal mögliche Ausgabewert des ADC. Es ist ungeschickt, in einer Funktion eine (lokale) Variable zu verwenden, die mit gleichem Namen ("maximum") auch im Hauptprogramm deklariert ist. Obwohl es verschiedene Variablen sind, führt der identische Name schnell zu Verwirrung. Und zum Schluss noch einen Hinweis: wenn du in definierten Zeitabständen A/D-Wandlungen durchführen willst, kann man dazu gut einen Timer verwenden, der die Wandlung alle x ms startet. Aber dazu sollte man sich mit Interrupts und deren Routinen auskennen ... Oder du verwendest einen Mega88 (ein "neuerer" Mega8); dieser kann den ADC hardwaremässig von einem Timer triggern lassen, ohne eine ISR zu brauchen.
IceCap schrieb: > Hallo, möchte einen Elektrozaun darauf überprüfen, ob Spannung anliegt. > Falls der gemessene ADC Wert 5s lang unter 2000V fällt, soll ... Ich kenne jetzt nicht den genauen Typ deines Zauns, aber an einem Weidezaun liegt doch nicht ständig Hochspannung an, sondern alle paar Sekunden kommt mal ein kurzer Impuls, den du mit einem langsamen ADC womöglich nicht einmal messen kannst. Nur so als Hinweis. Grüße, Peter
Danke für die vielen Hinweise, ich werde den Code nochmal überarbeiten und mich auch an Interrupten versuchen. Frage an Peter: Ich weiß jetzt nicht wie schnell der ADC des ATMega8 ist, aber sollte die Geschwindigkeit nicht ausreichen, den Spitzenwert eines kurzen Stromimpulses zu erfassen ? Natürlich weiß ich, dass an einem Weidezaungerät nicht ständig Spannung anliegt, deswegen sollen ja auch immer 5s lang gemessen werden. Falls in dieser Zeit kein Messwert >2000V zustande kommt, soll der Alarm auslösen. Dann soll erneut geprüft werden ob ein neuer Stromimpuls kommt, der den Alarm dann wieder abschaltet.
@ IceCap (Gast) der ADC kann mit 1MHZ getaktet werden, wenn du nur 8 der 10 Bit benützt. Dann liefert der etwa alle 15µs einen Messwert. Sonst (10 Bit) halt maximal 100kHz ADC-Takt. Laut Wikipedia liefert ein Zaun für etwa 5ms Strom. Da würde ich zur Sicherheit jede Milisekunde messen. Grüße, Peter
Hi
>Sonst (10 Bit) halt maximal 100kHz ADC-Takt.
Nein. Für 10Bit 50...200kHz ADC-Takt.
MfG Spess
Wollte nochmal Rückmeldung über den Fortschritt des Projektes geben. Habe mich nochmal hingesetzt, den Code überarbeitet und mit meinem MyAVR Board getestet. Die ADC Messung habe ich nochmal weggelassen, da ich erst mal mit ein paar grundliegenderen Sachen zu kämpfen hatte. Die LCD Ausgabe habe ich auf einem 16x2 Display mit implementiert. Natürlich wurde das LCD im ursprünglichen Code viel zu schnell angesteuert, so dass man kaum etwas erkennen konnte. Hilfsweise habe ich nun in der LCD Ausgabe eine for-Schleife eingebaut um nur jeden 20.000ten Messwert auszugeben. Kann man das auch etwas eleganter lösen ? Habe evtl. an einen Timer gedacht, der alle 2-3s einen Wert ausgibt, ist das zu machen und kann mir jemand evtl. Hinweise geben, wie ich das verwirkliche ? Beschäftige mich wie gesagt erst wieder seit Kurzem mit C-Programmierung und AVR.
IceCap schrieb: > Die LCD Ausgabe habe ich auf einem 16x2 Display mit implementiert. > Natürlich wurde das LCD im ursprünglichen Code viel zu schnell > angesteuert, so dass man kaum etwas erkennen konnte. > Hilfsweise habe ich nun in der LCD Ausgabe eine for-Schleife eingebaut > um nur jeden 20.000ten Messwert auszugeben. Kann man das auch etwas > eleganter lösen ? Habe evtl. an einen Timer gedacht, der alle 2-3s einen > Wert ausgibt, ist das zu machen und kann mir jemand evtl. Hinweise > geben, wie ich das verwirkliche ? Beschäftige mich wie gesagt erst > wieder seit Kurzem mit C-Programmierung und AVR. Dein Ansatz ist falsch. Dein Problem ist das ständige lcd_clear. Das braucht kein Mensch. Du musst deine Sichtweise ändern: Du willst nicht das Display ständig löschen und neu beschreiben, sondern du willst auf der Anzeige nur die Dinge überschreiben, die sich geändert haben. Dann bist du das Flackern los und hast trotzdem eine schnelle Reaktion. Edit: Aber aufpassen. Eventuell musst du manche Dinge mit Leerzeichen überschreiben. Sonst hast du den Fall, dass der Text "ZAUN FEHLER" wenn er durch "ZAUN EIN" überschrieben wird, auf der Anzeige ein "ZAUN EINLER" ergibt :-)
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.