ehong-tl / micropySX126X

Semtech SX126X LoRa driver for Micropython and CircuitPython.
MIT License
87 stars 20 forks source link

Pin 20 in use #16

Open bio-mod opened 1 year ago

bio-mod commented 1 year ago

Hey, Im trying to figure out how and playing around with the waveshare module in combination with the raspberry pi pico, however it seems ive ran into an issue trying to run the sample code:

from sx1262 import SX1262
import board
import time

sx = SX1262(spi_bus=1, 
         clk=board.GP10, 
         mosi=board.GP11, 
         miso=board.GP12, 
         cs=board.GP3, 
         irq=board.GP20, 
         rst=board.GP15, 
         gpio=board.GP2)

sx.begin(freq=868, bw=500.0, sf=12, cr=8, syncWord=0x12,
         power=10, currentLimit=60.0, preambleLength=8,
         implicit=False, implicitLen=0xFF,
         crcOn=True, txIq=False, rxIq=False,
         tcxoVoltage=1.7, useRegulatorLDO=False, blocking=True)

which returns me the error:

Traceback (most recent call last):
  File "code.py", line 23, in <module>
  File "/lib/sx1262.py", line 48, in begin
  File "/lib/sx1262.py", line 174, in setBlockingCallback
  File "/lib/sx126x.py", line 401, in clearDio1Action
  ValueError: GP20 in use

but I'm not sure what is causing this

ehong-tl commented 1 year ago

The example should work out of the box for Rpi Pico and Waveshare Pico LoRa HAT module without changing anything aside from the LoRa settings. Can you try this instead?

bio-mod commented 1 year ago

Im using circuitpython 8.0.2. So I have used the pin names rather then the int values in the example. other than that I have only changed the power from -5 to 10 ( or any positive int) or else it would give me a "bytes value out of range" error.

other ways ive tried to solve this, but without succes try a different module and different pico board tried both circiutpython 8.0.2 and 7.2.0

ehong-tl commented 1 year ago

Hi,

Can you add self.irq.deinit() after line 400 in sx126x.py file and try again?

dbell1867 commented 1 year ago

I had a similar issue and this edit to the sx126x.py file resolved it. CircuitPython 8.05 I understand that the code is for Micropython but I would have thought that importing board and switching pin to GP.# would work.

However, I get: File "code.py", line 46, in File "/lib/sx1262.py", line 187, in send File "/lib/sx1262.py", line 224, in _transmit File "/lib/sx126x.py", line 274, in transmit TypeError: 'bool' object is not callable

Line 46 is the sx.send(b"Hello World!")

line 187, (return self._transmit(data)

    def send(self, data):
        if not self.blocking:
            return self._startTransmit(data)
        else:
            return self._transmit(data)
Letulma commented 7 months ago

Hi, there is a simple fix for your knew problem in circuitpython. .value() isn't a method, so you only have to remove the brackets in line 320 file sx126x.py -> .value, so your function receive should look like this:

def receive(self, data, len_, timeout_en, timeout_ms):
        state = self.standby()
        ASSERT(state)

        timeout = 0

        modem = self.getPacketType()
        if modem == SX126X_PACKET_TYPE_LORA:
            symbolLength = float(1 << self._sf) / float(self._bwKhz)
            timeout = int(symbolLength * 100.0 * 1000.0)
        elif modem == SX126X_PACKET_TYPE_GFSK:
            maxLen = len_
            if len_ == 0:
                maxLen = 0xFF
            brBps = (float(SX126X_CRYSTAL_FREQ) * 1000000.0 * 32.0) / float(self._br)
            timeout = int(((maxLen * 8.0) / brBps) * 1000000.0 * 5.0)
        else:
            return ERR_UNKNOWN

        if timeout_ms == 0:
            pass
        else:
            timeout = timeout_ms * 1000

        if timeout_en:
            timeoutValue = int(float(timeout) / 15.625)
        else:
            timeoutValue = SX126X_RX_TIMEOUT_NONE

        state = self.startReceive(timeoutValue)
        ASSERT(state)

        start = ticks_us()
        while not self.irq.value:
            yield_()
            if timeout_en:
                if abs(ticks_diff(start, ticks_us())) > timeout:
                    self.fixImplicitTimeout()
                    self.clearIrqStatus()
                    self.standby()
                    return ERR_RX_TIMEOUT

        if self._headerType == SX126X_LORA_HEADER_IMPLICIT and self.getPacketType() == SX126X_PACKET_TYPE_LORA:
            state = self.fixImplicitTimeout()
            ASSERT(state)

        return self.readData(data, len_)

or you implement the fix that detects if circuitpython is used:

    def receive(self, data, len_, timeout_en, timeout_ms):
        state = self.standby()
        ASSERT(state)

        timeout = 0

        modem = self.getPacketType()
        if modem == SX126X_PACKET_TYPE_LORA:
            symbolLength = float(1 << self._sf) / float(self._bwKhz)
            timeout = int(symbolLength * 100.0 * 1000.0)
        elif modem == SX126X_PACKET_TYPE_GFSK:
            maxLen = len_
            if len_ == 0:
                maxLen = 0xFF
            brBps = (float(SX126X_CRYSTAL_FREQ) * 1000000.0 * 32.0) / float(self._br)
            timeout = int(((maxLen * 8.0) / brBps) * 1000000.0 * 5.0)
        else:
            return ERR_UNKNOWN

        if timeout_ms == 0:
            pass
        else:
            timeout = timeout_ms * 1000

        if timeout_en:
            timeoutValue = int(float(timeout) / 15.625)
        else:
            timeoutValue = SX126X_RX_TIMEOUT_NONE

        state = self.startReceive(timeoutValue)
        ASSERT(state)

        start = ticks_us()
        if implementation.name == 'micropython':
            while not self.irq.value():
                yield_()
                if timeout_en:
                    if abs(ticks_diff(start, ticks_us())) > timeout:
                        self.fixImplicitTimeout()
                        self.clearIrqStatus()
                        self.standby()
                        return ERR_RX_TIMEOUT
        if implementation.name == 'circuitpython':
            while not self.irq.value:
                yield_()
                if timeout_en:
                    if abs(ticks_diff(start, ticks_us())) > timeout:
                        self.fixImplicitTimeout()
                        self.clearIrqStatus()
                        self.standby()
                        return ERR_RX_TIMEOUT

        if self._headerType == SX126X_LORA_HEADER_IMPLICIT and self.getPacketType() == SX126X_PACKET_TYPE_LORA:
            state = self.fixImplicitTimeout()
            ASSERT(state)

        return self.readData(data, len_)

I hope you still try to get it work and this late answer will help. @ehong-tl can you pls add the second version to your repository.

P.S. @ehong-tl nonblocking callback isn't working in circuitpython, cause callbacks are'nt supported yet. Would you pls add a note in the readme. Code is tested with a Heltec Lora32 V3 and circuitpython 9.0.0.

Freyr86 commented 6 months ago

I know the topic is a bit old but I still have the same problem with the Lilygo T deck

I tried a few modifications but nothing worked. It is the SCK IO40 PIN which is causing problems, it is used both for the LoRa module and for the screen

It would be necessary to release it and resume after a reception test but I could not find the release function.