Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Oct 16 17:36
    soundanalogous commented #430
  • Oct 16 17:35
    soundanalogous commented #430
  • Oct 16 17:34
    soundanalogous commented #430
  • Oct 16 17:20
    soundanalogous commented #430
  • Oct 16 17:13
    m-elias commented #430
  • Oct 16 17:12
    soundanalogous commented #430
  • Oct 16 17:06
    m-elias commented #430
  • Oct 16 16:57
    soundanalogous commented #430
  • Oct 16 16:56
    soundanalogous commented #430
  • Oct 16 16:50
    m-elias commented #430
  • Oct 16 16:50
    m-elias commented #430
  • Oct 16 16:49
    m-elias commented #430
  • Oct 16 16:49
    m-elias commented #430
  • Oct 16 16:47
    m-elias opened #430
  • Oct 15 04:29
    soundanalogous commented #429
  • Oct 15 03:42
    JGMAGNO commented #429
  • Oct 14 17:59
    soundanalogous commented #429
  • Oct 14 17:58
    soundanalogous commented #429
  • Oct 14 08:48
    JGMAGNO opened #429
  • Oct 12 07:19
    mexchip commented #16
Clive Galway
@evilC
I don't see why that part is shifted to software, it would be way more efficient to do it in hardware surely?
            session = new ArduinoSession(connection);

            session.SetDigitalPinMode(2, PinMode.InputPullup);
            session.SetDigitalReportMode(0, true);
            session.DigitalStateReceived += Session_OnDigitalStateReceived;

...

        private void Session_OnDigitalStateReceived(object sender, FirmataEventArgs<DigitalPortState> eventArgs)
        {
            var isSet = eventArgs.Value.IsSet(2);
            Console.WriteLine($"Message is for port {eventArgs.Value.Port}. Pin2 value= {isSet}");
            session.SetDigitalPin(10, isSet);
        }
Do all the client libs work like this? You get zero delta information, just new state and you need to work out what changed yourself?
Clive Galway
@evilC
So I have a meg with like 56 digital pins, I would need to keep 7 blocks of 8 bit button states to know what changed?
Jeff Hoefs
@soundanalogous
Some firmata client libraries sort that out for you, it really depends on the particular library. The reason we use ports instead of individual pins is throughput. When updating on every iteration of the main loop, it's far more efficient to report 8 pins at a time rather than individually. However a buffering mechanism would solve the same issue, but it was not initially part of the architecture. It is something I'm considering however for Firmata v3.
Clive Galway
@evilC
yeah but for input, latency is way more important
Jeff Hoefs
@soundanalogous
yep far less latency when sending 8 pins at a time
Clive Galway
@evilC
in the send, yes, but up to 8x the processing on the client side
Jeff Hoefs
@soundanalogous
CPU processing speed vs 57600 baud
Clive Galway
@evilC
if the 8th pin of a port changes, I need to make 7 pointless checks to find that out
you could send more efficiently - in the above use case you only need to send two values to tell me that pin 56 changed to 1
for a port you are sending 8
but I spose what, you must always send a byte or something?
still, by switching to PIN/STATE you lose 50% bandwidth at most, but you could gain a bunch of CPU cycles at the host
maxing out the CPU of the arduino is no big deal
Jeff Hoefs
@soundanalogous
Well it depends on how much the CPU is doing. Firmata is a general protocol. You could have an application that does far more than check a few digital pin values.
Clive Galway
@evilC
input + arduino often means gaming
Jeff Hoefs
@soundanalogous
Currently there is no definition in the protocol for reading an individual digital pin. Once that is added you can do whatever you want in firmware.
firmata/protocol#68
Clive Galway
@evilC
I don't think my suggestion would require deprecating ports
Jeff Hoefs
@soundanalogous
Ports wouldn't be deprecated
A new feature would be added that enables reporting individual pins in addition to ports
A firmware implementation would use one method or the other
Clive Galway
@evilC
At the moment, a packet for a given port always holds all values for the pins in that port yeah, as 8 bits?
Jeff Hoefs
@soundanalogous
correct
1 bit per pin
Clive Galway
@evilC
so port 0 might be like 001234567
but in binary of course
so all I am saying is maybe allow a mode like 00110
Jeff Hoefs
@soundanalogous
That's how it works today
Clive Galway
@evilC
meaning "Port 0/ Pin 0 changed to 1 / Pin 1 changed to 0
but it can be sparse
ah I see, bits
duh
yeah I see, much bigger
4 bits to desribe which pin in port, plus 1 for state
Jeff Hoefs
@soundanalogous
Here's an example of parsing a digital message in firmata.js: https://github.com/firmata/firmata.js/blob/master/lib/firmata.js#L124-L149
Clive Galway
@evilC
I don't think I would have any trouble in doing it, I already have to do similar things when I process DirectInput and XInput
Clive Galway
@evilC
        private Dictionary<int, bool> pinStates = new Dictionary<int, bool>();

        private void Session_OnDigitalStateReceived(object sender, FirmataEventArgs<DigitalPortState> eventArgs)
        {
            var basePin = eventArgs.Value.Port * 8;
            for (var portPin = 0; portPin < 8; portPin++)
            {
                var fullPin = basePin + portPin;
                var isSet = eventArgs.Value.IsSet(portPin);
                if (!pinStates.ContainsKey(fullPin))
                {
                    pinStates.Add(fullPin, !isSet);
                }
                if (isSet == pinStates[fullPin]) continue;
                pinStates[fullPin] = isSet;
                Console.WriteLine($"Port {eventArgs.Value.Port}, Pin {portPin} (Pin #{fullPin}) changed to {isSet}");
            }
        }
I spose I may need to check if mode is pullup and stuff tho?
as from what I can tell, in pullup mode, unpressed is 1, but in normal mode, 0 is unpressed?
Clive Galway
@evilC
Hmm, the C# library does not seem to have a GetDigitalPinMode()
Clive Galway
@evilC
using Solid.Arduino;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Solid.Arduino.Firmata;

namespace FermataTest
{
    public class Class1
    {
        private readonly ArduinoSession _session;
        private readonly Dictionary<int, bool> _pinStates = new Dictionary<int, bool>();
        private readonly Dictionary<int, PinMode> _pinModes = new Dictionary<int, PinMode>();

        public Class1()
        {
            var connection = GetConnection();
            _session = new ArduinoSession(connection);

            SubscribeDigitalPin(2, PinMode.InputPullup);
            SubscribeDigitalPin(3, PinMode.InputPullup);
            SubscribeDigitalPin(4, PinMode.InputPullup);
            SubscribeDigitalPin(5, PinMode.InputPullup);
            SubscribeDigitalPin(6, PinMode.InputPullup);
            SubscribeDigitalPin(7, PinMode.InputPullup);
            SubscribeDigitalPin(8, PinMode.InputPullup);
            SubscribeDigitalPin(9, PinMode.InputPullup);
            SubscribeDigitalPin(10, PinMode.InputPullup);
            SubscribeDigitalPin(11, PinMode.InputPullup);
            SubscribeDigitalPin(12, PinMode.InputPullup);
            SubscribeDigitalPin(13, PinMode.InputPullup);

            _session.DigitalStateReceived += Session_OnDigitalStateReceived;
            Console.ReadLine();
            _session.Dispose();
            connection.Dispose();
        }

        public void SubscribeDigitalPin(int pin, PinMode mode)
        {
            _session.SetDigitalPinMode(pin, mode);
            _pinModes[pin] = mode;
            var port = pin / 8;
            _session.SetDigitalReportMode(port, true);
        }

        private void Session_OnDigitalStateReceived(object sender, FirmataEventArgs<DigitalPortState> eventArgs)
        {
            var basePin = eventArgs.Value.Port * 8;
            for (var portPin = 0; portPin < 8; portPin++)
            {
                var fullPin = basePin + portPin;
                if (!_pinModes.ContainsKey(fullPin))
                {
                    continue;
                }

                var pinMode = _pinModes[fullPin];
                var pressedValue = pinMode != PinMode.InputPullup;
                var isSet = eventArgs.Value.IsSet(portPin) == pressedValue;
                if (!_pinStates.ContainsKey(fullPin))
                {
                    _pinStates.Add(fullPin, false);
                }
                if (isSet == _pinStates[fullPin]) continue;
                _pinStates[fullPin] = isSet;
                Console.WriteLine($"Port {eventArgs.Value.Port}, Pin {portPin} (Pin #{fullPin}) changed to {isSet}");
            }
        }

        private static ISerialConnection GetConnection()
        {
            Console.WriteLine("Searching Arduino connection...");
            var connection = EnhancedSerialConnection.Find();

            Console.WriteLine(connection == null
                ? "No connection found. Make shure your Arduino board is attached to a USB port."
                : $"Connected to port {connection.PortName} at {connection.BaudRate} baud.");

            return connection;
        }
    }
}
Jeff Hoefs
@soundanalogous
Regarding pull-ups, that's correct. The value is 1 normally and 0 if pressed because the current is pulled up to VCC and when you press the button, it's pulled down to ground. You can find a thorough explanation here: https://learn.sparkfun.com/tutorials/pull-up-resistors.
Rabin Shrestha
@jyapujuju
Hello
I set pinb as input
When i read all six pin as it show me 0
It only work upto 31
Why??
KoToZ
@Mohamedtareque
Hey is there any documentation to start with