Enum: getting double duty?

Hi Folks,

I'm trying to get double duty out of an enum.

Specifically I am working with an MPU6050. Part of the operation is to define the range of the gyroscope. There are four values 250, 500 1,000 and 2,000.

I have used the following enum:

enum eGyroscope {
Gyro250 = 0x00,
Gyro500 = 0x08,
Gyro1000 = 0x10,
Gyro2000 = 0x18,
MaskGyro = 0x18
};

This works very well, except, I want more!

Part of the setting the range is also setting the divisor.
For example, setting a range of 250 means a divisor of 131.

So what I want is when I choose Gyro250, I get the bit pattern 0x00, BUT, I also get a second value of 131!

Is that possible.

P.S. at the moment I run a series of if statements to generate the second value.
Just trying to make the code 'work harder'. :slight_smile:

you could use 2 bytes

HiByte for the current value and LowByte for the 131/0x83

Gyro250 = 0x8300,

but to be honest - I don't like that.
an enumeration is an enumeration.
Put your "two value logic per enumeration" in your Code.

Use a simpler enum as an index to an array of structs containing the actual data

enum eGyroscope
{
    Gyro250,
    Gyro500,
    Gyryo1000,
    Gyro2000,
    MaskGyro
};

struct data
{
    char* name;
    int range;
    int divisor;
};

data gyroData[5] = {
    { "Gyro250", 0x00, 131 },
    { "Gyro500", 0x08, 145 },
    { "Gyro1000", 0x10, 170 },
    { "Gyro2000", 0x18, 180 },
    { "MaskGyro", 0x18, 255 }
};

void setup()
{
    Serial.begin(115200);
    Serial.println(gyroData[Gyro250].name);
    Serial.println(gyroData[Gyro250].range, HEX);
    Serial.println(gyroData[Gyro250].divisor);
    Serial.println();
    Serial.println(gyroData[Gyro2000].name);
    Serial.println(gyroData[Gyro2000].range, HEX);
    Serial.println(gyroData[Gyro2000].divisor);
}

void loop()
{
}

NOTE that is is not necessary to include the name in the struct for this to work but I added for illustration

OUTPUT

Gyro250
0
131

Gyro2000
18
180
3 Likes

@OzMaz

another proposal based on "put it in code":

enum eGyroscope {
  Gyro250,
  Gyro500,
  Gyro1000,
  Gyro2000,
  MaskGyro
};

uint8_t getRange(eGyroscope in) {
  switch (in) {
    case Gyro250: return 0x00;
    case Gyro500: return 0x08;
    case Gyro1000: return 0x10;
    case Gyro2000: return 0x18;
    case MaskGyro: return 0x18;
  }
  return 0;
}

uint8_t getDivisor(eGyroscope in) {
  switch (in) {
    case Gyro250: return 131;
    case Gyro500: return 132;
    case Gyro1000: return 133;
    case Gyro2000: return 134;
    case MaskGyro: return 135;
  }
  return 0;
}


void setup() {
 Serial.begin(115200);
 Serial.println(getDivisor(Gyro250), HEX);
 Serial.println(getRange(Gyro250));

}

void loop() {
  // put your main code here, to run repeatedly:
}
//
  • when you re-arange the order in the enum the code will still work
  • when you delete an entry in the enumeration and forget to edit the switch cases the compiler will give an error
  • when you add a new entry (or insert a new one within the existing values) and you miss to add the new value in the switch case the compiler will at least warn you that you missed a case (... when you have activated the warnings - what you should do anyway).
1 Like

Thanks for your solution noisca, good stuff.

I thought about the problem and came up with this solution.

enum eGyroscope {
  Gyro250   = 0,
  Gyro500   = 1,
  Gyro1000  = 2,
  Gyro2000  = 3,
  MaskGyro  = 4
};

int   GyroscopeRates[]   = {0x00,  0x08, 0x10, 0x18, 0x18};
float GyroscopeDivisor[] = {131.0, 66.5, 32.8, 16.4};

DivisorGyroscope = SetGyroscopeScale(eGyroscope::Gyro250);

float SetGyroscopeScale(eGyroscope Value) {

  int NewValue;
  int Mask;
  int temp;

  // Get the two related values.
  NewValue = GyroscopeRates[Value];
  Mask = GyroscopeRates[4];

  Wire.beginTransmission(I2C_MPU_ADDRESS);
  Wire.write(GYRO_CONFIG); 

  temp = Wire.read() & Mask;                     // Read the current value and clear the acceleration sensitivity bits.
  temp |= NewValue;                              // Set the new bits.
  Wire.write(temp);                              // Apply the new value.
  Wire.endTransmission(true);

  return GyroscopeDivisor[Value];

}

Thanks for your effort.

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