Trouble using softwareserial in a function

Hi There,

I am trying to use 2 softwareserial ports in a fucntion but cant seem to get it working. When I use the code outside of the function it works so I think I am maybe using incorrect data type or syntax. Can anyone tell me what I am doing wrong ? I am using 2 JSN-SR04T in serial mode and a Nano Every for a water tank level. I know softserial is not the best but I am only going to update data every 5 mins or so, so not concerned if the MCU is slowed down.


#include <LiquidCrystal_I2C.h>
#include <SoftwareSerial.h>

// Define connections to sensor
int S1_RX = 9;
int S1_TX = 8;
int S2_RX = 11;
int S2_TX = 10;
// Array to store incoming serial data
unsigned char data_buffer[4] = {0};
// Variable to hold checksum
unsigned char CS;
// defines variables
long duration;
int distance;
int TankLevel1;
int TankLevel2;
String Tank1;
String Tank2;
String S1 = "% ";
String S2 = "L";
String Header1 = "Tank 1 Level: ";
String Header2 = "Tank 2 Level: ";
int TankR = 90; //Tank Radius in cm
int TankH = 204; //Tank Height in cm 23cm + 181 cm
int StringLength;

// Object to represent software serial port
SoftwareSerial Sensor1(S1_RX, S1_TX);
SoftwareSerial Sensor2(S2_RX, S2_TX);

// set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x27, 16, 2);

//Level measurement Routine
int MeasureLevel (Stream &Sensor)
{
  if (Sensor.available() > 0) {

    delay(4);

    // Check for packet header character 0xff
    if (Sensor.read() == 0xff) {
      // Insert header into array
      data_buffer[0] = 0xff;
      // Read remaining 3 characters of data and insert into array
      for (int i = 1; i < 4; i++) {
        data_buffer[i] = Sensor.read();
      }

      //Compute checksum
      CS = data_buffer[0] + data_buffer[1] + data_buffer[2];
      // If checksum is valid compose distance from data
      if (data_buffer[3] == CS) {
        distance = (data_buffer[1] << 8) + data_buffer[2];
      }
    }
  }
  Serial.println(String("Distance: ") + distance);
  return distance;
}

void UpdateDisplay(int Length, String string1, String string2)
{
  lcd.setCursor(0, 0);
  lcd.print(string1);
  lcd.setCursor(0, 1);
  lcd.print(string2);
  for (int positionCounter = 0; positionCounter < Length; positionCounter++) {
    // scroll one position left:
    lcd.scrollDisplayLeft();
    // wait a bit:
    delay(1000);
  }
  for (int positionCounter = 0; positionCounter < Length; positionCounter++) {
    // scroll one position right:
    lcd.scrollDisplayRight(); \
    delay(500);
  }
}

void setup()
{
  // Set up software serial port
  Sensor1.begin(9600);
  Sensor2.begin(9600);
  lcd.init();
  lcd.clear();
  lcd.backlight();      // Make sure backlight is on
  Serial.begin(9600);
}
void loop()
{
  // Determine Tank1 water level and calculate volume to display
  TankLevel1 = MeasureLevel (Sensor1);
  int x1 = TankH - (TankLevel1/100);
  int v1 = constrain(((PI * (TankR * TankR) * x1) / 1000), 0, 4600); // Pi*r^2*height of water /1000000 to get m^3 then *1000 to get liters
  int p1 = constrain((v1 * 100 / 4600), 0, 100); // Tank Fill percentage 4600 L is usable
  Tank1 = Header1 + p1 + S1 + v1 + S2; //Build String for Display

  // Determine Tank2 water level and calculate volume to display
  TankLevel2 = MeasureLevel (Sensor2);
  int x2 = TankH - (TankLevel2/100);
  int v2 = constrain(((PI * (TankR * TankR) * x2) / 1000), 0, 4600); // Pi*r^2*height of water /1000000 to get m^3 then *1000 to get liters
  int p2 = constrain((v2 * 100 / 4600), 0, 100); // Tank Fill percentage 4600 L is usable
  Tank2 = Header2 + p2 + S1 + v2 + S2; //Build String for Display
  StringLength = Tank1.length();
  //debug
  Serial.println(String("Tank 1 Level ") + TankLevel1 + String(" x1 ") + x1 + String(" v1 ") + v1 + String(" p1 ") + p1);
  Serial.println(String("Tank 2 Level ") + TankLevel2 + String(" x2 ") + x2 + String(" v2 ") + v2 + String(" p2 ") + p2);

  //Update Display
  UpdateDisplay(StringLength / 2, Tank1, Tank2);

  delay(1000); //Update data every 1s
}

Stop right there

I have never seen a a project that successfully used 2 SoftwareSerial ports even when the listen() function was used and you don't even do that

Get a Teensy 3.2. It has 3 Hardware UARTS (Serial1, Serial2, Serial3) plus native USB (Serial) for User I/O and debugging. Not to mention 32-bit ARM architecture and lots of RAM & Flash.

Would it be possible to mix one softserial and the hardware (dedicated rx and tx pins) serial ?

I have a bunch of nanos so was hoping to use them for something. But seems like I might need to use something else like the teensy.

Yes, but it may require you to disconnect the device attached to pins 0 and 1 when uploading the code and you lose the ability to use Serial.print() for debugging or information output

[quote="UKHeliBob, post:6, topic:1000692, full:true"]
but it may require you to disconnect the device attached to pins 0 and 1 when uploading the code
[/quote]

I think USB and Serial1 are separate on the nano every. It also seems like there are actually 4 hardware UART port on the every as per this thread https://forum.arduino.cc/t/arduino-nano-every-access-to-4-serial/614358 so I might try that too.

I have no experience of the Nano Every. If it has multiple hardware UARTs that sounds like good news

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.