|
|
View previous topic :: View next topic |
Author |
Message |
sshahryiar
Joined: 05 May 2010 Posts: 94 Location: Dhaka, Bangladesh
|
Arduino's "map" function in CCS |
Posted: Wed Nov 28, 2012 10:39 pm |
|
|
In Arduino there's a very useful function called map. It simply scales an input to a desired output scale. For example you wish to scale 0-1023 count of an ADC to 0-5 volt range or take a value and represent it in some other scale which is much more easy to understand. In such cases the map function does this scaling for you. The limitation of this function is it only works in linear scales. However it can also be used to interpolate non-linear relations by calling it with different ranges for different segments. Here's the code for map function in CCS:
Code: |
double map(double value, float x_min, float x_max, float y_min, float y_max);
double map(double value, float x_min, float x_max, float y_min, float y_max)
{
return (y_min + (((y_max - y_min)/(x_max - x_min)) * (value - x_min)));
}
|
Example:
Code: |
#include <16F877A.h>
#device adc = 10
#device *= 16
#fuses HS, PUT, NOWDT, PROTECT, CPD, NOBROWNOUT, NODEBUG, NOLVP, NOWRT
#use delay(clock = 10MHz)
#include <lcd.c>
double map(double value, float x_min, float x_max, float y_min, float y_max);
void main()
{
unsigned int16 count=0;
float v=0;
lcd_init();
setup_adc(adc_clock_internal);
setup_adc_ports(AN0);
set_adc_channel(0);
for(;;)
{
count = read_adc();
v = map(count, 0, 1023, 0, 5);
lcd_gotoxy(1,1);
printf(lcd_putc,"V: %1.3f V ", v);
lcd_gotoxy(1,2);
printf(lcd_putc,"ADC: %4lu ", count);
}
}
double map(double value, float x_min, float x_max, float y_min, float y_max)
{
return (y_min + (((y_max - y_min)/(x_max - x_min)) * (value - x_min)));
}
|
[img]http://imageshack.us/photo/my-images/248/adcm.png/[/img]
Enjoy.
_________________ https://www.facebook.com/MicroArena
SShahryiar |
|
|
sshahryiar
Joined: 05 May 2010 Posts: 94 Location: Dhaka, Bangladesh
|
Constrain Function |
Posted: Sun Dec 02, 2012 8:39 am |
|
|
In addition to the map function, we can also use a function called constrain to limit an input within a specified boundary.
Code: |
float constrain(float value, float value_min, float value_max);
float constrain(float value, float value_min, float value_max)
{
if(value >= value_max)
{
return value_max;
}
else if(value <= value_min)
{
return value_min;
}
else
{
return value;
}
}
|
_________________ https://www.facebook.com/MicroArena
SShahryiar |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Sat Dec 22, 2012 2:26 pm |
|
|
This is an interesting general purpose function. Thank you.
However, its time domain performance may be a MAJOR problem if
you are needing maximum execution speed from the program that you graft it to. Though simple to express, there is an awful lot of floating point math for the processor to slog through, and the user should be careful to insure that the overhead of this all-purpose approach is not too much of a cycle-hog.
Since the number of cycles used is influenced by the values being 'mapped' , it may be very hard to know just how much average time it will occupy in any program that uses it. |
|
|
sshahryiar
Joined: 05 May 2010 Posts: 94 Location: Dhaka, Bangladesh
|
|
Posted: Sun Dec 23, 2012 10:10 pm |
|
|
Yes you are correct and I'm trying to improve this function so that the above mentioned facts can be minimized. Thanks. _________________ https://www.facebook.com/MicroArena
SShahryiar |
|
|
jacktaylor
Joined: 02 Sep 2017 Posts: 75
|
Re: Arduino's "map" function in CCS |
Posted: Sun Aug 12, 2018 12:25 pm |
|
|
I was looking for an explanation like that. I am passing a code in Arduino to the CCS compiler. I was having trouble figuring out how I could do normalization. So when driving a motor with a signal read from a potentiometer, the motor would rotate clockwise increasing the speed from zero to the maximum, the potentiometer being the maximum value ADC = 1023. With the potentiometer at 512 the motor must be stopped and with the potentiometer in ADC = 0, the motor must rotate in the reverse direction. The arduino program does just that, now with this explanation the code is already working. Great content.
Thanks for the topic still being posted after so many years.
sshahryiar wrote: | In Arduino there's a very useful function called map. It simply scales an input to a desired output scale. For example you wish to scale 0-1023 count of an ADC to 0-5 volt range or take a value and represent it in some other scale which is much more easy to understand. In such cases the map function does this scaling for you. The limitation of this function is it only works in linear scales. However it can also be used to interpolate non-linear relations by calling it with different ranges for different segments. Here's the code for map function in CCS:
Code: |
double map(double value, float x_min, float x_max, float y_min, float y_max);
double map(double value, float x_min, float x_max, float y_min, float y_max)
{
return (y_min + (((y_max - y_min)/(x_max - x_min)) * (value - x_min)));
}
|
Example:
Code: |
#include <16F877A.h>
#device adc = 10
#device *= 16
#fuses HS, PUT, NOWDT, PROTECT, CPD, NOBROWNOUT, NODEBUG, NOLVP, NOWRT
#use delay(clock = 10MHz)
#include <lcd.c>
double map(double value, float x_min, float x_max, float y_min, float y_max);
void main()
{
unsigned int16 count=0;
float v=0;
lcd_init();
setup_adc(adc_clock_internal);
setup_adc_ports(AN0);
set_adc_channel(0);
for(;;)
{
count = read_adc();
v = map(count, 0, 1023, 0, 5);
lcd_gotoxy(1,1);
printf(lcd_putc,"V: %1.3f V ", v);
lcd_gotoxy(1,2);
printf(lcd_putc,"ADC: %4lu ", count);
}
}
double map(double value, float x_min, float x_max, float y_min, float y_max)
{
return (y_min + (((y_max - y_min)/(x_max - x_min)) * (value - x_min)));
}
|
[img]http://imageshack.us/photo/my-images/248/adcm.png/[/img]
Enjoy.
|
|
|
|
|
|
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
|
Powered by phpBB © 2001, 2005 phpBB Group
|