SoftwareSerial example not working as expected - arduino

I recently bought an Arduino UNO to read the data outputted by my Smart Meter. The meter uses serial communication and I would like to see the values being outputted on my laptop screen. I figured I would need to use the SoftwareSerial library to read the incoming data and print that data on my screen using the hardware serial and the Serial Monitor in the Arduino IDE. To become familiar with (software) serial communication on the Arduino, I reviewed the documentation of the SoftwareSerial library. Problem is, I can't get the most basic example to work and I have been stuck on this for quite a while now. The example code is below, the example can be found here
#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); // RX, TX
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(57600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.println("Goodnight moon!");
// set the data rate for the SoftwareSerial port
mySerial.begin(4800);
mySerial.println("Hello, world?");
}
void loop() { // run over and over
if (mySerial.available()) {
Serial.write(mySerial.read());
}
if (Serial.available()) {
mySerial.write(Serial.read());
}
}
As far as I understand this, the following should happen:
- Type text in Serial Monitor window.
- Serial.read() reads this data and writes it to the Software Serial.
- The Software Serial reads this data and writes it back to Serial.
- That which was written appears on the screen.
But whatever I try, nothing happens. Among things I tried to following:
- Change the baud rate for both software and hardware serial (9600 for instance).
- Tried a different SoftwareSerial library (AltSoftSerial).
- Tried different RX and TX pins for SoftwareSerial.
- Instead of Serial.write(mySerial.read());, store the result in a char first.
I'm probably missing something obvious. I would be grateful to anyone who could shed some light on this or offer an alternative way for me to read the data from my Smart Meter.
Edit
I had no wiring, because the example specified "There is no circuit for this example". I tried all three options suggested by #slash-dev, but none had the expected behaviour:
SoftwareSerial with wires connecting pin 1 to pin 10 and pin 0 to pin 11. It prints strange characters:
Goodnight moon!
Ùniÿhtÿmoÿn!ÿ
nihtmoÿttt
AltSoftSerial with wires connecting 1-8 and 0-9. First prints Goodnight moon! and then it keeps printing Ô당¥�¡Ñ�moon!.
NeoSWSerial with wires connecting 1-10 and 0-11. Same as AltSoftSerial but keeps printing Ôë‹–+ë¡Ñ�j½½¹…j.

The baud rates must be the same on Serial and mySerial.
And you don't describe the connections, so I have to ask: Did you connect a wire from pin 1 (Serial transmit) to pin 10 (mySerial receive), and another wire from pin 0 (Serial receive) to pin 11 (mySerial transmit)? Note how they are crossed.
AltSoftSerial is really the best choice, but it only works on pin 8 (RX) and pin 9 (TX), which would require connecting 8 to 1 and 9 to 0. SoftwareSerial is very inefficient, because it disables interrupts for long periods of time. This can interfere with other parts of your sketch or other libraries.
My NeoSWSerial library is another alternative. It's almost as efficient as AltSoftSerial, but it works on any two pins. It can transmit and receive at the same time (unlike SoftwareSerial), but it only works at bauds 9600, 19200 and 38400.
EDIT:
I think what you've tried is probably working ok. All the software serial libraries use interrupts for processing individual bits instead of one interrupt per character. When there are other interrupts in the system (millis() TIMER0 or Serial), the bit "calculations" can be affected. This manifests as receiving the wrong byte. Your loopback test makes it especially susceptible because the sending and receiving are synchronized (the initial receive interrupt occurs while the transmit interrupt is starting the next char).
If you just hook 0 to 1, I think it will work, because the UART is able to send and receive at the same time, and it deals with complete characters, not bits. The character interrupts do not disturb the sending or receiving of the bits.
In developing the NeoSWSerial library, I have seen this manifest the same way. I had to use two Arduinos to fully test asynchronously (i.e., not synchronized). In your case, using AltSoftSerial for the SmartMeter should work fine, and you can choose different baud rates. If you are echoing the SmartMeter characters to Serial, be sure you have a higher baud rate on Serial.

This is most likely not related to the issues now 5 years ago, but in my case I was using the Arduino IDE 2.0.0-rc5 which was not writing to the soft serial for unknown reasons. I downgraded to Arduino IDE 1.8.19 and the same serial sketch worked.

Related

Arduino Uno and ESP8266 Shield won't communicate unless delay is 1,000

