whaleygeek / bitio

A micro:bit I/O device library for Python
Other
92 stars 31 forks source link

Support for analog reading of pins. #42

Open hegehog8761 opened 1 year ago

hegehog8761 commented 1 year ago

I was just wondering (as from what I can see it does not appear to currently be supported) whether a function that returns the current voltage of a pin, for things like variable resistors to be used as inputs. I only ask as I am trying to use a variable resistor in my current project and can only find the rather limited is_touched() function that only returns a true or false value. Thanks for any response to this request in advance.

hegehog8761 commented 1 year ago

Sorry about this but I just found the issue from 2017 referencing this (this one), it was marked as next update some time in October of last year. Just checking now if there is any update upon this, you mentioned in that post that the dir() method may not fully support this method, I was just wondering if there perhaps might be an update upon the functionality of these functions or if this may be scheduled for a later 'larger' update. Again, thanks in advance.

whaleygeek commented 1 year ago

Yes, sorry about that, I got busy with other projects!

You are right, there is currently no digital or analog read/write support, and it is on the list. The reason why it is not currently present, is that I wrote bitio as a way to publish projects in my Minecraft coding book for kids, and time was short, so I only implemented the bits I needed at the time for the book to be published.

The various important parts are implemented in api.py, you will see the TouchPin class there:

    class TouchPin():
        def __init__(self, name):
            self.name = name

        def is_touched(self):
            r = self.parent.cmd("print(%s.is_touched())" % self.name)
            r = eval(r)
            return r

To add an analog read, for resistor values, we would need an AnalogPin class, which sent the cmd '%s.read_analog()' command as per: https://microbit-micropython.readthedocs.io/en/v2-docs/pin.html?highlight=read_analog#microbit.MicroBitAnalogDigitalPin.read_analog

A half way house for this, to get you going, might be to just modify the TouchPin to add the read_analog() method, and then use any of these in your project: pin0.read_analog() pin1.read_analog() pin2.read_analog() and it should just work.

I think the new method on TouchPin would look like this:

        def read_analog(self):
            r = self.parent.cmd("print(%s.read_analog())" % self.name)
            r = eval(r)
            return r

If you wanted an analog on other pins, inside api.py you could add more pin names here in the same style as the lines above such as: https://github.com/whaleygeek/bitio/blob/master/src/microbit/api.py#L192

This is a 'get you going' hack that would work for analog read. There is a whole piece of work to do with pins in particular, as different pins support different modes, some support touch, some do not, some support analog, some do not. The model of pins needs re-architecting to support different overlapping pin features, to do this properly, but that is a bigger bit of work.

Hope this helps to get your project working for you though!

whaleygeek commented 1 year ago

Likewise, if you are only using pins 0,1,2, a hack for other modes could be to add these methods to TouchPin()

    def read_digital(self):
        r = self.parent.cmd("print(%s.read_digital())" % self.name)
        r = eval(r)
        return r

    def write_digital(self, value):
        self.parent.cmd("print(%s.write_digital(%s))" % (self.name, str(value))

    def set_analog_period(self, period):
        self.parent.cmd("print(%s.set_analog_period(%s))" % (self.name, str(period)))

    def set_analog_period_microseconds(self, period):
        self.parent.cmd("print(%s.set_analog_period_microseconds(%s))" % (self.name, str(period))

The precise MicroPython/micro:bit APIs for pins are documented here:

https://microbit-micropython.readthedocs.io/en/v1.0.1/pin.html

hegehog8761 commented 1 year ago

Thanks

whaleygeek commented 1 year ago

If someone wanted to try this, as well as adding the other pins, even though it is a hack, it would work, and I would accept it as a PR. Looking at @musabkilic here, in case he is interested in making this change and testing it!