software serial2

[

er, no..."currently only for Diecimila (16mhz atmega168)" :wink:

er, pity

send me a lilypad an an NG with an 8mhz xtal and ill make it work with 'em!

[

er, no..."currently only for Diecimila (16mhz atmega168)" :wink:

er, pity

send me a lilypad an an NG with an 8mhz xtal and ill make it work with 'em!

I needed a solution a while back, but improvised this instead.

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1201476854/5#5

This should work with your 168's aye, if I wanted to make something like a dualCoreDuino ;D

Thanks for that, it will be a huge help.

One question, with interrupts turned off when sending a char, does that mean that receive bits will be lost if they are presented at the same time as a character is being sent?

yes
but the old software serial couldnt do that either so its not really a big deal

No big deal at all (as long as users are aware that data may be missed if received while sending). Many thanks for taking the time and effort to impliment this. It will be very useful to me and I am sure many other people.

er, no..."currently only for Diecimila (16mhz atmega168)" :wink:

Isnt the Lillypad a 168? Not sure about the Bluetooth one.

er, no..."currently only for Diecimila (16mhz atmega168)" :wink:

Isnt the Lillypad a 168? Not sure about the Bluetooth one.

I believe the lilypad uses the internal clock so runs at 8mhz.

Hello ladyada,

I am working on the RFID reader which operates at baudrate 2400. I have tried to amend your coding in order to support it but I cannot figure out the correct _bitDelay for baudrate 2400....

Would you please provide me the library that supports baudrate 2400?!

Thanks for your assistant in advance!!!!!

You don't need to be changing the library, the parameters are set by the application.

SS works "up to" 9600, so the phidgets at 2400 should be fine

 #include <AFSoftSerial.h> 
 
 AFSoftSerial mySerial = AFSoftSerial(3, 2); 
 
 void setup() { 
  pinMode(13, OUTPUT); 
  Serial.begin(9600); 
  // set the data rate for the SoftwareSerial port 
  mySerial.begin(2400); 
  mySerial.println("Hello, world..."); 
 } 
 
 void loop()           // run over and over again 
 { 
  if (mySerial.available()) { 
    Serial.print((char)mySerial.read()); 
  } 
  if (Serial.available()) { 
    mySerial.print((char)Serial.read()); 
  } 
 }

You'll need to remove the 'hello world' of course :slight_smile:

However, after go through the source code of AFSoftSerial.cpp, it seems that it only supports down to 4800........

  _baudRate = speed;
  switch (_baudRate) {
  case 57600:
    _bitDelay = 17; break;
  case 38400:
    _bitDelay = 28; break;
  case 31250:
    _bitDelay = 36; break;
  case 19200:
    _bitDelay = 62; break;
  case 9600:
    _bitDelay = 128; break;
  case 4800:
    _bitDelay = 270; break;
  default:
    _bitDelay = 0;
  }

well its pretty trivial to add support for any baudrate. i havent officially released this so ill add 2400 - i didnt realize anything out there used < 4800 :stuck_out_tongue:

ladyada:
First of all, thanks for your reply!!
Actually, I am working on parallax RFID Reader Module which is configured as 2400bps. Therefore, I would like to amend the coding in AFSoftSerial in order to support the RFID module.

As mentioned before, I cannot figure out the appropriate _bitDelay for baudrate 2400. Could you do me a favour!? Thanks!!!

  _baudRate = speed;
  switch (_baudRate) {
...
...
case 2400:    _bitDelay = XXX ; break;
     default:    _bitDelay = 0;
  }

Ref.
http://www.parallax.com/Store/Microcontrollers/BASICStampModules/tabid/134/txtSearch/rfid/List/1/ProductID/114/Default.aspx?SortField=ProductName%2CProductName

How hard do you think it would be to be able to have multiple instances of the class on different pins? It's a bit misleading to be able to create lots of instances of the AFSoftSerial class but only have one of them able to receive data.

this is an unreleased project, i posted it "if someone wants to play with it...", it was designed so i could hack and debug my xport shield.
its not a direct replacement for the default softwareserial so if you need multiple serial ports, different baudrates or atmega8/lilypad support then this isnt for you. in fact, it isnt even fully debugged so for all i know it may not work in certain situations.

Sorry, I didn't mean to make unreasonable demands. The library is quite good for an unsupported / unreleased project. The reason I ask is only because I'd really like to replace the current SoftwareSerial library with something along the lines of the AFSoftSerial. I was hoping you might be able to do some of the clean-up / improvements. Do you have any time for that, or might you in the future? Or should I take a shot at it?

this is an unreleased project, i posted it "if someone wants to play with it...", it was designed so i could hack and debug my xport shield.
its not a direct replacement for the default softwareserial so if you need multiple serial ports, different baudrates or atmega8/lilypad support then this isnt for you. in fact, it isnt even fully debugged so for all i know it may not work in certain situations.

Don't worry about the Lilypad they join at the hip quite nicely via I2C and are inexpensive enough to stack two together to provide the solution I was looking for.

You did an excellent job it's a good start. And there's a great deal of enthusiasm for this as a solution to the nagging problem of only having one hardware serial, so moving it forward is a big accomplishment.

Ladyada,

Tom and I put your software serial up on the scope at the last hack to verify it's correct operation. We couldn't get it to work for the slower baud rates and came to a couple of conclusions about why. First off, thanks everyone at the Hacklab for helping!

Looking through your code, here are some suggestions to help improve your library...

You need to make sure multiple interrupts aren't stacking up without being handled so,

Having delays based on an overflowing timer0 interrupt inside of a pinChange interrupt handler is asking for trouble.
Also, why not disable the pin change interrupt (clear the mask) after the start bit?
When using a software serial, make sure other interrupts aren't screwing up recv delay;

Since you calculate constants for the delays anyway, why not use unoptimizable loops to generate your bit timing delays?

So maybe it could go like this (without a buffer of course),


pinChangeInterruptHandler()
{
if ( (RX pin is low) && (startBitArrived == FALSE) )
{
startBitArrived = TRUE
pinChangeMask = Disabled;
}

}

//the receive function
recv()
{
recvDone == FALSE;

while(recvDone == FALSE)
{

if (startBitArrived)
{
cli(); //disable interrupts
delay(bitTime/2); //use a fixed delay not based off of interrupts
for (unsigned char bit =0; bit < 8; bit++)
{
read RX pin;
delay(bitTime);
}

delay(bitTime/2); //put us at the end of the stop bit

recvDone = TRUE;
pinChangeMask = ENABLED;
startBitArrived = FALSE;
sei(); //enable interrupts
} //end if

} //end while

} //end recv

Ladyada,
Tom and I put your software serial up on the scope at the last hack to verify it's correct operation. We couldn't get it to work for the slower baud rates and came to a couple of conclusions about why. First off, thanks everyone at the Hacklab for helping!

Looking through your code, here are some suggestions to help improve your library...

You need to make sure multiple interrupts aren't stacking up without being handled so,

Having delays based on an overflowing timer0 interrupt inside of a pinChange interrupt handler is asking for trouble.
Also, why not disable the pin change interrupt (clear the mask) after the start bit?
When using a software serial, make sure other interrupts aren't screwing up recv delay;

what baud rates are you specifically referring to? what was your test that you couldnt get working?
could you specify where im using timer0 in my code? i dont see it anywhere so im not sure why you're referring to it. there should not be any interrupts that overlap unless, of course, you have the mismatched baud rates, but if you do that you're kinda on your own

I am referring to 9600 baud.

In your pin change interrupt handler, if you don't disable interrupts, how can you be assured the timing is correct? What if timer0 overflows during your recv routine? What if people are using other interrupts?

In whackDelay, how can you be sure the compiler won't optimize away your software delay loop? Maybe consider making those variables 'volatile'

When do you disable the pinchange mask?

I am referring to 9600 baud.

In your pin change interrupt handler, if you don't disable interrupts, how can you be assured the timing is correct? What if timer0 overflows during your recv routine? What if people are using other interrupts?

SIGNAL interrupt handlers, by default, call cli() at the beginning, and sei() at the end so no interrupts will get in the way while it receives data. i specifically call sei() and cli() for printing
if someone wants an interrupt to go off while receiving/transmitting data, well, they're SOL cause you cant get good timing otherwise :slight_smile:

In whackDelay, how can you be sure the compiler won't optimize away your software delay loop? Maybe consider making those variables 'volatile'

that could be happening, although it doesnt in my version of the Arduino software (10)
which version are you using? this would be helpful for debugging. thanks!

thanks

No problem!

It's really exciting seeing this library evolve into a powerful and robust library for the Arduino community. Great work everyone!

please answer the questions so that i can verify the problems you had

"which version of arduino software are you using? this would be helpful for debugging. thanks!"