meshtastic / python

The Python CLI and API for talking to Meshtastic devices
https://meshtastic.org
364 stars 154 forks source link

GPIO Watch crash if write gpio to 0 #110

Closed KiwiHC16 closed 2 years ago

KiwiHC16 commented 2 years ago

Equipment e480 is controlled by c500:

c480:

$ meshtastic --port /dev/ttyUSB0 --gpio-rd 0x10 --dest \!f244c480 
Connected to radio
Reading GPIO mask 0x10 from !f244c480
GPIO read response gpio_value=16

$ meshtastic --port /dev/ttyUSB0 --gpio-watch 0x10 --dest \!f244c480
Connected to radio
Watching GPIO mask 0x10 from !f244c480
Received RemoteHardware typ=GPIOS_CHANGED, gpio_value=16

c500

meshtastic --gpio-wrb 4 1 --dest \!f244c480

c480:

Received RemoteHardware typ=WRITE_GPIOS, gpio_value=16

c500:

meshtastic --gpio-wrb 2 1 --dest \!f244c480

c480:

Received RemoteHardware typ=WRITE_GPIOS, gpio_value=4

c500:

meshtastic --gpio-wrb 2 0 --dest \!f244c480

c480:

ERROR:root:Unexpected error in deferred execution <class 'KeyError'>
Traceback (most recent call last):
  File "/var/www/.local/lib/python3.7/site-packages/meshtastic/util.py", line 86, in _run
    o()
  File "/var/www/.local/lib/python3.7/site-packages/meshtastic/__init__.py", line 696, in <lambda>
    topic, packet=asDict, interface=self))
  File "/var/www/.local/lib/python3.7/site-packages/pubsub/core/publisher.py", line 216, in sendMessage
    topicObj.publish(**msgData)
  File "/var/www/.local/lib/python3.7/site-packages/pubsub/core/topicobj.py", line 452, in publish
    self.__sendMessage(msgData, topicObj, msgDataSubset)
  File "/var/www/.local/lib/python3.7/site-packages/pubsub/core/topicobj.py", line 482, in __sendMessage
    listener(data, self, allData)
  File "/var/www/.local/lib/python3.7/site-packages/pubsub/core/listener.py", line 237, in __call__
    cb(**kwargs)
  File "/var/www/.local/lib/python3.7/site-packages/meshtastic/remote_hardware.py", line 11, in onGPIOreceive
    print(f'Received RemoteHardware typ={hw["typ"]}, gpio_value={hw["gpioValue"]}')
KeyError: 'gpioValue'
KiwiHC16 commented 2 years ago

In //, I'm trying to understand the way of working of the code: https://meshtastic.discourse.group/t/gpio-read-write/3827

(I guess the answer is somewhere in RemoteHardwarePlugin.cpp)

/// Read all the pins mentioned in a mask
static uint64_t digitalReads(uint64_t mask)

pinModes(mask, INPUT_PULLUP);

digitalRead(i)
KiwiHC16 commented 2 years ago

All PIN free, you can read any GPIO as each of them return 1 e.g with mask on GPIO 14:

# meshtastic --port /dev/ttyUSB0 --gpio-rd 0x4000 --dest \!f244c500
Connected to radio
Reading GPIO mask 0x4000 from !f244c500
GPIO read response gpio_value=16384

Then if the GPIO 14 on the requested mask is 0 then you get a crash: e.g. With GPIO0 wired to the ground:

# meshtastic --port /dev/ttyUSB0 --gpio-rd 0x4000 --dest \!f244c500
Connected to radio
Reading GPIO mask 0x4000 from !f244c500
ERROR:root:Error while handling message from radio 'gpioValue'
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/dist-packages/meshtastic/__init__.py", line 885, in __reader
    self._handleFromRadio(self._rxBuf[HEADER_LEN:])
  File "/usr/local/lib/python3.7/dist-packages/meshtastic/__init__.py", line 566, in _handleFromRadio
    self._handlePacketFromRadio(fromRadio.packet)
  File "/usr/local/lib/python3.7/dist-packages/meshtastic/__init__.py", line 704, in _handlePacketFromRadio
    handler.callback(asDict)
  File "/usr/local/lib/python3.7/dist-packages/meshtastic/__main__.py", line 331, in onResponse
    print(f'GPIO read response gpio_value={hw["gpioValue"]}')
KeyError: 'gpioValue'

A work around is to interrogate a GPIO which is alway at 1 at the same time that we interrogate the interesting PIN. e.g. if I add the GPIO 0 in the mask:

With GPIO 14 at Ground:

# meshtastic --port /dev/ttyUSB0 --gpio-rd 0x4001 --dest \!f244c500
Connected to radio
Reading GPIO mask 0x4001 from !f244c500
GPIO read response gpio_value=1

With GPIO 14 open:

# meshtastic --port /dev/ttyUSB0 --gpio-rd 0x4001 --dest \!f244c500
Connected to radio
Reading GPIO mask 0x4001 from !f244c500
GPIO read response gpio_value=16385

Need to find the bug now that I can repeat the fault.

Looks like if the field gpio_value is not in the message if the value is 0. Is it in the firmware ? in the python decode code ?

mkinney commented 2 years ago

Which device is this? (T-Beam, Heltec, etc.)

What version of meshtastic are you using? (i.e., "meshtastic --version")

What version of python are you using? (i.e., "python --version")

Can you share "meshtastic --info"?

Can you run with "--debug" to see if that helps any?

mkinney commented 2 years ago

I was doing some testing on gpios, but I suspect you cannot simply add 3v (nor 5v) to a pin and have it change the gpio. But, I'm not sure.

I'm ordering some sensors to see if I can get the gpio stuff to work as expected.

mkinney commented 2 years ago

I've made progress today. I was able to get a setup working: 2 TLoraV1s, 1 LED on GPIO21 so I could visually see the GPIO change state. I discovered that the read was actually causing the value to change.

I also discovered that the gpioValue will not come thru in the protocol buffer because that's the default integer value. I should have some code fixes in the next couple of days. I think that's the root of your issue.

I want to test the "watch" functionality.