Commits

Tino de Bruijn  committed a40ea79

added tests for default message handlers

  • Participants
  • Parent commits f3feab1

Comments (0)

Files changed (2)

File pyfirmata/pyfirmata.py

     """
     Base class for any board
     """
+    firmata_version = None
+    command_handlers = {}
     
     def __init__(self, port, type="arduino", baudrate=57600):
         self.sp = serial.Serial(port, baudrate)
         # Allow 2 secs for Arduino's auto-reset to happen
-        self.pass_time(2)
+        # self.pass_time(2)
         self.type = type
-        self.command_handlers = {}
         self.setup_layout(BOARDS[type])
         
     def __str__(self):
         return True
 
     def _handle_report_version(self, data):
-        if len(data) < 3:
+        if len(data) < 2:
             return False
         major, minor = data
         self.firmata_version = (major, minor)
-
-        
+        return True
 
 class Port(object):
     """ An 8-bit port on the board """
 
 import pyfirmata
 from pyfirmata import mockup
+from pyfirmata.util import to_7_bits
 
-class TestLiveBoards(unittest.TestCase):
-    """
-    Test two live boards. On the 'transmitter' board:
-    
-    - connect 5v and analog port 0 directly
-    - connect digital port 2 to the 'receiver' board's analog port 2 directly
-    - connect digital port 5 to the 'receiver' board's analog port 5 directly
-    - connect 3v to the 'receiver' board's analog port 1 directly
-    
-    On the 'receiver' board:
-    
-    - connect ground and analog port 0 directly
-    
-    ..note::
-        This test can take quite a while, as it may take about 4 seconds each
-        time the setUp function is called.
-    """
-    
-    def setUp(self):
-        self.boards = pyfirmata.Boards()
-        assert len(self.boards) >= 2, "Only %d board(s) found. I need at least 2!" % len(boards)
-        x, y = self.boards.values()[0], self.boards.values()[1]
-        it1, it2 = pyfirmata.Iterator(x), pyfirmata.Iterator(y)
-        it1.start(), it2.start()
-        # give iterator time to iterate
-        self.pass_time(0.1)
-        x0, y0 = x.get_pin('a:0:i'), y.get_pin('a:0:i')
-        self.pass_time(0.1)
-        if x0.read() > 0.9 and y0.read() < 0.1: # x is transmitter
-            self.transmitter = x
-            self.receiver = y
-        elif y0.read() > 0.9 and x0.read() < 0.1: # y is transmitter
-            self.transmitter = x
-            self.receiver = y
-        else:
-            self.fail("Could not complete setup. One, and only one of the \
-                board's analog ports should be set high by connecting it to \
-                its 5v output. That board will be considered the transmitter. \
-                Values received: %f and %f" % (x0.read(), y0.read()))
-        self.Ta0 = self.transmitter.analog[0] # already taken by line 36
-        self.Ra1 = self.receiver.get_pin('a:1:i')
-        self.Ra2 = self.receiver.get_pin('a:2:i')
-        self.Ra5 = self.receiver.get_pin('a:5:i')
-        self.Td2 = self.transmitter.get_pin('d:2:o')
-        self.Td5 = self.transmitter.get_pin('d:5:p')
-        self.Td13 = self.transmitter.get_pin('d:13:o')
-        
-    def iterate(self):
-        self.transmitter.iterate()
-        self.receiver.iterate()
-        
-    def pass_time(self, t):
-        cont = time.time() + t
-        while time.time() < cont:
-            pass
-            
-    def test_led(self):
-        self.Td13.write(1)
-        print "Transmitters d13 should be high for 2 seconds..."
-        self.pass_time(2)
-        self.assertEqual(self.Td13.read(), 1)
-        
-    def test_high(self):
-        self.pass_time(0.1)
-        value = self.Ta0.read()
-        self.failIf(value < 0.99, msg="Too low: %f" % value) # Connected to 5v, it should be almost 1
-        value = self.Ra1.read()
-        self.failUnless(0.65 < value < 0.69, msg="not getting 3v! (%f not between 0.65 and 0.69)" % value) # Connected to 3v
-        
-    def test_in_out(self):
-        self.Td2.write(1)
-        self.pass_time(0.1)
-        value = self.Ra2.read()
-        self.failIf(value < 0.99, msg="Not high enough: %f" % value)
-        self.Td2.write(0)
-        self.assert_(self.Td2.read() == 0)
-        self.pass_time(0.1)
-        value = self.Ra2.read()
-        self.failIf(value > 0.01, msg="Too high: %f" % value)
+# This protocol uses the MIDI message format, but does not use the whole
+# protocol.  Most of the command mappings here will not be directly usable in
+# terms of MIDI controllers and synths.  It should co-exist with MIDI without
+# trouble and can be parsed by standard MIDI interpreters.  Just some of the
+# message data is used differently.
+# 
+# MIDI format: http://www.harmony-central.com/MIDI/Doc/table1.html
+# 
+#                              MIDI       
+# type                command  channel    first byte            second byte 
+# ---------------------------------------------------------------------------
+# analog I/O message    0xE0   pin #      LSB(bits 0-6)         MSB(bits 7-13)
+# digital I/O message   0x90   port       LSB(bits 0-6)         MSB(bits 7-13)
+# report analog pin     0xC0   pin #      disable/enable(0/1)   - n/a -
+# report digital port   0xD0   port       disable/enable(0/1)   - n/a -
+# 
+# sysex start           0xF0   
+# set pin mode(I/O)     0xF4              pin # (0-127)         pin state(0=in)
+# sysex end             0xF7   
+# protocol version      0xF9              major version         minor version
+# system reset          0xFF
 
-    # pwm into analog doesn't work...
-    def test_pwm(self):
-        self.pass_time(0.5)
-        # test high
-        self.Td5.write(1.0)
-        self.pass_time(1)
-        value = self.Ra5.read()
-        self.failUnless(0.99 < value < 1.0, msg="%f not between 0.99 and 1.0" % value)
-        # test middle
-        self.Td5.write(0.5)
-        self.pass_time(0.5)
-        value = self.Ra5.read()
-        self.failUnless(0.49 < value < 0.51, msg="%f not between 0.49 and 0.51" % value)
-        # test low
-        self.Td5.write(0.1)
-        self.pass_time(0.5)
-        value = self.Ra5.read()
-        self.failUnless(0.09 < value < 0.11, msg="%f not between 0.09 and 0.11" % value)
-        
-    def tearDown(self):
-        self.boards.exit()
+
 
 class TestBoard(unittest.TestCase):
     # TODO Test layout of Board Mega
         pyfirmata.pyfirmata.serial.Serial = mockup.MockupSerial
         self.board = pyfirmata.Board('test')
         # self.board.setup_layout(pyfirmata.BOARDS['normal'])
+        
+    
+    def test_handle_analog_message(self):
+        self.assertEqual(self.board.analog[3].read(), None)
+        # Test it returns false with not enough params
+        self.assertFalse(self.board._handle_analog_message([3, 127]))
+        # This sould set it correctly. 1023 (127, 7 in to 7 bit bytes) is the
+        # max value an analog pin will send and it should result in a value 1
+        self.assertTrue(self.board._handle_analog_message([3, 127, 7]))
+        self.assertEqual(self.board.analog[3].read(), 1)
+        
+    def test_handle_digital_message(self):
+        self.assertEqual(self.board.digital[5].read(), None)
+        # Test it returns false with not enough params
+        self.assertFalse(self.board._handle_digital_message([5, 1]))
+        # This should set it correctly.
+        self.assertTrue(self.board._handle_digital_message([5, 1, 0]))
+        self.assertEqual(self.board.digital[5].read(), 1)
+        
+    def test_handle_firmata_version(self):
+        self.assertEqual(self.board.firmata_version, None)
+        self.assertFalse(self.board._handle_report_version([1]))
+        self.assertTrue(self.board._handle_report_version([2, 1]))
+        self.assertEqual(self.board.firmata_version, (2, 1))
 
     def test_pwm_layout(self):
         pins = []
 
 
 suite = unittest.TestLoader().loadTestsFromTestCase(TestBoard)
-live_suite = unittest.TestLoader().loadTestsFromTestCase(TestLiveBoards)
 mockup_suite = unittest.TestLoader().loadTestsFromTestCase(TestMockupBoard)
 
 if __name__ == '__main__':