Just experimenting/learning code. Using Pro-mini on a sketch that had been proven on Uno.
It is the age old "KIT" flashing inline led from on end and back.
Had set up a breadboard with 12 LEDs and wired it to my Uno board. It ran very well. Then built a proto board with 8 LEDs and connected it to run in tandem. All good there.
Then decided to try Pro-mini, utilizing my proven code, I adjusted out put from pin 2 - pin 13 to run pin 2 - pin 9. The code compiled and verified and uploaded. The LEDs ran, except pin9 did not illuminate the LED.
Checked the LED by connecting to pin 8, LED proved good. Tested output of pin 9 with another LED using 330 ohm resistor and saw a dim illumination. Then tested output utilizing my Hantek scope and saw a low voltage output on pin 9 compared to other pins. The output was ~2.2vdc while the others were ~2.9vdc.
After that, connected Pro-mini to breadboard circuit with 12 LEDs, uploaded code utilizing pi 2 - pin 13 and all LEDs function normal.
Not that it is critical, yet my mind wonders "why did this happen", why did pin 9 have low output when the code ran pins 2 - 9 and all is good when it runs pins 2 - 13?
Below is the original code/sketch. The only modification made was the pin 13 was changed to pin 9. Any advice would be appreciated.
Thank you for entertaining my thread.
// LEDs from pins 2 through 13 to ground
//rewitten 6_25
//by Bill Schmid
//modified 30 Aug 2011
//by Tom Igoe
//his example code is in the public domain.
//https://www.arduino.cc/built-in-examples/ForLoopIteration
int Time; // The higher the number, the slower the timing.
int Pin; // Declare Pin
void setup() {
// use a for loop to initialize each pin as an output:
for (int Pin = 2; Pin < 13; Pin++)
{
pinMode(Pin, OUTPUT);
}
//Initialize timer variable
Time = 50;
}
void loop() {
// loop from the lowest pin to the highest:
for (int Pin = 2; Pin < 13; Pin++)
{
// turn the pin on:
digitalWrite(Pin, HIGH);
delay(Time);
// turn the pin off:
digitalWrite(Pin, LOW);
}
// loop from the highest pin to the lowest:
for (int Pin = 13; Pin > 2; Pin--)
{
// turn the pin on:
digitalWrite(Pin, HIGH);
delay(Time);
// turn the pin off:
digitalWrite(Pin, LOW);
}
}
the countdown is similarly flawed, as pin 2 does not get written, but 13 does.
Suggest you review carefully the three parameters of a for loop, and in particular the conditions around loop termination.
The declaration of a second Pin variable within the loop context is also problematic.
Basically the loop variable is often seperate from the actual thing (in this case a pin number) because the for loop uses 0 (zero) based numbering. Here is an example, there are many ways of doing this
for (int inxPin = 0; inxPin < 2; inxPin++){ // inxPin will have values 0, 1
pinMode((inxPin+1), OUTPUT); // pins being set to output are 1, 2
{
If you start at 2 in the loop, that will change pin 3 in your code.
Ye gods, no. Just use an array of pin numbers, use a for loop to iterate the array, and be done with it.
Why introduce offset-by-one math in such an obtuse manner? It will be incomprehensible tomorrow, much less a month from now, and is totally unnecessary.
FYI, I have never used an array of pins, can't tell you why.
Interesting side note: an engineer told me that every pin on an MCU must be set to a specific value. I don't recall what it was, but I assume LOW. That would dictate an array for sure, so why don't I see sample sketches that do that in any way? So far it has; it bit me, so I choose to ignore the UK Engineer.
I'm a strong advocate of the array approach. Use it wherever I can. Whether it's just an array of input pins and an array of output pins, or something more complex like using an array of structs having both, it makes code very 'transparent'. Additionally, in many cases you can have a simple processing logic which processes all the ins and outs as a loop. In extremis, loop() itself is looping, so one element of the array can be processed each time through loop.
re: side note - Interesting. A loooonnnnngggg time ago, that would have been expected, because output stages could 'oscillate' unless asserted, but I don't think it's an issue in anything modern. For one thing, most pins are by default input, for obvious reasons. If it needs to be an output, set it so. Now, once you have an output, you need to consider what the hardware will do
before the output is set as an output, when it is an input but might have a pullup - or not
what the initial state will be when it becomes an output
how long it might be before a desired state is applied to the output
what the connected circuit will do with all of the above
The above can often be observed when Arduinos are connected to LEDs or relays, resulting in a pulse on, then off, then on again in some cases.
Because arrays are deemed 'too scary for beginners', quite excessively in my mind. It's somewhat of a mystery to me, because there is very little magic or mystery, if explained in the right context.
IIRC, the Arduino documentation states that the pins are in a high-impedance state. My high school training in electronics, about 65 years ago, didn't cover impedance in the same way it is understood today. I still don't fully understand it, but I manage to get by.
I think your bulleted points suggest that in some cases, I need to write 'HIGH' or 'LOW' depending on the situation before the pinMode statement. Again, IIRC that prevents a 'pulse' going down the line, which can be pretty exciting in some scenarios.
It also depends on the board. From memory, the following will result in a HIGH output on an R3, but a LOW output on an R4. On the R4, pinMode sets the output LOW regardless.
what part of that did you not understand? The for loop iterates from 2 to 8, the terminating condition of 9 means it does nothing with that value. Hence, pin not set.
This is the problem several of us have pointed out with your for loops. There are many fixes, but it would be better if you took the time to comprehend how for loops work, rather than us just fixing code for you - if we do that, you'll be back time and again for the same problems.
Ok, the code was from a library. As mentioned, I am fairly new to coding (the language looks strange to me, trying to understand it, not easy from my current view) and looking to find where I am going wrong and how to do better. Can you elaborate on why "int Pin; // Declare Pin" is not used? And/or why it was used in the code I obtained? Not questioning your reasoning, just looking for more answers.
Thank you for your response :^)
Hi, you are saying pin 2 does not get written. Trying to understand, as pin 2 is an output. Would it not function if not written?
Please excuse my noobness, where can I find info about the 3 loop parameters and loop termination?
The for loop executes the following:
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
...
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);
It does not do pin 13(because 13 is not less than 13, so the loop terminates). Similarly, if you changed 13 to 9, pin 9 would not be done.
The increasing and decreasing loops within loop() have similar end condition problems.
As I pointed out to @sonofcy, a simple array of pin numbers would feed all 3 loops consistently. Read about, and think about, arrays, because if you'll be coding in C/C++, they'll be your lifeblood.
camsysca, you are making a valid point, thank you. I definitely want to understand, not just fix a problem. Have been wrestling with learning code for some time and it has not made much sense to me. So you state that the for loop iterates from 2 to 8, and the terminating condition of 9 will not do anything with that value. Yet changing the 9 to 13 will run all the pins 2 through 13 as intended. So this is confusing for me.
Again, I am not looking for a "fix". I want to understand the why.
Can you possibly direct me to text that might give that understanding?
Thank you again for having patience with me, I understand it can be frustrating to attempt to help someone, have been there myself, as a retired automotive tech it has happened. I understand cars, at least the ones that are older than 15 years :^)