Skip to content
Archived from the legacy DMS wiki — content may be outdated.

RFID Interlock

  • Add your names here
  • Andrew LeCody
  • Gus Reiter
  • Lampy Ken Purcell
  • Michael Lass
  • Mikel Duke
  • Nick Sainz

RFID Storage Cabinet

  • 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
  • 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
  • Time Used
  • Machine ID & User RFID
  • Certified Table
  • Trainer Table
  • User Table
  • Marker on Website
  • What machine is in use
  • Maintenance Mode – machine unavailable
  • Clock display
  • WiFi
  • Remote deactivation
  • Keypad for laser to do job estimate

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.

Prototype Demo Video

  • 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
  • 125KHz RFID Tags
  • Parallax Serial RFID Reader
  • Arduino Ethernet
  • 110V Relay
  • 2n2222 Transistors
  • Leds
  • Current Sensor
lcd commandi2c command
colori2cset -y 1 0x38 1 xx
cleari2cset -y 1 0x38 2 1
cursor offi2cset -y 1 0x38 2 12
cursor flashing blocki2cset -y 1 0x38 2 13
cursor underlinei2cset -y 1 0x38 2 14
cursor flashing block and underlinei2cset -y 1 0x38 2 15
cleari2cset -y 1 0x38 2 1
characteri2cset -y 1 0x38 3 1
no more characteri2cset -y 1 0x38 3 13

pinout where the yellow legend on the pins show overlaps with virutal capes can be found here: Black_eMMC_and_HDMI_pins.PNG

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.

File:Interlock Flow Chart.pdf

nxt i2c buffer

Arduino Ethernet Code

Java BeagleBoneBlack Code

Python Beaglebone Black Code

consider using http://www.pingo.io/docs/ so that we are not device dependant

opkg install python-pip python-setuptools python-smbus
pip install Adafruit_BBIO
pip install pyserial
pip install evdev
mkdir notsmb_1_3
cd notsmb_1_3
wget http://www.byvac.com/downloads/sws/notsmb_1_3.zip
unzip notsmb_1_3.zip
sudo python setup.py install
http://derekmolloy.ie/set-ip-address-to-be-static-on-the-beaglebone-black/
apt-get install python-smbus
pip install evdev

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

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.

fielddatatypefunction
”tool_id”stringthe id used to validate the rfid card with makermanager
”description”stringThe description of the tool
”timeout”int / floathow long to let the machine idle before automatically logging out
”warning”int / floathow many seconds of warning before automatically logging out will we give the user
connectiondictionaryhow 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

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.html
https://docs.python.org/3/library/logging.config.html#logging.config.dictConfig

Example

"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" ] },
}
},
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
"/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
}
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
ValueDescription
”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”… - - - …
ModifierYou 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
"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"
}
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.
"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"
},
{
"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"
}
}
#! /usr/bin/python
import Adafruit_BBIO.GPIO as GPIO
import 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)
#! /usr/bin/python
import serial
import time
import 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)
#! /usr/bin/python
from uuid import getnode as get_mac
mac = get_mac()
print hex(mac)
print hex(mac)[2:14]
#! /usr/bin/python
import urllib2
filehandle = urllib2.urlopen("http://www.google.com")
print(filehandle.readline())
#! /usr/bin/python
import sys
import 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...'

http://beaglebone.cameon.net/home/watchdog-timer

Use t-568b

May connect to the security vlan

Linux PC:

iptables --table nat --append POSTROUTING --out-interface wlan1 -j MASQUERADE
iptables --append FORWARD --in-interface eth3 -j ACCEPT
echo 1 > /proc/sys/net/ipv4/ip_forward

Beaglebone:

route add default gw 192.168.7.1
echo "nameserver 4.2.2.1" > /etc/resolv.conf
/usr/bin/ntpdate -b -s -u pool.ntp.org

http://lanceme.blogspot.com/2013/06/windows-7-internet-sharing-for.html

Migrated from the legacy DMS wiki: original page