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.
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 :)
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.
Related Posts
Categories
Electronics