Author Topic: Strange behavior on Teensy3.2 + RFM69W as gateway, talking to Moteino [solution]  (Read 4607 times)

Uncle Buzz

  • Full Member
  • ***
  • Posts: 146
  • Country: fr
EDIT: solved... before facing others issues, scroll to this post for solution.

Hi everyone !

At first, sorry for my poor english...

For testing purpose, I buyed 2 motineo R4 (with and without PCB antenna) and a RFM69W to Felix and I'm trying to deal with them.
What I want to do, is a gateway with the teensy (more power to do some other calculation, and fast USB serial included), and moteino as remote sensor node.

It's easy with Felix's example code to make moteino talking each other, but when I try to put the teensy in the game, it's game over !

I adapted the receiver.ino for teensy to make it working (removing flash and assigned PIN 14 to SCK instead of PIN 13), and I was happy to see some answer on my serial monitor... until I remark than my teensy receiving well moteino's message, but no one could hear it...

In fact, the teensy receives 3 times the same message, and got no answer when trying to ping moteino. It's like moteino send with retry 3 times (default behavior) without receiving ACK from teensy, and never reply to the ping request as they probably never received it...

Then I try to send a struct to see if I can encapsulate what I want, and as it worked like a charm beetween both moteino, teensy was not able te receive the correct message : my data are a struct with a size of 40 bytes, and when the receiver moteino receives correctly this 40 bytes, the teensy receives 60 bytes ! So it's not able to deal with them...
I tried to change the size of my struct, and when I send 12 bytes, the teensy received 16...

I used the 3.3V from teensy (250mA max),  PIN 10;11;12 and 14 (instead of 13 for LED) for SPI communication. I didn't see any changes with or without DIO0 forme RFM69 connected to a teensy pin...

I use the standard SPI library (i tried the special SPI library for teensy without any difference) and the RFM69 library + RFM69_ATC library.

Do any of you have an idea where I can dig to solve my problem ?
Did someone success to use RFM69 with teensy 3.2 and Felix's RFM69 library ?

Thanks for your help !


Uncle Buzz

  • Full Member
  • ***
  • Posts: 146
  • Country: fr
Re: Strange behavior with teensy 3.2 + RFM69W as gateway, talking to moteino
« Reply #1 on: November 03, 2016, 11:49:31 AM »
hum...
I tried more test, and I found than I received what I expect to, but where my struct has a size of 30 bytes on moteino, it has a size of 40 on teensy, probably due to the size of int or long on teensy which would be different from moteino...

Uncle Buzz

  • Full Member
  • ***
  • Posts: 146
  • Country: fr
Re: Strange behavior with teensy 3.2 + RFM69W as gateway, talking to moteino
« Reply #2 on: November 03, 2016, 12:13:09 PM »
Well...
The receiving parts work ! I had to add the delcaration __attribute__((__packed__)) on my struct on teensy, so his size it's the same than on moteino :

Code: [Select]
typedef struct __attribute__((__packed__)) {
  long timestamp;
  int16_t value;
} Acquisition;

What I understand is than since teensy's CPU is a 32bit unit, integer is coded on 4 bytes, even if i specified a smallest integer like int8_t or int16_t, space in memory is adapted to fill  out to the CPU's favored size, here 32 bit, so 2 more bytes than I expected...

I'm still having issue with teensy Tx...

Felix

  • Administrator
  • Hero Member
  • *****
  • Posts: 6866
  • Country: us
    • LowPowerLab
Re: Strange behavior with teensy 3.2 + RFM69W as gateway, talking to moteino
« Reply #3 on: November 03, 2016, 01:30:06 PM »
I haven't used a Teensy with RFM69 so I can't provide much help. Maybe the PJRC forums have more info on this.
But it sounds like the Teensy has a few gotchas like the one you discovered  :-\

jra

  • Jr. Member
  • **
  • Posts: 81
  • Country: us
Re: Strange behavior with teensy 3.2 + RFM69W as gateway, talking to moteino
« Reply #4 on: November 03, 2016, 05:47:26 PM »
Someone got this working a long while back, see https://forum.pjrc.com/threads/24576-RFM69W-(RFM69HW)-transceiver-T3?p=47264&viewfull=1#post47264 for details.  You might want to try it first with an older version of the library, c. 2014, more recent attempts seem to have been less successful https://forum.pjrc.com/threads/33382-RFM69-almost-not-working

Uncle Buzz

  • Full Member
  • ***
  • Posts: 146
  • Country: fr
Re: Strange behavior with teensy 3.2 + RFM69W as gateway, talking to moteino
« Reply #5 on: November 04, 2016, 09:19:54 AM »
Thanks for your replies !
I tried to use the old rfm69 library, but there are too many differences and so  too much work to do to make it running...
And if I understand this topics on PJRC forums, it was not working at all before a solution was found, and the workaround used is no longer necessary as it's now include in rfm69 library.

But I have another idea about my problem :
the pin DIO0 from RFM69 is attached to D0 on my teensy, and it should be used as an interrupt pin. But in the library, when _arm_ is used (it's the cas with teensy 3.x) the RF69_IRQ_PIN and RF69_IRQ_NUM are set to 10. But pin 10 is already used as CS  pin...
So, if I let RF69_IRQ_PIN and RF69_IRQ_NUM to 10, Rx is working, but not Tx, if I try to use another pin like 0 (and 0 as interrupt number since pin = interrupt number on teensy 3.x), Rx doesn't work.
From what I read in code of RFM69 library, the interupt is needed to transmit (and it would explain why it doesn't work with pin 10 as DIO0 can not be connected to these pin), but I don't know where is the problem with setting another PIN like 0...

Maybe the way I'm trying to set it is wrong ? I change
Code: [Select]
RFM69_ATC radio;
to
Code: [Select]
RFM69_ATC radio(csPin, irqPin, isRFM69HW, irqNum);
but Rx works only if irqPin and irqNum are set to 10, like in default behavior...  (I use the ATC mode, and I set same adjsutement on normal mode)

So, correct me if I'm on the wrong way, but I think my problem is about the interrupt pin...

Felix

  • Administrator
  • Hero Member
  • *****
  • Posts: 6866
  • Country: us
    • LowPowerLab
Re: Strange behavior with teensy 3.2 + RFM69W as gateway, talking to moteino
« Reply #6 on: November 04, 2016, 09:26:40 AM »
The interrupt pin you choose has to match the interrupt number defined in the library:

Code: [Select]
#elif defined(__arm__)//Use pin 10 or any pin you want
  #define RF69_IRQ_PIN          10
  #define RF69_IRQ_NUM          10

Whatever that is on the teensy...

Uncle Buzz

  • Full Member
  • ***
  • Posts: 146
  • Country: fr
Re: Strange behavior with teensy 3.2 + RFM69W as gateway, talking to moteino
« Reply #7 on: November 04, 2016, 09:39:54 AM »
If i'm not wrong, RF69_IRQ_PIN and RF69_IRQ_NUM are used as default values for creating a RFM69 or RFM69_ATC instance, but if I replace the call
Code: [Select]
RFM69_ATC radio;
by
Code: [Select]
RFM69_ATC radio(csPin, irqPin, isRFM69HW, irqNum);
, RF69_IRQ_PIN and RF69_IRQ_NUM are not used anymore, right ?

Uncle Buzz

  • Full Member
  • ***
  • Posts: 146
  • Country: fr
Re: Strange behavior with teensy 3.2 + RFM69W as gateway, talking to moteino
« Reply #8 on: November 04, 2016, 09:56:05 AM »
Well, it works !
I have to set pinMode of my interupt pin as input, declaring it as an interrupt pin is not sufficient...
Code: [Select]
pinMode(irqPin, INPUT);
I hope it's the last things to do, but right now, it work's like moteino R4 !

So here is my sketch :
Code: [Select]
// Sample RFM69 receiver/gateway sketch, with ACK and optional encryption, and Automatic Transmission Control
// Passes through any wireless received messages to the serial port & responds to ACKs
// It also looks for an onboard FLASH chip, if present
// RFM69 library and sample code by Felix Rusu - http://LowPowerLab.com/contact
// Copyright Felix Rusu (2015)

#include <RFM69.h>    //get it here: https://www.github.com/lowpowerlab/rfm69
#include <RFM69_ATC.h>//get it here: https://www.github.com/lowpowerlab/rfm69
#include <SPI.h>      //comes with Arduino IDE (www.arduino.cc)

//*********************************************************************************************
//************ IMPORTANT SETTINGS - YOU MUST CHANGE/CONFIGURE TO FIT YOUR HARDWARE *************
//*********************************************************************************************
#define NODEID        254    //unique for each node on same network
#define NETWORKID     100  //the same on all nodes that talk to each other
//Match frequency to the hardware version of the radio on your Moteino (uncomment one):
//#define FREQUENCY     RF69_433MHZ
#define FREQUENCY     RF69_868MHZ
//#define FREQUENCY     RF69_915MHZ
#define ENCRYPTKEY    "sampleEncryptKey" //exactly the same 16 characters/bytes on all nodes!
#define IS_RFM69HW    //uncomment only for RFM69HW! Leave out if you have RFM69W!
#define ENABLE_ATC    //comment out this line to disable AUTO TRANSMISSION CONTROL
//*********************************************************************************************

#define SERIAL_BAUD   115200

/**********************************************************/
/*     32 bit Teensy 3.0 and 3.1   */
/**********************************************************/
#if defined(__arm__) && defined(TEENSYDUINO) && defined(KINETISK)
#define LED           13 // teensy 3.2
#define CLOCKPIN      14 // teensy 3.2 alternative SCK since first SCK is mutualised with LED
#define T3_IRQ_PIN    0 // pin for irq on teensy 3.2
#define T3_IRQ_NUM    0 // number for IRQ on teensy 3.2
#endif

#define POINTS 5 // number of values to send at each transmission

typedef struct __attribute__((__packed__)) {
  long timestamp;
  uint8_t period;
  int16_t values[POINTS];
} Payload;

Payload theData;
//
#ifdef IS_RFM69HW
bool isRFM69HW = true;
#else
bool isRFM69HW = false;
#endif
//
#ifdef T3_IRQ_PIN
uint8_t irqPin = T3_IRQ_PIN;
#else
uint8_t irqPin = RF69_IRQ_PIN;
#endif

#ifdef T3_IRQ_NUM
uint8_t irqNum = T3_IRQ_NUM;
#else
uint8_t irqNum = RF69_IRQ_NUM;
#endif

uint8_t csPin = RF69_SPI_CS;

#ifdef ENABLE_ATC
RFM69_ATC radio(csPin, irqPin, isRFM69HW, irqNum);
#else
RFM69 radio(csPin, irqPin, isRFM69HW, irqNum);
#endif

bool promiscuousMode = false; //set to 'true' to sniff all packets on the same network

void setup() {
  Serial.begin(SERIAL_BAUD);
  delay(100);

  SPI.setSCK(CLOCKPIN); // alternative SCK pin
  pinMode(LED, OUTPUT);
  pinMode(irqPin, INPUT); // enable INPUT mode on IRQ pin

  radio.initialize(FREQUENCY, NODEID, NETWORKID);

#ifdef IS_RFM69HW
  radio.setHighPower(); //only for RFM69HW!
#endif
  radio.encrypt(ENCRYPTKEY);
  radio.promiscuous(promiscuousMode);
  //radio.setFrequency(919000000); //set frequency to some custom frequency
  char buff[50];
  sprintf(buff, "\nListening at %d Mhz...", FREQUENCY == RF69_433MHZ ? 433 : FREQUENCY == RF69_868MHZ ? 868 : 915);
  Serial.println(buff);

#ifdef ENABLE_ATC
  Serial.println("RFM69_ATC Enabled (Auto Transmission Control)");
#endif
}

void loop() {
...
}
« Last Edit: November 04, 2016, 10:00:11 AM by Uncle Buzz »

Felix

  • Administrator
  • Hero Member
  • *****
  • Posts: 6866
  • Country: us
    • LowPowerLab
Glad you figured it out, and yes you can override the CS & interrupt number in the constructor, as you already did :)

MrGlasspoole

  • NewMember
  • *
  • Posts: 35
  • Country: de
Hi Uncle Buzz.
Is the
Code: [Select]
#define POINTS 5
needed?

And i also don't see where
Code: [Select]
#ifdef IS_RFM69HW
  bool isRFM69HW = true;
#else
  bool isRFM69HW = false;
#endif
is used?

MrGlasspoole

  • NewMember
  • *
  • Posts: 35
  • Country: de
Edit:
Teensy-LC pin 0 has no interrupt capability.
Moved to pin 2 and it works.
/Edit

Ok i see where the "IS_RFM69HW" belongs and its working on the Teensy 3.2.
But the same code does not work on a Teensy-LC.
When i upload I see:
Code: [Select]
RFM69_Arduino_to_Teensy3.2_Receiver.ino: In function 'void loop()':

RFM69_Arduino_to_Teensy3.2_Receiver\RFM69_Arduino_to_Teensy3.2_Receiver.ino:105:34: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]

       theData = *(Payload*)radio.DATA; //assume radio.DATA actually contains our struct and not something else

                                  ^

