Concept

Build primarily as proof of concept and because I found the challenge interresting, this little unit is able to send an ascii string terminated with a CR/LF via a RS232 connection. It's emulating the transmission of a barcode and can be used with any kind of equipment that is expecting a barcode.

Schematic

I have been a little lazy on this project, as I have based it on the arduino serial V2 layout. This is also the reason I don't have a neat schematic to show. But I have the reference schematic from the arduino board. And my handdrawn notes on the wiring and keypad. Please note that I have replaced the transistor version of the TTL to RS232 circuit with a MAX232 chip. This makes a more stable signal for the RS232 communication.

arduino_reference_b 13061201c 13061202c2 13061202c1

Oh, and there is also a connection to pin1 on the SUB-D (not shown on the schematic) for supplying the BAR-X with a 5 volt from the RS232 port. (only available on specific equipment)

Photos

Of course a couple of photos of the finished product should not be missing :)

P1000649b P1000650b P1000648b

Sourcecode

And finally to make the whole thing work. Here is the sourcecode for the embedded program. Mind you it's nothing fancy. I tried using some procedures to shorten the code. But it never worked? So I took the sequential approach instead.


/******************************************
 * Barcode Emulator V0.1                  *
 * ====================================== *
 * A pre-defined ASCII code will be send  *
 * using RS232 to a PC or other equipment *
 * connected via the serial connection.   *
 * A Carriage Return(CR) and              *
 * Line feed (LF) char will be appended.  *
 * ====================================== *
 * Programmed by Rene Rasmussen 2011-09   *
 * This software released under the GPL   *
 ******************************************/
#include 
#include 
#include  /* define _delay_ms() ...*/
/* for the delay to work correctly the compiler optimization must be set to -O2 */

#define UART_BAUD_RATE 9600L
#define UART_BAUD_CALC(UART_BAUD_RATE,F_CPU) ((F_CPU)/((UART_BAUD_RATE)*16L)-1)

/* wait ms Milliseconds */
void delay_ms(uint16_t ms)
{
  uint16_t t;
  for(t=0; t<=ms; t++)
  _delay_ms(1);
}

void uart_putc(unsigned char c)
{
  while(!(UCSRA & (1 << UDRE))); /* Wait for UDR ready */
  UDR = c;
}

void uart_puts (unsigned char *s)
{
  while (*s)
  {
    uart_putc(*s);
    s++;
  }
}

void uart_ini()
{
  UCSRB |= (1 << TXEN);		/* Enable UART TX (send) */
  UCSRB |= (1 << RXEN);		/* Enable UART RX (receive) */
  UCSRC |= (1 << URSEL)|(1 << UCSZ0)|(1 << UCSZ1); /* Async, 8N1 */
  UBRRH=(uint8_t)(UART_BAUD_CALC(UART_BAUD_RATE,F_CPU)>>8); /* Choose Baudrate */
  UBRRL=(uint8_t)UART_BAUD_CALC(UART_BAUD_RATE,F_CPU);
}

void init_keypad()
{
  /* Set all keypad outputs (A-D) to HIGH */
  PORTC |= ((1<<0)|(1<<1)|(1<<2)|(1<<3));
}

