I'm new to the Aduino and I want to try using NewSoftSerial but I have not found any instructions anywhere about HOW to use it. From looking at examples, I have found the following:
//These lines must be included at the beginning BEFORE void setup() #include <NewSoftSerial.h> //includes the library
NewSoftSerial mySerial(2, 3); // defines the rx/tx pins (rxpin, txpin)
//within void setup()
mySerial.begin(9600); // sets the speed
//within void loop()
mySerial.read() //receives a byte
mySerial.print() // transmits a byte
mySerial.println("Hello, world"); // transmits a string with a carriage return
mySerial.available () // returns the number of bytes available.
Are there any OTHER commands or instructions available? Is there anything else that I should know about how this works? Is there a tutorial or any instructional information anywhere else?
Also, I know it's not the best way to review libraries, especially if you're new.. but you can always open the library folder, and view the .cpp and .h files to find out functions.
The .cpp file is generally the heart of the folder, while the .h folder contains all(most) the Commands that library uses.
Thanks Bob, I did what I could and tried NewSoftSerial. My simple program doesn't work. It's just a simple loopback test where pin 4 and pin 5 are connected together. Can anybody tell me what's wrong? mySerial.available is always zero, so no characters are ever received. Here's my code (thanks for any comments) :
//New Soft Serial experiment #include <NewSoftSerial.h>
const int rxPin=4, txPin=5 ;
char rchar='Z';
NewSoftSerial mySerial(rxPin,txPin);
void setup() {
Serial.begin(9600);
mySerial.begin(9600); //New Soft Serial speed
pinMode(rxPin,INPUT); pinMode(txPin,OUTPUT); pinMode(13,OUTPUT);
}
void loop() {
digitalWrite(13,HIGH); delay(1000); // I'm alive
mySerial.print('A');
if ( mySerial.available() > 0 ) { rchar = mySerial.read();}
Serial.println(rchar);
digitalWrite(13,LOW); delay(5000); //Wait and try again
}
I'm not too sure what exactly isn't working about this, I uploaded the code and it was working perfectly.
I do have to point out, everytime you print 'A' on the Serial, you're using Println to print rchar, which is defined as a 'Z' at the beginning of the program. So all you should be receiving is a Z on your Serial port, every 5 seconds.
But I did change my rx and tx pin to 8 and 9 respectively, not sure that'll make a huge difference or not.
HI, Bob, yes you're right - that's what I get - a 'Z' every five seconds on the serial monitor. I initialized rchar to 'Z' so that I would know if it changed from the initial value. I also changed this program to read the character without checking mySerial.available() first. When I did that, then I got FFFFFFFF (Hex) every five seconds. But if the code looks right to you, then I will recheck my connections and pin numbers (although there aren't very many of them). If you (or anybody) has any additional ideas of what might be wrong, please let me know. I'll try different pin numbers too.
Did I read correctly that you have "pins 4 and 5 connected together"? If so, be advised that you can't do a loopback test with NewSoftSerial this way, and in general, it's bad practice to wire two pins together unless you are absolutely sure you know what you're doing. If somebody brings one pin high while the other is low, you'll get a short that will fry your Arduino or worse!
NewSoftSerial is designed to communicate with serial devices in exactly the same way that Arduino's built-in serial port does. You connect two available pins to your peripheral device and NewSoftSerial emulates in software what the built-in port does on pins 0 and 1.
If you do mySerial.println, you send data to the device on the TX line. If you do mySerial.read(), you retrieve data that arrived on the RX line.
If you call mySerial.read() when no data is available, the library returns -1 (which you are printing as FFFFFFFF).
Thanks Mikal for your comments. My goal is just to make something with NewSoftSerial that works so that I can go from there. I understand what you said about connecting pins together. I'm new to Arduino so haven't thought about that. I note that I have done a loopback test with pin 0 and pin 1 using the onboard uart and that worked fine. But my question is: what's the simplest test that I can do that will show that I have NewSoftSerial working? if it's not a loopback test, then is there anything else? I eventually intend to connect the digital pins to a serial modem, but I want to do something first that shows that NewSoftSerial is working. Thanks for your comments.
The simplest test to use is the loop back wire from your sending pin to your receiving pin. As long as you are connecting a digital output pin to a digital input pin there is no fear of damage.
The caution of doing that in general is that if through software changes or errors the two pins were ever changed to both be output pins then damage could happen, so it's not a good general practice, but OK for short just testing, as you are doing.
Lefty, strictly speaking you are correct. It's ok to wire two pins together as long as at most one of them is an output pin. And in fact, as you might guess, that's exactly what happens in NewSoftSerial -- the TX pin is configured as output and the RX pin as input.
But there are two reasons why I don't think Roger should do that. First of all, unless he has dug through the code carefully, there is no way to be sure that a "black box" like the NewSoftSerial library (or any other) configures the pins safely at all times -- even though I can tell you that it does in this case.
The other reason is that it this loopback trick simply won't work with software serial solutions. If you send a byte to a TX pin using any software serial library, there is no way that the software can simultaneously receive that byte. The processor can only do one thing at a time.
Roger, if you just want to prove that NewSoftSerial is working, connect the Arduino to your PC and use NewSoftSerial to drive pins 0 and 1. These are wired to the FTDI serial-to-USB convertor and so if you do something like:
HI, Mikal, thanks for your additional explanations. I'll be experimenting this afternoon. But I have two additional questions:
As I said, I would like to use NewSoftSerial on pins 4 and 5 to control a serial modem (via a MAX232 circuit, which already works). I had hoped to make sure that NewSoftSerial works on pins 4 and 5 by using them in testing. Then if my serial modem connection doesn't work, I can be more sure than it's not a NewSoftSerial problem. Assuming that NewSoftSerial DOES work on pins 0/1 (which I expect), then is there ANY simple test that I can do to make sure NewSoftSerial works on pins 4/5?
My second question is related to your comment: "The other reason is that it this loopback trick simply won't work with software serial solutions. If you send a byte to a TX pin using any software serial library, there is no way that the software can simultaneously receive that byte. The processor can only do one thing at a time." As I'm sure you know, when you send "at" to a serial modem, you get back "OK" immediately. That's not a loopback, but it's close. In fact, that would be true on most commands to a serial modem. Do you think that NewSoftSerial will be able to receive the "OK" properly? or will it come back too fast for NewSoftSerial to detect all the characters?
I would really like to use NewSoftSerial, but if it doesn't fit this application, then I suppose I would have to try to connect a hardware uart to the Arduino (which I have never done). Thanks for any additional comments.
I thought that newsoftserial libary had evolved to utilize interrupts and thus is now non-blocking while transmitting, which would allow a simple loop back for testing? I could be wrong I guess, as I've been mostly using my new mega with it's four hardware serial ports.
Lefty, timing is critical when transmitting or receiving with software. To ensure precise timing, interrupts are disabled during both. Because of this, when you transmit a byte, the RX interrupt doesn't fire until the byte is completely finished transmitting, at which time it is of course too late. Does that make sense? The general TX logic is
transmit start bit
transmit bit0
transmit bit1
...
transmit bit7
transmit stop bit
<- RX interrupt fires here, but it's too late to watch the incoming bit by now.
Roger, NewSoftSerial is a good choice for a modem. An excellent way to test a device like this is to hook it up to, say, pins 4 and 5, and then write a test sketch that shuttles data from the (hardware) port to the software port and vice-versa, something like this:
#include <NewSoftSerial.h>
NewSoftSerial mySerial(4, 5);
void setup()
{
Serial.begin(9600);
mySerial.begin(9600);
Serial.println("Hello, world");
}
void loop()
{
if (Serial.available())
mySerial.print(Serial.read(), BYTE); // send bytes from HW port to SW port
if (mySerial.available())
Serial.print(mySerial.read(), BYTE); // send bytes from SW port to HW port
}
This should allow you to talk directly to your modem from the Arduino console. It's a great technique for testing TTL serial devices -- especially those that talk in human-readable text. It also validates NewSoftSerial for you.
Because of this, when you transmit a byte, the RX interrupt doesn't fire until the byte is completely finished transmitting, at which time it is of course too late.
So then NewSoftSerial only supports half-duplex serial communications (only one side can pass data at a time) ?
Yep, that statement is technically accurate. If a byte arrives precisely while another is being transmitted, it risks being lost or corrupted. If your application requires high bandwidth bidirectional data flow and cannot tolerate this, then software serial solutions are not for you. Note however that many applications can work fine with bidirectional soft serial. For example, a GPS application which does very little TX -- only configuration, etc -- will run a fairly low risk of interfering with the RX stream. And of course if the GPS checksum check does fail, another sentence will be coming down the pipe in a short time, giving an opportunity for recovery.