Impresora térmica serial con PsoC4 4200

Hola hoy veremos como controlar una impresora térmica serial. Por medio de el Psoc4 4200. Este tutorial nos permitirá explorar los distintos comandos necesarios para poder hacer algunos cambios en el comportamiento de la impresora. 

Estas impresoras son muy fáciles de controlar con arduino y la libreria thermalprinter.h de adafruit. Pero como para psoc no tenemos Libreria me propuse escribir un programa que  permita controlar funciones como la impresión de códigos de barra, texto subrayado, negrita, alineación de texto y configuracion. 

Para poder conectar estas impresoras térmicas tenemos que utilizar una conexión serial, para esto haremos uso del módulo UART [2.50] de psoc creator y asignaremos 2 pines para el puerto serie. A este modulo lo configuraremos en 9600 baudios ya que la impresora que tengo funciona a esa velocidad, aunque hay otras versiones que funcionan a 19600. 

Para la conexión serial con la impresora térmica, yo voy a utilizar el pin 1 del puerto 0 este pin sera el TX o pin de transmisión y para el pin de recepción usare el pin 2 del puerto 0. 

Además tendremos que conectar el pin gnd de la impresora a el pin gnd de nuestro psoc. 

Para alimentar la impresora yo utilizo los 5 volts de una fuente atx de pc. Estas impresoras necesitan por lo menos una fuente de 2 amperes para poder funcionar correctamente. Y el voltaje de alimentación puede ser desde 5 volts hasta 9 volts. 

Para comenzar con nuestro proyecto tendremos que crear un nuevo proyecto en psoc Creator, arrastramos los componentes como se ven en la siguiente imagen. esquemático impresora termica psoc creator

esquemático psoc creator

Vamos a utilizar para la comunicación con la impresora un modulo  UART [2.50], 

para este modulo vamos a necesitar ademas un 0 lógico conectado a su pin reset, y una interrupción o modulo isr, conectado al pin RXinterrupt. 

Luego configuramos este modulo como se ve en la imagen: 

 

Ademas como queremos enviar texto para ser impreso a travez de una pc, vamos a agregar un modulo UART (SCB mode), y lo configuramos como se ve en las siguientes imágenes. 

Ademas de esto vamos a utilizar el botón on board de la placa para disparar una impresión. 

Agregamos un pin de entrada digital y lo configuramos como se ve en la siguiente imagen.

digital input pin psoc4

No olvidar agregar y configurar el modulo Bootloadable, esto ya se vio en tutoriales anteriores. 

Con esto ya tenemos listo nuestro esquemático, ahora nos vamos a la pestaña pines y configuramos como se ve en la siguiente imagen. 

Ahora llega el turno del código fuente nos vamos al main.c y copiamos y pegamos el siguiente código fuente : 

/*
 Control de una impresora termica serial con psoc4
*/
#include "project.h"
// funciones
void initPrinter(); //configura la impresora
void printConfig(); // imprime pagina de configuracion
void printBarCode(char *text, int tipo); // imprime un codigo de barras
void resetPrinter(); // resetea la impresora
void feed(int l);  // avance de papel "l" lineas
void printAndFeed(int l); // imprime el contenido del buffer y avanza "l" lineas
void deftLnSpace(); // selecciona el espacio entre lineas por defecto
void setLnSpace(int s); // establece el espacio entre lineas por defecto 30
void setAlgnMode(int n); // establece el modo de alineacion Default is 0
void printBold(char *text);  // imprime texto en negrita
void printBoldFont(char *text); // selecciona fuente negrita
void printSub(char *text, int pixels); // texto subrayado
void invertido(char *text);  // color invertido
void printGrande(char *text); // texto grande
void printNormal(char *text); // normal
// variables
char printDensity = 15; // densidad de impresion
char printBreakTime = 15; // timepo de espera 
int heatTime = 80;
int heatInterval = 255;
char datoRecibidoPC;
char datoRecibidoPrint;
int zero = 0;

CY_ISR(interruptRX){
  datoRecibidoPrint = SERIAL_GetByte();
   if(0u != datoRecibidoPrint){UART_UartPutChar(datoRecibidoPrint);CyDelay(10);}

}



