Go Down

Topic: An Amusement Machine using LEDs (Read 2364 times) previous topic - next topic

TommyKat

OK Mike I understand I misspoke by calling everything with () a for loop. I will be re-reading everything and trying to ensure I make progress with the comprehension. Thanks for steering me along.
I have been reading your initial plan of attack and I now have a switch on pin13 declared as an input and it has a 5 volt supply with an onboard resistor, it is connected through to the ground. The default state of this pin is HIGH, when the switch is open the state is LOW.  I guess I need to insert a statement into the void loop along the lines of IF pin13 is LOW then stop the count...

Code: [Select]
byte symbols[] = {2, 3, 2, 4, 5, 6, 3, 2, 7, 2, 8, 9, 3, 4, 5, 2, 3, 2, 10, 2, 11, 2, 3, 9, 5 };

void setup() {
  
for(int i = 2; i<12; i++) { // declare pin numbers for 10 symbols
   pinMode(i, OUTPUT); //declare pins as outputs
   pinMode(13,INPUT_PULLUP);
   int count = 0;
  
 }
}
void loop() {
  // loop along 25 smbol array
 for(int i=0; i<25; i++){
   digitalWrite(symbols[i],HIGH); // will turn on the LED
   delay(600); // so you can see it
   digitalWrite(symbols[i],LOW); // will turn off the LED
  delay(200); // so you can see it off
  
  }
}
  

Grumpy_Mike

Quote
a statement into the void loop
Ok sorry to be a pain but let's get this right. It is called simply the loop function, it is not called "void loop", you need to separate its name from the sort of variable it returns.

Quote
The default state of this pin is HIGH, when the switch is open the state is LOW.
Yes that is right.
I am assuming that this code is tested and you can see the results on your hardware working, if not get it going now.

Quote
I guess I need to insert a statement into the void loop along the lines of IF pin13 is LOW then stop the count...
Well close. What I want you to do now is to remove the for statement from the loop function along with associated braces.
At the start of the function declare a variable called spinCount with
Code: [Select]
static int spinCount = 0;
The static bit means that the value is retained as the last value each time the loop function is entered. Now where you have the "i" as an index register replace the "i" with "spinCount".
if you were to just run this ( try it ) then the first symbol will just blink on and off, could you have predicted this?

So what we want to do is to increment the spinCount variable each time through the loop after you have displayed the symbols. This variable need to be wrapped round to keep it in the display range like this:-
Code: [Select]

if(spinCount == 25) spinCount = 0;

Note their are no braces here, if the test is true it will perform just the one statement.

Now the bit you have been worrying about. I said increment the spinCount variable BUT now only increment it if the switch is high. So you don't actually stop anything except the increment of the variable, and the last symbol will keep on blinking. Can you do that and verify it works?

TommyKat

I am getting excited now! Yes Mike I have a device built and the code does cycle through all 10 symbols for a total of 25, I don't have the switch working yet... My arduino is housed inside a cabinet already hooked up to a series of LEDs I will need to disassemble the cabinet to put the switch in. I am guessing I will need the switch working from this point onwards... Will do some serious homework and get back to you. Thanks again for the journey.

TommyKat

I have managed to do everything up until the final hurdle, getting the switch to work:
"Now the bit you have been worrying about. I said increment the spinCount variable BUT now only increment it if the switch is high. So you don't actually stop anything except the increment of the variable, and the last symbol will keep on blinking. Can you do that and verify it works?"
I am failing with the PIN15 function. I am blindly trying to plug it in here and there... Usual desperate moves. lol.


Code: [Select]
byte symbols[] = {2, 3, 2, 4, 5, 6, 3, 2, 7, 2, 8, 9, 3, 4, 5, 2, 3, 2, 10, 2, 11, 2, 3, 9, 5 };
 
 
void setup() {
 
for(int i = 2; i<12; i++) { // declare pin numbers for 10 symbols
   pinMode(i, OUTPUT); //declare pins as outputs
  pinMode(15,INPUT_PULLUP);

   int count = 0;
   
 }
}
void loop() {
  // loop along 25 smbol array

 static int spinCount = 0;

 if(spinCount == 25,digitalRead(15)=HIGH) spinCount = 0;
 
   
 {
   digitalWrite(symbols[spinCount],HIGH); // will turn on the LED
   delay(600); // so you can see it
   digitalWrite(symbols[spinCount],LOW); // will turn off the LED
  delay(200); // so you can see it off
   
  }
}
 

 

Grumpy_Mike

#34
Apr 19, 2018, 03:56 pm Last Edit: Apr 19, 2018, 03:59 pm by Grumpy_Mike
Quote
digitalRead(15)=HIGH
== in an if statement

Code: [Select]
if(spinCount == 25,digitalRead(15)=HIGH) spinCount = 0;
No do not look at the input pin here.

Look at it before you increment the spinCount variable, which you don't seem to be doing anyway.

TommyKat

OK , thanks Mike -

Incrementing the spinCount variable means I need to use the compound operator ++
which we have already covered this like so:

Code: [Select]
for(int i=0; i<25; i++)

Which means
x++;  // increment x by one and returns the old value of x

(as opposed to ++x; which returns the new value of x)

i being the 0 first symbol in the array, and counting up to 24 which is <25

So Question: if the x++ operator "returns" the old value of x does that simply mean the array is unaltered?

I am unsure what the change to x is being used for other than counting upwards.

So here follows my attempt to "increment the spinCount variable"

And an attempt to look at the input pin before hand

Code: [Select]

byte symbols[] = {2, 3, 2, 4, 5, 6, 3, 2, 7, 2, 8, 9, 3, 4, 5, 2, 3, 2, 10, 2, 11, 2, 3, 9, 5 };
 //set up an array of 25 symbols shring 10 different values from 2 to 11
 
void setup() {
 
for(int i = 2; i<12; i++) { // declare pin numbers for 10 symbol values
   pinMode(i, OUTPUT); //declare pins as outputs
  pinMode(15,INPUT_PULLUP); //declare pin 15 as input set to High

   int count = 0;
 
 }
}
void loop() {
  // loop along 25 smbol array

 static int spinCount = 0;

 if(spinCount == 25) spinCount = 0; //return spincount to 0 when it hits 25
 while(15==HIGH); //count continues while input is High
 for(int i=0; i<25; i++) //increment spinCount variable
   
 {
   digitalWrite(symbols[spinCount],HIGH); // will turn on the LED
   delay(600); // so you can see it
   digitalWrite(symbols[spinCount],LOW); // will turn off the LED
  delay(200); // so you can see it off
   
  }
}

Grumpy_Mike

Sorry stick and wrong end and all that there are many ways to increment a variable, all these perform exactly the same operation
Code: [Select]
 
spinCounter++;
++spinCounter;
spinCounter += 1;
spinCounter = spinCounter +1;
 


This
while(15==HIGH) ;
Will halt your program 15 is a number, it will always be high, you mean the input at pin 15 which involves a digital read. So all I was asking you to do was to add a
Code: [Select]

if(digitalRead == HIGH) spinCounter +=1;

To the code you posted previously.
I think you are at the over thinking it stage, but keep on going.

TommyKat

Seemed to make sense to me, but on compiling I get this error message highlighted on the new code :
ISO C++ forbids comparison between pointer and integer
Code: [Select]
byte symbols[] = {2, 3, 2, 4, 5, 6, 3, 2, 7, 2, 8, 9, 3, 4, 5, 2, 3, 2, 10, 2, 11, 2, 3, 9, 5 };
 
 
void setup() {
 
for(int i = 2; i<12; i++) { // declare pin numbers for 10 symbols
   pinMode(i, OUTPUT); //declare pins as outputs
  pinMode(15,INPUT_PULLUP);

   int count = 0;
   
 }
}
void loop() {
  // loop along 25 smbol array

 static int spinCount = 0;

 if(spinCount == 25) spinCount = 0;
 if(digitalRead == HIGH) spinCounter +=1;
 
   
 {
   digitalWrite(symbols[spinCount],HIGH); // will turn on the LED
   delay(600); // so you can see it
   digitalWrite(symbols[spinCount],LOW); // will turn off the LED
  delay(200); // so you can see it off
   
  }
}

Grumpy_Mike

OK the rule is when you get an error message then always post it, just like you post code.

If you read the message it tells you what is wrong: in this case:-
Code: [Select]
Users/mikecook/Desktop/sketch_apr20a/sketch_apr20a.ino: In function 'void loop()':
sketch_apr20a:20: error: 'spinCounter' was not declared in this scope
  if(digitalRead == HIGH) spinCounter +=1;
                          ^
exit status 1
'spinCounter' was not declared in this scope


That means the compiler has not seen the variable spinCounter declared.
You might think you declared it when you wrote:-
Code: [Select]
static int spinCount = 0;
But spinCount is a different variable than spinCounter.

The other thing wrong with that code is you should increment the variable FIRST and then check to see if it needs wrapping round.

TommyKat

Ok Mike. I have dropped all mention of "spinCounter" and the function is now "spinCount". I have also shifted the increment check to precede the wraparound check. And I still get the error message as follows:
Code: [Select]

sketch_apr17a.cpp: In function 'void loop()':
sketch_apr17a:21: error: ISO C++ forbids comparison between pointer and integer

When compelling this code:
byte symbols[] = {2, 3, 2, 4, 5, 6, 3, 2, 7, 2, 8, 9, 3, 4, 5, 2, 3, 2, 10, 2, 11, 2, 3, 9, 5 };
 
 
void setup() {
 
for(int i = 2; i<12; i++) { // declare pin numbers for 10 symbols
   pinMode(i, OUTPUT); //declare pins as outputs
  pinMode(15,INPUT_PULLUP); //declare pin 15 as an input with 5V pullup resitor

   int count = 0;
   
 }
}
void loop() {
  // loop along 25 smbol array

 static int spinCount = 0;

 
 if(digitalRead == HIGH) spinCount +=1; //checking if input remains high before advancing count
 if(spinCount == 25) spinCount = 0; //Checking if variable spinCount needs wrapping around

 
   
 {
   digitalWrite(symbols[spinCount],HIGH); // will turn on the LED
   delay(600); // so you can see it
   digitalWrite(symbols[spinCount],LOW); // will turn off the LED
  delay(200); // so you can see it off
   
  }
}
 

Grumpy_Mike

You forgot about the code tags when posting that.

Code: [Select]
if(digitalRead == HIGH)
That is not how you use digitLRead, you have to also specify a pin in brackets.

TommyKat

Thanks Mike! It works a charm now - that is to say the symbols cycle through the full array up until the switch circuit is closed and then the last displayed symbol continues to flash. Fantastic.

Here is the code that works:
Code: [Select]
byte symbols[] = {2, 3, 2, 4, 5, 6, 3, 2, 7, 2, 8, 9, 3, 4, 5, 2, 3, 2, 10, 2, 11, 2, 3, 9, 5 };
 
 
void setup() {
 
for(int i = 2; i<12; i++) { // declare pin numbers for 10 symbols
   pinMode(i, OUTPUT); //declare pins as outputs
  pinMode(15,INPUT_PULLUP); //declare pin 15 as an input with 5V pullup resitor

   int count = 0;
   
 }
}
void loop() {
  // loop along 25 smbol array

 static int spinCount = 0;

 
 if(digitalRead(15) == HIGH) spinCount +=1; //checking if input remains high before advancing count
 if(spinCount == 25) spinCount = 0; //Checking if variable spinCount needs wrapping around

 
   
 {
   digitalWrite(symbols[spinCount],HIGH); // will turn on the LED
   delay(600); // so you can see it
   digitalWrite(symbols[spinCount],LOW); // will turn off the LED
  delay(200); // so you can see it off
   
  }
}
 


So where to next?
Do we try to get three arrays active now?

Grumpy_Mike

