Software Serial on Nano pins 2 & 3 ??

I'm having trouble finding definitive documentation that says pins 2 (Rx) and 3 (Tx), may, or may not, be used for SoftwareSerial at 115200 baud

I have a fully working project with a BLE module on Hardware serial, but want to move it to SoftwareSerial because on the finished project I won't be able to disconnect the BLE for program upload. I'll also be able to use the serial monitor if needed.

Here is the code, which works fine if Hardware Serial is defined, but does not work on SoftwareSerial.

/*
   -- LED Strip Controller --
   
   This source code of graphical user interface 
   has been generated automatically by RemoteXY editor.
   To compile this code using RemoteXY library 2.3.3 or later version 
   download by link http://remotexy.com/en/library/
   To connect using RemoteXY mobile app by link http://remotexy.com/en/download/                   
     - for ANDROID 4.1.1 or later version;
     - for iOS 1.2.1 or later version;
    
   This source code is free software; you can REDistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.    
*/

#include <EEPROM.h>                   // used for saving settings

//////////////////////////////////////////////
//        RemoteXY include library          //
//////////////////////////////////////////////

// RemoteXY select connection mode and include library 
#define REMOTEXY_MODE__SOFTSERIAL
#include <SoftwareSerial.h>

#include <RemoteXY.h>

// RemoteXY connection settings 
#define REMOTEXY_SERIAL_RX 2
#define REMOTEXY_SERIAL_TX 3
#define REMOTEXY_SERIAL_SPEED 115200


// RemoteXY configurate  
#pragma pack(push, 1)
uint8_t RemoteXY_CONF[] =
  { 255,4,0,6,0,124,0,8,26,0,
  1,2,72,51,21,8,24,31,83,97,
  118,101,0,4,128,1,19,98,10,134,
  134,4,128,1,32,98,10,204,204,65,
  4,2,50,9,9,65,2,14,50,9,
  9,65,1,26,50,9,9,65,7,42,
  50,9,9,129,0,10,48,3,4,16,
  82,0,129,0,21,48,3,4,16,71,
  0,129,0,34,48,3,4,16,66,0,
  129,0,50,48,7,4,16,77,105,120,
  0,129,0,2,1,5,3,16,77,105,
  110,0,129,0,93,1,5,3,16,77,
  97,120,0,4,128,1,6,98,10,1,
  1 };
  
// this structure defines all the variables of your control interface 
struct {

    // input variable
  uint8_t save_button; // =1 if button pressed, else =0 
  int8_t GRN; // =0..100 slider position 
  int8_t BLU; // =0..100 slider position 
  int8_t RED; // =0..100 slider position 

    // output variable
  uint8_t RED_led_r; // =0..255 LED Red brightness 
  uint8_t GRN_led_g; // =0..255 LED Green brightness 
  uint8_t BLU_led_b; // =0..255 LED Blue brightness 
  uint8_t RGB_led_r; // =0..255 LED Red brightness 
  uint8_t RGB_led_g; // =0..255 LED Green brightness 
  uint8_t RGB_led_b; // =0..255 LED Blue brightness 

    // other variable
  uint8_t connect_flag;  // =1 if wire connected, else =0 

} RemoteXY;
#pragma pack(pop)

/////////////////////////////////////////////
//           END RemoteXY include          //
///////////////////////////////////////////// 
  
 
// EEPROM Addresses
#define SETTINGS_ID       "LED STRIP V1"
#define SETTINGS_ADDRESS  64

// Arduino Pins

// PWM Outputs
const byte pin_RED = 11;              // RED Channel (PWM)
const byte pin_GRN = 10;              // GRN Channel (PWM)
const byte pin_BLU =  9;              // BLU Channel (PWM)

// Define the settings udt
typedef struct udt_Settings {
  uint8_t RED;            // 0 to 255 
  uint8_t GRN;            // 0 to 255 
  uint8_t BLU;            // 0 to 255 
  char    id[19];         // this is last to catch structure changes
};

//Create the settings data of type udt_Settings
udt_Settings settings;

#ifdef REMOTEXY_MODE__SOFTSERIAL 
  SoftwareSerial mySerial = SoftwareSerial(REMOTEXY_SERIAL_RX,REMOTEXY_SERIAL_TX);
#endif

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

void setup() {
  RemoteXY_Init (); 

  pinMode (pin_RED, OUTPUT);
  pinMode (pin_GRN, OUTPUT);
  pinMode (pin_BLU, OUTPUT);
  pinMode (REMOTEXY_SERIAL_RX, INPUT);
  pinMode (REMOTEXY_SERIAL_TX, OUTPUT);
  
  // connect to the serial port

#ifdef REMOTEXY_MODE__SOFTSERIAL 
  mySerial.begin(REMOTEXY_SERIAL_SPEED);
#endif

#ifndef REMOTEXY_MODE__SOFTSERIAL 
  Serial.begin(REMOTEXY_SERIAL_SPEED);
#endif

  // retrieve settings from EEPROM
  
settingsLOAD();

// initialise start-up settings if not present
if (strcmp(settings.id, SETTINGS_ID) != 0) {
  settings.RED = 127;         // half brightness 
  settings.GRN = 127;         // half brightness 
  settings.BLU = 127;         // half brightness 
  strcpy(settings.id, SETTINGS_ID);

  settingsSAVE();
}

RemoteXY.RED = settings.RED;
RemoteXY.GRN = settings.GRN;
RemoteXY.BLU = settings.BLU;

} // end setup

