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<avr/io.h>
#include<string.h>
#include<util/delay.h> /* 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 */voiddelay_ms(uint16_tms){uint16_tt;for(t=0;t<=ms;t++)_delay_ms(1);}voiduart_putc(unsignedcharc){while(!(UCSRA&(1<<UDRE)));/* Wait for UDR ready */UDR=c;}voiduart_puts(unsignedchar*s){while(*s){uart_putc(*s);s++;}}voiduart_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);}voidinit_keypad(){/* Set all keypad outputs (A-D) to HIGH */PORTC|=((1<<0)|(1<<1)|(1<<2)|(1<<3));}voidmain(void){charCR,LF;/* Barcode to be send over RS232 */constunsignedchar*constbarcode[]={"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.