Sunday, December 18, 2011

Traction Control Part 1.1 - Monitoring Wheel Speed

The Atmega328 microprocessor at the heart of the Arduino is able to process 16 million operations per second.

The wheels or my test car running at full speed turn 68 times per second.

The Arduino is able to perform around a quarter of a million operations in the time it takes for my radio controller car wheel to rotate once.

Given these numbers I was confident of being able to monitor the speed of all four wheels, however I wasn't so sure of how to electronically sense the mechanical movement of the wheels. There are several challenges here -

1) I can't add anything to the wheel which upsets the balance, so no metal or magnets.
2) I have very little room to work with between the wheel and the wheel hub so have no option to add beam breakers to the wheel.
3) The front wheels need to turn freely in order to steer so I cannot impede their movement and cannot rely on a constant angle between the wheel and the sensor.

The solution I chose was to use pairs of infrared emitter and detector diodes.

  • Cheap
  • Easily Available
  • Non-invasive
  • Side facing design

The 'side facing design' means that the light is emitted and detected through the side of the diode, in our case this is an advantage as the diodes are very slim in profile and as the leads exit at the bottom this allows us to mount the diodes lying flat. The diodes are 2mm tall when mounted this way leaving around 10mm between the wheel hub and the wheel.

Most IR Sensor circuits rely on 'beam breaking' where an object passes between the emitter and the detector - breaking the beam. This is not an option in my case due to the small amount of space available and the amount of vibration present in the wheel and the hub.

One idea I had was to try sensing reflectance instead, to do this I initially set up a circuit with both the IR Emitter and Detector facing out from a prototype board. I then fixed a small strip of white tape to one of my tyres. At low speeds I was able to detect the white tape passing the in front of the sensors and count the revolutions per second. At this stage I was not concerned about higher speeds as the design was far from optimal.

The next step was to develop a package for the IR pair that could be mounted in the car between the wheel and the steering hub.


To do this I first trimmed the leads of the diodes and soldered on some flexible wire which I could later route around the car. I also used a layer of heat shrink to protect the wire joint from electrical shorts and mechanical wear.

Next I used double sided tape to mount the diodes to a square of styrene which I then glued to the wheel hub.



You should be able to spot the sensor mounted to the steering hub in the center of the picture below.


To ensure the best quality data I needed a sharp transition from reflecting to non-reflecting. To achieve this I sprayed the inside of the wheel satin black and then mounted a strip of 'bare metal foil'. This is an aluminum foil that has an adhesive on one side, its usually used for adding metal details to small 1/32 and 1/43 model cars and for this reason is exceptionally thin and therefore light enough not to upset the balance of the wheel.


On the other end of the sensor wires I soldered individual header pins allowing me to easily plug the sensors into my prototyping board.


Note that as I used a common ground wire for the two LEDs reducing my connetions from four to three.

I have made and mounted a set of sensors for both front wheels and now that I have proved the concept will eventually make sets for the rear wheels in order to monitor traction at all four corners.


Next up - connecting to the Arduino and writing the software, here is a preview -

