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. Count car-starts

Count car-starts

Scheduled Pinned Locked Moved My Project
47 Posts 5 Posters 12.8k 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.
  • tbowmoT tbowmo

    A solution could also be to hack into the wire harness of the car, and detect when the starter motor gets powered up by turning the key. It's 12v so a simple voltage divider could do it. (and perhaps a couple of diodes from arduino pin to GND and vcc for extra protection.)

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

    @tbowmo
    Yes, but I dont want to jeopardize my cars :)
    12v can be handle by the Arduino Pro min on RAW pin

    Z 1 Reply Last reply
    0
    • mfalkviddM mfalkvidd

      Solution 1 should be easy to implement by replacing your endless while loops with sending until you get an ack from the controller.

      An alternative solution could be to fetch the current time from the controller at startup, and compare the current time to the last time a report was sent. If the time was less than 5 minutes ago, don't do anything. If the time is more than 5 minutes ago, store current time in the eeprom, increment the number of starts and send the new value to the controller.

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

      @mfalkvidd said:
      ... store current time in the eeprom...

      How can I store timestamp to EEPROM, it can only handle a value maximum 256 or?

      mfalkviddM 1 Reply Last reply
      0
      • F flopp

        @mfalkvidd said:
        ... store current time in the eeprom...

        How can I store timestamp to EEPROM, it can only handle a value maximum 256 or?

        mfalkviddM Offline
        mfalkviddM Offline
        mfalkvidd
        Mod
        wrote on last edited by
        #17

        @flopp correct. The value needs to be split into four eeprom "slots"

        See http://playground.arduino.cc/Code/EEPROMReadWriteLong for info on how to do that.

        F 1 Reply Last reply
        0
        • mfalkviddM mfalkvidd

          @flopp correct. The value needs to be split into four eeprom "slots"

          See http://playground.arduino.cc/Code/EEPROMReadWriteLong for info on how to do that.

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

          @mfalkvidd
          thanks

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

            New version 1.1

            // Made by Daniel Nilsson
            // Tested with Domoticz 2.4440
            // 2016-03-12
            
            #include <SPI.h>
            #include <MySensor.h>
            
            #define CHILD_ID 0                          // Id of the sensor child
            #define NODE_ID AUTO                        // a number or AUTO to let controller assign
            #define SKETCH_NAME "Car start counter"     // Change to a fancy name you like
            #define SKETCH_VERSION "1.1"                // Your version
            
            int Controller;                             // Current start counts from Controller, like Domoticz
            boolean pcReceived = false;                 // If we have recieved the start counts from Controller or not 
            int starts;                                 // summary of all starts to be sent to Controller
            int eeprom;                                 // start counts read from/to be stored in EEPROM
            
            MySensor gw;
            MyMessage volumeMsg(CHILD_ID,V_RAIN);
            MyMessage lastCounterMsg(CHILD_ID,V_VAR1);
            
            void setup()
            {          
              delay(500);   // wait for radio
              delay(2*60000);  // Allow time if USB/cigarett plug is powered before you turned the key
            
              //Begin
              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);       
              Serial.println("");
              eeprom = gw.loadState(0);                       // read EEPROM
              Serial.print(eeprom);                           // print EEPROM
              Serial.println(" starts have not been sent");
              Serial.println("add 1 start");
              Serial.print(eeprom);
              Serial.print("+1=");
              eeprom = eeprom + 1;
              Serial.println(eeprom);
              gw.saveState(0,eeprom);                         // store to EEPROM at position 0
              Serial.println("");
              
              Serial.println("Startup completed");
            }
            
            void loop()
            { 
              
            //gw.process();
            
                //See if we have the start counts from Controller - and ask for it if we dont.
                if (!pcReceived) {
                  
                  Serial.println("Request start counts");
                  gw.request(CHILD_ID, V_VAR1);
                  //gw.process();
                  gw.wait(5000);
                  return;
                }
            
            Serial.println("");
            eeprom = gw.loadState(0);                     // read EEPROM
            Serial.print(eeprom);
            Serial.println(" starts have not been sent");
            Serial.print(Controller);
            Serial.println(" starts from Controller = ");    
            starts = Controller + eeprom;                 // total starts
            Serial.print(eeprom);
            Serial.print("+");
            Serial.print(Controller);
            Serial.print("=");
            Serial.println(starts);
            Serial.print("Send ");
            Serial.print(starts);
            Serial.println(" to Controller");
            Serial.println("");
            
            resend((volumeMsg.set(starts)), 5);
            //gw.send(volumeMsg.set(starts));
            resend((lastCounterMsg.set(starts)), 5);
            //gw.send(lastCounterMsg.set(starts));
            gw.wait(1000);
            Serial.println("");
            Serial.println("store 0 to EEPROM");
            gw.saveState(0,0);                            // set 0 start to EEPROM, all have been sent
            Serial.println("sleep");                      // mission accomplished
            while(1){}
            
            }
            
            // check if "st:fail" during gw.send, thanks n3ro
            void resend(MyMessage &msg, int repeats)
            {
              int repeat = 1;
              boolean sendOK = false;
              int repeatdelay = 2000;
            
            
              while ((sendOK == false) and (repeat < repeats)) {
                if (gw.send(msg)) {
                  sendOK = true;
                }
                else {
                  sendOK = false;
                  Serial.print("Error ");
                  Serial.println(repeat);
                }
                repeat++; delay(repeatdelay);
              }
              if (sendOK == false && repeat == repeats){
                loop();
              }
            }
            
            //Read if we have a incoming message.
            void incomingMessage(const MyMessage &message) {
              if (message.type==V_VAR1) {
                Controller = message.getULong();
                pcReceived = true;
                Serial.print("Received start counts from Controller: ");
                Serial.println(Controller);   
              }
            }
            

            thanks to @n3ro for st:fail and @sundberg84 for the hint
            @mfalkvidd maybe next version will have timestamp from Domoticz, i am still waiting for an answer if I can send date and time to database. As you can see I have removed while-loop until it successfully sent data to Controller

            mfalkviddM 1 Reply Last reply
            1
            • F flopp

              New version 1.1

              // Made by Daniel Nilsson
              // Tested with Domoticz 2.4440
              // 2016-03-12
              
              #include <SPI.h>
              #include <MySensor.h>
              
              #define CHILD_ID 0                          // Id of the sensor child
              #define NODE_ID AUTO                        // a number or AUTO to let controller assign
              #define SKETCH_NAME "Car start counter"     // Change to a fancy name you like
              #define SKETCH_VERSION "1.1"                // Your version
              
              int Controller;                             // Current start counts from Controller, like Domoticz
              boolean pcReceived = false;                 // If we have recieved the start counts from Controller or not 
              int starts;                                 // summary of all starts to be sent to Controller
              int eeprom;                                 // start counts read from/to be stored in EEPROM
              
              MySensor gw;
              MyMessage volumeMsg(CHILD_ID,V_RAIN);
              MyMessage lastCounterMsg(CHILD_ID,V_VAR1);
              
              void setup()
              {          
                delay(500);   // wait for radio
                delay(2*60000);  // Allow time if USB/cigarett plug is powered before you turned the key
              
                //Begin
                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);       
                Serial.println("");
                eeprom = gw.loadState(0);                       // read EEPROM
                Serial.print(eeprom);                           // print EEPROM
                Serial.println(" starts have not been sent");
                Serial.println("add 1 start");
                Serial.print(eeprom);
                Serial.print("+1=");
                eeprom = eeprom + 1;
                Serial.println(eeprom);
                gw.saveState(0,eeprom);                         // store to EEPROM at position 0
                Serial.println("");
                
                Serial.println("Startup completed");
              }
              
              void loop()
              { 
                
              //gw.process();
              
                  //See if we have the start counts from Controller - and ask for it if we dont.
                  if (!pcReceived) {
                    
                    Serial.println("Request start counts");
                    gw.request(CHILD_ID, V_VAR1);
                    //gw.process();
                    gw.wait(5000);
                    return;
                  }
              
              Serial.println("");
              eeprom = gw.loadState(0);                     // read EEPROM
              Serial.print(eeprom);
              Serial.println(" starts have not been sent");
              Serial.print(Controller);
              Serial.println(" starts from Controller = ");    
              starts = Controller + eeprom;                 // total starts
              Serial.print(eeprom);
              Serial.print("+");
              Serial.print(Controller);
              Serial.print("=");
              Serial.println(starts);
              Serial.print("Send ");
              Serial.print(starts);
              Serial.println(" to Controller");
              Serial.println("");
              
              resend((volumeMsg.set(starts)), 5);
              //gw.send(volumeMsg.set(starts));
              resend((lastCounterMsg.set(starts)), 5);
              //gw.send(lastCounterMsg.set(starts));
              gw.wait(1000);
              Serial.println("");
              Serial.println("store 0 to EEPROM");
              gw.saveState(0,0);                            // set 0 start to EEPROM, all have been sent
              Serial.println("sleep");                      // mission accomplished
              while(1){}
              
              }
              
              // check if "st:fail" during gw.send, thanks n3ro
              void resend(MyMessage &msg, int repeats)
              {
                int repeat = 1;
                boolean sendOK = false;
                int repeatdelay = 2000;
              
              
                while ((sendOK == false) and (repeat < repeats)) {
                  if (gw.send(msg)) {
                    sendOK = true;
                  }
                  else {
                    sendOK = false;
                    Serial.print("Error ");
                    Serial.println(repeat);
                  }
                  repeat++; delay(repeatdelay);
                }
                if (sendOK == false && repeat == repeats){
                  loop();
                }
              }
              
              //Read if we have a incoming message.
              void incomingMessage(const MyMessage &message) {
                if (message.type==V_VAR1) {
                  Controller = message.getULong();
                  pcReceived = true;
                  Serial.print("Received start counts from Controller: ");
                  Serial.println(Controller);   
                }
              }
              

              thanks to @n3ro for st:fail and @sundberg84 for the hint
              @mfalkvidd maybe next version will have timestamp from Domoticz, i am still waiting for an answer if I can send date and time to database. As you can see I have removed while-loop until it successfully sent data to Controller

              mfalkviddM Offline
              mfalkviddM Offline
              mfalkvidd
              Mod
              wrote on last edited by mfalkvidd
              #20

              Great work @flopp! Just one comment: You call loop if the 5 resend tries isn't enough. That will re-start the loop. What it also will do is to keep all variables in the loop and resend functions in memory. These will add up over time, which will crash your Arduino after a while. So if you start the engine at work and it takes too long time to reach home, the Arduino will have crashed before it is able to update the gateway. See http://arduino.stackexchange.com/questions/355/how-much-can-i-recurse-how-much-can-i-recurse-how-much-caqfsdrfw for technical details on stack usage and recursion.

              You might want to do something like this instead:

              bool resend(MyMessage &msg, int repeats)
              {
              ...
                if (sendOK == false && repeat == repeats){
                  return false;
                }
                return true;
              }
              

              and then change all

              resend(..., 5);
              

              to

              if (!resend(..., 5)) return;
              

              This will have the same effect, but will not accumulate stuff on the stack.

              F 1 Reply Last reply
              0
              • mfalkviddM mfalkvidd

                Great work @flopp! Just one comment: You call loop if the 5 resend tries isn't enough. That will re-start the loop. What it also will do is to keep all variables in the loop and resend functions in memory. These will add up over time, which will crash your Arduino after a while. So if you start the engine at work and it takes too long time to reach home, the Arduino will have crashed before it is able to update the gateway. See http://arduino.stackexchange.com/questions/355/how-much-can-i-recurse-how-much-can-i-recurse-how-much-caqfsdrfw for technical details on stack usage and recursion.

                You might want to do something like this instead:

                bool resend(MyMessage &msg, int repeats)
                {
                ...
                  if (sendOK == false && repeat == repeats){
                    return false;
                  }
                  return true;
                }
                

                and then change all

                resend(..., 5);
                

                to

                if (!resend(..., 5)) return;
                

                This will have the same effect, but will not accumulate stuff on the stack.

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

                @mfalkvidd
                Thanks for taking time to read my sketch :satisfied:

                if !(resend((lastCounterMsg.set(starts)), 5)) return;
                

                Arduino IDE says

                Car_counter.ino.ino: In function 'void resend(MyMessage&, int)':
                Car_counter.ino:117: error: return-statement with a value, in function returning 'void' [-fpermissive]
                Car_counter.ino:119: error: return-statement with a value, in function returning 'void' [-fpermissive]
                expected '(' before '!' token
                
                1 Reply Last reply
                0
                • F Offline
                  F Offline
                  flopp
                  wrote on last edited by flopp
                  #22

                  @mfalkvidd
                  this must help, or?

                  void send();
                  resend((volumeMsg.set(starts)), 5);
                  resend((lastCounterMsg.set(starts)), 5);
                  gw.wait(1000);
                  Serial.println("");
                  Serial.println("store 0 to EEPROM");
                  gw.saveState(0,0);                            // set 0 start to EEPROM, all have been sent
                  Serial.println("sleep");                      // mission accomplished
                  while(1){}
                  
                  }
                  
                  // check if "st:fail" during gw.send, thanks n3ro
                  void resend(MyMessage &msg, int repeats)
                  {
                    int repeat = 1;
                    boolean sendOK = false;
                    int repeatdelay = 2000;
                  
                    while ((sendOK == false) and (repeat < repeats)) {
                      if (gw.send(msg)) {
                        sendOK = true;
                      }
                      else {
                        sendOK = false;
                        Serial.print("Error ");
                        Serial.println(repeat);
                      }
                      repeat++; delay(repeatdelay);
                    }
                    if (sendOK == false && repeat == repeats){
                      void send();;
                    }
                  
                  1 Reply Last reply
                  0
                  • mfalkviddM Offline
                    mfalkviddM Offline
                    mfalkvidd
                    Mod
                    wrote on last edited by
                    #23

                    Sorry, I forgot to change void resend to bool resend. I have updated my previous post.

                    F 2 Replies Last reply
                    0
                    • mfalkviddM Offline
                      mfalkviddM Offline
                      mfalkvidd
                      Mod
                      wrote on last edited by
                      #24

                      And no, movin the code from loop to send does not help. The problem is that you will get recursive calls. send calls resend which calls send which calls resend which calls send which calls resend....and so on. For each call, the Arduino will store all variables on the stack and memory usage will grow and grow.

                      F 1 Reply Last reply
                      0
                      • mfalkviddM mfalkvidd

                        And no, movin the code from loop to send does not help. The problem is that you will get recursive calls. send calls resend which calls send which calls resend which calls send which calls resend....and so on. For each call, the Arduino will store all variables on the stack and memory usage will grow and grow.

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

                        @mfalkvidd
                        OK, so you have to go back to where it comes from

                        1 Reply Last reply
                        0
                        • mfalkviddM mfalkvidd

                          Sorry, I forgot to change void resend to bool resend. I have updated my previous post.

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

                          @mfalkvidd
                          Sorry, didnt work. Almost same error

                          Car_counter_1.2:84: error: expected '(' before '!' token
                          Car_counter_1.2:86: error: expected '(' before '!' token
                          expected '(' before '!' token
                          
                          1 Reply Last reply
                          0
                          • mfalkviddM mfalkvidd

                            Sorry, I forgot to change void resend to bool resend. I have updated my previous post.

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

                            @mfalkvidd
                            But if I put ! inside ( it works

                            if (!resend((volumeMsg.set(starts)), 5))return;
                            
                            1 Reply Last reply
                            0
                            • mfalkviddM Offline
                              mfalkviddM Offline
                              mfalkvidd
                              Mod
                              wrote on last edited by
                              #28

                              Yes, sorry about that. I edited my previous post to have ! inside ().

                              1 Reply Last reply
                              0
                              • F Offline
                                F Offline
                                flopp
                                wrote on last edited by flopp
                                #29
                                This post is deleted!
                                Z 1 Reply Last reply
                                0
                                • F flopp

                                  This post is deleted!

                                  Z Offline
                                  Z Offline
                                  Zeph
                                  Hero Member
                                  wrote on last edited by Zeph
                                  #30

                                  OK, let me see if I understand your overall flow.

                                  You have your node connected to switched 12V power in the car. When you turn on the car, the uC gets power, when you turn off the car it loses power. When the car is cranking, the voltage drops enough that it tends to reset again (or else the cranking position on your key switch actually cuts off auxiliary power used by the uC).

                                  So if you are at home and in range, loop() is called by the Arduino runtime just once; at the end of loop() the uC goes into an infinite busy loop rather than return, staying there until power is lost again. If you are away from home or the packets are lost for other reasons, resend() will cause a return from loop(), so that loop() will be called again by the Arduino runtime, so it will just keep trying until either power is lost, or it makes contact with your wireless network again.

                                  Meanwhile every time it starts, the first byte of eeprom is incremented in setup(), and then loop() tries to fetch VAR1, and send VAR1+eeprom(0) back. If it succeeds, then the first byte of eeprom is zeroed.

                                  Right?

                                  That sounds reasonable. My immediate concern would be inconsistent operation during cranking, if the input voltage went just low enough to make the uC unstable. If your car's wiring cuts the power entirely, not a problem. Likewise there appears to be time for the uC to boot, and fully update eeprom, before losing power during cranking. (It's best not to be writing eeprom as voltage drops). It appears that those are not problems for your system tho.

                                  F mfalkviddM 2 Replies Last reply
                                  0
                                  • F flopp

                                    @tbowmo
                                    Yes, but I dont want to jeopardize my cars :)
                                    12v can be handle by the Arduino Pro min on RAW pin

                                    Z Offline
                                    Z Offline
                                    Zeph
                                    Hero Member
                                    wrote on last edited by Zeph
                                    #31

                                    @flopp said:

                                    12v can be handle by the Arduino Pro min on RAW pin

                                    Cars go well above 14V during operation (as well as having noise glitches on top of that). If the regulator is only good up to 12v, operation could be marginal. Hence the suggestion from @tbowmo of a couple of diodes in the power feed, to drop a bit of the voltage as seen by the regulator.

                                    F 1 Reply Last reply
                                    0
                                    • Z Zeph

                                      OK, let me see if I understand your overall flow.

                                      You have your node connected to switched 12V power in the car. When you turn on the car, the uC gets power, when you turn off the car it loses power. When the car is cranking, the voltage drops enough that it tends to reset again (or else the cranking position on your key switch actually cuts off auxiliary power used by the uC).

                                      So if you are at home and in range, loop() is called by the Arduino runtime just once; at the end of loop() the uC goes into an infinite busy loop rather than return, staying there until power is lost again. If you are away from home or the packets are lost for other reasons, resend() will cause a return from loop(), so that loop() will be called again by the Arduino runtime, so it will just keep trying until either power is lost, or it makes contact with your wireless network again.

                                      Meanwhile every time it starts, the first byte of eeprom is incremented in setup(), and then loop() tries to fetch VAR1, and send VAR1+eeprom(0) back. If it succeeds, then the first byte of eeprom is zeroed.

                                      Right?

                                      That sounds reasonable. My immediate concern would be inconsistent operation during cranking, if the input voltage went just low enough to make the uC unstable. If your car's wiring cuts the power entirely, not a problem. Likewise there appears to be time for the uC to boot, and fully update eeprom, before losing power during cranking. (It's best not to be writing eeprom as voltage drops). It appears that those are not problems for your system tho.

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

                                      @Zeph
                                      Fully correct :) thanks for summarizing.

                                      Car A have a built in USB where I, today, take power. I have to test if the voltage will go low so the uC will not get correct power but not 0 volt(restart), I don't know what will happen then. This was your question?
                                      Car B have cigarette plug(12v output) so I use a converter to 5V, I think these converters can handle low input and still have 5V on output.

                                      I will test it for a while and count starts in my head(good luck)

                                      Next idea is to have a buzzer to beep when it has successfully sent data to Controller, just as information and if it beeps when I am away from home I have a mistake in the sketch

                                      1 Reply Last reply
                                      0
                                      • Z Zeph

                                        @flopp said:

                                        12v can be handle by the Arduino Pro min on RAW pin

                                        Cars go well above 14V during operation (as well as having noise glitches on top of that). If the regulator is only good up to 12v, operation could be marginal. Hence the suggestion from @tbowmo of a couple of diodes in the power feed, to drop a bit of the voltage as seen by the regulator.

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

                                        @Zeph
                                        you are right about 14V.

                                        Best should be to hide uC and connect to power(which only have power after crank)

                                        1 Reply Last reply
                                        0
                                        • Z Zeph

                                          OK, let me see if I understand your overall flow.

                                          You have your node connected to switched 12V power in the car. When you turn on the car, the uC gets power, when you turn off the car it loses power. When the car is cranking, the voltage drops enough that it tends to reset again (or else the cranking position on your key switch actually cuts off auxiliary power used by the uC).

                                          So if you are at home and in range, loop() is called by the Arduino runtime just once; at the end of loop() the uC goes into an infinite busy loop rather than return, staying there until power is lost again. If you are away from home or the packets are lost for other reasons, resend() will cause a return from loop(), so that loop() will be called again by the Arduino runtime, so it will just keep trying until either power is lost, or it makes contact with your wireless network again.

                                          Meanwhile every time it starts, the first byte of eeprom is incremented in setup(), and then loop() tries to fetch VAR1, and send VAR1+eeprom(0) back. If it succeeds, then the first byte of eeprom is zeroed.

                                          Right?

                                          That sounds reasonable. My immediate concern would be inconsistent operation during cranking, if the input voltage went just low enough to make the uC unstable. If your car's wiring cuts the power entirely, not a problem. Likewise there appears to be time for the uC to boot, and fully update eeprom, before losing power during cranking. (It's best not to be writing eeprom as voltage drops). It appears that those are not problems for your system tho.

                                          mfalkviddM Offline
                                          mfalkviddM Offline
                                          mfalkvidd
                                          Mod
                                          wrote on last edited by mfalkvidd
                                          #34

                                          @Zeph said:

                                          It's best not to be writing eeprom as voltage drops

                                          This is correct. However, shouldn't the BOD take care of that problem? Might be a good idea to set the BOD to 4.3V i stead of the default 2.7 though?

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


                                          14

                                          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