Printing (via Python) to Serial POS Printer

Hello all,

I'm attempting a microprinter project inspired by Tom Taylor tomtaylor.co.uk/projects/microprinter

I have an old Verifone Serial Printer with an RS232 port. Using a Max 233 chip and a wiring diagram found here.
flipbit.co.uk/micro-printer.html

I figured out the command codes and can print directly to the printer from the Arduino and use some formatting (red ribbon, double wide, line feed etc.)

My goal is to connect the arduino with an Ethernet Shield to the web and print out daily digest style reports (weather, latest tweets etc.). Python seems to be a good way to scrape sites/feed and gather the content which the arduino will read and then print in a format I design.

The problem is that I cannot get the Arduino sketch to read (or the Python script to supply) content. This test Python script

import serial # if you have not already done so
import time
ser = serial.Serial('/dev/ttyUSB0', 9600)
time.sleep(2)
ser.write('Goodnight Moon!')
#this goes to the printer but only the first letter is printed over and over

Combined with this Arduino sketch

/this sketch prints the first letter of pyPrintTest.py over and
over
/
#include <NewSoftSerial.h>

NewSoftSerial mySerial(3, 2);

char myString[ ] = {Serial.read( )};

void setup()
{
Serial.begin(9600);
Serial.println(myString[1]);

// set the data rate for the NewSoftSerial port
mySerial.begin(9600);
mySerial.println(myString[1]);
}

void loop() // run over and over again
{

if (mySerial.available()) {
Serial.print(myString[1]);
}
if (Serial.available()) {
mySerial.print(myString[1]);

}
// delay(2000); I commented out the delay since putting it in stops everything!
}

Just prints the first letter of the copy in the Python script again and again (so "G" in this example but "H" if I replace the G with an H).

From looking around I think my issue might be to do with making the Arduino look for a string of text but I'm stumped. Ultimately I want to have a bunch of scripts running (via cron or similar) that will output to a file (pickle or .json) that the Arduino will read.

Any suggestions gratefully received.

char myString[ ] = {Serial.read( )};

You can't execute code outside of a function. I'm surprised this even compiles. Serial.read() reads one byte from the serial port, if there is one to read. Even if this did compile and execute, all that you would have succeeded in doing is to declare an array large enough to hold one byte.

After this mis-allocation of memory, you consistently refer to the second element of your one element array.

In loop, you really might want to consider actually reading a byte from the serial ports now and then, instead of just sending the same byte over and over.

I'm surprised this even compiles.

me too - could be because Serial is defined as extern in hardwareSerial.h file ?

Just prints the first letter of the copy in the Python script again and again

There is only one character read from the serial port that stays in your buffer. Read http://www.arduino.cc/en/Serial/Read and adapt your sketch

Note that the index of array's in C++ start with 0 so declaring s[10] makes available s[0] .. s[9]

Hi,

Thanks for the responses, I was tying myself up in knots!

I figured it out so that I can now print from the Python script and make Serial.read read an array...I'm sure I have some extraneous code in there and I believe I need to put a NULL terminator in to tell the sketch to stop listening, but my initial goal has been accomplished.

#include <SoftwareSerial.h>

#define txPin 2
#define rxPin 4

char mycontent[23] = " "; //declaring an array with 23 characters "Goodnight Moon!"+ spare places
byte index = 0;

SoftwareSerial printer = SoftwareSerial(rxPin, txPin);


void setup()
{
  Serial.begin(9600);
  pinMode(txPin, OUTPUT);
  printer.begin(9600);
  Serial.flush();

}

void loop()
{

  if (Serial.available() > 0) {

    for(byte i=0; i=22; i++) {  //count that all the characters are in the serial buffer

        mycontent[23] = Serial.read();   // now read the buffer


      printer.print(mycontent[23],BYTE); // print it

    }

    delay(1000);  // this doesn't do anything right now
  }
}

and make Serial.read read an array

You did only use one element of the array (nr 23) which in fact was outside the array boundaries. Probably it did overwrite the byte index ... so it did not crash.

Stripped your sketch to

#include <SoftwareSerial.h>
#define txPin 2
#define rxPin 4
SoftwareSerial printer = SoftwareSerial(rxPin, txPin);

void setup()
{
  Serial.begin(9600);
  pinMode(txPin, OUTPUT); 
  printer.begin(9600);
  Serial.flush();
}

void loop()
{
  if (Serial.available() > 0) 
  {
    byte b = Serial.read();
    printer.print(b, BYTE); // print it
  }
}
if (Serial.available() > 0) {
    for(byte i=0; i=22; i++) {  //count that all the characters are in the serial buffer
        mycontent[23] = Serial.read();   // now read the buffer
      printer.print(mycontent[23],BYTE); // print it
    }
    delay(1000);  // this doesn't do anything right now
  }

Take a look at your for loop. It says "Start with i=0. Execute this block of code while i=22. After each execution, increment i by 1".

How many times is Serial.read() called? How many times is mycontent[23] overwritten? mtcontent[23] is not part of the mycontent array, as robtillaart points out.

    delay(1000);  // this doesn't do anything right now

When the comments and the code disagree, the code is right. It DOES do something. What is does is this: Every time there is serial data to be ignored, waste a whole second doing nothing.

On second though, perhaps that fits with your definition of not doing anything.

Serial.available() returns an integer, not a boolean. It is not saying yes, there is data to read or no there is no data to read. It is telling you how many bytes there are to read. You should capture that value, and use it in your for loop.

Thanks for the responses, I'm going to read up for a bit before revising this!