New User Get $30 User Coupons https://jlcpcb.com/CYT
Other Users Get SMT Coupons via Contacting JLCPCB Facebook
The map() function fails to properly distribute its output range to its input range.
Subscribed to my 2nd channel? Watch all my 3 minute videos on Julian's Shorts: https://www.youtube.com/channel/UCeewzdnwcY5Q6gcbnZKIY8g
Interested in my new garden workshop? Follow the entire build on Julian's Shednanigans:
https://www.youtube.com/channel/UCXfDjPehpC7B7lW2JFxeS4w
Join me on Odysee/LBRY: https://lbry.tv/$/invite/ @julian256:d
Octopus Energy referral link: share.octopus.energy/aqua-birch-918
(We each get £50)
#EasyEVSE
#ElectronicsCreators
Other Users Get SMT Coupons via Contacting JLCPCB Facebook
The map() function fails to properly distribute its output range to its input range.
Subscribed to my 2nd channel? Watch all my 3 minute videos on Julian's Shorts: https://www.youtube.com/channel/UCeewzdnwcY5Q6gcbnZKIY8g
Interested in my new garden workshop? Follow the entire build on Julian's Shednanigans:
https://www.youtube.com/channel/UCXfDjPehpC7B7lW2JFxeS4w
Join me on Odysee/LBRY: https://lbry.tv/$/invite/ @julian256:d
Octopus Energy referral link: share.octopus.energy/aqua-birch-918
(We each get £50)
#EasyEVSE
#ElectronicsCreators
I guess just map to one higher and then constrain the range in a further step to always be one 1000th step down from that top value. This restores entire range and removes top jitter.
Actually, it's a matter of definition. What is a "map" function intended to do? For some applications, the behavior of the "map" function makes sense. For yours, it does not. That's why documentation, and better an example, is important in coding. Also testing, especially edge cases, is also important.
This is the map function.
long map(long x, long in_min, long in_max, long out_min, long out_max) {
return (x – in_min) * (out_max – out_min) / (in_max – in_min) + out_min;
}
It's your expectation that's wrong, not the function.
This is the map function.
long map(long x, long in_min, long in_max, long out_min, long out_max) {
return (x – in_min) * (out_max – out_min) / (in_max – in_min) + out_min;
}
It's your expectation that's wrong, not the function.
Map worked as I expected, you solved it in the exact same way I would have done it.
I had the same thought everybody else had, but I actually watched the video so I know he's already using a constrain() function.
Hey Julian. Maybe a small box-filter will average out( settle down) your ADC value from the pot? I have seen where the lowest 5 or 6 bits of the ADC reading on a PIC12F683 is very noisy on the lower bits. A box filter of say 40 values makes it much more stable. Cheers from Canada.
Fun fact:
Pam is map backwards.
Julian, you might consider putting a statement after that pwm map to cap the value at 0x29. (Something like if(pwm > 0x29) pwm = 0x29; ) If the Arduino folks ever changed the behavior of this function to something like you describe, a future software update could cause your EVSE to start drawing excess power at the top end. Maybe also look at putting a decoupling cap on the potentiometer wiper to debounce it a bit?
If this is adjusting the power into the car I would test the power variable and limit its value to your max power before using it in the map function. You can't trust the value to be correct after passing through your radio system.
"That's an odd anomaly of the map() function".
Actually, things like this are very common in coding, in general.
If you were to do the math and code the mapping by-hand, I think you'd see why. This is an extension of Y=MX+B. Fractions are inherent, but Most general-purpose math functions like these use integer math. (must look at the function declaration to see, integers in, integers out).
Another commenter actually included the map() source. And, my guess is, this is a standard C function, so has been defined exactly this way on every machine compiling C since the 1980's. [And even if map isn't Standard C, there are MANY standard functions which have this so-called anomaly, which is not an anomaly at all, and is in the definition]. Which is to say, folk rely on these functioning exactly this way, and it should not be considered an anomoly, nor something to change. If you want different functionality, consider writing or finding e.g. a fmap(). Where f=floatingPoint, or rmap() where r=rounding.
Fractions are not rounded in integer-math. Nor, IIRC, in conversion from floats to ints.
There is a trick for integer rounding: say you're doing N/6, and want a rounded result. Then instead do (N+3)/6. This will give you standard rounding, where anything above 0.5 gets rounded-up.
There are other such tricks, such as (N+5)/6, and (N+1)/6. Each of these techniques has a purpose, and if your numbers really matter (e.g. if they're going to be used in more math down the line), then it's important to consider such things on a case-by-case basis. Often-times things like scaling (as you're doing with map()) should be the very last step (which can mean a lot of math done by-hand), so that small errors introduced at each step don't add up to big errors.
E.G. If doing N/6+5, it might be wise to consider, instead, doing (N+3+30)/6. But, of course, keep in mind that now you may need to consider longer integers.
Further, look again at the map() definition, it works with long ints. Every time you call it, it has to convert your ints to long, then do long math, then convert them back to ints… This is rather CPU-intensive. Akin to using "digitalWrite()" rather than writing to the PORTA register, directly.
I've been doing things like this, in C, for 25years, this sort of integer-math was a huge part of my Intro To C class. I only recall hearing of map() within the last few years, and have seen it several times since. I gather it somehow became rather popular as a result of folks' doing exactly what you've done… and the large "community" of folk learning from them. Thank you for highlighting this case.
Try this:
static inline float mapf(float in, float inMin, float inMax, float outMin,
float outMax) {
return (outMax – outMin) * (in – inMin) / (inMax – inMin) + outMin;
}