From 8d4888c495b3f560451c8ab5ceffc9e9ac974902 Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Wed, 31 Aug 2016 11:29:58 +0200 Subject: [PATCH 1/2] Zoul: added driver to control an AC light dimmer with zero-crossing --- examples/zolertia/zoul/Makefile | 4 +- examples/zolertia/zoul/test-ac-dimmer.c | 102 +++++++++++++++ platform/zoul/dev/ac-dimmer.c | 159 ++++++++++++++++++++++++ platform/zoul/dev/ac-dimmer.h | 108 ++++++++++++++++ 4 files changed, 371 insertions(+), 2 deletions(-) create mode 100644 examples/zolertia/zoul/test-ac-dimmer.c create mode 100644 platform/zoul/dev/ac-dimmer.c create mode 100644 platform/zoul/dev/ac-dimmer.h diff --git a/examples/zolertia/zoul/Makefile b/examples/zolertia/zoul/Makefile index 66b530341..c5e99f92c 100644 --- a/examples/zolertia/zoul/Makefile +++ b/examples/zolertia/zoul/Makefile @@ -5,12 +5,12 @@ CONTIKI_PROJECT += test-bmp085-bmp180 test-motion test-rotation-sensor CONTIKI_PROJECT += test-grove-light-sensor test-grove-loudness-sensor CONTIKI_PROJECT += test-weather-meter test-grove-gyro test-lcd test-iaq CONTIKI_PROJECT += test-pm10-sensor test-vac-sensor test-aac-sensor -CONTIKI_PROJECT += test-zonik test-dht22.c +CONTIKI_PROJECT += test-zonik test-dht22.c test-ac-dimmer.c test-servo.c CONTIKI_TARGET_SOURCEFILES += tsl2563.c sht25.c bmpx8x.c motion-sensor.c CONTIKI_TARGET_SOURCEFILES += adc-sensors.c weather-meter.c grove-gyro.c CONTIKI_TARGET_SOURCEFILES += rgb-bl-lcd.c pm10-sensor.c iaq.c zonik.c relay.c -CONTIKI_TARGET_SOURCEFILES += dht22.c servo.c +CONTIKI_TARGET_SOURCEFILES += dht22.c servo.c ac-dimmer.c all: $(CONTIKI_PROJECT) diff --git a/examples/zolertia/zoul/test-ac-dimmer.c b/examples/zolertia/zoul/test-ac-dimmer.c new file mode 100644 index 000000000..521b023e3 --- /dev/null +++ b/examples/zolertia/zoul/test-ac-dimmer.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2016, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ +/** + * \addtogroup zoul-examples + * @{ + * + * \defgroup zoul-ac-dimmer-test Krida Electronics AC light dimmer test example + * + * Demonstrates the use of an AC dimmer with zero-crossing, connected to the + * ADC1 and ADC2 pins (PA5 and PA4 respectively), powered over the D+5.1 pin + * + * @{ + * + * \file + * A quick program to test an AC dimmer + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include +#include "contiki.h" +#include "dev/ac-dimmer.h" +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +PROCESS(remote_ac_dimmer_process, "AC light dimmer test"); +AUTOSTART_PROCESSES(&remote_ac_dimmer_process); +/*---------------------------------------------------------------------------*/ +static uint8_t dimming; +static struct etimer et; +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(remote_ac_dimmer_process, ev, data) +{ + PROCESS_BEGIN(); + + dimming = 0; + SENSORS_ACTIVATE(ac_dimmer); + + printf("AC dimmer: min %u%% max %u%%\n", DIMMER_DEFAULT_MIN_DIMM_VALUE, + DIMMER_DEFAULT_MAX_DIMM_VALUE); + + /* Set the lamp to 10% and wait a few seconds */ + ac_dimmer.value(DIMMER_DEFAULT_MIN_DIMM_VALUE); + etimer_set(&et, CLOCK_SECOND * 5); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + /* Upon testing for duty cycles lower than 10% there was noise (probably from + * the triac), causing the driver to skip a beat, and from time to time made + * the test lamp blink. This is easily reproducible by setting the dimmer to + * 5% and using a logic analyzer on the SYNC and GATE pins. The noise was + * picked-up also by the non-connected test probes of the logic analyser. + * Nevertheless the difference between 10% and 2% bright-wise is almost + * negligible + */ + while(1) { + + dimming += DIMMER_DEFAULT_MIN_DIMM_VALUE; + if(dimming > DIMMER_DEFAULT_MAX_DIMM_VALUE) { + dimming = DIMMER_DEFAULT_MIN_DIMM_VALUE; + } + + ac_dimmer.value(dimming); + printf("AC dimmer: light is now --> %u\n", ac_dimmer.status(SENSORS_ACTIVE)); + + etimer_set(&et, CLOCK_SECOND); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/zoul/dev/ac-dimmer.c b/platform/zoul/dev/ac-dimmer.c new file mode 100644 index 000000000..c6b073c76 --- /dev/null +++ b/platform/zoul/dev/ac-dimmer.c @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2016, Zolertia - http://www.zolertia.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-ac-dimmer + * @{ + * + * \file + * Driver for the Krida Electronics AC light dimmer with zero-crossing, using + * a 50Hz frequency as reference (1/50Hz) ~20ms and 10ms half-cycle + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "ac-dimmer.h" +#include "dev/gpio.h" +#include "lib/sensors.h" +#include "dev/ioc.h" +/*---------------------------------------------------------------------------*/ +#define DIMMER_SYNC_PORT_BASE GPIO_PORT_TO_BASE(DIMMER_SYNC_PORT) +#define DIMMER_SYNC_PIN_MASK GPIO_PIN_MASK(DIMMER_SYNC_PIN) +#define DIMMER_GATE_PORT_BASE GPIO_PORT_TO_BASE(DIMMER_GATE_PORT) +#define DIMMER_GATE_PIN_MASK GPIO_PIN_MASK(DIMMER_GATE_PIN) +/*---------------------------------------------------------------------------*/ +static uint8_t enabled; +static uint8_t dimming; +/*---------------------------------------------------------------------------*/ +PROCESS(ac_dimmer_int_process, "AC Dimmer zero-cross interrupt process"); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(ac_dimmer_int_process, ev, data) +{ + PROCESS_EXITHANDLER(); + PROCESS_BEGIN(); + + int dimtime; + + while(1) { + PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL); + dimtime = (uint8_t)(100 - dimming); + dimtime *= 100; + + /* Off cycle */ + clock_delay_usec(dimtime); + GPIO_SET_PIN(DIMMER_GATE_PORT_BASE, DIMMER_GATE_PIN_MASK); + /* Triac on propagation delay */ + clock_delay_usec(DIMMER_DEFAULT_GATE_PULSE_US); + GPIO_CLR_PIN(DIMMER_GATE_PORT_BASE, DIMMER_GATE_PIN_MASK); + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +static void +dimmer_zero_cross_int_handler(uint8_t port, uint8_t pin) +{ + process_poll(&ac_dimmer_int_process); +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + return dimming; + case SENSORS_READY: + return enabled; + } + return DIMMER_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + if(!enabled) { + return DIMMER_ERROR; + } + + dimming = (uint8_t)type; + return DIMMER_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + if(type != SENSORS_ACTIVE) { + return DIMMER_ERROR; + } + + if(value) { + /* This is the Triac's gate pin */ + GPIO_SOFTWARE_CONTROL(DIMMER_GATE_PORT_BASE, DIMMER_GATE_PIN_MASK); + GPIO_SET_OUTPUT(DIMMER_GATE_PORT_BASE, DIMMER_GATE_PIN_MASK); + ioc_set_over(DIMMER_GATE_PORT, DIMMER_GATE_PIN, IOC_OVERRIDE_OE); + GPIO_CLR_PIN(DIMMER_GATE_PORT_BASE, DIMMER_GATE_PIN_MASK); + + /* This is the zero-crossing pin and interrupt */ + GPIO_SOFTWARE_CONTROL(DIMMER_SYNC_PORT_BASE, DIMMER_SYNC_PIN_MASK); + GPIO_SET_INPUT(DIMMER_SYNC_PORT_BASE, DIMMER_SYNC_PIN_MASK); + + /* Pull-up resistor, detect rising edge */ + GPIO_DETECT_EDGE(DIMMER_SYNC_PORT_BASE, DIMMER_SYNC_PIN_MASK); + GPIO_TRIGGER_SINGLE_EDGE(DIMMER_SYNC_PORT_BASE, DIMMER_SYNC_PIN_MASK); + GPIO_DETECT_RISING(DIMMER_SYNC_PORT_BASE, DIMMER_SYNC_PIN_MASK); + gpio_register_callback(dimmer_zero_cross_int_handler, DIMMER_SYNC_PORT, + DIMMER_SYNC_PIN); + + /* Spin process until an interrupt is received */ + process_start(&ac_dimmer_int_process, NULL); + + /* Enable interrupts */ + GPIO_ENABLE_INTERRUPT(DIMMER_SYNC_PORT_BASE, DIMMER_SYNC_PIN_MASK); + // ioc_set_over(DIMMER_SYNC_PORT, DIMMER_SYNC_PIN, IOC_OVERRIDE_PUE); + nvic_interrupt_enable(DIMMER_INT_VECTOR); + + enabled = 1; + dimming = DIMMER_DEFAULT_START_VALUE; + return DIMMER_SUCCESS; + } + + /* Disable interrupt and pins */ + + GPIO_DISABLE_INTERRUPT(DIMMER_GATE_PORT_BASE, DIMMER_GATE_PIN_MASK); + GPIO_SET_INPUT(DIMMER_GATE_PORT_BASE, DIMMER_GATE_PIN_MASK); + GPIO_SET_OUTPUT(DIMMER_SYNC_PORT_BASE, DIMMER_SYNC_PIN_MASK); + process_exit(&ac_dimmer_int_process); + + enabled = 0; + dimming = 0; + return DIMMER_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(ac_dimmer, AC_DIMMER_ACTUATOR, value, configure, status); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/zoul/dev/ac-dimmer.h b/platform/zoul/dev/ac-dimmer.h new file mode 100644 index 000000000..17d94b5b4 --- /dev/null +++ b/platform/zoul/dev/ac-dimmer.h @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2016, Zolertia - http://www.zolertia.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-sensors + * @{ + * + * \defgroup zoul-ac-dimmer AC light dimmer with zero-crossing driver + * + * Driver for an AC light dimmer with zero-crossing driver + * @{ + * + * \file + * Header file for an AC light dimmer with zero-crossing driver + */ +/*---------------------------------------------------------------------------*/ +#ifndef AC_DIMMER_H_ +#define AC_DIMMER_H_ +/* -------------------------------------------------------------------------- */ +/** + * \name AC dimmer default pins, ports and interrupt vector + * @{ + */ +#ifdef DIMMER_SYNC_CONF_PIN +#define DIMMER_SYNC_PIN DIMMER_SYNC_CONF_PIN +#else +#define DIMMER_SYNC_PIN 5 +#endif +#ifdef DIMMER_SYNC_CONF_PORT +#define DIMMER_SYNC_PORT DIMMER_SYNC_CONF_PORT +#else +#define DIMMER_SYNC_PORT GPIO_A_NUM +#endif +#ifdef DIMMER_GATE_CONF_PIN +#define DIMMER_GATE_PIN DIMMER_GATE_CONF_PIN +#else +#define DIMMER_GATE_PIN 4 +#endif +#ifdef DIMMER_GATE_CONF_PORT +#define DIMMER_GATE_PORT DIMMER_GATE_CONF_PORT +#else +#define DIMMER_GATE_PORT GPIO_A_NUM +#endif +#ifdef DIMMER_CONF_INT_VECTOR +#define DIMMER_INT_VECTOR DIMMER_CONF_INT_VECTOR +#else +#define DIMMER_INT_VECTOR NVIC_INT_GPIO_PORT_A +#endif +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name AC dimmer values + * @{ + */ +#define DIMMER_DEFAULT_START_VALUE 50 +#define DIMMER_DEFAULT_GATE_PULSE_US 15 +#define DIMMER_DEFAULT_MIN_DIMM_VALUE 10 +#define DIMMER_DEFAULT_MAX_DIMM_VALUE 80 +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name AC dimmer return types + * @{ + */ +#define DIMMER_ERROR (-1) +#define DIMMER_SUCCESS 0x00 +/** @} */ +/* -------------------------------------------------------------------------- */ +#define AC_DIMMER_ACTUATOR "AC light dimmer zero-cross" +/* -------------------------------------------------------------------------- */ +extern const struct sensors_sensor ac_dimmer; +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ +#endif /* RELAY_H_ */ +/* -------------------------------------------------------------------------- */ +/** + * @} + * @} + */ From 5e400dd43b5a2c6c2fd7f9e2ca56bf0d5e8ceffc Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Wed, 31 Aug 2016 15:36:31 +0200 Subject: [PATCH 2/2] Zoul: fixed ac-dimmer interrupt disable pin/port and check interrupt source --- platform/zoul/dev/ac-dimmer.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/platform/zoul/dev/ac-dimmer.c b/platform/zoul/dev/ac-dimmer.c index c6b073c76..47241ce33 100644 --- a/platform/zoul/dev/ac-dimmer.c +++ b/platform/zoul/dev/ac-dimmer.c @@ -78,7 +78,9 @@ PROCESS_THREAD(ac_dimmer_int_process, ev, data) static void dimmer_zero_cross_int_handler(uint8_t port, uint8_t pin) { - process_poll(&ac_dimmer_int_process); + if((port == DIMMER_SYNC_PORT) && (pin == DIMMER_SYNC_PIN)) { + process_poll(&ac_dimmer_int_process); + } } /*---------------------------------------------------------------------------*/ static int @@ -144,7 +146,7 @@ configure(int type, int value) /* Disable interrupt and pins */ - GPIO_DISABLE_INTERRUPT(DIMMER_GATE_PORT_BASE, DIMMER_GATE_PIN_MASK); + GPIO_DISABLE_INTERRUPT(DIMMER_SYNC_PORT_BASE, DIMMER_SYNC_PIN_MASK); GPIO_SET_INPUT(DIMMER_GATE_PORT_BASE, DIMMER_GATE_PIN_MASK); GPIO_SET_OUTPUT(DIMMER_SYNC_PORT_BASE, DIMMER_SYNC_PIN_MASK); process_exit(&ac_dimmer_int_process);