Control_LED_Picovoice.ino will not compile

I have just received my Nano 33 BLE Sense and am trying to get this project (my first in this device) working: Offline Voice AI on Arduino. Did you know it’s now possible to… | by Mohammadreza Rostam | Picovoice | Medium You can see the code here

#include <Picovoice_EN.h>

#include "params.h"


#define RED   (22)
#define BLUE  (24)
#define GREEN (23)

#define MEMORY_BUFFER_SIZE (70 * 1024)

static pv_picovoice_t *handle = NULL;

static int8_t memory_buffer[MEMORY_BUFFER_SIZE] __attribute__((aligned(16)));

static const float PORCUPINE_SENSITIVITY = 0.75f;
static const float RHINO_SENSITIVITY = 0.5f;

static void blink_led(String color, String speed, String iteration) {
    int32_t led_pin = 0;
    int32_t delay_time = 0;
    int32_t iteration_int = iteration.toInt();

    if (color == "red") {
        led_pin = RED;
    } else if (color == "blue") {
        led_pin = BLUE;
    } else if (color == "green") {
        led_pin = GREEN;
    }

    if (speed == "slow" || speed == "slowly" || speed == "low") {
        delay_time = 500;
    } else if (speed == "normal") {
        delay_time = 300;
    } else if (speed == "fast" || speed == "quickly" || speed == "rapidly" || speed == "high") {
        delay_time = 150;
    }

    for (int32_t i = 0; i < iteration_int; i++) {
        digitalWrite(led_pin, LOW); // turn the LED on (LOW is the voltage level)
        delay(delay_time);
        digitalWrite(led_pin, HIGH); // turn the LED off (HIGH is the voltage level)
        delay(delay_time);
    }

}

static void change_state(String color, String state) {
    int32_t led_pin = 0;
    if (color == "red") {
        led_pin = RED;
    } else if (color == "blue") {
        led_pin = BLUE;
    } else if (color == "green") {
        led_pin = GREEN;
    }

    if (state == "on") {
        digitalWrite(led_pin, LOW);
    } else {
        digitalWrite(led_pin, HIGH);
    }
}

static void party_led(void) {
    int32_t delay_time = 100;
    for (int32_t i = 0; i < 4; i++) {
        digitalWrite(RED, LOW);
        delay(delay_time);
        digitalWrite(GREEN, LOW);
        delay(delay_time);
        digitalWrite(BLUE, LOW);
        delay(delay_time);
        digitalWrite(RED, HIGH);
        delay(delay_time);
        digitalWrite(GREEN, HIGH);
        delay(delay_time);
        digitalWrite(BLUE, HIGH);
        delay(delay_time);
    }
}

static void wake_word_callback(void) {
    Serial.println("Wake word detected!");
}

static void inference_callback(pv_inference_t *inference) {
    Serial.println("{");
    Serial.print("    is_understood : ");
    Serial.println(inference->is_understood ? "true" : "false");
    if (inference->is_understood) {
        Serial.print("    intent : ");
        Serial.println(inference->intent);
        if (inference->num_slots > 0) {
            Serial.println("    slots : {");
            for (int32_t i = 0; i < inference->num_slots; i++) {
                Serial.print("        ");
                Serial.print(inference->slots[i]);
                Serial.print(" : ");
                Serial.println(inference->values[i]);
            }
            Serial.println("    }");
        }
    }
    Serial.println("}\n");

    if (inference->is_understood) {
        if (String(inference->intent) == "changeLightState") {
            String state = "";
            String color = "";

            for (int32_t i = 0; i < inference->num_slots; i++) {
                if (String(inference->slots[i]) == "state") {
                    state = String(inference->values[i]);
                } else if (String(inference->slots[i]) == "color") {
                    color = String(inference->values[i]);
                }

            }
            if (color == "") {
                change_state("red", state);
                change_state("green", state);
                change_state("blue", state);
            } else {
                change_state(color, state);
            }

        } else if (String(inference->intent) == "blinkLight") {
            String color = "";
            String iteration = "5";
            String speed = "normal";
            for (int32_t i = 0; i < inference->num_slots; i++) {
                if (String(inference->slots[i]) == "color") {
                    color = String(inference->values[i]);
                } else if (String(inference->slots[i]) == "iteration") {
                    iteration = String(inference->values[i]);
                } else if (String(inference->slots[i]) == "speed") {
                    speed = String(inference->values[i]);
                }
            }
            blink_led(color, speed, iteration);
        } else if (String(inference->intent) == "partyLight") {
            party_led();
        }
    }
    pv_inference_delete(inference);
}

void setup() {
    Serial.begin(9600);
    while (!Serial);

    pinMode(RED, OUTPUT);
    pinMode(BLUE, OUTPUT);
    pinMode(GREEN, OUTPUT);

    digitalWrite(RED, HIGH);
    digitalWrite(BLUE, HIGH);
    digitalWrite(GREEN, HIGH);

    pv_status_t status = pv_audio_rec_init();
    if (status != PV_STATUS_SUCCESS) {
        Serial.print("Audio init failed with ");
        Serial.println(pv_status_to_string(status));
        while (1);
    }

    status = pv_picovoice_init(
            MEMORY_BUFFER_SIZE,
            memory_buffer,
            sizeof(KEYWORD_ARRAY),
            KEYWORD_ARRAY,
            PORCUPINE_SENSITIVITY,
            wake_word_callback,
            sizeof(CONTEXT_ARRAY),
            CONTEXT_ARRAY,
            RHINO_SENSITIVITY,
            inference_callback,
            &handle);
    if (status != PV_STATUS_SUCCESS) {
        Serial.print("Picovoice init failed with ");
        Serial.println(pv_status_to_string(status));
        while (1);
    }

    const char *rhino_context = NULL;
    status = pv_picovoice_context_info(handle, &rhino_context);
    if (status != PV_STATUS_SUCCESS) {
        Serial.print("retrieving context info failed with");
        Serial.println(pv_status_to_string(status));
        while (1);
    }
    Serial.println("Wake word: Picovoice");
    Serial.println(rhino_context);
}

void loop() {
    const int16_t *buffer = pv_audio_rec_get_new_buffer();
    if (buffer) {
              const pv_status_t status = pv_picovoice_process(handle, buffer);
        if (status != PV_STATUS_SUCCESS) {
            Serial.print("Picovoice process failed with ");
            Serial.println(pv_status_to_string(status));
            while (1);
        }
    }
}

However I cannot get the .ino file to compile. I have included the project library and the Picovoice.EN library but the .ino fails to compile with the following error (on both my IDE and the CloudIDE).

/tmp/354268789/Control_LED_Picovoice/Control_LED_Picovoice.ino: In function 'void setup()':

/tmp/354268789/Control_LED_Picovoice/Control_LED_Picovoice.ino:10:32: error: invalid conversion from 'int' to 'const char*' [-fpermissive]

#define MEMORY_BUFFER_SIZE (70 * 1024)


/tmp/354268789/Control_LED_Picovoice/Control_LED_Picovoice.ino:170:13: note: in expansion of macro 'MEMORY_BUFFER_SIZE'

MEMORY_BUFFER_SIZE,

^~~~~~~~~~~~~~~~~~

/tmp/354268789/Control_LED_Picovoice/Control_LED_Picovoice.ino:180:20: error: invalid conversion from 'int8_t* {aka signed char*}' to 'int32_t {aka long int}' [-fpermissive]

&handle);

^

/tmp/354268789/Control_LED_Picovoice/Control_LED_Picovoice.ino:172:19: error: invalid conversion from 'unsigned int' to 'void*' [-fpermissive]

sizeof(KEYWORD_ARRAY),

^

/tmp/354268789/Control_LED_Picovoice/Control_LED_Picovoice.ino:180:20: error: invalid conversion from 'const uint8_t* {aka const unsigned char*}' to 'int32_t {aka long int}' [-fpermissive]

&handle);

^
pv_status_t pv_picovoice_init(
        const char *access_key,
        int32_t memory_size,
        void *memory_buffer,
        int32_t keyword_model_size,
        const void *keyword_model,
        float porcupine_sensitivity,
        void (*wake_word_callback)(void),
        int32_t context_model_size,
        const void *context_model,
        float rhino_sensitivity,
        bool require_endpoint,
        void (*inference_callback)(pv_inference_t *),
        pv_picovoice_t **object
);

