Zum Inhalt springen

Funktionsweise des Tonkopplers beim Meos Duo


Empfohlene Beiträge

Geschrieben

Liebes Forum,

 

ich lerne gerade ganz viel über Schmalfilme und Filmformate, weil ich ein paar Normal 8-Filme mittels Meopta Meos Duo und MiniDV-Camcorder digitalisieren will. Ich weiß, dass dabei keine Wunder zu erwarten sind, die ersten Ergebnisse sind aber schon ganz in Ordnung (mit AviSynth nachbearbeitet).

 

Eine Herausforderung ist die Synchronisierung von Camcorder und Projektor, mein Ziel ist es momentan den Projektor einigermaßen stabil auf 16 2/3 fps laufen zu lassen. Der Projektor hat einen Drehknopf (Potentiometer), über den man die Geschwindikeit zwischen 16 und 24 fps regeln kann. Das geht, aber genau treffen kann ich die 16 2/3 fps natürlich nur mit Glück.

 

Der Projektor hat aber einen Anschluss für einen Tonkoppler. Wenn ich das richtig verstehe, kann ein Tonkoppler darüber die Geschwindigkeit des Projektors steuern. Nur wie? Weiß hier jemand, was da genau passiert?

 

Ich habe bei anderer Gelegenheit schon mal Schaltungen mit Microcontrollern gebaut, könnte man darüber nicht exakt auf 16 2/3 regeln? Ein Schaltbild meines Projektors habe ich gefunden: http://www.super8-projektor.de/module/technik/download.php?id=77

 

Nur bin ich mir nicht sicher, was ich daraus für meine Idee lernen kann. Über Hinweise aller Art würde ich mich freuen.

 

Gruß

grox

Geschrieben

Die spannende Frage für Filmsammler ist hier: hast du denn Zweiband synchronisierte Filme mit dem Projektor übernommen? Sowas ist nicht sehr oft zu finden, weil dieser Vertoungsaufwand wirklich abschreckend für viele Filmer gewesen ist.

 

Mir sind in vielen Sammeljahren nur zwei Zweiband 8mm Filme untergekommen. Einer für den Siemens 800 und einer für den Pentax S 81.

Geschrieben

Der Meos duo hat einen eingebauten Reedkontakt

 

Dank Reed-Kontakt müsste ich ja die aktuelle Geschwindigkeit auslesen können. Mir ist nur noch nicht klar, wie ich einen Mikrocontroller mit dem Projektor verschalte, ohne am Projektor etwas zu verändern, also über die Tonkopplerbuchse.

 

hast du denn Zweiband synchronisierte Filme mit dem Projektor übernommen?

 

In meiner Kiste ist kein Tonband, nur eine leere Tonbandverpackung. Ich muss mal nachforschen, wo das Tonband aus der Verpackung hin ist. Ich vermute es gab eines zum Super 8-Rumpelstilzchen-Film, da wird nämlich ganz schön viel gesprochen.

Geschrieben

Soweit ich weiss hat der Tonkoppler die Pilottöne auf dem Tonband mit dem Impuls des Reedkontaktes verglichen. Gab es eine Differenz, wurde die Projektorgeschwindigkeit angepasst. Zu diesem Zweck wurde die Motorsteuerung durch den Koppler durchgeschleift. Ein Schalter in der Buchse überbrückte E/A für normalen Betrieb. Hier im Schaltbild scheint es Pin 6 und 7 zu sein. Kenne mich leider mit Meo aber nicht weiter aus.

Geschrieben (bearbeitet)

Pin 6 und 7 sind direkt in der Buchse untergebracht, mit einem entsprechenden Stecker würde die Steuerung unterbrochen werden. Ich dachte auch erst, dass der Tonkoppler sich hier sozusagen in die Leitung setzt (das meinst Du mit durchschleifen, oder?).. Diese Pins sind aber nicht von außen über einen Stecker zugänglich, es muss also irgendwie anders funktioniert haben.

 

Weiß vielleicht jemand, wozu direkt am Motor noch ein Generator untergebracht ist?

Bearbeitet von grox (Änderungen anzeigen)
Geschrieben

