SOLVED: Control thermal printer through openframeworks.

Hello,

Im trying to control a thermal printer connected to an arduino UNO through openframeworks. I'm trying to send bitmap data as rows over serial and then call printBitmap (adafruits library). The prints result in glitched images or a first line printed as text and then glitched image.

I thought it might be the data type or an error in the size of my buffer. I tried both and gave no different results. Then the error could be in the way i'm converting pixels to sendable data (which is based on the processing sketch from the adafruit github).

Some code and images (i'm not trying to print barcodes :wink: its a test image);

openFrameWorks

	int i = 0, x= 0, y = 0, b= 0, n= 0, rowBytes = 0, totalBytes = 0, lastBit = 0;
	unsigned char sum = 0;
	ofPixels pixelArray = imageOut;
	unsigned char * pixels = pixelArray.getPixels();
	

	rowBytes   = (imageOut.getWidth()) / 8;
	totalBytes = rowBytes * imageOut.getHeight();

	

	for(i=n=y=0; y<imageOut.getHeight(); y++) { // Each row...
		tempOutputFile << "\n  ";
		for(x=0; x<rowBytes; x++) { // Each 8-pixel block within row...
		  lastBit = (x < rowBytes - 1) ? 1 : (1 << (int)(rowBytes * 8 - imageOut.getWidth()));
		  sum     = 0; // Clear accumulated 8 bits
		  for(b=128; b>=lastBit; b >>= 1) { // Each pixel within block...
			  int hex = pixels[i++];
			  if((hex & 1) == 0) sum |= b; // If black pixel, set bit
		  }
		  tempOutputFile << sum; // Write accumulated bits
		  arduino.writeByte(sum);

		  if(++n < totalBytes);
		}
	}

Arduino

#define MODE_NORMAL 1
#define MODE_PRINTING 2

#include "SoftwareSerial.h"
#include "Adafruit_Thermal.h"

int printer_RX = 5;
int printer_TX = 6;
int programMode = MODE_NORMAL;

char readChar;
String readBuffer = "";

byte printBuffer[48];
int bufferCount = 0;

Adafruit_Thermal printer(printer_RX, printer_TX);

void setup(){
  Serial.begin(9600);
  printer.begin();
  
  //Call wake() before printing, sleeping after printing again
  //printer may stay hot otherwise.
  printer.sleep();
  
  
}
void loop(){
  if(programMode == MODE_NORMAL){
    while(Serial.available()){
      readChar = Serial.read();
      readBuffer.concat(readChar);
    }
    
    if(readBuffer == "PRINT"){
      Serial.println("OK");
      readBuffer = "";
      
      programMode = MODE_PRINTING;
    }

  }
  if(programMode == MODE_PRINTING){
    if(Serial.available() > 0){
      printBuffer[bufferCount] = Serial.read();
      bufferCount++;
    }
    if(bufferCount == 47){
       printer.printBitmap(384,1,printBuffer,false);
       bufferCount = 0;

    }
  }
  
  
}

This is on Windows x64, latest oF version.

tester.jpg

		tempOutputFile << "\n  ";

On the receiver, where are you accounting for having sent this crap?

Only arduino.WriteByte(sum) is sending to the Arduino. tempOutputFile is a file, as the name suggests i'm writing a txt file to check te output of that part of the program; \n to check that im actually writing 48 bytes to the Arduino.

Skuuf:
Only arduino.WriteByte(sum) is sending to the Arduino. tempOutputFile is a file, as the name suggests i'm writing a txt file to check te output of that part of the program; \n to check that im actually writing 48 bytes to the Arduino.

Yeah, OK, I see that now. What is this:

		  if(++n < totalBytes);

doing?

      printBuffer[bufferCount] = Serial.read();
      bufferCount++;
    }
    if(bufferCount == 47){
       printer.printBitmap(384,1,printBuffer,false);

After writing a byte to the array, you increment bufferCount. The value after writing in printBuffer[47] is 48. The if test then looks to be off by 1.

I don't know what the first two arguments to the printBitmap() method are. I'm assuming that you know that they are right.

I solved this issue by using ofxThermalPrinter addon for openFrameWorks. Instead of including the adafruit library on the Arduino i use SoftwareSerial.h.

if(Serial.available()>0){
        printer.write((uint8_t)Serial.read());
        printerReadCount++;
}

I disabled auto-reset on the arduino with a 10 uF capacitor for switching between Serial and ofxThermalPrinter library without resetting the Arduino.

NOTE: ofxThermalPrinter needs to be edited in order to work on Windows (Controlling Thermal printer through Arduino - #7 by Epoxis - advanced - openFrameworks)