DIY custom 2.4ghz RC radio system for robotics

Ho! little problem. I found the little innocent serout command to the Scott Edwards serial LCD at 9600baud is too slow. It actually adds ~25mS to the loop! This makes the total loop about 38mS. It should be around 20mS. Look like a faster serial LCD is in this projects future.

One last information post. As a reality check I injected values into channel 5, cha5=1000, cha5=1050, etc. and measured the results at the receivers servo output. Here are the results.

sent / measured 1000 - 1057 1050 - 1100 1100 - 1156 1150 - 1205 1200 - 1254 1250 - 1303 1300 - 1353 1350 - 1402 1400 - 1452 1450 - 1501 1500 - 1550 1550 - 1599 1600 - 1649 1650 - 1697 1700 - 1747 1750 - 1797 1800 - 1846 1850 - 1895 1900 - 194? 1950 - 199? 2000 - 204?

Little update, and a little problem.

Here is the thing with the keypad installed. 8)

The problem is the inputs from the joysticks are bouncing a bit. Like it will not settle between two values. So I’m getting jitter on the servo outputs. The pots are going directly to the analog inputs. I will try putting a small cap from ground to the wiper to clean it up.

Heh, I might get something done with it of I stopped testing things. :slight_smile:

I varied the timing on the PPM signal. If the sync period is too short, or too long the receiver will not connect with the transmitter. However the pulses from the receiver are generated at the same (23mS) rate no matter what the PPM rate is changed to. Also the outputs are generated sequentially, I think Kurte was asking this before.

So this means you can’t sent 5 channels any faster than 7 or 9. :frowning: My system will use just 5 channels for now.

that is pretty sharp looking. need something in the right hand corner though to balance the appearance out. :laughing:

I don’t know at what rate you poll the joysticks but if it is sufficiently high you can run a simple averaging filter.

It’s straight line code that appears to cycle at about 38mS with the slow serial LCD. So I should do a for next loop with say 4 or 5 tests and average them? I will give it a try.

Why update all 4 values every pass? Do you really need to see all 4 values twitch 25 times a second? Just update 1 value each time through the loop (i.e. move cursor then paint the value) and it should be only like 6 bytes a pass, right? Could even send that using hserial so you can spend more time polling the joystick inputs and keypad instead of waiting on serout. :wink:

On averaging… make a 2d array with 8 rows of 4 values, an index, and 4 sums. init them all to 0 at start. when you start your sampling pass subtract the value at array[index][0…3] from each sum. Now as you collect each sample add it to the corresponding sum and put it in array[index][0…3]. after you have all 4 sums you increment index and AND it with 0x07 to make it wrap. Divide each sum by 8 (right shift 3 times is fast) and that is your new average. It’s important to subtract the array value AT the index from the sum before you replace it with the new value and add the new value to the sum. This process is much faster than summing all 8 elements every time you update an element of the array. :smiley:

That’s easy… I can do that.

Um, gulp… :open_mouth:

if we don’t have a raid scheduled tonight when I get home I’ll see if my bap-foo works anymore… I don’t even think I have an IDE installed on my pc atm. last time I wrote some code for someone and didn’t test it Mike burned up some servos with it. :unamused: :laughing: :stuck_out_tongue:

Yeah, the code did a great job of making my servo go ZZzzzzzip! Grrrrrr ZZzzing! LOL!

Load up the latest BAP IDE, blow off the dust on the Mini ABB, and get back in the game! Eddie Eddie… He’s our man… If he can’t do it… No one can!!! :laughing:

BAH! If you had used manly servos they would have survived your use of a BYTE variable for a WORD sized value. :wink:

I sent Jim some code to test. Getting me, a PC with the IDE, a BAP+ABB, and time in the same place all at once seems to be a struggle atm so hopefully Jim doesn’t have any servos plugged in the first time he gets it to compile. :blush:

So what if I used limp wristed servos, as for the WORD, well had I not used the BYTE command I would not have learned as much. LOL!

Here is the code after EddieB fine tuned it. It now runs the loop in a respectable 18mS. 8)

EddieB also told me about a really sick idea in a PM. Sorry Eddie this is too cool to keep to myself!

The long range PS2 controller is only a prototype still in development at this stage. There is no guarantee it will make it to a real product. But this is something anyone can do right now. Effectively the PS2 replaces the joysticks and or the keypad. Just need to mary the PS2 code with the PPM generating code in this program to get 3000’ range robot control.

[code]; code written by Jim Frye, modified by EddieB <- genius
; declare variables here
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

; create variables for averaging code
index var byte
buffer1 var word(8)
buffer2 var word(8)
buffer3 var word(8)
buffer4 var word(8)
sum1 var word
sum2 var word
sum3 var word
sum4 var word

; initialize each buffer element, each sum, and then index to 0
for index = 0 to 7
buffer1(index) = 542
buffer2(index) = 542
buffer3(index) = 542
buffer4(index) = 542
next

sum1 = 4336
sum2 = 4336
sum3 = 4336
sum4 = 4336
index = 0

; initialize unused channels outside the main loop
cha5=1500
cha6=1500
cha7=1500

; chirpy squeak kinda thing
sound 9, [100\880, 100\988, 100\1046, 100\1175]

; wake up the display module
serout 8,N9600,[12, 14]

; initialize the ppm output signal
low 15

; — top of main loop —
start:

; averaging expects that the a/d values are < 4096
; for each channel
; read the a/d
; subtract the previous value from 8 samples ago from the sum
; store the new value in the circular buffer
; add the new value to the sum
; divide the sum by 8 to get the average value
; convert joystick values 392 - 692 to servo values 1000uS - 2000uS

adin 16, cha1 ; right vertical
sum1 = sum1 - buffer1(index)
buffer1(index) = cha1
sum1 = sum1 + cha1
cha1 = sum1 / 8
cha1 = (((cha1*42)-6500)/10)

adin 17, cha2 ; right horizontal
sum2 = sum2 - buffer2(index)
buffer2(index) = cha2
sum2 = sum2 + cha2
cha2 = sum2 / 8
cha2 = (((cha2*42)-6500)/10)

adin 18, cha3 ; left vertical
sum3 = sum3 - buffer3(index)
buffer3(index) = cha3
sum3 = sum3 + cha3
cha3 = sum3 / 8
cha3 = (((cha3*42)-6500)/10)

adin 19, cha4 ; left horizontal
sum4 = sum4 - buffer4(index)
buffer4(index) = cha4
sum4 = sum4 + cha4
cha4 = sum4 / 8
cha4 = (((cha4*42)-6500)/10)

; finally increment the index and limit its range to 0 to 7.
index = (index + 1) & 7

; update the display module
branch (index & 3), [update1,update2,update3,update4]

update4:
serout 8, N9600, [16, 80, dec cha4]
goto makepulses

update3:
serout 8, N9600, [16, 64, dec cha3]
goto makepulses

update2:
serout 8, N9600, [16, 92, dec cha2]
goto makepulses

update1:
serout 8, N9600, [16, 76, dec cha1]
; goto makepulses

; build and send the ppm output
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

; do it again ad infinitum
goto start [/code]

great work. I was wondering if you can use arrays for the channel variables? for example create a variable called chan(6) instead of cha1 cha2… etc.

Yep in much the same way as buffer1 is defined. Not sure if they support multiple dimension arrays or not. It would be nice to say buffer(6)(8). I think it compiles but not sure if it works as the manual says they support 1 dimensional arrays.

Kurt
P.S. they cool symbol is supposed to be a ( 8 ) without the spaces…

as you noted there is no indication in the manual the bap supports anything but single dimensional arrays, and it would be much cleaner looking code if it did. I suppose you could always implement them manually but any sort of optimization potential at the compiler level completely goes away at that point since it would have to fully recompute the index on every access.

anyway, kurte are you going to take this code and add your keypad scanning / demultiplexing logic to it?

I disabled smilies in your post so it shows up correctly :slight_smile:

Ok time for a small update. I had a few boxes made, they had to machine them down from a standard (taller) part. I’m converting the LCD display to a Matrix Orbital unit. Should be able to start working on the keyboard code soon.

Nice work Jim!

Regards,
TCIII

This thing looks awesome! Great work Jim!