Communication only works one way regardless of device

Started by kolaf, April 16, 2016, 04:54:49 PM

kolaf

For the noise problem I configure the node to attach the sensed RSSI directly before sending the packet to the packet so that the Gateway will display it. I then powered the node from a battery to see if the values changed. They did not. I get the same values when using the battery as I do when powering it from a USB port, around -65 to -75. The value varies depending on how I positioned the antenna and where my body is in relation to the node and other equipment in my room. I'm therefore guessing that this is actual background noise. Based on your comments I assume my best bet is to simply raise or remove the CSMA limit.

@WhiteHare all my moteinos a few years old, I think. I have never gotten any RFM69HW module separately, although I have some moteino clones as well.

joelucid

Wow, -65 dBm - that is VERY noisy in particular if it's continuous. This will impact your range very significantly so it's worth trying to move the frequency a little. Which you can easily do - just look at rfm69.cpp and how it sets the three frequency registers.

joelucid

I need to ask: you do put the radio into rx while you measure RSSI, correct? Otherwise this might be the RSSI from the last ack.

kolaf

Yes, it is in receive mode. I am reporting the value as is seen in the canSend function.

perky

That calls readRSSI() which seems to just read the RSSI register assuming the DAGC is continually updating it, but I'm really not sure that happens until it starts receiving something, and even then it seems flaky. I couldn't get it to work properly and I think WhiteHare had the same issue. If you replace that with one of the routines in that RSSI thread you may have more joy.

Something like this (untested):

uint8_t getRssi(void)
{
    uint8_t oldRssiThreshold;
    uint8_t rssiVal;

    oldRssiThreshold = rfm69RdSpi(REG_RSSITHRESH);
    rfm69WrSpi(REG_RSSITHRESH, 0xFF);  // permanently trigger
 
    while((rfm69RdSpi(REG_IRQFLAGS1) & IRQFLAGS1_RSSI)==0); // wait for RSSI
    rssiVal = rfm69RdSpi(REG_RSSIVALUE); // read RSSI

    // empty the FIFO if a packet received to restart receiver, 
    // otherwise RSSI value freezes
    if(rfm69RdSpi(REG_IRQFLAGS2) & IRQFLAGS2_PAYLOADREADY)
    {   
        while(rfm69RdSpi(REG_IRQFLAGS2) & IRQFLAGS2_FIFONOTEMPTY)
        {
           rfm69RdSpi(REG_FIFO);
        }
    }
    else
    {
        // restart to force a new reading
        rfm69WrSpi(REG_PACKETCONFIG2, (PACKETCONFIG2_RESTARTRX | PACKETCONFIG2_AUTORXRESTARTON));
    }
    rfm69WrSpi(REG_RSSITHRESH, oldRssiThreshold); // restore RSSI threshold
    
    return(rssiVal);
}

kolaf

Thanks. I guess this is what I should have been able to glean from the other thread we talked about? Apparently I didn't read it carefully enough :-).

Anyway, I implemented the function and fixed it up a bit to make it work, but in the end it seems to report the exact same values as the other function does. I still get between -64 and -70 located around 1 m away from my computer equipment.

The working function looks like this:

int16_t RFM69::getRssi(void)
{
    uint8_t oldRssiThreshold;
    int16_t rssiVal;

    oldRssiThreshold = readReg(REG_RSSITHRESH);
    writeReg(REG_RSSITHRESH, 0xFF);  // permanently trigger
 
    while((readReg(REG_IRQFLAGS1) & RF_IRQFLAGS1_RSSI)==0); // wait for RSSI
    rssiVal = -readReg(REG_RSSIVALUE); // read RSSI
    rssiVal >>= 1;

    // empty the FIFO if a packet received to restart receiver, 
    // otherwise RSSI value freezes
    if(readReg(REG_IRQFLAGS2) & RF_IRQFLAGS2_PAYLOADREADY)
    {   
        while(readReg(REG_IRQFLAGS2) & RF_IRQFLAGS2_FIFONOTEMPTY)
        {
           readReg(REG_FIFO);
        }
    }
    else
    {
        // restart to force a new reading
        writeReg(REG_PACKETCONFIG2, (RF_PACKET2_AUTORXRESTART_ON | RF_PACKET2_AUTORXRESTART_ON));
    }
    writeReg(REG_RSSITHRESH, oldRssiThreshold); // restore RSSI threshold
    
    return(rssiVal);
}

