Hallo Nachdem ich ohne uC ein PWM-Signal auswerten wollte und das nicht hinbekomme, habe ich mich endlich doch entschlossen, den einfachen Weg über ein uC zu gehen. Doch ich bin auch nicht so erfolgreich, wie ich mir das vorgestellt habe. Situation: Ein RC-Empfänger liefert mir ein PWM-Signal. Dieses muss sich kontinuierlich ändern, mindestens 1x pro 500ms. Wenn nicht, hat etwas zu geschehen (in meinem Fall bei einem Modellflugzeug den Fallschirm auswerfen). Wenn ich den Code mit einem Arduino-Mini laufen lasse (kann ich einmal schön über die Konsole sehen, was passiert) funktioniert es. Aber an einem ATtiny45 habe ich "Fehler". Das Testsetup ist wie folgt: - An Pin5 ist ein Servotester, - An Pin6 ist über einen Widerstand eine LED angeschlossen, - Alles über die gleiche Source mit 5V versorgt Der Code ist dieser hier: int inPin = 0; int outPin = 1; int brightness = 10; long lastMove = millis(); long switchDelay = 0; long switchDelayMax = 500; long switchState = 0; long switchStateLast = 0; long switchMove = 0; void setup(){ pinMode(outPin, OUTPUT); pinMode(inPin, INPUT); } void loop(){ switchState = pulseIn(inPin, HIGH); switchMove = switchState - switchStateLast; switchMove = abs(switchMove); switchStateLast = switchState; if (switchMove > 5) { lastMove = millis(); } switchDelay = millis() - lastMove; if (switchDelay > switchDelayMax) { digitalWrite(outPin, HIGH); } else { analogWrite(outPin, brightness); } delay(100); } Resultat: Wenn der Servotester automatisch und kontinuierlich das Signal ändert, ist die LED schwach. Wenn der Servotester manuel ist und ich ihn nicht bewege, ist meine Erwartung vom Code oben, dass die LED spätestens nach einer halben Sekunde kontinuierlich hell leuchtet. Tut sie aber nicht. Sie leuchtet meist schwach und in unregelmässigen Abständen blinkt sie kurz hell auf um gleich wieder schwach zu leuchten. Mal sind dazwischen 18s, mal auch nur 1s. Mit rumprobieren habe ich die Vermutung, dass schon die Differenzberechnung in switchMove nicht sauber funktioniert. Die "if (switchMove >5)" Abfrage sollte verhindern, dass wenn der RC-Empfänger kaum unterscheidbare Signale liefert, hier quasi eine Minimumschwelle ist, die es zu überschreiten gilt. Doch auch ohne Änderung über den Servotester ist hier manchmal die Bedingung erfüllt. Was mache ich falsch? Klar, als erstes ist es nicht in Assembler und alles Andere als optimal - aber ich kann leider nix anderes. Und einen Arduino-Mini einbauen will ich vom Platz her nicht. Danke für die Hilfen Gruess Dominik
@Dominik Jenzer (nique) >Ein RC-Empfänger liefert mir ein PWM-Signal. Dieses muss sich >kontinuierlich ändern, mindestens 1x pro 500ms. Wenn nicht, hat etwas zu >geschehen (in meinem Fall bei einem Modellflugzeug den Fallschirm >auswerfen). Was meinst du mit ändern? Muss mindestens alle 500ms ein Puls erscheinen oder soll sich alle 500ms die Pulsbreite ändern? Ersteres kann man sehr leicht mit einem retriggerbaren Monoflop machen, da braucht es keinen Controller.
Hallo, wenn länger als 500ms keiner mehr am Sender wackelt soll der Pin auf High gehen. Hab es mir aber noch nicht angeschaut. Wozu eigentlich den Tiny mit der PWM beschäftigen um die LED zu dimmen? Gruß aus Berlin Michael
Also RC-Empfänger ist PPM wenn ich mich nicht irre. Du willst also detektieren, wenn die Funkverbindung zwischen Sender und Empfänger verlorengegangen ist und dann das Komplettrettungssystem für dein Flugzeug auslösen. Das sagt mir zumindest meine Kristallkugel. Zuallererst würde ich mal die Fuses prüfen. Entweder Watchdog an oder Takt anders als erwartet. Und dann das komplette Projekt mit allen Dokumenten, Schaltplan, Layout, h und c Files sowie Makefile in ein Zip und das dann hier hochladen. Und dann verlassen wir vielleicht das magische Kristallkugelland.
Danke erst mal @amiga hat es erfasst. Ich will wissen, wenn keiner mehr am Sender "wackelt". Im Flieger wird zwischen RC-Empfänger und dem Tiny noch Autopilot sein, darum werte ich nicht einfach den Failsafe aus, sondern gehe explizit auf einen Kanal der übertragen werden muss und hier wird dauernd "gewackelt". Ich dimme die LED im Moment, damit es mich nicht blendet ;-) und ich zwischen den Ausgaben unterscheiden kann. Hell = Notprogramm Dimm = Alles läuft Aus = hab mal wieder ein Kabel ausgerissen. Später stosse ich dort weitere Routinen an. Im finalen Programm wird nicht nur der Fallschirm geschmissen, denn je nach gewackel wird die Beleuchtung vom Flieger noch gesteuert. Gewackel zwischen 1000 und 1500ms = gedimmte LED am Flieger - er ist am Boden. Gewackel zwischen 1500 und 2000 - Flieger ist in der Luft, die LED (total 60W) geben vollgas. Und im Notprogramm werden sie SOS blinken... und das hoffentlich am Fallschirm. Ist alles auf eine Board nur gesteckt. GND - Pin 4 +5 - Pin 8 In - Pin 5 Out - Pin 6 Out geht an R an D und dann an GND Servotester hängt auch an +5, GND und eben an Pin 5 Ich verwende den obigen Code mit Arduino 1.0.6, einen UNO als ISP-Programmer für den Tiny. Das mit den Fuses habe ich nicht im Griff. Wie prüfe ich das und wie stelle ich die ein (mit dem Arduino)?
Muss doch in der Arduino Doku irgendwo stehen. Oder in ner FAQ. Mit meinem STK500 und dem Lubuntu Notebook mache ich das per AVRDUDESS und dem Web-Fusecalculator. Wie die Programmierumgebung bei Arduino aussieht, kein Plan.
Ich habe den Code einmal vereinfacht: void loop(){ switchState = pulseIn(inPin, HIGH); switchMove = switchState - switchStateLast; switchMove = abs(switchMove); switchStateLast = switchState; if (switchMove < 10) { digitalWrite(outPin, HIGH); } else { analogWrite(outPin, brightness); } delay(100); } Und genau so auf den Tiny45 und auf ein Nano geladen. Den Schwellwert habe ich auf 10 gesetzt, weil ich mit dem Serial Monitor festgestellt habe, dass der uC ohne gewackel dennoch eine Differenz bis zu 9 bekam. Die Nano-Ausgabe ist wie gewünscht, auf dem Tiny habe ich bei ständigem gewackel (über einen Servotester) unregelmässige helle blinker drin. In der "Neutral"-Position des Servotesters (hier ändert sich der Input nicht mehr), bleibt beim Nano die LED schön hell, ohne unterbrüche. Beim Tiny lässt sich das nicht sagen, ob mehr gedimmt ist oder mehr hell ist. Das flackert recht wild.
Sascha schrieb: > Also RC-Empfänger ist PPM Es gibt Empfänger mit einer Art PWM(standardisierter fester Breite in 1-2ms/0%-100%)/6Adern mit denen man direkt die Servos einzeln ansteuern kann oder so eine Art Multiplex namens PPM mit 6 kanälen in einem Signal/Ader welches dann direkt auf eine FCU geht, hier sind die Kanäle mit Fester breite aneinandergereit. Jeder Kanal hat dabei 2ms. Einfach mal Googeln oder bei Wikipedia reinschauen. Der erste Googler mit "PulseIn Attiny" ergibt ein Timingproblem durch voreingestellte 1Mhz clock, während in der IDE bzw im Unterprogramm mit 8Mhz gerechnet wird. Da wäre jetzt wichtig ob Du schon Fuses gesetzt hast oder einmal in die Boards.txt schauen und die eingetragene "F_CLK"(oder so ähnlich, sitze gerad nicht am Rechner) des ausgewählten Boards überprüfen.
Danke @philipp_k59 - das dürfte ein guter Hinweis sein. Ich hab folgende Einstellungen zur Auswahl:
1 | attiny45.name=ATtiny45 (internal 1 MHz clock) |
2 | attiny45.bootloader.low_fuses=0x62 |
3 | attiny45.bootloader.high_fuses=0xdf |
4 | attiny45.bootloader.extended_fuses=0xff |
5 | attiny45.upload.maximum_size=4096 |
6 | attiny45.build.mcu=attiny45 |
7 | attiny45.build.f_cpu=1000000L |
8 | attiny45.build.core=arduino:arduino |
9 | attiny45.build.variant=tiny8 |
10 | |
11 | attiny45-8.name=ATtiny45 (internal 8 MHz clock) |
12 | attiny45-8.bootloader.low_fuses=0xe2 |
13 | attiny45-8.bootloader.high_fuses=0xdf |
14 | attiny45-8.bootloader.extended_fuses=0xff |
15 | attiny45-8.upload.maximum_size=4096 |
16 | attiny45-8.build.mcu=attiny45 |
17 | attiny45-8.build.f_cpu=8000000L |
18 | attiny45-8.build.core=arduino:arduino |
19 | attiny45-8.build.variant=tiny8 |
20 | |
21 | attiny45-20.name=ATtiny45 (external 20 MHz clock) |
22 | attiny45-20.bootloader.low_fuses=0xfe |
23 | attiny45-20.bootloader.high_fuses=0xdf |
24 | attiny45-20.bootloader.extended_fuses=0xff |
25 | attiny45-20.upload.maximum_size=4096 |
26 | attiny45-20.build.mcu=attiny45 |
27 | attiny45-20.build.f_cpu=20000000L |
28 | attiny45-20.build.core=arduino:arduino |
29 | attiny45-20.build.variant=tiny8 |
Bisher habe ich mit dem 1MHz gearbeitet. Werde Morgen mal mit der 8MHz-Variante testen. Oder gibts vorher noch andere Einstellungen zu tätigen?
Ach was morgen. Hat mir gleich keine Ruhe gelassen und gleich nochmals alles aufgebaut. Schon viel besser - bis fast sehr gut. Mit Servotester als Wackler leuchtet die LED nur noch sehr selten hell. Also ev. den Wert von 10 noch weiter erhöhen. Da die Wackler letzten endes automatisch erzeugt werden, kann ich selbst dafür sorgen, dass die Wertänderungen jeweils "steil" genug sind. Es ist interessant, ich habe am gleichen Servotester den ATtiny dran, wie auch den Nano. Und da sehe ich perfekt, wie die sich unterscheiden. Der Nano reagiert schon viel schneller! Aber für das wie ich es brauche, genügt das Verhalten vom tiny vollends. Danke Philipp, deins war der entscheidende Hinweis in der Form, wie ich etwas damit anfangen konnte. Ich wäre selbst nicht auf die Idee gekommen, dass es am PulseIn und dachte, dass ich mit dem Rechnen was nicht begreife oder die ABS-Funktion nicht geht.... Cool, Danke und gute Nacht.
Jetzt läuft es auf dem Nano genau wie ich es mir vorstelle. Aber auf dem Tiny noch nicht ganz. Zwar die Routine an sich schon, doch viiiiel zu langsam. In einem Fall gebe ich Morse-R aus. Das mache ich so, dass die an-aus-Folgen in einem Array in Form von ms gespeichert sind: int aFly[] = {mDit,mPause,mDah,mPause,mDit,mBreak}; Mit der Funktion millis prüfe ich immer die verstrichene Zeit und entscheide dann, ob im Array inkrementiert wird oder noch nicht und davon abhängig, ob die LED aus oder an soll.
1 | if (isLED) { |
2 | if ((millis() - lastTime) > aFly[iFly]) { |
3 | lastTime = millis(); |
4 | digitalWrite(outPin, LOW); |
5 | isLED = false; |
6 | iFly++; |
7 | } |
8 | } else { |
9 | if ((millis() - lastTime) > aFly[iFly]) { |
10 | lastTime = millis(); |
11 | digitalWrite(outPin, HIGH); |
12 | isLED = true; |
13 | iFly++; |
14 | } |
15 | } |
Im Nano funktioniert das, auch die Zeiten stimmen. Mit dem Tiny ist das gefühlt 10x langsamer!!! Dazu habe ich im Array die ms mal auf einen Zehntel eingestellt und da war es immer noch etwas langsamer als mit dem Nano. Das Gleiche mit dem Nano führt zu entsprechend schnellem blinken. Da gibts in Sachen Timing wohl noch was zu beachten. Weiss da jemand mehr?
Jetzt weiss ich mehr. Es genügt natürlich nicht, nur das Board mit 8MHz auszuwählen. Die Fuses werden erst mit dem "Bootloader installieren" gesetzt. Jetzt sieht es auch auf dem Tiny besser aus.
Ja genau, wollte ich eigentlich noch Anfügen ;) War mir nur nicht sicher ob die Fuses mit der Bootloader Option geschrieben werden. Das mache ich immer mit avrdude direkt. 1Mhz ist nun mal ne Auflösung von 1ns minus alles mögliche drumherum und du willst ja nanosekunde genau messen.
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.