def initiateADXL345(): # Creates SPI object with the following parameters: # - SPI device as "/dev/spidev1.0" # - Clock mode 3 (i.e., sets clock polarity 1, clock phase 1) # - Clock frequency set to 400KHz spi = SPI("/dev/spidev1.0", 3, 400000) # Address 0x31 OR'd with 0x40 MB bit. # Set to 0x08: 16g Full (13-bit) Resolution - 4mg/LSB. setDataFormat = [0x71, 0x0F] # Address 0x2D OR'd with 0x40 MB bit. # Set to 0x08: Measurement mode. setPowerCtl = [0x6D, 0x08] # Address 0x2C OR'd with 0x40 MB bit. # Set to 0x0D: 800 Hz Output Data Rate setDataRate = [0x6C, 0x0D] # Transfer settings to ADXL345. spi.transfer(setDataFormat) spi.transfer(setPowerCtl) spi.transfer(setDataRate) return spi
def initiateADXL345(): # Creates SPI object with the following parameters: # - SPI device as "/dev/spidev1.0" # - Clock mode 3 (i.e., sets clock polarity 1, clock phase 1) # - Clock frequency set to 400KHz spi = SPI("/dev/spidev1.0",3,400000) # Address 0x31 OR'd with 0x40 MB bit. # Set to 0x08: 16g Full (13-bit) Resolution - 4mg/LSB. setDataFormat = [0x71,0x0F] # Address 0x2D OR'd with 0x40 MB bit. # Set to 0x08: Measurement mode. setPowerCtl = [0x6D,0x08] # Address 0x2C OR'd with 0x40 MB bit. # Set to 0x0D: 800 Hz Output Data Rate setDataRate = [0x6C,0x0D] # Transfer settings to ADXL345. spi.transfer(setDataFormat) spi.transfer(setPowerCtl) spi.transfer(setDataRate) return spi
def query(slave_name, command, args=[]): """Selects the given SPI slave, sends it the SPI command and returns the received response as a stripped string. @param slave_name: _KNOWN_SPI_SLAVES key. @param command: _KNOWN_SPI_SLAVES[slave_name]['commands'] key. @param args: list of strings to be sent as command arguments. """ _select_spi_slave(slave_name) spi = SPI(_SPI_BUS_SETTINGS['dev'], _SPI_BUS_SETTINGS['mode'], _SPI_BUS_SETTINGS['freq_hz']) full_command = _KNOWN_SPI_SLAVES[slave_name]['commands'][command] if args: full_command += ' ' + ','.join(args) full_command += '*' + int_to_hex_string(_crc(full_command)) full_command = (bytes(full_command, 'ascii') + _SPI_MESSAGE_SEPARATOR).ljust(_SPI_COMMAND_LENGTH, b'\x00') response = spi.transfer(full_command) response = response.split(_SPI_MESSAGE_SEPARATOR)[0] spi.close() printable_response = ''.join(map(lambda ascii_num: chr(ascii_num), filter(lambda char: char >= 0x20 and char < 0x7f, response))) return printable_response
class MCP3208(object): MAX_CLOCK_SPEED = 2E+6 RESOLUTION = 0b1 << 12 SECOND_WORD_MASK = 0b00001111 def __init__(self): self.spi = SPI( config.get('MCP3208', 'device_file'), 0, MCP3208.MAX_CLOCK_SPEED ) self.Vref = config.getfloat('MCP3208', 'vref') def read(self): mosi_data = self._make_mosi_data() miso_data = self.spi.transfer(mosi_data) _, second_word, third_word = miso_data value = ((MCP3208.SECOND_WORD_MASK & second_word) << 8) + third_word return value * self.Vref / MCP3208.RESOLUTION def clean_up(self): self.spi.close() def _make_mosi_data(self): ch = config.getint('MCP3208', 'ch') raw_data = 0b0000011000 + ch first_word = (0b11100 & raw_data) >> 2 second_word = (0b11 & raw_data) << 6 return [first_word, second_word, 0b0]
class SpiPeripheryInterface(SpiBaseInterface): """ using `python-periphery` to send data""" def __init__(self, **kwargs): super().__init__(**kwargs) if not os.path.exists(self._dev): self.error(errors.CANT_FIND_ERROR) try: from periphery import SPI self._spi = SPI(self._dev, 0, self._spi_speed * 1e6) except ImportError: self.error(errors.CANT_IMPORT_PERIPHERY_ERROR) log.info('periphery spi dev {:s} speed @ {:.2f} MHz'.format( self._dev, self._spi.max_speed / 1e6)) def send_packet(self, data): package_size = 4032 # bit smaller than 4096 because of headers for i in range(int(math.ceil(len(data) / package_size))): start = i * package_size end = (i + 1) * package_size self._spi.transfer(data[start:end])
def initiateADXL345(): # Creates SPI object with the following parameters: # - SPI device as "/dev/spidev1.0" # - Clock mode 3 (i.e., sets clock polarity 1, clock phase 1) # - Clock frequency set to 5 MHz spi = SPI("/dev/spidev1.0", 3, 5000000) # Address 0x31 OR'd with 0x40 MB bit. # Set to 0x08: Full Resolution - 4mg/LSB. setDataFormat = [0x71, 0x0F] # Address 0x2D OR'd with 0x40 MB bit. # Set to 0x08: Measurement mode. setPowerCtl = [0x6D, 0x08] # print ("\n Setting Data Format... \n") spi.transfer(setDataFormat) # print ("\n Setting Power Control... \n") spi.transfer(setPowerCtl) return spi
''' 1: pip3 install python-periphery 2: cd /dev 3: ls 查看是否有spidev1.0的口 4: CLK为时钟,MOSI=发送, MISO=接收 5:鹏师傅74HC595串行通信,需要找一个IO口给一个上沿电平,先设置为低然后spi发消息,然后设置为高,再设置为低 GPIO.setmode(GPIO.BOARD) GPIO.setwarnings(False) GPIO.setup(12, GPIO.OUT) CS引脚默认打开,就可以不使用额外引脚了 ''' from periphery import SPI # Open spidev0.0 with mode 0 and max speed 1MHz spi = SPI("/dev/spidev0.0", 0, 1000000) # 树莓派有2个SPI CM4有5个SPI tx_msg = b'\x00\x01' tx_return = spi.transfer(tx_msg) rx_msg = spi.read() spi.close()
class Jedec: def __init__(self, device): self.spi=SPI(device, 0, 24000000) def sendit(self, request,resplen): # Padding for response data buffer=request + [0] * resplen reqlen=len(request) # send the data and get the response response=self.spi.transfer(buffer) return response[reqlen:] def RDID(self): response={} # op code 0x9f, response 3 bytes data=self.sendit([0x9f], 6) # First byte - manufacturer ID response['manufacturer']=[] i=1 response['manufacturer'].append(data[0]) if (chr(data[0]) == 0x7f): response['manufacturer'].append(data[i]) i+=1 if (chr(data[1]) == 0x7f): response['manufacturer'].append(data[i]) i+=1 if (chr(data[2]) == 0x7f): response['manufacturer'].append(data[i]) i+=1 response['type']=data[i] response['density']=data[i+1] return response def RES(self): response={} # op code 0xAB, response 3 bytes data=self.sendit([0xAB,0,0,0], 1) # First byte - manufacturer ID response['density']=chr(data[0]) return response def REMS(self): response={} # op code 0x90, response 2 bytes data=self.sendit([0x90,0,0], 2) # First byte - manufacturer ID response['manufacturer']=chr(data[0]) response['device']=chr(data[1]) return response def RDSCUR(self): response={} data=self.sendit([0x2B], 1) response['security']=chr(data[0]) return response def RDSR(self): response={} data=self.sendit([0x05], 1) response['status']=chr(data[0]) return response def READ(self, address, length): # op code 0x03 request=[0x03] # address is 3 bytes request.append((address & 0xff0000) >> 16) request.append((address & 0xff00) >> 8) request.append(address & 0xff) data=self.sendit(request, length) return ''.join(chr(x) for x in data) def RAW(self, data, length): # op code 0x03 request=data # address is 3 bytes d=self.sendit(request, length) print request return ''.join(chr(x) for x in d) def WREN(self): # op code 06 d=self.sendit([0x06],0) def RST(self): # op code 00 d=self.sendit([0x00],0) def WRDI(self): # op code 04 d=self.sendit([0x04],0) def PP(self, address, data): # op code 02 request=[0x2]
from periphery import SPI import time spi = SPI("/dev/spidev0.0", 0, 50000000,"msb",8,0) while True: #for y in range (0x04,0x08): for x in range(0x00,0x100): #if y==0x07 & x==0x9b: # break init= [0x18,0x03] data_in = spi.transfer(init) data_out = [0x04, x] data_in = spi.transfer(data_out) time.sleep(0.5) print("shifted out [0x%02x, 0x%02x]" % tuple(data_out))
#analyze from periphery import SPI spi = SPI("/dev/spidev0.0", 1, 500 * 1000) buff = [0x03, 0x0E, 0xFF] txt = input("address in hex(default 0x0E):") if txt != "": buff[1] = int(txt, 16) result = spi.transfer(buff) print("register address:0x%02X -- value:0x%02X" % (buff[1], result[2])) spi.close() #device tree SPI without CS from periphery import SPI from periphery import GPIO CS = GPIO("/dev/gpiochip0", 12, "out") spi = SPI("/dev/spidev0.0", 1, 1000000) tx = [0x02, 0x0F, 0x80] rx = [0x03, 0x0E] CS.write(False) spi.transfer(tx) CS.write(True) CS.write(False)
#!/usr/bin/python3 from periphery import SPI import time spi = SPI("/dev/spidev0.0", 0, 10000) while 1: data=spi.transfer([0]) print(data) time.sleep(0.1) spi.close()
class SPIComms(object): # Message headers defined for this communication protocl HEADERS = {"heartbeat": b'\x10', "message": b'\x20', "config": b'\x30'} def __init__(self, source): self.source = source self.data_length = self.source.get_flatten_length() # Store heartbeat received from microcontroller # Used to make sure that microcontroller is still available self.prev_heartbeat_count = 0 self.heartbeat_count = 0 # Create the data format message # Message is 4 bytes long # Defined in communication doc self.data_format_message = [0, self.data_length, 0, 0] self.spi = None self.signal_pin = None self.comm_thread = None self.max_error_count = 50 self.data_lock = threading.Lock() self.data = np.zeros(shape=(self.data_length, ), dtype=np.float32) def start(self): # Open spidev0.0 device with mode 0 and max speed 100 kHz if (self.spi is None): self.spi = SPI("/dev/spidev0.0", 0, 30000) #, bit_order= "lsb") # Open GPIO pin connection if (self.signal_pin is None): self.signal_pin = GPIO(6, "in") if (self.comm_thread is None): print("starting comms thread") self.comm_thread = threading.Thread(target=self._comm_thread_fn, daemon=True) self.comm_thread.start() def set_data(self, data): with self.data_lock: np.copyto(self.data, data) def _comm_thread_fn(self): while True: # Initialize the communications with the microcontoller self._comm_init() error_count = 0 while error_count < self.max_error_count: # heartbeat header self.prev_heartbeat_count = self.heartbeat_count self.heartbeat_count = int.from_bytes( self.spi.transfer(self.HEADERS["heartbeat"]), "little") if (self.heartbeat_count <= self.prev_heartbeat_count): print("ERROR") error_count += 1 else: error_count = 0 if (self.signal_pin.read()): print("Transferring data") self.spi.transfer(self.HEADERS['message']) with self.data_lock: self.data = self.source.tobytes() self.spi.transfer(self.data) time.sleep(0.01) def _comm_init(self): # Flags to store where in the comm init program is init_signal_received = False print("Starting init") # Create an array storing the responses received from the microcontroller responses = [b'\x00', b'\x00', b'\x00'] # Loop init process while not init_signal_received: # Pop the first response and append the last response responses.pop(0) responses.append(self.spi.transfer(b'\xFF')) startTime = time.time() # Read pin for 100 ms to check for correct response # Correct response is high on the signal pin and 0xFF, 0xFE, 0xFD heartbeat sequence while time.time() - startTime < 0.1: if (self.signal_pin.read() and responses == [b'\xff', b'\xfe', b'\xfd']): init_signal_received = True break print("Received signal, waiting for heartbeat") self.spi.transfer(self.HEADERS["config"]) responses = self.spi.transfer(b'\x00\x00\x00\x00') # Store the last two heartbeats self.prev_heartbeat_count = responses[2] self.heartbeat_count = responses[3] print("Heartbeat received, successful init!") # Wait until we receive request for data while (not self.signal_pin.read()): time.sleep(0.1) print("Received high on pin") print("Transmitting format message") # Transferring data format message self.spi.transfer(self.HEADERS["config"]) time.sleep(1) self.spi.transfer(self.data_format_message)
# Set to 0x02: 8g range setDataFormat = [0x71, 0x02] # Address 0x2D OR'd with 0x40 MB bit # Set to 0x08: Measurement mode. setPowerCtl = [0x6D, 0x08] # This is the DATAX0 register (0x32) OR'd with Read bit (0x80) # and Multiple Bytes bit (0x40). It is followed by 6 0x00 values # to read 6 bytes starting from DATAX0. When transferred, this # returns 7 bytes: NULL (0x00), DATAX0 (0x32), DATAX1 (0x33), # DATAY0 (0x34), DATAY1 (0x35), DATAZ0 (0x36), and DATAZ1 (0x37). dataX0 = [0xF2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] print("\n Setting Data Format... \n") spi.transfer(setDataFormat) print("\n Setting Power Control... \n") spi.transfer(setPowerCtl) # Takes LSB and MSB from any given axis # and converts them into an integer # from -256 to 255 def calcValue(lsb, msb): if msb == 255: trueValue = -256 + lsb else: trueValue = lsb return trueValue
# Set to 0x02: 8g range setDataFormat = [0x71,0x02] # Address 0x2D OR'd with 0x40 MB bit # Set to 0x08: Measurement mode. setPowerCtl = [0x6D,0x08] # This is the DATAX0 register (0x32) OR'd with Read bit (0x80) # and Multiple Bytes bit (0x40). It is followed by 6 0x00 values # to read 6 bytes starting from DATAX0. When transferred, this # returns 7 bytes: NULL (0x00), DATAX0 (0x32), DATAX1 (0x33), # DATAY0 (0x34), DATAY1 (0x35), DATAZ0 (0x36), and DATAZ1 (0x37). dataX0 = [0xF2,0x00,0x00,0x00,0x00,0x00,0x00] print ("\n Setting Data Format... \n") spi.transfer(setDataFormat) print ("\n Setting Power Control... \n") spi.transfer(setPowerCtl) # Takes LSB and MSB from any given axis # and converts them into an integer # from -256 to 255 def calcValue (lsb, msb): if msb == 255: trueValue = -256 + lsb else: trueValue = lsb return trueValue # This loop constantly outputs the values read from the sensor.
from periphery import SPI spi = SPI("/dev/spidev0.0", 2, 80 * 1000000) buffer = [0x2E] spi.transfer(buffer) spi.close()
class modbusserver(object): def __init__(self, server, slaveid): self.server = server self.slaveid = slaveid self.spi = SPI("/dev/spidev0.0", 1, 125000) #self.spi = spidev.SpiDev() #self.spi.open(0, 0) #self.spi.mode = 0b01 #self.spi.max_speed_hz = 500000 #self.spi.cshigh = False self.senddata = [0] * 41 self.recvdata = [0] * 41 self.metor_value = [0] * 16 self.last_metor_value = [0] * 16 self.coils_value = None self.last_coils_value = None self.led_tmp = [([0] * 8) for i in range(4)] self.led = [0] * 4 self.ai_value = [0] * 22 self.last_ai_value = [0] * 22 self.ai = [0] * 11 self.key_value = [0] * 4 self.last_key_value = [0] * 4 self.key_tmp = [([0] * 8) for i in range(4)] self.key = [0] * 32 self.slave = self.server.get_slave(self.slaveid) GPIO.setmode(GPIO.BCM) GPIO.setup(7, GPIO.IN) def sendtomcu(self): # add command word "UUUU3" self.senddata[0:5] = commandsend # get metor from PC self.metor_value = list( self.slave.get_values('HOLDING_REGISTERS', 0, 16)) #print("metor", self.metor_value) if (self.metor_value != self.last_metor_value): for i in range(0, 16): self.senddata[2 * i + 5] = self.metor_value[i] & 0xff self.senddata[2 * i + 5 + 1] = self.metor_value[i] >> 8 self.last_metor_value = copy.copy(self.metor_value) # get lamp from PC self.coils_value = self.slave.get_values('COILS', 0, 32) self.led_tmp[0] = self.coils_value[0:8] self.led_tmp[1] = self.coils_value[8:16] self.led_tmp[2] = self.coils_value[16:24] self.led_tmp[3] = self.coils_value[24:32] # change di from list to byte if (self.coils_value != self.last_coils_value): # chang 8 bit data to one byte for i in range(0, 4): for j in range(0, 8): if self.led_tmp[i][j] == 0x1: self.led[i] = self.led[i] | 0x80 else: self.led[i] = self.led[i] & 0x7f if j != 7: self.led[i] = self.led[i] >> 1 # package senddata self.senddata[37] = self.led[0] self.senddata[38] = self.led[1] self.senddata[39] = self.led[2] self.senddata[40] = self.led[3] self.last_coils_value = copy.copy(self.coils_value) # print("senddata = ", self.senddata) # Master start SPI transport # GPIO.output(7, GPIO.LOW) self.recvdata = self.spi.transfer(self.senddata) # GPIO.output(7, GPIO.HIGH) # print("recvdata", self.recvdata) # analysis receive data def recvmcu(self): # check command word if (self.recvdata[0:5] == list(commandrecv)): for i in range(0, 22): self.ai_value[i] = self.recvdata[i + 5] if (self.ai_value != self.last_ai_value): for i in range(0, 11): self.ai[i] = (self.ai_value[2 * i] & 0xff) + (self.ai_value[2 * i + 1] << 8) self.slave.set_values('READ_INPUT_REGISTERS', 0, self.ai) self.last_ai_value = copy.copy(self.ai_value) for i in range(0, 4): self.key_value[i] = self.recvdata[i + 27] # change key to list from byte if (self.key_value != self.last_key_value): self.last_key_value = copy.copy(self.key_value) for i in range(0, 4): for j in range(0, 8): if self.key_value[i] & 0x1 == 0x1: self.key_tmp[i][j] = 0x1 else: self.key_tmp[i][j] = 0x0 if j != 7: self.key_value[i] = self.key_value[i] >> 1 self.key[0:8] = self.key_tmp[0] self.key[8:16] = self.key_tmp[1] self.key[16:24] = self.key_tmp[2] self.key[24:32] = self.key_tmp[3] # package recvdaa self.slave.set_values('DISCRETE_INPUTS', 0, self.key)
gpio_out.write(True) data_out = [ ord('S'), ord(':'), ord('P'), ord('R'), ord('E'), ord(' '), ord('I'), ord('R'), ord(' '), ord('\n') ] data_in = spi.transfer(data_out) print("shifted out %-10s" % (''.join(chr(c) for c in data_out), )) print("shifted in %-10s" % (''.join(chr(c) for c in data_in), )) time.sleep(0.1) data_out = [ ord('S'), ord(':'), ord('G'), ord('E'), ord('T'), ord(' '), ord('I'), ord('R'),