summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tests/extmod_hardware/machine_counter.py90
-rw-r--r--tests/extmod_hardware/machine_encoder.py99
2 files changed, 189 insertions, 0 deletions
diff --git a/tests/extmod_hardware/machine_counter.py b/tests/extmod_hardware/machine_counter.py
new file mode 100644
index 000000000..62ac1fed4
--- /dev/null
+++ b/tests/extmod_hardware/machine_counter.py
@@ -0,0 +1,90 @@
+# Test machine.Counter implementation
+#
+# IMPORTANT: This test requires hardware connections: the out_pin and in_pin
+# must be wired together.
+
+try:
+ from machine import Counter
+except ImportError:
+ print("SKIP")
+ raise SystemExit
+
+import sys
+from machine import Pin
+
+if "esp32" in sys.platform:
+ id = 0
+ out_pin = 4
+ in_pin = 5
+else:
+ print("Please add support for this test on this platform.")
+ raise SystemExit
+
+import unittest
+
+out_pin = Pin(out_pin, mode=Pin.OUT)
+in_pin = Pin(in_pin, mode=Pin.IN)
+
+
+def toggle(times):
+ for _ in range(times):
+ out_pin(1)
+ out_pin(0)
+
+
+class TestCounter(unittest.TestCase):
+ def setUp(self):
+ out_pin(0)
+ self.counter = Counter(id, in_pin)
+
+ def tearDown(self):
+ self.counter.deinit()
+
+ def assertCounter(self, value):
+ self.assertEqual(self.counter.value(), value)
+
+ def test_connections(self):
+ # Test the hardware connections are correct. If this test fails, all tests will fail.
+ out_pin(1)
+ self.assertEqual(1, in_pin())
+ out_pin(0)
+ self.assertEqual(0, in_pin())
+
+ def test_count_rising(self):
+ self.assertCounter(0)
+ toggle(100)
+ self.assertCounter(100)
+ out_pin(1)
+ self.assertEqual(self.counter.value(0), 101)
+ self.assertCounter(0) # calling value(0) resets
+ out_pin(0)
+ self.assertCounter(0) # no rising edge
+ out_pin(1)
+ self.assertCounter(1)
+
+ def test_change_directions(self):
+ self.assertCounter(0)
+ toggle(100)
+ self.assertCounter(100)
+ self.counter.init(in_pin, direction=Counter.DOWN)
+ self.assertCounter(0) # calling init() zeroes the counter
+ self.counter.value(100) # need to manually reset the value
+ self.assertCounter(100)
+ toggle(25)
+ self.assertCounter(75)
+
+ def test_count_falling(self):
+ self.counter.init(in_pin, direction=Counter.UP, edge=Counter.FALLING)
+ toggle(20)
+ self.assertCounter(20)
+ out_pin(1)
+ self.assertCounter(20) # no falling edge
+ out_pin(0)
+ self.assertCounter(21)
+ self.counter.value(-(2**24))
+ toggle(20)
+ self.assertCounter(-(2**24 - 20))
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/tests/extmod_hardware/machine_encoder.py b/tests/extmod_hardware/machine_encoder.py
new file mode 100644
index 000000000..9bd2bb464
--- /dev/null
+++ b/tests/extmod_hardware/machine_encoder.py
@@ -0,0 +1,99 @@
+# Test machine.Encoder implementation
+#
+# IMPORTANT: This test requires hardware connections:
+# - out0_pin and in0_pin must be wired together.
+# - out1_pin and in1_pin must be wired together.
+
+try:
+ from machine import Encoder
+except ImportError:
+ print("SKIP")
+ raise SystemExit
+
+import sys
+from machine import Pin
+
+if "esp32" in sys.platform:
+ id = 0
+ out0_pin = 4
+ in0_pin = 5
+ out1_pin = 12
+ in1_pin = 13
+else:
+ print("Please add support for this test on this platform.")
+ raise SystemExit
+
+import unittest
+
+out0_pin = Pin(out0_pin, mode=Pin.OUT)
+in0_pin = Pin(in0_pin, mode=Pin.IN)
+out1_pin = Pin(out1_pin, mode=Pin.OUT)
+in1_pin = Pin(in1_pin, mode=Pin.IN)
+
+
+class TestEncoder(unittest.TestCase):
+ def setUp(self):
+ out0_pin(0)
+ out1_pin(0)
+ self.enc = Encoder(id, in0_pin, in1_pin)
+ self.pulses = 0 # track the expected encoder position in software
+
+ def tearDown(self):
+ self.enc.deinit()
+
+ def rotate(self, pulses):
+ for _ in range(abs(pulses)):
+ self.pulses += 1 if (pulses > 0) else -1
+ q = self.pulses % 4
+ # Only one pin should change state each "step" so output won't glitch
+ out0_pin(q in (1, 2))
+ out1_pin(q in (2, 3))
+
+ def assertPosition(self, value):
+ self.assertEqual(self.enc.value(), value)
+
+ def test_connections(self):
+ # 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)):
+ print("Testing channel ", ch)
+ outp(1)
+ self.assertEqual(1, inp())
+ outp(0)
+ self.assertEqual(0, inp())
+
+ def test_basics(self):
+ self.assertPosition(0)
+ self.rotate(100)
+ self.assertPosition(100 // 4)
+ self.rotate(-100)
+ self.assertPosition(0)
+
+ def test_partial(self):
+ # With phase=1 (default), need 4x pulses to count a rotation
+ self.assertPosition(0)
+ self.rotate(1)
+ self.assertPosition(0)
+ self.rotate(1)
+ self.assertPosition(0)
+ self.rotate(1)
+ self.assertPosition(1) # only 3 pulses to count first rotation?
+ self.rotate(1)
+ self.assertPosition(1)
+ self.rotate(1)
+ self.assertPosition(1)
+ self.rotate(1)
+ self.assertPosition(1)
+ self.rotate(1)
+ self.assertPosition(2) # 4 for next rotation
+ self.rotate(-1)
+ self.assertPosition(1)
+ self.rotate(-4)
+ self.assertPosition(0)
+ self.rotate(-4)
+ self.assertPosition(-1)
+ self.rotate(-3)
+ self.assertPosition(-1)
+
+
+if __name__ == "__main__":
+ unittest.main()