MLX90316 Hall-Effect Rotary Position Sensor for Steering Wheel

Hi everybody,

I have an analog output hall-effect sensor which is called MLX90316 from Melexis Company. I can read it with my arduino without problem. I use diagonally magnetized magnets with this sensor. When I rotate the magnet on the sensor it gives output in between 110-920. I want to use it for a replacement for multi-turn potentiometers. At full rotation completed, sensors value drops from 920 to 110. So I want to detect this discontinuity point and sum it to extend range of the output. I am planning to use this sensor for my steering wheel. It should give me a value in between 110-1500.

Code:

int val = 0;
int val2 = 0;
int sensorMin = 110;
int sensorMax = 920;
int state = 0;

void setup() {
  Serial.begin(9600);
}
void loop() {
  val = analogRead(A0);

  if(state == 0)
  {     
    Serial.print(val);
    Serial.println("   state 0");
    if(val >= sensorMax){
      state = 1;
    }
  }
  
  if (state == 1)
  {
    val2 = (sensorMax - sensorMin) + val;
    Serial.print(val2);
    Serial.println("   state 1");
    
    if(val2 < sensorMin){
      state = 0;
    }
  }
  delay(100);
}

Output example for the condition:

110
120
130
.
.
.
900
910
920
110
120
.
.
.

What I want is:

110
120
130
.
.
.
900
910
920
930
940
.
.
.
1500

Link: http://www.melexis.com/Hall-Effect-Sensor-ICs/Triaxis®-Hall-ICs/Rotary-Position-Sensor-IC-566.aspx

Any ideas for coding algorithm are welcome. What do you suggest?

Thank you.

Use the Map function to reverse the order

raschemmel:
Use the Map function to reverse the order

map function is not what i want..

Let me explain again. When I start to rotate magnet to the left it starts to give output starting from 110 and rises to 920 for 360 degree rotation. After this point, output drops to 110 again and rises to 920 again in each 360 degree rotation. I want to rotate the magnet 900 degree and take the output starting from 110 to 1510.

Rotating the magnet to the left should give me the increasing value and rotating the magnet to the right should give me the decreasing value.

Steering wheel;
Rotating Left: 1510-755
Center Position: 755
Rotating Right: 755-110

110
120
130
.
.
.
910
920
(920+110-110)=920
(920+120-110)=930
(920+130-110)=940
(920+140-110)=950
(920+150-110)=960
.
.
.
(920+700-110)=1510

Well you need a variable which tells you whether you are on the first or second revolution of the steering wheel.

You then need some bulletproof logic which detects when you transition from the first turn to the second turn, and back again from the second turn to the first turn.

And then you need a variable which represents the position you want, which you can calculate from the indicated position plus some offset when you are on the second turn.

  if (value < previous - 500)
    turns ++ ;
  if (value > previous + 500)
    turns -- ;
  previous = value ;
  angle = ((long) (value - 102) * 225) >> 9 ; // degrees
  angle += 360*turns ;

MarkT:

  if (value < previous - 500)

turns ++ ;
  if (value > previous + 500)
    turns -- ;
  previous = value ;
  angle = ((long) (value - 102) * 225) >> 9 ; // degrees
  angle += 360*turns ;

Thank you very much. It works very well. Can you tell me what you are doing in your algorithm? You have used some algebra and Bitshift operation. I want to understand the logic you have used.

I just detect the discontinuity and maintain a turns counter. Calculating degrees
is something you can figure out :wink:

MarkT:
I just detect the discontinuity and maintain a turns counter. Calculating degrees
is something you can figure out :wink:

Ok thank you. I have one problem. The code is working if I rotate the magnet slowly, but it fails if the magnet rotates fast. At fast displacement it fails to detect turns count and gives wrong output. Actually I have two conditions turns=0 and turns=1. I can not figure out this condition. May be I need another input for this turns detect condition.

Then you need to sample it more often - this is a fundamental problem related
to Shannon's sampling theorem.