void main (void)
{
   char CR, LF;

   /* Barcode to be send over RS232 */
   const unsigned char *const barcode[] = { "BARX01" ,
   "BARX02" , "BARX03", "BARX04",
   "BARX05" , "BARX06", "BARX07",
   "BARX08" , "BARX09", "BARX10",
   "BARX11" , "BARX12"};


   DDRC = 0; /* reset all bits to zero on port C */
   DDRD = 0; /* reset all bits to zero on port D */

/* Keypad layout
 *
 * col   1  2  3
 * row
 *	1	[1][2][3]
 *	2	[4][5][6]
 *	3	[7][8][9]
 *	4	[*][0][#]
 */
   DDRD &= ~(1 << 5);				/* PD5 set as input (DDRD.5 = 0) [column 1] */
   DDRD &= ~(1 << 6);				/* PD6 set as input (DDRD.6 = 0) [column 2] */
   DDRD &= ~(1 << 7);				/* PD7 set as input (DDRD.7 = 0) [column 3] */
   DDRC |= (1 << 0);				/* PC0 set as output (DDRC.0 = 1) [row 1] */
   DDRC |= (1 << 1);				/* PC1 set as output (DDRC.1 = 1) [row 2] */
   DDRC |= (1 << 2);				/* PC2 set as output (DDRC.2 = 1) [row 3] */
   DDRC |= (1 << 3);				/* PC3 set as output (DDRC.3 = 1) [row 3] */

   PORTD |= (1 << 5);				/* PD5 enable internal pull-up */
   PORTD |= (1 << 6);				/* PD6 enable internal pull-up */
   PORTD |= (1 << 7);				/* PD7 enable internal pull-up */

   DDRD |= (1 << 4);				/* PD4 set as output (DDRD.4 = 0) [LED] */
   PORTD &= ~(1 << 4);			/* PD4 set to LOW */

   CR = 0x0D;						/* Carriage Return Code */
   LF = 0x0A;						/* Linefeed */

   uart_ini();
   init_keypad();

   while (1) /* Loop forever */
   { 

/* Row 1 */
     PORTC &= ~(1<<0); /* Set A (DDRC.0) low */
     delay_ms(50); /* delay to allow port to settle */
     if((PIND & (1 << PIND5)) == 0)
     	   {
       uart_puts(barcode[0]);
       uart_putc(CR);
       uart_putc(LF);
       while ((PIND & (1 << PIND5)) == 0)
         {
         PORTD |= (1<<4); /* activate LED */
         }
       PORTD &= ~(1<<4); /* deactivate LED */
     	   }
     if((PIND & (1 << PIND6)) == 0)
     	   {
       uart_puts(barcode[1]);
       uart_putc(CR);
       uart_putc(LF);
       while ((PIND & (1 << PIND6)) == 0)
         {
         PORTD |= (1<<4); /* activate LED */
         }
       PORTD &= ~(1<<4); /* deactivate LED */
     	   }
     if((PIND & (1 << PIND7)) == 0)
     	   {
       uart_puts(barcode[2]);
       uart_putc(CR);
       uart_putc(LF);
       while ((PIND & (1 << PIND7)) == 0)
         {
         PORTD |= (1<<4); /* activate LED */
         }
       PORTD &= ~(1<<4); /* deactivate LED */
     	   }
     PORTC |= (1 << 0); /* Set A (DDRC.0) high */

/* Row 2 */
     PORTC &= ~(1<<1); /* Set B (DDRC.1) low */
     delay_ms(50); /* delay to allow port to settle */
     if ((PIND & (1 << PIND5)) == 0)
     	   {
       uart_puts(barcode[3]);
       uart_putc(CR);
       uart_putc(LF);
       while ((PIND & (1 << PIND5)) == 0)
         {
         PORTD |= (1<<4); /* activate LED */
         }
       PORTD &= ~(1<<4); /* deactivate LED */
     	   }
     if((PIND & (1 << PIND6)) == 0)
     	   {
       uart_puts(barcode[4]);
       uart_putc(CR);
       uart_putc(LF);
       while ((PIND & (1 << PIND6)) == 0)
         {
         PORTD |= (1<<4); /* activate LED */
         }
       PORTD &= ~(1<<4); /* deactivate LED */
     	   }
     if((PIND & (1 << PIND7)) == 0)
     	   {
       uart_puts(barcode[5]);
       uart_putc(CR);
       uart_putc(LF);
       while ((PIND & (1 << PIND7)) == 0)
         {
         PORTD |= (1<<4); /* activate LED */
         }
       PORTD &= ~(1<<4); /* deactivate LED */
     	   }
     PORTC |= (1 << 1); /* Set B (DDRC.1) high */

/* Row 3 */
     PORTC &= ~(1<<2); /* Set C (DDRC.2) low */
     delay_ms(50); /* delay to allow port to settle */
     if ((PIND & (1 << PIND5)) == 0)
     	   {
       uart_puts(barcode[6]);
       uart_putc(CR);
       uart_putc(LF);
       while ((PIND & (1 << PIND5)) == 0)
         {
         PORTD |= (1<<4); /* activate LED */
         }
       PORTD &= ~(1<<4); /* deactivate LED */
     	   }
     if((PIND & (1 << PIND6)) == 0)
       {
       uart_puts(barcode[7]);
       uart_putc(CR);
       uart_putc(LF);
       while ((PIND & (1 << PIND6)) == 0)
         {
         PORTD |= (1<<4); /* activate LED */
         }
       PORTD &= ~(1<<4); /* deactivate LED */
       }
     if((PIND & (1 << PIND7)) == 0)
       {
       uart_puts(barcode[8]);
       uart_putc(CR);
       uart_putc(LF);
       while ((PIND & (1 << PIND7)) == 0)
         {
         PORTD |= (1<<4); /* activate LED */
         }
       PORTD &= ~(1<<4); /* deactivate LED */
       }
     PORTC |= (1 << 2); /* Set C (DDRC.2) high */

/* Row 4 */
     PORTC &= ~(1<<3); /* Set C (DDRC.3) low */
     delay_ms(50); /* delay to allow port to settle */
     if ((PIND & (1 << PIND5)) == 0)
     	   {
       uart_puts(barcode[9]);
       uart_putc(CR);
       uart_putc(LF);
       while ((PIND & (1 << PIND5)) == 0)
         {
         PORTD |= (1<<4); /* activate LED */
         }
       PORTD &= ~(1<<4); /* deactivate LED */
       }
     if((PIND & (1 << PIND6)) == 0)
       {
       uart_puts(barcode[10]);
       uart_putc(CR);
       uart_putc(LF);
       while ((PIND & (1 << PIND6)) == 0)
         {
         PORTD |= (1<<4); /* activate LED */
         }
       PORTD &= ~(1<<4); /* deactivate LED */
       }
     if((PIND & (1 << PIND7)) == 0)
       {
       uart_puts(barcode[11]);
       uart_putc(CR);
       uart_putc(LF);
       while ((PIND & (1 << PIND7)) == 0)
         {
         PORTD |= (1<<4); /* activate LED */
         }
       PORTD &= ~(1<<4); /* deactivate LED */
       }
     PORTC |= (1 << 3); /* Set D (DDRC.3) high */
   }

Final words

This was fun. And I hope it will be of some use out there in the wild.



Categories

Electronics