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.7k 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.
  • F Offline
    F Offline
    flopp
    wrote on last edited by flopp
    #10
    This post is deleted!
    1 Reply Last reply
    1
    • F Offline
      F Offline
      flopp
      wrote on last edited by
      #11

      I have had some small problems with my sketch.

      I have 2 cars, A and B.

      A, as soon as I put in the key without turning it, USB port gets power. When I start the car, USB port losses power for a short while and Arduino restarts. This means that I will send data twice. Possible solution for this is to delay for 1-4 minutes but then I will not send anything when I am at home.

      B, when I unlock the car from remote control it power USB for ~30 seconds. This will result in same problem as car A.

      two things I want to implement to sketch.

      1. Send data as soon as I come home, so I can track exact date when I was using car. Not very important.
      2. Only send data when I actually use the car, not when I power Arduino ON. To solve this I have two solutins, GPS or Gyro. Gyro is the cheap and easy part so I will go for that at the moment. GPS should be perfect, then I can control that it should send data when I start to move and also send as soon as I come home.
      1 Reply Last reply
      0
      • mfalkviddM Offline
        mfalkviddM Offline
        mfalkvidd
        Mod
        wrote on last edited by
        #12

        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 2 Replies 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
          #13

          @mfalkvidd
          I used While just to not try to send data all the time, since it will only be able to send when I leave my house and not away from my house and my thought was not to use MCU so much maybe this is not a problem. I will test to not sleep until it have sent the data successful in this way it will send data within a few seconds as soon as I reach my house.

          Perfect idea about fetch time, yes this is definitely a solution for my USB-power-on problem

          Thanks

          1 Reply Last reply
          0
          • tbowmoT Offline
            tbowmoT Offline
            tbowmo
            Admin
            wrote on last edited by
            #14

            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 1 Reply Last reply
            0
            • 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
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          11

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