Heute zeige ich ein Arduino-Projekt, das ich auf MakerWorld.com entdeckt habe. Es handelt sich um eine Uhr, die angetrieben wird mit nur einen Schrittmotor. Faszinierend dabei ist, das der Stundenzeiger scheinbar magnetisch gesteuert wird und somit der Eindruck entsteht das dieser scheinbar in der Luft schwebt.
Es ist ein Remix des Projekts namens “Hollow Clock 4” von Shiura.

Was mich an diesem Projekt aber auch begeistert, ist der durchdachte Antrieb. Auf der Antriebswelle, die mit dem Schrittmotor verbunden ist, sitzt ein Schneckenrad und zusätzlich ein Zahnrad, die gleichzeitig den Stunden- und Minutenzeiger antreiben. Im Video zeige ich detaillierter, wie die Bauteile zusammen gebaut werden und funktionieren.
Hardware:
Nano Board
Stepper Motor 28BYJ-48 5V mit ULN2003 Treiberplatine / Datenblatt
2 Draht USB-C Buchse (Funktioniert mit USB-A Netzteil mit entsprechenden Kabel)
Irgend ein übrig gebliebenes USB-A Netzteil mit Kabel
Selbstschneidende Schraube M2.6×12
Magnete 8x3mm
Ein paar Details zum Schrittmotor 28BYJ-48:
Der Motor hat vier Spulen. Er benötigt 8 Halbschritte pro Umdrehung, was 45° pro Schritt entspricht.
Der Motor hat ein integriertes Getriebe, das die Präzision so verfeinert, das 64 Teilschritte an der Ausgangswelle pro Umdrehung notwendig sind.
In diesem Projekt wird der Motor mit einem ULN2003A-Treibermodul gesteuert, das die Steuerung mit dem Arduino Nano ermöglicht. Das Modul aktiviert die Spulen in der vom Skript vorgegebenen Reihenfolge, so dass sich der Rotor Schritt für Schritt in die gewünschte Richtung bewegt.
Warum USB-A Netzteil:
Da bei der verwendeten USB-C-Buchse nur GND und VBUS verdrahtet wurden, würde ein USB-C-Netzteil auf Pin CC1 oder CC2 kein Signal erhalten, um zu erkennen, dass das angeschlossene Gerät Strom benötigt und die Uhr würde nicht starten.
Das USB-A-Netzteil mit seinen vier Adern liefert den benötigten Strom einfach ohne dieses Startsignal.
Wer es mit einem USB-C Netzteil betreiben will, sollte es mit dieser 6 Draht Buchse versuchen, muss aber zusätzlich den CC-Pins (CC1 oder CC2) mit einem Widerstand (meistens 5.1kΩ) nach GND verbinden.
3D Druck Dateien:
Hollow Clock 4 von shiura Lösung original
+
Hollow Clock 4 Remix Remix und Neugestaltung von rotor- und rear-cover, case mit cap (ohne Verschraubung)
oder
optional das Case Gehäuse mit Öffnung für USB-C Buchse

Begonnen hatte ich damit, mir die zu Verfügung gestellten Dateien anzusehen und mir somit einen ersten Überblick zu verschaffen. Sehr erfreut war ich, als ich sah, dass auch mehrere Sketche für die Arduino IDE mit dabei lagen.
Ein wichtiger Teil dieses Projekts ist der Stundenzeiger, der mit einem Magneten ausgestattet ist. Ich habe festgestellt, dass der Zeiger bei drei und neun Uhr manchmal nach unten fiel, da der Magnet zu schwach war. Daher habe ich den auch beiliegenden 5mm längeren Stundenzeiger nachgedruckt und schon war das Problem beseitigt.
Nachdem alle Teile gedruckt waren, ging es an den Zusammenbau.
Verdrahtung:

Wie man bei der Verdrahtung sehen kann, wird der Nano und das Treiber-Modul direkt von dem USB Netzteil mit Strom versorgt. Das geht in meinem Fall da der eingesetzte Schrittmotor mit 5 Volt läuft.
Nicht in Versuchung geraten, das Treiber-Modul vom Entwicklungsboard zu versorgen, das würde dem Nano nicht gut tun.
Dann habe ich den Schrittmotor mit dem beiliegenden Sketch getestet.
Um Platz im Gehäuse zu erhalten, habe ich das Kabel des Motors deutlich gekürzt.
Und da ich schon mal am löten war, wurden auch gleich die Kabel vom Treiber-Modul zum Arduino mit gekürzt, sowie die zusätzlich Kabel für die externe Stromversorgung hinzugefügt.

Mit den gekürzten Kabeln konnte ich alles kompakter gestalten und besser in das kleine Gehäuse einbauen. Stromkabel geht zu Arduino und Treiber-Modul.

