Components and supplies
Arduino UNO R4 WIFI
MAX4466 microphone
Apps and platforms
Arduino IDE 1.8.19
NanoEdge AI Studio
Project description
Code
Sound data logger
c
Code to log data with the microphone
1#include <Wire.h> 2 3#define SENSOR_SAMPLES 512 4 5static float neai_buffer[SENSOR_SAMPLES] = {0.0}; 6static uint16_t neai_ptr = 0; 7 8int const AMP_PIN = A0; // Preamp output pin connected to A0 9 10/* Prototypes ----------------------------------------------------------*/ 11void get_microphone_data(void); 12 13void setup() { 14 // put your setup code here, to run once: 15 Serial.begin(115200); 16} 17void loop() { 18 // put your main code here, to run repeatedly: 19 get_microphone_data(); 20} 21 22 23/* Functions declaration ----------------------------------------------------------*/ 24void get_microphone_data() 25{ 26 static uint16_t temp = 0; 27 if (analogRead(AMP_PIN) > 400){ 28 int sub = 0; 29 while(neai_ptr < SENSOR_SAMPLES) { 30 if (sub > 8){ 31 /* Fill neai buffer with new accel data */ 32 neai_buffer[neai_ptr] = analogRead(AMP_PIN); 33 /* Increment neai pointer */ 34 neai_ptr++; 35 sub = 0; 36 } 37 else{ 38 temp = analogRead(AMP_PIN); 39 } 40 sub ++; 41 } 42 for(uint16_t i = 0; i < SENSOR_SAMPLES; i++) { 43 Serial.print(neai_buffer[i]); 44 Serial.print(" "); 45 } 46 Serial.print("\n"); 47 /* Reset pointer */ 48 neai_ptr = 0; 49 } 50}
Main code
c
The project code, with the flappy bird like game
1/* Libraries ----------------------------------------------------------*/ 2#include "ArduinoGraphics.h" 3#include "Arduino_LED_Matrix.h" 4#include <Wire.h> 5#include "NanoEdgeAI.h" 6#include "knowledge.h" 7#include <Scheduler.h> 8/* Defines ----------------------------------------------------------*/ 9/* Matrix part */ 10#define HEIGHT 8 11#define WIDTH 12 12#define PLAYER_X 10 //initial player position 13#define PLAYER_Y 4 14/* NEAI part */ 15#define SENSOR_SAMPLES 512 16#define AXIS 1 17 18/* Prototypes ----------------------------------------------------------*/ 19void introduction_message(void); 20void get_microphone_data(void); 21void adapt_game_level(void); 22void print_score(uint16_t game_score); 23void reset_global_variables(void); 24 25/* Objects ----------------------------------------------------------*/ 26ArduinoLEDMatrix matrix; 27 28/* Global variables ----------------------------------------------------------*/ 29int game_ongoing = 0; 30static byte wall_move = false; 31static int8_t player_move = 0; 32static uint8_t player_x = PLAYER_X, player_y = PLAYER_Y; 33static uint8_t wall_start_pix = 0, wall_pos_x = 0, wall_size = 3; 34static uint16_t score = 0, neai_ptr = 0, time_to_wait = 50; 35static float neai_buffer[SENSOR_SAMPLES * AXIS] = {0.0}; 36 37int const AMP_PIN = A0; // Preamp output pin connected to A0 38 39/* NanoEdgeAI variables part */ 40uint8_t neai_code = 0; 41uint16_t id_class = 0; // Point to id class (see argument of neai_classification fct) 42float output_class_buffer[CLASS_NUMBER]; // Buffer of class probabilities 43const char *id2class[CLASS_NUMBER + 1] = { // Buffer for mapping class id to class name 44 "unknown", 45 "up", 46 "down", 47}; 48 49/* Declare matrix to display */ 50byte frame[8][12] = { 51 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 52 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 53 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 54 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 55 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 56 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 57 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 58 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } 59}; 60 61/* Setup function ----------------------------------------------------------*/ 62void setup() { 63 Serial.begin(115200); 64 Scheduler.startLoop(loop2); //first loop is wall movement, second is player 65 66 matrix.begin(); 67 introduction_message(); //display a message when starting 68 69 /* Initialize NanoEdgeAI AI */ 70 neai_code = neai_classification_init(knowledge); 71 if (neai_code != NEAI_OK) { 72 Serial.print("Not supported board.\n"); 73 } 74 else { 75 game_ongoing = 1; //launch game if nanoedge working correctly 76 } 77} 78 79/* Infinite loop ----------------------------------------------------------*/ 80void loop() { 81 if (game_ongoing) { 82 /* Clean the last column of the matrix */ 83 for (uint8_t y = 0; y < HEIGHT; y++) { 84 frame[y][WIDTH - 1] = 0; 85 frame[y][WIDTH - 2] = 0; 86 } 87 88 /* Set wall position on the matrix using random */ 89 wall_start_pix = random(0, 5); 90 91 /* Move the wall through matrix */ 92 do { 93 if (wall_move) { 94 for (uint8_t y = 0; y < HEIGHT; y++) { 95 frame[y][wall_pos_x] = (y >= wall_start_pix && y < wall_start_pix + wall_size) ? 0 : 1; 96 if (wall_pos_x > 1) { 97 frame[y][wall_pos_x - 2] = 0; 98 } 99 } 100 wall_pos_x++; 101 } 102 wall_move = !wall_move; 103 104 /* Update display */ 105 matrix.renderBitmap(frame, HEIGHT, WIDTH); 106 107 /* Adapt level */ 108 adapt_game_level(); 109 110 /* Check if player touch the wall */ 111 if (frame[player_y][player_x] == frame[player_y][player_x - 1]) { 112 game_ongoing = 0; //stop the game 113 reset_global_variables(); 114 return; 115 } 116 } while (wall_pos_x < WIDTH); 117 /* Increment score counter */ 118 score++; 119 /* Reset wall position */ 120 wall_pos_x = 0; 121 } 122} 123 124 125void loop2() { 126 if (game_ongoing) { 127 /* make a classification only if we detect a sound */ 128 if (analogRead(AMP_PIN) > 400) { 129 get_microphone_data(); 130 neai_classification(neai_buffer, output_class_buffer, &id_class); 131 /* Player next movement based on class detected */ 132 if (id_class == 1) { 133 player_move = -1; //up 134 } 135 else if (id_class == 2) { 136 player_move = 1; //down 137 } 138 } 139 else { 140 //We don't want to repeat the same movement until we detect something else 141 id_class = 0; 142 player_move = 0; 143 } 144 //move the player 145 move_player(); 146 147 /* Clean neai buffer */ 148 memset(neai_buffer, 0.0, AXIS * SENSOR_SAMPLES * sizeof(float)); 149 } 150 delay(1); 151} 152 153/* Functions declaration ----------------------------------------------------------*/ 154void introduction_message() 155{ 156 matrix.beginDraw(); 157 matrix.stroke(0xFFFFFFFF); 158 matrix.textScrollSpeed(50); 159 160 // add the text 161 const char text[] = " Flappy bird! "; 162 matrix.textFont(Font_5x7); 163 matrix.beginText(0, 1, 0xFFFFFF); 164 matrix.println(text); 165 matrix.endText(SCROLL_LEFT); 166 167 matrix.endDraw(); 168} 169 170void move_player() { 171 /* Move the player and check if it stays in the screen */ 172 if (player_y + player_move >= 0 && player_y + player_move < HEIGHT) { 173 /* Clear player last position */ 174 frame[player_y][player_x] = 0; 175 /* Change player y coordinate */ 176 player_y += player_move; 177 } 178 /* Display player in matrix */ 179 frame[player_y][player_x] = 1; 180 181 /* Update display */ 182 matrix.renderBitmap(frame, HEIGHT, WIDTH); 183} 184 185/* function to get a single downsampled sample from sensor 186We get every values but keep only one every eight values because the model was train with data like this. 187It permits to listen for a longer period of time and get a better accuracy 188*/ 189void get_microphone_data() 190{ 191 static uint16_t temp = 0; //stock values 192 int sub = 0; //increment to downsample 193 //while the buffer is not full 194 while (neai_ptr < SENSOR_SAMPLES) { 195 //if it is the eighth value 196 if (sub > 8) { 197 /* Fill neai buffer with new accel data */ 198 neai_buffer[neai_ptr] = analogRead(AMP_PIN); 199 /* Increment neai pointer */ 200 neai_ptr++; 201 sub = 0; //reset increment 202 } 203 else { 204 temp = analogRead(AMP_PIN); 205 } 206 sub ++; 207 } 208 for(uint16_t i = 0; i < SENSOR_SAMPLES; i++) { 209 Serial.print(neai_buffer[i]); 210 Serial.print(" "); 211 } 212 Serial.print("\n"); 213 neai_ptr = 0; 214} 215 216void adapt_game_level() 217{ 218 /* Adapt speed & hole size */ 219 if (score < 5) { 220 time_to_wait = 50; 221 } 222 else if (score >= 5 && score < 10) { 223 time_to_wait = 40; 224 } 225 else if (score >= 10 && score < 15) { 226 time_to_wait = 30; 227 } 228 else if (score >= 15 && score < 20) { 229 wall_size = 2; 230 } 231 else { 232 wall_size = 1; 233 } 234 delay(time_to_wait); 235} 236 237void print_score(uint16_t game_score) 238{ 239 uint8_t text_pos_x = (game_score < 10) ? 5 : 3; 240 matrix.clear(); 241 matrix.beginDraw(); 242 matrix.stroke(0xFFFFFFFF); 243 char text[3]; 244 itoa(game_score, text, 10); 245 matrix.textFont(Font_4x6); 246 matrix.beginText(text_pos_x, 1, 0xFFFFFF); 247 matrix.println(text); 248 matrix.endText(); 249 matrix.endDraw(); 250} 251 252void reset_global_variables() 253{ 254 memset(frame, 0, WIDTH * HEIGHT * sizeof(byte)); 255 player_x = PLAYER_X; 256 player_y = PLAYER_Y; 257 print_score(score); 258 /* Reset score after loosing the party */ 259 score = 0; 260 /* Reset wall position */ 261 wall_pos_x = 0; 262 /* Reset wall size */ 263 wall_size = 3; 264 /* Reset delay */ 265 time_to_wait = 50; 266 delay(1000); 267 game_ongoing = 1; 268}
Downloadable files
Data Logger Code
sound_datalogger.ino
Main code
arduino_demo_flappy_bird_sound.ino
Comments
Only logged in users can leave comments