firmata / arduino

Firmata firmware for Arduino
GNU Lesser General Public License v2.1
1.53k stars 515 forks source link

Allow increasing the default number of pins #472

Closed nadvornik closed 1 year ago

nadvornik commented 3 years ago

I am using virtual pins to control internal variables of a sketch. Sometimes I need more pins than TOTAL_PINS defined in Boards.h. This pull request adds a possibility to increase the default. This is the most compatible implementation I can think of.

soundanalogous commented 3 years ago

Can you help me understand this use case and how this would benefit the larger Firmata user base?

nadvornik commented 3 years ago

I am using Indiduino driver to control various devices connected to a telescope. https://www.indilib.org/develop/arduino/110-welcome-to-indiduino.html

The main advantage of Indiduino is that the same libindi driver can work with many different devices. The functionality is defined in so called skeleton file and in arduino firmware.

It can either use StandardFirmata to control pins directly or a custom firmware to perform some non-trivial task.

Here is an example which use PWM "pins" for stepper motor: https://github.com/indilib/indi-3rdparty/blob/master/indi-duino/devices/Firmwares/INDIDUINOStepper/INDIDUINOStepper.ino#L185

I am trying to create a device with more complicated functionality and I ran out of available pins (TOTAL_PINS, 20 for Arduino NANO).

Another simple example would be using analog multiplexer 74HC4051, which adds 7 more analog inputs.

The value of TOTAL_PINS can't be changed without forking the library, so I created this pull request.

pgrawehr commented 1 year ago

Closing this PR, as use case is unclear. What use would "virtual" pins have, when there's nothing attached to them? If you use a port extender, the pins will be available from the driver of that extender.

nadvornik commented 1 year ago

Do you have any example code for using firmata with port extender?

pgrawehr commented 1 year ago

@nadvornik

You could do something like this (C# code, using library Iot.Device.Bindings.dll):

ArduinoBoard board = new ArduinoBoard("COM3", 115200);
var i2cDevice = board.CreateOrGetI2cBus(0).CreateDevice(0x20); // device address
var mcp23S17 = new Mcp23017(i2cDevice);
var gpioController = new GpioController(mcp23S17);
// Use gpioController as if it was a local one...

The driver (in this case the Mcp23017 class) is responsible for providing the gpio pins (via GpioController here). The board which is responsible for the firmata communication, handles this fully transparent.