Showing posts with label Data Logging. Show all posts
Showing posts with label Data Logging. Show all posts

Friday, May 11, 2012

Lap Timer Preview

Video 1 - Lap Review Mode

A quick tour through part of the menu system. Session summaries with best and average lap times, select a session to review the laps within the session.



Its very simple interface, ok to enter a mode, cancel to exit a mode and up/down to cycle through any options in a mode.

Video 2 - Daylight Laps




One of the challenges with using infra red for lap timing is that daylight will easily saturate the detectors rending them useless. My solution to this is to enclose the detector in a shade however even this isn't enough. To get reliable lap detection with no false laps I have painted the inside of the detector enclosure with 'ultra flat' paint.

The particular paint I have used is manufactured by Krylon and is targeted at hunters, paintballers and airsoft players that want maximum camouflage with no reflection from their equipment. The ability of this paint to suppress reflection stops any daylight from getting to the back of the enclosure. The only light that can reach the detector at the back of the enclosure is light directed directly at it, the light from a lapping car.



Test Car

Tamiya M03 Mini fitted with a Tamiya Sport Tuned motor and good for around 40Km/h.

The lap timer should be good for full size race car speeds, I plan to test at 120Km/h in the next day or two using my daily driver and a long stretch of empty road.

For race car and Kart speeds I will see who I can persuade to test the system at the Dubai Autodrome.


Inside The Lap Timer

Keeping the cost down.

A standalone Arduino, an LCD screen and not too much else.

Small enough to fit to the steering wheel of a Kart.









More soon...

Duane B



Friday, January 20, 2012

How To Read an RC Receiver With A Microcontroller - Part 2

If you read 'How To Read an RC Receiver With A Microcontroller - Part 1' you will probably have guessed that my approach is based around interrupts, you may even be thinking 'So what, there is nothing new in any of this'.

Your right on the first part, but writing the code to take control of the throttle signal on my 40Km/h RC Race car was a very long way from reading a signal and writing it to the serial port.

What Could Possibly Go Wrong ?

The real world quickly gets in the way - underground cables, vibration, noise from the RC Components in the car, mobile phone transmitters, the built up environment, low transmitter batteries, even passing traffic effects the signal.

During the design and test of the code, I had two hardware problems with a dry solder joint on the power capacitor attached to the electronic speed controller and a track on my low quality strip board which crumbled away. At the time I was not aware that these hardware issues were the cause and so I investigated every conceivable cause of interference.


Power Capacitor Soldered to ESC Power Terminals
Strip board track repaired after crumbling away!


One simple test repeated since the hardware issues were resolved involved propping the RC Car wheels off the ground and then walking away from the car with the transmitter. I repeated this many times, increasing the distance or changing the line of sight to include/exclude features in the built up environment. I was very surprised to see just how badly the signal degrades as you move the transmitter away from the car.



Transmitter and Receiver Adjacent To Each Other

Transmitter and Receiver 20 Meters Apart.



The charts show the pulse width variation over time with the transmitter set at a constant neutral signal. A straight line would indicate there is no variation in the pulse width, this is the result we might initially expect.

The two charts are generated using the code presented in the preceding post 'How To Read an RC Receiver With A Microcontroller - Part 1'


To create the charts, the serial output was cut and paste into Microsoft Excel.

The charts clearly show that as the distance between the transmitter and receiver increases, so the variation in the signal increases. My tests have shown that the built up environment has an additional effect, further compounding the effects of distance.


With no controller input and the transmitter positioned just 20 meters away, the signal output by the receiver would randomly wander by as much as 30 milliseconds either side of the transmitter signal. Some of this would be due to the built up environment, moving the transmitter to a position occluded by a steel reinforced concrete pillar would cause chaos in the servo at only 20 meters.

So this isn't going to work is it ?

Not only does it work, but it works brilliantly. The best thing I can say about using the Arduino to control the throttle signal is that you can't tell its there.

