RFID Interlock
Members
Section titled “Members”- Add your names here
- Andrew LeCody
- Gus Reiter
- Lampy Ken Purcell
- Michael Lass
- Mikel Duke
- Nick Sainz
- Provide power to an outlet once an authorized RFID tag is scanned.
- Will connect over HTTP(s) to a web service to query if a particular RFID tag is valid/authorized.
- After a configurable amount of time, a warning light/sound will go of to indicate that the tool will be shutoff. Users should be able to rescan to push back the timeout or off, to completely turn off power to the device ahead of the timeout.
- Detect if the attached device is in use and start timer once it is turned off to avoid interruptions
- Eat pizza
For Version 1
Section titled “For Version 1”Hardware
Section titled “Hardware”- RFID Reader
- BIG Red Button w/ led
- Current Sensor
- Relay
- AC Outlet
- Enclosure w/ screw and lock-ability
- Power Supply, 5v or 9v for relay
- Network Cable
- Arduino with network or Beagle Bone
Software
Section titled “Software”- Time Used
- Machine ID & User RFID
- Certified Table
- Trainer Table
- User Table
- Marker on Website
- What machine is in use
- Maintenance Mode – machine unavailable
For Version 2
Section titled “For Version 2”- Clock display
- WiFi
- Remote deactivation
- Keypad for laser to do job estimate
Status
Section titled “Status”Update 11/23/2013
Section titled “Update 11/23/2013”Development for BeagleBoneBlack has began. The Arduino was much to finicky with higher level functionality. Also, for some reason DHCP quit working after a few hours of testing and no code changes. There is example code below for Python, and the start of a Java app on Github.
After some research, there are various models of cheap (<$20) RFID USB readers available. These interface with the host as a keyboard which makes coding for BBB/RPi much simpler, but would be very difficult to do on Arduino. They also have the big advantage of coming as a packaged product, with a plastic housing and usb port installed instead of a bare pcb. The Parallax readers used in the Hackathon run about $45+, are bare pcb, and work over 5v Serial connection. This looks to be the cheaper and easier way to go.
Hackathon 11/09/2013
Section titled “Hackathon 11/09/2013”Achievements
Section titled “Achievements”- Created working prototype using an Arduino Ethernet.
- Successfully scanned an RFID tag, queried the server over ethernet, and retrieved authorization status and time.
- Enabled the use of a fan
- Successfully detected fan operational status using the current detecting circuit
- Started countdown timer was the fan was off, and successfully turned off the power
- Ate pizza
- Improve reading RFID tags, get ghost reads due to RF interference
- Improve code stability, Arduino seems to have issues processing large strings, possibly change to char arrays
- Create housing for reader and controller
Version 1
Section titled “Version 1”- 125KHz RFID Tags
- Parallax Serial RFID Reader
- Arduino Ethernet
- 110V Relay
- 2n2222 Transistors
- Leds
- Current Sensor
| lcd command | i2c command |
| color | i2cset -y 1 0x38 1 xx |
| clear | i2cset -y 1 0x38 2 1 |
| cursor off | i2cset -y 1 0x38 2 12 |
| cursor flashing block | i2cset -y 1 0x38 2 13 |
| cursor underline | i2cset -y 1 0x38 2 14 |
| cursor flashing block and underline | i2cset -y 1 0x38 2 15 |
| clear | i2cset -y 1 0x38 2 1 |
| character | i2cset -y 1 0x38 3 1 |
| no more character | i2cset -y 1 0x38 3 13 |
Beaglebone black
Section titled “Beaglebone black”pinout where the yellow legend on the pins show overlaps with virutal capes can be found here:
ADC for current monitoring
Section titled “ADC for current monitoring”This is a low impedence sensor, so if using a voltage divider, the divider resisters need to add up to about 900 ohm.
- P9_32, VDD_ADC, provides 1.8 volts
- P9_33, AIN4 <--- ok to use
- P9_35, AIN6 <--- ok to use
- P9_36, AIN5 <--- ok to use
- P9_37, AIN2 <--- weird
- P9_38, AIN3 <--- weird
- P9_39, AIN0 <--- ok to use
- P9_40, AIN1 <--- ok to use
GPIO available for controlling LEDs and the tool
Section titled “GPIO available for controlling LEDs and the tool”- P9_11, GPIO_30
- P9_12, GPIO_60
- P9_13, GPIO_31
- P9_14, GPIO_40
- P9_15, GPIO_48
- P9_16, GPIO_51
- P9_17, GPIO_4
- P9_18, GPIO_5
- P9_21, GPIO_3
- P9_22, GPIO_2
- P9_23, GPIO_49
- P9_24, GPIO_15
- P9_25, GPIO_117
- P9_26, GPIO_14
- P9_27, GPIO_125
- P9_30, GPIO_122
- P9_41, GPIO_20
- P9_42, GPIO_7
- P8_7, GPIO_66
- P8_8, GPIO_67
- P8_9, GPIO_69
- P8_10, GPIO_68
- P8_11, GPIO_45
- P8_12, GPIO_44
- P8_13, GPIO_23
- P8_14, GPIO_26
- P8_15, GPIO_47
- P8_16, GPIO_46
- P8_17, GPIO_27
- P8_18, GPIO_65
- P8_19, GPIO_22
There are more available if we disable either the HDMI or eMMC capes.
- http://learn.adafruit.com/setting-up-io-python-library-on-beaglebone-black/pwm
- http://beagleboard.org/support/BoneScript/analogWrite/ for pins
Designs
Section titled “Designs”File:Interlock Flow Chart.pdf
Wish list
Section titled “Wish list”nxt i2c buffer
- http://www.nxp.com/documents/leaflet/75016081.pdf
- http://www.nxp.com/products/interface_and_connectivity/i2c/i2c_bus_repeaters_hubs_extenders/
Software
Section titled “Software”Git Repositories
Section titled “Git Repositories”Python Beaglebone Black Code
Section titled “Python Beaglebone Black Code”Required Python Library
Section titled “Required Python Library”consider using http://www.pingo.io/docs/ so that we are not device dependant
Ångström distribution
Section titled “Ångström distribution”opkg install python-pip python-setuptools python-smbuspip install Adafruit_BBIOpip install pyserialpip install evdev
mkdir notsmb_1_3cd notsmb_1_3wget http://www.byvac.com/downloads/sws/notsmb_1_3.zipunzip notsmb_1_3.zipsudo python setup.py installstatic ip
Section titled “static ip”http://derekmolloy.ie/set-ip-address-to-be-static-on-the-beaglebone-black/Debian
Section titled “Debian”apt-get install python-smbuspip install evdevdisable HDMI
Section titled “disable HDMI”from http://www.logicsupply.com/blog/2013/07/18/disabling-the-beaglebone-black-hdmi-cape/
- df
- see /boot/uboot, cd to there.
- edit uEnv.txt
- find where it comments about HDMI
Configuration
Section titled “Configuration”in /etc/mother.ini
This is a JSON formatted file where the top level as a few things specific to the rfid interlock system followed by various connections.
Top Level
Section titled “Top Level”| field | datatype | function |
| ”tool_id” | string | the id used to validate the rfid card with makermanager |
| ”description” | string | The description of the tool |
| ”timeout” | int / float | how long to let the machine idle before automatically logging out |
| ”warning” | int / float | how many seconds of warning before automatically logging out will we give the user |
| connection | dictionary | how the connection is used in the rfid interlock. |
Top level
- which connection to define, various. Such as AIN[0-9], P8_23, unix device name for a serial connection, stdin, stdout. The dictionary found with
Logging
Section titled “Logging”Note that "logging": {"root": { "level": "DEBUG" }} should be at least ERROR, otherwise errors in the config file will go unnoticed by the system. The way to think about the python logging system is that at the top level you accept the most detailed messages that you could possibly want on the lower levels, then on the lower levels you lock the verbosity down. Note that a custom logging handler is used internally, and it notices ERROR messages, especially from the class constructors to know whether or not we have a properly configured system. If not, it will try to notify by putting all outputs into “error” mode and not accept badge swipes.
Lookup:
https://docs.python.org/3/howto/logging-cookbook.htmlhttps://docs.python.org/3/library/logging.config.html#logging.config.dictConfigExample
"logging": { "version": 1, "formatters": { "detailed": { "class": "logging.Formatter", "format": "%(asctime)s %(name)-15s %(levelname)-8s %(message)s" } }, "handlers": { "console": { "class": "logging.StreamHandler", "level": "CRITICAL" "formatter": "detailed", }, "var_log": { "class": "logging.FileHandler", "filename": "/var/log/mother.log", "mode": "a", "level": "INFO", "formatter": "detailed" } }, "root": { "level": "DEBUG", "handlers": ["console", "var_log"] }, "loggers": { "digital_output": { "level": "ERROR", "handlers": [ "var_log" ] }, "digital_monitor": { "level": "ERROR", "handlers": [ "var_log" ] }, "input_event_rfid_reader": { "level": "ERROR", "handlers": [ "var_log" ] }, "interlock": { "level": "ERROR", "handlers": [ "var_log" ] }, "keyboard_rfid_reader": { "level": "ERROR", "handlers": [ "var_log" ] }, "rfid_reader": { "level": "ERROR", "handlers": [ "var_log" ] }, "serial_rfid_reader": { "level": "ERROR", "handlers": [ "var_log" ] }, "stdio_output": { "level": "ERROR", "handlers": [ "var_log" ] }, }},RFID Reader Connection
Section titled “RFID Reader Connection”| Dictionary | Value | Description |
|---|---|---|
| common required settings | ||
| "comment" | string | human readable description |
| "mode" | "rfid_reader" | how many characters to skip before we start paying attention to the code |
| "code_skip_chars" | integer | how many characters to skip before we start paying attention to the code |
| "code_len" | integer | how many characters to pay attention to |
| "code_base" | integer | 10 if base ten, 16 if the code read is hexadecimal |
| Serial | the connection is a device in /dev/ that will respond nicely to .readline() function once read | |
| "type" | "serial" | |
| "baud" | integer | the baud rate |
| input event | a device in /dev/input/event[0-9] | |
| "type" | "input_event" | |
| keyboard input | ||
| "type" | "stdin" | input from keyboard |
examples
Section titled “examples”"/dev/ttyUSB0": { "mode": "rfid_reader", "type": "serial", "baud": 2400, "code_skip_chars": 2, "code_len": 10, "code_base": 16}
"/dev/input/event1": { "mode": "rfid_reader", "type": "input_event", "code_skip_chars": 0, "code_len": 10, "code_base": 10}Output Connection
Section titled “Output Connection”| Dictionary | Value | Description |
|---|---|---|
| common required settings | ||
| "comment" | string | human readable description |
| "mode" | "output" | what this connection does to reflect the state of the machine |
| "active" | see below in digital output options |
consider this to be "green light" state |
| "inactive_soon" | consider this to be "yellow light" state | |
| "inactive" | consider this to be "red light" state | |
| "error" | something is wrong, seriously wrong | |
| Digital | the connection is a pin that an LED or power control is connected to | |
| "type" | "digitial" | controls a digital output pin to reflect the state of the machine |
| "On" | "HIGH" | when the signal is high, that signifies that the device attached it on |
| "LOW" | when the signal is low, that signifies that the device attached it on. Inverted logic if you will. | |
| stdio | prints to the console that starts the rfid_interlock.py | |
| "type" | "stdio" | prints to the console that starts the rfid_interlock.py |
Digital Output Options
Section titled “Digital Output Options”| Value | Description |
| ”ON” | turn it on, dependent on the “on” field of the connection |
| ”OFF” | turn it off, dependent on the “on” field of the connection |
| ”BLINK” | turn it high, then low, then high. Defaults to half a second per high or low. |
| ”SOS” | … - - - … |
| Modifier | You can associate a modifier to the ON, OFF and BLINK digital output option. When used on BLINK, this will override the blink speed. When used with ON or OFF, it will switch to the other state after the specified number of seconds. |
| ”output” | if you turn a output option into a dictionary, you will need to add this “output” field to the dictionary and put the output option in for its value. |
| ”seconds” | integer / float |
examples
Section titled “examples”"P8_11": { "comment": "Active LED", "type": "digital", "mode": "output", "on": "HIGH", "error": "SOS", "active": {"output": "ON", "seconds": 1}, "inactive_soon": "OFF", "inactive": "OFF"}
"P8_11": { "comment": "Warning LED", "type": "digital", "mode": "output", "on": "HIGH", "error": "SOS", "active": "OFF", "inactive_soon": "ON", "inactive": "OFF"}Monitor Connection
Section titled “Monitor Connection”| Dictionary | Value | Description |
|---|---|---|
| common required settings | ||
| "comment" | string | human readable description |
| "mode" | "monitor" | values on this connection affect the state |
| "active" | condition | Switch the state to active and start the countdown to deactivate and countdown to warning timers. |
| "inactive_soon" | if we are not already in inactive_soon mode, then we switch the state to inactive_soon and set the deactivate timer to count down the seconds of warning | |
| "inactive" | switch the state to inactive and clear the timers | |
| "error" | we switch the state to error and clear the timers | |
| "reset_timer" | we reset the countdown timer and set the state to active whenever this happens | |
| digital settings | ||
| "type" | "digital" | we respond to voltage her going high or low |
| new state | "FALLING" | trigger when the signal goes low |
| "RISING" | trigger when the signal goes high | |
| analog to digital settings | ||
| "type" | "adc" | we respond to voltage her going high or low |
| new state | { "higher": float } | triggers whenever the adc value is higher than the value |
| { "lower": float } | triggers whenever the adc value is lower than the value | |
| { "higher": float, "lower": float } | if the higher value is higher than the lower value, then the higher and lower values then either can trigger a new state. If the higher value is lower than the lower value, then the higher and lower values must both evaluate to true to trigger the new state. |
|
examples
Section titled “examples”"AIN1": { "mode": "monitor", "type": "adc", "countdown_reset": { "higher": 0.209222216129 }},
"P9_14": { "comment": "PIR Sensor", "mode": "monitor", "type": "digital", "reset_timer": "FALLING"},
"P9_12": { "comment": "logout button", "mode": "monitor", "type": "digital", "inactive": "FALLING"},Example
Section titled “Example”{ "tool_id": "1", "tool_desc": "Table Saw", "timeout": 60,
"AIN1": { "description": "read in the amperage", "revision_log": [ "modified by Lance on ..", "LALALAL" ], "mode": "monitor",
"timer_reset": { "lower": 0.209222216129, "higher: 0.809222216129 },
"higher_power_value": 0.402222216129, "idle_power_value": 0.01666671038 }, "AIN2": { "description": "Temperature monitor", "mode": "monitor",
"soft_stop": { "higher": 0.809222216129, "lower": 0.909222216129 }, "hard_stop": { "higher": 0.909222216129 }, }, "AIN3": { "mode": "monitor", "timer_reset": { "higher": 0.209222216129 }, "higher_power_value": 0.402222216129, "idle_power_value": 0.01666671038 }, "P8_4": { "mode": "monitor", "hard_stop": "RISING", }, "P8_6": { "mode": "monitor", "RISING": "soft_stop" }, "P8_32": { "mode": "monitor", "time_reset": "RISING" }, "/dev/ttyO1": { "mode": "monitor", "baud_rate": "9600", "timer_reset": "resetme" }, "/dev/ttyO2": { "mode": "monitor", "baud_rate": "9600", "init": "send me data !", "timer_reset": "1" }, "P9_23": { "description": "Active LED", "mode": "output", "active": "HIGH", "inactive_soon": "LOW", "inactive": "LOW" }, "PWM1A": { "description": "Pulsing inactive soon LED", "mode": "output", "active": 0, "inactive_soon": "PULSE", "inactive": 0 }, "P9_25": { "description": "blinking inactive soon LED", "mode": "output", "active": "LOW", "inactive_soon": "BLINK", "inactive": "LOW" }, "P9_27": { "description": "Inactive LED", "mode": "output", "active": "LOW", "inactive_soon": "LOW", "inactive": "HIGH" }, "/dev/ttyUSB0": { "mode": "rfid_reader", "baud": 2400, "type": "serial" }, "P9_28": { "description": "Power On", "mode": "output", "active": "HIGH" }, "P9_30": { "description": "Enable Power On", "mode": "output", "active": { "output": "HIGH", "seconds": 120 } }, "P9_42": { "mode": "output", "inactive": { "power": "HIGH", "seconds": 1 } },
"stdin": { "mode": "rfid_reader", "type": "stdio" }, "/dev/ttyO3": { "description": "serial control", "baud_rate": 9600, "mode": "output", "active": "on\n", "inactive": "off\n" }, "/dev/dsp": { "type": "oss", "mode": "output", "active": "/var/mother/interlock/active.wav", "inactive_soon": "/var/mother/interlock/active_soon.wav", "inactive": "/var/mother/interlock/inactive.wav" }, "espeak": { "mode": "output", "active": "Power On", "inactive_soon": "Timing Out", "inactive": "Power Off", }, "/dev/ttyO3": { "mode": "output", "baud_rate": 9600, "inactive": "off\n" }}beaglebone black python snippets
Section titled “beaglebone black python snippets”breadboard_led.py
Section titled “breadboard_led.py”#! /usr/bin/python
import Adafruit_BBIO.GPIO as GPIOimport time
GPIO.setup("P8_10", GPIO.OUT)while True: GPIO.output("P8_10", GPIO.HIGH) time.sleep(0.5) GPIO.output("P8_10", GPIO.LOW) time.sleep(0.5)read_rfid.py
Section titled “read_rfid.py”#! /usr/bin/pythonimport serialimport timeimport urllib2
ser = serial.Serial('/dev/ttyUSB0', 2400)
while True: response = ser.readline().trim() if response <> "": print "raw: " + str(response) print "hex: " + str(response[-8:]) print "dec: " + str(int(response[-8:], 16)) rfid = str(int(response[-8:], 16))
filehandle = urllib2.urlopen("http://www.google.com/?" + rfid) print(filehandle.readline())
time.sleep(1)read_mac_address.py
Section titled “read_mac_address.py”#! /usr/bin/python
from uuid import getnode as get_macmac = get_mac()print hex(mac)print hex(mac)[2:14]read_url.py
Section titled “read_url.py”#! /usr/bin/python
import urllib2
filehandle = urllib2.urlopen("http://www.google.com")
print(filehandle.readline())user_led_blink.py
Section titled “user_led_blink.py”#! /usr/bin/python
import sysimport time
leds = [ '/sys/class/leds/beaglebone:green:usr0/brightness', '/sys/class/leds/beaglebone:green:usr1/brightness', '/sys/class/leds/beaglebone:green:usr2/brightness', '/sys/class/leds/beaglebone:green:usr3/brightness']
def ledon(n): value = open(leds[n],'w') value.write(str(1)) value.close()
def ledoff(n): value = open(leds[n],'w') value.write(str(0)) value.close()
if __name__ == '__main__': while True: for i, val in enumerate(leds): ledoff(i) time.sleep(1)
for i, val in enumerate(leds): ledon(i) time.sleep(1)
print 'Exiting...'Watchdog Timer
Section titled “Watchdog Timer”http://beaglebone.cameon.net/home/watchdog-timer
Network Connection
Section titled “Network Connection”Use t-568b
May connect to the security vlan
Routing through Linux PC over USB
Section titled “Routing through Linux PC over USB”Linux PC:
iptables --table nat --append POSTROUTING --out-interface wlan1 -j MASQUERADEiptables --append FORWARD --in-interface eth3 -j ACCEPTecho 1 > /proc/sys/net/ipv4/ip_forwardBeaglebone:
route add default gw 192.168.7.1echo "nameserver 4.2.2.1" > /etc/resolv.conf/usr/bin/ntpdate -b -s -u pool.ntp.orgRouting through Windows 7 over USB
Section titled “Routing through Windows 7 over USB”http://lanceme.blogspot.com/2013/06/windows-7-internet-sharing-for.html
Migrated from the legacy DMS wiki: original page