Wrong classification between online and on device

Question/Issue:
Hi, I am using raw features taken from the live classification and placing the data into the src/main.cpp. Ran the code using Zephyr , how can i get the classification output? I want to use it the classification value to write a conditional statement as an experiment but I am unsure how to.

What does res mean too? Its not the classification right?

MCU:Nrf52840-DK

Project ID:
Gabriel/with MIT

Hi @FYPGabriel what is the project ID? I can take a look, also please share some screenshots of your impulse config for others to review.

Best

Eoin

HI @Eoin ,

Here is my Project ID: 371696

Context: I am using process MITDB ECG results where the signals are broken down intro 3 windows. Each window is process with Kurtosis and Skewness formula and saved into a csv file. Each row consist of 3kurtosis value followed by 3 skewness value. Noisy data are labelled as 0 and non-noisy as 1. There is no time series involved and i just want to strictly use Edge classification function to deploy into my MCU(NRF52840DK) to determine and show my professor that it can run and return a classification value.

// Zpehyr 3.1.x and newer uses different include scheme
#include <version.h>
#if (KERNEL_VERSION_MAJOR > 3) || ((KERNEL_VERSION_MAJOR == 3) && (KERNEL_VERSION_MINOR >= 1))
#include <zephyr/kernel.h>
#else
#include <zephyr.h>
#endif
#include "edge-impulse-sdk/classifier/ei_run_classifier.h"
#include "edge-impulse-sdk/dsp/numpy.hpp"
#include <nrfx_clock.h>
extern "C" int engzee(const short int, int);


const short int input_arry[] = {...} // 45000+ hardcoded data points
int peak_indices[5000];

int engzee(const short int *input_arry, int *output_arry)
{
	int filter, time = 0, slopecrit, sign, maxslope = 0, nsig, nslope = 0, qtime, maxtime, t0,
		    t1, t2, t3, t4, t5, t6, t7, t8, t9;
	int s2 = 500;
	int scmin = 200;
	int scmax = 2000;
	int ms160 = 40;
	int ms200 = 50;
	long temp, t, found, counter = 0, counter1 = 0;
	t9 = t8 = t7 = t6 = t5 = t4 = t3 = t2 = t1 =
		input_arry[0]; // v[0] contains channel 1 signal, v[1] contains channel 2 signal

	do {

		filter = (t0 = input_arry[counter]) + 4 * t1 + 6 * t2 + 4 * t3 + t4 - t5 - 4 * t6 -
			 6 * t7 - 4 * t8 - t9;

		// printf("This is s2: %d\n", s2); // This value is 500
		// printf("This is scmin: %d\n", scmin); //This value is 200
		// printf("This is scmax: %d\n", scmax); // THis value is 2000
		if (time % s2 == 0) {
			if (nslope == 0) {
				slopecrit -= slopecrit >> 4;
				if (slopecrit < scmin) {
					slopecrit = scmin;
				}
			} else if (nslope >= 5) {
				slopecrit += slopecrit >> 4;
				if (slopecrit > scmax) {
					slopecrit = scmax;
				}
			}
		}
		if (nslope == 0 && abs(filter) > slopecrit) {
			nslope = 1;
			maxtime = ms160;
			sign = (filter > 0) ? 1 : -1;
			qtime = time;
		}
		if (nslope != 0) {
			if (filter * sign < -slopecrit) {
				sign = -sign;
				maxtime = (++nslope > 4) ? ms200 : ms160;
			} else if (filter * sign > slopecrit && abs(filter) > maxslope) {
				maxslope = abs(filter);
			}
			if (maxtime-- < 0) {
				if (2 <= nslope && nslope <= 4) {
					slopecrit += ((maxslope >> 2) - slopecrit) >> 3;
					if (slopecrit < scmin) {
						slopecrit = scmin;
					} else if (slopecrit > scmax) {
						slopecrit = scmax;
					}
					// temp = strtim("i"); //This corresponds to which sample is
					// on currently.
					found = temp - (time - qtime) - 4;

					// printf("QRS found:  %ld\n", found);
					output_arry[counter1] = counter;
					counter1++;
					time = 0;

				} else if (nslope >= 5) {
					// Artifact detected
				}
				nslope = 0;
			}
		}
		t9 = t8;
		t8 = t7;
		t7 = t6;
		t6 = t5;
		t5 = t4;
		t4 = t3;
		t3 = t2;
		t2 = t1;
		t1 = t0;
		time++;
		counter++;
		// printf("Current sample: %ld \n", counter);
		// printf("-----\n");

	} while (counter < 451390); // Total number of samples is 451389. Should correspond to about
				    // 250hz sampling.
	printf("Number of peaks: %ld\n", counter1);
	return counter1;
}



static const float features[] = {
	22.0309, 21.9531, 23.1694, 3.9961,4.1067,  4.2041
    // copy raw features here (for example from the 'Live classification' page)
    // see https://docs.edgeimpulse.com/docs/running-your-impulse-locally-zephyr
};

int raw_feature_get_data(size_t offset, size_t length, float *out_ptr) {
    memcpy(out_ptr, features + offset, length * sizeof(float));
    return 0;
}

int main() {
    int k;
    // This is needed so that output of printf is output immediately without buffering
    setvbuf(stdout, NULL, _IONBF, 0);

#ifdef CONFIG_SOC_NRF5340_CPUAPP
    // Switch CPU core clock to 128 MHz
    nrfx_clock_divider_set(NRF_CLOCK_DOMAIN_HFCLK, NRF_CLOCK_HFCLK_DIV_1);
#endif

    printk("Edge Impulse standalone inferencing (Zephyr)\n");

    if (sizeof(features) / sizeof(float) != EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE) {
        printk("The size of your 'features' array is not correct. Expected %d items, but had %u\n",
            EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE, sizeof(features) / sizeof(float));
        return 1;
    }

    ei_impulse_result_t result = { 0 };

    while (1) {
        // the features are stored into flash, and we don't want to load everything into RAM
        signal_t features_signal;
        features_signal.total_length = sizeof(features) / sizeof(features[0]);
        features_signal.get_data = &raw_feature_get_data;

        // invoke the impulse
        EI_IMPULSE_ERROR res = run_classifier(&features_signal, &result, true);
        printk("run_classifier returned: %d\n", res);

	// TODO
	if (res == 0) {
		k = engzee(input_arry, peak_indices);
	} else {
		return 1;
	}
        if (res != 0) return 1;

        printk("Predictions (DSP: %d ms., Classification: %d ms., Anomaly: %d ms.): \n",
                result.timing.dsp, result.timing.classification, result.timing.anomaly);

#if EI_CLASSIFIER_OBJECT_DETECTION == 1
        bool bb_found = result.bounding_boxes[0].value > 0;
        for (size_t ix = 0; ix < result.bounding_boxes_count; ix++) {
            auto bb = result.bounding_boxes[ix];
            if (bb.value == 0) {
                continue;
            }
            printk("    %s (%f) [ x: %u, y: %u, width: %u, height: %u ]\n", bb.label, bb.value, bb.x, bb.y, bb.width, bb.height);
        }
        if (!bb_found) {
            printk("    No objects found\n");
        }
#else
        for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) {
            printk("    %s: %.5f\n", result.classification[ix].label,
                                    result.classification[ix].value);
        }
#if EI_CLASSIFIER_HAS_ANOMALY == 1
        printk("    anomaly score: %.3f\n", result.anomaly);
#endif
#endif
        k_msleep(2000);
    }
}