Pages: [1]   Go Down
Author Topic: Serial transmission with dynamic buffer  (Read 583 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 30
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have a device which takes multiple serial commands. All the commands are of ~similar~ format. command, parameter 1, parameter 2, parameter3.....parameterN

I could write an individual function for each one, but that seems a little redundant. My end goal is to have 1 function, which will take any command and parameters, and send it to the device. If the transmission fails, I would like to inform the user 1.) that it did fail and 2.) what command specifically failed

I also want the function to clear the cmdtrans[] buffer so that I can send another command. As you will see, get_baud() has 1 parameter, and I later set cmdtrans to have 7 parameters, meaning I must modify the serial write buffer dynamically. In anycase, I've been working on this for a while, but for some reason it's not doing what I want. And suggestions from the wise community? Thanks for your help in advance.

uint8_t cmdtrans[]={0x55};
int incomingByte = 0;
int i = 1;

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

get_baud();
delay(3000);
uint8_t cmdtrans[]={0x4C, 0x00, 0x00, 0x7F, 0x7F, 0xFF, 0xFF};
delay(100);
}


void loop() {   // send data only when you receive data:
while(i=1){
exe();
i=2;
}
}// end loop

void get_baud(){
delay(5);
exe();
}

void exe(){
  
Serial.write(cmdtrans, sizeof(cmdtrans));
   if (Serial.available() > 0) {
      // read the incoming byte:
      incomingByte = Serial.read();
      //if (incomingByte = 0x15){
        //Serial.print("I received: ");
      //Serial.print(sizeof(cmdtrans)); Serial.println(incomingByte, HEX);
      //Serial.print(cmdtrans[0], HEX);
      //Serial.println(" command failed");//}
   }
   //clears buffer for next command
   uint8_t cmdtrans[] = {'\0'};
}
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
uint8_t cmdtrans[]={0x4C, 0x00, 0x00, 0x7F, 0x7F, 0xFF, 0xFF};
This instance of cmdtrans is local to setup. It goes out of scope as soon as setup ends.

Code:
   //clears buffer for next command
   uint8_t cmdtrans[] = {'\0'};
This does not do what the comment says. It creates a new instance of cmdtrans, local to loop() that contains one value (a NULL), that goes out of scope immediately.

You need to define an array of fixed size, that is large enough to hold all values that any command uses. Pass that array, and the number of values in the array, to any function that needs to use it.
Logged

0
Offline Offline
Sr. Member
****
Karma: 4
Posts: 323
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

To add to what PaulS said, if you're going to use a persistent buffer, it should be large enough to hold your largest command data set.  Because of this, you will need to make sure that you always memset() it back to all zeros -before- writing anything into it, otherwise you will have bytes left over in it when reading a shorter command.

e.g.:

Code:
memset(cmdtrans, 0, CMDBUFSIZE * sizeof(uint8_t)); // CMDBUFSIZE defines maximum buffer len


!c

Logged

Melbourne, Australia
Offline Offline
Full Member
***
Karma: 0
Posts: 219
Have you tried turning it off and on again?
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You can use the command malloc() for dynamic memory applications - However, as to my understanding, you should not.  The reason for this is that it may (for the lack of a better word) clash with the stack.  This will be an almost impossible thing to debug and crippling to your application.

Your best bet is to have a fixed buffer size.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Code:
uint8_t cmdtrans[]={0x55};

...

void setup() {
...
uint8_t cmdtrans[]={0x4C, 0x00, 0x00, 0x7F, 0x7F, 0xFF, 0xFF};
...
}

...

void exe(){
  
...
   uint8_t cmdtrans[] = {'\0'};
}

Your code is simply not doing what you appear to think it is. All of those cmdtrans variables are quite different from each other.

You need to read up a bit on C arrays and how to populate them. For example:

Code:
uint8_t cmdtrans[]={0x55};

That creates an array of 1 byte, which contains 0x55. That's all it does. It doesn't create a "dynamic array".

If you could specify the maximum number of bytes you might ever use, that would help. Then you could do something like:

Code:
uint8_t cmdtrans[42]={0x55};

Now you can use up to 42 bytes in the array (and initially you have 0x55, 0x00, 0x00 etc.).
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 30
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks everyone for posting. As you all are stating, I had a fundamental flaw in my initial logic. After further research on the topics you all have brought up, I am not sure it is worth my while to continue on with exactly what I stated I would like to do in the initial post.

I was hoping to be able to read the length of my array within the function exe(), but the more I read how to do that and judging by PaulS' post, that is not possible without some unconventional workaround. I am reluctant to do that, because my end goal is to turn this into a fairly nice library for public use when I am finished.

And passing the array's starts to get a bit tricky because I think it would require the usage of pointers which are a little beyond my level. Furthermore, malloc and some of those other more advanced techniques for manipulating memory are far beyond my knowledge level. I remember by Comp sci college buddies complaining about malloc hahaha good times!

in anycase, I think I am going to go back to the drawing board and see if I can come up with a simpler solution, that doesn't involve writing out a million different functions. If I have to learn to use pointers and all that, well then, I will have to. I am messing around with this to learn anyway.
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
If I have to learn to use pointers and all that, well then, I will have to. I am messing around with this to learn anyway.
Good. Learning about pointers will be good for you. Once you get beyond very basic coding, pointers become essential.

Understand that a pointer just points to some memory location, and the relationship between pointers and arrays (they are nearly identical), and pointers become easy to understand.

Dereferencing, incrementing, and decrementing pointers is the challenging part, initially, but once you understand how to do that, and know that you can step through memory using a pointer just like an array, pointers become easy, and second nature.
Logged

Pages: [1]   Go Up
Jump to: