Simple queueing system

Hi,

I'm fairly new to Arduino and my programming skills are quite basic.
I'm working on the programming side of an art project and am looking for guidance.

The project involves my receiving input from various buttons.
I want to put these button pushes into a queue, in the order in which they are received,
and to have the serial monitor tell me which button is at the front of the queue.

On sending a signal from the serial monitor, I want the program to take the top button out of the queue and move all the other buttons in the queue up one place, and to again tell me which button is at the front of the queue. This all to happen in real time, as further inputs arrive and I process the 'orders'.

I have written the following code, which I think will do the job (Testing starts tomorrow).
What I am interested in at this point is whether there is a more elegant way of getting the same result, but using less code, fewer 'if' statements etc.

All feedback gratefully received,
Apologies for the basic nature of the code,

Thanks

vutton_counter1.pde (12.5 KB)

Queue (abstract data type) - Wikipedia - paritcular emphasis on circular buffer implementation would serve you well I think...

Thanks. I knew there'd be something useful out there.

I found this: Arduino Playground - QueueArray Library which I have set about using,
but I am really struggling to get my head around how to apply it.

At this point I suspect I should be posting in the baby pool...
My question is, what 'data type' do I insert such that I can start to send my button labels into a queue,
and how do I use the 'void push (const T item)' command?

My logic said, put the 'QueueArray queue;' statement along with my definitions, before the 'setup' and 'loop',
replacing T with 'word' or 'int'

and then when my button is pushed, use the statement
'void push(const int b1)' or even 'void push(b1);' to put b1 into the queue
but I am getting nowhere.

Any tips greatly appreciated.
Thanks. Sam

Any tips greatly appreciated.

Post your code.
Explain your problems with the code.

We can't guess what issues you are having.

I am a new as well!!! so this is just theory and thoughts, I come from a Database and some minor programming background.

Thinking the logic through
Assuming you only want onpush and not worried about hold or let go.
Each button would have a ID. A, B, C, D,...
Now I would probably start with a predefined buffer (several variables and then move them to the next each iteration)
The question is how many do you need and that depends on how long will the delay between iterations be. Or how many can be processed before the next button registered. Could have multiple buffers or a ever growing/shrinking array or couple of arrays.

So I think I would use Main Buffer of say 5 variables then Back Buffer array capturing new buttons.
Now how would I do this, have a function that checks variables and rotates each execution and a input setting the last variable.
Back Buffer array I would have to have some kind of function that would constantly add one to array on button push and minus one each iteration to main buffer.

As far as actually doing this, hummmmmmm? Not sure why I would need something like this but does sound fun to build.

Hope this helps any, when I finish my project I might try it :).

Too much work, Maramor, for both you and the machine. The circular buffer is much easier and simpler. Instead of moving the contents of the array so element 0 is always the top, you change where the top is. And for size, keeping control of that is a good idea.

The sub-link to circular buffer:

Tip: if you have less than 257 buttons then use bytes for the array rather than ints. If you have less than 17 buttons you could use bits but it would ugly the code up some.

Ok, thanks for all the feedback.

Maramor, I think what you are suggesting is where I was heading initially. (see my first post) and as GoForSmoke says, it got really busy really fast.

Please find attached the current program.
I'm sure it's not right yet, and I though I've taken on board what a circular buffer is, I don't understand how to apply it yet, though thanks for the links in that direction. It seems like that is the key to me, just not sure how to implement...

I'm working from the code in the queue array link i posted previously.
I'm getting basic errors that I don't understand
and I suspect that once these basics are cleared up, on sending from the serial monitor the current program will dump the whole queue into my serial monitor at once, which is not what I want.

Any pointers/wrist slaps welcome!

#include <QueueArray.h>

#define BUT1 13 // button1 connected to digital pin 13
#define BUT2 12 // button2 connected to digital pin 12
#define BUT3 11 // button3 connected to digital pin 11
#define BUT4 10 // button4 connected to digital pin 10
#define BUT5 9 // button5 connected to digital pin 9

int incomingByte = 0;   // for incoming serial data

int b1val; //val will Be used to store the state of the input pin 13
int b1val2; //to check the state of the input pin is constant
int b1buttonState; //variavle to hold the button state

int b2val; //val will Be used to store the state of the input pin 12
int b2val2; //to check the state of the input pin is constant
int b2buttonState; //variavle to hold the button state

int b3val; //val will Be used to store the state of the input pin 11
int b3val2; //to check the state of the input pin is constant
int b3buttonState; //variavle to hold the button state

