0

i have built a TTL/RS232 converter to send strings via RS232 using an Arduino nano, following the tutorial:Arduino-RS232. My problem concerns the transmission baud rate, because in the tutorial it is suggested a short script which manually generates the code which will become the RS232 signal. In this script some constant delays are used, i.e. "bit9600Delay 100 " and so on. These delays are set for a baud rate of 9600, but i need to double it to have a baud of 19200. Is it enough to divide by two those constant values or should i use a different method? Thank you very much

  • Do you notice anything when you look at the 4800 baud values? – CL. Dec 28 '16 at 14:43
  • Dividing by two may not be the best option since bit4800 delay is 188 and bit9600 delay is 100. Seems like the delay is mainly used for reading the bits that were sent over the RS-232 port. So this wait time may be good to run at 19200 bps. After all, it looks to me like it is a simple delay to allow enough time to read back data without having it being distorted (nonsense). – 12Lappie Dec 28 '16 at 14:55
2

It is never good to base code on delays instead of intervals. This is especially true for faster intervals where the execution of the code its self consume a significant portion of the interval. Also note, some protocols only occasionally resynchronize. RS232 resynchronizes after each byte (about 8 bits of data). So any accumulated delay errors may impact the integrity of the bits furthest from the resynchronization event.

Instead of delays use the Arduino's built in hardware to send and receive RS232 communications. The hardware is designed to work independently of code execution and will out perform software implementations especially for the faster baud rates.

  • The waters might be a bit muddy here. I think the Arduino's delays are based on the number of ms passed (intervals of time). So they might be somewhat immune to interrupts. (That is to say, they may not be simply dumb loop counters.) Still, the built in processor HW is a much better choice for RS 232 communications. But, if you need a SW implemented RS 232 port, there are libraries which have already lamented over these problems of balancing code execution time against the necessary delays needed to generate the proper baud rate. – st2000 Dec 28 '16 at 15:17
  • Yes, the normal delay is based on time. delayMicroseconds is a tight loop. This is partly because of the granularity of the timer used for millis, micros and delay. – Nick Gammon Dec 29 '16 at 2:19
1

This Arduino sketch is a wonderful opportunity for you to learn the very basics of serial communication.
You should be very careful scaling the constants given in any baud rate program (whether using a hardware or software UART) as they are normally off by some small percentage, and without understanding the implications you may eventually introduce timing errors. There is a great description of the timing sensitivities in this Picaxe note.

The table below shows the actual bit times for various baud rates: enter image description here

Notice here that for 9600 baud the sketch uses a constant which will use a 100 uS delay function for the bit times. From the table above you can see that this is slightly inaccurate, and the more correct delay would be 104 uS. This is an error of about 4%.

Would this error prevent successful reception of characters in the sketch? Single characters with inter character spaces more than 1 character time, no ....but if you sent a string of characters end to end with no gaps this sketch would fail on receive.

Scaling the constant for 19200 baud --> 100/2 gives 50 but the bit time for 19200 is actually 52 uS, so again an error, this time of about 1%. If we scaled the constant (100) for 115200 --> 100/12 gives 8.3 uS while 104/12 gives 8.7 uS for an error 4.5% or close to 0%.

There is IMO an error in this sketch for the serial receive routine, since it's hard wired to expect 2 stop bits. Any concatenated characters separated by only one stop bit will fail (you miss the second character start bit).

int SWread()  
{   
  byte val = 0;   
  while (digitalRead(rx));   
  //wait for start bit   
  if (digitalRead(rx) == LOW) {   
    delayMicroseconds(halfBit9600Delay);   
    for (int offset = 0; offset < 8; offset++) {   
     delayMicroseconds(bit9600Delay);   
     val |= digitalRead(rx) << offset;   
    }   
    //wait for stop bit + extra    
    delayMicroseconds(bit9600Delay);     ....hard wired two stop bits   
    delayMicroseconds(bit9600Delay);     ....or 1 stop and 1 bit time gap   
    return val;    
  }  
}  

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.