Serial printing - odd results

I’m delving into the world of Arduino and having a blast so far.

My first project is likely a little too ambitious for a newbie, but I have some experience with the Processing.org language so figure I’m off to a good start.

I’m using the Arduino to interface with an old dot matrix printer (Citizen 120D from 1986). I’ve managed to get this ironed out to the point of getting a signal to the printer from the Arduino (via a MAX232 converter to up the voltage to the RS232 interface standard).
Really simple code at this point. (shown below) just to get something over to the printer.
The problem is that I’m getting some odd results.
Simple ‘Hello World’ type message that should be going over in ASCII (I’m guessing) and its resulting in this…(See the attachment)

Some characters printed and others are only the P in a square.
I know it’s not something wrong with the printer as I have another one (a Citizen 120D+) that does exactly the same thing.

Any suggestions?

void setup ()
{
Serial.begin(9600); //set printer baud rate
}

void loop() //looping sequence
{

Serial.write(“Hello World”); //Print “Hello world” to buffer
delay(2000);

}

'P' for "parity error"?

Slight update…

Tried it with the following code to just send over the ASCII codes.
Results are the same

void setup ()
{
Serial.begin(9600); //set printer baud rate
}

void loop() //looping sequence
{

Serial.write(72); //Print “H”
Serial.write(101); //Print “e”
Serial.write(108); //Print “l”
Serial.write(108); //Print “l”
Serial.write(111); //Print “o”
Serial.write(32); //Print " "
Serial.write(119); //Print “w”
Serial.write(111); //Print “o”
Serial.write(114); //Print “r”
Serial.write(108); //Print “l”
Serial.write(100); //Print “d”
Serial.write(32); //Print " "
Serial.write(13); //CR

delay(1000);

}

Good call.

I’ve switched the parity on the printer, and it’s reversed the way it prints the characters.

and thats switched what it prints out correctly.

Is there a way to define parity on the outgoing signal from the Arduino?
If there is, I can build a conversion reference table for anything that I want to print so it comes out right.

(On the picture the line of 'P’s under the ‘Hello World’ is when I tried switching parity checking off)

Is there a way to define parity on the outgoing signal from the Arduino?

See http://arduino.cc/en/Serial/Begin

Thanks for the link. I've done that and it doesn't seem to make a difference.

What I was after was a way of setting the parity on a per character basis, rather than define the standard for the whole communication. Is that possible?

I'm curious why you are using Serial.write() to send ASCII data, when that is what Serial.print() is for.

What I was after was a way of setting the parity on a per character basis, rather than define the standard for the whole communication. Is that possible?

Well, if you [u]really[/u] wanted to you could start Serial with the required parity, send a character, stop Serial, start it again with the required parity, send a character, stop Serial and so on but nobody would realistically do that would they ?

I think that you should investigate what it is about some characters that need a different parity and, as PaulS suggests, try Serial.print()

Is the printer protocol seven bits plus parity, or eight bits plus parity? What about the number of stop bits?

AWOL: Is the printer protocol seven bits plus parity, or eight bits plus parity? What about the number of stop bits?

From the manual...

Baud Rate 9600, 4800, 2400, 1200. 600, 300 or 110 Parity None, odd or even Data Bit 8-bit or 7-bit data length Stop Bit 2-bit or 1-bit Protocol XON / XOFF or DTR / DSR

I didn't expect this much interest in my little problem, thanks everyone. This is a great community.

Answering a couple of questions:

PaulS -"I'm curious why you are using Serial.write() to send ASCII data, when that is what Serial.print() is for."

I'd looked through the Serial standards pages and on other places on the web, then picked Serial.write() as I wanted to make sure it defined the transmission as BYTES (I know it should be the default but Serial.print() or Serial.write() don't seem to make any difference)

UKHeliBob - I will give it a try, but stopping and starting Serial seems like a lot of hassle given that these were simply plug in and print machines 20 years ago. But I will give it a try as I really want to get this working.

AWOL- The settings from the manual (Thanks Riva) are defined by dip switches. I've been playing around with them to see if there is a difference to no avail. Also just started trying Serial.begin(speed,config) to define the output from the Arduino and set the number of bits, parity and stop bits. Natively, the printer seems to see no difference between 1 or 2 stop bits (i.e. it makes no difference to what it prints out)

