I posted in that thread but since I can’t see the error im not sure what the cause is exactly. Here is some code using the ofarduino from master that works with an arduino mega that I did just last week and is live in a touring exhibit:
void ofApp::setupArduino(const int & version) {
// remove listener because we don't need it anymore
ofRemoveListener(ard.EInitialized, this, &ofApp::setupArduino);
// it is now safe to send commands to the Arduino
bSetupArduino = true;
// printf( firmware name and version to the console
ofLogNotice() << ard.getFirmwareName();
ofLogNotice() << "firmata v" << ard.getMajorFirmwareVersion() << "." << ard.getMinorFirmwareVersion();
ard.sendDigitalPinMode(config["Joystick_Up"].asInt(), ARD_INPUT_PULLUP);
ard.sendDigitalPinMode(config["Joystick_Right"].asInt(), ARD_INPUT_PULLUP);
ard.sendDigitalPinMode(config["Joystick_Down"].asInt(), ARD_INPUT_PULLUP);
ard.sendDigitalPinMode(config["Joystick_Left"].asInt(), ARD_INPUT_PULLUP);
ard.sendDigitalPinMode(config["Reed_Switch_0_degrees"].asInt(), ARD_INPUT_PULLUP);
ard.sendDigitalPinMode(config["Reed_Switch_45_degrees"].asInt(), ARD_INPUT_PULLUP);
ard.sendDigitalPinMode(config["Reed_Switch_90_degrees"].asInt(), ARD_INPUT_PULLUP);
ard.sendDigitalPinMode(config["Reed_Switch_135_degrees"].asInt(), ARD_INPUT_PULLUP);
ard.sendDigitalPinMode(config["Reed_Switch_180_degrees"].asInt(), ARD_INPUT_PULLUP);
ard.sendDigitalPinMode(config["Reed_Switch_225_degrees"].asInt(), ARD_INPUT_PULLUP);
ard.sendDigitalPinMode(config["Reed_Switch_270_degrees"].asInt(), ARD_INPUT_PULLUP);
ard.sendDigitalPinMode(config["Reed_Switch_315_degrees"].asInt(), ARD_INPUT_PULLUP);
ard.sendDigitalPinMode(config["Reed_Switch_Filter_1"].asInt(), ARD_INPUT_PULLUP);
ard.sendDigitalPinMode(config["Reed_Switch_Filter_2"].asInt(), ARD_INPUT_PULLUP);
ard.sendDigitalPinMode(config["Reed_Switch_Filter_3"].asInt(), ARD_INPUT_PULLUP);
ard.sendDigitalPinMode(config["Reed_Switch_Filter_4"].asInt(), ARD_INPUT_PULLUP);
ard.sendDigitalPinMode(config["Reed_Switch_Filter_5"].asInt(), ARD_INPUT_PULLUP);
ard.sendDigitalPinMode(config["Button_Layer_Select_1"].asInt(), ARD_INPUT_PULLUP);
ard.sendDigitalPinMode(config["Button_Layer_Select_2"].asInt(), ARD_INPUT_PULLUP);
ard.sendDigitalPinMode(config["Button_Layer_Select_3"].asInt(), ARD_INPUT_PULLUP);
ard.sendDigitalPinMode(config["Button_Layer_Select_4"].asInt(), ARD_INPUT_PULLUP);
ard.sendDigitalPinMode(config["Button_Layer_Visibility_1"].asInt(), ARD_INPUT_PULLUP);
ard.sendDigitalPinMode(config["Button_Layer_Visibility_2"].asInt(), ARD_INPUT_PULLUP);
ard.sendDigitalPinMode(config["Button_Layer_Visibility_3"].asInt(), ARD_INPUT_PULLUP);
ard.sendDigitalPinMode(config["Button_Layer_Visibility_4"].asInt(), ARD_INPUT_PULLUP);
ard.sendDigitalPinMode(config["Button_Reset"].asInt(), ARD_INPUT_PULLUP);
ard.sendDigitalPinMode(config["Button_Image_Select"].asInt(), ARD_INPUT_PULLUP);
ard.sendDigitalPinMode(config["Encoder_1_Reset"].asInt(), ARD_INPUT);
ard.sendDigitalPinMode(config["Encoder_2_Reset"].asInt(), ARD_INPUT);
ard.sendDigitalPinMode(config["Encoder_3_Reset"].asInt(), ARD_INPUT);
ard.sendAnalogPinReporting(config["IR_Sensor_Transparency"].asInt(), ARD_ANALOG);
ard.sendAnalogPinReporting(config["IR_Sensor_Scale"].asInt(), ARD_ANALOG);
ard.sendAnalogPinReporting(config["IR_Sensor_Repetition"].asInt(), ARD_ANALOG);
ard.attachEncoder(config["Encoder_1_Pin_A"].asInt(), config["Encoder_1_Pin_B"].asInt()); //Hue
ard.attachEncoder(config["Encoder_2_Pin_A"].asInt(), config["Encoder_2_Pin_B"].asInt()); //Saturation
ard.attachEncoder(config["Encoder_3_Pin_A"].asInt(), config["Encoder_3_Pin_B"].asInt()); //Brightness
ard.attachEncoder(config["Encoder_4_Pin_A"].asInt(), config["Encoder_4_Pin_B"].asInt()); //Rotation
ard.attachEncoder(config["Encoder_5_Pin_A"].asInt(), config["Encoder_5_Pin_B"].asInt()); //Image Picker
ard.enableEncoderReporting();
// Listen for changes on the digital and analog pins
ofAddListener(ard.EDigitalPinChanged, this, &ofApp::digitalPinChanged);
ofAddListener(ard.EAnalogPinChanged, this, &ofApp::analogPinChanged);
ofAddListener(ard.EEncoderDataReceived, this, &ofApp::encoderDataRecieved);
reset();
}
//--------------------------------------------------------------
void ofApp::updateArduino() {
ard.update();
}
// digital pin event handler, called whenever a digital pin value has changed
// note: if an analog pin has been set as a digital pin, it will be handled
// by the digitalPinChanged function rather than the analogPinChanged function.
//--------------------------------------------------------------
void ofApp::digitalPinChanged(const int & pinNum) {
if (pinNum == config["Reed_Switch_0_degrees"].asInt()) {
ard.getDigital(pinNum) == ARD_LOW ? rotation[layerSelected] = 0 : 0;
ard.resetEncoderPosition(3);
}
else if (pinNum == config["Reed_Switch_45_degrees"].asInt()) {
ard.getDigital(pinNum) == ARD_LOW ? rotation[layerSelected] = 45 : 0;
ard.resetEncoderPosition(3);
}
else if (pinNum == config["Reed_Switch_90_degrees"].asInt()) {
ard.getDigital(pinNum) == ARD_LOW ? rotation[layerSelected] = 90 : 0;
ard.resetEncoderPosition(3);
}
else if (pinNum == config["Reed_Switch_135_degrees"].asInt()) {
ard.getDigital(pinNum) == ARD_LOW ? rotation[layerSelected] = 135 : 0;
ard.resetEncoderPosition(3);
}
else if (pinNum == config["Reed_Switch_180_degrees"].asInt()) {
ard.getDigital(pinNum) == ARD_LOW ? rotation[layerSelected] = 180 : 0;
ard.resetEncoderPosition(3);
}
else if (pinNum == config["Reed_Switch_225_degrees"].asInt()) {
ard.getDigital(pinNum) == ARD_LOW ? rotation[layerSelected] = 225 : 0;
ard.resetEncoderPosition(3);
}
else if (pinNum == config["Reed_Switch_270_degrees"].asInt()) {
ard.getDigital(pinNum) == ARD_LOW ? rotation[layerSelected] = 270 : 0;
ard.resetEncoderPosition(3);
}
else if (pinNum == config["Reed_Switch_315_degrees"].asInt()) {
ard.getDigital(pinNum) == ARD_LOW ? rotation[layerSelected] = 315 : 0;
ard.resetEncoderPosition(3);
}
else if (pinNum == config["Button_Image_Select"].asInt()) {
switch (layerSelected) {
case 0:
layerCounter[0] += imgSelIndex;
imgLayer[0].load(imgDir[0].getPath(flooredModulo(layerCounter[0], int(imgDir[0].size()))));
imgLayer[0].mirror(true, false);
imgSelIndex = 0;
break;
case 1:
layerCounter[1] += imgSelIndex;
imgLayer[1].load(imgDir[1].getPath(flooredModulo(layerCounter[1], int(imgDir[1].size()))));
imgLayer[1].mirror(true, false);
imgSelIndex = 0;
break;
case 2:
layerCounter[2] += imgSelIndex;
imgLayer[2].load(imgDir[2].getPath(flooredModulo(layerCounter[2], int(imgDir[2].size()))));
imgLayer[2].mirror(true, false);
imgSelIndex = 0;
break;
case 3:
layerCounter[3] += imgSelIndex;
imgLayer[3].load(imgDir[3].getPath(flooredModulo(layerCounter[3], int(imgDir[3].size()))));
imgLayer[3].mirror(true, false);
imgSelIndex = 0;
break;
default:
break;
}
}
else if (pinNum == config["Button_Layer_Visibility_1"].asInt()) {
if (ard.getDigital(pinNum) == ARD_LOW && ofGetElapsedTimeMillis() - visTimer > 250) {
visTimer = ofGetElapsedTimeMillis();
layerVisibility[3] = !layerVisibility[3];
ard.sendByte(START_SYSEX);
ard.sendByte(LED_VISIBILITY);
ard.sendByte(0);
ard.sendByte(layerVisibility[3] ? 1 : 0);
ard.sendByte(END_SYSEX);
}
}
else if (pinNum == config["Button_Layer_Visibility_2"].asInt()) {
if (ard.getDigital(pinNum) == ARD_LOW && ofGetElapsedTimeMillis() - visTimer > 250) {
visTimer = ofGetElapsedTimeMillis();
layerVisibility[2] = !layerVisibility[2];
ard.sendByte(START_SYSEX);
ard.sendByte(LED_VISIBILITY);
ard.sendByte(1);
ard.sendByte(layerVisibility[2] ? 1 : 0);
ard.sendByte(END_SYSEX);
}
}
else if (pinNum == config["Button_Layer_Visibility_3"].asInt()) {
if (ard.getDigital(pinNum) == ARD_LOW && ofGetElapsedTimeMillis() - visTimer > 250) {
visTimer = ofGetElapsedTimeMillis();
layerVisibility[1] = !layerVisibility[1];
ard.sendByte(START_SYSEX);
ard.sendByte(LED_VISIBILITY);
ard.sendByte(2);
ard.sendByte(layerVisibility[1] ? 1 : 0);
ard.sendByte(END_SYSEX);
}
}
else if (pinNum == config["Button_Layer_Visibility_4"].asInt()) {
if (ard.getDigital(pinNum) == ARD_LOW && ofGetElapsedTimeMillis() - visTimer > 250) {
visTimer = ofGetElapsedTimeMillis();
layerVisibility[0] = !layerVisibility[0];
ard.sendByte(START_SYSEX);
ard.sendByte(LED_VISIBILITY);
ard.sendByte(3);
ard.sendByte(layerVisibility[0] ? 1 : 0);
ard.sendByte(END_SYSEX);
}
}
else if (pinNum == config["Button_Layer_Select_1"].asInt()) {
if (ard.getDigital(pinNum) == ARD_LOW) {
layerSelected = 3;
imgDisplayIndex = 3;
listenForAlpha = false;
listenForScale = false;
imgSelIndex = 0;
ard.resetEncoderPosition(3);
ard.sendByte(START_SYSEX);
ard.sendByte(LAYER_SELECTED);
ard.sendByte(0);
ard.sendByte(END_SYSEX);
}
}
else if (pinNum == config["Button_Layer_Select_2"].asInt()) {
if (ard.getDigital(pinNum) == ARD_LOW) {
layerSelected = 2;
imgDisplayIndex = 2;
listenForAlpha = false;
listenForScale = false;
imgSelIndex = 0;
ard.resetEncoderPosition(3);
ard.sendByte(START_SYSEX);
ard.sendByte(LAYER_SELECTED);
ard.sendByte(1);
ard.sendByte(END_SYSEX);
}
}
else if (pinNum == config["Button_Layer_Select_3"].asInt()) {
if (ard.getDigital(pinNum) == ARD_LOW) {
layerSelected = 1;
imgDisplayIndex = 1;
listenForAlpha = false;
listenForScale = false;
imgSelIndex = 0;
ard.resetEncoderPosition(3);
ard.sendByte(START_SYSEX);
ard.sendByte(LAYER_SELECTED);
ard.sendByte(2);
ard.sendByte(END_SYSEX);
}
}
else if (pinNum == config["Button_Layer_Select_4"].asInt()) {
if (ard.getDigital(pinNum) == ARD_LOW) {
layerSelected = 0;
imgDisplayIndex = 0;
listenForAlpha = false;
listenForScale = false;
imgSelIndex = 0;
ard.resetEncoderPosition(3);
ard.sendByte(START_SYSEX);
ard.sendByte(LAYER_SELECTED);
ard.sendByte(3);
ard.sendByte(END_SYSEX);
}
}
else if (pinNum == config["Joystick_Up"].asInt()) {
joyUp = ard.getDigital(pinNum) == ARD_LOW ? true : false;
}
else if (pinNum == config["Joystick_Right"].asInt()) {
joyRt = ard.getDigital(pinNum) == ARD_LOW ? true : false;
}
else if (pinNum == config["Joystick_Down"].asInt()) {
joyDn = ard.getDigital(pinNum) == ARD_LOW ? true : false;
}
else if (pinNum == config["Joystick_Left"].asInt()) {
joyLt = ard.getDigital(pinNum) == ARD_LOW ? true : false;
}
else if (pinNum == config["Encoder_1_Reset"].asInt()) {
ard.resetEncoderPosition(0);
}
else if (pinNum == config["Encoder_2_Reset"].asInt()) {
ard.resetEncoderPosition(1);
}
else if (pinNum == config["Encoder_3_Reset"].asInt()) {
ard.resetEncoderPosition(2);
}
else if (pinNum == config["Reed_Switch_Filter_1"].asInt()) {
if (ard.getDigital(pinNum) == ARD_LOW)
filterType[layerSelected] = 0;
}
else if (pinNum == config["Reed_Switch_Filter_2"].asInt()) {
if (ard.getDigital(pinNum) == ARD_LOW)
filterType[layerSelected] = 3;
}
else if (pinNum == config["Reed_Switch_Filter_3"].asInt()) {
if (ard.getDigital(pinNum) == ARD_LOW)
filterType[layerSelected] = 2;
}
else if (pinNum == config["Reed_Switch_Filter_4"].asInt()) {
if (ard.getDigital(pinNum) == ARD_LOW)
filterType[layerSelected] = 1;
}
if (pinNum == config["Button_Reset"].asInt()) {
reset();
}
else {
layerDirty = true;
}
}
//
// analog pin event handler, called whenever an analog pin value has changed
//--------------------------------------------------------------
void ofApp::analogPinChanged(const int & pinNum) {
// do something with the analog input. here we're simply going to printf( the pin number and
// value to the screen each time it changes
float sum = 0;
layerDirty = true;
if (pinNum == config["IR_Sensor_Transparency"].asInt()) {
for (int i = 0; i < 24; i++)
alphaBuffer[i] = alphaBuffer[i + 1];
alphaBuffer[24] = ofMap(ard.getAnalog(pinNum), 130, 590, 255, 80, true);
for (int i = 0; i < 25; i++)
sum += alphaBuffer[i];
sum /= 25;
if (listenForAlpha || abs(prevAlpha - sum) > 20) {
if (abs(prevAlpha - sum) > 20)
listenForAlpha = true;
prevAlpha = sum;
switch (layerSelected) {
case 0:
alpha[layerSelected] = sum;
break;
case 1:
alpha[layerSelected] = sum;
break;
case 2:
alpha[layerSelected] = sum;
break;
case 3:
alpha[layerSelected] = sum;
break;
}
}
}
else if (pinNum == config["IR_Sensor_Scale"].asInt()) {
for (int i = 0; i < 24; i++)
scaleBuffer[i] = scaleBuffer[i + 1];
scaleBuffer[24] = ofMap(ard.getAnalog(pinNum), 230, 470, .1, 4, true);
for (int i = 0; i < 25; i++)
sum += scaleBuffer[i];
sum /= 25;
if (listenForScale || abs(prevScale - sum) > .25) {
if (abs(prevScale - sum) > .25)
listenForScale = true;
prevScale = sum;
scale[layerSelected] = sum;
}
}
else if (pinNum == config["IR_Sensor_Repetition"].asInt()) {
if (ard.getAnalog(pinNum) < 250)
pattern[layerSelected] = 10;
if (ard.getAnalog(pinNum) >= 250 && ard.getAnalog(pinNum) < 325)
pattern[layerSelected] = 5;
if (ard.getAnalog(pinNum) >= 325 && ard.getAnalog(pinNum) < 400)
pattern[layerSelected] = 3;
if (ard.getAnalog(pinNum) >= 400)
pattern[layerSelected] = 0;
}
}
void ofApp::encoderDataRecieved(const vector<Firmata_Encoder_Data> & data) {
layerDirty = true;
for (int i = 0; i < data.size(); i++) {
switch (data[i].ID) {
case 0:
hue[layerSelected] = ofMap(data[i].direction ? data[i].position : max(120 - data[i].position, 0), 0, 120, 0, 255, true);
break;
case 1:
saturation[layerSelected] = ofMap(data[i].direction ? data[i].position : max(120 - data[i].position, 0), 0, 120, 255, 0, true);
break;
case 2:
brightness[layerSelected] = ofMap(data[i].direction ? data[i].position : max(120 - data[i].position, 0), 0, 120, 0, 255, true);
break;
case 3:
fineRotation[layerSelected] = data[i].direction ? -data[i].position : data[i].position;
break;
case 4:
if (abs(data[i].position - imgSelPos) >= 20) {
if (data[i].position - imgSelPos > 0) {
imgSelIndex++;
}
else {
imgSelIndex--;
}
imgSelPos = data[i].position;
}
break;
}
}
}
I’m not sure that will be helpful for the problems discussed here but just showing that it should be capable of communicating with pins beyond 22.