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. My Project
  3. Rain Gauge stopped sending[Solved]

Rain Gauge stopped sending[Solved]

Scheduled Pinned Locked Moved My Project
10 Posts 3 Posters 2.1k 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.
  • F Offline
    F Offline
    flopp
    wrote on last edited by flopp
    #1

    It was working for at least 24 hour then suddenly it stopped.

    DEBUG

    send: 24-24-6-0 s=255,c=0,t=17,pt=0,l=5,sg=0,st=ok:1.5.1
    send: 24-24-6-0 s=255,c=3,t=6,pt=1,l=1,sg=0,st=fail:6
    sensor started, id=24, parent=6, distance=2
    send: 24-24-6-0 s=255,c=3,t=11,pt=0,l=10,sg=0,st=ok:Rain Gauge
    send: 24-24-6-0 s=255,c=3,t=12,pt=0,l=3,sg=0,st=fail:1.8
    send: 24-24-6-0 s=1,c=0,t=10,pt=0,l=0,sg=0,st=ok:
    send: 24-24-6-0 s=2,c=0,t=30,pt=0,l=0,sg=0,st=ok:
    

    Seconds row, does that mean temperature?

    Ethernet Gateway 1.5.1
    Sensor Node 1.5.1
    Repeater Node 1.5.1

    Other Sensor nodes is connected and works fine.

    This is my sketch

    #include <SPI.h>
    #include <MySensor.h>  
    
    // Running this in Domoticz stable version 2.5 will not work - upgrade to beta.
    
    #define DIGITAL_INPUT_SENSOR 3                  // The reed switch you attached.  (Only 2 and 3 generates interrupt!)
    #define INTERRUPT DIGITAL_INPUT_SENSOR-2        // Usually the interrupt = pin -2 (on uno/nano anyway)
    
    #define CHILD_ID 1                              // Id of the sensor child
    #define BATT_CHILD 2
    #define NODE_ID 24                               // or AUTO to let controller assign
    #define SKETCH_NAME "Rain Gauge"                // Change to a fancy name you like
    #define SKETCH_VERSION "1.8"                    // Your version
    
    unsigned long SLEEP_TIME = 60*60000;            // Sleep time (in milliseconds).
    //unsigned long SLEEP_TIME = 20000;             // use this instead for debug
    
    float hwRainVolume = 0;                         // Current rainvolume calculated in hardware.
    int hwPulseCounter = 0;                         // Pulsecount recieved from GW
    float fullCounter = 0;                           // Counts when to send counter
    float bucketSize = 0.5;                           // Bucketsize mm, needs to be 1, 0.5, 0.25, 0.2 or 0.1
    boolean pcReceived = false;                     // If we have recieved the pulscount from GW or not 
    boolean reedState;                              // Current state the reedswitch is in
    boolean oldReedState;                           // Old state (last state) of the reedswitch
    unsigned long lastSend =0;                      // Time we last tried to fetch counter.
    
    MySensor gw;
    MyMessage volumeMsg(CHILD_ID,V_RAIN);
    MyMessage lastCounterMsg(CHILD_ID,V_VAR1);
    MyMessage battMsg(BATT_CHILD, V_VOLTAGE);
    
    //=========================
    // BATTERY VOLTAGE DIVIDER SETUP
    // 1M, 470K divider across battery and using internal ADC ref of 1.1V
    // Sense point is bypassed with 0.1 uF cap to reduce noise at that point
    // ((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts
    // 3.44/1023 = Volts per bit = 0.003363075
    /*
    #define VBAT_PER_BITS 0.003363075  
    #define VMIN 1.9                                  //  Vmin (radio Min Volt)=1.9V (564v)
    #define VMAX 3.0                                  //  Vmax = (2xAA bat)=3.0V (892v)
    int batteryPcnt = 0;                              // Calc value for battery %
    int batLoop = 0;                                  // Loop to help calc average
    int batArray[3];                                  // Array to store value for average calc.
    int BATTERY_SENSE_PIN = A0;                       // select the input pin for the battery sense point
    //=========================
    */
    
    long result;
    float batteryPcnt;
    float batteryVolt;
    
    void setup()  
    {  
      pinMode(6,OUTPUT);
      digitalWrite(6,HIGH);
      // use the 1.1 V internal reference
      //analogReference(INTERNAL);             // For battery sensing
      
      pinMode(DIGITAL_INPUT_SENSOR, INPUT_PULLUP);  // sets the reed sensor digital pin as input
    
      reedState = digitalRead(DIGITAL_INPUT_SENSOR); // Read what state the reedswitch is in
      oldReedState = reedState; // Set startup position for reedswitch
    
      delay(500); // Allow time for radio if power used as reset
    
      //Begin (Change if you dont want static node_id! (NODE_ID to AUTO)
      gw.begin(incomingMessage, NODE_ID, false);
      
      // Send the Sketch Version Information to the Gateway
      gw.sendSketchInfo(SKETCH_NAME, SKETCH_VERSION);
    
      // Register this device as Rain sensor (will not show in Domoticz until first value arrives)
      gw.present(CHILD_ID, S_RAIN);       
      gw.present(BATT_CHILD, S_MULTIMETER);
      
      Serial.println("Startup completed");
    }
    
    void loop()     
    { 
    
      Serial.println("start");
      
      digitalWrite(6,HIGH);
      delay(100);
      
    gw.process();
    //gw.begin(incomingMessage, NODE_ID, false);
    unsigned long currentTime = millis();
    
        //See if we have the counter/pulse from Domoticz - and ask for it if we dont.
        if (!pcReceived && (currentTime - lastSend > 5000)) {      
          gw.begin(incomingMessage, NODE_ID, false);
          gw.request(CHILD_ID, V_VAR1);
          Serial.println("Request pulsecount");
          lastSend=currentTime;
          gw.process();
          return;
        }
        if (!pcReceived) {
          return;
        }
        
    //Read if the bucket tipped over
    reedState = digitalRead(DIGITAL_INPUT_SENSOR);
    boolean tipped = oldReedState != reedState; 
    
        //BUCKET TIPS!
        if (tipped==true) {
        gw.begin(incomingMessage, NODE_ID, false);
        Serial.println("The bucket has tipped over...");
        oldReedState = reedState;
        hwRainVolume = hwRainVolume + bucketSize;
        gw.send(volumeMsg.set((float)hwRainVolume,1));
        gw.wait(1000);
        fullCounter = fullCounter + bucketSize;
    
          //Count so we send the counter for every 1mm
          if(fullCounter >= 1){
          hwPulseCounter++;
          gw.send(lastCounterMsg.set(hwPulseCounter));
          gw.wait(1000);
          fullCounter = 0;
          }
          
        }
        
        if (tipped==false) {
    
         //No bucket tipped over last sleep-period, check battery then...
         readVcc(); 
         Serial.println("tbx");
        }
    
    lastSend=currentTime;
    Serial.println("sleep");
    digitalWrite(6,LOW);
    delay(1000);
    gw.sleep(INTERRUPT, CHANGE, SLEEP_TIME); 
    //The interupt can be CHANGE or FALLING depending on how you wired the hardware.
    }
    
    //Read if we have a incoming message.
    void incomingMessage(const MyMessage &message) {
      if (message.type==V_VAR1) {
        hwPulseCounter = message.getULong();
        hwRainVolume = hwPulseCounter;
        pcReceived = true;
        Serial.print("Received last pulse count from gw: ");
        Serial.println(hwPulseCounter);   
      }
    }
    /*
    void batM() //The battery calculations
    {
       delay(500);
       // Battery monitoring reading
       int sensorValue = analogRead(BATTERY_SENSE_PIN);    
       delay(500);
       
       // Calculate the battery in %
       float Vbat  = sensorValue * VBAT_PER_BITS;
       int batteryPcnt = static_cast<int>(((Vbat-VMIN)/(VMAX-VMIN))*100.);
       Serial.print("Battery percent: "); Serial.print(batteryPcnt); Serial.println(" %");  
       
       // Add it to array so we get an average of 3 (3x20min)
       batArray[batLoop] = batteryPcnt;
      
       if (batLoop > 1) {  
         batteryPcnt = (batArray[0] + batArray[1] + batArray[2]);
         batteryPcnt = batteryPcnt / 3;
     
       if (batteryPcnt > 100) {
         batteryPcnt=100;
     }
     
         Serial.print("Battery Average (Send): "); Serial.print(batteryPcnt); Serial.println(" %");
           gw.sendBatteryLevel(batteryPcnt);
           batLoop = 0;
           
         //Sends 1 per hour as a heartbeat.
         gw.send(volumeMsg.set((float)hwRainVolume,1));   
         gw.send(lastCounterMsg.set(hwPulseCounter));
         }
         else 
         {
         batLoop++;
         }
    }
    */
    long readVcc() {
      Serial.println("readVcc");
      // Read 1.1V reference against AVcc
      ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
      delay(2); // Wait for Vref to settle
      ADCSRA |= _BV(ADSC); // Convert
      while (bit_is_set(ADCSRA,ADSC));
      result = ADCL;
      result |= ADCH<<8;
      result = 1126400L / result; // Back-calculate AVcc in mV
      //return result;
      gw.begin(incomingMessage, NODE_ID, false);
      batteryPcnt = (result - 3300) * 0.111111;
      batteryVolt = result/1000.000;
      gw.sendBatteryLevel(batteryPcnt);
      gw.send(battMsg.set(batteryVolt, 3));
      gw.send(volumeMsg.set((float)hwRainVolume,1));   
      gw.send(lastCounterMsg.set(hwPulseCounter));
      /*Serial.print("battery volt:");
      Serial.println(batteryVolt, 3);
      Serial.print("battery percent:");
      Serial.println(batteryPcnt);
      */
    }
    
    martinhjelmareM 1 Reply Last reply
    0
    • F flopp

      It was working for at least 24 hour then suddenly it stopped.

      DEBUG

      send: 24-24-6-0 s=255,c=0,t=17,pt=0,l=5,sg=0,st=ok:1.5.1
      send: 24-24-6-0 s=255,c=3,t=6,pt=1,l=1,sg=0,st=fail:6
      sensor started, id=24, parent=6, distance=2
      send: 24-24-6-0 s=255,c=3,t=11,pt=0,l=10,sg=0,st=ok:Rain Gauge
      send: 24-24-6-0 s=255,c=3,t=12,pt=0,l=3,sg=0,st=fail:1.8
      send: 24-24-6-0 s=1,c=0,t=10,pt=0,l=0,sg=0,st=ok:
      send: 24-24-6-0 s=2,c=0,t=30,pt=0,l=0,sg=0,st=ok:
      

      Seconds row, does that mean temperature?

      Ethernet Gateway 1.5.1
      Sensor Node 1.5.1
      Repeater Node 1.5.1

      Other Sensor nodes is connected and works fine.

      This is my sketch

      #include <SPI.h>
      #include <MySensor.h>  
      
      // Running this in Domoticz stable version 2.5 will not work - upgrade to beta.
      
      #define DIGITAL_INPUT_SENSOR 3                  // The reed switch you attached.  (Only 2 and 3 generates interrupt!)
      #define INTERRUPT DIGITAL_INPUT_SENSOR-2        // Usually the interrupt = pin -2 (on uno/nano anyway)
      
      #define CHILD_ID 1                              // Id of the sensor child
      #define BATT_CHILD 2
      #define NODE_ID 24                               // or AUTO to let controller assign
      #define SKETCH_NAME "Rain Gauge"                // Change to a fancy name you like
      #define SKETCH_VERSION "1.8"                    // Your version
      
      unsigned long SLEEP_TIME = 60*60000;            // Sleep time (in milliseconds).
      //unsigned long SLEEP_TIME = 20000;             // use this instead for debug
      
      float hwRainVolume = 0;                         // Current rainvolume calculated in hardware.
      int hwPulseCounter = 0;                         // Pulsecount recieved from GW
      float fullCounter = 0;                           // Counts when to send counter
      float bucketSize = 0.5;                           // Bucketsize mm, needs to be 1, 0.5, 0.25, 0.2 or 0.1
      boolean pcReceived = false;                     // If we have recieved the pulscount from GW or not 
      boolean reedState;                              // Current state the reedswitch is in
      boolean oldReedState;                           // Old state (last state) of the reedswitch
      unsigned long lastSend =0;                      // Time we last tried to fetch counter.
      
      MySensor gw;
      MyMessage volumeMsg(CHILD_ID,V_RAIN);
      MyMessage lastCounterMsg(CHILD_ID,V_VAR1);
      MyMessage battMsg(BATT_CHILD, V_VOLTAGE);
      
      //=========================
      // BATTERY VOLTAGE DIVIDER SETUP
      // 1M, 470K divider across battery and using internal ADC ref of 1.1V
      // Sense point is bypassed with 0.1 uF cap to reduce noise at that point
      // ((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts
      // 3.44/1023 = Volts per bit = 0.003363075
      /*
      #define VBAT_PER_BITS 0.003363075  
      #define VMIN 1.9                                  //  Vmin (radio Min Volt)=1.9V (564v)
      #define VMAX 3.0                                  //  Vmax = (2xAA bat)=3.0V (892v)
      int batteryPcnt = 0;                              // Calc value for battery %
      int batLoop = 0;                                  // Loop to help calc average
      int batArray[3];                                  // Array to store value for average calc.
      int BATTERY_SENSE_PIN = A0;                       // select the input pin for the battery sense point
      //=========================
      */
      
      long result;
      float batteryPcnt;
      float batteryVolt;
      
      void setup()  
      {  
        pinMode(6,OUTPUT);
        digitalWrite(6,HIGH);
        // use the 1.1 V internal reference
        //analogReference(INTERNAL);             // For battery sensing
        
        pinMode(DIGITAL_INPUT_SENSOR, INPUT_PULLUP);  // sets the reed sensor digital pin as input
      
        reedState = digitalRead(DIGITAL_INPUT_SENSOR); // Read what state the reedswitch is in
        oldReedState = reedState; // Set startup position for reedswitch
      
        delay(500); // Allow time for radio if power used as reset
      
        //Begin (Change if you dont want static node_id! (NODE_ID to AUTO)
        gw.begin(incomingMessage, NODE_ID, false);
        
        // Send the Sketch Version Information to the Gateway
        gw.sendSketchInfo(SKETCH_NAME, SKETCH_VERSION);
      
        // Register this device as Rain sensor (will not show in Domoticz until first value arrives)
        gw.present(CHILD_ID, S_RAIN);       
        gw.present(BATT_CHILD, S_MULTIMETER);
        
        Serial.println("Startup completed");
      }
      
      void loop()     
      { 
      
        Serial.println("start");
        
        digitalWrite(6,HIGH);
        delay(100);
        
      gw.process();
      //gw.begin(incomingMessage, NODE_ID, false);
      unsigned long currentTime = millis();
      
          //See if we have the counter/pulse from Domoticz - and ask for it if we dont.
          if (!pcReceived && (currentTime - lastSend > 5000)) {      
            gw.begin(incomingMessage, NODE_ID, false);
            gw.request(CHILD_ID, V_VAR1);
            Serial.println("Request pulsecount");
            lastSend=currentTime;
            gw.process();
            return;
          }
          if (!pcReceived) {
            return;
          }
          
      //Read if the bucket tipped over
      reedState = digitalRead(DIGITAL_INPUT_SENSOR);
      boolean tipped = oldReedState != reedState; 
      
          //BUCKET TIPS!
          if (tipped==true) {
          gw.begin(incomingMessage, NODE_ID, false);
          Serial.println("The bucket has tipped over...");
          oldReedState = reedState;
          hwRainVolume = hwRainVolume + bucketSize;
          gw.send(volumeMsg.set((float)hwRainVolume,1));
          gw.wait(1000);
          fullCounter = fullCounter + bucketSize;
      
            //Count so we send the counter for every 1mm
            if(fullCounter >= 1){
            hwPulseCounter++;
            gw.send(lastCounterMsg.set(hwPulseCounter));
            gw.wait(1000);
            fullCounter = 0;
            }
            
          }
          
          if (tipped==false) {
      
           //No bucket tipped over last sleep-period, check battery then...
           readVcc(); 
           Serial.println("tbx");
          }
      
      lastSend=currentTime;
      Serial.println("sleep");
      digitalWrite(6,LOW);
      delay(1000);
      gw.sleep(INTERRUPT, CHANGE, SLEEP_TIME); 
      //The interupt can be CHANGE or FALLING depending on how you wired the hardware.
      }
      
      //Read if we have a incoming message.
      void incomingMessage(const MyMessage &message) {
        if (message.type==V_VAR1) {
          hwPulseCounter = message.getULong();
          hwRainVolume = hwPulseCounter;
          pcReceived = true;
          Serial.print("Received last pulse count from gw: ");
          Serial.println(hwPulseCounter);   
        }
      }
      /*
      void batM() //The battery calculations
      {
         delay(500);
         // Battery monitoring reading
         int sensorValue = analogRead(BATTERY_SENSE_PIN);    
         delay(500);
         
         // Calculate the battery in %
         float Vbat  = sensorValue * VBAT_PER_BITS;
         int batteryPcnt = static_cast<int>(((Vbat-VMIN)/(VMAX-VMIN))*100.);
         Serial.print("Battery percent: "); Serial.print(batteryPcnt); Serial.println(" %");  
         
         // Add it to array so we get an average of 3 (3x20min)
         batArray[batLoop] = batteryPcnt;
        
         if (batLoop > 1) {  
           batteryPcnt = (batArray[0] + batArray[1] + batArray[2]);
           batteryPcnt = batteryPcnt / 3;
       
         if (batteryPcnt > 100) {
           batteryPcnt=100;
       }
       
           Serial.print("Battery Average (Send): "); Serial.print(batteryPcnt); Serial.println(" %");
             gw.sendBatteryLevel(batteryPcnt);
             batLoop = 0;
             
           //Sends 1 per hour as a heartbeat.
           gw.send(volumeMsg.set((float)hwRainVolume,1));   
           gw.send(lastCounterMsg.set(hwPulseCounter));
           }
           else 
           {
           batLoop++;
           }
      }
      */
      long readVcc() {
        Serial.println("readVcc");
        // Read 1.1V reference against AVcc
        ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
        delay(2); // Wait for Vref to settle
        ADCSRA |= _BV(ADSC); // Convert
        while (bit_is_set(ADCSRA,ADSC));
        result = ADCL;
        result |= ADCH<<8;
        result = 1126400L / result; // Back-calculate AVcc in mV
        //return result;
        gw.begin(incomingMessage, NODE_ID, false);
        batteryPcnt = (result - 3300) * 0.111111;
        batteryVolt = result/1000.000;
        gw.sendBatteryLevel(batteryPcnt);
        gw.send(battMsg.set(batteryVolt, 3));
        gw.send(volumeMsg.set((float)hwRainVolume,1));   
        gw.send(lastCounterMsg.set(hwPulseCounter));
        /*Serial.print("battery volt:");
        Serial.println(batteryVolt, 3);
        Serial.print("battery percent:");
        Serial.println(batteryPcnt);
        */
      }
      
      martinhjelmareM Offline
      martinhjelmareM Offline
      martinhjelmare
      Plugin Developer
      wrote on last edited by
      #2

      @flopp

      Hi!

      st=fail means radio comm problem. The second row is asking the controller for config, t=6, metric or imperial.

      Radio problems are often power related, sometimes it can also be bad piece of hardware.

      Check cables/connections.
      Try adding 4.7 uF capacitor near radio.
      Try adding two caps near radio.
      Try a different power source.
      Try another piece of radio.
      Move node closer or farther away from gateway.

      F 1 Reply Last reply
      0
      • martinhjelmareM martinhjelmare

        @flopp

        Hi!

        st=fail means radio comm problem. The second row is asking the controller for config, t=6, metric or imperial.

        Radio problems are often power related, sometimes it can also be bad piece of hardware.

        Check cables/connections.
        Try adding 4.7 uF capacitor near radio.
        Try adding two caps near radio.
        Try a different power source.
        Try another piece of radio.
        Move node closer or farther away from gateway.

        F Offline
        F Offline
        flopp
        wrote on last edited by
        #3

        @martinhjelmare

        Thanks.

        Just before you posted this I Cleared the EEprom and upload sketch again, then it started to work.

        martinhjelmareM 1 Reply Last reply
        0
        • F flopp

          @martinhjelmare

          Thanks.

          Just before you posted this I Cleared the EEprom and upload sketch again, then it started to work.

          martinhjelmareM Offline
          martinhjelmareM Offline
          martinhjelmare
          Plugin Developer
          wrote on last edited by
          #4

          @flopp

          OK. Good to hear. Do you think it was a routing problem, between node and gateway?

          F 1 Reply Last reply
          0
          • martinhjelmareM martinhjelmare

            @flopp

            OK. Good to hear. Do you think it was a routing problem, between node and gateway?

            F Offline
            F Offline
            flopp
            wrote on last edited by
            #5

            @martinhjelmare

            Yes, because when i test in my house it connects to my Repeater Node, but when I place it where it shall be I don't work anymore. It happened again.

            Can you confirm that: If it connects to a repeater node first time you start it it must go through that node everytime?

            1 Reply Last reply
            0
            • sundberg84S Offline
              sundberg84S Offline
              sundberg84
              Hardware Contributor
              wrote on last edited by
              #6

              If will self-heal and it takes some time, you need some ST:fails for it to search new parent. When it do that route is stored and next time it will send that route.

              Controller: Proxmox VM - Home Assistant
              MySensors GW: Arduino Uno - W5100 Ethernet, Gw Shield Nrf24l01+ 2,4Ghz
              MySensors GW: Arduino Uno - Gw Shield RFM69, 433mhz
              RFLink GW - Arduino Mega + RFLink Shield, 433mhz

              1 Reply Last reply
              0
              • martinhjelmareM Offline
                martinhjelmareM Offline
                martinhjelmare
                Plugin Developer
                wrote on last edited by
                #7

                Yes, I think 6 fails are needed, before searching for new route.

                1 Reply Last reply
                0
                • F Offline
                  F Offline
                  flopp
                  wrote on last edited by
                  #8

                  Now it works, without Repeater Node. I flipped the bucket a couple of times.

                  But i wonder why it didn't heal before.

                  Can it be that when the timer is waking up the Sensor Node it doesn't heal.

                  Because it has been offline for 12 hour, sleeping 1 hour each time, without healing. No rain had come during this period. Now i was flipping the bucket and it start to heal.

                  martinhjelmareM 1 Reply Last reply
                  0
                  • F flopp

                    Now it works, without Repeater Node. I flipped the bucket a couple of times.

                    But i wonder why it didn't heal before.

                    Can it be that when the timer is waking up the Sensor Node it doesn't heal.

                    Because it has been offline for 12 hour, sleeping 1 hour each time, without healing. No rain had come during this period. Now i was flipping the bucket and it start to heal.

                    martinhjelmareM Offline
                    martinhjelmareM Offline
                    martinhjelmare
                    Plugin Developer
                    wrote on last edited by
                    #9

                    @flopp

                    I think it's 6 consecutive fails that's needed before the route search, and from your first log, it seems not all messages were failing.

                    F 1 Reply Last reply
                    0
                    • martinhjelmareM martinhjelmare

                      @flopp

                      I think it's 6 consecutive fails that's needed before the route search, and from your first log, it seems not all messages were failing.

                      F Offline
                      F Offline
                      flopp
                      wrote on last edited by
                      #10

                      @martinhjelmare
                      Yes, that can be the reason.

                      Thanks everyone

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


                      13

                      Online

                      11.7k

                      Users

                      11.2k

                      Topics

                      113.1k

                      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