I'm very new to the Arduino/Microcontroller-world, so please be patient :)
I have 4 potentiometers and I want my LED to blink up, when one of these is beeing used.enter image description here
So far., so good.. the potentiometers are sending singnals to my inputs A0-A3. In the code I read and buffer the values of send to the inputs, so when a new value is recieved (potentiometer is beeing used), the funcion blinkLED()
is beeing triggered:
int ledPin = 13;
int pin[] = {A0, A1, A2, A3};
int cc[] = {20, 21, 22, 23};
int potiValues[] = {0, 0, 0, 0};
int potiValuesTmp[] = {0, 0, 0, 0};
void setup() {
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
}
void loop() {
// READ EVERY PIN
for(int i=0; i<=3; i++){
potiValues[i] = map(analogRead(pin[i]), 0, 1023, 0, 127);
if(potiValues[i] != potiValuesTmp[i]) {
// NEW VALUE RECIEVED - MAKE OUTPUT
Serial.println("Pin ");
Serial.print(pin[i]);
Serial.print(" - ");
Serial.print("Value: ");
Serial.print(potiValues[i]);
blinkLED();
}
potiValuesTmp[i] = potiValues[i];
}
}
void blinkLED() {
digitalWrite(ledPin, HIGH);
delay(1000);
digitalWrite(ledPin, LOW);
}
It somehow works on the emulator circuits.io
, but I'm not sure if I did it right(?) Maybe someone could have a look and tell me, what to improve?
But my main question is:
When the function blinkLED()
is triggered, there is this delay,.. does the whole loop()
-function wait, too?
-
Put a resistor in series with your LED or it will damage both the LED and the Arduino. 150 Ω or higher would be suitable. See LED calculator.Nick Gammon– Nick Gammon ♦2016年12月24日 04:42:23 +00:00Commented Dec 24, 2016 at 4:42
2 Answers 2
When the function blinkLED() is triggered, there is this delay,.. does the whole loop()-function wait, too?
Yes, when you call a function it doesn't return until it is done, and delay
is blocking.
You can rewrite a bit like this:
int ledPin = 13;
int pin[] = {A0, A1, A2, A3};
int cc[] = {20, 21, 22, 23};
int potiValues[] = {0, 0, 0, 0};
int potiValuesTmp[] = {0, 0, 0, 0};
void setup() {
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
}
unsigned long lastFlash;
int flashesToGo;
const unsigned long flashTime = 50; // ms
void loop() {
// READ EVERY PIN
for(int i=0; i<=3; i++){
potiValues[i] = map(analogRead(pin[i]), 0, 1023, 0, 127);
if(abs (potiValues[i] - potiValuesTmp[i]) > 3) {
// NEW VALUE RECEIVED - MAKE OUTPUT
Serial.print("Pin ");
Serial.print(pin[i]);
Serial.print(" - ");
Serial.print("Value: ");
Serial.println(potiValues[i]);
flashesToGo = 10;
potiValuesTmp[i] = potiValues[i];
}
}
// flash LED if required
if (flashesToGo > 0) // need more flashing?
{
// is it time to toggle the LED?
if (millis () - lastFlash >= flashTime)
{
// toggle LED
if (digitalRead (ledPin) == HIGH)
digitalWrite (ledPin, LOW);
else
digitalWrite (ledPin, HIGH);
// remember when we did it
lastFlash = millis ();
// count down
flashesToGo--; // one less flash
} // end of time for another flash
}
else
digitalWrite (ledPin, LOW); // ensure LED off
}
What this does is add to the main loop a few lines of code that toggle the LED after a certain time is up (50 ms currently). It counts down the number of toggles from a desired starting point (eg. 10) until they are all done. This means that the LED will flash without blocking.
Each time you detect a new analog reading the number of flashes is reset back to the maximum.
I modified your test for if the analog reading changed to be:
if(abs (potiValues[i] - potiValuesTmp[i]) > 3)
I found that without that, the LED flashed continually because the readings were slightly different each time (eg. 51, 52, 51, 50) which would probably just be error in the ADC reading.
With that change, it doesn't count as "changed" unless the reading changes by 3 (you could make it more, or less than that).
I want the LED to blink up just once - when I turn one of the potentiometers
In that case change:
flashesToGo = 10;
to:
flashesToGo = 2;
That is one HIGH and one LOW (one flash in total).
Yes, the main loop (aka void loop) will have to wait during the delay. One method of escaping that problem is to use the millis()
function. There is an example code called "blinkWithOutDelay" (or something like that). It pretty much uses the ATmega's internal timer. This method is more for advanced users. The millis()
functions is will return you the number of milliseconds since the start of your program.
Also, potentiometers are always in use. They will report back data everytime. Its not like if it had too fixed states like ON or OFF. So the problem is that they are all in used at the same time. You might consider changing the values of potiValuesTmp
. My varying that variable, you can make it so that at least one potentiometer has to be higher then a certain point.
-
Hey, thank you very much, I will have a look on the mentioned example. Just to verify I have not misunderstood you with this potentiometers.. I did this in my code, didn't I ? I mean, I buffer the values in the array so I can detect, when a potentiometer is beeing.. "used" :) .. or, did I get something wrong here?crunchy– crunchy2016年10月24日 22:09:27 +00:00Commented Oct 24, 2016 at 22:09
-
well, if they aint all at the zero position, they will be considered as USED in your programDat Ha– Dat Ha2016年10月24日 22:11:11 +00:00Commented Oct 24, 2016 at 22:11
-
by used you mean used one time, right?.. but not "used live" (sorry I don't know how to say that) .. I want the LED to blink up just once - when I turn one ot the potentiometers .. just like a status-LED which says "here.. you just did something"crunchy– crunchy2016年10月24日 22:18:55 +00:00Commented Oct 24, 2016 at 22:18
-
change all the vals of potiValuesTmp[] to 512Dat Ha– Dat Ha2016年10月24日 22:22:58 +00:00Commented Oct 24, 2016 at 22:22
-
sorry, I don't get it :/crunchy– crunchy2016年10月25日 05:48:03 +00:00Commented Oct 25, 2016 at 5:48
Explore related questions
See similar questions with these tags.