21 comments:

  1. Hi,
    Were you able to measure speed at high RPM with this setup? I am trying to measure the RPM of the output shaft of a gasoline engine from a 1/5 scale RC vehicle.

    Also, where did you get the IR transmitter and receiver pair?

    ReplyDelete
  2. Hi,

    The speed at the wheels is geared down from the output shaft speed, but it should still be possible to measure the shaft RPM with IR.

    A better option than the sensor I use it the sensor that Spectrum include with their telemetry systems you can see it in this post -

    http://rcarduino.blogspot.com/2012/03/reading-from-rc-reveiver-do-you-need.html

    Duane B

    ReplyDelete
  3. The spectrum sensor is included specifically to read the output shaft RPM.

    Duane B

    ReplyDelete
  4. Hi, Thanks for the great write-up. I'd followed your suggestion to set up a reflectance sensor to monitor wheel speed on my RC car. As I couldn't find the exact transmitter / sensor pair you'd used, I used an out of the box reflectance sensor instead (http://www.vishay.com/docs/83760/tcrt5000.pdf).

    The problem I'm having is that I'm not getting reliable triggering of the Arduino interrupts when using this setup. In some cases, I don't get any interrupts when the reflective surface passes over the sensor. In other cases, I get many interrupts happening per single transition of the reflective surface (sometimes as many as 30).

    Have you had similar issues? If so, please tell me how you'd resolved them.

    ReplyDelete
  5. Something quick and easy to try is to test your sensor in a darkened room away from sunlight and indoor sources of infra red.

    Duane B

    ReplyDelete
    Replies
    1. Thanks for your suggestion. I tried that in a dark room, the measurements are slightly more accurate. However, on the odd occasion I'm still getting multiple interrupts per transition of the reflective surface. I'd written some code that outputs, once a second, the cumulative total number of interrupts read.

      As you can see from the extract of the output below, it jumps from 28 to 59 within a one second interval even though there was only a single pass of the reflective surface during that interval.

      I've tried both Aluminium foil and white paper as reflective surfaces. I'd also tried another sensor unit (just in case the initial one was faulty).

      I"m at a point where I'm thinking I may need to build one of those Arduino based oscilloscopes to test the waveforms output from the sensor.

      Any other suggestions you may have are welcome.

      Count: 23
      Count: 23
      Count: 23
      Count: 23
      Count: 24
      Count: 24
      Count: 25
      Count: 26
      Count: 27
      Count: 27
      Count: 27
      Count: 27
      Count: 28
      Count: 59
      Count: 59
      Count: 59
      Count: 59
      Count: 59

      Delete
  6. Hi,
    Couple of ideas -

    1) Is the 59 constant - that would indicate a code problem.

    2) If not, does the sensor datasheet recommend using any supporting components such capacitors or resistors ?

    Duane B

    ReplyDelete
    Replies
    1. Hi,

      Thanks for taking the time to help me troubleshoot.

      1) 59 is not a constant. In fact, the code for this is pretty simple. It just counts the interrupts caused by the falling wave. I've included the sketch at the bottom.

      2) I'd checked my circuit. It seems okay. The fact that gets the interrupt most of the time tells me it's probably not an issue. As per the recommended usage of the sensor, I've got a 47uF capacitor to smooth out the input voltage. I'm using a 10k pull down resistor at the signal measurement point.

      After having done some further research on the internet, I'm beginning to suspect that a reading bounce within a given state is causing this problem. Is it possible that interrupts may be caused when the signal bounces within a narrow range (say 4-5V)? Some people seemed to have used a Schmidt trigger to solve that issue. Did you have to do anything like that in your RC setup?



      int pbIn = 0; // Interrupt 0 is on DIGITAL PIN 2!
      int ledOut = 4; // The output LED pin
      volatile int state = LOW; // The input state toggle

      int count = 0;


      void setup()
      {
      // Set up the digital pin 2 to an Interrupt and Pin 4 to an Output
      pinMode(ledOut, OUTPUT);

      //Attach the interrupt to the input pin and monitor falling signal
      attachInterrupt(pbIn, stateChange, FALLING);

      Serial.begin(9600);


      }

      void loop()
      {

      delay(1000);

      Serial.print("Count: ");
      Serial.println(count);
      }

      void stateChange()
      {
      state = !state;
      count++;
      /* if (state == LOW){
      digitalWrite(ledOut, HIGH);
      }else{
      digitalWrite(ledOut, LOW);
      }
      */
      // Serial.println("Stage changed");
      }

      Delete
  7. Hi,
    What are you using to spin the wheel ? if its a brushed motor then its possibly outputting enough noise to trigger multiple interrupts around each transition (light to dark/dark to light). One simple way to deal with this would be to clear any pending interrupts on the current pin before you leave the ISR. I am not able to test this at the moment, but try EIFR = 0; as the last line of your interrupt service routine.

    PS Your code looks wrong, I assume its not the exact code you used ?

    Duane B

    ReplyDelete
  8. Hi,

    Sorry, I should have been more clear. The code I'd included above was to test the wheel speed sensor by itself. The idea is if I turn the wheel by hand x turns then the serial output should return x counts. Once, I'm happy with the operation of the sensor I was going to update the main controller code.

    As I'm manually turning the wheel, the motor noise is not a concern for the test code.

    As you'd suggested, I tried clearing the pending interrupts by setting EIFR = 0. However, I'm still getting the issue of multiple interrupts.

    I'm going to try and find the same side-facing IR emitter / detector paid and see if I have any luck.

    Thanks again for your suggestions.

    ReplyDelete
    Replies
    1. Hi,

      I've been able to make some progress on this.

      It seems the signal coming from the reflectance sensor is rather noisy. It's possible that some of the inadvertent interrupts I was experiencing were due to the noise. I was able to address this by creating a 'debounce' circuit using a Schmitt trigger. I got a much more consistent set of interrupts when I fed the output of the Schmitt trigger to the Arduino interrupt pin.

      You can see the difference in the signal outputs in the link below (captured using an Arduino based Oscilloscope).
      http://dl.dropbox.com/u/2906812/Reflectance%20Sensor.pdf

      Now, I've got to figure out a way to verify its operation at high RPM.

      Thanks for your help along the way.

      Delete
    2. Hi,
      I have put together, a schmitt trigger to use with a new way of mounting the sensors that I am testing - its working nicely.

      Good idea

      Thanks
      Duane B

      Delete
  9. Great, I will try to find some time to get my set up out for a spin this weekend. I have a few ideas for a better mounting system for the sensors which is where i have struggled. What car are you using ?

    Duane B

    ReplyDelete
  10. Hi,

    I plan to install the kit on my Traxxas Slash 2WD. For now, I'm using an inexpensive generic model RC car as a test bed. The space is very limited on the test bed for sensors, etc. Once I move on to the Slash I should have a lot more room to play with.

    The main aim of the project is to implement a touch based controller (I've written an Android app running on Nexus 7 for this). I'm also looking to display real-time telemetry information from the car on the tablet. Once this is done, I'm hoping to experiment with traction / braking / stability controls.

    ReplyDelete
  11. Hi,
    This is a nice project for a rear wheel drive car like the Slash. It has a big advantage off road in that it is self contained without the wiring mess of wheel sensors + off road muck -

    http://rcarduino.blogspot.com/2012/07/rcarduino-yaw-control-part-2.html

    For the traction control project, I am having another go at a better mounting solution for wheel speed sensors today.

    Will post if it works.

    Duane B

    ReplyDelete
  12. Hi,

    I have previously read your post on yaw control. I am quite interested in trying it on the Slash. In fact, I have already ordered the gyroscope and am awaiting delivery.

    I have now incorporated the wheel speed sensor into the main code base and am getting real-time speed being displayed on the Android device. On the whole it works well when the card is being driven forward (I'm in the process of debugging erroneous readings in reverse).

    Looking forward to your write up on the new mounting solution. Also, if you have any tips on how to securely mount the Arduino / electronics on a car that undergoes a lot of bumps / shocks, please post that as well.

    ReplyDelete
  13. I finally have a reliable set of wheel sensors mounted on all four wheels and interfaced to the Arduino. It shouldn't take long to get the traction control project finished now that the hardware is sorted.

    Duane B

    ReplyDelete
    Replies
    1. Hi,

      I've used your technique to measure the wheel speed of the car and wrote about it at http://yogibotics.blogspot.com.au.

      Thanks for your help in troubleshooting. I've acknowledged your help in my blog.

      Yogi

      Delete
  14. Nice article. I think it is useful and unique article. I love this kind of article and this kind of blog. I have enjoyed it very much. Thanks for your website.
    TLR Carbon wheels

    ReplyDelete
  15. Craig Willows-Keetley shares the story of his journey to compete in the half Ironman length Challenge event in Phuket. Craig shares his training program, details of the race and lessons he learnt from the event. Hear his story about the Challenge event that’s a Challenge and a half!.
    Carbon bike wheels

    ReplyDelete