Switch the Moteino ID after initialize() call?

Started by Emil, May 14, 2015, 07:22:44 AM

Emil

I am implementing a dynamic (DHCP-like) ID assignment for my Moteino network. The benefit of this is being able to deploy multiple Moteino's, each running the identical sketch but still having a unique identity. If anyone is interested I can explain in more details and share code.

At boot the Moteino talks to a distinguished "gateway" ID and is assigned a specific ID for future communications. I have working software that calls initialize() in setup() and then again when switching to its assigned ID. The RFM69 library does not describe valid/invalid calling sequences.

Is it ok to call initialize() twice?

When I am switching ID, is the correct calling sequence
initialize()
encrypt()  // needed a second time?

I have seen a few crashes/reboots and wonder if there is a safe calling sequence I should be using.
I have searched the forum and internet but haven't found past discussions on this topic. Sorry if this has already been discussed.

Emil

Felix

    void setAddress(uint8_t addr);
    void setNetwork(uint8_t networkID);


Emil

Awesome. Thank you Felix/Tom.

Less than two hours from my original post and I have two excellent solutions. Faster than Microsoft support!

Emil

Emil

Felix

The library is outstanding and extremely easy to use. My request this morning was an atypical request.

Given the question i asked this morning will likely occur again, I have a minor suggestion for the library.

The naming convention for the node address varies between calls in the .cpp file and is inconsistent with the .h file.

.h initialize method signature names it as "ID"
.cpp initialize method names it "nodeID"
and the call to change it is "setAddress"

It might make the library clearer to have initialize() use an argument name of "address" or "nodeAddress".

setAddress as the method didn't click for me when I scanned the .h and .cpp files for likely methods to use.

setNodeAddress might be easier for beginners like myself to find.


RFM69.h
bool initialize(uint8_t freqBand, uint8_t ID, uint8_t networkID=1);
void setAddress(uint8_t addr);  
void setNetwork(uint8_t networkID);

RFM69.cpp
bool RFM69::initialize(uint8_t freqBand, uint8_t nodeID, uint8_t networkID)
void RFM69::setAddress(uint8_t addr)
void RFM69::setNetwork(uint8_t networkID)



Or maybe just add comments in the .h file with brief description of what each method does. Clearly you have begun doing this. I realize how busy you are, so I offer the following comments for the RFM69.h file.


    // initialize the radio
    bool initialize(uint8_t freqBand, uint8_t ID, uint8_t networkID=1);

    // set the node address
    void setAddress(uint8_t addr);

    // set the network address
    void setNetwork(uint8_t networkID);

    // check whether the radio can send a packet
    bool canSend();

    // send a packet
    // max bufferSize is 61 bytes
    void send(uint8_t toAddress, const void* buffer, uint8_t bufferSize, bool requestACK=false);

    // send a packet with retries to increase chances of success
    // 40ms roundtrip req for 61byte packets
    bool sendWithRetry(uint8_t toAddress, const void* buffer, uint8_t bufferSize, uint8_t retries=2, uint8_t retryWaitTime=40); 

    // check whether the radio has received a packet
    // should be polled immediately after sending a packet with ACK request
    bool receiveDone();

    // check whether the radio has received an acknowledgement (ACK) response
    // should be polled immediately after sending a packet with ACK request
    bool ACKReceived(uint8_t fromNodeID);

    // check whether an acknowledgement (ACK) was requested in the last received packet (non-broadcasted packet)
    bool ACKRequested();

    // send an acknowledgement (ACK) packet back to sender of last received packet
    // should be called immediately after reception in case sender wants ACK
    void sendACK(const void* buffer = "", uint8_t bufferSize=0);

    // get the frequency band (in Hz)
    uint32_t getFrequency();

    // set the frequency band (in Hz)
    void setFrequency(uint32_t freqHz);

    // set the encryption using a 16 byte key
    // To disable encryption use NULL or 0 as the key
    void encrypt(const char* key);

    // set the slave select pin
    void setCS(uint8_t newSPISlaveSelect);

    // get the received signal strength indicator (RSSI)
    int16_t readRSSI(bool forceTrigger=false);

    // set promiscuous mode
    //   true = disable filtering to capture all frames on network 
    //   false = enable node/broadcast filtering to capture only frames sent to this/broadcast address 
    void promiscuous(bool onOff=true);

    // set the radio high power to on/off
    // has to be called after initialize() for RFM69HW
    void setHighPower(bool onOFF=true); 

    // reduce/increase transmit power level
    void setPowerLevel(uint8_t level); 

    // put the radio to sleep
    void sleep();

    // get CMOS temperature (8bit)
    uint8_t readTemperature(uint8_t calFactor=0);

    // calibrate the internal RC oscillator for use in wide temperature variations
    void rcCalibration(); 

    // get the RFM69 internal register value
    uint8_t readReg(uint8_t addr);

    // set the RFM69 internal register
    void writeReg(uint8_t addr, uint8_t val);

    // serial print all the registers for debugging
    void readAllRegs();



Again, thank you for an outstanding library (and Moteino hardware)!

Emil

Felix

Thanks for the suggestions, I will consider adding the comments. Do you have a github account? Any chance you could submit a pull request with these changes that I can review and then merge? Would make my job a lot easier.

The namings are more of a convention approach.
For instance you would name address a variable and not a function. A function would get a name that suggests what the function does, a verb tells the user what happens - so setAddress() suggests the address can be changed via that function. For the casing I prefer the camelBack variation of CamelCasing. These practices are very common in software shops in small and big companies.

Emil

#6
Hi Felix

QuoteThanks for the suggestions, I will consider adding the comments. Do you have a github account? Any chance you could submit a pull request with these changes that I can review and then merge? Would make my job a lot easier.

Of course I will submit a pull request with github. I'm sure documenting the methods would be sufficient to deal with beginner questions like my earlier question.

Totally understand about the naming convention. Just pointing out a very minor naming inconsistency. It tripped me up and might trip up others.

       
  • consistent naming: initialize() and setNetwork() uses an same argument name of networkID
  • inconsistent naming: initialize() uses nodeID, but setAddress() uses addr

Emil

Hi Felix

I added a pull request to your library. Thank you again for an excellent library. Of course your Moteino's are the icing on the cake that make all my projects so easy now!

Emil

Felix

Thanks Emil for that and the feedback,
I will check it out soon!

daemach

Can you post your code please?  I'm trying to do the same thing and would hate to reinvent a perfectly good wheel.

Thanks!

Felix