Cardboard Gesture Recognition with Embedded AI
An example showing how to easily add AI to an Arduino project using NanoEdge AI Studio
Components and supplies
1
Arduino® UNO R4 WiFi
1
LIS3DH Triple-Axis Accelerometer
Apps and platforms
1
NanoEdge AI Studio
1
Arduino IDE 1.8.19
Project description
Code
Main code
c
The demo code
1/* If you want to use NEAI functions please, include NEAI library 2 * in your Arduino libraries then, uncomment NEAI parts in the following code 3 */ 4 5/* Libraries part */ 6#include <Wire.h> 7#include <Adafruit_LIS3DH.h> 8#include <Adafruit_Sensor.h> 9#include <Keyboard.h> 10#include <NanoEdgeAI.h> 11#include "knowledge.h" 12float input_user_buffer[DATA_INPUT_USER * AXIS_NUMBER]; // Buffer of input values 13float output_class_buffer[CLASS_NUMBER]; // Buffer of class probabilities 14uint16_t id_class = 0; 15 16/* Macros definitions */ 17#define SERIAL_BAUD_RATE 115200 18 19/* Default address is 0x18 but, if SDO is powered at 3v3, 20 * address is set to 0x19, so you need to change it 21 * depending on your current hardware configuration. 22 */ 23#define SENSOR_I2C_ADDR 0x18 24 25/* Sensor data rates. 26 * You can choose from: 27 * LIS3DH_DATARATE_1_HZ 28 * LIS3DH_DATARATE_10_HZ 29 * LIS3DH_DATARATE_25_HZ 30 * LIS3DH_DATARATE_50_HZ 31 * LIS3DH_DATARATE_100_HZ 32 * LIS3DH_DATARATE_200_HZ 33 * LIS3DH_DATARATE_400_HZ 34 * LIS3DH_DATARATE_LOWPOWER_1K6HZ 35 * LIS3DH_DATARATE_LOWPOWER_5KHZ 36 */ 37#define SENSOR_DATA_RATE LIS3DH_DATARATE_400_HZ 38 39/* Sensor ranges. 40 * You can choose from: 41 * LIS3DH_RANGE_16_G 42 * LIS3DH_RANGE_8_G 43 * LIS3DH_RANGE_4_G 44 * LIS3DH_RANGE_2_G 45 */ 46#define SENSOR_RANGE LIS3DH_RANGE_2_G 47 48/* NanoEdgeAI defines part 49 * NEAI_MODE = 1: NanoEdgeAI functions = AI Mode. 50 * NEAI_MODE = 0: Datalogging mode. 51 */ 52#define NEAI_MODE 1 53#define SENSOR_SAMPLES 256 54#define AXIS 3 55 56Adafruit_LIS3DH lis = Adafruit_LIS3DH(); 57 58/* Global variables definitions */ 59static uint16_t neai_ptr = 0; 60static float neai_buffer[SENSOR_SAMPLES * AXIS] = {0.0}; 61 62 63/* Initialization function: In this function, 64 * code runs only once at boot / reset. 65 */ 66void setup() { 67 /* Init serial at baud rate 115200 */ 68 Serial.begin(SERIAL_BAUD_RATE); 69 70 /* Init I2C connection between board & sensor */ 71 if (!lis.begin(SENSOR_I2C_ADDR)) { 72 Serial.println("Can't initialize I2C comm with LIS3DH sensor...\n"); 73 while(1); 74 } 75 Serial.println("OK"); 76 /* Init LIS3DH with desired settings: odr & range */ 77 lis.setRange(SENSOR_RANGE); 78 lis.setDataRate(SENSOR_DATA_RATE); 79 80 /* Initialize NanoEdgeAI AI */ 81 enum neai_state error_code = neai_classification_init(knowledge); 82 if (error_code != NEAI_OK) { 83 Serial.println("Error starting NanoEdge AI lib"); 84 /* This happens if the knowledge does not correspond to the library or if the library works into a not supported board. */ 85 } 86 87 Keyboard.begin(); 88 delay(1000); 89} 90 91/* Main function: Code run indefinitely */ 92void loop() { 93 /* Get data in the neai buffer */ 94 while (neai_ptr < SENSOR_SAMPLES) { 95 /* Check if new data if available */ 96 if (lis.haveNewData()) { 97 /* If new data is available we read it ! */ 98 lis.read(); 99 /* Fill neai buffer with new accel data */ 100 neai_buffer[AXIS * neai_ptr] = (float) lis.x; 101 neai_buffer[(AXIS * neai_ptr) + 1] = (float) lis.y; 102 neai_buffer[(AXIS * neai_ptr) + 2] = (float) lis.z; 103 /* Increment neai pointer */ 104 neai_ptr++; 105 } 106 } 107 /* Reset pointer */ 108 neai_ptr = 0; 109 110 /* Depending on NEAI_MODE value, run NanoEdge AI functions 111 * or print accelerometer data to the serial (datalogging) 112 */ 113 114 if (NEAI_MODE) { 115 neai_classification(neai_buffer, output_class_buffer, &id_class); 116 117 if (id_class == 1) { 118 Keyboard.write(KEY_PAGE_DOWN); 119 delay(100); 120 } else if (id_class == 2) { 121 Keyboard.write(KEY_PAGE_UP); 122 delay(100); 123 } 124 } else { 125 /* Print the whole buffer to the serial */ 126 for (uint16_t i = 0; i < AXIS * SENSOR_SAMPLES; i++) { 127 Serial.print((String)neai_buffer[i] + " "); 128 } 129 Serial.print("\n"); 130 } 131 132 /* Clean neai buffer */ 133 memset(neai_buffer, 0.0, AXIS * SENSOR_SAMPLES * sizeof(float)); 134}
Data logger
c
Data logger code to collect data
1/* If you want to use NEAI functions please, include NEAI library 2 * in your Arduino libraries then, uncomment NEAI parts in the following code 3 */ 4 5/* Libraries part */ 6#include <Wire.h> 7#include <Adafruit_LIS3DH.h> 8#include <Adafruit_Sensor.h> 9 10/* Macros definitions */ 11#define SERIAL_BAUD_RATE 115200 12 13/* Default address is 0x18 but, if SDO is powered at 3v3, 14 * address is set to 0x19, so you need to change it 15 * depending on your current hardware configuration. 16 */ 17#define SENSOR_I2C_ADDR 0x18 18 19/* Sensor data rates. 20 * You can choose from: 21 * LIS3DH_DATARATE_1_HZ 22 * LIS3DH_DATARATE_10_HZ 23 * LIS3DH_DATARATE_25_HZ 24 * LIS3DH_DATARATE_50_HZ 25 * LIS3DH_DATARATE_100_HZ 26 * LIS3DH_DATARATE_200_HZ 27 * LIS3DH_DATARATE_400_HZ 28 * LIS3DH_DATARATE_LOWPOWER_1K6HZ 29 * LIS3DH_DATARATE_LOWPOWER_5KHZ 30 */ 31#define SENSOR_DATA_RATE LIS3DH_DATARATE_400_HZ 32 33/* Sensor ranges. 34 * You can choose from: 35 * LIS3DH_RANGE_16_G 36 * LIS3DH_RANGE_8_G 37 * LIS3DH_RANGE_4_G 38 * LIS3DH_RANGE_2_G 39 */ 40#define SENSOR_RANGE LIS3DH_RANGE_2_G 41 42/* NanoEdgeAI defines part 43 * NEAI_MODE = 1: NanoEdgeAI functions = AI Mode. 44 * NEAI_MODE = 0: Datalogging mode. 45 */ 46#define NEAI_MODE 1 47#define SENSOR_SAMPLES 256 48#define AXIS 3 49 50Adafruit_LIS3DH lis = Adafruit_LIS3DH(); 51 52/* Global variables definitions */ 53static uint16_t neai_ptr = 0; 54static float neai_buffer[SENSOR_SAMPLES * AXIS] = {0.0}; 55 56 57/* Initialization function: In this function, 58 * code runs only once at boot / reset. 59 */ 60void setup() { 61 /* Init serial at baud rate 115200 */ 62 Serial.begin(SERIAL_BAUD_RATE); 63 64 /* Init I2C connection between board & sensor */ 65 if(!lis.begin(SENSOR_I2C_ADDR)) { 66 Serial.println("Can't initialize I2C comm with LIS3DH sensor...\n"); 67 while(1); 68 } 69 Serial.println("OK"); 70 /* Init LIS3DH with desired settings: odr & range */ 71 lis.setRange(SENSOR_RANGE); 72 lis.setDataRate(SENSOR_DATA_RATE); 73 74 delay(1000); 75} 76 77/* Main function: Code run indefinitely */ 78void loop() { 79 /* Get data in the neai buffer */ 80 while(neai_ptr < SENSOR_SAMPLES) { 81 /* Check if new data if available */ 82 if(lis.haveNewData()) { 83 /* If new data is available we read it ! */ 84 lis.read(); 85 /* Fill neai buffer with new accel data */ 86 neai_buffer[AXIS * neai_ptr] = (float) lis.x; 87 neai_buffer[(AXIS * neai_ptr) + 1] = (float) lis.y; 88 neai_buffer[(AXIS * neai_ptr) + 2] = (float) lis.z; 89 /* Increment neai pointer */ 90 neai_ptr++; 91 } 92 } 93 /* Reset pointer */ 94 neai_ptr = 0; 95 96 97 /* Print the whole buffer to the serial */ 98 for(uint16_t i = 0; i < AXIS * SENSOR_SAMPLES; i++) { 99 Serial.print((String)neai_buffer[i] + " "); 100 } 101 Serial.print("\n"); 102 103 104 /* Clean neai buffer */ 105 memset(neai_buffer, 0.0, AXIS * SENSOR_SAMPLES * sizeof(float)); 106}
Comments
Only logged in users can leave comments