int b4val; //val will Be used to store the state of the input pin 10
int b4val2; //to check the state of the input pin is constant
int b4buttonState; //variavle to hold the button state

int b5val; //val will Be used to store the state of the input pin 9
int b5val2; //to check the state of the input pin is constant
int b5buttonState; //variavle to hold the button state

const String msg1 = "button one";
const String msg2 = "button two";
const String msg3 = "button three";
const String msg4 = "button four";
const String msg5 = "button five";


QueueArray <char> queue;

void setup()
{
  Serial.begin(9600);    // set up Serial library at 9600 bps
  pinMode(BUT1, INPUT); //sets the digital pin as output
  pinMode(BUT2, INPUT); //sets the digital pin as output
  pinMode(BUT3, INPUT); //sets the digital pin as output  
  pinMode(BUT4, INPUT); //sets the digital pin as output
  pinMode(BUT5, INPUT); //sets the digital pin as output

}

void loop()                       // run over and over again
{
//assign each button a queue position when pressed

  b1val = digitalRead(BUT1);      //read input value of BUT1 and store it
  delay(10);                      // 10 milliseconds is a good amount of time
  b1val2 = digitalRead(BUT1);     // read the BUT1 input again to check for bounces
  if (b1val == b1val2) {          // make sure we got 2 consistant readings!
    if (b1val != b1buttonState) { // the button state of BUT1 has changed!
      if (b1val == HIGH) {        // check if the button is pressed (for push buttons)
          for (int b1 = 0; b1 < msg1.length (); b1++)   // push all the message's characters to the queue.
          queue.push (msg1.charAt (b1));
        } 
      }}}

  b2val = digitalRead(BUT2);      //read input value of BUT2 and store it
  delay(10);                      // 10 milliseconds is a good amount of time
  b2val2 = digitalRead(BUT2);     // read the BUT2 input again to check for bounces
  if (b2val == b2val2) {          // make sure we got 2 consistant readings!
    if (b2val != b2buttonState) { // the button state of BUT2 has changed!
      if (b2val == HIGH) {        // check if the button is pressed (for push buttons)
         for (int b2 = 0; b2 < msg2.length (); b2++)   // push all the message's characters to the queue.
         queue.push (msg2.charAt (b2));
        } 
      }}}
 
  b3val = digitalRead(BUT3);      //read input value of BUT3 and store it
  delay(10);                      // 10 milliseconds is a good amount of time
  b3val2 = digitalRead(BUT3);     // read the BUT3 input again to check for bounces
  if (b3val == b3val2) {          // make sure we got 2 consistant readings!
    if (b3val != b3buttonState) { // the button state of BUT3 has changed!
      if (b3val == HIGH) {        // check if the button is pressed (for push buttons) 
         for (int b3 = 0; b3 < msg3.length (); b3++)   // push all the message's characters to the queue.
         queue.push (msg3.charAt (b3));
        } 
      }}}
      
  b4val = digitalRead(BUT4);      //read input value of BUT4 and store it
  delay(10);                      // 10 milliseconds is a good amount of time
  b4val2 = digitalRead(BUT4);     // read the BUT4 input again to check for bounces
  if (b4val == b4val2) {          // make sure we got 2 consistant readings!
    if (b4val != b4buttonState) { // the button state of BUT4 has changed!
      if (b4val == HIGH) {        // check if the button is pressed (for push buttons)
         for (int b4 = 0; b4 < msg4.length (); b4++)   // push all the message's characters to the queue.
         queue.push (msg4.charAt (b4));
        } 
      }}}
      
  b5val = digitalRead(BUT5);      //read input value of BUT5 and store it
  delay(10);                      // 10 milliseconds is a good amount of time
  b5val2 = digitalRead(BUT5);     // read the BUT5 input again to check for bounces
  if (b5val == b5val2) {          // make sure we got 2 consistant readings!
    if (b5val != b5buttonState) { // the button state of BUT5 has changed!
      if (b5val == HIGH) {        // check if the button is pressed (for push buttons)
         for (int b5 = 0; b5 < msg5.length (); b5++)   // push all the message's characters to the queue.
         queue.push (msg5.charAt (b5));
        } 
      }}}
      
//respond to input from computer

  if (Serial.available() > 0) { //if there is input from the computer
    while (!queue.isEmpty ())   // pop all the message's characters from the queue.
    Serial.print (queue.pop ());
  Serial.println ();       // print end of line character.
  }

