Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use with Dragino Lora GPS Hat #21

Open
phraktle opened this issue Jul 12, 2017 · 22 comments
Open

Use with Dragino Lora GPS Hat #21

phraktle opened this issue Jul 12, 2017 · 22 comments
Labels

Comments

@phraktle
Copy link

Hi,

I'm trying to use the library with a Dragino Lora GPS Hat v1.4 board on a RPi3, with no luck so far (assertion error in set_freq during calibration). Has anyone successfully used this board? With what settings?

Thanks,
Viktor

@pointhi
Copy link

pointhi commented Sep 3, 2017

You need to do some little changes to the board configuration and on the board itself:

  • in the board class: DIO0 = 4
  • solder a jumper between pin 22 and 24 as done in the LowCostLoRaGw tutorial. The background is that Dragino didn't used the normal chip select pin which are supported by spidev, which requires this dirty hack (or some software workaround)

@acceleratiom
Copy link

Hi,
I did two changes: DIO0 =4 and the pins 22 to 24 jumper.
But I still have issues when running test_lorapy or (lora_util.py) on the RPI3.
I put some print in the code to get it, but I do not understand why I get an "unknown dio3 mapping!"
Do you any hint ?

Thanks,
Ludovic

pi@raspberrypi:~/pysx/pySX127x $ python lora_util.py
/home/pi/pysx/pySX127x/SX127x/board_config.py:51: RuntimeWarning: This channel is already in use, continuing anyway.  Use GPIO.setwarnings(False) to disable warnings.
  GPIO.setup(BOARD.LED, GPIO.OUT)
((' self.dio_mapping[3]: ', None)'selfmode',
1Traceback (most recent call last):
  File "/home/pi/pysx/pySX127x/SX127x/LoRa.py", line 196, in _dio3
)
    raise RuntimeError("unknown dio3 mapping!")
('selfmode', 3)
RuntimeError: Traceback (most recent call last):
unknown dio3 mapping!
  File "lora_util.py", line 35, in <module>
    lora = LoRa(verbose=False)
  File "/home/pi/pysx/pySX127x/SX127x/LoRa.py", line 100, in __init__
    self.rx_chain_calibration(calibration_freq)
  File "/home/pi/pysx/pySX127x/SX127x/LoRa.py", line 858, in rx_chain_calibration
    self.set_freq(freq_bkup)
  File "/home/pi/pysx/pySX127x/SX127x/LoRa.py", line 284, in set_freq
    assert self.mode == MODE.SLEEP or self.mode == MODE.STDBY or self.mode == MODE.FSK_STDBY
(' self.dio_mapping[3]: ', None)
AssertionError

@mayeranalytics
Copy link
Owner

mayeranalytics commented Dec 7, 2017 via email

@artificialsheep
Copy link

Hi, I had the same issue, indeed you need to set DIO0 = 4 but make sure you change SWITCH to something else (I used 21) and change DIO3 (which is NC on the Dragino shield) to something toher than 25 or you will conflict with the SPI CS pin (since you have now soldered board-pins 22 & 24 together (which are BCM pins 25 & 8). Make sure to reboot as well as your GPIO setup will be all weird, but now I have it working. @mayeranalytics what are your thought on making a Dragino subclass with the correct pins that would allow this to work out of the box? If someone also knows to to software re-map GPIO to avoid the soldering step this could also be nice.

@mayeranalytics
Copy link
Owner

@artificialsheep Thanks for the input. I don't have a Dragino shield, so I can't test anything. But if you have figured it out, and if you have the time, why don't you just make a pull request?

@mkshrps
Copy link

mkshrps commented Apr 17, 2018

Raspberry Pi stretch has an overlay for this included. To remap the SPI CE0 pin to work with the Dragino add the following to the /boot/config.txt file
dtoverlay=spi0-cs,cs0_pin=25
where 25 is the BCM designation for the GPIO (physical) pin 22.
you can also remap the SPI CE1 pin if you ever need to e.g.
dtoverlay=spi0-cs,s0_pin=25, cs1_pin=xx
The pin definitions for GPIO, BCM and wiring PI definitions can be found at https://pinout.xyz/
A couple of extra points to watch out for. Firstly if you remap the CS then you don't need to solder pin 22 to 24 and also make sure the RESET pin is asserted (high) specifically by setting the BCM pin 17 (physical pin 11).

@Bakhoj
Copy link

Bakhoj commented May 3, 2018

Hi,

I'm also trying to use this library with a Dragino Lora GPS Hat v1.4 board on a RPi3, which has to retrieve some data from a RN2483 on a Waspmote Pro v1.5 and is giving me some problems aswell.

I've also soldered the BCM 25 & 8 together and connected the DIO3 to BCM1 since it isn't connected on the board as seen here: PDF

At the moment I can recieve data, but only something like once a few minutes if it's sending every 2 second. Only the first 3 bytes have the correct values most of the time while the rest is partly correct, and sometimes it just gets a dump of data.

The code I'm using is a remake of the rx_cont.py:

main.py
import time
import sys
from SX127x.LoRa import *
from SX127x.board_config import BOARD

print("Start Master Module")

BOARD.DIO0 = 4
BOARD.DIO3 = 1
BOARD.SWITCH = 21
BOARD.setup()


class LoRaMaster(LoRa):
	def __init(self):
		super(LoRaRcvCont, self).__init__(verbose)
		self.set_mode(MODE.STDBY)
		#self.set_dio_mapping([0] * 6) 

	def on_rx_done(self):
		BOARD.led_on()
		print("\nRxDone")
		self.clear_irq_flags(RxDone=1)
		payload = self.read_payload(nocheck=True)
		print(bytes(payload).hex())
		self.set_mode(MODE.SLEEP)
		self.reset_ptr_rx()
		BOARD.led_off()
		self.set_mode(MODE.RXCONT)

	def on_txdone(self):
		print("\nTxDone")
		print(self.get_irq_flags())

	def on_cad_done(self):
		print("\non_CadDone")
		print(self.get_irq_flags())

	def on_rx_timeout(self):
		print("\non_RxTimeout")
		print(self.get_irq_flags())
		time.sleep(.5)
		self.set_mode(MODE.SLEEP)
		self.reset_ptr_rx()
		self.set_mode(MODE.RXCONT)

	def on_valid_header(self):
		print("\non_ValidHeader")
		print(self.get_irq_flags())

	def on_payload_crc_error(self):
		print("\non_PayloadCrcError")
		print(self.get_irq_flags())

	def on_fhss_change_channel(self):
		print("\non_Fhss_changeChannel")
		print(self.get_irq_flags())

	def start(self):
		self.reset_ptr_rx()
		self.set_mode(MODE.RXCONT)
		while True:
			time.sleep(.5)
			rssi_value = self.get_rssi_value()
			snr_value = self.get_pkt_snr_value()
			status = self.get_modem_status()
			sys.stdout.flush()
			sys.stdout.write("\r%d %d %d %d" % (rssi_value, snr_value, status['rx_ongoing'], status['modem_clear']))

lora = LoRaMaster()

try:
	lora.set_mode(MODE.STDBY)

	lora.set_freq(868.1)
	lora.set_coding_rate(CODING_RATE.CR4_5)
	lora.set_bw(BW.BW125)
	lora.set_spreading_factor(12)
	lora.set_pa_config(output_power=5)
	lora.set_preamble(12)
	lora.set_rx_crc(0)
	lora.set_implicit_header_mode(0)

	time.sleep(2)
except:
	print("Error in setup")
	print("Closing")
	BOARD.teardown()
	print("END")

print("Version: \t{}".format(lora.get_version()))
print("Frequency: \t{}MHz".format(lora.get_freq()))
print("Modem Config 1: {}".format(lora.get_modem_config_1()))
print("Modem Config 2: {}".format(lora.get_modem_config_2()))
print("PA Config: \t{}".format(lora.get_pa_config()))

print(lora)
assert(lora.get_agc_auto_on() == 1)

# Start Listening

try:
	lora.start()
except KeyboardInterrupt:
	sys.stdout.flush()
	print("")
	sys.stderr.write("KeyboardInterrupt\n")
finally:
	sys.stdout.flush()
	print("")
	lora.set_mode(MODE.SLEEP)
	print(lora)
	BOARD.teardown()

And when I run the code for some time:

main.py - Console
pi@raspberrypi:/project/python/lora_master $ python3 main.py
Start Master Module
Mode <- SLEEP
Mode <- FSK_STDBY
Mode <- SLEEP
Mode <- FSK_STDBY
Mode <- SLEEP
Mode <- STDBY
Version:        18
Frequency:      868.0999755859375MHz
Modem Config 1: {'coding_rate': 1, 'bw': 7, 'implicit_header_mode': 0}
Modem Config 2: {'rx_crc': 0, 'tx_cont_mode': 0, 'spreading_factor': 12}
PA Config:      {'max_power': 4, 'pa_select': 0, 'output_power': 5}
SX127x LoRa registers:
 mode               STDBY
 freq               868.099976 MHz
 coding_rate        CR4_5
 bw                 BW125
 spreading_factor   4096 chips/symb
 implicit_hdr_mode  OFF
 rx_payload_crc     OFF
 tx_cont_mode       OFF
 preamble           12
 low_data_rate_opti OFF
 agc_auto_on        ON
 symb_timeout       100
 freq_hop_period    0
 hop_channel        {'fhss_present_channel': 0, 'crc_on_payload': 0, 'pll_timeout': 0}
 payload_length     1
 max_payload_length 255
 irq_flags_mask     {'rx_done': 0, 'fhss_change_ch': 0, 'crc_error': 0, 'cad_detected': 0, 'rx_timeout': 0, 'tx_done': 0, 'cad_done': 0, 'valid_header': 0}
 irq_flags          {'rx_done': 0, 'fhss_change_ch': 0, 'crc_error': 0, 'cad_detected': 0, 'rx_timeout': 0, 'tx_done': 0, 'cad_done': 0, 'valid_header': 0}
 rx_nb_byte         0
 rx_header_cnt      0
 rx_packet_cnt      0
 pkt_snr_value      64.000000
 pkt_rssi_value     -164
 rssi_value         -164
 fei                0
 pa_select          RFO
 max_power          13.200000 dBm
 output_power       3.200000 dBm
 ocp                ON
 ocp_trim           100.000000 mA
 lna_gain           G1
 lna_boost_lf       0b0
 lna_boost_hf       0b0
 detect_optimize    0x3
 detection_thresh   0xa
 sync_word          0x12
 dio_mapping 0..5   [0, 0, 0, 0, 0, 0]
 tcxo               XTAL
 pa_dac             default
 fifo_addr_ptr      0x0
 fifo_tx_base_addr  0x80
 fifo_rx_base_addr  0x0
 fifo_rx_curr_addr  0x0
 fifo_rx_byte_addr  0x0
 status             {'signal_sync': 0, 'rx_ongoing': 0, 'signal_detected': 0, 'header_info_valid': 0, 'modem_clear': 1, 'rx_coding_rate': 0}
 version            0x12

Mode <- RXCONT
-103 64 1 0
RxDone
b8515c69303afdcc2097cb909df163fb139ce3b5f19edb15ae7a566404736325edb01fe156084f5479
Mode <- SLEEP
Mode <- STDBY
Mode <- RXCONT
-105 64 1 0
RxDone
b8515c69301afdcc80dfac57cadc2336c684d3b9478683516026a48c4673872dbb88bd82667ba147f5
Mode <- SLEEP
Mode <- STDBY
Mode <- RXCONT
-47 64 1 00
RxDone
120588ccf2
Mode <- SLEEP
Mode <- STDBY
Mode <- RXCONT
-105 64 1 0
RxDone
b8515c69301afdcc8099f25cf13af1b2901b2fa02205e4d448490f70131a9c5c46babc650862818a27
Mode <- SLEEP
Mode <- STDBY
Mode <- RXCONT
-107 64 1 0

Notice that the printout is decoded from byte to char, so the 120588ccf2 was the only close result here which should have been 120588FF88 which was send from the waspmote.

I'm suspecting it's something with the settings not being the same on both modules maybe?

If it's any help I do get the following errors when I'm trying to run lora_util.py and test_lora.py, and I have to restart the RPi to get the main.py code to work again after:

lora_util.py - console
pi@raspberrypi:/usr/lib/python3.5/pySX127x $ python3 lora_util.py
Traceback (most recent call last):
  File "lora_util.py", line 39, in <module>
    lora = LoRa(verbose=False)
  File "/usr/lib/python3.5/pySX127x/SX127x/LoRa.py", line 101, in __init__
    self.rx_chain_calibration(calibration_freq)
  File "/usr/lib/python3.5/pySX127x/SX127x/LoRa.py", line 857, in rx_chain_calibration
    self.set_freq(freq_bkup)
  File "/usr/lib/python3.5/pySX127x/SX127x/LoRa.py", line 283, in set_freq
    assert self.mode == MODE.SLEEP or self.mode == MODE.STDBY or self.mode == MODE.FSK_STDBY
AssertionError
test_lora.py - console
pi@raspberrypi:/usr/lib/python3.5/pySX127x $ python3 test_lora.py
F.....
======================================================================
FAIL: test_mode (__main__.TestSX127x)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test_lora.py", line 43, in wrapper
    func(self)
  File "test_lora.py", line 62, in test_mode
    self.assertEqual(lora.get_mode(), m)
AssertionError: 128 != 129

----------------------------------------------------------------------
Ran 6 tests in 0.012s

FAILED (failures=1)

Anyone have an idea what is missing?

Thanks,
Bakhoj

EDIT:
Had made some changes to lora_util.py which gave another error then the original code, it is changed now to only have the GPIO changed and is showing the correct error now.

@Bakhoj
Copy link

Bakhoj commented May 5, 2018

I fixed my problem with the partly incorrect data from the RN2483.

The Dragino LoRa GPS hat v.1.4's schematics referes to the LoRa module as "RFM92_93W" and I could not find out if it was using RFM92W or RFM93W. The main difference between the 2 is the spreading factor range, which for 92 is 6-12 and the 93 it is 6-9.
After changing the setup to use SF9 instead of 12 it worked.
The error with lora_util.py is gone aswell but the same error is still present when running test_lora.py is it something to be worried about? I understand it's something with the module being in the wrong mode?

@pyflier
Copy link

pyflier commented Aug 22, 2018

Hi Bakhoj
I'm facing exactly the same issue. but even more over two dio0 and dio1:
File "/home/pi/pySX127x-master/SX127x/LoRa.py", line 164, in _dio0
raise RuntimeError("unknown dio0mapping!")
RuntimeError: unknown dio0mapping!
Traceback (most recent call last):
File "/home/pi/pySX127x-master/SX127x/LoRa.py", line 177, in _dio1
raise RuntimeError("unknown dio1mapping!")

Just wondering if you managed to overcome the issue

@MikeRouten
Copy link

MikeRouten commented Nov 15, 2018

I am trying to get the Dragino board running on a Pi 3 but keep getting the following error:

Traceback (most recent call last):
  File "tx_ttn.py", line 40, in <module>
    lora = LoRaWANsend(False)
  File "tx_ttn.py", line 15, in __init__
    super(LoRaWANsend, self).__init__(verbose)
  File "/home/pi/LoRaWAN/SX127x/LoRa.py", line 100, in __init__
    self.rx_chain_calibration(calibration_freq)
  File "/home/pi/LoRaWAN/SX127x/LoRa.py", line 856, in rx_chain_calibration
    self.set_freq(freq_bkup)
  File "/home/pi/LoRaWAN/SX127x/LoRa.py", line 282, in set_freq
    assert self.mode == MODE.SLEEP or self.mode == MODE.STDBY or self.mode == MODE.FSK_STDBY
AssertionError

At this point in the code, self.mode = 0

I have applied the CS remap as suggested by mkshrps and I have modified the LoRa.py file DI0=4 value.

Does anyone have any suggestions on how to resolve this issue?

@mayeranalytics
Copy link
Owner

This type of error usually occurs when SPI communication with the LoRa chip isn't working properly. All the error message is saying is that the LoRa chip isn't in the state it should be in.

In this case the best approach is to go back to basics: Establish reliable communication, for example by reading out the RegOpMode register (0x01) and then toggling Sleep, Standby and Receiver mode and check whether the chip does really is in the appropriate state.
You can use LoRa.py in this library as a guide for how to do the communication in python. There's also plenty of info on the interweb. I suggest you install ipython on the Rasp and debug SPI/raspberry/LoRa chip in the REPL.
On the Rasp in can be worthwhile trying to change the SPI frequency.

When you get stuck, establish facts by eliminating error sources: E.g. try the Dragino with an Arduino and establish the board is fine. Then work forward. When SPI communication refuses to work then a Logic analyser can be useful.

This whole process can be quite frustrating, but if you proceed logically you can figure it out.

Or maybe someone else has already done that particular dance and can contribute the solution.

@artificialsheep
Copy link

artificialsheep commented Nov 19, 2018 via email

@mkshrps
Copy link

mkshrps commented Nov 19, 2018

Ideally you should use an oscilloscope to check what the pins are actually doing in particular the CS pin. If you can write a loop which reads a register you can then check the cs, Mosi,miso and sclk pins are doing something. This would confirm the remapping dtoverlay=spi0-cs,cs0_pin=25 is working . Also make sure the Reset pin is set high.

@MikeRouten
Copy link

For anyone that is interested, I got this working with the following configuration on a fresh install of Raspbian Stretch:

  1. Implement the /boot/config.txt changes that mkshrps suggested by adding "dtoverlay=spi0-cs,cs0_pin=25" to the config.txt record.

  2. Use the following values in board_config
    DIO0 = 4
    DIO1 = 23
    DIO2 = 24
    DIO3 = 21
    LED = 18
    SWITCH = 7

  3. ADD THE FOLLOWING LINES TO constants.py
    @add_lookup
    class SPI_BAUD_RATE:
    MAX_SPEED_HZ = 5000
    @add_lookup
    class SPI_MODE:
    SPI_MODE = 0b01

  4. ADD THE FOLLOWING LINES TO LoRa.py at the top of the class definition right after " spi = BOARD.SpiDev() ":
    spi.max_speed_hz = SPI_BAUD_RATE.MAX_SPEED_HZ
    spi.mode = SPI_MODE.SPI_MODE

With these changes / additions I was able to get the Dragino Hats talking to each other over the Pi's without having to do any soldering on the Hat.

@xmrhahnx
Copy link

xmrhahnx commented Mar 29, 2019

HI there, i'm facing with similar problem. I made the modification as MikeRouten suggested and the test_lora.py works as expected. But when i run the rx_cont.py or any other example i get this:

/home/pi/pySX127x-master/SX127x/board_config.py:58: RuntimeWarning: This channel is already in use, continuing anyway.  Use GPIO.setwarnings(False) to disable warnings.
  GPIO.setup(BOARD.LED, GPIO.OUT)
Traceback (most recent call last):
  File "rx_cont.py", line 101, in <module>
    print(lora)
  File "/home/pi/pySX127x-master/SX127x/LoRa.py", line 945, in __str__
    s += " pa_dac             %s\n" % ['default', 'PA_BOOST'][self.get_pa_dac()]
  File "/home/pi/pySX127x-master/SX127x/LoRa.py", line 56, in wrapper
    return func(self, self.spi.xfer([register_address, 0])[1])
  File "/home/pi/pySX127x-master/SX127x/LoRa.py", line 818, in get_pa_dac
    raise RuntimeError("Bad PA_DAC value %s" % hex(pa_dac))
RuntimeError: Bad PA_DAC value 0x3

any suggestion?

jonashoechst added a commit to Nature40/pySX127x that referenced this issue Sep 3, 2019
The config was adjusted according to [1], to support the Dragino
LoRa + GPS Board on the Raspberry Pi 3.

[1] mayeranalytics#21
amotl pushed a commit to daq-tools/pySX127x that referenced this issue Apr 27, 2020
The config was adjusted according to [1], to support the Dragino
LoRa + GPS Board on the Raspberry Pi 3.

[1] mayeranalytics#21
amotl pushed a commit to daq-tools/pySX127x that referenced this issue Apr 27, 2020
The config was adjusted according to [1], to support the Dragino
LoRa + GPS Board on the Raspberry Pi 3.

[1] mayeranalytics#21
@amotl
Copy link

amotl commented Apr 28, 2020

Hi there.

Introduction

We spent some time on revamping these libraries to be used within our Terkin Datalogger. While adding some bits from the community and general polishing, the main contribution from our pen was daq-tools/dragino-lorawan@772f552d, in order to be able to configure the Dragino class at runtime to become independent of the dragino.ini file. We hope this is as useful for the community as it was important to us.

Resources

The trees we have modified:

Usage

The code is driven by terkin.network.lora.LoRaDriverDragino. You might want to use this as an example blueprint.

Installation

This outlines an ad hoc way of getting the bits and pieces installed together in a coherent manner. Tearing the libraries apart and publishing them to PyPI would have been the better option, but we will postpone this into the future for now.

mkdir lib

# Install driver support for Dragino LoRa Hat.
curl --location https://github.com/daq-tools/dragino/archive/terkin.tar.gz | tar -C lib --strip-components=1 -xzvf - dragino-terkin/dragino

# Install updated pySX127x driver.
curl --location https://github.com/daq-tools/pySX127x/archive/dragino.tar.gz | tar -C lib/dragino --strip-components=1 -xzvf - pySX127x-dragino/SX127x

Credits

Thanks a bunch to

Cheers,
Jan and Andreas.

@chuanisawesome
Copy link

Hi,

I am new to using LoRa and the Dragino Hat for Raspberry pi. I am currently working on a project that I would like to have the Heltec LoRa32 talk to the Dragino Hat locally. Is there any suggestions on how to get started or if this is a possibility? I've ran the lora_test.py and I get this error:

87527FF5-2FA4-4723-87DB-DAD8FEE460CE

Thank you!

@mayeranalytics
Copy link
Owner

The failed test tells you that the LoRa chip is not in the correct mode, or registers don't have the expected values. This usually means that there are communication problems. When I look at your log, I see that the read commands seem to always return 0, and that is quite suspicious.

@chuanisawesome
Copy link

I end up using Heltec LoRa32 as my gateway since I'm having so much trouble with Dragino LoRa Hat for the RPi.

@amotl
Copy link

amotl commented May 10, 2022

Hi again,

following up on our last post at #21 (comment), we would like to bring to your attention that @BNNorman picked up the torch and has been working on his fork 1 continuously since May 2021.

For further information, see also daq-tools/dragino-lorawan#1 where Brian shared an overview about the improvements and features he has been working on, status November 2021.

With kind regards,
Andreas.

/cc @Tonkenfo

Footnotes

  1. https://github.com/BNNorman/dragino-1

@chuanisawesome
Copy link

Thank you so much @amotl ! I will look into it. I really appreciate it

@BNNorman
Copy link

I end up using Heltec LoRa32 as my gateway since I'm having so much trouble with Dragino LoRa Hat for the RPi.

Did you really mean Gateway? Gateways are supposed to be able to receive on 8 channels simultaneously. Single channel gateways are not supported by TTN (AFAIK).

Check your Dragino LoRA/GPS HAT version is V1.4 - it has DIO signals wired that previous versions do not. That may be your real issue with RPi.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

14 participants