DIY custom 2.4ghz RC radio system for robotics

Hi Jim,

I didn’t visited this topic for a few days and I totally surprised! You’ve build a fantastic open source remote! 8) I love the display in the middle. Adding the keypad would make it really awesome! I would love to try it out some day!

Xan

Hi Jim,

Again looks great.

I really like having that display there and can not wait to see the keypad in there. If I have time in the next day or so, I will hack up some preliminary code to read the keypad.

I think this is great. A few months ago I was thinking of building something like this to control my Rover over longer distances. At that time I was thinking of not using something like the airmod, but instead I was thinking of something like bluetooth or something like:
hvwtech.com/products_view.asp?ProductID=668, which is a 912mhz RF transeiver which sends and receives at 9600 baud and has a range of up to 800 feet. I am not sure if Parallax still makes them as I don’t see them on their site anymore, but I do see them up at some other sites. What I liked about this approach was that you did not having to encode the data in a PWM signal and then having to receive multiple channells of PWM at the other end. Just a thought.

Kurt

Good point Kurt, especially handling all the pwm at the end (receiver) take very much time. What about a little microcontroller taking care of all pwm readings with an interrupt code, so that the main BAP28 on BB2 just can send a pulse (IRQ) to the microcontroller when it needs the pwm data. And then the microcontroller can send the pwm data via a serout command to the BAP28? Just an idea :unamused:

I have looked at lots of options to do this. I fell in love with this approach for several reasons.

o The module is FFC approved and the range is really good. People are reporting 1000’ and some up to 3200’.
o The programming on the robot end is relatively easy. The approach may interest RC’ers, as it’s not too intimidating.
o The cost is not prohibitive.
o I suspect this technology is going to be bidi soon. No real proof, but I remember reading something about seeing the battery level of the model on the Transmitter.

I have looked at zigbee stuff and the costs were much higher. But I may try a zigbee setup later.

After several phone calls I finally got someone over at Electronix Express to tell me the keypads are in stock and will ship today. They also told me I can call them back tomorrow to get a tracking number. Wow and only 7 days after I ordered them. :smiling_imp:

I can’t recommend this company. Maybe I’m too critical but there are some real “winners” out there…

The good news is these 4 x 4 keypads are available all over the place. I will look for a better supplier.

Zenta, sure a co-processor would be a great addition.

Not really that familiar with the micro on the BAP but does it have hardware capture on any of the port pins? If it does and we are only talking about capturing a single channel to decode the keypad then could one of the folks familliar with the cpu architecture and doing BAP interrupts write a short routine to simple capture pulses on that channel and put the results in a variable? It seems like that would go a long way to minimizing the impact on the top level program loop.

Thanks in advance!

Here is a proposal for the Atom Pro pinout. The 4 x 8 keypad interface sure does gobble the I/O pins. If we ditch the speaker we can actually scan 3 joysticks! 8) I like having the speaker though.

X = Horizontal, Y = Vertical

P0 = Keypad A
P1 = Keypad B
P2 = Keypad C
P3 = Keypad D
P4 = Keypad 1
P5 = Keypad 2
P6 = Keypad 3
P7 = Keypad 4
P8 = PPM out
P9 = Speaker
P10 = LCD out
P11 = Spare
P12 = Keypad 5
P13 = Keypad 6
P14 = Keypad 7
P15 = Keypad 8
P16 = Joystick 2 (right) Y
P17 = Joystick 2 (right) X
P18 = Joystick 1 (left) Y
P19 = Joystick 1 (left) X

what no inputs for the 3-axis accelerometer module :question:

It’ll have to wait for Rev 2. :wink:

Hi Jim,

I don’t know why you placed every single button on a single pin but usally such keypaths will have a multiplexer so you will only need 4 inputs (4^2=16). You can simply read a nib instead of a single pin (this is a different command).

Xan

Um, he has two (2) 4x4 keypads , each having 4 rows and 4 columns for a total of 32 buttons. To read them he needs 4 x 8, that is 4 rows and 8 columns… which is exactly what he has… A-D, 1-8 which uses 12 of the 16 I/O lines on a BAP. :wink:

I should have labeled them differently to avoid confusion. BTW this proposal is admittedly overkill in the keys department. The goal was directed to 16 keys for behaviour/device control, and the second keypad for arm control.

R=Row C=Column P0 = Keypad R1 P1 = Keypad R2 P2 = Keypad R3 P3 = Keypad R4 P4 = Keypad C1 P5 = Keypad C2 P6 = Keypad C3 P7 = Keypad C4 P8 = PPM out P9 = Speaker P10 = LCD out P11 = Spare P12 = Keypad C5 P13 = Keypad C6 P14 = Keypad C7 P15 = Keypad C8 P16 = Joystick 2 (right) Y P17 = Joystick 2 (right) X P18 = Joystick 1 (left) Y P19 = Joystick 1 (left) X

If we want we can go a little more conservative and just do one keypad. One key could toggle from basic control to arm control. If so it would be more like this.

R=Row C=Column P0 = Spare analog input (battery check) P1 = Spare analog input P2 = Joystick 3 (optional) Y P3 = Joystick 3 (optional) X P4 = Keypad R1 P5 = Keypad R2 P6 = Keypad R3 P7 = Keypad R4 P8 = PPM out P9 = Speaker P10 = LCD out P11 = Spare P12 = Keypad C1 P13 = Keypad C2 P14 = Keypad C3 P15 = Keypad C4 P16 = Joystick 2 (right) Y P17 = Joystick 2 (right) X P18 = Joystick 1 (left) Y P19 = Joystick 1 (left) X

This frees up 4 more I/O pins. 8)

On the BAP we could use TimerW to capture the input timing of 4 pins FTIOA-FTIOD (P9-P12 on the BAP). However for this RC receiver we will probably be receiving at least 6 channels of PWM (2 for each joystick and I think Jim was thinking 2 for the keyboard states) as to leave enough difference in the values to receiving the values less error prone. My current Rover code (when the rover is in one piece) was using hardware interrupts (WKPxxx)for pins P0-p5, which was working reasonably well, but the large number of interrupts caused the timings of the bit bang functions like serout to not work very well. The basic version that is used on my Phoenix uses basic (pulsein) to get these values, which as it does not use interrupts implies that the serouts work well. However nothing else happens while the pulsein is waiting so your main code loop may take a lot longer to process and as Zenta mentioned and as such his phoenix may not walk as quickly as Xans.

Once the updated version of XAN’s code is up and I get a change to reintegrate my changes I will see how fast I can make it. I may try the approach I used on the Rover and maybe simply disable the Interrupt code while the serouts are being processed… But that is more for a different thread…

Kurt

Two keypads look cool but one is all you need, unless you have two people punching info at the same time! The extra four pins you save could be used as a simple switch joystick, like a HAT. You could incorporate a rotational encoder instead of the HAT.

why would you need to read the joystick channels? one or two channels to read the keypad and perhaps another control like russ suggested a wheel or hat or a slider even. heck it would be easy enough to do a 3-axis hat if you encode the z-axis switch in bit 7 and use bits 0-6 for the 8 possible positions.

Jim, sorry if this is off topic, also sorry if I have not explained myself very well. I think we are talking about the two different halves of the problem. In the prototype box, this should be sort-of easy. We read the values in from the two gimbals(joysticks) in the controller, this will generate the first 4 pwm signals that we send out on the airmod transmitter. We then read the state of the buttons on the keypad(s) and use it to generate a 5th and possibly 6th channel to transmit. I believe Jim proposed some values in the other thread. Something like:

NOP 1100uS 0 1150uS 1 1200uS 2 1250uS 3 1300uS 4 1350uS 5 1400uS 6 1450uS 7 1500uS 8 1550uS 9 1600uS 10 1650uS 11 1700uS 12 1750uS 13 1800uS 14 1850uS 15 1900uS

Now we get to the other part (hopefully in my Hex or Rover) and that is the receiver. It is my belief that the receiver will have 6 or more channels, where each channel will plug into different IO pins on the robots BAP board. We will then want to decode this information in order to control the robot. This is the part I was talking about earlier. You can spend a lot of time waiting in the Pulsein commands, especially if you don’t do them in the right order (another topic).

Kurt

Oh I was thinking the TX part of this was straight forward enough once you got a routine to generate the PPM signal with enough resolution to be useful. I thought Jim had already done the basics of that.

On the RX in my head I am thinking ROV so why would you need to decode the first 2 axis anyway as they are just speed and turn applied to an rc speed controller like the sabertooth things. However if I step back from my own project I can see that if you were looking to drive a gait sequencer or state machine for a legged robot then yes you would potentially need to decode all 6 or 7 PWM channels as delivered by the receiver. Now you may want to poke around on rcgroups because I think I saw some information about people opening/hacking the spektrum receiver and intercepting the PPM stream to access it directly rather than decode the individual servo outputs. If I get time around lunch I’ll see if I can re-trace my steps and find the information again. I also think I saw a project re-creating a PPM signal in hardware from the individual PWM servo signals… I want to say it was for something called a microkopter or something like that… so I’ll see if I can find that information too.

