Skip to content

Commit a84bcc9

Browse files
committed
all working, I think!
1 parent bdb8067 commit a84bcc9

25 files changed

+737
-538
lines changed

arduino-ledclock.ino

Lines changed: 13 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -3,59 +3,24 @@
33
// Based largely on public domain and Arduino code, with other sources mentioned herein
44

55
#include "config.h"
6+
#include RTC_H
7+
#include INPUTS_H
8+
#include NETWORK_H
9+
#include DISPLAY_H
10+
#include "controller.h"
611

712
void setup() {
813
Serial.begin(9600); while(!Serial); //only works on 33 IOT
9-
// rtcSetup();
10-
// inputsSetup();
11-
// networkSetup();
1214
displaySetup();
15+
rtcSetup();
16+
inputsSetup();
17+
networkSetup();
1318
}
1419

1520
void loop() {
16-
checkSerialInput();
17-
// rtcLoop();
18-
// inputsLoop();
19-
// networkLoop();
21+
checkSerialInput(); //controller
22+
rtcLoop();
23+
inputsLoop();
24+
networkLoop();
2025
displayLoop();
21-
}
22-
23-
// void ctrlEvt(byte ctrl, byte evt){ //called by the input interface
24-
// Serial.print(F("Btn "));
25-
// switch(ctrl){
26-
// case mainSel: Serial.print(F("mainSel ")); break;
27-
// case mainAdjDn: Serial.print(F("mainAdjDn ")); break;
28-
// case mainAdjUp: Serial.print(F("mainAdjUp ")); break;
29-
// case altSel: Serial.print(F("altSel ")); break;
30-
// default: break;
31-
// }
32-
// switch(evt){
33-
// case 1: Serial.println(F("pressed")); break;
34-
// case 2: Serial.println(F("short-held")); break;
35-
// case 3: Serial.println(F("long-held")); break;
36-
// case 0: Serial.println(F("released")); Serial.println(); break;
37-
// default: break;
38-
// }
39-
// if(ctrl==mainSel && evt==4) networkStartAdmin(); //very long hold
40-
//
41-
// } //end ctrlEvt
42-
//
43-
//
44-
//
45-
// //Serial input for control
46-
// int incomingByte = 0;
47-
// void checkSerialInput(){
48-
// if(Serial.available()>0){
49-
// incomingByte = Serial.read();
50-
// switch(incomingByte){
51-
// case 97: //a
52-
// networkStartAdmin(); break;
53-
// //networkStartAP(); break;
54-
// case 119: //w
55-
// networkStartWiFi(); break;
56-
// case 100: //d
57-
// networkDisconnectWiFi(); break;
58-
// default: break;
59-
// }
60-
// }
61-
// }
26+
}

config.h

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,43 @@
1-
#ifndef CONFIG_HEADER
2-
#define CONFIG_HEADER
1+
#ifndef CONFIG_H
2+
#define CONFIG_H
33

44

5-
////////// DISPLAY //////////
5+
//Which display?
66
#define DISPLAY_H "display-MAX7219.h"
7-
#include DISPLAY_H
87

9-
////////// INPUTS //////////
10-
#define INPUTS_H "inputs-LSM6DS3.h"
8+
9+
//Which inputs?
1110
//#define INPUTS_H "inputs-none.h"
12-
#include INPUTS_H
11+
#define INPUTS_H "inputs-LSM6DS3.h"
12+
13+
//What pins are associated with each input? (if using the LSM6DS3, just use any unique ints such as 1,2,3,4)
14+
//As the IMU "buttons" don't have pins, these are made-up values.
15+
const byte mainSel = 1;
16+
const byte mainAdjUp = 2;
17+
const byte mainAdjDn = 3;
18+
const byte altSel = 4;
19+
20+
const word btnShortHold = 1000; //for setting the displayed feataure
21+
const word btnLongHold = 3000; //for for entering options menu
22+
const word btnVeryLongHold = 5000; //for wifi IP info / AP start / admin start
23+
const word btnSuperLongHold = 15000; //for wifi forget
24+
25+
const int imuTestCountTrigger = 60; //IMU debouncing: how many test count needed to change the reported state
26+
27+
28+
//Which RTC?
29+
#define RTC_H "rtc-fake.h"
30+
//#define RTC_H "rtc-RTCZero.h"
31+
//#define RTC_H "rtc-DS3231.h"
32+
33+
34+
//Which network?
35+
//#define NETWORK_H "network-none.h"
36+
#define NETWORK_H "network-wifinina.h"
1337

14-
////////// RTC //////////
15-
#include "rtc-fake.h"
16-
//#include "rtc-RTCZero.h"
17-
//#include "rtc-DS3231.h"
1838

19-
////////// NETWORK //////////
20-
#include "network-wifinina.h"
21-
//#include "network-none.h"
39+
//Other stuff
40+
#define OFFSET -21600+3600 //we are this many seconds behind UTC
2241

2342

2443
#endif

controller.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
//controller.cpp
2+
3+
#include "Arduino.h"
4+
#include "config.h" //includes consts used here
5+
//#include "controller.h" //definitions for your own functions - needed only if calling functions before they're defined
6+
#include NETWORK_H //networkStartAdmin etc
7+
8+
void ctrlEvt(uint8_t ctrl, uint8_t evt){ //called by the input interface
9+
Serial.print(F("Btn "));
10+
switch(ctrl){
11+
case mainSel: Serial.print(F("mainSel ")); break;
12+
case mainAdjDn: Serial.print(F("mainAdjDn ")); break;
13+
case mainAdjUp: Serial.print(F("mainAdjUp ")); break;
14+
case altSel: Serial.print(F("altSel ")); break;
15+
default: break;
16+
}
17+
switch(evt){
18+
case 1: Serial.println(F("pressed")); break;
19+
case 2: Serial.println(F("short-held")); break;
20+
case 3: Serial.println(F("long-held")); break;
21+
case 0: Serial.println(F("released")); Serial.println(); break;
22+
default: break;
23+
}
24+
if(ctrl==mainSel && evt==4) networkStartAdmin(); //very long hold
25+
26+
} //end ctrlEvt
27+
28+
//Serial input for control
29+
int incomingByte = 0;
30+
void checkSerialInput(){
31+
if(Serial.available()>0){
32+
incomingByte = Serial.read();
33+
switch(incomingByte){
34+
case 97: //a
35+
networkStartAdmin(); break;
36+
//networkStartAP(); break;
37+
case 119: //w
38+
networkStartWiFi(); break;
39+
case 100: //d
40+
networkDisconnectWiFi(); break;
41+
default: break;
42+
}
43+
}
44+
}

controller.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//controller.h
2+
3+
#ifndef CONTROLLER_H
4+
#define CONTROLLER_H
5+
6+
void ctrlEvt(uint8_t ctrl, uint8_t evt);
7+
void checkSerialInput();
8+
9+
#endif

display-MAX7219.c renamed to display-MAX7219.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
//display-MAX7219.cpp
12
//based on Eberhard Farle's LedControl library - http://wayoda.github.io/LedControl
23

34
#include "Arduino.h"
4-
#include "display-MAX7219.h"
55
#include <LedControl.h>
6+
#include "config.h" //includes consts used here
7+
#include "display-MAX7219.h" //definitions for your own functions - needed only if calling functions before they're defined
68

79
#define NUM_MAX 4
810
#define ROTATE 90
@@ -97,7 +99,4 @@ void displayToggleBrightness(){
9799
}
98100
Serial.print(F("Changing brightness to ")); Serial.print(curBrightness,DEC); Serial.println(F("/15"));
99101
for(int i=0; i<NUM_MAX; i++) { lc.setIntensity(i,curBrightness); }
100-
}
101-
102-
103-
#endif //end of once-only header
102+
}

display-MAX7219.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
#ifndef DISPLAY_MAX7219_HEADER
2-
#define DISPLAY_MAX7219_HEADER
1+
//display-MAX7219.h
32

4-
#include "Arduino.h"
3+
#ifndef DISPLAY_MAX7219_H
4+
#define DISPLAY_MAX7219_H
55

66
void displaySetup();
77
void displayLoop();

