I have raspberry Pi 4 and it is connected to LS7366R, but I am not using the CS0 or cs1, am using any GPIO and controlling it (high/low) manually.
the encoder has A and B signals, and they are connected to the chip with a pull up resistor.
I am trying to write a code that gives me how many times the encoder rotates.
my code right now gives me values when the encoder rotates (positive to clockwise and negative counterclockwise) but the problem is these values doesn't make sense, because they change also based on the speed on the rotation.
https://wiki.dfrobot.com/Incremental_Photoelectric_Rotary_Encoder_-_400P_R_SKU__SEN0230 https://sdr-files.s3.us-east-2.amazonaws.com/product_info/LS7366R.pdf
I got the code from: https://github.com/corncobb/LS3766R-Raspberry-Pi/tree/master and changed it using ChatGPTt
this is my code:
import spidev
from time import sleep
import RPi.GPIO as GPIO
class LS7366R():
# Constants
CLEAR_COUNTER = 0x20
CLEAR_STATUS = 0x30
READ_COUNTER = 0x60
READ_STATUS = 0x70
WRITE_MODE0 = 0x88
WRITE_MODE1 = 0x90
# Modes
QUADRATURE_COUNT_MODE = 0x01
FOURBYTE_COUNTER = 0x00
THREEBYTE_COUNTER = 0x01
TWOBYTE_COUNTER = 0x02
ONEBYTE_COUNTER = 0x03
BYTE_MODE = [ONEBYTE_COUNTER, TWOBYTE_COUNTER, THREEBYTE_COUNTER, FOURBYTE_COUNTER]
# Values
max_val = 4294967295
# Global Variables
counterSize = 4
cs_pin = 23 # Set chip select pin to GPIO 23
#----------------------------------------------
# Constructor
def __init__(self, CSX, CLK, BTMD):
self.counterSize = BTMD
self.spi = spidev.SpiDev()
self.spi.open(0, CSX)
GPIO.setmode(GPIO.BCM)
self.cs_pin = 23 # Reassign the chip select pin
GPIO.setup(self.cs_pin, GPIO.OUT)
GPIO.output(self.cs_pin, GPIO.HIGH) # Set CS pin high initially
self.spi.max_speed_hz = CLK
GPIO.output(self.cs_pin, GPIO.LOW) # Set CS pin high initially
# 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.QUADRATURE_COUNT_MODE])
sleep(0.1)
self.spi.xfer2([self.WRITE_MODE1, self.BYTE_MODE[self.counterSize-1]])
GPIO.output(self.cs_pin, GPIO.HIGH) # Set CS pin high initially
def close(self):
print('\nThanks for using me! :)')
self.spi.close()
def clearCounter(self):
GPIO.output(self.cs_pin, GPIO.LOW) # Set CS pin low before sending command
self.spi.xfer2([self.CLEAR_COUNTER])
GPIO.output(self.cs_pin, GPIO.HIGH) # Set CS pin high after command
return '[DONE]'
def clearStatus(self):
GPIO.output(self.cs_pin, GPIO.LOW) # Set CS pin low before sending command
self.spi.xfer2([self.CLEAR_STATUS])
GPIO.output(self.cs_pin, GPIO.HIGH) # Set CS pin high after command
return '[DONE]'
def readCounter(self):
GPIO.output(self.cs_pin, GPIO.LOW) # Set CS pin low before sending command
readTransaction = [self.READ_COUNTER]
for i in range(self.counterSize):
readTransaction.append(0)
data = self.spi.xfer2(readTransaction)
GPIO.output(self.cs_pin, GPIO.HIGH) # Set CS pin high after command
EncoderCount = 0
for i in range(self.counterSize):
EncoderCount = (EncoderCount << 8) + data[i+1]
if data[1] != 255:
return EncoderCount
else:
return (EncoderCount - (self.max_val+1))
def readStatus(self):
GPIO.output(self.cs_pin, GPIO.LOW) # Set CS pin low before sending command
data = self.spi.xfer2([self.READ_STATUS, 0xFF])
GPIO.output(self.cs_pin, GPIO.HIGH) # Set CS pin high after command
return data[1]
if __name__ == "__main__":
from time import sleep
encoder = LS7366R(0, 1000000, 4) # Use CS0 for chip select
try:
while True:
print("Encoder count: ", encoder.readCounter(), " Press CTRL-C to terminate test program.")
sleep(0.5)
except KeyboardInterrupt:
encoder.close()
print("All done, bye bois.")