227 lines
5.9 KiB
C++
227 lines
5.9 KiB
C++
#include <CapacitiveSensor.h>
|
|
|
|
#define SERIAL_DEBUG 0
|
|
|
|
#define MODE_NORMAL 0
|
|
#define MODE_SETTIME 1
|
|
#define MODE_SETALARM 2
|
|
|
|
#define PIN_BUTTON 3
|
|
#define PIN_BUZZER 5
|
|
#define PIN_REG_CLOCK 7
|
|
#define PIN_REG_DATA 4
|
|
#define PIN_REG_LATCH 6
|
|
#define PIN_TOUCH_0 11
|
|
#define PIN_TOUCH_1 10
|
|
#define PIN_TOUCH_2 2
|
|
#define PIN_TOUCH_3 9
|
|
#define PIN_TOUCH_COM A1
|
|
|
|
CapacitiveSensor touch_0 = CapacitiveSensor(PIN_TOUCH_COM, PIN_TOUCH_0);
|
|
CapacitiveSensor touch_1 = CapacitiveSensor(PIN_TOUCH_COM, PIN_TOUCH_1);
|
|
CapacitiveSensor touch_2 = CapacitiveSensor(PIN_TOUCH_COM, PIN_TOUCH_2);
|
|
CapacitiveSensor touch_3 = CapacitiveSensor(PIN_TOUCH_COM, PIN_TOUCH_3);
|
|
|
|
// Matrix state
|
|
unsigned char matrix[8] = {0b10000001, 0, 0, 0, 0, 0, 0, 0b10000001};
|
|
unsigned char matrix_row_on = 0;
|
|
|
|
// Interface mode
|
|
unsigned char mode = MODE_NORMAL;
|
|
|
|
// Selected number (0..4: None, Hour, Minute, Second)
|
|
unsigned char number_selection = 0;
|
|
|
|
// Time added to internal clock, to fit real time
|
|
unsigned long time_offset = 0;
|
|
|
|
unsigned char alarm = false;
|
|
|
|
unsigned long alarm_time = 0;
|
|
|
|
// Is alarm ringing
|
|
unsigned char alarm_ringing = false;
|
|
unsigned long alarm_ring_start;
|
|
|
|
unsigned long last_light_measure = 0;
|
|
|
|
unsigned long touch_time[4] = {0, 0, 0, 0};
|
|
unsigned long last_touch_measure = 0;
|
|
unsigned char touch_step = 0;
|
|
|
|
// Bytewise reverse
|
|
unsigned char reverse(unsigned char b) {
|
|
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
|
|
b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
|
|
b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
|
|
return b;
|
|
}
|
|
|
|
unsigned char fix_pixels(unsigned char b) {
|
|
return (b << 1) | (b >> 7);
|
|
}
|
|
|
|
void shift_matrix() {
|
|
digitalWrite(PIN_REG_LATCH, LOW);
|
|
shiftOut(PIN_REG_DATA, PIN_REG_CLOCK, MSBFIRST, ~(1 << matrix_row_on));
|
|
shiftOut(PIN_REG_DATA, PIN_REG_CLOCK, MSBFIRST, fix_pixels(matrix[(matrix_row_on+7)%8]));
|
|
digitalWrite(PIN_REG_LATCH, HIGH);
|
|
matrix_row_on = (matrix_row_on + 1) % 8;
|
|
}
|
|
|
|
void draw_time(unsigned long t) {
|
|
unsigned char seconds = t/1000%60;
|
|
unsigned char minutes = t/60000%60;
|
|
unsigned char hours = t/3600000%24;
|
|
matrix[1] = reverse(seconds) >> 1;
|
|
matrix[2] = matrix[1];
|
|
matrix[3] = reverse(minutes) >> 1;
|
|
matrix[4] = matrix[3];
|
|
matrix[5] = reverse(hours) >> 1;
|
|
matrix[6] = matrix[5];
|
|
}
|
|
|
|
void draw_mode() {
|
|
switch(mode) {
|
|
case MODE_NORMAL: matrix[0] = 0b10000001; break;
|
|
case MODE_SETTIME: matrix[0] = 0b10011001; break;
|
|
case MODE_SETALARM: matrix[0] = 0b10111101; break;
|
|
}
|
|
if(alarm) matrix[0] |= 0b01000010;
|
|
}
|
|
|
|
void draw_number_selection() {
|
|
switch(number_selection) {
|
|
case 1: matrix[1] |= 0b10000001; break;
|
|
case 2: matrix[3] |= 0b10000001; break;
|
|
case 3: matrix[5] |= 0b10000001; break;
|
|
}
|
|
}
|
|
|
|
const unsigned char HEX_ALPHA[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
|
|
void send_hex(unsigned long val) {
|
|
Serial.write(HEX_ALPHA[(val >> 28) & 0xf]);
|
|
Serial.write(HEX_ALPHA[(val >> 24) & 0xf]);
|
|
Serial.write(HEX_ALPHA[(val >> 20) & 0xf]);
|
|
Serial.write(HEX_ALPHA[(val >> 16) & 0xf]);
|
|
Serial.write(HEX_ALPHA[(val >> 12) & 0xf]);
|
|
Serial.write(HEX_ALPHA[(val >> 8) & 0xf]);
|
|
Serial.write(HEX_ALPHA[(val >> 4) & 0xf]);
|
|
Serial.write(HEX_ALPHA[val & 0xf]);
|
|
Serial.write('\n');
|
|
}
|
|
|
|
void setup() {
|
|
pinMode(PIN_REG_DATA, OUTPUT);
|
|
pinMode(PIN_REG_CLOCK, OUTPUT);
|
|
pinMode(PIN_REG_LATCH, OUTPUT);
|
|
pinMode(PIN_BUZZER, OUTPUT);
|
|
pinMode(PIN_BUTTON, INPUT_PULLUP);
|
|
|
|
pinMode(13, OUTPUT);
|
|
digitalWrite(13, LOW);
|
|
|
|
#if SERIAL_DEBUG
|
|
Serial.begin(9600);
|
|
#endif
|
|
}
|
|
|
|
void loop() {
|
|
#if SERIAL_DEBUG
|
|
send_hex(touch_0.capacitiveSensor(10));
|
|
send_hex(touch_1.capacitiveSensor(10));
|
|
send_hex(touch_2.capacitiveSensor(10));
|
|
send_hex(touch_3.capacitiveSensor(10));
|
|
delay(100);
|
|
#endif
|
|
|
|
// Calibrate the thresholds according to your resistors
|
|
if(millis() > last_touch_measure + 15) {
|
|
switch(touch_step) {
|
|
case 0:
|
|
if(touch_0.capacitiveSensor(10) > 126 && millis() > touch_time[0] + 250) {
|
|
touch_time[0] = millis();
|
|
mode = (mode+1) % 3;
|
|
stop_ringing();
|
|
}
|
|
break;
|
|
case 1:
|
|
if(touch_1.capacitiveSensor(10) > 126 && millis() > touch_time[1] + 250) {
|
|
touch_time[1] = millis();
|
|
number_selection = (number_selection+1) % 4;
|
|
stop_ringing();
|
|
}
|
|
break;
|
|
case 2:
|
|
if(touch_2.capacitiveSensor(10) > 31 && millis() > touch_time[2] + 150) {
|
|
touch_time[2] = millis();
|
|
change_selected_number(1);
|
|
stop_ringing();
|
|
}
|
|
break;
|
|
case 3:
|
|
if(touch_3.capacitiveSensor(10) > 31 && millis() > touch_time[3] + 150) {
|
|
touch_time[3] = millis();
|
|
change_selected_number(-1);
|
|
stop_ringing();
|
|
}
|
|
}
|
|
touch_step = (touch_step + 1) % 4;
|
|
last_touch_measure = millis();
|
|
}
|
|
|
|
if(alarm && !alarm_ringing) {
|
|
unsigned long t = ((millis() + time_offset) / 1000) % 86400;
|
|
if(alarm_time / 1000 == t) {
|
|
alarm_ringing = true;
|
|
alarm_ring_start = millis();
|
|
}
|
|
}
|
|
|
|
if(alarm_ringing) {
|
|
if(millis()%1000 < 100) {
|
|
matrix[7] = 0b11111111;
|
|
analogWrite(PIN_BUZZER, 1);
|
|
} else {
|
|
matrix[7] = 0b10000001;
|
|
digitalWrite(PIN_BUZZER, LOW);
|
|
}
|
|
if(digitalRead(PIN_BUTTON) == LOW) {
|
|
stop_ringing();
|
|
}
|
|
}
|
|
|
|
draw_mode();
|
|
if(mode == MODE_SETALARM)
|
|
draw_time(alarm_time);
|
|
else
|
|
draw_time(millis() + time_offset);
|
|
draw_number_selection();
|
|
shift_matrix();
|
|
}
|
|
|
|
void change_selected_number(signed int nb) {
|
|
switch(mode) {
|
|
case MODE_NORMAL:
|
|
if(nb > 0) alarm = true;
|
|
else if(nb < 0) alarm = false;
|
|
case MODE_SETTIME: change_time(&time_offset, nb); break;
|
|
case MODE_SETALARM: change_time(&alarm_time, nb); break;
|
|
}
|
|
}
|
|
|
|
void change_time(unsigned long *t, signed int mul) {
|
|
switch(number_selection) {
|
|
case 1: *t += mul * 1000; break;
|
|
case 2: *t += mul * 60000; break;
|
|
case 3: *t += mul * 3600000; break;
|
|
}
|
|
*t %= 86400000;
|
|
}
|
|
|
|
void stop_ringing() {
|
|
digitalWrite(PIN_BUZZER, LOW);
|
|
matrix[7] = 0b10000001;
|
|
alarm_ringing = false;
|
|
}
|