Anscheinend wird der Motorstrom vom Koppler unter Umgehung der Projektorelektronik geregelt. Evtl. Pin 2 und 4 ???

Soweit ich mich erinnere, wurde bei manchen Westprojektoren der gesammte Motorstrom durch den Koppler geleitet.

Geschrieben

Über Pin 4 soll vermutlich der Steuerstrom für den Motortreiber (V2) geregelt werden. Je mehr Steuerstrom nach Masse abgeleitet wird, desto langsamer läuft der Projektor.

Da kannst du einfach einen PWM-Ausgang des Controllers, über einen FET als Treiber, dranhängen. Motoren lassen sich wunderbar mit PWM regeln. Der Controller bekommt noch einen Uhrenquarz für die genaue Taktsteuerung und das wars auch schon so ziemlich. Er vergleicht dann einfach den reinkommenden Pulstakt mit dem Quarztakt und steuert den Fehler aus.

Ob man so, ohne Synchronisation mit dem Aufnahmegerät ein flackerfreies Bild hinbekommt, ist allerdings fraglich. Ich würde zumindest die Sektorenblende rausnehmen.

Geschrieben

Das macht Sinn, ich werde es ausprobieren, sofern ich eine brauchbare Geschwindigkeitsmessung hinbekommen.

 

Ich habe mittlerweile eine Schaltung gebaut, um die Geschwindigkeit auszulesen (mit Hinweisen aus einem Elektronikforum: http://www.mikrocontroller.net/topic/343337 ). Das Problem: es kommen äußerst instabile Werte raus, bislang unbrauchbar.

 

Ob man so, ohne Synchronisation mit dem Aufnahmegerät ein flackerfreies Bild hinbekommt, ist allerdings fraglich. Ich würde zumindest die Sektorenblende rausnehmen.

 

Ich will es einfach mal ausprobieren. Und vielleicht synchronisiere ich dann - wenn ich nicht schon frustriert bin und mein Elektronikverständnis ausreicht - auch noch mit dem Camcorder-Signal.

 

Die Sektorenblende kann ich leider nicht rausnehmen, weil daran die Mechanik für den Filmtransport hängt, das lässt sich nicht trennen. Das Bild ist aber auch so ganz in Ordnung. Ich hätte am liebsten ordentlich getrennte Halbbilder, damit ich mittels field matching progressive Bilder bekomme, siehe http://avisynth.org.ru/docs/english/externalfilters/tivtc_tfm.htm

Geschrieben

Du solltest die Geschwindigkeit via Interrupt (ISR) auslesen. Das ist wesentlich exakter. Desweiteren beachte, dass Du die Messwerte im Falle von Divisionen auch als float castest :)

Ich messe die Umdrehungen per Reflektorlichtschranke an der Motorwelle (also optisch), im Prinzip ist das aber das gleiche.

 

Hier mal ein bisschen Code, der zumindest messtechnisch gut funktionierte als ich ihn zuletzt laufen hatte... das ist nix fertiges, aber you get the idea und Debug-Output über die serielle. Ignoriere die rmp3.calls, das funktionierte so nicht richtig :)

 

// Vrtonr 0.4

#include <RogueSD.h>
#include <RogueMP3.h>
#include <SoftwareSerial.h>

// Init RogueMP3
SoftwareSerial rmp3_serial(6, 7);
RogueMP3 rmp3(rmp3_serial);
RogueSD filecommands(rmp3_serial);
#define SONG "/test3.mp3"




// Konfiguration Eye
byte sollfps = 18;
#define DISCSEGS 1          // Wieviele Segmente hat die Scheibe? Bzw. Motorwellenfaktor


// Pin Deklarationen
const int ledPin = 13;       // the pin that the LED is attached to
int eye1Int = 0; // Pin 2
// const int emitterPin = 5;       // Hier kann man noch Energie sparen

// Modes!
#define IDLE  1
#define STOP  2
#define RUN  3
#define PLAY 4

// Variablen-Deklarationen fürs Auge

unsigned long rtStartMillis = 0;
unsigned long rtMillis = 0;
unsigned long filmStartMillis = 0;
unsigned long currentMillis = 0;
byte currentRtFrameCounter = 0;
float speedOffset = 0;
int lastSpeed = 100;
int newSpeed = 100;
boolean readLastImpMillis = false;
boolean run_init = true;
boolean idle_init = true;


