testing baumer sensors
This commit is contained in:
166
AltSensorTesting/AltSensorTesting.ino
Normal file
166
AltSensorTesting/AltSensorTesting.ino
Normal file
@@ -0,0 +1,166 @@
|
||||
#include <Arduino.h>
|
||||
#include <util/atomic.h>
|
||||
|
||||
// ── ADC Interrupt-driven single-channel read (A0) ────────────
|
||||
volatile uint16_t adc_result = 0;
|
||||
volatile bool adc_ready = false;
|
||||
|
||||
void setupADC() {
|
||||
// Reference = AVCC (5 V)
|
||||
ADMUX = (1 << REFS0);
|
||||
|
||||
// Channel = A0 (MUX[3:0] = 0000)
|
||||
ADMUX &= 0xF0;
|
||||
|
||||
// Prescaler = 16 → 16 MHz / 16 = 1 MHz ADC clock
|
||||
// Each conversion ≈ 13 ADC clocks → ~76.9 kHz sample rate
|
||||
ADCSRA = (1 << ADEN) | (1 << ADIE)
|
||||
| (1 << ADPS2); // ADPS = 100 → /16
|
||||
|
||||
// Start first conversion
|
||||
ADCSRA |= (1 << ADSC);
|
||||
}
|
||||
|
||||
// ── OOR digital input ────────────────────────────────────────
|
||||
#define OOR_PIN 2 // digital pin 2 — HIGH = out of range
|
||||
|
||||
volatile bool OOR;
|
||||
|
||||
ISR(ADC_vect) {
|
||||
uint16_t sample = ADC;
|
||||
// Discard if OOR pin (PD2) is HIGH
|
||||
OOR = (digitalRead(OOR_PIN));
|
||||
if (!OOR) {
|
||||
adc_result = sample;
|
||||
adc_ready = true;
|
||||
}
|
||||
ADCSRA |= (1 << ADSC); // kick off next conversion immediately
|
||||
}
|
||||
|
||||
// ── ADC → mm linear mapping ─────────────────────────────────
|
||||
// ADC 185 → 16 mm, ADC 900 → 26 mm
|
||||
// #define adcToMM(adc) (16.0f + (float)((adc) - 185) * (10.0f / 715.0f))
|
||||
#define adcToMM(adc) (0.0f + (float)((adc) - 0) * (10.0f / 1024.0f))
|
||||
|
||||
// ── Boundary tracking (in-range only) ────────────────────────
|
||||
#define TRACK_N 10
|
||||
uint16_t lowestVals[TRACK_N];
|
||||
uint16_t highestVals[TRACK_N];
|
||||
uint8_t lowestCount = 0;
|
||||
uint8_t highestCount = 0;
|
||||
|
||||
// Insert val into a sorted-ascending array of up to TRACK_N entries
|
||||
// keeping only the N smallest values seen so far.
|
||||
static void trackLowest(uint16_t val) {
|
||||
if (lowestCount < TRACK_N) {
|
||||
// Array not full — insert in sorted position
|
||||
uint8_t i = lowestCount;
|
||||
while (i > 0 && lowestVals[i - 1] > val) {
|
||||
lowestVals[i] = lowestVals[i - 1];
|
||||
i--;
|
||||
}
|
||||
lowestVals[i] = val;
|
||||
lowestCount++;
|
||||
} else if (val < lowestVals[TRACK_N - 1]) {
|
||||
// Replace the current largest of the "lowest" set
|
||||
uint8_t i = TRACK_N - 1;
|
||||
while (i > 0 && lowestVals[i - 1] > val) {
|
||||
lowestVals[i] = lowestVals[i - 1];
|
||||
i--;
|
||||
}
|
||||
lowestVals[i] = val;
|
||||
}
|
||||
}
|
||||
|
||||
// Insert val into a sorted-descending array of up to TRACK_N entries
|
||||
// keeping only the N largest values seen so far.
|
||||
static void trackHighest(uint16_t val) {
|
||||
if (highestCount < TRACK_N) {
|
||||
uint8_t i = highestCount;
|
||||
while (i > 0 && highestVals[i - 1] < val) {
|
||||
highestVals[i] = highestVals[i - 1];
|
||||
i--;
|
||||
}
|
||||
highestVals[i] = val;
|
||||
highestCount++;
|
||||
} else if (val > highestVals[TRACK_N - 1]) {
|
||||
uint8_t i = TRACK_N - 1;
|
||||
while (i > 0 && highestVals[i - 1] < val) {
|
||||
highestVals[i] = highestVals[i - 1];
|
||||
i--;
|
||||
}
|
||||
highestVals[i] = val;
|
||||
}
|
||||
}
|
||||
|
||||
static void resetTracking() {
|
||||
lowestCount = 0;
|
||||
highestCount = 0;
|
||||
}
|
||||
|
||||
static void printBoundaries() {
|
||||
Serial.println(F("--- 10 Lowest In-Range ADC Values ---"));
|
||||
for (uint8_t i = 0; i < lowestCount; i++) {
|
||||
Serial.println(lowestVals[i]);
|
||||
}
|
||||
Serial.println(F("--- 10 Highest In-Range ADC Values ---"));
|
||||
for (uint8_t i = 0; i < highestCount; i++) {
|
||||
Serial.println(highestVals[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// ── State ────────────────────────────────────────────────────
|
||||
bool sampling = false;
|
||||
|
||||
// ═════════════════════════════════════════════════════════════
|
||||
void setup() {
|
||||
Serial.begin(2000000);
|
||||
pinMode(OOR_PIN, INPUT);
|
||||
setupADC();
|
||||
Serial.println(F("Send '1' to start sampling, '0' to stop and print bounds."));
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// ── Serial command handling ──────────────────────────────
|
||||
if (Serial.available() > 0) {
|
||||
String cmd = Serial.readStringUntil('\n');
|
||||
cmd.trim();
|
||||
|
||||
if (cmd.charAt(0) == '1') {
|
||||
sampling = true;
|
||||
resetTracking();
|
||||
Serial.println(F("Sampling started."));
|
||||
} else if (cmd.charAt(0) == '0') {
|
||||
sampling = false;
|
||||
Serial.println(F("Sampling stopped."));
|
||||
printBoundaries();
|
||||
}
|
||||
}
|
||||
|
||||
// ── Main sample path ────────────────────────────────────
|
||||
if (!sampling) return;
|
||||
|
||||
// Grab the latest ADC value atomically
|
||||
uint16_t val;
|
||||
bool ready;
|
||||
bool newOOR;
|
||||
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
|
||||
ready = adc_ready;
|
||||
val = adc_result;
|
||||
adc_ready = false;
|
||||
newOOR = OOR;
|
||||
}
|
||||
|
||||
if (!ready) return; // nothing new — come back next iteration
|
||||
|
||||
// All values here are in-range (OOR filtered in ISR)
|
||||
trackLowest(val);
|
||||
trackHighest(val);
|
||||
|
||||
float mm = adcToMM(val);
|
||||
Serial.print(val);
|
||||
Serial.print(", ");
|
||||
Serial.print(mm, 2);
|
||||
Serial.print(" mm, ");
|
||||
Serial.println(newOOR ? "out of range" : "in range");
|
||||
}
|
||||
Reference in New Issue
Block a user