return array failed

hey,
can someone help me. i always return an Array this way, but here it dont work.

 byte * RFID::Print_Block() {
  if (arrayfull == true) {
    static unsigned char BlockData[4];
     Serial.println("first print");
    for (int i=5; i<9; i++){
      BlockData[i]=printArray[i];
      Serial.println(BlockData[i], HEX);
    }
      pruef = true;
      arrayfull = false;     
      return BlockData;
  }
  else if (NovalidArray == true ) {
    NovalidArray = false;
    return -2;
    }
    else return -4;
}

int RFID::pruefung(){
  if (pruef == true){
    Serial.println("second print");
    unsigned char *a;
    unsigned char Block[4];
    a=Print_Block(); 
    for (int i=0; i<4; i++){
       Block[i]=*(a+i);
       Serial.println(Block[i], HEX); 
  }
  pruef= false;
  }
 }
  }
 }

the Code prints this

⸮aah⸮first print
AA
B
B
68
second print
49
AC
D5
75
⸮aah╪aah⸮first print
AA
B
B
68
second print
49
AC
D5
75
⸮aah╪aah

return -2; But you promised to return a char pointer!

AWOL:
return -2; But you promised to return a char pointer!

oh it should be Byte, ist now correct.
i have alway the same problem

e return -4; But you promised to return a byte pointer.

the Problem isn't there, even if i Change to INT it dont work.

Hi,

as part of a project where I have to deal with telegrams from my RFID sensor, I am blocked.
I use a State Machine in my program to capture these telegrams.
the presence of a tag on the Sensor generates these telegrams. As soon as the sensor detects a tag, it sends a Telegram starting with 0xAA that I would like to embed in a Table to return.

#include "Arduino.h"
#include"RFID.h"
#include "MYHELPERS.h"

#define  RFID_Serialport Serial

void RFID::Read_Block()
{
  switch (state)
  { case senden:
      RFID_Serialport.begin(115200);
      Senden(RB_Nutzbytesanzahl, RB_Nutzbyte1, RB_Nutzbyte2);
      state = wait;
      break;

    case wait:
      digitalWrite(Send_Recievepin, LOW);
      if (RFID_Serialport.available() > 0) {
        state = ack;
      }
      else
        state = wait;
      break;

    case ack:
      startbyte = RFID_Serialport.read();
      if (startbyte == 0xAA ) {
        state = response;
      }
      else {
        state = ack;
      }
      break;

    case response:
      myList.add(startbyte);
      do {
        myList.add(RFID_Serialport.read());
      } while (RFID_Serialport.available() > 0);
      listlaenge = myList.size();
      byte empf[listlaenge];
      for (int h = 0; h < listlaenge; h++) {
        empf[h] = myList.get(h);
      }
      memcpy(&printArray, empf, 11 * sizeof(byte) );
      myList.clear();
      if (listlaenge == 11 ) {
        arrayfull = true;
        state = response; 
      }
    else {
      state = senden;
    }
    break;
  }
}
unsigned char* RFID::Print_Block() {
  if (arrayfull == true){ 
     Serial.println("first print");
    for (int i=0; i<4; i++){
     Serial.println(printArray[i], HEX);
    }
    static unsigned char prufar[11];       //-> the desired Array
    memcpy(&prufar, printArray, 11 * sizeof(unsigned char));
    Serial.println("values in prufar[i]"); l
    for (int i=0; i<4; i++){
    Serial.println(prufar[i], HEX);                 // -> I check that the desired Elements are copies
    }
    arrayfull = false;     
    return prufar;
  }
    else return NULL;
}

Header Datei with global variables in

#include <LinkedList.h>
#ifndef MYHELPERS_H
#define MYHELPERS_H
LinkedList<byte> myList = LinkedList<byte>();
static unsigned char printArray[20];
bool arrayfull=false;
bool NovalidArray= false;
byte startbyte;
int listlaenge;
enum State_enum {senden, wait, ack, response};
byte state= senden ;
#endif

Sketch

#include <LiquidCrystal.h>                                
#include"RFID.h"
RFID  RFID(6);  
LiquidCrystal lcd(12, 11, 5, 4, 3, 7); 

void setup() { 
  }

void loop() {
    RFID.Read_Block();
    delay(1);
    PrintBlocks();
}

int PrintBlocks(){
  unsigned char *checkbyte;
  checkbyte=RFID.Print_Block();
  if (checkbyte== NULL)
  {
    return;
    }
  else{
    unsigned char Block[4];
    checkbyte=RFID.Print_Block();
   Serial.println("second print");
    for (int i=0; i<4; i++){
       Block[i]= *(checkbyte+i);
     Serial.println(Block[i], HEX); 
  }
 }
}

debug

⸮aah⸮aah⸮first print
AA
B
B
68
values in p⸮]V⸮m⸮u5
AA
B
B
68
second print
A3
0
8
68
⸮aah╪aah

I do not see where I could have made a mistake for the values to be modified.
thank you for your help

byte * RFID::Print_Block() {
  if (arrayfull == true) {
    static unsigned char BlockData[4];

The declaration of the array should NOT be in the body of an if statement.

The function return type needs to match the array type, if you are planning to return a pointer to that array.

It would be better, though, since you do not always want to return an array, to make the return type in, and pass the function a pointer to the array you want it to write to.

      listlaenge = myList.size();
      byte empf[listlaenge];

can't be done. Array sizes needs to be known a compiler time!

do {
        myList.add(RFID_Serialport.read());
      } while (RFID_Serialport.available() > 0);

is a serial read without actually knowing there is something to read.

But why mess with a linked list library? (which you did not link!)

      listlaenge = myList.size();
      byte empf[listlaenge];

listlaenge is an integer und will obtain a value bevor the declaration of the array

do {
        myList.add(RFID_Serialport.read());
      } while (RFID_Serialport.available() > 0);

i know the information from the first step of the state machine that data are available (case:wait)

i have modified it, but i still have the same issues

void RFID::Read_Block()
{
  switch (state)
  { case senden:
      RFID_Serialport.begin(115200);
      Senden(RB_Nutzbytesanzahl, RB_Nutzbyte1, RB_Nutzbyte2);
      state = wait;
      break;

    case wait:
      digitalWrite(Send_Recievepin, LOW);
      if (RFID_Serialport.available() > 0) {
        state = ack;
      }
      else
        state = wait;
      break;

    case ack:
      startbyte = RFID_Serialport.read();
      if (startbyte == 0xAA ) {
        state = response;
      }
      else {
        state = ack;
      }
      break;

    case response:
      myList.add(startbyte);
      do {
        myList.add(RFID_Serialport.read());
      } while (RFID_Serialport.available() > 0);
      listlaenge = myList.size();
      byte empf[listlaenge];
      for (int h = 0; h < listlaenge; h++) {
        empf[h] = myList.get(h);
      }
      memcpy(&printArray, empf, 11 * sizeof(byte) );
      myList.clear();
      if (listlaenge == 11 ) {
        arrayfull = true;
        state = response; 
      }
    else {
      state = senden;
    }
    break;
  }
}
unsigned char* RFID::Print_Block() {
  static unsigned char prufar[11];
  if (arrayfull == true){ 
     Serial.println("first print");
    for (int i=0; i<4; i++){
     Serial.println(printArray[i], HEX);
    }
    memcpy(&prufar, printArray, 11 * sizeof(unsigned char));
    Serial.println("values in prufar[i]");
    for (int i=0; i<4; i++){
    Serial.println(prufar[i], HEX);
    }
    arrayfull = false;     
    return prufar;
  }
    else return NULL;
}

Sketch

void loop() {
    RFID.Read_Block();
    delay(1);
    PrintBlocks();
}

unsigned char PrintBlocks(){
  unsigned char *checkbyte;
  checkbyte=RFID.Print_Block();
  if (checkbyte== NULL)
  {
    return;
    }
  else{
    unsigned char Block[4];
    checkbyte=RFID.Print_Block();
   Serial.println("second print");
    for (int i=0; i<4; i++){
       Block[i]= *(checkbyte+i);
     Serial.println(Block[i], HEX); 
  }
 }
}

the pint

⸮aah╪aah⸮first print
AA
B
B
68
values in prufar[i]
AA
B
B
68
second print
A3
0
8
68
⸮aah╪aah

i am cunfused

pispa:
listlaenge is an integer und will obtain a value bevor the declaration of the array

Yes, but only at runtime. But the size needs to be know at compiler time :wink: And to be honest, I'm a bit surprised it doesn't generate an error or at least a warning. :o

pispa:
i know the information from the first step of the state machine that data are available (case:wait)

No you don't :wink: Because between case 'response' and case 'wait' you do case 'ack' which does a serial read. After which you don't know for sure there is anything more to read.

septillion:
Yes, but only at runtime. But the size needs to be know at compiler time :wink: And to be honest, I'm a bit surprised it doesn't generate an error or at least a warning. :o
No you don't :wink: Because between case 'response' and case 'wait' you do case 'ack' which does a serial read. After which you don't know for sure there is anything more to read.

as i wrote it on the top, 0xAA means , that a reponse ready is,
0xAA is in my case always the bigining of a Telegramm

Wow! How many more times are you going to post this topic?

(The correct answer to that question is "a very, very small number")

AWOL:
Wow! How many more times are you going to post this topic?

(The correct answer to that question is "a very, very small number")

becauze it dont work til now, despite all the changes

Arg, hate it when topics get shuffled why typing a reply. So a shorter answer this time.

Like I said in a different topic, see Serial as the mailmen who comes by max every day to drop a single letter at a time. if(Serial.available()) is the flag on the letter box. So the mailmen came by, dropped a letter, raised the flag. You see the flag raised, open the letter box, open the letter and see 0xAA. You think, "ahh, my beloved aunt wants to send a message". You straight away reach in the letter box for the next letter. Do you expect to find it?

I don't. I check my letter box regularly and I certainly don't take more than a day to open a single letter. So I wait for the flag to get raised again but now knowing the next letter is part of the "message from aunt Betty".

i understand what u mean, but it is also possible that the mailmen bring several letter instead one,
because of it, it works and i recieve the expected values,
now i just want to return it in the Loop ()

pispa:
i understand what u mean, but it is also possible that the mailmen bring several letter instead one,

Absolutely not. What is possible though is that your checking of letter box is just weekly and/or you need days and days to process a single letter. In the meantime the mailman came by multiple times. Aka, a case of being slow yourself. Probably bad/blocking code elsewhere.

pispa:
now i just want to return it in the Loop ()

For which you already received pointers what you do wrong :slight_smile: