Arduino/LaserClock/LaserClock.ino

185 lines
3.9 KiB
C++

/*
* author: MrBesen
*
* Program for a binary laser clock
*
* Setup: a Button on pin 12, Led pin 13, Laser / LED on pin 2-11 needs to be pwm! RTC-Modul DS3231 required, AmbientLightSensor on pin A0
*
*/
#include <Wire.h>
#include "DS3231.h"
DS3231 clock;
#define lightsens 1
#if lightsens
#define lightsensorpin A0
#define lightoff 1010
#define lighton 980
const size_t messure_size = 20;
unsigned short messure[messure_size];
size_t messure_pos = 0;
unsigned long messure_add = 0;
#endif
//pins for hour display
const unsigned char H[] = {8,9,10,11};
//pins for min display
const unsigned char M[] = {2,3,4,5,6,7};
//intensity of laser, when "off": 0 -> 0% on; 255 -> 100% on
const unsigned int offtime = 170;
//lowbrightnes values
const unsigned char offtime_lb = 140;
const unsigned char ontime_lb = 185;
bool brightmode = true;
bool houtremp;
inline bool pressed() {
return digitalRead(12) == LOW;
}
void set(const unsigned char pin, bool on) {
if(on) {
if(brightmode) {
digitalWrite(pin, HIGH);
} else {
analogWrite(pin, ontime_lb);
}
} else {
analogWrite(pin, brightmode ? offtime : offtime_lb);
}
}
//prints the data to the lasers, write(0,0)-> all off, write()-> all on
void write(unsigned char m = 255, unsigned char h = 255) {
//write minutes
for(unsigned char i = 0; i < 6; i++) {
set(M[i], m & (1 << i));
}
//write hour
for(unsigned char i = 0; i < 4; i++) {
set(H[i], h & (1 << i));
}
}
inline void writeTime() {
write(clock.getMinute(), clock.getHour(houtremp, houtremp));
}
void setup() {
pinMode(13, OUTPUT); // Pin 13 LED
//setup clock modul
Wire.begin();
clock.setClockMode(true); //set 12h format
clock.turnOffAlarm(1);//disable Arlam
clock.turnOffAlarm(2);
//Setup pins
for(unsigned char m = 0; m < 6; m++) {
pinMode(M[m], OUTPUT);
}
for(unsigned char h = 0; h < 4; h++) {
pinMode(H[h], OUTPUT);
}
pinMode(12, INPUT_PULLUP); // button
//setup messure array
int brightness = analogRead(lightsensorpin);
for(int i = 0; i < messure_size; i++) {
messure[i] = brightness;
}
messure_add = brightness * messure_size;
}
void blink() {
for(int i = 0; i < 6; i++) {
write(0, 0); // full off
delay(300);
write(); // full on
delay(300);
}
}
void setTime() {
while(pressed()) delay(5); // wait for not pressed anymore
write(); // full on
while(!pressed()) delay(5); //wait for press
//setup time
char mode = 0;//mode = 0-> set hour, mode = 1 -> set min, mode = 2 -> exit setup
bool pres = true;//was button pressed
unsigned long timeout = millis();
writeTime();
while(mode < 2) {
if(pressed()) { //button is pressed
if(!pres) { //button was not pressed before
timeout = millis(); //reset timeout
pres = true;
if(mode == 0) {//count hour
byte hour = clock.getHour(houtremp, houtremp)+1;
clock.setHour(hour == 13 ? 1 : hour);
} else {//count min
byte minute = clock.getMinute()+1;
clock.setMinute(minute == 60 ? 0 : minute);
}
writeTime();
}
} else {
pres = false;
}
if(millis() - timeout > 10000) { //timed out (button not pressed for 10s)
blink();
writeTime();
++mode;//next mode
//reset timeout
timeout = millis();
}
delay(50);
}
}
void loop() {
//update min
byte hour = clock.getHour(houtremp, houtremp);
if(hour > 12)
hour -=12;
clock.setHour(hour);
write(clock.getMinute(), hour);
//let the led blink
digitalWrite(13, millis()/1000 % 2 == 0);
delay(500);
if(pressed()) {
setTime();
}
//update lighting values
#if lightsens
unsigned short brightness = analogRead(lightsensorpin);//messure
messure_add -= messure[messure_pos]; //remove old value from avg
messure[messure_pos] = brightness; //add to array
messure_add += brightness; //add to avg
if((++messure_pos) == messure_size)//increment pos, check range
messure_pos = 0; //reset
unsigned short bavg = messure_add / messure_size;
if(bavg < lighton) {
brightmode = true;
} else if(bavg > lightoff) {
brightmode = false;
}
#endif
}