Mr_Xu
Published © GPL3+

Sundials Are Boring, Use Lasers Instead

A sundial type clock with stepper motors and lasers to show hour and minute.

IntermediateWork in progress2,967
Sundials Are Boring, Use Lasers Instead

Things used in this project

Hardware components

Arduino UNO
Arduino UNO
×1
Stepper motor driver board A4988
SparkFun Stepper motor driver board A4988
×2
28BYJ-48 stepper motor
×2
Photo interrupter
×1
Linear Laser
×2
Breadboard (generic)
Breadboard (generic)
×1

Hand tools and fabrication machines

Hot glue gun (generic)
Hot glue gun (generic)

Story

Read more

Schematics

Circuit diagram Laserclock

Schematics

Code

Dual Laser Clock with stepper motors

Arduino
A different way to show time.
//Dual steppermotor clock with lasers

// communication with RTC and RTC lib
#include <Wire.h>
#include "RTClib.h"

RTC_DS3231 rtc;

//stepper variables and lib

#include <Stepper.h>
#define STEPS 2038 // the number of steps in one revolution of your motor (28BYJ-48)
Stepper stepper1(STEPS, 8, 10, 9, 11); //minute stepper
Stepper stepper2(STEPS, 4, 6, 5, 7); //hour stepper
int startup = 0; // counter for resetting stepperposition
int Led = 13; // define LED pin
int buttonpin = 3; // define photo interrupter signal pin
int val; //define a numeric variable

// Startup, RTC check, calibration of steppers, adjusting steppers to current time
void setup()
{

  // RTC Time input
  Serial.begin(9600);
  delay(3000); // wait for console opening
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

  //Steppermotor calibration
  pinMode(Led, OUTPUT); // LED pin as output
  pinMode(buttonpin, INPUT); //photo interrupter pin as input

  // minute stepper calibration
  do {
    val = digitalRead(buttonpin); //read the value of the photointerrupter
    if (val == HIGH) // turn on LED when photointerrupter is blocked
    {
      stepper1.setSpeed(10); // 10 rpm
      stepper1.step(-50); // 50 steps from resetpoint
      startup = startup + 1;
      digitalWrite(Led, HIGH);
    }
    else
    {
      stepper1.setSpeed(5); // 5 rpm
      stepper1.step(1); // stepping towards photointerrupter
      digitalWrite(Led, LOW);
    }
  } while (startup < 2);
  // hour stepper calibration
  do {
    val = digitalRead(buttonpin); //read the value of the photointerrupter
    if (val == HIGH) // turn on LED when photointerrupter is blocked
    {
      stepper2.setSpeed(10); // 10 rpm
      stepper2.step(50); // 50 steps from resetpoint
      startup = startup + 1;
      digitalWrite(Led, HIGH);
    }
    else
    {
      stepper2.setSpeed(5); // 5 rpm
      stepper2.step(-1); // stepping towards photointerrupter
      digitalWrite(Led, LOW);
    }
  } while (startup < 4);
  startup = 0;
  digitalWrite(Led, LOW);


  // time check with RTC
  DateTime now = rtc.now();

  // adjusting steppers to current time
  stepper1.setSpeed(10); // 10 rpm
  stepper1.step(- now.minute() * 15); // adjust minute stepper

  stepper2.setSpeed(10); // 10 rpm
  if (now.hour() >= 12) {
    stepper2.step((now.hour() - 12) * 60 + now.minute()); // adjust hour stepper
  }
  else if (now.hour() <= 12) {
    stepper2.step(now.hour() * 60 + now.minute()); //  adjust hour stepper
  }

  // 90-96 control for testing purpose only
  Serial.print("Time ");
  Serial.print(now.hour());
  Serial.print(":");
  Serial.print(now.minute());
  Serial.print(":");
  Serial.print(now.second());
  Serial.println("");

}

