Micro bit relay

Good day. I apologize in advance if I offend anyone with my drawing or post. I am a newbie to Arduino and with the help of my son I compiled this code.

The code has been tested and is working fine so the problem must be on the hardware/circuit side. The circuit works 100% with out the shift function , so I need help in solving my problem.

I am using the SWC of the citroen. It has 8 wire that I input to the Arduino Nano, with internal pull up that reads each push of the button. the information is then send to the MCP4131 digipot as resitor values activating the radio remote input of the SONY XAV 601BT. The tip and sleeve of the mini jack is used. Sofar this part of the circuit and code is working like a dream, and that includes the encoder we use with polling.

The problem is to use the encoder we need to activate the "shift" function, where we ground the ring input of the radio (3.3Volt) to the sleeve of the mini jack. We are doing this by activating PIN 9 on the NANO to activate the transistor to close the circuit from the ring to the sleeve. I have tried a 2N2222 and BS170 to no avail. It doesn't work and it is as if its shorting to the tip input or are permanently activate. The SEEK function becomes the VOL function and the VOL function switches the radio off. I used from a 1 kOhm to a 2.2kOhm resistor in series from the PIN to the BASE of the transistor and a 10 to 12 kOhm to pull the BASE to GROUND. I have even remove the 10 - 12 kOhm from the circuit but still the same.

I was think as an alternative to use a small relay to activate the shift function, but its puzzling why the transistors isn't working. I have even gone so far as to swap the SOURCE and DRAIN of the transistor, but the same problem remains. I have tested the circuit without the transistors and is 100%.

Hany help would be appreciated.

Here is a raw copy of the code. All the libraries are included.

"
#include <PinButton.h>
#include <arduino-timer.h>
#include <SPI.h>

#include "Rotary.h"

// Set the Citroën SWC input buttons to pin numbers
// MultiButton automatically initializes the inputs with the internal pullup
PinButton SOURCE(2);
PinButton SEEK_UP(3);
PinButton SEEK_DN(5);
PinButton VOL_UP(7);
PinButton VOL_DN(4);

uint8_t ENCODER_WHEEL_A_PIN = 6;
uint8_t ENCODER_WHEEL_B_PIN = 8;

Rotary rotary = Rotary(ENCODER_WHEEL_A_PIN, ENCODER_WHEEL_B_PIN);

const int BUTTON_HOLD_TIME_MS = 500;

// Resistive values for the digital potentiometer output
const float SOURCE_OUTPUT_KOHM = 2.1;
const float SEEK_UP_OUTPUT_KOHM = 8.8;
const float SEEK_DN_OUTPUT_KOHM = 12.1;
const float VOL_UP_OUTPUT_KOHM =16.6;
const float VOL_DN_OUTPUT_KOHM = 23.6;
const float PRESET_DN_OUTPUT_KOHM = 12.9;
const float PRESET_UP_OUTPUT_KOHM = 8.1;

enum MCP413X_REGISTERS {
MCP413X_REG_WIPER = 0x00,
MCP413X_REG_TCON = 0x04
};

enum MCP413X_TCON_BITS {
MCP413X_TCON_TERM_B = 0x01,
MCP413X_TCON_TERM_W = 0x02,
MCP413X_TCON_TERM_A = 0x04,
MCP413X_TCON_HARDWARE_CTRL = 0x08
};

enum MCP413X_COMMAND_TYPES {
MCP413X_COMMAND_WRITE = 0x0,
MCP413X_COMMAND_READ = 0x3,
};

// Shift connection
const uint8_t SHIFT = 9;

// Digipot ChipSelect Pin
const uint8_t MCP413X_CS_PIN = 10;

// Encoder wheel state variables
uint8_t encoder_state = 0xFF;

void setDigipotWiperState(bool setWiperConnected) {

// Digipot ChipSelect enable
digitalWrite(MCP413X_CS_PIN, LOW);

uint16_t tcon_command = (MCP413X_REG_TCON << 12);
tcon_command |= (MCP413X_COMMAND_WRITE << 10);
tcon_command |= 0x100; // Weird TCON reserve bit should always be 1
tcon_command |= MCP413X_TCON_HARDWARE_CTRL; // Hardware enabled

if(setWiperConnected){
tcon_command |= MCP413X_TCON_TERM_W; // Enable Terminal W
tcon_command |= MCP413X_TCON_TERM_A; // Enable Terminal A
tcon_command |= MCP413X_TCON_TERM_B; // Enable Terminal B
}
Serial.print(F("TCOP SPI: "));
Serial.println(tcon_command, HEX);
SPI.transfer16(tcon_command);

digitalWrite(MCP413X_CS_PIN, HIGH);
}

