Hey Folks,
my logger is coming to an end right now and I seem to be able to send data to the sensor via RS-232 (Yeah)
I have a general question regarding Serial.read();
In the reference it is written that you get the first byte of incoming data. So to get a stream of ten byte, would it be possible to use a for-loop to get all bytes or is always the first byte returned (fixed in the buffer). An example is below. if Data is available on the serial port it shall be passed in an array and then printed out on the console.
The usual response to this construct is "You see that you've got at least one character in the serial buffer, then you go ahead and read all ten of them".
Serial comms are sllloooooowwww
At 9600 bps, the time between characters is enough for the Arduino to execute up to 16000 instructions.
Jopp,
well, sadly we just have a Serial communication, but the time between processing each loop will be min. 30Seconds...so that's fine ;). The Sensor-Logger Serial connection will be running with 57600 BPS..... so that's ok so far.
So every Byte is removed from the Buffer after reading. Thanks.
Think about it.
Going through the loop (you haven't posted all your code, but we'll ignore that for now) a character appears in the receive buffer.
So, "Serial.available()" returns 1.
Your code sees this one, and proceeds to read all ten of the character in the receive buffer, nine of which haven't yet arrived.
Maybe you could post all your code, and we can see what is really happening.
for(i=0;i<4;i++) // Send bytes to CDP (0x1b for start, 0x03 for PBP Mode, 0x1e and 0x00 for Checksum)
{
Serial1.write(OPCSend*);*
}*
i=0;*
delay(10000);*
if(Serial1.available()>0) //Anything received yet?*
{*
Serial.println("DATA"); //Check fo debugging*
for(i=0;i<1185;i++)//read every byte*
{*
_ OPCRespond*=Serial1.read();//read first byte and assign to Byte array*_ * }* * }* * for(d=0;d<100;d++)//Print out Data on console* * {* * Serial.println(OPCRespond[d],HEX);* * }* } [/quote]
Yes, I know that this won't work like it is written there. That was just my testprogram if the Sensor reacts for the sending commands.
I am planning to use the delay and some for loops, so that I read out some bytes and then wait to get some other bytes attached to the end.
That was my idea and because of that I was asking if the buffer gets emptied byte by byte
That was my idea and because of that I was asking if the buffer gets emptied byte by byte
Yes, the serial library manages the receiver interrupt buffer one character at a time, adding each character as it arrives to the buffer and adjusts a buffer pointer, and each Serial.read(); command takes but a single character (if any are avalible) out of the buffer and adjusts a buffer pointer.
Thanks AWOL,
sorry I had clicked wrong with the code Tag.
Another question:
Is it possible to assign a more bytes for the Serial Buffer? I think the serial buffer may be set by the Arduino environment in the RAM, am I right? Perhaps there is a way to place the beyond the Arduino IDE.
Otherwise it may be possible to check with available() if and how many bytes are in the buffer, read one out and check again how many bytes are inside it and keep track of the speed the bytes are passed through the buffer. I may think about that.....
Phyllomedusa:
Otherwise it may be possible to check with available() if and how many bytes are in the buffer, read one out and check again how many bytes are inside it and keep track of the speed the bytes are passed through the buffer. I may think about that.....
That is the appropriate method of reading serial data. There's really very few, if any, valid reasons for mucking around with the buffer size.
For loops and delays are just bad methods of handling serial data.
I used my freetime a bit to think about reading the serial data stream and coded a bit. I will try that when I am home and put the sensor in my vivarium to check with some particles to collect
Right now I thought about an routine to be called by loop which checks the amount of bytes in the buffer and starts collecting them if there are more than 50 bytes (could be modified later on for a bigger buffer).
Then it reads them byte by byte and stores the number of processed bytes of the stream in a global variable to find the position for the next Byte in the data array.
Code is here:....thanks for all your help and suggestions thumbs up.It's really a great and helpful community around here.
byte OPCSend[4] = {0x1B,0x03,0x1E,0x00}; //Start Byte (ESC); Command (3);Checksum (27+3=30),CHecksum Rest (0)
byte OPCRespond[1185];
int amount;//Variable for number of Bytes stored in the Serial buffer
int k=0;//Variable to store the Byte position in OPCRespond[]
void setup()
{
Serial.begin (9600);
Serial1.begin(57600);
}
void loop()
{
int i=0;
int d;
for(i=0;i<4;i++) // Send bytes to CDP (0x1b for start, 0x03 for PBP Mode, 0x1e and 0x00 for Checksum)
{
Serial1.write(OPCSend[i]);
}
i=0;
delay(10);
amount=0;
if(Serial1.available()>0) //Anything received yet?
{
Serial.println("DATA"); //Check for debugging
reading();
}
}
void reading()//Read serial data
{
int j;//counter for data
if(Serial1.available()>50)//check if there are more than 50 bytes in the buffer
{
for(j=k+1;j<50+amount;j++)//read every byte... first iteration k=0...next would be k+1 (51) in 50 Byte steps ;
{
OPCRespond[j]=Serial1.read();//read first buffered byte and assign to Byte array at next free position
}
k=j;//Store number of iterations in k for next call of reading
amount=Serial1.available();//Check for number of remining Bytes in Buffer and store that in amount-variable for next loop
reading();//recall the rading routine
}
else// Less than 50 Bytes in buffer
{
reading();//do it all over again....
}
}
Two issues:
If there are less than 50 bytes to read, you make a recursive call to the function.
If there are more than 50 bytes to read (miracle!), you read them, and make a recursive call to the function.
How will it ever end?
Why is is necessary to wait for there to be 50 bytes to read? You keep track of where in the buffer the new characters go, and add them to the buffer at the right place. So, why wait for 50? Why not 40? Or 20? Or, even better, 1?
The endless loop is a good point I hadn't thought of. So I will need to check with an if-clause if the end of the array is reached (through the variable k) and if that isn't true run the program again. So if k holds the number of the last position it won't be recalled...my idea right now.
I used 50 as some kind of golden mid. I don't want to get too many recalls of the routine so I used a higher value.
@AWOL:
I have seen some people using it and running out o memeory... It was the first thing to come to my mind right now and the Mega board offers a bit more memory so I hoped to get that running. I try to keep the number of recursions low.
Why are you performing recursive calls at all? Every pass through loop, read all available data, with one call to the function. If the data is not complete, don't do anything with it. If it is, use it, and reset the array pointer.
I don't get exactly what you mean I think. Wellm, the problem is that I need to read 1185Byte through the Serial-Port from a Sensor which just polls them out after a get-data command and store that in an array for further processing.
Each loop will be one measurement (1185Byte Stream).
But why does each loop need to be recursive?
It's a simple iteration.
Recursion (here) gets you nothing except a lot of hurt when it goes wrong (and looking at "k", that seems very likely)
Is there something about the structure (syntax) of the data that particularly lends itself to recursive parsing?
I'm sorry if my ideas work in a strange way, but I am not an engineer and that's just an idea that came to my mind to get all data ;).
I am sure there is a better way, but right now I haven't found it....
The data is just given after the poll command which is sent every time loop() is executed. It is a plain 1185byte stream where some bytes represent an chat, others long and unsigned long.... so nothing fancy I think.
Edit:
Maybe I check if anything is received yet with a while and run the storing
...above the same as before
void reading()//Read serial data
{
int j;
amount=Serial1.available();
while(Serial1.available()>0)
{
amount=Serial1.available();
for(j=k;j<k+amount;j++)
{
OPCResponse[j]=Serial1.read();
k=j+1;
}
}
}