Code conversion/equivalent help required

Hi all,

I am working on a project somebody else has created which uses an I/O expander chip but through lack of patience and local store stock, I am hoping to use shift registers instead…

I have got basic circuits up and running using the shift registers to prove the circuit works (20 x LED’s and 1 x digit 7 segment display) but now I want to try manipulate the existing I/O based code to run using the shift register based code. I don’t want to start from scratch because the code works/integrates with some other Visual Studio code and is proven but I just want to obviously change the way the Arduino sends the info to the end devices (LED’s + segment display).

Can somebody please help me highlight the code I will need to replace equivalent commands with? You dont have to show me code I need but if I know what I need to replace, I can work on it although I wont say no to more help! :grinning: I am also needing to remove the input/button commands as I am not using them. I am only interested in the LED outputs. I have started working on doing this but I am not confident enough and need to make sure I am on the right path as I am reasonably new at all of this.

#include <IOexp.h>
#include <Wire.h>

#define IO_ADDR1 (0x20)
#define IO_ADDR2 (0x22)
#define IO_ADDR3 (0x24)

#define PIN_HIGHBIT (2)
#define PIN_LOWBIT  (4)

int state, prevState = 0, count = 0;

int encoderStates[4][4] = {
{  0, -1,  1,  0 },
{  1,  0,  0, -1 },
{ -1,  0,  0,  1 },
{  0,  1, -1,  0 },
};

int patgears[9][7] = {
  {1,0,0,0,1,0,0},
  {1,0,0,0,1,0,1},
  {0,0,0,1,0,0,1},
  {1,0,1,1,1,1,0},
  {1,0,1,1,0,1,1},
  {1,1,0,1,0,0,1},
  {1,1,1,0,0,1,1},
  {1,1,1,0,1,1,1},
  {0,0,1,1,0,0,1}
};

volatile int buttonState[5];

IOexp myIOexpander1(IO_ADDR1);
IOexp myIOexpander2(IO_ADDR2);
IOexp myIOexpander3(IO_ADDR3);

long prevMilis1, prevMilis2, prevMilis3;
long blinkdelay1, blinkdelay2;
long rotarydelay;
long serialdelay;
bool blink1;
bool blink2;
volatile bool rotlock;

int inRPM, oldRPM;
int inGear, oldGear;
int inRev;
int inLimiter;

volatile int scrollval = 0;

void setup()
{
  
  pinMode(PIN_HIGHBIT, INPUT);
  pinMode(PIN_LOWBIT, INPUT);
  digitalWrite(PIN_LOWBIT, HIGH);
  digitalWrite(PIN_HIGHBIT, HIGH);
  
  Wire.begin();
  
  myIOexpander3.write(P2, true);
  myIOexpander3.write(P3, true);
  myIOexpander3.write(P4, true);
  myIOexpander3.write(P5, true);
  myIOexpander3.write(P6, true);
  
  turnoffall();
  
  blinkdelay1 = 500;
  blinkdelay2 = 200;
  rotarydelay = 50;
  serialdelay = 50;
  
  blink1 = false;
  blink2 = false;
  rotlock = false;
  
  prevMilis1 = 0;
  prevMilis2 = 0;
  prevMilis3 = 0;
  
  oldGear = 0;
  oldRPM = 0;
  inGear = oldGear;
  inRPM = oldRPM;
  
  for (int i = 0; i < 5; i++) {
    buttonState[i] = 1;
  }
  
  attachInterrupt(0, UpdateRotation, FALLING);
  
  Serial.begin(19200);
  Serial.println("Started");
}

void loop()
{
    unsigned int porta;
    byte botao;
    
    if (rotlock) {
       delay(1000);
       Serial.flush(); 
       rotlock = false;
    }
    
    if (Serial.available() > 0) {
      if (Serial.available() > 4) {
          if (Serial.read() == '#') {
            inRPM = Serial.read() - 48;
            inGear = Serial.read() - 48;
            inRev = Serial.read() - 48;
            inLimiter = Serial.read() - 48; 
          }
      }
    }
    
    if (inRPM != oldRPM) {
      showRPM(inRPM);
      oldRPM = inRPM;
    }
    
    if (inGear != oldGear) {
      showGear(inGear);
      oldGear = inGear;
    }
        
    myIOexpander3.write(P0, !inRev);
    
    if (inLimiter < 2) {
      myIOexpander3.write(P1, !inLimiter);
    } else if (inLimiter == 2) {
      myIOexpander3.write(P1, blink1);
    } else {
      myIOexpander3.write(P1, blink2);
    }
    
    for (int i = 0; i < 5; i++) {
      porta = powint(2, i + 2);
      botao = myIOexpander3.read(porta);
      if (botao != buttonState[i]) {
        Serial.write(i + 1);
        Serial.write(botao);

        buttonState[i] = botao ;
      }
    }
    
    processdelay();
}

void blinkFuel(bool blinkrate) {
  myIOexpander3.write(P1, blinkrate); 
}

void processdelay() {
  long currMilis;

  currMilis = millis();
  if ((currMilis - prevMilis1) > blinkdelay1) {
    prevMilis1 = currMilis;
    blink1 = !blink1; 
  }
  
  if ((currMilis - prevMilis2) > blinkdelay2) {
    prevMilis2 = currMilis;
    blink2 = !blink2; 
  } 
}

void showRPM(int leds) {
  unsigned int porta;
  
  if (leds == 0) {
    turnoffrpm();
  } else {
    for (int i = 1; i <= 8; i++) {
      porta = powint(2, i - 1);
      if (i <= leds) {
        myIOexpander1.write(porta, false);
      } else {
        myIOexpander1.write(porta, true);
      }
    }
    if (leds > 8)
      myIOexpander2.write(P0, false);
    else
      myIOexpander2.write(P0, true);
  }
}

void showGear(int gear) {
  unsigned int porta;
  
  for (int i = 1; i < 8; i++) {
    porta = powint(2, i);
    myIOexpander2.write(porta, !patgears[gear][i - 1]);
  }
}

void turnoffrpm() {
  myIOexpander1.fullwrite(B11111111);
  myIOexpander2.write(P0, true);
}

void turnoffgear() {
  unsigned int porta;
  
  for (int i = 1; i < 8; i++) {
    porta = powint(2, i);
    myIOexpander2.write(porta, true);
  }
}

void turnoffall() {
  myIOexpander1.fullwrite(B11111111);
  myIOexpander2.fullwrite(B11111111);
  myIOexpander3.write(P0, true);
  myIOexpander3.write(P1, true);
}

int powint(int base, int expo)
{
  if (expo == 0)
    return(1);
  else
    return(1 << expo);
}

void UpdateRotation() {
    byte botao;
    rotlock = true;
    
    if (digitalRead(PIN_LOWBIT)) {
        botao = 1;
        Serial.write(6);
        Serial.write(botao);
    } else {
        botao = 0;
        Serial.write(6);
        Serial.write(botao);
    }
}

I suggest you start by turning the three 8-bit IO expander objects into simple 8-bit variables:

uint8_t myIOexpander1;
uint8_t myIOexpander2;
uint8_t myIOexpander3;

That will cause a compile error whenever one of those objects is used. Fix each error by doing to the variable what was being done to the register (typically turning a bit on or off) and then call a function you will write to send those three variables to your three 8-bit shift registers.

You can remove the includes of Wire.h and IOexp.h. And the IO_ADDR defines.

Later, you can save a bunch of code and memory space by changing the 7-segment patterns into single bytes instead of 7 integers:

uint8_t patgears[9] = {
 B01000100,
 B01000101,
 B00001001,
 B01011110,
 B01011011,
 B01101001,
 B01110011,
 B01110111,
 B00011001};

johnwasser: I suggest you start by ...

I need to ask, what kind of skill level should/would you expect to be completing a task like this? I feel like I am in well over my head and its putting me off the project. I cant even see the ladder to get me out of the hole...

I have done what has been suggested (I think) which as stated, gave a whole pile of compile errors which I am trying to work on but I guess my lack of knowledge is showing through. Are you able to take a line of code that I need to change and provide an example please? I really want to try learn.

Excuse my naivety but when I have the final product, will I still have references to "myIOexpanderX" or is that just to highlight the changes I need to make at this stage?

Desperate for help please

:sweat_smile: