enqueue / dequeue question

After plenty of help from the experts here, I got my queing system working on a mock-up, but now I am trying to get it all working I seem to have a problem, perhaps its because I am enqueing in the interrupt routine , and dequeing in the main loop ?

Is this permitted ?

I can post some of the code if needed

I think you need to post the code. Essentially, variables that are manipulated in an ISR must be volatile.

Thanks Alexander,

I remembered the volatile ( after several hours debugguing this morning :slight_smile:

here is the part of the code with out the miles of lookup tables in the middle :- ( the curly braces will be wrong overall with all the snipping )

/* 
 VGA overlay generator for HiDefinition screens by John Smith  December 2010
 Various inputs representing door 1-9 are received via rf, and decoded to give
 a 4bit bcd code and a valid transmission (vt) signal to the video control micro.
 The number is queued and the first number is displayed on the screen, while a
 decimal to bcd converter send the 4 dequed bits and a valid pulse to the audio
 board, which announces the right number from a SD card via a DAC.
 
 This is the sketch for the video micro.
 */
#include <FIFO.h>
#include <SPI.h>

volatile int bcda ; // define bcd digital reads from HT12
volatile int bcdb;
volatile int bcdc;
volatile int bcdd;
volatile int qdoor;
int talking;     // HIGH while audio running
int valid = LOW;
int vb;          // vertial blocks of 16 lines making vert pixel size
int vwin;    // vert window out to generate black window ( gates ext with line window )
int pixel;    // timing signals for loading the shift registers
int oneshot;
volatile int door;    // door number to show and announce


int aPin = A0; //binary data in from Holtek chip
int bPin = A1;
int cPin = A2;
int dPin = A3;
int vtPin = A4; // valid transmission input from HT12
//int trigoutPin = A5;
int timingPin = 4;  // line timing signal input
int fsPin = 5; // frame sync pulse from VGA
int windowPin = 6;  // output to video switching to make black window
int runningPin = 12; // input from audio board, high when audio playing
//int window= HIGH; // starts window at top at switch on - enable if flicker at switch on
//const  int slaveSelectPin = 10;// has to be set for SPI library
volatile int aoutPin = 10 ; // queued bcd codes to audio board
volatile int boutPin = 9;
volatile int coutPin = 8;
volatile int doutPin = 7;
int vtoutPin = 3;   // vt trigger to audio board to start playing
FIFO<int,10> fifo; //store 10 ints

/////////////////////////////////////////////////////////
void setup ()   {
  //  pinMode (trigoutPin, OUTPUT );
  pinMode (aoutPin, OUTPUT );  // queued bcd codes to audio board
  pinMode (boutPin, OUTPUT );
  pinMode (coutPin, OUTPUT );
  pinMode (doutPin, OUTPUT );
  pinMode (vtoutPin, OUTPUT ); // valid transmission to trigger audio board
  pinMode (runningPin, INPUT );  // signal back from audio board (wave.isplaying)
  pinMode(aPin, INPUT);  //binary data in from Holtek chip
  pinMode(bPin, INPUT);
  pinMode(cPin, INPUT);
  pinMode(dPin, INPUT);
  pinMode(vtPin, INPUT);  // VT from Holtek chip
  pinMode(timingPin, INPUT);  // line timing signal input
  pinMode(fsPin, INPUT);    // vert sync input

  pinMode(windowPin, OUTPUT );  // for generating the background window  for the text
  attachInterrupt(0, queue, RISING);   // interupt routine from vt input ht12 to load new number to queue
  SPI.begin(); 
 Serial.begin(9600);

}
//////////////////////////////////////////////////

void loop () 
{
  digitalWrite ( vtoutPin, LOW);
  int valid = digitalRead ( vtPin );  // momentary high after valid trasmission after data latched
  int talking = digitalRead (runningPin );  // signal back from audio board (wave.isplaying)
  if ( valid ==HIGH || talking == HIGH ) {  // main loop runs if VT high or announcer talking
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    if ( talking == LOW ){      // if nothing playing at the moment
      if (fifo.count () > 0 )   //  check if there are any unread numbers in queue subroutine
      {
        qdoor = fifo.dequeue();  //  returns first unread number in queue


          // dec to bcd convert to send to audio chip ( what number to announce )
        if (qdoor == 1){
          digitalWrite ( aoutPin, HIGH); 
          digitalWrite ( boutPin, LOW);
          digitalWrite ( coutPin, LOW);
          digitalWrite ( doutPin, LOW);
        }  

        if (qdoor == 2){
          digitalWrite ( aoutPin, LOW); 
          digitalWrite ( boutPin, HIGH);
          digitalWrite ( coutPin, LOW);
          digitalWrite ( doutPin, LOW);
        }
[b]//and so on up to door 9 [/b]     
      }
           digitalWrite ( vtoutPin, HIGH);     //   start announcement
    }

    /*
//  [b]Here sits the display routine ( not shown )which works 100%[/b]
     
     */
// and the interrupt routine below

void queue ()  {
  bcda = digitalRead ( aPin );  // check the state of the HT12 data outputs
  bcdb = digitalRead ( bPin );
  bcdc = digitalRead ( cPin );
  bcdd = digitalRead ( dPin );

  if (bcda==1 && bcdb==0 && bcdc == 0 && bcdd == 0 )
  {    
    door = 1;  
  }
  if (bcda==0 && bcdb==1 && bcdc == 0 && bcdd == 0 ) {
    door = 2;
  }
  if (bcda==1 && bcdb==1 && bcdc == 0 && bcdd == 0 ) {
    door = 3;
  }
  if (bcda==0 && bcdb==0 && bcdc == 1 && bcdd == 0 ) {
    door = 4;
  }
  if (bcda==1 && bcdb==0 && bcdc == 1 && bcdd == 0 ) {
    door = 5;
  }
  if (bcda==0 && bcdb==1 && bcdc == 1 && bcdd == 0 ) {
    door = 6;
  }
  if (bcda==1 && bcdb==1 && bcdc == 1 && bcdd == 0 ) {
    door = 7;
  }
  if (bcda==0 && bcdb==0 && bcdc == 0 && bcdd == 1 ) {
    door = 8;
  }
  if (bcda==1 && bcdb==0 && bcdc == 0 && bcdd == 1 ) {
    door = 9;
  }

  fifo.enqueue(door);
}

These guys use the FIFO in an ISR: http://wiring.uniandes.edu.co/source/trunk/wiring/lib/Serial/

And, this:

if (bcda==1 && bcdb==0 && bcdc == 0 && bcdd == 0 )
  {    
    door = 1;  
  }
  if (bcda==0 && bcdb==1 && bcdc == 0 && bcdd == 0 ) {
    door = 2;
  }
  if (bcda==1 && bcdb==1 && bcdc == 0 && bcdd == 0 ) {
    door = 3;
  }
  if (bcda==0 && bcdb==0 && bcdc == 1 && bcdd == 0 ) {
    door = 4;
  }
  if (bcda==1 && bcdb==0 && bcdc == 1 && bcdd == 0 ) {
    door = 5;
  }
  if (bcda==0 && bcdb==1 && bcdc == 1 && bcdd == 0 ) {
    door = 6;
  }
  if (bcda==1 && bcdb==1 && bcdc == 1 && bcdd == 0 ) {
    door = 7;
  }
  if (bcda==0 && bcdb==0 && bcdc == 0 && bcdd == 1 ) {
    door = 8;
  }
  if (bcda==1 && bcdb==0 && bcdc == 0 && bcdd == 1 ) {
    door = 9;
  }

Can become this:

int door = (bcdd<<3) | (bcdc<<2) | (bcdb<<1) | (bcda);

:slight_smile:

You might want to look at Direct Port Manipulation, instead of digitalRead in the ISR.

All the rest of the stuff in that ISR should be done in loop. The ISR should set a flag indicating that the work needs to be done. The loop() function should check that flag, and do the work if/when it needs to be done.

Thanks guys,
I will have a look at that link , and thanks for the shortening of the code, I havn't got round to that yet ( you should see the lookup table )
And the reason I have put so much in the ISR rather than a flag ( which I had at first ) is that the ISR generally only operates when nothing is going on with the video output. Any extra work in the loop gets to a point where the sync is affected. I am not using any timers anywhere so I thought I would try the ISR.
Once the ISR has decided the number to display, it does nothing while the overlay displays ( except when another input comes along )
If I shorten the code in the main loop look-up tables ( along the lines you have shown here ) I might save some time.

I am not using any timers anywhere so I thought I would try the ISR.

Please bear in mind that I am a newbie having a lot of fun, and learning all the time !

Hi Alexander, I can't see any reference to FIFO s on the link, ...but basically are you saying it should work OK as I have it?

The shortened code for the BCD works great thanks, I will try and work it out when I get a chance and use it for the other similar tables in my other projects.

I might try and knock up a simple test version of the sketch tomorrow, but the problem is the MD wants to demonstrate this unit to a customer next week !

I love deadlines, and the lovely whoosh they make as they fly by.....

And the Direct Port Manipulation is going to take me a bit of time to understand, though the basic idea sounds great.
I was tempted to try it on the video side for the speed, but my 2 wire SPI is coping with the speed OK ( even with my miles of lookup tables )

Hello!
Yes, the wiring project uses the FIFO in an ISR. You see it in the .cpp file if you want to check.

In my experience most LUTs can be replaced with functions, but if you want LUTs because of performance, a function is not really an alternative.

Im afraid the example in the ccp file is over my head at the moment.

I will try some different combinations of what I have been doing and see if it comes right.