// Variablen für die ISR
volatile long totalFrameCounter = 0;
volatile byte rtFrameCounter = 0;
volatile unsigned long lastImpMillis = 0;
volatile byte mode = IDLE;


// Los gehts: Setup

void setup() {
pinMode(eye1Int, INPUT);     
digitalWrite(eye1Int, LOW);

//  pinMode(emitterPin, OUTPUT);     
//  digitalWrite(emitterPin, HIGH);
pinMode(ledPin, OUTPUT);     
Serial.begin(9600);
rmp3_serial.begin(9600);
Serial.println("rMP3 inited");

rmp3.sync();
rmp3.stop();
rmp3.setvolume(10);
rmp3.setspeed (newSpeed);
rmp3.playfile(SONG);
rmp3.playpause(); // Musik pausieren


//  char status = 'S';
uint8_t i;
//  int16_t newtime;

//  volume = rmp3.getvolume();  // this only gets the right volume


// Attach the interrupt for our eye
attachInterrupt(eye1Int, count, RISING);
}

void loop() {

switch(mode) {
  case IDLE:
    idle();
    break;
  case STOP:
    stop();
    break;
  case RUN:
    run();
    break;
}
}  

// ********************************************************************************************************

void run() {
if(run_init) {
  rmp3.playpause(); // Musik starten
  run_init = false;
  Serial.println(" PROJECTOR RUN : AUDIO START ");
}

// Prüfen, ob der Projektor läuft (wann war der letzte Interrupt?)
// TODO: Brauche ich den Semaphor?
if (readLastImpMillis) {
   lastImpMillis = millis();
   readLastImpMillis = false;
}
currentMillis = millis();
currentRtFrameCounter = rtFrameCounter;

//  if((rtFrameCounter) / DISCSEGS >= sollfps) {
if(currentRtFrameCounter >= sollfps) {
  rtMillis = currentMillis - rtStartMillis;  // Wieviele ms hat es gedauert?

  Serial.print(currentRtFrameCounter);
//    Serial.print((rtFrameCounter) / DISCSEGS);
  Serial.print(" f in ");
  Serial.print(rtMillis);
  Serial.print(" ms, so ");

  speedOffset = (float) ((float) rtMillis - 1000)/10;
  newSpeed = 100 + (int) speedOffset;

  Serial.print(speedOffset);
  Serial.print ("% off. FC: ");
  Serial.print(totalFrameCounter);

  Serial.print (", Film: ");

  Serial.print((totalFrameCounter/18)/60,DEC);Serial.print(':');
  if((totalFrameCounter/18)%60 < 10) Serial.print('0');
  Serial.print((totalFrameCounter/18)%60,DEC);

  Serial.print (totalFrameCounter/18);

  Serial.print (", Audio: ");
  playbackinfo pinfo;
  pinfo = rmp3.getplaybackinfo();
  Serial.print(pinfo.position/60,DEC);Serial.print(':');
  if(pinfo.position%60 < 10) Serial.print('0');
  Serial.print(pinfo.position%60,DEC);
  Serial.print(" Diff: "); Serial.print(pinfo.position-(totalFrameCounter/18));
  Serial.print(" New Speed: "); Serial.println(newSpeed);

  rtStartMillis = currentMillis;    // ms-Zähler zurücksetzen    
  rtFrameCounter = 0; // Umdrehungszähler zurücksetzen

  if (newSpeed != lastSpeed) {
    rmp3.setspeed(newSpeed);
    // delay(50);
    lastSpeed = newSpeed;
  }

} 
if (currentMillis - lastImpMillis > 250) {
  mode = STOP;
}
}


void idle() {
//  Serial.println(rtFrameCounter);
rtStartMillis = millis(); // Es könnte ja gleich wieder losgehen... 

if(idle_init) {
  Serial.print(" PAUSE AT ");
  playbackinfo pinfo;
  pinfo = rmp3.getplaybackinfo();
  Serial.print(pinfo.position/60,DEC);Serial.print(':');
  if(pinfo.position%60 < 10) Serial.print('0');
  Serial.println(pinfo.position%60,DEC);
  idle_init = false;
}
}  


