I'm working on a project where I want to sample a 100Khz 180-degree phase-shifted square wave. All I want from the square wave is the amplitude. The actual amplitude doesn't matter just that after the filtering the output is always consistent with the input. So, I have a Teensy 4.1 and have figured out the ADC sampling and some filtering that will magic the square wave into a constant value. My issue is the buffer/memory allocation. I'm not a programmer and normally cobble things together but I know what I want to do but am not sure how to execute it. Due to the averaging, I'd like to keep ~1K samples and then dump the oldest as new samples come in. Essentially a first in first out setup. I have no idea how to implement that and I'd welcome any suggestions. Thanks in advance
Cobbled together code:
#include <ADC.h>
#define testpin A9 // analog pin to be tested
#include <RunningMedian.h>
ADC *adc = new ADC();
/////////// Buffer declaration///////////////////////////////<--- This probably does nothing
#define BUFFER_SIZE (1L << 8)
uint16_t buffer[BUFFER_SIZE];
uint8_t buffer_count = BUFFER_SIZE;
////////////Averaging Setup//////////////////////////////////
const int numReadings = 100; //Number of data points to average
int readings[numReadings];
int readIndex = 0;
int total = 0;
int average = 0;
///////////////////Threshold/////////////////////////////////
const int numReadings1 = 100; //Number of data points to average
int readings1[numReadings1];
int readIndex1 = 0;
int total1 = 0;
int averageT = 0;
///////////////////Median Filter 1 Setup/////////////////////
RunningMedian samples = RunningMedian(5);
///////////////////Median Filter 2 Setup/////////////////////
RunningMedian samples1 = RunningMedian(5);
void setup() {
Serial.begin(1152000);
pinMode(testpin, INPUT);
//////////////////////ADC Setup///////////////////////////////////////////////////////////////////////////
adc->adc0->setResolution(12); // Sets Res
adc->adc0->setAveraging(1); // Causes heavy distortion if set nonzero
adc->adc0->setConversionSpeed(ADC_CONVERSION_SPEED::MED_SPEED); //Haven't noticed an advantage between MED or HIGH speed on errors
adc->adc0->setSamplingSpeed(ADC_SAMPLING_SPEED::HIGH_SPEED); // Same as above
adc->adc0->startContinuous(testpin); // starting continuous sampling
//////////////////Averaging//////////////////////////////////
for (int s = 0; s < numReadings; s++) {
readings = 0;}
/////////////////Threshold///////////////////////////////////
for (int average = 0; average < numReadings1; average++) {
readings[average] = 0;}
/////////////////////////////////////////////////////////////
}
void loop() {
test1();
}
void test1()
{
//uint16_t
float sample = adc->adc0->analogReadContinuous();
//////////////////Median Filter 1///////////////////////
samples.add(sample);
long h = samples.getHighest();
//////////////////Median Filter 2///////////////////////
samples1.add(h);
long s = samples1.getHighest();
///////////////////////////////////////////////////////
////////////////Averageing////////////////////////////
total = total - readings[readIndex];
readings[readIndex] = s;
total = total + readings[readIndex];
readIndex = readIndex + 1;
if (readIndex >= numReadings)
{readIndex = 0;
average = total / numReadings;}
///////////////////Threshold/////////////////////////////
total1 = total1 - readings1[readIndex1];
readings1[readIndex1] = average;
total1 = total1 + readings1[readIndex1];
readIndex1 = readIndex1 + 1;
if (readIndex1 >= numReadings1)
{readIndex1 = 0;
averageT = total1 / numReadings1;}
/////////////////////////////////////////////////////////
if (average > averageT*1.05);////////// Appiles the Threshold
{average=averageT;}//////////////// and creates a 10% window
if (average < averageT*1.05);////////// around the Threshold average
{average=averageT;}///////////////
///////////////////////////////////////////////////////////
Serial.print("\t");
Serial.print(sample);///origninal 100Khz signal
Serial.print("\t");
Serial.println(averageT);///Filtered and averaged signal
//
delay(1);
}
Cobbled together code:
#include <ADC.h>
#define testpin A9 // analog pin to be tested
#include <RunningMedian.h>
ADC *adc = new ADC();
/////////// Buffer declaration///////////////////////////////<--- This probably does nothing
#define BUFFER_SIZE (1L << 8)
uint16_t buffer[BUFFER_SIZE];
uint8_t buffer_count = BUFFER_SIZE;
////////////Averaging Setup//////////////////////////////////
const int numReadings = 100; //Number of data points to average
int readings[numReadings];
int readIndex = 0;
int total = 0;
int average = 0;
///////////////////Threshold/////////////////////////////////
const int numReadings1 = 100; //Number of data points to average
int readings1[numReadings1];
int readIndex1 = 0;
int total1 = 0;
int averageT = 0;
///////////////////Median Filter 1 Setup/////////////////////
RunningMedian samples = RunningMedian(5);
///////////////////Median Filter 2 Setup/////////////////////
RunningMedian samples1 = RunningMedian(5);
void setup() {
Serial.begin(1152000);
pinMode(testpin, INPUT);
//////////////////////ADC Setup///////////////////////////////////////////////////////////////////////////
adc->adc0->setResolution(12); // Sets Res
adc->adc0->setAveraging(1); // Causes heavy distortion if set nonzero
adc->adc0->setConversionSpeed(ADC_CONVERSION_SPEED::MED_SPEED); //Haven't noticed an advantage between MED or HIGH speed on errors
adc->adc0->setSamplingSpeed(ADC_SAMPLING_SPEED::HIGH_SPEED); // Same as above
adc->adc0->startContinuous(testpin); // starting continuous sampling
//////////////////Averaging//////////////////////////////////
for (int s = 0; s < numReadings; s++) {
readings
/////////////////Threshold///////////////////////////////////
for (int average = 0; average < numReadings1; average++) {
readings[average] = 0;}
/////////////////////////////////////////////////////////////
}
void loop() {
test1();
}
void test1()
{
//uint16_t
float sample = adc->adc0->analogReadContinuous();
//////////////////Median Filter 1///////////////////////
samples.add(sample);
long h = samples.getHighest();
//////////////////Median Filter 2///////////////////////
samples1.add(h);
long s = samples1.getHighest();
///////////////////////////////////////////////////////
////////////////Averageing////////////////////////////
total = total - readings[readIndex];
readings[readIndex] = s;
total = total + readings[readIndex];
readIndex = readIndex + 1;
if (readIndex >= numReadings)
{readIndex = 0;
average = total / numReadings;}
///////////////////Threshold/////////////////////////////
total1 = total1 - readings1[readIndex1];
readings1[readIndex1] = average;
total1 = total1 + readings1[readIndex1];
readIndex1 = readIndex1 + 1;
if (readIndex1 >= numReadings1)
{readIndex1 = 0;
averageT = total1 / numReadings1;}
/////////////////////////////////////////////////////////
if (average > averageT*1.05);////////// Appiles the Threshold
{average=averageT;}//////////////// and creates a 10% window
if (average < averageT*1.05);////////// around the Threshold average
{average=averageT;}///////////////
///////////////////////////////////////////////////////////
Serial.print("\t");
Serial.print(sample);///origninal 100Khz signal
Serial.print("\t");
Serial.println(averageT);///Filtered and averaged signal
//
delay(1);
}