Project 2 update and an introduction to I2C. I2C is pretty straight forward especially when working with a break-out board form a manufacturer that has good support and most of all a good library to accompany the board. For both the lab and part of Project 2 the Adafruit VL53L0X Time of Flight Distance Sensor was chosen. This small break-out board is easy to include in projects of all sizes due to it small for factor. The size and accuracy of this sensor is what lead to it being chosen for Project 2.
Project 2 must include some form of microcontroller-to-PC communication. We all sit in front of the computer, so of us for many many hours a day, and some of us sit in the same place for far too long. In concept, Project 2 hopes to address this behavior by using an Arduino Nano 33IoT, a few LED’s, the aforementioned VL53L0X Time of Flight Distance Sensor, and a few different code libraries-one being #keyboard.h. The general flow is as follows:
Set interval at which the user wants to disengage form computer use
Green, Yellow, and Red LED’s will light at given periods to alert user that the interval is coming to an end.
Once interval has elapsed, the Nano will send a sleep command to the PC, using the #keyboard.h library, to put the screen to sleep.
The Nano will then look for a sensor reading form the VL53L0X to determine if the user has moved from in front of the computer.
Once the distance reading of the sensor is greater than a given range the Nano will send a keyboard command of “SPACEBAR” to the PC which will in turn wake up the screen.
So far the individual code modules for each task work independently of each other. The next task is to combine the modules into a single sketch and test the functionality of the concept.
The biggest problem so far has been…WINDOWS!! Windows really doesn’t play nicely when accessing the COM ports and really hates when make a device that actually looks like two devices. Such as when you take a microcontroller, a Nano 33IoT, and make it a keyboard. This forces the PC to re-innumerate the serial devices shifting the Nano down on the port list to make a place for the new keyboard device created. This displays some odd behavior, when plugging in the Nano after the code has been flashed to the board, the screen shuts off immediately. This is not the intended behavior. Some adjustment to the code and possibly drivers will need to be investigated in order to sort this out.
The VL53L0X Time of Flight Distance Sensor on the other hand is a dream to work with, basically plug-and-play. The library is fairly easy to understand and make changes as need to accommodated different scenarios.
For the most part this lab about two-way serial communication is fairly straightforward and basically the same as the serial communication lab. Since I was using the on board IMU I needed to adapt the code to access the data it produces. Easily done by adding begin.imu() in the setup and instead of analogRead() using accelerometerRead(). The interesting part about using the internal IMU is how the library is written, the function always looks for three variables when executing the read. This was not made clear until I opened the library file in a text editor to find what the function was looking for. After that, the Arduino code performed as expected.
const int buttonPin = 2; // digital input
int sensorValue0;
int sensorValue1;
int sensorValue2;
void setup() {
Serial.begin(9600);// configure the serial connection:
pinMode(buttonPin, INPUT);// configure the digital input:
while (Serial.available() <= 0) {
Serial.println("hello"); // send a starting message
delay(300); // wait 1/3 second
}
}
void loop() {
if (Serial.available() > 0) {
int inByte = Serial.read();
sensorValue0 = analogRead(A0);
Serial.print(sensorValue0);
Serial.print(",");
sensorValue1 = analogRead(A1);
Serial.print(sensorValue1);
Serial.print(",");
// read the button:
sensorValue2 = digitalRead(buttonPin);
// print the results:
Serial.println(sensorValue2);
// Serial.print('\r\n');
}
}
On the p5.js side the code was no issue at all. Straightforward and easy to understand. Until adding the handshake portion of the code. Everything populated as expected but selecting the port from the drop down menu did nothing. Nada. Zilch. Zero. So on to troubleshooting this. My thought was since the menu has had only one option and it is pre-selected the portSelector.changed(openPort) call did nothing. So I plugged in a second Nano thinking this would help. It did not at first. The next thing I tried was to switch the boards since the board with the two-waySerialRead shows up as COM3, which is the first port on the list. So now if you’re still following, two Nano’s are plugged in the board with the correct code on it is connected to COM4 and the secondary board is connected at COM3. This enables me to select COM4 from the drop down and causes the portSelector.changed(openPort) function to be called and bam!!! It works! I’m still playing with the code to see if I can have a null value populate the list before the first active COM in order to force the portSelector.changed(openPort) function to be called.
var serial; // variable to hold an instance of the serialport library
var portSelector; // a select menu for the port list
var vert = 0;
var horiz = 0;
function setup() {
frameRate(120);
createCanvas(640, 480); // make canvas
background(0); // black background
smooth(); // antialias drawing lines
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.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
}
// get the list of ports:
function printList(portList) {
// make a select menu and position it:
portSelector = createSelect();
portSelector.position(10, 500);
// 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]);
// add item to the select menu:
portSelector.option(portList[i]);
}
// set a handler for when a port is selected from the menu:
portSelector.changed(openPort);
}
function openPort() {
var thisPort = portSelector.value();
if (thisPort != null) {
serial.open(thisPort);
}
}
function serverConnected() {
print('connected to server.');
}
function portOpen() {
console.log('the serial port opened.')
// send a byte to prompt the microcontroller to send:
serial.write('x');
}
function serialError(err) {
print('Something went wrong with the serial port. ' + err);
}
function portClose() {
print('The serial port closed.');
}
function serialEvent() {
// read a string from the serial port
// until you get carriage return and newline:
var inString = serial.readStringUntil('\r\n');
//check to see that there's actually a string there:
if (inString.length > 0) {
if (inString !== 'hello') { // if you get hello, ignore it
var sensors = split(inString, ','); // split the string on the commas
if (sensors.length > 2) { // if there are three elements
vert = map(sensors[0], 0, 1023, width, 0);
horiz = map(sensors[1], 0, 1023, 0, height);
if (sensors[2] != 0) {
noStroke();
fill(0);
rect(0, 0, width, height)
}
}
}
serial.write('x'); // send a byte requesting more serial data
}
}
function draw() {
fill(r, vert /2, horiz /2);
noStroke();
ellipseMode(CENTER);
ellipse(vert, horiz, 10, 10); // draw the circle
// }
// }
}
The above code is to generate an Etch-A-Sketch with a color gradient of blue and green mapped to the x, y location of the ellipse()
The internal IMU has a fairly low range, as stated in the literature it is -4-4, which gives a low resolution but works nonetheless. I’m going to try and map the value from the IMU in a different way to combat this issue.
The DOM, sounds scary but really it’s just like everything else in coding, with a little practice it’s not too bad at all. I had very little issue with this section of the class, mostly because it builds on the previous sections. Prior to this I had been using createSlider to alter different values for given elements in a sketch like color or diameter. Including other types DOM’s is pretty straight forward remembering to create a var to hold the information the DOM is providing is the key to making everything play nicely. Once the basic structure is setup, passing the information in is painless.
function addItem() {
// Create an li element
var li = createElement('li', itemInput.value());
// set li's parent to an element with id "todolist"
li.parent("todolist");
li.style('color', 'cyan')
}
I first used createP which didn’t take advantage of the <ol id='orderedlist'></ol> so I switched to createElement and that did the trick.
Overall adding DOM’s top p5.js is pretty intuitive and i can see how there are many possible scenarios that the will be useful in the future.
So I’ve started using class() for defining objects, got it. And now let’s put those objects into an array, no problem got it. Now let’s make it so they all move independently of each other….don’t got it.
See here is the problem, the block of code is pretty straight forward, when used on one object no problem however, if that object is in an array the issue rears it’s evil little head. When any of the objects in the array meet the criteria for this.x or this.y the value is inverted because it is multiplied by -1. So instead of each object independently meeting the criteria and changing the value by (*-1), ALL objects in the array are assigned this value at the same time. How can the object only be effected by the condition logic in the aforementioned block of code only when that object meets the criteria?
Here is the code in it’s entirety
let speedx = 3;
let speedy = 5;
let speedx1 = 2;
let speedy1 = 1;
let squares = [];
let spots = [];
function setup() {
createCanvas(600, 600);
frameRate(10);
}
function mousePressed() {
if (random(1) < 0.5) {
let s = new Square(mouseX, mouseY, 50, 50, 5);
squares.push(s);
} else {
let s2 = new Spot(mouseX, mouseY, 50, 50);
spots.push(s2);
}
}
function draw() {
background(0);
for (let square of squares) {
// push();
square.show();
square.move();
// pop();
for (let i = 0; i < squares.length; i++) {
squares[i].move();
squares[i].show();
}
}
for (let spot of spots) {
// push();
spot.show();
spot.move();
// pop();
for (let i = 0; i < spots.length; i++) {
spots[i].move();
spots[i].show();
}
}
}
class Square {
constructor(tempX, tempY, tempH, tempW) {
this.x = tempX;
this.y = tempY;
this.h = tempH;
this.w = tempW;
}
move() {
if ((this.x > width) || (this.x < 0)) {
speedx = speedx * -1;
}
this.x = this.x + speedx;
if ((this.y > height) || (this.y < 0)) {
speedy = speedy * -1;
}
this.y = this.y + speedy;
}
show() {
push();
rectMode(CENTER);
stroke(255);
strokeWeight(1);
noFill();
rect(this.x, this.y, this.w, this.h);
pop();
// p;rint(this.x);
}
}
class Spot {
constructor(spotX, spotY, spotH, spotW) {
this.x = spotX;
this.y = spotY;
this.h = spotH;
this.w = spotW;
}
move() {
push();
if ((this.x > width) || (this.x < 0)) {
speedx1 = speedx1 * -1;
}
this.x = this.x + speedx1;
if ((this.y > height) || (this.y < 0)) {
speedy1 = speedy1 * -1;
}
this.y = this.y + speedy1;
pop();
}
show() {
// push();
ellipseMode(CENTER);
stroke(255, 0, 0);
strokeWeight(1);
noFill();
ellipse(this.x, this.y, this.h, this.w);
// pop();
// print(this.x);
}
}
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.
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.
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.
What can I say, the expected end of an outstanding seven weeks of class. But let’s get into the making of “Three Pigs Of the Apocalypse”. Stephanie Chen, Shaurya Seth, and I set out to tell our re-imagining of “The Three Little Pigs”. The Big Bad Wolf is represented by three current events: civil unrest, environmental chaos, and the advent of technology. Using a 3D modeled and rendered environment allowed us to take video clips of these current event s and set them into a world a little different than our own.
The challenge of this particular project was not of content or technical skills but that of geography as the groups was spread out between 3 different time zones. Never fear though, with the advent of technology,…pun intended, and with the help of Zoom and Google Drive it was like we were sitting in the same room. This whole process went pretty smoothly.
So what were the biggest issues you might ask, well for one Adobe Premier Pro has a nasty bug in it that causes persistent crashes. After loosing a day due to this and a few hours of research an answer to the cause of these crashes emerged, .avi. Premier Pro has an issues with it’s .avi compiler/converter. This would cause dropped frames and the software would try and recover from this in loop causing the playback window to freeze and eventually crash the program. Thankfully, having worked on files with many components before, my incessant need to save constantly was a life saver. After finding the issue I converted all the media to .mp4 and replaced the clips and voilà no crashing!! Adobe, I’m calling you out here, this issue has been logged for OVER a year now and there is no official response anywhere on the internet ( I know cause I viewed all the internet in search of a solution), Adobe you need to fix this problem.
It took 72 hours of rendering to complete the 3D modeled environment. We also had to troubleshoot an issue with embedding the video into the modeled environment. The solution finally came by using After Effects to extract each individual frame and use those frames as the source file for the embedded video.
As with any creative process your biggest friend is problem solving and perseverance. So without any further diatribe by yours truly, enjoy the show.
class descriptiveName() seems to be a very powerful aspect of p5.js however, there are parts about that I do not understand. I can create a sketch not using class descriptiveName() and make it do what I want like in the example that follows, rotate() a Line() around a location.
Just using function draw() I get this, which is the outcome I was looking for.
When I use a class descriptiveName() I get this:
let inner = [];
function setup() {
createCanvas(400, 400);
// inner1 = new Inner(0, 0, -200, -200 );
for (let i = 0; i < 50; i++) {
let vx = random(0, width);
let vy = random(0, height);
inner[i] = new Inner(0, 0, vx, vy)
}
}
function draw() {
background(0);
translate(width / 2, height / 2);
for (let i = 0; i < inner.length; i++) {
inner[i].show();
push();
let rep = 15;
angleMode(DEGREES);
rotate(rep);
pop();
rep = rep * 2;
}
}
class Inner {
constructor(x1, y1, x2, y2) {
this.x = x1;
this.y = y1;
this.a = x2;
this.b = y2;
}
show() {
// let rep = 15;
// angleMode(DEGREES);
// translate(width / 2, height / 2);
// push();
// rotate(rep);
stroke(255);
line(this.x, this.y, this.a, this.b);
// rep = rep*2;
// pop();
}
}
The above code shows my experimentation with trying to get the same result from class descriptiveName() and placing everything in draw().
After spending some time on this I decide to try another sketch to fulfill the week five excursive.
Sliders control the size of the rect() as well as the RGB fill() values.
I feel a bit lost down a deep deep hole, slowly climbing towards what seems the top longing for the daylight to strike me directly however each time a the top appears the hole seemingly grows, endlessly slowing the progress that just happened. I suppose that this feeling will continue for sometime, there are clear objectives in my head but producing these outcomes has proven more difficult than at first anticipated. Time. Time is the answer, but not just time, time spent with what is new and there in lies the root of the issue, it’s all new therefore, the time needed to fully grasp the ideas is exponential since each concept builds on the last.
10PRINT is in theory fairly easy to understand however, when applying more complex functions to this code things change rapidly. The following examples are all based on the same code with VERY slight adjustments, the outputs are VERY different.
So my question is this: Are these all considered iterations of 10PRINT?
Based on what we learned for the past four weeks, we want to create something that incorporates components from previous Labs. Our project scope was to create a small DJ station with:
One rotary potentiometer
One ribbon/flex sensor that can be used to change the tone/pitch of the audio
One (or multiple) LEDs to indicate that the audio is on/off
Other ideas/functions we wanted to try exploring:
To map the range of the circular ribbon sensor to the RGB LED, so that the colours would change according to the touch sensor
To map the sound of the speaker to the musical notes, so different areas of the sensor will trigger different musical notes
To have multiple ribbon sensors
Process:
Since we are familiar with the setup of sensor + speaker combo, and adding LED should be fairly straightforward (we were wrong), we just need to work on incorporating the circular ribbon sensor into the circuit & the code component that comes with it.
We started by setting up the circular ribbon sensor and mapped its values and ranges. The ribbon sensor produced minimal but noticeable changes when touched, but the overall sound was not audible. Both Phil and I had pretty small speaker output from Lab 3, so it’s crucial that we figured out how to amplify it. We followed the transistor’s tutorial, as demonstrated by Tom, tried connecting it to Arduino Uno and changed to 5.5V, also found several other examples online, etc. but none of them seemed to work.
We decided it’s best to work on small chunks of circuits at a time, to ensure they are working and functioning as intended, before integrating them it into one big circuit setup, so: 1. connect ribbon sensor & rotary potentiometer to the speaker 2. connect speaker & pot to transistor 3. connect LED to the pots & speaker 4. integrate/code all components together.
Documentation:
1. Speaker + Rotary Pot with working Ribbon Sensor but small sound ft. Saturday Applications class
2. Speaker with Transistor for some audibly LOUD SOUND. Breadboard was tight so have to press the Arduino down.
3. Speaker + Potentiometer + Ribbon Sensor. Sound is clear, but there was not much difference in sound when rotating the pot vs pressing on the sensor.
4. Played around with the delay(). Found the pitch and range that we want to keep. We wanted to make sure that there is a clear, audible differentiation between the rotary pot and the ribbon sensor.
5. Testing RGB LED with ribbon sensor and rotary pot, LED is flickering but is not entirely responsive to either pots.
6. Cue the RGB LED drama. Played with more delay() settings while trying to connect the LED to the pot. Still no relationship/correlation between pot and LED, the latter is flickering randomly.
We spent a good chunk of time trying to incorporate RGB LEDs and got into an interesting situation where everything seems to be working in reverse. We noticed that the LEDs display the opposite colour of what we input (i.e. red (255,0,0) would trigger blue/cyan, and cyan(0,255,255) would trigger red). We changed the digital input pin, flipped the LED, checked the datasheet, added and blocked out multiple code lines, but nothing seemed to work.
We decided to test again with a different RGB LED found on the floor, and it worked! That’s when we realised that we have been working with anode RGB LED all along, using a code written for a cathode RGB LEDs. We also noticed how the anode connects to negative/ground, while cathode connected to positive/red. Why are there two different kinds, and what are some of the occasions or purposes where having two different types of LEDs would be beneficial?
7. Final Output: We discovered the RGB LED mystery (described below), dropped it and decided to use two LEDs instead. Each pot controls one LED.
Schematic:
Arduino code:
const int blueLed = 8; const int redLed = 7; int analogValue1 = 0; int brightness1 = 0; int analogValue2 = 0; int brightness2 = 0;
void loop() { // get sensor reading int rotPot = analogRead(A0); int ribPot = analogRead(A1);
//map results of sensor range to pitch range float frequency = map(rotPot, 0, 1023, 50, 880); float pitch = map(ribPot, 0, 255, 440, 880); // float blueLed = map(brightness1, 0, 1023, 0, 255); // float redLed = map(brightness2, 0, 1023, 0, 255);
The output is different from what we planned, but still cool nonetheless! The DJ Station is on and will play the sound by default. We have two modes of controlling the audio, and both produce noticeable differences/alterations to the audio. We also have two corresponding coloured LEDs light that will flicker (when the user touch the ribbon sensor) or turn on and off (when the user turn the rotary potentiometer). Phil also made awesome renderings and prototype the enclosure of what it can look like!
Renderings and prototype of enclosure:
Takeaway:
We recreated the circuit setup many times to debug, and this was where working on multiple breadboards really helped. One of our ongoing challenges was to connect the pots/speaker setup to the LEDs. We transferred the LEDs setup through multiple breadboards to debug, and each time we always seemed to miss out on something (wrong digital or analog pin, wrong leg, wrong connection to power/ground, forgot to bridge across the breadboard, forgot to change digital pin number in the code, etc.) Overall, this project helped us to be proactive in troubleshooting and to try as many solutions or approaches as we can because at this stage, there are only so many things that can go wrong (…right?)
Color-coding is important, so are documentation and iterations, very important to keep a note so we have something to fall back on in case future experimentations failed.
Questions:
Difference between Cathode and anode LED, and why is there a need for both? What are some use cases for these two types of LEDs?
How to map the sensor to the music notes and/or LED? We tried this earl
How to map the output of the sensor to the LED while something else is being used/mapped?
How to use analog input to control two outputs?
We were playing around with digital inputs, with most of our current setups using digital pin 7 to 9. We switched to digital pin 5 & 6 once and that, when combined with our (semi) working code, shut down the board. Why did that happen?
We layered some delays() and they produced interesting audio effects?
First I made a bouncing ball, second I made the fill() change from (0, 255) based on the X position and Y position, then I made the background() change from (0, 255) based on the ball’s X, Y position, finally I added three sliders to change the RGB values independently.
I’m still having to refer back to the reference material to get the syntax correct but most of the terms and thinking through the actions of the code are making sense. I feel like there is a pretty steep learning curve associated with any coding. I find it interesting to be a beginner again, I haven’t had that opportunity in a long time, and it feels good to be challenged again. I see this skill as such an integral building block for many of the projects I have the desires to work on.