void setDigipotWiperValue(float resistance_kohm) {
float wiper_base_kohm = 0.100; // Base wiper resistance (this needs tuning based on the input voltage)
float digipot_resistor_range = 50.0; // The full range of the resistor network excluding wiper resistance (from terminal A to terminal B).
float step_count = 128; // 128 for 7 bit digipots

float step_value = digipot_resistor_range / step_count;

if (resistance_kohm > digipot_resistor_range) {
// We can't set the resistance over 50kOhm, so clamp it to the max
resistance_kohm = digipot_resistor_range;
} else if (resistance_kohm < 0)
{
// There is no such thing as negative resistance. Do nothing and return.
return;
}
// resistance_kohm -= wiper_base_kohm; // subtract the wiper resistance from the desired value

uint8_t wiper_value = (uint8_t) round(resistance_kohm / step_value);

// Digipot ChipSelect enable
digitalWrite(MCP413X_CS_PIN, LOW);

uint16_t wiper_command = (MCP413X_REG_WIPER << 12);
wiper_command |= (MCP413X_COMMAND_WRITE << 10);
wiper_command |= wiper_value;

Serial.print(F("WIPER SPI: "));
Serial.println(wiper_command, HEX);
SPI.transfer16(wiper_command);

digitalWrite(MCP413X_CS_PIN, HIGH);
}

void setup() {
delay(50); // some microcontrollers reboot twice
Serial.begin(9600);
while (!Serial); // Wait until Serial is ready
Serial.println(F("setup(): begin"));

// Set ChipSelect pin output
pinMode(MCP413X_CS_PIN, OUTPUT);
//Set digital pin as output pin for ring to sleeve connection to be used as shift function
pinMode(SHIFT, OUTPUT);
digitalWrite(SHIFT, LOW); // Make sure the output is low on startup

SPI.begin();

setDigipotWiperState(false); // Initialize the digipot, but disconnect the wiper (open circuit)
}

/***** Timer stuff for "holding" the resistance till the radio has responded *****/
auto timer = timer_create_default(); // create a timer with default settings
uintptr_t button_disconnect_task = NULL;

bool timedWiperDisconnect(void *){
// Clear the state, once this task runs it shouldn't run again
button_disconnect_task = NULL;

// Clear the shift line
digitalWrite(SHIFT, LOW);
// Disconnect the digipot wiper
setDigipotWiperState(false);

}

// Push the "button" by applying the resistance value to the digipot output and then connecting the terminals for a set amount of time using the timer
void pushTheButton(float resistance_kohm, bool connectShift){
// Interrupt the existing timer if it exists and disconnect the digipot and shift
if(button_disconnect_task != NULL){
timer.cancel(button_disconnect_task);
timedWiperDisconnect(0);
}
Serial.print("Attempting to set resistance to ");
Serial.print(resistance_kohm);
Serial.println("kOhm");

// Check if we need to connect the SHIFT line
if(connectShift){
  digitalWrite(SHIFT, HIGH);      
  Serial.println("SHIFT enabled");
} else {      
  digitalWrite(SHIFT, LOW);
  Serial.println("SHIFT disabled");
}

// Set the resistance wiper register 
setDigipotWiperValue(resistance_kohm);    
delay(5);
// Enable the wiper connection
setDigipotWiperState(true);

// Schedule the disconnect in BUTTON_HOLD_TIME_MS milliseconds
button_disconnect_task = timer.in(BUTTON_HOLD_TIME_MS, timedWiperDisconnect);

}

void loop() {
// Update the button states (read the inputs)
SOURCE.update();
SEEK_UP.update();
SEEK_DN.update();
VOL_UP.update();
VOL_DN.update();

// Check clicked states with cascade.
// If more than one button is clicked, only the first one on this list should activate
if (SOURCE.isClick())
{
pushTheButton(SOURCE_OUTPUT_KOHM, false);
Serial.println(F("Click SOURCE"));
}
else if (SEEK_UP.isClick())
{
pushTheButton(SEEK_UP_OUTPUT_KOHM, false);
Serial.println(F("Click SEEK_UP"));
}
else if (SEEK_DN.isClick())
{
pushTheButton(SEEK_DN_OUTPUT_KOHM, false);
Serial.println(F("Click SEEK_DN"));
}
else if (VOL_DN.isClick())
{
pushTheButton(VOL_DN_OUTPUT_KOHM, false);
Serial.println(F("Click VOL_DN"));
}
else if (VOL_UP.isClick())
{
pushTheButton(VOL_UP_OUTPUT_KOHM, false);
Serial.println(F("Click VOL_UP"));
}

unsigned char result = rotary.process();
if (result == DIR_CW)
{
pushTheButton(PRESET_DN_OUTPUT_KOHM, true);
Serial.println(F("Rolled PRESET_DN"));
}
else if (result == DIR_CCW)
{
pushTheButton(PRESET_UP_OUTPUT_KOHM, true);
Serial.println(F("Rolled PRESET_UP"));
}

timer.tick();
}