For the past few day I have been tinkering with the SoftwareSerial library on an Arduino Nano V3, with little success. The final goal is to make a small device that can read data on the native, hardware, serial port and relay it at a different baud rate on a software port.
I was going to test this functionality by hooking up a second Arduino (an Uno) that sends att one baudrate and reads at another, simple right? Unfortunately I got stuck quite early. In this test I connected the TXs directly to the RXs so that data that is transmitted should be returned on the same serial port.
This is my first test application on the Nano:
#include <SoftwareSerial.h>
#define RXs 2
#define TXs 3
#define MIDI_BAUDRATE 31250
#define PC_BAUDRATE 115200
SoftwareSerial MIDI(RXs, TXs);
void setup()
{
// Setup serial input (in from IVC)
Serial.begin(PC_BAUDRATE);
// Setup serial output (out to MIDI)
MIDI.begin(MIDI_BAUDRATE);
}
void loop()
{
byte input;
if (Serial.available())
{
input = Serial.read();
MIDI.write(input);
//Data is OK here
input = MIDI.read();
Serial.println(input, DEC);
}
}
If I do this I always get 255 back. I figured that this is because MIDI.read() returns -1. I tried adding a few extra MIDI.write and a while loop that waits until MIDI.available() becomes true, but that never happens. I also tried adding a MIDI.listen() after MIDI.begin(...).
A variation on this was the following, but I never get any data back:
I did this mostly to make sure that there are not issues with sending and receiving at the same time on the same port. In the second example I connected pin 3 and 4 to each other. I can now write a lot of messages from the PC, by toggling a pin based on the value from the PC I can see that the data I get from the PC is OK. I could actually also send data from a software serial on the Arduino Uno to the native Arduino Nano serial and it looks good. This leads me to believe that the problem resides in the receiving end.
The first port uses the hardware serial at baud rate 115200 (or something else), but not the baud required by the MIDI standard. For now this is mainly a baud rate converter.
Regarding why I read regardless of whether there is anything to read it is for two reasons. Firstly it is one way to get something back. Basically it is an indication that I get a proper message back through the HW serial. It is a simple diagnosis that helped me see that there was nothing to read. Secondly there should be something to read. Perhaps with some delay added in between, but there never is. Not even after a few iterations. The serial port called MIDI is directly wired to itself, TX<->RX, shouldn't that allow reception of the sent message on the same port?
These two lines are not in the original sketch, but were added when I saw that I got no data on the second Arduino. At that time i removed the second Arduino and tried to get a message through software serial by short-cutting the lines on only one device. I have the same problem on both Nano and Uno, so I am sure that I am doing something wrong... I have very little experience in this so if you have suggestions I will be happy to hear them.
Regarding why I read regardless of whether there is anything to read it is for two reasons.
Firstly it is one way to get anything back.
Getting garbage, just for the sake of getting something, is stupid.
Secondly there should be something to read.
Why? Sooner or later, yes probably. I don't know what you have connected to the software serial port, so I'm not necessarily willing to concede that this statement is true. What I do know, though, is that there will NOT be data to read nanoseconds after having sent something to the software serial port. At least, not in response to what was just sent.
The serial port called MIDI is directly wired to itself, TX<->RX
Oh, well, that explains a lot. SoftwareSerial doesn't work like that. It can NOT be used for a loopback test because it can not listen and send at the same time.
Hello again and thanks for the help and the hint. I see why it should not be possible to transmit and receive at the same time with software serial.
I solved it in a slightly different way by connecting the HW TX lines and RX lines between the Arduinos to make them receive the same message at the same time. This made it possible for me to eliminate one intermediary. After this I used the AltSoftSerial of SoftwareSerial and let one device send the information and the other look for it on the software pins. It works great now!