-
Notifications
You must be signed in to change notification settings - Fork 0
/
PENDULUM.cpp
83 lines (66 loc) · 1.61 KB
/
PENDULUM.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
#include "PENDULUM.h"
#include <SPI.h>
#include "debug.h"
PENDULUM::PENDULUM() : ss(53) { }
void PENDULUM::begin() {
pinMode(ss, OUTPUT);
digitalWrite(ss, HIGH);
SPI.begin();
}
void PENDULUM::zero() {
/*
* Loop that polls position of the poendulum
* and makes sure the same position stays for a while
*/
DMSGLN("[PENDULUM] Waiting for pendulum to settle");
int hits = 0;
int16_t last = 0;
while(hits != 5) {
int16_t now = read_raw();
if(now == last) {
hits++;
}
else {
hits = 0;
}
last = now;
delay(50);
}
DMSGLN("[PENDULUM] Pendulum settled, zeroing");
transaction(commands::ZERO);
delay(200); //startup time
}
float PENDULUM::read() {
float out = read_raw();
out *= PI;
out /= 0x1FFF;
return out;
}
int16_t PENDULUM::read_raw() {
int16_t value = transaction(commands::READ);
value &= 0x3FFF; //discard parity bits
if(value & 0x2000) { //sign extension to 16bit
value |= 0xC000;
}
else {
value &= 0x3FFF;
}
return value;
}
int16_t PENDULUM::transaction(enum commands command) {
char buf[2] = {0x00, command};
DMSGLN("[PENDULUM] Sending a command: " + command);
SPI.beginTransaction(SPISettings(2000000, MSBFIRST, SPI_MODE0));
digitalWrite(ss, LOW);
delayMicroseconds(3);
SPI.transfer(&buf[0], 1 , SPI_CONTINUE);
delayMicroseconds(3); //required delay, does not work properly without it
SPI.transfer(&buf[1], 1, SPI_LAST);
SPI.endTransaction();
delayMicroseconds(3);
digitalWrite(ss, HIGH);
DMSGLN("[PENDULUM] Transfer finished");
int16_t out = buf[1];
out |= buf[0] << 8;
return out;
}