int main(void)
{
    CyGlobalIntEnable; // habilitamos las interrupciones globales
    SERIAL_Start(); // inicamos puerto Serie impresora
    UART_Start();  // habilitamos puerto serie usb PC
    isr_RXPrint_StartEx(interruptRX); // interrupcion recepcion impresora
    initPrinter(); // inicia y configura la impresora termica
    CyDelay(1000); // delay inicalizacion
    
    setAlgnMode(0); // alineacion a la derecha
    printNormal("PsoC4 4200 < izq"); // imprime texto noraml
    feed(2); // avanza 3 lineas
    setAlgnMode(1);  // alineacion centrado
    printBold("> PsoC4 centrado y negrita < "); // imprime negrita
    feed(2); 
    setAlgnMode(2);  // alineacion derecha
    printSub("der y sub > PsoC4 4200", 3); // texto subrayado
    feed(2);
    setAlgnMode(0); 
    invertido(" PSOC4 4200  INV"); // imprime color invertido
    feed(2);
    printBoldFont(" Fuente Negrita "); // selecciona fuente negrita
    feed(2);
    printGrande("PSOC 4 GRANDE"); // imprime texto grande
    feed(2);
    printBarCode("111234567890", 0); // imprime codigo de barras
    
    
    for(;;){
       
      datoRecibidoPC = UART_UartGetChar();
      // leemos un caracter desde el puerto serie usb
      // si no es nulo lo enviamos a la impresora
     if(0u != datoRecibidoPC){
                               UART_UartPutChar(datoRecibidoPC);
                               SERIAL_PutChar(27);
                               SERIAL_PutChar(69);
                               SERIAL_PutChar(1);
                               SERIAL_PutChar(datoRecibidoPC);CyDelay(10);} 
    if(Boton_Read() == 0){
        setAlgnMode(1);
        printGrande("*************");
        feed(1);
        printGrande(" TEXOLAB.NET "); // imprime texto grande
        feed(1);
        printGrande("*************");
        feed(3);
        CyDelay(1000);}
    
    } 
    
    
}


void initPrinter(){
    //Modificamos la velocidad de impresion y la temperatura
    // datasheet 27 55 n1 n2 n3
    // n1 = 0-255 Max Printing Dots, Unit (8dots), Default:7(64 dots)
    // n2 = 3-255 Heating time, Uint(10us), Default:80(800us)
    // n3 = 0-255 heating interval, Unit(10us), Default:2(20us)
   
    SERIAL_PutChar(27);  // comandos de configuracion
    SERIAL_PutChar(55);
    SERIAL_PutChar(7); // n1
    SERIAL_PutChar(heatTime); // n2
    SERIAL_PutChar(heatInterval); // n3
    SERIAL_PutChar(18); // Configuracion de la densidad de impresion y tiempo de espera
    SERIAL_PutChar(35);
    int printSetting = (printDensity<<4) | printBreakTime;
    SERIAL_WriteTxData(printSetting); //Combinación de  printDensity y printBreakTime
    
}

void printConfig(){
SERIAL_PutChar(18);  // imprime configuracion
SERIAL_PutChar(84);
}

void resetPrinter(){
SERIAL_PutChar(27);//resetea la impresora
SERIAL_PutChar(64);// establece los valores por defecto
}

void printBarCode(char *text, int tipo){ //imprime codigo de barras
feed(1); // los nuevos firmwares no imprimen codigos de barra sin un feed previo
SERIAL_PutChar(29);
SERIAL_PutChar(72);
SERIAL_PutChar(50);  //50 = numeros debajo del codigo de barras
                     //48 = no imprime los numeros
                     //49 = numeros sobre el codigo de barras
                     //51 = numeros debajo y sobre el codigo de barras 
SERIAL_PutChar(29);
SERIAL_PutChar(104);
SERIAL_PutChar(100); // Alto del codigo de barras default 50 (1 a 255)

SERIAL_PutChar(29);  //comando de impresion del codigo de barras
SERIAL_PutChar(107);
SERIAL_PutChar(tipo); //Tipo de codigo de barras
                      //0 = UPC-A largo 11,12 digitos
                      //1 = UPC-E largo 11,12 digitos
                      //2 = EAN13 largo 12,13 digitos
                      //3 = EAN8  largo 7,8 digitos
                      //4 = CODE39 alfanumerico largo >1 espacio,$,%,+,-,.,/,del 0 al 9, de A a Z
                      //5 = I25 largo > 1     0 al 9
                      //6 = CODEBAR largo >1   $+-./: del 0 al 9 de A a D
                      //7 = CODE93 >1   0-127
                      //8 = CODE128 >1  0-127
                      //9 = CODE11 >1  del 0 al 9
                      //10 =  MSI >1 del 0 al 9 
int i = 0;
while(i < 12){ SERIAL_PutChar(text[i]); i++;  }
SERIAL_PutChar(zero); // final del codigo de barras
CyDelay(3000); // delay necesario
}

void feed(int l){  // avance de papel
    int i = 0;
   while(i < l){ SERIAL_PutChar(10); i++;}  
}

void printAndFeed(int l){ //imprime el contenido del buffer y avanza
    SERIAL_PutChar(27);   // "l" lineas
    SERIAL_PutChar(74);
    SERIAL_PutChar(l);
}

void deftLnSpace(){ // espacio entre lineas por defecto
SERIAL_PutChar(27);
SERIAL_PutChar(50); 
    
}

void setLnSpace(int s){// setea espacio entre lineas
SERIAL_PutChar(27);
SERIAL_PutChar(51);
SERIAL_PutChar(s); 
}

void setAlgnMode(int n){ // setea el modo de alineacion
 SERIAL_PutChar(27);
SERIAL_PutChar(97);
SERIAL_PutChar(n);    
}

void printSub(char *text, int pixels){ // imprime texto subrayado
    SERIAL_PutChar(27);
    SERIAL_PutChar(45);
    SERIAL_PutChar(pixels);
    int len = strlen(text);
    uint8_t i = 0;
    while(i<len) { SERIAL_PutChar(text[i]);i++;} 
    feed(1);
    SERIAL_PutChar(27);
    SERIAL_PutChar(45);
    SERIAL_PutChar(0);
    CyDelay(3000);
}

void printBold(char *text){ // imprime negrita
    SERIAL_PutChar(27);
    SERIAL_PutChar(69);
    SERIAL_PutChar(1);
    int len = strlen(text);
    uint8_t i = 0;
    while(i<len) { SERIAL_PutChar(text[i]);i++; }
    CyDelay(3000);
    SERIAL_PutChar(27);
    SERIAL_PutChar(69);
    SERIAL_PutChar(0);
    CyDelay(3000);
    
}

void printBoldFont(char *text){ // selecciona fuente negrita
    SERIAL_PutChar(27);
    SERIAL_PutChar(69);
    SERIAL_PutChar(1);
    SERIAL_PutChar(27);
    SERIAL_PutChar(32);
    SERIAL_PutChar(1);
    int len = strlen(text);
    uint8_t i = 0;
    while(i<len) { SERIAL_PutChar(text[i]);i++; }
    CyDelay(3000);
    SERIAL_PutChar(27);
    SERIAL_PutChar(32);
    SERIAL_PutChar(0);
    SERIAL_PutChar(27);
    SERIAL_PutChar(69);
    SERIAL_PutChar(0);
    CyDelay(3000);
    
}



void invertido(char *text){ // invertir color
SERIAL_PutChar(29);
SERIAL_PutChar(66);
SERIAL_PutChar(1); 
int len = strlen(text);
    uint8_t i = 0;
    while(i<len) { SERIAL_PutChar(text[i]);i++; }
    CyDelay(3000);
SERIAL_PutChar(29);
SERIAL_PutChar(66);
SERIAL_PutChar(0); //  normal
}

void printNormal(char *text){
int len = strlen(text);
    uint8_t i = 0;
    while(i<len) { SERIAL_PutChar(text[i]);i++; }
    CyDelay(3000);
}

void printGrande(char *text){
uint8  c = 0b00010001; // grande
SERIAL_PutChar(29);
SERIAL_PutChar(33);
SERIAL_WriteTxData(c);
int len = strlen(text);
    uint8_t i = 0;
    while(i<len) { SERIAL_PutChar(text[i]);i++; }
CyDelay(3000);
c = 0b00000000; // normal
SERIAL_PutChar(29);
SERIAL_PutChar(33);
SERIAL_WriteTxData(c);
}

Ahora solo resta cargar el código en nuestro psoc 4 y comprobar su funcionamiento. 

Al arrancar el programa configura la impresora y luego imprime una muestra de texto justificado, negrita, subrayado, color invertido, texto grande, una muestra de un código de barras. 

Ademas si presionamos el botón onboard de nuestra placa se imprime el nombre de nuestro blog TEXOLAB.NET.

Ademas de esto si conectamos nuestro psoc por medio del puerto usb a nuestra pc y haciendo uso de un terminal serial (en mi caso uso el terminal serial de arduino ide), podremos enviar texto a la impresora que sera impreso luego de presionar la tecla enter. Ademas si presionamos la tecla enter haremos avanzar el papel. 

Ahora un video del programa en funcionamiento. 

Creo que el código fuente es bastante simple de entender y de adaptar a cualquier proyecto por lo tanto me voy saltar la explicación en detalle de cada función. 

Aunque si necesitan mas detalles no duden en dejar sus inquietudes en los comentarios.

Albertobauer

Alberto Bauer

soy putarraco y me la comursi

También te podría gustar...

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

es Español
X