Components and supplies
Arduino Nano RP2040 Connect
Arduino Oplà IoT Kit
Nicla Sense ME
Tools and machines
Linux laptop
Apps and platforms
Edge Impulse Studio
Thonny IDE
python
Project description
Code
Bluetooth Devices Scanner
python
This is the code scan the Bluetooth devices
1from bluepy.btle import Scanner, DefaultDelegate 2 3class ScanDelegate(DefaultDelegate): 4 def __init__(self): 5 DefaultDelegate.__init__(self) 6 7 def handleDiscovery(self, dev, isNewDev, isNewData): 8 if isNewDev: 9 print("Discovered device", dev.addr) 10 elif isNewData: 11 print("Received new data from", dev.addr) 12 13scanner = Scanner().withDelegate(ScanDelegate()) 14devices = scanner.scan(10.0) 15 16for dev in devices: 17 print("Device %s (%s), RSSI=%d dB" % (dev.addr, dev.addrType, dev.rssi)) 18 for (adtype, desc, value) in dev.getScanData(): 19 print(" {} = {}".format(desc, value)) 20 with open('/home/pi/bluepyscanlog.txt', 'a+') as the_file: 21 the_file.write("{}={}\n".format(desc, value))
interactivespaces
python
The code for all the elements in this project
1from bluepy import btle 2import paho.mqtt.client as mqtt 3from buildhat import Motor 4from buildhat import MotorPair 5from time import sleep 6import time 7import vlc 8import spotipy 9from spotipy.oauth2 import SpotifyOAuth 10 11""" 12Motors Lego ports 13""" 14right_arm = Motor('A') #define the port to connect the motor for the right arm 15left_arm = Motor('B')#define the port to connect the motor for the left arm 16 17broker_address="192.168.0.0" #put the ip from Raspberry as broker_address 18 19""" 20Spotify values 21""" 22device_id = ""#extract the device ID from the developers 23client_id = ""#extract the client ID from the developers 24client_secret = ""#extract the client secret from the developers 25redirect_uri = "http://localhost:8080" 26scope = "user-read-playback-state,user-modify-playback-state" 27 28sp = spotipy.Spotify( 29 auth_manager=spotipy.SpotifyOAuth( 30 client_id=client_id, 31 client_secret=client_secret, 32 redirect_uri=redirect_uri, 33 scope=scope, open_browser=False)) 34""" 35funcionts for movement of robot 36""" 37def combo(): #movement of arms 38 print("Run combo") 39 right_arm.run_for_seconds(1.3, speed=-100) 40 left_arm.run_for_seconds(1.3, speed=100) 41def back():#back to initial position 42 print("Run back") 43 right_arm.run_for_seconds(1.3, speed=100) 44 left_arm.run_for_seconds(1.3, speed=-100) 45def both():#move arms at same time 46 print("Run both") 47 right_arm.run_for_seconds(3, speed=-100, blocking=False) 48 left_arm.run_for_seconds(3, speed=100, blocking=False) 49def backb():#move back arms at same time 50 print("Run backb") 51 right_arm.run_for_seconds(3, speed=100, blocking=False) 52 left_arm.run_for_seconds(3, speed=-100, blocking=False) 53""" 54function to obtain values via Bluetooth 55""" 56def my_main_code(new_value): 57 #print(new_value) 58 move = new_value #Data streaming from Arduino Nicla SENSE ME 59 print(move) 60 client = mqtt.Client("P1") #create new instance 61 client.connect(broker_address) #connect to broker 62 client.subscribe("dance/lights")#subscribe to topic 63 #conditionals of classification from Nicla SENSE ME 64 if (move==1): 65 client.publish("dance/lights","on") #SEND TO MQTT BROKER on 66 print("on") 67 sp.start_playback(device_id=device_id ,uris=['spotify:track:5bXGg3XcbEGClkdZ8XYTkI']) 68 player= vlc.MediaPlayer('/home/pi/Desktop/model4/ink1.mp4') 69 player.play() 70 player.set_fullscreen(True) 71 for i in range(2):#for to move twice the robot arms 72 combo() 73 sleep(0.5) 74 back() 75 sleep(0.5) 76 while player.get_state() != vlc.State.Ended:#While to check the status from VLC 77 time.sleep(1) # Just to avoid unnecessary CPU use 78 playerstate = str(player.get_state()) 79 # printing the state of the video 80 print("State : " + str(playerstate)) 81 if (playerstate=="State.Ended"): 82 player.stop() 83 break 84 time.sleep(8) 85 if (move==2): 86 client.publish("dance/lights","on2")#SEND TO MQTT BROKER on2 87 print("on2") 88 sp.start_playback(device_id=device_id ,uris=['spotify:track:1o7D1gLUgpFR3eJfIgpSUx']) 89 player= vlc.MediaPlayer('/home/pi/Desktop/model4/ink4.mp4') 90 player.play() 91 player.set_fullscreen(True) 92 for i in range(2):#for to move twice the robot arms 93 both() 94 sleep(2) 95 backb() 96 sleep(1) 97 while player.get_state() != vlc.State.Ended: 98 time.sleep(1) # Just to avoid unnecessary CPU use 99 playerstate = str(player.get_state()) 100 # printing the state of the video 101 print("State : " + str(playerstate)) 102 if (playerstate=="State.Ended"): 103 player.stop() 104 break 105 time.sleep(8) 106 if (move==3):#for to move twice the robot arms 107 client.publish("dance/lights","on3")#SEND TO MQTT BROKER on2 108 print("on3") 109 sp.start_playback(device_id=device_id ,uris=['spotify:track:1c39AwcrkN9srI7Az5662I']) 110 player= vlc.MediaPlayer('/home/pi/Desktop/model4/magic.mp4') 111 player.play() 112 player.set_fullscreen(True) 113 for i in range(2): 114 combo() 115 sleep(0.5) 116 back() 117 sleep(0.5) 118 while player.get_state() != vlc.State.Ended: 119 time.sleep(1) # Just to avoid unnecessary CPU use 120 playerstate = str(player.get_state()) 121 # printing the state of the video 122 print("State : " + str(playerstate)) 123 if (playerstate=="State.Ended"): 124 player.stop() 125 break 126 time.sleep(10) 127 128# else: j 129# print("other value") 130 131 132class MyDelegate(btle.DefaultDelegate): 133 def __init__(self, callback): 134 self.callback = callback 135 btle.DefaultDelegate.__init__(self) 136 # ... initialise here 137 138 def handleNotification(self, cHandle, data): 139 # Convert data to be easily consumed by callback 140 num = int.from_bytes(data, byteorder='big') 141 self.callback(num) 142 143 144# Initialisation ------- 145p = btle.Peripheral("1a:b4:c0:25:3a:aa")#use the scanner.py file to obtain this BLE address for the NICLA 146p.setDelegate( MyDelegate(my_main_code) ) 147 148# Setup to turn notifications on, e.g. 149svc = p.getServiceByUUID("81c30e5c-1101-4f7d-a886-de3e90749161")#UUID SERVICE defined in Arduino code 150ch = svc.getCharacteristics("81c30e5c-2101-4f7d-a886-de3e90749161")[0]#UUID DATA SERVICE defined in Arduino code 151 152setup_data = b"\x01\00" 153p.writeCharacteristic(ch.valHandle+1, setup_data) 154 155# Main loop -------- 156 157while True: 158 if p.waitForNotifications(1.0): 159 # handleNotification() was called 160 continue 161 162 print("Waiting...")
setupspotify
python
Code to set up the spotify in Linux
1import spotipy 2from spotipy.oauth2 import SpotifyOAuth 3 4 5device_id = "" #add device ID from developers spotify 6client_id = ""#add client ID from developers spotify 7client_secret = "" #add client secret from developers spotify 8redirect_uri = "http://localhost:8080" 9scope = "user-read-playback-state,user-modify-playback-state" 10 11sp = spotipy.Spotify( 12 auth_manager=spotipy.SpotifyOAuth( 13 client_id=client_id, 14 client_secret=client_secret, 15 redirect_uri=redirect_uri, 16 scope=scope, open_browser=False)) 17 18 19sp.start_playback(device_id=device_id ,uris=['spotify:track:1o7D1gLUgpFR3eJfIgpSUx'])#change song
serialmodelnicla
c
Code of model with serial communication to Linux
1/* Edge Impulse ingestion SDK 2 * Copyright (c) 2022 EdgeImpulse Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 * 15 */ 16 17/* Includes ---------------------------------------------------------------- */ 18#include <tinymlinteractivespaces_inferencing.h> 19#include "Arduino_BHY2.h" //Click here to get the library: http://librarymanager/All#Arduino_BHY2 20 21/** Struct to link sensor axis name to sensor value function */ 22typedef struct{ 23 const char *name; 24 float (*get_value)(void); 25 26}eiSensors; 27 28/* Constant defines -------------------------------------------------------- */ 29#define CONVERT_G_TO_MS2 9.80665f 30 31/** Number sensor axes used */ 32#define NICLA_N_SENSORS 17 33 34 35/* Private variables ------------------------------------------------------- */ 36static const bool debug_nn = false; // Set this to true to see e.g. features generated from the raw signal 37 38SensorXYZ accel(SENSOR_ID_ACC); 39SensorXYZ gyro(SENSOR_ID_GYRO); 40SensorOrientation ori(SENSOR_ID_ORI); 41SensorQuaternion rotation(SENSOR_ID_RV); 42 43 44static bool ei_connect_fusion_list(const char *input_list); 45static float get_accX(void){return (accel.x() * 8.0 / 32768.0) * CONVERT_G_TO_MS2;} 46static float get_accY(void){return (accel.y() * 8.0 / 32768.0) * CONVERT_G_TO_MS2;} 47static float get_accZ(void){return (accel.z() * 8.0 / 32768.0) * CONVERT_G_TO_MS2;} 48static float get_gyrX(void){return (gyro.x() * 8.0 / 32768.0) * CONVERT_G_TO_MS2;} 49static float get_gyrY(void){return (gyro.y() * 8.0 / 32768.0) * CONVERT_G_TO_MS2;} 50static float get_gyrZ(void){return (gyro.z() * 8.0 / 32768.0) * CONVERT_G_TO_MS2;} 51static float get_oriHeading(void){return ori.heading();} 52static float get_oriPitch(void){return ori.pitch();} 53static float get_oriRoll(void){return ori.roll();} 54static float get_rotX(void){return rotation.x();} 55static float get_rotY(void){return rotation.y();} 56static float get_rotZ(void){return rotation.z();} 57static float get_rotW(void){return rotation.w();} 58 59 60static int8_t fusion_sensors[NICLA_N_SENSORS]; 61static int fusion_ix = 0; 62 63/** Used sensors value function connected to label name */ 64eiSensors nicla_sensors[] = 65{ 66 "accX", &get_accX, 67 "accY", &get_accY, 68 "accZ", &get_accZ, 69 "gyrX", &get_gyrX, 70 "gyrY", &get_gyrY, 71 "gyrZ", &get_gyrZ, 72 "heading", &get_oriHeading, 73 "pitch", &get_oriPitch, 74 "roll", &get_oriRoll, 75 "rotX", &get_rotX, 76 "rotY", &get_rotY, 77 "rotZ", &get_rotZ, 78 "rotW", &get_rotW, 79}; 80 81/** 82* @brief Arduino setup function 83*/ 84void setup() 85{ 86 /* Init serial */ 87 Serial.begin(115200); 88 // comment out the below line to cancel the wait for USB connection (needed for native USB) 89 while (!Serial); 90 Serial.println("Edge Impulse Sensor Fusion Inference\r\n"); 91 92 /* Connect used sensors */ 93 if(ei_connect_fusion_list(EI_CLASSIFIER_FUSION_AXES_STRING) == false) { 94 ei_printf("ERR: Errors in sensor list detected\r\n"); 95 return; 96 } 97 98 /* Init & start sensors */ 99 BHY2.begin(NICLA_I2C); 100 accel.begin(); 101 gyro.begin(); 102 ori.begin(); 103 rotation.begin(); 104 105} 106 107/** 108* @brief Get data and run inferencing 109*/ 110void loop() 111{ 112 //ei_printf("\nStarting inferencing in 2 seconds...\r\n"); 113 114 delay(2000); 115 116 if (EI_CLASSIFIER_RAW_SAMPLES_PER_FRAME != fusion_ix) { 117 ei_printf("ERR: Nicla sensors don't match the sensors required in the model\r\n" 118 "Following sensors are required: %s\r\n", EI_CLASSIFIER_FUSION_AXES_STRING); 119 return; 120 } 121 122 //ei_printf("Sampling...\r\n"); 123 124 // Allocate a buffer here for the values we'll read from the IMU 125 float buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE] = { 0 }; 126 127 for (size_t ix = 0; ix < EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE; ix += EI_CLASSIFIER_RAW_SAMPLES_PER_FRAME) { 128 // Determine the next tick (and then sleep later) 129 int64_t next_tick = (int64_t)micros() + ((int64_t)EI_CLASSIFIER_INTERVAL_MS * 1000); 130 131 // Update function should be continuously polled 132 BHY2.update(); 133 134 for(int i = 0; i < fusion_ix; i++) { 135 buffer[ix + i] = nicla_sensors[fusion_sensors[i]].get_value(); 136 } 137 138 int64_t wait_time = next_tick - (int64_t)micros(); 139 140 if(wait_time > 0) { 141 delayMicroseconds(wait_time); 142 } 143 } 144 145 // Turn the raw buffer in a signal which we can the classify 146 signal_t signal; 147 int err = numpy::signal_from_buffer(buffer, EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE, &signal); 148 if (err != 0) { 149 ei_printf("ERR:(%d)\r\n", err); 150 return; 151 } 152 153 // Run the classifier 154 ei_impulse_result_t result = { 0 }; 155 156 err = run_classifier(&signal, &result, debug_nn); 157 if (err != EI_IMPULSE_OK) { 158 ei_printf("ERR:(%d)\r\n", err); 159 return; 160 } 161 162 // print the predictions 163 //ei_printf("Predictions (DSP: %d ms., Classification: %d ms., Anomaly: %d ms.):\r\n", 164 //result.timing.dsp, result.timing.classification, result.timing.anomaly); 165 for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) { 166 //ei_printf("%s: %.5f\r\n", result.classification[ix].label, result.classification[ix].value); 167 if(result.classification[ix].value>0.8){ 168 //Serial.print(result.classification[ix].label); 169 if(result.classification[ix].label=="jump"){ 170 Serial.print(1); 171 } 172 else if(result.classification[ix].label=="run"){ 173 Serial.print(2); 174 } 175 else if(result.classification[ix].label=="side"){ 176 Serial.print(3); 177 } 178 } 179 } 180#if EI_CLASSIFIER_HAS_ANOMALY == 1 181 ei_printf(" anomaly score: %.3f\r\n", result.anomaly); 182#endif 183} 184 185#if !defined(EI_CLASSIFIER_SENSOR) || (EI_CLASSIFIER_SENSOR != EI_CLASSIFIER_SENSOR_FUSION && EI_CLASSIFIER_SENSOR != EI_CLASSIFIER_SENSOR_ACCELEROMETER) 186#error "Invalid model for current sensor" 187#endif 188 189 190/** 191 * @brief Go through nicla sensor list to find matching axis name 192 * 193 * @param axis_name 194 * @return int8_t index in nicla sensor list, -1 if axis name is not found 195 */ 196static int8_t ei_find_axis(char *axis_name) 197{ 198 int ix; 199 for(ix = 0; ix < NICLA_N_SENSORS; ix++) { 200 if(strstr(axis_name, nicla_sensors[ix].name)) { 201 return ix; 202 } 203 } 204 return -1; 205} 206 207/** 208 * @brief Check if requested input list is valid sensor fusion, create sensor buffer 209 * 210 * @param[in] input_list Axes list to sample (ie. "accX + gyrY + magZ") 211 * @retval false if invalid sensor_list 212 */ 213static bool ei_connect_fusion_list(const char *input_list) 214{ 215 char *buff; 216 bool is_fusion = false; 217 218 /* Copy const string in heap mem */ 219 char *input_string = (char *)ei_malloc(strlen(input_list) + 1); 220 if (input_string == NULL) { 221 return false; 222 } 223 memset(input_string, 0, strlen(input_list) + 1); 224 strncpy(input_string, input_list, strlen(input_list)); 225 226 /* Clear fusion sensor list */ 227 memset(fusion_sensors, 0, NICLA_N_SENSORS); 228 fusion_ix = 0; 229 230 buff = strtok(input_string, "+"); 231 232 while (buff != NULL) { /* Run through buffer */ 233 int8_t found_axis = 0; 234 235 is_fusion = false; 236 found_axis = ei_find_axis(buff); 237 238 if(found_axis >= 0) { 239 if(fusion_ix < NICLA_N_SENSORS) { 240 fusion_sensors[fusion_ix++] = found_axis; 241 } 242 is_fusion = true; 243 } 244 245 buff = strtok(NULL, "+ "); 246 } 247 248 ei_free(input_string); 249 250 return is_fusion; 251}
mqtt_opla
c
Code to control Carrier from Oplá Kit using MQTT
1#include <WiFiNINA.h> 2#include <PubSubClient.h> 3#include <Arduino_MKRIoTCarrier.h> 4#include "pitches.h" 5#include "secrets.h" 6 7MKRIoTCarrier carrier; 8 9uint32_t colorGreen = carrier.leds.Color(0, 200, 0); 10uint32_t colorRed = carrier.leds.Color(200, 0, 0); 11uint32_t colorBlue = carrier.leds.Color(0, 0, 200); 12 13int celebrationMelody[] = { 14 NOTE_C4, NOTE_G3, NOTE_G3, NOTE_A3, NOTE_G3, 0, NOTE_B3, NOTE_C4 15}; 16 17int finalMelody[] = { 18 NOTE_E6, NOTE_G6, NOTE_E7, NOTE_C7, NOTE_D7, NOTE_G7, NOTE_E7, NOTE_G6 19}; 20 21// note durations: 4 = quarter note, 8 = eighth note, etc.: 22int noteDurations[] = { 23 4, 8, 8, 4, 4, 4, 4, 4 24}; 25 26WiFiClient wifi; 27int status = WL_IDLE_STATUS; 28 29IPAddress server(192, 168, 0, 0);//change this value 30PubSubClient client(wifi); 31 32bool touchCheckCompleted = false; 33 34void setup() { 35 //pinMode(6, OUTPUT); 36 CARRIER_CASE = false; 37 delay(1500); 38 39 if (!carrier.begin()) 40 { 41 Serial.println("Carrier not connected, check connections"); 42 while (1); 43 } 44 //while (!Serial){ 45 // ; 46 //} 47 Serial.begin(9600); 48 Serial.println("OK"); 49 Serial.print("Connessione..."); 50 while (status != WL_CONNECTED) { 51 status = WiFi.begin(WIFI_SSID, WIFI_PASS); 52 Serial.print("."); 53 delay(1000); 54 } 55 Serial.println("Connected to WiFi!\n"); 56 57 client.setServer(server, 1883); 58 client.setCallback(callback); 59 60 if (client.connect("arduinosub")) { 61 Serial.println("mqtt connected"); 62 client.subscribe("dance/lights"); 63 } else { 64 Serial.println("mqtt not connected"); 65 Serial.print("failed, rc="); 66 Serial.println(client.state()); 67 } 68 69 //carrier.begin(); 70 //carrier.display.setRotation(0); 71 72} 73 74void loop() { 75 client.loop(); 76} 77 78 79void callback(char* topic, byte* payload, unsigned int length){ 80 String msg; 81 for (int i = 0; i < length; i++) { 82 msg += (char)payload[i]; 83 } 84 Serial.println(msg); 85 if (strcmp(topic, "dance/lights") == 0) { 86 if (msg == "on") { 87 touchCheckCompleted = true; 88 melody1(); 89 for (int ring = 0; ring <= 4; ring++) { 90 carrier.leds.setPixelColor(ring, colorGreen); 91 carrier.leds.show(); 92 delay(100); 93 carrier.leds.clear(); 94 Serial.print("Hola desde if: "); 95 Serial.println(msg); 96 lightsOff(); 97 } 98 for (int ring = 0; ring <= 4; ring++) { 99 carrier.leds.setPixelColor(ring, colorGreen); 100 carrier.leds.show(); 101 delay(100); 102 carrier.leds.clear(); 103 Serial.print("Hola desde if: "); 104 Serial.println(msg); 105 lightsOff(); 106 } 107 } else if(msg == "on2") { 108 touchCheckCompleted = true; 109 melody1(); 110 carrier.leds.setPixelColor(0, 200, 0, 255); 111 carrier.leds.setPixelColor(1, 200, 0, 255); 112 carrier.leds.setPixelColor(2, 200, 0, 255); 113 carrier.leds.setPixelColor(3, 200, 0, 255); 114 carrier.leds.setPixelColor(4, 200, 0, 255); 115 carrier.leds.show(); 116 delay(500); 117 lightsOff(); 118 delay(1000); 119 carrier.leds.setPixelColor(0, 200, 0, 255); 120 carrier.leds.setPixelColor(1, 200, 0, 255); 121 carrier.leds.setPixelColor(2, 200, 0, 255); 122 carrier.leds.setPixelColor(3, 200, 0, 255); 123 carrier.leds.setPixelColor(4, 200, 0, 255); 124 carrier.leds.show(); 125 delay(500); 126 lightsOff(); 127 delay(1000); 128 carrier.leds.setPixelColor(0, 200, 0, 255); 129 carrier.leds.setPixelColor(1, 200, 0, 255); 130 carrier.leds.setPixelColor(2, 200, 0, 255); 131 carrier.leds.setPixelColor(3, 200, 0, 255); 132 carrier.leds.setPixelColor(4, 200, 0, 255); 133 carrier.leds.show(); 134 delay(1000); 135 lightsOff(); 136 } else if(msg == "on3") { 137 touchCheckCompleted = true; 138 melody1(); 139 for (int ring = 0; ring <= 4; ring++) { 140 carrier.leds.setPixelColor(ring, colorBlue); 141 carrier.leds.show(); 142 delay(500); 143 carrier.leds.setPixelColor(ring, colorRed); 144 carrier.leds.show(); 145 delay(500); 146 carrier.leds.clear(); 147 Serial.print("Hola desde if: "); 148 Serial.println(msg); 149 lightsOff(); 150 } 151 } else { 152 //lightsOff(); 153 Serial.print("el mensaje fue:"); 154 Serial.print(msg); 155 } 156 } 157 } 158 159void lightsOff() { 160 carrier.leds.setPixelColor(0, 0, 0, 0); 161 carrier.leds.setPixelColor(1, 0, 0, 0); 162 carrier.leds.setPixelColor(2, 0, 0, 0); 163 carrier.leds.setPixelColor(3, 0, 0, 0); 164 carrier.leds.setPixelColor(4, 0, 0, 0); 165 carrier.leds.show(); 166} 167 168void melody1() { 169 if (touchCheckCompleted) { 170 for (int thisNote = 0; thisNote < 8; thisNote++) { 171 172 // to calculate the note duration, take one second divided by the note type. 173 //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc. 174 int noteDuration = 1000 / noteDurations[thisNote]; 175 carrier.Buzzer.sound(finalMelody[thisNote]); 176 delay(noteDuration); 177 // to distinguish the notes, set a minimum time between them. 178 // the note's duration + 30% seems to work well: 179 int pauseBetweenNotes = noteDuration * 1.0; 180 delay(pauseBetweenNotes); 181 // stop the tone playing: 182 carrier.Buzzer.noSound(); 183 } 184 } 185}
chargebattery
c
Code to charge battery with Nicla board
1/* 2 * This code is to charge battery 3 * using the nicla and the battery 4 * included for the challenge 5 * is needed the version 3.4.5 6 */ 7 8#include "Nicla_System.h" 9 10void setup(){ 11 nicla::begin(); 12 nicla::enableCharge(100); 13} 14void loop(){ 15// Your code here. 16}
datatoedgeimpulse
c
Code to extract/send data to Edge Impulse platform
1/* Edge Impulse Arduino examples 2 Copyright (c) 2022 EdgeImpulse Inc. 3 Permission is hereby granted, free of charge, to any person obtaining a copy 4 of this software and associated documentation files (the "Software"), to deal 5 in the Software without restriction, including without limitation the rights 6 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 copies of the Software, and to permit persons to whom the Software is 8 furnished to do so, subject to the following conditions: 9 The above copyright notice and this permission notice shall be included in 10 all copies or substantial portions of the Software. 11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 12 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 14 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 15 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 16 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 SOFTWARE. 18*/ 19 20/** 21 @brief Sample & upload data to Edge Impulse Studio. 22 @details Select 1 or multiple sensors by un-commenting the defines and select 23 a desired sample frequency. When this sketch runs, you can see raw sample 24 values outputted over the serial line. Now connect to the studio using the 25 `edge-impulse-data-forwarder` and start capturing data 26*/ 27 28#define SAMPLE_ACCELEROMETER 29#define SAMPLE_GYROSCOPE 30#define SAMPLE_ORIENTATION 31#define SAMPLE_ROTATION_VECTOR 32 33/** 34 Configure the sample frequency. This is the frequency used to send the data 35 to the studio regardless of the frequency used to sample the data from the 36 sensor. This differs per sensors, and can be modified in the API of the sensor 37*/ 38#define FREQUENCY_HZ 10 39 40/* Include ----------------------------------------------------------------- */ 41#include "Arduino_BHY2.h" 42 43/* Constants --------------------------------------------------------------- */ 44#if (FREQUENCY_HZ <= 0) 45#error "FREQUENCY_HZ should have a value greater than 0" 46#endif 47#define INTERVAL_MS (1000 / FREQUENCY_HZ) 48#define CONVERT_G_TO_MS2 9.80665f 49 50/* Forward declerations ---------------------------------------------------- */ 51void ei_printf(const char *format, ...); 52 53/* Private variables ------------------------------------------------------- */ 54static unsigned long last_interval_ms = 0; 55 56#ifdef SAMPLE_ACCELEROMETER 57SensorXYZ accel(SENSOR_ID_ACC); 58#endif 59#ifdef SAMPLE_GYROSCOPE 60SensorXYZ gyro(SENSOR_ID_GYRO); 61#endif 62#ifdef SAMPLE_ORIENTATION 63SensorOrientation ori(SENSOR_ID_ORI); 64#endif 65#ifdef SAMPLE_ROTATION_VECTOR 66SensorQuaternion rotation(SENSOR_ID_RV); 67#endif 68 69void setup() { 70 /* Init serial */ 71 Serial.begin(115200); 72 Serial.println("Edge Impulse sensor data ingestion\r\n"); 73 74 /* Init & start sensors */ 75 BHY2.begin(NICLA_I2C); 76#ifdef SAMPLE_ACCELEROMETER 77 accel.begin(); 78#endif 79#ifdef SAMPLE_GYROSCOPE 80 gyro.begin(); 81#endif 82#ifdef ORIENTATION 83 ori.begin(); 84#endif 85#ifdef SAMPLE_ROTATION_VECTOR 86 rotation.begin(); 87#endif 88} 89 90void loop() { 91 BHY2.update(); 92 delay(INTERVAL_MS); 93 94#ifdef SAMPLE_ACCELEROMETER 95 ei_printf("%f, %f, %f," 96 , (accel.x() * 8.0 / 32768.0) * CONVERT_G_TO_MS2 97 , (accel.y() * 8.0 / 32768.0) * CONVERT_G_TO_MS2 98 , (accel.z() * 8.0 / 32768.0) * CONVERT_G_TO_MS2 99 ); 100#endif 101#ifdef SAMPLE_GYROSCOPE 102 ei_printf("%f, %f, %f," 103 , (gyro.x() * 8.0 / 32768.0) * CONVERT_G_TO_MS2 104 , (gyro.y() * 8.0 / 32768.0) * CONVERT_G_TO_MS2 105 , (gyro.z() * 8.0 / 32768.0) * CONVERT_G_TO_MS2 106 ); 107#endif 108#ifdef SAMPLE_ORIENTATION 109 ei_printf("%f, %f, %f," 110 , ori.heading() 111 , ori.pitch() 112 , ori.roll() 113 ); 114#endif 115#ifdef SAMPLE_ROTATION_VECTOR 116 ei_printf("%f, %f, %f, %f," 117 , rotation.x() 118 , rotation.y() 119 , rotation.z() 120 , rotation.w() 121 ); 122#endif 123 ei_printf("\r\n"); 124} 125 126/** 127 @brief Printf function uses vsnprintf and output using Arduino Serial 128 @param[in] format Variable argument list 129*/ 130void ei_printf(const char *format, ...) { 131 static char print_buf[1024] = { 0 }; 132 133 va_list args; 134 va_start(args, format); 135 int r = vsnprintf(print_buf, sizeof(print_buf), format, args); 136 va_end(args); 137 138 if (r > 0) { 139 Serial.write(print_buf); 140 } 141}
Bluepy base code
Code base to receive data from Arduino in Python
1from bluepy import btle 2 3 4def my_main_code(new_value): 5 print("new value is: ", new_value) 6 7 8class MyDelegate(btle.DefaultDelegate): 9 def __init__(self, callback): 10 self.callback = callback 11 btle.DefaultDelegate.__init__(self) 12 # ... initialise here 13 14 def handleNotification(self, cHandle, data): 15 # Convert data to be easily consumed by callback 16 tum = int.from_bytes(data, byteorder='big') 17 self.callback(tum) 18 19 20# Initialisation ------- 21p = btle.Peripheral("1a:b4:c0:25:3a:aa")#change MAC adress 22p.setDelegate( MyDelegate(my_main_code) ) 23 24# Setup to turn notifications on, e.g. 25svc = p.getServiceByUUID("81c30e5c-1101-4f7d-a886-de3e90749161") 26ch = svc.getCharacteristics("81c30e5c-2101-4f7d-a886-de3e90749161")[0] 27 28setup_data = b"\x01\00" 29p.writeCharacteristic(ch.valHandle+1, setup_data) 30 31# Main loop -------- 32 33while True: 34 if p.waitForNotifications(1.0): 35 # handleNotification() was called 36 continue 37 38 print("Waiting...")
bluetoothandmodel
Arduino script with the model and BLE library
mqtt_nanorp2040
c
Base code to control Arduino Nano using MQTT
1#include <WiFiNINA.h> 2#include <PubSubClient.h> 3#include "secrets.h" 4 5WiFiClient wifi; 6int status = WL_IDLE_STATUS; 7 8IPAddress server(192, 168, 0, 0); //Ip raspberry 9PubSubClient client(wifi); 10 11void setup() { 12// while (!Serial){ 13// ; 14// } 15 pinMode(LEDR, OUTPUT); 16 pinMode(LEDG, OUTPUT); 17 pinMode(LEDB, OUTPUT); 18 Serial.begin(9600); 19 Serial.println("OK"); 20 Serial.print("Connessione..."); 21 while (status != WL_CONNECTED) { 22 status = WiFi.begin(WIFI_SSID, WIFI_PASS); 23 Serial.print("."); 24 delay(1000); 25 } 26 Serial.println("Connected to WiFi!\n"); 27 28 client.setServer(server, 1883); 29 client.setCallback(callback); 30 31 if (client.connect("arduinosub")) { 32 Serial.println("mqtt connected"); 33 client.subscribe("dance/lights"); //change depending on the topic you want to use or add new ones in case you're using more 34 } else { 35 Serial.println("mqtt not connected"); 36 Serial.print("failed, rc="); 37 Serial.println(client.state()); 38 } 39} 40 41void loop() { 42 client.loop(); 43} 44 45void callback(char* topic, byte* payload, unsigned int length){ 46 String msg; 47 for (int i = 0; i < length; i++) { 48 msg += (char)payload[i]; 49 } 50 Serial.println(msg); 51 if (strcmp(topic, "dance/lights") == 0) { 52 if (msg == "on") {//change this in case you're receiveing different messages 53 digitalWrite(LEDR, HIGH);//change all this part depending on what components you're using 54 delay(500); 55 digitalWrite(LEDR, LOW); 56 delay(500); 57 digitalWrite(LEDR, HIGH); 58 delay(500); 59 digitalWrite(LEDR, LOW); 60 delay(500); 61 digitalWrite(LEDR, HIGH); 62 delay(500); 63 digitalWrite(LEDR, LOW); 64 }else if(msg == "on2"){ 65 digitalWrite(LEDG, HIGH); 66 delay(400); 67 digitalWrite(LEDG, LOW); 68 delay(400); 69 digitalWrite(LEDG, HIGH); 70 delay(400); 71 digitalWrite(LEDG, LOW); 72 delay(400); 73 digitalWrite(LEDG, HIGH); 74 delay(400); 75 digitalWrite(LEDG, LOW); 76 Serial.print("el mensaje fue:"); 77 Serial.print(msg); 78 }else if(msg == "on3"){ 79 digitalWrite(LEDB, HIGH); 80 delay(1500); 81 digitalWrite(LEDB, LOW); 82 Serial.print("el mensaje fue:"); 83 Serial.print(msg); 84 } 85 else{ 86 //lightsOff(); 87 Serial.print("el mensaje fue:"); 88 Serial.print(msg); 89 } 90 } 91}
basecodeble
Base code for BLE library to send data to Linux
1//============================================================================== 2// Includes 3//============================================================================== 4 5#include <ArduinoBLE.h> 6#include "Nicla_System.h" 7#include "Arduino_BHY2.h" 8 9//============================================================================== 10// LED / State status functions 11//============================================================================== 12 13 14void rgbLedRed() 15{ 16 digitalWrite(LEDR, HIGH); 17 digitalWrite(LEDG, LOW); 18 digitalWrite(LEDB, LOW); 19} 20 21void rgbLedGreen() 22{ 23 digitalWrite(LEDR, LOW); 24 digitalWrite(LEDG, HIGH); 25 digitalWrite(LEDB, LOW); 26} 27 28void setupLED() { 29 // Prepare LED pins. 30 pinMode(LEDR, OUTPUT); 31 pinMode(LEDG, OUTPUT); 32 pinMode(LEDB, OUTPUT); 33} 34 35 36//============================================================================== 37// BLE 38//============================================================================== 39 40#define LOCAL_NAME "LalotestNICLA" //Change the name 41#define FLOAT_BYTE_SIZE 4 42#define UUID_GEN(val) ("81c30e5c-" val "-4f7d-a886-de3e90749161") 43 44BLEService service (UUID_GEN("1101")); 45BLEUnsignedCharCharacteristic gestureDataCharacteristic (UUID_GEN("2101"), BLERead | BLENotify); 46 47void setupBLE() { 48 service.addCharacteristic(gestureDataCharacteristic); 49 50 // Start the core BLE engine. 51 if (!BLE.begin()) 52 { 53 Serial.println("Failed to initialized BLE!"); 54 //showErrorLed(); 55 //while (1) showErrorLed(); 56 } 57 58 String address = BLE.address(); 59 60 // Output BLE settings over Serial. 61 Serial.print("address = "); 62 Serial.println(address); 63 64 address.toUpperCase(); 65 66 static String deviceName = LOCAL_NAME; 67 deviceName += " - "; 68 deviceName += address[address.length() - 5]; 69 deviceName += address[address.length() - 4]; 70 deviceName += address[address.length() - 2]; 71 deviceName += address[address.length() - 1]; 72 73 Serial.print("deviceName = "); 74 Serial.println(deviceName); 75 76 Serial.print("localName = "); 77 Serial.println(deviceName); 78 79 // Set up properties for the whole service. 80 BLE.setLocalName(deviceName.c_str()); 81 BLE.setDeviceName(deviceName.c_str()); 82 BLE.addService(service); 83 BLE.setAdvertisedService(service); 84 85 // Print out full UUID and MAC address. 86 Serial.println("Peripheral advertising info: "); 87 Serial.print("Name: "); 88 Serial.println(LOCAL_NAME); 89 Serial.print("MAC: "); 90 Serial.println(BLE.address()); 91 Serial.print("Service UUID: "); 92 Serial.println(service.uuid()); 93 94 // Start up the service itself. 95 96 BLE.advertise(); 97 98 Serial.println("Bluetooth device active, waiting for connections..."); 99} 100 101//============================================================================== 102// Setup / Loop 103//============================================================================== 104 105void setup() { 106 Serial.begin(115200); 107 setupLED(); 108 setupBLE(); 109 //rgbLedRed(); 110 rgbLedGreen(); 111} 112 113void loop() { 114 // if a central is connected to the peripheral: 115 static bool wasConnected = false; 116 bool isConnected = BLE.connected(); 117 wasConnected = isConnected; 118 if (isConnected) { //change this part to send data using BLE to python 119 int battery = analogRead(A0); 120 Serial.print("Battery Level % is now: "); 121 Serial.println(battery); 122 gestureDataCharacteristic.writeValue(battery); 123 delay(500); 124 } 125}
Comments
Only logged in users can leave comments