Interruptor táctil inalámbrico con retroiluminación fluorescente adicional

¡Saludos a todos los lectores de la sección “DIY o Do It Yourself” de Habr! El artículo de hoy tratará sobre el interruptor táctil del chip TTP223 | ficha de datos. El interruptor funciona en el microcontrolador nRF52832 | ficha de datos, se utilizó un módulo YJ-17103 con antena impresa y conector para antena externa MHF4. El interruptor táctil funciona con baterías CR2430 o CR2450. El consumo en modo de transmisión no supera los 8 mA, en modo de suspensión no supera los 6 µA.
Interruptor táctil inalámbrico con retroiluminación fluorescente adicional

Como todos los proyectos anteriores, este también es un proyecto Arduino, el programa está escrito en el IDE de Arduino. La implementación del software del dispositivo se basa en el protocolo Mysensors | Bibliotecas GitHub, Soporte de placa nRF5 GitHub en Missensores. Foro de la comunidad de habla inglesa - http://forum.mysensors.org, foro de la comunidad de habla rusa - http://mysensors.ru/forum/
(Para aquellos que quieran estudiar - Документация, Protocolo serial, API, Protocolo, analizador | para aquellos que deseen ayudar (contribuciones) en el desarrollo del proyecto - Документация)

El tablero de interruptor táctil fue desarrollado en el programa Deeptrace, teniendo en cuenta la fabricación posterior mediante el método de tecnología de planchado láser (LUT). El tablero se desarrolló en unas dimensiones de 60x60 mm (un panel de vidrio estándar tiene unas dimensiones de 80x80 mm). El circuito se imprimió en las páginas de la revista Antenna y se transfirió con una plancha Bosch con la configuración “Len” (potencia máxima) a una placa de fibra de vidrio de doble cara de 1.5 mm, 35 µm (en ausencia de otra).
Interruptor táctil inalámbrico con retroiluminación fluorescente adicional

El grabado se realizó con una solución de cloruro férrico, previamente preparada en proporciones de 1.5 cucharaditas por 250 ml de agua tibia. El proceso duró 15 minutos.
La perforación de orificios para las vías entre capas y para fijar el soporte de la batería se realizó con un minitaladro DREMEL 3000 montado en un soporte de perforación DREMEL 220. Los orificios para las vías entre capas se perforaron con un taladro de 0,4 mm y los orificios para el soporte de la batería con un taladro de 1,1 mm. . El recorte a lo largo de los bordes del tablero se realizó con el mismo minitaladro con un accesorio DREMEL 540 (círculo de corte d=32.0 mm). La poda se realizó en respirador.
El estañado del tablero grabado se realizó utilizando una aleación Rose en una solución acuosa (1 cucharadita de ácido cítrico cristalizado por 300 ml de agua).

El proceso de soldadura duró aproximadamente una hora, la mayor parte del tiempo se dedicó a soldar alambre (estañado, de 0.4 mm de diámetro) en los orificios para las vías entre capas.

El tablero se lavó con limpiador en aerosol FLUX OFF.
Interruptor táctil inalámbrico con retroiluminación fluorescente adicional

Interruptor táctil inalámbrico con retroiluminación fluorescente adicional

El diseño del cuerpo del dispositivo se realizó en un editor de diseño tridimensional asistido por computadora. Dimensiones de la caja 78,5 mm x 78,5 mm x 12 mm.
Interruptor táctil inalámbrico con retroiluminación fluorescente adicional

El modelo completo de la carcasa y la tapa del compartimento de la batería se guardó en formato STL, luego fue necesario preparar estos modelos para imprimir en una impresora SLA (agregando soportes, orientación). En esta etapa surgió un pequeño problema, ya que el área de impresión de las impresoras SLA domésticas es pequeña. El modelo de carcasa del dispositivo en la posición más óptima en relación al tiempo de impresión no encajaba en las dimensiones del área de impresión. Al colocar el modelo a 45 grados, también se obtuvo un resultado decepcionante: el peso del soporte era igual al peso del cuerpo del modelo. Se decidió imprimir el modelo en vertical, realizando un soporte en uno de los lados frontales, habiéndose acordado previamente el hecho de realizar el posprocesamiento. La impresión del cuerpo tomó 5 horas con una capa de 50 micras. A continuación, se procesó con papel de lija de grano muy fino (no escribiré el número porque no lo sé :)). La tapa de la batería tardó 40 minutos en imprimirse.
Interruptor táctil inalámbrico con retroiluminación fluorescente adicional

Los paneles de vidrio de Aliexpress se venden con un marco de plástico ya pegado, no hubo problemas para quitar el marco. Quité el panel de vidrio después de precalentarlo con un secador de pelo normal.
Interruptor táctil inalámbrico con retroiluminación fluorescente adicional

Interruptor táctil inalámbrico con retroiluminación fluorescente adicional

El difusor para la retroiluminación LED se realizó con cinta adhesiva de doble cara con adhesivo acrílico 3M 9088-200. Para la iluminación fluorescente había varios materiales entre los que elegir: cinta adhesiva china y papel adhesivo cortado en cintas de la empresa nacional Luminofor. La elección se hizo a favor de un fabricante nacional, en mi opinión, brilló más y por más tiempo. Se pegó encima un cuadrado de papel con pigmento fluorescente con cinta adhesiva de doble cara 3M 9088-200.

El vidrio se pegó al cuerpo del interruptor usando cinta de doble cara con adhesivo acrílico 3M VHB 4910.
Interruptor táctil inalámbrico con retroiluminación fluorescente adicional

La tapa se fijó con un tornillo M 1,4 X 5 mm.

El coste del dispositivo fue de 890 rublos.

Luego vino la parte del programa. Hubo algunos problemas. Resulta que los chips sensores TTP223 funcionan muy bien con una fuente de alimentación estabilizada de 3.3 V y no muy bien cuando se alimentan directamente desde una batería bien descargada. Al iniciar el dispositivo con una fuente de alimentación de alrededor de 2.5 V, además de una "reducción" adicional al realizar la presentación de Mysensors, el microcircuito TTP223 (inmediatamente después de la calibración) provocó una interrupción del MK ya que estaba con un disparador activo.

Se cambió el circuito de alimentación del microcircuito (administración de energía TTP223 con gpio MK), se suministró tierra adicional y se reemplazaron resistencias con mayor resistencia en las líneas de LED RGB (que van al otro lado de la placa del sensor capacitivo). También se agregó al software: activación de la alimentación del microcircuito capacitivo después de iniciar el marco Mysensors y elaborar la presentación. Se ha duplicado el retraso para la calibración automática del chip TTP223 cuando se aplica energía. Todos estos cambios eliminaron por completo este problema.

Antes de ver el código del programa, te recomiendo que te familiarices con la estructura básica de los bocetos en Mysensors.void before()
{
// Дополнительная функция, если сравнивать со стандартной структурой Ардуино скетчей, то before() это подобие setup(), отработка происходит до инициализации транспортного уровня Mysensors, рекомендуется например для инициализации устройств SPI
}

void setup()
{

}

void presentation()
{
//Тут происходит презентация ноды и ее сенсоров на контролере через маршрутизатор
sendSketchInfo("Name of my sensor node", "1.0"); // презентация названия ноды, версии ПО
present(CHILD_ID, S_WHATEVER, "Description"); // презентация сенсоров ноды, описания сенсоров
}

void loop()
{

}

Código de prueba del programa del interruptor táctil:test_sens.ino
/**
ТЕСТОВЫЙ СКЕТЧ СЕНСОРНОГО ВЫКЛЮЧАТЕЛЯ С ПРЕРЫВАНИЯМИ НА NRF_LPCOMP
*/
bool button_flag;
bool sens_flag;
bool send_flag;
bool detection;
bool nosleep;
byte timer;
unsigned long SLEEP_TIME = 21600000; //6 hours
unsigned long oldmillis;
unsigned long newmillis;
unsigned long interrupt_time;
unsigned long SLEEP_TIME_W;
uint16_t currentBatteryPercent;
uint16_t batteryVoltage = 0;
uint16_t battery_vcc_min = 2400;
uint16_t battery_vcc_max = 3000;

#define MY_RADIO_NRF5_ESB
//#define MY_PASSIVE_NODE
#define MY_NODE_ID 30
#define MY_PARENT_NODE_ID 0
#define MY_PARENT_NODE_IS_STATIC
#define MY_TRANSPORT_UPLINK_CHECK_DISABLED
#define IRT_PIN 3 //(PORT0, gpio 5)
#include <MySensors.h>
// see https://www.mysensors.org/download/serial_api_20
#define SENS_CHILD_ID 0
#define CHILD_ID_VOLT 254
MyMessage sensMsg(SENS_CHILD_ID, V_VAR1);
//MyMessage voltMsg(CHILD_ID_VOLT, V_VOLTAGE);

void preHwInit() {
sleep(2000);
pinMode(RED_LED, OUTPUT);
digitalWrite(RED_LED, HIGH);
pinMode(GREEN_LED, OUTPUT);
digitalWrite(GREEN_LED, HIGH);
pinMode(BLUE_LED, OUTPUT);
digitalWrite(BLUE_LED, HIGH);
pinMode(MODE_PIN, INPUT);
pinMode(SENS_PIN, INPUT);
}

void before()
{
NRF_POWER->DCDCEN = 1;
NRF_UART0->ENABLE = 0;
sleep(1000);
digitalWrite(BLUE_LED, LOW);
sleep(150);
digitalWrite(BLUE_LED, HIGH);
}

void presentation() {
sendSketchInfo("EFEKTA Sens 1CH Sensor", "1.1");
present(SENS_CHILD_ID, S_CUSTOM, "SWITCH STATUS");
//present(CHILD_ID_VOLT, S_MULTIMETER, "Battery");
}

void setup() {
digitalWrite(BLUE_LED, LOW);
sleep(100);
digitalWrite(BLUE_LED, HIGH);
sleep(200);
digitalWrite(BLUE_LED, LOW);
sleep(100);
digitalWrite(BLUE_LED, HIGH);
lpComp();
detection = false;
SLEEP_TIME_W = SLEEP_TIME;
pinMode(31, OUTPUT);
digitalWrite(31, HIGH);
/*
while (timer < 10) {
timer++;
digitalWrite(GREEN_LED, LOW);
wait(5);
digitalWrite(GREEN_LED, HIGH);
wait(500);
}
timer = 0;
*/
sleep(7000);
while (timer < 3) {
timer++;
digitalWrite(GREEN_LED, LOW);
sleep(15);
digitalWrite(GREEN_LED, HIGH);
sleep(85);
}
timer = 0;
sleep(1000);
}

void loop() {

if (detection) {
if (digitalRead(MODE_PIN) == 1 && button_flag == 0 && digitalRead(SENS_PIN) == 0) {
//back side button detection
button_flag = 1;
nosleep = 1;
}
if (digitalRead(MODE_PIN) == 1 && button_flag == 1 && digitalRead(SENS_PIN) == 0) {
digitalWrite(RED_LED, LOW);
wait(10);
digitalWrite(RED_LED, HIGH);
wait(50);
}
if (digitalRead(MODE_PIN) == 0 && button_flag == 1 && digitalRead(SENS_PIN) == 0) {
nosleep = 0;
button_flag = 0;
digitalWrite(RED_LED, HIGH);
lpComp_reset();
}

if (digitalRead(SENS_PIN) == 1 && sens_flag == 0 && digitalRead(MODE_PIN) == 0) {
//sens detection
sens_flag = 1;
nosleep = 1;
newmillis = millis();
interrupt_time = newmillis - oldmillis;
SLEEP_TIME_W = SLEEP_TIME_W - interrupt_time;
if (send(sensMsg.set(detection))) {
send_flag = 1;
}
}
if (digitalRead(SENS_PIN) == 1 && sens_flag == 1 && digitalRead(MODE_PIN) == 0) {
if (send_flag == 1) {
while (timer < 10) {
timer++;
digitalWrite(GREEN_LED, LOW);
wait(20);
digitalWrite(GREEN_LED, HIGH);
wait(30);
}
timer = 0;
} else {
while (timer < 10) {
timer++;
digitalWrite(RED_LED, LOW);
wait(20);
digitalWrite(RED_LED, HIGH);
wait(30);
}
timer = 0;
}
}
if (digitalRead(SENS_PIN) == 0 && sens_flag == 1 && digitalRead(MODE_PIN) == 0) {
sens_flag = 0;
nosleep = 0;
send_flag = 0;
digitalWrite(GREEN_LED, HIGH);
sleep(500);
lpComp_reset();
}
if (SLEEP_TIME_W < 60000) {
SLEEP_TIME_W = SLEEP_TIME;
sendBatteryStatus();
}
}
else {
//if (detection == -1) {
SLEEP_TIME_W = SLEEP_TIME;
sendBatteryStatus();
}
if (nosleep == 0) {
oldmillis = millis();
sleep(SLEEP_TIME_W);
}
}

void sendBatteryStatus() {
wait(20);
batteryVoltage = hwCPUVoltage();
wait(2);

if (batteryVoltage > battery_vcc_max) {
currentBatteryPercent = 100;
}
else if (batteryVoltage < battery_vcc_min) {
currentBatteryPercent = 0;
} else {
currentBatteryPercent = (100 * (batteryVoltage - battery_vcc_min)) / (battery_vcc_max - battery_vcc_min);
}

sendBatteryLevel(currentBatteryPercent, 1);
wait(2000, C_INTERNAL, I_BATTERY_LEVEL);
//send(powerMsg.set(batteryVoltage), 1);
//wait(2000, 1, V_VAR1);
}

