Firstly this questions is inferred from this answer answer .In that answer provides us a splitting a mp3 file with Python . That code is usefull , but for splitting two pieces . For instance if I want to split 30.00 th second to end of the audio , it is cool , but if I want to split from 30.00 to 35.00 it is useless for it . Below of that answer there is a comment about how to trim audio, like I said ,specific piece. When I imply that instructions to code it looked like that :
import struct
import sys
#MP3 frames are not independent because of the byte reservoir. This script does not account for
#that in determining where to do the split.
def SplitMp3(fi, firstSplit_sec,secondSplit_sec, out):
#Constants for MP3
bitrates = {0x0: "free", 0x1: 32, 0x2: 40, 0x3: 48, 0x4: 56, 0x5: 64, 0x6: 80, 0x7: 96, 0x8: 112,
0x9: 128, 0xa: 160, 0xb: 192, 0xc: 224, 0xd: 256, 0xe: 320, 0xf: "bad"}
freqrates = {0x0: 44100, 0x1: 48000, 0x2: 32000, 0x3: "reserved"}
countMpegFrames = 0
frameDuration = 0.026
unrecognizedBytes = 0
firstSplitFrame = int(round(firstSplit_sec / frameDuration))
secondSplitFrame = int(round(secondSplit_sec / frameDuration))
while True:
startPos = fi.tell()
#Check for 3 byte headers
id3Start = fi.read(3)
if len(id3Start) == 3:
if id3Start == b'TAG':
#print ("Found ID3 v1/1.1 header")
fi.seek(startPos + 256)
continue
if id3Start == b'ID3':
#Possibly a ID3v2 header
majorVer, minorVer, flags, encSize = struct.unpack(">BBBI", fi.read(7))
if majorVer != 0xFF and minorVer != 0xFF:
encSize1 = (encSize & 0x7f000000) >> 24
encSize2 = (encSize & 0x7f0000) >> 16
encSize3 = (encSize & 0x7f00) >> 8
encSize4 = (encSize & 0x7f)
if encSize1 < 0x80 and encSize2 < 0x80 and encSize3 < 0x80 and encSize4 < 0x80:
size = ((encSize & 0x7f000000) >> 3) + ((encSize & 0x7f0000) >> 2) + ((encSize & 0x7f00) >> 1) + (encSize & 0x7f)
unsync = (flags >> 7) & 0x1
extendedHeader = (flags >> 6) & 0x1
experimental = (flags >> 5) & 0x1
#print ("Found ID3v2 header")
#print ("version", majorVer, minorVer, unsync, extendedHeader, experimental)
#print ("size", size)
#TODO extendedHeader not supported yet
fi.seek(startPos + 10 + size)
continue
#Check for 4 byte headers
fi.seek(startPos)
headerRaw = fi.read(4)
if len(headerRaw) == 4:
headerWord = struct.unpack(">I", headerRaw)[0]
#Check for MPEG-1 audio frame
if headerWord & 0xfff00000 == 0xfff00000:
#print ("Possible MPEG-1 audio header", hex(headerWord))
countMpegFrames += 1
ver = (headerWord & 0xf0000) >> 16
bitrateEnc = (headerWord & 0xf000) >> 12
freqEnc = (headerWord & 0xf00) >> 8
mode = (headerWord & 0xf0) >> 4
cpy = (headerWord & 0xf)
if ver & 0xe == 0xa and freqEnc != 0xf:
#print ("Probably an MP3 frame")
bitrate = bitrates[bitrateEnc]
freq = freqrates[freqEnc >> 2]
padding = ((freqEnc >> 1) & 0x1) == 1
#print ("bitrate", bitrate, "kbps")
#print ("freq", freq, "Hz")
#print ("padding", padding)
frameLen = int((144 * bitrate * 1000 / freq ) + padding)
#Copy frame to output
fi.seek(startPos)
frameData = fi.read(frameLen)
if (secondSplitFrame >= countMpegFrames) and (countMpegFrames >= firstSplitFrame):
out.write(frameData)
fi.seek(startPos + frameLen)
continue
else:
raise RuntimeError("Unsupported format:", hex(ver), "header:", hex(headerWord))
#If no header can be detected, move on to the next byte
fi.seek(startPos)
nextByteRaw = fi.read(1)
if len(nextByteRaw) == 0:
break #End of file
unrecognizedBytes += 1
#print ("unrecognizedBytes", unrecognizedBytes)
#print ("countMpegFrames", countMpegFrames)
#print ("duration", countMpegFrames * frameDuration, "sec")
When I use this function it produces loosy output . For instance if I want to split 0.0 to 41.00 it gives me 0.00 to 37.00 , and this loosieness is increasing with amount of slice. I've struggled to understand some parts of code . So I am asking how can I solve that loosiness ? Am I missing something ?
Note : I already tried to pydub and similar modules . But they are useless . Always giving memory error and slow . This is really fast .
I couldn't find a solution for loosiness problem therefore I used ffmpeg for slicing .
subprocess.call(["ffmpeg","-i",input_file,"-acodec","copy","-loglevel","quiet","-ss",str(start),"-to",str(end),"-metadata","title={}".format(name),output_file+".mp3"])
Related
Im trying to establish my own Raspy-Installation with a light-control.
I am trying to get a script-code working, to enable the light-control-service.
I am getting a really simple error message, but i cant fix it on my own:
Traceback (most recent call last):
File "test.py", line 13, in <module>
bus.write_byte_data(0x39, 0x00 | 0x80, 0x03)
IOError: [Errno 5] Input/output error
I just want to show you the complete code. Is anyone able to help me? :)
from os import system
system("sudo killall pigpiod")
system("sudo pigpiod")
import RPi.GPIO as GPIO
import time
import pigpio
import smbus
bus = smbus.SMBus(1)
#Lichtsensor (Adresse 0x39) initialisieren
#Power On Mode
bus.write_byte_data(0x39, 0x00 | 0x80, 0x03)
bus.write_byte_data(0x39, 0x01 | 0x80, 0x02)
#kurze Pause
time.sleep(0.5)
#Lichtsensor auslesen
data = bus.read_i2c_block_data(0x39, 0x0c | 0x80, 2)
data1 = bus.read_i2c_block_data(0x39, 0x0e | 0x80, 2)
#Lichtdaten aufbereiten
ch0 = data[1] * 256 + data[0]
ch1 = data1[1] * 256 + data1[0]
#Lichtdaten ausgeben
print "Volles Spektrum (Infrarot+sichtbar) : %d lux" %ch0
print "Infrarot-Wert: %d lux" %ch1
print "sichtbares Licht-Wert : %d lux" %(ch0 - ch1)
#GPIO ports setzen und zuweisen
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
red = 17
green = 27
blue = 22
PIR = 5
GPIO.setup(red, GPIO.OUT)
GPIO.setup(green, GPIO.OUT)
GPIO.setup(blue, GPIO.OUT)
GPIO.setup(PIR, GPIO.IN)
pi = pigpio.pi()
#Variablen definieren
pi.set_PWM_dutycycle(red, 0)
pi.set_PWM_dutycycle(green, 0)
pi.set_PWM_dutycycle(blue, 0)
fade_in_delay = .1
fade_out_delay = .1
delay_time = 5
mycolor = blue
brightness = 200
min_light = 9
moment = 0
RUNNING = True
#Script starten
try:
while RUNNING:
data = bus.read_i2c_block_data(0x39, 0x0c | 0x80, 2)
data1 = bus.read_i2c_block_data(0x39, 0x0e | 0x80, 2)
ch0 = data[1] * 256 + data[0]
ch1 = data1[1] * 256 + data1[0]
light = ch0 - ch1
print "sichtbares Licht-Wert : %d lux" %(light)
if pi.read(PIR):
print "PIR = ON"
else:
print "PIR = OFF"
if moment > 1:
start = moment
else:
start = 0
if (pi.read(PIR) & (light < min_light)):
for x in range(start,brightness):
pi.set_PWM_dutycycle(mycolor, x)
time.sleep(fade_in_delay)
moment = x
while (pi.read(PIR) & (light < min_light)):
time.sleep(delay_time)
if not (pi.read(PIR) & (moment > 0)):
for x in range(brightness, 0, -1):
pi.set_PWM_dutycycle(mycolor, x)
time.sleep(fade_out_delay)
moment = 0
except KeyboardInterrupt:
RUNNING = False
I couldnt transform the usual tools to fix the problem i got by using google. Im also just a beginner in writing own python-scripts. Normally I´m looking for existing codes (like this) and get it done for my own use case.
I am using the following code to get the temperature of a PT100 (3-wire) and a PT1000 (2-wire) simultaneously on my raspberry.
According to https://cdn-learn.adafruit.com/downloads/pdf/adafruit-max31865-rtd-pt100-amplifier.pdf my wiring is correct.
from Max31865 import Max31865
maxGarraum = Max31865()
maxGarraum.initPt100_3WireSensor(26, True)
maxFleisch = Max31865()
maxFleisch.initPt1000_2WireSensor(24, True)
while True:
maxGarraum.getCurrentTemp()
time.sleep(1)
My Max31865.py looks like the following:
import time, math
import RPi.GPIO as GPIO
# import numpy
class Max31865():
def initPt1000_2WireSensor(self, iCsPin):
self.csPin = iCsPin
# Fleischsensor Pt1000 (2-wire)
self.registerCode = 0xA2
self.setupGPIO()
def initPt100_3WireSensor(self, iCsPin):
self.csPin = iCsPin
# Garraumsensor Pt100 (3-wire)
self.registerCode = 0xB2
self.setupGPIO()
def setupGPIO(self):
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(self.csPin, GPIO.OUT)
GPIO.setup(self.misoPin, GPIO.IN)
GPIO.setup(self.mosiPin, GPIO.OUT)
GPIO.setup(self.clkPin, GPIO.OUT)
GPIO.output(self.csPin, GPIO.HIGH)
GPIO.output(self.clkPin, GPIO.LOW)
GPIO.output(self.mosiPin, GPIO.LOW)
def getCurrentTemp(self):is
# b10000000 = 0x80
# 0x8x to specify 'write register value'
# 0xx0 to specify 'configuration register'
#
# 0b10110010 = 0xB2
# Config Register - https://datasheets.maximintegrated.com/en/ds/MAX31865.pdf
# ---------------
# bit 7: Vbias -> 1 (ON)
# bit 6: Conversion Mode -> 0 (MANUAL)
# bit 5: 1-shot ->1 (ON)
# bit 4: 3-wire select -> 1 (3 wire config) (0 for 2-/4-wire)
# bit 3-2: fault detection cycle -> 0 (none)
# bit 1: fault status clear -> 1 (clear any fault)
# bit 0: 50/60 Hz filter select -> 0 (60Hz)
#
# 0b11010010 or 0xD2 for continuous auto conversion
# at 60Hz (faster conversion)
# one shot
self.writeRegister(0, self.registerCode)
# conversion time is less than 100ms
time.sleep(.1) # give it 100ms for conversion
# read all registers
out = self.readRegisters(0, 8)
conf_reg = out[0]
#print("Config register byte: %x" % conf_reg)
[rtd_msb, rtd_lsb] = [out[1], out[2]]
rtd_ADC_Code = ((rtd_msb << 8) | rtd_lsb) >> 1
temp = self.calcTemperature(rtd_ADC_Code)
"""
# High fault threshold
[hft_msb, hft_lsb] = [out[3], out[4]]
hft = ((hft_msb << 8) | hft_lsb) >> 1
# Low fault threshold
[lft_msb, lft_lsb] = [out[5], out[6]]
lft = ((lft_msb << 8) | lft_lsb) >> 1
print ("High fault threshold: ", hft , " --- Low fault threshold: " , lft)
"""
status = out[7]
# 10 Mohm resistor is on breakout board to help
# detect cable faults
# bit 7: RTD High Threshold / cable fault open
# bit 6: RTD Low Threshold / cable fault short
# bit 5: REFIN- > 0.85 x VBias -> must be requested
# bit 4: REFIN- < 0.85 x VBias (FORCE- open) -> must be requested
# bit 3: RTDIN- < 0.85 x VBias (FORCE- open) -> must be requested
# bit 2: Overvoltage / undervoltage fault
# bits 1,0 don't care
# print "Status byte: %x" % status
if ((status & 0x80) == 1):
raise FaultError("High threshold limit (Cable fault/open)")
if ((status & 0x40) == 1):
raise FaultError("Low threshold limit (Cable fault/short)")
if ((status & 0x04) == 1):
raise FaultError("Overvoltage or Undervoltage Error")
return temp
def writeRegister(self, regNum, dataByte):
GPIO.output(self.csPin, GPIO.LOW)
# 0x8x to specify 'write register value'
addressByte = 0x80 | regNum;
# first byte is address byte
#print("Cs-Pin: ", self.csPin, "Addresse: ", addressByte)
self.sendByte(addressByte)
# the rest are data bytes
self.sendByte(dataByte)
GPIO.output(self.csPin, GPIO.HIGH)
def readRegisters(self, regNumStart, numRegisters):
out = []
GPIO.output(self.csPin, GPIO.LOW)
# 0x to specify 'read register value'
self.sendByte(regNumStart)
for byte in range(numRegisters):
data = self.recvByte()
out.append(data)
GPIO.output(self.csPin, GPIO.HIGH)
return out
def sendByte(self, byte):
for bit in range(8):
GPIO.output(self.clkPin, GPIO.HIGH)
if (byte & 0x80):
GPIO.output(self.mosiPin, GPIO.HIGH)
else:
GPIO.output(self.mosiPin, GPIO.LOW)
byte <<= 1
GPIO.output(self.clkPin, GPIO.LOW)
def recvByte(self):
byte = 0x00
for bit in range(8):
GPIO.output(self.clkPin, GPIO.HIGH)
byte <<= 1
if GPIO.input(self.misoPin):
byte |= 0x1
GPIO.output(self.clkPin, GPIO.LOW)
return byte
def calcTemperature(self, RTD_ADC_Code):
global temp
R_REF = 0.0 # Reference Resistor
Res0 = 0.0; # Resistance at 0 degC for 400ohm R_Ref
a = 0.0
b = 0.0
c = 0.0
if (self.registerCode == 0xA2):
############# PT1000 #############
R_REF = 4300.0 # Reference Resistor
Res0 = 1000.0; # Resistance at 0 degC for 430ohm R_Ref
a = .00381
b = -.000000602
# c = -4.18301e-12 # for -200 <= T <= 0 (degC)
c = -0.000000000006
# c = 0 # for 0 <= T <= 850 (degC)
else:
############# PT100 #############
R_REF = 430.0 # Reference Resistor
Res0 = 100.0; # Resistance at 0 degC for 430ohm R_Ref
a = .00390830
b = -.000000577500
# c = -4.18301e-12 # for -200 <= T <= 0 (degC)
c = -0.00000000000418301
# c = 0 # for 0 <= T <= 850 (degC)
Res_RTD = (RTD_ADC_Code * R_REF) / 32768.0 # PT1000 Resistance
#print("CS-Pin: " , self.csPin, " --- ADC-Value: ", RTD_ADC_Code , " --- Resistance: ", round(Res_RTD, 2) , " Ohms")
# Callendar-Van Dusen equation
# Res_RTD = Res0 * (1 + a*T + b*T**2 + c*(T-100)*T**3)
# Res_RTD = Res0 + a*Res0*T + b*Res0*T**2 # c = 0
# (c*Res0)T**4 - (c*Res0)*100*T**3
# + (b*Res0)*T**2 + (a*Res0)*T + (Res0 - Res_RTD) = 0
#
# quadratic formula:
# for 0 <= T <= 850 (degC)
temp = -(a * Res0) + math.sqrt(a * a * Res0 * Res0 - 4 * (b * Res0) * (Res0 - Res_RTD))
temp = round(temp / (2 * (b * Res0)), 2)
# removing numpy.roots will greatly speed things up
# temp_C_numpy = numpy.roots([c*Res0, -c*Res0*100, b*Res0, a*Res0, (Res0 - Res_RTD)])
# temp_C_numpy = abs(temp_C_numpy[-1])
# print "Solving Full Callendar-Van Dusen using numpy: %f" % temp_C_numpy
if (temp < 0): # use straight line approximation if less than 0
# Can also use python lib numpy to solve cubic
# Should never get here in this application
temp = (RTD_ADC_Code / 32) - 256
print ("CSPin " , self.csPin, " - ADC: ", RTD_ADC_Code , " - Resistance: ", round(Res_RTD, 2) , " Ohms - Temp: " , temp)
return temp
##############################################################################################################################
# Programmstart #
###############################################################################################################################
csPin = 0
misoPin = 21
mosiPin = 19
clkPin = 23
registerCode = 0
# BOARD:21,19,23
# BCM: 9,10,11
class FaultError(Exception):
pass
The problem is that I get no data for the PT100-rtd - only for the PT1000.
The wiring with my raspberry must be correct, because I also adapted my code to test the wiring with two PT1000-rtd and it works.
I think that my problem is somewhere at "getCurrentTemp(self)". Maybe at the readRegister(..) and writeRegister(..) with the "regNum" and "regNumStart".
Any idea?
It looks like you are trying to use the circuitPython code.
Look at this location for the latest version of this code.
Follow the instructions and ensure that you have all required
dependencies met on your platform.
Look here for their simple example of how to test.
Good Luck!
I've been working on a small weather station for APRS using Direwolf and some python scripts on my RPi 3.
My dilemma seems simple, but I'm lacking in python knowledge.
I have my main code for my BMP180 sensor that outputs data in a specific format for the temp and pressure. However, I added a humidity sensor but I've been unable to combine the code to get the outputted format that I need.
Here's my main code with the code at the bottom that I need added in to get the desired output (also shown at the bottom for the print job)
i.e.
#050501z000/000g000t042r000p000P000h42b9999 RPI
Where
h42=h+humidity percentage.
#Main BMP180 code
-----------------------------------------------------------------------------
import smbus
import time
import sys
from ctypes import c_short
DEVICE = 0x77 # Default device I2C address
bus = smbus.SMBus(1) # Rev 2 Pi uses 1
def convertToString(data):
# Simple function to convert binary data into
# a string
return str((data[1] + (256 * data[0])) / 1.2)
def getShort(data, index):
# return two bytes from data as a signed 16-bit value
return c_short((data[index] << 8) + data[index + 1]).value
def getUshort(data, index):
# return two bytes from data as an unsigned 16-bit value
return (data[index] << 8) + data[index + 1]
def readBmp180Id(addr=DEVICE):
# Chip ID Register Address
REG_ID = 0xD0
(chip_id, chip_version) = bus.read_i2c_block_data(addr, REG_ID, 2)
return (chip_id, chip_version)
def readBmp180(addr=DEVICE):
# Register Addresses
REG_CALIB = 0xAA
REG_MEAS = 0xF4
REG_MSB = 0xF6
REG_LSB = 0xF7
# Control Register Address
CRV_TEMP = 0x2E
CRV_PRES = 0x34
# Oversample setting
OVERSAMPLE = 3 # 0 - 3
# Read calibration data
# Read calibration data from EEPROM
cal = bus.read_i2c_block_data(addr, REG_CALIB, 22)
# Convert byte data to word values
AC1 = getShort(cal, 0)
AC2 = getShort(cal, 2)
AC3 = getShort(cal, 4)
AC4 = getUshort(cal, 6)
AC5 = getUshort(cal, 8)
AC6 = getUshort(cal, 10)
B1 = getShort(cal, 12)
B2 = getShort(cal, 14)
MB = getShort(cal, 16)
MC = getShort(cal, 18)
MD = getShort(cal, 20)
# Read temperature
bus.write_byte_data(addr, REG_MEAS, CRV_TEMP)
time.sleep(0.005)
(msb, lsb) = bus.read_i2c_block_data(addr, REG_MSB, 2)
UT = (msb << 8) + lsb
# Read pressure
bus.write_byte_data(addr, REG_MEAS, CRV_PRES + (OVERSAMPLE << 6))
time.sleep(0.04)
(msb, lsb, xsb) = bus.read_i2c_block_data(addr, REG_MSB, 3)
UP = ((msb << 16) + (lsb << 8) + xsb) >> (8 - OVERSAMPLE)
# Refine temperature
X1 = ((UT - AC6) * AC5) >> 15
X2 = (MC << 11) / (X1 + MD)
B5 = X1 + X2
temperature = (B5 + 8) >> 4
# Refine pressure
B6 = B5 - 4000
B62 = B6 * B6 >> 12
X1 = (B2 * B62) >> 11
X2 = AC2 * B6 >> 11
X3 = X1 + X2
B3 = (((AC1 * 4 + X3) << OVERSAMPLE) + 2) >> 2
X1 = AC3 * B6 >> 13
X2 = (B1 * B62) >> 16
X3 = ((X1 + X2) + 2) >> 2
B4 = (AC4 * (X3 + 32768)) >> 15
B7 = (UP - B3) * (50000 >> OVERSAMPLE)
P = (B7 * 2) / B4
X1 = (P >> 8) * (P >> 8)
X1 = (X1 * 3038) >> 16
X2 = (-7357 * P) >> 16
pressure = P + ((X1 + X2 + 3791) >> 4)
return (temperature/10.0 * 9/5 +32,pressure/10)
def main():
(chip_id, chip_version) = readBmp180Id()
# print "Chip ID :", chip_id
# print "Version :", chip_version
(temperature,pressure)=readBmp180()
print time.strftime("#%d%H%Mz")+('000g000t0{0:0.0f}r000p000P000h00b{1:0.0f} RPI'.format(temperature, pressure))
if __name__=="__main__":
main()
#Code that needs to be added
import Adafruit_DHT
humidity = Adafruit_DHT.read_retry(Adafruit_DHT.AM2302, 17)
if humidity <= 99:
print('{0:0.0f}'.format(humidity))
else:
print('00')
#Desired output of print
#print time.strftime("#%d%H%Mz")+('000g000t0{0:0.0f}r000p000P000h00b{1:0.0f} RPI'.format(temperature, pressure))
#Where h00 = h(humidity output of the sensor)
Put import at the beginning of script and rest in main()
You can use {:02.0f} to get always two digits - ie. h09
import Adafruit_DHT
def main():
chip_id, chip_version = readBmp180Id()
temperature, pressure = readBmp180()
humidity = Adafruit_DHT.read_retry(Adafruit_DHT.AM2302, 17)
if humidity > 99:
huminidy = 0
print time.strftime("#%d%H%Mz") + '000g000t0{:0.0f}r000p000P000h{:02.0f}b{:0.0f} RPI'.format(temperature, huminidy, pressure)
if __name__=="__main__":
main()
My goal is to use dual RFID RC522 readers with Orange PI.
So far, I have managed to make only one working. (reading google, armbian and orange pi forums). Here is what I have done so far:
Hardware connection:
single RC 522
MOSI ——————————> pin 19
MISO ——————————-> pin 21
SCLK ——————————-> pin 23
SDA ——————————–> pin 24
RST ———————————> pin 22
IRQ ———————————-> NONE
Second reader uses shared pins, except SDA, it goes to pin 26 on orange PI
software:
Install python dev
apt-get install python-dev
Install orangepi_PC_gpio_pyH3 Library
git clone https://github.com/duxingkei33/orangepi_PC_gpio_pyH3.git
cd orangepi_PC_gpio_pyH3
python setup.py install
Install SPI-Py Library
git clone https://github.com/lthiery/SPI-Py.git
cd SPI-Py
python setup.py install
Install MFRC522-python
git clone https://github.com/rasplay/MFRC522-python.git
The tricky part is, MFRC522-python is made to work with RASPBERRY PI on orange pi, one guy offered a solution by modifying MFRC522.py
#import RPi.GPIO as GPIO
import pyA20.gpio as GPIO
import spi
import signal
class MFRC522:
NRSTPD = 22
MAX_LEN = 16
PCD_IDLE = 0x00
PCD_AUTHENT = 0x0E
PCD_RECEIVE = 0x08
PCD_TRANSMIT = 0x04
PCD_TRANSCEIVE = 0x0C
PCD_RESETPHASE = 0x0F
PCD_CALCCRC = 0x03
PICC_REQIDL = 0x26
PICC_REQALL = 0x52
PICC_ANTICOLL = 0x93
PICC_SElECTTAG = 0x93
PICC_AUTHENT1A = 0x60
PICC_AUTHENT1B = 0x61
PICC_READ = 0x30
PICC_WRITE = 0xA0
PICC_DECREMENT = 0xC0
PICC_INCREMENT = 0xC1
PICC_RESTORE = 0xC2
PICC_TRANSFER = 0xB0
PICC_HALT = 0x50
MI_OK = 0
MI_NOTAGERR = 1
MI_ERR = 2
Reserved00 = 0x00
CommandReg = 0x01
CommIEnReg = 0x02
DivlEnReg = 0x03
CommIrqReg = 0x04
DivIrqReg = 0x05
ErrorReg = 0x06
Status1Reg = 0x07
Status2Reg = 0x08
FIFODataReg = 0x09
FIFOLevelReg = 0x0A
WaterLevelReg = 0x0B
ControlReg = 0x0C
BitFramingReg = 0x0D
CollReg = 0x0E
Reserved01 = 0x0F
Reserved10 = 0x10
ModeReg = 0x11
TxModeReg = 0x12
RxModeReg = 0x13
TxControlReg = 0x14
TxAutoReg = 0x15
TxSelReg = 0x16
RxSelReg = 0x17
RxThresholdReg = 0x18
DemodReg = 0x19
Reserved11 = 0x1A
Reserved12 = 0x1B
MifareReg = 0x1C
Reserved13 = 0x1D
Reserved14 = 0x1E
SerialSpeedReg = 0x1F
Reserved20 = 0x20
CRCResultRegM = 0x21
CRCResultRegL = 0x22
Reserved21 = 0x23
ModWidthReg = 0x24
Reserved22 = 0x25
RFCfgReg = 0x26
GsNReg = 0x27
CWGsPReg = 0x28
ModGsPReg = 0x29
TModeReg = 0x2A
TPrescalerReg = 0x2B
TReloadRegH = 0x2C
TReloadRegL = 0x2D
TCounterValueRegH = 0x2E
TCounterValueRegL = 0x2F
Reserved30 = 0x30
TestSel1Reg = 0x31
TestSel2Reg = 0x32
TestPinEnReg = 0x33
TestPinValueReg = 0x34
TestBusReg = 0x35
AutoTestReg = 0x36
VersionReg = 0x37
AnalogTestReg = 0x38
TestDAC1Reg = 0x39
TestDAC2Reg = 0x3A
TestADCReg = 0x3B
Reserved31 = 0x3C
Reserved32 = 0x3D
Reserved33 = 0x3E
Reserved34 = 0x3F
serNum = []
def __init__(self,spd=1000000):
spi.openSPI(speed=spd)
# GPIO.setmode(GPIO.BOARD)
# GPIO.setup(22, GPIO.OUT)
# GPIO.output(self.NRSTPD, 1)
self.MFRC522_Init()
def MFRC522_Reset(self):
self.Write_MFRC522(self.CommandReg, self.PCD_RESETPHASE)
def Write_MFRC522(self,addr,val):
spi.transfer(((addr<<1)&0x7E,val))
def Read_MFRC522(self,addr):
val = spi.transfer((((addr<<1)&0x7E) | 0x80,0))
return val[1]
def SetBitMask(self, reg, mask):
tmp = self.Read_MFRC522(reg)
self.Write_MFRC522(reg, tmp | mask)
def ClearBitMask(self, reg, mask):
tmp = self.Read_MFRC522(reg);
self.Write_MFRC522(reg, tmp & (~mask))
def AntennaOn(self):
temp = self.Read_MFRC522(self.TxControlReg)
if(~(temp & 0x03)):
self.SetBitMask(self.TxControlReg, 0x03)
def AntennaOff(self):
self.ClearBitMask(self.TxControlReg, 0x03)
def MFRC522_ToCard(self,command,sendData):
backData = []
backLen = 0
status = self.MI_ERR
irqEn = 0x00
waitIRq = 0x00
lastBits = None
n = 0
i = 0
if command == self.PCD_AUTHENT:
irqEn = 0x12
waitIRq = 0x10
if command == self.PCD_TRANSCEIVE:
irqEn = 0x77
waitIRq = 0x30
self.Write_MFRC522(self.CommIEnReg, irqEn|0x80)
self.ClearBitMask(self.CommIrqReg, 0x80)
self.SetBitMask(self.FIFOLevelReg, 0x80)
self.Write_MFRC522(self.CommandReg, self.PCD_IDLE);
while(i<len(sendData)):
self.Write_MFRC522(self.FIFODataReg, sendData[i])
i = i+1
self.Write_MFRC522(self.CommandReg, command)
if command == self.PCD_TRANSCEIVE:
self.SetBitMask(self.BitFramingReg, 0x80)
i = 2000
while True:
n = self.Read_MFRC522(self.CommIrqReg)
i = i - 1
if ~((i!=0) and ~(n&0x01) and ~(n&waitIRq)):
break
self.ClearBitMask(self.BitFramingReg, 0x80)
if i != 0:
if (self.Read_MFRC522(self.ErrorReg) & 0x1B)==0x00:
status = self.MI_OK
if n & irqEn & 0x01:
status = self.MI_NOTAGERR
if command == self.PCD_TRANSCEIVE:
n = self.Read_MFRC522(self.FIFOLevelReg)
lastBits = self.Read_MFRC522(self.ControlReg) & 0x07
if lastBits != 0:
backLen = (n-1)*8 + lastBits
else:
backLen = n*8
if n == 0:
n = 1
if n > self.MAX_LEN:
n = self.MAX_LEN
i = 0
while i<n:
backData.append(self.Read_MFRC522(self.FIFODataReg))
i = i + 1;
else:
status = self.MI_ERR
return (status,backData,backLen)
def MFRC522_Request(self, reqMode):
status = None
backBits = None
TagType = []
self.Write_MFRC522(self.BitFramingReg, 0x07)
TagType.append(reqMode);
(status,backData,backBits) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE, TagType)
if ((status != self.MI_OK) | (backBits != 0x10)):
status = self.MI_ERR
return (status,backBits)
def MFRC522_Anticoll(self):
backData = []
serNumCheck = 0
serNum = []
self.Write_MFRC522(self.BitFramingReg, 0x00)
serNum.append(self.PICC_ANTICOLL)
serNum.append(0x20)
(status,backData,backBits) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE,serNum)
if(status == self.MI_OK):
i = 0
if len(backData)==5:
while i<4:
serNumCheck = serNumCheck ^ backData[i]
i = i + 1
if serNumCheck != backData[i]:
status = self.MI_ERR
else:
status = self.MI_ERR
return (status,backData)
def CalulateCRC(self, pIndata):
self.ClearBitMask(self.DivIrqReg, 0x04)
self.SetBitMask(self.FIFOLevelReg, 0x80);
i = 0
while i<len(pIndata):
self.Write_MFRC522(self.FIFODataReg, pIndata[i])
i = i + 1
self.Write_MFRC522(self.CommandReg, self.PCD_CALCCRC)
i = 0xFF
while True:
n = self.Read_MFRC522(self.DivIrqReg)
i = i - 1
if not ((i != 0) and not (n&0x04)):
break
pOutData = []
pOutData.append(self.Read_MFRC522(self.CRCResultRegL))
pOutData.append(self.Read_MFRC522(self.CRCResultRegM))
return pOutData
def MFRC522_SelectTag(self, serNum):
backData = []
buf = []
buf.append(self.PICC_SElECTTAG)
buf.append(0x70)
i = 0
while i<5:
buf.append(serNum[i])
i = i + 1
pOut = self.CalulateCRC(buf)
buf.append(pOut[0])
buf.append(pOut[1])
(status, backData, backLen) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE, buf)
if (status == self.MI_OK) and (backLen == 0x18):
print "Size: " + str(backData[0])
return backData[0]
else:
return 0
def MFRC522_Auth(self, authMode, BlockAddr, Sectorkey, serNum):
buff = []
buff.append(authMode)
buff.append(BlockAddr)
i = 0
while(i < len(Sectorkey)):
buff.append(Sectorkey[i])
i = i + 1
i = 0
while(i < len(serNum)):
buff.append(serNum[i])
i = i +1
(status, backData, backLen) = self.MFRC522_ToCard(self.PCD_AUTHENT,buff)
if not(status == self.MI_OK):
print "AUTH ERROR!!"
if not (self.Read_MFRC522(self.Status2Reg) & 0x08) != 0:
print "AUTH ERROR(status2reg & 0x08) != 0"
return status
def MFRC522_Read(self, blockAddr):
recvData = []
recvData.append(self.PICC_READ)
recvData.append(blockAddr)
pOut = self.CalulateCRC(recvData)
recvData.append(pOut[0])
recvData.append(pOut[1])
(status, backData, backLen) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE, recvData)
if not(status == self.MI_OK):
print "Error while reading!"
print "Got data size: "+str(backLen)
i = 0
if len(backData) == 16:
print "Sector "+str(blockAddr)+" "+str(backData)
def MFRC522_Write(self, blockAddr, writeData):
buff = []
buff.append(self.PICC_WRITE)
buff.append(blockAddr)
crc = self.CalulateCRC(buff)
buff.append(crc[0])
buff.append(crc[1])
(status, backData, backLen) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE, buff)
if not(status == self.MI_OK) or not(backLen == 4) or not((backData[0] & 0x0F) == 0x0A):
status = self.MI_ERR
print str(backLen)+" backdata &0x0F == 0x0A "+str(backData[0]&0x0F)
if status == self.MI_OK:
i = 0
buf = []
while i < 16:
buf.append(writeData[i])
i = i + 1
crc = self.CalulateCRC(buf)
buf.append(crc[0])
buf.append(crc[1])
(status, backData, backLen) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE,buf)
if not(status == self.MI_OK) or not(backLen == 4) or not((backData[0] & 0x0F) == 0x0A):
print "Error while writing"
if status == self.MI_OK:
print "Data writen"
def MFRC522_Init(self):
# GPIO.output(self.NRSTPD, 1)
self.MFRC522_Reset();
self.Write_MFRC522(self.TModeReg, 0x8D)
self.Write_MFRC522(self.TPrescalerReg, 0x3E)
self.Write_MFRC522(self.TReloadRegL, 30)
self.Write_MFRC522(self.TReloadRegH, 0)
self.Write_MFRC522(self.TxAutoReg, 0x40)
self.Write_MFRC522(self.ModeReg, 0x3D)
self.AntennaOn()
def GPIO_CLEEN(self):
GPIO.cleanup()
4 lines are commented (109 - 111, 357) and first line is replaced to use pyA20.gpio instead of RPi.GPIO.
After that, I run read.py and it works like a charm.
import MFRC522
import signal
continue_reading = True
MIFAREReader = MFRC522.MFRC522()
cardA = [5,74,28,185,234]
cardB = [83,164,247,164,164]
cardC = [20,38,121,207,132]
def end_read(signal, frame):
global continue_reading
continue_reading = False
print "Ctrl+C captured, ending read."
MIFAREReader.GPIO_CLEEN()
signal.signal(signal.SIGINT, end_read)
while continue_reading:
(status,TagType) = MIFAREReader.MFRC522_Request(MIFAREReader.PICC_REQIDL)
if status == MIFAREReader.MI_OK:
print "Card detected"
(status,backData) = MIFAREReader.MFRC522_Anticoll()
if status == MIFAREReader.MI_OK:
print "Card read UID: "+str(backData[0])+","+str(backData[1])+","+str(backData[2])+","+str(backData[3])+","+str(backData[4])
if backData == cardA:
print "is Card A"
elif backData == cardB:
print "is Card B"
elif backData == cardC:
print "is Card C"
else:
print "wrong Card"
That is the way to use the reader on ORANGE PI PC. I googled and read further, in order to use second reader I need to modify exact same lines that I commented in order it to work. It controls RC522 with that SDA PIN, chooses from which reader to read the data. I try to uncomment any of them, but errors appear. Looks like those use specific RPi.GPIO functions. My python knowledge is very basic. I try to find where exactly are described pins that are used, and failed. Tried just to replace that pin 24 with 26 in order to read data from second readed. So far no success.
I have very similar setup and have had similar problems.
It seems I managed to solve them, just last night! :)
My project involves:
Orange pi zero
12-13 RFID-RC522 modules (for now only 2)
SPI communication
since I will need lots of digital output pins I will use 12-13 shift register ICs (74HC595)
Approaches and problems:
connect together SCK, MISO and MOSI pins, pull RST high, control each SS line separately by modifying MFRC522 class. Didn't work, maybe my timings were off, should connect logic analyzer and see.
connect together SCK, MISO, MOSI AND SS pins, pull RST high, switch on/off Vcc or GND pins (power down all readers but one, read from that one, switch to next). Didn't work and presented very interesting situation. In some cases RFID module can read cards even with Vcc, or GND, or both pins DISCONNECTED!!! There is some significant leakage current from the signal pins. Here I tried demuxes, shift registers, line driver ICs, nothing worked.
Finally, approach that DOES work. Connect together SCK, MISO, MOSI AND SS pins, control RST pin. RST when pulled low powers down module. Pull it up to power-on. So, initially all RST pins are pulled low, then one-by-one are pulled high, small delay to allow module to boot up (I use 200ms), call MFRC522_Init() (not sure if necessary in each cycle, doesn't hurt I guess), perform read, pull RST low, switch to next module. Nice side effect of this approach is low power consumption: 2 powered-down modules draw 3.6mA, 1 on - 1 off draw 18mA.
Hope this helps! :)
It was been a while, i had learn a little, made two RC522 readers to work on ESP8266, but same scenario can be used on ORANCE PI, in my previous attempt I was trying to make them work in separate SPI interface, now I use one interface and control them with SS (SDA) signal, when is send LOW on it, reader is active for communication. That way can be used more than one and control them that way. Hope that help to someone who seek an answers here :)
I want a normal format for the MAC-Address I got from get_node().
The format I get is 0x0L0xdL0x60L0x76L0x31L0xd6L, I want the 0x deleted and the L-term to a real hex number. It should be 00-0D-60-76-31-D6 .
How can I realize this?
def getNetworkData (self):
myHostname, myIP, myMAC = AU.getHostname()
touple1 = (myMAC & 0xFF0000000000) >> 40
touple2 = (myMAC & 0x00FF00000000) >> 32
touple3 = (myMAC & 0x0000FF000000) >> 24
touple4 = (myMAC & 0x000000FF0000) >> 16
touple5 = (myMAC & 0x00000000FF00) >> 8
touple6 = (myMAC & 0x0000000000FF) >> 0
readableMACadress = hex(touple1) + hex(touple2) + hex(touple3) + hex(touple4) + hex(touple5) + hex(touple6)
print readableMACadress
return myHostname, myIP, readableMACadress
Use
readableMACaddress = '%02X-%02X-%02X-%02X-%02X-%02X' % (touple1, touple2, touple3, touple4, touple5, touple6)
More concisely, you can eliminate the temporary touple variables by using
readableMACaddress = '-'.join('%02X' % ((myMAC >> 8*i) & 0xff) for i in reversed(xrange(6)))