Can you help with this PLEASE!

Hi,

I have been looking at the DIY RC transmitter post and was hoping that someone might be able to help with this. In the program the joystick show 392 - 692 with the A/D and have to be converted to show 1000us - 2000us servo value. In the program it uses the math below:

cha1=(((cha142)-6500)/10)
cha2=(((cha2
42)-6500)/10)
cha3=(((cha342)-6500)/10)
cha4=(((cha4
42)-6500)/10)

Can any explane what this all means??? My stick values are different 0 - 1024. What would the math that I would have to change to be above to get my stick valuse to be the 1000us - 2000us servo value. This is the pnly part of the code I am having porblems with!!!

If anyone can help that would be great!!!

Greg

I don’t remember the reasoning behind those equations but…

Where ‘Joy’ is the ADC reading…

Joy/1023.0*1000+1000

First you convert the reading to a percentage by dividing by the maximum(1023), then multiply by the range you want(2000 - 1000 = 1000), finally add the minimum value(1000). Order of operations means you don’t need any ().

EDIT: the .0 on 1024.0 is important. That tells the compiler to perform a floating point operation and not an integer operation. If you only put Joy\1024*1000*1000 you would only get two output values because integer math says that (0 - 1022)/1023 = 0 and 1023/1023 = 1. I hope that makes sense…

Hey there,

Honestly its really not all that complicated this is where you really need the map() command for C++ would be crazy handy now.

Since the values you get are 392-692 that’s roughly 300 in decimal to use as your left/right range or your forward backward range. you have to do some basic math to add arbitrary values to get them within your range of 1000-2000.

as an example

392 would be your 1000 mark
542 would be your 1500 mark
692 would be your 2000 mark.
Hope this helps.

–Aaron

As was mentioned, on an Arduino you could use the map command. Which is a very simple function:

long map(long x, long in_min, long in_max, long out_min, long out_max) { return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; }

Not sure what you are using for the code base, but the XBee version of the DIY code(I think both BAP and Arduino) has stuff in place to handle this for you. That is the is a mode where you move all of the joysticks to their Minimum/maximum values (actually I recommend only moving straight up/down and Left/Right for this as you may get slightly higher values in diagonals, but you probably don’t want these values. And for most of the joysticks you release it to allow it to get back to the center position (which in your case you hope is near 512). My code then maps everything below the center point to the range 0-127 and everything at the center point (plus or minus slop factor) to 128 and everything above to 129-255.

The code/should be cleaned up, but one of the calculations looks like:

sums(0) = sums(0) - buffer0(index) ; subtract off old value adin 3, buffer0(index) ; sums(0) = sums(0) + buffer0(index) ; Add on new value if sums(0) >= AtoDMidT8(0) then ;(v-510)*128/126 so 636->128 bPacket(2) = (128 + ((sums(0)-AtoDMidT8(0))*128)/(AtoDMaxT8(0)-AtoDMidT8(0))) max 255 elseif sums(0) <= AtodMinT8(0) bPacket(2) = 0 else ; (v-510)*128/118 so 392-> -128 Note converted 0-127 bPacket(2) = ((sums(0)-AtoDMinT8(0))*128)/(AtoDMidT8(0) - AtoDMinT8(0)) endif ;bPacket(2) = ((((((sums(0) + SumOffsets(0)) min (AToDMins(0)*8)) / 8) - AToDMins(0)) * 256) / AToDRanges(0)) max 255

The Arduino version uses the map function and also tables to know which joysticks/sliders/pots have a center value to decide how to map. Also I do the code in a loop instead of exploding it out for each item.

[code]void ReadJoysticks(boolean fCheckandTrans) { // Initialize the joysticks.
byte i;

// Calculate which index of our raw array we should now reuse.
g_iRaw = (g_iRaw+1) & 0x7;

// Now lets read in the next analog reading and smooth the values
for (i=0; i<NUMANALOGS; i++) {
    g_awRawSums* -= g_aawRawAnalog[g_iRaw]*;        // remove the value we overwrite from sum
    g_aawRawAnalog[g_iRaw]* = analogRead(i);
    g_awRawSums* += g_aawRawAnalog[g_iRaw]*;        // Add the new value in

    // Lets calculate our calibrated values from 0-255 whith 128 as center point
    if (g_awRawSums* <= g_awAnalogMins*)
        diyp.ab[g_aiRawToDIYP[i]] = 0;                // Take care of out of range low
    else if (g_awRawSums* >= g_awAnalogMaxs*)
        diyp.ab[g_aiRawToDIYP[i]] = 255;              // out of range high
    else if (!g_afAnalogUseMids*)
        diyp.ab[g_aiRawToDIYP[i]] = map(g_awRawSums*, g_awAnalogMins*, g_awAnalogMaxs*, 0, 255);
    else if (g_awRawSums* <= g_awAnalogMids*)
        diyp.ab[g_aiRawToDIYP[i]] = map(g_awRawSums*, g_awAnalogMins*, g_awAnalogMids*, 0, 128);
    else
        diyp.ab[g_aiRawToDIYP[i]] = map(g_awRawSums*, g_awAnalogMids*, g_awAnalogMaxs*, 128, 255);

    // Try to give the robot as quick a response as possible when a request comes in...
    if (fCheckandTrans)
        CheckAndTransmitDataPacket(&diyp);

}

// Do the same for the Battery voltage
g_wRawBatterySum -= g_awRawBatAnalog[g_iRaw];
g_awRawBatAnalog[g_iRaw] = analogRead(BATTERY_PIN);
g_wRawBatterySum += g_awRawBatAnalog[g_iRaw];

}[/code]
Hope that helps
Kurt*********************

Ha! that’s why I love Kurt’s responses his code is always so easy for him to understand and for everyone else it takes them a long time to grasp it.

Baby steps!

The more I see examples for basic micro the more im glad I started to poke around with C++ and an arduino.

??? Sorry
I simply showed the map function that goggle returned. Would be easy to make the same function in basic. Or you could put the code inline, by plugging in your values.

The earlier rc remote code was first done by Robot Dude, with input from several of us. I complicated it with the xbee version, as I wanted the code to work with different joysticks, without code change, so code was added to find the valid ranges for each one. Xan (I think) added code to find the zero points, when the remote was turned on. Later I added code to more normalize the values, as if for example range was 0 to 1023, but the center was 530, there would be issues if yo simply mapped the two ranges, as with simple mapping, the robot would start moving …

The arduino version, simply added some simple range checks, and the mapped the ranges above and below the mid point separately as to normalize the range as to get the full range 0-255

Some more complications to the code, is that we try to improve the quality of the AtoD conversions, by averaging the last 8 values. It has been awhile but that may have been EddieB who contributed that part. That is why our mins, maxs, mids, are all multiplied by 8 (we did this external to this code). Also where some of the strange constants in the original code came from.

I hope this helps!

Kurt I’m just giving you a difficult time :slight_smile: