mayeranalytics / pySX127x

This is a python interface to the Semtech SX127x, HopeRF RFM9x, Microchip RN2483 long range, low power transceiver families.
GNU Affero General Public License v3.0
171 stars 115 forks source link

Send text #26

Closed rpsreal closed 6 years ago

rpsreal commented 6 years ago

Hi, I'm trying to communicate an arduino and a raspberry Pi through two RA-02 lora modules. I am using the RadioHead library in the Ardino and I'm trying to use this python library on the side of Raspberry Pi. Communication between two arduinos works fine, the library on raspberry pi does not report errors, but the communication between arduino and raspberry pi just works by using the raspberry pi as receiver. Sending messages from the raspberry pi is not recollected by the arduino. It looks like a coding problem used when the message is sent that is not collected by the RadioHead library and therefore discarded. Is there a way to send a string, instead of the 0x0f byte sent in tx_beacon.py? I have spent days around this code and have not yet come up with any solutions, any help is welcome.

mayeranalytics commented 6 years ago

tx_beacon.py is sort of a prototype transmitting application. It sends a small payload in regular intervals, its purpose is to establish contact, test ranges, etc. Where it says self.write_payload([0x0f]) you can write whatever you like. So if you stick a list("hello".encode('ascii')) in there instead of [0x0f] you're sending "hello" in ASCII encoding. I don't know what exactly the RadioHead library does but presumably there's a way to dump the received messages to serial and watch them arrive. The 0x0f is some weird ASCII character that might not even show up in your terminal. So try the "hello". Alternatively, just dump hex codes or ints in the RadioHead app, then something, i.e. the 0x0f, should show up. Also, the configurations of the chip have to match on both sides, Rasp and Arduino. Since you can RX on the Rasp it seems that the configs are ok, though. Otherwise, modules, antennas, etc. are identical on both sides? If not, that may be worth looking at - although I don't really see how that might lead to this RX/TX asymmetry, but with RF anything can happen...

rpsreal commented 6 years ago

Thanks a lot for the help. I tried to do the test to send the "hello" but gives the following error:

Traceback (most recent call last): File "./tx_beacon.py", line 128, in lora.start() File "./tx_beacon.py", line 96, in start self.write_payload(list("hello".encode('ascii'))) File "/home/pi/pySX127x/SX127x/LoRa.py", line 237, in write_payload return self.spi.xfer([REG.LORA.FIFO | 0x80] + payload)[1:] TypeError: Non-Int/Long value in arguments: b6cb0608.

The modules are exactly the same as the antennas, but to be sure I changed them but did not get any changes. Once again, thank you for helping me.

mayeranalytics commented 6 years ago
    The input to spi.xfer has to be a list of int, but what I gave you is a list of string, so just map ord over it and it’ll be fine.In any case, just send something that is not a 0x0f but a visible ascii character.What else have you tried?The antenna thing is the least likely cause, so I’d do that when all other ideas are exhausted.

More ideas: Flip the modules and see if the symptoms change. If not, it’s most likely a config problem. Dump the LoRa chip configs on both sides and compare them carefully. General advice: Try to eliminate causes for failure. Proceed systematically.

    Get Outlook for iOS

On Thu, May 3, 2018 at 1:14 PM +0200, "Rui Silva" notifications@github.com wrote:

Thanks a lot for the help.

I tried to do the test to send the "hello" but gives the following error:

Traceback (most recent call last):

File "./tx_beacon.py", line 128, in

lora.start()

File "./tx_beacon.py", line 96, in start

self.write_payload(list("hello".encode('ascii')))

File "/home/pi/pySX127x/SX127x/LoRa.py", line 237, in write_payload

return self.spi.xfer([REG.LORA.FIFO | 0x80] + payload)[1:]

TypeError: Non-Int/Long value in arguments: b6cb0608.

The modules are exactly the same as the antennas, but to be sure I changed them but did not get any changes.

Once again, thank you for helping me.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.

rpsreal commented 6 years ago

Ok, if I use python 3 I do not have the error I described in the previous comment. I think the map function is not necessary since it gives the same result a list of int: _

Python 3.5.2 (default, Nov 23 2017, 16:37:01) [GCC 5.4.0 20160609] on linux Type "help", "copyright", "credits" or "license" for more information.

list("hello".encode('ascii')) [104, 101, 108, 108, 111] list(map(int,"hello".encode('ascii'))) [104, 101, 108, 108, 111]

_

So I think the problem is not from this library, I do not think it's a hardware problem, either. I changed the Lora module and the antenna to a new one and there was no change in the result. The led on the Arduino board lights whenever a packet is sent by Raspberry pi, so I think the arduino can receive data but does not show it on the serial monitor. At this point I'm almost sure the problem is in the HadioHead library. I use this code in Arduino to receive data:

uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
uint8_t len = sizeof(buf);
void loop()
{
  if (rf95.available())
  {
    if (rf95.recv(buf, &len))
    {
      RH_RF95::printBuffer("Received: ", buf, len);
      Serial.print("Got: ");
      Serial.println((char*)buf);
      Serial.print("RSSI: ");
      Serial.println(rf95.lastRssi(), DEC);
    }
    else
    {
      Serial.println("Receive failed");
    }
  }
}

I went to see the code used by HadioHead library, which is this :

bool RH_RF95::recv(uint8_t* buf, uint8_t* len)
{
    if (!available())
    return false;
    if (buf && len)
    {
    ATOMIC_BLOCK_START;
    // Skip the 4 headers that are at the beginning of the rxBuf
    if (*len > _bufLen-RH_RF95_HEADER_LEN)
        *len = _bufLen-RH_RF95_HEADER_LEN;
    memcpy(buf, _buf+RH_RF95_HEADER_LEN, *len);
    ATOMIC_BLOCK_END;
    }
    clearRxBuf(); // This message accepted and cleared
    return true;
}
rpsreal commented 6 years ago

Hello again, I have been working on the problem yet with no solution in sight. It's not a hardware problem, and I'm pretty sure Arduino can receive the data but it's not accepted by the library, nor does it show it on the Serial Monitor. I know this because the arduino led comes on whenever Raspberry Pi sends a packet. I think the RadioHead Library only accepts the package if it has a certain configuration so I did the following test: I put an Arduino as receiver, another arduino sending packets and raspberry Pi also sending packets. Having this configuration I only receive, in the Arduino receiver on the Serial monitor, the messages sent by the other Arduino, the packets sent by Raspberry Pi are discarded. So I put Raspberry Pi this time to receive data and an Arduino to send packages with the message 'hello'. I edited the file rx_cont.py and put: print(bytes(payload).decode("utf-8",'strict')) Whenever I get an Arduino package I get the following error:

RxDone Traceback (most recent call last): File "/home/pi/pySX127x/SX127x/LoRa.py", line 158, in _dio0 self.on_rx_done() File "./rx_cont.py", line 47, in on_rx_done print(bytes(payload).decode("utf-8",'strict')) UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte

Before I solved this problem by putting 'ignore' in the decode function, like this: print(bytes(payload).decode("utf-8",'ignore'))

To try to understand exactly the package that Arduino sends, I used the following code: print(bytes(payload)) And I get this every time Raspberry Pi gets the package send by the Arduino:

RxDone b'\xff\xff\x00\x00hello\x00 \x00\x00'

I also tried this way: print(bytes(payload).decode("utf-8", "replace")) And I get this:

��hello

In conclusion, I think I have to send the package in a stable configuration for the Arduino so that the package is accepted and shown on the Serial monitor, but I do not know exactly what I have to send. I would appreciate if you could help me.

rpsreal commented 6 years ago

Ok, I finally got it working. It is necessary to send 4 characters before each message to the HadioHead library to collect the message as valid. So for anyone who is trying to communicate an arduino with the HadioHead library and a raspberry pi with this library you have to do the following: Edit the rx_cont.py file on on_rx_done: print(bytes(payload).decode("utf-8",'ignore')) This allows you to receive Arduino packages without errors or extraneous characters.

In the file tx_beacon.py edit in the start (self) function: self.write_payload([255, 255, 0, 0, 104, 101, 108, 108, 111]) To send "hello" The first 4 characters are essential for the Arduino to detect the packet sent (0xff, 0xff, 0x00, 0x00) The rest is the message "hello"

list("hello".encode('utf_8')) [104, 101, 108, 108, 111] [0xff, 0xff, 0x00, 0x00, 104, 101, 108, 108, 111] [255, 255, 0, 0, 104, 101, 108, 108, 111]

Thanks for the help mayeranalytics, you can now close this Issue

rpsreal commented 6 years ago

Just one more information: it seems that it is necessary to put a \ x00 at the end of the message so that the package is fully received by the HADIOHEAD library. Like this: (to send 'hello') self.write_payload([255, 255, 0, 0, 104, 101, 108, 108, 111, 0])

I created a fork of this library in order to communicate with the Arduino, adapted to the Ai-Thinker Ra-02 LoRa module, the code can be consulted here -> rpsreal/LoRa_Ra-02_Arduino.

mcmayer commented 6 years ago

The radiohead library requires a certain header, see line 28ff of RH_RF95.h

// The length of the headers we add.
// The headers are inside the LORA's payload
#define RH_RF95_HEADER_LEN 4

The header is used to transport some flags, I think. The final 0x00 is just the usual C-string termination.

rpsreal commented 6 years ago

I think you're right, the first 4 characters are flags. I do not know what they mean the 0xff, 0xff, 0x00, 0x00 but with these characters the communication does not have any problem, it works perfectly.