How to FS3x to Due via TRS?

My first post here, so if this in in the wrong area - I apologise .

I have a Due setup in keyboard emulation with a few buttons working more or less fine (windows 10 doesn't like it on certain USB ports).

I'd like to add an FS3x (3 button stomp box made by Digitech) as an extra set of 3 buttons. The FS3x is connected via a Stereo (TRS - 3 conductor only) cable.

I know I could make my own enclosure with as many switches as I want, but I'd like to try and use what I have easily available for a few reasons, not worth going into here.

This is a wiring diagram for a work-alike fs3x, to help understand what is going on at the switch end of things.

|484x500

I'm currently using (more or less) the wiring setup described here for my project (https://www.arduino.cc/en/Tutorial/KeyboardAndMouseControl)

If anyone can help me work out what I need to do on my Due side of things so I can add a TRS socket to my Due/enclosure and run a TRS cable to the FS3x and add an extra 3 buttons easily, it'd be greatly appreciated.

Beyond setting up the wiring without frying my Due, what would I need to do to my code to get the 3 switches working independently?

Based on how I read the diagram for the footswitch, I believe the FS3x will send a signal to 1 pin when a certain button is pressed, the 2nd pin for the 2nd button and both pins if the 3rd is pressed. Based on that, I think I'd need to do something like what I list below, but I don't know if Arduino can handle code along the lines of;

while (digitalRead(4) == LOW) {
and
while (digitalRead(6) == LOW) {
delay(10);
      Keyboard.press(blahblahblah);

If I'm reading it wrongly, or the Due can't accept that kind of code, could a wiring method (with some combination of diodes perhaps) be used to take the 3 conductors of the TRS and make it into 4 (ground and 3 pins) for the Due?

Any help or advice that could be offered will be received gladly.

Hi ZagatoZee,

I’m reading the diagram the same way. Here are a couple of pointers.

  1. You will need to enable the internal pullups on your 3 input pins [pinMode( x, INPUT_PULLUP)] so they read HIGH when the pedals are not pressed.

  2. You will have to “debounce” the inputs since when you close the switch, the arduino will see several transistions HIGH/LOW before it settles on LOW (mechanical switches are noisy when the make/break a connection) There are several “button” libraries that handle this for you or you can do it yourself. Basically, you have to delay() a bit when reading the switches to make sure they are in a stable position (HIGH or LOW)

  3. One way to decide what to do after you read your debounced switches would be like this:

// assume sw1, sw2 are the states of the the 2 pins, either HIGH or LOW
// and you have debounced them
if ( sw1 == LOW && sw2 == LOW ) {
  // both active -> pedal 3
  // <insert response to pedal 3 here
} else if ( sw2 == LOW ) {
  // pedal 2
  // <insert response to pedal 2 here
} else if ( sw1 == LOW ) {
  // pedal 1
  // <insert response to pedal 1 here
} else {
  // no pedals
  // <insert response to no pedals here
}

Thank you blh64, that helps with the code portion I was wondering about and seems like it'll be more than easy enough to implement.

I didn't include this before since I was trying to avoid clutter, but I think my code is already covering the button and pull up issues you mention.

/* ZagatoZee 2 button control of iRotate commands for my secondary monitor.
ctrl+shift+left to rotate 90 degrtees to portrait, ctrl+shift+up for normal landscape
The circuit:
  - pushbutton attached from pin 4(etc) to +5V
  - 10 kilohm resistor attached from pin 4 to ground 
*/

#include "Keyboard.h"

const int buttonPin4 = 4;          // input pin for pushbutton
const int buttonPin6 = 6;          // input pin for pushbutton
char ctrlKey = KEY_LEFT_CTRL;     // adds ctrl key
char shiftKey = KEY_LEFT_SHIFT;   // adds shift key
char leftKey = KEY_LEFT_ARROW;    // adds left arrow
char upKey = KEY_UP_ARROW;        // adds up arrow 

void setup() {
  // make the pushButton pins inputs:
   pinMode(buttonPin4, INPUT_PULLUP);
   pinMode(buttonPin6, INPUT_PULLUP);
  // initialize control over the keyboard:
  Keyboard.begin(); 
}
void loop(){
    while (digitalRead(4) == LOW) {
    // do nothing until pin 4 goes HIGH
    delay(10);
    }
    delay(10);
    // rotate to portrait mode:
  Keyboard.press(ctrlKey);
  Keyboard.press(shiftKey);
  Keyboard.press(leftKey);
  delay(50);
  Keyboard.releaseAll();


while (digitalRead(6) == LOW) {
    // do nothing until pin 5 goes HIGH
    delay(10);
}
  delay(10);
  // rotate to landscape mode:
  Keyboard.press(ctrlKey);
  Keyboard.press(shiftKey);
  Keyboard.press(upKey);
  delay(50);
  Keyboard.releaseAll();
}

I'm still trying to get my head around the wiring needed on the Due side of the TRS cable, since the requirement of the 10kohm resistors on the switched side but before the connection to ground is complicating things (at least in my head) if trying to use the FS3x as is.

The TRS cable can be connected directly to the pins on the Due. The Due has internal pull-ups. I'm confused about the statement of a 10kohm resistor on the switched side.

Also in your code, if you reorder your pin[] array from LSB to MSB, you don't have to have the for() run from 7..0

blh64: I'm confused about the statement of a 10kohm resistor on the switched side.

Thank you. I thought it "should" be able to do that, but the other projects I started lifting the code and design from used the 10kohm resistors and warned about frying arduinos if they were not present. Perhaps this is only relevant for a certain setup (a different board) - and since I lifted segments from 2 or 3 different projects have bypassed their need now.

That simplifies matters greatly. Thank you very much.

As I see it currently, there is no logical reason then that this won't work;

|500x226

With your help above on the if / else syntax it seems like this should be quite easily doable - and be conveniently scale-able.

I really appreciate your help.

Any idea why this code results in ONLY the down arrow working - and it does that on 2 of the 3 buttons?

#include "Keyboard.h"

char upKey = KEY_UP_ARROW;        // adds up arrow 
char downKey = KEY_DOWN_ARROW;    // adds down arrow 
char enterKey = KEY_RETURN;       // adds enter key

void setup() {
  // read the 2 pins that the fs3x are connected to
   pinMode(buttonPin12, INPUT_PULLUP);
   pinMode(buttonPin13, INPUT_PULLUP);
  // initialize control over the keyboard:
  Keyboard.begin(); 
}

void loop(){
if (digitalRead(12) == LOW && digitalRead(13) == LOW ) {
  // both active -> pedal 3
  delay(10);
  Keyboard.press(upKey);
  delay(10);
  Keyboard.releaseAll();
} 

else if (digitalRead(13) == LOW ) {
  // pedal 2
  delay(10);
  Keyboard.press(downKey);
  delay(10);
  Keyboard.releaseAll();
} 

else if (digitalRead(12) == LOW ) {
  // pedal 1
  delay(10);
  Keyboard.press(enterKey);
  delay(10);
  Keyboard.releaseAll();
} 
}

*edit to add - If I swap the pins on the Arduino Due (12 and 13) - nothing works at all.

Disregard the above post - the code is perfectly fine, it was my wiring that was wrong.

Trying to gator clip onto the TRS port terminals gave the above issue. Gator clipping direct to the TRS cable end - solved it, so obviously I have goofed somewhere with the connections.

Digging up this old post in case anyone else is struggling to setup FS3X with arduino. By using the AceButton library (https://github.com/bxparks/AceButton/) you can do pretty much anything and avoid several problems, mainly the ones that arise from the fact that the footswitch uses 2 wires with 3 switches (GND excluded).
A brief discussion about it here: https://github.com/bxparks/AceButton/discussions/74
and a small example following:

/*
 * A small example of using Digitech's FS3X footswitch with Arduino,
 * using the AceButton library (https://github.com/bxparks/AceButton/)
 * In this example, the "MODE" button is used to toggle a "song" mode ON/OFF
 * (ON mode keeps the LED on) and the UP/DOWN buttons have different functionality
 * in each mode. (LED blinks every time UP/DOWN is pressed)
 * This is a stripped-down version of the original "Encoded8To3Buttons" example
 */

#include <AceButton.h>
using namespace ace_button;

// Select 3 to use Encoded4To2ButtonConfig
#define NUM_BUTTONS 3

#ifdef ESP32
  // Different ESP32 boards use different pins
  static const int LED_PIN = 2;
#else
  static const int LED_PIN = LED_BUILTIN;
#endif

// LED states. Some microcontrollers wire their built-in LED the reverse.
static const int LED_ON = HIGH;
static const int LED_OFF = LOW;

static const uint8_t BUTTON_PIN0 = 10;    // FS3X's tip pin
static const uint8_t BUTTON_PIN1 = 11;    // FS3X's ring pin

byte getMode = 0; // Song Mode ON/OFF

// Each button is assigned to the virtual pin number (1-7) which comes from the
// binary bit patterns of the 3 actual pins. Button b0 cannot be used
// because it is used to represent "no button pressed".
  Encoded4To2ButtonConfig buttonConfig(BUTTON_PIN0, BUTTON_PIN1);

  AceButton buttonMode(&buttonConfig, 1);   // Config MODE button
  AceButton buttonDown(&buttonConfig, 2);   // Config DOWN button
  AceButton buttonUp(&buttonConfig, 3);     // Config UP button

// Forward reference to prevent Arduino compiler becoming confused.
void handleEvent(AceButton*, uint8_t, uint8_t);

void setup() {
  Serial.begin(115200);

  // initialize built-in LED as an output
  pinMode(LED_PIN, OUTPUT);

  // Pins uses the built-in pull up register.
  pinMode(BUTTON_PIN0, INPUT_PULLUP);
  pinMode(BUTTON_PIN1, INPUT_PULLUP);
  buttonConfig.setEventHandler(handleEvent);
}

void loop() {
  buttonMode.check();     // FS3X's MODE button
  buttonDown.check();     // FS3X's DOWN button
  buttonUp.check();       // FS3X's UP button
}

// The event handler for FS3X buttons.
void handleEvent(AceButton* button, uint8_t eventType, uint8_t buttonState) {
  switch (eventType) {
    case AceButton::kEventPressed:
    if (button->getPin() == 1) {        // If FS3X's MODE button is pressed
      if (getMode ==0){       
        getMode = 1;
        Serial.println(F("Song mode: ON"));   // If Song mode is on
        digitalWrite(LED_PIN, LED_ON);
      }
      else {
        getMode = 0;
        Serial.println(F("Song mode: OFF"));  // If Song mode is off
        digitalWrite(LED_PIN, LED_OFF);
      }
    }
    if (button->getPin() == 2) {        // If FS3X's DOWN button is pressed
      digitalWrite(LED_PIN, LED_OFF);
      delay(20);
      digitalWrite(LED_PIN, LED_ON);
      delay(20);
      if (getMode == 0) {               // If Song mode is off
        Serial.println(F("Previous song"));
        digitalWrite(LED_PIN, LED_OFF);
      }
      else Serial.println(F("Previous section"));   // If Song mode is on
    }
    if (button->getPin() == 3) {        // If FS3X's UP button is pressed
      digitalWrite(LED_PIN, LED_OFF);
      delay(20);
      digitalWrite(LED_PIN, LED_ON);
      delay(20);
      if (getMode == 0) {               // If Song mode is off
        Serial.println(F("Next song"));
        digitalWrite(LED_PIN, LED_OFF);
      }
      else Serial.println(F("Next section"));   // If Song mode is on
    }
      break;
  }
}