Programming - If statements

Hello, I am making a vehicle detection device using an HMC5883l magnetometer, my problem right now is about the programming as one of the results is not being displayed despite having its condition as true. The other 2 are okay and seem to be displayed as intended. This aims to be a condition-based program to know when will the Arduino go in sleep mode and when it will wake up.

#include <Wire.h> //I2C Arduino Library
#define addr 0x1E //I2C Address for The HMC5883

int sensorValue=0;
int lastsensorValue;
int carInValue;
int carOutValue;

void setup()
{
Serial.begin(9600);
Wire.begin();
Wire.beginTransmission(addr);
Wire.write(0x02);
Wire.write(0x00); //Continuously Measure
Wire.endTransmission();
//Read the data
Wire.requestFrom(addr, 6);
if(6<=Wire.available())
{
  Serial.print("Calibrating...");
  Serial.println();
  delay(2000);
  sensorValue = Wire.read()<<8;
  sensorValue |= Wire.read();
  carOutValue = sensorValue;
  const int carOutValue=carOutValue;
  lastsensorValue=sensorValue;
  Serial.print("Setting the first reading as No Car Value...");
  Serial.println();
  delay(5000);
}
}

void loop()
{
Wire.beginTransmission(addr);
Wire.write(0x03);
Wire.endTransmission();
//Read the data
Wire.requestFrom(addr, 6);
if(6<=Wire.available())
{
  Serial.println();
  sensorValue = Wire.read()<<8; //MSB  x 
  sensorValue |= Wire.read(); //LSB  x
  Serial.print("Last Value:");
  Serial.print(lastsensorValue);
  Serial.println();
  Serial.print("No Car Value:");
  Serial.print(carOutValue);
  Serial.println();
  Serial.print("CO diff:");
  Serial.print(abs(sensorValue-carOutValue));
  Serial.println();
  delay(5000);

  if((abs(lastsensorValue))-(abs(sensorValue))<=100)
  {
    Serial.print("Nothing Happened");
    Serial.println();
    Serial.print("Sensor Value:");
    Serial.print(sensorValue);
    Serial.println();
    Serial.print("Diff:");
    Serial.print(abs(sensorValue-lastsensorValue));
    Serial.println();
    lastsensorValue=sensorValue;
  }
  else if((abs(sensorValue-carOutValue))>=101) 
  {
    Serial.print("Car In");
    Serial.println();
    Serial.print("Car In Value:");
    Serial.print(sensorValue);
    Serial.println();
    Serial.print("Diff:");
    Serial.print(abs(sensorValue-lastsensorValue));
    Serial.println();
    carInValue=sensorValue;
    lastsensorValue=sensorValue;
  }
  else if((abs(carOutValue-sensorValue))<=100)
  {
    Serial.print("Car Out");
    Serial.println();
    Serial.print("Car Out Value:");
    Serial.print(sensorValue);
    Serial.println();
    Serial.print("Diff:");
    Serial.print((abs(sensorValue-lastsensorValue)));
    Serial.println();
    lastsensorValue=sensorValue;
  }
}

delay(3000);
}

the “Car In” result is the problem and I can’t get it to be displayed even tho the difference of “Car Out” value from the “New Value” is almost 600 and the difference of “Last reading value” and “New Value” is also almost the same as the difference of “Car out” Value.

Below is the displayed results, and as you can see it should display “Car In” when the “Diff” is 601

I think I missing something simple but can’t see it for the last few hours. thank you for your time reading my topic, any tips or advice would be appreciated.

The first if is true because diff is 2, so the else if for “car in” doesn’t get executed.

I don’t understand what you’re actually trying to do, but it’s clear what’s wrong from the serial output. You might want to print all three variables that are tested in your if else sequence just before it.

Hi,
Is there a reason you are not using the HMC5883l Library?

What model Arduino are you using?

From your code, are you looking for a change in magnetic field above or below a certain level?
I assume you are using a piece of metal or magnet to do your experiments?

I have thought of doing a similar thing to detect vehicles coming in through a gateway.

Tom… :grinning: :+1: :coffee: :australia:

1 Like

Hi,
This is how I would envision the code.

void loop()
{
threshold = 100
sensorVal = Read Sensor
If (abs(sensorVal - oldsensorVal) > threshold)
  true  movementdetected = true
  false movementdetected = false

If (movementdetected)
    true Serial print   ("Yes we detected a movement in the force!!!!")
    false Serial print  ("No we haven't detected a movement in the force..")
oldsensorval = sensorval
}

This is only pseudo code, but I hope it shows the principle.

I don’t think the increase or decrease in magnetic field will mean specific coming or going of a vehicle, only the movement in the sensor range.
You cannot guarantee that vehicles have all the same magnetic field and direction to influence the background you are referencing to.

I would start with this logic and get it working before adding to it.
Do your code in stages.

Have you written code that just reads the sensor and outputs values so you can see how they are influenced buy different magnetic fields strength and polarity?

Tom… :grinning: :+1: :coffee: :australia:

1 Like

I think you mean -600

The difference of 2 absolute numbers can still be negative, but the absolute of the difference can’t.

You have:

if ((abs(lastsensorValue)) - (abs(sensorValue)) <= 100)

Ahh … speedy @TomGeorge beat me (I’m still getting used to this forum)

2 Likes

Not part of the problem, but what is the point of const int carOutValue=carOutValue; in setup(), particularly when the variable is not even used in that scope

2 Likes

Hello,
This is actually from a Hmc5883l library and i worked it up to be like this.

I am using Arduino uno r3

This code aims to detect drastic magnetic changes in a parking spot. Hence, if the car leaves from the spot or just arrived. if there are no changes(no car for a while) it will print nothing happened and if (car parked there for a while) still will be declared as nothing happened for that particular time. I am confused as to why the “car In” is not being displayed despite of having its only condition being met.

Yes it only detects a vehicle based on the difference of last value, “car out” value, and new value. I made it like this to log all the values to see why it goes in thru a certain condition

I see, this actually may be true as i didnt think of this.

But i noticed that every new value (sensorvalue) is postive. I checked my code and i didnt make it so that it will print a abs value of the newsensorvalue

My goal there is to get the very first reading as the “Car out” value so that it is calibrated in a way that every other readings after will be based on the very first reading that is why i saved it as carOutValue immediately after getting the sensor reading. The const int is just me being paranoid of something that somehow will make it change to another value. I dont know how to approach it in another way so…

Even if it achieved your aim, the fact that it is declared in setup() means that it can only be accessed in setup().

I strongly suspect that declaring a variable as equal to itself in the declaration is undefined behaviour, so you cannot be sure what the value will be anyway

Hi
Yes I am talking about when the diff for the first time is 600, it should(as far as i know) display “Car In”

The c0 diff is the difference from the carOutValue(which is the very first reading) and the new value. While diff is the difference from the lastvalue and new value from every loop.

I am making a vehicle detection device for a parking space that can tell if nothing is happening(parked for a while or no car for a while) and if the car goes away from the spot or just arrived.

Hi
As you can see from the display there is a no car value that prints a constant value. And i think that is the carOutValue and the very first sensor value

Not all cars/trucks/buses with have the same magnetic signature, so establishing a reference level with no cars would be the most logical.
Do all your measurements against the reference.

void setup()
{
establish reference == magreference

void loop()
{
threshold = 100
sensorVal = Read Sensor
If (abs(sensorVal - magreference) > threshold)
  true  movementdetected = true
  false movementdetected = false

If (movementdetected)
    true Serial print   ("Yes we detected a movement in the force!!!!")
    false Serial print  ("No we haven't detected a movement in the force..")

}

I don’t think you will get this in one go, so I would be out in the field testing.
Using Serial.print to let you see your raw IMU data…etc…

Tom… :grinning: :+1: :coffee: :australia:

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