rxcenter is used to get the middle of the pulse, so when reading the bit stream you're not on a falling or rising edge.

What I actually did was place the existing table in Excel; Calculate the "ideal" table (clock/baud) and adjust the numbers for the differences (subtractions). For the 8Mhz I got a negative value so I adjusted the formula with an additional max() [pragmatic].

First test with Arduino 1.0 SoftwareSerial example code and a Serial LCD - 9600 & 19200 baud - it behaves identical. Mind you: Both the original table version and the new formula version miss a byte once and a while when sending more than ~10 bytes Adding a delay(1) in the code helps a bit but.....

// Set up RX interrupts, but only if we have a valid RX baud rate if (_rx_delay_stopbit) { if (digitalPinToPCICR(_receivePin)) { *digitalPinToPCICR(_receivePin) |= _BV(digitalPinToPCICRbit(_receivePin)); *digitalPinToPCMSK(_receivePin) |= _BV(digitalPinToPCMSKbit(_receivePin)); } tunedDelay(_tx_delay); // if we were low this establishes the end }

The memory size of the 2 sketches:TABLE BASED : 4484FORMULA BASED: 4302==> 182 bytes less

every entry in the DELAY_TABLE = 12 bytes x 12 entries = 144 bytesso the code is also shorter => no search loop and progmem calls)

in fact as we calculate the baudrate we can also leave out the following lines from SoftwareSerial::begin()- _rx_delay_centering = _rx_delay_intrabit = _rx_delay_stopbit = _tx_delay = 0;- if (_rx_delay_stopbit)- and remove the local variable baud too

A serial protocol is like a train with wagons and on each wagon there is one bit, 10 bits in total (including start/stop bits). The baud rate represents the speed of the train.

The software serial receiving code is triggered by the edge of the start bit (train). To read a bit properly one wants to read the value of the signal (HIGH/LOW) in the middle of the bit, not at the edges.

rxCenter is the time to the (approx) middle of the first (start) bit, rxIntra, rxStop are used as timings from the middle of one bit to the middle of the next. The higher the baud rate the lower these numbers.

tx is used for the timing for the transmit.

You can see this in the code of the library - C:\Program Files (x86)\arduino-1.0\libraries\SoftwareSerial - (windows)and search for this function - void SoftwareSerial::recv() -

Did a more extensive test with the SoftwareSerial using the formula approach.I connected two Arduino's - UNO, 16Mhz (resonator) + 2009, 16Mhz (crystal) + IDE 1.0 - both using SoftwareSerial, one Master and the other Slave (essentially an echo).

The master sent byte 0x55 at baudrate 100 and waits until the slave echos it back. If the answer is not 0x55, the test fails and master prints a message. Otherwise it just increases the baud rate with 100 and starts over.

The results are pretty good as it only gets constantly distorted above 190K baud.Between 90K and 190K it only failed 10 times.

I took 0x55 as test pattern 0x55 == 01010101 ; it helps to see what happened. (see comments after output

Typical output (multiple runs had comparable output)Note: started with baud rate 100 in steps of 100...

Conclusion from the tests, SoftwareSerial "by formula" works very good up to 70.000 and reasonable well up to 115.200Tweaking the formulas further may improve the test results but for now I'm quite satisfied.

This SoftwareSerial "by formula" allows one to build a communication channel in which the baud rate is constantly altered, making it very difficult to eavesdrop - and yes to get in sync

I applaud this effort. Thanks for investigating so thoroughly. I always thought it might be fun to develop some equations that allow the synthesis of the "table" values on the fly, and now it looks like you are pretty close to doing just that.

It's good that you are getting error-free transmission up to 70K. Make sure you test not just the single byte round trip, but also lots of bursts. The values should vary Example:

1. Arduino sends 0x55 as fast as possible to host for one minute.2. Arduino sends 0xFE as fast as possible to host for one minute.3. Arduino sends 0x01 as fast as possible to host for one minute.4. Host sends 0x55 as fast as possible to Arduino for one minute.5. Host sends 0xFE as fast as possible to Arduino for one minute.6. Host sends 0x01 as fast as possible to Arduino for one minute.

When constructing the tables, I found several times that I thought the values were good--until I tested the large bursts.

If we want to improve performance at baud rates > 57.6K, I think we're going to have to optimize the timer tick vector. I studied this for some time with the logic analyzer and discovered that the occasional glitch was due to a timer tick interrupt being processed exactly when a pin change was pending.

Lastly, and you probably already know this, but if your formula is off a bit for the lower baud rates, it shouldn't be a big deal. They are very tolerant.