==================================
That's because the random() function is not random, it's psuedorandom. If you watch carefully, you should be seeing the exact same sequence every time you run the program. There is also the randomseed() function which generates a new seed number for the random() function. This is from the Arduino site:
If it is important for a sequence of values generated by random() to differ, on subsequent executions of a sketch, use randomSeed() to initialize the random number generator with a fairly random input, such as analogRead() on an unconnected pin.
--Randy
Modeling the Reading Railroad in the 1950's
Visit my web site at www.readingeastpenn.com for construction updates, DCC Info, and more.
Mel,
One thing I've noticed is that your setup routine is a little off. You've got the LED pins defined as 0-13, but the for loop goes from 1-14 (i = 1, numleds = 14). As such, when you run it, pin 0 will be undefined, and pin 14 will be set up as an output even though it's not in use.
As for why pin #9, I suspect it's because the Arduino random function is really pseudo-random. Namely, it returns the next member in a sequence of numbers, and this sequence is actually set, not generated. As such, it'll return the same numbers for each execution. It would appear that the output of the random function is triggering the conditions to activate pin 9 each time the sketch is run.
The randomseed function (https://www.arduino.cc/en/Reference/RandomSeed) initiates the random number generator to a different point in the sequence. I would suggest putting this in your startup routine, to initiate the random number generator. There are two approaches you could take:
1) Put a different number in the randomseed function for each Arduino.
2) Perform an analogread() on an undefined & unused analog pin, and feed this into the randomseed function on startup. Given that the analog pin isn't in use, the value of the read from it will be random.
I've used approach no. 2 in my own programming.
The Location: Forests of the Pacific Northwest, OregonThe Year: 1948The Scale: On30The Blog: http://bvlcorr.tumblr.com
"sketch?"Why not, oh, say... "program?"
Disclaimer: This post may contain humor, sarcasm, and/or flatulence.
Michael Mornard
Bringing the North Woods to South Dakota!
RR_Mel Thanks for your input guys! I’m not a programmer! I’m an old electronics guy, a very old electronics guy! All 14 ports in my sketch work as is. I didn’t notice that all the Arduinos had the same sequence, I seldom turn them on at the same time so I guess that puts them out of sync and not noticeable. I don’t believe in fixing something that isn’t broke so I don’t think I’ll attempt to change my sketch. It took some doings just to get it to work and I’m afraid if I attempt to change it I’ll screw it up.
As others have noted, your "for" loop doesn't include port 0. The Arduino pins default to inputs, and writing "high" to an input enables its internal resistor, which will dim your LED, though as you have observed it still works.
I get that if you don't want to change your code that's fine, but it just takes a few seconds, so I've copied your code here with the appropriate changes others have already mentioned in case you change your mind:
Bayfield Transfer Railway "sketch?" Why not, oh, say... "program?"
I figured that Arduino uses "sketch" for "program."It annoys me. It annoys me when neologims are used for concepts we already have words for. It's one of the things that pissed me off so much about Java. Enough with the "cute" coffee puns already, those things all have names.
Arduino was originally designed for artists. The word 'program' scares artists. So they called it a 'sketch'. I am not an artist (the mess in front of me as I try to draw out even a simple schematic for a Tortoise controlling signals in a good example - but none of the electronic CAD programs I have contain a Tortoise as a component. LEDs, sure. Diodes, Sure. Turtles? Nope). I write programs for my Arduinos - actually I only use the Arduinos for development, my finished project will have just the ATMegas 328P microcontroller and supporting components. In fact, half the time I use Visual Studio to develop my programs rather than the Arduino IDE.
The sketch/programming language used in the Arduino is a version of the 'c' programming language. If interested, obtain a book on the Arduino 'c' as that 'c' is not a full 'c' or 'c++'. Confusing!
PukkaArduino 'c' as that 'c' is not a full 'c' or 'c++'.
can you give an example of something you can do in c/c++ that you can't do on an Arduino?
greg - Philadelphia & Reading / Reading
Well, Arduino isn't directly based on C or C++, it's actually based on Wiring. It's very close to C++ but not exactly the same. Unless you're a hardcore C++ programmer, it doesn't really matter much.
You can of course directly access the micro's control registers in Arduino, or program an Arduino using Atmel Studio and use 'pure' C. To do so, you directly manipulate the control registers and port registers in the Atmega chip. It's WAY faster than pinMode, digitalWrite, and digitalRead. But you need to keep track of each bit of the port register yourself and use bitmasking to turn a given pin on and off. If you need ultimate performance, direct control in Arduino is the first step. If that's STILL not fast enough, then direct programming with Atmel Studio is the way to go. They may only be 8 bit, and run at 16MHz, but the ATMega 328 used in the Uno and Nano are actually pretty fast. Most of the things we need for model railroads, the speed you get using the Arduino IDE to code is plenty fast enough.
i see gcc tools under ther hardware/. Looks like it's using the GNU compiler which is standard c/c++ which we use on our small-cell project.
rrinkerYou can of course directly access the micro's control registers in Arduino, or program an Arduino using Atmel Studio and use 'pure' C.
don't understand how accessing HW registers is relavent to the question.
There are various ways of accessing HW registers affecting multiple I/O pins with different features and performance. This is an age old problem. Can't you write your own version versions of digitalWrite/Read that are faster, if needed?
still looking for an example
You should be able to use an C/C++ construct, so long as you observe the limits of the microcontroller - there are differences around floating point support since the ATMega series used in common Arduinos is only an 8 bit processor and doesn't have the scratch register space to to high precision math. This affects double and float types - it's pretty well documented on the Arduino site.
The reverse is not true though, since Arduino's flavor has extensions from Wiring as part of the language which will not be in standard C/C++. This is where the HW register access is relevent. Unless you write your own routines and call them the same name, an Arduino program won't compile in stock C.
Does any of it matter? You can program these things with anything you are comfortable with. The Arduino IDE is a bit simplistic and doesn't do much more than I can do with Notepad++ but you can always use the Visual Studio add-in that I do and leverage VS (free edition even) as a superior IDE yet still have the convenience of a button to upload the program to the Arduino like in the Arduino IDE. Or you can go whole hog and use Atmel Studio (which is VS with Atmel's add ins) and write directly to the hardware. There's a lot of animosity on the aprt of 'professional' embedded programmers towards the Arduino IDE. True it is lacking compared to high end professional development systems, but it does get the job done and allows people who might not be able to do so to write working code. I think it's a good thing, as it hides the complexity of working with the HW registers and lets you focus on just learning the C syntax and program flow. Once you've got that down you can take the next step and replace all the digitalWrite, digitalRead, and pinMode stuff with direct register access. One step at a time.
Arduino Wiring Guide as used at a college.
are you guys suggesting that Arduino C is not standard C because functions like pinmode() and DigitalWrite() aren't part of any standard C library?
There are some differences in data types as well. boolean and byte aren't standard C types. They do map to bool and unsigned char for the most part but Arduino code with such type declarations won;t just compile in a C compiler.
It's close enough, but it's not exactly standard C.
rrinker It's close enough, but it's not exactly standard C.
i'm curious how people understand what a language is.
one difference I see is that the IDE must wrap the .ino file within another more standard c/cpp file with additional includes (one reason it's not a .c/cpp file). One include is Arduino.h (hardware/arduino/avr/cores/arduino/Arduino.h). I need to explicitly include arduino.h in my .c/cpp files in multi-file projects.
Arduino.h includes several standard includes (e.g. stdlib, string, math), common Arduino #defines (e.g. HIGH, INPUT_PULLUP), typedefs (e.g. boolean, byte), and function declarations (e.g. pinMode, analogWrite, delay).
these things (e.g. HIGH, byte, delay()) are not part of the language, they are conventional customizations for the Arduino environment.
rrinkerThere are some differences in data types as well. boolean and byte aren't standard C types.
arduino.h uses typedefs to define new data types from existing ones:
typedef unsigned int word; typedef bool boolean; typedef uint8_t byte;
bool is a standard C++ data type and uint8_t is typedef'd in stdint.h as unsigned char. Unsigned int is standard C which doesn't define the size of an int.
rrinkerThey do map to bool and unsigned char for the most part but Arduino code with such type declarations won;t just compile in a C compiler.
I have taken Arduino code, added these typedefs and stubs for pinMode(), digitalWrite(), ..., and compiled an Arduino application with the standard GNU compiler (I use cygwin on windows). This is a good way to simulate and save time during embedded program development.
Our small-cell project is required to use stdint.h which defines uint8_t, int16_, uint32_t, ... for variables outside file scope. They are not defined by the language and this usage is becoming common industry practice. Our small-cell project has functions similar to pinMode() and digitalWrite() that are unique to our system and application.
we recently upgraded to c++14. It adds some esoteric features that i'm unlikely to ever use. It doesn't mean that the code i wrote 20 years ago is not C++.
the point is, the Arduino build environment provides all the superfluous coding needed to build an Arduino application using a standard, flexible and mature programing language rather than write their own language (C-51). This makes it easy for novices to create Arduino programs and use Arduinos for custom and intelligent electronic projects. Much better than the KIM-1 I started with.
In some wyas it's better than the days of old - the smaller 8 bit micros may be the clooses thing to the old processors that there is, in that the raw machine language is actually learnable. I stopped assembly after the 8088 was done, the further extensions they kept adding made it near impossible to memorize all the opcodes. The instruction set of modern processors - I don't even want to contemplate the number of opcodes.
My first machine was an RCA CDP1802. It has 91 op codes, most of which I still remember. I still have that computer and it still works - I can fire it up and do some simple demo programs purely from memory. My second foray into machine code was the Z80 on a friend's TRS-80. Don't really remember a whole lot of it but when I see some code I can begin to recall it. Third attempt was 6502, same as the KIM-1, but on an Apple II. My program for the advanced BASIC class in HS was too slow to update the video, so I redid the video routines in assembly. And was that ever a pain in the rear - I was so used to the 1802, with 16x 16 bit registers, any of which could be the program counter, a pointer, or whatever. And even the Z80 had quite a few registers, although not quite as flexible as the 1802 (PC and X were fixed). The 6502 though - almost no registers to speak of. Even the simpliest of tasks required you to build a stack and stack pointer and keep track of it all. I got my project working, but I hated that processor from the get-go.
There certainly are productivity gains using higher level languages, but the higher you get, there is always some tradeoff. The simplicity of Arduino statements like pinMode and digitalWrite are a good example - they are a fraction of the speed of direct register manipulation, but infinitely easier to understand.
The rare times I need to write code at work that's more than Powershell scripting, I typically use VB.NET as various BASIC dialects are still the languages I have the moost experience with. For simple Powershell scripts I just type them in a text editor, but for more complex needs (and you can do a LOT with Powershell) I usually use the Quest PowerGUI IDE (free). The microcontroller stuff is all personal/hobby stuff and the simplicity of Arduino wins out. I haven't yet hit a level where the program runs too slowly and I need to resort to direct register manipulation, but even if I do, Atmel's designs seem MUCH easier to use than Microchip's (and I really hope Microchip doesn't ruin the Atmega series). I have a few development systems for smaller PICs, but never went very far with them as they seem extremely complicated. I've also seen some of the examples for the newer 32 bit micros and if the amount of code required to simply blink an LED is any indications - no thanks. I am firmly of the opinion that if an 8 bit device can fully meet the requirements, there is zero point in throwing a 32 bit device at the problem just because 32 > 8. There are so many applications where 16MHz and 8 bits are PLENTY to accomplish the task with a more than satisfactory response time. There is a tendency today to throw more hardware at problems that don;t need more hardware, just for marketing purposes. I recently got a new iPad, only because I finally managed to drop my old one and smashed the screen. The new one has a processor that is much faster and has more cores than the old one. But it doesn't read books or read my email any faster (my two main uses of it). I never would have gotten a new one had I not smashed the old one.
Anyway this has gotten way off the original topic which really was imply the difference between random and psuedorandom number generators and how to seed the random function in an Arduino (a similar function is available in most programming languages to keep each 'random' pattern from being the same).
I will close by saying it is far from just me who calls these dialect differences new 'languages'. It seems like ever other dya there is an article on the 'latest and greatest' programming language which are often given cute names but when you look are really just c/c++ varients, or Java derivatives. It's like the latest trend is to write (or modify) a compiler to 'invent' your own language that solves some (but never all) shortcomings in the original language. There are very few truly NEW languages coming out.
rrinkerIf it is important for a sequence of values generated by random() to differ, on subsequent executions of a sketch, use randomSeed() to initialize the random number generator with a fairly random input, such as analogRead() on an unconnected pin.
won't an unconnected analog input be pulled high or low? The inputs are multi-function and there's lots of circuitry hanging on the pin (datasheet pg 73)
for this purpose, wouldn't it better to tie it to a noisy signal or a sinusoid so that it's value is constantly changing, maybe even an RC?
The analog pins have input pullup disabled by default - would cause a bit of a problem if the analog pins were pulled high. Unless otherwise definied, the analog pins are floating, so they will return various values depending on the surrounding environment - like leaving a scope probe flapping in the breeze and not grounded. The majority input will likely be picking up the 60Hz AC sine.