I got this shield below which fits great with my Arduino Uno. Moreover, I have managed to upload code to the shield with a serial adapter and send/receive UDP messages. As the picture shows this shield goes right on top of the Arduino UNO.
My ESP8266 Shield
The problem is that the communication between Arduino and the Shield is very slow.
For example, I use the code below to Arduino to write something using Serial (115200).
void loop() {
writeString("Hello!");
delay(1000);
}
Then I use a simple code to the ESP8266 shield to read the data from Arduino and send it via UDP (writeString is just a simple converter).
Udp.beginPacket(ip, localUdpPort);
writeString(Serial.readString());
Udp.endPacket();
void writeString(String stringData) {
for (int i = 0; i < stringData.length(); i++) {
Serial.write(stringData[i]);
// Push each char 1 by 1 on each loop pass
}
}
It works fine, the "Hello!" string is read from the ESP8266 shield and sent using UDP. The problem is that if I put anything below 1,000 ms of delay in the Arduino, the ESP shield does not read anything, which is strange considering that the shield is on the top of the Arduino with no restrictions between serial communication.
From https://www.arduino.cc/en/Serial/ReadString:
Serial.readString() reads characters from the serial buffer into a string. The function terminates if it times out (see setTimeout()).
From https://www.arduino.cc/en/Serial/SetTimeout:
It defaults to 1000 milliseconds.
So because you use this Serial.readString() thing with the default timeout there will always be a delay of 1000 ms before the string is received.
If you insist on messing with String, there is a similar function: Serial.readStringUntil():
The function terminates if the terminator character is detected or it times out
So you have it detect the terminating character of the string:
Serial.readStringUntil('\n');
In this case the timeout is merely a safeguard to keep the code from hanging if for some reason the terminating character should not arrive but this should never happen if things are working correctly so there are no unnecessary delays.
The trouble with that is your current code doesn't send a terminator but that's easy enough to fix.
I recommend that you consider using the more efficient and safer string (char array) rather than String. There is an equivalent function: Serial.readBytesUntil().

how to get AT response from ESP8266 connected to arduino