// ***********************************************************************
// LOOP
// ***********************************************************************
void loop() { 
  RemoteXY_Handler ();

// PWM Control (inverted, due to P-channel MOSFET drive) 
 
  analogWrite(pin_RED, map(RemoteXY.RED, 100, 0, 0, 255));
  analogWrite(pin_GRN, map(RemoteXY.GRN, 100, 0, 0, 255));
  analogWrite(pin_BLU, map(RemoteXY.BLU, 100, 0, 0, 255));

// control screen LEDs
  RemoteXY.RED_led_r = map(RemoteXY.RED, 0, 100, 0, 255); 
  RemoteXY.GRN_led_g = map(RemoteXY.GRN, 0, 100, 0, 255); 
  RemoteXY.BLU_led_b = map(RemoteXY.BLU, 0, 100, 0, 255);
  
  RemoteXY.RGB_led_r = map(RemoteXY.RED, 0, 100, 0, 255); 
  RemoteXY.RGB_led_g = map(RemoteXY.GRN, 0, 100, 0, 255); 
  RemoteXY.RGB_led_b = map(RemoteXY.BLU, 0, 100, 0, 255); 
  
// respond to the Save button
  if (RemoteXY.save_button) {
    RemoteXY.save_button = 0;
    
// turn the LEDs off for visual indication
    analogWrite(pin_RED,255);
    analogWrite(pin_GRN,255);
    analogWrite(pin_BLU,255);
    
    settings.RED = RemoteXY.RED; 
    settings.GRN = RemoteXY.GRN; 
    settings.BLU = RemoteXY.BLU; 
   
    settingsSAVE();

    delay(50);
  }
  
} // void(loop)

//********************************************************
// Save settings to EEPROM
void settingsSAVE() {
  byte EEPROMAddress = SETTINGS_ADDRESS;
  const byte* pointer = (const byte*)(const void*)&settings;
  for (unsigned int i = 0; i < sizeof(settings); i++) EEPROM.write(EEPROMAddress++, *pointer++);
  } // void settingsSAVE()

//********************************************************
// Load settings from EEPROM
void settingsLOAD() {
  byte EEPROMAddress = SETTINGS_ADDRESS;
  byte* pointer = (byte*)(void*)&settings;
  for (unsigned int i = 0; i < sizeof(settings); i++) *pointer++ = EEPROM.read(EEPROMAddress++);
  } // void settingsLOAD()

daba:
I'm having trouble finding definitive documentation that says pins 2 (Rx) and 3 (Tx)

I guess it's documented by omission. You can use any pins on the Nano with the SoftwareSerial library. This is because all pins on the ATmega328P support pin change interrupt.

daba:
at 115200 baud

Despite what the documentation says, some users have found that 115200 baud does not work reliably with SoftwareSerial.

pert:
I guess it's documented by omission. You can use any pins on the Nano with the SoftwareSerial library. This is because all pins on the ATmega328P support pin change interrupt.
Despite what the documentation says, some users have found that 115200 baud does not work reliably with SoftwareSerial.

Thanks for that.... In my case 115200 baud isn't working at all ...

Something else must be wrong with this, I have tried pins 4 (Rx) and 5 (Tx), and still not working.

Next step I guess is to drop the BLE baud rate down, and re-test.

Do yourself a favor and use a board that has a real hardware UART that you can use, like the Arduino Micro for example.
SoftwareSerial is a hack, and it works unreliably at high baud rates, or if you have some other interrupts set up as well.

Pieter

Don't expect SoftwareSerial to work faster than 38400 baud, and start with 9600.

...R

AltSoftSerial is much more reliable than SoftwareSerial, but you have to use two specific pins: 8&9 on a Nano. It disables PWM on pin 10.

My NeoSWSerial is almost as good, and it will work on any two pins. It only supports baud rates 9600, 19200 and 38400.

Both of these libraries are available from the Arduino Library Manager, under the menu Sketch-> Include Library-> Manage Libraries.

SoftwareSerial is very inefficient, because it disables interrupts for long periods of time. It cannot send and receive at the same time.

2 Likes

michealE:
i need to send sensor MLX90614 output readings by Bluetooth from arduino nano to arduino mega but it is not working

As yours is a new question I have suggested to the Moderator to move it to its own Thread.

Please tell us in as much detail as possible what happens when you run your programs and what you want it to do that is different.

"not working" does not provide any useful info from which to help you.

There is no reason to use SoftwareSerial on a Mega when it has 3 spare HardwareSerial ports.

You may find something useful in Serial Input Basics - simple reliable ways to receive data.

...R

PS ... When posting code please use the code button </>
codeButton.png

so your code 
looks like this

and is easy to copy to a text editor See How to use the Forum