Go Down

Topic: NewSoftSerial Library: An AFSoftSerial update (Read 39158 times) previous topic - next topic


It doesn't compile again ;-(

OS: openSUSE 11.1

i | avr-libc                       | package    | 1.6.6-10.7           | i586   | AVR
i | cross-avr-binutils             | package    | 2.19-9.1             | i586   | openSUSE-11.1-Oss
i | cross-avr-gcc44                | package    | 4.4.0_20090604-15.3  | i586   | AVR


NewSoftSerial.cpp:54: warning: only initialized variables can be placed into program memory area
/tmp/cc5IqSje.s: Assembler messages:
/tmp/cc5IqSje.s:229: Error: register r24, r26, r28 or r30 required
/tmp/cc5IqSje.s:282: Error: register r24, r26, r28 or r30 required
o: In function `main':
undefined reference to `NewSoftSerial::NewSoftSerial(unsigned char, unsigned char)'

There is one option though:

You can also install gcc43, then it works again as it then uses gcc43, but you need to keep gcc44 or it will downgrade avr-libc and that gets some more dependency hell going ;-(


Simple newbie question..
Does NewSoftSerial use Timer2 at all?




Aug 02, 2009, 08:02 am Last Edit: Aug 02, 2009, 08:24 am by p53 Reason: 1

I am new to Arduino and need multiple serial ports, but I have a question about NewSoftSerial: the page at Arduiniana says that you can only use one serial device at a time, and have to designate one as "active" at any given time. Does this mean the buffer cannot receive data from the inactive devices? I have a setup where it is unpredictable which serial devices will chime in next and when, so I can't declare ahead of time--I need to "listen" to all of them, all the time. Will NSS not work for me, or does the "one at a time" rule only apply to READING the buffer, not the buffer accumulation itself?

Also, is there any documentation to NSS that lists all the functions you can call, and how they work, sort of like the "Reference" section of the main Arduino page?

Sorry if these questions are dumb, I'm a newb. Thanks in advance!


Aug 02, 2009, 11:25 pm Last Edit: Aug 02, 2009, 11:58 pm by mikalhart Reason: 1
Hi p53--

Your question is far from dumb.

I'm afraid the "one at a time" rules applies to the actual reception of the data and not just to when you check the buffer.  The reason is this.  If two devices are connected via "soft" serial ports, we have to assume that they are transmitting independently to the Arduino.  As you say, it is entirely unpredictable when a byte might arrive from either one.  But reliable reception on a software port requires that the whenever a byte arrives, the processor is 100% occupied in receiving it.  So you see, if two bytes arrive from the ports at close to the same time, the processor can either abandon the partly-finished byte that arrived first to process the second, or ignore the second in favor of the first, but it cannot process both at once.

That's why you can't actively receive on two ports at once.

However, there are many successful designs out there where, say, you monitor the serial GPS device for a while, perhaps processing a single sentence, and then make your XBee active for another while.  You might also see if one of the devices might be attached instead to a hardware port.

I hope some of this helps.  I'd like to help your project succeed.

To answer your last question, no, I have long wanted to add a "reference" section to all my Arduiniana libraries, but unfortunately the project has not yet bubbled up to the top of my priority stack.

Good luck!




Thanks, that makes sense. I was hoping that maybe there was some magic beyond the horizon of my understanding that would make simultaneous reception possible, but that was wishful thinking. I'll try to come up with a synchronized scheme whereby each device holds off until its "turn" to "speak"--I think this may be feasible without losing any data. The other devices are actually other Arduinos, so I can probably program them to wait, and then say everything in bursts.

Thanks for all your voluntary hard work on this! No rush on the Reference page, I think I can figure out what I need from the included code examples.



Patrick, I happen to be working with this multi-port receive issue in some writing I'm doing.  Perhaps this sample sketch might give you an idea how you might structure your code.  This kind of solution isn't for everyone, but it might be enlightening.

Here I have an XBee radio that I am listening for input on.  As soon as I get a 'y' from the radio, I want to note my position, as defined by the serial GPS device I also have connected.  Here's a solution that will work with NewSoftSerial:

Code: [Select]
#include <NewSoftSerial.h>
const int rxpin1 = 2;
const int txpin1 = 3;
const int rxpin2 = 4;
const int txpin2 = 5;
NewSoftSerial gps(txpin1, rxpin1); // gps device connected to pins 2 and 3
NewSoftSerial xbee(txpin2, rxpin2); // gps device connected to pins 2 and 3

void setup()

void loop()
 if (xbee.available() > 0) // xbee is active.  Any characters available?
   if (xbee.read() == 'y') // if xbee received a 'y' character
     unsigned long start = millis(); // begin listening to the GPS for 10 seconds
     while (start + 100000 > millis())
       if (gps.available() > 0) // now gps device is active
         char c = gps.read();
         // *** process gps data here

After 10 seconds of processing GPS, it returns to listening to the XBee.  This paradigm isn't for everyone, but something similar might work for you.



Nov 12, 2009, 09:45 pm Last Edit: Nov 12, 2009, 09:46 pm by madworm Reason: 1
NewSoftSerial V9 doesn't compile on openSUSE 11.2

i | avr-libc                       | package    | 1.6.7-4.2
i | cross-avr-binutils         | package    | 2.19.51-16.1
i | cross-avr-gcc44           | package    | 4.4.1_20090817-17.1

The offending code:

Code: [Select]
inline void NewSoftSerial::tunedDelay(uint16_t delay) {
 uint8_t tmp=0;

 asm volatile("sbiw    %0, 0x01 \n\t"
   "ldi %1, 0xFF \n\t"
   "cpi %A0, 0xFF \n\t"
   "cpc %B0, %1 \n\t"
   "brne .-10 \n\t"
   : "+r" (delay), "+a" (tmp)
   : "0" (delay)

Same error about some registers as posted before.


Nov 25, 2009, 03:14 am Last Edit: Nov 25, 2009, 03:54 am by bugmenot3 Reason: 1
Thanks for making, this it's awesome!

With regards to the error above, the offending line is the "sbiw    %0, 0x01 \n\t". I'm messing around with alternatives, I found some place that suggests manually moving %0 into a register before calling sbiw which I'll try soon.

edit: 64bit linux, GCC 4.4.2, avr-gcc 4.4.1. I don't know what I'm doing so I gave up on my mov r30, %0 and sbiw r30, 0x01 idea.


Hmmm... Thanks for the analysis.  It may be tricky to modify it to work correctly with GCC 4.4 AND still maintain the correct timing.

-- Mikal


If only the register naming of inline assembler didn't suck that much... I swear I've read more than one manual regarding this and it still is pretty obscure stuff.


I wonder if the best solution for NewSoftSerial would be to abandon this little tunedDelay() function and migrate over to DelayMicroseconds().




sorry for this "necro post", but I'm running out of ideas.
I'm trying to interface an arduino with a bluetooth chip, enabling the arduino to talk to my computer (over bluetooth).
I'd like to describe the situation / problem first, I'll give a short list of technical data at the bottom. All help is appreciated.

I have an arduino that I have hooked up to a bluetooth device, I'm trying to make the arduino talk to my computer (which also has a bluetooth device, obviously). I have tried the SoftwareSerial library, which doesn't appear to ever see anything it can read, a custom method that is based on a interrupt on the rx pin, trying to read the bits as the fly past (to my understanding this is also how NewSoftSerial reads data), aswell as the SoftwareSerial library.
I can send data to my laptop without problems, it arrives just as I send it (with a quirk of inverted linebreak/newline characters, but thats a quirk of the bluetooth chip I reckon), the receiving data on the arduino side is the problem.
SoftwareSerial denies the existance of ever seeing anything arrive.
The NewSoftSerial however, shows promise.
While calls to the available() method say that it has nothing to read, pure calls to the read() method give back invalid values (-1, no byte found). But this is the part where I see promise, because it will print a number of error bytes based on the number of characters I sent to the arduino (bluetooth device).
ie: I send a message "hello" to the arduino, the arduino would print 5 times a -1 value to the computer through its hardware serial.
This tells me that it is receiving something, but I have the feeling it doesn't know what it is it is trying to read..
Any insights and help regarding the matter would be most appreciated!

The sketch(es), in case it yields any information regarding the issue:
Code: [Select]
#include <NewSoftSerial.h>

NewSoftSerial mySerial = NewSoftSerial(2, 3, false);

void setup()
 pinMode(2, INPUT);  //softserial rx
 pinMode(3, OUTPUT); //softserial tx
 pinMode(4, OUTPUT); //reset pin of the bluetooth module
 pinMode(5, INPUT);  //"has a connection" pin of the bluetooth module
 pinMode(8, OUTPUT); //led
 digitalWrite(4, LOW);
 delay(1800); //reset the bluetooth module for at least 1500ms
 digitalWrite(4, HIGH);

void loop()
//most basic attempt, which prints a number of -1's equal to the number of characters sent to the arduino

//basic test attempt, doesn't print anything on Serial
 if(!digitalRead(5)) //this pin goes HIGH if the bluetooth device has a connection
   digitalWrite(8, HIGH); //light up a LED
   digitalWrite(8, LOW); //no connection, turn off the LED

Technical details:
- OS of computer: ubuntu 9.10
    - class2 transmitter
- Arduino IDE version 16
- NewSoftSerial version 10
- DFRduino duemilanove with atmega328 chip
- promi-ESD bluetooth chip
    - 9600bps baud (baud rate of 9600, I assume?)
    - 8 data bit, no parity, stop bit 1
    - H/W flow control
    - 3.3v input voltage (a custom chip drops the arduino voltages for safe interfacing)
    - pulls 73mA in its most power hungry state
    - class1 transmitter


Hi, running your example program:

#include <NewSoftSerial.h>

NewSoftSerial mySerial(2, 3);

void setup()  
 Serial.println("Goodnight moon!");

 // set the data rate for the NewSoftSerial port
 mySerial.println("Hello, world?");

void loop()                     // run over and over again
 if (mySerial.available()) {
 if (Serial.available()) {

I've got two PUTTY windows open, the hardware uart is on COM3, and the SoftSerial is on COM4 on pins 2, 3.  Both windows print out their greetings fine.  When I type on COM3, I see the characters echoed on COM4 tty.  However, when I type on COM4, I don't see anything echoed back to COM3.  

COM3 is going to a tested FTDI, COM4 is a Modern Device P4, going to a Profile RS232->USB cable. Both have been tested for uploads with Arduino.


Hard to say for sure, but the appearance of that RS-232 worries me.  I suspect either a voltage level problem (RS-232 is different than TTL) or perhaps the RX wire is not correctly connected to pin 2.


Go Up