variable changing value....can't figure out why

Yes, I'm new to C and Arduino, but used other languages.

I've got a BMA180 accelerometer connected to a Mega2560. I think they are communicating properly, but running into some random problems. For example, I have a code I found on the web (no header in the code...and now I can't find where I first found it!) that I've modified. It trips an error flag if the Arduino and BMA180 have trouble communicating, and sets variable "error" to a value of 1. My problem is, the value starts off as a 0 and then mysteriously changes to a 1 in the middle of my code. I added a bunch of .println statements to figure out exactly where it is happening

  result = Wire.endTransmission();
  Serial.println(error);   //at this point, the serial monitor shows a value of "0"
  checkResult(result);    //this is a function prints various messages depending on value of "result" but has no code to change value of error
  Serial.println(error);   //at this point, still showing a value of "0"
    
  if(result > 0)   //the value of result is usually (hopefully!) zero, and so this if loop doesn't run, "error" shouldn't change.  Note that I *think* the if loop doesn't get activated because it does NOT give me a serial monitor message saying "error changed to 1"
  {
    error = 1;
    Serial.println("error changed to 1");
  }

  Serial.println(error);   //but now, after going past the loop which it shouldn't run, the error value has changed to "1".

At the very beginning of the code, there is a "int error;" statement to define the variable, but I'm guessing something is over writing my variable?? Suggestions?

At the very beginning of the code, there is a "int error;

No, there isn't. (hint)

(BTW "result" != "error")

You are referring to error and result as if they were the same variable. They aren't :slight_smile:

DenverD:
At the very beginning of the code, there is a "int error;" statement to define the variable, but I'm guessing something is over writing my variable?? Suggestions?

Enough of this. Post all your code please. And post your serial output, don't just describe it.

Ok, I tried to follow the conflicting recommendations....post all the code....and post only the relevant code.....so the whole thing is below. Serial output is first, code is second.

Thanks for the "hints" (yes, I can use sarcasm too :stuck_out_tongue_closed_eyes:).

I hope that "int temp, result, error;" is an acceptable way to declare mulitple variables, I've just copied it from other code examples.

Yes, I know that result and error are different variables.

The general logic is that result should be equal to 0 (I haven't looked up all of the answers that can come out of the Wire.endTransmission(), but I assume that is why he used >0).

If result if greater than zero, turn the error flag to 1.

So right before the if statement, error = 0 (output line 4), and result = 0. But right after the if statement, error =1 (output line 5).

So for some reason, error gets changed and I can't figure out why. All of the Serial.print statements were my attempt to figure out exactly when it changes.

Related, I'm used to initializing all of my variables (explicit statement error = 1; at the beginning), but the originator of this code doesn't. Was that bad practice? Or am I missing something.

0
Id = 3
0
Read/Write success...Result code is 0
0
1
Correct ID
Read/Write success...Result code is 0
0
1
Read/Write success...Result code is 0
0
1
Read/Write success...Result code is 0
0
1
1
BMA180 NOT initialized!
X = 20
X = 16
X = 16
X = 16
X = 16
int x;

void initBMA180()
{
  int temp, result, error;

  Serial.println(error);
 
  Wire.beginTransmission(address);
  Wire.write(0x00);
  Wire.requestFrom(address, 1);
  while(Wire.available()) 
  {
    temp = Wire.read();
  }
  Serial.print("Id = ");
  Serial.println(temp);
  result = Wire.endTransmission();
  Serial.println(error);
  checkResult(result);
  Serial.println(error);
    
  if(result > 0)
  {
    error = 1;
    Serial.println("error changed to 1");
  }
  //else
  //{
  //  error=0;
  //}  
  Serial.println(error);
  
  delay(10);
  if(temp == 3)
  {
    Serial.println("Correct ID");
    // Connect to the ctrl_reg1 register and set the ee_w bit to enable writing.
    Wire.beginTransmission(address);
    Wire.write(0x0D);
    Wire.write(B0001);
    result = Wire.endTransmission();
    checkResult(result);
    Serial.println(result);
    if(result > 0)
    {
      error = 1;
      Serial.println("error changed to 1");
    }
    Serial.println(error);
    
    delay(10);
    // Connect to the bw_tcs register and set the filtering level to 10hz.
    Wire.beginTransmission(address);
    Wire.write(0x20);
    Wire.write(B00001000);
    result = Wire.endTransmission();
    checkResult(result);
    Serial.println(result);
    if(result > 0)
    {
      error = 1;
      Serial.println("error changed to 1");
    }
    Serial.println(error);
    
    delay(10);
    // Connect to the offset_lsb1 register and set the range to +- 2.
    Wire.beginTransmission(address);
    Wire.write(0x35);
    Wire.write(B0100);
    result = Wire.endTransmission();
    checkResult(result);
    Serial.println(result);
    if(result > 0)
    {
      error = 1;
      Serial.println("error changed to 1");
    }
    Serial.println(error);
    delay(10);
  }

  Serial.println(error);
 
  if(error == 0)
  {
    Serial.println("BMA180 Init Successful"); 
  }
  else
  {
    Serial.println("BMA180 NOT initialized!");
  }
}

void checkResult(int result)
{
  if(result >= 1)
  {
    Serial.print("PROBLEM..... Result code is ");
    Serial.println(result);
  } 
  else
  {
    Serial.print("Read/Write success...Result code is ");
    Serial.println(result);
  }
}

I added an explicit error = 0; at the beginning to initialize the variable. Now, it seems to work every time (ie, the variable error doesn't change from 0 to 1 after passing the if statement).

So I think I do need to initialize the variables. Can anyone tell me what was likely happening? Why did the print statements indicate the value was zero, but somehow it really wasn't? Or wasn't stable?

My code is working, but I still want to know why. Thanks in advance!

D

First:

  int temp, result, error;

  Serial.println(error);

The variable error is not initialized and is thus undefined. Printing it doesn't prove much.

I added an explicit error = 0; at the beginning to initialize the variable.

Good. Now can you post the complete code? What you posted doesn't compile:

sketch_sep15a.cpp: In function 'void initBMA180()':
sketch_sep15a:8: error: 'Wire' was not declared in this scope
sketch_sep15a:8: error: 'address' was not declared in this scope

DenverD:
So I think I do need to initialize the variables. Can anyone tell me what was likely happening? Why did the print statements indicate the value was zero, but somehow it really wasn't? Or wasn't stable?

By not initializing the variable it is undefined. The compiler's optimization may have not bothered to load the variable correctly (between print statements) because an undefined value is, well, undefined. You can't rely on it.

Make that will not - the compiler will NEVER insert additional code to initialize LOCAL variables for you!

It was initially undefined, yes. But his test appears to demonstrate that the undefined-ness persists in the sense that, from one access to the next, the variable might change in value.

Sorry, still new to this. The "main" code was in a different window, attached below.

The undefined variable was definitely the problem. I could make the code work, and then not work, by adding or removing the error=1; line. Very, very strange that the value changes in the middle of the code though. I would have thought the address pointer would point to some place in the RAM, and that nothing would change the content of the address until the code changes it. Evidently this isn't true.

Again, I found this code on the net and it at least got me started. I've found this and several other issues with the code. Once complete, I plan to post the wiring as well as code so others can use it. I'm certainly not the first nor the only one trying to get BMA180 accelerometers to work with Arduino.

#include <Wire.h>

#define address 0x40

void setup()
{
  Wire.begin();
  Serial.begin(9600);
  initBMA180();
  delay(2000);
}

void loop()
{

  readAccel();  

  delay(200);
}

DenverD:
I would have thought the address pointer would point to some place in the RAM, and that nothing would change the content of the address until the code changes it. Evidently this isn't true.

You would think that, it is reasonable. However the compiler optimizes variables into registers for speed and efficiency. It's optimization must have said "don't care" when loading the register, since the value was undefined, it had no need to care about putting the same undefined value into the register each time.