LAGSILVA
Published © CC BY-NC-ND

Digital Clock with Mirrored Display Driven by Accelerometers

This is an amazing digital clock with automatic cancellation of the mirroring effect! Just move it in front of a mirror and be amazed!

BeginnerFull instructions provided30 minutes15,688

Things used in this project

Story

Read more

Code

Mirrored_Clock_Using_Multi_Shield_V2_3.ino

Arduino
Code for Arduino UNO
/*
  Project:  Mirrored Clock with Multi Shield
  Author:   LAGSILVA
  Hardware: Arduino UNO R3 / Multi-Function Shield
  Date:     09.Jul.2018
  License:  Rev 2.3 (Deleted Brightness Control & Added Fahreinheit Temperature Feature)
*/

#define SDA_PORT PORTD
#define SDA_PIN 5
#define SCL_PORT PORTD
#define SCL_PIN 6

#include <SoftWire.h>
#define MPU 0x68                                // I2C address for MPU6050
SoftWire Wire = SoftWire();

#include <Time.h>                               // Time library
#include <TimeLib.h>
#include <MsTimer2.h>                           // Timer library

// Module connection pins (Digital Pins)
#define LATCH_PIN 4                             // Arduino UNO conection on Pin #4  = Latch of Display Module
#define CLK_PIN 7                               // Arduino UNO conection on Pin #7  = Clock of Display Module
#define DATA_PIN 8                              // Arduino UNO conection on Pin #8  = Data of Display Module

#define POT_PIN A0
#define BTN_1_PIN A1
#define BTN_2_PIN A2
#define BTN_3_PIN A3

//    Front:       Upside Down:     Upside Down Mirror:     Front Mirror:
//      A               D                    D                   A
//     ----            ----                 ----                ----
//  F |    | B      C |    | E           E |    | C          B |    | F
//     -G -            -G -                 -G -                -G -
//  E |    | C      B |    | F           F |    | B          C |    | E
//     ----            ----                 ----                ----
//      D               A                    A                   D
//

//   Chars Code
byte N[] = {0xFC, 0x60, 0xDA, 0xF2, 0x66, 0xB6, 0xBE, 0xE0, 0xFE, 0xF6, 0xC6, 0x9C, 0x8E};

int hora, minuto;
int unidadeHora, unidadeMinuto, dezenaHora, dezenaMinuto, delayRefresh;
byte mirror, tempStatus, lastStatus, tCF;
unsigned long ti;
boolean ajustaHora = true, ajustaMinuto = true, mostraTemperatura = true;


//Variaveis para armazenar valores dos sensores
int AcX, AcY, AcZ, Temp;


void setup() {

  pinMode(LATCH_PIN, OUTPUT);
  pinMode(CLK_PIN, OUTPUT);
  pinMode(DATA_PIN, OUTPUT);

  pinMode(POT_PIN, INPUT);
  pinMode(BTN_1_PIN, INPUT);
  pinMode(BTN_2_PIN, INPUT);
  pinMode(BTN_3_PIN, INPUT);

  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);

  MsTimer2::set(120, kbdRead);
  MsTimer2::start();

  Wire.begin();
  Wire.beginTransmission(MPU);
  Wire.write(0x6B);

  //Inicializa o MPU-6050
  Wire.write(0);
  Wire.endTransmission(true);

  mirror = 1;   // Front View (No Mirror)
  tempStatus = 0;
  lastStatus = 0;
  tCF = 0;

}


