#include <ets_sys.h>
#include <osapi.h>
#include <user_interface.h>
#include <os_type.h>
#include "driver/uart.h"
#include "driver/gpio16.h"
#include "user_config.h"
#include "wemos.h"
#define DELAY 1000 /* milliseconds */
#define HOT_PIN D1 /* Pin of hot water */
#define COLD_PIN D2 /* Pin of cold water */
#define EXT_POWER_PIN D0 /* Pin of monitoring external power */
LOCAL os_timer_t mainTimer, buttonTimer;
_waterCounter waterCounter;
LOCAL uint8_t ICACHE_FLASH_ATTR debounce(uint8 sample) {
static uint8 state = 0xFF, cnt0, cnt1;
uint8 delta;
delta = sample ^ state;
cnt1 = (cnt1 ^ cnt0) & delta;
cnt0 = ~cnt0 & delta;
state ^= (cnt0 & cnt1);
return state;
}
LOCAL void ICACHE_FLASH_ATTR buttonTimer_cb(void *arg) {
uint8 bitHot, bitCold, bitStatus, counter = 0;
bitHot = gpio_read(HOT_PIN);
bitCold = gpio_read(COLD_PIN) << 1;
counter |= bitHot;
counter |= bitCold;
waterCounter.status = debounce(counter);
if (waterCounter.status & 0x01) {
if (!(waterCounter.status_old & 0x01)) {
waterCounter.status_old |= 0x01;
waterCounter.counterHotWater++;
os_printf("hotCounter = %d\r\n", waterCounter.counterHotWater);
}
} else {
if (waterCounter.status_old & 0x01) {
waterCounter.status_old &= ~0x01;
}
}
if (waterCounter.status & 0x02) {
if (!(waterCounter.status_old & 0x02)) {
waterCounter.status_old |= 0x02;
waterCounter.counterColdWater++;
os_printf("coldCounter = %d\r\n", waterCounter.counterColdWater);
}
} else {
if (waterCounter.status_old & 0x02) {
waterCounter.status_old &= ~0x02;
}
}
}
LOCAL void ICACHE_FLASH_ATTR wakeupFromMotion(void) {
wifi_fpm_close();
wifi_set_opmode(STATION_MODE);
os_printf("Wake up from sleep.\r\n");
}
void ICACHE_FLASH_ATTR sleepOnNow() {
wifi_station_disconnect();
wifi_set_opmode(NULL_MODE);
wifi_fpm_set_sleep_type(LIGHT_SLEEP_T); //light sleep mode
gpio_pin_wakeup_enable(GPIO_ID_PIN(pin_num[HOT_PIN]),
GPIO_PIN_INTR_LOLEVEL); /* Set the interrupt to look for LOW pulses on HOT_PIN */
gpio_pin_wakeup_enable(GPIO_ID_PIN(pin_num[COLD_PIN]),
GPIO_PIN_INTR_LOLEVEL); /* Set the interrupt to look for LOW pulses on COLD_PIN */
wifi_fpm_open();
wifi_fpm_set_wakeup_cb(wakeupFromMotion); //wakeup callback
wifi_fpm_do_sleep(0xFFFFFFF);
}
LOCAL void ICACHE_FLASH_ATTR mainTimer_cb(void *arg)
{
uint8 bit;
bit = gpio_read(EXT_POWER_PIN);
if (!bit) {
os_printf("Power low. Light sleep now ...\r\n");
os_delay_us(50000);
sleepOnNow();
}
}
/******************************************************************************
* FunctionName : user_rf_cal_sector_set
* Description : SDK just reversed 4 sectors, used for rf init data and paramters.
* We add this function to force users to set rf cal sector, since
* we don't know which sector is free in user's application.
* sector map for last several sectors : ABBBCDDD
* A : rf cal
* B : at parameters
* C : rf init data
* D : sdk parameters
* Parameters : none
* Returns : rf cal sector
*******************************************************************************/
uint32 ICACHE_FLASH_ATTR user_rf_cal_sector_set(void)
{
enum flash_size_map size_map = system_get_flash_size_map();
uint32 rf_cal_sec = 0;
switch (size_map) {
case FLASH_SIZE_4M_MAP_256_256:
rf_cal_sec = 128 - 8;
break;
case FLASH_SIZE_8M_MAP_512_512:
rf_cal_sec = 256 - 5;
break;
case FLASH_SIZE_16M_MAP_512_512:
case FLASH_SIZE_16M_MAP_1024_1024:
rf_cal_sec = 512 - 5;
break;
case FLASH_SIZE_32M_MAP_512_512:
case FLASH_SIZE_32M_MAP_1024_1024:
rf_cal_sec = 1024 - 5;
break;
default:
rf_cal_sec = 0;
break;
}
return rf_cal_sec;
}
void ICACHE_FLASH_ATTR user_rf_pre_init(void)
{
}
void ICACHE_FLASH_ATTR user_init(void)
{
// Configure the UART
// uart_init(BIT_RATE_115200, BIT_RATE_115200);
uart_div_modify(0, UART_CLK_FREQ / 115200);
if (set_gpio_mode(HOT_PIN, GPIO_INPUT, GPIO_PULLUP)) {
os_printf("GPIO%d set input mode\r\n", pin_num[HOT_PIN]);
}
if (set_gpio_mode(COLD_PIN, GPIO_INPUT, GPIO_PULLUP)) {
os_printf("GPIO%d set input mode\r\n", pin_num[COLD_PIN]);
}
if (set_gpio_mode(EXT_POWER_PIN, GPIO_INPUT, GPIO_PULLDOWN)) {
os_printf("GPIO%d set input mode\r\n", pin_num[EXT_POWER_PIN]);
}
wifi_set_opmode(STATION_MODE);
os_timer_disarm(&buttonTimer);
os_timer_setfn(&buttonTimer, (os_timer_func_t *)buttonTimer_cb, (void *)0);
os_timer_arm(&buttonTimer, 50, true);
os_timer_disarm(&mainTimer);
os_timer_setfn(&mainTimer, (os_timer_func_t *)mainTimer_cb, (void *)0);
os_timer_arm(&mainTimer, DELAY, 1);
}