Pages: [1]   Go Down
Author Topic: Read remote txt then print with Thermal Printer  (Read 1585 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 14
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi fellas;

I'm trying to read a .txt file on my server with python and send the message via serial to the Thermal Printer connected to Arduino Mega.

I've found some snippets for arduino, php and python. Mainly from: http://clete2.com/2009/11/control-lcd-text-over-web-interface-arduino/

Clete did exactly what i wanna do but with a LCD display as output device instead of a printer.

So, heres my problem:

When i deploy my arduino code, open the serial monitor and type something, the printer prints out without any problems.

But when i close the monitor and run my python script it won't do anything. Only when i stop running the script the printer prints out "Hello Printer!" which is in the setup() of my arduino code.

Here are the python and arduino codes:

Python

Code:
import serial
import time
import urllib



ser = serial.Serial('COM3', 19200, timeout=0)
url = "http://www.aerovisual.net/experiments/remoteprint/remote.txt"
previousMessage= ";"

while(True):
    message = urllib.urlopen(url).read()
    if(previousMessage != message):
        ser.write(message)
        previousMessage = message
        print message
        time.sleep(100)

Arduino

Code:
#include "SoftwareSerial.h"
const int buttonPin = 22;
int buttonState = 0;
int printer_RX_Pin = 6;  // this is the green wire
int printer_TX_Pin = 5;  // this is the yellow wire
SoftwareSerial Thermal(6, 5);

void setup(){
  Serial.begin(19200);
  Thermal.begin(19200);
  //printer.begin();
  pinMode(buttonPin, INPUT);
 
 Thermal.write("Hello Printer!");

  Serial.println();
  Serial.println("Parameters set");
}

void loop() {
  char option;

         
        while(Serial.available() > 0) {
          option = Serial.read(); //Take a character from serial port and check what it is
         
            Thermal.write(option); //Push this character to printer             
            Serial.write(option);
            delay(50);
           
        }

        delay(500);
 }

Thanks for the help.
Logged

Switzerland
Offline Offline
Faraday Member
**
Karma: 111
Posts: 5251
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Wait for about 2 seconds before sending anything to the Arduino. The opening of the serial interface resets the Arduino and it's waiting then on the serial interface for new sketches to be uploaded. If you wait 2 seconds before sending anything the bootloader ends it's work and gives control to your sketch which then can read your text and prints it to the printer.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 14
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Wait for about 2 seconds before sending anything to the Arduino. The opening of the serial interface resets the Arduino and it's waiting then on the serial interface for new sketches to be uploaded. If you wait 2 seconds before sending anything the bootloader ends it's work and gives control to your sketch which then can read your text and prints it to the printer.

Thanks for the reply. Doest this mean i should throw another delay() at the start of the loop?

Btw i had a semi success by submitting the words between single quotes. (ex: 'Lorem') But the printer doesn't always respond. Sometimes it prints out the words sometimes its not.

Is it some sort of overflow issue? Printing speed is rather slow as well. It could also be an encoding issue since putting the words between single quotes partially solves the problem.
Logged

Switzerland
Offline Offline
Faraday Member
**
Karma: 111
Posts: 5251
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Doest this mean i should throw another delay() at the start of the loop?

No, remove the delay() from loop(). You have to insert a delay at the start of your python prog just after opening the serial interface. A delay of 2 seconds is usually enough.

Quote
Is it some sort of overflow issue? Printing speed is rather slow as well. It could also be an encoding issue since putting the words between single quotes partially solves the problem.

As I don't know the type of printer you're using, I cannot tell. From your description that the printer prints something after you stop your python script I assumed it's the bootloader blocking because it gets serial traffic during it's code upload phase.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 14
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Guess i solved the problem by making the change in the arduino code:

Code:
Thermal.write(option);

to

Code:
Thermal.println(option);

The problem is with this way the printer prints out one char at a time and it put every char on a single line.

How can i put these chars in an array and form a sentence?
Logged

Switzerland
Offline Offline
Faraday Member
**
Karma: 111
Posts: 5251
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I guess you haven't solved the problem, you just introduced a new one. Thermal.write() puts out exactly one byte (character) while Thermal.println() writes the character and two more (carriage return and newline).

The next problem is that you're using SoftwareSerial with a not so low baud rate. If your printer is picky about serial timings it will get lots of errors because SoftwareSerial is not so exact in timings, especially if used in conjunction with the hardware serial (interrupts influence the timing).

Have you tried my proposed changes or are you just ignoring anything I write?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 14
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Have you tried my proposed changes or are you just ignoring anything I write?

Of course not. i've put
Code:
time.sleep(3)
before sending data to arduino in python. I also removed the delay() from arduino code.

While i get complete words this way, the printer doesn't always print out the data or i have to push couple of messages via serial to get them printed at the same time.

If i store the char's in an array and use println(Array) would it solve the problem?
Logged

Switzerland
Offline Offline
Faraday Member
**
Karma: 111
Posts: 5251
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

First try to comment out that line:

Code:
Serial.write(option);

Does that improve the printer responsibility?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 14
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

First try to comment out that line:

Code:
Serial.write(option);

Does that improve the printer responsibility?

sadly no.
Logged

Switzerland
Offline Offline
Faraday Member
**
Karma: 111
Posts: 5251
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Try this new loop():

Code:
#define BUFFER_SIZE 80

void loop() {
  char buffer[BUFFER_SIZE];
  uint8_t pos = 0;

  while(Serial.available() > 0 && pos < BUFFER_SIZE) {
    buffer[pos++] = Serial.read(); //Take a character from serial port and check what it is
  }
  if (pos > 0) {
    Thermal.write(buffer, pos);
    pos = 0;
  }
}

This way you collect the characters while the serial buffer has some available and write them out all in one step. This way the probability that the SoftwareSerial is interrupted by the reception of a byte on the hardware serial is lowered, the timing exactness is increased and you may be successful.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 14
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank you for your help pylon!

It prints almost instantly now. It also prints out whatever it reads from serial.

There's problem tho:
 
Code:
Thermal.write(buffer, pos);
Gives the famous:
Code:
invalid conversion from 'char*' to 'const uint8_t*'
I've tried to cast but didn't work.

I've removed the pos arg from the write function. It compiled without any problems and as i've mentioned printer reacted instantly. But now most of the letters are broken (replaced by other ASCII chars]

I've used print instead of write as well but again no luck.

Thanks again for your help.

Logged

Switzerland
Offline Offline
Faraday Member
**
Karma: 111
Posts: 5251
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

OK, then change the declaration:

Code:
uint8_t buffer[BUFFER_SIZE];

or change the write line to

Code:
Thermal.write((const uint8_t *)buffer, pos);

Both modifications should work. But you cannot remove the pos parameter!
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 14
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

OK, then change the declaration:

Code:
uint8_t buffer[BUFFER_SIZE];

or change the write line to

Code:
Thermal.write((const uint8_t *)buffer, pos);

Both modifications should work. But you cannot remove the pos parameter!

Thank you very much Pylon. I was trying to cast uint8 onto pos instead of buffer ^^

After the change the problems persisted until realizing that i've been sending the date w/o line ending. I did a test with Java serial monitor and saw that when i send the data with \n the printer would print everything perfectly and quickly.

So i've changed the line on python:
Code:
ser.write(message)
to:
Code:
ser.write(message+"\n")

Now everything's working as intended. Thanks again for your help and don't forget to drop me a line:

http://www.aerovisual.net/experiments/remoteprint/submit.php

Logged

Pages: [1]   Go Up
Jump to: