FIFO

Hello Guys,

I have predefined locoaddress array with follwing values {"1830", "3", "999", "4444"} and would like to know how can I leverge Queing/fifo mechanisim to move the items as follows

Before sending any thing it looks like this
1830
3
999
4444

if I send "12345" I want array to reflect

12345
1830
3
999

if I send "45678" I want array to reflect

45678
12345
1830
3

if I send "91011" I want array to reflect

91011
45678
12345
1830

I have tried several libraries that handles Queue or FIFO nothing works if you have any recommendation
can you please provide the example that works with my use case

Thanks in advance

char* TempLocoAddress[4] = {"1830", "3", "999", "4444"}; //Setting the Default loco addresses at the startup
char* LocoAddress[4] = {"1830", "3", "999", "4444"}; //Setting the Default loco addresses at the startup
char Locoadding[6]  ; //Setting the Default loco addresses at the startup
char test[6] = {"12345"} ;
#define TEXT_LEN 10
char textfield[TEXT_LEN + 1] = "";
#define maxLocos 4
void setup() {
  Serial.begin(9600);
 
 //Adding First value to the existing array LocoAddress
  strcpy(Locoadding, test);
  strcpy(textfield, Locoadding);
  addLocoAddressToArray(textfield);
  ///Adding second value to the array
  strcpy(test, "45678");
  strcpy(Locoadding, test);
  strcpy(textfield, Locoadding);
  addLocoAddressToArray(textfield);
  ///Adding third value to the array
  strcpy(test, "91011");
  strcpy(Locoadding, test);
  strcpy(textfield, Locoadding);
  addLocoAddressToArray(textfield);
}

void loop() {
  //nothing here
}


void addLocoAddressToArray(char LocoToAdd[]) {
  Serial.println ();
  Serial.print ("locotoadd : " );
  Serial.print(LocoToAdd);
  Serial.println ();
  int k = 0;

    if (LocoToAdd != "") {
    LocoAddress[k] = LocoToAdd;
    for (byte j = 0; j < maxLocos - 1  ; j++)
    {
      k++;
      LocoAddress[k] = TempLocoAddress[j];
      Serial.print (" k ");
      Serial.print(k);
      Serial.print ("**LocoAddress Added  : " );
      Serial.print(LocoAddress[k]);
      Serial.println ();

      if (k > 3) {
        j = maxLocos;
      }
    }


    for (int i = 0; i <= maxLocos - 1  ; i++)
    {
      Serial.println ();
      Serial.print (i);
      Serial.print (" LocoAddress ");
      Serial.print (LocoAddress[i]);
      Serial.println ();
      TempLocoAddress[i] = LocoAddress[i]; //making copy of the array to temp array
    }
    //memcpy(TempLocoAddress, LocoAddress, 6); Doesnt  work
    for (int i = 0; i <= maxLocos - 1  ; i++)
    {
      Serial.println ();
      Serial.print (i);
      Serial.print (" TempLocoAddress ");
      Serial.print (TempLocoAddress[i]);
      Serial.println ();
    }



  }

}

Your examples all show what happens when you put something in to an array that's already full. What do you expect to happen when you take something out?

basically its a push pop requirement
Before sending any thing it looks like this
1830
3
999
4444

if I push"12345" I want array to reflect and 4444 should pops out

12345
1830
3
999

You have specified a "delay line". The output is delayed 4 steps from what was input. Am I right?

The words "push" and "pop" are usually used to describe the opposite of a FIFO, which is FILO (first in, last out) often called a "stack".

Actually you are righ it is FILO

I did not understand your comment about "delay line" please elaborate
appreciated

Maybe something like this?

Edit: same thing but using memmove instead of strcpy

You made the output exactly equal to the input, except with a delay.

sahar_ca:
if I push"12345" I want array to reflect and 4444 should pops out

12345
1830
3
999

From that state, you need to input 4 more things before "12345" appears at the output. The delay is 4.

You said initially that you wanted a queue. Think about a queue at the bank, ticket counter or whatever. If there is a lot of demand, then new people arriving at the back don't "push" others off the front. The queue just gets bigger. More people wait.

When the server is ready to serve another person, the person at the front of the queue gets served. If they are served faster than they are arriving at the back then the queue will "empty" so that there are no people waiting.

No need for queue or stack for your little problem. The algorithm should be simple:

  1. Initialize your initial data:
    A B C D
  2. Initialize current index to the last element in the array, which will be "poped" out when you insert new element:
    current_index = 3
  3. When inserting new element E, get the value at current_index (D), insert E at current_index, move current_index back by 1:
    current_index = 2
    A B C E
    output = D
    if current_index < 0, the wrap it back to 3.
  4. Go to 3)

To visualize the data, print forward from the current_index, wrap around if needed.

Thanks for your help Guys issue has been resolved I changed the Data type from char* to Char and leverage strcpy

Here is the Code that worked please ignore the Eprom logic it is for my next step

#include "Arduino.h"
#include<EEPROM.h>
char TempLocoAddress[4][6] = {"1830", "3", "999", "4444"}; //Setting the Default loco addresses at the startup
char LocoAddress[4][6] = {"1830", "3", "999", "4444"}; //Setting the Default loco addresses at the startup
char Locoadding[6]; //Setting the Default loco addresses at the startup
char test[6] = {"12345"} ;
#define TEXT_LEN 10
char textfield[TEXT_LEN + 1] = "";
#define maxLocos 4
int debug = 1; // set to 1 to show debug info on serial port - may cause issues with DCC++ depending on what is sent

struct MyObject {
 char loc0[10];
 char loc1[10];
 char loc2[10];
 char loc3[10];
};




void setup() {
 Serial.begin(9600);
 getAddressesfromEprom();
 strcpy(Locoadding, test);
 strcpy(textfield, Locoadding);
 addLocoAddressToArray(textfield);
 getAddressesfromEprom();
 //Adding second value to the array
 strcpy(test, "45678");

 strcpy(Locoadding, test);

 strcpy(textfield, Locoadding);

 addLocoAddressToArray(textfield);
 getAddressesfromEprom();
 //Adding second value to the array
 strcpy(test, "91011");

 strcpy(Locoadding, test);

 strcpy(textfield, Locoadding);

 addLocoAddressToArray(textfield);
 getAddressesfromEprom();
 //Adding second value to the array
 strcpy(test, "12131");

 strcpy(Locoadding, test);

 strcpy(textfield, Locoadding);

 addLocoAddressToArray(textfield);
 getAddressesfromEprom();
 strcpy(test, "12131");

 strcpy(Locoadding, test);

 strcpy(textfield, Locoadding);

 addLocoAddressToArray(textfield);
 getAddressesfromEprom();
}
void loop() {
 //nothing here
}

void addLocoAddressToArray(char LocoToAdd[]) {
 for (int i = 0; i <= maxLocos - 1  ; i++)
 {
   if (!strcmp(LocoToAdd, LocoAddress[i])) {
     LocoToAdd = "";
     i = maxLocos;
     Serial.print (" Loco already existed no need to update ");
   }
 }
 int k = 0;
 if (LocoToAdd != "") {

   strcpy(LocoAddress[k], LocoToAdd);
   for (byte j = 0; j < maxLocos - 1  ; j++)
   {
     k++;
     strcpy(LocoAddress[k], TempLocoAddress[j]);
     if (k == 4) {
       j = maxLocos;
     }
   }
   for (int i = 0; i <= maxLocos - 1  ; i++)
   {
     strcpy(TempLocoAddress[i], LocoAddress[i]); //making copy of the array to temp array
   }
   saveAddressestoEeProm();
 }
}

void getAddressesfromEprom() {
 int eeAddress = sizeof(float); //Move address to the next byte after float 'f'.

 MyObject customVar; //Variable to store custom object read from EEPROM.
 EEPROM.get(eeAddress, customVar);
 Serial.println("Read custom object from EEPROM: ");
 Serial.println(customVar.loc0);
 Serial.println(customVar.loc1);
 Serial.println(customVar.loc2);
 Serial.println(customVar.loc3);

 if (customVar.loc0 != "") {
   strcpy(LocoAddress[0], customVar.loc0);
   strcpy(LocoAddress[1], customVar.loc1);
   strcpy(LocoAddress[2], customVar.loc2);
   strcpy(LocoAddress[3], customVar.loc3);
 }
 for (int i = 0; i <= maxLocos - 1  ; i++)
 {
   Serial.println ();
   Serial.print (i);
   Serial.print (" LocoAddress Get add ");
   Serial.print (LocoAddress[i]);
   Serial.println ();
 }
}

void saveAddressestoEeProm() {
 int eeAddress = 0;   //Location we want the data to be put.
 for (int i = 0; i <= maxLocos - 1  ; i++)
 {
   Serial.println ();
   Serial.print (i);
   Serial.print (" LocoAddress Save add ");
   Serial.print (LocoAddress[i]);
   Serial.println ();
 }
 //Data to store.
 MyObject customVar = {
   LocoAddress[0],
   LocoAddress[1],
   LocoAddress[2],
   LocoAddress[3]
 };
 // eeAddress += sizeof(float); //Move address to the next byte after float 'f'.
 EEPROM.put(eeAddress, customVar);
}

Why not just int?

-jim lee

There seems to be other requirements that weren't mentioned. The code above won't add something that's already in the list of 4 items. People aren't allowed to queue up twice?

jimLee:
Why not just int?

-jim lee

This was just a sample subset code ,My actual code is provding as Char and significant of lines already written I dont want to change the base code and there is a chance that I could use Alpha numeric in future.

Thanks

MorganS:
There seems to be other requirements that weren't mentioned. The code above won't add something that's already in the list of 4 items. People aren't allowed to queue up twice?

This new requirement was added yesterday to avoid unnecessary data.

Thanks for the interest