I would like to implement a network of objects able to share information with several input/output. So I need software serial. However, I find the SoftwareSerial library from Arduino not really interesting as it doesn't have any buffer/interrupt.
I discovered and tested the AFSoftwareSerial from ladyada and it suits my needs perfectly except for one thing: I run with low voltage, so I use ATMega168V10 chips with internal clock so it runs at 8 MHz (same as lilypad). The AFSoftwareSerial is hardcoded very specifically to run at 16MHz.
In one of her replies, ladyada suggests it's possible to implement it.
Looking at AFSoftwareSerial.cpp I found out the critical section:
I decided to create this post to address this specific issue. I don't know much about ASM code so I don't know how to code it for F_CPU=8000000. Any suggestions?
There's actually another issue I just found out about regarding AFSoftwareSerial, which is that the receive buffer is static. Which means that if I got several AFSoftSerial objects they will all have the same buffer.
This is another issue that would need to get addressed IMHO since one of the main objectives behind SoftwareSerial is to be able to have several serial communication channels.
I'm currently working on a patch for separate buffers for each receive pin. I'll send it here once done.
I would need help wrt whackDelay(uint16_t delay) however, to get it to work with 8MHz. I'm just not familiar with assembly so I don't know what you intended to do in that function (and why you needed to use assembly code, for that matter).
Here is a hack you can try, why not call softwareSerial.begin with double the baud rate, this will be pretty close to the correct speed at the slower baud rates.
If that doesn't work at the baud rate you need, or you want something a little less hacky, you could tweek the values for _bitDelay in the case statement in the begin() method of AFSoftwareSerial.cpp.
Unfortunately that link doesn't have a suggestion for changing the software so the hack isn't necessary.
If someone here wants to tinker, I suggest that the #if is removed from the asm code and put in case statement in the method that calculates _bitdelay. At the slower baud rates, _bitdelay will be half its current value on an 8mhz clock. As the baud rate increases it will be increasingly less than half (as the time delay of digitalWrite becomes more significant).
This could be a fun project for someone with an oscilloscope and an 8mhz board.
Good to hear you have it working, but I expect that it will fail at high baud rates because the delay will need to be reduced to compensate for the 4us or more it takes digitalWrite when running on an 8mhz clock. I think some of the higher baud case statements may need a #if statment to compensate for this, but you may need a scope to find the best values.
tatien: can you post a patched version of the library (with multiple buffer support)? The patches you posted didn't seem to apply cleanly to the the version of the library I downloaded.
IF so, may I make the suggestion that it be modified slightly to inherit from Print before incorporation? That way we don't have to duplicate the formatting code that Print already provides, especially if/when floating point is added to Print. It would be nice if the HW and SW serial interfaces were identical.
@ladyada and @tatien: May I ask why AFSoftwareSerial seems to support only pins 0-13 (and not 14-19 -- the ones marked "analog in")?
if (_receivePin < 8) {
// a PIND pin, PCINT16-23
PCMSK2 |= _BV(_receivePin);
PCICR |= _BV(2);
} else if (_receivePin <= 13) {
// a PINB pin, PCINT0-5
PCICR |= _BV(0);
PCMSK0 |= _BV(_receivePin-8);
}
@tatien: Can you explain why all instances of your modified AFSoftwareSerial must share the same baud rate? Is there a physical reason for that, or is it just a matter of convenience?