void loop() {

  delayRefresh = 50;

  Wire.beginTransmission(MPU);
  Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);

  //Solicita os dados do sensor
  Wire.requestFrom(MPU, 14, true);

  //Armazena o valor dos sensores nas variaveis correspondentes
  AcX = Wire.read() << 8 | Wire.read(); //0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
  AcY = Wire.read() << 8 | Wire.read(); //0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  AcZ = Wire.read() << 8 | Wire.read(); //0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
  Temp = Wire.read() << 8 | Wire.read(); //0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)

  AcX = map(AcX, -16384, 16384, -90, 90);
  AcY = map(AcY, -16384, 16384, -90, 90);
  AcZ = map(AcZ, -16384, 16384, -90, 90);
  Temp = map(Temp, -16384, 16384, -40, 85) + 10;              // Personal correction factor for Temperature: +10


  if (-AcY > 0 && AcZ > 0) {
    mirror = 1;                                               // Front View (No Mirror)
  }

  if (AcY > 0 && -AcZ > 0) {
    mirror = 2;                                               // Mirror View
  }

  if (-AcY > 0 && -AcZ > 0) {
    mirror = 3;                                               // Mirror View (Upside Down)
  }

  if (AcY > 0 && AcZ > 0) {
    mirror = 4;                                               // Front View (Upside Down)
  }

  hora = hour();
  minuto = minute();
  unidadeHora = hora % 10;
  dezenaHora = hora / 10;
  unidadeMinuto = minuto % 10;
  dezenaMinuto = minuto / 10;

  if (tempStatus == 0) {                                                        // Display only the Time (HH:MM)

    ti = millis();                                                              // Initial time for blinking dot

    while ((millis() - ti) < delayRefresh) {                                    // Timer in miliseconds to refresh the display


      if (mirror < 3) {                                                         // No Mirror (1) or Front Mirror (2) mode
        displayChars(N[dezenaHora], mirror, 0);                                 // Display Digit 0
        displayChars(N[unidadeHora], mirror, 1);                                // Display Digit 1
        displayChars(N[dezenaMinuto], mirror, 2);                               // Display Digit 2
        displayChars(N[unidadeMinuto], mirror, 3);                              // Display Digit 3
        displayChars(0, 1, 3);                                                  // Clear Digit 3 (last digit)
      }

      if (mirror >= 3) {                                                        // Up Side Down Mirror (3) mode
        displayChars(N[dezenaHora], mirror, 3);                                 // Display Digit 3
        displayChars(N[unidadeHora], mirror, 2);                                // Display Digit 2
        displayChars(N[dezenaMinuto], mirror, 1);                               // Display Digit 1
        displayChars(N[unidadeMinuto], mirror, 0);                              // Display Digit 0
        displayChars(0, 1, 0);                                                  // Clear Digit 0 (last digit)
      }

      displayChars(1, 1, 1);                                                    // Display Dot at Digit 1
      displayChars(0, 1, 1);                                                    // Clear Dot (Blinking Effect)

    }

  }

  if (tempStatus == 1) {                                                        // Display only the Temperature (C or F)

    if (tCF == 1) {
      Temp = Temp * 9 / 5 + 32;
    }

    ti = millis();                                                              // Initial time for blinking dot

    while ((millis() - ti) < delayRefresh ) {                                   // Timer in miliseconds to refresh the display

      if (mirror < 3) {                                                         // No Mirror (1) or Front Mirror (2) mode
        displayChars(N[Temp / 10], mirror, 0);                                  // Display tenth of Temperature
        displayChars(N[Temp % 10], mirror, 1);                                  // Display unit of Temperature
        displayChars(N[10], mirror, 2);                                         // Display symbol of Degrees
        if (tCF == 0) {
          displayChars(N[11], mirror, 3);                                       // Display "C (symbol of Celsius Degrees)
        }
        else {
          displayChars(N[12], mirror, 3);                                       // Display "F" (symbol of Fahrenheit Degrees)
        }
        displayChars(0, 1, 3);                                                  // Clear Digit 3 (last digit)
      }

      if (mirror >= 3) {                                                        // Up Side Down Mirror (3) mode
        displayChars(N[Temp / 10], mirror, 3);                                  // Display tenth of Temperature
        displayChars(N[Temp % 10], mirror, 2);                                  // Display unit of Temperature
        displayChars(N[10], mirror, 1);                                         // Display symbol of Degrees
        if (tCF == 0) {
          displayChars(N[11], mirror, 0);                                       // Display "C (symbol of Celsius Degrees)
        }
        else {
          displayChars(N[12], mirror, 0);                                       // Display "F" (symbol of Fahrenheit Degrees)
        }
        displayChars(0, 1, 0);                                                  // Clear Digit 0 (last digit)
      }

    }

  }

}


void displayChars(byte num, byte statusM, byte disp) {                            // Chars Display Routine

  byte k, charsM = 0;

  if (statusM == 1) {                                                             // No Mirror
    charsM = num;
  }

  if (statusM == 2) {                                                             // Front Mirror
    for (k = 0; k <= 7; k++) {
      charsM = bitWrite(charsM, 7 - k, bitRead(num, k));
    }
    charsM = (charsM << 4 | (charsM << 2) >> 4 & 12 ) | ((charsM & 64) >> 5);
  }

  if (statusM == 3) {                                                             // Upside Down Mirror
    for (k = 0; k <= 7; k++) {
      charsM = bitWrite(charsM, 7 - k, bitRead(num, k));
    }
    charsM = (charsM << 7 | (charsM << 1) & 124 ) | ((charsM & 64) >> 5);
  }

  if (statusM == 4) {                                                             // Front Upside Down
    charsM = ((num >> 2) << 5) | ((num >> 5 ) << 2) | (num & 2);
  }

  digitalWrite(LATCH_PIN, LOW);
  shiftOut(DATA_PIN, CLK_PIN, LSBFIRST, ~charsM);                                 // Display number
  shiftOut(DATA_PIN, CLK_PIN, LSBFIRST, 128 >> disp);                             // Set Digit (0-1-2-3)
  digitalWrite(LATCH_PIN, HIGH);

}


void kbdRead() {        // Push Buttons Reading

  ajustaHora = digitalRead(BTN_1_PIN);
  ajustaMinuto = digitalRead(BTN_2_PIN);
  mostraTemperatura = digitalRead(BTN_3_PIN);

  if (!ajustaHora && tempStatus == 0) {                                           // Set Hour
    adjustTime(3600);
    delayRefresh = 150;
  }

  if (!ajustaMinuto && tempStatus == 0) {                                         // Set Minute
    adjustTime(60);
    delayRefresh = 150;
  }

  if (!mostraTemperatura) {                                                       // Move to Temperature Mode
    tempStatus = (tempStatus + 1) % 2;
    delay(200);
  }

  if (!ajustaHora && tempStatus == 1) {                                           // Set to C or F
    tCF = (tCF + 1) % 2;
    delay(200);
  }

}

Credits

LAGSILVA

LAGSILVA

20 projects • 189 followers
Making original applications for Arduino!

Comments