Decoding stream containing hex-values received on Serial port.

Hi!

I'm working on hacking the remains of a thermal label-printer at the moment.
Brother didn't publish any usable drivers for this ancient P-touch label printer, so i decided to take it apart and 'improve' it. I've replaced electronics with Arduino and can print text/graphics from arrays in my code.

Now, to make it a tiny bit more usable, i want to be able to send an image via serial to be printed.

For now i've settled to the XBM file-format which GIMP can produce. It is quite straight forward.

Here is an example of what a file with a 16x16 pixel array would look like:

#define 16x16_width 16
#define 16x16_height 16
static unsigned char 16x16_bits[] = {
   0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

The plan was just to send the image as a text file via serial terminal emulator.

The printhead has 128 elements across it's whole width and i think that sending a 128 pixel wide image every time is the easiest way to cope with different media. Then it's up to me to place the graphics i want printed, in the right spot in the file. So every time i transmit data to the printer, i will send 128 pixels wide (16 bytes) and as long as i want, until the file terminates with the }-character.

So i need a piece of code that keeps watching the serial port. When it encounters the { it gets ready to receive the data. I want to read the incoming data into an array with 16 bytes.

I've tried many different approaches for the last couple of hours but i always come up with something that doesn't work or simply gets out of hand (nested switch/case into eternity)

Some of my crap code which isn't working:

byte dataArray [16] = {0};
byte runstate = 0;
char inData = 0;
byte byteCounter = 0;

void setup() {
  Serial.begin(9600);
}

void loop() {
  switch (runstate) {
    case 0: // First byte has not been seen in the serial buffer yet.
      if (Serial.available() > 0) {
        inData = Serial.read();
        if (inData == '{')  // First sign in data packet has been recognised. Set runstate = 1 to continue decoding.
          runstate = 1;
        break;
      }
    case 1:
      inData = Serial.read();
      if (inData != 'x')  // If received sign is not 'x' (in 0x... then read next byte, loop another round and check again)
      {
        inData = Serial.read();
      }
      else if (inData == 'x') 
        runstate = 2; // x as been found in serial string. Set runstate = 2 to start decoding first digit of hex-number.
      break;
    case 2:
      inData = Serial.read();
      switch (inData) {
        case '0':
          dataArray[byteCounter] = 0x0;
          runstate = 3;
          break;
        case '1':
          dataArray[byteCounter] = 0x10;
          runstate = 3;
          break;
        case '2':
          dataArray[byteCounter] = 0x20;
          runstate = 3;
          break;
        case '3':
          dataArray[byteCounter] = 0x30;
          runstate = 3;
          break;
        case '4':
          dataArray[byteCounter] = 0x40;
          runstate = 3;
          break;
        case '5':
          dataArray[byteCounter] = 0x50;
          runstate = 3;
          break;
        case '6':
          dataArray[byteCounter] = 0x60;
          runstate = 3;
          break;
        case '7':
          dataArray[byteCounter] = 0x70;
          runstate = 3;
          break;
        case '8':
          dataArray[byteCounter] = 0x80;
          runstate = 3;
          break;
        case '9':
          dataArray[byteCounter] = 0x90;
          runstate = 3;
          break;
        case 'A':
          dataArray[byteCounter] = 0xA0;
          runstate = 3;
          break;
        case 'B':
          dataArray[byteCounter] = 0xB0;
          runstate = 3;
          break;
        case 'C':
          dataArray[byteCounter] = 0xC0;
          runstate = 3;
          break;
        case 'D':
          dataArray[byteCounter] = 0xD0;
          runstate = 3;
          break;
        case 'E':
          dataArray[byteCounter] = 0xE0;
          runstate = 3;
          break;
        case 'F':
          dataArray[byteCounter] = 0xF0;
          runstate = 3;
          break;
      }
    case 3: // Runstate = 3 = Decode second digit of received hex-number. Set runstate = 4 to advance decoding.
      inData = Serial.read();
      switch (inData) {
        case '0':
          dataArray[byteCounter] = dataArray[byteCounter] | 0x0;
          runstate = 4;
          break;
        case '1':
          dataArray[byteCounter] = dataArray[byteCounter] | 0x01;
          runstate = 4;
          break;
        case '2':
          dataArray[byteCounter] = dataArray[byteCounter] | 0x02;
          runstate = 4;
          break;
        case '3':
          dataArray[byteCounter] = dataArray[byteCounter] | 0x03;
          runstate = 4;
          break;
        case '4':
          dataArray[byteCounter] = dataArray[byteCounter] | 0x04;
          runstate = 4;
          break;
        case '5':
          dataArray[byteCounter] = dataArray[byteCounter] | 0x05;
          runstate = 4;
          break;
        case '6':
          dataArray[byteCounter] = dataArray[byteCounter] | 0x06;
          runstate = 4;
          break;
        case '7':
          dataArray[byteCounter] = dataArray[byteCounter] | 0x07;
          runstate = 4;
          break;
        case '8':
          dataArray[byteCounter] = dataArray[byteCounter] | 0x08;
          runstate = 4;
          break;
        case '9':
          dataArray[byteCounter] = dataArray[byteCounter] | 0x09;
          runstate = 4;
          break;
        case 'A':
          dataArray[byteCounter] = dataArray[byteCounter] | 0x0A;
          runstate = 4;
          break;
        case 'B':
          dataArray[byteCounter] = dataArray[byteCounter] | 0x0B;
          runstate = 4;
          break;
        case 'C':
          dataArray[byteCounter] = dataArray[byteCounter] | 0x0C;
          runstate = 4;
          break;
        case 'D':
          dataArray[byteCounter] = dataArray[byteCounter] | 0x0D;
          runstate = 4;
          break;
        case 'E':
          dataArray[byteCounter] = dataArray[byteCounter] | 0x0E;
          runstate = 4;
          break;
        case 'F':
          dataArray[byteCounter] = dataArray[byteCounter] | 0x0F;
          runstate = 4;
          break;
      }
   case 4:
   byteCounter++;
   runstate = 1;
  }

  Serial.print(runstate);
  Serial.print(" ");
  Serial.println(dataArray[0], HEX);
  Serial.print("  ");
  Serial.println(dataArray[1], HEX);
  Serial.print("  ");
  Serial.println(dataArray[2], HEX);

  if (byteCounter >= 15)
  {
    Serial.print("END!");
    while(1);
    }
}

I think the right way would be to read the data into a string and then process it, but what do i do when the arriving data can be such big amount of data? The Arduino doesn't have enough RAM for receiving even a 128x128 pix image.

Please guide me in the right direction. Programming isn't my forte - electronics is.
// Per.

Here's everything you need to know: Serial Input Basics - updated

This post might help;
https://forum.arduino.cc/index.php?topic=504105.msg3445632#msg3445632

Maybe you are making this more complicated than it needs to be.

Think of each printing ASCII character as representing 4 bits or pixels.

So storing an array of 32 characters would give you the data needed to print one line of 128 pixels (where the pixel is either on or off no colour).

So to print a line you just process the character array one character at a time and output the pixels to the printer;

‘0’ prints 0000

‘1’ prints 0001

‘2’ prints 0010

‘3’ prints 0011

‘4’ prints 0100

‘5’ prints 0101

‘6’ prints 0110

‘7’ prints 0111

‘8’ prints 1000

‘9’ prints 1001

‘A’ prints 1010

‘B’ prints 1011

‘C’ prints 1100

‘D’ prints 1101

‘E’ prints 1110

‘F’ prints 1111

You are using pecial characters to denote the beginning and end of the file.

Personally I would also include end of line characters after every 32 hex characters sent.

That will make looking at what is being sent and debugging your code much easier.

ardly:
Maybe you are making this more complicated than it needs to be.

Think of each printing ASCII character as representing 4 bits or pixels.

So storing an array of 32 characters would give you the data needed to print one line of 128 pixels (where the pixel is either on or off no colour).

Printing with the actual data i have under control. It works. I have an array with 16 bytes and they correspond to the bytes sent to the print head.

The reason that i cannot split up the received bytes into 4-bit packages is that the file i receive is one byte for the first 8 pixels and so on.

It's the interpretation of the serial string that is giving me problems. I can't realise it in my head how to do it elegantly.

// Per.

Zapro:
It's the interpretation of the serial string that is giving me problems. I can't realise it in my head how to do it elegantly.

Can you post an example of the serial data that the Arduino actually receives?

...R

Robin2:
Can you post an example of the serial data that the Arduino actually receives?

...R

I did, in the first post.

Here's a link to the actual file.

// Per.

Zapro:
I did, in the first post.

Not that I can see.

But maybe the array you have defined in your OriginalPost is a proxy for the data. If so, and if (for illustration) we assume all the values happen to be printable characters the data would look like ABCDEFGH.......... for 32 values

Then, it seems to me the first line of your image uses the data in AB, the second line uses CD etc
For further clarification AB is the bits 0100 0001 0100 0010
The characters AB are also the hex values 0x41 0x42 - which is what @ardly was illustrating in Reply #3

Having said all that, if you are still confused please tell us what it is that is confusing you.

...R

Yes, he did, the file format is useable as a C source file. The start and end markers important to the printer are { and }. Somewhat inefficient, but it seems appropriate for this printer.

Zap, it's already split into 4-bit packages. The hex digits each encode 4 bits like Robin said.

Well I'll be; "XBM files differ markedly from most image files in that they take the form of C source files".

I was not expecting that!

Importantly "If the image width does not match a multiple of 8, the extra bits in the last byte of each row are ignored".

If it would change anything, i might change specifications and go for a .BMP file sent to the Arduino instead. It is not written as ASCII afterall, but contains the raw bytes.

// Per.

Zapro:
If it would change anything, i might change specifications and go for a .BMP file sent to the Arduino instead. It is not written as ASCII afterall, but contains the raw bytes.

Why?

The format you are currently trying to work with seems very simple.

...R

Robin2:
Why?

The format you are currently trying to work with seems very simple.

...R

I don't know. I'm a hardware guy and i would love to do this in hardware if i could.

I've looked into the examples on the link that i got in first response.

Last example seems to be what i'm looking after, but i'm having this issue that i will only have one start marker, then a variable amount of data, and then one stop marker.

The printhead is 128 pixel wide so i will be sending the printer a 128x"somethingbig", so putting the data into an array won't work like shown in the example. If i create an array of 2048bytes i would be able to print a square label - done.

Now i will look at the example code, and try to change it so it reads in 16 bytes, prints a line, reads the next 16 etc. until it will see the end marker, which will stop the printing and actuate the label cutter.

Is there any elegant way of turning e.g. 0xAA received in ascii and stuff it into my array? I'm wondering that.

// Per.

Zapro:
The printhead is 128 pixel wide so i will be sending the printer a 128x"somethingbig", so putting the data into an array won't work like shown in the example. If i create an array of 2048bytes i would be able to print a square label - done.

You need to make a good attempt at writing the code and then post it if it does not work. That way we will be able to understand better how your mind is approaching the problem.

It seems to me all you need to so is send the 16 bytes to the printer one after the other. The only complexity is what order it expects to receive the data. But a little trial and error should sort that out. If it is a Serial connection to the printer then something like this should do it

for (byte n = 0; n < 16; n++) {
  Serial.write(16x16_bits[n]);
}

By the way creating variable names only with digits makes things very confusing

...R

Hi. I see that i expressed myself wrong. I am not sending data to a printer with the Arduino.

I have the printer mechanics from a dead Brother P-touch label printer (PT-2500PC). The electronics is defunct and close source. I made some new electronics that can drive the stepper, DC-motor and printhead. This is connected to my Arduino.

I am /not/ in control of how my received data looks like. I simply make a new image in software like GIMP/Paint/Whatever and save it as an BMP, or what might be simpler to use, XBM.

The plan was to simply open up a serial terminal emulator on the computer and send the image file off as an textfile. Then it would be transmitted byte-for-byte for the Arduino to interpret.

The code i am using to send data off to the printhead is this. It behaves like a shift register.

void sendBytes(byte bits) {

 for (int i = 0; i < 16; i++)
 {
   shiftOut(DATA, CLOCK, MSBFIRST, bits);
 }
 digitalWrite(LATCH, LOW);
 digitalWrite(LATCH, HIGH);

 delay(1);
 digitalWrite(STROBE, LOW);
 delayMicroseconds(2000);
 digitalWrite(STROBE, HIGH);
}

And here's how the printhead works, electrically:

Does it make any more sense now?

Zapro:
Does it make any more sense now?

Yes and no.

That code snippet seems to send the same byte 16 times - why would you do that?

And the latch and strobe stuff seems to be unconnected to the shiftOut() - is that intentional? If so why?

In any case, it seems to me that the code I suggested is still generally relevant except that your sendBytes() function would substitute for Serial.write(). And I suspect your sendBytes() function should be sendByte() - singular

...R

OK. To clarify what's going on, i will post my test program here. I will print a QR-code on the tape when a switch is pressed and hold. It's only for testing the hardware, nothing else. No serial-receive is going on.

#define POW_ON  5
#define MOT_A   3
#define MOT_B   2
#define MOT_PWR 4
#define CUT_A   6
#define CUT_B   7
#define CUT_SW  8

#define FEED_SW A3
#define LED A4

#define DATA 11
#define CLOCK 13
#define LATCH 9
#define STROBE A0

byte state = 0;
byte inversion = 0;
int counter = 0;
byte line = 0;


//Byte array of bitmap of 128 x 49 px:
byte img2 [] = { 
0xfe, 0x49, 0xbe, 0x8c, 0xf4, 0xbf, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x82, 0x5, 0xa6, 0x86, 0xdf, 0xa0, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0xba, 0x8e, 0xed, 0x93, 0x61, 0xae, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0xba, 0x65, 0x1c, 0x76, 0x5, 0x2e, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0xba, 0x3f, 0x43, 0xf3, 0xe8, 0x2e, 0x80, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x82, 0x55, 0x8e, 0x26, 0x36, 0x20, 0x80, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfe, 0xaa, 0xaa, 0xaa, 0xaa, 0xbf, 0x80, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa0, 0xd6, 0x20, 0x49, 0x80, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xef, 0xa7, 0x6f, 0xff, 0xca, 0xe2, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x60, 0x4e, 0x1, 0x7, 0x10, 0x4b, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x86, 0xa4, 0x46, 0x78, 0xb1, 
0x47, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x60, 0x27, 0x39, 0xd5, 
0xc7, 0xdb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6a, 0x15, 0xb9, 
0xdb, 0x99, 0xb9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x91, 0x4d, 
0x22, 0x59, 0x48, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf7, 
0xd5, 0xb3, 0xaa, 0xc2, 0x9c, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x18, 0x17, 0x76, 0x64, 0x10, 0x6e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0xbb, 0xb6, 0xae, 0x2, 0x7f, 0x49, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0xd5, 0x36, 0x35, 0x9e, 0x81, 0x5f, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0xdf, 0xa3, 0x15, 0x9, 0x38, 0x4d, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x29, 0x39, 0xb1, 0x26, 0x6b, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x53, 0x7a, 0x85, 0x99, 0xc9, 0x8d, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x61, 0xc8, 0xff, 0x69, 0xdd, 0x37, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xdf, 0x9e, 0x7, 0xf0, 0x54, 0xff, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd8, 0xcc, 0xb2, 0x34, 0xb3, 0x8c, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xca, 0xa7, 0x76, 0xa0, 0x38, 0xa9, 
0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x58, 0xa7, 0x42, 0x35, 0x11, 
0x8f, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4f, 0xf5, 0x73, 0xf8, 
0xb9, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1d, 0x77, 0xf5, 
0x10, 0xff, 0x1a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe2, 0x6d, 
0x99, 0xbe, 0xd8, 0x96, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb9, 
0x7d, 0x75, 0x99, 0x81, 0xb4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0xc7, 0x39, 0x8d, 0x61, 0x3a, 0x2b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x1, 0x2d, 0x5b, 0xb4, 0x23, 0x14, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0xee, 0x8f, 0x66, 0x49, 0xbe, 0x8d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x24, 0x27, 0x43, 0x7, 0x58, 0x3b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0xd6, 0x4a, 0x3b, 0x5a, 0xc0, 0xe7, 0x80, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x50, 0x39, 0xde, 0x93, 0x3f, 0x55, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1a, 0xa, 0xae, 0xa9, 0xf8, 0x24, 0x80, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0xa8, 0xdc, 0xd9, 0x89, 0xd0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x46, 0xa4, 0x45, 0xf5, 0xc8, 0xaa, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x70, 0xea, 0xb0, 0xbd, 0x74, 0x88, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe2, 0x57, 0x63, 0xee, 0x4f, 
0xfb, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x87, 0x46, 0x25, 
0x49, 0x89, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfe, 0xfd, 0x86, 
0xb9, 0x5, 0xae, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x82, 0xee, 
0x4e, 0x3d, 0x48, 0x8c, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xba, 
0xfc, 0xeb, 0xfd, 0x9e, 0xfa, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0xba, 0x15, 0x9, 0xa1, 0xd9, 0x55, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0xba, 0xbc, 0xc5, 0xf8, 0x30, 0x9c, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x82, 0xb5, 0x1b, 0xa4, 0x5c, 0x75, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0xfe, 0xa6, 0xe6, 0xe6, 0x38, 0xa8, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0,
// PADDING!
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};

byte font [] = {0x7E, 0x11, 0x11, 0x11, 0x7E}; // A

byte framebuffer [16][16] = {0};  // Initialise array

void setup() {

for (byte i=0; i<16; i++)
{
  framebuffer [i][0] = 0B10101010;
  }

Serial.begin(9600);


  pinMode (POW_ON, OUTPUT);
  pinMode (MOT_A, OUTPUT);
  pinMode (MOT_B, OUTPUT);
  pinMode (MOT_PWR, OUTPUT);
  pinMode (CUT_A, OUTPUT);
  pinMode (CUT_B, OUTPUT);
  pinMode (CUT_SW, INPUT);
  pinMode (FEED_SW, INPUT);
  pinMode (LED, OUTPUT);

  pinMode (DATA, OUTPUT);
  pinMode (CLOCK, OUTPUT);
  pinMode (LATCH, OUTPUT);
  pinMode (STROBE, OUTPUT);

  pinMode (A5, INPUT);
  randomSeed(analogRead(5));

  digitalWrite(STROBE, HIGH);
  digitalWrite(LATCH, HIGH);
  digitalWrite(LED, HIGH);  // Active low


  digitalWrite (POW_ON, HIGH);  // Turn on SMPS boost
}

void step() {

  switch (state) {
    case 0:
      digitalWrite (MOT_A, LOW);  // State 0 on stepper
      digitalWrite (MOT_B, LOW);  // State 0 on stepper
      state++;
      break;
    case 1:
      digitalWrite (MOT_A, LOW);  // State 1 on stepper
      digitalWrite (MOT_B, HIGH);  // State 1 on stepper
      state++;
      break;
    case 2:
      digitalWrite (MOT_A, HIGH);  // State 2 on stepper
      digitalWrite (MOT_B, HIGH);  // State 2 on stepper
      state++;
      break;
    case 3:
      digitalWrite (MOT_A, HIGH);  // State 3 on stepper
      digitalWrite (MOT_B, LOW);  // State 3 on stepper
      state++;
      break;
  }
  if (state > 3) state = 0;
}

void sendBytes(byte bits) {

  for (int i = 0; i < 16; i++)
  {
    shiftOut(DATA, CLOCK, MSBFIRST, bits);
  }
  digitalWrite(LATCH, LOW);
  digitalWrite(LATCH, HIGH);

  delay(1);
  digitalWrite(STROBE, LOW);
  delayMicroseconds(2000);
  digitalWrite(STROBE, HIGH);
}

void sendBytes2(byte bits) {

  for (int i = 0; i < 16; i++)
  {
    shiftOut(DATA, CLOCK, MSBFIRST, framebuffer[i][line]);
    Serial.print(framebuffer[i][line]);
  }
  Serial.println("");

    
  digitalWrite(LATCH, LOW);
  digitalWrite(LATCH, HIGH);

  delay(1);
  digitalWrite(STROBE, LOW);
  delayMicroseconds(2000);
  digitalWrite(STROBE, HIGH);
}

void loop() {


  if (digitalRead(FEED_SW) == LOW)
  {
  digitalWrite (MOT_PWR, HIGH);  // Turn on Stepper Motor driver
  digitalWrite(LED, LOW);
  
  sendBytes2(0);
  line++;
  if (line == 59) line = 0;

  
  step();
  delayMicroseconds(8400);
  step();
  delayMicroseconds(8400);
  }
  else
  {
  digitalWrite(LED, HIGH);
  digitalWrite (MOT_PWR, LOW);  // Turn off Stepper Motor driver
    
    }

}

Attached is some parts of the service manual explaining how it all works.

// Per.

http://forum.arduino.cc/index.php?action=dlattach;topic=508609.0;attach=232038

Screen Shot 2017-11-02 at 23.31.58.png

Zapro:
OK. To clarify what's going on, i will post my test program here.

I'm sorry if this seems unkind but I am not prepared to give the time needed to learn all about the project you are trying to implement. Perhaps I'm lazy.

However if you can provide a succinct explanation of how the data in your Original Post needs to be manipulated in order to meet the requirements of your device I will try to help with the code.

In the code you posted in Reply #16 there is a function sendBytes2(). If that works for the data in that program, why won't it work for the data in your Original Post?

...R

I'm giving up.

Thank you for your kind help. I'll show myself out.

Zapro:
I'm giving up.

Pity.

It seems to me you already have most of the solution.

I wonder if you imagine that there must be a BIG COMPLEX answer to your problem, when in fact all that is needed is a small simple answer.

...R