'MySensoring' a GE Washer


  • Hero Member

    This is another very simple "Wash Cycle Completed" sensor. It's design uses the same Optocoupler sensing design I used in the Kiddie Smoke Detector project. The only difference is that I'm using 1 AC to DC transformer, and a boost module to boost the washer speaker power to fire the Optocoupler.

    Parts:

    1. 1 Cheap AC/DC converter
    2. 1 Optocoupler
    3. 1 Step up Regulator
    4. 1 Small Proto Board.
    5. Some wire

    Highlights:
    Use the Washers .5vdc Signal Piezo to interface with the Pro-Mini. The voltage to the Piezo is to low to drive the Optocoupler so I had to use a boost module to boost the voltage to the Optocoupler. I'm not sure what the long term effect will be on washers control board Piezo drive circuit, so I will follow up if I encounter a problem.

    Again Uses the same sketch as the Kiddie Smoke Project, with the only change being to CYCLE_INTERVAL (For my dryer 3 works well)

    Sketch:

    // Based on Author: Patrick 'Anticimex' Fallberg Interrupt driven binary switch example with dual interrupts
    
    #include <MySensor.h>
    #include <SPI.h>
    
    #define SKETCH_NAME "Washer End Cycle"
    #define SKETCH_MAJOR_VER "1"
    #define SKETCH_MINOR_VER "1"
    
    #define CHILD_ID 3
    
    #define SIREN_SENSE_PIN 3   // Arduino Digital I/O pin for optocoupler for siren
    
    unsigned int SLEEP_TIME			= 32400; // Sleep time between reads (in seconds) 32400 = 9hrs?
    long CYCLE_COUNTER					= 3;  // This is the number of times we want the Audio Counter to reach before triggering a signal to controller.
    unsigned long CYCLE_INTERVAL		= 3; // How long do we want to watch once first detected (in seconds) 
    											//Adjust for your smoke detector, you want to pick up the siren signal at least 3 time to help stop false alarms. 
    unsigned long CYCLE_RATE			= 90; // How fast do we want to move checking the Pin state in the Status Check (in Millis) Adjust for your smoke detector
    											//Adjust for your smoke detector, you want to pick up the siren signal at least 3 time to help stop false alarms.
    unsigned long CYCLE_TIME_OKSTATUS	= 8; // How long do we want to watch for "all clear" once we have confirmed an Alarm (in seconds)
    unsigned long CYCLE_RATE_OKSTATUS	= 500; // How fast do we want to move checking the Pin state when checking for an OK status (in Millis)
    
    int oldValue=1;
    int value=0;
    
    
    MySensor sensor_node;
    MyMessage msg(CHILD_ID, V_TRIPPED);
    
    void setup()  
    {  
    	sensor_node.begin();
    	// Setup the Siren Pin HIGH
    	pinMode(SIREN_SENSE_PIN, INPUT_PULLUP);
    	// Send the sketch version information to the gateway and Controller
    	sensor_node.sendSketchInfo(SKETCH_NAME, SKETCH_MAJOR_VER"."SKETCH_MINOR_VER);
    	sensor_node.present(CHILD_ID, S_SMOKE); 
    	//Send the state -- Always send Alarm state on power up.
    	sensor_node.send(msg.setSensor(CHILD_ID).set("1"), true);
    	
    }
    
    // Loop will iterate on changes on the BUTTON_PINs
    void loop() 
    {
    	// Check to see if we have a alarm. I always want to check even if we are coming out of sleep for heartbeat.
    	AlarmStatus();
    	// Sleep until we get a audio power hit on the optocoupler or 9hrs
    	sensor_node.sleep(SIREN_SENSE_PIN-2,FALLING, SLEEP_TIME * 1000UL);
    	
    } 
    
    void AlarmStatus()
    {
    	
    // We will check the status now, this could be called by an interrupt or heartbeat
    int siren_audio_count	=0;
    long cycle_time			=0; 	
    unsigned long startedAt = millis();
    
    	Serial.println("Status Check");
    	//Read the Pin
    	value = digitalRead(SIREN_SENSE_PIN);
        // If Pin return a 0 (LOW), then we have a Alarm Condition
    	if (value != 1) {
    		 //We are only going to check for status for CYCLE_INTERVAL time I think this should help stabilize Siren Sensing
    		  while(millis() - startedAt < CYCLE_INTERVAL * 1000)
    		  {
    			  //We are going to check CYCLE_RATE fast
    			  if(millis() - cycle_time > CYCLE_RATE ) {
    				  // save the last time you Checked
    				  cycle_time = millis();
    				    //We will count each time SIREN_SENSE_PIN is 0 (Alarm - LOW) for the above time and at the above rate.
    					value = digitalRead(SIREN_SENSE_PIN);  
    						if (value != 1)
    						{
    							siren_audio_count++;
    							Serial.print("Audio Count: ");
    							Serial.println(siren_audio_count);
    						} 
    			  }
    		  }
    				// Eval siren audio hit count against our limit. If we are => then CYCLE_COUNTER then lets start a loop for "All Clear" reset
    				// If we continue to return an audio power hit, then we will continue to send to the controller. 
    				if (siren_audio_count>=CYCLE_COUNTER)
    				{
    					Serial.println("Alarm Detected");
    					
    					do 
    					{
    					  //update gateway with bad news.
    					  //sensor_node.send(msg.set("1"));
    					  sensor_node.send(msg.setSensor(CHILD_ID).set("1"), true);
    					  Serial.println("Alarm Detected Sent to gateway");
    					} while (IsAlarmAllClear()!=1);
    				
    				}
    	}
    	//Pin returned a 1 (High) so there is no alarm. 
    	else
    	{
    	  IsAlarmAllClear();
    	}
    }
    
    int IsAlarmAllClear()
    // We are looking for an gap in time that we no longer see an audio power hit to the optocoupler. 
    
    {
     int alarmOn				=0;
     long cycle_time			=0;
     unsigned long startedAt	= millis();
    
    	//We are only going to check for status for CYCLE_TIME_OKSTATUS time	
    	while(millis() - startedAt < CYCLE_TIME_OKSTATUS * 1000)
    	{
    		//We are going to check CYCLE_RATE_OKSTATUS fast
    		if(millis() - cycle_time > CYCLE_RATE_OKSTATUS) {
    			// save the last time you Checked
    			cycle_time = millis();
    			int value = digitalRead(SIREN_SENSE_PIN);
    			if (value != 1) //We are still in an alarm state
    			{
    				alarmOn++;
    			}
    		}
    	}
    			if (alarmOn < 1)
    			{
    				// We don't have any sign that we are still in an alarm status
    				//Send all clear msg to controller
    				//sensor_node.send(msg.set("0"));
    				sensor_node.send(msg.setSensor(CHILD_ID).set("0"), true);
    				// Used to update the node - NOT used for battery check.
    				sensor_node.sendBatteryLevel(random(1, 100) );
    				Serial.println("All Clear");
    				return 1;
    			} 
    			else
    			{
    				// We are still in an alarm status
    				//The calling function will handle sending NOT CLEAR to controller				
    				Serial.println("NOT CLEAR");
    				return 0;
    			} 	 
    

    }

    Here a some Pictures:

    20150613_091041.jpg

    20150613_091049.jpg

    20150613_091057.jpg

    20150613_091106.jpg

    2015-06-13_11-12-02.png


  • Admin

    You've been busy this weekend ;)


  • Hero Member

    @hek More like a busy week.. :sweat:



  • Thanks! i updated it to version 2.0 but it's working perfectly

    // Based on Author: Patrick 'Anticimex' Fallberg Interrupt driven binary switch example with dual interrupts
    // Enable debug prints to serial monitor
    #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    
    //#define MY_REPEATER_FEATURE
    #define MY_NODE_ID 17
    
    #include <SPI.h>
    #include <MySensors.h>
    
    #define CHILD_ID 1
    
    #define SIREN_SENSE_PIN 3   // Arduino Digital I/O pin for optocoupler for siren
    
    unsigned int SLEEP_TIME      = 32400; // Sleep time between reads (in seconds) 32400 = 9hrs?
    long CYCLE_COUNTER          = 3;  // This is the number of times we want the Audio Counter to reach before triggering a signal to controller.
    unsigned long CYCLE_INTERVAL    = 3; // How long do we want to watch once first detected (in seconds) 
                          //Adjust for your smoke detector, you want to pick up the siren signal at least 3 time to help stop false alarms. 
    unsigned long CYCLE_RATE      = 90; // How fast do we want to move checking the Pin state in the Status Check (in Millis) Adjust for your smoke detector
                          //Adjust for your smoke detector, you want to pick up the siren signal at least 3 time to help stop false alarms.
    unsigned long CYCLE_TIME_OKSTATUS = 8; // How long do we want to watch for "all clear" once we have confirmed an Alarm (in seconds)
    unsigned long CYCLE_RATE_OKSTATUS = 500; // How fast do we want to move checking the Pin state when checking for an OK status (in Millis)
    
    int oldValue=1;
    int value=0;
    
    
    //MySensors sensor_node;
    MyMessage msg(CHILD_ID, V_TRIPPED);
    
    void setup()  
    {  
      // Setup the Siren Pin HIGH
      pinMode(SIREN_SENSE_PIN, INPUT_PULLUP);
    }
    
    void presentation()  
    { 
    
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("Washer End Cycle", "1.1");
      present(CHILD_ID, S_SMOKE); 
      //Send the state -- Always send Alarm state on power up.
      send(msg.setSensor(CHILD_ID).set("1"), true);
      
    }
    
    // Loop will iterate on changes on the BUTTON_PINs
    void loop() 
    {
      // Check to see if we have a alarm. I always want to check even if we are coming out of sleep for heartbeat.
      AlarmStatus();
      // Sleep until we get a audio power hit on the optocoupler or 9hrs
      sleep(SIREN_SENSE_PIN-2,FALLING, SLEEP_TIME * 1000UL);
      
    } 
    
    void AlarmStatus()
    {
      
    // We will check the status now, this could be called by an interrupt or heartbeat
    int siren_audio_count =0;
    long cycle_time     =0;   
    unsigned long startedAt = millis();
    
      Serial.println("Status Check");
      //Read the Pin
      value = digitalRead(SIREN_SENSE_PIN);
        // If Pin return a 0 (LOW), then we have a Alarm Condition
      if (value != 1) {
         //We are only going to check for status for CYCLE_INTERVAL time I think this should help stabilize Siren Sensing
          while(millis() - startedAt < CYCLE_INTERVAL * 1000)
          {
            //We are going to check CYCLE_RATE fast
            if(millis() - cycle_time > CYCLE_RATE ) {
              // save the last time you Checked
              cycle_time = millis();
                //We will count each time SIREN_SENSE_PIN is 0 (Alarm - LOW) for the above time and at the above rate.
              value = digitalRead(SIREN_SENSE_PIN);  
                if (value != 1)
                {
                  siren_audio_count++;
                  Serial.print("Audio Count: ");
                  Serial.println(siren_audio_count);
                } 
            }
          }
            // Eval siren audio hit count against our limit. If we are => then CYCLE_COUNTER then lets start a loop for "All Clear" reset
            // If we continue to return an audio power hit, then we will continue to send to the controller. 
            if (siren_audio_count>=CYCLE_COUNTER)
            {
              Serial.println("Alarm Detected");
              
              do 
              {
                //update gateway with bad news.
                //sensor_node.send(msg.set("1"));
                send(msg.setSensor(CHILD_ID).set("1"), true);
                Serial.println("Alarm Detected Sent to gateway");
              } while (IsAlarmAllClear()!=1);
            
            }
      }
      //Pin returned a 1 (High) so there is no alarm. 
      else
      {
        IsAlarmAllClear();
      }
    }
    
    int IsAlarmAllClear()
    // We are looking for an gap in time that we no longer see an audio power hit to the optocoupler. 
    
    {
     int alarmOn        =0;
     long cycle_time      =0;
     unsigned long startedAt  = millis();
    
      //We are only going to check for status for CYCLE_TIME_OKSTATUS time  
      while(millis() - startedAt < CYCLE_TIME_OKSTATUS * 1000)
      {
        //We are going to check CYCLE_RATE_OKSTATUS fast
        if(millis() - cycle_time > CYCLE_RATE_OKSTATUS) {
          // save the last time you Checked
          cycle_time = millis();
          int value = digitalRead(SIREN_SENSE_PIN);
          if (value != 1) //We are still in an alarm state
          {
            alarmOn++;
          }
        }
      }
          if (alarmOn < 1)
          {
            // We don't have any sign that we are still in an alarm status
            //Send all clear msg to controller
            //sensor_node.send(msg.set("0"));
            send(msg.setSensor(CHILD_ID).set("0"), true);
            // Used to update the node - NOT used for battery check.
            sendBatteryLevel(random(1, 100) );
            Serial.println("All Clear");
            return 1;
          } 
          else
          {
            // We are still in an alarm status
            //The calling function will handle sending NOT CLEAR to controller        
            Serial.println("NOT CLEAR");
            return 0;
          }    
    }
    


  • why not connect the buzzer signal direct to arduino analog read? optocoupter for a 80cents arduino?


Log in to reply
 

Looks like your connection to MySensors Forum was lost, please wait while we try to reconnect.