Problem with SoftwareSerial to HardwareSerial bridge

Hi guys,

i´m really getting frustrated :cry:

I´m about to make a home automation system.
All i need at the moment is a working "Bridge-Code" from SoftwareSerial to the HardwareSerial.

to the System:
I made a Processing sketch which is talking to a MySql DB. Processing is taking the data from the DB an encapsulates it into a Serial Stream which is send over serial to Arduino. (something like #2/1/1/255/300/0/0/|)

If i connect the sensornode directly via usb all is fine!
Im getting data from the node, write it to the db, send commands,...

With a bridgenode (Arduino, HardwareSerial to PC, SoftwareSerial to Sensornode) i have serious problems which i´m not able to solve ;).
The fact, that i´m able to send commands (turn lights on/off, set the time on the node) verifies, that the communication from PC -> bridge -> sensornode is working.

BUT: I´m not getting useable data back. the node should answer with something like #1/2/2/234/350/1/535/0/|
But i only get somthing like: $%"(jd!("§

Maybe there is a mismatch of datatypes???
How can i solve that?
any suggestions?

i use the SoftwareSerial Example sketch for the bridge

Thanks for helping me

#include <SoftwareSerial.h>

SoftwareSerial mySerial(2, 3); // 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 Leonardo only
  }


 // Serial.println("Goodnight moon!");

  // set the data rate for the SoftwareSerial port
  mySerial.begin(57600);
  //mySerial.println("Hello, world?");
}

void loop() // run over and over
{
  if (mySerial.available())
    Serial.write(mySerial.read());
  if (Serial.available())
    mySerial.write(Serial.read());
}

Can you provide a link to the datasheet for the sensor you are using?

If this was my project I would read and save (temporarily) all the data from the PC (or from the sensor, in the other direction) before passing it to the sensor (or PC).

For one thing, that would allow you to "view" the data to make sure it was being received correctly.

Another way of looking at the problem may be to write a short program that reads the sensor and just displays the data in the Serial Monitor.

...R

hi Robin,

there is no datasheet available. I´m building it my self :wink: i posted the hardware of my sensornode on my blog (seril-q.blogspot.co.at).

The sensors are all working fine. The only problem is the connection from Serial to SoftwareSerial.
I´m going to split the whole incoming data into INT´s (Serial.parseInt()) store them and print them on the SoftwareSerial.

thank you for helping me.

You are sure that your send to the node is working but receive is not.
If it was me, I would check the wiring and which pins are connected on the node.

Send 1 character at a time... still the node will send whole messages.

Serial is more than speed. The datasheet for the node should give all the details. But still I am pretty sure that a mismatch would not allow you to send commands.

I think this puzzle is not showing enough pieces to finish.

Errrrr, just read your reply to Robin and I have to ask if your node is sending ASCII chars or binary data?

Are there differences between what you have and the picture on your site?

YES, the RS485 Bus isn´t implemented. Im using SoftwareSerial RX/TX directly.

I´m sending ASCII Chars

I'm probably telling you how to suck eggs, but you realise you have to cross the wires (ie, tx -> rx and rx -> tx)

SerialQ:
YES, the RS485 Bus isn´t implemented. Im using SoftwareSerial RX/TX directly.

I´m sending ASCII Chars

The node reads ASCII and sends ASCII back then wiring is all I can think of to go wrong.
You have all the grounds connected?
The only wire I can think of besides that is node TX to Arduino RX since the rest works.

they are connected right. i won´t be able to set commands if the aren´t connected right :wink:

do they have to share common ground?

Ground on the node must connect to ground on the Arduino.

Another thing to try is slowing the baud rate.

Jumpers in breadboards are not always solid connections, btw.

SerialQ:
do they have to share common ground?

Absolutely. Won't work without.

So, again thx for your help!

I did a last test, just to be sure that everything about my protocoll/the cabeling is fine.

I tried to communicate over a seperate USB RS232 adapter to my nano v3 (thats the sensornode).
well the cable is much longer (20cm) and everything is fine.
SoftwareSerial is the problem and it is driving me crazy at the moment...

any other suggestions to solve my SoftSerial problem?

SerialQ:
any other suggestions to solve my SoftSerial problem?

Did you try my suggestion (in Reply #1) to write a short program to read data from the sensor and display it on the Serial Monitor?

If so, did it work?

If you tried it and it did not work, what did happen?

...R

hi robin,

it works if i´m connected directly via usb or with an fttdi adapter to rx/tx of the nano.

(PC to node)
if i do the same with SoftwareSerial, i can send commands, and the timesyc -> success.

(node to PC)
the strange thing is: i have 2 buttons which generate a message (it is shorter than the reply to the commands) this is also working. but the reply to the command is crap... so oneway communication work, if we are waiting for a reply,... maybe a timing issue? already tried with delay...

i´m really confused at the moment :wink: and thankful for any help i can get...

see picture:

The most common mistake is sending bytes of data, but then treating it as if it's a string at the other end (or vica versa)

just have a quick look at the link i posted above... what do you think? timing?

THx KenF for your suggestions (really appreciate that!)

KenF:
The most common mistake is sending bytes of data, but then treating it as if it's a string at the other end (or vica versa)

that would be true if everything what comes over the SoftSerial is mess, but in fact it isn´t.

confusing...
after hours of frustration it´s fun again :smiley:

SerialQ:
hi robin,

it works if i´m connected directly via usb or with an fttdi adapter to rx/tx of the nano.

(PC to node)
if i do the same with SoftwareSerial, i can send commands, and the timesyc -> success.

(node to PC)
the strange thing is: i have 2 buttons which generate a message (it is shorter than the reply to the commands) this is also working. but the reply to the command is crap... so oneway communication work, if we are waiting for a reply,... maybe a timing issue? already tried with delay...

I can't relate this to my suggestion.

All I was thinking of was a simple program to read X bytes from the sensor using SoftwareSerial and then send them to the Serial monitor so you could read them.

In my mind that is PC (Serial Monitor) --- Arduino --- node

...R

SerialQ:
https://drive.google.com/file/d/0B2Ap07DW_1K1MEpqLXdOaGFEVWM/view?usp=sharing

just have a quick look at the link i posted above... what do you think? timing?

i already tested that, have a look at the image.

If someone wants to join to find out what´s wrong

here is the Arduino sketch for the node (didn´t comment it, sry for that):

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
#include <dht.h>
#include <Time.h>
#include <Servo.h>
#include <SoftwareSerial.h>
//#include <TimeAlarms.h>
#include <DS1307RTC.h>

SoftwareSerial RS485(2, 3); // RX, TX
Servo backlight;

#define BACKLIGHT_PIN     12
#define dht_dpin A0
#define out1 6
#define out2 7
#define in1 11
#define in2 12
#define LDR A1

#define bridgenode 0 //define wheter it ist a bride or not
#define myaddress 2 //define address of node
#define broadcast 255 //define address for broadcast packets
#define master 1 //define masters address

#define sof '#' //start of frame
#define dof '/' //division of frame
#define plm 'P' //payloadmarker
#define eof '|' //end of frame

#define rf 0 //read
#define wf 1 //write
#define ack 2 //ack
#define set 3 //set from node
#define utch '@' //start of TimeSync

boolean x;
boolean lstate;
boolean in1state;
boolean oldin1 = 0;
boolean in2state;
boolean oldin2 = 0;
int ldr;
int T = 22;
int H = 70;
int t;
int h;
int H1;
int L1;
int t1;
int h1;
int clear = 0;
int clearflag = 20;
int clocktimer = 2000;
int sensor2timer = 5000;
int settimer = 1000;
unsigned int brig = 0;
long stmillis = 0;
long ptmillis = 0;
long psmillis = 0;
long dbodelay = 150;
long lastdbo1 = 0;
long lastdbo2 = 0;
long setmillis = 0;
dht DHT;

LiquidCrystal_I2C  lcd(0x3f, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  
char a=0;
char b=1;
char c=2;
char d=3;
char e=4;
char f=5;
char g=6;

byte temp[8]={
  B00100,
  B01010,
  B01010,
  B01010,
  B01110,
  B11111,
  B11111,
  B01110,
};
byte temp0[8]={
  B00100,
  B01010,
  B01010,
  B01010,
  B01010,
  B10001,
  B10001,
  B01110,
};
byte hum[8]={
  B00100,
  B00100,
  B00100,
  B01110,
  B01110,
  B11111,
  B11111,
  B01110,
};
byte sw0[8]={
  B01110,
  B10001,
  B10001,
  B10001,
  B01010,
  B01110,
  B01010,
  B01110,
};
byte sw1[8]={
  B01110,
  B11111,
  B11111,
  B11111,
  B01110,
  B01110,
  B01010,
  B01110,
};
byte ldr0[8]={
  B11111,
  B10001,
  B10001,
  B10001,
  B10001,
  B10001,
  B10001,
  B11111,
};
byte ldr1[8]={
  B11111,
  B10001,
  B10101,
  B10101,
  B10101,
  B10101,
  B10001,
  B11111,
};
void setup()
{ backlight.attach(10);
  pinMode ( out1, OUTPUT);
  pinMode ( out2, OUTPUT);
  pinMode ( in1, INPUT_PULLUP);
  pinMode ( in2, INPUT_PULLUP);
  pinMode ( LDR, INPUT);
  //pinMode ( BACKLIGHT_PIN, OUTPUT );
  
  lcd.begin (16,2); 
  //digitalWrite ( BACKLIGHT_PIN, HIGH );
  backlight.write(255);
  lcd.createChar(a, temp);
  lcd.createChar(b, hum);
  lcd.createChar(c, ldr0);
  lcd.createChar(d, ldr1);
  lcd.createChar(e, sw0);
  lcd.createChar(f, sw1);
  lcd.createChar(g, temp0);
  
  Serial.begin(115200);
  //uncomment if RTC present
  //setSyncProvider(RTC.get);   // get RTCTime if possible
  //if(timeStatus()!= timeSet) 
  //   Serial.println("keine Daten von RTC");
  //else
  //  Serial.println("RTC Daten empfangen"); 
     
  Serial.println("AHAP V0.3c");

  lcd.clear();
  lcd.home();
  lcd.print("AHAP V0.3c");
  lcd.setCursor (16,1);
  lcd.print("Init");
  for(int i=0; i<12;i++)
  {
    lcd.print(".");
    delay(250);
  }
  lcd.clear();
}

void protocol()
{
  while (Serial.available() >0){
   char c = Serial.read();
    if(c == sof)
    {   
      int add = Serial.parseInt();
      if(add == myaddress)
      {
        int rem = Serial.parseInt();
        if (rem == master)
        {
          int c = Serial.parseInt();
          if (c == rf) 
        {  
          constructmsg();
        }
          if (c == wf)
          {
            T = Serial.parseInt();
            H = Serial.parseInt();
            oldin1 = Serial.parseInt();
            oldin2 = Serial.parseInt();
            //constructmsg();
          }
        }
      }
      if(add == broadcast){
        int rem = Serial.parseInt();
        if (rem == master){
          //what todo if boradcast arrives?
        }
        else {
        Serial.println(rem);
        }
      }
      else {
        //Softserial Bridege to RS485
      }      
    }
  if (c==utch){
   readtime();
   } 
  }
}

void constructmsg()
{
            Serial.print(sof);
            Serial.print(master);
            Serial.print(dof);
            Serial.print(myaddress);
            Serial.print(dof);
            Serial.print(ack);
            Serial.print(dof);
            Serial.print(plm);
            Serial.print(dof);
            Serial.print(t1);
            Serial.print(dof);
            Serial.print(h1);
            Serial.print(dof);
            Serial.print(x);
            Serial.print(dof);
            Serial.print(ldr);
            Serial.print(dof);
            Serial.print(lstate);
            Serial.print(dof);
            Serial.println(eof);
}
void constructset()
{
            Serial.print(sof);
            Serial.print(master);
            Serial.print(dof);
            Serial.print(myaddress);
            Serial.print(dof);
            Serial.print(set);
            Serial.print(dof);
            Serial.print(plm);
            Serial.print(dof);        
            Serial.print(x);
            Serial.print(dof);
            Serial.print(lstate);
            Serial.print(dof); 
            Serial.println(eof);
}

void loop()
{   
    protocol();
    long smillis = millis ();
    long tmillis = millis ();
    
  if (tmillis - ptmillis > clocktimer) 
  {    
     ptmillis = millis();
     digitalClockDisplay();  
  } 
  
  if (smillis - psmillis > sensor2timer) 
  {
   psmillis = millis();     
   Sensor(); 
  }
  Sensor2();  
}

void Sensor()
{
  DHT.read22(dht_dpin);
  h = DHT.humidity;
  h1 = DHT.humidity*10;
  t = DHT.temperature;
  t1 = DHT.temperature*10;
 
  lcd.setCursor (0,1);
  lcd.write(b);
  lcd.print(" ");
  if (h<100){
  lcd.print(h);
  lcd.print("%");
  }
  else {
  h == 99;  
  lcd.print(h);
  lcd.print("%");
  }
  lcd.print(" ");
  lcd.write(a);
  lcd.print(" ");
  if (h<100){
  lcd.print(t);
  lcd.print("C");
  }
  else {
  t == 99;
  lcd.print(t);
  lcd.print("C");
  }  
}


void Sensor2()
{ 
  ldr = analogRead(LDR);
  ldra();
  if (ldr <= 40) {
    backlight.write(0);
    backlight.detach(); 
  }
  else {
    backlight.attach(10);
    backlight.write(((ldr/900)*1024)/4);  
  }
  
  in1state = digitalRead(in1);
  if (in1state == LOW){
    
    if (millis() - lastdbo1 > dbodelay){
      lastdbo1 = millis();
      oldin1++;
      if (oldin1 >1){
        oldin1=0;
      }  
    }
    
    lstate=oldin1;
    if (millis() - setmillis > settimer)
    {
      setmillis = millis();
      constructset();
    }
 }
     
 in2state = digitalRead(in2);
  if (in2state == LOW){
    
    if (millis() - lastdbo2 > dbodelay){
      lastdbo2 = millis();
      oldin2++;
      if (oldin2 >1){
      oldin2=0;
      }
     }
    
    x = oldin2;
    if (millis() - setmillis > settimer)
    {
      setmillis = millis();
      constructset();
    }
  }

    digitalWrite(out1, oldin1);
    lcd.setCursor (13,1);
    if (oldin1 == 1){ 
      lcd.write(d);
    }
    else {
      lcd.write(c);
    }
    
    digitalWrite(out2, oldin2);
    lcd.setCursor (15,1);
    if (oldin2 == 1 || t < T){
      oldin2 = 1; 
      lcd.write(a);
      }
    else {
      lcd.write(g);
      }
}

void ldra()
{
  lcd.setCursor (14,1);
  if (analogRead(LDR)>=200){ 
    lcd.write(f);
  }
  else {
    lcd.write(e);
    }
}  

void digitalClockDisplay()
{ 
  lcd.home();
  if (hour()<10) {
    lcd.print("0");
  }
  lcd.print(hour());
  printDigits(minute());
  lcd.print(" ");
  if (day() <10) {
    lcd.print("0");
  }
  lcd.print(day());
  lcd.print("/");
  if (month() <10) {
    lcd.print("0");
  }
  lcd.print(month());
  lcd.print("/");
  lcd.print(year());
}

void printDigits(int digits)
{
  lcd.print(":");
  if(digits < 10)
    lcd.print('0');
  lcd.print(digits);
}

void readtime()
{  
  int hour = Serial.parseInt();
  int minute = Serial.parseInt();
  int second = Serial.parseInt();
  int day = Serial.parseInt();
  int month = Serial.parseInt();
  int year = Serial.parseInt();
 
setTime(hour,minute,second,day,month,year);
  if (bridgenode == 1){
   RS485.print(utch);
   RS485.print(hour);
   RS485.print(dof); 
   RS485.print(minute);
   RS485.print(dof); 
   RS485.print(second);
   RS485.print(dof); 
   RS485.print(day);
   RS485.print(dof);   
   RS485.print(month);
   RS485.print(dof); 
   RS485.print(year);
   RS485.print(eof); 
  }
}