-
Notifications
You must be signed in to change notification settings - Fork 1
/
nano_clock_timer_2022.ino
142 lines (109 loc) · 3.28 KB
/
nano_clock_timer_2022.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// Pendulum Clock Timer
// Reference clock from GPS
// Pendulum triggers an optoswitch at bottom dead centre
// DiyMore Nano requires Old Bootloader
// Hazel Mitchell & Mike Godfrey 19/12/2022
#include <SPI.h>
#include <Wire.h>
//Define hardware connections
#define Pen_sw 2
#define PPS_pin 3
//Variables setup
volatile long Phase_Offset = 0;
volatile long Pen_Pass = 0;
volatile unsigned long Pen_Start = 0;
volatile unsigned long Pen_End = 0;
volatile unsigned long Timer_End = 0;
volatile byte GPS_state = LOW;
volatile byte Pen_state = 0;
volatile byte Pass_state = 0;
volatile byte mystatus = 0;
volatile byte penPasses = 0;
volatile byte timesincePPS = 1;
volatile byte timesincePen = 1;
volatile unsigned long lastPen = 0;
volatile unsigned long debounceTime = 800;
volatile unsigned long bounceTime = 0;
void setup() {
pinMode(Pen_sw, INPUT);
pinMode(PPS_pin, INPUT);
attachInterrupt(digitalPinToInterrupt(PPS_pin), PPS_trigger, RISING);
attachInterrupt(digitalPinToInterrupt(Pen_sw), Pendulum_rise, RISING);
Serial.begin(9600);
Wire.begin();
delay(500);
}
void loop() {
//tester();
if (Pass_state == 1){
if (digitalRead(Pen_sw) == 0){
Pen_End = micros();
Pass_state = 0;
//Serial.println("Pendulum falling");
}
}
}
//Triggers when the pendulum pass begins
void Pendulum_rise(){
bounceTime = (millis()-lastPen);
if (bounceTime > debounceTime){
lastPen = millis();
//Serial.println("Pendulum rising");
//Check Pendulum state
if (Pen_state == 1){
Pen_state = 2; //-> Pendulum is on second pass
Pen_Start = micros(); //-> Record current time from micros in timer_start
Pass_state = 1; //-> Used to indicate that the pendulum is still passing
}
else {
Pen_state = 1; //-> Pendulum is on first pass
}
}
}
//Triggers when the pendulum pass ends
void Pendulum_fall(){
bounceTime = (micros()-Pen_Start);
if (bounceTime > 0){
Serial.println("Pendulum falling");
if (Pen_state == 2){ //-> Pendulum is on second pass
Pen_End = micros(); //-> Record current time from micros in Pen_End
detachInterrupt(digitalPinToInterrupt(Pen_sw));
attachInterrupt(digitalPinToInterrupt(Pen_sw), Pendulum_rise, RISING);
}
}
}
//Triggers every second on pulse from GPS
void PPS_trigger(){
mystatus = 1;
timesincePPS = 0;
if (Pen_state == 2){
Timer_End = micros();
Phase_Offset = Timer_End - Pen_Start; //-> Record current time vs timer_start in microseconds
Pen_Pass = Pen_End - Pen_Start; //-> Duration of pendulum pass
noInterrupts();
sendToMega();
//Serial.println();
//Serial.println();
interrupts();
Pen_state = 0; //-> Reset states - i.e. Pendulum state = 0
}
}
void sendToMega() {
char buf[50];
ltoa(Phase_Offset, buf, 10);
Serial.write(buf);
Serial.write("v");
ltoa(Pen_Pass, buf, 10);
Serial.write(buf);
}
//Test code using simulated pendulum and pps triggers
void tester() {
delay(40);
Pendulum_rise();
//Serial.println("Pendulum triggered");
delay(10);
Pendulum_fall();
delay(950);
PPS_trigger();
Serial.println("GPS triggered");
}