/
pulsar-receiver.cpp
88 lines (74 loc) · 2.44 KB
/
pulsar-receiver.cpp
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
// -=- Angular Deplexer -=-
// A little chip to take multiplexed PPM
// signals, and split them up over the
// digital pins, for RC things, and
// fun little cassette tape robots!
// <3 Bluebie
#define F_CPU 9600000UL // 9.6 MHz
#include <stdlib.h>
#include <avr/io.h>
#include <util/delay.h>
// For the niceness
#define bit(number) _BV(number)
#define becomeInput(pin) DDRB &= ~_BV(pin);
#define becomeOutput(pin) DDRB |= _BV(pin);
#define pinOn(pin) PORTB |= _BV(pin);
#define pinOff(pin) PORTB &= ~_BV(pin);
#define delay(ms) _delay_ms(ms);
#define digitalRead(pin) ((PINB & _BV(pin)) > 0)
#define digitalWrite(pin, state) if (state) pinOn(pin) else pinOff(pin);
#define comparator ((ACSR & 0b00100000) > 0)
// Note to self, PB0 and PB1 are AIN0 (+) and AIN1 (-) for comparator
// PB2, PB3, PB4, and PB5 are our servo signalers!
// And now for some settings...
#define outputs 3
#define first_output 2
#define max_output first_output + outputs - 1
#define reset_gap_minimum 3000
#define minimum_gap 1
unsigned long pollComparatorUntil(bool value) {
unsigned long count = 1;
delay(minimum_gap);
while (comparator != value) count++;
return count;
}
int main() {
// Setup the comparator
becomeInput(0);
becomeInput(1);
pinOff(0);
pinOff(1);
// Setup our outputs
becomeOutput(2);
becomeOutput(3);
becomeOutput(4);
// Not using this, it's the reset pin!
//becomeOutput(5);
// Todo: See if the internal bandgap is a good enough voltage for comparator
// Magic analog comparator configuration voodoo:
// ACD=0, ACBG=0, ACO=0 ACI=0 ACIE=0 ACIC=0 ACIS1, ACIS0
// - interrupt on output toggle
ACSR = 0b00000000;
// ADEN=1
ADCSRA = 0b10000000;
// ACME=0 (on) ADEN=0 MUX = b000 for use of AIN1
ADCSRB = 0b00000000;
// Save some power by turning off the digital input on AIN0 and AIN1
DIDR0 = 0b00111100;
// Voodoo done.
// Do a little dance!
unsigned char output = first_output;
unsigned long gap = 0;
while(true) {
//gap = pollComparatorUntil(false); // wait till the thingy goes low (i.e. pulse done!)
gap = pollComparatorUntil(true); // wait till it does high, and then...
if (output <= max_output) pinOff(output); // turn off the last servo
output++; // change to the next one
if (gap > reset_gap_minimum) {
output = first_output;
}
// Pop the new Servo's signal on!
if (output <= max_output) pinOn(output);
}
return 0;
}