void stop() {
Serial.println(" PROJECTOR STOP: AUDIO STOP ");
rtFrameCounter = 0; // Roundtrip Umdrehungszähler zurücksetzen
rmp3.playpause(); // Musik anhalten
run_init = true;
idle_init = true;
mode = IDLE;
}  


// Wieviel Zeit ist seit Projektorstart vergangen?
// An welcher Filmbildnummer sind wir jetzt?
// An welcher Filmbildnummer müssten wir jetzt sein?
// Wie ist die Differenz? In Bildern und in Sekunden?


// ISR
void count() {
volatile static unsigned long last_interrupt_time = 0;
volatile unsigned long interrupt_time = millis();
// Cheeeeap debouncing
if (interrupt_time - last_interrupt_time > 30) {
  totalFrameCounter++;
  rtFrameCounter++;
  readLastImpMillis = true;
  mode = RUN;
  last_interrupt_time = interrupt_time;
}

}

 

 

Geschrieben (bearbeitet)

Wow, danke!!! Interrupt hatte ich schon drin, der hat allerdings zu oft ausgelöst, ich weiß nicht warum. Mit einem zusätzlichen digitalRead() in der Interrupt-Funktion klappt aber alles.

 

Ich habe jetzt folgenden Code, mit dem alles richtig funktioniert:

 

/*
* LCD RS pin to digital pin 12
* LCD Enable pin to digital pin 11
* LCD D4 pin to digital pin 7
* LCD D5 pin to digital pin 6
* LCD D6 pin to digital pin 5
* LCD D7 pin to digital pin 4
* LCD R/W pin to ground

* 10K resistor:
* ends to +5V and ground
* wiper to LCD VO pin (pin 3)

* reed (projector) to pin 2
* status led to pin 1
*/

// include the library code:
#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 7, 6, 5, 4);
const int pin_touch = 2;
const int pin_led = 1;

unsigned long mspt = 0ul; //Milliseconds per touch
int state_touch = HIGH;


void setup() {
 lcd.begin(16, 2);
 lcd.setCursor(0, 0);
 lcd.print("MsPT");
 lcd.setCursor(8, 0);
 lcd.print("FPS");

 pinMode(pin_led, OUTPUT);
 pinMode(pin_touch, INPUT);
 attachInterrupt(0,count,CHANGE);
}

void loop() {
 static unsigned long time_current;
 static unsigned long time_lcd = 0ul;
 float fps = 0.0;
 static char buff_lcd[8];
 time_current = millis();

 //state led
 digitalWrite(pin_led,!state_touch);

 //lcd
 if ((time_current - time_lcd) > 1000) {
   //calculate fps
   if (mspt == 0) fps = 0.0f;
   else fps = (4ul * 1000ul) / (float)mspt;

   lcd.setCursor(0, 1);
  sprintf(buff_lcd,"%-5d", (int)mspt);
  lcd.print(buff_lcd);

  lcd.setCursor(8, 1);
  dtostrf(fps,5,2,buff_lcd);
  lcd.print(buff_lcd);

  time_lcd = time_current;
 }
 //delay(10);
}


void count() {
 static unsigned long time_current;
 static unsigned long time_touch = 0ul;
 static unsigned long time_debounce = 0ul;

 time_current= millis();

 if (digitalRead(pin_touch) != state_touch) {
   if ((time_current - time_debounce) > 30) {
     state_touch = !state_touch;

  if (state_touch == HIGH) {
       if (time_touch > 0)
	 mspt = runningAverage(time_current - time_touch);
       time_touch = time_current;
  }
     time_debounce = time_current;
   }
 }	
}

unsigned long runningAverage(unsigned long M)
{
static const int LMSIZE = 5;
static unsigned long LM[LMSIZE];
static byte index = 0;
static unsigned long sum = 0ul;
static byte count = 0;
//change element in array and update sum
sum -= LM[index];
LM[index] = M;
sum += LM[index];

//change index
index = (index+1) % LMSIZE;
if (count < LMSIZE) count++;
return sum / count;
}

Bearbeitet von grox (Änderungen anzeigen)
Geschrieben

Das ist ja echt elegant. PID-Regler wäre natürlcih die Krönung, aber mir persönlich zu hoch. Früher hätte man ne PLL gebaut, aber der Meo will ja offenbar keinen Takt, insofern ist Deine Steuerung schon echt gut.

Das mit den Störungen ist komisch. Passiert es auch, wenn Du den Arduino per Batterie (bzw. Notebook-USB) betreibst? Hast DU ein Oszilloskop, mit dem Du mal ein paar Pegel beobachten könntest? EIn zusätzlicher Sieb-Elko an VCC wird auf jeden Fall nicht schaden...

Geschrieben

PID-Regler habe ich dem Arduino beigebracht: http://www.mikrocontroller.net/topic/343337#3798707

 

Der Arduino hängt schon die ganze Zeit an Batterien, das kann es nicht sein. Ich vermute Störungen in den dünnen Signalleitungen. Ein Oszilloskop habe ich leider nicht. Taugen solche Billigdinger bei eBay eigentlich was? www.ebay.de/itm/Mini-Digital-Oszilloskop-DSO201-TFT-Oscilloscope-Pocket-Taschengrose-Portable-/331186590554

 

Nächster Schritt ist dann die Synchronisation mit dem Camcorder, mal sehen was das bringt.

Geschrieben (bearbeitet)

Dieses TFT-Oszi taugt wahrscheinlich nicht viel. Die max. Samplingrate ist 1Mhz. D.h. damit man etwas erkennen kann, dann ist man auf ca. 100kHz oder noch stärker beschränkt. Deinen Tonkoppler bekommt man natürlich damit angezeigt, aber nicht viel mehr.

Entweder du kaufst dir ein billiges analoges Gerät oder du gibst deutlich mehr als die 55Euro aus und kaufst dir ein brauchbares digitales Oszi.. Allerdings sollte man Testberichte lesen. Ein Test in den c´t Hardwarehacks offenbarte teils sehr unausgegorene Geräte.

Bearbeitet von Theseus (Änderungen anzeigen)

Erstelle ein Benutzerkonto oder melde Dich an, um zu kommentieren

Du musst ein Benutzerkonto haben, um einen Kommentar verfassen zu können

Benutzerkonto erstellen

Neues Benutzerkonto für unsere Community erstellen. Es ist einfach!

Neues Benutzerkonto erstellen

Anmelden

Du hast bereits ein Benutzerkonto? Melde Dich hier an.

Jetzt anmelden
×
×
  • Neu erstellen...

Filmvorführer.de mit Werbung, externen Inhalten und Cookies nutzen

  I accept

Filmvorfuehrer.de, die Forenmitglieder und Partner nutzen eingebettete Skripte und Cookies, um die Seite optimal zu gestalten und fortlaufend zu verbessern, sowie zur Ausspielung von externen Inhalten (z.B. youtube, Vimeo, Twitter,..) und Anzeigen.

Die Verarbeitungszwecke im Einzelnen sind:

  • Informationen auf einem Gerät speichern und/oder abrufen
  • Datenübermittlung an Partner, auch n Länder ausserhalb der EU (Drittstaatentransfer)
  • Personalisierte Anzeigen und Inhalte, Anzeigen- und Inhaltsmessungen, Erkenntnisse über Zielgruppen und Produktentwicklungen
Durch das Klicken des „Zustimmen“-Buttons stimmen Sie der Verarbeitung der auf Ihrem Gerät bzw. Ihrer Endeinrichtung gespeicherten Daten wie z.B. persönlichen Identifikatoren oder IP-Adressen für diese Verarbeitungszwecke gem. § 25 Abs. 1 TTDSG sowie Art. 6 Abs. 1 lit. a DSGVO zu. Darüber hinaus willigen Sie gem. Art. 49 Abs. 1 DSGVO ein, dass auch Anbieter in den USA Ihre Daten verarbeiten. In diesem Fall ist es möglich, dass die übermittelten Daten durch lokale Behörden verarbeitet werden. Weiterführende Details finden Sie in unserer  Datenschutzerklärung, die am Ende jeder Seite verlinkt sind. Die Zustimmung kann jederzeit durch Löschen des entsprechenden Cookies widerrufen werden.