I have no idea why this has been happening:
byte potenciometro = 0;int redpin=9;
void setup() {
Serial.begin(9600);
}
void loop() {
int valor=analogRead(potenciometro); delay(50);
Serial.println();
Serial.print(valor, DEC);
analogWrite(redpin,valor); }
This code above has been working just fine. However, i understand the LEDs will work properly with intensities that range from 1 to 255, so i replaced this line
Serial.print(valor, DEC);
for this Serial.print((valor/700)*255, DEC);
and all that the IDE has been returning since then is 0 as console output.
i tried also just
Serial.print(valor/700, DEC);
and i get nothing but 0s
anyone?
my arduino is the UNO version.
2 Answers 2
In the C family of programming languages, the division operator (/
),
when used with integer arguments, provides an integer division. You
get the integer quotient, and you can use %
to get the remainder.
If you want a floating point division, then at least one of the arguments should be a floating point number. E.g.:
Serial.print(valor / 700.0 * 255);
(the DEC
argument is redundant). The final result is then truncated to
an integer before being passed to Serial.print()
.
A better option, which is outlined in dhimaspw's answer, is to do the
multiplication before the division. This way you avoid costly floating
point operations. If you do that, however, you should be careful about
overflows: valor*255
can be as big as 1023 ×ばつかける 255
=わ 260865, which is larger than the maximum value an int
can store
(215−1 = 32767). You should then write
Serial.print(valor * 255L / 700);
where the L
suffix forces the operation to be carried using long
integers.
The simplest solution, however, is to use the Arduino function map()
,
which does essentially the same as above:
Serial.print(map(valor, 0, 700, 0, 255));
-
Serial.print(valor / 700.0f * 255);
would work better. 700.0 is a double not a float and so by the rules of the c language that entire calculation is done as doubles. Adding thatf
in turns it into a float. On a low end microcontroller you really want to avoid doubles as much as possible, double operations are twice as slow as a floats and floats are slow enough already.Andrew– Andrew2016年12月06日 10:12:56 +00:00Commented Dec 6, 2016 at 10:12 -
1@Andrew: The OP is working on an Uno. A
double
is the same as afloat
on the AVRs.Edgar Bonet– Edgar Bonet2016年12月06日 10:41:27 +00:00Commented Dec 6, 2016 at 10:41 -
That in this particular case the standards aren't followed and so it doesn't make a difference isn't a good justification for inefficient coding. Pressing 1 extra key is a small price for a good habit and portable efficient code.Andrew– Andrew2016年12月06日 10:49:39 +00:00Commented Dec 6, 2016 at 10:49
-
Not meaning to nitpick but I'd just point out that mapping floats to doubles on the UNO is a software choice implemented in the gnu compilers, not hardware-driven at all as the hardware has no support for floating point. A different tool-set might well implement a different choice. So could a programmer using gnu for that matter, by defining an 'sfloat' (small- or single-precision float) object and its arithmetic operators.JRobert– JRobert2016年12月06日 21:13:47 +00:00Commented Dec 6, 2016 at 21:13
Using Serial.print (xx,DEC)
will give you a number on decimal base (round number). That's why your first code works
To solve this, you just simply change to
Serial.print((valor*255/700),4) //4 digits behind comma
-
i tried adding this before the analogWrite valor=((valor*255/700),4); but the intensity of the led remains fixedDavid Spira– David Spira2016年12月06日 07:30:18 +00:00Commented Dec 6, 2016 at 7:30
-
AnalogWrite only receive round numbers.duck– duck2016年12月06日 07:33:48 +00:00Commented Dec 6, 2016 at 7:33
-
2This solution overflows for values over the 128 (analog read returns values 0..1023) and it doesn't really explain why
valor/700
is zero or one if the value is greater or equals to 700KIIV– KIIV2016年12月06日 10:14:57 +00:00Commented Dec 6, 2016 at 10:14
GND
and5V
(I suppose 3.3V)? If you have full scale values (0..1023) it's possible just divide the value by 4 to get result between 0 and 255.