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 <SPI.h>
3
4#include "constants.h"
5#include "my_ADS126X.h"
6#include "noise_analyzer.h"
7
8#define USE_ADC1 1 // 1 = ADC1 (32-bit), 0 = ADC2 (24-bit)
9#define USE_CHOP 0 // Chop mode currently not working
10
11// Chnage the following line to automatically use the correct pins for the board
12// being tested (PT_Board, LC_Board, RTD_Board, or TC_Board)
13#define PINS_ACTIVE_LAYOUT sense_board_pins::PT_Board
14
15// This line MUST be after the #define PINS_ACTIVE_LAYOUT or it will override it
16#include "sense_board_pins.h"
17
19
22
23// Configuration sweep arrays
24struct TestConfig {
25 uint8_t filter;
26 uint8_t rate;
27 const char* filterName;
28 const char* rateName;
29 uint16_t expectedSPS; // For timing calculations
30};
31
32// Define test configurations (filter x rate combinations)
34 // SINC1 - Fast, low rejection
35 {ADS126X_SINC1, ADS126X_RATE_2_5, "SINC1", "2.5 SPS", 3},
36 {ADS126X_SINC1, ADS126X_RATE_100, "SINC1", "100 SPS", 100},
37 {ADS126X_SINC1, ADS126X_RATE_1200, "SINC1", "1200 SPS", 1200},
38 {ADS126X_SINC1, ADS126X_RATE_19200, "SINC1", "19200 SPS", 19200},
39
40 // SINC2 - Moderate rejection
41 {ADS126X_SINC2, ADS126X_RATE_10, "SINC2", "10 SPS", 10},
42 {ADS126X_SINC2, ADS126X_RATE_100, "SINC2", "100 SPS", 100},
43 {ADS126X_SINC2, ADS126X_RATE_1200, "SINC2", "1200 SPS", 1200},
44
45 // SINC3 - Good rejection, typical choice
46 {ADS126X_SINC3, ADS126X_RATE_10, "SINC3", "10 SPS", 10},
47 {ADS126X_SINC3, ADS126X_RATE_100, "SINC3", "100 SPS", 100},
48 {ADS126X_SINC3, ADS126X_RATE_1200, "SINC3", "1200 SPS", 1200},
49
50 // SINC4 - Best rejection
51 {ADS126X_SINC4, ADS126X_RATE_10, "SINC4", "10 SPS", 10},
52 {ADS126X_SINC4, ADS126X_RATE_100, "SINC4", "100 SPS", 100},
53 {ADS126X_SINC4, ADS126X_RATE_1200, "SINC4", "1200 SPS", 1200},
54
55 // FIR - Low latency
56 {ADS126X_FIR, ADS126X_RATE_2_5, "FIR", "2.5 SPS", 3},
57 {ADS126X_FIR, ADS126X_RATE_10, "FIR", "10 SPS", 10},
58 {ADS126X_FIR, ADS126X_RATE_20, "FIR", "20 SPS", 20},
59};
60
61// Calculate appropriate sample count based on data rate
62// Target ~30 seconds max per config for fast rates, but at least 100 samples
63size_t getSampleCount(uint16_t sps) {
64 if (sps <= 10)
65 return 100; // 10-40 seconds for slow rates
66 if (sps <= 100)
67 return 500; // 5 seconds
68 if (sps <= 1200)
69 return 1000; // ~1 second
70 return 1000; // Cap at 1000 for fast rates
71}
72
73const int numConfigs = sizeof(testConfigs) / sizeof(testConfigs[0]);
75bool testComplete = false;
76size_t targetSamples = 0; // Dynamic sample count for current config
77
79 // Stop ADC
80 if (USE_ADC1)
81 ads126x.stopADC1();
82 else
83 ads126x.stopADC2();
84
85 delay(50); // Allow ADC to stop
86
87 // Apply new configuration
88 ads126x.setFilter(config.filter);
89 ads126x.setRate(config.rate);
90
91 delay(50); // Allow filter/rate to settle
92
93 // Start ADC
94 if (USE_ADC1)
95 ads126x.startADC1();
96 else
97 ads126x.startADC2();
98
99 delay(100); // Allow ADC to stabilize after start
100}
101
103 uint8_t adcResolution = USE_ADC1 ? 32 : 24;
104
105 float rmsLsb = noiseAnalyzer.rmsNoiseLsb();
106 float ppLsb = noiseAnalyzer.peakToPeakNoiseLsb();
107 float nfb = noiseAnalyzer.noiseFreeBits(adcResolution);
108 float enobValue = noiseAnalyzer.enob(adcResolution);
109 double meanValue = noiseAnalyzer.mean();
110 size_t samples = noiseAnalyzer.sampleCount();
111
112 Serial.println("\n========================================");
113 Serial.print("Filter: ");
114 Serial.print(config.filterName);
115 Serial.print(" | Rate: ");
116 Serial.println(config.rateName);
117 Serial.println("========================================");
118 Serial.print("Samples: ");
119 Serial.println(samples);
120 Serial.print("Mean: ");
121 Serial.print(meanValue, 1);
122 Serial.println(" codes");
123 Serial.print("RMS: ");
124 Serial.print(rmsLsb, 3);
125 Serial.println(" LSB");
126 Serial.print("P-P: ");
127 Serial.print(ppLsb, 1);
128 Serial.println(" LSB");
129 Serial.print("NFB: ");
130 Serial.print(nfb, 2);
131 Serial.print(" / ");
132 Serial.print(adcResolution);
133 Serial.println(" bits");
134 Serial.print("ENOB: ");
135 Serial.print(enobValue, 2);
136 Serial.print(" / ");
137 Serial.print(adcResolution);
138 Serial.println(" bits");
139 Serial.println("========================================\n");
140}
141
142void setup() {
143 Serial.begin(115200);
144
145 // Wait for serial connection (up to 5 seconds)
146 unsigned long startWait = millis();
147 while (!Serial && (millis() - startWait < 5000)) {
148 delay(100);
149 }
150
151 Serial.println("\n\n===============================================");
152 Serial.println(" ADS126X Filter/Rate Sweep Test");
153 Serial.println("===============================================");
154 Serial.print("ADC: ");
155 Serial.println(USE_ADC1 ? "ADC1 (32-bit)" : "ADC2 (24-bit)");
156 Serial.print("Configs: ");
157 Serial.print(numConfigs);
158 Serial.println(" filter/rate combinations");
159 Serial.println("Samples: 100-1000 per config (adaptive)");
160 Serial.println("===============================================\n");
161
162 SPI.begin(Pins.ADC_SCLK, Pins.ADC_MISO, Pins.ADC_MOSI, Pins.ADC_CS_1);
163 SPI.setFrequency(1'000'000);
164 SPI.setDataMode(SPI_MODE1);
165 pinMode(Pins.ADC_DRDY_1, INPUT);
166
167 ads126x.begin(Pins.ADC_CS_1);
168
169 // Common configuration
170 ads126x.setOutputmagnitudeTDACP(0b00000111);
171 ads126x.setOutputmagnitudeTDACN(0b00000000);
172
173 if (USE_ADC1)
174 ads126x.setInputMux(ADS126X_TDAC, ADS126X_TDAC);
175 else
176 ads126x.setADC2Mux(ADS126X_TDAC, ADS126X_TDAC);
177
178 ads126x.bypassPGA();
179
180 if (USE_CHOP)
181 ads126x.setChopMode(ADS126X_CHOP_1);
182
183 // Start first configuration
184 Serial.println(">>> Starting test sweep...\n");
187
188 Serial.print("Config ");
189 Serial.print(currentConfigIndex + 1);
190 Serial.print("/");
191 Serial.print(numConfigs);
192 Serial.print(": ");
193 Serial.print(testConfigs[currentConfigIndex].filterName);
194 Serial.print(" @ ");
195 Serial.print(testConfigs[currentConfigIndex].rateName);
196 Serial.print(" (");
197 Serial.print(targetSamples);
198 Serial.println(" samples)");
199}
200
201void loop() {
202 if (testComplete) {
203 // All tests done, just idle
204 delay(1000);
205 return;
206 }
207
208 if (USE_ADC1) {
209 while (digitalRead(Pins.ADC_DRDY_1) != LOW) {
211 }
212 } else {
214 }
215
217
218 const auto reading = USE_ADC1 ? ads126x.readADC1() : ads126x.readADC2();
219
220 if (!reading.checksumValid) {
221 return; // Skip bad samples
222 }
223
224 // Collect samples
225 size_t count = noiseAnalyzer.sampleCount();
226 if (count < targetSamples) {
227 noiseAnalyzer.addSample(reading.value);
228 count = noiseAnalyzer.sampleCount();
229
230 // Show progress
231 size_t interval = targetSamples >= 500 ? 100 : 25;
232 if (count % interval == 0 || count == 1) {
233 Serial.print(" Collecting: ");
234 Serial.print(count);
235 Serial.print("/");
236 Serial.println(targetSamples);
237 }
238 return;
239 }
240
241 // Collected enough samples - print results for this configuration
243
244 // Move to next configuration
247 Serial.println("\n========================================");
248 Serial.println(" ALL TESTS COMPLETE!");
249 Serial.println("========================================\n");
250 testComplete = true;
251 return;
252 }
253
254 // Reset analyzer and configure next test
255 noiseAnalyzer.reset();
258
259 Serial.print("\nConfig ");
260 Serial.print(currentConfigIndex + 1);
261 Serial.print("/");
262 Serial.print(numConfigs);
263 Serial.print(": ");
264 Serial.print(testConfigs[currentConfigIndex].filterName);
265 Serial.print(" @ ");
266 Serial.print(testConfigs[currentConfigIndex].rateName);
267 Serial.print(" (");
268 Serial.print(targetSamples);
269 Serial.println(" samples)");
270}
static SerialStub Serial
Definition Arduino.h:128
#define INPUT
Definition Arduino.h:21
int digitalRead(int)
Definition Arduino.h:50
void pinMode(int, int)
Definition Arduino.h:46
unsigned long millis()
Definition Arduino.h:29
#define SPI_MODE1
Definition Arduino.h:131
#define LOW
Definition Arduino.h:20
void delayMicroseconds(unsigned int)
Definition Arduino.h:58
#define ADS126X_TDAC
Definition STAR_ADS126X.h:5
#define ADS126X_RATE_20
#define ADS126X_RATE_19200
#define ADS126X_CHOP_1
#define ADS126X_SINC2
#define ADS126X_FIR
#define ADS126X_RATE_100
#define ADS126X_RATE_2_5
#define ADS126X_RATE_1200
#define ADS126X_SINC1
#define ADS126X_RATE_10
#define ADS126X_SINC4
#define ADS126X_SINC3
void delay(int ms)
TestConfig testConfigs[]
Definition main.cpp:33
size_t getSampleCount(uint16_t sps)
Definition main.cpp:63
#define USE_ADC1
Definition main.cpp:8
void setup()
Definition main.cpp:142
int currentConfigIndex
Definition main.cpp:74
bool testComplete
Definition main.cpp:75
void configureADC(const TestConfig &config)
Definition main.cpp:78
#define USE_CHOP
Definition main.cpp:9
static ADS126X ads126x
Definition main.cpp:20
NoiseAnalyzer noiseAnalyzer
Definition main.cpp:21
size_t targetSamples
Definition main.cpp:76
void printResults(const TestConfig &config)
Definition main.cpp:102
const int numConfigs
Definition main.cpp:73
constexpr const Layout & Pins
void loop()
Definition main.cpp:201
static const idle_config_t config
Definition idle_task.c:17
size_type count(const key_type &key) const
Definition json.hpp:19264
constexpr const Layout & Pins
uint8_t rate
Definition main.cpp:26
const char * filterName
Definition main.cpp:27
uint16_t expectedSPS
Definition main.cpp:29
uint8_t filter
Definition main.cpp:25
const char * rateName
Definition main.cpp:28