Hi, I am sending a txt file over serial to sd card. The problem is I send the value over serial and to be able to categorize the input of serial I use some tags like "#" or "$". But if binary data of incoming data is "#", data scrumbles. Reason for this is the program continues to run. I use SerialEvent but in some cases, I want to close global and peripheral interrupts so that program will not run and I wont use tags for a number of incoming byte. Lets say, I have a txt file and I will send 900 bytes. If incoming byte is 0xF2(just a start command), I will know the next byte will be the number of incoming bytes. and I will disable the global and peripheral interrupts so that no data will be lost and scrumbled. when all the bytes processed, I will enable interrupts again. I use this method in PIC but do not know how to do in arduino.
Serial uses interrupts. If you disable interrupts with noInterrupts() then you will lose data.
If you have other interrupts of your own that are taking too much time, then fix those first.
Note that SerialEvent() was described in the older documentation as if it was an interrupt but it isn't. It just runs once after each loop(). If you use that, then you must make sure that your main loop() always finishes in a reasonable amount of time before the Serial buffer fills up.
MorganS:
Serial uses interrupts. If you disable interrupts with noInterrupts() then you will lose data.
If you have other interrupts of your own that are taking too much time, then fix those first.
Note that SerialEvent() was described in the older documentation as if it was an interrupt but it isn't. It just runs once after each loop(). If you use that, then you must make sure that your main loop() always finishes in a reasonable amount of time before the Serial buffer fills up.
This is what i want to do, while program is running, the program will enter SerialEvent function once and it will not go out until i send a connection loss signal such as a byte. Then program will continue to work. To be able to do this, i want to disable global and peropheral interrupts so that data can flow flawlessly.
nurimo:
This is what i want to do, while program is running, the program will enter SerialEvent function once and it will not go out until i send a connection loss signal such as a byte. Then program will continue to work. To be able to do this, i want to disable global and peropheral interrupts so that data can flow flawlessly.
I reckon you can do that without using interrupts and without using SerialEvent.
Serial data cannot flow at all if interrupts are disabled.
AND .... How can you send a byte to signify connection loss if the connection is lost ? ? ?
Give us the full details of what you are trying to achieve and someone will probably be able to suggest a solution.
nurimo:
This is what i want to do, while program is running, the program will enter SerialEvent function once and it will not go out until i send a connection loss signal such as a byte. Then program will continue to work. To be able to do this, i want to disable global and peropheral interrupts so that data can flow flawlessly.
Then you are doing something wrong. The Serial interrupts will ensure that you never miss a byte so long as you DON'T disable interrupts for an excessive period (like more than a millisecond) and you regularly empty the buffer (like every 60 milliseconds.) [These timings assume 9600 baud - shorter periods required for higher baud rates.]
MorganS:
Then you are doing something wrong. The Serial interrupts will ensure that you never miss a byte so long as you DON'T disable interrupts for an excessive period (like more than a millisecond) and you regularly empty the buffer (like every 60 milliseconds.) [These timings assume 9600 baud - shorter periods required for higher baud rates.]
What are you really trying to do?
I said in my first post, i send a txt file using windows form application to the arduino. Arduino records the data. But there is some problem that i didnot see before. Lets say i use tag "#" to start the transmission of txt file into the sd card. And lets say i use "*" as an indicator that transmission is done. When i ude SerialEvent to monitor serial communication and tags. What if the incoming data (txt file data) is equivalent to tags in binary representation, then the transmission is scrumbled. Now i dont want to use tags to indicate that transmission started and ended. I already know when will it be i just need to send the number of bytes that i will send to arduino first and in a for loop, i will wait all of the bytes arrive and write them to sd card. This is what i am trying to do.
nurimo:
Lets say, I have a txt file and I will send 900 bytes. If incoming byte is 0xF2(just a start command), I will know the next byte will be the number of incoming bytes.
Taking your word for what you say: this won't work. 900 is too big a number for a byte. You need at least two bytes to communicate the number of bytes in the file.
nurimo:
i will wait all of the bytes arrive and write them to sd card.
This means you have to reserve a buffer in your memory that can store the largest file you're ever going to send over - even at just 900 bytes that's almost half of the available memory. The SD library takes quite a chunk of memory as well, I suppose this is in part due to its own read/write buffers. I hope you're not doing much else with your Arduino as you have just 2048 bytes of RAM to work with.
As you don't mention otherwise, I'm assuming an Uno or equivalent ATmega328p based Arduino here. There are systems with more RAM.
nurimo:
Lets say i use tag "#" to start the transmission of txt file into the sd card. And lets say i use "*" as an indicator that transmission is done.
Have you studied the example in Serial Input Basics that uses start- and end-markers? Have you tried it?
Robin2:
Have you studied the example in Serial Input Basics that uses start- and end-markers? Have you tried it?
...R
yes thats what i am saying. Lets say, I use "#" as start marker, what if the data itself represents #, then if condition triggers again. And it is not desired.
The problem of the end marker appearing in the data has already been solved. The header must include the number of bytes. I think the OP is already doing this. There are cases when you're sending binary data and there is no "something else".
MorganS:
The problem of the end marker appearing in the data has already been solved. The header must include the number of bytes. I think the OP is already doing this. There are cases when you're sending binary data and there is no "something else".
I have dealt with that by using the byte values 255, 254 and 253 as special. 254 can be the start marker and 255 the end marker and if any of the three byte values actually occurs in the data stream it is replaced by a pair starting with 253. If the receiving code sees a 253 it knows that the next character is data rather than a marker. So, if 254 was required as part of the data it would be replaced by 253 254.
In the OP's case, I suspect something much simpler will suffice - using some non ASCII byte values for the start- and end-markers.