Hello all, this is my first post here, I hope I'm posting in the right place. I'm very new to Arduino and electronics and have been trying to work on something that is beyond my capabilities, but I'm getting tantalisingly close to a working prototype, but I have a bug that I am struggling to fix.
My project is to be able to send digital data from Pure Data (a visual programming music application) on my laptop to Arduino, then output as voltage via a quad DAC to a modular synth. This will basically allow me to send voltage to my synth to modulate and sequence it in all sorts of ways.
Phase one of my project is just to control the 0-5 volts going from Arduino to the synth via Pure Data. Next phases will be to increase the output voltage to -5/+5v, and to add more DACs, but that is for later.
So far I have successfully sent voltage from Arduino to the synth and modulated via Pure Data on the laptop, but the sound I am getting is a bit garbled/glitchy while being modulated and I believe it is because each message that is sent via serial is being preceded by a separate message "0" - so for example, if I assign volume to a potentiometer, each micro turn of the pot would set the volume to zero for a micro second before then setting the correct value. At least, that's what I think is happening.
Here's a screenshot from Pure Data showing what should be a single message received via serial:

I get the same result when I disconnect from Pure Data and send manually via the serial monitor in the Arduino IDE.
I'll paste my sketch below. I suspect my problem is something to do with the index variable that is set to 0 near the beginning of the loop section, but I haven't been able to find an alternative solution to that section of the code. Any unrelated improvements to the code are welcome, I am learning.
/*
Assigns value ranges to the 4 outputs of the MCP4728 quad DAC, which can then be controlled via Pure Data.
Based on these video tutorials by Sound Simulator (https://www.youtube.com/@SoundSimulator) on Youtube:
https://www.youtube.com/watch?v=PaWp6zny83I&list=PLyFkFo29zHvC5oiRAdwvwxADUeLhCm3lV&index=15
https://www.youtube.com/watch?v=zdYGiBlbBP8&list=PLyFkFo29zHvC5oiRAdwvwxADUeLhCm3lV&index=15
*/
// include dependencies for MCP4728 quad DAC
#include <Adafruit_MCP4728.h>
// this library allows you to communicate with I2C devices
#include <Wire.h>
Adafruit_MCP4728 mcp;
// Initiate variables
char buffer[40];
int index = 0;
int value = 0;
int CV1 = 0;
int CV2 = 0;
int CV3 = 0;
int CV4 = 0;
// the setup function runs once when you press reset or power the board
void setup(void) {
// start serial connection and set the 'Baud rate' (serial communication speed in bits per second). The baud rate must be set to the same value in Pure Data in order for the serial communication to work.
Serial.begin(115200);
// will pause Zero, Leonardo, etc until serial console opens
while (!Serial) {
delay(10);
}
// send message to Pure Data to confirm we are connected
Serial.println("Adafruit MCP4728 test!");
// try to initialize MCP4728
if (!mcp.begin()) {
Serial.println("Failed to find MCP4728 chip");
while (1) {
delay(10);
}
}
}
// the loop function runs over and over again forever
void loop() {
// check to see if anything is available in the serial receive buffer
while (Serial.available() > 0) {
// receive data sent to [comport] left inlet in Pure Data
index = 0;
do {
buffer[index] = Serial.read();
if (buffer[index]!=-1) {
index++;
}
}
while (buffer[index-1]!=32);
// convert value from ascii to integer
value = atoi(buffer);
// send converted value back to [comport] left outlet in Pure Data for debugging
Serial.println(value);
// assign value range to cv 1
if (value >= 0 && value <= 4095) { //0 to 4095
CV1 = value;
mcp.setChannelValue(MCP4728_CHANNEL_A, value);
}
// assign value range to cv 2
if (value >= 4096 && value <= 8191) { //4096 to 8191
CV2 = value - 4096;
mcp.setChannelValue(MCP4728_CHANNEL_B, CV2);
}
// assign value range to cv 3
if (value >= 8192 && value <= 12287) { //8192 to 12287
CV3 = value - 8192;
mcp.setChannelValue(MCP4728_CHANNEL_C, CV3);
}
// assign value range to cv 4
if (value >= 12288 && value <= 16383) { //12288 to 16383
CV4 = value - 12288;
mcp.setChannelValue(MCP4728_CHANNEL_D, CV4);
}
// delay(5);
}
}