Skip to content

Commit a7fc45f

Browse files
committed
Change sampling rate function
1 parent a1b4ff9 commit a7fc45f

File tree

3 files changed

+42
-98
lines changed

3 files changed

+42
-98
lines changed

examples/Example-2-5leadECGstream-arduino-plotter/Example-2-5leadECGstream-arduino-plotter.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,5 +89,5 @@ void loop()
8989
Serial.println(samples.ch3);
9090
}
9191
}
92-
//delay(10);
92+
delay(15);
9393
}

src/protocentral_ads1293.cpp

Lines changed: 31 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -430,39 +430,26 @@ bool ADS1293::setSamplingRate(ADS1293::SamplingRate s)
430430
}
431431
}
432432

433-
// numeric target ODR for each enum
433+
// numeric target ODR for each supported enum (R1=4,R2=4; vary R3)
434434
float targetHz = 0.0f;
435435
switch (s)
436436
{
437-
case ADS1293::SamplingRate::SPS_25600: targetHz = 25600.0f; break;
438-
case ADS1293::SamplingRate::SPS_12800: targetHz = 12800.0f; break;
439-
case ADS1293::SamplingRate::SPS_6400: targetHz = 6400.0f; break;
440-
case ADS1293::SamplingRate::SPS_3200: targetHz = 3200.0f; break;
441-
case ADS1293::SamplingRate::SPS_1600: targetHz = 1600.0f; break;
442-
case ADS1293::SamplingRate::SPS_1280: targetHz = 1280.0f; break;
443-
case ADS1293::SamplingRate::SPS_1066: targetHz = 1067.0f; break; // datasheet shows 1067
444-
case ADS1293::SamplingRate::SPS_853: targetHz = 853.0f; break;
445-
case ADS1293::SamplingRate::SPS_800: targetHz = 800.0f; break;
446-
case ADS1293::SamplingRate::SPS_640: targetHz = 640.0f; break;
447-
case ADS1293::SamplingRate::SPS_533: targetHz = 533.0f; break;
448-
case ADS1293::SamplingRate::SPS_426: targetHz = 426.0f; break;
449-
case ADS1293::SamplingRate::SPS_400: targetHz = 400.0f; break;
450-
case ADS1293::SamplingRate::SPS_320: targetHz = 320.0f; break;
451-
case ADS1293::SamplingRate::SPS_266: targetHz = 266.0f; break;
452-
case ADS1293::SamplingRate::SPS_200: targetHz = 200.0f; break;
453-
case ADS1293::SamplingRate::SPS_160: targetHz = 160.0f; break;
454-
case ADS1293::SamplingRate::SPS_100: targetHz = 100.0f; break;
455-
case ADS1293::SamplingRate::SPS_50: targetHz = 50.0f; break;
456-
case ADS1293::SamplingRate::SPS_25: targetHz = 25.0f; break;
437+
case ADS1293::SamplingRate::SPS_1600: targetHz = 1600.0f; break; // R3=4
438+
case ADS1293::SamplingRate::SPS_1067: targetHz = 1066.6667f; break; // R3=6
439+
case ADS1293::SamplingRate::SPS_800: targetHz = 800.0f; break; // R3=8
440+
case ADS1293::SamplingRate::SPS_533: targetHz = 533.3333f; break; // R3=12
441+
case ADS1293::SamplingRate::SPS_400: targetHz = 400.0f; break; // R3=16
442+
case ADS1293::SamplingRate::SPS_200: targetHz = 200.0f; break; // R3=32
443+
case ADS1293::SamplingRate::SPS_100: targetHz = 100.0f; break; // R3=64
444+
case ADS1293::SamplingRate::SPS_50: targetHz = 50.0f; break; // R3=128
457445
default: return false;
458446
}
459447

460-
// Allowed decimation values per datasheet
461-
const uint8_t r1Candidates[] = {4, 2}; // prefer standard pace (4) then double pace (2)
462-
const uint8_t r2Candidates[] = {4, 5, 6, 8};
448+
// Fix R1=4 and R2=4 per requirement. Only vary R3 from allowed candidates.
449+
const uint8_t r1 = 4;
450+
const uint8_t r2 = 4;
463451
const uint8_t r3Candidates[] = {4, 6, 8, 12, 16, 32, 64, 128};
464452

465-
// Mapping from value -> register code
466453
auto r2Code = [](uint8_t v) -> uint8_t {
467454
switch (v) {
468455
case 4: return 0x01;
@@ -486,61 +473,22 @@ bool ADS1293::setSamplingRate(ADS1293::SamplingRate s)
486473
}
487474
};
488475

