multiple hall sensors

First off, let me say that i have a total of about 10 hours of learning C++/ Arduino language (flipping back and forth between what code means what). I have a degree in Industrial Engineering (not electrical at all) and have programmed via ladder logic in college and work. I saw someone else's project like this and figured it was the best idea since sliced bread to take my competitiveness to the next level. they really didnt share any code or script so that left me with trying to figure everything out on my own. The script that I wrote below ultimately is taken from several other peoples scripts that I found online and adapted to fit. I do not have an arduino at this time (just ordered the Mega as I hope that this can also run a few other things in my race car such as dash, fire suppression system...).

This is my first post here and I know people always get sour if the post is in the wrong section. If that is so, I am sorry. I am just here to learn.

The idea of the program is very simple... in a way. I have 4 hall sensors, one on each wheel of the vehicle. They will detect a magnet attached to the backside of my disk brake and then change that into a RPM. That RPM will then be compared front to back as well as left to right in order to determine any differences in wheel speed aka loss of traction. It will be computed by river front / passenger front)*100) in order to get the percent difference between the two. This will then be compared to a Pot percentage. I will use the Pot to set my driving conditions. such as, when I am drag racing, I want to maintain as near 100% traction as possible since I am trying to apply max power to the ground vs. when I am warming up the tires and I need them to spin. or when driving in the rain, loss of traction could be considered 90%. All of this feeds into my if else statements resulting in the cutting of both fuel injector and spark to one cylinder per %5 of traction loss over required amount (100% required, 85% determined, 3 cylinders will be cut). The goal here is to make a traction control system for a drag / race car (non legal) that can be fine tuned by the driver. there is a lot more that needs to be adjusted in order to get it dialed in but I am hoping that I can start with the code that I have.

int rawValue;
int oldValue;
byte potPercentage;
byte oldPercentage;

// Hall sensor Code
int hallsensor = 2; // Hall sensor at pin 2 Driver front
int hallsensor = 3; // Hall sensor at pin 3 Passenger front
int hallsensor = 18; // Hall sensor at pin 18 Driver rear
int hallsensor = 19; // Hall sensor at pin 19 Passenger rear
volatile byte counter;
unsigned int rpm;
unsigned long passedtime;

int fdriverHall = 2; // Front driver set up
volatile byte counter fd;
unsigned int rpm fd;
unsigned long passedtime fd;

int fpassengerHall = 3; // Front passenger set up
volatile byte counter fp;
unsigned int rpm fp;
unsigned long passedtime fp;

int rdriverHall = 18; // Rear driver set up
volatile byte counter rd;
unsigned int rpm rd;
unsigned long passedtime rd;

int rpassengerHall = 19; // rear passenger setup
volatile byte counter rp;
unsigned int rpm rp;
unsigned long passedtime rp;

cylinder 1 = 4
cylinder 2 = 5
cylinder 3 = 6
cylinder 4 = 7
cylinder 5 = 8
cylinder 6 = 9
cylinder 7 = 10
cylinder 8 = 11

void setup() {
Serial.begin(115200); // set serial monitor to this value, or change the value

pinMode (A0, INPUT);   // set Pot pin A0 to input

// Cylinder control output setup
pinMode ( cylinder 1, OUTPUT); // pin mode cylinder 1
pinMode ( cylinder 2, OUTPUT); // pin mode cylinder 2
pinMode ( cylinder 3, OUTPUT); // pin mode cylinder 3
pinMode ( cylinder 4, OUTPUT); // pin mode cylinder 4
pinMode ( cylinder 5, OUTPUT); // pin mode cylinder 5
pinMode ( cylinder 6, OUTPUT); // pin mode cylinder 6
pinMode ( cylinder 7, OUTPUT); // pin mode cylinder 7
pinMode ( cylinder 8, OUTPUT); // pin mode cylinder 8

pinMode (fdriverHall, INPUT);  // Hall sensor Driver front input
attachInterrupt(fdriverHall, isr, RISING); //Interrupt for front driver Hall sensor
fdriver counter = 0;
fdriver rpm = 0;
fdriver passedtime = 0; //Initialise the values

pinMode (fpassengerHall, INPUT);  // Hall sensor Passenger front input
attachInterrupt(fpassengerHall, isr, RISING); //Interrupt for front passenger Hall sensor
fpassenger counter = 0;
fpassenger rpm = 0;
fpassenger passedtime = 0; //Initialise the values

pinMode (rdriverHall, INPUT); // Hall sensor Driver rear input
attachInterrupt(rdriverHall, isr, RISING); //Interrupt for rear driver Hall sensor
rdriver counter = 0;
rdriver rpm = 0;
rdriver passedtime = 0; //Initialise the values

pinMode (rpassengerHall, INPUT); // Hall sensor Passenger rear input
attachInterrupt(rpassengerHall, isr, RISING); //Interrupt for rear passenger Hall sensor
rpassenger counter = 0;
rpassenger rpm = 0;
rpassenger passedtime = 0; //Initialise the values

}