Riva - Thanks for the quote from the manual - Do you have one of these printers? or did you find it on-line? I already have a couple of difference manuals downloaded from the web, but there doesn't seem to be anything definitive about this model. If you have something, please please send it over.

When you changed the DIP switches, did you power-cycle the printer?

If you set the printer for eight bits, no parity, one stop bit, then everything should simply work, unless you have a slight speed mismatch.

125ml: Riva - Thanks for the quote from the manual - Do you have one of these printers? or did you find it on-line? I already have a couple of difference manuals downloaded from the web, but there doesn't seem to be anything definitive about this model. If you have something, please please send it over.

Sorry, don't have the printer just looked it up online. Further to AWOL's suggestion of setting printer to use arduino default 8N1 serial you may need to also set software flow control and alter you sketch to drip feed (don't fill Serial buffer) characters and obey XON/XOFF requests from printer. Another option to test is reducing the baud rate to something less than 9600.

UKHeliBob - I will give it a try, but stopping and starting Serial seems like a lot of hassle given that these were simply plug in and print machines 20 years ago. But I will give it a try as I really want to get this working.

I wasn't being serious and did say

nobody would realistically do that would they ?

If you are going to try it then that implies that you know which characters need which parity. Care to share as it may give some clues to the problem ?

UKHeliBob, I got that you weren't being serious. But I'll give anything a try at this point.

So, I've built a map of the characters that are printed and those that aren't with a simple bit of code. Had to use Serial.write() as when I tried it with Serial.print() it just printed the numbers, not the corresponding ACSII characters.

The map is attached as a PDF.

Interestingly, there are a few characters that are printed that are from the extended ASCII set rather than the standard 127 set.

notably 91, 93 and 124.

Riva - I'll play with the baud rate, XON/XOFF requests (currently I have it set to the data ready protocol) and drip feeding (using delay() I guess)

The code I used to build the table.

void setup () { Serial.begin(9600); //set printer baud rate }

int output = 32;

void loop() //looping sequence {

Serial.write(output); //Print each letter

delay(1000);

if(output == 126) { // This loop loops forever and does nothing while(true) { continue; } } output++; }

Had to use Serial.write() as when I tried it with Serial.print() it just printed the numbers, not the corresponding ACSII characters.

void setup ()
{
Serial.begin(9600); //set printer baud rate
}

int output = 32;

void loop() //looping sequence
{

Serial.print((char)output); // Print each letter

delay(1000);

if(output == 126) {
    // This loop loops forever and does nothing
    while(true) {
      continue;
    }

Please note the use of code tags and of "print"

Ahhhh, got it. Thanks

And here is the PDF that I failed to attach to the earlier post.

printer character map.pdf (35.6 KB)

I've confirmed that there is nothing wrong or strange with the printer, as I can print text to it directly from 'screen' on my mac, without changing anything. Without any parity problems.

I did change a couple of settings on the printer. Switch from data ready to XON/XOFF and turn off parity check.

Baud 9600, XON/XOFF, 7 bit, Parity check off, Parity Even

So it looks like it's the XON/XOFF as I had tried switching between 7 and 8 bit, odd and even parity, with little difference.

Nice one Riva, looks like that may be the answer!

Now to get some checking loops into the code and to test it further.

Baud 9600, XON/XOFF, 7 bit, Parity check off, Parity Even

Don't you want 9600, XON/XOFF, 8 bit, Parity check off, no parity?

I would set all the DIP switches off. This will give you 9600 baud, XON/XOFF flow control, 8 data bits, no parity checking. Further reading of the manual and it quotes...

The XON/XOFF Protocol This is the simplest of the software protocols. When the printer’s buffer fills up it sends the ASCII code XOFF (13 HEX) to the computer to tell it to stop sending information. When there is again some room in the buffer the printer sends the ASCII code XON (11 HEX) to the computer to tell it to resume sending information. If the computer doesn’t stop sending information within 256 characters after it receives an XOFF code the information that overfills the buffer will be lost.

As the Arduino Serial buffer is only 64 bytes long you probably don't need to drip feed but react in a timely manner to XOFF commands.