-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtiming_maths.h
99 lines (52 loc) · 2.25 KB
/
timing_maths.h
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
/* Timing Maths
Algorithms to convert:
BPM to:
- Delay Between Beats (uS) (Db)
- Delay Between Clock Ticks (uS)
Db to:
- Delay between beats * duty cycle
*/
uint32_t bpm_to_delay(uint16_t bpm) { // Output is delay value for an entire beat. This needs to be halved to use with our tick system (50% duty), or subdivided to account for other duty cycles
// BPM / 60 = Beats per second (Hz)
// Hz * 1000 = lambda (mS)
// Hz * 1,000,000 = lambda (uS)
// Hz * 500,000 = 1/2 lambda (uS) // This one for ticks system < This produced a bpm that felt far too low. Each beat on the sequencer actually needs to be a half beat
// Hz * 25000 = 1/4 lambda (uS) // <- This felt far more correct
//
// Serial.printf("\n\nBPM: [%i]\n", bpm);
float hz = bpm / 60.0;
char buffer[16];
dtostrf(hz, 3, 6, buffer);
// Serial.printf("hz: [%s]\n", buffer);
uint32_t delay_per_tick = 250000 / hz;
// Serial.printf("delay_per_tick: [%i]\n\n", delay_per_tick);
return delay_per_tick;
}
// Although this data structure and function might work, our implementation only requires the time HIGH,
struct duty_delay {
uint32_t time_high;
uint32_t time_low;
};
duty_delay duty_cycle_calc( uint32_t lambda, float duty_cycle) { //
uint32_t time_high = lambda * duty_cycle;
uint32_t time_low = lambda - time_high;
duty_delay output = {time_high, time_low};
return output;
}
// Same Function as above but only returns time HIGH
uint32_t duty_cycle_high(uint32_t lambda, float duty_cycle) { //
// As lambda is a half beat, we must double it here to make the duty cycle calcs work for a whole beat
lambda = lambda * 2;
uint32_t time_high = lambda * duty_cycle ;
uint32_t time_low = lambda - time_high;
char buffer[16];
dtostrf(duty_cycle, 3, 6, buffer);
// Serial.printf("\nDuty Cycle: [%s], Time High: [%i], Time Low: [%i] \n", buffer, time_high, time_low);
return time_high;
}
// Function ties together all previously written functions to take in a BPM value, set all interrupt timers and set duty cycles
void update_clock_tempo(uint16_t tempo) {
uint32_t master_clock_delay = bpm_to_delay(tempo);
timerSetup(master_clock_delay);
duty_high = duty_cycle_high(master_clock_delay, DUTY_CYCLE);
}