Here's a quick example I knocked up that uses the (cube) formula recommended by Mike_K. This is all integer math and uses the range -1024 to +1024 for the input, output, and expo value. You could easily modify the code to use some other range, but 1024 is plenty accurate enough for radio control. If you increase the range then beware exceeding the limits that a (signed) 16-bit integer can hold: -32768 to +32767
Code: Select all
/* demonstrates a fast integer 'expo' function
* input, output, and expo amount are all integers in range -1024 <= value <= 1024.
* if you wish to use a different range, use bit-shifts to scale to that range, call the function and then bit-shift the result back to the range you want.
*
* ceptimus June 2019
*/
int expo(int input, int xpo) {
if (xpo == 0 || input == 0) {
return input; // no need to calculate when zero xpo is applied
}
// clip values to keep within allowed range
if (input < -1024) {
input = -1024;
} else if (input > 1024) {
input = 1024;
}
if (xpo < -1024) {
xpo = -1024;
} else if (xpo > 1024) {
xpo = 1024;
}
int32_t cube, i; // intermediate values use 32-bits. input values (16-bits) are cast to 32-bit for calculations.
cube = (int32_t)input * (int32_t) input; // first calculate square
cube >>= 10; // shift ten bits (divide by 1024) to normalize
cube *= input; // now cube
cube >>= 10; // re-normalize
cube *= xpo; // now xpo * input^3
cube >>= 10; // re-normalize
i = (int32_t)input * (int32_t)xpo;
i >>= 10;
int32_t output = (int32_t)input - i + cube;
return (int)output;
}
void setup() {
Serial.begin(115200);
Serial.print("Expo\tInput\tOutput\n");
for (int xpo = 0; xpo < 1024; xpo += 102) { // roughly 10% steps
for (int input = -1024; input <= 1024; input += 128) {
int output = expo(input, xpo);
Serial.print(xpo);
Serial.print("\t");
Serial.print(input);
Serial.print("\t");
Serial.print(output);
Serial.print("\n");
}
Serial.print("\n");
}
}
void loop() {
}
...and here's what the program output looks like. The xpo is increasing by roughly 10% for each block (102/1024) and values are tabled for the input range -1024 to 1024 going in steps of 128 within each block. The function obviously works for all (roughly) two million possible input permutations (four million if you count using negative expo), but it would take up too much room to show them all!
Note: although Futaba got it wrong and negative expo is what you (usually) want to use on Futaba, this formula implements expo in the (correct) JR / Spektrum sense.
Code: Select all
Expo Input Output
0 -1024 -1024
0 -896 -896
0 -768 -768
0 -640 -640
0 -512 -512
0 -384 -384
0 -256 -256
0 -128 -128
0 0 0
0 128 128
0 256 256
0 384 384
0 512 512
0 640 640
0 768 768
0 896 896
0 1024 1024
102 -1024 -1024
102 -896 -875
102 -768 -735
102 -640 -601
102 -512 -474
102 -384 -351
102 -256 -232
102 -128 -116
102 0 0
102 128 116
102 256 232
102 384 351
102 512 473
102 640 601
102 768 735
102 896 875
102 1024 1024
204 -1024 -1024
204 -896 -854
204 -768 -702
204 -640 -562
204 -512 -436
204 -384 -318
204 -256 -209
204 -128 -103
204 0 0
204 128 103
204 256 208
204 384 318
204 512 435
204 640 562
204 768 701
204 896 854
204 1024 1024
306 -1024 -1024
306 -896 -833
306 -768 -668
306 -640 -523
306 -512 -398
306 -384 -286
306 -256 -184
306 -128 -90
306 0 0
306 128 90
306 256 184
306 384 286
306 512 397
306 640 523
306 768 668
306 896 833
306 1024 1024
408 -1024 -1024
408 -896 -813
408 -768 -635
408 -640 -485
408 -512 -359
408 -384 -253
408 -256 -161
408 -128 -78
408 0 0
408 128 77
408 256 160
408 384 252
408 512 359
408 640 484
408 768 634
408 896 812
408 1024 1024
510 -1024 -1024
510 -896 -791
510 -768 -601
510 -640 -446
510 -512 -321
510 -384 -219
510 -256 -136
510 -128 -65
510 0 0
510 128 65
510 256 136
510 384 219
510 512 320
510 640 446
510 768 601
510 896 791
510 1024 1024
612 -1024 -1024
612 -896 -770
612 -768 -568
612 -640 -407
612 -512 -283
612 -384 -187
612 -256 -113
612 -128 -53
612 0 0
612 128 53
612 256 112
612 384 187
612 512 282
612 640 407
612 768 567
612 896 770
612 1024 1024
714 -1024 -1024
714 -896 -750
714 -768 -534
714 -640 -368
714 -512 -245
714 -384 -154
714 -256 -89
714 -128 -40
714 0 0
714 128 40
714 256 89
714 384 154
714 512 244
714 640 368
714 768 534
714 896 750
714 1024 1024
816 -1024 -1024
816 -896 -729
816 -768 -501
816 -640 -330
816 -512 -206
816 -384 -122
816 -256 -65
816 -128 -28
816 0 0
816 128 27
816 256 64
816 384 121
816 512 206
816 640 329
816 768 500
816 896 728
816 1024 1024
918 -1024 -1024
918 -896 -707
918 -768 -467
918 -640 -291
918 -512 -168
918 -384 -88
918 -256 -41
918 -128 -15
918 0 0
918 128 15
918 256 41
918 384 88
918 512 167
918 640 291
918 768 467
918 896 707
918 1024 1024
1020 -1024 -1024
1020 -896 -687
1020 -768 -434
1020 -640 -252
1020 -512 -130
1020 -384 -55
1020 -256 -17
1020 -128 -2
1020 0 0
1020 128 2
1020 256 16
1020 384 55
1020 512 129
1020 640 252
1020 768 433
1020 896 687
1020 1024 1024