#42
Apr 22, 2018, 12:55 pm Last Edit: Apr 22, 2018, 12:56 pm by Grumpy_Mike
Quote
Do we try to get three arrays active now?
Yes we do, but we will do things properly.
We are going to make a function called something like spin. It will contain all the code that is currently in the loop function, with some small changes.
So highlight the contents of the loop functional to but not including the final closing brace and select cut.
Then paste it below the closing brace of the now empty loop function.

Now we make this into a function by putting the line
Code: [Select]
int spin(){
Before this first line of this pasted code, and put a closing brace after the last line.

Then look at the line
Code: [Select]
if(digitalRead(15) == HIGH) spinCount +=1;
And add after it
Code: [Select]
else return spinCount;
Finally add the line
Code: [Select]
spin();
To the empty loop function.

Now this should just work exactly like before, but it is in a better shape for progress.

See if you can write something at the top of this new spin function that holds in a loop until the input switch is low. It will be just one line and use the while command.

TommyKat

OK, I have altered the code as instructed (I hope) and it compiles OK - so am intrigued to see where to next...
Code: [Select]
byte symbols[] = {2, 3, 2, 4, 5, 6, 3, 2, 7, 2, 8, 9, 3, 4, 5, 2, 3, 2, 10, 2, 11, 2, 3, 9, 5 };
 
 
void setup() {
 
for(int i = 2; i<12; i++) { // declare pin numbers for 10 symbols
   pinMode(i, OUTPUT); //declare pins as outputs
  pinMode(15,INPUT_PULLUP); //declare pin 15 as an input with 5V pullup resitor

   int count = 0;
   
 }
}
void loop() {spin();
}
int spin(){
  // loop along 25 smbol array

 static int spinCount = 0;

 
 if(digitalRead(15) == HIGH) spinCount +=1; //checking if input remains high before advancing count
 else return spinCount;
 if(spinCount == 25) spinCount = 0; //Checking if variable spinCount needs wrapping around

 
   
 {
   digitalWrite(symbols[spinCount],HIGH); // will turn on the LED
   delay(600); // so you can see it
   digitalWrite(symbols[spinCount],LOW); // will turn off the LED
  delay(200); // so you can see it off
   
  }
}

Grumpy_Mike

So we are both on the same page I have tided up your code and made some small changes.
Code: [Select]
byte symbols[] = {2, 3, 2, 4, 5, 6, 3, 2, 7, 2, 8, 9, 3, 4, 5, 2, 3, 2, 10, 2, 11, 2, 3, 9, 5 };
int count = 0;
 
void setup() {
for(int i = 2; i<12; i++) { // declare pin numbers for 10 symbols
   pinMode(i, OUTPUT); //declare pins as outputs
 }
   pinMode(15,INPUT_PULLUP); //declare pin 15 as an input with 5V pullup resitor
}
void loop() {
  spin();
}

int spin(){
  // loop along 25 smbol array
 static int spinCount = 0;
 while(digitalRead(15) == LOW){ } // do nothing until the switched is moved
 
 if(digitalRead(15) == HIGH){
  spinCount +=1; //checking if input remains high before advancing count
 }
 else {
  return symbols[spinCount]; // send back the symbol it landed on
 }
 if(spinCount == 25) spinCount = 0; //Checking if variable spinCount needs wrapping around
    digitalWrite(symbols[spinCount],HIGH); // will turn on the LED
    delay(600); // so you can see it
    digitalWrite(symbols[spinCount],LOW); // will turn off the LED
    delay(200); // so you can see it off
}


Note the removal of the useless { } around the bits blinking the symbols and I have changed the spin function to return not the count but the symbol. I have also added the bit you forgot that was not to start the spinning until the switch is high.

Now the next stage is to get the chosen symbol blinking, just for one reel at the moment.
You should write another function, call it "flash", that takes in a pin number of a symbol and flashes it for the required time before returning. The symbol pin it flashes is given by the returned value of the spin function so you need to add a call to your flash function in the loop function.

Try that.

Go Up