# \[Announce\] node-red-node-Arduino (Firmata) remastered \`v1.3.4-20250331\`

**URL:** <https://discourse.nodered.org/t/announce-node-red-node-arduino-firmata-remastered-v1-3-4-20250331/96317>\
**Category:** Share Your Nodes\
**Created:** [29 March 2025 05:03 UTC](https://discourse.nodered.org/t/announce-node-red-node-arduino-firmata-remastered-v1-3-4-20250331/96317 "2025-03-29T05:03:52Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![PizzaProgram](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/pizzaprogram/32/19431_2.png) [@PizzaProgram](https://discourse.nodered.org/u/PizzaProgram)\
**Post date:** [29 March 2025 05:03 UTC](https://discourse.nodered.org/t/announce-node-red-node-arduino-firmata-remastered-v1-3-4-20250331/96317/1 "2025-03-29T05:03:52Z")

</div>

_... after 1+ month (200+ hours of time investment), I proudly present:_

# The first stable version of Arduino / Firmata module.

Currently it can be downloaded from: [here v1.3.3](https://github.com/user-attachments/files/19515074/node-red-node-arduino_v1.3.3.zip). I'm planning to create a pull request too.

The `1.1 version` currently available for download at npm + Github is:

- **not working** in many ways,

so I had to rewrite it _(almost)_ completely. _(ca. 70 lines left untouched from 770.)_ The whole process of it is: [here...](https://github.com/node-red/node-red-nodes/issues/920#issuecomment-2677430920)

 ![kép](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/4/a/4ac6879fff66391bdd938f7ff8e56bb4391263ff.png)

# What changed:

1. "max pin" problem solved. Now works again with Raspberry Pi - Pico (+ESP32) boards too!

2. analogue pin checking! (NR crashed before)

3. more help added to html = setup panels

 ![kép](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/3/4/34348177d196976a48dd7cbc556aeb697570b20b.png)

1. `msg.payload = "reset"` \>\> resets board _(more later...)_

2. added many `else` and constants to speed up execution

3. renamed variables to be unique. Like: node -\> `brdNode`, `nodeIn`, `nodeOut`

4. added error handling for unhandled errors

5. changed `var` to `let` everywhere

6. added emit -\> to immediate auto-update all in/out nodes  
if **master-board state** changed !

7. created clear status definitions. + according visual colour + text status for each

8. added "sampling interval" _(more later ... )_

9. added: log2consol checkbox (setup)

10. Deploy works !

11. Partial deploy works also!! 🥇  
_Even changing 1-1 pin during run without stopping or restart._

12. msg.payload null warning for Out-node input

13. added new Out-node types: `[RESET, INTERVAL]`

14. Event / emit exceed limit problems of v1.1 **solved!**

15. Added: `Name` config for better naming / label showing

16. can handle "no board" / "no com set" / "no pin set"

17. endless "board-search" animation probably solved. (need testing!)

18. Auto-timed connect retry (100ms - 10sec increasing)

- so if board gets only **later** plugged in (after start) \>\> it works too!

1. **auto-pin-conflict search** and show system
2. **version** is shown at in+out config panel

_+ all kinds of bug fixes ..._

 ![kép](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/c/3/c38907f2c0e6d70f8d30388fa817b24238e252d4.png)

## About Sampling-interval:

A value of millisecond between `10-65500` can be set ! 👍

- Both at startup on the Arduino setup panel,
- and at runtime via `msg.payload = 500` if node-out Type is set for this.

This will reduce or increase the speed, how (analogue) data will flow (if changed).  
This is a global value. So individual pins can not be set differently at Firmata firmware.  
Default value is now **changed** from 19ms to: `200ms`, because even my high speed laptop could not handle the amount of debugs showing even for 1 pin.

- 200ms =\> max 5 message will be sent pro second, if value changes  
_(for each analogue pin you subscribed for)_.

## About board-reset:

This function has 2 purpose:

1. it will stop sending analogue values + will set all output pins to default LOW
2. helps after restart, because the board can be re-attached to NR.

_Note:_ it happens very fast. So if there is only a "LED blink", you will hardly notice anything, because "output" will work again after a few milliseconds.  
Analogue read (and maybe digital in too!) will stop completely until flow restart.

Two ways to do it:

1. Set Arduino-out node to: **reset** + send a: `msg.payoload = true or 1`
2. Send `msg.payload = reset` to any "Out" node.

 ![kép](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/9/3/93b9f9237d98ba43f6975f1471ba756ca14f4a89.png)

Try it yourself, and leave a comment!

---

<div class="post-metadata">

**Author:** ![PizzaProgram](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/pizzaprogram/32/19431_2.png) [@PizzaProgram](https://discourse.nodered.org/u/PizzaProgram)\
**Post date:** [30 March 2025 10:40 UTC](https://discourse.nodered.org/t/announce-node-red-node-arduino-firmata-remastered-v1-3-4-20250331/96317/2 "2025-03-30T10:40:40Z")

</div>

1. **Fixed** some sentences at HTML + Readme.md + Help  
_(could not figure out, how to embed active URL links into help)_
2. **Deleted** half of the tips visible up here, as @dceejay requested at his PMs
3. Log to console default is: OFF (unchecked)
4. changed version number to: 1.3.3-20250330 (from ..0329)
5. added help to "Arduino out" node too !
6. uploaded and [requested a Pull at github](https://github.com/node-red/node-red-nodes/pull/1091).

 ![kép](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/3/b/3bd43cf96c0753b23272a543d3d9a7d6358a7ea7.png)

---

<div class="post-metadata">

**Author:** ![PizzaProgram](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/pizzaprogram/32/19431_2.png) [@PizzaProgram](https://discourse.nodered.org/u/PizzaProgram)\
**Post date:** [30 March 2025 11:18 UTC](https://discourse.nodered.org/t/announce-node-red-node-arduino-firmata-remastered-v1-3-4-20250331/96317/3 "2025-03-30T11:18:07Z")

</div>

## Very bad news:

Just tested:

- if sampling interval is set to a high value _(eg. 2000ms)_
- short pressing **digital input** will not work!

I wrote to all the help files explanations sentences which suggests: it only affects the analogue ports.

I will open an issue at Configurable-Firmata firmware page, maybe there is a workaround?

---

<div class="post-metadata">

**Author:** ![PizzaProgram](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/pizzaprogram/32/19431_2.png) [@PizzaProgram](https://discourse.nodered.org/u/PizzaProgram)\
**Post date:** [1 April 2025 09:15 UTC](https://discourse.nodered.org/t/announce-node-red-node-arduino-firmata-remastered-v1-3-4-20250331/96317/4 "2025-04-01T09:15:39Z")

</div>

## Auto-port-search finally fixed!

 ![kép](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/2/f/2f78045d8014ec10226d4a0194823fdb55650fd1.png)

1. had to rewrite both (html+JS) functions to async !
2. added try-catch for error handling
3. response naming changed to `path` ! _(had to debug for hours...)_
4. added logs to both browser's console & node-red-log (console)

```log
Available Ports: [
  {
    path: 'COM3',
    manufacturer: 'Microsoft',
    serialNumber: '6&35CA52AB&0&0000',
    pnpId: 'USB\\VID_2E8A&PID_00C0&MI_00\\6&35CA52AB&0&0000',
    locationId: '0000.0014.0000.001.000.000.000.000.000',
    friendlyName: 'Soros USB-eszköz (COM3)',
    vendorId: '2E8A',
    productId: '00C0'
  }
]

```

---

<div class="post-metadata">

**Author:** ![PizzaProgram](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/pizzaprogram/32/19431_2.png) [@PizzaProgram](https://discourse.nodered.org/u/PizzaProgram)\
**Post date:** [2 April 2025 12:20 UTC](https://discourse.nodered.org/t/announce-node-red-node-arduino-firmata-remastered-v1-3-4-20250331/96317/5 "2025-04-02T12:20:41Z")

</div>

News:

## 1. [Pull Request](https://github.com/node-red/node-red-nodes/pull/1092) created. Waiting for accept of: `v1.3.4-20250331`.

* * *

About earlier:

> [@PizzaProgram](#):
>
> - if sampling interval is set to a high value _(eg. 2000ms)_
> - short pressing **digital input** will not work!

## 2. [Asked](https://github.com/firmata/ConfigurableFirmata/issues/179) the programmer of Firmata

to enhance the code to be able to accept different setup for different type of pins.

---

<div class="post-metadata">

**Author:** ![PizzaProgram](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/pizzaprogram/32/19431_2.png) [@PizzaProgram](https://discourse.nodered.org/u/PizzaProgram)\
**Post date:** [6 April 2025 15:26 UTC](https://discourse.nodered.org/t/announce-node-red-node-arduino-firmata-remastered-v1-3-4-20250331/96317/6 "2025-04-06T15:26:04Z")

</div>

## Good news:

A [code part](https://github.com/firmata/ConfigurableFirmata/pull/181/commits/491e84acc9366f8a979724efc3ac0275c97626fb) of _Configurable Firmata_ has been found, prevented reporting of digital pins at higher sampling rate.  
Read [here...](https://github.com/firmata/ConfigurableFirmata/issues/179#issuecomment-2779360705)

The only "side effect" is, that fluctuating pins will be reported more times,  
but I think that's ok, because usually if someone is not using proper pullup-resistors, it's not a software problem.

After this pull request is accepted, everyone should upgrade his Firmata firmware.

* * *

I2C and SPI is also affected, because until now sampling rate was not effecting them.  
From now on, **it will!**

### Note:

if using unshielded or long cables, _(especially in electric noisy or 110V/240V environment,)_ it is strongly recommended to use [optocoupler](https://duckduckgo.com/?q=optocoupler&t=ffab&iar=images&iax=images&ia=images). There are complete 4 channel boards under $2 price, and can handle 12V/24V to work stable even at 100/1000 meters of cable.

---

<div class="post-metadata">

**Author:** ![PizzaProgram](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/pizzaprogram/32/19431_2.png) [@PizzaProgram](https://discourse.nodered.org/u/PizzaProgram)\
**Post date:** [6 April 2025 16:05 UTC](https://discourse.nodered.org/t/announce-node-red-node-arduino-firmata-remastered-v1-3-4-20250331/96317/7 "2025-04-06T16:05:12Z")

</div>

# Changes at: `v1.4.1-20250405`

1. In-nodes do not report / send new message on start!

2. Fixed: Reported "pin conflict" at "String", "sampling rate", etc. types too.

3. Fixed: Reported "wrong pin" at "String-in" type. (strings do not use Pins)  
\_Strings nodes did not accept Pin values, like: `99`

4. String-in node can start before board-report. _(no need to wait)_  
This way it will report even "...starting" message coming from Firmata board.

5. Circumvent Firmata-io is reporting "opening port" messages as "Error".  
_(while it is not one.)_

# Noticed behaviour at disconnect:

While unplugging / disconnecting the board, sometimes it can happen, that:

- **Close** event

gets called by Node-red Firmata-io, instead of:

- (transport-) **Disconnect** event

In these cases it will completely close all sub-nodes, so

### In-nodes will stop receiving in-values !

### What will still work after reconnecting:

- Outputs, like turning a Pin High/Low
- String-in

PS: I have no Wifi capable boards to test, but behaviour will probably the same.  
Because Node-RED does not properly propagating the current state of NR service, like:

```js
RED.starting
RED.stopping
RED.started
RED.restarting
RED.flowRestart
RED.deploying

```

it is nearly impossible to distinguish, why close is happening.

If these values of NR would be available, the nodes could start a repeating:

- reconnecting + event-re-subscibing function.

---

<div class="post-metadata">

**Author:** ![PizzaProgram](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/pizzaprogram/32/19431_2.png) [@PizzaProgram](https://discourse.nodered.org/u/PizzaProgram)\
**Post date:** [13 April 2025 01:15 UTC](https://discourse.nodered.org/t/announce-node-red-node-arduino-firmata-remastered-v1-3-4-20250331/96317/8 "2025-04-13T01:15:55Z")

</div>

## About Temperature read at RPi-Pico - SOLVED!

The problem was on CustomFirmata's Firmware side:

1. The board definition is wrong. _There are 31 pins, including 5 analogue. (Not 30 / 4!)_  
So, for Pico1 board, you must change the file ...Arduino\libraries  
770. lines to this:

2. Had to change the resolution to 12 bit. _(See code below)_

3. Also IMHO it is essential, to use an up-to-date board library, called: [Earle Phil's Arduino-Pico](https://github.com/earlephilhower/arduino-pico) instead of the 4 year old "[embedOS](https://github.com/arduino/mbed-os)".

So, it is necessary adding following lines to the `setup()` part, before exporting and flashing to RPi-Pico board:

```c
void setup()
{
...
  analogReadResolution(12);
  // send TEMP °C + RawTempValue, formatted as JSON.
#include <stdio.h>
  float c = analogReadTemp();
  char buf[50], buf2[25];
  snprintf(buf , 25, "{\"celsius\": %f, ", c);

#include <hardware/structs/adc.h>
  hw_set_bits(&adc_hw->cs, ADC_CS_TS_EN_BITS);
  delay(1); // Allow things to settle. Without this, readings can be erratic
  int _rt = analogRead(TOTAL_PINS - 1);
  snprintf(buf2, 25, "\"rawTemp\": %d }", _rt);
  strcat (buf , buf2);

  Firmata.sendString(F( buf ));	

// float celsius = 27.0f - ((v * vref / 4096.0f) - 0.706f) / 0.001721f; // const float vref = 3.3f; 
}

```

Result during bootup is coming through Adruino-in STRING node:

```json
{"celsius": 23.3933, "rawTemp": 881 }

```

### The main difference was this: `analogReadResolution(12);`

Without that line, only values like: `219`, `220` came always. _(Probably because the default resolution is 10bit.)_

So now I can read the same values (779-882) with Node-RED too ! 🙂  
Anyway the interesting thing is, that even at max resolution (12 bit) the temp values having too big jumps if I apply the math:  
Ca. `0.47` °C jumps between 2 values.

```list
860 => 34.628632 
861 => 34.160488 
862 => 33.692379 
863 => 33.224236 
864 => 32.756092 
865 => 32.287949 
866 => 31.819803 
867 => 31.351692 
868 => 30.883549 
869 => 30.415405 
870 => 29.947262 
871 => 29.479116 
872 => 29.011007 
873 => 28.542864 
874 => 28.074718 
875 => 27.606575 
876 => 27.138432 
877 => 26.670322 
878 => 26.202177 
879 => 25.734034 
880 => 25.265888 
881 => 24.797745 
882 => 24.329636 
883 => 23.861492 
884 => 23.393347 
885 => 22.925203 
886 => 22.457060 
887 => 21.988949 
888 => 21.520805 
889 => 21.052662 
890 => 20.584518 
891 => 20.116373 
892 => 19.648264 
893 => 19.180119 
894 => 18.711975 
895 => 18.243832 
896 => 17.775688 
897 => 17.307579 
898 => 16.839434 
899 => 16.371290 
900 => 15.903146 
901 => 15.435001 
902 => 14.966892 
903 => 14.498748 
904 => 14.030603 
905 => 13.562460 
906 => 13.094316 
907 => 12.626206 
908 => 12.158062 
909 => 11.689918 
910 => 11.221774 
911 => 10.753630 
...

```

---

<div class="post-metadata">

**Author:** ![PizzaProgram](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/pizzaprogram/32/19431_2.png) [@PizzaProgram](https://discourse.nodered.org/u/PizzaProgram)\
**Post date:** [19 October 2025 15:49 UTC](https://discourse.nodered.org/t/announce-node-red-node-arduino-firmata-remastered-v1-3-4-20250331/96317/9 "2025-10-19T15:49:36Z")

</div>

For those, who want to compile Firmata for RPi-Pico boards, hereby I'm sharing my improved .INO file that is working better, until it is officially released as v3.4.0+

It has many improvements compared to the standard ConfigurableFirmata example file.  
_(See comments inside the code)_

I strongly recommend to compile it with board library, called: [Earle Phil's Arduino-Pico](https://github.com/earlephilhower/arduino-pico) instead of the 4 year old "[embedOS](https://github.com/arduino/mbed-os)".

### Remember to

overwrite the boards.h file in the library folder!

```c
/*
 * ConfigurableFirmata standard example file, for Serial + Wifi communication.
 *
 * Read more about board support and how to install necessary libraries here:
 * https://github.com/firmata/ConfigurableFirmata/blob/master/BoardSupport.md
 */

/* Usage: Easily enable or disable each module. 
 * To disable, put: // before "#define ... " lines.
 * Disable everything you do not need. 
 * Enable modules one by one, and re-re-try to compile to see if it works? 
 */

/* 1.1) Change this string to identify this board easier. Like: "My Pico-robot2025"
 * Firmata will send this info to client library (which is running on a PC or RPi-Pi) after first connect.
 * Also: version protocol + capabilities will be sent too. */
const char* boardName = "myFirmataBoard";

/* 1.2.) Safety Password for future use. Not implemented yet. 
 * ! WARNING ! Never send the plain boardPassw back to the host! 
 * Mix it with the "salt" ( = random code / timestamp), you recieved from host, and create a (hexa)HASH from those two before sending it back. */
const char* boardPassw = ""; 

/* 2.1.) ENABLE_WIFI
 * Uncomment this, to enable WIFI instead of serial communication. 
 * (Tested on ESP32, but should also work with Wifi-enabled Arduinos + PicoW + Pico2W)  
 */
//#define ENABLE_WIFI
const char* ssid = "your-ssid";
const char* password = "your-password";
const int NETWORK_PORT = 27016;

/* 2.2.) ... or set serial baud rate:
 * !WARNING! This value should match with the client library connection speed!
 * (Because usually UART chips can not handle assimetric connections.) 
 * Default was 57600 for long time. The "firmata.js" client library is still using that value. 
 * If connected via USB-UART, this value has no effect, because the rate is always maximum. (1Mbit)
 * read more here: https://github.com/firmata/ConfigurableFirmata/issues/180 
 */
const int BAUD_RATE = 1200; // 2400 3600 7200 9600 14400 28800 57600 115200 230400 460800 921600 or higher?. 

/* 3.1.) DISABLE_BLINK_VERSION
 * Uncomment to save a couple of seconds by disabling the startup blink sequence,
 * !WARNING! Some LEDs are connected to real GPIO ports! Like at: Arduino Nano board.
 * So this prevents turning relays ON/OFF/ON/OFF... quickly during boot, what can be bad. :-(
 */
//#define DISABLE_BLINK_VERSION

/* 3.2.) ENABLE_START_BLINK
           Uncomment this to pause booting process by blinking the LED 2x, 7 seconds long.
					 See at: setup() at near end of this file.
           It is useful, if you need time to start a debugger process or serial monitor before boot happens. 
*/
//#define ENABLE_START_BLINK

/* 3.3.) Uncomment these 2 lines, to Set On / Off state to then opposite:
 * (Some cheap relay boards need GND to close the circuit, and 5V to open.)
 * ! WARNING ! This "Software Solution" is not 100% safe to use! 
 * ! DANGER ! On critical applications, (water boil, solar, industry ...) rather solve it on the the hardware side. 
 * it is always wiser to use proper opto NPN decouplers between this board and the relays.
 */
// #define LOW 1
// #define HIGH 0 

/* 4.1) Note that the SERVO module is not supported yet on ESP32. So either disable this or patch the library
 * More info / current state of fix: https://github.com/firmata/ConfigurableFirmata/issues/178 */
#ifndef ESP32
// #define ENABLE_SERVO 
#endif

// 4.2.) Other modules: (simply disable everything you do not need)  
//#define ENABLE_ONE_WIRE
//#define ENABLE_ACCELSTEPPER
//#define ENABLE_BASIC_SCHEDULER // This is rarely used and probably will not compile/work
//#define ENABLE_SERIAL // This is for using an other serial through GPIO pins. Not for default Host-USB-serial.
//#define ENABLE_I2C
//#define ENABLE_SPI
#define ENABLE_ANALOG
#define ENABLE_DIGITAL
//#define ENABLE_DHT 
#define ENABLE_FREQUENCY

// 4.3.) SLEEP is supported only for AVR and ESP32
#if defined (ESP32) || defined (ARDUINO_ARCH_AVR)
  #define ENABLE_SLEEP
#endif

// 5.) LED signaling the state of board. 
//#define BLINK_SERIAL_STATE // enable this if you want your LED blinking: slow/fast, if serial is: OK/not

#ifdef BLINK_SERIAL_STATE
  #define NORMAL_BLINK_INTERVAL 1000
  #define FAST_BLINK_INTERVAL 100
  #define SERIAL_TIMEOUT 2000

  unsigned long lastSerialTime = 0;
  unsigned long lastBlinkTime = 0;
  unsigned long blinkInterval = NORMAL_BLINK_INTERVAL;
  bool ledState = false;
#endif

/ ***********************************************
 ***DO NOT CHANGE things down from here***
         (unless you know what you do)

     The setup() and loop() are at the end.
************************************************ /
#include <ConfigurableFirmata.h>

#ifdef ENABLE_DIGITAL
  #include <DigitalInputFirmata.h>
  DigitalInputFirmata digitalInput;

  #include <DigitalOutputFirmata.h>
  DigitalOutputFirmata digitalOutput;
#endif

#ifdef ENABLE_SLEEP
  #include "ArduinoSleep.h"
  ArduinoSleep sleeper(39, 0);
#endif

#ifdef ENABLE_ANALOG
  #include <AnalogInputFirmata.h>
  AnalogInputFirmata analogInput;

  #include <AnalogOutputFirmata.h>
  AnalogOutputFirmata analogOutput;
#endif

#ifdef ENABLE_WIFI
  #include <WiFi.h>
  #include "utility/WiFiClientStream.h"
  #include "utility/WiFiServerStream.h"
  WiFiServerStream serverStream(NETWORK_PORT);
#endif

#ifdef ENABLE_I2C
  #include <Wire.h>
  #include <I2CFirmata.h>
  I2CFirmata i2c;
#endif

#ifdef ENABLE_SPI
  #include <Wire.h>
  #include <SpiFirmata.h>
  SpiFirmata spi;
#endif

#ifdef ENABLE_ONE_WIRE
  #include <OneWireFirmata.h>
  OneWireFirmata oneWire;
#endif

#ifdef ENABLE_SERIAL
  #include <SerialFirmata.h>
  SerialFirmata serial;
#endif

#ifdef ENABLE_DHT
  #include <DhtFirmata.h>
  DhtFirmata dhtFirmata;
#endif

#include <FirmataExt.h>
FirmataExt firmataExt;

#ifdef ENABLE_SERVO
  #include <Servo.h>
  #include <ServoFirmata.h>
  ServoFirmata servo;
#endif

#include <FirmataReporting.h>
FirmataReporting reporting;

#ifdef ENABLE_ACCELSTEPPER
#include <AccelStepperFirmata.h>
  AccelStepperFirmata accelStepper;
#endif

#ifdef ENABLE_FREQUENCY
#include <Frequency.h>
  Frequency frequency;
#endif

#ifdef ENABLE_BASIC_SCHEDULER
// The scheduler allows to store scripts on the board, however this requires a kind of compiler on the client side.
// When running dotnet/iot on the client side, prefer using the FirmataIlExecutor module instead
  #include <FirmataScheduler.h>
  FirmataScheduler scheduler;
#endif

void systemResetCallback()
{
// Does more harm than good on ESP32 (because may touch pins reserved
// for memory IO and other reserved functions)
#ifndef ESP32 
	for (byte i = 0; i < TOTAL_PINS; i++) 
	{
		if (FIRMATA_IS_PIN_ANALOG(i)) 
		{
			Firmata.setPinMode(i, PIN_MODE_ANALOG);
		} 
		else if (IS_PIN_DIGITAL(i)) 
		{
			Firmata.setPinMode (i, PIN_MODE_OUTPUT);
		}
	}
#endif
	firmataExt.reset();
}

void initTransport()
{
#ifdef DISABLE_BLINK_VERSION
  Firmata.disableBlinkVersion();
#endif
  
#ifdef ESP8266
  // need to ignore pins 1 and 3 when using an ESP8266 board. These are used for the serial communication.
  Firmata.setPinMode(1, PIN_MODE_IGNORE);
  Firmata.setPinMode(3, PIN_MODE_IGNORE);
#endif

#ifdef ENABLE_WIFI
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  pinMode(VERSION_BLINK_PIN, OUTPUT);
  bool pinIsOn = false;
  while (WiFi.status() != WL_CONNECTED)
	{
		delay(100);
		pinIsOn = !pinIsOn;
		digitalWrite(VERSION_BLINK_PIN, pinIsOn);
	}
	Firmata.begin(serverStream);
	Firmata.blinkVersion(); // Because the above doesn't do it.
#else 
	Firmata.begin(BAUD_RATE);
#endif
}

void initFirmata()
{
#ifdef ENABLE_DIGITAL
	firmataExt.addFeature(digitalInput);
	firmataExt.addFeature(digitalOutput);
#endif
	
#ifdef ENABLE_ANALOG
	firmataExt.addFeature(analogInput);
	firmataExt.addFeature(analogOutput);
#endif
	
#ifdef ENABLE_SERVO
	firmataExt.addFeature(servo);
#endif
	
#ifdef ENABLE_I2C
	firmataExt.addFeature(i2c);
#endif
	
#ifdef ENABLE_ONE_WIRE
	firmataExt.addFeature(oneWire);
#endif

#ifdef ENABLE_SERIAL
	firmataExt.addFeature(serial);
#endif
	
#ifdef ENABLE_BASIC_SCHEDULER
	firmataExt.addFeature(scheduler);
#endif
	
  firmataExt.addFeature(reporting);
#ifdef ENABLE_SPI
	firmataExt.addFeature(spi);
#endif
#ifdef ENABLE_ACCELSTEPPER
	firmataExt.addFeature(accelStepper);
#endif
	
#ifdef ENABLE_DHT
	firmataExt.addFeature(dhtFirmata);
#endif

#ifdef ENABLE_FREQUENCY
	firmataExt.addFeature(frequency);
#endif

#ifdef ENABLE_SLEEP
	firmataExt.addFeature(sleeper);
#endif

	Firmata.attach(SYSTEM_RESET, systemResetCallback);
}

/ *************END of Definitions part************* /

void setup()
{

  // Boot pause BLINK test: 
#ifdef ENABLE_START_BLINK
  pinMode(VERSION_BLINK_PIN, OUTPUT);
      digitalWrite(VERSION_BLINK_PIN, HIGH);
      delay(4000);
      digitalWrite(VERSION_BLINK_PIN, LOW);
      delay(1000);
      digitalWrite(VERSION_BLINK_PIN, HIGH);
      delay(100);
      digitalWrite(VERSION_BLINK_PIN, LOW);
#endif

#ifdef BLINK_SERIAL_STATE
  pinMode(VERSION_BLINK_PIN, OUTPUT);
  digitalWrite(VERSION_BLINK_PIN, LOW);
  lastSerialTime = millis();
#endif

	// Set firmware name and version.
	// (Need to do this before initTransport(), because some client libraries expect that a reset sends this automatically.)
	Firmata.setFirmwareNameAndVersion(boardName, FIRMATA_FIRMWARE_MAJOR_VERSION, FIRMATA_FIRMWARE_MINOR_VERSION);

	initTransport();
	Firmata.sendString(F("Booting device. Stand by...\n"));

	initFirmata();
	Firmata.sendString(F("init complete \n"));

	Firmata.parse(SYSTEM_RESET);
	Firmata.sendString(F("parse complete \n"));

  // Raspberry Pi Pico/Pico2/W temperature initialization, using Earle F.'s library.

	analogReadResolution(12);
	// send TEMP °C + RawTempValue, formatted as JSON.
#include <stdio.h>
  float c = analogReadTemp();
  char buf[127], buf2[32];
  snprintf(buf , 25, "{\"celsius\": %f ", c);

#include <hardware/structs/adc.h>
	hw_set_bits(&adc_hw->cs, ADC_CS_TS_EN_BITS);
  delay(1); // Allow things to settle. Without this, readings can be erratic
	int _rt = analogRead(TOTAL_PINS - 1);
  snprintf(buf2, 25, ",\"rawTemp\": %d", _rt);
  strcat (buf , buf2);
	// float celsius = 27.0f - ((v * vref / 4096.0f) - 0.706f) / 0.001721f; // const float vref = 3.3f; 

  // Send serial + boardName
  uint len;
  pico_get_unique_board_id_string(buf2, len);
  strcat (buf , ",\"serial\":\"");
  strcat (buf , buf2);
  strcat (buf , "\",\"boardName\":\"");
  strcat (buf , boardName);
  strcat (buf , "\"}");
  Firmata.sendString(F( buf ));

/*
  // speed test: send 1000*100 char and measure speed (100 char = 1424 bit including SYSEX start/stop)

  unsigned long t1, t2 = 0;
  t1 = millis();
  for (int k = 0; k<1000; k++) {
    Firmata.sendString(F( "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" ));
  }
  t2 = millis();
  snprintf(buf , 32, "start (ms): %d ", t1); // 1882ms
  Firmata.sendString(F( buf ));
  snprintf(buf , 32, "end (ms): %d ", t2); // 3466ms
  Firmata.sendString(F( buf ));
  snprintf(buf , 32, "Ellapsed: %d ", t2-t1); //1424 bit = 1584ms -> 904126 baud 
  Firmata.sendString(F( buf ));
*/  
  
}

void loop()
{
#ifdef BLINK_SERIAL_STATE
  // Check for incoming serial data
  if (Serial.available()) {
    lastSerialTime = millis();
  }

  // Adjust blink interval based on serial timeout
  if (millis() - lastSerialTime > SERIAL_TIMEOUT) {
    blinkInterval = FAST_BLINK_INTERVAL;
  } else {
    blinkInterval = NORMAL_BLINK_INTERVAL;
  }

  // Blink LED
  if (millis() - lastBlinkTime >= blinkInterval) {
    ledState = !ledState;
    digitalWrite(VERSION_BLINK_PIN, ledState);
    lastBlinkTime = millis();
  }
#endif

	while(Firmata.available()) 
	{
		Firmata.processInput();
		if (!Firmata.isParsingMessage()) 
		{
			break;
		}
	}

// delay(1);

	firmataExt.report(reporting.elapsed());
#ifdef ENABLE_WIFI
	serverStream.maintain();
#endif
}

```
