Go Down

Topic: Canon EOS 350D über Arduino Nano ansteuern (Read 1 time) previous topic - next topic

LutzB

Hallo zusammen!

Ich möchte meine Spiegelreflex über einen Arduino Nano ansteuern. Dazu muss ich zwei verschiedene Kontakte auf Masse ziehen.
Kann ich das über zwei kleine Relais machen? Ich habe bei Reichelt folgendes Relais gefunden:
http://www.reichelt.de/Reedrelais-Magnete/DIP-7212-D-5V/3/index.html?;ACTION=3;LA=446;ARTICLE=27651;GROUPID=3291;artnr=DIP+7212-D+5V
Den Code habe ich soweit fertig und mit zwei LEDs die Relais Simuliert.
Muss ich bei den Relais etwas beachten wenn ich diese am Arduino anschließe?
Ich würde an die Spule des Relais einmal Masse und einen Pin des Arduino anschließen.
Funktioniert das so?
Über eure Hilfe würde ich mich freuen!

Grüße

Lutz

Serenifly

#1
Jun 28, 2013, 08:37 pm Last Edit: Jun 28, 2013, 08:56 pm by Serenifly Reason: 1
Reed Relais sind Magnetschalter (oder sehr zuverlässige Relais mit Reed-Kontakten). Du willst eher Miniaturrelais. z.B.:
http://www.reichelt.de/Miniaturrelais/G5V-1-5V/3/index.html?;ACTION=3;LA=2;ARTICLE=28332;GROUPID=3292;artnr=G5V-1+5V
http://www.reichelt.de/Miniaturrelais/JV-05/3/index.html?;ACTION=3;LA=2;ARTICLE=79391;GROUPID=3292;artnr=JV+05

Und dann einen kleinen Transistor (z.B. BC337 oder irgendeinen anderen NPN in TO-92) als Treiber davor, da ein Arduino Pin nur 40mA liefert. Nimm diese Schaltung:
http://www.mikrocontroller.net/wikifiles/4/4f/Relais_npn.png

Die linke, und ganz wichtig: die Diode nicht vergessen. Für den Basiswiderstand etwa 1-2kOhm



Wenn da nicht viel Strom fließt, kann man auch Analogschalter HC4066 nehmen. Das kommt darauf an was du da genau schalten willst. Ich habe bei mir z.B. ein Gerät durch den UNO steuern wollen und dabei die Taster des Geräts mit Analogschaltern überbrückt (das Gerät "denkt" dann sie wären gedrückt) und ein Relais nur für den AN/AUS Taster genommen wo mehr Strom geflossen ist. Funktioniert sehr schön, nimmt wenig Platz weg und ist lautlos. Wenn du aber was mit Leistung auf Dauer schalten willst sind Relais die korrekte Wahl.

marau

Hallo zusammen,

ich habe mir eben mal das Datenblatt des genannten Relais angeschaut.

Das Relais hat einen Spulenwiderstand von 200 Ohm, daraus resultiert ein Spulenstrom von 25mA, also kein Problem für einen Ausgang.
Solange es bei zwei Relais bleibt, ist kein Treiber erforderlich, da der Summenstrom von 200mA nicht überschritten wird.

Da das Relais eine Freilaufdiode integriert hat, ist jedoch unbedingt die Polung zu beachten!
An Pin 2 kommt der Arduino-Ausgang, Pin 6 kommt an Masse.


Grüße

Martin

Klaus_ww

Hab ich auch gerade gemacht  ;)

Die Variante mit einem 4066 halte ich aber auch für die bessere, da die EOS sicherlich auch damit zurechtkommt. Sollte mich sehr wundern wenn nicht  :~

Vorteil: kleiner, deutlich weniger Stromverbrauch

LutzB

Danke erstmal für eure schnellen Antworten!

Wenn ich das richtig verstanden habe kann ich den 4066 verwenden da ich nur ca 10mA schalten muss.
Kann ich dann einfach den Control-Pin vom 4066 mit nem Arduino-Pin ansteuern oder muss ich da noch Widerstände oder ähnliches integrieren?

Grüße

Lutz

Serenifly

Das geht einfach so, wie bei anderen Logic-ICs auch.

Ich habe bei mir einen der Ausgänge jeden Schalters fest auf Masse gelegt und den anderen mit dem offenen Kontakt des Tasters verbunden. Dann muss man nur noch die Masse des ICs/Arduinos einmal mit der Masse des Geräts verbinden.

Du solltest die Eingänge der zwei unbenutzten Taster (es sind 4 pro IC) auch auf Masse legen.

uwefed

Du brauchst gar kein Relais.
Möglichkeiten:
* Für Selbsichere und solche die wissen was sie machen der minimalismus: Negativeren Pol des Remoteanschlußes auf Gnd Arduino schalten und auf die anderen 2 Anschlüße je ein Pin und dieses zwischen Eingang ( offen) und Ausgang LOW (gedrückt) umschalten Ausgang HIGH darf dabei nie geschalten werden!!!.
* NPN Transistor über Basiswiderstand ansteuern, Emittor auf GND, negativeren Pol des Remoteanschlußes auf Gnd Arduino schalten und Positiveren auf Collektor
* Optokopler: Emittor auf  negativeren Pol des Remoteanschlußes; Collektor auf positiveren. Optokoppler mit vorwiderstand wie LED ansteuern.
* Über Infrarotschnittstelle der EOS 350D http://sebastian.setz.name/arduino/my-libraries/multi-camera-ir-control/
* Über Universal-TV-Fernsteuerung bei bestimmten Codeeinstellung http://www.camerahacker.com/universal_remote/index.php
* Über PTP Interface USB- Interface wie von PC und mitgelieferten Steuerprogramm. Dazu brauchst Du ein USB HOST Shield. http://www.circuitsathome.com/tag/ptp . Vollkontrolle inclusive Verschlußzeiten, Blende ecc. bei einigen Objektiven auch Fokussteuerung.

Grüße Uwe

Serenifly

#7
Jun 28, 2013, 09:43 pm Last Edit: Jun 28, 2013, 09:51 pm by Serenifly Reason: 1
Mhh stimmt, bei nur 10mA gibt es noch andere Optionen. Optokoppler wären sehr gut. Die brauchen keine extra Betriebsspannung wie die ICs :)

z.B. hier mit 2 in einem DIP-8 Gehäuse:
http://www.reichelt.de/Optokoppler/ILD-74/3/index.html?;ACTION=3;LA=446;ARTICLE=8773;GROUPID=3046;artnr=ILD+74


Kam bei mir leider nicht in Frage, da die Pullups des Geräts sehr niedrig waren und ich keine mit genügend Kollektorstrom gefunden habe (bzw. das oft nicht vernünftig angegeben ist)

uwefed

Optokoppler: Du nimmst einen H11F1M, H11F2M, H11F3M und Du brauchst die Polung an der Kamera nicht zu beachten.
Grüße Uwe

LutzB

Einen Großen Dank nochmal für die vielen Tipps und Hilfestellungen!
Ich hab mich für den 4066 entschieden und das funktioniert auch 1A!

Beim weiteren aufbau meines Projekts habe ich festgestellt das die delay-Funktion nur bis 32000ms funktioniert. Ich variiere die Belichtungsdauer über ein Poti. Dabei möchte ich den Bereich von 30Sekunden bis 600 Sekunden abdecken. Die Zeit lasse ich mir in Sekunden auf einem LCD-Display anzeigen. Wenn ich jetzt aber den Wert in Millisekunden anzeigen lasse kann ich beobachten das der Wert ab 32000ms wieder sinkt und sogar bis -32000 sinkt obwohl ich das Poti weiter erhöhe.

Habt ihr da einen Tipp für mich wie ich das Problem umgehen kann?
Hier mein Code:
Code: [Select]

// include the library code:
#include <LiquidCrystal.h>
int sensor1=A0;
int sensorvalue=0;
int verschlusszeitsekunden=0;
int verschlusszeit=0;
int ausloeser=10;
int ausloeseknopf=9;
int buttonstate=0;
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {
  pinMode(ausloeser, OUTPUT);
  pinMode(ausloeseknopf, INPUT);
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.clear();
  lcd.setCursor(15, 0);
  lcd.print("Canon Digital");
  lcd.setCursor(15, 1);
  lcd.print("INTERFACE");
  delay(100);
  lcd.clear();
  lcd.setCursor(14, 0);
  lcd.print("Canon Digital");
  lcd.setCursor(14, 1);
  lcd.print("INTERFACE");
  delay(100);
  lcd.clear();
  lcd.setCursor(13, 0);
  lcd.print("Canon Digital");
  lcd.setCursor(13, 1);
  lcd.print("INTERFACE");
  delay(100);
  lcd.clear();
  lcd.setCursor(12, 0);
  lcd.print("Canon Digital");
  lcd.setCursor(12, 1);
  lcd.print("INTERFACE");
  delay(100);
  lcd.clear();
  lcd.setCursor(11, 0);
  lcd.print("Canon Digital");
  lcd.setCursor(11, 1);
  lcd.print("INTERFACE");
  delay(100);
  lcd.clear();
  lcd.setCursor(10, 0);
  lcd.print("Canon Digital");
  lcd.setCursor(10, 1);
  lcd.print("INTERFACE");
  delay(100);
  lcd.clear();
  lcd.setCursor(9, 0);
  lcd.print("Canon Digital");
  lcd.setCursor(9, 1);
  lcd.print("INTERFACE");
  delay(100);
  lcd.clear();
  lcd.setCursor(8, 0);
  lcd.print("Canon Digital");
  lcd.setCursor(8, 1);
  lcd.print("INTERFACE");
  delay(100);
  lcd.clear();
  lcd.setCursor(7, 0);
  lcd.print("Canon Digital");
  lcd.setCursor(7, 1);
  lcd.print("INTERFACE");
  delay(100);
  lcd.clear();
  lcd.setCursor(6, 0);
  lcd.print("Canon Digital");
  lcd.setCursor(6, 1);
  lcd.print("INTERFACE");
  delay(100);
  lcd.clear();
  lcd.setCursor(5, 0);
  lcd.print("Canon Digital");
  lcd.setCursor(5, 1);
  lcd.print("INTERFACE");
  delay(100);
  lcd.clear();
  lcd.setCursor(4, 0);
  lcd.print("Canon Digital");
  lcd.setCursor(4, 1);
  lcd.print("INTERFACE");
  delay(100);
  lcd.clear();
  lcd.setCursor(3, 0);
  lcd.print("Canon Digital");
  lcd.setCursor(3, 1);
  lcd.print("INTERFACE");
  delay(100);
  lcd.clear();
  lcd.setCursor(2, 0);
  lcd.print("Canon Digital");
  lcd.setCursor(3, 1);
  lcd.print("INTERFACE");
  delay(100);
  lcd.clear();
  lcd.setCursor(1, 0);
  lcd.print("Canon Digital");
  lcd.setCursor(3, 1);
  lcd.print("INTERFACE");
  delay(4000);
  lcd.clear();
}

void loop() {
  sensorvalue=analogRead(sensor1);
  verschlusszeitsekunden=map(sensorvalue, 0, 1023, 30, 600);
  verschlusszeit=(verschlusszeitsekunden*1000);     
  buttonstate=digitalRead(ausloeseknopf);
  lcd.clear();
  lcd.setCursor(1, 0);
  // print the number of seconds since reset:
  lcd.print("Verschlusszeit:");
  lcd.setCursor(1,1);
  lcd.print(verschlusszeitsekunden);
  lcd.setCursor(7,1);
  lcd.print("Sekunden");
  delay(200);

  if(buttonstate == HIGH){
    digitalWrite(ausloeser, HIGH);
    lcd.clear();
    lcd.setCursor(1,0);
    lcd.print("Bitte LAECHELN");
    lcd.setCursor(1,1);
    lcd.print(verschlusszeitsekunden);
    lcd.setCursor(5,1);
    lcd.print("Sekunden");
    delay(verschlusszeit);
    digitalWrite(ausloeser, LOW);
  }
  else {
    digitalWrite(ausloeser, LOW);
  }
}



Gruß Lutz

michael_x

Du meinst sicher  32768 ms

Dein Code ist mir zu lang um das zu suchen *), aber
int ist einfach der falsche Datentyp für Zahlen die
-  nicht < 0 sein können
-  größer als 32767 werden können

