Welcome, Guest. Please Login or Register
YaBB - Yet another Bulletin Board
09.02.2010 at 18:04:07
News: Server upgrade went fine, you are now at the new system


Pages: 1 2 3 
software serial2 (Read 11076 times)
ladyada
Full Member
***
Offline

Arduino rocks

Posts: 232

software serial2
05.02.2008 at 22:00:05
 
i need to use software serial to interface with the xport, but i couldnt get consistant results, even at 9600 so i poked at it a little and made a version that uses a pinchange interrupt (for diecimila or NG with chip upgrade only!). now it buffers the input characters to avoid the dreaded 'lost bits' errors i got.
it seems to work great! i will clean it up and make it more 'objecty' and maybe turn it into a library, but if someone wants to play with it...

/*
* Software UART
*
*/

int ledPin = 13;                // LED connected to digital pin 13

/*******************************************************************************
********/

#include <avr/pgmspace.h>

#define altPrint(x) alt_ROMputstring(PSTR(x), 0)
#define altPrintln(x) alt_ROMputstring(PSTR(x), 1)

int rxpin, txpin, altserialdelay = 0;
#define MAX_ALTRX_BUFF 8
char altRXD[MAX_ALTRX_BUFF];
int altrxsize = 0;

SIGNAL(SIG_PIN_CHANGE0)
{
 if ((rxpin >=8) && (rxpin <= 13)) {
   altRecv();
 }
}
SIGNAL(SIG_PIN_CHANGE2)
{
 if (rxpin <8) {
   altRecv();
 }
}

void altDelay(int delay) {
 while (delay != 0) {
    delay--;
 }
}

void altRecv(void) {
 char i, d = 0;
 if (digitalRead(rxpin))
   return;       // not ready!
 altDelay(altserialdelay-5); // one half bit
 for (i=0; i<8; i++) {
   PORTB |= _BV(5);
   altDelay(altserialdelay*2); // one bit
   PORTB &= ~_BV(5);
   if (digitalRead(rxpin))
     d |= (1 << i);
 }
 altRXD[altrxsize] = d; // save data
 altrxsize++;  // got a byte
 altDelay(altserialdelay*2);
}

void altSerialSetup(int baudrate, char tx, char rx) {
 txpin = tx;
 pinMode(txpin, OUTPUT);
 digitalWrite(txpin, HIGH);
 rxpin = rx;
 pinMode(rxpin, INPUT);
 digitalWrite(rxpin, HIGH);  // pullup!
 if (baudrate == 19200) {
    altserialdelay = 62; // these are determined experimentally
 } else if (baudrate == 9600) {
    altserialdelay = 128;  // these are determined experimentally
 }    
 if (rxpin < 8) {
   // a PIND pin, PCINT16-23
   PCMSK2 |= _BV(rxpin);
   PCICR |= _BV(2);
 } else if (rxpin <= 13) {
   // a PINB pin, PCINT0-5
   PCICR |= _BV(0);    
   PCMSK0 |= _BV(rxpin-8);
 }
}


void altPutchar(char d) {
 int i;
 cli();  // turn off interrupts, make it nice & kleen
 digitalWrite(txpin, LOW);       //start bit
 altDelay(altserialdelay*2);
 for (i=0; i< 8; i++) {
   if (d & 0x1) {
      digitalWrite(txpin, HIGH);
   } else {
      digitalWrite(txpin, LOW);
   }
   altDelay(altserialdelay*2);
   d >>= 1;
 }
 digitalWrite(txpin, HIGH);     // one stop bit
 sei();   // turn on interrupts
 altDelay(altserialdelay*2);  
}

void alt_ROMputstring(const char *str, uint8_t nl) {
 uint8_t i;

 for (i=0; pgm_read_byte(&str[i]); i++) {
   altPutchar(pgm_read_byte(&str[i]));
 }
 if (nl) {
   altPutchar('\n'); altPutchar('\r');
 }
}
void altPrintNumber(uint16_t n) {
     uint8_t cnt=0, flag=0;
     
     while (n >= 10000UL) { flag = 1; cnt++; n -= 10000UL; }
     if (flag) altPutchar('0'+cnt);
     cnt = 0;
     while (n >= 1000UL) { flag = 1; cnt++; n -= 1000UL; }
     if (flag) altPutchar('0'+cnt);
     cnt = 0;
     while (n >= 100UL) { flag = 1; cnt++; n -= 100UL; }
     if (flag) altPutchar('0'+cnt);
     cnt = 0;
     while (n >= 10UL) { flag = 1; cnt++; n -= 10UL; }
     if (flag) altPutchar('0'+cnt);
     cnt = 0;
     altPutchar('0'+n);
     return;
}

int altAvailable(void) {
 
 
}

/*******************************************************************************
********/



void setup()                    // run once, when the sketch starts
{
 pinMode(ledPin, OUTPUT);      // sets the digital pin as output
 altSerialSetup(9600, 2, 3);
 Serial.begin(9600);
}

int counter=0;
void loop()                     // run over and over again
{
 digitalWrite(ledPin, LOW);    // sets the LED off

 if (altrxsize) {
     Serial.print(altRXD[0]);
     altrxsize--;
 }
 if (Serial.available()) {
     altPutchar(Serial.read());
 }

}

Back to top
 
 
View Profile   IP Logged
mellis
YaBB Administrator
*****
Online



