97 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			97 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C
		
	
	
	
| 
 | |
| ////////////////////////////////////
 | |
| //   DEVICE-SPECIFIC LED SERVICES //
 | |
| ////////////////////////////////////
 | |
| 
 | |
| // NOTE: This example is constructed only for the purpose of demonstrating how to
 | |
| // emulate a pushbutton in HomeSpan.  The length of the blinking routine is MUCH longer
 | |
| // than HomeSpan should spend on an update().  To see how this effects HomeKit, try changing
 | |
| // the number of blinks to 50, or keep it at 3 and increase the delay times in update() so
 | |
| // that the blink routine takes 10 seconds or more. When activated, HomeKit will think the
 | |
| // device has become non-responsive if it does not receive a return message from update() within
 | |
| // a certain period of time.
 | |
| 
 | |
| // In practice, pushbuton emulation is used for very short routines, such as driving
 | |
| // an IR LED or an RF transmitter to send a code to a remote device.
 | |
| 
 | |
| // New and changed lines in comparison with Example 9 are noted as "NEW!"
 | |
| 
 | |
| struct DEV_Blinker : Service::LightBulb {           // LED Blinker
 | |
| 
 | |
|   int ledPin;                                       // pin number defined for this LED
 | |
|   int nBlinks;                                      // NEW! number of times to blink
 | |
|   
 | |
|   SpanCharacteristic *power;                        // reference to the On Characteristic
 | |
|   
 | |
|   DEV_Blinker(int ledPin, int nBlinks) : Service::LightBulb(){       // constructor() method
 | |
| 
 | |
|     power=new Characteristic::On();                 
 | |
|         
 | |
|     this->ledPin=ledPin;                            
 | |
|     this->nBlinks=nBlinks;                           // NEW! number of blinks
 | |
|     pinMode(ledPin,OUTPUT);                         
 | |
|     
 | |
|     Serial.print("Configuring LED Blinker: Pin=");   // initialization message
 | |
|     Serial.print(ledPin);
 | |
|     Serial.print("  Blinks=");                       // NEW! add output message for number of blinks
 | |
|     Serial.print(nBlinks);
 | |
|     Serial.print("\n");
 | |
| 
 | |
|   } // end constructor
 | |
| 
 | |
|   boolean update(){                              // update() method
 | |
| 
 | |
|     // NEW! Instead of turning on or off the LED according to newValue, we blink it for
 | |
|     // the number of times specified, and leave it in the off position when finished.
 | |
|     // This line is deleted...
 | |
|     
 | |
|     // digitalWrite(ledPin,power->getNewVal());      
 | |
| 
 | |
|     // and is replaced by...
 | |
| 
 | |
|     if(power->getNewVal()){                       // check to ensure HomeKit is requesting we "turn on" this device (else ignore)
 | |
| 
 | |
|       LOG1("Activating the LED Blinker on pin=");
 | |
|       LOG1(ledPin);
 | |
|       LOG1("\n");
 | |
| 
 | |
|       for(int i=0;i<nBlinks;i++){                     // loop over number of blinks specified
 | |
|         digitalWrite(ledPin,HIGH);                    // turn pin on
 | |
|         delay(100);                                   // wait 100 ms
 | |
|         digitalWrite(ledPin,LOW);                     // turn pin off
 | |
|         delay(250);                                   // wait 250 ms
 | |
|       }
 | |
|       
 | |
|     } // if newVal=true
 | |
| 
 | |
|     // Note that the delays above of 100ms and 250ms are for illustrative purposes only
 | |
|     // (and so you can see the LED blink). In practice, if you were controlling an IR LED
 | |
|     // or an RF transmitter, the whole signal would likely transmit in 10ms total.
 | |
|     
 | |
|     return(true);                               // return true
 | |
|   
 | |
|   } // update
 | |
| 
 | |
|   // NEW! Here we implement a very simple loop() method that checks to see if the power Characteristic
 | |
|   // is "on" for at least 3 seconds.  If so, it resets the value to "off" (false).
 | |
| 
 | |
|   void loop(){
 | |
| 
 | |
|     if(power->getVal() && power->timeVal()>3000){   // check that power is true, and that time since last modification is greater than 3 seconds 
 | |
|       LOG1("Resetting Blinking LED Control\n");     // log message  
 | |
|       power->setVal(false);                         // set power to false
 | |
|     }      
 | |
|     
 | |
|   } // loop
 | |
|   
 | |
| };
 | |
|       
 | |
| //////////////////////////////////
 | |
| 
 | |
| // HomeKit Bug Note:  There is an apparent bug in HomeKit uncovered during the development of this example.
 | |
| // If you have an Accessory with three or more Services, and the Accessory receives a notification message
 | |
| // from the device, AND the HomeKit interface is open to show the detailed control for this Service tile
 | |
| // in the HomeKit app, then for some reason HomeKit sends an update() request back to the device asking to 
 | |
| // set the Characteristic to the value that it just received from an Event Notification.  HomeKit is not supposed
 | |
| // to send update requests in response to an Event Notification.
 |