void loop() {

// front driver wheel RPM calculator
fdriver rpm = 60*1000/(millis() - fdriver passedtime)*fdriver counter;
fdriver passedtime = millis();
fdriver counter = 0;

// front passenger wheel RPM calculator
fpassenger rpm = 60*1000/(millis() - fpassenger passedtime)*fpassenger counter;
fpassenger passedtime = millis();
fpassenger counter = 0;

// rear driver wheel RPM calculator
rdriver rpm = 60*1000/(millis() - rdriver passedtime)*rdriver counter;
rdriver passedtime = millis();
rdriver counter = 0;

// rear passenger wheel RPM calculator
rpassenger rpm = 60*1000/(millis() - rpassenger passedtime)*rpassenger counter;
rpassenger passedtime = millis();
rpassenger counter = 0;


// pot code
// converts the position of a 10k lin(B) pot to 0-100%
// pot connected to A0, 5volt and ground
 rawValue = analogRead(A0);  // read input twice
 rawValue = analogRead(A0);  // ignore bad hop-on region of a pot by removing 8 values at both extremes
 rawValue = constrain(rawValue, 8, 1015); // add some deadband
 if (rawValue < (oldValue - 4) || rawValue > (oldValue + 4)) oldValue = rawValue; // convert to percentage
 potPercentage = map(oldValue, 8, 1008, 0, 100); // Only print if %value changes
 if (oldPercentage != potPercentage) oldPercentage = potPercentage;



// Math for calculating slip in wheel speed or loss of traction
// 5% loss of traction. I am hoping 5% will acount for rpm differance in wheel RPM while turning. If not, I can change it to 3 or higher... havent done the math on this yet.
if ((fdriver rpm/fpassenger rpm)*100) <= (potPercentage-5) || ((rdriver rpm/rpassenger rpm)*100) <= (potPercentage-5) || ((fdriver rpm/rdriver rpm)*100) <= (potPercentage-5) || ((fpassenger rpm/rpassenger rpm)*100) <= (potPercentage-5) digitalWrite (cylinder 1, LOW);
else digitalWrite (cylinder 1, HIGH); 

// 10% loss of traction below required or pot set
if ((fdriver rpm/fpassenger rpm)*100) <= (potPercentage-10) || ((rdriver rpm/rpassenger rpm)*100) <= (potPercentage-10) || ((fdriver rpm/rdriver rpm)*100) <= (potPercentage-10) || ((fpassenger rpm/rpassenger rpm)*100) <= (potPercentage-10) digitalWrite (cylinder 2, LOW);
else digitalWrite (cylinder 2, HIGH); 

// 15% loss of traction below required or pot set
if ((fdriver rpm/fpassenger rpm)*100) <= (potPercentage-15) || ((rdriver rpm/rpassenger rpm)*100) <= (potPercentage-15) || ((fdriver rpm/rdriver rpm)*100) <= (potPercentage-15) || ((fpassenger rpm/rpassenger rpm)*100) <= (potPercentage-15) digitalWrite (cylinder 3, LOW);
else digitalWrite (cylinder 3, HIGH);

// 20% loss of traction below required or pot set
if ((fdriver rpm/fpassenger rpm)*100) <= (potPercentage-20) || ((rdriver rpm/rpassenger rpm)*100) <= (potPercentage-20) || ((fdriver rpm/rdriver rpm)*100) <= (potPercentage-20) || ((fpassenger rpm/rpassenger rpm)*100) <= (potPercentage-20) digitalWrite (cylinder 4, LOW);
else digitalWrite (cylinder 4, HIGH);

// 25% loss of traction below required or pot set
if ((fdriver rpm/fpassenger rpm)*100) <= (potPercentage-25) || ((rdriver rpm/rpassenger rpm)*100) <= (potPercentage-25) || ((fdriver rpm/rdriver rpm)*100) <= (potPercentage-25) || ((fpassenger rpm/rpassenger rpm)*100) <= (potPercentage-25) digitalWrite (cylinder 5, LOW);
else digitalWrite (cylinder 5, HIGH);

// 30% loss of traction below required or pot set
if ((fdriver rpm/fpassenger rpm)*100) <= (potPercentage-30) || ((rdriver rpm/rpassenger rpm)*100) <= (potPercentage-30) || ((fdriver rpm/rdriver rpm)*100) <= (potPercentage-30) || ((fpassenger rpm/rpassenger rpm)*100) <= (potPercentage-30) digitalWrite (cylinder 5, LOW);
else digitalWrite (cylinder 5, HIGH);

}

