Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.
|
Forum Index : Microcontroller and PC projects : MATH INTERPOLATE in1(), in2(), ratio, out()
Author | Message | ||||
stanleyella Guru Joined: 25/06/2022 Location: United KingdomPosts: 1641 |
Is this a scale function? This command implements the following equation on every array element: out = (in2 - in1) * ratio + in1 Arrays can have any number of dimensions and must be distinct and have the same number of total elements. The command works with bot integer and floating point arrays in any mixture If it not scale forget but if it is, some real numbers please. eg. out = (in2 - in1) * ratio + in1 what is ratio? it is I can not understand the manual sometimes. If I wanted to convert 0V to 3.3V to rc servo values pulse out would this work please? |
||||
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 3503 |
Hi Stanleyella, As far as I know the interpolate function will not do this. You should use MATH ADD and MATH SCALE See below where I scale an array of measurement values. First you determine the gain (out range/in range) I subtract an input offset (math add) The scale to output range (math scale) Then adjust screen position (offset) by math add. The 2 math add steps could be done in one, but I decided for this 2 steps since it makes code better understandable. 'convert the rmt() data to display data rmd() gain=76/(rmsmin-rmsmax) Math add rmt(),-rmsmax,rmd() 'rmd is also a double buffer Math scale rmd(),gain,rmd() Math add rmd(),161,rmd() 'put the data in the window Edited 2022-09-25 05:58 by Volhout PicomiteVGA PETSCII ROBOTS |
||||
stanleyella Guru Joined: 25/06/2022 Location: United KingdomPosts: 1641 |
More like the arduino map function but in basic. Thanks @Volhout, I will research. ' OPTION EXPLICIT ; This library is free software; you can redistribute it and/or ; modify it under the terms of the GNU Lesser General Public ; License as published by the Free Software Foundation; either ; version 2.1 of the License, or (at your option) any later version. ; This library is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ; Lesser General Public License for more details. ; You should have received a copy of the GNU Lesser General Public ; License along with this library; if not, write to the Free Software ; Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ;******************************************************************************** ; IMPORTANT: ; THIS FILE IS ESSENTIAL FOR SOME OF THE COMMANDS IN GCBASIC. DO NOT ALTER THIS FILE ; UNLESS YOU KNOW WHAT YOU ARE DOING. CHANGING THIS FILE COULD RENDER SOME GCBASIC ; COMMANDS UNUSABLE! ;******************************************************************************** ; 18.02.2018 Initial release to the world. ; Re-Scales a number from one range to another. That is, a value of fromLow would get Scaled to toLow, a value of fromHigh to toHigh, values in-between to values in-between, etc. ; Does not constrain values to within the range, because out-of-range values are sometimes intended and useful. The constrain() function may be used either before or after this function, if limits to the ranges are desired. ; Note that the "lower bounds" of either range may be larger or smaller than the "upper bounds" so the Scale() function may be used to reverse a range of numbers, for example ; myvalue = Scale( InValue , 1, 50, 50, 1) ; ; The function also handles negative numbers well, so that this example ; myvalue = Scale( inValue, 1, 1023, 50, -100) is also valid and works well. ; ; The Scale() function uses integer maths. function scale ( in l_map as word, in l_fromLow as integer, in l_fromHigh as integer, in l_toLow as integer, in l_toHigh as integer) as integer dim l_syscalc as integer dim l_syscalcF as long l_syscalcf = 0 repeat (l_toHigh - l_toLow) l_syscalcf = l_syscalcf + ( l_map - l_fromLow ) end Repeat l_syscalc = ( l_fromHigh - l_fromLow ) scale = (l_syscalcf / l_syscalc) + l_toLow end function |
||||
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 3503 |
Note that the math functions work on arrays(bulk data). The arduino map funtion on single data points. For a single datapoint ( one adc value at a time) simple multiply and add are sufficient. No need to use math. My example scales 320 datapoint in these 3 lines to screen coordinates. PicomiteVGA PETSCII ROBOTS |
||||
stanleyella Guru Joined: 25/06/2022 Location: United KingdomPosts: 1641 |
@Volhout- for instant conversion from 0 to 3.3V value to 0 to 270 degrees on a lcd would need maths I can not remember. There is probably a formula for every thing. |
||||
phil99 Guru Joined: 11/02/2018 Location: AustraliaPosts: 1776 |
As 0V = 0 deg. and 3.3V = 270 deg. Since 0 = 0 no offset needed just the scale factor of 270 / 3.3 Vin = Pin(x) Angle = 270 / 3.3 * Vin 'degrees For a servo there is a minimum pulse width, that will be the offset and the range will be Max Pulse Width - Min Pulse Width which is divided by the voltage range to get the scale factor. Vin = Pin(x) PW = MinPW + (MaxPW - MinPW) / (3.3 - 0.0) * Vin Edit Wiki - " The control signal is a digital PWM signal with a 50 Hz frame rate. Within each 20 ms timeframe, an active-high digital pulse controls the position. The pulse nominally ranges from 1.0 ms to 2.0 ms with 1.5 ms always being center of range. " For a PWM frequency of 50Hz the period is 20mS and MinPW is 5% and MaxPW is 10% to get 0 to 270 deg. rotation. PWM (%) = 5 + 5 / 3.3 * Vin . Edited 2022-09-25 17:51 by phil99 |
||||
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 3503 |
Just a practical remark: typical RC servos have a guarantied travel of +/- 60 degrees, and most will do +/-90 degrees. But 270 degrees of travel is not common. Phil99's proposal should work. But it may not give you the full +/-90 degrees. For that you may need to find the limits by varying PWM from 4% to 11% (in stead of 5% to 10%). The 5-10 is guaratied to work with all servos. The 4-11 may not work on the servos you have. But try you can. So the math would be PWM = 4 + adc*7/3.3 The PWM value can be a float. I.e. 6.53% Edited 2022-09-25 20:07 by Volhout PicomiteVGA PETSCII ROBOTS |
||||
stanleyella Guru Joined: 25/06/2022 Location: United KingdomPosts: 1641 |
Hi. I was discussing a "map" or "scale" function that I have used but not with mmbasic. I have many micro SG90 servos that I use 650uS-2400uS pulses to move. I found some old code that draws a dial that matches a rotary pot's rotation and drove a servo that matched it. It used the new then scale function and it is a useful function. 8bit pics/avr not much ram for arrays. I am trying to convert the previous basic integer scale that is admitted was ripped from arduino code. I will post if successful. Take care, stan |
||||
stanleyella Guru Joined: 25/06/2022 Location: United KingdomPosts: 1641 |
Hi, This first scale attempt works for scale 0-100 to 0-255. 50=128, 100=255. Someone cleverer than could make this a function but no idea about floats. option explicit dim integer l_syscalc,l_syscalcf,l_fromHigh,l_fromLow,scale,l_toHigh,l_toLow,lim1,l_map l_fromLow=0:l_fromHigh=100:l_toLow=0:l_toHigh=255 ' 0 to 100 scaled 0 to 255 l_map=100 ' value to scale 'the scale code l_syscalcf = 0 lim1=l_toHigh - l_toLow do while lim1>0 l_syscalcf = l_syscalcf + ( l_map - l_fromLow ) lim1=lim1-1 loop l_syscalc = ( l_fromHigh - l_fromLow ) scale = (l_syscalcf / l_syscalc) + l_toLow cls text 0,0,str$(scale) ' lcd display l_fromLow=0:l_fromHigh=33000:l_toLow=0:l_toHigh=255 ' 0 to 33000 scaled 0 to 255 l_map=12000 ' value to scale gives 93 Edited 2022-09-26 07:44 by stanleyella |
||||
stanleyella Guru Joined: 25/06/2022 Location: United KingdomPosts: 1641 |
Try it. I am not good at sums. Please improve it. option explicit dim integer l_syscalc,l_syscalcf,l_fromHigh,l_fromLow,scval,l_toHigh,l_toLow,lim1,l_map,sc l_fromLow=0:l_fromHigh=100:l_toLow=0:l_toHigh=1024 do cls for l_map=0 to 100 scale text 0,0,str$(l_map) text 48,0,str$(scval) ' lcd display pause 100 next pause 1000 loop sub scale 'the scale code l_syscalcf = 0 lim1=l_toHigh - l_toLow do while lim1>0 l_syscalcf = l_syscalcf + ( l_map - l_fromLow ) lim1=lim1-1 loop l_syscalc = ( l_fromHigh - l_fromLow ) scval = (l_syscalcf / l_syscalc) + l_toLow end sub cls text 0,0,str$(scval) ' lcd display |
||||
Tinine Guru Joined: 30/03/2016 Location: United KingdomPosts: 1646 |
But does anyone have an example of MATH INTERPOLATE? It's a head-scratcher for me |
||||
stanleyella Guru Joined: 25/06/2022 Location: United KingdomPosts: 1641 |
In the mathematical field of numerical analysis, interpolation is a type of estimation, a method of constructing new data points based on the range of a discrete set of known data points. Wikipedia y=y_{1}+\left(x-x_{1}\right) \frac{\left(y_{2}-y_{1}\right)}{\left(x_{2}-x_{1}\right)} y = linear interpolation value x = independent variable x_1, y_1 = values of the function at one point x_2, y_2 = values of the function at another point It does not seem to be in the manual MATH Simple functions MATH(ATAN3 x,y) MATH(COSH a) MATH(LOG10 a) MATH(SINH a) MATH(TANH a) Simple Statistics MATH(CHI a()) MATH(CHI_p a()) MATH(CORREL a(), a()) MATH(MAX a() [,index%]) The math function performs many simple mathematical calculations that can be programmed in Basic but there are speed advantages to coding looping structures in C and there is the advantage that once debugged they are there for everyone without re-inventing the wheel. Returns ATAN3 of x and y Returns the hyperbolic cosine of a Returns the base 10 logarithm of a Returns the hyperbolic sine of a Returns the hyperbolic tan of a Returns the Pearson's chi-squared value of the two dimensional array a()) Returns the associated probability in % of the Pearson's chi-squared value of the two dimensional array a()) Returns the Pearson’s correlation coefficient between arrays a() and b() Returns the maximum of all values in the a() array, a() can have any PicoMite User Manual Page 128 MATH(MEAN a()) MATH(MEDIAN a()) MATH(MIN a(), [index%]) MATH(SD a()) MATH(SUM a()) Vector Arithmetic MATH(MAGNITUDE v()) MATH(DOTPRODUCT v1(), v2()) Matrix Arithmetic MATH(M_DETERMINANT array!()) |
||||
JohnS Guru Joined: 18/11/2011 Location: United KingdomPosts: 3650 |
You may be using an out of date manual as it's in mine (e.g. for picomite). John |
||||
phil99 Guru Joined: 11/02/2018 Location: AustraliaPosts: 1776 |
MATH INTERPOLATE in1(),in2(), ratio, out() This command implements the following equation on every array element: out = (in2 - in1) * ratio + in1 Arrays can have any number of dimensions and must be distinct and have the same number of total elements. The command works with bot integer and floating point arrays in any mixture eg > clear > dim a(1)=(5,20), b(1)=(15,30), r=0.5, x(1) > MATH INTERPOLATE a(), b(), r, x() > Print x(0),x(1) 10 25 > |
||||
CaptainBoing Guru Joined: 07/09/2016 Location: United KingdomPosts: 1985 |
Map() function here |
||||
Tinine Guru Joined: 30/03/2016 Location: United KingdomPosts: 1646 |
This command implements the following equation on every array element: out = (in2 - in1) * ratio + in1 Arrays can have any number of dimensions and must be distinct and have the same number of total elements. The command works with bot integer and floating point arrays in any mixture eg > clear > dim a(1)=(5,20), b(1)=(15,30), r=0.5, x(1) > MATH INTERPOLATE a(), b(), r, x() > Print x(0),x(1) 10 25 > Thanks Phil....this could be darned useful Craig |
||||
Print this page |