Liebes Forum, ich habe einen 8mm-Filmprojektor, den ich zur Digitalisierung von alten Schmalfilmen verwenden will. Dazu muss der Projektor möglichst exakt mit einer Geschwindigkeit von 16 2/3 frames per second (fps) laufen. Am Projektor gibt es ein Potentiometer-Drehknopf, mit dem die Geschwindigkeit zwischen 16 und 24 fps geregelt werden kann. Damit ich genauer regeln kann, will ich die aktuelle Geschwindigkeit auslesen und zum Beispiel auf einem LCD anzeigen. (später will ich die Geschwindigkeit vielleicht auch noch automatisch regeln lassen oder sogar mit dem Videosignal des Camcorders synchronisieren). Die Frage: wie kann ich hier einen Mikrocontroller (Arduino oder ATtiny85) anschließen, ohne die bestehende Schaltung zu verändern? Im angehängten Schaltbild des Projektors sieht man: Im Projektor ist bereits ein Reed-Kontakt verbaut, der bei jedem dritten Bild einmal kurz öffnet. Außerdem gibt es eine Anschlussbuchse für einen sogenannten Tonkoppler, mit dem theoretisch von einem Tonbandgerät aus die Geschwindigkeit des Projektors gesteuert werden kann, um Ton und Bild zu synchronisieren. Ich würde genau da gern den Mikrocontroller anschließen. Ich weiß allerdings nicht so recht wie, weil dort zum einen gleichgerichtete 24V vorliegen und zum anderen noch ein weiterer, direkt im Motor verbauter Generator rumspukt, von dem ich den Sinn nicht verstehe. Vielleicht habt ihr Hinweise? Gruß und Dank grox P.S.: Falls ich im falschen Unterforum gelandet bin, sagt es mir bitte.
Der Schaltplan ist etwas ungewähnlich zu lesen (Masse ist nicht unten), aber schön simpel. An Pin 5 des DIN-Steckers hast du 26V anliegen, an Pin 2 Masse. Wenn du über einen 10kOhm-Widerstand Pin 5 mit Pin 3 verbindest, müsste Pin 3 bei geschlossenem Schalter auf 0 gehen, ansonsten auf 26V. Das kannst du am Arduino auswerten, du solltest aber zwischen Pin 3 und Pin 2 eine Zenerdiode schalten, die den Arduino-Eingang vor den 26V schützt. Über Pin 4 kannst du die Basis von Y2 verziehen, damit den Motorstrom beeinflussen und damit wiederum die Geschwindigkeit. Ich würd´s so machen: den Projektor von Hand etwas zu schnell stellen, einen Widerstand mit 150 Ohm und einen FET in Serie gegen Masse (Pin 2) schalten und dann mit einer PWM mit irgendwas > 10 kHz die Geschwindigkeit beeinflussen (ein Arduino-Ausgang kommt dann an das Gate des FET). Als FET reicht ein Kleisignaltyp à la 2N7002, er sollte nur 30V VDS aushalten und 100mA und logic-level sein. Theoretisch wird am Gate von Y2 zwar eine Gleichspannung erwartet, aber die Induktivität der Motorwicklung sollte das locker glattbügeln. Max
:
Bearbeitet durch User
Vielen Dank für die Erläuterung, ich brauche noch einen Moment, um das zu verstehen. Dabei ist mir noch eine andere Idee gekommen, von der ich nicht weiß, ob sie funktioniert oder den Arduino zerstört: 1. Geschwindigkeit auslesen: An Pin 3 der Buchse schaltet der Reed-Kontakt Masse. Wenn ich nun die Masse des Arduino mit der Masse des Projektors verbinde, das Plus des Arduino per Pullup-Widerstand von 1kOhm an einen Arduino-Pin gebe und an den gleichen Arduino-Pin den Buchsen-Pin 3 (Reed-Kontakt) anlege - funktioniert das oder raucht mir alles ab? Dann müsste doch immer LOW anliegen, solange der Reed-Kontakt nicht unterbrochen ist, oder? 2. Geschwindigkeit beeinflussen: Mit R5 kann die Geschwindigkeit eingestellt werden. In der DIN-Buchse ist zwischen Pin 6 und 7 anscheinend ein schaltender Kontakt, der beim Einstecken des Steckers unterbrochen wird. Kann ich da nicht ein FET sozusagen als zusätzlichen Widerstand einsetzen, den ich per Arduino steuere? Ich wüsste nur nicht, welche Anschlüsse an welche PINs.
Max G. schrieb: > Wenn du > über einen 10kOhm-Widerstand Pin 5 mit Pin 3 verbindest, müsste Pin 3 > bei geschlossenem Schalter auf 0 gehen, ansonsten auf 26V. > Das kannst du am Arduino auswerten, du solltest aber zwischen Pin 3 und > Pin 2 eine Zenerdiode schalten, die den Arduino-Eingang vor den 26V > schützt. Ich verstehe noch nicht, wie ich den Arduino anschließe. Ist das so gemeint: Arduino-Masse an Buchsen-Pin 2, Arduino-Input-Pin an Buchsen-Pin 3 und fertig? Die Stromkreise von Arduino und Projektor sind doch dann gar nicht verbunden, oder? Woher kommt denn dann das Spannungsgefälle am Arduino-Input-Pin? Tut mir Leid, wenn das eine blöde Frage ist, ich habe noch nicht so viel Erfahrung mit der Beschaltung von Mikrocontrollern.
grox schrieb: > An Pin 3 der Buchse schaltet der Reed-Kontakt Masse. Wenn ich nun die > Masse des Arduino mit der Masse des Projektors verbinde, das Plus des > Arduino per Pullup-Widerstand von 1kOhm an einen Arduino-Pin gebe und an > den gleichen Arduino-Pin den Buchsen-Pin 3 (Reed-Kontakt) anlege - > funktioniert das oder raucht mir alles ab? Ja, das ist vermutlich sogar der bessere Vorschlag als meiner. Du musst nur die Masse des Projektors (Pin 2) mit der Arduino-Masse verbinden. Dsa solltest du aber sowieso tun, siehe unten. > Mit R5 kann die Geschwindigkeit eingestellt werden. In der DIN-Buchse > ist zwischen Pin 6 und 7 anscheinend ein schaltender Kontakt, der beim > Einstecken des Steckers unterbrochen wird. Kann ich da nicht ein FET > sozusagen als zusätzlichen Widerstand einsetzen, den ich per Arduino > steuere? Ich wüsste nur nicht, welche Anschlüsse an welche PINs. OK, den Schaltkontakt hatte ich übersehen. Mein Vorschlag mit der PWM lief auf genau das hinaus. Hier wirst du ein bisschen experimentieren müssen. Miss mal in ausgestecktem Zustand die Spannung an Pin 4 (gegen Masse an Pin 2) und drehe den Geschwindigkeitsregler je einmal auf seine Anschlagspositionen. Dann melde dich wieder mit dem Ergebnis. Ein Multimeter hast du? Die Spannung erzeugst du nachher mittels Pulsweitenmodulation (PWM). > Ich verstehe noch nicht, wie ich den Arduino anschließe. Ist das so > gemeint: Arduino-Masse an Buchsen-Pin 2, Arduino-Input-Pin an > Buchsen-Pin 3 und fertig? Ja, du musst aber noch den Pullup beschalten, wie du schon selbst geschrieben hattest. > Die Stromkreise von Arduino und Projektor sind doch dann gar nicht > verbunden, oder? Woher kommt denn dann das Spannungsgefälle am > Arduino-Input-Pin? Vom Pullup. Max
Max G. schrieb: > OK, den Schaltkontakt hatte ich übersehen. Mein Vorschlag mit der PWM > lief auf genau das hinaus. Hier wirst du ein bisschen experimentieren > müssen. Miss mal in ausgestecktem Zustand die Spannung an Pin 4 (gegen > Masse an Pin 2) und drehe den Geschwindigkeitsregler je einmal auf seine > Anschlagspositionen. Dann melde dich wieder mit dem Ergebnis. Ein > Multimeter hast du? > Die Spannung erzeugst du nachher mittels Pulsweitenmodulation (PWM). Und ich hatte übersehen, dass dieser Schaltkontakt ja gar nicht über einen Stecker abgegriffen werden kann, der ist nur hinter der Buchse verschaltet. Außerdem braucht man einen speziellen Stecker, damit der überhaupt schaltet. Alles sehr unpraktisch. Ich habe die Spannung gemessen, sie bewegt sich zwischen 27,5V (schnell) und 28,3V (langsam). Dabei schwankt die Messung jeweils um etwa 0,1 Volt. (Gemessen als Gleichspannung, richtig? Bei Einstellung des Multimeters auf Wechselspannung kommen über 60 Volt raus.) Ich versuche nachher mal die Geschwindigkeitsmessung. Kann ich statt 10k auch 100k oder irgendetwas dazwischen als Widerstand nehmen? Habe leider nur noch einen einzigen 10k-Widerstand vorrätig ): Max G. schrieb: > du solltest aber zwischen Pin 3 und > Pin 2 eine Zenerdiode schalten, die den Arduino-Eingang vor den 26V > schützt. Wenn ich hier eine 4,7-Volt-Zenerdiode einsetze, wird dann nicht bei geschlossenem Reed (der Normalzustand) auch im Projektor die Spannung reduziert?
Max G. schrieb: > An Pin 5 des DIN-Steckers hast du 26V anliegen, an Pin 2 Masse. Wenn du > über einen 10kOhm-Widerstand Pin 5 mit Pin 3 verbindest, müsste Pin 3 > bei geschlossenem Schalter auf 0 gehen, ansonsten auf 26V. > Das kannst du am Arduino auswerten, du solltest aber zwischen Pin 3 und > Pin 2 eine Zenerdiode schalten, die den Arduino-Eingang vor den 26V > schützt. Das habe ich gerade getestet, dabei ist die Sicherung F2 durchgebrannt (2 Ampere). Hatte einen 27k-Widerstand zwischen Pin5 und Pin3 sowie eine 4,7V-Zenerdiode zwischen Pin3 und Pin2, sonst nichts. Ich war mir bei der Polung der Zenerdiode nicht ganz sicher, muss der Ring/Kathode an Pin 3? Kann eine Verpolung den Kurzschluss ausgelöst haben? Oder funkt der Generator (direkt am Motor) irgendwie dazwischen?
grox schrieb: > ich habe einen 8mm-Filmprojektor, den ich zur Digitalisierung von alten > Schmalfilmen verwenden will. Dazu muss der Projektor möglichst exakt mit > einer Geschwindigkeit von 16 2/3 frames per second (fps) laufen. Nein. Er muß exakt synchron zum Aufnahmegerät laufen (ggf. mit einem ganzzahligen Teilerfaktor). Das ist etwas völlig anderes. > später will ich die > Geschwindigkeit vielleicht auch noch automatisch regeln lassen oder > sogar mit dem Videosignal des Camcorders synchronisieren). Nö, nicht später. Das ist von vornherein der einzig zielführende Ansatz. > Im angehängten Schaltbild des Projektors sieht man: Im Projektor ist > bereits ein Reed-Kontakt verbaut, der bei jedem dritten Bild einmal kurz > öffnet. Nein der öffnet einmal pro echtem Bild. Der Faktor 3 kommt von der Flügelblende, die dieses eine Bild dreimal verdunkelt, um dem Auge eine höhere Framerate vorzugaukeln, als physisch vorhanden ist. > Vielleicht habt ihr Hinweise? Kauf' dir ein auch nur halbwegs hochwertiges digitales Fotogerät als Zielgerät, welches hinreichend schnell Einzelbilder aufnehmen kann (wenigstens in SD- oder VGA-Auflösung) und über einen externen Auslöser verfügt. Diesen Fernauslöser hängst du dann einfach über ein einstellbares Verzögerungsglied an das Reed-Relais des Projektors. Das Verzögerungsglied stellst du dann so ein, daß in den Aufnahmen keine Schatten der Flügelblende mehr zu erkennen sind, also das gesamte Nutzbild gleichmäßig ausgeleuchtet erscheint. Und schon bist du fertig. Und es ist sogar fast schon der optimale Aufbau für diese Aufgabe. Besser wird es nur noch (bei sonst gleichbleibendem Aufbau), wenn man die Leinwand durch einen "Repro-Schirm" ersetzt.
@ c-hater: Sicher, wenn ich optimale Ergebnisse haben will, hast Du viel richtiges gesagt. Ich will es aber nicht übertreiben, dann kann ich die Filme auch einem Digitalisierungsprofi übergeben. Ich will mit dem, was ich habe, soweit wie möglich kommen. Und vor allem will ich dabei Spaß am Lernen haben. c-hater schrieb: > Nein der öffnet einmal pro echtem Bild. Der Faktor 3 kommt von der > Flügelblende Der öffnet in meinem Projektor tatsächlich einmal alle drei Bilder bzw. alle 9 "Flügelschläge", das habe ich überprüft. c-hater schrieb: > Diesen Fernauslöser hängst du dann einfach über ein > einstellbares Verzögerungsglied an das Reed-Relais des Projektors. Genaus für diese Idee, ein externes Gerät an den Reed-Kontakt zu hängen, suche ich Hinweise. Wenn ich die Schaltung im Projektor nicht verändern will, ist das gar nicht so einfach. Jedenfalls für mich.
grox schrieb: >> Nein der öffnet einmal pro echtem Bild. Der Faktor 3 kommt von der >> Flügelblende > > Der öffnet in meinem Projektor tatsächlich einmal alle drei Bilder bzw. > alle 9 "Flügelschläge", das habe ich überprüft. Noch einmal überprüft: es stimmt beides nicht, er öffnet alle vier Bilder.
grox schrieb: > dabei ist die Sicherung F2 durchgebrannt Hatte doch tatsächlich die Belegung des Steckers verdreht, die Z-Diode hat also einen Kurzschluss verursacht. Wie blöd. Neuer Versuch mit folgendem Aufbau: 10k-Pullup-Widerstand zwischen Arduino-Pin und Arduino-5-Volt. Arduino-Pin über eine Diode (Ring Richtung Projektor) mit Projektor-Pin3 (Reed-Kontakt) verbunden. Arduino-Masse mit Projektor-Pin2 (Masse) verbunden. Das funktioniert soweit. Allerdings ist die darüber ausgelesene Geschwindigkeit erstens sehr schwankend (mind. +/- 10 FPS) und zweitens in der Regel zu hoch. Trotz Software-Debouncing (Werte von 10-100ms ausprobiert) im Arduino. Ich habe keine Ahnung, wie das zu Stande kommt. Irgendetwas ist da falsch, der Projektor läuft nämlich ruhiger, als die angezeigten Geschwindigkeitsschwankungen. Was könnte ich noch probieren?
grox schrieb: > Das funktioniert soweit. Allerdings ist die darüber ausgelesene > Geschwindigkeit erstens sehr schwankend (mind. +/- 10 FPS) und zweitens > in der Regel zu hoch. Trotz Software-Debouncing (Werte von 10-100ms > ausprobiert) im Arduino. > > Ich habe keine Ahnung, wie das zu Stande kommt. Irgendetwas ist da > falsch, der Projektor läuft nämlich ruhiger, als die angezeigten > Geschwindigkeitsschwankungen. Was könnte ich noch probieren? Soweit gelöst...ohne genau zu wissen, wo der Fehler liegt. Jedenfalls hat der Interrupt im Arduino zu oft zwischendurch ausgelöst, habe deshalb in der Interrupt-Funktion einfach noch einmal den Pin ausgelesen und ausgewertet (digitalRead), jetzt haut es hin. Vielen vielen Dank für die bisherige Unterstützung, ich mache mich bei Gelegenheit an die Steuerung der Motorgeschwindigkeit.
Vermutlich hat der Schalter geprellt, deine Lösung ist gefühlt ein bisschen ungewöhnlich, aber legitim. Du kannst noch10 nF (Wert aus dem Bauch heraus) zwischen Pins 3 und 2 hängen, wenn es noch weiter Probleme gibt. Wen dein Stecker den Kontakt nicht schaltet, ist das nicht tragisch.Mein Vorschlag von oben müsste trotzdem funktionieren. Viel Erfolg, du schaffst das! Max
Am Ende sieht es so einfach aus :-) Die Schaltung funktioniert tatsächlich, wenn auch immer mal Schwankungen auftreten. Irgendwie scheint der Arduino auch noch gestört zu werden, auf dem LCD erscheinen hinter meiner Ausgabe merkwürdige Zeichen. Was mir nicht klar ist, vielleicht hast Du/habt ihr noch Hinweise: wie schütze ich den Arduino besser? Ich habe vor allem Bedenken, dass die Grounds nicht immer auf dem gleichen Niveau sind oder dass irgendwo Spannung anliegt, die nicht sein darf. Weil dieser ominöse Generator im Projektor ja auch noch Spannung erzeugt. Und weil der Transformator beim Ausschalten vermutlich auch umgedrehte Spannung erzeugt. Oder nicht? D1 ist zum Beispiel einfach eine "Angstdiode", keine Ahnung ob die überhaupt sinnvoll ist. Kann man zwischen die Grounds von Arduino und Projektor auch noch eine "Angstdiode" setzen? Der Vollständigkeit halber noch mein Arduino-Code:
1 | /* |
2 | * Control speed of projector MEOS DUO |
3 | |
4 | |
5 | * LCD Setup: |
6 | * LCD RS pin to digital pin 9 |
7 | * LCD Enable pin to digital pin 8 |
8 | * LCD D4 pin to digital pin 7 |
9 | * LCD D5 pin to digital pin 6 |
10 | * LCD D6 pin to digital pin 5 |
11 | * LCD D7 pin to digital pin 4 |
12 | * LCD R/W pin to ground |
13 | * 10K resistor: |
14 | * - ends to +5V and ground |
15 | * - wiper to LCD VO pin (LCD pin 3) |
16 | |
17 | * Pin Setup: |
18 | * Reed (projector) to pin 2 |
19 | * Mosfet gate to pin 3 |
20 | * |
21 | */ |
22 | |
23 | #include <LiquidCrystal.h> |
24 | #include <PWM.h> |
25 | |
26 | //Global variables and constants |
27 | LiquidCrystal lcd(9, 8, 7, 6, 5, 4); |
28 | |
29 | const signed long int pwm_frequency = 10000; //frequency of pwm (in Hz) |
30 | const int pin_pmw = 3; |
31 | const int pin_touch = 2; |
32 | |
33 | // 16 2/3 fps = 240mspt |
34 | unsigned long mspt_target = 240ul; //Target Milliseconds per touch |
35 | unsigned long mspt = 0ul; //Current milliseconds per touch |
36 | int state_touch = HIGH; //Is reed contact in touch? |
37 | int state_newdata = LOW; //Is there a new measure to adjust speed to? |
38 | |
39 | void setup() { |
40 | //Init LCD |
41 | lcd.begin(16, 2); |
42 | lcd.setCursor(0, 0); |
43 | lcd.print("MsPT"); |
44 | lcd.setCursor(8, 0); |
45 | lcd.print("FPS"); |
46 | |
47 | //Input |
48 | pinMode(pin_touch, INPUT); |
49 | |
50 | //Initialize pwm timers (except for 0, to save time keeping functions) |
51 | InitTimersSafe(); |
52 | SetPinFrequencySafe(pin_pmw, pwm_frequency); |
53 | |
54 | //Attach touch interrupt |
55 | attachInterrupt(0,count,CHANGE); |
56 | } |
57 | |
58 | void loop() { |
59 | static unsigned long time_current; |
60 | static unsigned long time_lcd; |
61 | float fps = 0.0; |
62 | static char buff_lcd[8]; |
63 | static int value_pwm = 255; |
64 | static int diff_pwm = 0; |
65 | |
66 | //reference time |
67 | time_current = millis(); |
68 | |
69 | //adjust speed |
70 | if (state_newdata & (mspt != mspt_target)) { |
71 | |
72 | //too fast..slow down..increase pwm |
73 | //too slow..accelerate..decrease pwm |
74 | |
75 | diff_pwm = (mspt_target - mspt); |
76 | if (abs(diff_pwm) < 10) diff_pwm = diff_pwm / abs(diff_pwm); |
77 | value_pwm = value_pwm + diff_pwm; |
78 | |
79 | value_pwm = constrain(value_pwm,0,255); |
80 | |
81 | pwmWrite(pin_pmw,value_pwm); |
82 | state_newdata = LOW; |
83 | } |
84 | |
85 | //lcd |
86 | if ((time_current - time_lcd) > 1000) { |
87 | |
88 | //Calculate fps |
89 | if (mspt == 0) fps = 0.0f; |
90 | else fps = (4ul * 1000ul) / (float)mspt; |
91 | |
92 | //Display values |
93 | lcd.setCursor(0, 1); |
94 | sprintf(buff_lcd,"%-5d", (int)mspt); |
95 | lcd.print(buff_lcd); |
96 | |
97 | lcd.setCursor(8, 1); |
98 | dtostrf(fps,5,2,buff_lcd); |
99 | lcd.print(buff_lcd); |
100 | |
101 | time_lcd = time_current; |
102 | } |
103 | } |
104 | |
105 | /* |
106 | Interrupt function for touches of reed contact |
107 | */ |
108 | void count() { |
109 | static unsigned long time_current; |
110 | static unsigned long time_touch = 0ul; |
111 | static unsigned long time_debounce = 0ul; |
112 | |
113 | time_current= millis(); |
114 | |
115 | if (digitalRead(pin_touch) != state_touch) { |
116 | if ((time_current - time_debounce) > 30) { |
117 | state_touch = !state_touch; |
118 | |
119 | if (state_touch == HIGH) { |
120 | if (time_touch > 0) { |
121 | mspt = time_current - time_touch; |
122 | state_newdata = HIGH; |
123 | } |
124 | time_touch = time_current; |
125 | } |
126 | time_debounce = time_current; |
127 | } |
128 | } |
129 | } |
grox schrieb: > Kann man zwischen die Grounds von Arduino und Projektor auch noch eine > "Angstdiode" setzen? Nein, damit verschiebst du die Potentiale und riskierst das Gegenteil von dem, was du eigentlich bezwecken wolltest. Besser ist es, einfach vernünftige, stabile Anschlussleitungen zu nehmen. Sorge vor allem dafür, das der Arduino gut abgeblockt wird (mit einem sauberen Netzteil und evtl. zusätzlichem Abblockkondensator an der Vcc des Boards. grox schrieb: > Die Schaltung funktioniert tatsächlich, wenn auch immer mal Schwankungen > auftreten. Du bist jetzt soweit, das du dir die Implementation eines PID Reglers überlegen kannst, der als Sollwert den V-Impuls der Kamera bekommt und als Ist das mit 3 multiplizierte Reed-Signal des Projektors. Der Reglerausgang steuert dann deine MOSFet Routine an. Du wirst mit den P,I und D Faktoren ein wenig rumexperimentieren müssen, aber dann den Projektor stabil und phasensynchron regeln können.
Sehr hilfreiche Hinweise, bin dabei sie umzusetzen!
Matthias Sch. schrieb: > Du bist jetzt soweit, das du dir die Implementation eines PID Reglers > überlegen kannst PID Regler habe ich nun, siehe unten. Fehlt nur noch die Synchronisation mit der Kamera, habe mir dafür einen LM1881N bestellt. Allerdings bezweifle ich, dass das mit dem Projektor gut funktioniert, der läuft so unruhig; außerdem misst der Reed-Kontakt nur alle vier Bilder, ich müsste wohl eine extra Lichtschranke einbauen. Der Arduino hängt an einem Batteriepack und ich habe einen 100nf-Keramik-Kondensator vor die (vom Arduino abgezweigte) Stromversorgung des LCD gehängt, trotzdem kommen merkwürdige Zeichen. Sind wohl die dünnen Signalleitungen, das ist ja alles nur auf ein Breadboard gesteckt. Der R4-Widerstand wird im Betrieb ziemlich warm, ist so etwas eigentlich normal? Auch ist zwischenzeitig die Sicherung im Projektor mal wieder durchgebrannt, das PWM-Geflimmer scheint den Motor zu beanspruchen. Mit der bisherigen Lösung bin ich aber schon ganz zufrieden, den Rest erledigt AviSynth mit srestore ganz passabel.
1 | /* |
2 | * Control speed of projector MEOS DUO |
3 | |
4 | |
5 | * LCD Setup: |
6 | * LCD RS pin to digital pin 9 |
7 | * LCD Enable pin to digital pin 8 |
8 | * LCD D4 pin to digital pin 7 |
9 | * LCD D5 pin to digital pin 6 |
10 | * LCD D6 pin to digital pin 5 |
11 | * LCD D7 pin to digital pin 4 |
12 | * LCD R/W pin to ground |
13 | * 10K resistor: |
14 | * - ends to +5V and ground |
15 | * - wiper to LCD VO pin (LCD pin 3) |
16 | |
17 | * Pin Setup: |
18 | * Reed (projector) to pin 2 |
19 | * Mosfet gate to pin 3 |
20 | * |
21 | */ |
22 | |
23 | #include <LiquidCrystal.h> |
24 | #include <PWM.h> |
25 | #include <EEPROM.h> |
26 | |
27 | //Global variables and constants |
28 | LiquidCrystal lcd(9, 8, 7, 6, 5, 4); |
29 | |
30 | const long pwm_frequency = 10000; //frequency of pwm (in Hz) |
31 | const int pin_pwm = 3; |
32 | const int pin_touch = 2; |
33 | |
34 | long mspt = 0l; //Milliseconds per touch |
35 | int state_touch = HIGH; |
36 | int state_newdata = LOW; |
37 | long value_pwm = 0L; |
38 | |
39 | void setup() { |
40 | //Init LCD |
41 | lcd.begin(16, 2); |
42 | lcd.setCursor(0, 0); |
43 | lcd.print("MsPT"); |
44 | lcd.setCursor(5, 0); |
45 | lcd.print("FPS"); |
46 | |
47 | value_pwm = (long)EEPROM.read(0); |
48 | |
49 | //Input and output |
50 | pinMode(pin_touch, INPUT); |
51 | |
52 | //Initialize pwm timers (except for 0, to save time keeping functions) |
53 | InitTimersSafe(); |
54 | bool success = SetPinFrequencySafe(pin_pwm, pwm_frequency); |
55 | //if(success) digitalWrite(pin_led, HIGH); |
56 | |
57 | //Attach touch interrupt |
58 | attachInterrupt(0,count,CHANGE); |
59 | } |
60 | |
61 | void loop() { |
62 | static long time_current; |
63 | static long time_eeprom = millis(); |
64 | static long time_lcd = 0L; |
65 | static long time_adjust = 0L; |
66 | float fps = 0.0f; |
67 | static char buff_lcd[8]; |
68 | |
69 | |
70 | //reference time |
71 | time_current = millis(); |
72 | |
73 | //adjust speed |
74 | if (state_newdata) { |
75 | //too fast..slow down..increase pwm |
76 | //too slow..accelerate..decrease pwm |
77 | value_pwm = value_pwm + calculate_pid(mspt); |
78 | value_pwm = constrain(value_pwm,0L,255L); |
79 | pwmWrite(pin_pwm,value_pwm); |
80 | state_newdata = LOW; |
81 | } |
82 | |
83 | //lcd |
84 | if ((time_current - time_lcd) > 1000L) { |
85 | |
86 | //calculate fps |
87 | if (mspt == 0L) fps = 0.0f; |
88 | else fps = (4L * 1000L) / (float)mspt; |
89 | |
90 | //Display values |
91 | lcd.setCursor(0, 1); |
92 | sprintf(buff_lcd,"%-5d", (int)mspt); |
93 | lcd.print(buff_lcd); |
94 | |
95 | lcd.setCursor(5, 1); |
96 | dtostrf(fps,5,2,buff_lcd); |
97 | lcd.print(buff_lcd); |
98 | |
99 | time_lcd = time_current; |
100 | } |
101 | |
102 | //Save current pwm to eeprom every 30 seconds for next startup |
103 | if ((time_current - time_eeprom) > 30000L) { |
104 | EEPROM.write(0,(byte)value_pwm); |
105 | time_eeprom = time_current; |
106 | } |
107 | } |
108 | |
109 | /* |
110 | * PID regulator |
111 | * |
112 | * Todo: pid is called in irregular intervals, |
113 | * integration and differentiation should |
114 | * be relative to time of last calls |
115 | */ |
116 | |
117 | long calculate_pid(long value_in) { |
118 | const float param_p = 1.5f; |
119 | const float param_i = 0.1f; |
120 | const float param_d = 0.1f; |
121 | const long output_min = -200L; |
122 | const long output_max = +200L; |
123 | |
124 | //Target Milliseconds per touch -> 16 2/3 fps = 240mspt |
125 | const long value_target = 240L; |
126 | |
127 | static long value_error = 0L; |
128 | static long value_out = 0L; |
129 | static long value_lastin = 0L; |
130 | |
131 | static float value_pterm = 0.0f; |
132 | static float value_iterm = 0.0f; |
133 | static float value_dterm = 0.0f; |
134 | |
135 | //Proportional term |
136 | value_error = value_target - value_in; |
137 | value_pterm = param_p * value_error; |
138 | |
139 | //Integrate with windup limit |
140 | value_iterm += param_i * value_error; |
141 | value_iterm = constrain(value_iterm,(float)output_min,(float)output_max); |
142 | |
143 | //Derivative on Measurement, not Error |
144 | value_dterm = -param_d * (value_in - value_lastin); |
145 | value_lastin = value_in; |
146 | |
147 | value_out = round(value_pterm + value_iterm + value_dterm); |
148 | return constrain(value_out,output_min,output_max); |
149 | } |
150 | |
151 | /* |
152 | Interrupt function for touches of reed contact |
153 | */ |
154 | void count() { |
155 | static long time_current; |
156 | static long time_touch = 0L; |
157 | static long time_debounce = 0L; |
158 | |
159 | time_current= millis(); |
160 | |
161 | if (digitalRead(pin_touch) != state_touch) { |
162 | if ((time_current - time_debounce) > 30) { |
163 | state_touch = !state_touch; |
164 | |
165 | if (state_touch == HIGH) { |
166 | if (time_touch > 0) { |
167 | //mspt = runningAverage(time_current - time_touch); |
168 | mspt = time_current - time_touch; |
169 | state_newdata = HIGH; |
170 | } |
171 | time_touch = time_current; |
172 | } |
173 | time_debounce = time_current; |
174 | } |
175 | } |
176 | } |
grox schrieb: > Der R4-Widerstand wird im Betrieb ziemlich warm, ist so etwas eigentlich > normal? Der bildet ja im Betrieb zusammen mit dem Projektorinternen R1 einen Spannungsteiler für ca 26V(!) und das an zusammen 300 Ohm. Da fliessen also im geschlossenen Zustand des MOSTFet mal eben um die 100mA und das erwärmt den Widerstand ganz schön (P=U*I, wobei U=13V, I~0,1A, also P~1,3Watt). Ich würde mit dem PWM Signal eher auf die Basis von V1 gehen (den KF508), natürlich über einen Basisvorwiderstand. Da reicht dann ein kleiner Steuerstrom. Polarität ist hier high=Motor läuft langsamer, Low=Motor läuft schneller, aber das ist an der Drain deines MOSFet ja genauso. PWM ist für so einen Motor auch oft nicht das richtige, es kann besser sein, das du die PWM schon auf der MC Platine filterst und nur noch ein Analogsignal auf die Basis von V1 schiebst.
:
Bearbeitet durch User
Was soll der R4 in der Schaltung auch anderes machen als zu heizen? Ich sehe da keine andere Funktion, weg damit. Widerstände wären eher vor den Prozessoreingängen von Nutzen, um Stör-Spikes zu dämpfen, dann kann die D1 da z.B. auch weg.
batman schrieb: > Was soll der R4 in der Schaltung auch anderes machen als zu heizen? Ich > sehe da keine andere Funktion, weg damit. Wenn ich R4 entferne: erhöht sich dann nicht der Strom im Projektor enorm, sobald der Mosfet schließt? Habe soweit verstanden, dass ich eine kleine Heizung gebaut habe, vielen Dank für die Erläuterungen. Der Widerstand kann 1W ab, läuft also möglicherweise am Limit. Matthias Sch. schrieb: > Ich würde mit dem PWM Signal eher auf die Basis von V1 gehen (den > KF508), natürlich über einen Basisvorwiderstand. Da komme ich leider nicht über die Buchse ran, die eingezeichneten Kontakte 6 und 7 sind in der Buchse verborgene Schaltkontakte.
Matthias Sch. schrieb: > PWM ist für so einen Motor auch oft nicht das richtige, es kann > besser sein, das du die PWM schon auf der MC Platine filterst und nur > noch ein Analogsignal auf die Basis von V1 schiebst. Kann ich dazu einfach ein Elko zwischen Mosfet-Drain und Masse schalten? Habe mich vorhin über Tiefpass-Filter belesen. Aber noch nicht so ganz durchdrungen, wie man die dimensioniert und anschließt.
grox schrieb: > Kann ich dazu einfach ein Elko zwischen Mosfet-Drain und Masse schalten? Es ist vllt. gar keine dumme Idee, die Stufe um V1 extern nachzubauen, also richtig mit einem NPN, der den Strom verträgt. Ich kenne mich mit den Russen nicht aus, aber ein z.B. BC639 oder BC337 kann die 100mA leicht ohne Rotbäckchen. Den steuerst du dann über den Tiefpass an. Der ist leichter linear zu bekommen als der MOSFet und die Schaltung im Projektor zeigt ja, das es so auch gedacht ist. Ein Tiefpass am Ausgang des jetzigen MOSFet kannst du mal probieren, aber der muss schon recht kräftig dimensioniert sein, weil dir ja die Verstärkung von V1 fehlt. Mit dem jetzigen 150R in Reihe können da schnell mal ein paar µF zusammenkommen, um das glatter zu kriegen. Je höher deine PWM Frequenz, desto kleiner kann der Elko sein. grox schrieb: > Aber noch nicht so ganz > durchdrungen, wie man die dimensioniert und anschließt. Du möchtest die PWM Frequenz am besten völlig unterdrücken und trotzdem die Regelung schnell lassen. Also wählst du eine hohe PWM Frequenz und schaust dann am besten mit dem Oszi, wie gross der C sein muss.
Matthias Sch. schrieb: > Ein Tiefpass am Ausgang des jetzigen MOSFet kannst du mal probieren, > aber der muss schon recht kräftig dimensioniert sein, weil dir ja die > Verstärkung von V1 fehlt. Habe meine Daten mal in folgenden Rechner eingegeben: http://www.electronicdeveloper.de/FilterPassivTiefpassRCPWM1.aspx Mit 10kHz PWM, 150 Ohm und 10uF komme ich auf ca.4mV Ripple und ca. 23ms Verzögerung, wenn ich das richtig interpretiere. Scheint mir im ersten Moment gut auszusehen. Dann kommen bei mir einige Fragezeichen auf: - Kann ich da einen Elko (mit Polung) nehmen, oder muss es ein Keramikkondensator sein? Gibt es überhaupt Keramikkondensatoren mit 10uF? In meiner Bastelkiste finde ich so einen nicht. - Alternativ könnte ich die PWM-Frequenz erhöhen, geht im Fast PW-Mode wohl bis ca. 60kHz hoch. Welche Nebenwirkungen hat das? - Alternativ könnte ich den Widerstand erhöhen. Dann zweige ich aber weniger Strom ab, wodurch der "Regelbereich" geringer wird. Müsste ich das ausprobieren oder kann man irgendwie verhersagen, bis zu welcher Größe des Widerstands noch eine brauchbare Regelung hinzubekommen ist? Ich bin euch allen sehr dankbar, dass ihr mir so geduldig beim Lernen helft!!! Matthias Sch. schrieb: > Es ist vllt. gar keine dumme Idee, die Stufe um V1 extern nachzubauen, > also richtig mit einem NPN, der den Strom verträgt. Gute Idee. Bin noch dabei, das zu durchdenken. Matthias Sch. schrieb: > Du möchtest die PWM Frequenz am besten völlig unterdrücken und trotzdem > die Regelung schnell lassen. Also wählst du eine hohe PWM Frequenz und > schaust dann am besten mit dem Oszi, wie gross der C sein muss. Habe leider kein Oszilloskop, hätte natürlich gern eines. Muss ich aber erstmal sparen.
grox schrieb: > Kann ich da einen Elko (mit Polung) nehmen, oder muss es ein > Keramikkondensator sein? Nimm ruhig einen Elko, negative Steuerspannung kommt ja nicht vor - du musst ihn also nur richtig polen (Minus an Masse, Plus an den Punkt nach dem 150 Ohm). grox schrieb: > Gibt es überhaupt Keramikkondensatoren mit > 10uF? Gibts schon, aber ist hier absolut nicht nötig. Haben die wenigsten in der Bastelkiste. grox schrieb: > Alternativ könnte ich die PWM-Frequenz erhöhen, geht im Fast PW-Mode > wohl bis ca. 60kHz hoch. Welche Nebenwirkungen hat das? Nee, nee, 10kHz sind schon ok. Je höher die Frequenz angesetzt wird, umso höher sind die Umschaltverluste deines MOSFet, das wäre bei 60kHz noch nicht beträchtlich, aber spürbar, der MOSFet wird ein wenig wärmer. grox schrieb: > Muss ich aber > erstmal sparen. Tu das. Ein Oszi ist mit das hilfreichste Messgerät, was man als Elektronikbegeisterter haben kann.
Die Störungen auf dem LCD sind weg, nachdem ich den Eingang anders aufgebaut habe: ein Widerstand und eine Z-Diode sollen für Schutz vor zu hoher Spannung (die theoretisch gar nicht auftreten kann, weil es ein Masse-Input ist) und gleichzeitig für eine geringere Empfindlichkeit des Input Pins sorgen. Ein Elko soll außerdem das PWM-Signal glätten. Wobei ich nur einen mit 220uF gefunden habe, der auch die Spannung aushält, eigentlich wollte ich nach etwas Rumrechnen mit dem oben verlinkten Tool einen 100uF-Elko einsetzen. Ganz klar ist mir nicht, ob das wirklich ein Tiefpass-Filter ist. Normalerweise würde ja dann der Elko auf der anderen Seite von R4 eingehängt werden. Was aber hier wohl beim Schließen des Mosfets zu einem Kurzschluss des Elkos führen würde. Oder entsteht der Tiefpassfilter in diesem Fall durch den projektorinternen Widerstand + Kondensator und R4 ist lediglich als Verbraucher anzusehen? Oder habe ich einen Knoten im Kopf? Die Schaltung ist im Anhang. Ich glaube genauer bekomme ich die Steuerung nicht hin, auch wenn Geschwindigkeitsschwankungen auftreten (ca. +/-1ms pro Bild). Diese Schwankungen treten aber auch auf, wenn ich die Steuerung weglasse, das liegt wohl an der projektorinternen Hardware.
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.