Moving string position in array

Hello all,

I have searched for a solution or at least some guidance on a problem I am having with a new program I am trying to write and am still stuck.

Basically I have a board that will be monitoring some hardware for several different inputs that will cause various alarm conditions. I need to log the last 50 alarms that have occurred on the system, and I was looking to use a character array, but need to roll the different alarm messages through the array so that they are in chronological order from newest to oldest. Ideally I would like two arrays that are matched, one with the alarm text and another with the date and time stamp. I am trying to do this with a function that steps all the messages back one step in the array and then makes the most recent position 1.

void alarmHandler(char messageIn, int time){
for (int i = 50; i > 0; i--){
messageArray = messageArray[i-1];

  • }*
  • messageArray[0] = messageIn;*
    }
    But I keep getting nothing but errors, it seems like when I try and set the first section of the array equal to the new message, it it trying to force it in as a single character.
    I am trying to avoid doing this with an SD card and text files. I don't care if I lose the messages on a reset, and I am using a Due, so ram restrictions are not that big of a concern either.
    Any suggestions or pointers where I can look?
    Thanks,
    Jim

Post your code
Use code tags.

This is from a sketch I was using to try and make this work. The intent is that the outer loop runs by sending messages to the function, and the inner loop prints the current messages in the array

char messageArray;

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:

for (int i = 1; i < 51; i++){
  String sendMessage = "Alarm Message - ";
   sendMessage = sendMessage + i;
   
  alarmHandler(sendMessage, i);
    for (int j = 0; j < 51; j++){
      Serial.println(messageArray[j]);
    }
    //Serial.println(sendMessage);
  delay(1000);
}

}
void alarmHandler(String messageIn, int time){
  for (int i = 4; i > 0; i--){
    messageArray[i] = messageArray[i-1];
  }
  messageArray[0] = messageIn;
}

char messageArray;``Serial.println(messageArray[j]);
This looks wrong to me.

I have been messing with this for the last few hours, so I know it isn't working, and there may be some mis-matched data types in here at the moment. The messageArray variable should be an array of 50 messages

Not working?
Is it even compiling ?

First question is are your alarm messages fixed or dynamic? "Door open" is an example of a fixed alarm message that is always the same when the door is open. "Overvoltage 3879V" is an example of a dynamic alarm message that varies depending on what the sensed voltage is. If your messages are fixed, setup an array of strings with your messages and include the message array index with your timestamp in the array of alarms.

Rather than move elements in your alarm array, just shift the insertion point. To output the array in reverse time order, work backwards from the insertion point. For forward time order, move forward in the array from the insertion point.

Nope, I am getting the error "invalid conversion from 'char*' to 'char' at the moment. Below is my current code

char messageArray[1000];

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:

for (int i = 1; i < 51; i++){
  char sendMessage[20] = "Alarm Message - ";
   sendMessage = sendMessage + i;
   
  alarmHandler(sendMessage, i);
    for (int j = 0; j < 51; j++){
      Serial.println(messageArray[j]);
    }
    //Serial.println(sendMessage);
  delay(1000);
}

}
void alarmHandler(char messageIn, int time){
  for (int i = 51; i > 0; i--){
    messageArray[i] = messageArray[i-1];
  }
  messageArray[0] = messageIn;
}

why do you need the "int time" parameter in the alarmHandler function if then you're not using it?

void alarmHandler(char messageIn, int time){
  for (int i = 51; i > 0; i--){
    messageArray[i] = messageArray[i-1];
  }
  messageArray[0] = messageIn;
}

is that your whole code? I'm note sure what you are trying to do...

for (int i = 1; i < 51; i++){
  char sendMessage[20] = "Alarm Message - ";
   sendMessage = sendMessage + i;

I know what this is doing, but I'm not clear what it is you intend.

Try something like this...

#define ARRAYSIZE 50

struct alarm {
  int time;
  char *msg;
};

struct alarm alarms[ARRAYSIZE];

char *messages[10] = {
  "alarm message 1",
  "alarm message 2",
  "alarm message 3",
  "alarm message 4",
  "alarm message 5",
  "alarm message 6",
  "alarm message 7",
  "alarm message 8",
  "alarm message 9",
  "alarm message 10",
};

int insertionPoint=0;

void setup() {
  Serial.begin(9600);
}

void loop() {
  newAlarm(5,millis()%0xFFFF);
}

void newAlarm(int msgIndex, int time) {
  alarms[insertionPoint].time = time;
  alarms[insertionPoint].msg = messages[msgIndex];
  ++insertionPoint %= ARRAYSIZE;
}

void printAlarms() {
  for (int i=0;i<ARRAYSIZE;i++) {
    Serial.print(alarms[insertionPoint+i%ARRAYSIZE].time);
    Serial.print("  ");
    Serial.println(alarms[insertionPoint+i%ARRAYSIZE].msg);
  }
}

@boguz - This isn't my entire code, just a section that I brought over to a new sketch to work with it. The time variable was intended to go into another array that would have its positions in lockstep with the alarmmessage one, I just hadn't gotten around to using it yet.

@AWOL - I am trying to use the loop there to generate some messages with different text in them, so I can watch it move through the final array. It was a string function initially, and that would take my static text and put the current step number at the end of it.

@DavidOConnor - I am trying out the code you sent over, I have never used a structure before, but thanks to the Google, it looks like that will be a big help. What are you doing with the %0xFFFF after the millis() statement?

You chose type int for your time stamps, millis() returns unsigned long, so I used the mod operator to trim it down to size. Feel free to modify for the time stamp of your choice.

So I had to make some tweaks to the code as far as the inertionPoint counter and the printAlarm function. I have the alarms printing out in descending order as to when they occured. The newAlarm function seems to be doing what I need it to do, not to just bring it back into my main program. Thanks to DavidOConnor for getting me on the right track!

#define ARRAYSIZE 20

struct alarm {
  int time;
  char *msg;
};

struct alarm alarms[ARRAYSIZE];

char *messages[10] = {
  "alarm message 1",
  "alarm message 2",
  "alarm message 3",
  "alarm message 4",
  "alarm message 5",
  "alarm message 6",
  "alarm message 7",
  "alarm message 8",
  "alarm message 9",
  "alarm message 10",
};

int insertionPoint=0;

void setup() {
  Serial.begin(9600);
}

void loop() {
  for (int i = 0; i < 9; i++){
  newAlarm(i,millis()%0xFFFF);
  Serial.println("Alarm Buffer");
  printAlarms();
  delay(1000);
  }
}

void newAlarm(int msgIndex, int time) {
  alarms[insertionPoint].time = time;
  alarms[insertionPoint].msg = messages[msgIndex];
  if (insertionPoint < ARRAYSIZE - 1){
    insertionPoint++;
  }
    else{
      insertionPoint=0;
  }
  //++insertionPoint %= ARRAYSIZE;
}

void printAlarms() {

  for (int i = insertionPoint -1; i >= 0; i--){
      Serial.print("Current Step is - ");
      Serial.print(i);
      Serial.print(" - ");
      Serial.print(alarms[i].time);
      Serial.print(" ");
      Serial.println(alarms[i].msg);
    }
  for (int i = 19; i >= insertionPoint; i--){
      Serial.print("Current Step is - ");
      Serial.print(i);
      Serial.print(" - ");
      Serial.print(alarms[i].time);
      Serial.print(" ");
      Serial.println(alarms[i].msg);
    }
  }
char *messages[10] = {
  "alarm message 1",
  "alarm message 2",
  "alarm message 3",
  "alarm message 4",
  "alarm message 5",
  "alarm message 6",
  "alarm message 7",
  "alarm message 8",
  "alarm message 9",
  "alarm message 10",
};

Waste of RAM.
Factor it.