Forum - MCS Electronics

Author Message
Dave Joined: 05 Feb 2005
Posts: 270
Location: McMinnville, OR  Posted: Fri Jun 27, 2014 7:35 pm    Post subject: C map function This is the C map function converted to bascom.

The map function is very handy for converting analog input to a more usable range for display.

Here is the description from the C reference manual:
 Quote: map(value, fromLow, fromHigh, toLow, toHigh) Description Re-maps a number from one range to another. That is, a value of fromLow would get mapped 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 map() function may be used to reverse a range of numbers, for example y = map(x, 1, 50, 50, 1); The function also handles negative numbers well, so that this example y = map(x, 1, 50, 50, -100); is also valid and works well. The map() function uses integer math so will not generate fractions, when the math might indicate that it should do so. Fractional remainders are truncated, and are not rounded or averaged.

Here is a bascom example:
 Code: \$regfile = "m88def.dat" \$crystal = 8000000 \$baud = 38400 \$hwstack = 50 \$swstack = 50 \$framesize = 50 declare function map(x as Integer , byval in_min as Integer , byval in_max as integer , byval out_min as integer , byval out_max as Integer) as Integer dim i as integer dim x as integer for i = 100 to 500    x = map(i , 100 , 500 , 0 , 100)   'map 100-500 to 0-100    print i;" = ";x next end function map(x as integer , byval in_min as integer , byval in_max as integer , byval out_min as integer , byval out_max as integer) as integer    local i1 as long    local i2 as long    i1=x - in_min    i2=out_max - out_min    i1=i1 * i2    i2=in_max - in_min    i1=i1/i2    i1=i1 + out_min    map = i1 end function  snipsnip Joined: 10 Feb 2014
Posts: 66
Location: Melbourne  Posted: Sat Feb 28, 2015 2:09 am    Post subject: just want to say thanks, a handy function. I was trying to figure out how to do this, had smoke coming out my ears. Good for GLCD's - Should make writing a GPS graphical track log viewer easy. maybe even 3D views?? cheers  i.dobson Joined: 05 Jan 2006
Posts: 1541
Location: Basel, Switzerland  Posted: Sat Feb 28, 2015 10:05 am    Post subject: Hello,

And here's my version:-

 Code: '----------------------------------------------------------------------------- Dim Sensor_accumulator(10) As Long                          'Sensor smoothed Dim Sensor_raw(10) As Word                                  'Sensor Raw Dim Sensor(10) As Integer                                   'Actual value Dim Sensor_long As Long Dim Sensor_value_long As Long Dim Sensor_float As Single Function Smooth_sensor(byval Sensor_value As Word , Byval Array_position As Byte , Byval Scale_sensor As Byte) As Integer    'Function    : Scale and smooth value using array position as pointer    'Author      : Ian Dobson    'Inputs      : None.    'Outputs     : None    'Limitations :    'Changes     :    'Date        : 6.5.2014    Dim Accumulator As Long    'smooth raw value    Sensor_value_long = Sensor_value                         'Add new    Sensor_long = Sensor_accumulator(array_position)         'Load value into temp var.    Accumulator = Sensor_long                                'This is the old average on LONG form    Shift Accumulator , Right , Smoothing_factor(array_position)       'Accumulator sum divided by 2^smoothing factor    Sensor_raw(array_position) = Accumulator                 'Save raw value    Sensor_long = Sensor_long - Accumulator                  'Subtract old value    Sensor_long = Sensor_long + Sensor_value_long    Sensor_accumulator(array_position) = Sensor_long         'Save accumulator for next time    If Smoothing_factor(array_position) = 0 Then             'NO Smoothing       Sensor_raw(array_position) = Sensor_value_long        'Pass raw value    End If    If Scale_sensor = 1 Then       'generate real value       Sensor_float = Sensor_raw(array_position) - Zeropoint(array_position)       'Subtract 0 point       Sensor_float = Sensor_float / Scale_factor(array_position)       'Scale raw to actual       If Sensor_float > 0 Then          Sensor(array_position) = Sensor_float              'Return integer          Smooth_sensor = Sensor_float       Else          Sensor(array_position) = 0          Smooth_sensor = 0       End If    Else       'no scaling required       Sensor(array_position) = Sensor_raw(array_position)       Smooth_sensor = Sensor_raw(array_position)    End If End Function

