baudrate problem with teensy to teensy byte package communication

Status
Not open for further replies.
I am curious about the use of noInterrupts () interrupts() block when used in the routines running in interrupt context. If you issue an interrupts() command, does that enable all interrupts right then and subject the program to the possible condition that a 2nd interrupt may enter the same routine? Meaning you could have the processor enter non-reentrant code.

You are right rcarr, thank you. I do not know how I could manage the transfer of data between different interrupts without using noInterrupts(), interrupts() ...
 
I don't know that I am correct on anything, I am asking. But while in an interrupt, you do not need noInterrupts() because all interrupts of the same priority will wait.

For your issue, I am suspecting the SD card write while in an interrupt context. I have not played with cards myself but I believe I have read on these forums that sometimes an SD card write will take much longer than expected and if done in an interrupt, none of your other code will run. So possibly your serial line misses a lot of characters because the loop code ( or your previous interval timer code ) can't run while waiting for the SD card write to finish.
 
I agree with rcarr, the lag is due to SD card write time. You are opening and closing the file each time, which is not ideal. You need to use a binary system with preallocated space. There are a lot of examples out there, but if you have a packet of 512, it should be easy to fill it, write and move on. You will see very minimal lag with this. Think you asked this in another thread, so should be no surprise to you that you are seeing this random slowing of data. I suggest use the SD fat example, it might work perfect for you, just change the struct to your data and you should be fine.
 
you should run 2 parallel arrays, write to one, when its full, start writing it to sd while filling the other
rinse and repeat
 
I'm looking at the code from msg #19. While it's better (and much easier to read the code now :) ), the parsing for the message start sequence is still not what it really should be.

You're *still* taking the approach of reading 3 bytes before checking ANY of them.

Code:
    input_bytes = 0;
    while (!(input_bytes >= 3)) {
      if ((Serial1.available() > 0) && (input_bytes < 3)) {
        Incoming_Data.vData[input_bytes] = Serial1.read();
        input_bytes++;
      }
    }
    // check if the first three bytes are correct
    if (checkPacket_start(Incoming_Data.vData)) {

When "input_bytes" is 0, 1 or 2, you should read 1 byte. If that 1 byte is not exactly the expected byte of your 3 byte sequence, you should immediately set input_bytes back to zero. You should use "continue" or otherwise begin looking for the first byte. Do not call checkPacket_end() after you set input_bytes back to zero. You know there isn't any data, but your code does this anyway, perhaps rechecking the message in the buffer from last time?

Anyway, the point is when "input_bytes" is zero, read 1 byte and check it. Increment "input_bytes" to 1 only if that byte is correct. Then read 1 more, and check it. The idea is to immediately put "input_bytes" back to zero when you receive any byte that isn't the correct start sequence WITHOUT READING MORE BYTES after the bad one.

When something goes wrong, the very next byte might be the true beginning of a packet. Never read beyond a bad byte and discard the stuff you didn't use. Always stop when something is bad and treat the very next byte after a wrong start as the possible new start of a good message.
 
I saw this example that does what Paul notes in Post #30 - :: bolderflight/UBLOX/blob/master/UBLOX.cpp#L331

It is reading a GPS string over Serial - so the situation at hand is very similar.

The code calls READ - which calls PARSE to look for a completed message - but it verifies each of the two start bytes in that case and resets the index to [0] if not found.

<edit>: Btw - this is being used on a system reading the GPS at 5 Hz - IMU on i2c at up to 480 Hz usable (of 500) - and also sending out those 480 IMU readings using the SPI_MSTransfer SPI code to a second Teensy. It would run faster but the EIGEN and DOUBLE (not float) math takes more time each second to run any faster. Offloading the USB output to the Slave saves 200 micros per calc interval and that 480 IMU readings is 10% higher because of it - it was running that 10% slower when it was not using the 50 micros of time it takes for the 100 byte transfer. The impact of this is 10% on the T_3.6 at 240 MHz - it is even more on the T_3.5 system where the SPI can transmit at about the same speed and save even more time with the Slave doing the USB output and formatting. So that is a busy system - if the Encoder reads are fast over SPI (under ~800 us?) - squeezing in another 40 micros to transfer the 34 bytes to your slave over SPI might actually speed things up and provide a simple CRC checked data delivery even at 1000 Hz.
 
Last edited:
In hindsight, I probably should have mentioned Bill Porter's excellent EasyTransfer library much earlier in this thread.

https://github.com/madsci1016/Arduino-EasyTransfer

Bill library does pretty much exactly what you're trying to accomplish here, sending a struct of data between 2 boards. There are actually 4 versions of the library to use 4 different ways of communicating. The main one uses Serial.
 
Thank you every body for your precious help. I am actually working on the code and I am trying to implement your suggestions.
I will let you know any progress as soon as possible! :)
 
Hi everybody,
I have implemented both the data acquisition and the writing on the SD card in the void loop (no more timers and interrupts) and I am able to save the data on the card at 1 kHz.
There are some more details to be fixed but now the code works way better than before.

Thank you again for your precious help.
 
not a fan of while loops, especially when they sit there waiting for bytes, most likely it sat there because it DIDN'T receive anything, which is possible

You should just capture the bytes as they come in, Nick Gammon has examples that are better than above

Whats the packet your receiving? does it include a header, id, checksum? what does it look like? I wouldnt suggest the while loop method waiting for bytes, its blocking and may potentially sit there forever

Nick has made a page for serial data parsing, it's a good base to start with
https://www.gammon.com.au/serial
 
Status
Not open for further replies.
Back
Top