Serial and SoftSerial libraries and timeout marker?

Status
Not open for further replies.

Lukashuk

Well-known member
Hello all!
I ran into a problem. The Serial and SoftSerial libraries have no idea what timeout is.
I looked a lot of webpages and did not find a solution.
As is well known, many protocols such as ModBus use timeout.
Where timeout is the gap between packets and should be> = 1.5 the duration of the transmission of one byte.
Since the data packet may have different lengths. Marker timeout. can signal the end of a packet,
as well as a marker to allow the transfer of a new packet.
I use packets with a length of 2 bytes or more, and do not use the checksum, so I cannot use the ModBus library.
So the question is: where should I change the Serial library and / or SoftSerial to get such a marker?
I understand that I have to insert a code of something like timeout = micros () and (or) to start another timer to count the timeout
which is reset when receiving a new byte or an interrupt is triggered if more timeout.
I hope for your help and thank you in advance.
 
Last edited:
I am not sure what you are asking for...

There are a couple of different ways to do the timeouts...

That is you can simply roll your own....
Where you do something like:
Code:
uint32_t time_last_char = 0;
...
   if (Serial1.available() {
      my_byte = Serial1.read();
      time_last_char = micros();
   } else if ((micros() - time_last_char) > timeout) {
      ... do timeout
  }

Or you can use some of the built in serial support.
Example look at: https://www.arduino.cc/reference/en/language/functions/communication/serial/readbytes/
It shows you how you can set a timeout...
 
Thank you for responding.
I need to know - is there a sign of the end of the transfer (timeout has passed)? to start analyzing the package, and can i send a new package.
Here is a simple code.

Code:
#include "PinChangeInterrupt.h"

#define key 12
#define led 13
volatile byte state ;
volatile byte clocks ;
byte number1=0x10;
byte number2=0x20;

void setup() 
{
 pinMode(key, INPUT); 
 digitalWrite(key, HIGH); 
 pinMode(led, OUTPUT);
 attachPCINT(digitalPinToPCINT(key), Change_led, CHANGE);
 Serial.begin(4800);
}

void loop() 
{
  digitalWrite(led, state); 
  bitWrite(number1, 2, state); 
  Serial.write(number1); Serial.write(number2); 

  delay(500);
}


void Change_led(void)
{
  clocks++;
  if(clocks>5)
  {
    state = !state;
    clocks=0;
  } 
}





To send packets, I want to replace loop () with
Code:
void loop ()
{
 if (timeout)
 {
 digitalWrite (led, state);
 bitWrite (number1, 2, state);
 Serial.write (number1); Serial.write (number2);
 }
}
Sorry for my english.
 
Thank you for responding.
I need to know - is there a sign of the end of the transfer (timeout has passed)? to start analyzing the package, and can i send a new package.
Here is a simple code. To send packets, I want to replace loop () with
Code:
void loop ()
{
 if (timeout)
 {
 digitalWrite (led, state);
 bitWrite (number1, 2, state);
 Serial.write (number1); Serial.write (number2);
 }
}
Sorry for my english.
 
I forgot to add that in the if( timeout) I also want to analyze the package
Code:
if (timeout)
 {
  [B]MyAnalis();[/B]
  digitalWrite (led, state);
  bitWrite (number1, 2, state);
  Serial.write (number1); Serial.write (number2);
 }
 
it turned out preparation
Code:
#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<DOR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)

// USART Receiver buffer
#define RX_BUFFER_SIZE0 8
byte rx_buffer0[RX_BUFFER_SIZE0];
byte pointer_rxbuf =0;
byte value;
byte timeout=1;
unsigned long time;

#define LED_PIN 5

void setup()
{
  pinMode(LED_PIN, OUTPUT);
  UartInit(); 
}
void loop() 
{
 if((micros() - time) >= 1875)//if bautrate 9600 - 19 milisec ~ 1,5 period 
  {
    timeout=1;
  }
  
 if (timeout)//allow transfer
  { //ship as much as you need
   send_UART(0x53); // ASCII  'S'
   send_UART(0x2D); // ASCII  '-'
   send_UART(0x45); // ASCII  'E' 
   timeout=0;   
  }

 if(pointer_rxbuf==1)//my need resiv only 2 byte, where 0 is the first byte
  { 
    //here we process the received packet
     if(rx_buffer0[0]==0x31)PORTB |= 1 << LED_PIN;
     if(rx_buffer0[1]==0x32) PORTB &= ~(1 << LED_PIN);     
  }
}

void UartInit(void)
{
  UCSR0B |= (1<<RXEN0)  | (1<<TXEN0) | (1<<RXCIE0);    // UART RX, TX
  UCSR0C |= (1<<UCSZ01) | (1<<UCSZ00)             ;    // Asynchron 8N1
  UBRR0H = 0;
  UBRR0L = 0x67; //Baud Rate 9600
  sei();
}

void send_UART(byte value) 
{
  while(!( UCSR0A & (1 << UDRE0)));   // Waiting for the transmit buffer to clear.
  UDR0 = value; // We place the data in the buffer, we begin transfer
}

ISR(USART_TX_vect)
{
  
}

ISR(USART_RX_vect)
{
   value = UDR0;             //read UART register into value
   // тут обрабатываете принятый байт...
  if((micros() - time) < 1250)//if bautrate 9600 - 1250 microsec ~ 1 period transfer 1 byte
  {
    time =  micros();
    pointer_rxbuf++;
    rx_buffer0[pointer_rxbuf]=value;
  }
  if((micros() - time) >= 1875)//~1,5 period
  {  
    time =  micros(); 
    pointer_rxbuf=0;
    rx_buffer0[pointer_rxbuf]=value;
  }
}
 
Status
Not open for further replies.
Back
Top