So, when switch 1 is pressed, you push 'b', 'u', 't', 't', 'o', 'n', ' ', 'o', 'n', and 'e' onto the stack, instead of '1'. Why?

        } 
      }}}

Lovely. Just lovely. Sure makes it easy to see which } goes with which {.

Looks to me, though, like we just reached the end of loop. But, there's a whole bunch more code. Does that mess even compile?

Ah. Sarcasm. I got excited for a second there!

No, it didn't compile. It was the brackets, so thanks.

This does now compile.

#include <QueueArray.h>

#define BUT1 13 // button1 connected to digital pin 13
#define BUT2 12 // button2 connected to digital pin 12
#define BUT3 11 // button3 connected to digital pin 11
#define BUT4 10 // button4 connected to digital pin 10
#define BUT5 9 // button5 connected to digital pin 9

int incomingByte = 0;   // for incoming serial data

int b1val; //val will Be used to store the state of the input pin 13
int b1val2; //to check the state of the input pin is constant
int b1buttonState; //variavle to hold the button state

int b2val; //val will Be used to store the state of the input pin 12
int b2val2; //to check the state of the input pin is constant
int b2buttonState; //variavle to hold the button state

int b3val; //val will Be used to store the state of the input pin 11
int b3val2; //to check the state of the input pin is constant
int b3buttonState; //variavle to hold the button state

int b4val; //val will Be used to store the state of the input pin 10
int b4val2; //to check the state of the input pin is constant
int b4buttonState; //variavle to hold the button state

int b5val; //val will Be used to store the state of the input pin 9
int b5val2; //to check the state of the input pin is constant
int b5buttonState; //variavle to hold the button state

const String msg1 = "button one";
const String msg2 = "button two";
const String msg3 = "button three";
const String msg4 = "button four";
const String msg5 = "button five";


QueueArray <char> queue;

void setup()
{
  Serial.begin(9600);    // set up Serial library at 9600 bps
  pinMode(BUT1, INPUT); //sets the digital pin as output
  pinMode(BUT2, INPUT); //sets the digital pin as output
  pinMode(BUT3, INPUT); //sets the digital pin as output  
  pinMode(BUT4, INPUT); //sets the digital pin as output
  pinMode(BUT5, INPUT); //sets the digital pin as output

}

void loop()                       // run over and over again
{
//assign each button a queue position when pressed

  b1val = digitalRead(BUT1);      //read input value of BUT1 and store it
  delay(10);                      // 10 milliseconds is a good amount of time
  b1val2 = digitalRead(BUT1);     // read the BUT1 input again to check for bounces
  if (b1val == b1val2) {          // make sure we got 2 consistant readings!
    if (b1val != b1buttonState) { // the button state of BUT1 has changed!
      if (b1val == HIGH) {        // check if the button is pressed (for push buttons)
          for (int b1 = 0; b1 < msg1.length (); b1++)   // push all the message's characters to the queue.
          queue.push (msg1.charAt (b1));
        } 
      }
    }

  b2val = digitalRead(BUT2);      //read input value of BUT2 and store it
  delay(10);                      // 10 milliseconds is a good amount of time
  b2val2 = digitalRead(BUT2);     // read the BUT2 input again to check for bounces
  if (b2val == b2val2) {          // make sure we got 2 consistant readings!
    if (b2val != b2buttonState) { // the button state of BUT2 has changed!
      if (b2val == HIGH) {        // check if the button is pressed (for push buttons)
         for (int b2 = 0; b2 < msg2.length (); b2++)   // push all the message's characters to the queue.
         queue.push (msg2.charAt (b2));
        } 
      }
    }
 
  b3val = digitalRead(BUT3);      //read input value of BUT3 and store it
  delay(10);                      // 10 milliseconds is a good amount of time
  b3val2 = digitalRead(BUT3);     // read the BUT3 input again to check for bounces
  if (b3val == b3val2) {          // make sure we got 2 consistant readings!
    if (b3val != b3buttonState) { // the button state of BUT3 has changed!
      if (b3val == HIGH) {        // check if the button is pressed (for push buttons) 
         for (int b3 = 0; b3 < msg3.length (); b3++)   // push all the message's characters to the queue.
         queue.push (msg3.charAt (b3));
        } 
      }
    }
      
  b4val = digitalRead(BUT4);      //read input value of BUT4 and store it
  delay(10);                      // 10 milliseconds is a good amount of time
  b4val2 = digitalRead(BUT4);     // read the BUT4 input again to check for bounces
  if (b4val == b4val2) {          // make sure we got 2 consistant readings!
    if (b4val != b4buttonState) { // the button state of BUT4 has changed!
      if (b4val == HIGH) {        // check if the button is pressed (for push buttons)
         for (int b4 = 0; b4 < msg4.length (); b4++)   // push all the message's characters to the queue.
         queue.push (msg4.charAt (b4));
        } 
      }
    }
      
  b5val = digitalRead(BUT5);      //read input value of BUT5 and store it
  delay(10);                      // 10 milliseconds is a good amount of time
  b5val2 = digitalRead(BUT5);     // read the BUT5 input again to check for bounces
  if (b5val == b5val2) {          // make sure we got 2 consistant readings!
    if (b5val != b5buttonState) { // the button state of BUT5 has changed!
      if (b5val == HIGH) {        // check if the button is pressed (for push buttons)
         for (int b5 = 0; b5 < msg5.length (); b5++)   // push all the message's characters to the queue.
         queue.push (msg5.charAt (b5));
        } 
      }
    }
      
//respond to input from computer and write to serial monitor which button is at the top of the queue

  if (Serial.available() > 0) { //if there is input from the computer
    while (!queue.isEmpty ())   // pop all the message's characters from the queue.
    Serial.print (queue.pop ());
  Serial.println ();       // print end of line character.
  }
}

As the final output links to something I have to action in the real world I want the message to the serial monitor to be a word. 'button x' was the stand in. I don't know yet to know how to simply file numbers 1-5 into the queue and then to convert that into a more useful message to the serial monitor. Could I use 'byte' instead of 'char'? And then what, I don't know?

To be honest I don't really understand how the lines to pop and push code into the queue operate. I would like to simply store numbers in a queue, pop the top one out on input from the serial monitor, whilst new numbers are pushed in at the back of the queue on button input.

A circular buffer makes a FIFO, a First In - First Out queue. That's as opposed to LIFO, Last In - First Out.

The circle is like a clock. Start at 1 and go to 12, and next is 1 again. You can write that a few different ways (and still see something different later, I swear!) which is why the article doesn't just say "do this" and neither do I.

The concept is pretty simple, the implementation less so when it comes to preventing overflow (more than 12 items in a 12 item queue) or underflow (trying to take another item out when the last one has already been taken out) but I find that making drawings of how things should happen helps, usually step by step drawings. Beyond that I can repeat what's in the article or parts of it.

Here's my 4 position circular queue array, it is empty:

0 - 0
1 - 0
2 - 0
3 - 0
start = end = -1 meaning there is no data in the queue

I add a value, 50
0 - 50
1 - 0
2 - 0
3 - 0
start = 0
end = 0

I add a value, 60
0 - 50
1 - 60
2 - 0
3 - 0
start = 0
end = 1

I add a value, 70
0 - 50
1 - 60
2 - 70
3 - 0
start = 0
end = 2

I remove a value, it will be whatever is at the start index... 50
0 - 50
1 - 60
2 - 70
3 - 0
start = 1
end = 2

I remove a value, it will be whatever is at the start index... 60
0 - 50
1 - 60
2 - 70
3 - 0
start = 2
end = 2

If I were to remove the value now at start then start and end would go back to being -1, no items left but...
I add a value, 21
0 - 50
1 - 60
2 - 70
3 - 21
start = 2
end = 3

I add a value, 32
0 - 32
1 - 60
2 - 70
3 - 21
start = 2
end = 0

I add a value, 43
0 - 32
1 - 43
2 - 70
3 - 21
start = 2
end = 1

I can't add a value now, the queue is full. My circular queue function must return an error if I try and my code must be ready to 'see' and handle that. I could use a separate variable to flag good/error or if my data is all within a limited range I could return an out-of-range value, either way the main code needs to check and be able to deal with the error.

At every point, to the code it is "now".

The best way in C++ is to write a class that holds the queue and pointers with functions called, oh say "give" and "take" or whatever makes sense but be nice so that later on you don't wonder what you were drinking.

It's not real small code though certainly not big code. It's something you can wrap up and use again and again later on. In that way it's a puzzle that leaves you with a tool. Take your time and it will work out.

I would like to simply store numbers in a queue, pop the top one out on input from the serial monitor, whilst new numbers are pushed in at the back of the queue on button input.

Then, why don't you?

QueueArray <char> queue;

The type in the <> defines the type of the queue. Make it int (or, even better, byte). To store ints (or bytes).

Hello.

Thanks, GoForSmoke.
I'm hoping that the code from the QueueArray here: Arduino Playground - QueueArray Library will save me the trouble of having to create my own class. Do you think that it will? I'm super daunted by attempting such a thing.
Can you recommend a good online tutorial for creating a class of a type like the circular buffer FIFO?
Pages like this :constructor - How to write a simple class in C++? - Stack Overflow aren't basic enough for me.

I guess now would be a good time to ask for any advice regarding good sources of c++ programming information for beginners. Anyone?

PaulS, I've changed the end of the code to do as you suggest.
It verifies ok at the very least.
I'm not very confident that the command 'byte pop = x' will do anything. (testing it physically is pending a trip out for resistors)
Again, I'm following the notes from this page link: Arduino Playground - QueueArray Library
Do you think it will? or should it read, 'queue.pop byte = x' or byte queue.pop = x?
I'm a little confused because on the page he describes his 'Methods' in one way and then appears to implement them through his code in a different way. Why is this?

Cheers

#include <QueueArray.h>

#define BUT1 13 // button1 connected to digital pin 13
#define BUT2 12 // button2 connected to digital pin 12
#define BUT3 11 // button3 connected to digital pin 11
#define BUT4 10 // button4 connected to digital pin 10
#define BUT5 9 // button5 connected to digital pin 9

int incomingByte = 0;   // for incoming serial data
int x; // for printing the popped byte

int b1val; //val will Be used to store the state of the input pin 13
int b1val2; //to check the state of the input pin is constant
int b1buttonState; //variavle to hold the button state

int b2val; //val will Be used to store the state of the input pin 12
int b2val2; //to check the state of the input pin is constant
int b2buttonState; //variavle to hold the button state

int b3val; //val will Be used to store the state of the input pin 11
int b3val2; //to check the state of the input pin is constant
int b3buttonState; //variavle to hold the button state

int b4val; //val will Be used to store the state of the input pin 10
int b4val2; //to check the state of the input pin is constant
int b4buttonState; //variavle to hold the button state

int b5val; //val will Be used to store the state of the input pin 9
int b5val2; //to check the state of the input pin is constant
int b5buttonState; //variavle to hold the button state

const String msg1 = "01";
const String msg2 = "02";
const String msg3 = "03";
const String msg4 = "04";
const String msg5 = "05";


QueueArray <byte> queue;

void setup()
{
  Serial.begin(9600);    // set up Serial library at 9600 bps
  pinMode(BUT1, INPUT); //sets the digital pin as output
  pinMode(BUT2, INPUT); //sets the digital pin as output
  pinMode(BUT3, INPUT); //sets the digital pin as output  
  pinMode(BUT4, INPUT); //sets the digital pin as output
  pinMode(BUT5, INPUT); //sets the digital pin as output

}

void loop()                       // run over and over again
{
//assign each button a queue position when pressed

  b1val = digitalRead(BUT1);      //read input value of BUT1 and store it
  delay(10);                      // 10 milliseconds is a good amount of time
  b1val2 = digitalRead(BUT1);     // read the BUT1 input again to check for bounces
  if (b1val == b1val2) {          // make sure we got 2 consistant readings!
    if (b1val != b1buttonState) { // the button state of BUT1 has changed!
      if (b1val == HIGH) {        // check if the button is pressed (for push buttons)
          for (int b1 = 0; b1 < msg1.length (); b1++)   // push all the message's characters to the queue.
          queue.push (msg1.charAt (b1));
        } 
      }
    }

  b2val = digitalRead(BUT2);      //read input value of BUT2 and store it
  delay(10);                      // 10 milliseconds is a good amount of time
  b2val2 = digitalRead(BUT2);     // read the BUT2 input again to check for bounces
  if (b2val == b2val2) {          // make sure we got 2 consistant readings!
    if (b2val != b2buttonState) { // the button state of BUT2 has changed!
      if (b2val == HIGH) {        // check if the button is pressed (for push buttons)
         for (int b2 = 0; b2 < msg2.length (); b2++)   // push all the message's characters to the queue.
         queue.push (msg2.charAt (b2));
        } 
      }
    }
 
  b3val = digitalRead(BUT3);      //read input value of BUT3 and store it
  delay(10);                      // 10 milliseconds is a good amount of time
  b3val2 = digitalRead(BUT3);     // read the BUT3 input again to check for bounces
  if (b3val == b3val2) {          // make sure we got 2 consistant readings!
    if (b3val != b3buttonState) { // the button state of BUT3 has changed!
      if (b3val == HIGH) {        // check if the button is pressed (for push buttons) 
         for (int b3 = 0; b3 < msg3.length (); b3++)   // push all the message's characters to the queue.
         queue.push (msg3.charAt (b3));
        } 
      }
    }
      
  b4val = digitalRead(BUT4);      //read input value of BUT4 and store it
  delay(10);                      // 10 milliseconds is a good amount of time
  b4val2 = digitalRead(BUT4);     // read the BUT4 input again to check for bounces
  if (b4val == b4val2) {          // make sure we got 2 consistant readings!
    if (b4val != b4buttonState) { // the button state of BUT4 has changed!
      if (b4val == HIGH) {        // check if the button is pressed (for push buttons)
         for (int b4 = 0; b4 < msg4.length (); b4++)   // push all the message's characters to the queue.
         queue.push (msg4.charAt (b4));
        } 
      }
    }
      
  b5val = digitalRead(BUT5);      //read input value of BUT5 and store it
  delay(10);                      // 10 milliseconds is a good amount of time
  b5val2 = digitalRead(BUT5);     // read the BUT5 input again to check for bounces
  if (b5val == b5val2) {          // make sure we got 2 consistant readings!
    if (b5val != b5buttonState) { // the button state of BUT5 has changed!
      if (b5val == HIGH) {        // check if the button is pressed (for push buttons)
         for (int b5 = 0; b5 < msg5.length (); b5++)   // push all the message's characters to the queue.
         queue.push (msg5.charAt (b5));
        } 
      }
    }
      
//respond to input from computer and write to serial monitor which button is at the top of the queue

  if (Serial.available() > 0) { //if there is input from the serial monitor
    byte pop = x;
    if (x = 01) {
    Serial.print ("button 1");
    Serial.println ();       // print end of line character.
      if (x = 02) {
      Serial.print ("button 2");
      Serial.println ();       // print end of line character.
        if (x = 03) {
        Serial.print ("button 3");
        Serial.println ();       // print end of line character.
          if (x = 03) {
          Serial.print ("button 3");
          Serial.println ();       // print end of line character.
            if (x = 03) {
            Serial.print ("button 3");
            Serial.println ();       // print end of line character.
            }
          }
        }
      }
    }
  }
}
QueueArray <byte> queue;

So, now we have a stack of bytes.

          for (int b1 = 0; b1 < msg1.length (); b1++)   // push all the message's characters to the queue.
          queue.push (msg1.charAt (b1));

So, you are STILL pushing characters onto the stack. Why?

You want to ditch all the String objects and for loops, and do this:

queue.push(1);

You are making this far more complicated than it needs to be.

making this far more complicated than it needs to be.

Indeed. It is my way.

So I've stripped out all the guff with strings and simplified it.
Hoping the input from specific buttons into the queue is close to functioning now. (?)

I'm also hoping that the arduino output to serial monitor on input from serial monitor, which I also simplified, is closer to working too. I'm unsure how one gets the byte popped from the queue to be displayed on said serial monitor though, hence why I attempted to assign it to x.

#include <QueueArray.h>

#define BUT1 13 // button1 connected to digital pin 13
#define BUT2 12 // button2 connected to digital pin 12
#define BUT3 11 // button3 connected to digital pin 11
#define BUT4 10 // button4 connected to digital pin 10
#define BUT5 9 // button5 connected to digital pin 9

int incomingByte = 0;   // for incoming serial data
int x; // for printing the popped byte

int b1val; //val will Be used to store the state of the input pin 13
int b1val2; //to check the state of the input pin is constant
int b1buttonState; //variavle to hold the button state

int b2val; //val will Be used to store the state of the input pin 12
int b2val2; //to check the state of the input pin is constant
int b2buttonState; //variavle to hold the button state

int b3val; //val will Be used to store the state of the input pin 11
int b3val2; //to check the state of the input pin is constant
int b3buttonState; //variavle to hold the button state

int b4val; //val will Be used to store the state of the input pin 10
int b4val2; //to check the state of the input pin is constant
int b4buttonState; //variavle to hold the button state

int b5val; //val will Be used to store the state of the input pin 9
int b5val2; //to check the state of the input pin is constant
int b5buttonState; //variavle to hold the button state

QueueArray <byte> queue;

void setup()
{
  Serial.begin(9600);    // set up Serial library at 9600 bps
  pinMode(BUT1, INPUT); //sets the digital pin as output
  pinMode(BUT2, INPUT); //sets the digital pin as output
  pinMode(BUT3, INPUT); //sets the digital pin as output  
  pinMode(BUT4, INPUT); //sets the digital pin as output
  pinMode(BUT5, INPUT); //sets the digital pin as output

}

void loop()                       // run over and over again
{
//assign each button a queue position when pressed

  b1val = digitalRead(BUT1);      //read input value of BUT1 and store it
  delay(10);                      // 10 milliseconds is a good amount of time
  b1val2 = digitalRead(BUT1);     // read the BUT1 input again to check for bounces
  if (b1val == b1val2) {          // make sure we got 2 consistant readings!
    if (b1val != b1buttonState) { // the button state of BUT1 has changed!
      if (b1val == HIGH) {        // check if the button is pressed (for push buttons)
          queue.push (1);
        } 
      }
    }

  b2val = digitalRead(BUT2);      //read input value of BUT2 and store it
  delay(10);                      // 10 milliseconds is a good amount of time
  b2val2 = digitalRead(BUT2);     // read the BUT2 input again to check for bounces
  if (b2val == b2val2) {          // make sure we got 2 consistant readings!
    if (b2val != b2buttonState) { // the button state of BUT2 has changed!
      if (b2val == HIGH) {        // check if the button is pressed (for push buttons)
         queue.push (2);
        } 
      }
    }
 
  b3val = digitalRead(BUT3);      //read input value of BUT3 and store it
  delay(10);                      // 10 milliseconds is a good amount of time
  b3val2 = digitalRead(BUT3);     // read the BUT3 input again to check for bounces
  if (b3val == b3val2) {          // make sure we got 2 consistant readings!
    if (b3val != b3buttonState) { // the button state of BUT3 has changed!
      if (b3val == HIGH) {        // check if the button is pressed (for push buttons) 
         queue.push (3);
        } 
      }
    }
      
  b4val = digitalRead(BUT4);      //read input value of BUT4 and store it
  delay(10);                      // 10 milliseconds is a good amount of time
  b4val2 = digitalRead(BUT4);     // read the BUT4 input again to check for bounces
  if (b4val == b4val2) {          // make sure we got 2 consistant readings!
    if (b4val != b4buttonState) { // the button state of BUT4 has changed!
      if (b4val == HIGH) {        // check if the button is pressed (for push buttons)
         queue.push (4);
        } 
      }
    }
      
  b5val = digitalRead(BUT5);      //read input value of BUT5 and store it
  delay(10);                      // 10 milliseconds is a good amount of time
  b5val2 = digitalRead(BUT5);     // read the BUT5 input again to check for bounces
  if (b5val == b5val2) {          // make sure we got 2 consistant readings!
    if (b5val != b5buttonState) { // the button state of BUT5 has changed!
      if (b5val == HIGH) {        // check if the button is pressed (for push buttons)
         queue.push (5);
        } 
      }
    }
      
//respond to input from computer and write to serial monitor which button is at the top of the queue

  if (Serial.available() > 0) { //if there is input from the serial monitor
    byte pop = x;            //pop the byte from the front of the queue and label it x
    Serial.print (x)         //print x to the serial monitor
    Serial.println ();       // print end of line character.
  }
}
  if (Serial.available() > 0) { //if there is input from the serial monitor
    byte pop = x;            //pop the byte from the front of the queue and label it x
    Serial.print (x)         //print x to the serial monitor
    Serial.println ();       // print end of line character.
  }

What is x? You are assigning it to a variable called pop and then printing it.

I think you want

byte popped = queue.pop();

which you then print.

If you don't read the byte send to the serial port, Serial.available() will continue to return true once the first byte arrives.

You may need to check that there is actually something to pop, and make sure that the syntax for popping a value from the stack is correct.

Yup , use a queue like the guys before have mentioned. Push and pop are the only two bits of code you would need for the whole queue part of the program , no arrays needed.

No arrays needed? And the queue is stored where? In what?

champigmail:

  • I'm super daunted by attempting such a thing.
  • Can you recommend a good online tutorial for creating a class of a type like the circular buffer FIFO?
    -I guess now would be a good time to ask for any advice regarding good sources of c++ programming information for beginners.

You've already written a lot more than it would take. Rolling your own is a great way to learn and understand, including seeing your own mistakes and the "you coulda's". Just don't get to the emotional level if for no reason than that's where people's thinking starts breaking down. It's probably why so many breakthroughs happen when the pressure is off.

My learning was mostly accomplished long before I had internet, but then I didn't get that until 1996. The C++ books that helped me the most are for the Borland compiler I bought in 1993. I look them up and they both list as for the advanced programmer. Funny, I thought the Kaare Christian book would be a boon to intermediate programmers as he discusses everything is very clear and simple terms... to me.

How best to go about it depends on how you are/were academically and what you were taught before. Some people can crack into manuals, do the exercises, and pick it up. Others should take a class and if they can handle that then keep taking them until they can make sense of the manuals on their own. My schooling was mostly geared for learn how to learn and it's stood me well ever since. The best beginner programming tool I had was a very simple programmable calculator without a lot of BS to get in my way!

What is x? You are assigning it to a variable called pop and then printing it.

I think you want
Code:
byte popped = queue.pop();
which you then print.

If you don't read the byte send to the serial port, Serial.available() will continue to return true once the first byte arrives.

You may need to check that there is actually something to pop, and make sure that the syntax for popping a value from the stack is correct.

Thanks. My 'x' was intended to be your 'popped' but I had it in the wrong spot. I understand now.

The syntax appears to be correct. Something that is confusing me is that instructions for using the command 'pop', for example, are written

// pop an item from the queue.
T pop ();

but then in practice one doesn't write 'byte pop', rather one writes 'queue.pop' completely ignoring the instruction to write T, which I have nominated as 'byte'. Why is this?

It would also appear that there is a function to check whether the queue is empty written in to the pop command, here:

// pop an item from the queue.
template<typename T>
T QueueArray<T>::pop () {
  // check if the queue is empty.
  if (isEmpty ())
    exit ("QUEUE: can't pop item from queue: queue is empty.");

  // fetch the item from the array.
  T item = contents[head++];

  // decrease the items.
  items--;

  // wrap-around index.
  if (head == size) head = 0;

  // shrink size of array if necessary.
  if (!isEmpty () && (items <= size / 4))
    resize (size / 2);

  // return the item from the array.
  return item;
}

And thus that I don't need to write that in. Am I correct? If not, I don't understand how to use the 'bool' keyword. I tried writing 'bool isEmpty() = true;' , 'bool queue.isEmpty() = true', 'queue.isEmpty() = true' and variations on this before the setup, in setup and in the void loop, all to no avail. I understood that one had to set the queue as empty prior to it being filled, and then one could check if that value had changed later, but couldn't make this happen. Why is this?

Thanks again.

Something that is confusing me is that instructions for using the command 'pop', for example, are written

Where T is the type of the queue.

This means that Queue::pop() will return an object of the type used in the instantiation of the class (byte, in your case).

but then in practice one doesn't write 'byte pop', rather one writes 'queue.pop' completely ignoring the instruction to write T, which I have nominated as 'byte'. Why is this?

The pop() method pops something off of some stack. Which stack? You could have a number of stacks. To define which stack, the method needs to be called on an instance of the Queue class (queue in your case). The invocation of the method does not ignore the type. It returns an object of the type of the queue.

You could have

QueueArray <double> dblStack;
QueueArray <int> intStack;
QueueArray <byte> byteStack;
QueueArray <char> charStack;
QueueArray <weird> weirdStack;

Then, dblStack.pop() would return a double, weirdStack.pop() would return a weird, and byteStack.pop() would return a byte.

And thus that I don't need to write that in. Am I correct?

Yes, and no. The attempt to pop a value from an empty stack will result in a call to exit(), shutting your Arduino down. It's probably better to never cause that to happen.

If not, I don't understand how to use the 'bool' keyword. I tried writing 'bool isEmpty() = true;' , 'bool queue.isEmpty() = true', 'queue.isEmpty() = true' and variations on this before the setup, in setup and in the void loop, all to no avail.

The isEmpty() method is already defined, to return a boolean value (true or false). So, you want something like:

if(!queue.isEmpty())
{
   byte val = queue.pop();
   // Do something with val
}
else
   Serial.println("No balloons here to pop, boss");

I understood that one had to set the queue as empty prior to it being filled, and then one could check if that value had changed later, but couldn't make this happen. Why is this?

One does not set the queue to empty. One creates a queue, and, on creation, that queue is empty. The snippet above shows how to test for an empty queue, and do something only if it isn't empty.