Cereal…err SERIAL

Cereal…err SERIAL
Cereal…err SERIAL

Code used to obtain data from the onboard IMU of the Arduino Nano IoT

Lab: Intro to Asynchronous Serial Communications

#include <Arduino_LSM6DS3.h>

void setup() {
  Serial.begin(9600);
  IMU.begin();
  while (Serial.available() <= 0) {
    //while (IMU.accelerationAvailable() <= 0) {
    Serial.println("hello"); // send a starting message
    delay(300);              // wait 1/3 second
  }
}


void loop () {

  float aX, aY, aZ;
  float gX, gY, gZ;
  const char * comma = ", ";
  if (IMU.accelerationAvailable() && IMU.gyroscopeAvailable() && Serial.available());
  int inByte = Serial.read();
  IMU.readAcceleration(aX, aY, aZ);
  IMU.readGyroscope(gX, gY, gZ);
  Serial.print(aX); Serial.print(comma); Serial.print("aX"); Serial.print(comma);
  Serial.print(aY); Serial.print(comma); Serial.print("aY"); Serial.print(comma);
  Serial.print(aZ); Serial.print(comma); Serial.print("aZ"); Serial.print(comma);
  Serial.print(gX); Serial.print(comma); Serial.print("gX"); Serial.print(comma);
  Serial.print(gY); Serial.print(comma); Serial.print("gY"); Serial.print(comma);
  Serial.println(gZ); Serial.println("gZ");
}

Lab: Serial Input to p5.js

I started with a sketch to enable communication from the Nano 33IoT to the computer, this communication enabled the computer to know which port the Nano was connected to. Using an intermediary program called P5.serialcontrol I was able to find the port that the Nano was connected to, in my case it was COM4. The code below is for the Nano.

void setup() {
  Serial.begin(9600); // initialize serial communications
}
 
void loop() {
  int potentiometer = analogRead(A0);                  // read the input pin
  int mappedPot = map(potentiometer, 0, 1023, 0, 255); // remap the pot value to fit in 1 byte
  Serial.write(mappedPot);                             // print it out the serial port
  delay(1);                                            // slight delay to stabilize the ADC
}

This next code is from p5.js.

let serial; // variable to hold an instance of the serialport library
 
function setup() {
  serial = new p5.SerialPort(); // make a new instance of the serialport library
  serial.on('list', printList); // set a callback function for the serialport list event
 
  serial.list(); // list the serial ports
}
 
// get the list of ports:
function printList(portList) {
  // portList is an array of serial port names
  for (var i = 0; i < portList.length; i++) {
    // Display the list the console:
    console.log(i + portList[i]);
  }
}

After the I knew the port, the next task was communication between the Nano and the p5.js web editor, this is no easy task luckily the aforementioned program , P5.serialcontrol comes to the rescue again. This is especially important for this communication to work since the p5.js environment and the Nano cannot natively communicate. The code is rather complex and includes a library file.

The library file is very long find it at the link below.

https://github.com/p5-serial/p5.serialport/blob/master/lib/p5.serialport.js

Here is the code to interface with the potentiometer connected to the Nano.

// let serial; // variable to hold an instance of the serialport library
 
// function setup() {
//   serial = new p5.SerialPort(); // make a new instance of the serialport library
//   serial.on('list', printList); // set a callback function for the serialport list event
 
//   serial.list(); // list the serial ports
// }
 
// // get the list of ports:
// function printList(portList) {
//   // portList is an array of serial port names
//   for (var i = 0; i < portList.length; i++) {
//     // Display the list the console:
//     console.log(i + portList[i]);
//   }
// }
let xPos = 0; 
let serial;          // variable to hold an instance of the serialport library
let portName = 'COM4';  // fill in your serial port name here
let inData;                             // for incoming se 

function setup() {
  createCanvas(1200, 500);
  background(0x08, 0x16, 0x40);
  serial = new p5.SerialPort();       // make a new instance of the serialport library
  serial.list();
  serial.open('COM4');
  serial.on('list', printList);  // set a callback function for the serialport list event
  serial.on('connected', serverConnected); // callback for connecting to the server
  serial.on('open', portOpen);        // callback for the port opening
  serial.on('data', serialEvent);     // callback for when new data arrives
  serial.on('error', serialError);    // callback for errors
  serial.on('close', portClose);      // callback for the port closing
 
  // serial.list();                      // list the serial ports
  // serial.open(portName);              // open a serial port
  
}
 
function graphData(newData) {
  // map the range of the input to the window height:
  var yPos = map(newData, 0, 255, 0, height);
  // draw the line in a pretty color:
  stroke(0xA8, 0xD9, 0xA7);
  line(xPos, height, xPos, height - yPos);
  // at the edge of the screen, go back to the beginning:
  if (xPos >= width) {
    xPos = 0;
    // clear the screen by resetting the background:
    background(0x08, 0x16, 0x40);
  } else {
    // increment the horizontal position for the next reading:
    xPos++;
  }
}

// get the list of ports:
function printList(portList) {
  // portList is an array of serial port names
  for (var i = 0; i < portList.length; i++) {
    // Display the list the console:
    console.log(i + portList[i]);
  }
}

function serverConnected() {
  console.log('connected to server.');
}
 
function portOpen() {
  console.log('the serial port opened.')
}
 
function serialEvent() {
 inData = Number(serial.read());
}
 
function serialError(err) {
  console.log('Something went wrong with the serial port. ' + err);
}
 
function portClose() {
  console.log('The serial port closed.');
}

function draw(){
  // background(0);
  //  fill(255);
  //  text("sensor value: " + inData, 2, 10);
  graphData(inData);
}

Lab: Serial Output From p5.js

Here I some input happening in p5.js and need to have the Nano do something, in this case light a red LED.

Here is the code for the Nano.

const int ledPin = 5; // the pin that the LED is attached to
int incomingByte;     // a variable to read incoming serial data into
 
void setup() {
  Serial.begin(9600);             // initialize serial communication
  pinMode(ledPin, OUTPUT);        // initialize the LED pin as an output
}
 
void loop() {
  if (Serial.available() > 0) { // see if there's incoming serial data
    incomingByte = Serial.read(); // read it
    if (incomingByte == 'H') {    // if it's a capital H (ASCII 72),
      digitalWrite(ledPin, HIGH); // turn on the LED
      // if you're using a speaker instead of an LED, uncomment line below  and comment out the previous line:
      //  tone(5, 440);           // play middle A on pin 5
    }
    if (incomingByte == 'L') {    // if it's an L (ASCII 76)
      digitalWrite(ledPin, LOW);  // turn off the LED
      // if you're using a speaker instead of an LED, uncomment line below  and comment out the previous line:
      // noTone(5);
    }
  }
}

Again we need to include the library file for P5.serialcontrol

The library file is very long find it at the link below.

https://github.com/p5-serial/p5.serialport/blob/master/lib/p5.serialport.js

And here is the p5.js code to turn on the red LED

  var serial;          // variable to hold an instance of the serialport library
var portName = 'COM3'; // fill in your serial port name here
var inData;                            // for incoming serial data
var outByte = 0;                       // for outgoing data
 
function setup() {
  createCanvas(400, 300);          // make the canvas
  serial = new p5.SerialPort();    // make a new instance of the serialport library
  serial.on('data', serialEvent);  // callback for when new data arrives
  serial.on('error', serialError); // callback for errors
  serial.open(portName);           // open a serial port
}


function serialEvent() {
  // read a byte from the serial port:
  var inByte = serial.read();
  // store it in a global variable:
  inData = inByte;
}
 
function serialError(err) {
  println('Something went wrong with the serial port. ' + err);
}

function draw() {
// black background, white text:
  background(0);
  fill(255);
  // display the incoming serial data as a string:
  text("incoming value: " + inData, 30, 30);
}

function mouseDragged() {
  // map the mouseY to a range from 0 to 255:
  outByte = int(map(mouseY, 0, height, 0, 255));
  // send it out the serial port:
  serial.write(outByte);
}

function keyPressed() {
  if (key >= 0 && key <= 9) { // if the user presses 0 through 9
    outByte = byte(key * 25); // map the key to a range from 0 to 225
  }
  serial.write(outByte); // send it out the serial port
}

The previous five videos show various different interactions with the Nano using serial communication.  Once I understood what was happening and how to alter the code inside p5.js to communicate the way I wanted it to this process wasn’t too bad, now if I had to write that library file…I’m not sure if I’d know where to start.