I've built a project which multiplexed 20 odd pots through a Teensy and into Pure Data on my mac, to use with guitar processing effects. Now i'm trying to add virtual pots by using a joystick to select a virtual pot position on x axis and increase/decrease the value on Y axis.
I've gotten the code setup to remember the value of the pot once the joystick goes back to neutral, and to appropriately advance to the next virtual pot or backwards to previous pot. The selected virtual pot sets the array index for the array that stores the Y axis pot values.
I have the code working to remember the Y axis values when the joystick returns to neutral and to print the value to serial when it changes. The problem I'm having is that when I attempt to store the last value in the array, and then re-read it the next time I come back to that position with the x-axis selector, there is some bleed through happening.
You can see in the image attached that I scroll up to position 4, change the Y value up to 170, then scroll back down to position 0. On the way, it changes position 3 value to 170. When I scroll again past position 4 it begins writing value 170 into the array at positions 6,7,8, etc... Eventually if I scroll through the X-axis positions enough it really starts jumbling up the values or dropping them to zero.
I figured I was trying to read/write to the array too quickly, and added the 30ms delay which actually seems to have resolved the jumbling and now the code behaves how it should. Of course, now going from value of 0 up to 1024 on the Y axis takes much longer.
// Use a joystick on X axis to select incremental position by one's.
// Each toggle will advance the position count whichever direction it is moved (+ or -).
// Y axis will then read pot value and store value in an array.
// The array position and value will be transmitted via serial.
int selectPosition = 0; // The position selector will go from 0 to 29, for 30 total control options in pure data
int lastPosition = 0; // save the last position
const int selectMax = 29; // last position
const int selectMin = 0; // first position
const int selectMove = 1; // Increase in selectPosition with each step
const int Xjoystick = A0; // center pin of joystick X connected here
int XpotValue = 0; // starts at zero
const int XpotCenter = 512; // adjust to suit your joystick
const int XpotDeadRange = 150; // movements by this much either side of centre are ignored
const int Yjoystick = A1; // center pin of joystick Y connected here
int YpotValue = 0; //starts at zero
const int YpotCenter = 512;
const int YpotDeadRange = 50;
int lastValue = 0; // last Y value for concept trial only, won't work with the array setup in the final
const int valueMax = 1024; //max Y potentiometer value
const int valueMin = 0; //min Y potentiometer value
const int valueMove = 5; //Increase selected array value by this number
unsigned long curMillisX;
unsigned long readIntervalMillisX = 150; //time between reads of X joystick position.
unsigned long lastReadMillisX;
unsigned long curMillisY;
unsigned long readIntervalMillisY = 20; //time between reads of Y joystick position.
unsigned long lastReadMillisY;
int valueArray[30]; //store the Y joystick value in each selected X position (from 0-29)
int arrayIndex = 0; //to be mated to selectPosition to advance the array.
void setup() {
Serial.begin(9600);
}
void loop() {
curMillisX = millis();
curMillisY = millis();
readXJoystick();
readYJoystick();
}
void readXJoystick() {
// check the time
if (curMillisX - lastReadMillisX >= readIntervalMillisX) {
lastReadMillisX += readIntervalMillisX; //update lastRead time
XpotValue = analogRead(Xjoystick); // read the Xjoystick
// figure if a move is required
if (XpotValue > XpotCenter + XpotDeadRange) {
selectPosition += selectMove;
}
if (XpotValue < XpotCenter - XpotDeadRange) {
selectPosition -= selectMove;
}
// check that the values are within limits
if (selectPosition > selectMax) {
selectPosition = selectMax;
}
if (selectPosition < selectMin) {
selectPosition = selectMin;
}
}
if (selectPosition != lastPosition) { //check if the position has changed and print the result to serial if so
Serial.print("Position");
Serial.println(selectPosition);
arrayIndex = selectPosition; // the position advances the array index accordingly
lastPosition = selectPosition; // save the position
}
}
void readYJoystick() { //read from Y stick and advance/subtract the value when the stick is out of the deadzone
// check the time
if (curMillisY - lastReadMillisY >= readIntervalMillisY) {
lastReadMillisY += readIntervalMillisY;
// read the Yjoystick
YpotValue = analogRead(Yjoystick);
lastValue = valueArray[arrayIndex]; //set last value to the previous saved value in the array at position determined by X joystick
// figure if a move is required by reading the last value of the valueArray based on the index position from X joystick.
if (YpotValue > YpotCenter + YpotDeadRange) { //If > than the dead range ++
lastValue += valueMove;
}
if (YpotValue < YpotCenter - YpotDeadRange) { //If < than dead range --
lastValue -= valueMove;
}
// check that the values are within limits
if (valueArray[arrayIndex] > valueMax) {
lastValue = valueMax; // if higher than limit set to max
}
if (valueArray[arrayIndex] < valueMin) {
lastValue = valueMin; // if lower than limit set to min
}
}
if (lastValue != valueArray[arrayIndex]) { //if value changed, print new value to serial
Serial.print("value position ");
Serial.print(arrayIndex);
Serial.print("-");
Serial.println(lastValue);
valueArray[arrayIndex] = lastValue; // the selected position in the array is now written with the new value from the Y joystick.
}
delay(30);
}
Is there a more efficient way or error-proof way to store and retrieve the values while maintaining the maximum speed?
Thank you for any recommendations or corrections! Always looking to learn and appreciate all the helpful topics here