Nachdem ich den Uhrenaufbau montiert und einen kleinen Deckel auf der Rückseite angebracht hatte, sah das Ganze schon sehr schick aus. Siehe erstes Bild oben.
Arduino-Sketch:
Zum Schluss habe ich das Ganze mit dem beiliegenden Test-Sketch bespielt, der den Minutenzeiger jede Sekunde statt alle 60 Sekunden weiterlaufen lässt. Dies ermöglichte eine schnelle Überprüfung der Funktion. (und funktionierte tadellos)
Test-Quellcode:
// wait for a single step of stepper
int delaytime = 1;
// ports used to control the stepper motor
// if your motor rotate to the opposite direction,
// change the order as {5, 4, 3, 2};
int port[4] = {2, 3, 4, 5};
// sequence of stepper motor control
int seq[8][4] = {
{ LOW, HIGH, HIGH, LOW},
{ LOW, LOW, HIGH, LOW},
{ LOW, LOW, HIGH, HIGH},
{ LOW, LOW, LOW, HIGH},
{ HIGH, LOW, LOW, HIGH},
{ HIGH, LOW, LOW, LOW},
{ HIGH, HIGH, LOW, LOW},
{ LOW, HIGH, LOW, LOW}
};
void rotate(int step) {
static int phase = 0;
int i, j;
int delta = (step > 0) ? 1 : 7;
step = (step > 0) ? step : -step;
for(j = 0; j < step; j++) {
phase = (phase + delta) % 8;
for(i = 0; i < 4; i++) {
digitalWrite(port[i], seq[phase][i]);
}
delay(delaytime);
}
// power cut
for(i = 0; i < 4; i++) {
digitalWrite(port[i], LOW);
}
}
void setup() {
pinMode(port[0], OUTPUT);
pinMode(port[1], OUTPUT);
pinMode(port[2], OUTPUT);
pinMode(port[3], OUTPUT);
}
void loop() {
for(int i = 0; i < 10; i++) {
rotate(-512*11);
}
// delay(1000);
}
Das finale Original-Sketch, veranlasst den Motor etwa alle 60 Sekunden kurz anzulaufen. Jetzt muss sich zeigen wie genau die Uhr dann läuft.
Finaler Quellcode:
// Hollow Clock 4 from Shiura - thingiverse
// Please tune the following value if the clock gains or loses.
// Theoretically, standard of this value is 60000.
#define MILLIS_PER_MIN 60000 // milliseconds per a minute
// Motor and clock parameters
// 4096 * 90 / 12 = 30720
#define STEPS_PER_ROTATION 30720 // steps for a full turn of minute rotor
// wait for a single step of stepper
int delaytime = 2;
// ports used to control the stepper motor
// if your motor rotate to the opposite direction,
// change the order as {5, 4, 3, 2};
int port[4] = {2, 3, 4, 5};
// sequence of stepper motor control
int seq[8][4] = {
{ LOW, HIGH, HIGH, LOW},
{ LOW, LOW, HIGH, LOW},
{ LOW, LOW, HIGH, HIGH},
{ LOW, LOW, LOW, HIGH},
{ HIGH, LOW, LOW, HIGH},
{ HIGH, LOW, LOW, LOW},
{ HIGH, HIGH, LOW, LOW},
{ LOW, HIGH, LOW, LOW}
};
void rotate(int step) {
static int phase = 0;
int i, j;
int delta = (step > 0) ? 1 : 7;
int dt = 20;
step = (step > 0) ? step : -step;
for(j = 0; j < step; j++) {
phase = (phase + delta) % 8;
for(i = 0; i < 4; i++) {
digitalWrite(port[i], seq[phase][i]);
}
delay(dt);
if(dt > delaytime) dt--;
}
// power cut
for(i = 0; i < 4; i++) {
digitalWrite(port[i], LOW);
}
}
void setup() {
pinMode(port[0], OUTPUT);
pinMode(port[1], OUTPUT);
pinMode(port[2], OUTPUT);
pinMode(port[3], OUTPUT);
rotate(-20); // for approach run
rotate(20); // approach run without heavy load
rotate(STEPS_PER_ROTATION / 60);
}
void loop() {
static long prev_min = 0, prev_pos = 0;
long min;
static long pos;
min = millis() / MILLIS_PER_MIN;
if(prev_min == min) {
return;
}
prev_min = min;
pos = (STEPS_PER_ROTATION * min) / 60;
rotate(-20); // for approach run
rotate(20); // approach run without heavy load
if(pos - prev_pos > 0) {
rotate(pos - prev_pos);
}
prev_pos = pos;
}
Sollte die Uhr zu schnell die falsche Uhrzeit zeigen, werde ich die Lösung um ein RealTimeClock Modul DS3231 erweitern. Mal sehen…
Video:
Update nach 4 Wochen:
Die Uhr lief bisher 4 Wochen ohne Probleme und zeigte immer die richtige Uhrzeit an.
Heute jedoch hatte die Antriebswelle das lose liegende Antriebsrad nach oben gedrückt und die Zeiger blieben stehen.
Ich hatte alle Bauteile die alle samt am 3D Drucker mit einer 0,4 mm Düse (Nozzles) gedruckt wurden, nun mit einer 0,2 mm Düse für den Antrieb neu gedruckt.

Bild: Deutlich zu sehen, links die feinere Oberfläche.
Mal sehen, ob das Problem damit gelöst wurde