Hi
my setup is as following:
code: PIC24 = Node
PCDuino = Gateway
distance = 1m
antenna = 83mm cable
PIC24 <-SPI-> RFM69CW )))))))sendWithRetry())))))-> RFM69CW <-SPI-> PCDuino (receiving every paket. RSSI = -105)
PCDuino <-SPI-> RFM69CW ))))))))sendACK())))))))-> RFM69CW <-SPI-> PIC24 (receiving ACK only each 3-10 time. RSSI = -30)
My problem is, i don´t know where i have to search for the problem. Does the RSSI shows that the radio on PIC24 have problems with receiving or do the radio on the PCDuino have problems with sending?
It´s curious that the ACK is randomly receiving.
BR from germany
Quote from: Smu_Puh on March 21, 2016, 12:38:21 PM
my setup is as following:
code: PIC24 = Node
PCDuino = Gateway
Hi,
What is PIC24 and PCDuino?
PIC24 is the running µC (PIC24FJ256DA210) on that the node-project is running and PCDuino is an PC-like Arduino with linux on it (PCDuino V3) and the gateway running on it.
Sorry, not familiar with that hardware.
;D The Hardware will not be the point.
My question focus on the problem-finding-path. I see that one of my transeivers have problem with sending or receiving. I´m not so familiar with the RSSI function, so i don´t know what the bad value of -105 tells me.
Tells me that the sending of PIC24-side is poor or the receiving on PCDuino-side is poor?
Maybe the PcDuino is the wrong tool for the job: it's using its very fast arm processor to more or less run a software emulation of an atmega328, but it's only getting time slices from the linux OS, which has an overhead during which it can't be paying full attention. i.e. it's not deterministic real-time like a dedicated mcu. Plus, who knows how good (or not) the emulation really is? I don't see any meaningful upside to justify this approach.
So you think the PCDuino is the problem in this case?
Because the SPI-communication works correct and i´m using the arduinish header pis for communication with the RFM module.
Am i right, that the rssi value, my PCDuino-gateway-code shows me, after receiving the packet, tells me that the PCDuino do have a problem?
The gateway-side (PCDuino) receives everything. But the PIC24-side receives only randomly.
I'm just saying that if you're going to plug in something exotic, it's less headache to start first with standardized hardware that's known to work, verify it's working, and then later go exotic. Otherwise, there's too many uncontrolled variables in effect all at once, which (obviously) makes troubleshooting difficult.
Ok, but what do the RSSI-values tell me exactly (first post) ?
Simply put, the -105 tells you the radio, as presently configured, is registering a relatively weak signal. In contrast, -30 is a very strong signal. Assuming those values are typical, I'm not sure what would explain such a large asymmetry in your particular case. There are many different possibilities as to why that might happen, and I doubt anyone could be a priori certain as to which is in play based purely on the information you have provided. You might get lucky and find the cause right away, or it might lead in unexpected directions and take a very long time to sort. By now I've logged enough time debugging RFM69 related issues that I appreciate the value of starting out with a backstop to limit the downside: i.e. it mitigates against the otherwise unprotected risk of falling into an unexpectedly deep hole of unknowns.
Anyhow, good luck with your project.
Thank you WhiteHare,
I´m also a friend of developing upwards step-by-step to know at a certain points what´s going on everytime.
By know, i have no big choise to start with for example moteino-modules and go on porting it to my system. Because i know the moteinos will work. Nevermind.
I think i have a new clue, which points on the big difference between both RSSI values.
On the PIC side, runs the Node-project. I´ve ported the whole library (rfm.cpp rfm.h node ...) to C without trouble. The only thing that i have problems with is the arduinish millis(),which in my port is not exactly everytime 1ms.
When i add a certain delay direct after the "setMode(RF69_MODE_TX)" in "void RFM69::sendFrame", like 10ms, the received RSSI-value on the PCDuino-side changes from ca. -100 to ca. -35 dBm.
In my understanding, the TX-mode need some time to warm up. Maybe i have the same problem with the RX-mode, that it warms not long enough up, that i loose some ACK-pakets sended from PCDuino <-> PIC.
Am i thinking in the right direction? Do i have to check the mode-changes?
Quote from: Smu_Puh on March 23, 2016, 04:44:33 PM
Do i have to check the mode-changes?
That's a very good question, and I don't know whether or not it has ever been definitely proven one way or the other. Maybe a careful reading of the datasheet would answer the question, but I have not embarked upon that for this particular question.
I´ve putted while ((rfm69_readReg(REG_IRQFLAGS1) & RF_IRQFLAGS1_MODEREADY) == 0x00); after each setMode as seen here:
void rfm69_setMode(UINT8 newMode) {
if (newMode == _mode)
return;
switch (newMode) {
case RF69_MODE_TX:
rfm69_writeReg(REG_OPMODE, (rfm69_readReg(REG_OPMODE) & 0xE3) | RF_OPMODE_TRANSMITTER);
if (_isRFM69HW)rfm69_setHighPowerRegs(TRUE);
while ((rfm69_readReg(REG_IRQFLAGS1) & RF_IRQFLAGS1_MODEREADY) == 0x00);
// DelayMs(10);
break;
case RF69_MODE_RX:
rfm69_writeReg(REG_OPMODE, (rfm69_readReg(REG_OPMODE) & 0xE3) | RF_OPMODE_RECEIVER);
if (_isRFM69HW)rfm69_setHighPowerRegs(FALSE);
while ((rfm69_readReg(REG_IRQFLAGS1) & RF_IRQFLAGS1_MODEREADY) == 0x00);
// DelayMs(10);
break;
case RF69_MODE_SYNTH:
rfm69_writeReg(REG_OPMODE, (rfm69_readReg(REG_OPMODE) & 0xE3) | RF_OPMODE_SYNTHESIZER);
break;
case RF69_MODE_STANDBY:
rfm69_writeReg(REG_OPMODE, (rfm69_readReg(REG_OPMODE) & 0xE3) | RF_OPMODE_STANDBY);
// DelayMs(10);
break;
case RF69_MODE_SLEEP:
rfm69_writeReg(REG_OPMODE, (rfm69_readReg(REG_OPMODE) & 0xE3) | RF_OPMODE_SLEEP);
break;
default: //RF69_OP_NONE // NONE
return;
}
// we are using packet mode, so this check is not really needed
// but waiting for mode ready is necessary when going from sleep because the FIFO may not be immediately available from previous mode
while (_mode == RF69_MODE_SLEEP && (rfm69_readReg(REG_IRQFLAGS1) & RF_IRQFLAGS1_MODEREADY) == 0x00); // wait for ModeReady
_mode = newMode;
}
Nothing changed on the RSSI (still bad).
Only when i put a little delay in the rfm69_sendFrame methode, the RSSI goes ca. -35dBm RSSI:
void rfm69_sendFrame(UINT8 toAddress, const void* buffer, UINT8 bufferSize, BOOL requestACK, BOOL sendACK) {
rfm69_setMode(RF69_MODE_STANDBY); // turn off receiver to prevent reception while filling fifo
while ((rfm69_readReg(REG_IRQFLAGS1) & RF_IRQFLAGS1_MODEREADY) == 0x00); // wait for ModeReady
rfm69_writeReg(REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_00); // DIO0 is "Packet Sent"
if (bufferSize > RF69_MAX_DATA_LEN) bufferSize = RF69_MAX_DATA_LEN;
UINT8 CTLbyte = 0x00;
if (sendACK)
CTLbyte = RFM69_CTL_SENDACK;
else if (requestACK)
CTLbyte = RFM69_CTL_REQACK;
UINT8 _address = 15; //64; //replace with nodeID
UINT8 tmpRADIO_IE = RADIO_IE;
RADIO_IE = 0; // disable radio ints during communication
RADIO_CS = 0; // select radio SPI bus
spiPut(REG_FIFO | 0x80);
spiPut(bufferSize + 3);
spiPut(toAddress);
spiPut(_address);
spiPut(CTLbyte);
UINT8 i = 0;
for (i; i < bufferSize; i++) {
spiPut(((UINT8*) buffer)[i]);
}
RADIO_CS = 1; // de-select radio SPI bus
RADIO_IE = tmpRADIO_IE; // restore interrupt state
// no need to wait for transmit mode to be ready since its handled by the radio
rfm69_setMode(RF69_MODE_TX);
RADIO_IE = 0;
UINT32 txStart = millis();
while (RADIO_D0_PIN == 0 && millis() - txStart < RF69_TX_LIMIT_MS); // wait for DIO0 to turn HIGH signalling transmission finish
// while (rfm69_readReg(REG_IRQFLAGS2) & RF_IRQFLAGS2_PACKETSENT == 0x00); // wait for ModeReady
DelayMs(20);
RADIO_IF = 0;
RADIO_IE = 1;
rfm69_setMode(RF69_MODE_STANDBY);
}
:o
The usual way is to monitor REG_OPMODE until it shows the target mode has become operational. Just looking at MODEREADY might give you a false positive because, for example, if moving into RX mode from idle mode, the sequencer first has to do PLL mode.
So, come to think of it, that actually answers my own question (cf. reply #11 above): it is an example that proves the need to check for mode change completion. :)
Still the same behavior...
I have risen the retrayWaitTime to 400ms, the retries to 4 times and set a 20ms Delay right after the while (RADIO_D0_PIN == 0); in sendFrame
With this setting i´m receiving 8 of 10 acknowledgements and a very low RSSI again.
Anywone else?
Hi,
i´m getting closer and closer to the solution.
Now, i´m getting 100% of the acknoledgments and realistic RSSI-values!
It looks like the problem is
while (digitalRead(_interruptPin) == 0);
in
void RFM69::sendFrame(...)
When i comment that line out and use instead only
while(millis() - txStart < RF69_TX_LIMIT_MS);,
everything works fine...
So i think that somthing running too fast in this section
Have you tried using a weak pullup resistor on the interrupt pin? It sounds like there's a chance that may solve the issue your hardware is encountering without your having to hack the library.
Hi WhiteHare,
i don´t know why an pull-up will help in this situation. The interrupt works well, but to fast in my mind.
Only because you had said that the place in the code where it was hungup was:
while (digitalRead(_interruptPin) == 0);
The question, which probably only you can answer, should be: why is the interrupt pin forever LOW? Is there something about your unusual hardware that's causing that? Or maybe your RSSI threshold is set wrong , and so the interrupt is triggering nearly immediately all the time (depending on how your software is configured to trigger)?
Ok little missunderstanding :)
The interrupt doesn´t hang forever. It works well. But i have to put a little delay at it because it interrupts like imidialy after going to TX-mode, so my RSSI value will be bad if i don´t input a little delay.
What is it that triggers your interrupt pin during Rx? Is it an RSSI that's above threshhold, or it is packet received, or....? It sounds as though triggering the interrupt based on packet received would address your issue.