RFM69_Arduino_to_Teensy3.2_Receiver\RFM69_Arduino_to_Teensy3.2_Receiver.ino:105:15: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]

       theData = *(Payload*)radio.DATA; //assume radio.DATA actually contains our struct and not something else
« Last Edit: December 09, 2016, 01:00:02 PM by Felix »

perky

  • Hero Member
  • *****
  • Posts: 873
  • Country: gb
In general type punning pointers can be dangerous when not using devices with the same word size. Type punning pointers is when, for example, you cast a pointer to a long as a byte pointer so you can read the individual bytes of that long (sometimes also assuming the significance order that they are stored in). It's often used as a simple short-cut in place of unions and structure copying (the latter can also trip you up if there is padding in one system but not in the other).
Mark.

Felix

  • Administrator
  • Hero Member
  • *****
  • Posts: 6866
  • Country: us
    • LowPowerLab
In general type punning pointers can be dangerous when not using devices with the same word size.
Isn't that usually compiler dependent?

perky

  • Hero Member
  • *****
  • Posts: 873
  • Country: gb
Yes, you're right. It's not specifically different word sizes, the order of how things are stored is not defined by C so it's compiler dependent. In theory you can get situations where bytes are stored on 32bit boundaries with padding, so casting a byte to a long might yield strange results. Anyway, if you're using the same compiler and the hardware has the same architecture you stand a good chance it will be OK.
Mark.