Showing posts with label SwitchBot. Show all posts
Showing posts with label SwitchBot. Show all posts

Wednesday, October 4, 2023

DIY SwitchBot using Matter Over Thread running on Silicon Labs EFR32xG24 Explorer Kit in 5 Minutes.

The following steps guide you to DIY SwitchBot using Matter Over Thread running on Silicon Labs EFR32xG24 Explorer Kit xG24-EK2703A in 5 minutes.

1. Make sure you install Silicon Labs Simplicity Studio v5 and GSDK 4.3.1 with Matter extension 2.1.0-1.1.

2.Connect your xG24-EK2703A kit to your desktop and create "Matter - SoC OnOff Plug over Thread" project as base for your DIY SwitchBot using Matter Over Thread project.

3.Install and add a "sg90" PWM instance in "SOFTWARE COMPONENTS"

4.Configure "sg90" instance to use Timer0 PA00 as PWM output with PWM frequency 50 Hz.

 

5. Replace source code in "void AppTask::ActionCompleted(OnOffPlugManager::Action_t aAction)" with the following codes (red lines), which implements on/off rotating position for SG90 to turn on/off switch.

//YK for SG90 SwitchBot
#include "sl_pwm.h"
#include "sl_pwm_init_sg90_config.h"
#include "sl_sleeptimer.h"

extern sl_pwm_instance_t sl_pwm_sg90;

void AppTask::ActionCompleted(OnOffPlugManager::Action_t aAction)
{
    // action has been completed on the outlet
    if (aAction == OnOffPlugManager::ON_ACTION)
    {
        SILABS_LOG("Outlet ON")
        sl_pwm_set_duty_cycle(&sl_pwm_sg90, 2);
        sl_pwm_start(&sl_pwm_sg90);
        sl_sleeptimer_delay_millisecond(200);
        sl_pwm_set_duty_cycle(&sl_pwm_sg90, 5);
        sl_sleeptimer_delay_millisecond(200);
        sl_pwm_stop(&sl_pwm_sg90);
    }
    else if (aAction == OnOffPlugManager::OFF_ACTION)
    {
        SILABS_LOG("Outlet OFF")
        sl_pwm_set_duty_cycle(&sl_pwm_sg90, 9);
        sl_pwm_start(&sl_pwm_sg90);
        sl_sleeptimer_delay_millisecond(200);
        sl_pwm_set_duty_cycle(&sl_pwm_sg90, 5);
        sl_sleeptimer_delay_millisecond(200);
        sl_pwm_stop(&sl_pwm_sg90);
    }
#ifdef SL_CATALOG_SIMPLE_BUTTON_PRESENT
    if (sAppTask.mSyncClusterToButtonAction)
    {
        chip::DeviceLayer::PlatformMgr().ScheduleWork(UpdateClusterState, reinterpret_cast<intptr_t>(nullptr));
        sAppTask.mSyncClusterToButtonAction = false;
    }
#endif
}

6. Add the following two line to set initial SG90 position after "sl_pwm_init(&sl_pwm_sg90, &pwm_sg90_config);" in "void sl_pwm_init_instances(void)".

  //YK for SG90 SwitchBot
  sl_pwm_set_duty_cycle(&sl_pwm_sg90, 5);
  sl_pwm_start(&sl_pwm_sg90);

7. Build and download firmware into xG24-EK2703A kit(remember to dowload bootloader into the kit too)

8. Connect GND, PWR, Signal line of SG90 to GND, 3V3, and PWM pin on xG24-EK2703A kit.

9.Start RTT viewer to get QR code link for Matter Provision.


 

10. Since Apple Home supports Matter Over Thread now, we use Apple HomePod mini (iOS 17) and iPhone Home App to add our DIY SwitchBot into Apple Home.

11. Now, we can mount the DIY SwitchBot to wall switch and use Apple Home to control wall switch/light remotely.



Tuesday, December 7, 2021

Prototype OpenThread/HomeKit SwitchBot using Silicon Labs EFR32

Apple releases HomePod Mini to support Thread protocol. The following steps show you how easily to prototype an OpenThread/HomeKit SwitchBot using Silicon Labs EFR32:

1. Connect SLWSTK6000B to USB port of Desktop to start Simplicity Studio V5 and create "HomeKit Lightbulb DMP" in Launcher Tab


2. Configure "HomeKit Lightbulb DMP" as Sleepy MTD for power saving.

2.1 Revise FTD to MTD


 

2.2 Set "Enable reception when sleeping" to Disable in "UARTDRV Core"

 


2.3 Revise the following configurations in app.h.

#define kAccessorySleepInterval ((HAPTime) 5*HAPSecond)

#define kThreadDeviceType (kHAPPlatformThreadDeviceCapabilities_MTD)

2.4 Revise the following configurations in App_Base.h.

#define THREAD_CHILD_TIMEOUT_IN_SECONDS 9

 

3. Add the following codes in app.c

#include "em_device.h"
#include "em_cmu.h"
#include "em_emu.h"
#include "em_chip.h"
#include "em_gpio.h"
#include "em_timer.h"
//#include "bsp.h"

// Note: change this to set the desired output frequency in Hz
#define PWM_FREQ 50

// Note: change this to set the desired duty cycle (used to update CCVB value)
static volatile int dutyCyclePercent = 10;

// stores 1 msTicks from the SysTick timer
volatile uint32_t msTicks;

/**************************************************************************//**
 * @brief
 *    Interrupt handler for TIMER0 that changes the duty cycle
 *
 * @note
 *    This handler doesn't actually dynamically change the duty cycle. Instead,
 *    it acts as a template for doing so. Simply change the dutyCyclePercent
 *    global variable here to dynamically change the duty cycle.
 *****************************************************************************/
void TIMER0_IRQHandler(void)
{
  // Acknowledge the interrupt
  uint32_t flags = TIMER_IntGet(TIMER0);
  TIMER_IntClear(TIMER0, flags);

  // Update CCVB to alter duty cycle starting next period
  TIMER_CompareBufSet(TIMER0, 0, (TIMER_TopGet(TIMER0) * dutyCyclePercent) / 100);
}

/**************************************************************************//**
 * @brief GPIO initialization
 *****************************************************************************/
void initGpio(void)
{
  // Enable GPIO and clock
  CMU_ClockEnable(cmuClock_GPIO, true);

  // Configure PC10 (Expansion Header Pin 16) as output
  GPIO_PinModeSet(gpioPortC, 10, gpioModePushPull, 0);
}

/**************************************************************************//**
 * @brief
 *    TIMER initialization
 *****************************************************************************/
void initTimer(void)
{
  // Enable clock for TIMER0 module
  CMU_ClockEnable(cmuClock_TIMER0, true);

  // Configure TIMER0 Compare/Capture for output compare
  // Use PWM mode, which sets output on overflow and clears on compare events
  TIMER_InitCC_TypeDef timerCCInit = TIMER_INITCC_DEFAULT;
  timerCCInit.mode = timerCCModePWM;
  TIMER_InitCC(TIMER0, 0, &timerCCInit);

  // Route TIMER0 CC0 to location 15 and enable CC0 route pin
  // TIM0_CC0 #15 is GPIO Pin PC10
  TIMER0->ROUTELOC0 |=  TIMER_ROUTELOC0_CC0LOC_LOC15;
  TIMER0->ROUTEPEN |= TIMER_ROUTEPEN_CC0PEN;

  // Set top value to overflow at the desired PWM_FREQ frequency
  TIMER_TopSet(TIMER0, CMU_ClockFreqGet(cmuClock_TIMER0) / (8 * PWM_FREQ));

  // Set compare value for initial duty cycle
  TIMER_CompareSet(TIMER0, 0, (TIMER_TopGet(TIMER0) * dutyCyclePercent) / 100);

  // Initialize the timer
  TIMER_Init_TypeDef timerInit = TIMER_INIT_DEFAULT;
  timerInit.prescale = timerPrescale8;
  TIMER_Init(TIMER0, &timerInit);

  // Enable TIMER0 compare event interrupts to update the duty cycle
  TIMER_IntEnable(TIMER0, TIMER_IEN_CC0);
  NVIC_EnableIRQ(TIMER0_IRQn);
}

void sg90_on(void){
  dutyCyclePercent=25;
  initTimer();
  sl_udelay_wait(110000);
  dutyCyclePercent=10;
  initTimer();
  sl_udelay_wait(110000);
  dutyCyclePercent=25;
  initTimer();
  sl_udelay_wait(110000);
  CMU_ClockEnable(cmuClock_TIMER0, false);
  GPIO_PinModeSet(gpioPortC, 10, gpioModePushPull, 0);
}
void sg90_off(void){
  dutyCyclePercent=25;
  initTimer();
  sl_udelay_wait(130000);
  dutyCyclePercent=45;
  initTimer();
  sl_udelay_wait(130000);
  dutyCyclePercent=25;
  initTimer();
  sl_udelay_wait(130000);
  CMU_ClockEnable(cmuClock_TIMER0, false);
  GPIO_PinModeSet(gpioPortC, 10, gpioModePushPull, 0);
}

4. Add the following code to AppInitialize(), TurnOnLightBulb(), and TurnOffLightBulb() in app.c

4.1 Add initGpio() in AppInitialize().

4.2 Add sg90_on() in  TurnOnLightBulb().

4.3 Add sg90_off() in  TurnOffLightBulb().

5. Rename HomeKit device name to "OT HomeKit SwitchBot" in HomeKit Configurator


6. Connect SG90 servo motor to EXP Header (pin15-PC10) of SLWSTK6000B and build/download application into SLWSTK6000.

 


7. You need to have a HomePod mini, which supports OpenThread, and provision "OT HomeKit SwitchBot" with iPhone Home App.


 

8. Test it with Siri to trigger "OT HomeKit SwitchBot" to turn off/on my office light, which you can refer to the following video.


9. In Energy Profiler, you can see low average power consumption on "OT HomeKit SwitchBot" which is configured as Sleepy MTD and perfectly suitable for battery power.