PDA

View Full Version : Barcode reader with PIC16f877A ?



iugmoh
- 24th January 2008, 12:56
Hi all,
I need your help in attendance registration project : I decide to register my students attendance automatically where each student has ID card with he's own number printed in barcode format with 11 digits like this "120061235" when we scaned it.
I read alot about barcode reader ps/2 protocol and know how it works and how i can interface with PIC16f877a , but i don't where is the problem I don't know how to display this ID number on an LCD for example

I use the interrupt to get clock
please anyone have an idea how to read barcode reader and display on LCD ?

here is my code:
Include "Modedefs.Bas"
DEFINE LCD_DREG PORTD 'LCD data port
DEFINE LCD_DBIT 4 'LCD data starting bit 0 or 4
DEFINE LCD_RSREG PORTD 'LCD register select port
DEFINE LCD_RSBIT 2 'LCD register select bit
DEFINE LCD_EREG PORTD 'LCD enable port
DEFINE LCD_EBIT 3 'LCD enable bit
DEFINE LCD_BITS 4 'LCD bus size 4 or 8
DEFINE LCD_LINES 4 'Number lines on LCD

DEFINE OSC 4 ' We're using a 4 MHz oscillator

Clr CON 1 ' Serial LCD command to clear LCD
LINE1 CON 128 ' Line #1 of serial LCD
LINE2 CON 192 ' Line #2 of serial LCD
LINE3 CON 148 ' Line #3 of serial LCD
LINE4 CON 212 ' Line #4 of serial LCD
Ins CON 254 ' Instruction for LCD command-mode


symbol SCL = PORTC.3 ' I2C CLOCK pin
symbol SDA = PORTC.4 ' I2C DATA pin
symbol clock_barcode=portb.0
symbol data_barcode=portb.1
input clock_barcode
input data_barcode
output portd.1
symbol but1=portb.2
input but1
portd.1=0

ON INTERRUPT GOTO reg_id
OPTION_REG = %00000101 ; falling edge of clock
pause 2000
INTCON = %10010000 ' Enable RB0 interrupt

Addr Var byte ' 8-bit memory address in EEPROM
EE_ByteOut Var Byte ' Variable whose value is to be stored to EEPROM
EE_ByteIn Var Byte ' Variable for storing the value read from EEPROM
ID var bit[250]
char var byte
countstep var byte
counter var byte

counter=0
TRISD = 0 ' Port D is output
EE_ByteOut=0

lcdout Ins,clr,INS,Line1,"Please Ins. ID card"
Main:

if but1=0 then
lcdout ins,clr,ins,line1,#counter,ins,line2
pause 3000


for countstep=0 to counter


lcdout #id[countstep]
pause 2000
next

counter=0

endif

goto main ' Remain in loop

DISABLE ' Disable interrupts in handler
reg_id:



if clock_barcode=0 then ; test falling edge
id[counter]=data_barcode

endif

counter=counter+1

portd.1=data_barcode ' Turn on LED when interrupted
intcon.1=0 ; reset int
RESUME ' Return to main program
ENABLE ' Enable interrupts after handler

skimask
- 24th January 2008, 14:22
I read alot about barcode reader ps/2 protocol and know how it works and how i can interface with PIC16f877a , but i don't where is the problem I don't know how to display this ID number on an LCD for example

please anyone have an idea how to read barcode reader and display on LCD ?
A bit contradictory, dontcha think?

Anywhos...
Usually, I put my On Interrupt near the beginning of a program, and skip over it into my main program. Some say it's good practice, others say they don't care, and still others say it straightens out execution sometimes. I don't know, I just know it works for me.

So, assuming you really have a good handle on your hardware and how the barcode scanner actually works, then this little bit of a rewrite should work for you.
(yes it's all crammed together, that's just the way I roll, you can reformat it all you want)



<-----LCD & Other DEFINES.....
<-----
clr con 1 : line1 con 128 : line2 con 192 : line3 con 148 : line4 con 212
ins con 254 : scl var portc.3 : sda var portc.4 : clock_barcode var portb.0
data_barcode var portb.1 : input clock_barcode : input data_barcode
output portd.1 : but1 var portb.2 : input but1 : portd.1 = 0 : option_reg = 5
pause 2000 : intcon = $90 : addr var byte : char var byte
ee_byteout var byte : ee_bytein var byte : id var bit[250]
countstep var byte : counter var byte : counter = 0 : trisd = 0 : ee_byteout = 0
On Interrupt Goto reg_id
goto mainloop
DISABLE ' Disable interrupts in handler
reg_id:
intcon.1 = 0
if clock_barcode=0 then ; test falling edge
id[counter]=data_barcode
endif
counter=counter+1 : portd.1=data_barcode
RESUME ' Return to main program
ENABLE ' Enable interrupts after handler[/QUOTE]
mainloop: lcdout Ins,clr,Line1,"Please Ins. ID card"
Main:
if but1=0 then
lcdout ins,clr,line1,#counter,ins,line2 : pause 3000
for countstep=0 to counter : lcdout #id[countstep] : pause 2000 : next
counter=0
endif
goto main ' Remain in loop
end


And it looks to me as if the whole code isn't here...

iugmoh
- 24th January 2008, 14:31
Thank you for your reply and your information, i will try to change my code now and see if it's working.

iugmoh
- 24th January 2008, 15:31
I modify my code, and it's more stable and better than previous which give me the number of bits were scanned counter=96 but previous it's not the same,
Here is my code after modifications
====================================

DEFINE LCD_DREG PORTD 'LCD data port
DEFINE LCD_DBIT 4 'LCD data starting bit 0 or 4
DEFINE LCD_RSREG PORTD 'LCD register select port
DEFINE LCD_RSBIT 2 'LCD register select bit
DEFINE LCD_EREG PORTD 'LCD enable port
DEFINE LCD_EBIT 3 'LCD enable bit
DEFINE LCD_BITS 4 'LCD bus size 4 or 8
DEFINE LCD_LINES 4 'Number lines on LCD
DEFINE OSC 4 ' We're using a 4 MHz oscillator

symbol clock_barcode=portb.0 ; clock of barcode reader ps/2
symbol data_barcode=portb.1 ; data of barcode reader ps/2
symbol but1=portb.2

ID var bit[250]
char var byte
countstep var byte
counter var byte

Clr CON 1 ' Serial LCD command to clear LCD
LINE1 CON 128 ' Line #1 of serial LCD
LINE2 CON 192 ' Line #2 of serial LCD
LINE3 CON 148 ' Line #3 of serial LCD
LINE4 CON 212 ' Line #4 of serial LCD
Ins CON 254 ' Instruction for LCD command-mode



input clock_barcode
input data_barcode
output portd.1
input but1

OPTION_REG = %00000101 ; falling edge of clock
INTCON = %10010000 ' Enable RB0 interrupt
counter=0

pause 2000 ; time for lcd to turn on
ON INTERRUPT GOTO reg_id
lcdout Ins,clr,INS,Line1,"Please Ins. ID card"
goto main

;;;;;;; interrupt service routine
DISABLE ' Disable interrupts in handler
reg_id:
intcon.1=0 ; reset int
if clock_barcode=0 then ; test falling edge
id[counter]=data_barcode
counter=counter+1
endif

RESUME ' Return to main program
ENABLE ' Enable interrupts after handler
;;;;;;;;;;;;;;;;;


Main:


if but1=0 then
lcdout ins,clr,ins,line1,#counter,ins,line2 : pause 3000
for countstep=0 to counter : lcdout #id[countstep] : pause 2000 : next
counter=0
endif

goto main ' Remain in loop

end


=========================

please if one can tell me if my code is true or not ,which it's collect data from barcode reader ps/2 every falling edge trigger of clock which this will tell the microcontroller interrupt service routine to save the data bit on this edge!

skimask
- 24th January 2008, 15:39
One of the problems you're going to have is the fact that you won't get an interrupt in the middle of a statement.
For instance,
Pause 3000...
The On Interrupt won't trigger for at least 3 seconds.
(However, instead of Pause 3000, you can use:
for x = 1 to 300 : pauseus 10 : next x...at least then the PIC will check for an interrupt every 10 microseconds)

Any LCDOUT command won't let an On Interrupt trigger during the execution of the LCDOUT command, which can take a few milliseconds, an eternity when dealing with fast signals.

In general, all interrupts are checked BEFORE or AFTER every statement (I don't remember which). So, if you're executing a single command, an ON INTERRUPT won't happen in the middle of it.

Either recode your program to keep anything in the main loop from holding up an interrupt or think about researching and switching over to DT's Instant Interrupts.

iugmoh
- 24th January 2008, 15:50
[QUOTE=skimask;49542]One of the problems you're going to have is the fact that you won't get an interrupt in the middle of a statement.
QUOTE]

oky I avoid this problem by placing If statement " If but1=0 " which all commands inside this if statement will not execute untill I press the button placed on portb.2

but I want to ask if there is something wrong in my code

skimask
- 24th January 2008, 15:54
oky I avoid this problem by placing If statement " If but1=0 " which all commands inside this if statement will not execute untill I press the button placed on portb.2
You sure did...missed that one, but it's still a valid point for future reference.


but I want to ask if there is something wrong in my code
Does it work?

If code_works = 1 then
nothing_wrong_with_code = 1
else
nothing_wrong_with_code = 0
something_wrong_with_code = 1
endif

iugmoh
- 24th January 2008, 16:04
You sure did...missed that one, but it's still a valid point for future

oky for testing my code I insert ID card with this number "120063718" and the barcode give me a sound that the scanning completed , then if the scanning stage I pressed the button to display the data collected from this barcode reader the data output as follows

counter=96
data bits=
10100001001111100010000011111100111110001000000111 0100101101011000000111010000011111100 ...........

I want to know how to decode this data to display this ID number 120063718

skimask
- 24th January 2008, 16:10
oky for testing my code I insert ID card with this number "120063718" and the barcode give me a sound that the scanning completed , then if the scanning stage I pressed the button to display the data collected from this barcode reader the data output as follows
counter=96
data bits=
10100001001111100010000011111100111110001000000111 0100101101011000000111010000011111100 ...........
I want to know how to decode this data to display this ID number 120063718

For one thing, we don't know which barcode scanner you're using (not that it would matter much).
Second thing, how does your scanner encode the information that it outputs?
Obviously you've got data there. Whether it's good data or not is another story.
What do the dots mean? Do they mean that there is more data to follow or are those the end of the string?
Is this some sort of ASCII encoded data? BCD? Grey code? Otherwise? 8 bit data chunks? 12 bit? 4 bit repeated/inverted?

iugmoh
- 24th January 2008, 16:19
For one thing, we don't know which barcode scanner you're using

oky, my barcode reader type is "PS/2 Keyboard Wedge Barcode Scanner" and I test it with my PS/2 PC port , which when i insert the ID card it's automatically display the number "120063718" with new line

I know that the problem is how to know how encoding is done ?

skimask
- 24th January 2008, 16:23
oky, my barcode reader type is "PS/2 Keyboard Wedge Barcode Scanner" and I test it with my PS/2 PC port , which when i insert the ID card it's automatically display the number "120063718" with new line

I know that the problem is how to know how encoding is done ?

Then you'll probably have to get a list of the actual PS/2 scancodes relating to various keypresses, numeric, alpha, whatever. Probably throw all of those into a lookup table, crunch the table and get your keypress out of it.
Basically, you're building a PS/2 keyboard reader. I'd be willing to bet that if you found some PS/2 reader code somewhere for plugging in a standard keyboard, that it would actually work.

iugmoh
- 24th January 2008, 16:34
I will thank you another time for your patience, I understand that you are meaning that I can replace my barcode reader by a keyboard and pressing the same ID number to know how each number is encoding

oky i will try this

skimask
- 24th January 2008, 16:44
I will thank you another time for your patience, I understand that you are meaning that I can replace my barcode reader by a keyboard and pressing the same ID number to know how each number is encoding

oky i will try this

That would be my bet.
So in the end, you're project would be (with enough info in tables or whatever) a capable PS/2 keyboard reader.
But I'm guessing here...and it makes sense to me.

Push 1 once...write down the sequence of bits returned...push 1 again, compare the sequence to before
then push 2 once, write down that sequence, etc.etc. and so on...

What do you get on the display for a single press of the number 1 on the keyboard, one press, one release of that single key...not the numeric keypad, but the number 1 above the Q?

iugmoh
- 24th January 2008, 17:02
I found the barcode reader specifications after a period time of searching
here is the link
http://s176338940.onlinehome.fr/pdf/IDICOD/2xxx.pdf

my barcode reader model is SSR-2110

but the manual is in franch i don't understand that

skimask
- 24th January 2008, 17:10
Push 1 once...write down the sequence of bits returned...push 1 again, compare the sequence to before
then push 2 once, write down that sequence, etc.etc. and so on...
What do you get on the display for a single press of the number 1 on the keyboard, one press, one release of that single key...not the numeric keypad, but the number 1 above the Q?
What did you come up with? Anything?


I found the barcode reader specifications after a period time of searching
here is the link
http://s176338940.onlinehome.fr/pdf/IDICOD/2xxx.pdf
my barcode reader model is SSR-2110
but the manual is in franch i don't understand that
Not going to read it, not going to attempt it, that's your job. Besides, I don't know french...

mister_e
- 24th January 2008, 20:50
By the datasheet, if your reader is SSR2110, it use the regular PS/2 interface.

There's few code example to read/decode/interface PS2 keyboard here

skimask
- 24th January 2008, 20:51
By the datasheet, if your reader is SSR2110, it use the regular PS/2 interface.

There's few code example to read/decode/interface PS2 keyboard here

There ya go...he knows french :D

Although that datasheet was sparse if it's anything...(even I could figure out some of those crazy words :) )

iugmoh
- 25th January 2008, 14:48
I make the interface between barcode reader and PIC16f877A successfully after many problems face me, yes it's working fine now.

thanks for all who help me

bluebubble
- 26th December 2008, 05:11
Could you please help me to finish my project on ps2 barcode reader? Can you please share your code?
i want to interface a ps2 barcode reader to PIC and want to read a barcode sticker and send the decoded data to RS232.