Thanks for the quick reply. I commented out the existing pv_picovoice_init() and replaced it with the code you posted. The .ino now compiles but in the monitor I get the message "retrieving context menu failed withINVALID ARGUMENT"

How exactly were you suggesting I use the code you posted?

/*status = pv_picovoice_init(
            MEMORY_BUFFER_SIZE,
            memory_buffer,
            sizeof(KEYWORD_ARRAY),
            KEYWORD_ARRAY,
            PORCUPINE_SENSITIVITY,
            wake_word_callback,
            sizeof(CONTEXT_ARRAY),
            CONTEXT_ARRAY,
            RHINO_SENSITIVITY,
            inference_callback,
            &handle);*/

           pv_status_t pv_picovoice_init(
        const char *access_key,
        int32_t memory_size,
        void *memory_buffer,
        int32_t keyword_model_size,
        const void *keyword_model,
        float porcupine_sensitivity,
        void (*wake_word_callback)(void),
        int32_t context_model_size,
        const void *context_model,
        float rhino_sensitivity,
        bool require_endpoint,
        void (*inference_callback)(pv_inference_t *),
        pv_picovoice_t **object
);

I posted the function prototype from the documentation for the library, so that you could compare your argument list with theirs.
(Hint: they're different)

There is no reason to copy the function prototype into your code, because you already told the compiler about it using the .h header file

Disclaimer: I have never used this library, and had never heard of it before this morning

You are calling this function:

        pv_status_t pv_picovoice_init(
        const char *access_key,
        int32_t memory_size,
        void *memory_buffer,

And you are passing these arguments:

status = pv_picovoice_init(
            MEMORY_BUFFER_SIZE,
            memory_buffer,

It appears that you forgot to pass the Access Key. The compiler is complaining that the first argument is the wrong type for an access key, the second argument is the wrong type for the memory size...

Thanks! I have now got an access key from PicoVoice. But how to add it to the code? I have tried defining it as ACCESS_KEY and adding "ACCESS_KEY," above "MEMORY_BUFFER_SIZE," but that doesn't work. I'm sorry if my questions are a bit dumb but I have only just received the Nano 33 BLE Sense and this is the first project I have tried it with. I thought I'd study the code after I got the thing working.

That should work if you defined ACCESS_KEY correctly. How did you define your access key as ACCESS_KEY? It should probably look like one of these:

#define ACCESS_KEY "THE_ACCESS_KEY_VALUE"

const char *ACCESS_KEY = "THE_ACCESS_KEY_VALUE";

const char ACCESS_KEY[] = "THE_ACCESS_KEY_VALUE";

I used the first one on your list:

#define ACCESS_KEY "THE_ACCESS_KEY_VALUE"

which resulted in the following error

/tmp/906203462/Control_LED_Picovoice/Control_LED_Picovoice.ino: In function 'void setup()':

/tmp/906203462/Control_LED_Picovoice/Control_LED_Picovoice.ino:183:20: error: cannot convert 'pv_picovoice_t** {aka pv_picovoice**}' to 'void (*)(pv_inference_t*)' for argument '12' to 'pv_status_t pv_picovoice_init(const char*, int32_t, void*, int32_t, const void*, float, void (*)(), int32_t, const void*, float, bool, void (*)(pv_inference_t*), pv_picovoice_t**)'

&handle);

^

Error during build: exit status 1

I have since tried your other two methods, with the same error message.

Thanks for your help, chaps. I have found another example INO which works perfectly. I will try and pinpoint the errors in the project mentioned above and if I am successful I will post the coreections here.

You have fixed the first error in that function call but there is another error.

I think the problem is a missing "require_endpoint" argument between "rhino_sensitivity" and "inference_callback". It should be a true or false value.

Thank you once again for your help. I fixed the missing "require_endpoint" argument between "rhino_sensitivity" and "inference_callback" and the INO now compiles! However the serial monitor gives the error message

[ERROR] keyword file belongs to a different version of the library. keyword file is '1.9.0' while the library is '2.1.0'.
Picovoice init failed with INVALID_ARGUMENT

It seems that the project I was trying to implement is outdated. However I have found another one which works but it not so comprehensive, so I will try and improve that. I hope I can come back here with further questions on this project/topic.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.