Controlling Thermal printer through Arduino

Hello,

Im trying to print bitmaps with a thermal printer (the adafruit one) that is connected through an Arduino.

It is for a project called selfiemachine. It is a scanner camera (also controlled through OF) that uploads it’s output instantly to http://selfiemachine.epoxys.nl . The arduino was used to control the OF program. I’d like to add the printer for direct output instead of only a download of the selfie.

It’s not working though; the prints look glitched and even when i try to print vertical blocks of black / manual input throught the serial monitor it seems to shift everything to the right.

code in OF:

	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:

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;
       
    }
  }
  
  
}

I guess there is something wrong with converting pixels to sendable data or the way of sending it.

(Using Windows7 x64, Visual Studio Express 2012 and the latest OF)

Original

Print

I think if you were explaining with words what your nested loop is supposed to do people might have a better chance to help you.

And a quick thought : what is the type of pixels imageOut is holding ? If it’s RGB or RGBA pixels[i] might not be what you think it is.

hey is already an addon for interfacing with them by the amazing @patricio!

@silverbahamut: Its after dithering and it’s grayscale. Pixels[i] gave the same print as ofImage.getBrightness().

This is based on a processing sketch from the library provided by adafruit: https://github.com/adafruit/Adafruit-Thermal-Printer-Library . This one is writing a header file for the arduino containing a bitmap 8 pixels represented in one byte.

I did the same, it writes to a file only to check what im sending. Im trying to send sum to the arduino at once.

@theDANtheMAN: I looked at it, but it’s for OSX/linux (?) The above is half processing sketch / @patricio 's work.

I think there is win support…the library has a bunch of windows #defines for adding in different headers… I think the example is just Linux/OSX

1 Like

It compiled when i changed the following stuff:

  • including math.h
  • including windows.h
  • including
  • changing paths
  • changing uint8_t data[rowBytesClipped];
    to
  • adding [code] void ofxThermalPrinter::usleep(DWORD waitTime){
    LARGE_INTEGER perfCnt, start, now;

    QueryPerformanceFrequency(&perfCnt);
    QueryPerformanceCounter(&start);

    do {
    QueryPerformanceCounter((LARGE_INTEGER*) &now);
    } while ((now.QuadPart - start.QuadPart) / float(perfCnt.QuadPart) * 1000 * 1000 < waitTime);
    }[/code] which seems to be an alternative to usleep on windows :expressionless:

As an empty program it compiles alright but when i start using ofxThermalPrinter the program breaks on startup. I think the fault is in serial.cc and i cant think of a solution.

selfieMachineThermalPrinter_debug.exe!serial::Serial::SerialImpl::flushOutput() Line 442 C++

Serial::SerialImpl::flushOutput () { THROW (IOException, "flushOutput is not supported on Windows."); }

Any ideas to solve this problem?

SOLVED:

Just removed flushOutput from setup, it was not used in ofxThermalPrinter besides the setup. Either change baudrate of arduino serial.begin to 19200 or ofxThermalPrinter BAUDRATE to 9600

Arduino:

SoftwareSerial printer(printer_RX, printer_TX);

void setup(){
  Serial.begin(9600);
  printer.begin(19200);
  
}
void loop(){
  if(Serial.available()>0){
    printer.write((uint8_t)Serial.read());
  }
  
}

I have to stop the Arduino from resetting upon connecting and then it will work fine this way. Thanks alot @patricio :slight_smile:

1 Like