PDA

View Full Version : Linear to S Curve conversion



luminas
- 19th May 2007, 16:20
Greetings !
This is my first post, I found this forum is a great place to learn from the experts

I want to convert linear response of a pot to S curve ( see graph below )

<img src=http://i201.photobucket.com/albums/aa306/luminas_photo/Scurve.gif>

I appreciate any suggestion


Jon

mat janssen
- 19th May 2007, 16:31
Try to add a negative sine to your linear curve that must work. Or make a lookup table.

Darrel Taylor
- 20th May 2007, 01:39
Silly me, I was going for a 3rd order polynomial. Doh!

But you're right mat! Add a negative sine.

http://www.pbpgroup.com/files/MinusSine.jpg

luminas,

Now I assume there's more information to it.
Obviously you don't want the integer results from 0-10. I'm sure you want some decimals or something.

Can you elaborate a little?

Best regards,

luminas
- 20th May 2007, 02:51
Hi Darrel & Mat,


Thanks for your great information :)

I want to compensate result of an ADC input ( 0 - 1024 )
what is the formula to do this ?


Jon

skimask
- 20th May 2007, 04:53
Hi Darrel & Mat,
Thanks for your great information :)
I want to compensate result of an ADC input ( 0 - 1024 )
what is the formula to do this ?
Jon

Look at D_T's last post...the formula is RIGHT THERE.
D_T has already done the hard work for you.

Darrel Taylor
- 20th May 2007, 05:35
...the formula is RIGHT THERE ...

Yeah, well, except that the range is from 0-1023 now, and PBP's SIN function takes a "Binary Radian" input (0-255), giving a result of -127 to 127. Sure, it's all there.

But now we need to line it all up.

Got any idea's?
<br>

skimask
- 20th May 2007, 06:05
Yeah, well, except that the range is from 0-1023 now, and PBP's SIN function takes a "Binary Radian" input (0-255), giving a result of -127 to 127. Sure, it's all there.
But now we need to line it all up.
Got any idea's?
<br>

We don't know how 'hard' he needs his compensation curve...for that matter, we don't know a lot about this 'function'...

'Divide down' the SIN result to make it less agressive, multiply it up for more compensation, add in some linear interpolation to 'fill in the blanks'...
We just don't know what's 'REALLY' needed here.

If this was some sort of R/C controller for a model airplane or something, I'd think he was trying to add a bit of double sided 'exponential throw' into his programming...

Darrel Taylor
- 20th May 2007, 09:10
We don't know how 'hard' he needs his compensation curve...for that matter, we don't know a lot about this 'function'...

OK, so let's stick with what we DO know.

The original Data spanned from 0-10.
If we expand that to 10-bit, we can make it 0-1000, plus 23. Just multiply by 100.

And, since the PBP SIN function takes an 8-bit input, we can divide the A/D value (X) by 4 to get the Angle in "Binary Radians". (I assume this is the 'Divide down' method)
Then running it through a short PBP program I got the SIN(A) values. (shown in the odd gray color)

http://www.pbpgroup.com/files/MinusSine2.jpg

Here you can see "Less than Optimal" results.
It's quite a large error.

So I guess the question now is ....
What's the "multiply it up for more compensation" method?
<br>

Acetronics2
- 20th May 2007, 09:48
Got any idea's?

<br>

YES ...

IF our friend would dare to tell us what's the FINAL use ot this curve ...

Alain

PS: Tools for you, Darrel ...

http://curveexpert.webhop.net/

luminas
- 20th May 2007, 11:10
Wow, this is more than what I expected from the forum. Great !

Darrel: You are right, first problem is solved with the negative sine things,

now the question is" how to adjust the " hardness " of the curve


Alain: The purpose of this curve is to compensate the output of a joystick to suit players response in a game.

Some player like "agrresive" joystick response while some other like "standard,linear" response.

Jon

mat janssen
- 20th May 2007, 11:31
Gain!
x-aSIN(B)
a is the gain.

T.Jackson
- 20th May 2007, 13:06
The purpose of this curve is to compensate the output of a joystick to suit players response in a game. Some player like "agrresive" joystick response while some other like "standard,linear" response.


I'm a bit puzzled by that - wondering if you could explain further?

Acetronics2
- 20th May 2007, 13:39
Trent ...

That's just to give a so called " exponential " response to the Joystick :

smooth ( reduced output / stick displacement ) in the center region and give full output for full stick displacement ...

so, the gain depends on the input variable value ... to use intellectual language.

Modellers use that feature most of time ...

Alain

T.Jackson
- 20th May 2007, 14:07
I see. I think a lot of games now rely on non-proportional digital. Guess in this domain there's not a lot that can be done to tweak things. All arcade games use digital.

Darrel Taylor
- 20th May 2007, 23:55
Gain!
x-aSIN(B)
a is the gain.

Yup again,

But, PBP will have problems trying to multiply the negative values from the SIN function.
So you'll need to remove the sign before multiplying.

Been playing with it here. I think this program might do what you want Jon.

It's only for 1 axis, but it should get you started. There are 3 POT's in this example. AN0 is the axis input, AN1 is the Gain setting, and AN2 is a Trim setting. 10-turn 10K pots should be good for the Gain and Trim.

It uses HSEROUT to display the results in Hyperterminal.

<code><font color="#008000"><b>DEFINE </b></font><b>ADC_BITS </b><font color="#800000"><b>10
</b></font><b>ADCON1</b>.<font color="#800000"><b>7 </b></font>= <font color="#800000"><b>1 </b></font><font color="#0000FF"><b><i>; Right Justify
;ADCON2.7 = 1 ; 18F4550

</i></b></font><b>NEG </b><font color="#008000"><b>VAR BIT
</b></font><b>Temp </b><font color="#008000"><b>VAR BYTE
</b></font><b>Result </b><font color="#008000"><b>VAR WORD
</b></font><b>Xaxis </b><font color="#008000"><b>VAR WORD
</b></font><b>Xgain </b><font color="#008000"><b>VAR WORD
</b></font><b>Xtrim </b><font color="#008000"><b>VAR WORD
</b></font><b>ADvalue </b><font color="#008000"><b>VAR WORD
</b></font><b>GainAvg </b><font color="#008000"><b>VAR WORD
</b></font><b>TrimAvg </b><font color="#008000"><b>VAR WORD
</b></font><b>Avg </b><font color="#008000"><b>VAR WORD
</b></font><b>AvgCount </b><font color="#008000"><b>CON </b></font><font color="#800000"><b>16
</b></font><b>spread </b><font color="#008000"><b>CON </b></font><font color="#800000"><b>50

</b></font><b>Main</b>:
<font color="#008000"><b>ADCIN </b></font><font color="#800000"><b>0</b></font>, <b>Xaxis </b><font color="#0000FF"><b><i>; Axis input is not averaged

</i></b></font><font color="#008000"><b>ADCIN </b></font><font color="#800000"><b>1</b></font>, <b>ADvalue </b><font color="#0000FF"><b><i>; 0 = no gain, 1023 = gain 3.98
</i></b></font><b>Avg </b>= <b>GainAvg </b>: <font color="#008000"><b>GOSUB </b></font><b>Average </b><font color="#0000FF"><b><i>; Gain is averaged to stabilize it's value
</i></b></font><b>Xgain </b>= <b>Avg </b>: <b>GainAvg </b>= <b>Avg

</b><font color="#008000"><b>ADCIN </b></font><font color="#800000"><b>2</b></font>, <b>ADvalue </b><font color="#0000FF"><b><i>; 0 = adjust center -127, 1023 = adjust +128
</i></b></font><b>Avg </b>= <b>TrimAvg </b>: <font color="#008000"><b>GOSUB </b></font><b>Average </b><font color="#0000FF"><b><i>; Trim is averaged to stabilize it's value
</i></b></font><b>Xtrim </b>= <b>Avg </b>: <b>TrimAvg </b>= <b>Avg

</b><font color="#0000FF"><b><i>;--- Add Sine and Trim to the Xaxis input ------------------------------------
</i></b></font><b>Temp </b>= <font color="#008000"><b>SIN</b></font>(<b>Xaxis</b>&gt;&gt;<font color="#800000"><b>2</b></font>)
<b>NEG </b>= <b>Temp</b>.<font color="#800000"><b>7
</b></font><b>Result </b>= <font color="#008000"><b>ABS</b></font>(<b>Temp</b>) */ <b>Xgain
</b><font color="#008000"><b>IF </b></font><b>NEG </b><font color="#008000"><b>THEN </b></font><b>Result </b>= -<b>Result
Result </b>= <b>Xaxis </b>+ <b>Result </b>+ (<b>Xtrim </b>&gt;&gt; <font color="#800000"><b>2 </b></font>- <font color="#800000"><b>127</b></font>)

<font color="#0000FF"><b><i>;--- Display the results in HyperTerminal ------------------------------------
</i></b></font><font color="#008000"><b>HSEROUT </b></font>[<font color="#800000"><b>27</b></font>,<font color="#FF0000">&quot;[H&quot;</font>,<font color="#FF0000">&quot;Xaxis = &quot;</font>,<font color="#008000"><b>DEC </b></font><b>Xaxis</b>,<font color="#FF0000">&quot; &quot;</font>,<font color="#800000"><b>13</b></font>,<font color="#800000"><b>10</b></font>, <b>_
</b><font color="#FF0000">&quot;Xgain = &quot;</font>,<font color="#008000"><b>DEC </b></font><b>Xgain</b>&gt;&gt;<font color="#800000"><b>8</b></font>,<font color="#FF0000">&quot;.&quot;</font>,<font color="#008000"><b>DEC2 </b></font>((<b>Xgain </b>&amp; <font color="#800000"><b>$0FF</b></font>) */ <font color="#800000"><b>100</b></font>),<font color="#FF0000">&quot; &quot;</font>,<font color="#800000"><b>13</b></font>,<font color="#800000"><b>10</b></font>, <b>_
</b><font color="#FF0000">&quot;Xtrim = &quot;</font>,<font color="#008000"><b>SDEC </b></font>(<b>Xtrim </b>&gt;&gt; <font color="#800000"><b>2 </b></font>- <font color="#800000"><b>127</b></font>),<font color="#FF0000">&quot; &quot;</font>,<font color="#800000"><b>13</b></font>,<font color="#800000"><b>10</b></font>, <b>_
</b><font color="#FF0000">&quot;Result= &quot;</font>,<font color="#008000"><b>SDEC </b></font><b>Result</b>,<font color="#FF0000">&quot; &quot;</font>,<font color="#800000"><b>13</b></font>,<font color="#800000"><b>10</b></font>]

<font color="#008000"><b>PAUSE </b></font><font color="#800000"><b>100
</b></font><font color="#008000"><b>GOTO </b></font><b>Main

</b><font color="#0000FF"><b><i>' -=-=-=-=-=-= Average Analog values -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
</i></b></font><b>Average</b>: <font color="#0000FF"><b><i>' Smooth data
</i></b></font><font color="#008000"><b>IF ABS </b></font>(<b>ADvalue </b>- <b>Avg</b>) &gt; <b>spread </b><font color="#008000"><b>THEN
</b></font><b>Avg </b>= <b>ADvalue
</b><font color="#008000"><b>ELSE
</b></font><b>Avg </b>= (<b>Avg</b>*(<b>AvgCount</b>-<font color="#800000"><b>1</b></font>)+<b>ADvalue</b>)/<b>AvgCount
</b><font color="#008000"><b>ENDIF
RETURN

</b></font>

The output in Hyperterminal should look like this ... (in real time)

http://www.pbpgroup.com/files/SineOutput.jpg

HTH,

skimask
- 21st May 2007, 01:50
Modellers use that feature most of time ...
Alain

MOST?
Heck, I use it ALL of the time...makes me look like a better pilot!
I only wish that the full size light aircraft had the same type of setup, might make some of my landings look a bit better :D

Darrel Taylor
- 21st May 2007, 02:03
Hey!

We're trying to help somebody out here.

You two(3) want to chit chat. Start another thread.
<br>

luminas
- 21st May 2007, 04:37
Thanks Darrel,

The code is working now :)

After experimenting, I am still confused how to adjust the x axis width, independently to left and to right from the center

The real problem is that the stick (mechanical ) stroke is not identical, say to left 30 degree, to right 26 degree
but electrically they are centered [ at 50k on 100k stick ]
this will make our curve response not equal


If we can adjust the most left / right position, then we can have nice curve, which has true equal left / right width


Jon

Darrel Taylor
- 21st May 2007, 05:00
That's what I was trying to do with the Trim.

It allows you to adjust the "Center" position of the Control.

I'm just using pots on a breadboard here, maybe it's not doing it right on the real thing.

Can you give me any numbers?
<br>

Acetronics2
- 21st May 2007, 09:43
Hi, Darrel

Reading your kind post ... I just remember placing a resistor from the hot side of the pot to the cursor, and another, the same value, from the cursor to the cold side of the pot give a nice exponential shape to the "pot " response.

so, using a twin pot instead of my two stupid resistors might give a trimmable response ( care to the minimum value !!! )

Was a pleasure to help you

Alain

luminas
- 22nd May 2007, 14:15
Well, it seems that the stroke does not matter anymore, the difference is not significant.

Case closed and I'd like to thank you all for helping :)