Und für Zahlen, die nicht größer als 255 werden, ist es einfach Verschwendung.
Das einzige schlechte Grund, int zu nehmen, ist dass man so wenige Tasten tippen muss.   



*)  verschlusszeit=(verschlusszeitsekunden*1000);     

Und warum sind verschlusszeit und verschlusszeitsekunden globale Variable ?
Nur damit man den Fehler nicht gleich sieht ?

LutzB

Danke erstmal für die Antwort.
Leider komme ich mit der Antwort nicht weiter.

Quote
int ist einfach der falsche Datentyp für Zahlen die
-  nicht < 0 sein können
-  größer als 32767 werden können

Welchen Datentyp muss ich für große Zahlen benutzen?

Quote
Und warum sind verschlusszeit und verschlusszeitsekunden globale Variable ?
Nur damit man den Fehler nicht gleich sieht ?

Wie muss ich das Verstehen?

Da Ich Anfänger im Programmieren bin und mir meine bisherigen Projekte aus Beispielcodes zusammengewürfelt habe war das für mich so erstmal richtig. Aber ich möchte gerne aus meinen Fehlern lernen und würde mich über Tipps sehr freuen!

Hier nochmal der gekürzte Code:

Code: [Select]

int sensor1=A0;
int sensorvalue=0;
int verschlusszeitsekunden=0;
int verschlusszeit=0;
int ausloeser=10;
int ausloeseknopf=9;
int buttonstate=0;


void setup() {
  pinMode(ausloeser, OUTPUT);
  pinMode(ausloeseknopf, INPUT);
}

void loop() {
  sensorvalue=analogRead(sensor1);
  verschlusszeitsekunden=map(sensorvalue, 0, 1023, 30, 600);
  verschlusszeit=(verschlusszeitsekunden*1000);     
  buttonstate=digitalRead(ausloeseknopf);

  if(buttonstate == HIGH){
    digitalWrite(ausloeser, HIGH);
    delay(verschlusszeit);
    digitalWrite(ausloeser, LOW);
  }
  else {
    digitalWrite(ausloeser, LOW);
  }
}

Serenifly

#12
Jul 05, 2013, 02:04 pm Last Edit: Jul 05, 2013, 02:41 pm by Serenifly Reason: 1
unsigned long ist das größte für positive Zahlen. Hat 4 Bytes und geht bis 4,294,967,295:
http://arduino.cc/en/Reference/UnsignedLong

Das ist auch womit Delay intern arbeitet:
http://arduino.cc/en/Reference/Delay

Wenn du da einen 2-Byte int übergibst wandelt der das in einen ulong um

Rein theoretisch könntest du auch unsigned int nehmen. Dann hättest du schon maximal das doppelte als mit dem normalen signed int: max. 65,535


Generell zu den Datenbereichen kannst du dir z.B. mal das ansehen:
http://msdn.microsoft.com/en-us/library/s3f49ktz%28v=vs.80%29.aspx

Das ist für .NET/Visual C++ und weicht daher etwas ab, aber grob passt es. Was es beim Arduino nicht gibt sind 8-Byte Double. Die sind genauso breit wie Float (4 Byte). Und 64-Bit Typen gibt es natürlich generell nicht. Dafür aber "byte" für 0-255. Ints sind 2-Byte, also Int16 und immer signed. Da sieht man z.B. auch dass bools immer ein ganzes Byte belegen. Aber die Bereiche sind halt übersichtlich angegeben.

michael_x

Wenn du durch Tips mehr lernst als durch selber googeln, bitte sehr:
Code: [Select]

int  verschlusszeitsekunden=map(sensorvalue, 0, 1023, 30, 600);
unsigned long  verschlusszeit=(verschlusszeitsekunden*1000L); 
 

Ein Tip:   (int)600 * 1000 ist beim Arduino nicht 600000, probiere es aus und staune !
Zu den Datentypen findest du hier einige Anregungen:   http://arduino.cc/en/Reference/HomePage

LutzB

Danke für die Hilfe!
Hab den Tipp ins Programm übernommen und es funktioniert  :)
Bisher war mir das nicht klar, dass es verschiedene Datentypen gibt.Ich kannte nur int :( Werd mir eure Links mal genau anschauen und durchlesen!

Grüße

Lutz

Go Up