// startup loop with 12:00:00, 0:00:00 and hourly resets of stepper. Stepper minute increment
void loop()
{

  // update of RTC time
  DateTime now = rtc.now();

  // Reset minute and hour stepper at 12:00:00
  if (now.hour() == 12 && now.minute() == 00 && now.second() == 00) {

    // minute stepper calibration
    do {
      val = digitalRead(buttonpin); //read the value of the photointerrupter
      if (val == HIGH) // turn on LED when photointerrupter is blocked
      {
        stepper1.setSpeed(10); // 10 rpm
        stepper1.step(-50); // 50 steps from resetpoint
        startup = startup + 1;
        digitalWrite(Led, HIGH);
      }
      else
      {
        stepper1.setSpeed(5); // 5 rpm
        stepper1.step(1); // stepping towards photointerrupter
        digitalWrite(Led, LOW);
      }
    } while (startup < 2);
    // hour stepper calibration
    do {
      val = digitalRead(buttonpin); //read the value of the photointerrupter
      if (val == HIGH) // turn on LED when photointerrupter is blocked
      {
        stepper2.setSpeed(10); // 10 rpm
        stepper2.step(50); // 50 steps from resetpoint
        startup = startup + 1;
        digitalWrite(Led, HIGH);
      }
      else
      {
        stepper2.setSpeed(5); // 5 rpm
        stepper2.step(-1); // stepping towards photointerrupter
        digitalWrite(Led, LOW);
      }
    } while (startup < 4);
    startup = 0;
    digitalWrite(Led, LOW);

    // delay so that event does not repeat
    delay(1000);
  }

  // stepper motor reset at 0:00:00
  if (now.hour() == 00 && now.minute() == 00 && now.second() == 00) {

    // minute stepper calibration
    do {
      val = digitalRead(buttonpin); //read the value of the photointerrupter
      if (val == HIGH) // turn on LED when photointerrupter is blocked
      {
        stepper1.setSpeed(10); // 10 rpm
        stepper1.step(-50); // 50 steps from resetpoint
        startup = startup + 1;
        digitalWrite(Led, HIGH);
      }
      else
      {
        stepper1.setSpeed(5); // 5 rpm
        stepper1.step(1); // stepping towards photointerrupter
        digitalWrite(Led, LOW);
      }
    } while (startup < 2);
    // hour stepper calibration
    do {
      val = digitalRead(buttonpin); //read the value of the photointerrupter
      if (val == HIGH) // turn on LED when photointerrupter is blocked
      {
        stepper2.setSpeed(10); // 10 rpm
        stepper2.step(50); // 50 steps from resetpoint
        startup = startup + 1;
        digitalWrite(Led, HIGH);
      }
      else
      {
        stepper2.setSpeed(5); // 5 rpm
        stepper2.step(-1); // stepping towards photointerrupter
        digitalWrite(Led, LOW);
      }
    } while (startup < 4);
    startup = 0;
    digitalWrite(Led, LOW);

    // delay so that event does not repeat
    delay(1000);

  }

  // hourly minute stepper reset

  if (now.minute() == 0 && now.second() == 0 ) {

    do {
      val = digitalRead(buttonpin); //read the value of the photointerrupter
      if (val == HIGH) // turn on LED when photointerrupter is blocked
      {
        stepper1.setSpeed(10); // 10 rpm
        stepper1.step(-50); // 50 steps from resetpoint
        startup = startup + 1;
        digitalWrite(Led, HIGH);
      }
      else
      {
        stepper1.setSpeed(5); // 5 rpm
        stepper1.step(1); // stepping towards photointerrupter
        digitalWrite(Led, LOW);
      }
    } while (startup < 2);

    startup = 0;
    digitalWrite(Led, LOW);

    // delay so that event does nor repeat
    delay(1000);

  }

  // minute stepper one minute increment, hourstepper one minute increment

  if (now.second() == 59) {

    stepper1.setSpeed(10); // 1 rpm
    stepper1.step(-15); // 15 stepps equals one minute

    stepper2.setSpeed(10); // 10 rpm
    stepper2.step(1); // 1 stepp equals one minute on hour steppper

    // delay so that event does not repeat
    delay(1000);

  }

  digitalWrite(Led, LOW);

}

Credits

Mr_Xu

Mr_Xu

0 projects • 3 followers

Comments