The first few times I drove the current version of the software I kept having to bring the car back in to check that I hadn't shorted something and bypassed the Arduino completely.

So how does it work ?

First of all the mechanical nature of the servos and motors in our equipment provides a certain amount of signal smoothing, put simply, they just cannot move fast enough to react to the variation in the signal and so their position at any point in time reflects an average value of the signal in the preceding milli seconds.

Sample signal variation over 1 second - a random walk around the value 1540 - the value output by the transmitter.


In addition to the smoothing provided by the mechanical nature of the car, I have included a 'confidence' algorithm in the code. This algorithm compares the current input to the previous output, if the variation is small it ranks the new signal with a low value, if the variation is larger, the signal scores a higher degree of confidence. If the signal returns to its original value the confidence is reset to zero. The basic concept is that if we receive a vastly different signal, the chances are that its a new command from the driver, but if we receive a series of wandering signals they can generally be ignored provided that they do not creep in one direction which would indicate a subtle but valid input from the driver.


// Confidence Version 2, smaller, better, faster ?

int nDifference = nThrottleIn - nThrottleOut;

 if(nDifference == 0)
 {
    nConfidence = 0;
 }
 else
 {
   nConfidence += (nDifference/4);
 }
  
 if((nConfidence >= SENSITIVITY) || (nConfidence <= -SENSITIVITY)) // SENSITIVITY = 8
 {
   nConfidence = 0;
  
   // do something with this pulse ....
 }



I am currently open minded as to the value of the confidence algorithm. Standard RC Equipment works well enough without the addition of this algorithm, however it is at a cost of battery drain, heat and mechanical wear. The real value of the algorithm in a mircocontroller environment is potentially in providing a lightweight, easily tuned mechanism to condition the signal for input into subsequent algorithms without introducing the lag that results from smoothing across multiple samples.

The following charts show a badly degraded signal before and after the simple confidence algorithm -

Signal Before Algorithm


Signal After Algorithm


In the charts above, the confidence algorithm clearly smooths a large amount of the signal noise, however it is too sensitive to cope with the extremes.

One feature of the algorithm is that the sensitivity can be easily changed through a single variable. 

Test Conditions 
The tests were performed with the transmitter and receiver at opposite ends of a steel reinforced concrete villa  -

The line of sight was occluded by at least two walls
The receiver was adjacent to and transmitting serial data to a laptop. 
The line of sight included an LCD TV and a kitchen appliance.

The reinforced walls, LCD TV and Kitchen Appliance have all been observed to cause a large degree of interference to RC equipment and signals. 

Ideally the tests should be repeated with a higher value sensitivity however the test conditions are extreme and do not provide any qualification of the algorithms real world usefulness.

At present the algorithm has very little performance impact and clearly removes some noise, however before the algorithm can be qualified into or out of the RC Arduino projects it will need to be tested in the two most common RC Applications -

1) Racing - This is a tough environment with multiple transmitters sharing a fairly narrow physical and electro magnetic space. 
2) Street Driving - This has its own challenges in the form of distorted signals reflecting from the build up environment.

In use to date, the confidence algorithm has no detrimental effect so it stays 'in' with one small change - 'Sensitivity' actually has the opposite effect and should really be renamed 'Damping' to reflect it effect on the signal variation.

Next up - Bad Pulses And What To Do With Them

How To Read an RC Receiver With A Microcontroller - Part 1

Its a very common question, 'How do I read an RC Receiver with my micro controller' and the answer is often very simple however the simple answer is close to useless in a real world application.

The approach outlined in this series of posts has been tested in an RC Race car running at 40+ Kmh at a range of 100 meters.

The approach is reliable, resilient, easy to understand and easy to modify. It has been tested using using 27Mhz AM radio equipment and entry level electronics. Use of better quality electronics and radio equipment will provide improvements in range and signal quality however as the development process has demonstrated, even low end equipment can be interfaced with Arduino for control of an RC Race car.

