Created
November 3, 2021 06:32
-
-
Save jasongao97/a62ca38fb93f0e5152428d2f3c51e19e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
'Time Globe' - A lamp clock that shows time by the angle of its light | |
Midterm for 'Time' by Jason Gao | |
10/25/2021 | |
*/ | |
#include <Servo.h> | |
#include <Adafruit_NeoPixel.h> | |
#include <IRremote.h> | |
// PINS | |
#define PIN_SPIN_DIR 0 | |
#define PIN_SPIN_STEP 1 | |
#define PIN_SPIN_RST 2 | |
#define PIN_IR 3 | |
#define PIN_SPIN_M2 4 | |
#define PIN_SPIN_M1 5 | |
#define PIN_SPIN_M0 6 | |
#define PIN_TILT 9 | |
#define PIN_LED 10 | |
#define NUM_OF_MODE 5 | |
#define NUM_OF_LED 13 | |
#define STEP_PER_REVOLUTION 6400 | |
// The step pin stay HIGH for 2 milliseconds | |
// according to https://www.ti.com/lit/ds/symlink/drv8825.pdf | |
#define STEP_LOW_DURATION 2 | |
// IR protocol(s) | |
#define DECODE_NEC | |
Servo tilt; | |
Adafruit_NeoPixel pixels(NUM_OF_LED, PIN_LED, NEO_GRBW + NEO_KHZ800); | |
// https://en.wikipedia.org/wiki/Axial_tilt | |
// Earth (real) / Earth (present) / Venus / Jupiter / Neptune | |
const unsigned int milPerStep[NUM_OF_MODE] = {13500, 4, 8, 1, 2}; | |
const unsigned int maxTilt[NUM_OF_MODE] = {66, 66, 7, 9, 80}; | |
const bool rotateDir[NUM_OF_MODE] = {HIGH, HIGH, LOW, HIGH, HIGH}; | |
const uint32_t oneColor[NUM_OF_MODE] = {0x01000000, 0xaa000000, 0x00d1bda9, 0x00a35f31, 0x001757cc}; | |
byte mode = 0; | |
unsigned long lastMoment = 0; | |
byte currentStep = 0; | |
bool currentDir = rotateDir[mode]; | |
uint32_t currentColor = oneColor[mode]; | |
void setup() { | |
Serial.begin(9600); | |
Serial.println("Hello Planetime"); | |
// declare pins as output | |
pinMode(PIN_SPIN_DIR, OUTPUT); | |
pinMode(PIN_SPIN_STEP, OUTPUT); | |
pinMode(PIN_SPIN_RST, OUTPUT); | |
pinMode(PIN_SPIN_M0, OUTPUT); | |
pinMode(PIN_SPIN_M1, OUTPUT); | |
pinMode(PIN_SPIN_M2, OUTPUT); | |
digitalWrite(PIN_SPIN_M0, HIGH); | |
digitalWrite(PIN_SPIN_M1, HIGH); | |
digitalWrite(PIN_SPIN_M2, HIGH); | |
digitalWrite(PIN_SPIN_RST, HIGH); | |
tilt.attach(PIN_TILT); | |
// init neopixels | |
pixels.begin(); | |
for (int i = 0; i < NUM_OF_LED; i++) { | |
pixels.setPixelColor(i, oneColor[mode]); | |
} | |
pixels.show(); | |
IrReceiver.begin(PIN_IR); | |
} | |
void loop() { | |
decodeCommand(); | |
spin(); | |
updateAttr(); | |
} | |
/** | |
Decode IR command and update attributes | |
*/ | |
void decodeCommand() { | |
if (IrReceiver.decode()) { | |
IrReceiver.printIRResultShort(&Serial); | |
IrReceiver.resume(); | |
if (IrReceiver.decodedIRData.command == 0x45) { | |
// 1 | |
mode = 0; | |
} else if (IrReceiver.decodedIRData.command == 0x46) { | |
// 2 | |
mode = 1; | |
} else if (IrReceiver.decodedIRData.command == 0x47) { | |
// 3 | |
mode = 2; | |
} else if (IrReceiver.decodedIRData.command == 0x44) { | |
// 4 | |
mode = 3; | |
} | |
} | |
} | |
/** | |
Update Color and Direction | |
*/ | |
void updateAttr() { | |
if (oneColor[mode] != currentColor) { | |
currentColor = oneColor[mode]; | |
for (int i = 0; i < NUM_OF_LED; i++) { | |
pixels.setPixelColor(i, oneColor[mode]); | |
} | |
pixels.show(); | |
} | |
if (rotateDir[mode] != currentDir) { | |
digitalWrite(PIN_SPIN_DIR, rotateDir[mode]); | |
currentDir = rotateDir[mode]; | |
} | |
} | |
/** | |
Spin the light and adjust tilt | |
*/ | |
void spin() { | |
unsigned long present = millis(); | |
if (present - lastMoment > milPerStep[mode]) { | |
// one step | |
digitalWrite(PIN_SPIN_STEP, HIGH); | |
delayMicroseconds(STEP_LOW_DURATION); | |
digitalWrite(PIN_SPIN_STEP, LOW); | |
// adjust the tilt | |
int angle = sin(double(currentStep) / STEP_PER_REVOLUTION * 2 * PI) * maxTilt[mode] * 2 - maxTilt[mode] + 1520; | |
tilt.writeMicroseconds(angle); | |
// record the step | |
currentStep += 1; | |
if (currentStep >= STEP_PER_REVOLUTION) currentStep = 0; | |
lastMoment = present; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment