Hilfe bei neuer Funktion in LS7366R.py
Verfasst: Samstag 4. November 2017, 01:00
Hallo zusammen,
ich versuche das Script LS7366R.py von hier mit der Funktion WRITE_DTR + LOAD_COUNTER (Zeile def loadCounter(self, enc_val):) zu erweitern um einen Startzählerwert vorzugeben.
Bisher sind meine Versuche gescheitert, bekomme zwar keine Fehlermeldung aber auch der Wert (9999) wird nicht in den LS7366R geschrieben. Jetzt hab ich hier gelesen wie man in der Arduino Sprache den Byte-Wert zerlegt und in den LS7366R schreibt, nur weiß ich nicht wie ich das in Python hinbekomme den dezimalen Wert 9999 in bytes umzuwandeln und dann rüzuberschreiben.
hier mein LS7366R.py:
und hier Auszüge für die byte Umwandlung und Übertragung aus dem zweiten Link:
Wäre super nett wenn ihr mir helfen könntet
Gruß
Thilo
ich versuche das Script LS7366R.py von hier mit der Funktion WRITE_DTR + LOAD_COUNTER (Zeile def loadCounter(self, enc_val):) zu erweitern um einen Startzählerwert vorzugeben.
Bisher sind meine Versuche gescheitert, bekomme zwar keine Fehlermeldung aber auch der Wert (9999) wird nicht in den LS7366R geschrieben. Jetzt hab ich hier gelesen wie man in der Arduino Sprache den Byte-Wert zerlegt und in den LS7366R schreibt, nur weiß ich nicht wie ich das in Python hinbekomme den dezimalen Wert 9999 in bytes umzuwandeln und dann rüzuberschreiben.
hier mein LS7366R.py:
Code: Alles auswählen
#!/usr/bin/python
#Python library to interface with the chip LS7366R for the Raspberry Pi
#Written by Federico Bolanos
#Source: https://github.com/fbolanos/LS7366R
#Last Edit: February 8th 2016
#Reason: Refactoring some names
import sys
import spidev
from time import sleep
# Usage: import LS7366R then create an object by calling enc = LS7366R(CSX, CLK, BTMD)
# CSX is either CE0 or CE1, CLK is the speed, BTMD is the bytemode 1-4 the resolution of your counter.
# example: lever.Encoder(0, 1000000, 4)
# These are the values I normally use.
class LS7366R():
#-------------------------------------------
# Constants
# Commands
CLEAR_COUNTER = 0x20
CLEAR_STATUS = 0x30
READ_COUNTER = 0x60
READ_STATUS = 0x70
WRITE_DTR = 0x98
LOAD_COUNTER = 0xE0
LOAD_OTR = 0xE4
WRITE_MODE0 = 0x88
WRITE_MODE1 = 0x90
# Count Operating Modes
# 0x00: non-quadrature count mode. (A = clock, B = direction).
# 0x01: x1 quadrature count mode (one count per quadrature cycle).
# 0x02: x2 quadrature count mode (two counts per quadrature cycle).
# 0x03: x4 quadrature count mode (four counts per quadrature cycle).
FOURX_COUNT = 0x01
# Count Byte Modes
FOURBYTE_COUNTER = 0x00 # counts from 0 to 4,294,967,295
THREEBYTE_COUNTER = 0x01 # counts from 0 to 16,777,215
TWOBYTE_COUNTER = 0x02 # counts from 0 to 65,535
ONEBYTE_COUNTER = 0x03 # counts from 0 to 255
# Enable/disable counter
EN_CNTR = 0x00 # counting enabled
DIS_CNTR = 0x04 # counting disabled
BYTE_MODE = [ONEBYTE_COUNTER, TWOBYTE_COUNTER, THREEBYTE_COUNTER, FOURBYTE_COUNTER]
# Values
max_val = 4294967295
# Global Variables
counterSize = 4 #Default 4
#----------------------------------------------
# Constructor
def __init__(self, CSX, CLK, BTMD):
self.counterSize = BTMD #Sets the byte mode that will be used
self.spi = spidev.SpiDev() #Initialize object
self.spi.open(0, CSX) #Which CS line will be used
self.spi.max_speed_hz = CLK #Speed of clk (modifies speed transaction)
#Init the Encoder
print 'Clearing Encoder CS%s\'s Count...\t' % (str(CSX)), self.clearCounter()
print 'Clearing Encoder CS%s\'s Status..\t' % (str(CSX)), self.clearStatus()
self.spi.xfer2([self.WRITE_MODE0, self.FOURX_COUNT])
sleep(.1) #Rest
self.spi.xfer2([self.WRITE_MODE1, self.BYTE_MODE[self.counterSize-1]])
def close(self):
print '\nThanks for using me! :)'
self.spi.close()
def clearCounter(self):
self.spi.xfer2([self.CLEAR_COUNTER])
return '[DONE]'
def clearStatus(self):
self.spi.xfer2([self.CLEAR_STATUS])
return '[DONE]'
def loadCounter(self, enc_val): # neue Funktion @Thilo
VAL = [hex(enc_val).upper()]
loadTransaction = [self.WRITE_DTR]
self.spi.xfer2(loadTransaction, VAL)
self.spi.xfer2([self.LOAD_COUNTER])
return '[DONE]'
def readCount(self): # andere Vorgehensweise @Thilo
readTransaction = [self.READ_COUNTER]
for i in range(self.counterSize):
readTransaction.append(0)
data = self.spi.xfer2(readTransaction)
if self.counterSize == 4:
count_value = (data[1]<<24) + (data[2]<<16) + (data[3]<<8) + (data[4])
else:
if self.counterSize == 3:
count_value = (data[1]<<16) + (data[2]<<8) + (data[3])
else:
if self.counterSize == 2:
count_value = (data[1]<<8) + (data[2])
else:
count_value = data[1]
return count_value
def readCounter(self):
readTransaction = [self.READ_COUNTER]
for i in range(self.counterSize):
readTransaction.append(0)
data = self.spi.xfer2(readTransaction)
EncoderCount = 0
for i in range(self.counterSize):
EncoderCount = (EncoderCount << 8) + data[i+1]
if data[1] != 255:
return ("+" + str(EncoderCount))
else:
return (EncoderCount - (self.max_val+1))
def readStatus(self):
data = self.spi.xfer2([self.READ_STATUS, 0xFF])
return data[1]
if __name__ == "__main__":
from time import sleep
encoder = LS7366R(0, 1000000, 4)
try:
while True:
sys.stdout.write('\rEncoder count: ' + str(encoder.readCounter())+" CTRL+C for exit",)
sys.stdout.flush()
sleep(0.2)
except KeyboardInterrupt:
encoder.close()
print "All done, bye bye."
Code: Alles auswählen
// =================================================================================
// Wrong, DTR changes its width with the byte mode. This function needs to be fixed
// to reflect those changes.
void LS7366R::writeDTR(unsigned long set){
byte b1, b2, b3, b4;
b1 = set & 0xFF;
b2 = (set >> 8) & 0xFF;
b3 = (set >> 16) & 0xFF;
b4 = (set >> 32) & 0xFF;
digitalWrite(_SS, LOW);
SPI.transfer(0x98); // Write DTR
SPI.transfer(b1);
SPI.transfer(b2);
SPI.transfer(b3);
SPI.transfer(b4);
digitalWrite(_SS, HIGH);
}
// =================================================================================
Gruß
Thilo