welcome!

First off, thanks for putting your code inside tags!

Second, I looked at your code and it appears you need to learn a bit more C programming since the code won't compile, as-is. A couple of hints to get you going...

You can't have multiple definitions of the same variable 'hallsensor'. A beginner might use something like hallsensor1, hallsensor2, etc. or a better way would be to use an array like hallsensors[4] (if you are comfortable with that).

All your 'cylinder' variables need to have a type and you can't have spaces in the name so these should all be:
int cylinder1 = 4;
int cylinder2 = 5;
etc.

or again, use an array
int cylinders[8] = [ 4,5,6,7,8,9,10,11 ];

Probably the biggest issue with your code is that you can't just duplicate your interrupt code for all 4 hall sensors. The arduino Mega only hase certain pins that allow external interrups. Check out this link:

Good luck!

I just figured out how to do the verify function within arduino so that should hopefully help me locate issues.

After I posted the script, I noticed that I screwed up the hall sensor naming. I should get that fixed with a little ease.

I didnt even notice the spaces within the cylinder naming, thanks for pointing that out. It has been fixed.

As per the interrupts, I am using pins 2,3,18,19 (at least i am trying to). shouldn't this allow me to use the interrupt function in order to ensure that I am getting the correct signal.

BTW, I have calculated each wheel to turn at approximately 800 RPM while going 70 or 13 rev/sec with 4 wheels turning I will be sensing 52 revolutions per sec which should be easy for the arduino mega. I do plan on using the mega however since I will eventually use this almost as a body control module.

With the interrupts, make sure you are correctly mapping your pins to the actual interrupt numbers

attachInterrupt(digitalPinToInterrupt(pin), ISR, mode);

so you code would look something like this:

attachInterrupt(fdriverHall1, isr1, RISING);
attachInterrupt(fdriverHall2, isr2, RISING);
attachInterrupt(fdriverHall3, isr3, RISING);
attachInterrupt(fdriverHall4, isr4, RISING);

I think this is a little closer. I should have fixed the stuff that yall mentioned. I still do not have my arduino (its in the mail). As soon as its in, I will start working though tutorials and learning more so i can hopefully finish this.

int rawValue;
int oldValue;
byte potPercentage;
byte oldPercentage;

// Hall sensor Code
int fdriverHall = 2; // Front driver set up
volatile byte fdriver counter;
unsigned int fdriver rpm;
unsigned long fdriver passedtime;

int fpassengerHall = 3; // Front passenger set up
volatile byte fpassenger counter;
unsigned int fpassenger rpm;
unsigned long fpassenger passedtime;