perky

Well, that seems to have eliminated the RSSI reading function and it looks like that's the real noise level. Have you been able to get any lower readings, like remove the antenna, battery operate and stick inside a metal box? And maybe temorarily tack the antenna pin to ground while you do it (don't transmit while you do that)?

kolaf

I bumped the frequency up to 869 and this dropped the rssi down to -95/-100. I guess the reason for the high RSSI is interference with my zwave network at 868.47 MHz. Still, it is a bit weird says the zwave network is packet-based and does not transmit that often.

Edit: Unfortunately I cannot get the communication to work either on 869 or 867 MHz. I try to change the frequency simply by replacing the three bytes in the radio initialisation so that it looks like this:
/* 0x07 */ { REG_FRFMSB, (uint8_t) (freqBand==RF69_315MHZ ? RF_FRFMSB_315 : (freqBand==RF69_433MHZ ? RF_FRFMSB_433 : (freqBand==RF69_868MHZ ? RF_FRFMSB_867 : RF_FRFMSB_915))) },
    /* 0x08 */ { REG_FRFMID, (uint8_t) (freqBand==RF69_315MHZ ? RF_FRFMID_315 : (freqBand==RF69_433MHZ ? RF_FRFMID_433 : (freqBand==RF69_868MHZ ? RF_FRFMID_867 : RF_FRFMID_915))) },
    /* 0x09 */ { REG_FRFLSB, (uint8_t) (freqBand==RF69_315MHZ ? RF_FRFLSB_315 : (freqBand==RF69_433MHZ ? RF_FRFLSB_433 : (freqBand==RF69_868MHZ ? RF_FRFLSB_867 : RF_FRFLSB_915))) },

Note the reference to 867. It seems to read the RSSI correctly, but the gateway is not able to receive anything that is sent by the node. I'm not sure if this is because sending fails or if reception fails. Is there any other failsafe that needs to be changed to allow it to transmit at a different frequency, perhaps?

Edit: I am afraid I broke something. I am now not able to receive anything at the gateway. I can verify that the rssi recorded by the gateway increases from -65 to around -17 the short period the node transmits, but it does not seem to be able to detect the packet. I have reverted all changes I did to the frequency shifting. Are there some kind of registers I need to explicitly reset or something to get the frequency to stick?

Edit again: it turns out that calling the getRssi function repeatedly before sending cause something to fail. As soon as I removed this, communication between the two devices was restored as normal, even with the new frequency. I'm happy to report that collocation with the sensor inside my barn (50 m away) has been restored after changing the frequency, probably because a got away from the noise near the gateway which was higher than the signal from the barn node (-77).

So to summarise, Fixing the receiver sleep/standby functionality, reducing the bit rate, and changing the frequency was what it took for me to get a (for now) stable network :-). Thanks for the help, guys.

perky

Well, that's worrying. You're in Norway right? I was under the impression the 868.0MHz to 868.6MHz band has been harmonized over Europe and is restricted to 25mW erp and 1% duty cycle, unless you use LBT+AFA but the effect is still to reduce the duty cycle on any particular frequency. So if your RSSI readings are correct it means the z-wave system (or something) is permanently broadcasting! That's not good.

Anyway, -95 to -100 is much better, although I would expect a little lower. At least you can move forward now ;-)
Mark.

WhiteHare

#54
Quote from: perky on April 19, 2016, 04:01:19 PM
I'm going to throw something out there, I noticed on my setup (my own code, I don't use any libraries) that the receiver would refuse to decode the first packet it sees after transitioning from standby mode to RX mode. It was strange because it saw an RSSI interrupt of the correct value and at the correct time, but did not detect an address match or get a packet received for the first packet.

@perky I'm willing to tack a crack at reproducing the failure sequence you're experiencing, but before I do, just a point of clarification.  I'm assuming your interrupt handling routine remains active when transitioning from standby into RxMode using the sequencer (or are you waiting until ModeReady before attaching the ISR and/or enabling interrupts?), and that you're in packet mode (obviously), with the interrupt tied to DIO0, and DIOx mapping is 11b.  In this case, you're getting two interrupts: the first occuring when PLL Locks and then the second when RSSI goes HIGH.  So, was transmission of the packet (the one which you're saying the RFM69 refused to decode) started immediately after ModeReady went high?  The reason I ask is that if it was started too much earlier, then the RSSI might still go HIGH (i.e. the second interrupt) and even appear to have the right RSSI value based on energy received from bits transmitted after the preamble, even though at that point the packet was officially missed.  So, I guess I'm wondering whether you've ruled out that possibility, and if so, how, so that I can attempt to reproduce your finding using your same method.

As an aside, it appears as though the RFM69 is going to keep the Rx settings it picked during the RSSI samplings (which might have been based on garbage frame fragments or junk transmissions from some other kind of radio or simply spurious noise) basically forever until it finally does actually receive a valid packet, but which must be received using those possibly erroneous settings (or unless you manually program a time-out via the mcu to restart Rx-mode after the RSSI flag goes HIGH if no packet has been received within a particular timeframe).  Other than Listen-Mode, I don't remember reading anywhere that the RFM69 will ever time itself out and restart Rx-mode on its own, that is unless after a packet it deems valid is received and/or its FIFO is subsequently emptied.  Is that right?  Also, if RxBw were narrow and if AFC happened to screw up for some reason and pull the RFM69 too far from the proper Rx frequency, I suppose it might be lost that way forever unless the mcu was programmed to eventually timeout waiting for a packet to be received and instead restart the Rx-mode.  It does look as though the RFM69 has a timeout function (described in 3.4.18 of the SX1231h datasheet), but it appears it only (?) is "used to warn the companion processor to shut down the receiver and return to a lower power mode."

perky

OK, first thing is I am not using any libraries. The code is actually quite simple, I'm polling the SPI for flags like RSSI, address match and payload ready bits so don't use interrupts. The RSSI status happens at exactly the correct time (seen on a scope by setting an output when the SPI reads an RSSI status), and the register reads the expected RSSI, but no address match (and subsequently no payload ready) when putting into RX mode from standby. A simple change to put into sleep rather than standby fixes it. The datasheet says that entering RX mode from any state should reset the receiver, including from standby, but this appears not to reset it fully. I put it into RX mode about 5ms before the packet is sent from the server, I see that exact timing on the scope so it's not immediately triggering on noise. I see exactly the same timing when using sleep instead, but this time I get an address match. It really does look like the internals are not being reset properly.

I hope you can re-create it, it'll add more weight to the argument.
Mark.

kolaf

Hi guys,

Any progress on pinpointing the issue and creating a better fix for it?

My system has been running quite stably for a time now after switching from standby to sleep, so I'm quite happy.

I just thought I would give a short update on my background noise issue. I bought a cheap sdr radio which I plugged into my android phone to use a is a cheap frequency analyser. I have attached a screenshot where it is tuned to the 868 MHz band. As you can see, it is quite noisy, so I clearly have some kind of transmitter that is very active on this band. It's quite constant everywhere in the house, and even outside several hundred metres from my house. I have no idea what it is yet, but I'm planning to do some strangulation to see if I can figure it out :-).

https://goo.gl/photos/vqo41ZZ3W8H1HRQY6

joelucid

#57
I can't help you with your background noise issue obviously. But your posts were the ones that finally pushed me to get a cheap sdr myself. I can only recommend it to everybody. $20 or so and you can finally see what the radios are doing in real time. No more wondering whether you have a bug on the rx or tx side. Very useful, thanks!