mirror of
https://github.com/micropython/micropython.git
synced 2025-12-16 09:50:15 +01:00
tests/extmod_hardware/machine_encoder.py: Fix initial rotation count.
ESP32 requires initial high levels of the channels before starting the count, in order to have 4 pulse for the first rotation. Also add tests for encoder phases x2 and x4. Signed-off-by: Ihor Nehrutsa <Ihor.Nehrutsa@gmail.com>
This commit is contained in:
committed by
Damien George
parent
f3804c6589
commit
d980bbd237
@@ -13,6 +13,9 @@ except ImportError:
|
|||||||
import sys
|
import sys
|
||||||
from machine import Pin
|
from machine import Pin
|
||||||
|
|
||||||
|
PRINT = False
|
||||||
|
PIN_INIT_VALUE = 1
|
||||||
|
|
||||||
if "esp32" in sys.platform:
|
if "esp32" in sys.platform:
|
||||||
id = 0
|
id = 0
|
||||||
out0_pin = 4
|
out0_pin = 4
|
||||||
@@ -33,25 +36,70 @@ in1_pin = Pin(in1_pin, mode=Pin.IN)
|
|||||||
|
|
||||||
class TestEncoder(unittest.TestCase):
|
class TestEncoder(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
out0_pin(0)
|
out0_pin(PIN_INIT_VALUE)
|
||||||
out1_pin(0)
|
out1_pin(PIN_INIT_VALUE)
|
||||||
self.enc = Encoder(id, in0_pin, in1_pin)
|
self.enc = Encoder(id, in0_pin, in1_pin, phases=1)
|
||||||
|
self.enc2 = Encoder(id + 1, in0_pin, in1_pin, phases=2)
|
||||||
|
self.enc4 = Encoder(id + 2, in0_pin, in1_pin, phases=4)
|
||||||
self.pulses = 0 # track the expected encoder position in software
|
self.pulses = 0 # track the expected encoder position in software
|
||||||
|
if PRINT:
|
||||||
|
print(
|
||||||
|
"\nout0_pin() out1_pin() enc.value() enc2.value() enc4.value() |",
|
||||||
|
out0_pin(),
|
||||||
|
out1_pin(),
|
||||||
|
"|",
|
||||||
|
self.enc.value(),
|
||||||
|
self.enc2.value(),
|
||||||
|
self.enc4.value(),
|
||||||
|
)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
self.enc.deinit()
|
self.enc.deinit()
|
||||||
|
try:
|
||||||
|
self.enc2.deinit()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
self.enc4.deinit()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
def rotate(self, pulses):
|
def rotate(self, pulses):
|
||||||
for _ in range(abs(pulses)):
|
for _ in range(abs(pulses)):
|
||||||
self.pulses += 1 if (pulses > 0) else -1
|
self.pulses += 1 if (pulses > 0) else -1
|
||||||
q = self.pulses % 4
|
if pulses > 0:
|
||||||
# Only one pin should change state each "step" so output won't glitch
|
if self.pulses % 2:
|
||||||
out0_pin(q in (1, 2))
|
out0_pin(not out0_pin())
|
||||||
out1_pin(q in (2, 3))
|
else:
|
||||||
|
out1_pin(not out1_pin())
|
||||||
|
else:
|
||||||
|
if self.pulses % 2:
|
||||||
|
out1_pin(not out1_pin())
|
||||||
|
else:
|
||||||
|
out0_pin(not out0_pin())
|
||||||
|
if PRINT:
|
||||||
|
print(
|
||||||
|
"out0_pin() out1_pin() enc.value() enc2.value() enc4.value() pulses self.pulses |",
|
||||||
|
out0_pin(),
|
||||||
|
out1_pin(),
|
||||||
|
"|",
|
||||||
|
self.enc.value(),
|
||||||
|
self.enc2.value(),
|
||||||
|
self.enc4.value(),
|
||||||
|
"|",
|
||||||
|
pulses,
|
||||||
|
self.pulses,
|
||||||
|
)
|
||||||
|
|
||||||
def assertPosition(self, value):
|
def assertPosition(self, value, value2=None, value4=None):
|
||||||
self.assertEqual(self.enc.value(), value)
|
self.assertEqual(self.enc.value(), value)
|
||||||
|
if not value2 is None:
|
||||||
|
self.assertEqual(self.enc2.value(), value2)
|
||||||
|
if not value4 is None:
|
||||||
|
self.assertEqual(self.enc4.value(), value4)
|
||||||
|
pass
|
||||||
|
|
||||||
|
@unittest.skipIf(sys.platform == "mimxrt", "cannot read back the pin")
|
||||||
def test_connections(self):
|
def test_connections(self):
|
||||||
# Test the hardware connections are correct. If this test fails, all tests will fail.
|
# Test the hardware connections are correct. If this test fails, all tests will fail.
|
||||||
for ch, outp, inp in ((0, out0_pin, in0_pin), (1, out1_pin, in1_pin)):
|
for ch, outp, inp in ((0, out0_pin, in0_pin), (1, out1_pin, in1_pin)):
|
||||||
@@ -64,7 +112,7 @@ class TestEncoder(unittest.TestCase):
|
|||||||
def test_basics(self):
|
def test_basics(self):
|
||||||
self.assertPosition(0)
|
self.assertPosition(0)
|
||||||
self.rotate(100)
|
self.rotate(100)
|
||||||
self.assertPosition(100 // 4)
|
self.assertPosition(100 // 4, 100 // 2, 100)
|
||||||
self.rotate(-100)
|
self.rotate(-100)
|
||||||
self.assertPosition(0)
|
self.assertPosition(0)
|
||||||
|
|
||||||
@@ -72,27 +120,39 @@ class TestEncoder(unittest.TestCase):
|
|||||||
# With phase=1 (default), need 4x pulses to count a rotation
|
# With phase=1 (default), need 4x pulses to count a rotation
|
||||||
self.assertPosition(0)
|
self.assertPosition(0)
|
||||||
self.rotate(1)
|
self.rotate(1)
|
||||||
self.assertPosition(0)
|
self.assertPosition(1, 1, 1)
|
||||||
self.rotate(1)
|
self.rotate(1)
|
||||||
self.assertPosition(0)
|
self.assertPosition(1, 1, 2)
|
||||||
self.rotate(1)
|
self.rotate(1)
|
||||||
self.assertPosition(1) # only 3 pulses to count first rotation?
|
self.assertPosition(1, 2, 3)
|
||||||
self.rotate(1)
|
self.rotate(1)
|
||||||
self.assertPosition(1)
|
self.assertPosition(1, 2, 4) # +4
|
||||||
self.rotate(1)
|
self.rotate(1)
|
||||||
self.assertPosition(1)
|
self.assertPosition(2, 3, 5)
|
||||||
self.rotate(1)
|
self.rotate(1)
|
||||||
self.assertPosition(1)
|
self.assertPosition(2, 3, 6)
|
||||||
self.rotate(1)
|
self.rotate(1)
|
||||||
self.assertPosition(2) # 4 for next rotation
|
self.assertPosition(2, 4, 7)
|
||||||
|
self.rotate(1)
|
||||||
|
self.assertPosition(2, 4, 8) # +4
|
||||||
self.rotate(-1)
|
self.rotate(-1)
|
||||||
self.assertPosition(1)
|
self.assertPosition(2, 4, 7)
|
||||||
self.rotate(-4)
|
|
||||||
self.assertPosition(0)
|
|
||||||
self.rotate(-4)
|
|
||||||
self.assertPosition(-1)
|
|
||||||
self.rotate(-3)
|
self.rotate(-3)
|
||||||
self.assertPosition(-1)
|
self.assertPosition(1, 2, 4) # -4
|
||||||
|
self.rotate(-4)
|
||||||
|
self.assertPosition(0, 0, 0) # -4
|
||||||
|
self.rotate(-1)
|
||||||
|
self.assertPosition(0, 0, -1)
|
||||||
|
self.rotate(-1)
|
||||||
|
self.assertPosition(0, -1, -2)
|
||||||
|
self.rotate(-1)
|
||||||
|
self.assertPosition(0, -1, -3)
|
||||||
|
self.rotate(-1)
|
||||||
|
self.assertPosition(-1, -2, -4) # -4
|
||||||
|
self.rotate(-1)
|
||||||
|
self.assertPosition(-1, -2, -5)
|
||||||
|
self.rotate(-3)
|
||||||
|
self.assertPosition(-2, -4, -8) # -4
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
Reference in New Issue
Block a user