void lpComp() {
NRF_LPCOMP->PSEL = IRT_PIN;
NRF_LPCOMP->ANADETECT = 1;
NRF_LPCOMP->INTENSET = B0100;
NRF_LPCOMP->ENABLE = 1;
NRF_LPCOMP->TASKS_START = 1;
NVIC_SetPriority(LPCOMP_IRQn, 15);
NVIC_ClearPendingIRQ(LPCOMP_IRQn);
NVIC_EnableIRQ(LPCOMP_IRQn);
}

void s_lpComp() {
if ((NRF_LPCOMP->ENABLE) && (NRF_LPCOMP->EVENTS_READY)) {
NRF_LPCOMP->INTENCLR = B0100;
}
}

void r_lpComp() {
NRF_LPCOMP->INTENSET = B0100;
}

#if __CORTEX_M == 0x04
#define NRF5_RESET_EVENT(event)
event = 0;
(void)event
#else
#define NRF5_RESET_EVENT(event) event = 0
#endif

extern "C" {
void LPCOMP_IRQHandler(void) {
detection = true;
NRF5_RESET_EVENT(NRF_LPCOMP->EVENTS_UP);
NRF_LPCOMP->EVENTS_UP = 0;
MY_HW_RTC->CC[0] = (MY_HW_RTC->COUNTER + 2);
}
}

void lpComp_reset () {
s_lpComp();
detection = false;
NRF_LPCOMP->EVENTS_UP = 0;
r_lpComp();
}

MiTableroNRF5.cpp
#ifdef MYBOARDNRF5
#include <variant.h>

/*
* Pins descriptions. Attributes are ignored by arduino-nrf5 variant.
* Definition taken from Arduino Primo Core with ordered ports
*/
const PinDescription g_APinDescription[]=
{
{ NOT_A_PORT, 0, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER}, // LFCLK
{ NOT_A_PORT, 1, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER}, // LFCLK
{ PORT0, 2, PIO_DIGITAL, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), ADC_A0, PWM4, NOT_ON_TIMER},
{ PORT0, 3, PIO_DIGITAL, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), ADC_A1, PWM5, NOT_ON_TIMER},
{ PORT0, 4, PIO_DIGITAL, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), ADC_A2, PWM6, NOT_ON_TIMER},
{ PORT0, 5, PIO_DIGITAL, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), ADC_A3, PWM7, NOT_ON_TIMER},
{ PORT0, 6, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER}, // INT3
{ PORT0, 7, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER}, // INT4
{ PORT0, 8, PIO_DIGITAL, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM10, NOT_ON_TIMER}, //USER_LED
{ PORT0, 9, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER}, // NFC1
{ PORT0, 10, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER}, // NFC2
{ PORT0, 11, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER}, // TX
{ PORT0, 12, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER}, // RX
{ PORT0, 13, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER}, // SDA
{ PORT0, 14, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER}, // SCL
{ PORT0, 15, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER}, // SDA1
{ PORT0, 16, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER}, // SCL1
{ PORT0, 17, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER}, // TP4
{ PORT0, 18, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER}, // TP5
{ PORT0, 19, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER}, // INT2
{ PORT0, 20, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER}, // INT1
{ PORT0, 21, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER}, // INT1
{ PORT0, 22, PIO_DIGITAL, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM9, NOT_ON_TIMER},
{ PORT0, 23, PIO_DIGITAL, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM8, NOT_ON_TIMER},
{ PORT0, 24, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER}, // INT
{ PORT0, 25, PIO_DIGITAL, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM11, NOT_ON_TIMER}, //RED_LED
{ PORT0, 26, PIO_DIGITAL, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM11, NOT_ON_TIMER}, //GREEN_LED
{ PORT0, 27, PIO_DIGITAL, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM11, NOT_ON_TIMER}, //BLUE_LED
{ PORT0, 28, PIO_DIGITAL, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), ADC_A4, PWM3, NOT_ON_TIMER},
{ PORT0, 29, PIO_DIGITAL, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), ADC_A5, PWM2, NOT_ON_TIMER},
{ PORT0, 30, PIO_DIGITAL, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), ADC_A6, PWM1, NOT_ON_TIMER},
{ PORT0, 31, PIO_DIGITAL, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), ADC_A7, PWM0, NOT_ON_TIMER}
};

// Don't remove this line
#include <compat_pin_mapping.h>

#endif

MiTableroNRF5.h
#ifndef _MYBOARDNRF5_H_
#define _MYBOARDNRF5_H_

