Pages: [1]   Go Down
Author Topic: Wierd problem when using SoftwareSerial  (Read 638 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 18
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hello.

i am using an arduinoMega 2560.

it has 4 hardware serial ports, but i need 1 more.

so i included a software serial-port.

at first i was only using the 4 hardware ports.
i was reading bytes from 3 and sending them with the 4th.

now i wanted to send them over the software port.

here my code with the hardware port:
Code:
if (Serial3.available()) {

    Serial3.setTimeout(45);                           
    Serial3.readBytes(comein_3, 11);                         


     if ( puffer[4] != (byte) comein_3[9] ){    // here i check if there is new data
      for( int i=5; i<10; i++ ){
        puffer[ i-5 ] = comein_3[ i ];                 
      }



  // ************************ here i do some things with the bytes  *********************************************

      // in the end the bytes that were in the "puffer"-array are now in "fertig_daten"
     

      Serial.print( (char*) fertig_daten);              // here i send them over the hardware port
                                                                  // this works just fine

      serial_out.print( (char*) fertig_daten);        // here i try to send my data over the software serial port
                                                                   
    }
  }

my problem now is, when i try to use the software port, my controll-function if the bytes read from serial3 are new doesnt work anymore.
here:
Code:
if ( puffer[4] != (byte) comein_3[9] ){    // here i check if there is new data
      for( int i=5; i<10; i++ ){
        puffer[ i-5 ] = comein_3[ i ];                 
      }

when i use the hardware port, send the date it works fine.
i am reading data from a RFID-Reader and if the Transponders is held into the antenna-field, the reader sends the transponder-number over and over again.
but i only need it once, so i use the controll-function to check if the data, which i read is different from the data i read the last time.
and for some reasons, when i try to use the software serial port that doesnt work anymore.
Logged

Switzerland
Offline Offline
Faraday Member
**
Karma: 96
Posts: 4755
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Post complete code!

You know that interrupts are disabled during the whole transfer of a byte using the SoftwareSerial class, don't you? If you use SoftwareSerial you generally shouldn't expect that anything other is going on on that Arduino during that use, at least not in a timely manner.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 18
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

the complete code is very long and has a lot of stuff, that has nothing to do with the part, that is causing the problem.

should i post it anyway?

and yeah i know that.

it seems like, when i send stuff with the software serial it screws with the buffer of serial3.(could that be?)
changes some bytes for what ever reason, which causes the if( puffer[4] != (byte) comein_3[9] ) to become true, despite the fact that the some transponder is beeing read.
Logged

Switzerland
Offline Offline
Faraday Member
**
Karma: 96
Posts: 4755
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
should i post it anyway?

Showing us just excerpts of your code doesn't allow us to find the parts that may interfere. For example you don't show how the serials are initialized or how the buffers are defined.
Ideally you minimize your sketch to the smallest size still showing the problem you described. Then post that code.

Quote
it seems like, when i send stuff with the software serial it screws with the buffer of serial3.(could that be?)

I don't think so. It's more probable that you miss some characters if the interrupts are disabled for a too long time because the serial buffers are filled within interrupt service routines. If you have 4 serial interfaces receiving data and sending that data out using a SoftwareSerial chances are quite high that the SoftwareSerial code is using so much processor time (with interrupts disabled) that the serial receiving is not reliable anymore.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 18
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

okay, here is the code.

there is also an if (Serial1.available()) and if (Serial2.available()) construct which does the same as the if (Serial3.available()).
had to cut it, because of the 9500 character limit.
Code:

#include <LiquidCrystal.h>
#include "Wire.h"
#include <SoftwareSerial.h>
#include <EEPROM.h>

SoftwareSerial serial_out(10, 11); // RX, TX

// here was a lot of variable declaration

void setup(){

  
  // Initialisieren der seriellen Schnittstellen
  Serial.begin (2400);                          // Serial 0 mit einer Baud-Rate von 2400 initialisieren
  Serial1.begin(9600, SERIAL_8E1);              // Serial 1 mit 9600 Baud und Even-Parity initialisieren
  Serial2.begin(9600, SERIAL_8E1);              // Serial 2 mit 9600 Baud und Even-Parity initialisieren
  Serial3.begin(9600, SERIAL_8E1);              // Serial 3 mit 9600 Baud und Even-Parity initialisieren

  // Software-Port initialisieren mit 2400 Baud
  serial_out.begin(2400);

}

//*********************************************************************
//*********************************************************************  ==> MAIN BEGIN <==

void loop()
{

  // ************************************* Print Serial with Time-Stamp (Serial_3)  

  // when characters arrive over the serial port...
  if (Serial3.available()) {

    Serial3.setTimeout(45);                            // 45 ms fürs Datenholen
    Serial3.readBytes(comein_3, 11);                   // 11 Bytes einlesen          


     if ( puffer[4] != (byte) comein_3[9] ){
      for( int i=5; i<10; i++ ){
        puffer[ i-5 ] = comein_3[ i ];                // 5 benötigeten Bytes in Puffer ablegen  
      }



  // here i put the bytes from puffer into fertig_daten

      for( int i=0; i<=9; i++ ){                                              // Daten in Speicher ablegen zur Anzeige auf LCD
        EEPROM.write( count  + i, fertig_daten[ i ]);
      }

      EEPROM.write( count + 10, ';');      // Zeit ebenfalls in Speicher ablegen
      EEPROM.write( count + 11, stunde_1);
      EEPROM.write( count + 12, minute_1);
      EEPROM.write( count + 13, minute_2);
      EEPROM.write( count + 14, sekunde_1);
      EEPROM.write( count + 15, sekunde_2);
      EEPROM.write( count + 16, millisekunde_1);
      EEPROM.write( count + 17, millisekunde_2);
      EEPROM.write( count + 18, '#');

      show = count;                                     // Platzierung merken
      count = count + 19;                               // Speicherstelle erhöhen
      // ************************************** Speicherstelle in EEPROM speicher ****************************
      val[3]=count % 10;                                 // aufteilen auf 3 stellen
      delay(10);
      val[2]=(count % 100)/ 10;
      delay(10);
      val[1]=(count % 1000) / 100;
      delay(10);



      EEPROM.write(1, val[1]);                            // speichern der 3 stellen
      delay(10);
      EEPROM.write(2, val[2]);
      delay(10);
      EEPROM.write(3, val[3]);
      delay(10);
      // ********************************************************************************************

      fertig_daten[ 10 ] = ';';                                               // Trennzeichen in Puffer ablegen
      fertig_daten[ 11 ] = stunde_1;                                          // Zeit in Übergabe-Array ablegen

      fertig_daten[ 12 ] = minute_1;
      fertig_daten[ 13 ] = minute_2;

      fertig_daten[ 14 ] = sekunde_1;
      fertig_daten[ 15 ] = sekunde_2;

      fertig_daten[ 16 ] = millisekunde_1;
      fertig_daten[ 17 ] = millisekunde_2;

      fertig_daten[ 18 ] = '#';                         // Abschlußzeichen in Puffer ablegen

      
      serial_out.print( (char*) fertig_daten);          // Datenübertragung an SK-System


      if (led_3_State == LOW) {
        //digitalWrite(led_3_Pin, HIGH);                                         // LED aneinschalten
        led_3_Millis = currentMillis;                                          // Zeitpunkt des Einschaltens von LED1
        led_3_State = HIGH;
      }
    }
  }




  //********************************************************************* Print chip
  if ( show != show_alt){                     // Nur neue Ausschrift, wenn neue Daten

    lcd.setCursor(0, 2);
    lcd.print("Platz ");

    if((show/19+1)<10){
      lcd.print("0");
    }
    lcd.print((show/19)+1);

    lcd.setCursor(8, 2);

    lcd.print(":");

    for(int b=0; b<=9;b++){
      lcd.write( EEPROM.read( show + b ) );
    }

    //********************************************************************* Print Memory

    lcd.setCursor(0, 3);
    lcd.print("Zeit: ");

    lcd.write( EEPROM.read( show + 11 ) );
    lcd.print(":");

    lcd.write( EEPROM.read( show + 12 ) );
    lcd.write( EEPROM.read( show + 13 ) );
    lcd.print(":");

    lcd.write( EEPROM.read( show + 14 ) );
    lcd.write( EEPROM.read( show + 15 ) );
    lcd.print(":");

    lcd.write( EEPROM.read( show + 16 ) );
    lcd.write( EEPROM.read( show + 17 ) );

    show_alt = show;                                              // Stelle merken, für Vergleich ob neue Daten da sind
  }

  //*********************************************************************  ==> MAIN END <==
  //*********************************************************************

}

Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 18
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

no one an idee?
Logged

Switzerland
Offline Offline
Faraday Member
**
Karma: 96
Posts: 4755
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Your serial_out connection has a baud rate of 2400. Sending of one byte needs about 4ms, during this time interrupts are disabled. The hardware of the 4 hardware serial interfaces can hold 1 Byte then an interrupt service routine has to copy that byte from the internal register to a buffer in the RAM. If this is not done until the next byte is completely received, that byte gets lost. During the 4ms of your SoftwareSerial transmission each of the 4 hardware serial interfaces can receive up to 4 characters, 3 of them are lost because the interrupt is disabled. Did you get the problem? Don't use SoftwareSerial in this setup!
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 18
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

okay, that makes sense.


could i solve the problem, if i would set the baud from my software serial up to 9600?
or should it be higher?

or doesnt it work at all, with the stuff i want to do?
Logged

Switzerland
Offline Offline
Faraday Member
**
Karma: 96
Posts: 4755
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
could i solve the problem, if i would set the baud from my software serial up to 9600?
or should it be higher?

Driving the speed higher will not make you happy. The principal problem persists. You must eliminate the SoftwareSerial class.

I would give the AltSoftSerial library a try (http://www.pjrc.com/teensy/td_libs_AltSoftSerial.html). It's fixed to two pins and it removes PWM from two pins but I guess in your case it's the most cost effective solution.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 18
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

haha, thanks, it works now with the altSoftSerial.
thanks guys
Logged

Pages: [1]   Go Up
Jump to: