rdm6300 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/rdm6300.rb +138 -0
- metadata +58 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: de049d9e1aa342bf79fd57474de2068df2fc54a7a88750305771656c28f11a90
|
4
|
+
data.tar.gz: 567199ef4ae0818b72f0c64b7c47732a332deec14ac0132a9aaa50a57c2db27e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bf5e6ebfde8424c50a90b0f8e2822ec6ac863586a8722b4c4ade44241af398a162b5140cfc6f76b5677304868f915849b964e2dafe0a7ce4b1ef41ba193d8d17
|
7
|
+
data.tar.gz: a60e53446d3ab94efcb6f1b21d86dbc7082cc3ad626a76098437a08e094e0a3d757c15540869cb3d66f86d836dd227eb5ef3be4483116a1f26566245ea603284
|
data/lib/rdm6300.rb
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
require 'serialport'
|
2
|
+
|
3
|
+
##
|
4
|
+
# This class reads 125kHz tags over an RS-232 serial port using the RDM6300 module
|
5
|
+
class Rdm6300
|
6
|
+
##
|
7
|
+
# Read 125kHz RFID tags from a serial port using the RDM6300 module as follows:
|
8
|
+
# rdm = Rdm6300.new('/dev/ttyS0')
|
9
|
+
# while true
|
10
|
+
# puts rdm.get_tag()
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# This will return a zero-padded string with the tag number.
|
14
|
+
|
15
|
+
# RDM6300 uses 0x02 to indicate the start of a tag
|
16
|
+
START_CODE = 0x02
|
17
|
+
# RDM6300 uses 0x03 to indicate the end of a tag
|
18
|
+
END_CODE = 0x03
|
19
|
+
# Valid tag data will always have a total length of 12 bytes over RS-232
|
20
|
+
VALID_LENGTH = 12
|
21
|
+
|
22
|
+
# The default serial port is /dev/ttyAMA0 since this is the primary serial port on a Raspberry Pi
|
23
|
+
#
|
24
|
+
# You will need to stop the Linux kernel using /dev/ttyAMA0 if you want to use it with the RDM6300
|
25
|
+
#
|
26
|
+
# On a Raspberry Pi 4 and Raspberry Pi OS, this can be done by adding enable_uart=1 and dtoverlay=disable-bt to /boot/config.txt
|
27
|
+
# and removing console=serial0,115200 from /boot/cmdline.txt
|
28
|
+
#
|
29
|
+
# The flush delay handles the situation where rogue RF triggers the RDM6300. Genuine tag data takes less than a second
|
30
|
+
# to transmit to the RDM6300. If there is tag data that takes longer than flush_delay to arrive, the input buffer is flushed.
|
31
|
+
# This improves the reliability of a long-running tag reader.
|
32
|
+
def initialize(serial_port_dev = '/dev/ttyAMA0', debug: false, flush_delay: 10)
|
33
|
+
@serial_port_dev = serial_port_dev
|
34
|
+
@debug = debug
|
35
|
+
@flush_delay = flush_delay
|
36
|
+
@serial_port = SerialPort.new(@serial_port_dev, 9600, 8, 1, SerialPort::NONE)
|
37
|
+
@serial_port.read_timeout = 0
|
38
|
+
end
|
39
|
+
|
40
|
+
# Closes the serial port
|
41
|
+
def close
|
42
|
+
@serial_port.close
|
43
|
+
end
|
44
|
+
|
45
|
+
# Waits for a tag to be presented and returns a zero-padded string with the tag id
|
46
|
+
def get_tag()
|
47
|
+
@received_bytes = []
|
48
|
+
@time_of_last_byte = Time.now
|
49
|
+
@receive_started = false
|
50
|
+
|
51
|
+
# Flush input buffer if partial data was received
|
52
|
+
@timeout_active = true
|
53
|
+
Thread.new do
|
54
|
+
while @timeout_active
|
55
|
+
sleep 1
|
56
|
+
if @receive_started and (Time.now - @time_of_last_byte) > @flush_delay
|
57
|
+
STDERR.puts "Received_bytes not empty after #{@flush_delay}s" if @debug
|
58
|
+
@time_of_last_byte = Time.now
|
59
|
+
@received_bytes = []
|
60
|
+
@receive_started = false
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
while true
|
66
|
+
byte = nil
|
67
|
+
begin
|
68
|
+
byte = @serial_port.readbyte
|
69
|
+
rescue EOFError => e
|
70
|
+
# This shouldn't happen if @serial_port.read_timeout == 0
|
71
|
+
STDERR.puts "Timed out reading serial data" if @debug
|
72
|
+
@time_of_last_byte = Time.now
|
73
|
+
@received_bytes = []
|
74
|
+
next
|
75
|
+
end
|
76
|
+
|
77
|
+
# check if this is the first byte received and it is valid. if not, reset
|
78
|
+
if !@receive_started and byte != START_CODE
|
79
|
+
STDERR.puts "Got initial byte but it is not #{START_CODE} (#{byte})" if @debug
|
80
|
+
reset_serial_buffer()
|
81
|
+
end
|
82
|
+
|
83
|
+
if !@receive_started and byte == START_CODE
|
84
|
+
@receive_started = true
|
85
|
+
@time_of_last_byte = Time.now
|
86
|
+
next
|
87
|
+
end
|
88
|
+
|
89
|
+
if byte > 127
|
90
|
+
STDERR.puts "Got invalid byte #{byte}, resetting" if @debug
|
91
|
+
reset_serial_buffer()
|
92
|
+
next
|
93
|
+
end
|
94
|
+
|
95
|
+
if byte == END_CODE
|
96
|
+
if @received_bytes.length == VALID_LENGTH
|
97
|
+
if checksum_is_valid?(@received_bytes)
|
98
|
+
@timeout_active = false
|
99
|
+
return '%010d' % @received_bytes[2..9].join.to_i(16)
|
100
|
+
else
|
101
|
+
STDERR.puts "Failed to verify checksum for received data" if @debug
|
102
|
+
end
|
103
|
+
else
|
104
|
+
STDERR.puts "Invalid number of bytes received (#{@received_bytes.length})" if @debug
|
105
|
+
end
|
106
|
+
reset_serial_buffer()
|
107
|
+
next
|
108
|
+
end
|
109
|
+
|
110
|
+
@received_bytes << byte.chr
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# Resets the serial buffer, called after a tag is presented
|
115
|
+
def reset_serial_buffer()
|
116
|
+
@receive_started = false
|
117
|
+
@received_bytes = []
|
118
|
+
@serial_port.close
|
119
|
+
@serial_port = SerialPort.new(@serial_port_dev, 9600, 8, 1, SerialPort::NONE)
|
120
|
+
@time_of_last_byte = Time.now
|
121
|
+
end
|
122
|
+
|
123
|
+
# Checks if the tag checksum is valid
|
124
|
+
def checksum_is_valid?(received_bytes)
|
125
|
+
# Format is 10 data bytes then two checksum bytes
|
126
|
+
# Group the received bytes into pairs, convert from ascii to hex, then XOR them
|
127
|
+
pairs = []
|
128
|
+
received_bytes[0..9].each_with_index do |char, index|
|
129
|
+
next if index % 2 == 1
|
130
|
+
pairs << char + received_bytes[index + 1]
|
131
|
+
end
|
132
|
+
checksum = pairs.map { |pair| pair.to_i(16) }.inject(:^)
|
133
|
+
|
134
|
+
# Then compare to [10..12] of received_checksum
|
135
|
+
received_checksum = (received_bytes[10] + received_bytes[11]).to_i(16)
|
136
|
+
return checksum == received_checksum
|
137
|
+
end
|
138
|
+
end
|
metadata
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rdm6300
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Luke Stutters
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-05-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: serialport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
description: rdm6300 is a Ruby library provides a simple interface for reading 125kHz
|
28
|
+
RFID tags over an RS-232 serial port using the RDM6300 module
|
29
|
+
email: lukestuts@gmail.com
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- lib/rdm6300.rb
|
35
|
+
homepage: https://github.com/lukestuts/ruby-rdm6300
|
36
|
+
licenses:
|
37
|
+
- GPL-3.0
|
38
|
+
metadata: {}
|
39
|
+
post_install_message:
|
40
|
+
rdoc_options: []
|
41
|
+
require_paths:
|
42
|
+
- lib
|
43
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '0'
|
53
|
+
requirements: []
|
54
|
+
rubygems_version: 3.0.3
|
55
|
+
signing_key:
|
56
|
+
specification_version: 4
|
57
|
+
summary: Read 125kHz RFID tags using the RDM6300 module
|
58
|
+
test_files: []
|