/* Analog Encoder for Piston Rail
This encoder encodes up to twenty pistons on a piston rail. The rail is supplied with +5V and Ground.
A resistor array consisting up to twenty 100 ohm resistors in series is then connected to 5V and Ground.
The pistons connect the junction points between resistors to a sensing wire which goes to an analog input
an Arduino. See diagram below.
When a piston is pressed, the encoder derives the the number of the piston being pressed and generates
a MIDI ON and OFF message for that piston. More information on the Organ Forum:
https://organforum.com/forums/forum/organ-building-repair-restoration/virtual-organs/856461-encoding-a-rotary-switch
The program where this is to be used needs to include in the Declaration and Initialization sections the
statements below.
The two procedures: void scanPistons() and void encodePiston() must also be included.
The main loop section illustrates how the procedure scanPistons() can be called for each rail in turn
when preceded by the following Parameters:
numPistons // specifies the number of pistons (and resistors) used on that rail
stepSize //stepSize = 1023/numPistons;
halfStep //halfStep = stepSize/2;
analogPin // specifies the analog input to be scanned
noteOffset // specifies the number to be added to the piston number to generate the note number
channelNumber // the channel on which the MIDI meassage is to be output
Created 2024 DEC 27 by John Coenraads
Modified 2024 DEC 28 added code to squelch electrical nois
*/
// Declarations
int analogValue, analogValue1, analogValue2;
byte noteNumber, numPistons, analogPin, noteOffset, channelNumber;
int stepSize, halfStep;
byte i;
//Initialization
void setup()
{
Serial.begin(31250);
//Serial.begin(9600);
}
void loop()
{
//Specify Parameters before calling scanPistons
numPistons = 20;
stepSize = 51; //stepSize = 1023/numPistons;
halfStep = 25; //halfStep = stepSize/2;
analogPin = 69;
noteOffset = 10;
channelNumber = 0x90;
scanPistons(); //scan rail connected to analog pin 69, output on channel 1
//Specify Parameters before calling scanPistons
numPistons = 20;
stepSize = 51; //stepSize = 1023/numPistons;
halfStep = 25; //halfStep = stepSize/2;
analogPin = 68;
noteOffset = 100;
channelNumber = 0x91;
scanPistons(); //scan rail connected to analog pin 68, output on channel 2
}
void scanPistons()
{
analogValue = analogRead (analogPin);
// Serial.println (analogValue);
if (analogValue > halfStep)
{
delay (1);
analogValue1 = analogRead (analogPin);
if (abs(analogValue - analogValue1) < 3)
{
delay (1);
analogValue2 = analogRead (analogPin);
if (abs(analogValue - analogValue2) < 3)
{
encodePiston();
}
}
}
}
void encodePiston()
{
noteNumber = 0;
for (i = 1; i < numPistons +1; i ++)
{
if (analogValue > ((i * stepSize) - halfStep))
{noteNumber = i;}
}
if (noteNumber > 0)
{Serial.write (channelNumber); //note ON,
Serial.write (noteNumber + noteOffset);
Serial.write (0x7f);
delay (500);
Serial.write (channelNumber); //note ON, with zero velocity
Serial.write (noteNumber + noteOffset);
Serial.write (0);
}
}