Update 05/11/12 Read multiple RC channels with a smoother, faster library -
http://rcarduino.blogspot.com/2012/11/how-to-read-rc-channels-rcarduinofastlib.html
For the background to this and the original sketch before optimisation see - 
http://rcarduino.blogspot.com/2012/04/how-to-read-multiple-rc-channels-draft.html


Update 04/11/12 - For those of you looking to read a PPM Stream instead of individual channels, I will have a small fast library up this week - will post an update with the link here -
http://rcarduino.blogspot.ae/2012/11/how-to-read-rc-receiver-ppm-stream.html


Background Information

What are we looking for when we read from an RC Receiver ? Its not what I originally expected, my guess was that it was an analogue signal that would be amplified by the speed controller or servo controller to drive the motors. Its not analogue at all, its actually mostly empty space.

Each channel decoded by your receiver is sent to your ESCs and Servos as a train of pulses, these pulses are sent about 50 times a second but the suprising part is, each pulse only lasts between one and two milliseconds (1/1000 to 2/1000 of a second). Before the next pulse arrives, there is a gap of 10 times the length of the even longest pulse.

In an Electric RC Car a pulse width of 1000 is full reverse or brake, a pulse width of 2000 is full throttle and a pulse of 1500 is neutral. Note that these may be reversed, but the nature and range of the signal does not change.

This pulse train as it comes from the receiver could not be used to drive anything, not even a toy motor. The ESC or Servo control circuitry takes the pulse train as an input and generates a very different output, not just in power, but also in profile and even polarity in the case of reversing a motor.


The Simple Approach and Why Its Wrong

A common suggestion is to connect the receiver to the microcontroler such that there is a common ground (GND) between the two devices and then attach the white or orange signal wire from the receiver to one of the digital input microcontroller pins.

From here there are a variety of approaches to reading the values from the pins -

PulseIn (a blocking polling approach)

PulseIn is a function available with the Arduino that implements an approach know as 'poling'. It essentially sits around waiting for something to happen, until something happens the rest of your code is blocked. This is okay for a simple lab exercise to read and print values from a receiver but it is a hopeless approach for a real world application. Fortunately there are better approaches that do not require a major learning curve.

Timers

There is an example in the Arduino Playground which uses timers ReadReceiver. It may offer greater resolution than the method I am using, but it is also considerably more complicated and as I will show in a follow up post, the source receiver signal degrades rapidly as you move outside the lab rendering the increased accuracy less valuable.

Interrupts

The Timer example and my own approach both use Interrupts. Interrupts allow you to declare your interest in an event and then have the micro controller 'interrupt' your code whenever the event occurs.

Lets take a closer look at the channel signal and determine which bits we should be interested in -



If all we are interested in is the pulse duration, why not use pulseIn ? after all there is nothing else of interest in the signal.

The Arduino UNO is able to perform 16 million operations in one second. In the 2 milli second duration of a full throttle pulse, the Arduino could have performed 32,000 operations ! Thats a lot of wasted power. But it gets worse, what if you call pulseIn immediately after a pulse, you will have to wait a whole 20 milliseconds for the next pulse to arrive and complete. Thats a full 320,000 operations useful operations your code could have completed.

On average you can expect to call pulseIn in the center between two pulses, this means that over an extended period, half or your available processing power is wasted just waiting for the next pulse to arrive and complete. If you add more inputs, the approach becomes quickly unsustainable as you can only give your attention to a single input at a time.

Don't Use Pulse In !

Here are some updates showing the code in action - 

Active Yaw Control Of An RC Race Car
http://rcarduino.blogspot.com/2012/07/rcarduino-yaw-control-part-2.html 

Mapping RC Car Controls To A  Tank Tracked Robot
http://rcarduino.blogspot.com/2012/05/interfacing-rc-channels-to-l293d-motor.html 


Using an interrupt to efficiently detect new pulses and output to serial

For reading multiple RC Channels see - 

http://rcarduino.blogspot.co.uk/2012/04/how-to-read-multiple-rc-channels-draft.html


// First Example in a series of posts illustrating reading an RC Receiver with
// micro controller interrupts.
//
// Subsequent posts will provide enhancements required for real world operation
// in high speed applications with multiple inputs.
//
// http://rcarduino.blogspot.com/
//
// Posts in the series will be titled - How To Read an RC Receiver With A Microcontroller

// See also http://rcarduino.blogspot.co.uk/2012/04/how-to-read-multiple-rc-channels-draft.html 

#define THROTTLE_SIGNAL_IN 0 // INTERRUPT 0 = DIGITAL PIN 2 - use the interrupt number in attachInterrupt
#define THROTTLE_SIGNAL_IN_PIN 2 // INTERRUPT 0 = DIGITAL PIN 2 - use the PIN number in digitalRead

#define NEUTRAL_THROTTLE 1500 // this is the duration in microseconds of neutral throttle on an electric RC Car

volatile int nThrottleIn = NEUTRAL_THROTTLE; // volatile, we set this in the Interrupt and read it in loop so it must be declared volatile
volatile unsigned long ulStartPeriod = 0; // set in the interrupt
volatile boolean bNewThrottleSignal = false; // set in the interrupt and read in the loop
// we could use nThrottleIn = 0 in loop instead of a separate variable, but using bNewThrottleSignal to indicate we have a new signal
// is clearer for this first example

void setup()
{
  // tell the Arduino we want the function calcInput to be called whenever INT0 (digital pin 2) changes from HIGH to LOW or LOW to HIGH
  // catching these changes will allow us to calculate how long the input pulse is
  attachInterrupt(THROTTLE_SIGNAL_IN,calcInput,CHANGE);

  Serial.begin(9600);
}

void loop()
{
 // if a new throttle signal has been measured, lets print the value to serial, if not our code could carry on with some other processing
 if(bNewThrottleSignal)
 {

   Serial.println(nThrottleIn); 

   // set this back to false when we have finished
   // with nThrottleIn, while true, calcInput will not update
   // nThrottleIn
   bNewThrottleSignal = false;
 }

 // other processing ...
}

void calcInput()
{
  // if the pin is high, its the start of an interrupt
  if(digitalRead(THROTTLE_SIGNAL_IN_PIN) == HIGH)
  {
    // get the time using micros - when our code gets really busy this will become inaccurate, but for the current application its
    // easy to understand and works very well
    ulStartPeriod = micros();
  }
  else
  {
    // if the pin is low, its the falling edge of the pulse so now we can calculate the pulse duration by subtracting the
    // start time ulStartPeriod from the current time returned by micros()
    if(ulStartPeriod && (bNewThrottleSignal == false))
    {
      nThrottleIn = (int)(micros() - ulStartPeriod);
      ulStartPeriod = 0;

      // tell loop we have a new signal on the throttle channel
      // we will not update nThrottleIn until loop sets
      // bNewThrottleSignal back to false
      bNewThrottleSignal = true;
    }
  }
}



Next up - Part 2 including what does the signal really look like ? and more of the code to deal with it.

For reading multiple channels using an interrupt driven technique see -

http://rcarduino.blogspot.co.uk/2012/04/how-to-read-multiple-rc-channels-draft.html

Monday, December 26, 2011

Spice Vs M-Grips



M-Grips (blue) for the win in this case. I would have expected the Spice tyres to show the highest G's but it was early morning so the spice would be struggling to get up to temperature.

Sunday, December 25, 2011

Data Logging Part 3 - Data Logged !!!

I have finally logged some data to the SD Card. To make life super easy I am logging the data is CSV format, this is a very simple text based format that can be imported by any spreadsheet application, in my case I am using Excel. The charts are simply generated by selecting the data and clicking the Excel chart icon.

The first test - Figure of 8 and Max Acceleration, Max Braking.

This first chart plots the X,Y,Z Axis as red, orange, pink. I would not have expected to see much movement in the Z axis as the car is running on reasonably flat tarmac however I am running smaller tyres than normal and so the car is dragging on the road where I haven't yet raised the suspension to compensate. Bumping along small stones is one possible cause for the movement in the Z Axis. For the remaining charts I have removed the Z - Axis so that we can see whats happening in the X and Y Axis (lateral G-Force and acceleration/braking).


I am quite pleased with the data here. For the first half of the test I was driving in a steady figure of 8, you can see this in the graph where on the left side the pink (acceleration/braking) line is steady and the lateral G-Forces swing from positive to negative as the car corners to the left and then to the right.

For the second half of the test I changed to accelerating and braking, again this shows up clearly as the pink line now moves from the positive to the negative, accelerating to braking. Interestingly you can see that the M03 is able to brake much harder that it can accelerate - pretty much what you would expect but its nice to see it captured consistently. I can also see from the red line that at the end of my acceleration and braking runs I always turned to the right to start the next run. The final point of interest is that the test strip was on a slope, and you can see this in the acceleration and braking runs where the peak G-Force under braking is higher on the first and third runs (uphill) than on the second and fourth runs (downhill).


Scatter Graph
This last graph plots each data point on an X and Y Axis, with more data it should provide a reasonable representation of the traction circle.

Again you can see that I spent more time turning left and that the brake force was about 50% higher than the acceleration.
Thats the easy bit finished. Now I need to develop a test protocol to confirm the quality of the test data. I also need to run some tests comparing spinout data with controlled high speed cornering, its pretty useless data if spinouts can't be determined from successfully negotiated high speed corners.

Thursday, December 22, 2011

Data Logging Part 2 - A User Interface

My first attempt at a micro controller user interface -
I am pretty happy with it, its a thousand times better than the horrible interfaces you get on your average Electronic Speed Controller. Take the example of a Tamiya TEU104BK, the user interface consists of a single 1*2 mm grey button hidden in a 4mm recess in the case. The button and indicator light are in highlighted area in the pic below, a 10mm push button is included for size comparison.


While I have used a great big bright red 10mm push button, I haven't completely broken away from tradition, the interface still relies on the users ability to count and interpret a sequence of flashing lights. The reason for this is that mirco controllers provide a limited number of inputs and outputs. Each of these inputs/outputs can be extremely powerful so using them up with indicators, displays and multiple push buttons is an unacceptable waste of resources.

The data logger user interface


1 Big Red 10mm Push Button
1 Bright Red LED to signal 'Recording'
1 Bright Green LED to signal 'Sending recorded data over the serial interface'

The system has 5 states -

StateMeaningRecord IndicatorSerial Indicator
IdleNot currently doing anythingBrief flash every 2 secondsAs Record
RecordRecording Data to SD CardOnOff
SerialReading SD Data and writing to serialOffOn
Memory FullNo more data can be recordedOn 1 Second/Off 1 SecondAs Record
ErrorSomething is wrongRapid Alternate with SerialRapid Alternate with Record


To move between states the push button must be held for 1 second or more. To enter record from idle 1 Second, to enter Serial from idle 4 Seconds, to exit either record or idle 1 second.

All I need now is a Micro SD Card and the data logger is up and running.

Monday, December 19, 2011

Data Logging Part 1 - Acceleration

Its so easy to build circuits and programs with the Arduino that I have a few projects progressing side by side on the same hardware. In this project I intent to record performance data on board my RC Racer then upload the data for analysis on the PC. Something which I see as very simple but very useful is the ability to record and visualise the traction circle for different setups. For my purposes the traction circle will be plotted from the X and Y G-forces acting on my car, to sense and record these forces I am using an ADXL335 3-Axis Accelerometer and a Micro SD Card. Both of these are available on easy to use 'breakout' boards that can be plugged directly into the Arduino UNO.
The two plots above are produced from live data coming from the Arduino into my PC, I am using 'Processing' to display the results. The screen area represents +-1G in the X and Y Axis, Z is not plotted. The first plot is generated with the board flat on the table. The second plot is the result of me tapping the side of the table to generate some movement in the X-Axis, then tapping the front of the table to get some action on the Y-Axis, but the really interesting plot is the next one -

Here I have used the constant 1G acceleration provided by good old fashioned gravity. By tilting the board from one side to the other I can use gravity to apply 1G of acceleration to the left and then the right. You can see the result of this in the lines running right, up and down from the center. The diagonal line running from the center to the top right is the result of me trying to 'draw' the line by progressivley tilting the board and letting gravity do the work. This was surprisingly difficult, it had that addictive quality that the simplest of games have - something thats quick and easy to understand, takes a while to master and can always be improved upon. I can think up a dozen gaming applications for this - for example physical tetris where you actually have to rotate the controller to rotate the tiles and then swing the control to the left or right to position tiles. Another application would be target based sports simulations, the sensor is sensitive enough to pick up hand tremors.

Getting back to the main purpose of this project, the left side of the screen shows a sample of a traction circle I have generated by rotating the board which is sensing the constant 1G force of gravity over a range of angles. In practice most of the plot points would be toward the center of the screen but this provides a quick bench test and proof of concept. The sensor I am using can sense up to 3G, and also records the z-axis which I am recording but not currently plotting. I have no idea what to expect in the car, probably less than 1G but will get some plots up with different tyres in the next day or so - I know that racing tyres are worth every penny compared to stock tyres and soon I will be able to prove it !

Tuesday, December 6, 2011

What can I do with an RC Car and Arduino ?

One of the strengths of the Arduino is the ease with which it can be interfaced with inputs (sensors) and outputs (motors, servos, LEDs, speakers etc, etc, etc)

In the coming weeks I hope to be able to build the following radio controlled car based projects

1) G-Force Logging - use an accelerometer connected to the Arduino to measure acceleration and deceleration and log this data to an SD Card.

2) Traction Alarm - use infra red sensors to measure the speed of the wheels and sound an alarm or flash a visual signal whenever the speed of one wheel exceeds the other by a given percentage

3) Training Mode - It would be nice to have a button to push to put a car in training mode, this would limit the power to 25 or 50% allowing me to pass the controls to my kids and then easily return the car to full power when I get the controls back

4) Traction Control - This is really a combination of 2 and 3 with a lot of extra work required. The circuit from 2 would be used to detect wheelspin and the circuit from 3 would be used to manage the power being requested from the motor. With some experimentation it should be possible to create a program to vary the motor power based on the degree of wheelspin detected and the amount of power being requested by the driver. It would also be nice to combine this with 1) to be able to log acceleration with and without traction control.

5) Traction Contol with Brake Force Control - Assuming that 4) can be made to work, the next logical step is to add active brake by using the same principle to detect a wheel locking and automatically reduce the brake force.

6) Yaw control - Yaw is movement in the left to right axis, like the fishtailing that rear wheel drive cars produce under hard acceleration. It is possible to sense this using a gyroscope and have the car automatically correct by steering into the skid.

7) Active Torque Distribution - In a twin motor car it should be possible to send power to which ever axle is generating the most grip

And now a quick look at some cars

Rear Wheel Drive Tamiya F103 GT with HPI Zonda Bodyshell


Front Wheel Drive Tamiya M03 with Kamtec Beetle Bodyshell


This final car is a front wheel drive car joined to a rear wheel drive car, it was an interesting project and very fast, much faster than the two donor cars.

Custom 4WD Twin Motored Car

Unfortunatley as fast as this car was, the handling was too unpredictable. The rear of the car was built from a Tamiya M04 a car with notoriously bad handling. Getting this car to handle will require Active Torque Distribution at the very least.