Posts: 3006
Cambridge, MA
Re: software serial2
Reply #1 - 05.02.2008 at 22:34:23
 
Awesome.

The current SoftwareSerial library kind of sucks, so it would be great to have this as a replacement.  Let us know when you do and I can include it in the distribution.
Back to top
 
 
View Profile | WWW   IP Logged
ladyada
Full Member
***
Offline

Arduino rocks

Posts: 232

Re: software serial2
Reply #2 - 06.02.2008 at 00:55:43
 
ok i fixed it

http://www.ladyada.net/make/eshield/AFSoftSerial.zip

supports RX and TX, up to 57600 tested. due to the delay inherent in digitalRead() its probably not possible to go any faster.
should probably be poked at by others. currently only for Diecimila (16mhz atmega168)

#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(9600);
 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());
 }
}
Back to top
 
 
View Profile   IP Logged
John_Ryan
God Member
*****
Offline

skcor oniudrA

Posts: 684

Re: software serial2
Reply #3 - 06.02.2008 at 04:53:09
 
ladyada wrote on 06.02.2008 at 00:55:43:
ok i fixed it

http://www.ladyada.net/make/eshield/AFSoftSerial.zip

supports RX and TX, up to 57600 tested. due to the delay inherent in digitalRead() its probably not possible to go any faster.
should probably be poked at by others. currently only for Diecimila (16mhz atmega168)

#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(9600);
 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());
 }
}


What a genius, you rock! That fixes a huge problem, that would enable a few serial devices to be connected to one board, how did you do it?

Will it work with BT's, Lilypads and NG's?
Back to top
 
 
View Profile   IP Logged
ladyada
Full Member
***
Offline

Arduino rocks

Posts: 232

Re: software serial2
Reply #4 - 06.02.2008 at 06:01:52
 
Quote:
What a genius, you rock! That fixes a huge problem, that would enable a few serial devices to be connected to one board, how did you do it?


actually you can only have one software serial device at a time (right now) because of the pinchange interrupt. i could adapt it for more but its a real hassle and, well, i figure this is good enough for now.

Quote:
Will it work with BT's, Lilypads and NG's?


er, no..."currently only for Diecimila (16mhz atmega168)"  Wink
Back to top
 
 
View Profile   IP Logged
mem
God Member
*****
Online

Have fun!

Posts: 5417
London
Re: software serial2
Reply #5 - 06.02.2008 at 06:16:46
 
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?
Back to top
 
 
View Profile   IP Logged
John_Ryan
God Member
*****
Offline

skcor oniudrA

Posts: 684

Re: software serial2
Reply #6 - 06.02.2008 at 06:31:20
 
ladyada wrote on 06.02.2008 at 06:01:52:
[

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


er, pity
Back to top
 
 
View Profile   IP Logged
ladyada
Full Member
***
Offline

Arduino rocks

Posts: 232

Re: software serial2
Reply #7 - 06.02.2008 at 06:39:37
 
mem wrote on 06.02.2008 at 06:16:46:
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
Back to top
 
 
View Profile   IP Logged
ladyada
Full Member
***
Offline

Arduino rocks

Posts: 232

Re: software serial2
Reply #8 - 06.02.2008 at 06:40:29
 
John_Ryan wrote on 06.02.2008 at 06:31:20:
ladyada wrote on 06.02.2008 at 06:01:52:
[

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!
Back to top
 
 
View Profile   IP Logged
John_Ryan
God Member
*****
Offline

skcor oniudrA

Posts: 684

Re: software serial2
Reply #9 - 06.02.2008 at 09:14:58
 
ladyada wrote on 06.02.2008 at 06:40:29:
John_Ryan wrote on 06.02.2008 at 06:31:20:
ladyada wrote on 06.02.2008 at 06:01:52:
[

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  Grin
Back to top
 
 
View Profile   IP Logged
mem
God Member
*****
Online

Have fun!

Posts: 5417
London
Re: software serial2
Reply #10 - 06.02.2008 at 10:58:06
 
ladyada wrote on 06.02.2008 at 06:39:37:
mem wrote on 06.02.2008 at 06:16:46:
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.



Back to top
 
 
View Profile   IP Logged
Cheater
God Member
*****
Offline



Posts: 593
Brisbane, Australia
Gender: male
Re: software serial2
Reply #11 - 07.02.2008 at 08:06:05
 
ladyada wrote on 06.02.2008 at 06:01:52:
er, no..."currently only for Diecimila (16mhz atmega168)"  Wink

Isnt the Lillypad a 168? Not sure about the Bluetooth one.
Back to top
 
 
View Profile | WWW   IP Logged
mem
God Member
*****
Online

Have fun!

Posts: 5417
London
Re: software serial2
Reply #12 - 07.02.2008 at 11:35:07
 
Cheater wrote on 07.02.2008 at 08:06:05:
ladyada wrote on 06.02.2008 at 06:01:52:
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.  
Back to top
 
 
View Profile   IP Logged
kwan6887
YaBB Newbies
*
Offline

Arduino rocks

Posts: 3

Re: software serial2
Reply #13 - 10.02.2008 at 14:45:08
 
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!!!!!
Back to top
 
 
View Profile   IP Logged
John_Ryan
God Member
*****
Offline

skcor oniudrA

Posts: 684

Re: software serial2
Reply #14 - 10.02.2008 at 14:59:08
 
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

Code:
 #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 Smiley
Back to top
 
 
View Profile   IP Logged
Pages: 1 2 3