Go Down

Topic: Help to read RC 2channel input and fulfill dream. Pics inside! (Read 1 time) previous topic - next topic

magnusvr

Hi!
For the last 15 years, Iv'e been wanting to build an RC-car with all the fancy lights, braking, reverse, blinker etc.
Iv'e taken a small Kyosho Mini-Z Overland truck and installed a plethora of LED's, this was done 10 years ago.
Not until now that Iv'e discovered Arduino, is it getting close to realization.
I've managed to read the TTL input from a standard RC reciever, with the 1-2 ms pulses signifying turning left or rigth etc.
This small model however, does not have those. It has a all-in-one 27Mhz AM reciever with motor driver and steering servo driver in it. The only signal Iv'e found is from somewhere within the radio reciever. It comes as a 3-4 volt PWM signal (See pic). It seems to come with 3 pulses after another and its the low period that means something. When I turn the knobs of the RC control, the low periods increase or decrease, but the high periods remain constant and is moved right or left. First channel one, then channel two, then another long period of low.



How can I read this and get measurements of the pulses' lenght, in microseconds?

I figured I'd use the AD1 input on my Arduino Uno and did something like this: (This is in Pseudocode, I know)

while (input > 10){} //wait here until low pulse starts
start = micros();
while (input < 10){} //wait for pulse to finish
timeA = start - micros(); //get reading for low period A.

while (input > 10){} //wait here until low pulse starts
start = micros();
while (input < 10){} //wait for pulse to finish
timeB = start - micros(); //get reading for low period B.

while (input > 10){} //wait here until low pulse starts
start = micros();
while (input < 10){} //wait for pulse to finish
timeC = start - micros(); //get reading for low period C.

lcd.out(timeA);
lcd.out("+");
lcd.out(timeB);
lcd.out("+");
lcd.out(timeC);
timeA, timeB, TimeC=0;
delay(1000);

loop...

This gives me printouts on my LCD-shield like this:


I'm getting wierd results.
Reasonable numbers? Maybe, bit not really. Also they seem constans. Sometimes "10200" changes to "10176" or so, but nothing seems to be changing by me changing the controls. I should be getting variations when I turn the knobs on the RC control.

Any ideas? Am I thinking correctly? Is this feasible?

Magician

Quote
How can I read this and get measurements of the pulses' lenght, in microseconds?

Try PulseIn: http://arduino.cc/en/Reference/PulseIn

magnusvr

I did not know about pulseIn()! Beautyful command! But I have now tried it and I'm not getting any values at all. Or rather, the methid returns "0". I get some values when I scrape the wire from the car onto pin2 (mechanically creating pulses), so I know that it is the right pin and the method ought to work, but it does not.
I tried using both pin 2 and three, and changing from low to high.
I think the problem with PulseIn is that it requires TTL level signals. I believe that the signal I have to work with is not TTL compliant, ie HIGH is 3.5 volt or so.

Further input much appreciated.

KR
/Magnus

Magician

Quote
when I scrape the wire from the car onto pin2 (mechanically creating pulses),
You need  wire and pull-up / pull-down resistor to simulate a pulse "mechanically".

magnusvr

You are probably both right and wrong.
Apparently I was able to generate some kind of noise that it could trigger on. But that is all beside the point.

The question is how I should proceed to get the Arduino to give me the length of the low periods.

I was not able to get a stable reading using the AD, perhaps the AD-function is not fast enough? I read somewhere that you could only get about 10 readings per second using Arduino?


Magician

Quote
The question is how I should proceed to get the Arduino to give me the length of the low periods.

Have you read PulseIn tutorial page? Aparently not:
Quote
Description
Reads a pulse (either HIGH or LOW) on a pin. For example, if value is HIGH, pulseIn() waits for the pin to go HIGH, starts timing, then waits for the pin to go LOW and stops timing. Returns the length of the pulse in microseconds. Gives up and returns 0 if no pulse starts within a specified time out.

Quote
I was not able to get a stable reading using the AD, perhaps the AD-function is not fast enough?

One reading takes 120 useconds, you results should be acuurate down to this value. It's difficult to say more, as you didn't provide an actual code.
Only remarks I can guess,  trys to set higher value, about 10% of pulse is normal for a duration measurements:

while (input > 60){} //wait here until low pulse starts   <<<<-- about 10% from 3V signal.
start = micros();

DuaneB

Hi,
   If its a 27mhz unit, I cant see why it would not be standard in which case any of the code from my blog will do more or less what you want - although what you have written suggests the signal is inverted.

Try some of the code samples from my blog and see what happens -

http://rcarduino.blogspot.com/2012/01/how-to-read-rc-receiver-with.html
http://rcarduino.blogspot.com/2012/04/how-to-read-multiple-rc-channels-draft.html

Duane B

rcarduino.blogspot.com

Read this
http://rcarduino.blogspot.com/2012/04/servo-problems-with-arduino-part-1.html
then watch this
http://rcarduino.blogspot.com/2012/04/servo-problems-part-2-demonstration.html

Rcarduino.blogspot.com

magnusvr

#7
Aug 03, 2012, 10:01 pm Last Edit: Aug 03, 2012, 10:08 pm by magnusvr Reason: 1
SOLVED IT! :)

Thank you all for input!
Duane; as i explained in the first post, this is a Kyosho Mini-z "motherboard", it does not seem to have standard RC-signals. It is an integrated RX, servo driver, motor driver etc. It has 6 wires running to the steering servo motor (+- / -+ and position sensors) and also just the connectors to the motor, no ESC in between.
I have not been able to detect any standard RC TTL signals on this board, just this low level signal.
Because its not TTL, pulseIn() would not work for me.
I think my oscilloscope is off showing me 4volts, I get the feeling this signal has a high of 1 volt or so. Digital voltmeter says 0,3 or 1, can't remember right now.

ANYHOW, my problem was the speed of the readAnalog()-function. It turned out I was not able to read fast enough, I got values around every 0.7 milliseconds or so, not at all enough to measure the difference between one and two millis with any resolution. I though this was due to the AD or AVR or Arduino not beeing fast enough.

Solution: I was able to find code for Arduino to modify the AD prescaler to the value of 16, giving be LOTS more reads in the same period of time, and perfect resolution!
So, if you need a higher AD-frequency, lookie here, its just copy and paste!

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1208715493/11

KR
Magnus

Magician


Go Up