map function

Dear All,

I read some topics about this subject but I still not understand how map is working... I need to tell you I'm a Arduino's beginner, and I'm not sure "map" is the good function for my application.
I try to generate at the output a "triangular signal" using a coarse of a pot; I explain, when I turn the pot from zero to the middle of it coarse I would like to increase the voltage at the output to a max voltage (easy) but at the middle of the coarse of the pot I would like the voltage at the output start to decrease and goes to zero when the pot continu it coarse.
In fact with one coarse of the pot the output increase and decrease...
I'm crazy? :confused:

Or to go up and down with the max output at the centre position...

void loop()
{
  int potVal = analogRead(A0);

  int val = map(potVal,0,1023,0,200);

  if (val > 100)
  {
    val = 200 - val;
  }

  Serial.println(val);
  delay(1000);
}

Martin,

Great thank you for your reply,
Yes to go up and down with the max output at the center of the pot... of course your sentence is evidently more explicit than my long text.
As I'm a very strong beginner I have had another problem :
I try to insert an output for a LED in your code, but unsuccessfully... sorry to ask you again where I could define any analog output in your code to see the LED light goes up and down with the pot?

I try to insert an output for a LED in your code, but unsuccessfully.

Please post what you tried.

The easiest way, which is a very poor example would be

const int ledPin = 9;

void loop()
{
  int potVal = analogRead(A0);

  int val = map(potVal,0,1023,0,200);

  if (val > 100)
  {
    val = 200 - val;
  }

  Serial.println(val);

  analogWrite(ledPin, val * 2);

  delay(1000);
}

The analogWrite() function takes two parameters, the pin number and the value to write. This value can have the range of 0 to 255, but in the code above I’ve simply doubled val which will give 0 to 200.

It’s very sloppy coding, so I’ll leave it to you to correct it to give full range output.
You’ll need to use a PWM pin (pin 9 is OK on anything 328p-based), and don’t forget a resistor in series with the LED.

Have a go and post your code if it doesn’t work.

Hello Martin,

Wonderful... It's working now with this code :

" int sensorPin = A0;
int ledPin = 9;
int sensorValue = 0;

void setup() {
pinMode(ledPin, OUTPUT);
}

void loop()
{
int potVal = analogRead(A0);

int val = map(potVal,0,1023,0,255);

if (val > 125)
{
val = 255 - val;
}

analogWrite(ledPin, val * 2);

delay(50);
} "

Another great thank's for your patience

Have a nice day.

Rather than using a sawtooth shape, you can use a parabolic shape.

int potVal = analogRead(A0);
int smoothedVal = potVal * (1023-potVal);
int val = map(smoothedVal,0,256*255,0,200);

PaulMurrayCbr:
Rather than using a sawtooth shape, you can use a parabolic shape.

int potVal = analogRead(A0);

int smoothedVal = potVal * (1023-potVal);
int val = map(smoothedVal,0,256*255,0,200);

Warning: 512 * (1023-512) will not fit in an int. Use a long.
Warning: 256255 is not the highest value. 512511 is.
Note: the top of the output range should be 255 for a PWM output.

int val = map(potVal,0,1023,0,255);

map() is a pretty expensive way to divide by 4.

The way I would do it:

const int sensorPin = A0;    
const int ledPin = 9;      

void setup() {
  pinMode(ledPin, OUTPUT);
}

void loop() {
  int val = analogRead(sensorPin);

  // fold over the upper half of the range
  if (val > 511)
    val = 1023 - val; // 512->511, 1023->0

  // 'val' is now a number from 0 to 511


  // Divide by 2 to get it into the 0-255 range for analog write
  analogWrite(ledPin, val / 2);

  delay(50);
}

Very glad to see my question so discussed.

If I could ask you another question... But I'm afraid to do that in this forum which is plenty of strong developer!

Who to divide by 3 the coarse pot and obtain 3 min and 3 max on the output?
As the pot turn for 270°, I would like from 0° to 90° the output go up, then between 90 ° and 180° the output decrease to 0 and in final from 180° to 270° the output go up.

I looking for that since this morning and I have currently a headache :-).

So if it is easy for you, my eyes are open with interest.

Thanks for your help.

1/3 of 1023 is 341.
2/3 of 1023 is 682.

const int sensorPin = A0;    
const int ledPin = 9;      

void setup() {
  pinMode(ledPin, OUTPUT);
}

void loop() {
  int val = analogRead(sensorPin);

// 0-341 -> 0-341
// 342-682 -> 340-0
// 683-1023 -> 1-341

  if (val > 682)
    // Upper third of the range goes 1 to 341
    val = val-682;
  else
  if (val > 341)
    // Middle third goes from 340 to 0
    val = 682 - val;

  // 'val' is now a number from 0 to 341

  // Map into the 0-255 range for analog write
  analogWrite(ledPin, map(val, 0, 341, 0, 255));

  delay(50);
}

you should check multimap - http://playground.arduino.cc/Main/MultiMap -

#include "MultiMap.h"

const int sensorPin = A0;    
const int ledPin = 9;      

int in[] = { 0, 341, 682, 1023 };
int out[] = { 0, 255, 0, 255 } ;

void setup() 
{
  pinMode(ledPin, OUTPUT);
}

void loop() 
{
  int val = analogRead(sensorPin);
  analogWrite(ledPin, multiMap(val, in, out, 4));
  delay(50);
}

If you need a more complex curve, just add points to the in and out arrays
and adjust the (last) length parameter in the multimap() call.

you must place the MultiMap code in a MultiMap.h file of course.

Hello,

My project is now ok.

With one pot, I command a RVB LED with your help.
Each color have different curve due to the pot :
The red have 2 up and down in one coarse.
The blue have 3 down and up in one coarse.
the green have the inverse curve of the blue.
here the code if you want to see :

Marilou_RVB.ino (1.95 KB)