Lynxmotion Tech Support

www.lynxmotion.com
It is currently Wed Jun 19, 2013 10:50 am

All times are UTC - 6 hours [ DST ]




Post new topic Reply to topic  [ 7 posts ] 
Author Message
PostPosted: Wed Jul 04, 2012 9:53 am 
Offline
Roboteer

Joined: Mon Feb 13, 2012 7:45 pm
Posts: 5
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=(((cha1*42)-6500)/10)
cha2=(((cha2*42)-6500)/10)
cha3=(((cha3*42)-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


Top
 Profile  
 
PostPosted: Thu Jul 05, 2012 9:08 am 
Offline
Arduino Wizard-in-Training
User avatar

Joined: Thu Sep 09, 2010 4:56 pm
Posts: 252
Location: I don't even know
I don't remember the reasoning behind those equations but...

Where 'Joy' is the ADC reading...

Code:
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
Code:
 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...

_________________
Devon Simmons, Former Programmer for Lynxmotion.
I can try to help, but I can only offer you my best effort.


Top
 Profile  
 
PostPosted: Thu Jul 05, 2012 11:09 am 
Offline
Roboteer

Joined: Sun Nov 30, 2008 3:08 pm
Posts: 446
Location: Portland Oregon
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

_________________
Is the warranty voided yet? ... and why not?


Top
 Profile  
 
PostPosted: Thu Jul 05, 2012 11:56 am 
Offline
Robot Guru
User avatar

Joined: Sat Apr 15, 2006 1:42 pm
Posts: 4423
As was mentioned, on an Arduino you could use the map command. Which is a very simple function:
Code:
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:
Code:
      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[i] -= g_aawRawAnalog[g_iRaw][i];        // remove the value we overwrite from sum
        g_aawRawAnalog[g_iRaw][i] = analogRead(i);
        g_awRawSums[i] += g_aawRawAnalog[g_iRaw][i];        // Add the new value in

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

Hope that helps
Kurt


Top
 Profile  
 
PostPosted: Thu Jul 05, 2012 11:30 pm 
Offline
Roboteer

Joined: Sun Nov 30, 2008 3:08 pm
Posts: 446
Location: Portland Oregon
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.

_________________
Is the warranty voided yet? ... and why not?


Top
 Profile  
 
PostPosted: Fri Jul 06, 2012 6:00 pm 
Offline
Robot Guru
User avatar

Joined: Sat Apr 15, 2006 1:42 pm
Posts: 4423
LikWidChz wrote:
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.

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!


Top
 Profile  
 
PostPosted: Sat Jul 07, 2012 2:47 pm 
Offline
Roboteer

Joined: Sun Nov 30, 2008 3:08 pm
Posts: 446
Location: Portland Oregon
Kurt I'm just giving you a difficult time :)

_________________
Is the warranty voided yet? ... and why not?


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC - 6 hours [ DST ]


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group