ESP32_Scope/ESP32_Oscilloscope/data_analysis.ino
2024-02-05 19:46:31 +01:00

237 lines
6.8 KiB
C++

void peak_mean(uint16_t *i2s_buffer, uint32_t len, float * max_value, float * min_value, float *pt_mean) {
max_value[0] = i2s_buffer[0];
min_value[0] = i2s_buffer[0];
mean_filter filter(5);
filter.init(i2s_buffer[0]);
float mean = 0;
for (uint32_t i = 1; i < len; i++) {
float value = filter.filter((float)i2s_buffer[i]);
if (value > max_value[0])
max_value[0] = value;
if (value < min_value[0])
min_value[0] = value;
mean += i2s_buffer[i];
}
mean /= float(BUFF_SIZE);
mean = to_voltage(mean);
pt_mean[0] = mean;
}
//true if digital/ false if analog
bool digital_analog(uint16_t *i2s_buffer, uint32_t max_v, uint32_t min_v) {
uint32_t upper_threshold = max_v - 0.05 * (max_v - min_v);
uint32_t lower_threshold = min_v + 0.05 * (max_v - min_v);
uint32_t digital_data = 0;
uint32_t analog_data = 0;
for (uint32_t i = 0; i < BUFF_SIZE; i++) {
if (i2s_buffer[i] > lower_threshold) {
if (i2s_buffer[i] > upper_threshold) {
//HIGH DIGITAL
digital_data++;
}
else {
//ANALOG/TRANSITION
analog_data++;
}
}
else {
//LOW DIGITAL
digital_data++;
}
}
//more than 50% of data is analog
if (analog_data < digital_data)
return true;
return false;
}
void trigger_freq_analog(uint16_t *i2s_buffer,
float sample_rate,
float mean,
uint32_t max_v,
uint32_t min_v,
float *pt_freq,
float *pt_period,
uint32_t *pt_trigger0,
uint32_t *pt_trigger1) {
float freq = 0;
float period = 0;
bool signal_side = false;
uint32_t trigger_count = 0;
uint32_t trigger_num = 10;
uint32_t trigger_temp[trigger_num] = {0};
uint32_t trigger_index = 0;
//get initial signal relative to the mean
if (to_voltage(i2s_buffer[0]) > mean) {
signal_side = true;
}
//waveform repetitions calculation + get triggers time
uint32_t wave_center = (max_v + min_v) / 2;
for (uint32_t i = 1 ; i < BUFF_SIZE; i++) {
if (signal_side && i2s_buffer[i] < wave_center - (wave_center - min_v) * 0.2) {
signal_side = false;
}
else if (!signal_side && i2s_buffer[i] > wave_center + (max_v - wave_center) * 0.2) {
freq++;
if (trigger_count < trigger_num) {
trigger_temp[trigger_count] = i;
trigger_count++;
}
signal_side = true;
}
}
//frequency calculation
if (trigger_count < 2) {
trigger_temp[0] = 0;
trigger_index = 0;
freq = 0;
period = 0;
}
else {
//simple frequency calculation fair enough for frequencies over 2khz (20hz resolution)
freq = freq * 1000 / 50;
period = (float)(sample_rate * 1000.0) / freq; //us
//from 2000 to 80 hz -> uses mean of the periods for precision
if (freq < 2000 && freq > 80) {
period = 0;
for (uint32_t i = 1; i < trigger_count; i++) {
period += trigger_temp[i] - trigger_temp[i - 1];
}
period /= (trigger_count - 1);
freq = sample_rate * 1000 / period;
}
//under 80hz, single period for frequency calculation
else if (trigger_count > 1 && freq <= 80) {
period = trigger_temp[1] - trigger_temp[0];
freq = sample_rate * 1000 / period;
}
}
//setting triggers offset and getting second trigger for debug cursor on drawn_channel1
/*
The trigger function uses a rise porcentage (5%) obove the mean, thus,
the real waveform starting point is some datapoints back.
The resulting trigger gets a negative offset of 5% of the calculated period
*/
uint32_t trigger2 = 0;
if (trigger_temp[0] - period * 0.05 > 0 && trigger_count > 1) {
trigger_index = trigger_temp[0] - period * 0.05;
trigger2 = trigger_temp[1] - period * 0.05;
}
else if (trigger_count > 2) {
trigger_index = trigger_temp[1] - period * 0.05;
if (trigger_count > 2)
trigger2 = trigger_temp[2] - period * 0.05;
}
pt_trigger0[0] = trigger_index;
pt_trigger1[0] = trigger2;
pt_freq[0] = freq;
pt_period[0] = period;
}
void trigger_freq_digital(uint16_t *i2s_buffer,
float sample_rate,
float mean,
uint32_t max_v,
uint32_t min_v,
float *pt_freq,
float *pt_period,
uint32_t *pt_trigger0) {
float freq = 0;
float period = 0;
bool signal_side = false;
uint32_t trigger_count = 0;
uint32_t trigger_num = 10;
uint32_t trigger_temp[trigger_num] = {0};
uint32_t trigger_index = 0;
//get initial signal relative to the mean
if (to_voltage(i2s_buffer[0]) > mean) {
signal_side = true;
}
//waveform repetitions calculation + get triggers time
uint32_t wave_center = (max_v + min_v) / 2;
bool normal_high = (mean > to_voltage(wave_center)) ? true : false;
if (max_v - min_v > 4095 * (0.4 / 3.3)) {
for (uint32_t i = 1 ; i < BUFF_SIZE; i++) {
if (signal_side && i2s_buffer[i] < wave_center - (wave_center - min_v) * 0.2) {
//signal was high, fell -> trigger if normal high
if (trigger_count < trigger_num && normal_high) {
trigger_temp[trigger_count] = i;
trigger_count++;
}
signal_side = false;
}
else if (!signal_side && i2s_buffer[i] > wave_center + (max_v - wave_center) * 0.2) {
freq++;
//signal was low, rose -> trigger if normal low
if (trigger_count < trigger_num && !normal_high) {
trigger_temp[trigger_count] = i;
trigger_count++;
}
signal_side = true;
}
}
freq = freq * 1000 / 50;
period = (float)(sample_rate * 1000.0) / freq; //us
if (trigger_count > 1) {
//from 2000 to 80 hz -> uses mean of the periods for precision
if (freq < 2000 && freq > 80) {
period = 0;
for (uint32_t i = 1; i < trigger_count; i++) {
period += trigger_temp[i] - trigger_temp[i - 1];
}
period /= (trigger_count - 1);
freq = sample_rate * 1000 / period;
}
//under 80hz, single period for frequency calculation
else if (trigger_count > 1 && freq <= 80) {
period = trigger_temp[1] - trigger_temp[0];
freq = sample_rate * 1000 / period;
}
}
trigger_index = trigger_temp[0];
if (trigger_index > 10)
trigger_index -= 10;
else
trigger_index = 0;
}
pt_trigger0[0] = trigger_index;
pt_freq[0] = freq;
pt_period[0] = period;
}