Author Topic: Sending single transmission to multiple nodes?  (Read 91698 times)

blebson

  • NewMember
  • *
  • Posts: 23
  • Country: us
Sending single transmission to multiple nodes?
« on: March 16, 2017, 12:35:08 AM »
I'm currently creating an automated blind system. Right now I have a Wifi to RF gateway controlling the different blinds separately. One of my stretch goals is to add the ability to control a group of blinds at once. Instead of sending a value (0-180) to a single blind, I want to send it to a range or subset of them. Is this possible or will I have to manually trigger each one separately?

joelucid

  • Hero Member
  • *****
  • Posts: 868
Re: Sending single transmission to multiple nodes?
« Reply #1 on: March 16, 2017, 02:53:43 AM »
That's easily possible: just send the packet to node address 255 and all nodes will receive. The problem with broadcasts is ACKs which would collide. The typical approach to deal with that weakness is to just send the data redundantly. So instead of one packet you send 3 and hope that at least one makes it to every destination.

joe

TomWS

  • Hero Member
  • *****
  • Posts: 1930
Re: Sending single transmission to multiple nodes?
« Reply #2 on: March 16, 2017, 07:48:56 AM »
I agree with Joe and would add that the packet that you broadcast could contain flags related to each of your nodes so, instead of sending to a node, whose blinds you want to adjust, you set the corresponding flag in the packet.  Each receiving node can then check to see if the broadcast affects them.

blebson

  • NewMember
  • *
  • Posts: 23
  • Country: us
Re: Sending single transmission to multiple nodes?
« Reply #3 on: March 16, 2017, 11:26:57 AM »
So that almost gets me where I need to be, the problem is that at this point I'm going to have 5 blinds connected but only three of them would function as a group. Are the only options all or one?

syrinxtech

  • Sr. Member
  • ****
  • Posts: 347
  • Country: us
    • Syrinx Technologies
Re: Sending single transmission to multiple nodes?
« Reply #4 on: March 16, 2017, 11:39:24 AM »
blebson,

I would add a "group" field to your packet.  That way, you could still send a broadcast to node 255.  Everyone would receive the message, but they would only respond if they were in the group ID. 

ChemE

  • Sr. Member
  • ****
  • Posts: 419
  • Country: us
Re: Sending single transmission to multiple nodes?
« Reply #5 on: March 16, 2017, 04:39:34 PM »
If you are going to have 5 blinds why not just use a byte or bit in the payload to correspond to each blind?  As others have said, broadcast to node 255 so they all receive the packet and then within the packet if I find 01000 000 in a byte and that 1 is my bit, then I change from open/close.  If I find a 0, I do nothing.  Or the 0s and 1s could be closed and open and I make my state whatever the flag calls for.  Just don't request an ack when your gateway broadcasts to node 255 so you don't have to handle collisions.

EDIT: Or I could have said exactly what Tom suggested, oops!  Flags is the way to go here.
« Last Edit: March 16, 2017, 04:41:08 PM by ChemE »

TomWS

  • Hero Member
  • *****
  • Posts: 1930
Re: Sending single transmission to multiple nodes?
« Reply #6 on: March 16, 2017, 07:33:50 PM »
So that almost gets me where I need to be, the problem is that at this point I'm going to have 5 blinds connected but only three of them would function as a group. Are the only options all or one?

Here is an example of what I (and apparently ChemE and syrinxtech  ;)  am/are saying:

Code: [Select]
struct PACKET
{
    uint8_t
       flags,
       openness;
} packetOut;

#define BLINDS_1   0b00000001
#define BLINDS_2   0b00000010
#define BLINDS_3   0b00000100
#define BLINDS_4   0b00001000
#define BLINDS_5   0b00010000

#define LIVING_ROOM_GROUP  (BLINDS_1 | BLINDS_2 | BLINDS_3)
#define DINING_ROOM_GROUP (BLINDS_4 | BLINDS_5)
...
  // open up the livingroom blinds
 packetOut.flags = LIVING_ROOM_GROUP;
 packetOut.openness = FULL_OPEN;    // whatever FULL Open value is...

