Hey all, I’m trying to figure out the best way to attack this problem. I have a Mic (Max4466) -> ADC (ADS1115) -> Arduino Nano 33 IoT -> Processing via Serial (USB).
My current test sketches work like this:
-Arduino is continually getting Mic values in loop(), and when it gets a ‘1’ from Processing, it sends the current Mic value via Serial. Mic values can be either -1 to 1 or abs(-1 to 1), depending on what Processing will need.
-Processing sends a ‘1’ then a ‘0’ to the Arduino every frame of draw(), receives the current mic value, and prints the value to console.
That’s all well and good, but draw() is only running at 60fps and the ADC’s sample rate is 44.1 KHz. Arduino’s loop() runs at about 117 KHz.
I have a few audio-visualizer sketches that use the Sound library’s amplitude and fft classes, and the audio input. I want to modify them to use the serial values instead of the sound card so that i can use the Arduino with my RasPi. For fft to work it’s going to need to call the values from the Arduino at samplerate, not framerate. At the same time, draw() still needs to run at framerate because it’s drawing the visualizations.
Other than buying a a soundcard for the RasPi (which is still an option if this is too complicated), how can i get the Processing sketch to read the serial values at 44.1 KHz or get the serial values into the Sound input?
Test Sketch Processing:
import processing.serial.*;
Serial myPort;
String inString = "";
void setup()
{
size(200, 200);
// Show serial ports
printArray(Serial.list());
// Set up Serial ports
String portName = Serial.list()[4];
myPort = new Serial(this, portName, 9600);
// Show selected port names
println("");
println(portName);
println(myPort);
}
void draw()
{
// Call to Arduino
myPort.write('1');
myPort.write('0');
// Get from Arduino
int lf = 10;
while (myPort.available() > 0)
{
inString = myPort.readStringUntil(lf);
}
float arduinoVal = float(inString);
println(arduinoVal);
}
Mic Sketch Arduino:
#include<Wire.h>
#include <Adafruit_ADS1015.h>
// ADC
Adafruit_ADS1115 ads;
// Mic Level
float outVal = 0.0f;
// Store Processing Call Variable
char processingCallVal;
void setup()
{
Serial.begin(9600);
// ADS1115 setup
ads.setGain(GAIN_ONE);
ads.begin();
}
void loop()
{
// Process Mic/ADC input
int16_t adc0 = ads.readADC_SingleEnded(0);
float multiplier = 0.125f;
//outVal = abs( 1 - ( (adc0 * multiplier) / 1644.0f ) ); // amplitude between 0 and 1
outVal = 1 - ( (adc0 * multiplier) / 1644.0f ); // Amplitude between -1 and 1
// If there's incoming serial data from Processing, read it
if (Serial.available())
{
processingCallVal = Serial.read();
}
// If the Processing value is 1, send the current Mic/ADC value and reset to 0
if (processingCallVal == '1')
{
Serial.println( outVal );
processingCallVal = '0';
}
else
{
processingCallVal = '0';
}
}