i2C and switch/case Statements with arrays

Hi,
I have a project where I want to control a motordriver with a potentiometer over i2C. I have my master sending the pot data correctly to the slave. I wish to use the data received in a switch/ case statement, and for some reason, I cant get it to work. The slave is receiving the data correctly but it is ignoring my attempt to turn the case into an array value (the speed of the motor).
the slave receives data (106, 107, 108, etc) and my switch statement should convert it into a number from the array (140, 130, 120) which is the speed of the motor, but for some reason doesnt. I feel like there is a basic error I’m making, but I cant see it. Any ideas?


#include <Wire.h>

// I/O PINS

//#define LED A2
#define SENSOR_A1 A1

// VARIABLES

byte dataFromI2C;
byte dataToI2C;
unsigned long  millisJunction;
static unsigned long prevTime = 0;


bool SENSOR_A1_Trigger = false;



/////////////////////////////////////Speed array//////////////////////////////////////
////####################0,1,2,03,04,05,06,07,08,09,10,11,012,013,014,015,016,017,018,019,020,021,022,023//
byte speedArrayA [] = {0, 0, 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 200, 220, 240};
//byte speedArrayB [] = {0, 0, 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 200, 220, 240};
//byte speedArrayC [] = {0, 0, 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 200, 220, 240};
byte speedTrainA = 0, speedTrainB = 0, speedTrainC = 0;
//////////////////////////////////////////////////////////////

void setup() {

  // Initializing I2C
  Serial.begin(9600); // for debugging
  Wire.begin(7); // set address #7
  Wire.onReceive(receiveI2C);
  Wire.onRequest(requestI2C);
  Serial.println("Ready LOCAL 7: ");
  Serial.print(SENSOR_A1_Trigger);

 // pinMode(LED, OUTPUT);
  pinMode(SENSOR_A1, INPUT);
 // digitalWrite(LED, HIGH);


}

void loop() {

  //sensor read
  sensorRead();


  //   motorSpeed();
 bool trainDir;
  if (dataFromI2C != 0) Serial.println(dataFromI2C);
  if (dataFromI2C != 0) {
    Serial.println("go--");
    switch (dataFromI2C) {

      Serial.println("go--");
      
      case 101: trainDir = 0  ; break; // fwd
      case 102: trainDir = 1 ; break; //bwd
      case 103: speedTrainA = speedArrayA[23]; break;
      case 104: speedTrainA = speedArrayA[22]; break;
      case 105:  speedTrainA = speedArrayA[21]; break;
      case 106: speedTrainA = speedArrayA[20]; break;
      case 107: speedTrainA = speedArrayA[19]; break;
      case 108: speedTrainA = speedArrayA[18]; break;
      case 109: speedTrainA = speedArrayA[17]; break;
      case 110: speedTrainA = speedArrayA[16]; break;
      case 111: speedTrainA = speedArrayA[15]; break;
      case 112: speedTrainA = speedArrayA[14]; break;
      case 113: speedTrainA = speedArrayA[13]; break;
      case 114: speedTrainA = speedArrayA[12]; break;
      case 115: speedTrainA = speedArrayA[11]; break;
      case 116: speedTrainA = speedArrayA[10]; break;
      case 117: speedTrainA = speedArrayA[9]; break;
      case 118: speedTrainA = speedArrayA[8]; break;
      case 119: speedTrainA = speedArrayA[7]; break;
      case 120: speedTrainA = speedArrayA[6]; break;
      case 121: speedTrainA = speedArrayA[5]; break;
      case 122: speedTrainA = speedArrayA[4]; break;
      case 123: speedTrainA = speedArrayA[3]; break;
      case 124: speedTrainA = speedArrayA[2]; break;
      case 125: speedTrainA = speedArrayA[1]; break;
      case 126: speedTrainA = speedArrayA[0]; break;

        if (trainDir == 0) {
          Serial.print(speedTrainA);
        }
        if (trainDir == 1) {
          Serial.print(-speedTrainA);

        }


    }

    dataFromI2C = 0;

  }





  /* // COMMAND PARSING
    if (dataFromI2C != 0) {
     switch (dataFromI2C) {

     // LED OFF
     case 30: digitalWrite(LED, LOW); break;
     // LED ON
     case 31: digitalWrite(LED, HIGH); break;



     }

    dataFromI2C = 0;

    }
  */
}

// ----------- FUNCTIONS ----------- //
void sensorRead() {



  SENSOR_A1_Trigger = digitalRead(SENSOR_A1 );
  if (SENSOR_A1_Trigger != 0) {
    dataToI2C = 71;
    //  Serial.print(" |to:");
    // Serial.println(dataToI2C);
  }
  else dataToI2C = 0;



}

void receiveI2C(int howMany) {
  while (Wire.available() > 0) {
    dataFromI2C = Wire.read();
    //   Serial.print(" |from:");
    // Serial.println(dataFromI2C);
  }
}
void requestI2C() {
  if (dataToI2C != 0) {
    Wire.write(dataToI2C); // respond with message to master
    //     Serial.print(" |to:");
    //   Serial.println(dataToI2C);
  }
}

What does the compiler says if you turn on all warnings? Try sticking to only case entries in the switch, with no code outside any case:…break;

The code compiles, without any issue.
when I insert Serial.print into the receiveI2C function, it prints the incoming data so I know the master is sending correctly.

My error seems to be at the switch statement
If I insert a couple more serial.print statements like below, the first two will print (the data from the slave followed by “do----” but the third after the switch statement (“go----”) will not

if (dataFromI2C != 0) Serial.println(dataFromI2C);
  if (dataFromI2C != 0) {
    Serial.println("do--");
    switch (dataFromI2C) {
      Serial.println("go--");

What does the doc about switch case say the compiler will do upon entering the switch or finding break

If condition evaluates to the value that is equal to the value of one of constant_expressions, then control is transferred to the statement that is labeled with that constant_expression.

If condition evaluates to the value that doesn’t match any of the case: labels, and the default: label is present, control is transferred to the statement labeled with the default: label.

The break statement, when encountered in statement exits the switch statement

So whatever you put outside the labels is not of much use.
Put the printing before or after the switch.

Note as well that instead of writing tons of similar cases like you did

      case 103: speedTrainA = speedArrayA[23]; break;
      case 104: speedTrainA = speedArrayA[22]; break;
      case 105: speedTrainA = speedArrayA[21]; break;
      case 106: speedTrainA = speedArrayA[20]; break;
      case 107: speedTrainA = speedArrayA[19]; break;
      case 108: speedTrainA = speedArrayA[18]; break;
      case 109: speedTrainA = speedArrayA[17]; break;
      case 110: speedTrainA = speedArrayA[16]; break;
      case 111: speedTrainA = speedArrayA[15]; break;
      case 112: speedTrainA = speedArrayA[14]; break;
      case 113: speedTrainA = speedArrayA[13]; break;
      case 114: speedTrainA = speedArrayA[12]; break;
      case 115: speedTrainA = speedArrayA[11]; break;
      case 116: speedTrainA = speedArrayA[10]; break;
      case 117: speedTrainA = speedArrayA[9]; break;
      case 118: speedTrainA = speedArrayA[8]; break;
      case 119: speedTrainA = speedArrayA[7]; break;
      case 120: speedTrainA = speedArrayA[6]; break;
      case 121: speedTrainA = speedArrayA[5]; break;
      case 122: speedTrainA = speedArrayA[4]; break;
      case 123: speedTrainA = speedArrayA[3]; break;
      case 124: speedTrainA = speedArrayA[2]; break;
      case 125: speedTrainA = speedArrayA[1]; break;
      case 126: speedTrainA = speedArrayA[0]; break;

you can use the range notation and do a bit of maths

case 103 ... 126: speedTrainA = speedArrayA[some_math_here]; break;

And you write a small formula that gives you 23 if the switch value is 103 and 0 if the switch value is 126. Simple linear formula, left as an exercise :wink:

1 Like

You hope that the compiler defaults to integer (it does) and that a negative unsigned byte can be printed (it does).

byte speedTrainA = 0;

Serial.print(-speedTrainA);

Could you add a cast to integer before making it negative ?

int speed = (int) speedTrainA;
Serial.print( -speed);

I have made a small simulation in Wokwi: https://wokwi.com/arduino/projects/297645374317789704.
Click the green start button. After clicking the Stop button, you can change things and try that.

Thanks JML! You have solved my issue and answered my next challenge as well!

My problem was that this code was still within the switch statement, moving it out side has solved it.

  if (trainDir == 0) {
          Serial.println(speedTrainA);
        }
        if (trainDir == 1) {
          Serial.println(-speedTrainA);

And double thanks for pointing me in the right direction in shortening the amount of code I need to write

Great
Have fun

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