The function smooth's and scales the input value writing the result to an array. The function expects:
The raw value to be scaled
Array position/Sensor number (Used for writing the result and finding the Zero/Span/Scaling factors)
Should the sensor be scaled Yes/No (1/0)

The function expects the following arrays to be defined
Zeropoint, this holds the raw value for the scaled 0 point
Scale_factor, this holds the scaling factor (number of raw points for 1 scaled unit)
Sensor_raw, this holds the raw smoothed but not scaled sensor value (This can be used to calculate the span during sensor recalibration).

I'm using this code on a project with currently 10 different sensors each with their own scaling/zero/smoothing factors. On start up the AVR reads the values for Zero/Span/Smoothing from an eeprom then starts scanning all the sensors.

Regards
Ian Dobson

_________________
Home of AVRTimer, the Bascom timer value calculator.
http://www.planet-ian.com

Walking on water and writing software to specification is easy if they're frozen.   Meister Joined: 27 May 2010
Posts: 314 Posted: Sat Feb 28, 2015 5:50 pm    Post subject: http://www.vias.org/tmdatanaleng/cc_scaling.html
This does scaling (mapping) without AVR divisions:
 Code: 'Example: Assume Temp4 linear function of Servo angle Const Datamax = 7160 Const Datamin = 1430 Const Servomin = 14.5 Const Servomax = 53.9 Const C1 =(servomax -servomin) /(datamax -datamin) Const C2 =(servomin * Datamax -servomax * Datamin) /(datamax -datamin)   Dim  Temp4 As Single 'consider you measured Temp4=1500 and would like to know what the Servo angle was Temp4=1500 Temp4 = Temp4 * C1 Temp4 = Temp4 + C2

yields Temp4=53.418674
So the range from Datamin to Datamax ("X-axis") is mapped linearly to the range from Servomax to Servomin ("Y-axis").
The input range is not limited to Datamin to Datamax.
Using this frequently.
Regards, Meister  Dave Joined: 05 Feb 2005
Posts: 270
Location: McMinnville, OR  Posted: Thu Sep 03, 2020 1:02 am    Post subject: @i.dobson, @Meiter Thanks for the reply's and suggestions. Sorry I took over 5 years to respond. I think I'll be switching to Meiter mapping method from now on. Nice improvement. Thanks for the tip.  six1 Joined: 27 Feb 2009
Posts: 553  Posted: Fri Sep 04, 2020 5:56 am    Post subject: @Dave Meister's procedure only makes sense, if Data is available at compile time! if you'll get data from Sensors, you'll better go with i.Dobson best, michael_________________For technical reasons, the signature is on the back of this message.  Display posts from previous: All Posts1 Day7 Days2 Weeks1 Month3 Months6 Months1 Year Oldest FirstNewest First

 Jump to: Select a forum BASCOM AVR/8051----------------BASCOM-AVRBASCOM-8051BASCOM-ARDUINOShare your working BASCOM-8051 code hereShare your working BASCOM-AVR code hereBASCOM BETA-SLA BASCOM Related----------------EASY TCP/IPAVR-DOSAR7212KokkeKat FAT-free SD card libBASCOM Project Blog Other Stuff----------------VariousPCB'sRoboticsNew WebSiteAnnouncementsAVR Archive----------------BASCOM-AVR ArchiveBASCOM-8051 ArchiveBASCOM-AVR Unsupported versionsEasy TCP/IP ArchiveBASCOM-EDB
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 vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum