From 6fc08fded2a365f028486d16133d5b1d338785af Mon Sep 17 00:00:00 2001 From: Mike Sizov Date: Mon, 17 Apr 2023 00:44:13 +0700 Subject: [PATCH] Add command for printing 4 shades of grayscale image. It works in a similar way as a monochrome print, but with few differences: 1. User needs to send 3 rows of color bitstrings for each image row. 2. Printer will stay in place while printing all 3 non-white 'colors', it will feed the paper each third line. 3. User must multiply height by 3. 4. Command is different: cmd[0] == ASCII_GS && cmd[1] == 118 && cmd[2] == 49 E.g. For image 200x200, user needs to send header with width 200, height 600. Image data is arranged the following way (fourth color is blank): 25 bytes (200bits) of 1st color for first row 25 bytes (200bits) of 2nd color for first row 25 bytes (200bits) of 3rd color for first row 25 bytes (200bits) of 1st color for second row 25 bytes (200bits) of 2nd color for second row ...etc... --- Code/thermal_printer/config.h | 3 +- .../thermal_printer/devterm_thermal_printer.c | 27 ++++++++ Code/thermal_printer/printer.c | 64 ++++++++++++++++++- Code/thermal_printer/printer.h | 1 + 4 files changed, 93 insertions(+), 2 deletions(-) diff --git a/Code/thermal_printer/config.h b/Code/thermal_printer/config.h index 7aaf19a..d08ee2f 100644 --- a/Code/thermal_printer/config.h +++ b/Code/thermal_printer/config.h @@ -167,12 +167,13 @@ #define PRINT_STATE 0 #define ESC_STATE 1 #define GET_IMAGE 2 +#define GET_GRAY_IMAGE 3 #define ALIGN_LEFT 0 #define ALIGN_CENTER 1 #define ALIGN_RIGHT 2 -#define IMAGE_MAX 9224 +#define IMAGE_MAX (9224*64) #define BITS8 8 diff --git a/Code/thermal_printer/devterm_thermal_printer.c b/Code/thermal_printer/devterm_thermal_printer.c index 0a0909e..867d8f4 100644 --- a/Code/thermal_printer/devterm_thermal_printer.c +++ b/Code/thermal_printer/devterm_thermal_printer.c @@ -683,6 +683,23 @@ void parse_cmd(CONFIG *cfg, uint8_t *cmd, uint8_t cmdidx) { cmd_idx = 0; ser_cache.idx = 0; } + // GS v 1 p wL wH hL hH d1…dk + if (cmd[0] == ASCII_GS && cmd[1] == 118 && cmd[2] == 49) { + uint16_t width = cmd[4] + cmd[5] * 256; + uint16_t height = cmd[6] + cmd[7] * 256; + uint16_t k; + k = width * height; + if (k <= IMAGE_MAX) { + cfg->state = GET_GRAY_IMAGE; + cfg->img->num = k; + cfg->img->idx = 0; + cfg->img->width = width; + cfg->img->need_print = 1; + } + // do not reset_cmd() + cmd_idx = 0; + ser_cache.idx = 0; + } } } @@ -700,6 +717,16 @@ void parse_serial_stream(CONFIG *cfg, uint8_t input_ch) { reset_cmd(); cfg->state = PRINT_STATE; } + } else if (cfg->state == GET_GRAY_IMAGE) { + cfg->img->cache[cfg->img->idx] = input_ch; + cfg->img->idx++; + if (cfg->img->idx >= cfg->img->num) { // image full + if (cfg->img->need_print == 1) { + print_gray_image8(cfg); + } + reset_cmd(); + cfg->state = PRINT_STATE; + } } else if (cfg->state == ESC_STATE) { cmd[cmd_idx] = input_ch; cmd_idx++; diff --git a/Code/thermal_printer/printer.c b/Code/thermal_printer/printer.c index 7c09058..2ccf646 100644 --- a/Code/thermal_printer/printer.c +++ b/Code/thermal_printer/printer.c @@ -340,7 +340,7 @@ void print_dots_8bit(CONFIG *cfg, uint8_t *Array, uint8_t characters, while (y < STB_NUMBER) { - while (i < 10) { + while (i < cfg->density) { digitalWrite(STBx[y], HIGH); delayus(HEAT_TIME + cfg->density * 46); @@ -837,6 +837,68 @@ uint8_t print_image8(CONFIG *cfg) { return rv; } +uint8_t print_gray_image8(CONFIG *cfg) { + + uint16_t height; + uint16_t x, y, addr; + + uint8_t rv; + uint8_t LinePixels[MAXPIXELS]; + + uint8_t maxchars = PRINTER_BITS / 8; + height = cfg->img->num / cfg->img->width; + y = 0; + addr = 0; + // gray print uses 4 colors with following convention + // 3N+0th line has cfg->density/4 + // 3N+1th line has cfg->density/2 + // 3N+2th line has cfg->density + // white pixels should be unset in all 3 lines + uint8_t density = cfg->density; + uint8_t feed_pitch = cfg->feed_pitch; + rv = IsPaper(); + ENABLE_VH; + while (y < height) { + x = 0; + while (x < cfg->img->width) { + addr = x + y * cfg->img->width; + + if (cfg->img->revert_bits > 0) // LSB + LinePixels[x] = invert_bit(cfg->img->cache[addr]); + else + LinePixels[x] = cfg->img->cache[addr]; + + x++; + } + rv = IsPaper(); + if (rv == IS_PAPER) { + if (y % 3 == 0) { + cfg->density = density / 4; + cfg->feed_pitch = 0; + } + if (y % 3 == 1) { + cfg->density = density / 2; + cfg->feed_pitch = 0; + } + if (y % 3 == 2) { + cfg->density = density; + cfg->feed_pitch = feed_pitch; + } + print_dots_8bit_split(cfg, LinePixels, x); + delayus(HEAT_TIME*2); + } + y++; + } + cfg->img->need_print = 0; + + cfg->img->num = 0; + cfg->img->idx = 0; + cfg->img->width = 0; + DISABLE_VH; + + return rv; +} + void print_cut_line(CONFIG *cfg) { uint8_t bs, i; diff --git a/Code/thermal_printer/printer.h b/Code/thermal_printer/printer.h index 7cc9344..3d3bae8 100644 --- a/Code/thermal_printer/printer.h +++ b/Code/thermal_printer/printer.h @@ -37,6 +37,7 @@ uint8_t print_lines8(CONFIG *,int,int); uint8_t invert_bit(uint8_t a); uint8_t print_image8(CONFIG *); +uint8_t print_gray_image8(CONFIG *); void print_cut_line(CONFIG *); void printer_set_font_mode(CONFIG *cfg, int);