IR Sensors Read, Compare, and Output Code?

Hi,

Totally new to the Arduino coding and microcontrollers in general but I am in charge of making the code for our Senior Project which is a traction control system based on IR sensors. We have a DC motor powered go-kart and everything works beautifully except we have to implement a traction control system.

Here is the summary of the system. The wheels have reflective plates which let the IR detector output of about 1.5V-1.6V to the Arduino UNO from 1-AA battery to each sensor. When they do not detect the plates, the voltage ranges anywhere from 0.2V-1.0V. We have a total of 3 sensors, one front right sensor, one front left sensor, and one rear sensor mounted on the shaft. What our traction control system is supposed to do is take a reading from each of the front sensors, get the absolute value difference of each and if it is more than 20% of the average of the two, turn on a signal which closes our circuit to enable our calibrated second potentiometer as throttle. If the front sensors are within range, the rear and front are compared in the same style and have the output sent out.

Now, I know my code probably has plenty of flaws and I am totally open to suggestions and I should probably be using some sort of frequency reading and comparing but I do not know how to use PulseIn() properly or any other frequency detection code. Again, this is my first time using this.

Our final submission is tomorrow so I do not have a lot of time and this is my last resort before saying "screw it".

Thanks in advance for anyone helping out! :slight_smile:

/*
PD Kart Traction Control System
Contains 3 IR Sensors which monitor wheel speed and
compared
*/

int FRS = A0;           //Front Right Sensor input to A0
int FLS = A1;           //Front Left Sensor input to A1
int RS = A2;            //Rear Sensor input to A2
int Traction = 9;      //Outputs 5V from Pin 9 to external circuit for amount of time given


void setup()
{
  analogReference(EXTERNAL);   //Reference voltage of 1.6V
  pinMode(Traction, OUTPUT);
  
}


void loop()
{
  int ReadFRS = analogRead(FRS);    //Reads analog input from A0
  int ReadFLS = analogRead(FLS);    //Reads analog input from A1
  int ReadRS = analogRead(RS);      //Reads analog input from A2
  
  int FrontAverage = (ReadFRS + ReadFLS)/2;           //Takes the average of A0 and A1 and puts it into variable FrontAverage
  int FrontCompare = abs(ReadFRS - ReadFLS);          //Takes the absolute difference betweem A0 and A1  
  int TotalCompare = abs(ReadRS - FrontAverage);      //Takes the absolute difference between FrontCompare and RearSensor
  
    if(FrontCompare >  0.2 * FrontAverage) 
   {
      digitalWrite(Traction, HIGH);
      delay(3000);
      digitalWrite(Traction, LOW);
   }
  
        else if(TotalCompare > 0.2 * (ReadRS + FrontAverage)/2) 
     {
        digitalWrite(Traction, HIGH);
        delay(3000);
        digitalWrite(Traction, LOW);
     }
  
  
}
/code]

...
Now, I know my code probably has plenty of flaws and I am totally open to suggestions and I should probably be using some sort of frequency reading and comparing but I do not know how to use PulseIn() properly or any other frequency detection code. Again, this is my first time using this.

Our final submission is tomorrow so I do not have a lot of time and this is my last resort before saying "screw it".

will you explain what hurdle you facing and Is it not working?

Cybernetician:
will you explain what hurdle you facing and Is it not working?

The issues we are having is that the output is constantly being turned on and it should only be on if any of the two front wheels are spinning less than the rear. In other words, if the input from FRS is a higher average than FLS, the pin should be on.

My worry is that most likely I would have to use some sort of frequency input read to have a better compare versus an instantaneous compare since the voltages would never match other wheels at any specific time when the readings are taken, they might but that is by chance.

Thanks for your reply!

First i haven't experience of something like that but i try my best to help you.

The issues we are having is that the output is constantly being turned on and it should only be on if any of the two front wheels are spinning less than the rear. In other words, if the input from FRS is a higher average than FLS, the pin should be on.

Lets start troubleshooting post the values of

ReadFRS
ReadFLS
ReadRS
FrontAverage
.
.
.

by using Serial.

Serial.prinln(ReadFRS);
Serial.prinln(ReadFLS);
Serial.prinln(ReadRS);
Serial.prinln(FrontAverage);
Serial.prinln(FrontCompare);
Serial.prinln(TotalCompare);

Cybernetician,

Thank you very much for your support, unfortunately, I am not at the shop where the kart is at, we called it a night and will continue tomorrow. If I get a chance, I will copy and paste what values we are getting. Thank you very much again for your efforts and if anything I can pick this up tomorrow morning.

I know I'm new to the site but is it possible that the code below.

int FrontCompare = abs(ReadFRS - ReadFLS)
or
int TotalCompare = abs(ReadRS - FrontAverage);

could result in a negative numbers and thus greatly changing the indifference in comparison.

I guess if you keep making left hand turns you should be ok for the FrontCompare. :wink:

I know I'm new to programming but I don't see anything in the sketch to count the wheel or shaft revolutions within a given amount time.

I'm thinking that most automotive ABS cycle something like every 200ms or less. Counting the inputs pulses with in a specific amount of time doing some math like you have above. Then determining if in fact the drive wheels are slipping. I'm thinking you have everything to make it work but you missing a bit of programming.

If your lucky maybe some programming guru will help your team pass you final for tomorrow. :wink:

could result in a negative numbers and thus greatly changing the indifference in comparison.

Difficult to see how the result of an abs operation could return a negative value, but I'm ready to be surprised.

Correct, I tried to use the PulseIn() code but I was not sure how to make it read for only a 1 second or less. My issue is reading in data from the sensors like a frequency or an array of voltages via analog input. I tired an array and it was just a mess and the code was all over the place since I am not familiar with arrays at all in any programming language.

As the code you posted is full of 3 second delays I can't see any chance of you geting it to work. You need to look at blink without delay

Mark

It's a great application for a Arduino.

I think if the inputs from FRS, FLS and RS are accumulated for 300ms or so and then cycled through the code and invert any negative equation result from (ReadFRS - ReadFLS) or (ReadRS - FrontAverage) it would work but I have no idea how to do it.

    if(FrontCompare >  0.2 * FrontAverage) 
   {
      digitalWrite(Traction, HIGH);
      delay(3000);
      digitalWrite(Traction, LOW);
   }
  
        else if(TotalCompare > 0.2 * (ReadRS + FrontAverage)/2) 
     {
        digitalWrite(Traction, HIGH);
        delay(3000);
        digitalWrite(Traction, LOW);
     }

Correct, I just don't know how to accumulate readings for 300ms and add them. I tried an array from the smoothing arduino reference guide and it was a mess working whenever it wanted.

How big are the wheels?
Or how many inputs per rotation of the wheel?
And are all the sensors have the same inputs per rotation including the rear?

I'll look around and see if I can find some counting sketch that could be applied to what ya have.

This may work
http://arduino.cc/forum/index.php/topic,39237.0.html

Thank you all for the replies! I will look into it a little later because we still have to clean and paint the final design and make a few reports. Thanks again for all who have contributed. Hopefully we get something that can work!