Dot matrix printer interpreting custom (any) escape sequences as text

I am trying to work on making a program for my selfmade dot matrix printer, but instead of it interpreting bytes 0x1b, 0x47 as switch to graphics mode, it prints them as text. I will provide the link to the Wokwi project which houses the code.

Since you seem to know about escape sequence of characters, are you using the correct character to identify an “escape”? What are you using? Should be the ASCII character for escape.

Have you created the driver to interpret the character stream?

I do want to use the escape character (want because it doesn’t work (unlike AutoHotKey)).

I want the provided Arduino code to interpret the stream of bytes

So fix it! You need to remember that you read an escape character so the very next character can be properly interpreted. And after that forget that you read an escape character.

So the code is the driver and it runs on an arduino. How is the printer connected, to what pins etc.

I don't see any code, post it in code tags after Auto Formatting it.
BTW, I don't do Wokwi.

Here's the code. Some comments are in Slovak. I'm sorry about that.


#include "storage.h"

// *Note: Don't use PROGMEM, because it'll make the code not get the proper values!!!

int lsindex = 0;  // index of read letter in template
int letpos = 0;
int pixpos = 0;
long steppos = 0;
unsigned char letter = 0;
unsigned char letter2 = 0;
byte pixval = 0;
String received = "";
byte cmsht = 29;
byte pmsht = 59;
byte stcpx = 27;
byte stppx = 61;
byte pxln = 9;
long lnfsa = 0;
char overflow = 0;
unsigned long nowtimemicros = 0;
unsigned long lastpulse = 0;
byte printmode = 0;  // defaults to text
byte pxpos = 0;

void setup() {

  DDRB = 255;
  PORTB = 0;

  pinMode(6, INPUT_PULLUP);   // koncový kalibračný spínač
  pinMode(A1, INPUT_PULLUP);  // posuv o 5mm von
  pinMode(A2, INPUT_PULLUP);  // posuv o 5mm dnu

  pinMode(2, OUTPUT);  // stepper 1 step
  pinMode(3, OUTPUT);  // stepper 1 dir
  pinMode(4, OUTPUT);  // stepper 2 step
  pinMode(5, OUTPUT);  // stepper 2 dir

  Serial.begin(76800);


  digitalWrite(3, LOW);
  while (digitalRead(6) == HIGH) {
    digitalWrite(2, HIGH);
    delayMicroseconds(125);
    digitalWrite(2, LOW);
    delayMicroseconds(125);
  }

  digitalWrite(3, HIGH);
  for (int s = 0; s < (stcpx * 26); s = s + 1) {
    digitalWrite(2, HIGH);
    delayMicroseconds(125);
    digitalWrite(2, LOW);
    delayMicroseconds(125);
  }

  delay(250);
  Serial.write(0x0A);  // tento riadok môžete vynechať
}

void loop() {
  while (!Serial.available()) {

    if (digitalRead(A1) == LOW) {
      delay(500);
      bplf();
    }
    if (digitalRead(A2) == LOW) {
      delay(500);
      bpluf();
    }
  }

  received = sstringr();

  for (int f = 0; f < received.length(); f = f + 1) {
    letter = received[f];
    letter2 = received[f + 1];

    if (printmode == 0) {
      if (letpos > 19) {
        letpos = 0;
        if (letter != 10 || letter != 13) {
          lnfsa = pxln * stppx;
          crlf();
          overflow = letter;
          dotmatrixtext(overflow);
        } else {
          lnfsa = pxln * stppx;
          crlf();
        }
      } else if (letter == 10) {
        letpos = 0;
        lnfsa = pxln * stppx;
        crlf();
      }

      else if (letter == 13) {
        letpos = 0;
        lnfsa = pxln * stppx;
        crlf();
      }

      else if (letter == 27) {
        if (letter2 == 'G') {
          printmode = 1; // graphics mode
        }
        if (letter2 == 'T') {
          printmode = 0; // text mode
        }
        if (letter2 == 'L') { // load paper to top margin
          pxln = 4;
          for (byte r = 0; r < 9; r = r + 1) {
            bplf();
          }
          pxln = 9;
        }
        if (letter2 == 'E') {
          for (byte r = 0; r < 20; r = r + 1) {
            bpluf();
          }
        }
      }
      else {
        dotmatrixtext(letter);
        letpos = letpos + 1;
      }
    }

    if (printmode == 1) {

      if (pixpos > 119) {
        lnfsa = pxln * stppx;
        crlf();
      }

      else {
        dotmatrixgraphics(letter);
      }

    }

  }

}

void dotmatrixgraphics(byte graphdat) {
  Serial.println("Graphics");

  for (byte b = 8; b-- > 0;) {
    if ((pixval >> b & 0x01) == 0) {
      Serial.print(' ');
    } else {
      Serial.print('#');
    }
  }
  Serial.println();

  for (byte y = 0; y < stcpx; y = y + 1) {
    steppos = steppos + 1;

    digitalWrite(2, HIGH);
    delayMicroseconds(cmsht);
    digitalWrite(2, LOW);
    delayMicroseconds(cmsht);

    if (y > 10) {
      PORTB = 0;
    }

    else {
      PORTB = graphdat;
    }
  }

}

void dotmatrixtext(unsigned char character) {
  Serial.println("Text");
  digitalWrite(3, HIGH);
  lsindex = (character - 32) * 6;
  for (byte i = 0; i < 6; i = i + 1) {
    pixval = 0;
    pixval = font[lsindex + i];
    pixpos = pixpos + 1;

    for (byte b = 8; b-- > 0;) {
      if ((pixval >> b & 0x01) == 0) {
        Serial.print(' ');
      } else {
        Serial.print('#');
      }
    }
    Serial.println();

    for (byte y = 0; y < stcpx; y = y + 1) {
      steppos = steppos + 1;

      digitalWrite(2, HIGH);
      delayMicroseconds(cmsht);
      digitalWrite(2, LOW);
      delayMicroseconds(cmsht);

      if (y > 10) {
        PORTB = 0;
      }

      else {
        PORTB = pixval;
      }
    }
  }
}

void crlf() {
  digitalWrite(3, LOW);
  digitalWrite(5, HIGH);
  while (steppos > 0) {
    steppos = steppos - 1;
    digitalWrite(2, HIGH);
    delayMicroseconds(cmsht);
    digitalWrite(2, LOW);
    delayMicroseconds(cmsht);
  }
  while (lnfsa > 0) {
    lnfsa = lnfsa - 1;
    digitalWrite(4, HIGH);
    delayMicroseconds(pmsht);
    digitalWrite(4, LOW);
    delayMicroseconds(pmsht);
  }
}

void bplf() {
  digitalWrite(5, HIGH);
  lnfsa = pxln * stppx;
  while (lnfsa > 0) {
    lnfsa = lnfsa - 1;
    digitalWrite(4, HIGH);
    delayMicroseconds(pmsht);
    digitalWrite(4, LOW);
    delayMicroseconds(pmsht);
  }
}

void bpluf() {
  digitalWrite(5, LOW);
  lnfsa = pxln * stppx;
  while (lnfsa > 0) {
    lnfsa = lnfsa - 1;
    digitalWrite(4, HIGH);
    delayMicroseconds(pmsht);
    digitalWrite(4, LOW);
    delayMicroseconds(pmsht);
  }
}

String sstringr() {
  Serial.write(0x13);
  char message = 0;
  String content = "";

  while (Serial.available()) {
    message = Serial.read();
    content += message;
  }

  if (content != "" && !Serial.available()) {
    Serial.write(0x11);
    return content;
  }
}

Problem is that I don’t know where it’s going wrong, despite me looking at it for a long time

The printer is connected to any USB device which is capable of sending any byte over a COM port. The printhead is driven by transistors, which are controlled by the port B of my standalone ATmega328P (uses internal 8MHz clock).

This is what the nested if statements are supposed to do. If letter is the esc character, then look at the next letter (unsigned char letter2) to see what is the command (E - eject paper, G - graphics mode, L - load paper, T - text mode)

I didn’t take the code rereading the letter of the command next iteration into account. I’ll try to fix that. But then why isn’t it doing what it’s told to via the esc sequences?

For up to date (near real time) code check the Wokwi project page provided in the first post. BEWARE: The code has some troubleshooting Serial.print() commands in it.

If you will begin to debug your code using serial.Print(), you will soon discover the error. Well, perhaps not. That is the most bizarre communications code I have ever seen! Good luck.

Thanks, I'll need it.

I can't do the troubleshooting in Wokwi (because it can't send the escape character as far as I'm aware), so I'll have to put tens of insertion cycles on the poor socket holding the ATmega in electrical contact.

It's been decades but shouldn't you be using UART NOT USB? The USB chip may change what you are sending, especially esc stuff. Try pins 1 and 2.

I use a USB to UART converter because my laptop doesn't have a UART port

Instead I'll try a diferrent character