inputs-LSM6DS3.cpp

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
//inputs-LSM6DS3.cpp
2+
3+
#include "Arduino.h"
4+
#include <Arduino_LSM6DS3.h>
5+
#include "config.h" //includes consts used here
6+
#include "inputs-LSM6DS3.h" //definitions for your own functions - needed only if calling functions before they're defined
7+
#include "controller.h" //ctrlEvt
8+
9+
// Hardware inputs and value setting
10+
byte btnCur = 0; //Momentary button currently in use - only one allowed at a time
11+
byte btnCurHeld = 0; //Button hold thresholds: 0=none, 1=unused, 2=short, 3=long, 4=verylong, 5=superlong, 10=set by btnStop()
12+
unsigned long inputLast = 0; //When a button was last pressed
13+
unsigned long inputLast2 = 0; //Second-to-last of above
14+
//TODO the math between these two may fail very rarely due to millis() rolling over while setting. Need to find a fix. I think it only applies to the rotary encoder though.
15+
int inputLastTODMins = 0; //time of day, in minutes past midnight, when button was pressed. Used in paginated functions so they all reflect the same TOD.
16+
17+
//IMU "debouncing"
18+
int imuYState = 0; //the state we're reporting (-1, 0, 1)
19+
int imuYTestState = 0; //the state we've actually last seen
20+
int imuYTestCount = 0; //how many times we've seen it
21+
int imuZState = 0; //the state we're reporting (-1, 0, 1)
22+
int imuZTestState = 0; //the state we've actually last seen
23+
int imuZTestCount = 0; //how many times we've seen it
24+
25+
26+
void inputsSetup(){
27+
if(!IMU.begin()){ Serial.println("Failed to initialize IMU!"); while(1); }
28+
// Serial.print("Accelerometer sample rate = ");
29+
// Serial.print(IMU.accelerationSampleRate());
30+
// Serial.println(" Hz");
31+
// Serial.println();
32+
// Serial.println("Acceleration in G's");
33+
// Serial.println("X\tY\tZ");
34+
35+
// vertical: x=1, y=0, z=0
36+
// forward: x=0, y=0, z=1
37+
/// f a bit 0.8 0 0.7
38+
// bakward: x=0. y=0, z=-1
39+
// b a bit 0.8 0 -0.5
40+
//left: x=0, y=1, z=0
41+
//right: -1
42+
//upside -1 0 0
43+
}
44+
void inputsLoop(){
45+
float x, y, z;
46+
IMU.readAcceleration(x,y,z);
47+
int imuState;
48+
//Assumes Arduino is oriented with components facing back of clock, and USB port facing up
49+
if(y<=-0.5) imuState = -1;
50+
else if(y>= 0.5) imuState = 1;
51+
else if(y>-0.3 && y<0.3) imuState = 0;
52+
else imuState = imuYTestState; //if it's not in one of the ranges, treat it as "same"
53+
if(imuYTestState!=imuState){ imuYTestState=imuState; imuYTestCount=0; }
54+
if(imuYTestCount<imuTestCountTrigger){ imuYTestCount++; /*Serial.print("Y "); Serial.print(imuYTestState); Serial.print(" "); for(char i=0; i<imuYTestCount; i++) Serial.print("#"); Serial.println(imuYTestCount);*/ if(imuYTestCount==imuTestCountTrigger) imuYState=imuYTestState; }
55+
56+
if(z<=-0.5) imuState = -1;
57+
else if(z>= 0.5) imuState = 1;
58+
else if(z>-0.3 && z<0.3) imuState = 0;
59+
else imuState = imuZTestState;
60+
if(imuZTestState!=imuState){ imuZTestState=imuState; imuZTestCount=0; }
61+
if(imuZTestCount<imuTestCountTrigger){ imuZTestCount++; /*Serial.print("Z "); Serial.print(imuZTestState); Serial.print(" "); for(char i=0; i<imuZTestCount; i++) Serial.print("#"); Serial.println(imuZTestCount);*/ if(imuZTestCount==imuTestCountTrigger) imuZState=imuZTestState; }
62+
63+
64+
//TODO change this to millis / compare to debouncing code
65+
checkBtn(mainSel);
66+
checkBtn(mainAdjUp);
67+
checkBtn(mainAdjDn);
68+
checkBtn(altSel);
69+
}
70+
71+
72+
bool readInput(byte btn){
73+
switch(btn){
74+
//Assumes Arduino is oriented with components facing back of clock, and USB port facing up
75+
//!() necessary since the pushbutton-derived code expects false (low) to mean pressed
76+
case mainSel: return !(imuZState < 0); //clock tilted backward
77+
case mainAdjDn: return !(imuYState > 0); //clock tilted left
78+
case mainAdjUp: return !(imuYState < 0); //clock tilted right
79+
case altSel: return !(imuZState > 0); //clock tilted forward
80+
default: break;
81+
}
82+
} //end readInput
83+
84+
void checkBtn(byte btn){
85+
//Changes in momentary buttons, LOW = pressed.
86+
//When a button event has occurred, will call ctrlEvt
87+
bool bnow = readInput(btn);
88+
unsigned long now = millis();
89+
//If the button has just been pressed, and no other buttons are in use...
90+
if(btnCur==0 && bnow==LOW) {
91+
btnCur = btn; btnCurHeld = 0; inputLast2 = inputLast; inputLast = now; //inputLastTODMins = tod.hour()*60+tod.minute();
92+
ctrlEvt(btn,1); //hey, the button has been pressed
93+
}
94+
//If the button is being held...
95+
if(btnCur==btn && bnow==LOW) {
96+
if((unsigned long)(now-inputLast)>=btnSuperLongHold && btnCurHeld < 5) { //account for rollover
97+
btnCurHeld = 5;
98+
ctrlEvt(btn,5); //hey, the button has been long-held
99+
}
100+
else if((unsigned long)(now-inputLast)>=btnVeryLongHold && btnCurHeld < 4) { //account for rollover
101+
btnCurHeld = 4;
102+
ctrlEvt(btn,4); //hey, the button has been long-held
103+
}
104+
else if((unsigned long)(now-inputLast)>=btnLongHold && btnCurHeld < 3) { //account for rollover
105+
btnCurHeld = 3;
106+
ctrlEvt(btn,3); //hey, the button has been long-held
107+
}
108+
else if((unsigned long)(now-inputLast)>=btnShortHold && btnCurHeld < 2) {
109+
btnCurHeld = 2;
110+
ctrlEvt(btn,2); //hey, the button has been short-held
111+
}
112+
}
113+
//If the button has just been released...
114+
if(btnCur==btn && bnow==HIGH) {
115+
btnCur = 0;
116+
if(btnCurHeld < 10) ctrlEvt(btn,0); //hey, the button was released //4 to 10
117+
btnCurHeld = 0;
118+
}
119+
}
120+
void btnStop(){
121+
//In some cases, when handling btn evt 1/2/3, we may call this so following events 2/3/0 won't cause unintended behavior (e.g. after a fn change, or going in or out of set) //4 to 10
122+
btnCurHeld = 10;
123+
}

0 commit comments

Comments
 (0)