P5js plotter nano BLE

P5js plotter nano BLE è l’esperimento che ti permette di usare i dati provenienti dall’IMU presente sulla nuova arduino nano BLE direttamente in p5Js ed eseguirne un plotter grafico.

Su p5Js ho già scritto alcuni articoli, l’ultimo, in termini di tempo, riguardava la possibilità di realizzare 3 grafici lineari con dati random:

i dati erano allora generati dal comando “random(0, (height/3)-1)” che genera appunto un dato casuale nel range indicato.

Alcuni articoli di premessa al presente possono esserti utili:

anche se in questo esempio useari solo i dati dell’accelerometro nessuno ti vieta di scrivere un progetto più complesso in cui usare anche quelli del giroscopio e del magnetometro.

Il progetto P5js plotter nano BLE

In questo progetto: P5js plotter nano BLE usi una arduino nano dotata di IMU e BLE per raccogliere i dati di posizione nello spazio e trasferirli al P5Js.

In particolare in questa prima leggerai solo come realizzare la parte relativa alla componente cliente P5Js e come integrare la possibilità di realizzare grafici da dati random con la ricezione dei dati attraverso il BLE: Bluetooth Low Energy.

Nel prossimo articolo leggerai come scrivere il codice lato Arduino in cui i dati raccolti dalla nuova nano BLE saranno trasferiti al computer per usarli con questa parte del progetto.

L’area di visualizzazione

L’area dio visualizzazione dei dati è la medesima già vitsa, un’area da 800 x 400 px che è opprtunamente divisa in 3 sottoaree:

a ciascuna delle quali è statao assegnato un colore ( patriottico ) ed una lettera corrispondente all’asse del quale sranno visualizzati i dati.

Il codice

il codice del progetto è il seguente:

const serviceUuid = "19b10010-e8f2-537e-4f6c-d104768a1214";              
const characteristicsUUID = {
  accX: "19b10011-e8f2-537e-4f6c-d104768a1214",
  accY: "19b10012-e8f2-537e-4f6c-d104768a1214",
  accZ: "19b10013-e8f2-537e-4f6c-d104768a1214"
}
let accXCharacteristic;
let accYCharacteristic;
let accZCharacteristic;
let myBLE;
let x=0;
let accX,accY,accZ;
let y1,y2,y3;
let oldX, oldY1, oldY2, oldY3
let step = 5;
let h3 = 0;


function setup() {
  createCanvas(800, 400);
  init();
  myBLE = new p5ble();

  // Create a 'Connect and Start Notifications' button
  const connectButton = createButton('Connect and Start Notifications')
  connectButton.mousePressed(connectAndStartNotify);
  
  h3 = int((height/3)-1);

}

function init() {
  background(0);
  stroke(0, 0, 255);
  line(0, height / 1.5, width, height / 1.5);
  line(0, height / 3, width, height / 3);
  textSize(32);    
  
  fill(0, 255, 0);          text('X', 5, 30);
  fill(255);    text('Y', 5, 165);
  fill(255, 0, 0);    text('Z', 5, 295);
}

function draw() {
  //console.log("X: ", x, " A: ", accX, " B: ", accY, " C: ", accZ, " H3: ", h3);

  
  if ( 0 < accX && accX < 180 ) y1 = int(map(accX, 0, 180, 0, h3,   true)); 
  if ( 0 < accY && accY < 180 ) y2 = h3+int(map(accY,0,180,0,h3,    true)); 
  if ( 0 < accZ && accZ < 180 ) y3 = (h3*2)+int(map(accZ,0,180,0,h3,true)); 
  
  if (oldX < 800) {
    stroke(0, 255, 0);        line(oldX, oldY1, x, y1);
    stroke(255);              line(oldX, oldY2, x, y2);
    stroke(255, 0, 0);        line(oldX, oldY3, x, y3);

  }
  
  oldX = x;
  oldY1 = y1;
  oldY2 = y2;
  oldY3 = y3;

  if (x > 800) { x = 0; init(); } 
  else {         x += step      }
}

function connectAndStartNotify() {
  // Connect to a device by passing the service UUID
  myBLE.connect(serviceUuid, gotCharacteristics);
}

function gotCharacteristics(error, characteristics) {
  if (error) console.log('error: ', error);

  console.log(characteristics[1].uuid);
  for (let i = 0; i < characteristics.length; i++) {
    if (characteristics[i].uuid == characteristicsUUID.accX) {
      accXCharacteristic = characteristics[i];
      myBLE.startNotifications(accXCharacteristic, handleAccX);
    } else if (characteristics[i].uuid == characteristicsUUID.accY) {
      accYCharacteristic = characteristics[i];
      myBLE.startNotifications(accYCharacteristic, handleAccY);
    } else if (characteristics[i].uuid == characteristicsUUID.accZ) {
      accZCharacteristic = characteristics[i];
      myBLE.startNotifications(accZCharacteristic, handleAccZ);
    } else {
      console.log("nothing");
    }
  }
}

function handleAccX(data) {
  //console.log('X: ', data);
  accX = Number(data);
}

function handleAccY(data) {
  //console.log('Y: ', data);
  accY = Number(data);
}

function handleAccZ(data) {
  //console.log('Z: ', data);
  accZ = Number(data);
}

Descrizione del codice P5Js

in cui le prime linee 001-006 definiscono gli UUID del servizio e delle tre caratterisctiche che userai per trasferire i dati di accelerazione dei tre singoli assi.

Come scelta progettuale ho deciso di creare tre caratteristiche che potessero essere utilizzate in modo indipendente per ciascun asse.

linee 007-016: definisci tutte le variabili che ti serviranno per il corretto funzionamento dello sketch;

linea 020: crei l’area di 800x400px in cui saranno visualizzati i grafici dei tre assi;

linea 021: richiami la funzione init() che non è stata cambiata dal precedente esempio;

linee 022-026: anche queste non sono cambiate rispetto al primo esempio di connessione BLE da P5Js e servono per creare l’oggetto myBLE ed il bottone.

Tale bottone ti serve per eseguire la scansione ed accoppiamento dei dispositivi Bluetooth;

linea 028: calcola un terzo dell’altezza per eseguire agevolmente i calcoli per il render delle linee grafiche;

Salto la funzione init() in cui le uniche linee aggiunte sono 039,040,041 in cui ciascuna linea scrive la corrispondente lettera.

La funzione draw

La funzione draw è simile a quella che hai già visto per la realizzazione di grafici random.

La differenza che in questo esempio le linee 048-050 sono precedute, ciascuna, da un if il cui scopo è assicurarti che i dati ricevuti siano in un angolo compreso tra 0 e 180.

Al posto dei numeri sommati alla coordinata y ( come hai  visto nel precedente articolo ) in questo ho usato la variabbile h3 che è già pronta per tale utilizzo.

Le restanti linee sono identiche alle precedenti e tale concetto vale anche per le funzioni: connectAndStartNotify() e gotCharacteristics(error, characteristics) mentre cambiano le funzioni successive:

linee 093-096: definisci la funzione handleAccX richiamata dalla linea 080 quando arrivano dati sulla specifica caratteristica. 

Lo scopo della handleAccX è valorizzare la variabile accX con il dato normalizzato numericamente;

Per facilitarci il compito  farai in modo che lo sketch arduino ti invii il valore angolare in scala 0-180° in modo da rendere più semplici le operazioni di realizzazione del grafico.

Il video

Ecco un video dimostrativo di ciò che vedrai nel P5Js script quando avrai connesso il tuo arduino nano BLE:

Nei prossimi articoli leggerai come realizzare lo sketch su arduino.

Prima di inserire un commento, per favore, leggi il regolamento

Permanent link to this article: https://www.mauroalfieri.it/elettronica/p5js-plotter-nano-ble.html

Lascia un commento

Your email address will not be published.

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.