Hi Eddie,

As you said for many you may simply hook up the first joystick output directly to your speed controller. That is what I had when I first built my rover. But later I wanted some control over it. For example maybe if I press a button, the RC controller is now controlled by the software on the Atom. Pressing another button, maybe I want to use the joystick to now controll the gripper on the front of the rover or the pan and tilt on top…
Would be great to find a way to intercept the stuff before it seperate channels on the receiver…

Now back on subject:

This morning I started hacking the first round of the keypad. I have one of these:jameco.com/webapp/wcs/stores/servlet/ProductDisplay?langId=-1&storeId=10001&catalogId=10001&productId=152063

I need to continue debugging my code as some of the BAP code is not debugging the way I would expect:
I tried using DIRA, DIRB (latter DIRL) to setup the input/output bits the way I wanted: the P0-P3 output, P4-P7 input, and then tried using OutA, InB to try to set and read 4 bits at a time and it is not getting the results I expect. Will debug more later. But now the electricians have arrived…

Kurt

Here’s a little program update. When I asked for a formula for converting the joystick values to the servo output values I mistakenly used 900us to 2100uS. This caused a problem in the receiver resulting on a non-symmetrical response. I needed to change it to 1000uS to 2000uS. To avoid floating math I multiplied by 42, subtracted 6500 then divided the result by 10. Beth created a spreadsheet formula so we could alter the two values to get the best result. So now the LCD displays the correct values and the joysticks now center at 1500 and have a symmetrical throw. Next I will throw a Bot Board II and Atom Pro on the receiver side and start writing a simple routine to measure the keypad channels to turn some LED’s on and off.

[code]cha1 var word
cha2 var word
cha3 var word
cha4 var word
cha5 var word
cha6 var word
cha7 var word
a_key var bit
b_key var bit
c_key var bit

sound 9, [100\880, 100\988, 100\1046, 100\1175]

serout 8,N9600,[12, 14]

low 15

start:

adin 16, cha1 ;right vertical
adin 17, cha2 ;right horizontal
adin 18, cha3 ;left vertical
adin 19, cha4 ;left horizontal

;convert joystick values 392 - 692 to servo values 1000uS - 2000uS
cha1=(((cha142)-6500)/10)
cha2=(((cha2
42)-6500)/10)
cha3=(((cha342)-6500)/10)
cha4=(((cha4
42)-6500)/10)
cha5=1500
cha6=1500
cha7=1500

serout 8,N9600,[16, 64, dec cha3, 16, 76, dec cha1, 16, 80, dec cha4, 16, 92, dec cha2]
;serout 8,N2400,"hello world “]
;serout S_OUT,i57600,[dec5 cha1\5,” “,dec5 cha2\5,” “,dec5 cha3\5,” “,dec5 cha4\5,” ",13]

makepulses:
pulsout 15,800
pauseus ((cha12)-800)
pulsout 15,800
pauseus ((cha2
2)-800)
pulsout 15,800
pauseus ((cha32)-800)
pulsout 15,800
pauseus ((cha4
2)-800)
pulsout 15,800
pauseus ((cha52)-800)
pulsout 15,800
pauseus ((cha6
2)-800)
pulsout 15,800
pauseus ((cha7*2)-800)
pulsout 15,800
goto start[/code]

I decided to lay down some specifics pertaining to the joystick configuration. In the RC world there is Mode 1 popular in Europe and Mode 2 popular in the states. In mode 2 the left joysticks vertical axis is used for throttle and does not return to center if released. The right gimbal has spring returns on both axis. In robotics a single stick used for motion control would need to return to center (stop the robot) if released. So we use the right stick for motion control. The left stick lends itself to pan and tilt operation. I sometimes remove the horizontal centering springs on the left stick as well.

I chose to scan the gimbals in this order.

Ch1 - right vertical, spring return, Throttle (elevator)
Ch2 - right horizontal, spring return, Steering (ailerons)
Ch3 - left vertical, no spring return, Tilt (throttle)
Ch4 - left horizontal, spring return, Pan (rudder)

Also here is how the sticks are working now.

1958uS 1962uS | | | | 1009uS ----o----2008uS 1004uS----o----2017uS | | | | 1084uS 1051uS