Serial.print show garbage when used several times

Hi everyone,

I have a problem with Serial.println

I use it to monitor 4 values. When I use it once, it works great but when I use it from 2 to 4 times, it show garbage on the monitor :

Here is an example of the 1st one :

0000000000000011

Here is what I get when I use the 4 altogether :

#include <RCSwitch.h>
#include <EEPROM.h>


#define deviceSerial 3

RCSwitch mySwitch = RCSwitch();

int button1 = PB2;
int button2 = PB1;
int button3 = PB0;

int radio = PB3;
int keepalive = PB4;

int i = 0;

char buttons[4] = "000";

char * intToBin(unsigned int k, int maxlen = 0){
  int i = 0, j;
  if(maxlen == 0){
    maxlen = sizeof(k) * 8;
  }
  unsigned int exponent;
  j = maxlen - 1;
  char bin[maxlen];
  
  while(i <= j){
    exponent = 1 << (j - i);
    if(k >= exponent){
      k -= exponent;
      sprintf(bin + i, "%s", "1");
    }
    else {
      sprintf(bin + i, "%s", "0");
    }
    i++;
  }
  if(k > 0){
    return false;
  }
  return bin;
}

unsigned int nextCode(){
  int occurrence = getOccurrence();
  //incrementOccurrence();
  int *censored*;
  return *censored*;
}

int getOccurrence(){
  return EEPROM.read(0) + EEPROM.read(1);
}

void incrementOccurrence(){
  int occurrence = getOccurrence() + 1;
  if(occurrence >= 4095){
    EEPROM.write(0, 1);
    EEPROM.write(1, 0);
  }
  else if (occurrence >= 255){
    EEPROM.write(0, 255);
    EEPROM.write(1, occurrence - 255);
  }
  else {
    EEPROM.write(0, occurrence);
    EEPROM.write(1, 0);
  }
}

void transmit(){
  char message[64];

  Serial.println(intToBin(deviceSerial));
  Serial.println(intToBin(nextCode()));
  Serial.println(intToBin(getOccurrence()));
  Serial.println(buttons);

  //mySwitch.send(message);
}

void setup() {
  Serial.begin(9600);
  pinMode(keepalive, OUTPUT);
  digitalWrite(keepalive, HIGH);
  
  pinMode(button1, INPUT);
  pinMode(button2, INPUT);
  pinMode(button3, INPUT);
  
  mySwitch.enableTransmit(radio);
  
  delay(10);
  
  if(digitalRead(button1) == 1){
    
    buttons[0] = 49;
  }
  if(digitalRead(button2) == 1){
    buttons[1] = 49;
  }
  if(digitalRead(button3) == 1){
    buttons[2] = 49;
  }

  transmit();
  
  // Self shutdown
  digitalWrite(PB4, LOW);
}

void loop() {
}

Thanks

That's not the fault of Serial.println() but of your programming.

You're returning a local variable (bin) to the main routine in intToBin(). Once the program leaves intToBin() that pointer is becoming invalid. It might still contain the content it had in the routine but some of it might already be reused. That's what you see when you print it.

yes I can imagine that my code is the source of the problem.

In this case, why even the 1st one is messy ?

The bin array goes out of scope at the moment that you leave the function so you return a pointer to nothing.

You should also not mix return types; false is a bool and the function is supposed to return a pointer to char; rather return NULL. And you will have to check that return value before using it. But this is a bit moot because of bin going out of scope; different approach needed :wink:

Ok I added a malloc in the function and freeing the pointers after using them:

char * intToBin(unsigned int k, int maxlen = 0){
  int i = 0, j;
  if(maxlen == 0){
    maxlen = sizeof(k) * 8;
  }
  unsigned int exponent;
  j = maxlen - 1;
  char *bin = malloc(maxlen + 1);
  while(i <= j){
    exponent = 1 << (j - i);
    if(k >= exponent){
      k -= exponent;
      sprintf(bin + i, "%s", "1");
    }
    else {
      sprintf(bin + i, "%s", "0");
    }
    i++;
  }
  return bin;
}

...

void transmit(){
  char message[64];
  char * serial = intToBin(deviceSerial);
  char * code = intToBin(nextCode());
  char * occurrence = intToBin(getOccurrence());
  Serial.println(serial);
  Serial.println(code);
  Serial.println(occurrence);
  Serial.println(buttons);

  free(serial);
  free(code);
  free(occurrence);

  //mySwitch.send(message);
}

I come from higher level code, I really try to avoid pointers and stuff.. I need it to work, I'll have time to learn after.