Skip to content
  • MySensors
  • 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. Combine several scetches to 1 node

Combine several scetches to 1 node

Scheduled Pinned Locked Moved Development
4 Posts 2 Posters 1.0k Views 2 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.
  • X Offline
    X Offline
    xypzo
    wrote on last edited by
    #1

    Hi
    I am having trouble combining multiple scetches into one node since the last mysensors library update.
    I have combined the DHT and RELAY scetches and they work great. I just want to add an interrupt sensor (door, motion, whatever) to pin 3.
    I think the problem is the sleep function. it is different in all 3 scetches, i am an absolute NOOB with programming, but simply cut/paste is not working anymore.

    Can somebody please be of any assistance? You would save the day! thanks!

    #define MY_DEBUG
    #define MY_RADIO_NRF24
    #define MY_REPEATER_FEATURE
    
    #include <SPI.h>
    #include <MySensors.h>
    #include <DHT.h>
    
    static const uint64_t UPDATE_INTERVAL = 60000;
    static const uint8_t FORCE_UPDATE_N_READS = 10;
    
    #define CHILD_ID_HUM 3
    #define CHILD_ID_TEMP 4
    #define DHT_DATA_PIN 8
    #define SENSOR_TEMP_OFFSET 0
    
    #define RELAY_PIN 4  // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
    #define NUMBER_OF_RELAYS 2 // Total number of attached relays
    #define RELAY_ON 1  // GPIO value to write to turn on attached relay
    #define RELAY_OFF 0 // GPIO value to write to turn off attached relay
    
    float lastTemp;
    float lastHum;
    uint8_t nNoUpdatesTemp;
    uint8_t nNoUpdatesHum;
    bool metric = true;
    
    MyMessage msgHum(CHILD_ID_HUM, V_HUM);
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    
    DHT dht;
    
    
    void before()
    {
      for (int sensor = 1, pin = RELAY_PIN; sensor <= NUMBER_OF_RELAYS; sensor++, pin++) {
        // Then set relay pins in output mode
        pinMode(pin, OUTPUT);
        // Set relay to last known state (using eeprom storage)
        digitalWrite(pin, loadState(sensor) ? RELAY_ON : RELAY_OFF);
      }
    }
    
    void presentation()
    {
      // Send the sketch version information to the gateway
      sendSketchInfo("DHT & Relays", "2.0");
    
      // Register all sensors to gw (they will be created as child devices)
      present(CHILD_ID_HUM, S_HUM);
      present(CHILD_ID_TEMP, S_TEMP);
      for (int sensor = 1, pin = RELAY_PIN; sensor <= NUMBER_OF_RELAYS; sensor++, pin++) {
        // Register all sensors to gw (they will be created as child devices)
        present(sensor, S_BINARY);
    
        metric = getControllerConfig().isMetric;
      }
    }
    
    void setup()
    {
    
      dht.setup(DHT_DATA_PIN); // set data pin of DHT sensor
    
      // Sleep for the time of the minimum sampling period to give the sensor time to power up
      // (otherwise, timeout errors might occure for the first reading)
      sleep(dht.getMinimumSamplingPeriod());
    
    }
    
    void loop()
    {
      // Force reading sensor, so it works also after sleep()
      dht.readSensor(true);
    
      // Get temperature from DHT library
      float temperature = dht.getTemperature();
      if (isnan(temperature)) {
        Serial.println("Failed reading temperature from DHT!");
      } else if (temperature != lastTemp || nNoUpdatesTemp == FORCE_UPDATE_N_READS) {
        // Only send temperature if it changed since the last measurement or if we didn't send an update for n times
        lastTemp = temperature;
    
        // apply the offset before converting to something different than Celsius degrees
        temperature += SENSOR_TEMP_OFFSET;
    
        if (!metric) {
          temperature = dht.toFahrenheit(temperature);
        }
        // Reset no updates counter
        nNoUpdatesTemp = 0;
        send(msgTemp.set(temperature, 1));
    
    #ifdef MY_DEBUG
        Serial.print("T: ");
        Serial.println(temperature);
    #endif
      } else {
        // Increase no update counter if the temperature stayed the same
        nNoUpdatesTemp++;
      }
    
      // Get humidity from DHT library
      float humidity = dht.getHumidity();
      if (isnan(humidity)) {
        Serial.println("Failed reading humidity from DHT");
      } else if (humidity != lastHum || nNoUpdatesHum == FORCE_UPDATE_N_READS) {
        // Only send humidity if it changed since the last measurement or if we didn't send an update for n times
        lastHum = humidity;
        // Reset no updates counter
        nNoUpdatesHum = 0;
        send(msgHum.set(humidity, 1));
    
    #ifdef MY_DEBUG
        Serial.print("H: ");
        Serial.println(humidity);
    #endif
      } else {
        // Increase no update counter if the humidity stayed the same
        nNoUpdatesHum++;
      }
    
      // Sleep for a while to save energy
      sleep(UPDATE_INTERVAL);
    }
    void receive(const MyMessage &message)
    {
      // We only expect one type of message from controller. But we better check anyway.
      if (message.type == V_STATUS) {
        // Change relay state
        digitalWrite(message.sensor - 1 + RELAY_PIN, message.getBool() ? RELAY_ON : RELAY_OFF);
        // Store state in eeprom
        saveState(message.sensor, message.getBool());
        // Write some debug info
        Serial.print("Incoming change for sensor:");
        Serial.print(message.sensor);
        Serial.print(", New status: ");
        Serial.println(message.getBool());
      }
    }
    
    skywatchS 1 Reply Last reply
    0
    • X xypzo

      Hi
      I am having trouble combining multiple scetches into one node since the last mysensors library update.
      I have combined the DHT and RELAY scetches and they work great. I just want to add an interrupt sensor (door, motion, whatever) to pin 3.
      I think the problem is the sleep function. it is different in all 3 scetches, i am an absolute NOOB with programming, but simply cut/paste is not working anymore.

      Can somebody please be of any assistance? You would save the day! thanks!

      #define MY_DEBUG
      #define MY_RADIO_NRF24
      #define MY_REPEATER_FEATURE
      
      #include <SPI.h>
      #include <MySensors.h>
      #include <DHT.h>
      
      static const uint64_t UPDATE_INTERVAL = 60000;
      static const uint8_t FORCE_UPDATE_N_READS = 10;
      
      #define CHILD_ID_HUM 3
      #define CHILD_ID_TEMP 4
      #define DHT_DATA_PIN 8
      #define SENSOR_TEMP_OFFSET 0
      
      #define RELAY_PIN 4  // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
      #define NUMBER_OF_RELAYS 2 // Total number of attached relays
      #define RELAY_ON 1  // GPIO value to write to turn on attached relay
      #define RELAY_OFF 0 // GPIO value to write to turn off attached relay
      
      float lastTemp;
      float lastHum;
      uint8_t nNoUpdatesTemp;
      uint8_t nNoUpdatesHum;
      bool metric = true;
      
      MyMessage msgHum(CHILD_ID_HUM, V_HUM);
      MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
      
      DHT dht;
      
      
      void before()
      {
        for (int sensor = 1, pin = RELAY_PIN; sensor <= NUMBER_OF_RELAYS; sensor++, pin++) {
          // Then set relay pins in output mode
          pinMode(pin, OUTPUT);
          // Set relay to last known state (using eeprom storage)
          digitalWrite(pin, loadState(sensor) ? RELAY_ON : RELAY_OFF);
        }
      }
      
      void presentation()
      {
        // Send the sketch version information to the gateway
        sendSketchInfo("DHT & Relays", "2.0");
      
        // Register all sensors to gw (they will be created as child devices)
        present(CHILD_ID_HUM, S_HUM);
        present(CHILD_ID_TEMP, S_TEMP);
        for (int sensor = 1, pin = RELAY_PIN; sensor <= NUMBER_OF_RELAYS; sensor++, pin++) {
          // Register all sensors to gw (they will be created as child devices)
          present(sensor, S_BINARY);
      
          metric = getControllerConfig().isMetric;
        }
      }
      
      void setup()
      {
      
        dht.setup(DHT_DATA_PIN); // set data pin of DHT sensor
      
        // Sleep for the time of the minimum sampling period to give the sensor time to power up
        // (otherwise, timeout errors might occure for the first reading)
        sleep(dht.getMinimumSamplingPeriod());
      
      }
      
      void loop()
      {
        // Force reading sensor, so it works also after sleep()
        dht.readSensor(true);
      
        // Get temperature from DHT library
        float temperature = dht.getTemperature();
        if (isnan(temperature)) {
          Serial.println("Failed reading temperature from DHT!");
        } else if (temperature != lastTemp || nNoUpdatesTemp == FORCE_UPDATE_N_READS) {
          // Only send temperature if it changed since the last measurement or if we didn't send an update for n times
          lastTemp = temperature;
      
          // apply the offset before converting to something different than Celsius degrees
          temperature += SENSOR_TEMP_OFFSET;
      
          if (!metric) {
            temperature = dht.toFahrenheit(temperature);
          }
          // Reset no updates counter
          nNoUpdatesTemp = 0;
          send(msgTemp.set(temperature, 1));
      
      #ifdef MY_DEBUG
          Serial.print("T: ");
          Serial.println(temperature);
      #endif
        } else {
          // Increase no update counter if the temperature stayed the same
          nNoUpdatesTemp++;
        }
      
        // Get humidity from DHT library
        float humidity = dht.getHumidity();
        if (isnan(humidity)) {
          Serial.println("Failed reading humidity from DHT");
        } else if (humidity != lastHum || nNoUpdatesHum == FORCE_UPDATE_N_READS) {
          // Only send humidity if it changed since the last measurement or if we didn't send an update for n times
          lastHum = humidity;
          // Reset no updates counter
          nNoUpdatesHum = 0;
          send(msgHum.set(humidity, 1));
      
      #ifdef MY_DEBUG
          Serial.print("H: ");
          Serial.println(humidity);
      #endif
        } else {
          // Increase no update counter if the humidity stayed the same
          nNoUpdatesHum++;
        }
      
        // Sleep for a while to save energy
        sleep(UPDATE_INTERVAL);
      }
      void receive(const MyMessage &message)
      {
        // We only expect one type of message from controller. But we better check anyway.
        if (message.type == V_STATUS) {
          // Change relay state
          digitalWrite(message.sensor - 1 + RELAY_PIN, message.getBool() ? RELAY_ON : RELAY_OFF);
          // Store state in eeprom
          saveState(message.sensor, message.getBool());
          // Write some debug info
          Serial.print("Incoming change for sensor:");
          Serial.print(message.sensor);
          Serial.print(", New status: ");
          Serial.println(message.getBool());
        }
      }
      
      skywatchS Offline
      skywatchS Offline
      skywatch
      wrote on last edited by skywatch
      #2

      @xypzo said in Combine several scetches to 1 node:

      This should do it - It compiles but I cannot test it, so that is down to you!

      #define MY_DEBUG
      #define MY_RADIO_NRF24
      #define MY_REPEATER_FEATURE
      
      static const uint64_t UPDATE_INTERVAL = 60000;
      static const uint8_t FORCE_UPDATE_N_READS = 10;
      #define DIGITAL_INPUT_SENSOR 3
      #define CHILD_ID 1
      #define CHILD_ID_HUM 3
      #define CHILD_ID_TEMP 4
      #define DHT_DATA_PIN 8
      #define SENSOR_TEMP_OFFSET 0
      
      #define RELAY_PIN 4  // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
      #define NUMBER_OF_RELAYS 2 // Total number of attached relays
      #define RELAY_ON 1  // GPIO value to write to turn on attached relay
      #define RELAY_OFF 0 // GPIO value to write to turn off attached relay
      
      #include <SPI.h>
      #include <MySensors.h>
      #include <DHT.h>
      
      float lastTemp;
      float lastHum;
      uint8_t nNoUpdatesTemp;
      uint8_t nNoUpdatesHum;
      bool metric = true;
      
      MyMessage msgHum(CHILD_ID_HUM, V_HUM);
      MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
      MyMessage msg(CHILD_ID, V_TRIPPED);
      DHT dht;
      
      
      void before()
      {
        for (int sensor = 1, pin = RELAY_PIN; sensor <= NUMBER_OF_RELAYS; sensor++, pin++) {
          // Then set relay pins in output mode
          pinMode(pin, OUTPUT);
          // Set relay to last known state (using eeprom storage)
          digitalWrite(pin, loadState(sensor) ? RELAY_ON : RELAY_OFF);
          pinMode(DIGITAL_INPUT_SENSOR, INPUT);
         digitalWrite(DIGITAL_INPUT_SENSOR, HIGH);
        }
      }
      
      void presentation()
      {
        // Send the sketch version information to the gateway
        sendSketchInfo("DHT & Relays", "2.0");
      
        // Register all sensors to gw (they will be created as child devices)
        present(CHILD_ID, S_DOOR);
        present(CHILD_ID_HUM, S_HUM);
        present(CHILD_ID_TEMP, S_TEMP);
        for (int sensor = 1, pin = RELAY_PIN; sensor <= NUMBER_OF_RELAYS; sensor++, pin++) {
          // Register all sensors to gw (they will be created as child devices)
          present(sensor, S_BINARY);
      
          metric = getControllerConfig().isMetric;
        }
      }
      
      void setup()
      {
      
        dht.setup(DHT_DATA_PIN); // set data pin of DHT sensor
      
        // Sleep for the time of the minimum sampling period to give the sensor time to power up
        // (otherwise, timeout errors might occure for the first reading)
        sleep(dht.getMinimumSamplingPeriod());
      
      }
      
      void loop()
      {
        // Force reading sensor, so it works also after sleep()
        dht.readSensor(true);
      
        // Get temperature from DHT library
        float temperature = dht.getTemperature();
        if (isnan(temperature)) {
          Serial.println("Failed reading temperature from DHT!");
        } else if (temperature != lastTemp || nNoUpdatesTemp == FORCE_UPDATE_N_READS) {
          // Only send temperature if it changed since the last measurement or if we didn't send an update for n times
          lastTemp = temperature;
      
          // apply the offset before converting to something different than Celsius degrees
          temperature += SENSOR_TEMP_OFFSET;
      
          if (!metric) {
            temperature = dht.toFahrenheit(temperature);
          }
          // Reset no updates counter
          nNoUpdatesTemp = 0;
          send(msgTemp.set(temperature, 1));
      
      #ifdef MY_DEBUG
          Serial.print("T: ");
          Serial.println(temperature);
      #endif
        } else {
          // Increase no update counter if the temperature stayed the same
          nNoUpdatesTemp++;
        }
      
        // Get humidity from DHT library
        float humidity = dht.getHumidity();
        if (isnan(humidity)) {
          Serial.println("Failed reading humidity from DHT");
        } else if (humidity != lastHum || nNoUpdatesHum == FORCE_UPDATE_N_READS) {
          // Only send humidity if it changed since the last measurement or if we didn't send an update for n times
          lastHum = humidity;
          // Reset no updates counter
          nNoUpdatesHum = 0;
          send(msgHum.set(humidity, 1));
      
      #ifdef MY_DEBUG
          Serial.print("H: ");
          Serial.println(humidity);
      #endif
        } else {
          // Increase no update counter if the humidity stayed the same
          nNoUpdatesHum++;
        }
      bool tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH;
        
          send(msg.set(tripped?"1":"0"));  // Send tripped value to gw
      
          // Sleep until interrupt comes in on motion sensor. Send update every two minute.
          sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, UPDATE_INTERVAL);
      
        // Sleep for a while to save energy
        //sleep(UPDATE_INTERVAL);
      }
      void receive(const MyMessage &message)
      {
        // We only expect one type of message from controller. But we better check anyway.
        if (message.type == V_STATUS) {
          // Change relay state
          digitalWrite(message.sensor - 1 + RELAY_PIN, message.getBool() ? RELAY_ON : RELAY_OFF);
          // Store state in eeprom
          saveState(message.sensor, message.getBool());
          // Write some debug info
          Serial.print("Incoming change for sensor:");
          Serial.print(message.sensor);
          Serial.print(", New status: ");
          Serial.println(message.getBool());
        }
      }
      

      I am not sure it is possible for the node to receive a message when it is asleep?

      X 1 Reply Last reply
      1
      • skywatchS skywatch

        @xypzo said in Combine several scetches to 1 node:

        This should do it - It compiles but I cannot test it, so that is down to you!

        #define MY_DEBUG
        #define MY_RADIO_NRF24
        #define MY_REPEATER_FEATURE
        
        static const uint64_t UPDATE_INTERVAL = 60000;
        static const uint8_t FORCE_UPDATE_N_READS = 10;
        #define DIGITAL_INPUT_SENSOR 3
        #define CHILD_ID 1
        #define CHILD_ID_HUM 3
        #define CHILD_ID_TEMP 4
        #define DHT_DATA_PIN 8
        #define SENSOR_TEMP_OFFSET 0
        
        #define RELAY_PIN 4  // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
        #define NUMBER_OF_RELAYS 2 // Total number of attached relays
        #define RELAY_ON 1  // GPIO value to write to turn on attached relay
        #define RELAY_OFF 0 // GPIO value to write to turn off attached relay
        
        #include <SPI.h>
        #include <MySensors.h>
        #include <DHT.h>
        
        float lastTemp;
        float lastHum;
        uint8_t nNoUpdatesTemp;
        uint8_t nNoUpdatesHum;
        bool metric = true;
        
        MyMessage msgHum(CHILD_ID_HUM, V_HUM);
        MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
        MyMessage msg(CHILD_ID, V_TRIPPED);
        DHT dht;
        
        
        void before()
        {
          for (int sensor = 1, pin = RELAY_PIN; sensor <= NUMBER_OF_RELAYS; sensor++, pin++) {
            // Then set relay pins in output mode
            pinMode(pin, OUTPUT);
            // Set relay to last known state (using eeprom storage)
            digitalWrite(pin, loadState(sensor) ? RELAY_ON : RELAY_OFF);
            pinMode(DIGITAL_INPUT_SENSOR, INPUT);
           digitalWrite(DIGITAL_INPUT_SENSOR, HIGH);
          }
        }
        
        void presentation()
        {
          // Send the sketch version information to the gateway
          sendSketchInfo("DHT & Relays", "2.0");
        
          // Register all sensors to gw (they will be created as child devices)
          present(CHILD_ID, S_DOOR);
          present(CHILD_ID_HUM, S_HUM);
          present(CHILD_ID_TEMP, S_TEMP);
          for (int sensor = 1, pin = RELAY_PIN; sensor <= NUMBER_OF_RELAYS; sensor++, pin++) {
            // Register all sensors to gw (they will be created as child devices)
            present(sensor, S_BINARY);
        
            metric = getControllerConfig().isMetric;
          }
        }
        
        void setup()
        {
        
          dht.setup(DHT_DATA_PIN); // set data pin of DHT sensor
        
          // Sleep for the time of the minimum sampling period to give the sensor time to power up
          // (otherwise, timeout errors might occure for the first reading)
          sleep(dht.getMinimumSamplingPeriod());
        
        }
        
        void loop()
        {
          // Force reading sensor, so it works also after sleep()
          dht.readSensor(true);
        
          // Get temperature from DHT library
          float temperature = dht.getTemperature();
          if (isnan(temperature)) {
            Serial.println("Failed reading temperature from DHT!");
          } else if (temperature != lastTemp || nNoUpdatesTemp == FORCE_UPDATE_N_READS) {
            // Only send temperature if it changed since the last measurement or if we didn't send an update for n times
            lastTemp = temperature;
        
            // apply the offset before converting to something different than Celsius degrees
            temperature += SENSOR_TEMP_OFFSET;
        
            if (!metric) {
              temperature = dht.toFahrenheit(temperature);
            }
            // Reset no updates counter
            nNoUpdatesTemp = 0;
            send(msgTemp.set(temperature, 1));
        
        #ifdef MY_DEBUG
            Serial.print("T: ");
            Serial.println(temperature);
        #endif
          } else {
            // Increase no update counter if the temperature stayed the same
            nNoUpdatesTemp++;
          }
        
          // Get humidity from DHT library
          float humidity = dht.getHumidity();
          if (isnan(humidity)) {
            Serial.println("Failed reading humidity from DHT");
          } else if (humidity != lastHum || nNoUpdatesHum == FORCE_UPDATE_N_READS) {
            // Only send humidity if it changed since the last measurement or if we didn't send an update for n times
            lastHum = humidity;
            // Reset no updates counter
            nNoUpdatesHum = 0;
            send(msgHum.set(humidity, 1));
        
        #ifdef MY_DEBUG
            Serial.print("H: ");
            Serial.println(humidity);
        #endif
          } else {
            // Increase no update counter if the humidity stayed the same
            nNoUpdatesHum++;
          }
        bool tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH;
          
            send(msg.set(tripped?"1":"0"));  // Send tripped value to gw
        
            // Sleep until interrupt comes in on motion sensor. Send update every two minute.
            sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, UPDATE_INTERVAL);
        
          // Sleep for a while to save energy
          //sleep(UPDATE_INTERVAL);
        }
        void receive(const MyMessage &message)
        {
          // We only expect one type of message from controller. But we better check anyway.
          if (message.type == V_STATUS) {
            // Change relay state
            digitalWrite(message.sensor - 1 + RELAY_PIN, message.getBool() ? RELAY_ON : RELAY_OFF);
            // Store state in eeprom
            saveState(message.sensor, message.getBool());
            // Write some debug info
            Serial.print("Incoming change for sensor:");
            Serial.print(message.sensor);
            Serial.print(", New status: ");
            Serial.println(message.getBool());
          }
        }
        

        I am not sure it is possible for the node to receive a message when it is asleep?

        X Offline
        X Offline
        xypzo
        wrote on last edited by xypzo
        #3

        IT WORKS, thank you very much!
        One thing, the interrupt (motion) status is only sent when the other data (temp hum) is being send. So once a minute it jumps from "on" to "off" in stead of every time the Sensor goes HI/LO.
        Is there a way to fix that?
        Thanks again, you are a HERO

        skywatchS 1 Reply Last reply
        0
        • X xypzo

          IT WORKS, thank you very much!
          One thing, the interrupt (motion) status is only sent when the other data (temp hum) is being send. So once a minute it jumps from "on" to "off" in stead of every time the Sensor goes HI/LO.
          Is there a way to fix that?
          Thanks again, you are a HERO

          skywatchS Offline
          skywatchS Offline
          skywatch
          wrote on last edited by skywatch
          #4

          @xypzo > One thing, the interrupt (motion) status is only sent when the other data (temp hum) is being send. So once a minute it jumps from "on" to "off" in stead of every time the Sensor goes HI/LO.

          Is there a way to fix that?

          Don't sleep the node. It won't be able to receive messages during it's sleep anyway so incomming messages will be lost as well.

          1 Reply Last reply
          0

          Hello! It looks like you're interested in this conversation, but you don't have an account yet.

          Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

          With your input, this post could be even better 💗

          Register Login
          Reply
          • Reply as topic
          Log in to reply
          • Oldest to Newest
          • Newest to Oldest
          • Most Votes


          10

          Online

          12.0k

          Users

          11.2k

          Topics

          113.4k

          Posts


          Copyright 2025 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
          • MySensors
          • OpenHardware.io
          • Categories
          • Recent
          • Tags
          • Popular