Ein paar Grundlagen zum Bau einer Barndoor Montierung

Sterne

Sterne ohne Nachführung

Nachts ist es ziemlich dunkel. Wenn man Sterne oder andere astronomische Objekte fotografieren möchte, dann muss man sie länger belichten. Da gibt es allerdings ein Problem. Die Erde bewegt sich offenbar tatsächlich. Statt knallscharfer Sterne bekommt man bei langer Belichtungszeit nämlich lange Striche.

Kein Problem, dafür gibt es Montierungen, die die Bewegung der Sterne ausgleichen. Eine von diesen Montierungen kann man auch als mittelmäßig begabter Hobby-Bastler leicht selber bauen, nämlich die Barndoor Monierung

Die Barndoor-Montierung (auch Scotch Mount) besteht aus zwei Brettern, die über ein Scharnier miteinander verbunden sind. Wenn wir nun eines der Bretter fest mit der Erde verbinden und auf dem anderen Brett die Kamera befestigen, dann müssen wir nur noch das Scharnier exaktgenau parallel zur Erdachse ausrichten und wir können die Drehung der Erde leicht durch langsames “aufklappen” der Bretter ausgleichen.

Nagut, man braucht dafür wackelfreie Scharniere und man muss ganz genau wissen, wie schnell sich die Erde dreht oder anders ausgedrückt wie schnell sich die astronomischen Objekte scheinbar am Himmel bewegen..

Bei der Sonne ist es einfach. Die steht alle 24 Stunden wieder (etwa) an der gleichen Stelle. Sie bewegt sich also (scheinbar) um 15° pro Stunde (360°/24) oder um 0,25° pro Minute (360°/24/60).

Bei den Sternen ist es etwas komplizierter, denn die Erde dreht sich ja nicht nur um sich selbst, sondern auch noch (rückwärts) um die Sonne. Sie dreht sich also pro Jahr nicht etwa 365,25 mal um sich selbst sondern 366,25 (genau 366,2422) mal. Die Sterne sind daher nicht nach genau 24 Stunden wieder an der gleichen Stelle am Himmel, sondern schon nach 23,9345 Stunden (23 Stunden, 56 Minuten und 4,099 Sekunden) oder 1436.068 Minuten. Näheres siehe zum Beispiel im Wikipedia Artikel Siderischer Tag)

Gut, zurück zu unseren Aufnahmen des Sternenhimmels. Wenn wir keine Striche sondern punktförmige Sterne aufnehmen wollen, dann müssen wir die Kamera pro Minute um exaktgenau 0,25068450797 Grad (360° / 1436.068 Minuten) nachführen.

Weblinks:

Schrittmotor 28BYJ48 am Arduino

Seit einiger Zeit werden bei Ebay kleine Getriebe-Schrittmotoren vom Typ 28BYJ48 mitsamt einem ULN2003 Treibermodul aus China für unter drei Euro angeboten. Ohne zusätzliche Versandkosten! Keine Ahnung, wie sich das rechnet. Das gleiche Paket aus Schrittmotor und Treibermodul gibt es aber auch bei inländischen Anbietern für unter fünf Euro. (Zum Beispiel hier über Amazon).

28BYJ48, ULN2003, Arduino

28BYJ48, ULN2003, Arduino

Getriebe Übersetzung

Diese keinen Schrittmotoren werden offenbar eigentlich eingesetzt, um Steuerungsklappen in Klimaanlagen hin und her zu bewegen. Den Herstellern war es also egal, welche Übersetzung das Getriebe ganz genau hat. Zumindest bei meinem Modell stimmt die angegebene Übersetzung von 1:64 nicht genau. Es hat ebenfalls die hier berechnete Übersetzung von 1:63,68395. Das bedeutet, dass nicht 4096 Steps pro Umdrehung nötig sind, sondern nur 4075,772… Steps. Für viele Anwendungen ist das wohl egal, aber wenn der Motor fortlaufend in eine Richtung drehen soll (z.B. als Sekundenzeiger einer Uhr), muss dieser Umstand berücksichtigt werden.

Anschluss an den Arduino

ULN2003

ULN2003

Ich habe hier die digitalen Pins 8, 9, 10,11 des Arduino zum Anschluss des Motor-Treibers verwendet. Für die ersten Versuche reichte die Versorgung aus dem USB-Port. Für ernstzunehmende Anwendungen ist natürlich eine externe Quelle nötig.

Der Jumper auf dem Schrittmotor-Treiber (rechts neben dem VCC-Pin) muss gesteckt bleiben. Wenn ich es richtig verstehe, dann kann man durch entfernen dieses Jumpers die Stromversorgung zum Motor unterbrechen.

Betrieb am Arduino

Ich habe gar nicht versucht die Arduino Stepper-Library zu verwenden. Offenbar gab (gibt?) es mit der bei diesem Motor Probleme. Außerdem wollte ich genauer verstehen, wie man mit so einem Schrittmotor umgeht.Prinzipiell habe ich bei meinen Versuchen auf die Lösung von Benutzer celem im Arduino Forum aufgebaut.

Laut Datenblatt soll der Motor in folgender Sequenz angesteuert werden:

In 1 In 2 In 3 In 4
0 0 0 1
0 0 1 1
0 0 1 0
0 1 1 0
0 1 0 0
1 1 0 0
1 0 0 0
1 0 0 1

Ein einfacher Sketch zum Testen sieht zum Beispiel so aus:

const int motorPin1 = 8;  // Blue   - In 1
const int motorPin2 = 9;  // Pink   - In 2
const int motorPin3 = 10; // Yellow - In 3
const int motorPin4 = 11; // Orange - In 4
                          // Red    - pin 5 (VCC)

unsigned int lowSpeed  = 10000; // Notabene: nicht über 16000
unsigned int highSpeed =  1000;

void setup() {
  pinMode(motorPin1, OUTPUT);
  pinMode(motorPin2, OUTPUT);
  pinMode(motorPin3, OUTPUT);
  pinMode(motorPin4, OUTPUT);
}

void loop()
{ unsigned long n = millis() / 3000; // 3 Sekunden

  switch(n % 8)
  { case 0: stop();               break;
    case 1: rechtsrum(lowSpeed);  break;
    case 2: stop();               break;
    case 3: linksrum(lowSpeed);   break;
    case 4: stop();               break;
    case 5: rechtsrum(highSpeed); break;
    case 6: stop();               break;
    case 7: linksrum(highSpeed);  break;
  }
}

void rechtsrum(unsigned int motorSpeed)
{ // 1
  digitalWrite(motorPin4, HIGH);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin1, LOW);
  delayMicroseconds(motorSpeed);

  // 2
  digitalWrite(motorPin4, HIGH);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin1, LOW);
  delayMicroseconds(motorSpeed);

  // 3
  digitalWrite(motorPin4, LOW);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin1, LOW);
  delayMicroseconds(motorSpeed);

  // 4
  digitalWrite(motorPin4, LOW);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin1, LOW);
  delayMicroseconds(motorSpeed);

  // 5
  digitalWrite(motorPin4, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin1, LOW);
  delayMicroseconds(motorSpeed);

  // 6
  digitalWrite(motorPin4, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin1, HIGH);
  delayMicroseconds(motorSpeed);

  // 7
  digitalWrite(motorPin4, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin1, HIGH);
  delayMicroseconds(motorSpeed);

  // 8
  digitalWrite(motorPin4, HIGH);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin1, HIGH);
  delayMicroseconds(motorSpeed);
}

void linksrum(unsigned int motorSpeed)
{ // 1
  digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, LOW);
  delayMicroseconds(motorSpeed);

  // 2
  digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, LOW);
  delayMicroseconds(motorSpeed);

  // 3
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, LOW);
  delayMicroseconds(motorSpeed);

  // 4
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin4, LOW);
  delayMicroseconds(motorSpeed);

  // 5
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin4, LOW);
  delayMicroseconds(motorSpeed);

  // 6
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin4, HIGH);
  delayMicroseconds(motorSpeed);

  // 7
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, HIGH);
  delayMicroseconds(motorSpeed);

  // 8
  digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, HIGH);
  delayMicroseconds(motorSpeed);
}

void stop()
{ digitalWrite(motorPin4, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin1, LOW);
}

Werbung:

Weblinks:

Gabellichtschranke TCST1103 am Arduino

Für ein kleines Projekt benötige ich zwei Endabschalter. Dafür habe ich mir ein paar Gabel-Lichtschranken vom Typ TCST1103 besorgt. Das entsprechende Datenblatt gibt es zum Beispiel bei Vishay. Damit ich beim nächsten Mal nicht wieder ewig herum suchen muss, wie man das Teil am Arduino betreibt, hier eine kleine Anleitung:

TCST1103 am Arduino

TCST1103 am Arduino

Auf der kleinen Lichtschranke ist die Infrarot-LED mit dem Buchstaben E (Emitter) bezeichnet. Der Fototransistor ist entsprechend mit D (Detector) bezeichnet.

Im Prinzip habe ich die Schaltung aus dem Datenblatt verwendet. Allerdings habe ich als Vorwiderstand für die LED (bei 5V Versorgungsspannung) einen 220 Ohm Vorwiderstand verwendet. Beim zweiten Widerstand (vom Fototransistor zur Masse) habe ich etwas herum probiert. Der Wert war relativ unkritisch. 10K lieferte zum Beispiel sehr zuverlässige Ergebnisse.
Weblinks:

Werbung:

Hier noch der verwendete Arduino-Sketch:

/*
 * Testing TCST1103 on analog port 0
 *
 * Author:
 *   Heiner Otterstedt
 * 
 * Weblinks:
 *   http://www.hobby-werkstatt-blog.de
 * 
 */

int sensorPin = A0;
int ledPin = 13;
int sensorValue = 0;

void setup()
{ pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
}

void loop()
{ sensorValue = analogRead(sensorPin);
  Serial.println(sensorValue);
  if(sensorValue > 512) digitalWrite(ledPin, HIGH);
  else                  digitalWrite(ledPin, LOW);
  delay(200);
}

Amboss selbst gebaut

Zufällig las ich gerade bei Instructables einen Artikel über den Selbstbau eines Amboss aus einer Eisenbahnschiene. Da fiel mir ein, dass ich so etwas ähnliches vor gut dreißig Jahren auch mal gebaut habe. Da bei meiner Amboss-Version wohl keine ausführliche Anleitung nötig ist, um sie nachzubauen hier nur ein Foto:

Selbst gebauter Amboss

Aus einer Eisenbahnschiene selbst gebauter Amboss

Gut, man sieht ihm an, dass ein Amboss nicht unbedingt ein Werkzeug ist, dass ich täglich verwende, aber er hat mir über die Zeit schon häufig hilfreich zur Seite gestanden. Unter anderem ist auf diesem Amboss die Pflanzschaufel entstanden, die ich immer noch fast täglich benutze.

Siehe auch:

Weblinks:

Modifikation strafbar

Wenn bei mir irgendein Gerät nicht so arbeitet wie ich es erwarte, dann nehme ich es mir vor und baue es so zurecht, wie ich es gerne haben möchte. Und dabei ist mir vollkommen schnuppe, was der ursprüngliche Hertsteller des Geräts davon hält. Vollkommen schnuppe! Ist ja auch kaum vorstellbar, dass zum Beispiel der Hersteller meiner Tischbohrmaschine gerichtlich gegen mich vorgeht, weil ich seine Bohrmaschine entsprechend meinen Bedürfnissen verändert habe.

Wirklich?

Wie das Make Blog vor ein paar Tagen unter den Titel “Sony’s War on Makers, Hackers, and Innovators” berichtet, geht Sony in den Vereinigten Staaten gerade mit heftigsten juristischen Mitteln gegen Leute vor, die auf ihrer Playstation 3 Linux installieren wollen. Naja, was die Gerichtsbarkeit betrifft ist dort drüben in den USA bekanntlich so manches möglich. Da sind wir hier zum Glück vernünftiger.

Wirklich?

Sony Computer Entertainment hat es tatsächlich geschafft einen deutschen Richter davon zu überzeugen, dass es eine Straftat ist, die eigene Playstation zu erkunden und die Ergebnisse zu veröffentlichen. Gestern wurde durch richterlichen Beschluss die erste Wohnung eines Playstation-Besitzers durchsucht und sein Equipment beschlagnahmt.

Arduino IDE unter OpenSuse-Linux installieren

Um die Arduino-IDE unter OpenSuse installieren zu können müssen eine Reihe von Abhängigkeiten erfüllt sein. Diese Abhängigkeiten kann man natürlich relativ leicht händisch auflösen – einfacher geht es aber, wenn man das OpenSuse Arduino-Repsitory benutzt. Hier eine Minianleitung zur Installation an der Konsole (das Gleiche funktioniert natürlich auch mit Yast). In der Konsole gibt man als root folgende 4 Befehle ein:

  • zypper ar http://download.opensuse.org/repositories/home:/kwk:/arduino/openSUSE_11.3 arduino
  • zypper ar http://download.opensuse.org/repositories/CrossToolchain:/avr/openSUSE_11.3 cross-avr
  • zypper ref
  • zypper in arduino

Wer das Ganze lieber mit der Hand macht – bei mir (Suse 11.3, 64 Bit,  Gnome, …) mussten folgende Pakete installiert werden, um zuletzt die Arduino-IDE installieren zu können:

  • uisp-20050207suse-144.1.x86_64
  • gcc45-gij-4.5.0_20100604-1.9.x86_64
  • cross-avr-gcc-4.3.3_20100125-28.10.x86_64
  • cross-avr-binutils-2.19.1-33.5.x86_64
  • avrdude-5.10-44.9.x86_64
  • java-1_6_0-sun-1.6.0.u23-0.2.1.x86_64
  • gcc-gij-4.5-4.2.x86_64
  • rxtx-java-2.2pre2-4.6.x86_64
  • avr-libc-1.7.0-3.5.noarch
  • java-1_5_0-gcj-compat-1.5.0.0-114.1.x86_64
  • arduino-0022-6.1.x86_64

Siehe auch:

Arduino: Servos ansteuern

Damit sich meine kleine Roboter-Platform auch aus etwas komplizierteren Lagen selbstständig heraus navigieren kann, muss sie nicht nur feststellen, ob sich vor ihr ein Hindernis befindet. Sie muss auch nachsehen, ob sich neben ihr Hindernisse befindet. Deshalb habe ich den den GP2D12 Entfernungssensor kipp- und schwenkbar montiert. Das Kippen und Schwenken des Sensors erfolgt über zwei Servos.

Meine Recherche zum Ansteuern von Servos mit dem Arduino ergab zunächst etwas verwirrende Ergebnisse. Offenbar war in der Entwicklungsumgebung früher (vor Version 0017) keine Servo-Library enthalten. Die Library, die damals zum Download bereit stand, musste etwas anders angesprochen werden als die Version, die seit 0017 im der Entwicklungsumgebung enthalten ist. Näheres hier: Arduino Playground – Servo.

In meinem kleinen Beispiels-Sketch werden zwei Servos (Pin 8 und Pin 9) über die Tasten 8, 4, 6, 2 (am Besten auf dem Nummernblock) gesteuert. Damit die im Roboter verbauten Servos nirgends anstoßen ist die Drehrichtung in beide Richtungen begrenzt.

— schnipp —

#include <Servo.h>

// Pins festlegen
int pin1 = 9;
int pin2 = 8;

// Servo-Objekt erzeugen
Servo servo1;
Servo servo2;

// Ausgangsposition in Winkelgraden
int pos1 = 90;
int pos2 = 45;

void setup()
{ servo1.attach(pin1);
  servo2.attach(pin2);
  Serial.begin(9600);
}

void loop()
{ // Drehung begrenzen
  if(pos1 < 0) pos1 = 0;
  if(pos1 > 180) pos1 = 180;
  if(pos2 < 45) pos2 = 45;
  if(pos2 > 130) pos2 = 130;

  // Position setzen
  servo1.write(pos1);
  servo2.write(pos2);

  delay(50);

  if(Serial.available())
  { char ch = Serial.read();

    switch(ch)
    { case '4': pos1-=45; break; // schwenken
      case '6': pos1+=45; break; // schwenken
      case '8':  pos2-=10; break; // kippen
      case '2':   pos2+=10; break; // kippen
    }
  }
}

— schnapp —

Siehe auch:

Arduino: The Documentary

Und wenn ich nun schon mal dabei bin Iframes in dieses Blog einzubinden (was ich eigentlich eher ungern mache), dann kann ich ja auch gleich die niegelnagelneue Dokumentation zur Geschichte des Arduino einbinden.

Arduino The Documentary (2010) English HD from gnd on Vimeo.

Inzwischen besitze ich zwei Stück von diesen Arduinos – einen Arduino Uno und einen Arduino Romeo. Ich muss also wohl nicht besonders betonen, dass ich dieses Open Source Hardware und Software Bündel ziemlich Klasse finde.

Die Hobbywerkstatt Facebook Page

Ich weiß nicht, kann man heute eigentlich noch irgendwie beweisen, dass man existiert, wenn man keine Facebook Seite hat? Ach ja, Personalausweis! Naja, nach meinem Personalausweis hat allerdings schon lange niemand mehr gefragt. Nach meiner Facebook-Seite dagegen schon.

Egal, jedenfalls hat dieses Werkstatt-Blog nun auch eine Facebook Page. Wenn Du also gerade nichts anderes zu tun hast, dann solltest Du jetzt unbedingt den “Gefällt mir Button” klicken ;-)

Arduino: GP2D12 Distance Measuring Sensor

Mit dem Entfernungssensor GP2D12 von Sharp lässt sich relativ sicher der Abstand zu Hindernissen ermitteln – zumindest im Bereich zwischen 10 und 80 Zentimeter. Der Anschluss des Sensors an den Arduino ist denkbar einfach – die Datenleitung wird mit einem der analogen Eingänge (in diesem Fall Pin 0) verbunden.

Etwas komplizierter ist es, die Messergebnisse in einen lesbaren Wert (z.B. Zentimeter) umzuwandeln. Der Werte des Sensors sind nicht linear, sondern sie müssen interpretiert werden. Ein brauchbarer Ansatz dafür stammt von Javier Valencia und ist an dieser Stelle dokumentiert.

Hier ein kleiner Sketch, mit dem ich die Werte vom Entfernungsmesser in lesbarer Form auf die serielle Schnittstelle ausgebe:

— schnipp —

/*
 * Read values from GP2D12 infrared distance sensor; convert readings to centimeters
 *
 * Version: 0.1 2011.01.05
 * Weblinks:
 *   http://www.hobby-werkstatt-blog.de/
 *   http://www.arduino.cc/playground/Main/ReadGp2d12Range
 */

int pinGp2D12=0;

/*
 * This sensor should be used with a refresh rate of 36ms or greater.
 * Inspired by: Javier Valencia, http://www.arduino.cc/playground/Main/ReadGp2d12Range
 */

float read_gp2d12()
{ int val = analogRead(pinGp2D12);
  if (val < 3) return -1; // invalid value
  float ret = (6787.0 /((float)val - 3.0)) - 4.0;
  if(ret > 80.0)
  return(80.0);
  else
  if(ret < 9.6) return(0.0);
  else return(ret);
} 

void setup()
{ pinMode(pinGp2D12, INPUT); // initialize the digital pin as an output
  Serial.begin(9600);
}

void loop()
{ Serial.println( read_gp2d12());
  delay(1000);
}

— schnapp —

Siehe auch:

Weblinks: