Struggling with switching Arduino and Random numbers

Sorry Mike, I have had enough. I cant work it out and I dont understand what your clues are.

I am wasting my time and I think its better if I just use the picaxe as I am confident I can do that and wont be wasting anyone elses time or my own.

To be perfectly honest I am not impressed with the way all the program codes etc are set out. It makes no sense to me that only some of the stuff is shown under reference and other stuff is not and you have to try and hunt high and low to find it.

I spent a crap load on a book from Arduino that I was told would contain all the code necessary and when I got home I find it just has a bunch of projects and nothing else to help me.

Thanks for everything.

Mazza: A certain amount of discouragement and fruatration is normal. There is a lot to learn, and as you say it is not always set out in the easiest way. Don't give up.

I took the time to go through your code and produce something closer to what you want. Let me offer some feedback about what I found while editing.

  1. The construct 'if (x=HIGH)' should be 'if (x==HIGH)'. Note carefully the difference. The first one assigns HIGH to X. The second one tests whether x is equal to HIGH. If you use the first where you think you are using the second one you get an interesting debugging experience.

  2. The construct 'if (x==HIGH');' should not have the semicolon after it. Semicolon is a statement. This construct says "if X is HIGH do nothing", and the following statement is executed without regard for the if. Another interesting debugging experience. Use if(x==HIGH) {stmt;stmt;stmt;} instead.

  3. The code wasn't consistently indented to reflect the nesting structure. This will trip up your eyes when you try to find bugs. Adopt a consistent style, preferably by reading and imitating code from people you like. Fortune favors those who keep their code neat as a pin.

  4. Thinking carefully about the algorithm pays off. Look how much simpler the loop() is below.

byte whichpin = 3;	// set to 3 so turning it off is harmless

void setup() {
    Serial.begin(9600);          
    randomSeed(analogRead(0));
    pinMode(2,INPUT);
    pinMode(3, OUTPUT);
    pinMode(4, OUTPUT);
    pinMode(5, OUTPUT);
    pinMode(6, OUTPUT);
    pinMode(7, OUTPUT);
    pinMode(8, OUTPUT);
    pinMode(9, OUTPUT);
    pinMode(10, OUTPUT);
}

void loop() {
	if (digitalRead(2)) {
		digitalWrite(whichpin, LOW);
		whichpin = random(3,10);
		digitalWrite(whichpin, HIGH);
	}
}

There is a lot of fun to be had here when things are working correctly, but a certain amount of frustration is part of the bargain. Stick with it, you'll figure it out.

-br

Hi Mazza!
you post code in your reply#1 in which condition of IF statement like that

if(ranNum==3)
        {
        digitalWrite(3, HIGH);
        }

but in your reply#21

if(signal=LOW)                                                   //the input turns off
break;

and

if(signal=HIGH);

By looking first reply it's mean you know how to use IF statement

"=" is you used for assignment
== is you used for comparing

Why you put terminator ";" at the end of third IF statement
if(signal=HIGH);

Cyber, yeah cheers, stupid mistake partly because of exhaustion and partly because I am struggling with the syntax.

Billroy, cheers for that mate and also a perfect example of why I am having so many problems and frustrations...........there simply is no such thing as a whichpin in the code section.

I am used to having a book full of code, there uses, syntax and options sitting next to me so I can compare them all and then pick and choose what I want.Well thats how it was in Basic days........lol. I still have all those old books.

I am totalled for tonight so gunna hit the sack.............Im in Australia and its quite late/early morning actually. However tomorrow I will give that a run but more importantly try to understand what its doing and why.........I consider that as important as having it work.

Im a sparky by trade so the wiring and hardware is pretty much straight forward for me with just the odd calculation that I have to look up here and there that is no longer in my head. But this programming thing.............lol, well.

By any chance is there a decent book or website with the code that you would suggest?

Anyways off to bed and thanks again mate. Will post back, probably with a heap of questions tomorrow.

Best wishes.

Just so you will have something to wake up to:-

.there simply is no such thing as a whichpin in the code section.

First line of the code:-

byte whichpin = 3;

The code that Billroy posted will work too quickly and it will look like all the LEDs are on a bit dim. To slow it down add a delay(200) after the turning on of the LED.

I am used to having a book full of code, there uses, syntax and options sitting next to me so I can compare them all and then pick and choose what I want.

Nowadays it is on line a good place to start is here:-

The C language is very much like Basic. However my advice to you would be to go slowly and try and think why what is happening is happening don't just give up and try something else. When I learned to program it was on punch cards and you could only have one run a day. If something went wrong you thought about it rather than just try something else.
Actions are always logical, try and "play being the processor" that is doing each line in your head as the processor would. Remember it is very fast, if you turn on and LED and then OFF again you will not see it change.