I am fighting with ESP8266 wifi module and connecting arduino. After updating firmware to newest version i started to programm arduino to get data incoming from wifi. I saw many examples about maiking webserver via ESP8266 but none of them works for me.
ESP is connected to my Arduino Leonardo:
>
Arduino -> ESP8266
power 3.3V -> vcc
ground -> ground
tx -> rx (via logic level converter 5->3.3V)
rx -> tx (via logix level converter
power 3.3V ->gpio0 (without any resistors)
I made simple sketch:
void setup(void){
Serial.begin(9600);
Serial1.begin(115200);
}
void loop() {
if(Serial1.available())
{
Serial.println("WIFI IS AVAILABLE");
Serial1.println("AT");
delay(1000);
} else {
Serial.println("WIFI not available.");
delay(1000);
}
}
After executing it ESP8266 is powered (red led is on) and also every second blue led (blinks). That makes me sure that in fakt "AT" command is transmited to module. But there are also two issues:
i want to get response from esp - in this case word "OK". I tried Serial1.read() but it only reads one byte. Serial1.readString() makes my messages "wifi not available" and sametimes "wifi is available" as if for a while the connection would be unavailable
after uploading sketch to arduino and having powered esp8266 wifi module is always unavailable - i need to power the module off and on again to have it working.
Anybody please can help me?
What you need to do is change your approach a bit. Do not check if data is available. The trick is to send the module something and then check for data.
Do something like:
while (Serial.available() > 0)
Serial.read();
to clear the buffer before any command you want to send. Then send the command. Then check for data as a response.
Do not rely on that Blue LED as any indication. It is only an indication that the ESP8266 is busy using the WiFi in some sort of way, whether it is doing keepalives, initializing WiFi or whatever. It can be totally unrelated to whatever you are sending. If you do not receive a valid response then you must assume that there is comms issues between you and the module. One thing though is that if that Blue LED never goes off then either the module has frozen or the firmware was corrupted. I have had that many times. I then reload the firmware and usually that fixes it. It usually only happens during development times where I reset, upload code or change wires.
I use mine with an atmega328 on a separate slef-built board and not the one on the Uno and run that board on 3.3v itself and then use a logic level converter between that atmega board and my Uno so that I can program it. But I have had sporadic issues with non-comms but I suspect it might be power related. Be aware that running your Serial via the logic level converter might also be causing comms issues.
Proposed wiring: All pins except RX,TX,VCC and GND goes to VCC via 10K pullup resistors. RX goes to the arduino's TX and TX goes to the arduino's RX. Of course you know where VCC and GND goes.

Strange output with serial

I have an Arduino with a shield communicating with a motor controller over RS-232/Serial. During communications when I receive a response from the motor controller there are random characters / irregular responses.
The commands and responses are simple ASCII strings.
I have no problem communicating over serial between my PC and the arduino, and no problem connecting over serial between my PC and the motor controller, but together these two don't want to get along. Can anyone think of a reason why this would be the case?
Same baud rate (9600), standard settings: 8 bits, 1 stop bit no parity on all devices.
On the Arduino I'm using SoftwareSerial to communicate with the motor controller and the Serial Monitor to enter commands.
Any ideas?
SoftwareSerial is very susceptible to interrupts from other sources. If pins 8&9 are available, you should use AltSoftSerial. If not, and the motor controller sends plain text responses, you should use a library I posted on github, NeoSWSerial.

Cannot connect to ESP8266 after serial speed change

After some trial and error, tonight my Arduino Uno began talking to an ESP8266 module, with the most common wiring, 3.3V power to the module from a well-sized external supply, direct connection of the 3.3V TX line, and a voltage divider to read from the 5V RX.
SoftwareSerial esp8266(2,3);
void setup()
{
Serial.begin(9600);
esp8266.begin(115200);
char buffer[50];
esp8266.write("AT\r\n");
esp8266.readBytes(buffer, sizeof(buffer));
Serial.println(buffer);
}
After setting the 115200 speed for the ESP8266<->Arduino serial communication, some clear boot messages and command responses appeared on the serial monitor.
Since these messages were interleaved by some garbage characters, I tried reducing the communication speed.
For this purpose I issued the command AT+IPR=9600 to the module, which immediately showed some action on the blue LED, an OK response on the console and finally resulted in the same LED being fixed on.
I consequently adjusted the serial speed on the Arduino side, with esp8266.begin(9600);, but could never obtain any further communication with the module.
I can now see garbage only at any speed.
Could the module have escalated to a different speed? I tried many of them (4800, 57600, 19200, back to 115200 etc.) but no clear response appeared on the monitor.
May you suggest any attempt to reestablish the connection? Any way to reset the last command result?
I'd rather avoid setting up for firmware update, if any simpler solution can be tried.
Here is the solution!
The AT+IPR command was known to break the firmware and make the module unresponsive until a complete reflash.
I found the solution in this forum discussion.

Arduino Timing issue with Digi Xbee V1 Read function in Loop()

I am beginning to work with XBee RF Modules and have a general concern as to how and why this timing issue occurs... The two XBee do indeed communicate, and I am testing one thru Shield on Arduino Uno and the other via USB Connector on PC and X-CTU. The code is (generally) as follows, using the sample code from Sparkfun as a base (located at https://learn.sparkfun.com/tutorials/xbee-shield-hookup-guide)
// We'll use SoftwareSerial to communicate with the XBee:
#include <SoftwareSerial.h>
// XBee's DOUT (TX) is connected to pin 2 (Arduino's Software RX)
// XBee's DIN (RX) is connected to pin 3 (Arduino's Software TX)
SoftwareSerial XBee(2, 3); // RX, TX
void setup()
{
// Set up both ports at 9600 baud. This value is most important
// for the XBee. Make sure the baud rate matches the config
// setting of your XBee.
XBee.begin(9600);
Serial.begin(9600);
}
void loop()
{
if (XBee.available())
{ // If data comes in from XBee, send it out to serial monitor
Xbee.write("ready");
Serial.write(XBee.read());
}
}
My concern comes with the fact I am sending packets of 2 ASCII chars (2 digits, 10, 20, 30, etc) just to test. In the console monitor of X-CTU, I notice the following. (bold being received, italic being sent.)
10 readyready 20 readyready 30 readyready etc...
Can someone explain to me in layman's terms of how this is occurring? I cannot understand how the code executes in this order.
You're using "AT mode" or "transparent serial" mode on your XBee, so characters arrive one at a time. There isn't any packetizing going on.
So you send a packet with 10 from X-CTU. The XBee on your Arduino receives that packet and starts sending the payload to the Arduino. The Arduino receives 1 which triggers the code to send ready in response. Then the Arduino receives 0 and sends another ready.
You would need to add some sort of framing to your serial stream (like adding a carriage return after each line of data) or switch to API mode (which delivers network payloads wrapped in headers and a checksum) if you want to look at your data in chunks, instead of as a stream.
I haven't used it, but there's an xbee-arduino library designed for using XBee modules in API mode on Arduino microcontrollers.

Resources