// do three sends like Joe suggested
 radio.send(RFM69_BROADCAST, &packetOut, sizeof(packetOut);
 delay(40);
 radio.send(RFM69_BROADCAST, &packetOut, sizeof(packetOut);
 delay(40);
 radio.send(RFM69_BROADCAST, &packetOut, sizeof(packetOut);
 delay(40);
...
 // close the dining room blinds
 packetOut.flags = DINNG_ROOM_GROUP;
 packetOut.openness = FULL_CLOSE;    // whatever FULL Close value is...

// do three sends like Joe suggested
 radio.send(RFM69_BROADCAST, &packetOut, sizeof(packetOut);
 delay(40);
 radio.send(RFM69_BROADCAST, &packetOut, sizeof(packetOut);
 delay(40);
 radio.send(RFM69_BROADCAST, &packetOut, sizeof(packetOut);
 delay(40);
...


And in each of the nodes:
Code: [Select]
   #define MY_NODE_FLAG   BLINDS_3   

   if (radio.receiveDone())
   {
       if (radio.DATALEN==sizeof(struct PACKET)  && radio.TARGET == RFM69_BROADCAST)
       {
           struct PACKET
              *myPacket = (struct PACKET *)radio.DATA;
           if (myPacket->flags & MY_NODE_FLAG)
           {
                openBlinds( myPacket->openness);
           }
      }
   }

or some such...

blebson

  • NewMember
  • *
  • Posts: 23
  • Country: us
Re: Sending single transmission to multiple nodes?
« Reply #7 on: March 16, 2017, 07:39:04 PM »
So I'm currently using the Low Power Listening fork of the RFM69 library. All of my blinds are battery powered so I wanted to ensure they can be sustained but a small solar panel in cloudy Seattle...

This means that all of my transmissions will be the wake-up burst. Will this packet-based ID still work in this application?

TomWS

  • Hero Member
  • *****
  • Posts: 1930
Re: Sending single transmission to multiple nodes?
« Reply #8 on: March 17, 2017, 08:34:34 AM »
So I'm currently using the Low Power Listening fork of the RFM69 library. All of my blinds are battery powered so I wanted to ensure they can be sustained but a small solar panel in cloudy Seattle...

This means that all of my transmissions will be the wake-up burst. Will this packet-based ID still work in this application?
Yes, the content is still the same, regardless of transmission method.
Tom

syrinxtech

  • Sr. Member
  • ****
  • Posts: 347
  • Country: us
    • Syrinx Technologies
Re: Sending single transmission to multiple nodes?
« Reply #9 on: March 17, 2017, 09:50:40 AM »
Here is an example of what I (and apparently ChemE and syrinxtech  ;)  am/are saying:

Code: [Select]
struct PACKET
{
    uint8_t
       flags,
       openness;
} packetOut;

#define BLINDS_1   0b00000001
#define BLINDS_2   0b00000010
#define BLINDS_3   0b00000100
#define BLINDS_4   0b00001000
#define BLINDS_5   0b00010000

#define LIVING_ROOM_GROUP  (BLINDS_1 | BLINDS_2 | BLINDS_3)
#define DINING_ROOM_GROUP (BLINDS_4 | BLINDS_5)
...
  // open up the livingroom blinds
 packetOut.flags = LIVING_ROOM_GROUP;
 packetOut.openness = FULL_OPEN;    // whatever FULL Open value is...

// do three sends like Joe suggested
 radio.send(RFM69_BROADCAST, &packetOut, sizeof(packetOut);
 delay(40);
 radio.send(RFM69_BROADCAST, &packetOut, sizeof(packetOut);
 delay(40);
 radio.send(RFM69_BROADCAST, &packetOut, sizeof(packetOut);
 delay(40);
...
 // close the dining room blinds
 packetOut.flags = DINNG_ROOM_GROUP;
 packetOut.openness = FULL_CLOSE;    // whatever FULL Close value is...

// do three sends like Joe suggested
 radio.send(RFM69_BROADCAST, &packetOut, sizeof(packetOut);
 delay(40);
 radio.send(RFM69_BROADCAST, &packetOut, sizeof(packetOut);
 delay(40);
 radio.send(RFM69_BROADCAST, &packetOut, sizeof(packetOut);
 delay(40);
...


And in each of the nodes:
Code: [Select]
   #define MY_NODE_FLAG   BLINDS_3   

   if (radio.receiveDone())
   {
       if (radio.DATALEN==sizeof(struct PACKET)  && radio.TARGET == RFM69_BROADCAST)
       {
           struct PACKET
              *myPacket = (struct PACKET *)radio.DATA;
           if (myPacket->flags & MY_NODE_FLAG)
           {
                openBlinds( myPacket->openness);
           }
      }
   }

or some such...

TomWS, that's a sweet piece of code you provided.  I like your method better than my "group" idea.  Bit fiddling is a lost art in a lot of today's world...thanks for reminding us.

blebson

  • NewMember
  • *
  • Posts: 23
  • Country: us
Re: Sending single transmission to multiple nodes?
« Reply #10 on: May 10, 2017, 11:30:24 PM »
TomWS, I ended up using your packet idea and it worked great. I am now working on the response from the Moteino back to the base station. I wanted to use the same 'Packet' technique but add different data types. There would be three types of data, a battery percentage (int), a battery voltage (float), and a solar charging status (char or String). Is there any way to use this struct to send all three data types at once?

I currently have it defined as the following:

Code: [Select]
struct PACKET
{
  uint8_t percent;
  float voltage;
  String charger;
} packetOut;

however the float and String value don't seem to be transmitting correctly, is this a limitation of the packet concept or am I doing something wrong?

TomWS

  • Hero Member
  • *****
  • Posts: 1930
Re: Sending single transmission to multiple nodes?
« Reply #11 on: May 11, 2017, 07:37:39 AM »
TomWS, I ended up using your packet idea and it worked great. I am now working on the response from the Moteino back to the base station. I wanted to use the same 'Packet' technique but add different data types. There would be three types of data, a battery percentage (int), a battery voltage (float), and a solar charging status (char or String). Is there any way to use this struct to send all three data types at once?

I currently have it defined as the following:

Code: [Select]
struct PACKET
{
  uint8_t percent;
  float voltage;
  String charger;
} packetOut;

however the float and String value don't seem to be transmitting correctly, is this a limitation of the packet concept or am I doing something wrong?
A String 'type' is actually an instance of a class and has beaucoup stuff hidden behind the 'scenes'.  Use fixed length char array and you'll be fine.  Also, you can represent the battery voltage in uint16_t and get millivolt resolution and save two bytes (and a bunch of floating point code overhead).

As long as both ends know the structure of the packet and its based on primitive types, sending structures is trivial.

Tom
PS: I'll wager that if you search this forum for 'readvcc' you'll find a number of examples on how to read the processor's VCC in exactly uint16_t resolution.
« Last Edit: May 11, 2017, 07:39:48 AM by TomWS »

blebson

  • NewMember
  • *
  • Posts: 23
  • Country: us
Re: Sending single transmission to multiple nodes?
« Reply #12 on: May 11, 2017, 10:12:35 PM »
So at this point I'm stuck trying to send the 4 digit int for the milivolt value of the battery. I've tried sending as uint16_t and uint8_t but get garbage values from the receiving arduino. my packet definition looks as follows;

Code: [Select]
struct PACKET
{
  uint8_t percent;
  uint16_t voltage;
  char charger;
} packetOut;

Where percent is a 2 digit int, voltage is a 4 digit int and charger is a single char.

TomWS

  • Hero Member
  • *****
  • Posts: 1930
Re: Sending single transmission to multiple nodes?
« Reply #13 on: May 12, 2017, 07:29:55 AM »
So at this point I'm stuck trying to send the 4 digit int for the milivolt value of the battery. I've tried sending as uint16_t and uint8_t but get garbage values from the receiving arduino. my packet definition looks as follows;

Code: [Select]
struct PACKET
{
  uint8_t percent;
  uint16_t voltage;
  char charger;
} packetOut;

Where percent is a 2 digit int, voltage is a 4 digit int and charger is a single char.
There's nothing wrong with the structure definition, there must be a problem with the way you're sending it and/or processing it on the receiving end.  If you post those code snippets, we'll take a look.
Tom

blebson

  • NewMember
  • *
  • Posts: 23
  • Country: us
Re: Sending single transmission to multiple nodes?
« Reply #14 on: May 12, 2017, 10:54:56 AM »
I can try to post the code tonight. I'm using low power listening mode on the moteino but I'm not sure if that matters. The base station is receiving the battery percentage correctly but then gets a garbage value for voltage and nothing for charger.