Cette solution peut reposer sur n'importe quelle Arduino. Ici, j'ai pris un clone d'arduino Pro Micro, basée sur un ATmega32U4 qui gère directement l'USB et est d'une toute petite taille.

Nous allons utiliser 2 entrées (D2/D3) pour connecter les 2 phases de l'encodeur incrémental, et 4 sorties (D4/D5/D6/D7) pour émuler l'encodeur absolu 4 bits. Les sorties ne sortent pas un code binaire classique, mais un code binaire modifié pour ne changer qu'un bit à la fois afin d'éviter les artefacts. Ceci s'appelle le code Grey. Toutefois, le fabriquant américain CTS a trouvé bon de pas utiliser le code grey standard, mais un code à sa sauce.

En voici la table de vérité : 

////////////////////////////////////////////////////////////////////////////////////////////
// CTS Gray code, extracted from datasheet. a bit different from standard grey code.
////////////////////////////////////////////////////////////////////////////////////////////
//      A     B     E     F   dec value
////////////////////////////////////////////////////////////////////////////////////////////
// 0    0     0     0     0   0
// 1    0     0     0     1   1
// 2    0     0     1     1   3
// 3    0     0     1     0   2
// 4    1     0     1     0   10
// 5    1     0     1     1   11
// 6    1     1     1     1   15
// 7    1     1     1     0   14
// 8    0     1     1     0   6
// 9    0     1     1     1   7
// 10   0     1     0     1   5
// 11   0     1     0     0   4
// 12   1     1     0     0   12
// 13   1     1     0     1   13
// 14   1     0     0     1   9
// 15   1     0     0     0   8

Le montage va prélever un GND et un 5V directement sur la carte mère du rack. Il va être raccordé à l'encodeur incrémental par un petit connecteur pour permettre le démontage de la face avant. 3 fils seront nécessaires, une masse au centre, la première sortie (channel A) sur l'entrée 2 de l'arduino et la 2e sortie (channel B) sur l'entrée 3 de l'arduino.

L'encodeur d'origine devra être dessoudé de la carte mère. Nous pourrons avec 5 fils raccorder la masse, et les 4 sorties de l'arduino comme suit:

////////////////////////////////////////////////////////////////////////////////////////////
//    Top view . (x) corresponding Arduino output number
// +-------------+
// |(1)E GND F(2)|
// |             |
// |(3)A GND B(0)|
// +-------------+
//      |   |  
//      |   | Axis
//      +---+

D'un point de vue logiciel, nous allon sutiliser une bibliothèques additionnelles :

  • https://docs.arduino.cc/libraries/encoder/ pour gérer l'encodeur incrémental (avec interruptions pour ne pas rater de pas

Voici le code source  /images/Digitech/Quadratic-2-4bit-Gray.ino (cliquez pour télécharger)

////////////////////////////////////////////////////////////////////////////////////////////
// Quadratic-2-4bit-Gray
////////////////////////////////////////////////////////////////////////////////////////////
// Use an arduino (here mini) to convert a Quadratic encoder (2 wires) to a 4 bit Gray CTS variant
// Those encoders are used on some old Digitech effects :
// GSP2101, GSP2101 Artist, GSP2101 Limited Edition, GSP2101 LE or GSP 2101 Artist PRO, Legend II, Valve FX, TSR-6
// CTS  (Digitech reference 44-0092, CTS Ref 2-288X Grey)
// Datasheet: https://www.ctscorp.com/Files/DataSheets/Encoders/encoders-288-datasheet.pdf
// Unfortunately, they're difficult to find / buy and very expensive (>50€)
// This code uses an arduino to read a standard 2 phases quadratic encoder and output
// on 4 bits a grey code for direct remplacement.
////////////////////////////////////////////////////////////////////////////////////////////
//    Top view . (x) corresponding Arduino output number
// +-------------+
// |(1)E GND F(2)|
// |             |
// |(3)A GND B(0)|
// +-------------+
//      |   |  
//      |   | Axis
//      +---+
//
////////////////////////////////////////////////////////////////////////////////////////////
// I/O
////////////////////////////////////////////////////////////////////////////////////////////
// Prototyping on Arduino Nano / CH340 / USB3
const int InA = 2; // to be wired to channel A
const int InB = 3; // to be wired to channel B
const int Out0 = 4; // to be wired to B on Digitech PCB
const int Out1 = 5; // to be wired to E
const int Out2 = 6; // to be wired to F
const int Out3 = 7; // to be wired to A
////////////////////////////////////////////////////////////////////////////////////////////
// CTS Gray code, extracted from datasheet. a bit different from standard grey code.
////////////////////////////////////////////////////////////////////////////////////////////
//      A   B   E   F   dec value
////////////////////////////////////////////////////////////////////////////////////////////
// 0    0   0   0   0   0
// 1    0   0   0   1   1
// 2    0   0   1   1   3
// 3    0   0   1   0   2
// 4    1   0   1   0   10
// 5    1   0   1   1   11
// 6    1   1   1   1   15
// 7    1   1   1   0   14
// 8    0   1   1   0   6
// 9    0   1   1   1   7
// 10   0   1   0   1   5
// 11   0   1   0   0   4
// 12   1   1   0   0   12
// 13   1   1   0   1   13
// 14   1   0   0   1   9
// 15   1   0   0   0   8
 
//#define ENCODER_DO_NOT_USE_INTERRUPTS
#include <Encoder.h>
 
// display on serial if DEBUG set
//#define DEBUG
 
// activate input pullups for encoder
#define INPUT_PULLUP
// If Quadratic inputs do not support interrupts, disable them.
//#define ENCODER_DO_NOT_USE_INTERRUPTS
 
// The encoder
Encoder myEnc(InA, InB);
 
// Positions
long position;
long newPos;
 
uint8_t GrayCode [] = {0,1,3,2,10,11,15,14,6,7,5,4,12,13,9,8};
 
void setup() {
  #ifdef DEBUG
  Serial.begin(9600);
  Serial.println("Quadratic to 4 bit gray code");
  #endif
  // 4 grey pins are outputs
  pinMode (Out0,OUTPUT);
  pinMode (Out1,OUTPUT);
  pinMode (Out2,OUTPUT);
  pinMode (Out3,OUTPUT);
  // Initial position = 0
  myEnc.write(0);
  position  = 0;
  newPos = 0;
}
 
void loop() {
  // Note in library, internal pos is 4* real pos
  // each step is 4 steps.
  newPos = myEnc.read()/4;
  uint8_t Gray;
  if (newPos != position) {
    if (newPos>15) {
      newPos=0;
      myEnc.write(0);
      }
    if (newPos<0) {
      newPos=15;
      myEnc.write(15*4);
      }
    position = newPos;
    Gray = GrayCode[position];
 
    // Set outputs to corresponding computed grey code
    digitalWrite (Out0 ,!bitRead(Gray,0));
    digitalWrite (Out1 ,!bitRead(Gray,1));
    digitalWrite (Out2 ,!bitRead(Gray,2));
    digitalWrite (Out3 ,!bitRead(Gray,3));
 
    #ifdef DEBUG
    // print on serial
    Serial.print(position);
    Serial.print(": ");
    for(int i = 3; i>= 0; i--)
      {
      Serial.print(bitRead(Gray,i));
      }
    Serial.println();
    #endif
  }
}

Voici à quoi ressemble le résultat final. En rouge, le +5V, en Jauneles fils du codeur incrémental, en vert les sorties vers l'emplacement de l'encodeur absolu sur le pcb et en noir les masses.