NewSoftSerial Duemilanove - baud rates?

Posted on arduiniana already in the hope that Mikal will see it but is awaiting moderation at the moment and thought I'd throw it open to the boards in case others might know the answer to this..

Having a bit of a problem with what I think is down to a writing baud rate issue with NSS..

I have the PC connected to the Duemilanove via USB, then pin 3 of the arduino (Tx) connected to the serial connection on a Milford Instruments LCD display screen. Which accepts baud rates of 9600 or 2400 depending on the baud jumper, is 8bit, no parity and one stop bit.

I have the baud jumper installed so it should be reading at 9600 baud.

Pin 3 of the Duemilanove is connected to a level converter to bring it to 5v. I have also tried without the level converter inverting the lcd NewSoftSerial in the sketch but same results.

In this instance / tiny project the Duemilanove should be acting as a USB to serial converter. The sketch is as follows:

#include <NewSoftSerial.h>

NewSoftSerial lcd(2, 3);

void setup()
{
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);
  Serial.begin(9600);
  lcd.begin(9600);
}

void loop()
{
  if(Serial.available())
  {
    char c = Serial.read();
    lcd.print(c);
    Serial.print(c);
    Serial.print((bool) lcd.overflow());
  }
}

So it should be reading from Serial (1 char at a time) then printing to the LCD display via pin 3 (additional Serial prints for debugging)..

At the PC side I have a python script to send the commands (clear the LCD display, reset the cursor position and send some 'test' text):

import serial
def echo(string):
    if ser.isOpen():
        for i in range(len(string)):
            ser.write(string[i])
            ser.flush()
            print "Tx: %d" % ord(string[i])
            c = ser.read()
            print "Rx: %d" % ord(c)
            o = ser.read()
            print "Overflow: %s" % o
            
ser = serial.Serial(port='/dev/ttyUSB0', baudrate=9600, timeout=1)
ser.open()
echo(chr(254) + chr(1))
echo(chr(254) + chr(0))
echo("test")
ser.close()

At 9600 baud either side of the Arduino, data is getting through to the display screen but about 50% of the time at least 1 of the 4 characters that make up the initial string is garbled. However the messages that come back through the USB serial port to the PC are always correct and there's no overflow.

Connecting the LCD display directly to the PC with a serial cable or through a USB to serial converter (PL2303) it works 100% of the time fine.

I tried the lower baud rate that the LCD provides (2400) which appeared to make things marginally better (slightly more consistent with the correct message appearing) - probably somewhere between 70% - 80% correct on the display but still not accurate all of the time.

I'm assuming the board isn't writing with NSS accurately, and looks like a baud issue when writing with NSS.. Any ideas / things to test?

P.S. I've also just tried sending the same bytes / messages directly from the sketch (without the Serial read) and same problem..

Thanks

Data sheet for the Milford LCD display - milinst.co.uk - This website is for sale! - milinst Resources and Information.

The bit rate from NewSerial is very precise.
What you describe could be a problem of signal level.

What is that level shifter you talked of?

In rare cases a device will not accept 0/5V as RS-232 signal (it not indebted to do so!) It might really need a higher level and/or negative levels...

What about ground connnection? -I just ask for completeness..

Thanks for your reply deSilva..

I was wondering this as well since doing some more testing and I have had consistently accurate messages from one pc to another PC via the arduino / level shifter. The level conversion is done via a Maxim 3323E chip - Mixed-signal and digital signal processing ICs | Analog Devices and is set up exactly as shown here: http://www.arduino.cc/en/Tutorial/ArduinoSoftwareRS232

If this is the problem which I'm beginning to think it's more and more likely, I'm still not sure why communication works perfectly from the PC through the prolific PL2303 which being USB would be providing ~5v level as well wouldn't it?

through the prolific PL2303 which being USB would be providing ~5v level as well wouldn't it?

I think this is a cable with a 9p subD plug at its other end? Then it will provide +/- 12 Volts. Or is it just a tiny break-out board?

Nevertheless you should use the Maxim chip ..
If you have a multimeter, can you take a voltage from
Pin 2,6, and 7 please?
This will verify whether the chip is correctly wired to all that caps...
There should be no characters send during that measurement.

Level shift voltages after the arduino:

Pin 2 = 6.57v
Pin 6 = -5.51v
Pin 7 = 6.57v

Also.. the PL2303 cable I have is the USB to 9Pin DSub type, but I just checked the Tx pin on that which is showing as -6.53v..

Well this is not bad! Though a little bit funny.... The MAX chip doubles (and inverts) the voltage, so this somehow indicates a 3.3 volt supply, but it should be a 5 v supply, shouldn't it??

Yea, the max chip is definitely connected to the 5v pin of the arduino.. Measuring pin 16 (Vcc) of the max 3233e is reading 4.93v

Ok some further testing....

I wanted to see how the true UART port behaved so I uploaded the following sketch onto the board:

void setup()
{
pinMode(13, OUTPUT);
digitalWrite(13, HIGH);
Serial.begin(9600);
}

void loop()
{
Serial.print((char) 254);
Serial.print((char) 1);
Serial.print((char) 254);
Serial.print((char) 0);
Serial.print("Test!");
delay(500);
}

Which simply clears the display, resets the home position then prints the string 'Test!' to it.

Changed my Tx pin on the arduino from my previous sketch so arduino pin 1 is going through the level converter to the display. Disconnected the USB then powered the board with a 12v PSU - display worked perfectly (no garbled messages).

I then connected back up the USB, uploaded the NSS equivalent sketch:

#include <NewSoftSerial.h>

NewSoftSerial lcd(2, 3);

void setup()
{
pinMode(13, OUTPUT);
digitalWrite(13, HIGH);
lcd.begin(9600);
}

void loop()
{
lcd.print((char) 254);
lcd.print((char) 1);
lcd.print((char) 254);
lcd.print((char) 0);
lcd.print("Test!");
delay(500);
}

Put the Tx back to pin 3 through the level converter again. Disconnected the USB and powered with the 12v PSU again, reset the board and the garbled messages are back..

Where it should be showing 'Test!' i get some characters randomly substituted - Such as the ohm / omega symbol instead of the last 't' or the e becomes E, the s sometimes appears as what looks like the infinity symbol..

Just out of dispair: Can you connect two different pins, say 6 an 7 or even better 8 an 9? Burned-out I/Os in the chip can show similar symptoms...

Just tried putting the Tx on Pin 7 - same garbled messages problem. Also tried on Pin 9, again same result.

I've taken some photos of the messages that appear on the display and will upload shortly..

How the display appears for some of (maybe 50 - 60%) of the time:

The common yet different types of garbled messages that show up regularly:



I had thesignals from NewSoftSerial on the osciloscope now:

2400 baud: Measured bit rate: 2350
9600 baud: Measured length of bitcell: 106us (should: 104,2)
19600 baud: Measured length of bitcell: 53.5us (should: 52)
The stopbit is a little bit longer and jitters somewhat.

So there is nothing here that should affect the serial communication...

Tried the same with a different Dueilanove, different caps, different max chip, still the same.. Very confused now :-/

Do you have something in your software that might influence the interrupt system? That would cause a noticle jittter of the bitcells...

Well I simplified it by just using the sketches in reply #8. Simply sending the messages out straight from the arduino. Mikal has confirmed that there doesn't appear to be anything wrong with the logic - "Logically this seems ok. Are all devices grounded? All operating at the correct voltage? There isn't any RS-232 anywhere, is there?"

However I suppose there is RS232 by way of the level shifter..

I'm not sure that there is much left to try, I'm sure the LCD device itself is fine because it works through the dedicated UART port through the level shifter just fine, and through the PL2303.

The only other thing to try is a .22uf cap in place of C1 of the charge pump required for the Max 3323 which is specified in their datasheet but this is not what is shown in the arduino rs232 tutorial - http://www.arduino.cc/en/Tutorial/ArduinoSoftwareRS232

I'm not convinced this would actually achieve any different results though as the existing circuit (wired the arduino rs232 tutorial way) works through the UART pins.

You never proved how you wired the MAX... especially the pins 11,12,13 have to be HIGH, as this is a very specialized chip (and should never have been used as an tutorial example)!

I feel still a little bit uneasy about the +/- 6 V... It shpould vave been 10...

But as you said, it works with HardwareSerial....

It is not worth posting a screenshot of the oscillogram. I ran HardwareSerial and NewSoftwareSerial in parallal an the signals were highly correlated. SoftwareSerial - as posted -lost a little bit, 20us from stop bit to stop bit = 20us/1ms = 2%. This is inside the tolerance....

I have also now wired exactly as the 'Typical Operating Circuit', under the '±15kV ESD-Protected, RS-232 Transceivers for Multidrop Applications' section of the chip manufacturers datasheet: http://datasheets.maxim-ic.com/en/ds/MAX3322E-MAX3323E.pdf

Pins:

1 - C1+
2 - C3+ (- to gnd)
3 - C1-
4 - C2+
5 - C2-
6 - C4+ (- to gnd)
7 - Connected to the serial of the Milford LCD
8 -
9 -
10 -
11 - 5v
12 - 5v
13 - 5v
14 - 5v
15 - gnd
16 - 5v

I'm assuming now it can only be the NSS timings or an extremely sensitive LCD unit..?

Still working on your problem?

In the meantime there had been two more issues with NSS
(1) The receive via NSS shows a garbled character from time to time (should have not so much to do with your issue)

(2) The transmission or receive of a character by NSS happens uninterruptable. This means that a character to be received through hardware serial might get lost, if the bit rate of NSS is slow. So against the common feeling the NSS should work better the higher its bit rate. Especially the bit rate for hardware serial should be lower or at least thesame to avoid drop outs here.

Alas, all this can hardly have to do with your issue, as you reflect all incomming characters correctly back to the PC.... Though it might beworth an experiment to set the PC (!) connection down to 4800 baud

I have again looked through the NSS code, but no obvious mistakes there....