You forgot about the code tags when posting that.
if(digitalRead == HIGH)
That is not how you use digitLRead, you have to also specify a pin in brackets.
You forgot about the code tags when posting that.
if(digitalRead == HIGH)
That is not how you use digitLRead, you have to also specify a pin in brackets.
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:
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?
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
int spin(){
Before this first line of this pasted code, and put a closing brace after the last line.
Then look at the line
if(digitalRead(15) == HIGH) spinCount +=1;
And add after it
else return spinCount;
Finally add the line
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.
OK, I have altered the code as instructed (I hope) and it compiles OK - so am intrigued to see where to next...
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
}
}
So we are both on the same page I have tided up your code and made some small changes.
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.
Thanks again Mike. Each time you tidy up it seems to make sense, I feel like I can read the code and understand it (sort of). Given your challenge to move forward I see two tasks:
"write another function, call it "flash", that takes in a pin number of a symbol and flashes it for the required time before returning"
add a call for the returned value of the spin function to initiate this flash function.
First Effort:
Since we already have a neat flashing sequence established at the end of the current loop function I thought (lazily) I would reuse that code to both call up the returned symbol value and alter the timing:
if(return symbols[spinCount]>1);
digitalWrite(symbols[spinCount],HIGH); // will turn on the LED
delay(1000); // so you can see it
digitalWrite(symbols[spinCount],LOW); // will turn off the LED
delay(3000); // so you can see it off
I was hoping that the returned symbol would declare the pin number and would just "be there" to work on...
I put that code at the end of the loop function and it did compile and I uploaded it but the lights demonstrated that I was interrupting the spin function when the switch is open HIGH and getting a glacial hybrid version of the spin, and when the switch is closed LOW no lights at all. After that I tried lots of variations on the theme, but things got worse. I basically tried to copy the spin function syntax and play around with it.
So back to basics;
The loop function is currently comprised of the spin function which sits inside a pair of braces, - and there follows more braces and code to complete the spin and return a final value when the switch is high. During this loop function values from an array in the set-up function are called in one at a time. If I want to write a new flash function it will also operate inside the loop function, but I am having trouble seeing how the spin and flash functions co-exist. If I need to call up a returned value of the spin function - does the flash code need to piggyback onto the spin code and sit inside the braces of the
spin function? Or should it precede the spin function and get called in when needed? I am unsure how I grab the returned switch LOW symbol and hold onto it... (given that its value needs to be retained while we spin for the second and third time). To me this is like Russian Dolls, I need to work out what fits inside what before I can work out what each little doll looks like.
I'm still working at it...
I feel like I can read the code and understand it (sort of)
Good, that is the main point of this exercise. Reading code is the first step to being able to write it.
ince we already have a neat flashing sequence established at the end of the current loop function I thought (lazily) I would reuse that code to both call up the returned symbol value and alter the timing:
Basically good thinking, when ever we see code being repeated we can hive off that code into a function and simply call that function when it needs repeating. But you can’t make the function do both jobs. The blinking code when a reel stops should be slower, but not that slow, and it should not be looking to advance any counter. The trick here is to pass the blink on off times into this new function.
So you need to remove the actual light on off code, those four lines, and replace the three things that change, on time, off time and what LED, with variables that the function accepts. You have not done passing a variable into a function yet so look that up.
This line:-
if(return symbols[spinCount]>1);
Is not right, that return is a command and when evaluating that if statement the function the line of code is in will instantly exit and nothing else will be done.
Yes it is like Russian dolls but you are in control of that. The description is more closely linked to a technique called recursion, which is where a function calls itself. This is powerful but not something you need to do here and it can easily go wrong if you are not careful.
Inching my way forward Mike, but first I need to go backwards... When we introduced the line of code
while(digitalRead(15) == LOW){ } // do nothing until the switch is movedwe lost the flash function that had been working to that point, now when the switch is LOW nothing more happens. Perhaps this line should be in the setup function? As I try passing the return symbols[spinCount] variable into the flash function I can't really test if the code is working since I no longer have a flashing reel stop.
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 switch 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
{ flash(); //call up the flash function
}
}
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
}
void flash() {
static int spinCount = 0;
digitalWrite(symbols[spinCount],HIGH); // will turn on the LED
delay(25); // so you can see it
digitalWrite(symbols[spinCount],LOW); // will turn off the LED
delay(25); // so you can see it off
}
we lost the flash function that had been working to that point
Don’t worry, we will put the flash back but this times on our terms, not in the convoluted way it was flashing. The way it was flashing stops you flashing the the sequence of three reels that you want eventually.
OK Mike, I look forward to the reappearance of the new improved flash. In the meantime I have made a stab at "passing a variable into a function". I have tried to call up the flash function after the else function which returns the last symbol following the switch closing. I am unsure how the integer for the pin number is retained but it seems like I need to re-declare "int Spincount =0" for the compiler to be happy (not a great basis for introducing a term). Anyway, I am pretty sure this is not right, and the code is certainly not giving me a flash on switching off, but I am keen to know if I am on the right track.
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 switch 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
{ flash(); //call up the flash function
}
}
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
}
void flash() {
static int spinCount = 0;
digitalWrite(symbols[spinCount],HIGH); // will turn on the LED
delay(25); // so you can see it
digitalWrite(symbols[spinCount],LOW); // will turn off the LED
delay(25); // so you can see it off
}
No sorry nothing like.
You have to pass a number into a function, read up about how functions work
You can’t call anything in code after a return it will never get called. The flash function needs to be called ( with the appropriate numbers passed to it ), in both the spin and the loop functions.
The flash function needs to use the numbers passed to it for on time off time and pin numbers, not used fixed constants to decide those. You need to remove those digitalWrites and delays from your spin function and have that part just call the flash function.
So Mike... have done my homework... read lots, watched tutorials etc... but still stuck.
I see many functions demonstrated with "stuff" inside the function brackets, this worries me.
Having assigned all 10 LED pins an integer, our code is now dealing with an array of integers, that we call symbols. So the code we write needs to call up these symbols as integers. But I am unsure how to grab hold of these symbol/integers. When you wrote the spin function the function brackets are empty, like so
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
I can't quite see where the array numbers start to be called in. I am guessing that the symbol values are passed into the empty function brackets by convention... but if I write a new Flash function I am unsure how to pass on the looped values, are they still just integers that will populate the function without any label? Or am I looking to work on something called symbols[spinCount], or maybe just spinCount... And then I need to work out where to stick the flash function. Am confused. I guess I am trying to understand the spin function better before I tackle the flash function.
You are worrying about something there is no need to worry about. A symbolic LED number can be extracted from an array and stored in anothe variable.
Functions can take in none or many variables and return one or no variables. So the flash function should be
void flash( int onTime, int offTime, byte symbol) {
digitalWrite(symbol,HIGH); // will turn on the LED
delay(onTime); // so you can see it
digitalWrite(symbol,LOW); // will turn off the LED
delay(offTime); // so you can see it off
}
So to flash LED 6 for 100ms on and 50mS off you use the line
flash(100,50,6);
The function does the work but the code calling the function does the job of saying how the work is done.
The numbers in the function call can also be variables, they do not have to be constants.
That is very cool! I have managed to get the device back to cycling through the symbol array with the new flash function. Try as i might I can't find a way to retain the last symbol. I think the "do nothing" line prevents the slow flash:
if(digitalRead(15) == LOW){ } // do nothing until the switch is moved
Here is the code I have now:
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();
}
void flash( int onTime, int offTime, byte symbol) {
digitalWrite(symbol,HIGH); // will turn on the LED
delay(onTime); // so you can see it
digitalWrite(symbol,LOW); // will turn off the LED
delay(offTime); // so you can see it off
}
int spin(){
// loop along 25 smbol array
static int spinCount = 0;
if(digitalRead(15) == LOW){ } // do nothing until the switch is moved
if(digitalRead(15) == HIGH){
spinCount +=1; //checking if input remains high before advancing count
flash(600,200,symbols[spinCount]); // quick flash for each moving symbol
}
else {
return symbols[spinCount]; // send back the symbol it landed on
}
if(spinCount == 25) spinCount = 0; //Checking if variable spinCount needs wrapping around
}
Well, making my own modest progress now (Thank you Mike)
I have the flash function now working for the reel spin and the reel stop.
Where to next? Assuming I have things straight so far. Are we ready for a second reel?
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();
}
void flash( int onTime, int offTime, byte symbol) {
digitalWrite(symbol,HIGH); // will turn on the LED
delay(onTime); // so you can see it
digitalWrite(symbol,LOW); // will turn off the LED
delay(offTime); // so you can see it off
}
int spin(){
// loop along 25 smbol array
static int spinCount = 0;
if(digitalRead(15) == LOW){ } // do nothing until the switch is moved
if(digitalRead(15) == HIGH){
spinCount +=1; //checking if input remains high before advancing count
flash(600,200,symbols[spinCount]); // quick flash for each moving symbol
}
else {
flash(1000,1000,symbols[spinCount]);
}
if(spinCount == 25) spinCount = 0; //Checking if variable spinCount needs wrapping around
}
I am at the maker fair this weekend so can’t respond too quickly.
The spin function seems to have lost its return statement.
The next step is to use the return value from spin in the loop function, to flash the symbol for a fixed time or number of flashes using a for loop or while loop.
So make an array called wheel with three elements to receive the values for each call to spin, so we can use them in an other function when we want to flash the whole sequence later on.
Thanks for looking in Mike, busy as you are... So I had the fast reel spin flash and the slow reel stop flash working only by removing the return statement, as you say
You can't call anything in code after a return it will never get called
. With the return statement in the code I get nothing but darkness after the switch returns to LOW . I am unclear why the return structure is needed to pass a value to the reel stop function when the if structure for the switch does this for us by stopping the spinCount if(digitalRead(15) == LOW){ } // do nothing until the switch is moved But I understand you are setting up a means of storing the values for later use... Which is why you declared a static variable maybe. So I guess the return statement remains and I will try to get another loop happening... No rush, just wanted you to know I am still in gear, be it forward or reverse.
Having fun - if not actually achieving fresh flashing action.
I have tried to set out the latest coding directives and am still stuck on passing the value of the first spin into the slow flash array for further flashing. Plus not sure how to start the whole second spin. Do I repeat all the code used for the first spin, or is there some other magic available.
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();
}
void flash( int onTime, int offTime, byte symbol) {
digitalWrite(symbol, HIGH); // will turn on the LED
delay(onTime); // so you can see it
digitalWrite(symbol, LOW); // will turn off the LED
delay(offTime); // so you can see it off
}
int spin() {
// loop along 25 smbol array
static int spinCount = 0;
if (digitalRead(15) == LOW) { } // do nothing until the switch is moved
if (digitalRead(15) == HIGH) {
spinCount += 1; //checking if input remains high before advancing count
flash(600, 200, symbols[spinCount]); // quick flash for each moving symbol
}
else {
return symbols[spinCount]; // send back the symbol it landed on
}
if (spinCount == 25) spinCount = 0; //Checking if variable spinCount needs wrapping around
}
// retain symbols[spinCount] value and pass it into a new array for slow fashing etc
const byte wheel[3] = {1,2,3};
int wheelCount = 0;
byte wheel[0]== symbols[spinCount];
flash(1000, 500, symbols[spinCount]); // slow flash for symbol stop
// starting a new loop for the 2nd reel spin which has a new array:
byte symbols2[] = {10, 4, 9, 2, 3, 4, 9, 5, 6, 4, 9, 7, 8, 4, 9, 11, 9, 3, 5, 9, 5, 3, 2, 9, 4 };
int count2 = 0;
So make an array called wheel with three elements to receive the values for each call to spin,
byte wheel[3];
Put this after the symbols definition.
use the return value from spin in the loop function
wheel[0] = spin();
to flash the symbol for a fixed time or number of flashes
For the moment use:-
for(int i =0; i < 40; i ++){
flash(800,400,wheel[0]);
}
See how I am passing values and grabbing returned values.
Do that from the last but one code not the latest you posted.
Wow, that is sweet. I'm not sure I have it exactly right...
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 };
byte wheel[3];
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();
wheel[0] = spin();
for (int i = 0; i < 3; i ++) {
flash(8000, 40, wheel[0]);
}
}
void flash( int onTime, int offTime, byte symbol) {
digitalWrite(symbol, HIGH); // will turn on the LED
delay(onTime); // so you can see it
digitalWrite(symbol, LOW); // will turn off the LED
delay(offTime); // so you can see it off
}
int spin() {
// loop along 25 smbol array
static int spinCount = 0;
if (digitalRead(15) == LOW) { } // do nothing until the switch is moved
if (digitalRead(15) == HIGH) {
spinCount += 1; //checking if input remains high before advancing count
flash(600, 200, symbols[spinCount]); // quick flash for each moving symbol
}
else {
return symbols[spinCount]; // send back the symbol it landed on
}
if (spinCount == 25) spinCount = 0; //Checking if variable spinCount needs wrapping around
}
I see the values getting passed into this "sub loop" and it does hang onto the last value when the switch is open, but as I have it arranged the subloop is running before each loop of the main loop and adding time (as I confirmed by slowing the stop flash to 8000).