Skip to content
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. Development
  3. Serial gateway, which example to follow??
  • Getting Started
  • Controller
  • Build
  • Hardware
  • Download/API
  • Forum
  • Store

Serial gateway, which example to follow??

Scheduled Pinned Locked Moved Development
19 Posts 4 Posters 7.0k Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • skatunS Offline
    skatunS Offline
    skatun
    wrote on last edited by
    #1

    Hi all, I am pretty new to Mysensor, however I have used some sensor code successfully.

    My setup is a RPI b+ running openhab connected to my gateway with usb cable which is an arduino due.

    So the plan is to use the openhab binding to connect tothe gateway. So my idea was that locally attached sensor will be assigned node id 0-9, softwareserial nodes 10-19 and rf everything higher.

    So I started reading up on the serial gateway, the one that comes in the sketch folder of the development branch, on the mysensor webpage, some on rpi. So I am unsure which one to use.. The one in the sketch folder, I dont know how to decode income serial message and send it off on the software serial, also it fails to compile when you disable RF(like if you only have locally attached sensors or software serial nodes)

    I also did some reading up on rs422 and software serial.

    So I have made a sketch that almost compiles, I only have an issue with using the MyMessage library to split the incoming string and were wondering if someone could help me out on how to use it so that i can redirect incoming nodeID 10 to software serial.

    #include <SoftwareSerial.h>
    #include <SPI.h>
    #include <MyConfig.h>
    #include <MySensors.h>
    
    
    
    // Enable debug prints to serial monitor
    //#define MY_DEBUG
    
    /*
    * Un comment the lines below whenever we want to use a radio modem..
    */
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    //
    // Enable serial gateway
    #define MY_GATEWAY_SERIAL
    
    
    
    SoftwareSerial mySerial(10, 11); // RX, TX
    
    //Some constant that holds the things received on serial line
    #define MAX_RECEIVE_LENGTH 100 // Max buffersize needed for messages coming from controller
    #define MAX_SEND_LENGTH 120 // Max buffersize needed for messages destined for controller
    char inputString[MAX_RECEIVE_LENGTH] = "";    // A string to hold incoming commands from serial/ethernet interface
    int inputPos = 0;
    boolean commandComplete = false;  // whether the string is complete
    
    
    //Switch  Bar  "Bar"  <drink>   (gBar)  {mysensors="1;2;V_LIGHT"}
    void parseAndSend(char *commandBuffer) {
      MyMessage msg = new MyMessage(); // fails here.....
      
      msg.set(commandBuffer);
    
      //Locally attached sensor......
      if (msg.destination = 0) {
    
      }
    
      //We forward our message on software serial
      else if (msg.destination = 10) {
        mySerial.write(commandBuffer);
      }
    
      // send it out on the radio modem, to be implemented later
      else {
    
      }
    
    }
    
    
    
    void setup() {
      // Send startup log message on serial
      //serial(PSTR("0;0;%d;0;%d;Gateway startup complete.\n"),  C_INTERNAL, I_GATEWAY_READY);
      //Set up all our software serial ports...
      mySerial.begin(9600);
      // Setup locally attached sensors
    }
    
    void presentation() {
      // Present locally attached sensors
      //how to do this???
    }
    
    void loop() {
      // Send locally attached sensor data here
      //gw.process();
    
      if (commandComplete) {
        // A command wass issued from serial interface
        // We will now try to send it to the actuator
        parseAndSend(inputString);
        commandComplete = false;
        inputPos = 0;
      }
    
      if (mySerial.available())
        Serial.write(mySerial.read());
    }
    
    
    void serialEvent() {
      while (Serial.available()) {
        // get the new byte:
        char inChar = (char)Serial.read();
        // if the incoming character is a newline, set a flag
        // so the main loop can do something about it:
        if (inputPos < MAX_RECEIVE_LENGTH - 1 && !commandComplete) {
          if (inChar == '\n') {
            inputString[inputPos] = 0;
            commandComplete = true;
          } else {
            // add it to the inputString:
            inputString[inputPos] = inChar;
            inputPos++;
          }
        } else {
          // Incoming message too long. Throw away
          inputPos = 0;
        }
      }
    }
    
    

    Any help will be highly appreciated

    1 Reply Last reply
    0
    • skatunS Offline
      skatunS Offline
      skatun
      wrote on last edited by
      #2

      @skatun said:

      MyMessage msg = new MyMessage(); // fails here.....

      msg.set(commandBuffer);

      It is basically this piece of the code I have problems with:)

      1 Reply Last reply
      0
      • hekH Offline
        hekH Offline
        hek
        Admin
        wrote on last edited by
        #3

        Not sure what you're doing here.. But if you want to receive data from the controller, just use the receive() function.. No need to parse any serial data. It's handled by MySensors.

        You just do exactly like any other radio node.. I.e. call present() etc,

        skatunS 1 Reply Last reply
        0
        • hekH hek

          Not sure what you're doing here.. But if you want to receive data from the controller, just use the receive() function.. No need to parse any serial data. It's handled by MySensors.

          You just do exactly like any other radio node.. I.e. call present() etc,

          skatunS Offline
          skatunS Offline
          skatun
          wrote on last edited by
          #4

          @hek
          Thanks, so this link is not valid?

          so how can I use the receive method to obtain the nodeID?

          nodeID = receive().destination
          
          1 Reply Last reply
          0
          • hekH Offline
            hekH Offline
            hek
            Admin
            wrote on last edited by
            #5

            Not if you use 2.0, which the example above looked like.

            Check out the 2.0 RelayActuator-example for an hint of how to use receive() for incoming data.

            skatunS 1 Reply Last reply
            0
            • hekH hek

              Not if you use 2.0, which the example above looked like.

              Check out the 2.0 RelayActuator-example for an hint of how to use receive() for incoming data.

              skatunS Offline
              skatunS Offline
              skatun
              wrote on last edited by
              #6

              @hek
              Thanks, I have downloaded today the 2.0 version from github
              This however gives me this error code:

              In file included from C:\Users\kim\Documents\Arduino\openhab\openhab.ino:4:0:
              
              C:\Users\kim\Documents\Arduino\libraries\MySensors/MySensors.h:287:4: error: #error No forward link or gateway feature activated. This means nowhere to send messages! Pretty pointless.
              
                 #error No forward link or gateway feature activated. This means nowhere to send messages! Pretty pointless.
              
                  ^
              

              Which I thought was patched now..

              I also tried to implement the receive code as you suggested, see code below in version 2.0 style and not 1.5 style as the webpage suggest. My gateway currently are pretty simply, if it receieve node id= 10 send it off on software serial, i.e send the whole buffer to that node. (Eventually I will have 7 software serial nodes..id =10..16 and 24 locally attached sensors, as well as a few radio nodes)

              #include <SoftwareSerial.h>
              #include <SPI.h>
              #include <MyConfig.h>
              #include <MySensors.h>
              
              // Enable debug prints to serial monitor
              //#define MY_DEBUG
              
              // Enable serial gateway
              #define MY_GATEWAY_SERIAL
              
              SoftwareSerial mySerial(10, 11); // RX, TX
              
              void setup() {
              
                //Set up all our software serial ports...
                mySerial.begin(9600);
                // Setup locally attached sensors
              }
              
              void presentation() {
                // Present locally attached sensors
              
              }
              
              void loop() {
                // Send locally attached sensor data here
                gw.process();
              
                //Just forward data received on software serial to the controller
                if (mySerial.available()) {
                  Serial.write(mySerial.read());
                }
              
              }
              
              
              void receive(const MyMessage &msg) {
              
              
                //Locally attached sensor......
                if (msg.destination = 0) {
              
                }
              
                //We forward our message on software serial
                else if (msg.destination = 10) {
                  mySerial.write(msg); //is this the complete message??
                }
              
                // send it out on the radio modem, to be implemented later
                else {
              
                }
              
              }
              
              1 Reply Last reply
              0
              • hekH Offline
                hekH Offline
                hek
                Admin
                wrote on last edited by hek
                #7

                Include the MySensor.h after #defines.

                Use one of the examples as a template. So you'll get the structuring right.

                skatunS 1 Reply Last reply
                0
                • hekH hek

                  Include the MySensor.h after #defines.

                  Use one of the examples as a template. So you'll get the structuring right.

                  skatunS Offline
                  skatunS Offline
                  skatun
                  wrote on last edited by
                  #8

                  @hek
                  Now it compiles:) Thanks. So 2 questions for you:
                  1:The receieve event is triggered when a whole string with \n is received on the serial line?
                  2: How to get the whole string sent from controller? msg.getString() or msg.getStream() (Trying to understand the MyMessage.h file...)

                  Updated code below

                  // Enable debug prints to serial monitor
                  //#define MY_DEBUG
                  
                  // Enable serial gateway
                  #define MY_GATEWAY_SERIAL
                  
                  
                  #include <SoftwareSerial.h>
                  #include <SPI.h>
                  #include <MySensors.h>
                  
                  SoftwareSerial mySerial(10, 11); // RX, TX
                  
                  void setup() {
                  
                    //Set up all our software serial ports...
                    mySerial.begin(9600);
                    // Setup locally attached sensors
                  }
                  
                  void presentation() {
                    // Present locally attached sensors
                    //how to do this???
                  }
                  
                  void loop() {
                    // Send locally attached sensor data here
                  
                    if (mySerial.available()) {
                      Serial.write(mySerial.read());
                    }
                  
                  }
                  
                  
                  void receive(const MyMessage &msg) {
                  
                  
                    //Locally attached sensor......
                    if (msg.destination == 0) {
                  
                    }
                  
                    //We forward our message on software serial
                    else if (msg.destination == 10) {
                      //mySerial.write(msg); //is this the complete message??
                    }
                  
                    // send it out on the radio modem, to be implemented later
                    else {
                  
                    }
                  
                  }
                  
                  skatunS 1 Reply Last reply
                  0
                  • skatunS skatun

                    @hek
                    Now it compiles:) Thanks. So 2 questions for you:
                    1:The receieve event is triggered when a whole string with \n is received on the serial line?
                    2: How to get the whole string sent from controller? msg.getString() or msg.getStream() (Trying to understand the MyMessage.h file...)

                    Updated code below

                    // Enable debug prints to serial monitor
                    //#define MY_DEBUG
                    
                    // Enable serial gateway
                    #define MY_GATEWAY_SERIAL
                    
                    
                    #include <SoftwareSerial.h>
                    #include <SPI.h>
                    #include <MySensors.h>
                    
                    SoftwareSerial mySerial(10, 11); // RX, TX
                    
                    void setup() {
                    
                      //Set up all our software serial ports...
                      mySerial.begin(9600);
                      // Setup locally attached sensors
                    }
                    
                    void presentation() {
                      // Present locally attached sensors
                      //how to do this???
                    }
                    
                    void loop() {
                      // Send locally attached sensor data here
                    
                      if (mySerial.available()) {
                        Serial.write(mySerial.read());
                      }
                    
                    }
                    
                    
                    void receive(const MyMessage &msg) {
                    
                    
                      //Locally attached sensor......
                      if (msg.destination == 0) {
                    
                      }
                    
                      //We forward our message on software serial
                      else if (msg.destination == 10) {
                        //mySerial.write(msg); //is this the complete message??
                      }
                    
                      // send it out on the radio modem, to be implemented later
                      else {
                    
                      }
                    
                    }
                    
                    skatunS Offline
                    skatunS Offline
                    skatun
                    wrote on last edited by
                    #9

                    @hek
                    So finally I got home to grab my arduino so I can do some hardware testing and not just software!

                    It seems like the receive method is not running on the gateway, I have read through everything on the library api three times now, but I still can not figure out how the receive method are working. It runs inside the main loop, hence you can not use any sleep routine as far as I understood.
                    0_1468333270528_Screenshot_1.png image url)

                    What can I do to get the receive method to run?

                    skatunS 1 Reply Last reply
                    0
                    • skatunS skatun

                      @hek
                      So finally I got home to grab my arduino so I can do some hardware testing and not just software!

                      It seems like the receive method is not running on the gateway, I have read through everything on the library api three times now, but I still can not figure out how the receive method are working. It runs inside the main loop, hence you can not use any sleep routine as far as I understood.
                      0_1468333270528_Screenshot_1.png image url)

                      What can I do to get the receive method to run?

                      skatunS Offline
                      skatunS Offline
                      skatun
                      wrote on last edited by
                      #10

                      Its not something in the transport class I need to change right?

                      AWIA 1 Reply Last reply
                      0
                      • skatunS skatun

                        Its not something in the transport class I need to change right?

                        AWIA Offline
                        AWIA Offline
                        AWI
                        Hero Member
                        wrote on last edited by
                        #11

                        @skatun What do you want to accomplish? The "receive method" just runs if you receive messages from other sensors (not locally connected}.

                        skatunS 1 Reply Last reply
                        0
                        • AWIA AWI

                          @skatun What do you want to accomplish? The "receive method" just runs if you receive messages from other sensors (not locally connected}.

                          skatunS Offline
                          skatunS Offline
                          skatun
                          wrote on last edited by
                          #12

                          @AWI
                          Basically I have my Gateway(Mega, might swap to Due, higher resolution ADC), on my gateway I have:
                          1 radio modem connected,
                          7 Arduino nano which are soldered to tx/rx(I might need to resolder those?),
                          12 motion sensors,
                          1 pulsePowerMeter,
                          6 ledstrips
                          1 IR generator(simulate my tv /stereo,etc remote)

                          So if my controller Openhab:
                          sends or receive CHildID = 0 then send/receive data to locally attached sensor
                          sends or receive CHildID = 10-16 then send/receive data on software serial to the 7 arduino nano(Basically relay sensor nodes)
                          sends or receive CHildID = 20-31 then send/receive data on radio to my radio nodes(temperature mainly)

                          My problem is that I can not figure out how to set up software serial with my sensor.

                           If msg.destination =16 sendTo software Serial on pin 34
                          

                          Below is a picture of my Gateway setup:
                          0_1468414835666_IMG_20160713_145404[1].jpg

                          AWIA 1 Reply Last reply
                          0
                          • skatunS skatun

                            @AWI
                            Basically I have my Gateway(Mega, might swap to Due, higher resolution ADC), on my gateway I have:
                            1 radio modem connected,
                            7 Arduino nano which are soldered to tx/rx(I might need to resolder those?),
                            12 motion sensors,
                            1 pulsePowerMeter,
                            6 ledstrips
                            1 IR generator(simulate my tv /stereo,etc remote)

                            So if my controller Openhab:
                            sends or receive CHildID = 0 then send/receive data to locally attached sensor
                            sends or receive CHildID = 10-16 then send/receive data on software serial to the 7 arduino nano(Basically relay sensor nodes)
                            sends or receive CHildID = 20-31 then send/receive data on radio to my radio nodes(temperature mainly)

                            My problem is that I can not figure out how to set up software serial with my sensor.

                             If msg.destination =16 sendTo software Serial on pin 34
                            

                            Below is a picture of my Gateway setup:
                            0_1468414835666_IMG_20160713_145404[1].jpg

                            AWIA Offline
                            AWIA Offline
                            AWI
                            Hero Member
                            wrote on last edited by
                            #13

                            @skatun I'm still confused. Looks like you are forcing the MySensors protocol to do your own thing.
                            Your topology has different nano's (nodes) connected via tx/rx to the gateway. The MySensors way to communicate with these is to treat them as 'nodes' and communicate to them by means of the wired protocol. Each of these nodes needs a different node number.
                            Then if you want to combine this with radio communication you need a different gateway which communicates by means of the wireless (rf24) protocol with the remote nodes.

                            skatunS 1 Reply Last reply
                            0
                            • AWIA AWI

                              @skatun I'm still confused. Looks like you are forcing the MySensors protocol to do your own thing.
                              Your topology has different nano's (nodes) connected via tx/rx to the gateway. The MySensors way to communicate with these is to treat them as 'nodes' and communicate to them by means of the wired protocol. Each of these nodes needs a different node number.
                              Then if you want to combine this with radio communication you need a different gateway which communicates by means of the wireless (rf24) protocol with the remote nodes.

                              skatunS Offline
                              skatunS Offline
                              skatun
                              wrote on last edited by
                              #14

                              @AWI

                              Quote:"means of the wired protocol"
                              I was so fortunate that I could connect most of my nodes and sensors wired, more reliable, no need to change battery so I tried todo so with most of my nodes and sensors.

                              Quote : "Then if you want to combine this with radio communication you need a different gateway"
                              Why do I need two gateways, why cant one gateway handle both wired and radio? For now I don't need the radio, just locally and wired connection

                              Quote:" Each of these nodes needs a different node number."
                              Yupp thats why I try to give them static node numbers: So the one on balcony gets ID 11 the one in the bar is 13 and so on. (my idea was to group ID numbers, 0 locally sensor, 10-19 software serial, >20 radio nodes, >50 wifi nodes ,>70 rs485 nodes)

                              The benefit of using MySensor is that the Openhab has a binding for it, I can use the example codes for my nodes(like the relay with button sketch) and I need some format of the string sended/received from the controller to my nodes anyway, so why not use the mysensor format?

                              so My orignally Idea was to use the serial event:

                              void serialEvent() {
                                while (Serial.available()) {
                                  // get the new byte:
                                  char inChar = (char)Serial.read();
                                  // if the incoming character is a newline, set a flag
                                  // so the main loop can do something about it:
                                  if (inputPos < MAX_RECEIVE_LENGTH - 1 && !commandComplete) {
                                    if (inChar == '\n') {
                                      inputString[inputPos] = 0;
                                      commandComplete = true;
                                    } else {
                                      // add it to the inputString:
                                      inputString[inputPos] = inChar;
                                      inputPos++;
                                    }
                                  } else {
                                    // Incoming message too long. Throw away
                                    inputPos = 0;
                                  }
                                }
                              }
                              

                              and then use the Message class to split the input buffer the string based "," like in vba I would just use arrayMy = split(inputBuffer,",")

                              Then If ID=11 forward the whole thing to software serial to the balcony, then the code on that node would be exactly the same as if the message came over the radio link.

                              That was my orginally idea, but then @hek suggested that I should rather use the receive method since this grab the buffer from serial somehow.

                              I am open to all solutions:) I just have limited space on some of my nodes which makes it hard to implement a radio link on them as well as an rs485 shield. (even using nano is hard)

                              skatunS 1 Reply Last reply
                              0
                              • skatunS skatun

                                @AWI

                                Quote:"means of the wired protocol"
                                I was so fortunate that I could connect most of my nodes and sensors wired, more reliable, no need to change battery so I tried todo so with most of my nodes and sensors.

                                Quote : "Then if you want to combine this with radio communication you need a different gateway"
                                Why do I need two gateways, why cant one gateway handle both wired and radio? For now I don't need the radio, just locally and wired connection

                                Quote:" Each of these nodes needs a different node number."
                                Yupp thats why I try to give them static node numbers: So the one on balcony gets ID 11 the one in the bar is 13 and so on. (my idea was to group ID numbers, 0 locally sensor, 10-19 software serial, >20 radio nodes, >50 wifi nodes ,>70 rs485 nodes)

                                The benefit of using MySensor is that the Openhab has a binding for it, I can use the example codes for my nodes(like the relay with button sketch) and I need some format of the string sended/received from the controller to my nodes anyway, so why not use the mysensor format?

                                so My orignally Idea was to use the serial event:

                                void serialEvent() {
                                  while (Serial.available()) {
                                    // get the new byte:
                                    char inChar = (char)Serial.read();
                                    // if the incoming character is a newline, set a flag
                                    // so the main loop can do something about it:
                                    if (inputPos < MAX_RECEIVE_LENGTH - 1 && !commandComplete) {
                                      if (inChar == '\n') {
                                        inputString[inputPos] = 0;
                                        commandComplete = true;
                                      } else {
                                        // add it to the inputString:
                                        inputString[inputPos] = inChar;
                                        inputPos++;
                                      }
                                    } else {
                                      // Incoming message too long. Throw away
                                      inputPos = 0;
                                    }
                                  }
                                }
                                

                                and then use the Message class to split the input buffer the string based "," like in vba I would just use arrayMy = split(inputBuffer,",")

                                Then If ID=11 forward the whole thing to software serial to the balcony, then the code on that node would be exactly the same as if the message came over the radio link.

                                That was my orginally idea, but then @hek suggested that I should rather use the receive method since this grab the buffer from serial somehow.

                                I am open to all solutions:) I just have limited space on some of my nodes which makes it hard to implement a radio link on them as well as an rs485 shield. (even using nano is hard)

                                skatunS Offline
                                skatunS Offline
                                skatun
                                wrote on last edited by
                                #15

                                @hek
                                I am making great progress on my gateway:) I am almost done wiring everything and software is coming along. So my sensors sends out data nicely to the controller, however I can not receive commands, which is essentials for my RGB led strips.

                                I am trying to send this from the Serial Monitor in arduino: 0,30,1,0,40,ff0000\n

                                However the received method never gets called, what am I missing?

                                // Enable debug prints to serial monitor
                                //#define MY_DEBUG
                                
                                // Enable serial gateway
                                #define MY_GATEWAY_SERIAL
                                
                                
                                #include <SoftwareSerial.h>
                                #include <SPI.h>
                                #include <MySensors.h>
                                #include <ChainableLED.h>
                                
                                SoftwareSerial mySerial(10, 11); // RX, TX
                                
                                
                                MyMessage msg1(1, V_LIGHT);
                                
                                //RGB
                                int NUM_LEDS = 34;
                                ChainableLED leds(5, 6, NUM_LEDS);  // CLK, DATA, LEDS
                                
                                //PowerMeter
                                #define DIGITAL_INPUT_SENSOR 3  // The digital input you attached your light sensor.  (Only 2 and 3 generates interrupt!)
                                #define PULSE_FACTOR 1000       // Nummber of blinks per KWH of your meeter
                                #define SLEEP_MODE false        // Watt-value can only be reported when sleep mode is false.
                                #define MAX_WATT 10000          // Max watt value to report. This filetrs outliers.
                                
                                
                                #define CHILD_ID_POWER 2       // Id of the sensor child
                                #define CHILD_ID_RGB_START 30
                                #define NUM_LEDS_STRIPS 5
                                
                                
                                int counter[NUM_LEDS_STRIPS];
                                int current[NUM_LEDS_STRIPS][3];
                                int step[NUM_LEDS_STRIPS][3];
                                
                                
                                unsigned long SEND_FREQUENCY = 20000; // Minimum time between send (in milliseconds). We don't wnat to spam the gateway.
                                double ppwh = ((double)PULSE_FACTOR) / 1000; // Pulses per watt hour
                                boolean pcReceived = false;
                                volatile unsigned long pulseCount = 0;
                                volatile unsigned long lastBlink = 0;
                                volatile unsigned long watt = 0;
                                unsigned long oldPulseCount = 0;
                                unsigned long oldWatt = 0;
                                double oldKwh;
                                unsigned long lastSend;
                                MyMessage wattMsg(CHILD_ID_POWER, V_WATT);
                                MyMessage kwhMsg(CHILD_ID_POWER, V_KWH);
                                MyMessage pcMsg(CHILD_ID_POWER, V_VAR1);
                                
                                
                                void setup() {
                                
                                  //Set up all our software serial ports...
                                  mySerial.begin(9600);
                                  // Setup locally attached sensors
                                
                                
                                  //RGB
                                
                                  leds.init();
                                  for (byte CHILD_ID_RGB = CHILD_ID_RGB_START; CHILD_ID_RGB < NUM_LEDS_STRIPS; CHILD_ID_RGB++) {
                                    counter[CHILD_ID_RGB] = 0;
                                    current[CHILD_ID_RGB][0] = 0;
                                    current[CHILD_ID_RGB][1] = 0;
                                    current[CHILD_ID_RGB][2] = 0;
                                    step[CHILD_ID_RGB][0] = 0;
                                    step[CHILD_ID_RGB][1] = 0;
                                    step[CHILD_ID_RGB][2] = 0;
                                    leds.setColorRGB(CHILD_ID_RGB, current[CHILD_ID_RGB][0], current[CHILD_ID_RGB][1], current[CHILD_ID_RGB][2]); // Turn of on startup
                                  }
                                
                                
                                  // Power Meter
                                  // Fetch last known pulse count value from gw
                                  request(CHILD_ID_POWER, V_VAR1);
                                
                                  // Use the internal pullup to be able to hook up this sketch directly to an energy meter with S0 output
                                  // If no pullup is used, the reported usage will be too high because of the floating pin
                                  pinMode(DIGITAL_INPUT_SENSOR, INPUT_PULLUP);
                                
                                  attachInterrupt(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), onPulse, RISING);
                                  lastSend = millis();
                                
                                }
                                
                                void presentation() {
                                  // Present locally attached sensors
                                
                                  //RGB 0,30,1,0,40,ff0000\n
                                  sendSketchInfo("RGB Led", "1.2");
                                  for (byte CHILD_ID_RGB = CHILD_ID_RGB_START; CHILD_ID_RGB < NUM_LEDS_STRIPS; CHILD_ID_RGB++) {
                                    present(CHILD_ID_RGB, S_RGB_LIGHT);
                                  }
                                
                                
                                  //RELAY
                                  sendSketchInfo("Relay & Button", "1.0");
                                
                                  // Register all sensors to gw (they will be created as child devices)
                                  present(1, S_LIGHT);
                                
                                
                                  //POWER METER
                                  // Send the sketch version information to the gateway and Controller
                                  sendSketchInfo("Energy Meter", "1.0");
                                
                                  // Register this device as power sensor
                                  present(CHILD_ID_POWER, S_POWER);
                                
                                
                                }
                                
                                void loop() {
                                  // Send locally attached sensor data here
                                  //send(msg1.set(true), true); // Send new state and request ack back
                                  if (mySerial.available()) {
                                    Serial.write(mySerial.read());
                                  }
                                
                                  //RGB
                                  for (byte CHILD_ID_RGB = CHILD_ID_RGB_START; CHILD_ID_RGB < NUM_LEDS_STRIPS; CHILD_ID_RGB++) {
                                    if (counter[CHILD_ID_RGB] >= 0) {
                                      counter[CHILD_ID_RGB]--;
                                      int i = 1020 - counter[CHILD_ID_RGB];
                                      current[CHILD_ID_RGB][0] = calculateVal(step[CHILD_ID_RGB][0], current[CHILD_ID_RGB][0], i);
                                      current[CHILD_ID_RGB][1] = calculateVal(step[CHILD_ID_RGB][1], current[CHILD_ID_RGB][1], i);
                                      current[CHILD_ID_RGB][2] = calculateVal(step[CHILD_ID_RGB][2], current[CHILD_ID_RGB][2], i);
                                
                                      leds.setColorRGB(CHILD_ID_RGB, current[CHILD_ID_RGB][0], current[CHILD_ID_RGB][1], current[CHILD_ID_RGB][2]);
                                    }
                                  }
                                
                                  //POWER
                                  unsigned long now = millis();
                                  // Only send values at a maximum frequency or woken up from sleep
                                  bool sendTime = now - lastSend > SEND_FREQUENCY;
                                  if (pcReceived && (SLEEP_MODE || sendTime)) {
                                    // New watt value has been calculated
                                    if (!SLEEP_MODE && watt != oldWatt) {
                                      // Check that we dont get unresonable large watt value.
                                      // could hapen when long wraps or false interrupt triggered
                                      if (watt < ((unsigned long)MAX_WATT)) {
                                        send(wattMsg.set(watt));  // Send watt value to gw
                                      }
                                      Serial.print("Watt:");
                                      Serial.println(watt);
                                      oldWatt = watt;
                                    }
                                
                                    // Pulse cout has changed
                                    if (pulseCount != oldPulseCount) {
                                      send(pcMsg.set(pulseCount));  // Send pulse count value to gw
                                      Serial.print("PulseCount:");
                                      Serial.println(pulseCount);
                                      double kwh = ((double)pulseCount / ((double)PULSE_FACTOR));
                                      oldPulseCount = pulseCount;
                                      if (kwh != oldKwh) {
                                        send(kwhMsg.set(kwh, 4));  // Send kwh value to gw
                                        oldKwh = kwh;
                                        Serial.print("KWh:");
                                        Serial.println(kwh);
                                      }
                                    }
                                    lastSend = now;
                                  } else if (sendTime && !pcReceived) {
                                    // No count received. Try requesting it again
                                    request(CHILD_ID_POWER, V_VAR1);
                                    Serial.println("requesting a new value");
                                    lastSend = now;
                                  }
                                
                                }
                                
                                
                                
                                //PowerMeter
                                void onPulse() {
                                  unsigned long newBlink = micros();
                                  unsigned long interval = newBlink - lastBlink;
                                  if (interval < 10000L) { // Sometimes we get interrupt on RISING
                                    return;
                                  }
                                  watt = (3600000000.0 / interval) / ppwh;
                                  lastBlink = newBlink;
                                
                                  pulseCount++;
                                }
                                
                                //RGB
                                void setColor(byte led, int R, int G, int B) {
                                  step[led][0] = calculateStep(current[led][0], R);
                                  step[led][1] = calculateStep(current[led][1], G);
                                  step[led][2] = calculateStep(current[led][2], B);
                                
                                  counter[led] = 255;
                                }
                                
                                int calculateStep(int prevValue, int endValue) {
                                  int step = endValue - prevValue; // What's the overall gap?
                                  if (step) {                      // If its non-zero,
                                    step = 255 / step;            //   divide by 1020
                                  }
                                  return step;
                                }
                                
                                int calculateVal(int step, int val, int i) {
                                
                                  if ((step) && i % step == 0) { // If step is non-zero and its time to change a value,
                                    if (step > 0) {              //   increment the value if step is positive...
                                      val += 1;
                                    }
                                    else if (step < 0) {         //   ...or decrement it if step is negative
                                      val -= 1;
                                    }
                                  }
                                  // Defensive driving: make sure val stays in the range 0-255
                                  if (val > 255) {
                                    val = 255;
                                  }
                                  else if (val < 0) {
                                    val = 0;
                                  }
                                  return val;
                                }
                                
                                
                                
                                
                                
                                void receive(const MyMessage & msg) {
                                  Serial.println("Hello");
                                
                                  //send(msg1.set(true), true);
                                
                                  if (msg.type == V_RGB) {
                                    String hexstring = msg.getString();
                                    long number = (long) strtol( &hexstring[0], NULL, 16);
                                    int colorR = number >> 16;
                                    int colorG = number >> 8 & 0xFF;
                                    int colorB = number & 0xFF;
                                
                                    // Write some debug info
                                    Serial.print("Incoming change for sensor:");
                                    Serial.print(msg.sensor);
                                    Serial.print(", Red: ");
                                    Serial.print(colorR);
                                    Serial.print(", Green: ");
                                    Serial.print(colorG);
                                    Serial.print(", Blue: ");
                                    Serial.print(colorB);
                                    Serial.print(", New status: ");
                                    Serial.println(msg.getString());
                                
                                    setColor(msg.sensor, colorR, colorG, colorB);
                                    //leds.setColorRGB(message.sensor, colorR, colorG, colorB);
                                  }
                                
                                  //POWER
                                  if (msg.type == V_VAR1) {
                                    pulseCount = oldPulseCount = msg.getLong();
                                    Serial.print("Received last pulse count from gw:");
                                    Serial.println(pulseCount);
                                    pcReceived = true;
                                  }
                                
                                  //Locally attached sensor......
                                  if (msg.destination == 0) {
                                
                                  }
                                
                                  //We forward our message on software serial
                                  else if (msg.destination == 10) {
                                    Serial.println("halla 3");
                                    //mySerial.write(msg.getStream()); //is this the complete message??
                                  }
                                
                                  // send it out on the radio modem, to be implemented later
                                  else {
                                
                                  }
                                
                                }
                                
                                tekkaT 1 Reply Last reply
                                0
                                • skatunS skatun

                                  @hek
                                  I am making great progress on my gateway:) I am almost done wiring everything and software is coming along. So my sensors sends out data nicely to the controller, however I can not receive commands, which is essentials for my RGB led strips.

                                  I am trying to send this from the Serial Monitor in arduino: 0,30,1,0,40,ff0000\n

                                  However the received method never gets called, what am I missing?

                                  // Enable debug prints to serial monitor
                                  //#define MY_DEBUG
                                  
                                  // Enable serial gateway
                                  #define MY_GATEWAY_SERIAL
                                  
                                  
                                  #include <SoftwareSerial.h>
                                  #include <SPI.h>
                                  #include <MySensors.h>
                                  #include <ChainableLED.h>
                                  
                                  SoftwareSerial mySerial(10, 11); // RX, TX
                                  
                                  
                                  MyMessage msg1(1, V_LIGHT);
                                  
                                  //RGB
                                  int NUM_LEDS = 34;
                                  ChainableLED leds(5, 6, NUM_LEDS);  // CLK, DATA, LEDS
                                  
                                  //PowerMeter
                                  #define DIGITAL_INPUT_SENSOR 3  // The digital input you attached your light sensor.  (Only 2 and 3 generates interrupt!)
                                  #define PULSE_FACTOR 1000       // Nummber of blinks per KWH of your meeter
                                  #define SLEEP_MODE false        // Watt-value can only be reported when sleep mode is false.
                                  #define MAX_WATT 10000          // Max watt value to report. This filetrs outliers.
                                  
                                  
                                  #define CHILD_ID_POWER 2       // Id of the sensor child
                                  #define CHILD_ID_RGB_START 30
                                  #define NUM_LEDS_STRIPS 5
                                  
                                  
                                  int counter[NUM_LEDS_STRIPS];
                                  int current[NUM_LEDS_STRIPS][3];
                                  int step[NUM_LEDS_STRIPS][3];
                                  
                                  
                                  unsigned long SEND_FREQUENCY = 20000; // Minimum time between send (in milliseconds). We don't wnat to spam the gateway.
                                  double ppwh = ((double)PULSE_FACTOR) / 1000; // Pulses per watt hour
                                  boolean pcReceived = false;
                                  volatile unsigned long pulseCount = 0;
                                  volatile unsigned long lastBlink = 0;
                                  volatile unsigned long watt = 0;
                                  unsigned long oldPulseCount = 0;
                                  unsigned long oldWatt = 0;
                                  double oldKwh;
                                  unsigned long lastSend;
                                  MyMessage wattMsg(CHILD_ID_POWER, V_WATT);
                                  MyMessage kwhMsg(CHILD_ID_POWER, V_KWH);
                                  MyMessage pcMsg(CHILD_ID_POWER, V_VAR1);
                                  
                                  
                                  void setup() {
                                  
                                    //Set up all our software serial ports...
                                    mySerial.begin(9600);
                                    // Setup locally attached sensors
                                  
                                  
                                    //RGB
                                  
                                    leds.init();
                                    for (byte CHILD_ID_RGB = CHILD_ID_RGB_START; CHILD_ID_RGB < NUM_LEDS_STRIPS; CHILD_ID_RGB++) {
                                      counter[CHILD_ID_RGB] = 0;
                                      current[CHILD_ID_RGB][0] = 0;
                                      current[CHILD_ID_RGB][1] = 0;
                                      current[CHILD_ID_RGB][2] = 0;
                                      step[CHILD_ID_RGB][0] = 0;
                                      step[CHILD_ID_RGB][1] = 0;
                                      step[CHILD_ID_RGB][2] = 0;
                                      leds.setColorRGB(CHILD_ID_RGB, current[CHILD_ID_RGB][0], current[CHILD_ID_RGB][1], current[CHILD_ID_RGB][2]); // Turn of on startup
                                    }
                                  
                                  
                                    // Power Meter
                                    // Fetch last known pulse count value from gw
                                    request(CHILD_ID_POWER, V_VAR1);
                                  
                                    // Use the internal pullup to be able to hook up this sketch directly to an energy meter with S0 output
                                    // If no pullup is used, the reported usage will be too high because of the floating pin
                                    pinMode(DIGITAL_INPUT_SENSOR, INPUT_PULLUP);
                                  
                                    attachInterrupt(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), onPulse, RISING);
                                    lastSend = millis();
                                  
                                  }
                                  
                                  void presentation() {
                                    // Present locally attached sensors
                                  
                                    //RGB 0,30,1,0,40,ff0000\n
                                    sendSketchInfo("RGB Led", "1.2");
                                    for (byte CHILD_ID_RGB = CHILD_ID_RGB_START; CHILD_ID_RGB < NUM_LEDS_STRIPS; CHILD_ID_RGB++) {
                                      present(CHILD_ID_RGB, S_RGB_LIGHT);
                                    }
                                  
                                  
                                    //RELAY
                                    sendSketchInfo("Relay & Button", "1.0");
                                  
                                    // Register all sensors to gw (they will be created as child devices)
                                    present(1, S_LIGHT);
                                  
                                  
                                    //POWER METER
                                    // Send the sketch version information to the gateway and Controller
                                    sendSketchInfo("Energy Meter", "1.0");
                                  
                                    // Register this device as power sensor
                                    present(CHILD_ID_POWER, S_POWER);
                                  
                                  
                                  }
                                  
                                  void loop() {
                                    // Send locally attached sensor data here
                                    //send(msg1.set(true), true); // Send new state and request ack back
                                    if (mySerial.available()) {
                                      Serial.write(mySerial.read());
                                    }
                                  
                                    //RGB
                                    for (byte CHILD_ID_RGB = CHILD_ID_RGB_START; CHILD_ID_RGB < NUM_LEDS_STRIPS; CHILD_ID_RGB++) {
                                      if (counter[CHILD_ID_RGB] >= 0) {
                                        counter[CHILD_ID_RGB]--;
                                        int i = 1020 - counter[CHILD_ID_RGB];
                                        current[CHILD_ID_RGB][0] = calculateVal(step[CHILD_ID_RGB][0], current[CHILD_ID_RGB][0], i);
                                        current[CHILD_ID_RGB][1] = calculateVal(step[CHILD_ID_RGB][1], current[CHILD_ID_RGB][1], i);
                                        current[CHILD_ID_RGB][2] = calculateVal(step[CHILD_ID_RGB][2], current[CHILD_ID_RGB][2], i);
                                  
                                        leds.setColorRGB(CHILD_ID_RGB, current[CHILD_ID_RGB][0], current[CHILD_ID_RGB][1], current[CHILD_ID_RGB][2]);
                                      }
                                    }
                                  
                                    //POWER
                                    unsigned long now = millis();
                                    // Only send values at a maximum frequency or woken up from sleep
                                    bool sendTime = now - lastSend > SEND_FREQUENCY;
                                    if (pcReceived && (SLEEP_MODE || sendTime)) {
                                      // New watt value has been calculated
                                      if (!SLEEP_MODE && watt != oldWatt) {
                                        // Check that we dont get unresonable large watt value.
                                        // could hapen when long wraps or false interrupt triggered
                                        if (watt < ((unsigned long)MAX_WATT)) {
                                          send(wattMsg.set(watt));  // Send watt value to gw
                                        }
                                        Serial.print("Watt:");
                                        Serial.println(watt);
                                        oldWatt = watt;
                                      }
                                  
                                      // Pulse cout has changed
                                      if (pulseCount != oldPulseCount) {
                                        send(pcMsg.set(pulseCount));  // Send pulse count value to gw
                                        Serial.print("PulseCount:");
                                        Serial.println(pulseCount);
                                        double kwh = ((double)pulseCount / ((double)PULSE_FACTOR));
                                        oldPulseCount = pulseCount;
                                        if (kwh != oldKwh) {
                                          send(kwhMsg.set(kwh, 4));  // Send kwh value to gw
                                          oldKwh = kwh;
                                          Serial.print("KWh:");
                                          Serial.println(kwh);
                                        }
                                      }
                                      lastSend = now;
                                    } else if (sendTime && !pcReceived) {
                                      // No count received. Try requesting it again
                                      request(CHILD_ID_POWER, V_VAR1);
                                      Serial.println("requesting a new value");
                                      lastSend = now;
                                    }
                                  
                                  }
                                  
                                  
                                  
                                  //PowerMeter
                                  void onPulse() {
                                    unsigned long newBlink = micros();
                                    unsigned long interval = newBlink - lastBlink;
                                    if (interval < 10000L) { // Sometimes we get interrupt on RISING
                                      return;
                                    }
                                    watt = (3600000000.0 / interval) / ppwh;
                                    lastBlink = newBlink;
                                  
                                    pulseCount++;
                                  }
                                  
                                  //RGB
                                  void setColor(byte led, int R, int G, int B) {
                                    step[led][0] = calculateStep(current[led][0], R);
                                    step[led][1] = calculateStep(current[led][1], G);
                                    step[led][2] = calculateStep(current[led][2], B);
                                  
                                    counter[led] = 255;
                                  }
                                  
                                  int calculateStep(int prevValue, int endValue) {
                                    int step = endValue - prevValue; // What's the overall gap?
                                    if (step) {                      // If its non-zero,
                                      step = 255 / step;            //   divide by 1020
                                    }
                                    return step;
                                  }
                                  
                                  int calculateVal(int step, int val, int i) {
                                  
                                    if ((step) && i % step == 0) { // If step is non-zero and its time to change a value,
                                      if (step > 0) {              //   increment the value if step is positive...
                                        val += 1;
                                      }
                                      else if (step < 0) {         //   ...or decrement it if step is negative
                                        val -= 1;
                                      }
                                    }
                                    // Defensive driving: make sure val stays in the range 0-255
                                    if (val > 255) {
                                      val = 255;
                                    }
                                    else if (val < 0) {
                                      val = 0;
                                    }
                                    return val;
                                  }
                                  
                                  
                                  
                                  
                                  
                                  void receive(const MyMessage & msg) {
                                    Serial.println("Hello");
                                  
                                    //send(msg1.set(true), true);
                                  
                                    if (msg.type == V_RGB) {
                                      String hexstring = msg.getString();
                                      long number = (long) strtol( &hexstring[0], NULL, 16);
                                      int colorR = number >> 16;
                                      int colorG = number >> 8 & 0xFF;
                                      int colorB = number & 0xFF;
                                  
                                      // Write some debug info
                                      Serial.print("Incoming change for sensor:");
                                      Serial.print(msg.sensor);
                                      Serial.print(", Red: ");
                                      Serial.print(colorR);
                                      Serial.print(", Green: ");
                                      Serial.print(colorG);
                                      Serial.print(", Blue: ");
                                      Serial.print(colorB);
                                      Serial.print(", New status: ");
                                      Serial.println(msg.getString());
                                  
                                      setColor(msg.sensor, colorR, colorG, colorB);
                                      //leds.setColorRGB(message.sensor, colorR, colorG, colorB);
                                    }
                                  
                                    //POWER
                                    if (msg.type == V_VAR1) {
                                      pulseCount = oldPulseCount = msg.getLong();
                                      Serial.print("Received last pulse count from gw:");
                                      Serial.println(pulseCount);
                                      pcReceived = true;
                                    }
                                  
                                    //Locally attached sensor......
                                    if (msg.destination == 0) {
                                  
                                    }
                                  
                                    //We forward our message on software serial
                                    else if (msg.destination == 10) {
                                      Serial.println("halla 3");
                                      //mySerial.write(msg.getStream()); //is this the complete message??
                                    }
                                  
                                    // send it out on the radio modem, to be implemented later
                                    else {
                                  
                                    }
                                  
                                  }
                                  
                                  tekkaT Offline
                                  tekkaT Offline
                                  tekka
                                  Admin
                                  wrote on last edited by tekka
                                  #16

                                  @skatun GW receive() has been fixed in PR#522. We are currently working on the 2.0.1 release, more will follow soon.

                                  skatunS 1 Reply Last reply
                                  0
                                  • tekkaT tekka

                                    @skatun GW receive() has been fixed in PR#522. We are currently working on the 2.0.1 release, more will follow soon.

                                    skatunS Offline
                                    skatunS Offline
                                    skatun
                                    wrote on last edited by
                                    #17

                                    @tekka Thanks for the feedback, does that implies if I download the dev branch from git now it should be fixed?

                                    here is the output from my serial monitor when i enabled logging:

                                    0;255;3;0;9;Starting gateway (R-NGA-, 2.0.0-beta)
                                    0;255;3;0;14;Gateway startup complete.
                                    0;2;2;0;24;
                                    0;255;3;0;9;No registration required
                                    0;255;3;0;9;Init complete, id=0, parent=0, distance=0, registration=1
                                    0;2;2;0;24;
                                    

                                    I am trying to get my RGB lights to work:

                                    
                                    #define CHILD_ID_RGB_START 30
                                    #define NUM_LEDS_STRIPS 5
                                    
                                    void presentation() {
                                      // Present locally attached sensors
                                    
                                      //RGB 0,30,1,0,40,ff0000\n
                                      sendSketchInfo("RGB Led", "1.2");
                                      Serial.println("Lets present some RGB");
                                      for (byte CHILD_ID_RGB = CHILD_ID_RGB_START; CHILD_ID_RGB < NUM_LEDS_STRIPS; CHILD_ID_RGB++) {
                                        Serial.print("RGB ID: ");
                                        Serial.println(CHILD_ID_RGB);
                                        present(CHILD_ID_RGB, S_RGB_LIGHT);
                                      }
                                    

                                    How can I add logging to Serial monitor to gateway, because Serial.println("Lets present some RGB"); does not produce any output?

                                    shouldn't this line registered my lights as sensors in MYSController?

                                    
                                    present(CHILD_ID_RGB, S_RGB_LIGHT);
                                    

                                    So I am afraid there is something wrong with my for loop, even though i can not spot the mistake.

                                    tekkaT 1 Reply Last reply
                                    0
                                    • skatunS skatun

                                      @tekka Thanks for the feedback, does that implies if I download the dev branch from git now it should be fixed?

                                      here is the output from my serial monitor when i enabled logging:

                                      0;255;3;0;9;Starting gateway (R-NGA-, 2.0.0-beta)
                                      0;255;3;0;14;Gateway startup complete.
                                      0;2;2;0;24;
                                      0;255;3;0;9;No registration required
                                      0;255;3;0;9;Init complete, id=0, parent=0, distance=0, registration=1
                                      0;2;2;0;24;
                                      

                                      I am trying to get my RGB lights to work:

                                      
                                      #define CHILD_ID_RGB_START 30
                                      #define NUM_LEDS_STRIPS 5
                                      
                                      void presentation() {
                                        // Present locally attached sensors
                                      
                                        //RGB 0,30,1,0,40,ff0000\n
                                        sendSketchInfo("RGB Led", "1.2");
                                        Serial.println("Lets present some RGB");
                                        for (byte CHILD_ID_RGB = CHILD_ID_RGB_START; CHILD_ID_RGB < NUM_LEDS_STRIPS; CHILD_ID_RGB++) {
                                          Serial.print("RGB ID: ");
                                          Serial.println(CHILD_ID_RGB);
                                          present(CHILD_ID_RGB, S_RGB_LIGHT);
                                        }
                                      

                                      How can I add logging to Serial monitor to gateway, because Serial.println("Lets present some RGB"); does not produce any output?

                                      shouldn't this line registered my lights as sensors in MYSController?

                                      
                                      present(CHILD_ID_RGB, S_RGB_LIGHT);
                                      

                                      So I am afraid there is something wrong with my for loop, even though i can not spot the mistake.

                                      tekkaT Offline
                                      tekkaT Offline
                                      tekka
                                      Admin
                                      wrote on last edited by tekka
                                      #18

                                      @skatun looks like you didn't define a radio on your GW, so your RGB example runs locally on the GW?

                                      skatunS 1 Reply Last reply
                                      0
                                      • tekkaT tekka

                                        @skatun looks like you didn't define a radio on your GW, so your RGB example runs locally on the GW?

                                        skatunS Offline
                                        skatunS Offline
                                        skatun
                                        wrote on last edited by
                                        #19

                                        @tekka Thats correct, i am only running locally attached sensor:) I was luckily enough to run sth like 35 cables to my gateway, I might add radio in the future to reach down to my basement.

                                        1 Reply Last reply
                                        0
                                        Reply
                                        • Reply as topic
                                        Log in to reply
                                        • Oldest to Newest
                                        • Newest to Oldest
                                        • Most Votes


                                        9

                                        Online

                                        11.7k

                                        Users

                                        11.2k

                                        Topics

                                        113.0k

                                        Posts


                                        Copyright 2019 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
                                        • Login

                                        • Don't have an account? Register

                                        • Login or register to search.
                                        • First post
                                          Last post
                                        0
                                        • OpenHardware.io
                                        • Categories
                                        • Recent
                                        • Tags
                                        • Popular