476+
// Choose the R3 candidate that best matches targetHz with R1=4,R2=4
477+
uint8_t chosenR3 = r3Candidates[0];
489478
float bestErr = 1e9f;
490-
uint8_t bestR1 = 4, bestR2 = 4, bestR3 = 64;
491-
float bestODR = 0.0f;
492-
493-
// Fast-path: if caller requested 100 SPS, program the registers to the
494-
// recommended values from the datasheet/example to avoid any ambiguity.
495-
if (s == ADS1293::SamplingRate::SPS_100) {
496-
// R1 = 4 -> write 0x00 to R1_RATE (bits clear)
497-
// R2 = 5 -> write 0x02 to R2_RATE (encoding)
498-
// R3 = 64 -> write 0x40 to R3_RATE_CHx
499-
bool ok = true;
500-
ok &= writeRegister(Register::R1_RATE, 0x00);
501-
ok &= writeRegister(Register::R2_RATE, 0x02);
502-
ok &= writeRegister(Register::R3_RATE_CH1, 0x40);
503-
ok &= writeRegister(Register::R3_RATE_CH2, 0x40);
504-
ok &= writeRegister(Register::R3_RATE_CH3, 0x40);
505-
delay(1);
506-
507-
// Verify by reading back
508-
uint8_t v = 0;
509-
if (!readRegister(Register::R1_RATE, v) || v != 0x00) return false;
510-
if (!readRegister(Register::R2_RATE, v) || v != 0x02) return false;
511-
if (!readRegister(Register::R3_RATE_CH1, v) || v != 0x40) return false;
512-
if (!readRegister(Register::R3_RATE_CH2, v) || v != 0x40) return false;
513-
if (!readRegister(Register::R3_RATE_CH3, v) || v != 0x40) return false;
514-
return ok;
515-
}
516-
517-
for (uint8_t r1 : r1Candidates)
518-
{
519-
for (uint8_t r2 : r2Candidates)
520-
{
521-
for (uint8_t r3 : r3Candidates)
522-
{
523-
float odr = fs / (static_cast<float>(r1) * r2 * r3);
524-
float err = fabsf(odr - targetHz);
525-
if (err < bestErr)
526-
{
527-
bestErr = err;
528-
bestR1 = r1;
529-
bestR2 = r2;
530-
bestR3 = r3;
531-
bestODR = odr;
532-
}
533-
if (err == 0.0f) break;
534-
}
535-
if (bestErr == 0.0f) break;
479+
for (uint8_t r3 : r3Candidates) {
480+
float odr = fs / (static_cast<float>(r1) * static_cast<float>(r2) * static_cast<float>(r3));
481+
float err = fabsf(odr - targetHz);
482+
if (err < bestErr) {
483+
bestErr = err;
484+
chosenR3 = r3;
536485
}
537-
if (bestErr == 0.0f) break;
486+
if (err == 0.0f) break;
538487
}
539488

540-
// Program R1, R2 and R3 registers. R1_RATE bits select 2x pace when set.
541-
uint8_t r1Reg = (bestR1 == 2) ? 0x07 : 0x00; // bits [2:0] map channels 3..1
542-
uint8_t r2Reg = r2Code(bestR2);
543-
uint8_t r3Reg = r3Code(bestR3);
489+
uint8_t r1Reg = 0x00; // R1=4 -> bits cleared
490+
uint8_t r2Reg = r2Code(r2); // r2=4 -> 0x01
491+
uint8_t r3Reg = r3Code(chosenR3);
544492

545493
bool ok = true;
546494
ok &= writeRegister(Register::R1_RATE, r1Reg);
@@ -550,5 +498,12 @@ bool ADS1293::setSamplingRate(ADS1293::SamplingRate s)
550498
ok &= writeRegister(Register::R3_RATE_CH3, r3Reg);
551499
delay(1);
552500

501+
// Verify writes by reading back at least R2 and R3
502+
uint8_t verify = 0;
503+
if (!readRegister(Register::R2_RATE, verify)) return false;
504+
if (verify != r2Reg) return false;
505+
if (!readRegister(Register::R3_RATE_CH1, verify)) return false;
506+
if (verify != r3Reg) return false;
507+
553508
return ok;
554509
}

src/protocentral_ads1293.h

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -209,27 +209,16 @@ class ADS1293 {
209209
// ECG channels. If you change the AFE_RES (FS_HIGH) or R1_RATE, the resulting
210210
// ODR will change.
211211
enum class SamplingRate : uint8_t {
212-
// Added high-rate DRATE options (DR[3:0] mapping)
213-
SPS_25600, // DR = 0x00 -> 25.6 kSPS
214-
SPS_12800, // DR = 0x01 -> 12.8 kSPS
215-
SPS_6400, // DR = 0x02 -> 6.4 kSPS
216-
SPS_3200, // DR = 0x03 -> 3.2 kSPS
217-
SPS_1600,
218-
SPS_1280,
219-
SPS_1066,
220-
SPS_853,
221-
SPS_800,
222-
SPS_640,
223-
SPS_533,
224-
SPS_426,
225-
SPS_400,
226-
SPS_320,
227-
SPS_266,
228-
SPS_200,
229-
SPS_160,
230-
SPS_100,
231-
SPS_50,
232-
SPS_25
212+
// Only include output rates that can be produced with R1=4, R2=4 and
213+
// R3 in {4,6,8,12,16,32,64,128} (ODR = 102400 / (4*4*R3) = 6400 / R3)
214+
SPS_1600, // R3=4
215+
SPS_1067, // R3=6 (~1066.667)
216+
SPS_800, // R3=8
217+
SPS_533, // R3=12 (~533.333)
218+
SPS_400, // R3=16
219+
SPS_200, // R3=32
220+
SPS_100, // R3=64
221+
SPS_50 // R3=128
233222
};
234223

235224
// Configure R2/R3 rate registers for the requested output data rate (ODR).

0 commit comments

Comments
 (0)