STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
main.cpp
Go to the documentation of this file.
1#include <Arduino.h>
2#include <Wire.h>
3
4// Pin config
5#define SDA_PIN 4
6#define SCL_PIN 5
7
8// AS5600 registers
9#define AS5600_ADDR 0x36
10#define REG_ZMCO 0x00
11#define REG_CONF_HI 0x07
12#define REG_CONF_LO 0x08
13#define REG_STATUS 0x0B
14#define REG_RAW_MSB 0x0C
15#define REG_RAW_LSB 0x0D
16#define REG_AGC 0x1A
17#define REG_MAG_HI 0x1B
18#define REG_MAG_LO 0x1C
19
20#define STATUS_MH 0x08
21#define STATUS_ML 0x10
22#define STATUS_MD 0x20
23#define READ_ERROR 0xFFFF
24
25float startAngle = 0.0f;
26float degAngle = 0.0f;
27float correctedAngle = 0.0f;
28bool sensorOk = false;
29
30bool i2cReadBytes(uint8_t reg, uint8_t* buf, uint8_t len) {
31 Wire.beginTransmission((uint8_t)AS5600_ADDR);
32 Wire.write(reg);
33 uint8_t err = Wire.endTransmission(false);
34 if (err != 0)
35 return false;
36 Wire.requestFrom((uint8_t)AS5600_ADDR, (uint8_t)len);
37 if (Wire.available() < len)
38 return false;
39 for (uint8_t i = 0; i < len; i++)
40 buf[i] = Wire.read();
41 return true;
42}
43
44// Verify AS5600 ACKs on the bus
45bool as5600Ping() {
46 Wire.beginTransmission((uint8_t)AS5600_ADDR);
47 return Wire.endTransmission() == 0;
48}
49
51 Serial.println("[AS5600] --- Register dump ---");
52 uint8_t val;
53
54 // ZMCO (0x00): number of times zero-pos has been permanently burned (0-3)
55 if (i2cReadBytes(REG_ZMCO, &val, 1))
56 Serial.printf(" ZMCO (0x00) = 0x%02X (burn count: %d)\n", val,
57 val & 0x03);
58 else
59 Serial.println(" ZMCO read FAILED");
60
61 // CONF (0x07-0x08): default is 0x0000 on a fresh part
62 uint8_t conf[2];
63 if (i2cReadBytes(REG_CONF_HI, conf, 2))
64 Serial.printf(" CONF (0x07) = 0x%02X%02X\n", conf[0], conf[1]);
65 else
66 Serial.println(" CONF read FAILED");
67
68 // STATUS (0x0B)
69 if (i2cReadBytes(REG_STATUS, &val, 1)) {
70 Serial.printf(" STATUS (0x0B) = 0x%02X [ ", val);
71 if (val & STATUS_MD)
72 Serial.print("MD ");
73 if (val & STATUS_MH)
74 Serial.print("MH ");
75 if (val & STATUS_ML)
76 Serial.print("ML ");
77 if (!(val & 0x38))
78 Serial.print("NO_MAGNET ");
79 Serial.println("]");
80 } else
81 Serial.println(" STATUS read FAILED");
82
83 // RAW ANGLE (0x0C-0x0D)
84 uint8_t raw[2];
85 if (i2cReadBytes(REG_RAW_MSB, raw, 2))
86 Serial.printf(" RAW (0x0C) = 0x%02X%02X (%d)\n", raw[0], raw[1],
87 ((raw[0] << 8) | raw[1]) & 0x0FFF);
88 else
89 Serial.println(" RAW read FAILED");
90
91 // AGC (0x1A): auto-gain control, 0 if no magnet / bus dead
92 if (i2cReadBytes(REG_AGC, &val, 1))
93 Serial.printf(
94 " AGC (0x1A) = %d (ideal ~128, 0=no magnet/bad bus)\n", val);
95 else
96 Serial.println(" AGC read FAILED");
97
98 // MAGNITUDE (0x1B-0x1C): CORDIC magnitude
99 uint8_t mag[2];
100 if (i2cReadBytes(REG_MAG_HI, mag, 2))
101 Serial.printf(" MAG (0x1B) = %d\n",
102 ((mag[0] << 8) | mag[1]) & 0x0FFF);
103 else
104 Serial.println(" MAG read FAILED");
105
106 Serial.println("[AS5600] -------------------------");
107}
108
109uint16_t readRawAngle() {
110 uint8_t buf[2];
111 if (!i2cReadBytes(REG_RAW_MSB, buf, 2))
112 return READ_ERROR;
113 return ((uint16_t)(buf[0] << 8) | buf[1]) & 0x0FFF;
114}
115
116float rawToDegrees(uint16_t raw) {
117 return raw * 0.087890625f;
118}
119
121 Serial.println("[AS5600] Waiting for magnet...");
122 unsigned long start = millis();
123 while (millis() - start < 3000) {
124 uint8_t status;
125 if (!i2cReadBytes(REG_STATUS, &status, 1)) {
126 Serial.println("[AS5600] ERROR: could not read STATUS");
127 delay(500);
128 continue;
129 }
130 status &= 0x38;
131 if (status & STATUS_MD) {
132 if (status & STATUS_MH) {
133 Serial.println("[AS5600] WARNING: magnet too strong");
134 return false;
135 }
136 if (status & STATUS_ML) {
137 Serial.println("[AS5600] WARNING: magnet too weak");
138 return false;
139 }
140 Serial.println("[AS5600] Magnet detected OK");
141 return true;
142 }
143 delay(100);
144 }
145 Serial.println("[AS5600] ERROR: no magnet detected after 3 s");
146 return false;
147}
148
151 if (correctedAngle < 0)
152 correctedAngle += 360.0f;
153}
154
155void setup() {
156 Serial.begin(115200);
157 delay(2000);
158 Serial.println("\n=== AS5600 Ball Valve Encoder ===");
159
160 Wire.begin(SDA_PIN, SCL_PIN);
161 Wire.setClock(400000);
162 Serial.printf("I2C initialized SDA=%d SCL=%d 400 kHz\n", SDA_PIN,
163 SCL_PIN);
164
165 if (!as5600Ping()) {
166 Serial.println("[AS5600] No ACK at 0x36 — check wiring / pull-ups");
167 Serial.println("=================================");
168 return;
169 }
170 Serial.println("[AS5600] ACK OK at 0x36");
171
173
175
176 uint16_t raw = readRawAngle();
177 if (raw != READ_ERROR) {
179 Serial.printf("Start angle tared at: %.1f deg\n", startAngle);
180 } else {
181 Serial.println("WARNING: could not tare start angle");
182 }
183 Serial.println("=================================");
184}
185
186void loop() {
187 if (!sensorOk) {
188 delay(2000);
189 Serial.println("[retry] Pinging AS5600...");
190 if (as5600Ping()) {
193 } else {
194 Serial.println("[retry] No ACK");
195 }
196 return;
197 }
198
199 uint16_t raw = readRawAngle();
200 if (raw == READ_ERROR) {
201 Serial.println("ERROR: I2C read failed");
202 } else {
203 degAngle = rawToDegrees(raw);
204 correctAngle();
205 Serial.printf("Raw: %4d Abs: %6.1f deg Corrected: %6.1f deg\n", raw,
207 }
208 delay(100);
209}
static SerialStub Serial
Definition Arduino.h:128
unsigned long millis()
Definition Arduino.h:29
void delay(int ms)
uint8_t reg
void setup()
Definition main.cpp:142
void loop()
Definition main.cpp:201
#define SCL_PIN
Definition main.cpp:6
bool i2cReadBytes(uint8_t reg, uint8_t *buf, uint8_t len)
Definition main.cpp:30
#define REG_STATUS
Definition main.cpp:13
void dumpDiagnostics()
Definition main.cpp:50
#define SDA_PIN
Definition main.cpp:5
float startAngle
Definition main.cpp:25
bool as5600Ping()
Definition main.cpp:45
float rawToDegrees(uint16_t raw)
Definition main.cpp:116
#define REG_MAG_HI
Definition main.cpp:17
#define REG_RAW_MSB
Definition main.cpp:14
#define REG_ZMCO
Definition main.cpp:10
#define AS5600_ADDR
Definition main.cpp:9
#define STATUS_ML
Definition main.cpp:21
float degAngle
Definition main.cpp:26
#define STATUS_MH
Definition main.cpp:20
void correctAngle()
Definition main.cpp:149
bool checkMagnetPresence()
Definition main.cpp:120
#define READ_ERROR
Definition main.cpp:23
#define REG_CONF_HI
Definition main.cpp:11
#define STATUS_MD
Definition main.cpp:22
uint16_t readRawAngle()
Definition main.cpp:109
bool sensorOk
Definition main.cpp:28
#define REG_AGC
Definition main.cpp:16
float correctedAngle
Definition main.cpp:27
static void start(gnss_frame_parser_t *p, uint8_t byte)
Definition gnss_frame.c:45