From e928ced601f16acdddff54b46c04e1e4f4bfd7f9 Mon Sep 17 00:00:00 2001 From: James Harton Date: Sun, 3 May 2020 10:03:03 +1200 Subject: [PATCH 01/27] Add the Board configuration for Teensy 4.0 --- Boards.h | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/Boards.h b/Boards.h index a56ed8d6..57bf4b6f 100644 --- a/Boards.h +++ b/Boards.h @@ -536,6 +536,36 @@ writePort(port, value, bitmask): Write an 8 bit port. #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) #define PIN_TO_SERVO(p) (p) +// Teensy 4.0 +#elif defined(__IMXRT1062__) +#define TOTAL_ANALOG_PINS 14 +#define TOTAL_PINS 40 +#define VERSION_BLINK_PIN 13 +#define PIN_SERIAL1_RX 0 +#define PIN_SERIAL1_TX 1 +#define PIN_SERIAL2_RX 7 +#define PIN_SERIAL2_TX 8 +#define PIN_SERIAL3_RX 15 +#define PIN_SERIAL3_TX 14 +#define PIN_SERIAL4_RX 16 +#define PIN_SERIAL4_TX 17 +#define PIN_SERIAL5_RX 21 +#define PIN_SERIAL5_TX 20 +#define PIN_SERIAL6_RX 25 +#define PIN_SERIAL6_TX 24 +#define PIN_SERIAL7_RX 28 +#define PIN_SERIAL7_TX 29 +#define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS) +#define IS_PIN_ANALOG(p) ((p) >= 14 && (p) <= 27) +#define IS_PIN_PWM(p) (((p) >= 0 && (p) <= 16) || ((p) >= 18 && (p) <= 19) || ((p) >= 22 && (p) <= 25) || ((p) >= 28 && (p) <= 29)|| ((p) >= 33 && (p) <= 39)) +#define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS) +#define IS_PIN_I2C(p) ((p) == 18 || (p) == 19) +#define IS_PIN_SERIAL(p) (((p) >= 0 && (p) <= 1) || ((p) >= 7 && (p) <= 8) || ((p) >= 14 && (p) <= 17) || ((p) >= 20 && (p) <= 21) || ((p) >= 24 && (p) <= 25) || ((p) >= 28 && (p) <= 29)) +#define PIN_TO_DIGITAL(p) (p) +#define PIN_TO_ANALOG(p) ((p) - 14) +#define PIN_TO_PWM(p) (p) +#define PIN_TO_SERVO(p) (p) + // Leonardo #elif defined(__AVR_ATmega32U4__) From 5f42c13d07600a3019aada39b4fabec9f764d263 Mon Sep 17 00:00:00 2001 From: James Harton Date: Sun, 3 May 2020 10:42:49 +1200 Subject: [PATCH 02/27] Enable support for all seven Teensy 4.0 UARTS. --- utility/SerialFirmata.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/utility/SerialFirmata.h b/utility/SerialFirmata.h index a05b761a..f8ec2d7b 100644 --- a/utility/SerialFirmata.h +++ b/utility/SerialFirmata.h @@ -66,7 +66,7 @@ #define HW_SERIAL4 0x04 #define HW_SERIAL5 0x05 #define HW_SERIAL6 0x06 -// extensible up to 0x07 +#define HW_SERIAL7 0x07 #define SW_SERIAL0 0x08 #define SW_SERIAL1 0x09 @@ -91,6 +91,8 @@ #define RES_TX5 0x0b #define RES_RX6 0x0c #define RES_TX6 0x0d +#define RES_RX7 0x0e +#define RES_TX7 0x0f // Serial command bytes #define SERIAL_CONFIG 0x10 @@ -143,6 +145,10 @@ namespace { #if defined(PIN_SERIAL6_RX) if (pin == PIN_SERIAL6_RX) return RES_RX6; if (pin == PIN_SERIAL6_TX) return RES_TX6; + #endif + #if defined(PIN_SERIAL7_RX) + if (pin == PIN_SERIAL7_RX) return RES_RX7; + if (pin == PIN_SERIAL7_TX) return RES_TX7; #endif return 0; } @@ -193,6 +199,12 @@ namespace { pins.rx = PIN_SERIAL6_RX; pins.tx = PIN_SERIAL6_TX; break; + #endif + #if defined(PIN_SERIAL7_RX) + case HW_SERIAL7: + pins.rx = PIN_SERIAL7_RX; + pins.tx = PIN_SERIAL7_TX; + break; #endif default: pins.rx = 0; From d20889e5acf025f7922b8eff85410036153bd3ff Mon Sep 17 00:00:00 2001 From: Jeff Hoefs Date: Sat, 11 Jul 2020 23:52:08 -0700 Subject: [PATCH 03/27] Fix compile error for M0 boards --- utility/SerialFirmata.h | 1 - 1 file changed, 1 deletion(-) diff --git a/utility/SerialFirmata.h b/utility/SerialFirmata.h index a05b761a..9c905aef 100644 --- a/utility/SerialFirmata.h +++ b/utility/SerialFirmata.h @@ -54,7 +54,6 @@ // serial buffer/message size and the Firmata frame size (4 bytes) to prevent fragmentation // on the transport layer. //#define FIRMATA_SERIAL_RX_DELAY 50 // [ms] -#define FIRMATA_SERIAL_RX_DELAY 50 #define FIRMATA_SERIAL_FEATURE From 61a54c77c748846dfbd2443e081c321e2576b6f9 Mon Sep 17 00:00:00 2001 From: Malik Enes Safak Date: Thu, 20 Aug 2020 21:32:49 +0300 Subject: [PATCH 04/27] New firmata clients for Max and Pure Data --- readme.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/readme.md b/readme.md index 3632b1f6..80a00b83 100644 --- a/readme.md +++ b/readme.md @@ -73,6 +73,7 @@ Most of the time you will be interacting with Arduino with a client library on t * [https://github.com/nfrancois/firmata](https://github.com/nfrancois/firmata) * Max/MSP * [http://www.maxuino.org/](http://www.maxuino.org/) + * [https://github.com/NullMember/MaxFirmata](https://github.com/NullMember/MaxFirmata) * Elixir * [https://github.com/kfatehi/firmata](https://github.com/kfatehi/firmata) * Modelica @@ -85,6 +86,8 @@ Most of the time you will be interacting with Arduino with a client library on t * [http://openframeworks.cc/documentation/communication/ofArduino/](http://openframeworks.cc/documentation/communication/ofArduino/) * Rust * [https://github.com/zankich/rust-firmata](https://github.com/zankich/rust-firmata) +* Pure Data + * [https://github.com/NullMember/PDFirmata](https://github.com/NullMember/PDFirmata) Note: The above libraries may support various versions of the Firmata protocol and therefore may not support all features of the latest Firmata spec nor all Arduino and Arduino-compatible boards. Refer to the respective projects for details. From 06ad2338c4154cf83e9d556f52d7e9ade03cecf3 Mon Sep 17 00:00:00 2001 From: Jeff Hoefs Date: Sun, 29 Nov 2020 15:44:48 -0800 Subject: [PATCH 05/27] add nono-33-iot to Boards.h --- Boards.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Boards.h b/Boards.h index 34610be8..b2d149bd 100644 --- a/Boards.h +++ b/Boards.h @@ -261,6 +261,23 @@ writePort(port, value, bitmask): Write an 8 bit port. #define PIN_TO_SERVO(p) ((p) - 2) +// Arduino Nano 33 IoT +#elif defined(ARDUINO_SAMD_NANO_33_IOT) +#define TOTAL_ANALOG_PINS 8 +#define TOTAL_PINS 22 // 14 Digital + 8 Analog +#define IS_PIN_DIGITAL(p) ((p) < TOTAL_PINS) +#define IS_PIN_ANALOG(p) ((p) > 13 && (p) < 14 + TOTAL_ANALOG_PINS) +#define IS_PIN_PWM(p) digitalPinHasPWM(p) +#define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) < MAX_SERVOS) // deprecated since v2.4 +#define IS_PIN_I2C(p) ((p) == PIN_WIRE_SDA || (p) == PIN_WIRE_SCL) +#define IS_PIN_SPI(p) ((p) == PIN_SPI_SS || (p) == PIN_SPI_MOSI || (p) == PIN_SPI_MISO || (p) == PIN_SPI_SCK) +#define IS_PIN_SERIAL(p) ((p) == PIN_SERIAL1_RX || (p) == PIN_SERIAL1_TX) //defined in variant.h RX = 0 TX = 1 +#define PIN_TO_DIGITAL(p) (p) +#define PIN_TO_ANALOG(p) ((p) - 14) +#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) +#define PIN_TO_SERVO(p) (p) // deprecated since v2.4 + + // Arduino/Genuino MKR1000 or MKR1010 #elif defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_MKRWIFI1010) #define TOTAL_ANALOG_PINS 7 From ff8bc9336e0b70a3821a86b7dca0bdd1f45b1b3d Mon Sep 17 00:00:00 2001 From: Jeff Karney Date: Sun, 28 Mar 2021 15:16:02 -0500 Subject: [PATCH 06/27] Add missing link for PHP Client "carica" The link to https://github.com/ThomasWeinert/carica-firmata was empty so it linked nowhere. Updated to actually link to the URL. --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 80a00b83..f79e8821 100644 --- a/readme.md +++ b/readme.md @@ -63,7 +63,7 @@ Most of the time you will be interacting with Arduino with a client library on t * Pharo * [https://github.com/pharo-iot/Firmata](https://github.com/pharo-iot/Firmata) * PHP - * [https://github.com/ThomasWeinert/carica-firmata]() + * [https://github.com/ThomasWeinert/carica-firmata](https://github.com/ThomasWeinert/carica-firmata) * [https://github.com/oasynnoum/phpmake_firmata](https://github.com/oasynnoum/phpmake_firmata) * Haskell * [http://hackage.haskell.org/package/hArduino](http://hackage.haskell.org/package/hArduino) From 1a30384e9e420949df2e40e1c2759c5fa7c5b343 Mon Sep 17 00:00:00 2001 From: Christopher Stawarz Date: Mon, 12 Apr 2021 15:13:27 -0400 Subject: [PATCH 07/27] Added Arduino Nano 33 BLE to Boards.h --- Boards.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Boards.h b/Boards.h index b2d149bd..fa8a3466 100644 --- a/Boards.h +++ b/Boards.h @@ -278,6 +278,23 @@ writePort(port, value, bitmask): Write an 8 bit port. #define PIN_TO_SERVO(p) (p) // deprecated since v2.4 +// Arduino Nano 33 BLE +#elif defined(ARDUINO_ARDUINO_NANO33BLE) +#define TOTAL_ANALOG_PINS 8 +#define TOTAL_PINS 22 // 14 Digital + 8 Analog +#define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS) +#define IS_PIN_ANALOG(p) ((p) >= 14 && (p) < 14 + TOTAL_ANALOG_PINS) +#define IS_PIN_PWM(p) digitalPinHasPWM(p) +#define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) < MAX_SERVOS) // deprecated since v2.4 +#define IS_PIN_I2C(p) ((p) == PIN_WIRE_SDA || (p) == PIN_WIRE_SCL) // SDA = 18, SCL = 19 +#define IS_PIN_SPI(p) ((p) == PIN_SPI_SS || (p) == PIN_SPI_MOSI || (p) == PIN_SPI_MISO || (p) == PIN_SPI_SCK) +#define IS_PIN_SERIAL(p) ((p) == PIN_SERIAL_RX || (p) == PIN_SERIAL_TX) //defined in pins_arduino.h RX = 1 TX = 0 +#define PIN_TO_DIGITAL(p) (p) +#define PIN_TO_ANALOG(p) ((p) - 14) +#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) +#define PIN_TO_SERVO(p) (p) // deprecated since v2.4 + + // Arduino/Genuino MKR1000 or MKR1010 #elif defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_MKRWIFI1010) #define TOTAL_ANALOG_PINS 7 From dd69de8684d131ca47dcc48da011eca799b290da Mon Sep 17 00:00:00 2001 From: Christopher Stawarz Date: Fri, 7 May 2021 09:29:49 -0400 Subject: [PATCH 08/27] Add support for ArduinoBLE devices to StandardFirmataBLE --- examples/StandardFirmataBLE/bleConfig.h | 39 +++- utility/ArduinoBLE_UART_Stream.cpp | 3 + utility/ArduinoBLE_UART_Stream.h | 256 ++++++++++++++++++++++++ 3 files changed, 291 insertions(+), 7 deletions(-) create mode 100644 utility/ArduinoBLE_UART_Stream.cpp create mode 100644 utility/ArduinoBLE_UART_Stream.h diff --git a/examples/StandardFirmataBLE/bleConfig.h b/examples/StandardFirmataBLE/bleConfig.h index a783ce9b..def71f17 100644 --- a/examples/StandardFirmataBLE/bleConfig.h +++ b/examples/StandardFirmataBLE/bleConfig.h @@ -1,15 +1,15 @@ /*================================================================================================== * BLE CONFIGURATION * - * If you are using an Arduino 101, you do not need to make any changes to this file (unless you - * need a unique ble local name (see below). If you are using another supported BLE board or shield, - * follow the instructions for the specific board or shield below. - * - * Make sure you have the Intel Curie Boards package v2.0.2 or higher installed via the Arduino - * Boards Manager. + * If you are using a device supported by the ArduinoBLE library or an Arduino 101, you do not need + * to make any changes to this file (unless you need a unique ble local name (see below)). If you + * are using another supported BLE board or shield, follow the instructions for the specific board + * or shield below. * * Supported boards and shields: - * - Arduino 101 (recommended) + * - Devices supported by the ArduinoBLE library, including the Arduino MKR WiFi 1010, + * Arduino UNO WiFi Rev.2, Arduino Nano 33 IoT, and Arduino Nano 33 BLE + * - Arduino 101 * - RedBearLab BLE Shield (v2) ** to be verified ** * - RedBearLab BLE Nano ** works with modifications ** * - Adafruit Feather M0 Bluefruit LE @@ -20,6 +20,25 @@ // within the same physical space #define FIRMATA_BLE_LOCAL_NAME "FIRMATA" +/* + * ArduinoBLE devices + * + * Be sure to install the ArduinoBLE library via the Arduino Library Manager. + * + */ +#if defined(ARDUINO_SAMD_MKRWIFI1010) || defined(ARDUINO_AVR_UNO_WIFI_REV2) || defined(ARDUINO_SAMD_NANO_33_IOT) || defined(ARDUINO_ARDUINO_NANO33BLE) +#define ARDUINO_BLE + +// Value is specified in units of 0.625 ms +#define FIRMATA_BLE_ADVERTISING_INTERVAL 32 // 20ms (20 / 0.625) + +// These values are specified in units of 1.25 ms and must be between +// 0x0006 (7.5ms) and 0x0c80 (4s). +#define FIRMATA_BLE_MIN_INTERVAL 0x000c // 15ms (15 / 1.25) +#define FIRMATA_BLE_MAX_INTERVAL 0x0018 // 30ms (30 / 1.25) +#endif + + /* * Arduino 101 * @@ -107,6 +126,12 @@ * END BLE CONFIGURATION - you should not need to change anything below this line *================================================================================================*/ +#ifdef ARDUINO_BLE +#include "utility/ArduinoBLE_UART_Stream.h" +ArduinoBLE_UART_Stream stream; +#endif + + #ifdef _VARIANT_ARDUINO_101_X_ #include "utility/BLEStream.h" BLEStream stream; diff --git a/utility/ArduinoBLE_UART_Stream.cpp b/utility/ArduinoBLE_UART_Stream.cpp new file mode 100644 index 00000000..3fffed30 --- /dev/null +++ b/utility/ArduinoBLE_UART_Stream.cpp @@ -0,0 +1,3 @@ +/* + * Implementation is in ArduinoBLE_UART_Stream.h to avoid linker issues. + */ diff --git a/utility/ArduinoBLE_UART_Stream.h b/utility/ArduinoBLE_UART_Stream.h new file mode 100644 index 00000000..e87c4669 --- /dev/null +++ b/utility/ArduinoBLE_UART_Stream.h @@ -0,0 +1,256 @@ +/* + ArduinoBLE_UART_Stream.h + + Based on BLEStream.h and the HardwareBLESerial library: + https://github.com/Uberi/Arduino-HardwareBLESerial + */ + +#ifndef _ARDUINO_BLE_UART_STREAM_H_ +#define _ARDUINO_BLE_UART_STREAM_H_ + +#include + +#define BLE_ATTRIBUTE_MAX_VALUE_LENGTH 20 + + +class ArduinoBLE_UART_Stream : public Stream +{ + public: + ArduinoBLE_UART_Stream(); + + void setLocalName(const char *localName); + void setAdvertisingInterval(unsigned short advertisingInterval); + void setConnectionInterval(unsigned short minConnInterval, unsigned short maxConnInterval); + void setFlushInterval(int flushInterval); + + void begin(); + bool poll(); + void end(); + + // Print overrides + size_t write(uint8_t byte); + using Print::write; // Expose other write variants + + // Stream overrides + int available(); + int read(); + int peek(); + void flush(); + + private: + void dataReceived(const unsigned char *data, size_t size); + + static void connectedHandler(BLEDevice central); + static void disconnectedHandler(BLEDevice central); + + static void rxWrittenHandler(BLEDevice central, BLECharacteristic characteristic); + + static void txSubscribedHandler(BLEDevice central, BLECharacteristic characteristic); + static void txUnsubscribedHandler(BLEDevice central, BLECharacteristic characteristic); + + BLEService uartService; + BLECharacteristic rxCharacteristic; + BLECharacteristic txCharacteristic; + + String localName; + unsigned short advertisingInterval; + unsigned short minConnInterval; + unsigned short maxConnInterval; + int flushInterval; + + bool connected; + + unsigned char rxBuffer[256]; + size_t rxHead; + size_t rxTail; + + bool txSubscribed; + unsigned char txBuffer[BLE_ATTRIBUTE_MAX_VALUE_LENGTH]; + size_t txCount; + unsigned long lastFlushTime; + + static ArduinoBLE_UART_Stream *instance; +}; + + +ArduinoBLE_UART_Stream::ArduinoBLE_UART_Stream() : + uartService("6E400001-B5A3-F393-E0A9-E50E24DCCA9E"), + rxCharacteristic("6E400002-B5A3-F393-E0A9-E50E24DCCA9E", BLEWriteWithoutResponse | BLEWrite, BLE_ATTRIBUTE_MAX_VALUE_LENGTH), + txCharacteristic("6E400003-B5A3-F393-E0A9-E50E24DCCA9E", BLENotify, BLE_ATTRIBUTE_MAX_VALUE_LENGTH), + advertisingInterval(0), + minConnInterval(0), + maxConnInterval(0), + flushInterval(100), // Default flush interval is 100ms + connected(false), + rxHead(0), + rxTail(0), + txSubscribed(false), + txCount(0), + lastFlushTime(0) +{ + instance = this; +} + +void ArduinoBLE_UART_Stream::setLocalName(const char *localName) +{ + this->localName = localName; +} + +void ArduinoBLE_UART_Stream::setAdvertisingInterval(unsigned short advertisingInterval) +{ + this->advertisingInterval = advertisingInterval; +} + +void ArduinoBLE_UART_Stream::setConnectionInterval(unsigned short minConnInterval, unsigned short maxConnInterval) +{ + this->minConnInterval = minConnInterval; + this->maxConnInterval = maxConnInterval; +} + +void ArduinoBLE_UART_Stream::setFlushInterval(int flushInterval) +{ + // The minimum allowed connection interval is 7.5ms, so don't try to flush + // more frequently than that + this->flushInterval = max(flushInterval, 8); +} + +void ArduinoBLE_UART_Stream::begin() +{ + BLE.begin(); + + if (localName.length() > 0) { + BLE.setLocalName(localName.c_str()); + } + if (advertisingInterval > 0) { + BLE.setAdvertisingInterval(advertisingInterval); + } + if (minConnInterval > 0 && maxConnInterval > 0) { + BLE.setConnectionInterval(minConnInterval, maxConnInterval); + } + + BLE.setEventHandler(BLEConnected, connectedHandler); + BLE.setEventHandler(BLEDisconnected, disconnectedHandler); + + rxCharacteristic.setEventHandler(BLEWritten, rxWrittenHandler); + uartService.addCharacteristic(rxCharacteristic); + + txCharacteristic.setEventHandler(BLESubscribed, txSubscribedHandler); + txCharacteristic.setEventHandler(BLEUnsubscribed, txUnsubscribedHandler); + uartService.addCharacteristic(txCharacteristic); + + BLE.addService(uartService); + BLE.setAdvertisedService(uartService); + BLE.advertise(); +} + +bool ArduinoBLE_UART_Stream::poll() +{ + if (millis() - lastFlushTime > flushInterval) { + flush(); // Always calls BLE.poll() + } else { + BLE.poll(); + } + return connected; +} + +void ArduinoBLE_UART_Stream::end() +{ + flush(); + txCharacteristic.setEventHandler(BLEUnsubscribed, NULL); + txCharacteristic.setEventHandler(BLESubscribed, NULL); + txSubscribed = false; + + rxCharacteristic.setEventHandler(BLEWritten, NULL); + rxHead = 0; + rxTail = 0; + + BLE.setEventHandler(BLEDisconnected, NULL); + BLE.setEventHandler(BLEConnected, NULL); + connected = false; + + BLE.end(); +} + +size_t ArduinoBLE_UART_Stream::write(uint8_t byte) +{ + if (!txSubscribed) { + return 0; + } + txBuffer[txCount] = byte; + txCount++; + if (txCount == sizeof(txBuffer)) { + flush(); + } + return 1; +} + +int ArduinoBLE_UART_Stream::available() +{ + return (rxHead - rxTail + sizeof(rxBuffer)) % sizeof(rxBuffer); +} + +int ArduinoBLE_UART_Stream::read() +{ + if (rxTail == rxHead) { + return -1; + } + uint8_t byte = rxBuffer[rxTail]; + rxTail = (rxTail + 1) % sizeof(rxBuffer); + return byte; +} + +int ArduinoBLE_UART_Stream::peek() +{ + if (rxTail == rxHead) { + return -1; + } + return rxBuffer[rxTail]; +} + +void ArduinoBLE_UART_Stream::flush() +{ + if (txCount > 0) { + txCharacteristic.setValue(txBuffer, txCount); + txCount = 0; + } + lastFlushTime = millis(); + BLE.poll(); +} + +void ArduinoBLE_UART_Stream::dataReceived(const unsigned char *data, size_t size) +{ + for (size_t i = 0; i < size; i++) { + rxBuffer[rxHead] = data[i]; + rxHead = (rxHead + 1) % sizeof(rxBuffer); + } +} + +void ArduinoBLE_UART_Stream::connectedHandler(BLEDevice central) +{ + instance->connected = true; +} + +void ArduinoBLE_UART_Stream::disconnectedHandler(BLEDevice central) +{ + instance->connected = false; +} + +void ArduinoBLE_UART_Stream::rxWrittenHandler(BLEDevice central, BLECharacteristic characteristic) +{ + instance->dataReceived(characteristic.value(), characteristic.valueLength()); +} + +void ArduinoBLE_UART_Stream::txSubscribedHandler(BLEDevice central, BLECharacteristic characteristic) +{ + instance->txSubscribed = true; +} + +void ArduinoBLE_UART_Stream::txUnsubscribedHandler(BLEDevice central, BLECharacteristic characteristic) +{ + instance->txSubscribed = false; +} + +ArduinoBLE_UART_Stream * ArduinoBLE_UART_Stream::instance = NULL; + + +#endif // _ARDUINO_BLE_UART_STREAM_H_ From 74b036386f0969529732b82c3b3bcf2545a816ba Mon Sep 17 00:00:00 2001 From: Christopher Stawarz Date: Mon, 1 Nov 2021 09:43:44 -0400 Subject: [PATCH 09/27] Clarify why the implementations of ArduinoBLE_UART_Stream and BluefruitLE_SPI_Stream are in their respective header files --- utility/ArduinoBLE_UART_Stream.cpp | 3 ++- utility/BluefruitLE_SPI_Stream.cpp | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/utility/ArduinoBLE_UART_Stream.cpp b/utility/ArduinoBLE_UART_Stream.cpp index 3fffed30..747fa84e 100644 --- a/utility/ArduinoBLE_UART_Stream.cpp +++ b/utility/ArduinoBLE_UART_Stream.cpp @@ -1,3 +1,4 @@ /* - * Implementation is in ArduinoBLE_UART_Stream.h to avoid linker issues. + * Implementation is in ArduinoBLE_UART_Stream.h to avoid making ArduinoBLE a + * build-time dependency for all projects that use the Firmata library. */ diff --git a/utility/BluefruitLE_SPI_Stream.cpp b/utility/BluefruitLE_SPI_Stream.cpp index 93953e96..86d2788c 100644 --- a/utility/BluefruitLE_SPI_Stream.cpp +++ b/utility/BluefruitLE_SPI_Stream.cpp @@ -1,3 +1,5 @@ /* - * Implementation is in BluefruitLE_SPI_Stream.h to avoid linker issues. + * Implementation is in BluefruitLE_SPI_Stream.h to avoid making + * Adafruit_BluefruitLE_nRF51 a build-time dependency for all projects that use + * the Firmata library. */ From d337c155c960c9ffcf2baf4d2c2f475e1342dacf Mon Sep 17 00:00:00 2001 From: Space Date: Sat, 15 Jan 2022 19:03:30 +0200 Subject: [PATCH 10/27] Arduino Uno Wifi Rev 2 Configured For Pyfirmata Major Changes: Added Arduino Uno Wifi Rev 2's pinouts to boards.h Added HWSerial port ID to utility/SerialFirmata.h --- Boards.h | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/Boards.h b/Boards.h index fa8a3466..bcd4405c 100644 --- a/Boards.h +++ b/Boards.h @@ -675,7 +675,7 @@ writePort(port, value, bitmask): Write an 8 bit port. // Sanguino/Melzi, e.g. Creality Ender-3 #elif defined(__AVR_ATmega1284P__) #define TOTAL_ANALOG_PINS 8 -#define TOTAL_PINS 32 +#define TOTAL_PINS 32 #define VERSION_BLINK_PIN 13 #define PIN_SERIAL1_RX 8 //PD0 #define PIN_SERIAL1_TX 9 //PD1 @@ -999,6 +999,31 @@ writePort(port, value, bitmask): Write an 8 bit port. #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) #define PIN_TO_SERVO(p) (p) // deprecated since v2.4 +//Arduino Uno Wifi Rev2 +#elif defined(__AVR_ATmega4809__) +#define TOTAL_ANALOG_PINS NUM_ANALOG_INPUTS //6 +#define TOTAL_PINS 41 // 14 digital + 6 analog + 6 reserved + 10 internal used + 2 I2C + 3 SPI +#define TOTAL_PORTS 3 +#define VERSION_BLINK_PIN LED_BUILTIN //25 +#define PIN_SERIAL1_RX 0 +#define PIN_SERIAL1_TX 1 +#define PIN_SERIAL2_RX 23 +#define PIN_SERIAL2_TX 24 +#define PIN_SERIAL0_RX 26 +#define PIN_SERIAL0_TX 27 +#define IS_PIN_DIGITAL(p) (((p) >= 0 && (p) < 20) || (p) == 25) +#define IS_PIN_ANALOG(p) ((p) >= 14 && (p) < 19) +#define IS_PIN_PWM(p) digitalPinHasPWM(p) +#define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS) +#define IS_PIN_I2C(p) ((p) == 20 || (p) == 21) +#define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK) +#define IS_PIN_SERIAL(p) ((p) == 23 || (p) == 24 || (p) == 26 || (p) == 27) +#define PIN_TO_DIGITAL(p) (p) +#define PIN_TO_ANALOG(p) ((p) - 14) +#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) +#define PIN_TO_SERVO(p) (p) + + // anything else #else #error "Please edit Boards.h with a hardware abstraction for this board" From 0595a293bd5081f83d03271e69123fea13675da2 Mon Sep 17 00:00:00 2001 From: Space Date: Sat, 15 Jan 2022 19:04:51 +0200 Subject: [PATCH 11/27] Arduino Uno Wifi Rev 2 Configured For Pyfirmata Major Changes: Added Arduino Uno Wifi Rev 2's pinouts to boards.h Added HWSerial port ID to utility/SerialFirmata.h --- utility/SerialFirmata.h | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/utility/SerialFirmata.h b/utility/SerialFirmata.h index 3ce33299..eb969da1 100644 --- a/utility/SerialFirmata.h +++ b/utility/SerialFirmata.h @@ -48,9 +48,9 @@ // a) continuous streaming at higher baud rates: enable but set to 0 (receive buffer store & forward) // b) messages: set to a value below min. inter message delay (message store & forward) // c) continuous streaming at lower baud rates or random characters: undefine or set to -1 (disable) -// 3) Smaller delays may not have the desired effect, especially with less powerful CPUs, +// 3) Smaller delays may not have the desired effect, especially with less powerful CPUs, // if set to a value near or below the average Firmata main loop duration. -// 4) The Firmata stream write buffer size must be equal or greater than the max. +// 4) The Firmata stream write buffer size must be equal or greater than the max. // serial buffer/message size and the Firmata frame size (4 bytes) to prevent fragmentation // on the transport layer. //#define FIRMATA_SERIAL_RX_DELAY 50 // [ms] @@ -78,6 +78,8 @@ #define SERIAL_READ_ARR_LEN 12 // map configuration query response resolution value to serial pin type +#define RES_RX0 0x00 +#define RES_TX0 0x01 #define RES_RX1 0x02 #define RES_TX1 0x03 #define RES_RX2 0x04 @@ -121,6 +123,10 @@ namespace { #if defined(PIN_SERIAL_RX) // TODO when use of HW_SERIAL0 is enabled #endif + #if defined(PIN_SERIAL0_RX) + if (pin == PIN_SERIAL0_RX) return RES_RX0; + if (pin == PIN_SERIAL0_TX) return RES_TX0; + #endif #if defined(PIN_SERIAL1_RX) if (pin == PIN_SERIAL1_RX) return RES_RX1; if (pin == PIN_SERIAL1_TX) return RES_TX1; @@ -163,6 +169,12 @@ namespace { // // TODO when use of HW_SERIAL0 is enabled // break; #endif + #if defined(PIN_SERIAL0_RX) + case HW_SERIAL0: + pins.rx = PIN_SERIAL0_RX; + pins.tx = PIN_SERIAL0_TX; + break; + #endif #if defined(PIN_SERIAL1_RX) case HW_SERIAL1: pins.rx = PIN_SERIAL1_RX; From 8ae1ad602e0cb3918748b428778d8daa3f1bbdee Mon Sep 17 00:00:00 2001 From: bovid-19 <103042464+bovid-19@users.noreply.github.com> Date: Tue, 19 Apr 2022 12:14:04 +0200 Subject: [PATCH 12/27] cl-firmata (Common Lisp) added to readme/libraries --- readme.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/readme.md b/readme.md index f79e8821..8777587b 100644 --- a/readme.md +++ b/readme.md @@ -88,6 +88,8 @@ Most of the time you will be interacting with Arduino with a client library on t * [https://github.com/zankich/rust-firmata](https://github.com/zankich/rust-firmata) * Pure Data * [https://github.com/NullMember/PDFirmata](https://github.com/NullMember/PDFirmata) +* Common Lisp + * [https://github.com/cjfuller/cl-firmata](https://github.com/cjfuller/cl-firmata) Note: The above libraries may support various versions of the Firmata protocol and therefore may not support all features of the latest Firmata spec nor all Arduino and Arduino-compatible boards. Refer to the respective projects for details. From 2a9dbcefc2cc96968e07ac5d5c24ba11a67a5bb8 Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Sun, 15 May 2022 17:23:27 +0200 Subject: [PATCH 13/27] Support for Arduino Nano Every --- Boards.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Boards.h b/Boards.h index fa8a3466..52286fac 100644 --- a/Boards.h +++ b/Boards.h @@ -238,6 +238,20 @@ writePort(port, value, bitmask): Write an 8 bit port. #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) #define PIN_TO_SERVO(p) (p) +#elif defined(AVR_NANO_EVERY) || defined(ARDUINO_NANO_EVERY) || defined(ARDUINO_AVR_NANO_EVERY) +#define TOTAL_ANALOG_PINS 8 +#define TOTAL_PINS 24 // 14 digital + 8 analog + 2 i2c +#define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 21) // TBD if pins 0 and 1 are usable +#define IS_PIN_ANALOG(p) ((p) >= 14 && (p) < 14 + TOTAL_ANALOG_PINS) +#define IS_PIN_PWM(p) digitalPinHasPWM(p) +#define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) < MAX_SERVOS) // deprecated since v2.4 +#define IS_PIN_I2C(p) ((p) == PIN_WIRE_SDA || (p) == PIN_WIRE_SCL) // SDA = 22, SCL = 23 +#define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK) +#define PIN_TO_DIGITAL(p) (p) +#define PIN_TO_ANALOG(p) ((p) - 14) +#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) +#define PIN_TO_SERVO(p) (p) // deprecated since v2.4 + // Arduino DUE #elif defined(__SAM3X8E__) #define TOTAL_ANALOG_PINS 12 From d006ab48f29878422c5a6ef2655d7a6f6d2f8a23 Mon Sep 17 00:00:00 2001 From: Kevin Gilliam Date: Thu, 15 Sep 2022 16:23:45 -0700 Subject: [PATCH 14/27] Added Teensy 4.1 pins to Boards.h --- Boards.h | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 70 insertions(+), 7 deletions(-) diff --git a/Boards.h b/Boards.h index 355af4eb..211404cb 100644 --- a/Boards.h +++ b/Boards.h @@ -584,10 +584,23 @@ writePort(port, value, bitmask): Write an 8 bit port. #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) #define PIN_TO_SERVO(p) (p) -// Teensy 4.0 +// Teensy 4.0 and Teensy 4.1 #elif defined(__IMXRT1062__) -#define TOTAL_ANALOG_PINS 14 -#define TOTAL_PINS 40 +#if !defined(TEENSY40) && !defined(TEENSY41) + #warning Assuming TEENSY40. Please #define TEENSY40 or TEENSY41. + #define TEENSY40 +#endif +#if defined(TEENSY40) + #define TOTAL_PINS 40 + #define TOTAL_ANALOG_PINS 14 + #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) <= 27) + #define PIN_TO_ANALOG(p) ((p) - 14) +#elif defined(TEENSY41) + #define TOTAL_PINS 55 + #define TOTAL_ANALOG_PINS 18 + #define IS_PIN_ANALOG(p) (((p) >= 14 && (p) <= 27) || ((p) >= 38 && (p) <= 41)) + #define PIN_TO_ANALOG(p) (((p) <= 27) ? ((p) - 14 ) : ((p) - 24)) +#endif #define VERSION_BLINK_PIN 13 #define PIN_SERIAL1_RX 0 #define PIN_SERIAL1_TX 1 @@ -603,14 +616,64 @@ writePort(port, value, bitmask): Write an 8 bit port. #define PIN_SERIAL6_TX 24 #define PIN_SERIAL7_RX 28 #define PIN_SERIAL7_TX 29 +#if defined(TEENSY40) + #define IS_PIN_SERIAL(p) (((p) == PIN_SERIAL1_RX) || \ + ((p) == PIN_SERIAL1_TX) || \ + ((p) == PIN_SERIAL2_RX) || \ + ((p) == PIN_SERIAL2_TX) || \ + ((p) == PIN_SERIAL3_RX) || \ + ((p) == PIN_SERIAL3_TX) || \ + ((p) == PIN_SERIAL4_RX) || \ + ((p) == PIN_SERIAL4_TX) || \ + ((p) == PIN_SERIAL5_RX) || \ + ((p) == PIN_SERIAL5_TX) || \ + ((p) == PIN_SERIAL6_RX) || \ + ((p) == PIN_SERIAL6_TX) || \ + ((p) == PIN_SERIAL7_RX) || \ + ((p) == PIN_SERIAL7_TX)) + #define IS_PIN_PWM(p) (((p) >= 0 && (p) <= 16) || \ + ((p) == 18) || \ + ((p) == 19) || \ + ((p) >= 22 && (p) <= 25) || \ + ((p) == 28) || \ + ((p) == 29) || \ + ((p) >= 33 && (p) <= 39)) +#elif defined(TEENSY41) + #define PIN_SERIAL8_RX 34 + #define PIN_SERIAL8_TX 35 + #define IS_PIN_SERIAL(p) (((p) == PIN_SERIAL1_RX) || \ + ((p) == PIN_SERIAL1_TX) || \ + ((p) == PIN_SERIAL2_RX) || \ + ((p) == PIN_SERIAL2_TX) || \ + ((p) == PIN_SERIAL3_RX) || \ + ((p) == PIN_SERIAL3_TX) || \ + ((p) == PIN_SERIAL4_RX) || \ + ((p) == PIN_SERIAL4_TX) || \ + ((p) == PIN_SERIAL5_RX) || \ + ((p) == PIN_SERIAL5_TX) || \ + ((p) == PIN_SERIAL6_RX) || \ + ((p) == PIN_SERIAL6_TX) || \ + ((p) == PIN_SERIAL7_RX) || \ + ((p) == PIN_SERIAL7_TX) ||\ + ((p) == PIN_SERIAL8_RX) || \ + ((p) == PIN_SERIAL8_TX)) + #define IS_PIN_PWM(p) (((p) >= 0 && (p) <= 15) || \ + ((p) == 18) || \ + ((p) == 19) || \ + ((p) >= 22 && (p) <= 25) || \ + ((p) == 28) || \ + ((p) == 29) || \ + ((p) == 33) || \ + ((p) == 36) || \ + ((p) == 37) || \ + ((p) >= 42 && (p) <= 47) || \ + ((p) == 51) || \ + ((p) == 54)) +#endif #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS) -#define IS_PIN_ANALOG(p) ((p) >= 14 && (p) <= 27) -#define IS_PIN_PWM(p) (((p) >= 0 && (p) <= 16) || ((p) >= 18 && (p) <= 19) || ((p) >= 22 && (p) <= 25) || ((p) >= 28 && (p) <= 29)|| ((p) >= 33 && (p) <= 39)) #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS) #define IS_PIN_I2C(p) ((p) == 18 || (p) == 19) -#define IS_PIN_SERIAL(p) (((p) >= 0 && (p) <= 1) || ((p) >= 7 && (p) <= 8) || ((p) >= 14 && (p) <= 17) || ((p) >= 20 && (p) <= 21) || ((p) >= 24 && (p) <= 25) || ((p) >= 28 && (p) <= 29)) #define PIN_TO_DIGITAL(p) (p) -#define PIN_TO_ANALOG(p) ((p) - 14) #define PIN_TO_PWM(p) (p) #define PIN_TO_SERVO(p) (p) From e8781a40e8d94597d7783b59f368fb5ce85f67a4 Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Tue, 13 Dec 2022 20:13:35 +0100 Subject: [PATCH 15/27] Remove broken link Fixes #496 --- readme.md | 1 - 1 file changed, 1 deletion(-) diff --git a/readme.md b/readme.md index 8777587b..66ef8e3a 100644 --- a/readme.md +++ b/readme.md @@ -28,7 +28,6 @@ Most of the time you will be interacting with Arduino with a client library on t * processing * [https://github.com/firmata/processing](https://github.com/firmata/processing) - * [http://funnel.cc](http://funnel.cc) * python * [https://github.com/MrYsLab/pymata4](https://github.com/MrYsLab/pymata4) * [https://github.com/MrYsLab/pymata-express](https://github.com/MrYsLab/pymata-express) From b2d893edb666cff98402b9dc945f3261f906bf44 Mon Sep 17 00:00:00 2001 From: Jeff Hoefs Date: Tue, 13 Dec 2022 16:28:19 -0800 Subject: [PATCH 16/27] Update bugfix version --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index 0dc9a348..04e0ff47 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Firmata -version=2.5.8 +version=2.5.9 author=Firmata Developers maintainer=https://github.com/firmata/arduino sentence=Enables the communication with computer apps using a standard serial protocol. For all Arduino/Genuino boards. From 376428187efcf004c26022edd151dbd2233aafbb Mon Sep 17 00:00:00 2001 From: Jeff Hoefs Date: Tue, 13 Dec 2022 16:31:00 -0800 Subject: [PATCH 17/27] Add note about .sh file --- release.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/release.sh b/release.sh index 0c47db8d..089f34e3 100644 --- a/release.sh +++ b/release.sh @@ -1,6 +1,6 @@ #!/bin/sh -# use this script to package Firmata for distribution +# [Optional] use this script to package Firmata for distribution # package for Arduino 1.0.x mkdir -p temp/Firmata @@ -15,7 +15,7 @@ cd temp find . -name "*.DS_Store" -type f -delete zip -r Firmata.zip ./Firmata/ cd .. -mv ./temp/Firmata.zip Arduino-1.0.x-Firmata-2.5.8.zip +mv ./temp/Firmata.zip Arduino-1.0.x-Firmata-2.5.9.zip #package for Arduino 1.6.x and 1.8.x cp library.properties temp/Firmata @@ -29,5 +29,5 @@ cd .. find . -name "*.DS_Store" -type f -delete zip -r Firmata.zip ./Firmata/ cd .. -mv ./temp/Firmata.zip Firmata-2.5.8.zip +mv ./temp/Firmata.zip Firmata-2.5.9.zip rm -r ./temp From 28ac1e062b4700d6ab84c4125fbaa7e7c603dfa7 Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Wed, 28 Dec 2022 08:51:08 +0100 Subject: [PATCH 18/27] Remove test sketch Fails linter check, and tests are done from the PC now --- test/firmata_test/firmata_test.ino | 172 ----------------------------- test/readme.md | 13 --- 2 files changed, 185 deletions(-) delete mode 100644 test/firmata_test/firmata_test.ino delete mode 100644 test/readme.md diff --git a/test/firmata_test/firmata_test.ino b/test/firmata_test/firmata_test.ino deleted file mode 100644 index db058535..00000000 --- a/test/firmata_test/firmata_test.ino +++ /dev/null @@ -1,172 +0,0 @@ -/* - * To run this test suite, you must first install the ArduinoUnit library - * to your Arduino/libraries/ directory. - * You can get ArduinoUnit here: https://github.com/mmurdoch/arduinounit - * Download version 2.0 or greater or install it via the Arduino library manager. - */ - -#include -#include - -void setup() -{ - Serial.begin(9600); -} - -void loop() -{ - Test::run(); -} - -test(beginPrintsVersion) -{ - FakeStream stream; - - Firmata.begin(stream); - - char expected[] = { - REPORT_VERSION, - FIRMATA_PROTOCOL_MAJOR_VERSION, - FIRMATA_PROTOCOL_MINOR_VERSION, - 0 - }; - assertEqual(expected, stream.bytesWritten()); -} - -void processMessage(const byte *message, size_t length) -{ - FakeStream stream; - Firmata.begin(stream); - - for (size_t i = 0; i < length; i++) { - stream.nextByte(message[i]); - Firmata.processInput(); - } -} - -byte _digitalPort; -int _digitalPortValue; -void writeToDigitalPort(byte port, int value) -{ - _digitalPort = port; - _digitalPortValue = value; -} - -void setupDigitalPort() -{ - _digitalPort = 0; - _digitalPortValue = 0; -} - -char * _receivedString; -void handleStringCallback(char *str) -{ - _receivedString = str; -} - -test(processWriteDigital_0) -{ - setupDigitalPort(); - Firmata.attach(DIGITAL_MESSAGE, writeToDigitalPort); - - byte message[] = { DIGITAL_MESSAGE, 0, 0 }; - processMessage(message, 3); - - assertEqual(0, _digitalPortValue); -} - -test(processWriteDigital_127) -{ - setupDigitalPort(); - Firmata.attach(DIGITAL_MESSAGE, writeToDigitalPort); - - byte message[] = { DIGITAL_MESSAGE, 127, 0 }; - processMessage(message, 3); - - assertEqual(127, _digitalPortValue); -} - -test(processWriteDigital_128) -{ - setupDigitalPort(); - Firmata.attach(DIGITAL_MESSAGE, writeToDigitalPort); - - byte message[] = { DIGITAL_MESSAGE, 0, 1 }; - processMessage(message, 3); - - assertEqual(128, _digitalPortValue); -} - -test(processWriteLargestDigitalValue) -{ - setupDigitalPort(); - Firmata.attach(DIGITAL_MESSAGE, writeToDigitalPort); - - byte message[] = { DIGITAL_MESSAGE, 0x7F, 0x7F }; - processMessage(message, 3); - - // Maximum of 14 bits can be set (B0011111111111111) - assertEqual(0x3FFF, _digitalPortValue); -} - -test(defaultDigitalWritePortIsZero) -{ - setupDigitalPort(); - Firmata.attach(DIGITAL_MESSAGE, writeToDigitalPort); - - byte message[] = { DIGITAL_MESSAGE, 0, 0 }; - processMessage(message, 3); - - assertEqual(0, _digitalPort); -} - -test(specifiedDigitalWritePort) -{ - setupDigitalPort(); - Firmata.attach(DIGITAL_MESSAGE, writeToDigitalPort); - - byte message[] = { DIGITAL_MESSAGE + 1, 0, 0 }; - processMessage(message, 3); - - assertEqual(1, _digitalPort); -} - -test(setFirmwareVersionDoesNotLeakMemory) -{ - Firmata.setFirmwareVersion(1, 0); - int initialMemory = freeMemory(); - - Firmata.setFirmwareVersion(1, 0); - - assertEqual(0, initialMemory - freeMemory()); -} - -test(sendStringShouldEncode2BytesPerChar) -{ - FakeStream stream; - Firmata.begin(stream); - // reset the buffer because the firmware name string will be sent on Firmata.begin - stream.reset(); - - char testString[] = "hi!"; - Firmata.sendString(testString); - - byte expected[] = { START_SYSEX, STRING_DATA, 'h', 0, 'i', 0, '!', 0, END_SYSEX }; - - int len = stream.bytesWritten().length(); - assertEqual(sizeof(expected), len); - for (byte i = 0; i < len; i++) { - assertEqual(expected[i], (byte)stream.bytesWritten().charAt(i)); - } -} - -test(receivedStringShouldDecodeFrom2BytesPerChar) -{ - Firmata.attach(STRING_DATA, handleStringCallback); - - byte message[] = { START_SYSEX, STRING_DATA, 'b', 0, 'y', 0, 'e', 0, '!', 0, END_SYSEX }; - processMessage(message, 11); - - assertEqual("bye!", _receivedString); -} - diff --git a/test/readme.md b/test/readme.md deleted file mode 100644 index ab8f8c3d..00000000 --- a/test/readme.md +++ /dev/null @@ -1,13 +0,0 @@ -# Testing Firmata - -Tests tests are written using the [ArduinoUnit](https://github.com/mmurdoch/arduinounit) library (version 2.0). - -Follow the instructions in the [ArduinoUnit readme](https://github.com/mmurdoch/arduinounit/blob/master/readme.md) to install the library. - -Compile and upload the test sketch as you would any other sketch. Then open the -Serial Monitor to view the test results. - -If you make changes to Firmata.cpp, run the tests in /test/ to ensure -that your changes have not produced any unexpected errors. - -You should also perform manual tests against actual hardware. From c285135275c4dd4f0d0bbf82da3c5844a29eaf07 Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Wed, 28 Dec 2022 08:52:44 +0100 Subject: [PATCH 19/27] Fix linter warning --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index 04e0ff47..6e27f0b8 100644 --- a/library.properties +++ b/library.properties @@ -1,7 +1,7 @@ name=Firmata version=2.5.9 author=Firmata Developers -maintainer=https://github.com/firmata/arduino +maintainer=Firmata team sentence=Enables the communication with computer apps using a standard serial protocol. For all Arduino/Genuino boards. paragraph=The Firmata library implements the Firmata protocol for communicating with software on the host computer. This allows you to write custom firmware without having to create your own protocol and objects for the programming environment that you are using. category=Device Control From c243c077e99c6404a32d4397af5b65b945aec99f Mon Sep 17 00:00:00 2001 From: joreg Date: Tue, 25 Apr 2023 22:44:47 +0200 Subject: [PATCH 20/27] added link to vvvv/VL implementation --- readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 66ef8e3a..9d72f2e6 100644 --- a/readme.md +++ b/readme.md @@ -79,8 +79,8 @@ Most of the time you will be interacting with Arduino with a client library on t * [https://www.wolfram.com/system-modeler/libraries/model-plug/](https://www.wolfram.com/system-modeler/libraries/model-plug/) * Go * [https://github.com/kraman/go-firmata](https://github.com/kraman/go-firmata) -* vvvv - * [https://vvvv.org/blog/arduino-second-service](https://vvvv.org/blog/arduino-second-service) +* vvvv/VL + * [https://github.com/vvvv/VL.IO.Firmata](https://github.com/vvvv/VL.IO.Firmata) * openFrameworks * [http://openframeworks.cc/documentation/communication/ofArduino/](http://openframeworks.cc/documentation/communication/ofArduino/) * Rust From e276e3446b25d039090219d8f01f0a8ea533ff2a Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Mon, 24 Jul 2023 19:54:25 +0200 Subject: [PATCH 21/27] #505 Arduino Nano Every is a ATMega 4809 Therefore this definition must come after. Basically, no board should directly use the ATMega 4809 bare definitions. --- Boards.h | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Boards.h b/Boards.h index 211404cb..d8bf4dde 100644 --- a/Boards.h +++ b/Boards.h @@ -219,6 +219,20 @@ writePort(port, value, bitmask): Write an 8 bit port. #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) #define PIN_TO_SERVO(p) ((p) - 2) +#elif defined(AVR_NANO_EVERY) || defined(ARDUINO_NANO_EVERY) || defined(ARDUINO_AVR_NANO_EVERY) +#define TOTAL_ANALOG_PINS 8 +#define TOTAL_PINS 24 // 14 digital + 8 analog + 2 i2c +#define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 21) // TBD if pins 0 and 1 are usable +#define IS_PIN_ANALOG(p) ((p) >= 14 && (p) < 14 + TOTAL_ANALOG_PINS) +#define IS_PIN_PWM(p) digitalPinHasPWM(p) +#define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) < MAX_SERVOS) // deprecated since v2.4 +#define IS_PIN_I2C(p) ((p) == PIN_WIRE_SDA || (p) == PIN_WIRE_SCL) // SDA = 22, SCL = 23 +#define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK) +#define PIN_TO_DIGITAL(p) (p) +#define PIN_TO_ANALOG(p) ((p) - 14) +#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) +#define PIN_TO_SERVO(p) (p) // deprecated since v2.4 + // Arduino UNO WiFi rev2 (ATMega 4809) #elif defined(__AVR_ATmega4809__) #define TOTAL_ANALOG_PINS 6 @@ -238,20 +252,6 @@ writePort(port, value, bitmask): Write an 8 bit port. #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) #define PIN_TO_SERVO(p) (p) -#elif defined(AVR_NANO_EVERY) || defined(ARDUINO_NANO_EVERY) || defined(ARDUINO_AVR_NANO_EVERY) -#define TOTAL_ANALOG_PINS 8 -#define TOTAL_PINS 24 // 14 digital + 8 analog + 2 i2c -#define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 21) // TBD if pins 0 and 1 are usable -#define IS_PIN_ANALOG(p) ((p) >= 14 && (p) < 14 + TOTAL_ANALOG_PINS) -#define IS_PIN_PWM(p) digitalPinHasPWM(p) -#define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) < MAX_SERVOS) // deprecated since v2.4 -#define IS_PIN_I2C(p) ((p) == PIN_WIRE_SDA || (p) == PIN_WIRE_SCL) // SDA = 22, SCL = 23 -#define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK) -#define PIN_TO_DIGITAL(p) (p) -#define PIN_TO_ANALOG(p) ((p) - 14) -#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) -#define PIN_TO_SERVO(p) (p) // deprecated since v2.4 - // Arduino DUE #elif defined(__SAM3X8E__) #define TOTAL_ANALOG_PINS 12 From 931b692b8a075f5a00f79a4c5af85d62ca40e8c5 Mon Sep 17 00:00:00 2001 From: PaulStoffregen Date: Thu, 10 Aug 2023 03:21:19 -0700 Subject: [PATCH 22/27] Improve defines for Teensy 4.0 and Teensy 4.1 --- Boards.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Boards.h b/Boards.h index d8bf4dde..a54f755c 100644 --- a/Boards.h +++ b/Boards.h @@ -586,16 +586,16 @@ writePort(port, value, bitmask): Write an 8 bit port. // Teensy 4.0 and Teensy 4.1 #elif defined(__IMXRT1062__) -#if !defined(TEENSY40) && !defined(TEENSY41) - #warning Assuming TEENSY40. Please #define TEENSY40 or TEENSY41. - #define TEENSY40 +#if !defined(ARDUINO_TEENSY40) && !defined(ARDUINO_TEENSY41) + #warning Assuming ARDUINO_TEENSY40. Please #define ARDUINO_TEENSY40 or ARDUINO_TEENSY41. + #define ARDUINO_TEENSY40 #endif -#if defined(TEENSY40) +#if defined(ARDUINO_TEENSY40) #define TOTAL_PINS 40 #define TOTAL_ANALOG_PINS 14 #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) <= 27) #define PIN_TO_ANALOG(p) ((p) - 14) -#elif defined(TEENSY41) +#elif defined(ARDUINO_TEENSY41) #define TOTAL_PINS 55 #define TOTAL_ANALOG_PINS 18 #define IS_PIN_ANALOG(p) (((p) >= 14 && (p) <= 27) || ((p) >= 38 && (p) <= 41)) @@ -616,7 +616,7 @@ writePort(port, value, bitmask): Write an 8 bit port. #define PIN_SERIAL6_TX 24 #define PIN_SERIAL7_RX 28 #define PIN_SERIAL7_TX 29 -#if defined(TEENSY40) +#if defined(ARDUINO_TEENSY40) #define IS_PIN_SERIAL(p) (((p) == PIN_SERIAL1_RX) || \ ((p) == PIN_SERIAL1_TX) || \ ((p) == PIN_SERIAL2_RX) || \ @@ -638,7 +638,7 @@ writePort(port, value, bitmask): Write an 8 bit port. ((p) == 28) || \ ((p) == 29) || \ ((p) >= 33 && (p) <= 39)) -#elif defined(TEENSY41) +#elif defined(ARDUINO_TEENSY41) #define PIN_SERIAL8_RX 34 #define PIN_SERIAL8_TX 35 #define IS_PIN_SERIAL(p) (((p) == PIN_SERIAL1_RX) || \ From 24308ec7a5969076050b85e5039aaf5c40d970dc Mon Sep 17 00:00:00 2001 From: "Zachary J. Fields" Date: Mon, 28 Aug 2023 08:20:28 -0500 Subject: [PATCH 23/27] feat: Arduino Uno R4 support --- Boards.h | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/Boards.h b/Boards.h index a54f755c..f6cc0422 100644 --- a/Boards.h +++ b/Boards.h @@ -141,6 +141,13 @@ writePort(port, value, bitmask): Write an 8 bit port. #define digitalPinHasPWM(p) IS_PIN_DIGITAL(p) #endif +#undef IS_PIN_INTERRUPT +#if defined(digitalPinToInterrupt) && defined(NOT_AN_INTERRUPT) +#define IS_PIN_INTERRUPT(p) (digitalPinToInterrupt(p) > NOT_AN_INTERRUPT) +#else +#define IS_PIN_INTERRUPT(p) (0) +#endif + // Arduino Duemilanove, Diecimila, and NG #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__) #if defined(NUM_ANALOG_INPUTS) && NUM_ANALOG_INPUTS == 6 @@ -447,6 +454,30 @@ writePort(port, value, bitmask): Write an 8 bit port. #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) #define PIN_TO_SERVO(p) (p) // deprecated since v2.4 +// Arduino UNO R4 Minima and Wifi +// The pinout is the same as for the classical UNO R3 +#elif defined(ARDUINO_UNOR4_MINIMA) || defined(ARDUINO_UNOR4_WIFI) +#if defined(NUM_ANALOG_INPUTS) && NUM_ANALOG_INPUTS == 6 +#define TOTAL_ANALOG_PINS 6 +#define TOTAL_PINS 20 // 14 digital + 6 analog +#else +#define TOTAL_ANALOG_PINS 8 +#define TOTAL_PINS 22 // 14 digital + 8 analog +#endif +// These have conflicting(?) definitions in the core for this CPU +#undef IS_PIN_PWM +#undef IS_PIN_ANALOG +#define VERSION_BLINK_PIN 13 +#define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 19) +#define IS_PIN_ANALOG(p) ((p) >= 14 && (p) < 14 + TOTAL_ANALOG_PINS) +#define IS_PIN_PWM(p) digitalPinHasPWM(p) +#define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) - 2 < MAX_SERVOS) +#define IS_PIN_I2C(p) ((p) == 18 || (p) == 19) +#define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK) +#define PIN_TO_DIGITAL(p) (p) +#define PIN_TO_ANALOG(p) ((p) - 14) +#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) +#define PIN_TO_SERVO(p) ((p) - 2) // Teensy 1.0 #elif defined(__AVR_AT90USB162__) From a46444edfee2410a9c08168c8b48c710b18dad9e Mon Sep 17 00:00:00 2001 From: Birger Koblitz Date: Sun, 3 Sep 2023 09:46:58 +0200 Subject: [PATCH 24/27] Documentation: Add reference to the Firmata Linux Kernel module Adds a reference to the (experimental) Linux Kernel Module firmata_mod, which allows users to use standard Linux userspace APIs/tools to access GPIO, I2C or SPI devices made available on an Arduino attached to a Linux host PC via a serial interface and running the Firmata firmware. In addition, existing Linux Kernel modules for devices using I2C/SPI can also be associated with devices on the Arduino. --- readme.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/readme.md b/readme.md index 9d72f2e6..cde48641 100644 --- a/readme.md +++ b/readme.md @@ -89,6 +89,8 @@ Most of the time you will be interacting with Arduino with a client library on t * [https://github.com/NullMember/PDFirmata](https://github.com/NullMember/PDFirmata) * Common Lisp * [https://github.com/cjfuller/cl-firmata](https://github.com/cjfuller/cl-firmata) +* Linux Kernel Module + * [https://github.com/logicog/firmata_mod] Note: The above libraries may support various versions of the Firmata protocol and therefore may not support all features of the latest Firmata spec nor all Arduino and Arduino-compatible boards. Refer to the respective projects for details. From 1b593388fb2d0996d38063cd999c541d5fcd3725 Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Mon, 9 Sep 2024 07:17:36 +0200 Subject: [PATCH 25/27] Fix compilation for UNOR4 --- Boards.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Boards.h b/Boards.h index f6cc0422..b53d2447 100644 --- a/Boards.h +++ b/Boards.h @@ -470,7 +470,7 @@ writePort(port, value, bitmask): Write an 8 bit port. #define VERSION_BLINK_PIN 13 #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 19) #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) < 14 + TOTAL_ANALOG_PINS) -#define IS_PIN_PWM(p) digitalPinHasPWM(p) +#define IS_PIN_PWM(p) IS_PIN_DIGITAL(p) #define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) - 2 < MAX_SERVOS) #define IS_PIN_I2C(p) ((p) == 18 || (p) == 19) #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK) From 1866deb3343a1e95b552e2de8f2037119bd02617 Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Thu, 12 Sep 2024 21:10:04 +0200 Subject: [PATCH 26/27] A correct definition already exists --- Boards.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/Boards.h b/Boards.h index b53d2447..0a7c3eb7 100644 --- a/Boards.h +++ b/Boards.h @@ -465,12 +465,10 @@ writePort(port, value, bitmask): Write an 8 bit port. #define TOTAL_PINS 22 // 14 digital + 8 analog #endif // These have conflicting(?) definitions in the core for this CPU -#undef IS_PIN_PWM #undef IS_PIN_ANALOG #define VERSION_BLINK_PIN 13 #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 19) #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) < 14 + TOTAL_ANALOG_PINS) -#define IS_PIN_PWM(p) IS_PIN_DIGITAL(p) #define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) - 2 < MAX_SERVOS) #define IS_PIN_I2C(p) ((p) == 18 || (p) == 19) #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK) From 6c48901d3f608ee44f3e8b93999457391e3573f4 Mon Sep 17 00:00:00 2001 From: Patrick Grawehr Date: Thu, 12 Sep 2024 21:19:50 +0200 Subject: [PATCH 27/27] This also is no longer used --- Boards.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/Boards.h b/Boards.h index 0a7c3eb7..1d92cddd 100644 --- a/Boards.h +++ b/Boards.h @@ -464,11 +464,8 @@ writePort(port, value, bitmask): Write an 8 bit port. #define TOTAL_ANALOG_PINS 8 #define TOTAL_PINS 22 // 14 digital + 8 analog #endif -// These have conflicting(?) definitions in the core for this CPU -#undef IS_PIN_ANALOG #define VERSION_BLINK_PIN 13 #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 19) -#define IS_PIN_ANALOG(p) ((p) >= 14 && (p) < 14 + TOTAL_ANALOG_PINS) #define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) - 2 < MAX_SERVOS) #define IS_PIN_I2C(p) ((p) == 18 || (p) == 19) #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)