# for loop reads pots, passes value to PWM pins, can this be in the same for loop?

In the code below I am using a `for` loop to iterate over analog pins (potentiometers) and pass their value, after being mapped, to `PWM` enabled analog output pins (currently controlling LED brightness). While this works as is, I am curious about the following: would it be better to split the `analogRead` and `analogWrite` lines into separate `for` loops, or would that simply be redundant from a code standpoint? My concern is accidentally mixing up the pot values due to difficult-to-perceive timing issues.

The code:

``````static const uint8_t analog_pins[] = {A0, A1, A2, A3};
static const uint8_t digital_pins[] = {3, 5, 6, 9};
int pot_vals[] = {0, 0, 0, 0};
int val[] = {0, 0, 0, 0};

void setup() {
Serial.begin(9600);

// setup inputs, outputs
for ( int i = 0; i < 4; i++ ) {
pinMode( analog_pins[i], INPUT );
pinMode( digital_pins[i], OUTPUT );
}
}

void loop() {
for (int i = 0; i < 4; i++) {
val[i] = analogRead(analog_pins[i]);
analogWrite(digital_pins[i], map( val[i], 0, 1023, 0, 255 ));
}
delay(2);
}
``````
• Analogue pins are configured as `input` by default. It is unnecessary to declare them in `setup`. – goddland_16 Jul 13 '17 at 5:16

## 2 Answers

Having both the `analogRead()` and `analogWrite()` in the same loop is perfectly fine. That would be be my preferred choice if only for one reason: less RAM consumption. If you split them in two loops, you have to store somewhere the readings of the four channels, either before or after mapping. If you keep them in the same loop, you don't need the `pot_vals[]` nor `val[]` arrays. You would use a local variable instead, which consumes no RAM:

``````void loop() {
for (int i = 0; i < 4; i++) {
int val = analogRead(analog_pins[i]);
analogWrite(digital_pins[i], map(val, 0, 1023, 0, 255));
}
delay(2);
}
``````

My concern is accidentally mixing up the pot values due to difficult-to-perceive timing issues.

“Difficult to perceive”? I would call these issues “imaginary” instead. You have no risk of “mixing” any values here. Maybe, if you can elaborate on the kind of issues you imagine you could have, we could help you clear some misunderstanding about how the microcontroller executes your code.

Edit: To expand on Andrew's comment, the `for` loop can be optimized as

``````for (int i = 0; i < 4; i++) {
unsigned int val = analogRead(analog_pins[i]);
analogWrite(digital_pins[i], val / 4);
}
``````

Dividing the value by 4 is the best way to map the input range to the output range. It gives a more uniform mapping than the `map()` call above, as every output value is mapped to exactly 4 input values. It could be noted, though, that `map(val, 0, 1024, 0, 256)` gives the same uniform mapping.

The division by 4, however, is optimized by the compiler into a bit shift, which is orders of magnitude faster than `map()`, and likely to consume less stack space. There is one caveat to be aware of: this optimization is only possible if `val` is unsigned. If it is signed, then it is compiled into a call to a division routine, which is quite expensive.

One could be tempted to go even further and get rid of the temporary `val` variable, like:

``````for (int i = 0; i < 4; i++) {
analogWrite(digital_pins[i], (unsigned int) analogRead(analog_pins[i]) / 4);
}
``````

However, there is zero benefit from doing so: from the point of view of an optimizing compiler, this form is exactly equivalent to the previous one. I prefer the former which I deem more readable.

• If you want to really simplify the code and minimize memory usage then you could even do: `for (int i = 0; i < 4; i++) analogWrite(digital_pins[i], analogRead(analog_pins[i])/4);` – Andrew Jul 13 '17 at 7:55
• @Andrew: Your comment is both right and misleading: a naive reader may wrongly think that your not using the intermediate `val` variable is what reduces the memory footprint. – Edgar Bonet Jul 13 '17 at 16:48

Obviously you can. Except that in most cases your loop execution is much faster than your own period so that you end up changing the duty cycles multiple times in one period.

Not an advisable aporoach. If you have to do it think about configuring the pwm center aligned.
{"ft_lang_label":"__label__en","ft_lang_prob":0.8818486,"math_prob":0.92675006,"size":2302,"snap":"2021-04-2021-17","text_gpt3_token_len":611,"char_repetition_ratio":0.09094865,"word_repetition_ratio":0.04950495,"special_character_ratio":0.26498696,"punctuation_ratio":0.14376321,"nsfw_num_words":0,"has_unicode_error":false,"math_prob_llama3":0.9551138,"pos_list":[0],"im_url_duplicate_count":[null],"WARC_HEADER":"{\"WARC-Type\":\"response\",\"WARC-Date\":\"2021-04-10T13:58:15Z\",\"WARC-Record-ID\":\"<urn:uuid:b7c4b4ac-10fb-4428-8b85-22712ca10604>\",\"Content-Length\":\"176450\",\"Content-Type\":\"application/http; msgtype=response\",\"WARC-Warcinfo-ID\":\"<urn:uuid:85817876-dbe5-4c27-b615-6e47ffc00e0e>\",\"WARC-Concurrent-To\":\"<urn:uuid:65443fdd-b288-4c0b-9aab-04e096d4d093>\",\"WARC-IP-Address\":\"151.101.65.69\",\"WARC-Target-URI\":\"https://arduino.stackexchange.com/questions/41561/for-loop-reads-pots-passes-value-to-pwm-pins-can-this-be-in-the-same-for-loop\",\"WARC-Payload-Digest\":\"sha1:3DQ6IZDEVLRJKCPHOZPQGD3CKGXZTKKI\",\"WARC-Block-Digest\":\"sha1:G2JN7KMIAEEUHRVLEELENAEHXBI5ZVFN\",\"WARC-Identified-Payload-Type\":\"text/html\",\"warc_filename\":\"/cc_download/warc_2021/CC-MAIN-2021-17/CC-MAIN-2021-17_segments_1618038057142.4_warc_CC-MAIN-20210410134715-20210410164715-00100.warc.gz\"}"}