diff --git a/html/pymata4/private_constants.html b/html/pymata4/private_constants.html
index 18f9ae2..e55b86e 100644
--- a/html/pymata4/private_constants.html
+++ b/html/pymata4/private_constants.html
@@ -79,7 +79,7 @@
Module pymata4.private_constants
PWM_MESSAGE = 0xE0 # Firmata confusingly conflates analog input with PWM output
REPORT_VERSION = 0xF9 # report protocol version
- # start of FirmataPlus defined SYSEX commands
+ # start of FirmataExpress defined SYSEX commands
KEEP_ALIVE = 0x50 # keep alive message
ARE_YOU_THERE = 0x51 # poll for boards existence
I_AM_HERE = 0x52 # response to poll
@@ -111,7 +111,7 @@ Module pymata4.private_constants
SYSEX_REALTIME = 0x7F # MIDI Reserved for realtime messages
# reserved for PyMata
- PYMATA_EXPRESS_THREADED_VERSION = "1.00"
+ PYMATA_EXPRESS_THREADED_VERSION = "1.01"
# each byte represents a digital port
# and its value contains the current port settings
@@ -206,7 +206,7 @@
PWM_MESSAGE = 0xE0 # Firmata confusingly conflates analog input with PWM output
REPORT_VERSION = 0xF9 # report protocol version
- # start of FirmataPlus defined SYSEX commands
+ # start of FirmataExpress defined SYSEX commands
KEEP_ALIVE = 0x50 # keep alive message
ARE_YOU_THERE = 0x51 # poll for boards existence
I_AM_HERE = 0x52 # response to poll
@@ -238,7 +238,7 @@
SYSEX_REALTIME = 0x7F # MIDI Reserved for realtime messages
# reserved for PyMata
- PYMATA_EXPRESS_THREADED_VERSION = "1.00"
+ PYMATA_EXPRESS_THREADED_VERSION = "1.01"
# each byte represents a digital port
# and its value contains the current port settings
diff --git a/pymata4/private_constants.py b/pymata4/private_constants.py
index b1b4b0e..89f912b 100644
--- a/pymata4/private_constants.py
+++ b/pymata4/private_constants.py
@@ -70,7 +70,7 @@ class PrivateConstants:
SYSEX_REALTIME = 0x7F # MIDI Reserved for realtime messages
# reserved for PyMata
- PYMATA_EXPRESS_THREADED_VERSION = "1.01"
+ PYMATA_EXPRESS_THREADED_VERSION = "1.02"
# each byte represents a digital port
# and its value contains the current port settings
diff --git a/pymata4/pymata4.py b/pymata4/pymata4.py
index 8cc8f40..6c4ca5c 100644
--- a/pymata4/pymata4.py
+++ b/pymata4/pymata4.py
@@ -790,8 +790,7 @@ def keep_alive(self, period=1, margin=.3):
will physically reset itself.
Frequency of keep alive transmission is calculated as follows:
- keep_alive_sent = period - (period * margin)
-
+ keep_alive_sent = period - margin
:param period: Time period between keepalives. Range is 0-10 seconds.
0 disables the keepalive mechanism.
@@ -1347,6 +1346,9 @@ def _digital_message(self, data):
# get pin value
value = port_data & 0x01
+ # retrieve previous value
+ last_value = self.digital_pins[pin].current_value
+
# set the current value in the pin structure
self.digital_pins[pin].current_value = value
time_stamp = time.time()
@@ -1358,8 +1360,9 @@ def _digital_message(self, data):
else:
message = [PrivateConstants.INPUT, pin, value, time_stamp]
- if self.digital_pins[pin].cb:
- self.digital_pins[pin].cb(message)
+ if last_value != value:
+ if self.digital_pins[pin].cb:
+ self.digital_pins[pin].cb(message)
port_data >>= 1
diff --git a/pypi_desc.md b/pypi_desc.md
index d0d2815..3b3a39f 100644
--- a/pypi_desc.md
+++ b/pypi_desc.md
@@ -18,7 +18,7 @@ Pymata4 is a Firmata client that, like its asyncio sibling,
* **Piezo Tone Generation.**
* **Baud rate of 115200**
-Major features
+### Major features
* **Fully documented intuitive API**
diff --git a/setup.py b/setup.py
index cec80db..b399d6e 100644
--- a/setup.py
+++ b/setup.py
@@ -11,7 +11,7 @@
packages=['pymata4'],
install_requires=['pyserial'],
- version='1.01',
+ version='1.02',
description="A Python Protocol Abstraction Library For Arduino Firmata",
long_description=long_description,
long_description_content_type='text/markdown',