Honeywell SS495A hall sensor problem reading

Hello,

At first, I'm sorry for my bad English

I'm building a fuel consumption cumputer for my oldtimer (car).

I've sorted almost everything out and I did get it worked on my desk. I had a flowmeter from biotech for measuring the litres and I used a hall sensor for measuring the RPM.

I bought a special disk with magnets for my driveshaft, but the magnets weren't alligned properly for my old sensor. The disk has only N on the outside, and my first sensor needed an N-pole to set (1023) and a S-pole to reset (0).

So I ordered the sensor mentioned in the title and the problems started. This sensor gives a reading between 0-1023 and has a reading of 500 when ther is no magnet around an gets to 0 when a N-pole comes a long.

But now I get random readings and sometimes I get a rpm count without any reason. Also it interferes with the flowmeter. So when there is flowcount I get the same rpm count.

I hope somebody can help me, I've included an sample code.

I've tried to change rissing into falling or low, but both seems not to help.

 float rpmHV;
 float flowHV;
 float rpmTRV;
 float flowTRV;
 float rpmTAV;
 float flowTAV;


void setup()
{
  attachInterrupt(1, rpm_fun, RISING);
  rpmHV = 0;
  rpmTRV = 0;
  rpmTAV = 0;

  attachInterrupt(0, flow_fun, RISING);
  flowHV= 0;
  flowTRV= 0;
  flowTAV= 0;
}


void rpm_fun()
{
  rpmHV++;
  rpmTRV++;
  rpmTAV++;

}

void flow_fun()
{
  flowHV++;
  flowTRV++;
  flowTAV++;
}

The code you posted is not complete. Can you post the complete code? Then we can advise you from the point where you left.

wrt the posted code:

  • I am missing "void loop()" where you process the variables

  • vars in ISR() must be volatile

  • vars in ISR() are best declared unsigned long (counts faster than float, go up to 4 billion++; fits most jobs)

Thank you for your reply. Here is my complete code. Im a starter so I made a lot of unnecessary steps.

I used float because I'm calculating with significant numbers, and i didn't get it work with unsigned long.

What do you mean with ISR?

part 1

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,16,2);

int XPin=A1;
int YPin=A0;
int resetPin=10;
int contact=9;
int contactstatus= HIGH;
int lastcontactState=LOW;

unsigned long millisreset;
int reseter;

int xreading;
int yreading;

int menuCounter = 1;
int menupState = HIGH; 
int lastmenupState=LOW;
int menumState = HIGH; 
int lastmenumState=LOW;

int eenheidCounter = 1;
int eenheidpState = HIGH; 
int lasteenheidpState=LOW;
int eenheidmState = HIGH; 
int lasteenheidmState=LOW;

volatile float rpmHV;
volatile float flowHV;
volatile float rpmTRV;
volatile float flowTRV;
volatile float rpmTAV;
volatile float flowTAV;

unsigned long millisstilstand;
int stilstandmillisA=1500;
int stilstand;

int HVmillis;
unsigned long millishv;

float RPMAFSTAND= 1.5625;
float totaldistance=0;

float tankinhoud= 35.0;
float stationair=0;
float HKL;
float HLK;
float TVKL;
float TVLK;
float TVL;
float GTVKL;
float GTVLK;
float OVKL;
float OVLK;
float OVL;
float ARK;


void setup()
{
  lcd.init(); 


  pinMode(resetPin, INPUT);
  pinMode(contact, INPUT);

  attachInterrupt(1, rpm_fun, LOW);
  rpmHV = 0;
  rpmTRV = 0;
  rpmTAV = 0;

  attachInterrupt(0, flow_fun, RISING);
  flowHV= 0;
  flowTRV= 0;
  flowTAV= 0;

  Serial.begin(9600);
} 

void loop(){
  beeldscherm();
  menuteller();
  eenheidteller();
  verbruik();
  stilstaan();
  reset();
  contactvoorwaarden();
}

void contactvoorwaarden(){
  contactstatus= digitalRead(contact);
  if (contactstatus!= lastcontactState){
  if (contactstatus==HIGH){
    lcd.backlight();
    lcd.display();
    lcd.clear();
    menuCounter=16;
     }
  else{
    lcd.noBacklight();
    lcd.noDisplay();
  }}
   lastcontactState =contactstatus;
    
  
}


void reset(){
  reseter=digitalRead(resetPin);
  if (reseter==HIGH){
    millisreset = millis() + 3000;  
  }

  if ((long)(millis()-millisreset)>=0 && reseter==LOW){
    lcd.clear();
    menuCounter=10;
  }
}

void menuteller(){
  xreading=analogRead(XPin);

  if(xreading > 600){
    menupState=HIGH;
  }
  else{
    menupState=LOW;
  }

  if(xreading < 434){
    menumState=HIGH;
  }
  else{
    menumState=LOW;
  }

  if (menupState != lastmenupState ) {
    if (menupState == HIGH) {
      menuCounter--;
      lcd.clear();
    }
  }
  lastmenupState= menupState;

  if (menumState != lastmenumState ) {
    if (menumState == HIGH) {
      menuCounter++;
      lcd.clear();
    }
  }
  lastmenumState= menumState;
}


void eenheidteller(){

  yreading=analogRead(YPin);

  if(yreading > 600){
    eenheidpState=HIGH;
  }
  else{
    eenheidpState=LOW;
  }

  if(yreading < 434){
    eenheidmState=HIGH;
  }
  else{
    eenheidmState=LOW;
  }

  if (eenheidpState != lasteenheidpState ) {
    if (eenheidpState == HIGH) {
      eenheidCounter--;
      lcd.clear();
    }
  }
  lasteenheidpState= eenheidpState;

  if (eenheidmState != lasteenheidmState ) {
    if (eenheidmState == HIGH) {
      eenheidCounter++;
      lcd.clear();
    }
  }
  lasteenheidmState= eenheidmState;
}

void beeldscherm(){

  if (menuCounter == 0){
    menuCounter = 5;
  }
  else if (menuCounter == 1){
    if (rpmHV==0){
      lcd.setCursor(0,0);
      lcd.print("actueel verbruik");
      lcd.setCursor(7,1);
      lcd.print("liter/uur");
      lcd.setCursor(0,1);
      lcd.print(stationair,1);
      lcd.print("  ");
    }
    else if (eenheidCounter ==1){
      lcd.setCursor(0,0);
      lcd.print("actueel verbruik");
      lcd.setCursor(7,1);
      lcd.print("     km/L");
      lcd.setCursor(0,1);
      lcd.print(HKL,1);
      lcd.print("  ");
    }
    else if (eenheidCounter ==2){
      lcd.setCursor(0,0);
      lcd.print("actueel verbruik");
      lcd.setCursor(7,1);
      lcd.print("  L/100km");
      lcd.setCursor(0,1);
      lcd.print(HLK,1);
      lcd.print("  ");
    }
    else if (eenheidCounter >=3){
      eenheidCounter =1;
    }
    else if (eenheidCounter ==0){
      eenheidCounter = 2;
    }
  }

  else if (menuCounter == 2){
    if (eenheidCounter ==1){
      lcd.setCursor(3,0);
      lcd.print("verbruik trip");
      lcd.setCursor(12,1);
      lcd.print("km/L");
      lcd.setCursor(0,1);
      lcd.print(TVKL,1);
      lcd.print("  ");
    }
    else if (eenheidCounter ==2){
      lcd.setCursor(3,0);
      lcd.print("verbruik trip");
      lcd.setCursor(9,1);
      lcd.print("L/100km");
      lcd.setCursor(0,1);
      lcd.print(TVLK,1);
      lcd.print("  ");
    }
    else if (eenheidCounter ==3){
      lcd.setCursor(3,0);
      lcd.print("verbruik trip");
      lcd.setCursor(11,1);
      lcd.print("Liter");
      lcd.setCursor(0,1);
      lcd.print(TVL,1);
      lcd.print("  ");
    }
    else if (eenheidCounter >=4){
      eenheidCounter =1;
    } 
    else if (eenheidCounter ==0){
      eenheidCounter = 3;
    }
  }

  else if (menuCounter == 3){
    if (eenheidCounter ==1){
      lcd.setCursor(3,0);
      lcd.print("verbruik tank");
      lcd.setCursor(12,1);
      lcd.print("km/L");
      lcd.setCursor(0,1);
      lcd.print(GTVKL,1);
      lcd.print("  ");
    }
    else if (eenheidCounter ==2){
      lcd.setCursor(3,0);
      lcd.print("verbruik tank");
      lcd.setCursor(9,1);
      lcd.print("L/100km");
      lcd.setCursor(0,1);
      lcd.print(GTVLK,1);
      lcd.print("  ");
    }
    else if (eenheidCounter >=3){
      eenheidCounter =1;
    }   
    if (eenheidCounter ==0){
      eenheidCounter = 2;
    }
  }

  else if (menuCounter == 4){
    if (eenheidCounter ==1){
      lcd.setCursor(0,0);
      lcd.print("overall verbruik");
      lcd.setCursor(12,1);
      lcd.print("km/L");
      lcd.setCursor(0,1);
      lcd.print(OVKL,0);
      lcd.print("  ");
    }
    else if (eenheidCounter ==2){
      lcd.setCursor(0,0);
      lcd.print("overall verbruik");
      lcd.setCursor(9,1);
      lcd.print("L/100km");
      lcd.setCursor(0,1);
      lcd.print(OVLK,0);
      lcd.print("  ");
    }
    else if (eenheidCounter ==3){
      lcd.setCursor(0,0);
      lcd.print("overall verbruik");
      lcd.setCursor(11,1);
      lcd.print("Liter");
      lcd.setCursor(0,1);
      lcd.print(OVL,0);
      lcd.print("  ");
    }
    else if (eenheidCounter >=4){
      eenheidCounter =1;
    }  
    else if (eenheidCounter ==0){
      eenheidCounter = 3;
    }
  } 
  else if (menuCounter == 5){

    lcd.setCursor(5,0);
    lcd.print("actieradius");
    lcd.setCursor(14,1);
    lcd.print("km");
    lcd.setCursor(0,1);
    lcd.print(ARK,1);
    lcd.print("  ");
  }

part 2

  else if (menuCounter == 6){
    menuCounter = 1;
  }
  else if (menuCounter == 7){
    menuCounter = 10; 
  }
  else if (menuCounter == 8){
    lcd.setCursor(0,0);
    lcd.print("X          TERUG");
    lcd.setCursor(7,1);
    lcd.print("tripreset");
    if(yreading<434){
      lcd.clear();
      menuCounter=1;
    }
  }

  else if (menuCounter == 9){
    lcd.setCursor(0,0);
    lcd.print("X      TANKRESET");
    lcd.setCursor(11,1);
    lcd.print("terug");
    if(yreading<434){
      lcd.clear();
      menuCounter=13;
      eenheidCounter =1;
    }
  }

  else if (menuCounter == 10){
    lcd.setCursor(0,0);
    lcd.print("X      TRIPRESET");
    lcd.setCursor(7,1);
    lcd.print("tankreset");
    if(yreading<434){
      lcd.clear();
      menuCounter=16;
      eenheidCounter =1;
    }
  }
  else if (menuCounter == 11){
    menuCounter = 8;
  }
  else if (menuCounter == 12){
    menuCounter = 13;
  }
  else if (menuCounter == 13){
    if (eenheidCounter==1){
      lcd.setCursor(1,0);
      lcd.print("tank resetten?");
      lcd.setCursor(0,1);
      lcd.print("  ja       X NEE");
      if(reseter==LOW){
        lcd.clear();
        menuCounter=1;
      }
    }
    if (eenheidCounter==2){
      lcd.setCursor(1,0);
      lcd.print("tank resetten?");
      lcd.setCursor(0,1);
      lcd.print("X JA         nee");
      if(reseter==LOW){
        lcd.clear();
        lcd.setCursor(1,0);
        lcd.print("tank is gereset");
        flowTAV=0;
        rpmTAV=0;
        delay (1000);
        menuCounter=1;
      }
    }
    else if (eenheidCounter >=3){
      eenheidCounter =1;
    }   
    else if (eenheidCounter ==0){
      eenheidCounter = 2;
    }
  }
  else if (menuCounter == 14){
    menuCounter = 13;
  }
  else if (menuCounter == 15){
    menuCounter = 16;
  }
  else if (menuCounter == 16){
    if (eenheidCounter==1){
      lcd.setCursor(1,0);
      lcd.print("trip resetten?");
      lcd.setCursor(0,1);
      lcd.print("  ja       X NEE");
      if(reseter==LOW){
        lcd.clear();
        menuCounter=1;
      }
    }
    else if (eenheidCounter==2){
      lcd.setCursor(1,0);
      lcd.print("trip resetten?");
      lcd.setCursor(0,1);
      lcd.print("X JA         nee");
      if(reseter==LOW){
        lcd.clear();
        lcd.setCursor(1,0);
        lcd.print("trip is gereset");
        flowTRV=0;
        rpmTRV=0;
        delay (1000);
        menuCounter=1;
      }
    }
    else if (eenheidCounter >=3){
      eenheidCounter =1;
    }   
    else if (eenheidCounter ==0){
      eenheidCounter = 2;
    }
  }
  else if (menuCounter == 17){
    menuCounter = 16;
  }
}


void rpm_fun()
{
  rpmHV++;
  rpmTRV++;
  rpmTAV++;

}

void flow_fun()
{
  flowHV++;
  flowTRV++;
  flowTAV++;
}
void verbruik(){
  if ((long)(millis()-millishv) >=0){
    HKL =1.0/flowHV*2.5*rpmHV*RPMAFSTAND;
    HLK=40.0/rpmHV/RPMAFSTAND*flowHV;
    stationair=3600000/HVmillis*(flowHV/2500);
    TVKL= 1.0/flowTRV*2.5*rpmTRV*RPMAFSTAND;
    TVLK= 40.0/rpmTRV/RPMAFSTAND*flowTRV;
    TVL= flowTRV/2500.0;
    GTVKL=1.0/flowTAV*2.5*rpmTAV*RPMAFSTAND;
    GTVLK= 40.0/rpmTAV/RPMAFSTAND*flowTAV;
    ARK=(tankinhoud-flowTAV/2500.0)*GTVKL;
    OVL+=(flowHV/2500.0);
    totaldistance+=(rpmHV*RPMAFSTAND);
    OVKL=totaldistance/OVL;
    OVLK=100.0/totaldistance*OVL;
    flowHV=0;
    rpmHV=0;
    millishv=millis() + HVmillis;
    Serial.println(rpmTRV);

  }
}
void stilstaan(){
  if ((long)(millis()-millisstilstand)>=1000){
    millisstilstand=millis()+ stilstandmillisA;
    stilstand=rpmHV;
  }

  if ((long)(millis()-millisstilstand)>=0){
    if (stilstand ==rpmHV){
      HVmillis=2000;
    }
    else
      HVmillis=500;
  }
}

ISR means "interrupt service routine" I believe, it is the little function that gets called when the interrupt occurs, if you set it up properly. Unfortunately, I only know what the acronym means, I don't know if yours is right.

Now if it was me, I'd put the rpm_fun and the flow_fun before setup(), otherwise when the compiler is reading all the code, it will come to the place in setup() where rpm_fun and flow_fun are mentioned, and not know what they are. You might need to have either a declaration or definition for those functions, preceding the spot where they are referenced in setup(). On the other hand, the compiler these days might be smart enough to figure that out.

The other thing I would vaguely suggest, is to test the different aspects of your system separately. For example, test the data collecting parts and just send the data to a laptop so you can see it is working. Then test all the LCD stuff separately. I have had a fair bit of grief getting LCD's to work.

Thank you for your replies. I stripped down my entire project to only the hall sensor and the flowmeter. I also stripped down my code.

But the problem still occurs, and it only occurs when I replace the type hall sensor, with my old hall sensor (latching melexis US 1881) it worked just fine.

My rpm count raises randomly without any magnet in the neighbourhoud. I'm thinking that the problem have to do with the different types of hall sensor latching/ linear. But I don't know how to solve this.

volatile float rpmHV;
volatile float flowHV;
volatile float rpmTRV;
volatile float flowTRV;
volatile float rpmTAV;
volatile float flowTAV;

int HVmillis=500;
unsigned long millishv;

void setup()
{
    attachInterrupt(1, rpm_fun, RISING);
  rpmHV = 0;
  rpmTRV = 0;
  rpmTAV = 0;

  attachInterrupt(0, flow_fun, RISING);
  flowHV= 0;
  flowTRV= 0;
  flowTAV= 0;

  Serial.begin(9600);
  
}

void loop(){
  if ((long)(millis()-millishv) >=0){
  Serial.print("rpmcount: "); 
  Serial.println(rpmHV);
  Serial.print("flowcount: ");
  Serial.println(flowHV);
  millishv=millis() + HVmillis;
  }}
  
  void rpm_fun()
{
  rpmHV++;
  rpmTRV++;
  rpmTAV++;

}

void flow_fun()
{
  flowHV++;
  flowTRV++;
  flowTAV++;
}

Edit, the problem also occurs when i disconnect the hall sensor from the arduino

stripped to something more minimal, with all initializations in place (there were some missing) , and a proper 500 millisec interval timing
(code not tested, give it a try...

// initialize while declaring vars
volatile unsigned long rpmHV = 0;
volatile unsigned long flowHV = 0;

unsigned long lastTime = 0;  
#define INTERVAL 500UL

void setup()
{
  attachInterrupt(1, rpm_fun, RISING);
  attachInterrupt(0, flow_fun, RISING);
  Serial.begin(9600);
  Serial.println("start...");
}

void loop()
{
  unsigned long now = millis();  // to prevent that the next read of millis jumps a few millisecs
  if (now - lastTime >= INTERVAL)   // every 500 milliseconds
  {
    lastTime = now;
    Serial.print("time: "); 
    Serial.println(now);
    Serial.print("rpmcount: "); 
    Serial.println(rpmHV * 2 * 60);   // rounds per half second => to rounds per minute
    Serial.print("flowcount: ");
    Serial.println(flowHV);   // needs some math too
  }
}
  
void rpm_fun()
{
  rpmHV++;
}

void flow_fun()
{
  flowHV++;
}

I don't know why you make calculations in the print. Because the rpm counts up, every time the magnets come by, the rpm gets one higher. At the end of the loop the rpmHV should be reset to zero, to make it work

And I also need the other 2 RPM and FLOW parameters, because I also make calculations with them. (fuelusage now, fuelusage tank, fuelusage trip, overall fuel usage)

Why do you write: #define INTERVAL 500UL what is the difference with int interval=500; ? (no offense I want to learn)

But to go short I have still interference with the flowmeter. But only with the "new" hall sensor.

maybe a very stupid question. but how do I connect the honeywell SS495A sensor.

I know the first pin is 5V, second Ground, Third is output. Shouldn't I place a resistor between 5v and output, or output and ground and how big should it be.

Because when I place an LED between output and ground there is no interference, but the hall sensor doesnt work and when I replace the LED by a 100k resistor there is still interference

The SS495A is an analogue output sensor, there is no need to use a pull-up or pull-down resitor. It you are just counting pulses, it would be better to use the hall effect switch version SS441A device. This will switch high when the magnet passes over the sensor, and then low when it is not. It also has all the hysteresis and Schmitt triggering ciruitry to avoid glitches. I use this device in a tachometer of mine.

Thanks!!