0

I'm trying to run a camless engine and I need to track the angular position of the crankshaft of the engine. For that I have a wheel with 30 magnets attached to the crankshaft so that when the wheel spins with the crankshaft, a Hall-Effect sensor detects a magnet and adds + one to the counter of magnets. When one full rotation is completed (i.e when 30 magnets have passed), I reset the counter to 0. Here's the code:

const int hall = 2;
int hallcounter = 0;
int hallstate = 0;
int lasthallstate = 0;
unsigned long triggerTime;
unsigned long last_triggerTime;
unsigned long timeGap;
unsigned long last_timeGap;
unsigned int degree;
unsigned int state;
int newstate;


void setup() {
  pinMode(hall, INPUT_PULLUP);
  Serial.begin(115200);
  pinMode(10, OUTPUT);    // sets the digital pin 10 as output
  pinMode(11, OUTPUT);    // sets the digital pin 11 as output
  attachInterrupt(0, magnet_detect, RISING);//Initialize the intterrupt pin digital pin 2
  digitalWrite(10, HIGH); //initialize relays at open
  digitalWrite(11, HIGH); //second relay
  degree = 0;
}


 void loop()
 {
  //The compiler says this is needed otherwise the govt. takes my cat
   }

void magnet_detect() {
      hallcounter ++;
     
      if (hallcounter==30)
      {
        //Serial.println(state);
        Serial.println("missing tooth");
        hallcounter = 0; 
        state++; //This right here is garbage and you know it.
      }
    
      Serial.println(hallcounter);
    
     //degree = hallcounter * 6;
     if ((state % 2) == 0) { //Bool wasn't working so this dumpster fire got started.
        Serial.print("ETAT ADM 1 ");
        if (1 <= hallcounter && hallcounter <= 17) { //EDIT HERE INTAKE
        digitalWrite(10, LOW); // sets the digital pin 10 on
        }
        else {
        digitalWrite(10, HIGH);  // sets the digital pin 10 off
        }
     }
     if ((state % 2) == 1) {
        Serial.print("ETAT ECH 2 ");
        if (18 <= hallcounter && hallcounter <= 29) { //EDIT HERE EXHAUST
        digitalWrite(11, LOW); // sets the digital pin 13 on
        }
        else {
        digitalWrite(11, HIGH);  // sets the digital pin 13 off
        }
     }
  lasthallstate = hallstate;
}

Here's the problem: the Hall sensor is connected to digital Pin 2 but when one magnet passes, instead of sending just one pulse it gives a random number of pulses (between 5 and 10), therefore adding way too much to the "hall counter".

Here is the model of Hall sensor I am using: https://www.amazon.fr/Magnétique-Linéaire-Compatible-Microcontrôleurs-Raspberry/dp/B09WN2HZBS/ref=sr_1_8?__mk_fr_FR=ÅMÅŽÕÑ&crid=3V5JE4FIHXWWA&keywords=capteur+effet+hall+arduino&qid=1675534680&sprefix=capteur+effet+hall+arduino%2Caps%2C71&sr=8-8

Is there any chance to solve the problem ? I just want to receive one pulse from the sensor, not 10 (it should behave like an all or nothing sensor).

Or I just should buy another type of Hall sensor ?

Thanks

1 Answers1

0

I figured it might be because of signal bouncing. Here's a version of the code without ISR, using a delay of 8 milliseconds to filter out the bounces:


const int hall = 2;
int hallcounter = 0;
int hallstate = 0;
int lasthallstate = 0;
unsigned int state;
int newstate;


void setup() {
  pinMode(hall, INPUT);
  Serial.begin(115200);
  pinMode(10, OUTPUT);    // sets the digital pin 10 as output
  pinMode(11, OUTPUT);    // sets the digital pin 11 as output
  digitalWrite(10, HIGH); //initialize relays at open
  digitalWrite(11, HIGH); //second relay
}


 void loop()
 {
   hallstate = digitalRead(hall);
   if (hallstate != lasthallstate) {
     if (hallstate == HIGH) {
       hallcounter ++;
       Serial.println(hallcounter);

     }
     delay(8);
   }
   lasthallstate=hallstate;

   if (hallcounter==29){
     Serial.println("RESET");
     hallcounter=0;
     state++;
   }
   if ((state%2)==0){
     //Serial.println("ETAT ADM 1");
     if (1 <= hallcounter && hallcounter <= 17){
       digitalWrite(10,LOW);
     }
     else{
       digitalWrite(10,HIGH);
     }
   }
   if ((state%2)==1){
     //Serial.println("ETAT ECH 2");
     if (18 <= hallcounter && hallcounter <= 27){
       digitalWrite(11,LOW);
     }
     else if (hallcounter == 28){
       digitalWrite(11,HIGH);
     }
   }

 }

The problem now is I can't run the engine with 30 magnets on the crankshaft: at 900 RPM, a delay of 8 ms of delay makes me lose almost 40 degrees of rotation on the crankshaft.