Thanks Bill and Mike.

Unfortunately that code does exactly what I was already able to do.

The problem is that I only want it to generate one number for each pass of HIGH from input switch 2. That input switch will be staying HIGH for a variable ammount of time.
Once it goes to LOW then that should turn whatever output was on HIGH from the first pass through to LOW which it currently does.
Then when the input goes HIGH again, I want one more number generated
And so on.

I have had it at the stage where I can get just one to stay on by entering a WHILE loop but I dont seem to able to exit that loop when the input goes LOW.

That is where I am certain I had it all wrong but because I am struggling to understand the ; and the { } and how they affect things and when they can and cannot be used.

Everytime I had what I considered logical the verifier would force me to delete or add one or the other or tell me my BREAK was outside the loop etc. Then when I got things happy for the verifier the program would get stuck in the loop...........well either that or the random number generator always started at exactly the same number because the same number LED would be lighting every time.

Try this code:-

byte whichpin = 3;	// set to 3 so turning it off is harmless
int inputState=HIGH, oldState=LOW;
void setup() {
    Serial.begin(9600);          
    randomSeed(analogRead(0));
    for(int i=3;i<11;i++) {
     pinMode(i, OUTPUT); 
    }
    pinMode(2,INPUT);
}

void loop() {
 inputState = digitalRead(2);
	if (inputState != oldState) {  // a change has occoured
            if(inputState == HIGH) { // input high so turn on a random LED
		whichpin = random(3,10); // calculate what LED is to be on
		digitalWrite(whichpin, HIGH);  // set the LED on
            } // end of input high
            else { // here if input is low
                digitalWrite(whichpin, LOW); // turn of the LED that was on
            } // end of input is low
	} // end of a change has occoured
oldState = inputState;
}

Copy and paste it in. Read the comments. If it does not do what you want say again what you want and what it does.

Everytime I had what I considered logical the verifier would force me to delete or add one or the other or tell me my BREAK was outside the loop etc.

In any contest between a human and a compiler the compiler is correct in what is logical.
The braces enclose blocks of code and must be nested like this:-

{ code { code } code }

Thanks Mike,

What is happenning now is that everything works perfectly except that the same LED comes on every single time.

I have also reached this stage on numerous occasions and each time I have come up with the following options generally going with option 2 and offering poor syntax or coding and hence the reason I am here.

Either it is not random selecting

Stuck permanently in a loop

the first number selected in a random function is always the same.

Or is it possible that the analogread (0) which is supposed to be noise affected is not noise affected for the first run through?

Is it possible that the "noise" part of analogread has to be turned on? I have extreme doubts about this but hey just throwing it out there.

I just had an idea, is there anyway to run the random selector once doing nothing so that the second pass would end up selecting the useable random number? At least that would prove or disprove theories 3 and 4.

I have spent hours going through other peoples builds trying to find someone with a similar setup but no luck as yet..........well no luck from the point of view that I could fully understand what was being done and therefore to pick out the relevant bits.

PS if it means anything, turning everything off for a few minutes and then turning it all back on again does not change anything at all...........even the same LED blinks which is by the way output 3.

hmmmm..........is that a clue? 3 is the first of the series? I know it doesnt make sense and yes I am clutching at straws.

By the way, just to confirm for myself that everything is working fine at hardware level, I have tested the multiple blink program which has almost identical OUTLET setup and it works fine.

What is happenning now is that everything works perfectly except that the same LED comes on every single time.

OK
immediately after the loop add this line:-

void loop() {
 inputState = random(0,10);
 inputState = digitalRead(2);

What this will do is to keep on generating random numbers all the time. This will be out of sync with your external signal and so will randomize what you get.
Remember the same number coming on say four or five times in a row can still be a random number. Do you always want it to be a different number? While it is not random people often think this is what random numbers should do. If so then keep generating a number until it is different.

if(inputState == HIGH) { // input high so turn on a random LED
		whichpin = random(3,10); // calculate what LED is to be on
		digitalWrite(whichpin, HIGH);  // set the LED on

this should be:-

if(inputState == HIGH) { // input high so turn on a random LED
               int temp = whichpin;
		while(temp == whichpin) { whichpin = random(3,10); }// calculate what LED is to be on
		digitalWrite(whichpin, HIGH);  // set the LED on

Yes I definitely want a random number every time and yes that could mean the same one quite a number of times in a row.....Some call it luck, I call it variance.

However I left the program running for a good half hour and during that time it would have had the input switch turn on and off many hundreds of times and the chances of the same number coming up that many times are astronomical.

I have added the code and it has not changed anything except that now its selected number 7 as its lock in number so that removes the clue of the first number which I never really believed anyways. (see last post by me)

Looking at the way its coded though isnt the program selecting that random number and calling it inputState and then in the very next line changing it to equal digitalRead(2)?

Just to be 100% certain I have everything the way you intended...........

byte whichpin = 3;	// set to 3 so turning it off is harmless
int inputState=HIGH, oldState=LOW;
void setup() {
    Serial.begin(9600);          
    randomSeed(analogRead(0));
    for(int i=3;i<11;i++) {
     pinMode(i, OUTPUT); 
    }
    pinMode(2,INPUT);
}

void loop() {
  inputState = random(0,10);
 inputState = digitalRead(2);
	if (inputState != oldState) {  // a change has occoured
            if(inputState == HIGH) { // input high so turn on a random LED
		whichpin = random(3,10); // calculate what LED is to be on
		digitalWrite(whichpin, HIGH);  // set the LED on
            } // end of input high
            else { // here if input is low
                digitalWrite(whichpin, LOW); // turn of the LED that was on
            } // end of input is low
	} // end of a change has occoured
oldState = inputState;
}

Mike I just noticed an interesting thing, if I remove the input pin that is plugged into digital 2 and move it to say dig 1 or 0 or analog 1-5 then the same led continues to flash.
While the pin is unplugged nothing happens at all which is what you would expect but we have not set any of the other pins as anything?

By the way the signal is a regulated 5.oV DC input which I understand is well within specs.

and move it to say dig 1 or 0

Do not use digital pins 0 & 1 these have the serial signals on them and they make things more complex to use.

or analog 1-5 then the same led continues to flash.

Have you changed the code to reflect the change in pin. Using analogue pin 0 means you have to call it digital pin 14, with pin 15 for analogue 1 and so on.
If you don't change the code then yes it will continue to flash.
Are you saying that the latest code still flashes the same LED?

Yes it does mate. Been happily doing it now for about 20 mins or so

So still no change unfortunately.

How is the switch wired up?

This is very odd. I have just tried this code with a wire from pin 2 touching on the USB socket and print statements in place of LEDs lighting up. This works how I would expect it to, what happens for you?

byte whichpin = 3;	// set to 3 so turning it off is harmless
int inputState=HIGH, oldState=LOW;
void setup() {
    Serial.begin(9600);          
    randomSeed(analogRead(0));
    for(int i=3;i<11;i++) {
     pinMode(i, OUTPUT); 
    }
    pinMode(2,INPUT);
    digitalWrite(2, HIGH);
}

void loop() {
  inputState = random(0,10);
 inputState = digitalRead(2);
	if (inputState != oldState) {  // a change has occoured
            if(inputState == HIGH) { // input high so turn on a random LED
		whichpin = random(3,10); // calculate what LED is to be on
		// digitalWrite(whichpin, HIGH);  // set the LED on
                Serial.print(whichpin);
                Serial.println(" on");
            } // end of input high
            else { // here if input is low
                digitalWrite(whichpin, LOW); // turn of the LED that was on
                Serial.print(whichpin);
                Serial.println(" off");
            } // end of input is low
	} // end of a change has occoured
oldState = inputState;
}

Run the serial monitor to see the output.

I don't understand this:

  inputState = random(0,10);
 inputState = digitalRead(2);

What is the point of assigning inputState a random number and then assigning it a value based on a switch state?

One should go.

What is the point of assigning inputState a random number and then assigning it a value based on a switch state?

He was complaining that the random function always gave him the same number. So that was to spin the random number generator while the loop was idle as the actual number was picked on every transition of an external asynchronous signal. It is a cheap way of seeding.

As it turns out he still reports the random function is giving the same value so there is something going on that he is unaware that he is not telling us.

I suppose insted of:-

inputState = random(0,10);

I could have used:-

random(0,10);

but as the variable was not being used until the next line it didn't matter.

My latest thought is that this signal that is being fed in from outside is not a logic level signal and the ground of that signal is not connected to the ground of the arduino. Therefore the arduino board is being "wanged" on a transition and is resting the processor, which is why the random number is the same.

Therefore we need from Mazza more detail about this signal and if it causes the on board LED to flash when it makes a transition.

Mike, you have hit the nail on the head mate.

Missing ground and as such circuit incomplete.

Excellent example of mind fixation. (this is a major problem for pilots and has been the cause of numerous crashes over the years) In my case, because I was feeling uncertain about the software I was totally fixated on that and not noticing that there was a fundamental error elsewhere..............a missing ground.

As is the case in airline crashes there was also more than one mistake............when ever I checked the signal I used an easy to get to 0V and of course that was not on the Arduino.

My sincere thanks to all involved but especially to Mike for your patience and thought processes.