Unknown value read from array

I have a model train layout with pushbuttons connected in a matrix to an arduino mega (Master). The master then radios another arduino mega (Slave) to operate an SG90 servo (via a HCPCA9685) to throw the relevant point. All that works ok.
However when I try to read the microswitches on PButton 8 I am getting an incorrect pin# value..
Below are the pin assignments for the 9 servos: PButton 8 operates servo 0, whose microswitches are connected to pins 22 & 23.

byte straightMSPin[] = {22,24,29,27,30,33,35,37,39};
byte turnoutMSPin[] = {23,25,28,26,31,32,34,36,38};
byte DS1straightPin = 40;
byte DS1turnoutPin = 41;
byte DS2straightPin = 42;
byte DS2turnoutPin = 43;

Here is the code to change a point:

void changePoint(int whichWay){
  switch (whichWay){
    case 1:
    Myservo.Servo(whichServo, servoHomePos[whichServo]); //servo back to home
    delay(500); //allow time for servo to move
    Serial.print("case 1 ");
    Serial.print(straightMSPin[whichServo]);
    Serial.println(turnoutMSPin[whichServo]);
    checkPoint(whichWay);
    break;
    case 2:
    Myservo.Servo(whichServo, servoTurnoutPos[whichServo]); // set servo to turnout
    delay(500);
    Serial.print("case 2 ");
    Serial.print(straightMSPin[whichServo]);
    Serial.println(turnoutMSPin[whichServo]);
    checkPoint(whichWay);
    break;
  }

and here is the results on the serial monitor:

case 2 22120
Check point - straightMSPin 22 turnoutMSPin 120
Servo 0 changed
Straight Micropin 22
Turnout Micropin 120
straightMS value 1
turnoutMS value 1
2 Data sent ok

case 1 22120
Check point - straightMSPin 22 turnoutMSPin 120
0 not changed
Straight Micropin 22
Turnout Micropin 120
straightMS value 0
turnoutMS value 1
2 Data sent ok

case 2 2928
Check point - straightMSPin 29 turnoutMSPin 28
Servo 2 changed
Straight Micropin 29
Turnout Micropin 28
straightMS value 0
turnoutMS value 1
2 Data sent ok

case 1 2726
Check point - straightMSPin 27 turnoutMSPin 26
Servo 3 changed
Straight Micropin 27
Turnout Micropin 26
straightMS value 1
turnoutMS value 0
1 Data sent ok

case 2 3031
Check point - straightMSPin 30 turnoutMSPin 31
Servo 4 changed
Straight Micropin 30
Turnout Micropin 31
straightMS value 0
turnoutMS value 1
2 Data sent ok

In the first example PButton was pressed to change the point from straight to turnout.
As you can see the pin# for the turnout microswitch is showing 120 when it should be 23.
I have no idea where the value of 120 is coming from.
In the second example PButton 8 was pressed to change the point from turnout to straight.
The point changes direction and the relevant microswitch is operated.
The next three examples show the results when push buttons 10, 11 & 12 are pressed. They all work as expected.
I have spent several hours checking and rechecking the wiring from the microswitches to the slave arduino mega and from the servos to the HCPCA9685.
I am hoping someone can spot some stupid error I have made which is giving the wrong turnout microswitch pin number as 120 when it should be 23.

I am hoping someone can spot some stupid error

You didn't post all your code.

It is likely a memory scribble, but without all your code....

@op,
Could be micro switch bouncing issues!

Here's all the code as requested.

// Wire Slave Receiver No 2
// point status 1 = straight; 2 - turn out; 0 = failed

#include <Wire.h>
#include <HCPCA9685.h>
#include <SPI.h>
#include <NRFLite.h>
#include <EEPROM.h>
#define I2CAdd 0x40
HCPCA9685 Myservo(I2CAdd);
const static byte slave_ID = 2;       
const static byte MasterradioID = 0;
const static byte CE = 9;
const static byte CSN = 10;
struct RadioPacket {// Any packet up to 32 bytes can be sent.
    byte FromRadioId;
    byte pushbuttonNumber;
    bool didchange;
    byte pointStatus;
};
NRFLite slaveRadio;
RadioPacket _radioData;
int currentpointPos =1; // 1=straight, 2 = turnout
int currentposdoubleSlip =1;    //positions are 1, 2, 3, 4

byte straightMSPin[] = {23,24,29,27,30,33,35,37,39};
byte turnoutMSPin[] = {22,25,28,26,31,32,34,36,38};
byte DS1straightPin = 40;
byte DS1turnoutPin = 41;
byte DS2straightPin = 42;
byte DS2turnoutPin = 43;
int DS1 = 9; //servo output number for doubleslip
int DS2 = 10;
int DS1servoHome = 10;
int DS1servoTurnout = 120;
int DS2servoHome = 10;
int DS2servoTurnout = 120;

// original servo home and turnout positions saved to EEPROM
int servoHomePos[]= {1, 10, 160, 120, 5, 150, 130, 10, 10};
int servoTurnoutPos[]= {140, 120, 10, 10, 170, 10, 10, 140, 120};

int button2servomap[]={8, 9, 11, 12, 13, 14, 16, 17, 18, 15, 15};
int whichServo = 0;
int whichButton = 0;
byte currentPosition[9];
bool didpointChange = false;
byte myPos;
bool straightMS = false;
bool turnoutMS = false;

void setup(){
  /* Initialise the library and set it to 'servo mode' */ 
  Myservo.Init(SERVO_MODE);
  /* Wake the device up */
  Myservo.Sleep(false);
  
  Serial.begin(115200);           // start serial for output
  // set pins to Inputs
  for (int x =22; x<45; x++){
    pinMode(x, INPUT);
  }
/*   //read status all points except double slip
   for (int y = 0; y<8; y++){
    if (digitalRead(straightMSPin[y]) == HIGH){
      lhMicro[y] = HIGH;
      currentPosition[y] = 1; //straight. assumes lhmicro is high when straight.
    }else {
      lhMicro[y] = LOW;
    }
    if (digitalRead(turnoutMSPin[y]) == HIGH){
      rhMicro[y] = HIGH;
      currentPosition[y] = 2; // turnout
     }else{
      rhMicro[y] = LOW;
     }
   }*/
  // write homepos to EEPROM servo values. 0 -10 LH; 11-21 RH
 /* for (int z = 0; z <11; z++){
    EEPROM.write(z, servoHomePos[z]);
  }
  for (int z =11; z<22; z++){
    EEPROM.write(z, servoTurnoutPos[z-11]);
  }delay(2000);
  
//read servo home and turnout positions from EEPROM
  for (int z =0; z<11; z++){
    myPos = EEPROM.read(z);
    //Serial.println(myPos);
    servoHomePos[z] = myPos;
  }*/
  for (int z = 11; z<22; z++){
    myPos = EEPROM.read(z);
    servoTurnoutPos[z-11] = myPos;
  }
 
    if (!slaveRadio.init(slave_ID, CE, CSN)){
        Serial.println("Cannot communicate with radio");
        while (1); // Wait here forever.
    }else{
      Serial.println("Radio OK");
    }
  for (int z= 0; z<9; z++){
    currentPosition[z]=1; //straight
  }
  // set all points to straight
  for (int p =0; p<11; p++){
    Myservo.Servo(p, servoHomePos[p]);
    delay(500);
  }
}

void readMaster(){
     slaveRadio.readData(&_radioData); 
     // Note how '&' must be placed in front of the variable name.
     whichButton = _radioData.pushbuttonNumber;
     //delay(500);
     selectServo();
     reportPointchange();
}

void selectServo(){
  // button2servomap
  for (int servomatch = 0; servomatch <10; servomatch++){
    if (button2servomap[servomatch] == whichButton){
      whichServo = servomatch;
      break;
    }
  }
  switch (whichServo){
    case 0 ... 8:  // points 8 to 16; double slip is 17/18
      // get current position of that point 
      if ((currentPosition[whichServo])==1){
        //move point to turnout
        changePoint(2);
        currentPosition[whichServo] = 2;
      }else{
        //move point to straight 1
        changePoint(1);
        currentPosition[whichServo] = 1;
      }
      // read point status
    break;
    case 9 ... 10:  //double slip servos 9 & 10
     // This slip requires different handling.Has two dependent servos
     changedoubleSlip();
     checkdoubleslipMicros();
    break;
  }
}

void changePoint(int whichWay){
  switch (whichWay){
    case 1:
    Myservo.Servo(whichServo, servoHomePos[whichServo]); //servo back to home
    delay(500); //allow time for servo to move
    checkPoint(whichWay);
    break;
    case 2:
    Myservo.Servo(whichServo, servoTurnoutPos[whichServo]); // set servo to turnout
    delay(500);
    checkPoint(whichWay);
    break;
  }
}

void checkPoint(int newPosition){
  didpointChange = false;
  straightMS = false;
  turnoutMS = false;
  switch (newPosition){
    case 1:
    straightMS = digitalRead(straightMSPin[whichServo]);
    turnoutMS = digitalRead(turnoutMSPin[whichServo]);
      if (straightMS== HIGH){;  //straightMS closed
      didpointChange = true;
      currentPosition[whichServo]= 1;
      Serial.print("Straight ");
      Serial.println(straightMS);
    };
    break;
    case 2:
    straightMS =digitalRead(straightMSPin[whichServo]);
    turnoutMS = digitalRead(turnoutMSPin[whichServo]);
      if (turnoutMS== HIGH){;
      didpointChange = true;
      currentPosition[whichServo] = 2;
      Serial.print("Turnout ");
      Serial.println(turnoutMS);
    }
    break;
  }
  if (didpointChange){
    Serial.print(whichServo);
    Serial.println(" changed");
  } else {
    Serial.print(whichServo);
    Serial.println(" not changed");
  }
    Serial.print("Straight Micropin ");
    Serial.println(straightMSPin[whichServo]);
    Serial.print("Turnout Micropin ");
    Serial.println(turnoutMSPin[whichServo]);
    Serial.print("straightMS value ");
    Serial.println(straightMS);
    Serial.print("turnoutMS value ");
    Serial.println(turnoutMS);
}

void changedoubleSlip(){
  // both servos are at home pos from setup.
  switch (currentposdoubleSlip){
    case 1:
      //move servo DS1 to turnout position
      Myservo.Servo(DS1, DS1servoTurnout);
      currentposdoubleSlip++;
      break;
    case 2:
      // move servo DS2 to turnout position
      Myservo.Servo(DS2, DS2servoTurnout);
      currentposdoubleSlip++;
      break;
    case 3:
      // move servo DS1 to home position
      Myservo.Servo(DS1, DS1servoHome);
       currentposdoubleSlip++;
      break;
    case 4:
      // move DS2 to home position
      Myservo.Servo(DS2, DS2servoHome);
      currentposdoubleSlip=1;
      break;
     }
     currentpointPos - currentposdoubleSlip;
}

void checkdoubleslipMicros(){
    didpointChange = false;
    bool DSMSa = false;
    bool DSMSb = false;
    switch (currentposdoubleSlip){
      case 1:
        DSMSa = digitalRead(DS1straightPin);    //40
        DSMSb = digitalRead(DS2straightPin);    //42
        didpointChange = (DSMSa && DSMSb);
      break;
      case 2:
        DSMSa = digitalRead(DS1turnoutPin);     //41
        DSMSb = digitalRead(DS2straightPin);    //42
        didpointChange = (DSMSa && DSMSb);
      break;
      case 3:
        DSMSa = digitalRead(DS1turnoutPin);     //41
        DSMSb = digitalRead(DS2turnoutPin);     //43
        didpointChange = (DSMSa && DSMSb);
      break;
      case 4:
        DSMSa = digitalRead(DS1straightPin);    //40
        DSMSb = digitalRead(DS2turnoutPin);     //43
        didpointChange = (DSMSa && DSMSb);
      break;
    }
}

void reportPointchange(){
  _radioData.FromRadioId = 2;
  _radioData.pushbuttonNumber = whichButton;
  _radioData.didchange = didpointChange;
  _radioData.pointStatus = currentpointPos;
  if(slaveRadio.send(MasterradioID, &_radioData, sizeof(_radioData))){
    Serial.print(_radioData.didchange);
    Serial.println(" Data sent ok");
    Serial.println();
  }
}

void loop(){
  while(!slaveRadio.hasData()){
  }
    readMaster();
}

In this code servoTurnoutPos only appears to have 9 elements, but you are reading 11:

  for (int z = 11; z<22; z++){
    myPos = EEPROM.read(z);
    servoTurnoutPos[z-11] = myPos;

The same problem is true in other places, but they are commented out, but use servoHomePos aswell. You also write 11 positions when these arrays only have 9 elements.

Problem solved. Thanks to those who scratched their head over this issue. I discovered that if I commented out the lines in the setup where the EEPROM is read, the problem goes away. Perhaps someone with a better understanding can explain the connection.

Did you fix the problem described by countrypaul ?

johnhb:
Problem solved. Thanks to those who scratched their head over this issue. I discovered that if I commented out the lines in the setup where the EEPROM is read, the problem goes away. Perhaps someone with a better understanding can explain the connection.

Did you increase the size of the servoHomePos or servoTurnoutPos arrays to 11 or decrease the initialization of those arrays to 9? If not, you are exceeding the bounds of the arrays and overwriting other memory locations which can cause weird behavior.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.