map() uses whole numbers and does not stop at the limits. Wrap the result in constrain() to keep it in range.
What the message means
The function scales linearly. If the input goes past the input range, the output goes past the output range too.
Fix it in this order
- Check that the input range matches what the sensor really gives.
- Wrap the result as constrain(map(x, a, b, c, d), c, d).
- For fractions, multiply first or use your own float formula.
- For a reversed range, swap the output limits, as in map(x, 0, 1023, 255, 0).
- Print the raw value to check the real range.
Why it happens
map() applies a straight-line scaling from one range to another, and it does the arithmetic with whole numbers. Any fraction is dropped, so a small output range loses detail, and an input outside the stated range gives an output outside the stated range, because the function does not clip it.
constrain() clips the result to the limits you choose. If you need fractions, scale the numbers up before you map and scale down afterwards, or use floating-point arithmetic on your own.
If you see this, do this
| You see | Do this |
|---|---|
| Output above the maximum | Add constrain(). |
| Steps look coarse | map() uses integers. |
Related
integer division, joystick centre.
Last reviewed: November 2026. These are the usual causes and the order that finds them fastest. Test on your own board; clones and cables differ.
Why this happens
The map() function computes (x – in_min) * (out_max – out_min) / (in_max – in_min) + out_min using long integers. The division is integer division, so the fraction is cut off, not rounded. The formula is a straight line that continues forever, so an input outside the input range gives an output outside the output range.
Both effects follow from the design. Mapping 0 to 1023 onto 0 to 10 can only produce 11 different values, and each value covers roughly 93 input counts. The function never clips; clipping is your job.
How to confirm the cause
- Print the raw input and the mapped output side by side for a range of inputs.
- Move the sensor through its full travel and note the smallest and largest raw values. If they are not the in_min and in_max you wrote, the mapping is off.
- Check the inputs below in_min and above in_max. If the output goes beyond your limits there, you need constrain().
- Work one value out by hand with the formula and compare. A difference of one count is truncation.
- If you wrote your own formula with int variables, check for overflow: on an Uno an int holds up to 32767.
Worked example
Hand-checked values for map(x, 0, 1023, 0, 255).
x = 512 : 512*255/1023 = 130560/1023 = 127.6 -> map gives 127
x = 1100 : 1100*255/1023 = 280500/1023 = 274.2 -> map gives 274 (above 255)
x = 3 : map(3, 0, 1023, 0, 10) = 30/1023 -> 0
int raw = analogRead(A0);
int pwm = constrain(map(raw, 0, 1023, 0, 255), 0, 255);
float volts = raw * (5.0 / 1023.0); // use float maths when you need fractionsCommon mistakes
- Using 0 and 1023 as the input range when the sensor really gives 200 to 800.
- Expecting rounding. The result is always cut down.
- Passing float values and expecting float results. map() works on long integers.
- Writing raw * 255 / 1023 with int variables. raw * 255 can reach 260865, which overflows a 16-bit int on an Uno.
- Adding constrain() to the input only and forgetting the output.
If this did not fix it
- Noise in the analog reading, which makes the mapped value flicker. Average a few readings.
- A joystick whose centre is not exactly 512, so the neutral position gives a small non-zero output. Add a dead band.
- A reference voltage other than 5 V, which changes what the 0 to 1023 range means.