#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus

// Number of pins defined in PinDescription array
#define PINS_COUNT (32u)
#define NUM_DIGITAL_PINS (32u)
#define NUM_ANALOG_INPUTS (8u)
#define NUM_ANALOG_OUTPUTS (8u)

/*
* LEDs
*
* This is optional
*
* With My Sensors, you can use
* hwPinMode() instead of pinMode()
* hwPinMode() allows to use advanced modes like OUTPUT_H0H1 to drive LEDs.
* https://github.com/mysensors/MySensors/blob/development/drivers/NRF5/nrf5_wiring_constants.h
*
*/
#define PIN_LED1 (16)
#define PIN_LED2 (15)
#define PIN_LED3 (17)
#define RED_LED (PIN_LED1)
#define GREEN_LED (PIN_LED2)
#define BLUE_LED (PIN_LED3)
#define INTERRUPT_PIN (5)
#define MODE_PIN (25)
#define SENS_PIN (27)

/*
* Analog ports
*
* If you change g_APinDescription, replace PIN_AIN0 with
* port numbers mapped by the g_APinDescription Array.
* You can add PIN_AIN0 to the g_APinDescription Array if
* you want provide analog ports MCU independed, you can add
* PIN_AIN0..PIN_AIN7 to your custom g_APinDescription Array
* defined in MyBoardNRF5.cpp
*/
static const uint8_t A0 = ADC_A0;
static const uint8_t A1 = ADC_A1;
static const uint8_t A2 = ADC_A2;
static const uint8_t A3 = ADC_A3;
static const uint8_t A4 = ADC_A4;
static const uint8_t A5 = ADC_A5;
static const uint8_t A6 = ADC_A6;
static const uint8_t A7 = ADC_A7;

/*
* Serial interfaces
*
* RX and TX are required.
* If you have no serial port, use unused pins
* CTS and RTS are optional.
*/
#define PIN_SERIAL_RX (11)
#define PIN_SERIAL_TX (12)

#ifdef __cplusplus
}
#endif

#endif

El interruptor tiene un botón táctil y un botón táctil en la parte posterior del dispositivo. Este botón táctil se utilizará para los modos de servicio, el modo de enlace inalámbrico y el reinicio del dispositivo. El botón tiene una función anti-rebote de hierro. La línea del sensor capacitivo y la línea del botón táctil están conectadas a través de diodos Schottky y conectadas al pin analógico p0.05, y también desde el sensor capacitivo y el botón táctil hay líneas a los pines MK p0.25 y p0.27. .0.05 para leer estados después de activar la interrupción en el pin p0.05. En el pin pXNUMX se activa una interrupción a través del comparador (NRF_LPCOMP) a través de EVENTS_UP. Recibí inspiración para resolver el problema. aquí и aquí.

El conmutador se añadió a la red Mysensors, gestionado por el controlador doméstico inteligente Majordomo (sitio del proyecto)

Código PHP para agregar un interruptor al método statusUpdate

if (getGlobal("MysensorsButton01.status")==1) {
if (getGlobal('MysensorsRelay04.status') == 0) {
setGlobal('MysensorsRelay04.status', '1');
} else if (getGlobal('MysensorsRelay04.status') == 1) {
setGlobal('MysensorsRelay04.status', '0');
} 
}

Mira el resultado en el vídeo.

Interruptor táctil inalámbrico con retroiluminación fluorescente adicional

Posteriormente se hizo una opción con un convertidor boost, pero esto no está relacionado con el funcionamiento del microcircuito capacitivo TTP223, hay más deseo de una iluminación buena y uniforme al presionar las teclas durante toda la duración de la batería.

mirarInterruptor táctil inalámbrico con retroiluminación fluorescente adicional

Interruptor táctil inalámbrico con retroiluminación fluorescente adicional

Proyecto Github - github.com/smartboxchannel/EFEKTA_WIRELESS_TOUCH_SWITCH

Habla rusa sitio comunitario missensores

Chat de Telegram Missensores — solución rápida a problemas con Mysensors, consejos, trucos, instalación de placas, trabajo con microcontroladores atmega 328, stm32, nRF5 en el IDE de Arduino — @missensores_rus

Pocas fotosInterruptor táctil inalámbrico con retroiluminación fluorescente adicional

Interruptor táctil inalámbrico con retroiluminación fluorescente adicional

Interruptor táctil inalámbrico con retroiluminación fluorescente adicional

Interruptor táctil inalámbrico con retroiluminación fluorescente adicional

Interruptor táctil inalámbrico con retroiluminación fluorescente adicional

Fuente: habr.com

Añadir un comentario