int rdriverHall = 18; // Rear driver set up
volatile byte rdriver counter;
unsigned int rdriver rpm;
unsigned long rdriver passedtime;

int rpassengerHall = 19; // rear passenger setup
volatile byte rpassenger counter;
unsigned int rpassenger rpm;
unsigned long rpassenger passedtime;

cylinder1 = 4
cylinder2 = 5
cylinder3 = 6
cylinder4 = 7
cylinder5 = 8
cylinder6 = 9
cylinder7 = 10
cylinder8 = 11

void setup() {
Serial.begin(115200); // set serial monitor to this value, or change the value

pinMode (A0, INPUT);   // set Pot pin A0 to input

// Cylinder control output setup
pinMode ( cylinder 1, OUTPUT); // pin mode cylinder 1
pinMode ( cylinder 2, OUTPUT); // pin mode cylinder 2
pinMode ( cylinder 3, OUTPUT); // pin mode cylinder 3
pinMode ( cylinder 4, OUTPUT); // pin mode cylinder 4
pinMode ( cylinder 5, OUTPUT); // pin mode cylinder 5
pinMode ( cylinder 6, OUTPUT); // pin mode cylinder 6
pinMode ( cylinder 7, OUTPUT); // pin mode cylinder 7
pinMode ( cylinder 8, OUTPUT); // pin mode cylinder 8

pinMode (fdriverHall, INPUT);  // Hall sensor Driver front input
attachInterrupt(fdriverHall, isr, RISING); //Interrupt for front driver Hall sensor
fdriver counter = 0;
fdriver rpm = 0;
fdriver passedtime = 0; //Initialise the values

pinMode (fpassengerHall, INPUT);  // Hall sensor Passenger front input
attachInterrupt(fpassengerHall, isr, RISING); //Interrupt for front passenger Hall sensor
fpassenger counter = 0;
fpassenger rpm = 0;
fpassenger passedtime = 0; //Initialise the values

pinMode (rdriverHall, INPUT); // Hall sensor Driver rear input
attachInterrupt(rdriverHall, isr, RISING); //Interrupt for rear driver Hall sensor
rdriver counter = 0;
rdriver rpm = 0;
rdriver passedtime = 0; //Initialise the values

pinMode (rpassengerHall, INPUT); // Hall sensor Passenger rear input
attachInterrupt(rpassengerHall, isr, RISING); //Interrupt for rear passenger Hall sensor
rpassenger counter = 0;
rpassenger rpm = 0;
rpassenger passedtime = 0; //Initialise the values

}

void loop() {

// front driver wheel RPM calculator
fdriver rpm = 60*1000/(millis() - fdriver passedtime)*fdriver counter;
fdriver passedtime = millis();
fdriver counter = 0;

// front passenger wheel RPM calculator
fpassenger rpm = 60*1000/(millis() - fpassenger passedtime)*fpassenger counter;
fpassenger passedtime = millis();
fpassenger counter = 0;

// rear driver wheel RPM calculator
rdriver rpm = 60*1000/(millis() - rdriver passedtime)*rdriver counter;
rdriver passedtime = millis();
rdriver counter = 0;

// rear passenger wheel RPM calculator
rpassenger rpm = 60*1000/(millis() - rpassenger passedtime)*rpassenger counter;
rpassenger passedtime = millis();
rpassenger counter = 0;


// pot code
// converts the position of a 10k lin(B) pot to 0-100%
// pot connected to A0, 5volt and ground
 rawValue = analogRead(A0);  // read input twice
 rawValue = analogRead(A0);  // ignore bad hop-on region of a pot by removing 8 values at both extremes
 rawValue = constrain(rawValue, 8, 1015); // add some deadband
 if (rawValue < (oldValue - 4) || rawValue > (oldValue + 4)) oldValue = rawValue; // convert to percentage
 potPercentage = map(oldValue, 8, 1008, 0, 100); // Only print if %value changes
 if (oldPercentage != potPercentage) oldPercentage = potPercentage;



// Math for calculating slip in wheel speed or loss of traction
// 5% loss of traction. I am hoping 5% will acount for rpm differance in wheel RPM while turning. If not, I can change it to 3 or higher... havent done the math on this yet.
if (((fdriver rpm/fpassenger rpm)*100) <= (potPercentage-5) || ((rdriver rpm/rpassenger rpm)*100) <= (potPercentage-5) || ((fdriver rpm/rdriver rpm)*100) <= (potPercentage-5) || ((fpassenger rpm/rpassenger rpm)*100) <= (potPercentage-5)) digitalWrite (cylinder1, LOW);
else digitalWrite (cylinder1, HIGH); 

// 10% loss of traction below required or pot set
if (((fdriver rpm/fpassenger rpm)*100) <= (potPercentage-10) || ((rdriver rpm/rpassenger rpm)*100) <= (potPercentage-10) || ((fdriver rpm/rdriver rpm)*100) <= (potPercentage-10) || ((fpassenger rpm/rpassenger rpm)*100) <= (potPercentage-10)) digitalWrite (cylinder2, LOW);
else digitalWrite (cylinder2, HIGH); 

// 15% loss of traction below required or pot set
if (((fdriver rpm/fpassenger rpm)*100) <= (potPercentage-15) || ((rdriver rpm/rpassenger rpm)*100) <= (potPercentage-15) || ((fdriver rpm/rdriver rpm)*100) <= (potPercentage-15) || ((fpassenger rpm/rpassenger rpm)*100) <= (potPercentage-15)) digitalWrite (cylinder3, LOW);
else digitalWrite (cylinder3, HIGH);

// 20% loss of traction below required or pot set
if (((fdriver rpm/fpassenger rpm)*100) <= (potPercentage-20) || ((rdriver rpm/rpassenger rpm)*100) <= (potPercentage-20) || ((fdriver rpm/rdriver rpm)*100) <= (potPercentage-20) || ((fpassenger rpm/rpassenger rpm)*100) <= (potPercentage-20)) digitalWrite (cylinder4, LOW);
else digitalWrite (cylinder4, HIGH);

// 25% loss of traction below required or pot set
if (((fdriver rpm/fpassenger rpm)*100) <= (potPercentage-25) || ((rdriver rpm/rpassenger rpm)*100) <= (potPercentage-25) || ((fdriver rpm/rdriver rpm)*100) <= (potPercentage-25) || ((fpassenger rpm/rpassenger rpm)*100) <= (potPercentage-25)) digitalWrite (cylinder5, LOW);
else digitalWrite (cylinder5, HIGH);

// 30% loss of traction below required or pot set
if (((fdriver rpm/fpassenger rpm)*100) <= (potPercentage-30) || ((rdriver rpm/rpassenger rpm)*100) <= (potPercentage-30) || ((fdriver rpm/rdriver rpm)*100) <= (potPercentage-30) || ((fpassenger rpm/rpassenger rpm)*100) <= (potPercentage-30)) digitalWrite (cylinder 5, LOW);
else digitalWrite (cylinder 5, HIGH);
volatile byte fdriver counter;

Did that even compile?

unsigned int fdriver rpm;
unsigned long fdriver passedtime;

Or that?

volatile byte rdriver counter;
unsigned int rdriver rpm;
unsigned long rdriver passedtime;

Or that?

It did not. If it did, I wouldn't be posting here. I'm still trying to figure out what everything means googling one thing at a time.

Hi,
Can I suggest you start from scratch and get ONE Hall Effect Sensor working, before trying to get all 4?

Start with a blank code and build up just for ONE Hall device.
Forget for the moment about output control.
One you get code for one device working, then add another and get it working, then the third working and the fourth.
Use Serial Monitor to help debug.

Once you have the RPM working , then look at your algorithm for detecting RPM differences.
Only attempt the next stage after getting the previous working.
It will keep your bugs to a minimum.

Can you please post a copy of your circuit for ONE Hall device, in CAD or a picture of a hand drawn circuit in jpg, png?

Tom... :slight_smile: