Calling a function that has similar variables as the parent function

I've noticed that when I execute the following print_payload function, the Arduino crashes and locks up completely

void print_payload(byte * payload)
{
 
 char buf[16];
 lcd.clear();
 sprintf(buf, "RX: %d%d%d", payload[0], payload[1], payload[2]);
 lcd.setCursor(0,1);
 lcd.print(buf);
 delay(1000);
 print_prompt();
 
}

void print_prompt()
{
  const char * msg = "WAITING...";
  char buf[16];
  sprintf(buf, "%16s", msg);
  lcd.setCursor(0,1);
  lcd.print(buf);
}

I had a hunch that the freezing type behaviour was to do with the buf variable so I changed the char buf[16] variable in print_prompt to char buf1[16] and the freezing behaviour stopped and the code executed normally.

Could anyone explain why I encountered the freezing? I thought the variable space for the two functions should have been separate?

Any help appreciated,

Andy

How and where is the payload array declared ?

  char buf[16];
  sprintf(buf, "%16s", msg);
  lcd.setCursor(0,1);
  lcd.print(buf);

This is plain silly.

No need to copy any data anywhere.

  lcd.setCursor(0,1);
  lcd.print(msg);

The 16 character string and the terminating NULL will not fit in a 16 element array. The string you are specifying is not 16 characters, so the %16s should just be %s.

And, you should be using snprintf(), to make CERTAIN that you don't overflow the array.

Loop code where payload is loaded

void loop()
{
	

         byte buf [10]={0};

          byte received = recvMsg (fAvailable, fRead, buf, sizeof (buf));
		  

          if (received)
         {
				/*lcd.clear();
				for(int x=0; x<5; x++)
				{
					lcd.print(buf[x], HEX);
				}
				lcd.setCursor(0,1);
				for(int x=0; x<5; x++)
				{
					lcd.print(buf[x+5], HEX);
				}*/
				

				if((buf[0] == 0x2B) && (buf[6] == 0x2D))
				{
					lcd.clear();
					lcd.print("HERE");
					delay(3000);
					lcd.clear();



					byte adr = buf[1];
					byte cmd = buf[2];
					byte payload[3] = {buf[3], buf[4], buf[5]};
					
					print_payload(payload);
					
				}
				

            }

}

The purpose of the ‘silly’ sprintf(buf, “%16s”, msg); is to left pad with spaces so the message is displayed on the right hand side of the LCD as opposed to left

Thanks,

Andy

The purpose of the 'silly' sprintf(buf, "%16s", msg); is to left pad with spaces so the message is displayed on the right hand side of the LCD as opposed to left

You know the length of a line on the LCD. You know the number of characters to print.

Simple arithmetic would tell you the number of spaces to pad with, and a for loop to print that number of spaces would be far less code (and a lot more obvious).

Still, 16 + 1 is not 16 or less.

Thanks for the feedback paul. Ive modified the software as follows:

#include <Wire.h>
#include <LiquidCrystal_PCF8574.h>
#include <EEPROM_FIX.h>
#include <find_lcd.h>

#include <RS485_protocol.h>
#include "rs485_functions.h"

#define eeLCD 0

LiquidCrystal_PCF8574 lcd(EEPROM.read(eeLCD));

void setup()
{

rs485_init();

lcd.begin(16, 2);
findLCD(eeLCD);

lcd.setBacklight(255);

print_prompt();
	
}

void loop()
{
	

         byte buf [10]={0};

          byte received = recvMsg (fAvailable, fRead, buf, sizeof (buf));
		  

          if (received)
         {
				/*lcd.clear();
				for(int x=0; x<5; x++)
				{
					lcd.print(buf[x], HEX);
				}
				lcd.setCursor(0,1);
				for(int x=0; x<5; x++)
				{
					lcd.print(buf[x+5], HEX);
				}*/
				

				if((buf[0] == 0x2B) && (buf[6] == 0x2D))
				{
					lcd.clear();
					lcd.print("HERE");
					delay(3000);
					lcd.clear();



					byte adr = buf[1];
					byte cmd = buf[2];
					byte payload[3] = {buf[3], buf[4], buf[5]};
					
					print_payload(payload, cmd);
					
				}
				

            }

}

void print_payload(byte * payload, byte cmd)
{
	
	
  lcd.print("Locker: ");
  for(int x=0; x<3; x++)
  {
    lcd.print(payload[x]);
  }
  
  lcd.setCursor(0,1);
  if(cmd){sprintf(buf, "%16s", "ON");}
  else{sprintf(buf, "%16s", "OFF");}

	delay(1000);

  print_prompt();
	
}

void print_prompt()
{
  lcd.clear();
  lcd.print("STATUS");
  lcd.setCursor(0,1);
  
  const char msg [] = "WAITING...";
  lcd_print_right(msg, sizeof(msg));

}

void lcd_print_right(char * msg, int msg_size)
{
  for(int x = 16-(msg_size-1); x--; x>0)
  {
    lcd.print(" ");
  }
  lcd.print(msg);
}

Please let me know if you have any other tips

Regarding the char buf[16] issue, do you think this was to do with the memory allocation for sprintf ?

Ive modified the software as follows:

Does that even compile?

void print_payload(byte * payload, byte cmd)
{
	
	
  lcd.print("Locker: ");
  for(int x=0; x<3; x++)
  {
    lcd.print(payload[x]);
  }
 
  lcd.setCursor(0,1);
  if(cmd){sprintf(buf, "%16s", "ON");}
  else{sprintf(buf, "%16s", "OFF");}

Where is that buf array defined? It needs to be at least 17 elements long, to hold 16 characters plus a terminating NULL.

It looks to me like lcd_print_right() needs to be used more, and sprintf() not at all.