追加の蛍光灯付きワイヤレスタッチスイッチ

Habr の「DIY or Do It Yourself」セクションをご覧の皆様、こんにちは。 今日の記事は、TTP223 チップのタッチ スイッチについて説明します。 データシート。 スイッチは nRF52832 マイクロコントローラーで動作します。 データシートでは、プリント アンテナと外部 MHF17103 アンテナ用コネクタを備えた YJ-4 モジュールが使用されました。 タッチ スイッチは CR2430 または CR2450 電池で動作します。 送信モードの消費電力は 8 mA 以下、スリープ モードの消費電力は 6 µA 以下です。
追加の蛍光灯付きワイヤレスタッチスイッチ

これまでのすべてのプロジェクトと同様、これも Arduino プロジェクトであり、プログラムは Arduino IDE で書かれています。 デバイスのソフトウェア実装は、Mysensors プロトコルに基づいています。 GitHub ライブラリ, nRF5 ボードのサポート GitHub マイセンサーで。 英語コミュニティフォーラム - http://forum.mysensors.org、ロシア語コミュニティフォーラム - http://mysensors.ru/forum/
(勉強したい方へ) Документация, シリアルプロトコル, API, プロトコル, パーサー | お手伝いをしたい方へ(貢献) プロジェクトの開発中 - Документация)

タッチ スイッチ ボードは、レーザー アイロン テクノロジー (LUT) 方式を使用したその後の製造を考慮して、Deeptrace プログラムで開発されました。 このボードは 60x60mm の寸法で開発されました (標準のガラスパネルの寸法は 80x80mm)。 回路は Antenna マガジンのページに印刷され、「Len」設定 (最大出力) でボッシュ アイロンを使用して 1.5 mm、35 μm の両面フォイル グラスファイバー基板 (別のものがない場合) に転写されました。
追加の蛍光灯付きワイヤレスタッチスイッチ

エッチングは、温水250ml当たり小さじ1.5杯の割合で予め調製した塩化第二鉄溶液を用いて実施した。 このプロセスには 1.5 分かかりました。
層間ビア用の穴を開け、バッテリー ホルダーを固定するための穴は、DREMEL 3000 ドリル スタンドに取り付けられた DREMEL 220 ミニ ドリルで実行されました。層間ビア用の穴は 0,4 mm ドリルで開けられ、バッテリー ホルダー用の穴は 1,1 mm ドリルで開けられました。 。 ボードの境界に沿ったトリミングは、DREMEL 540 アタッチメントを備えた同じミニドリルを使用して実行されました (切断円 d=32.0mm)。 剪定は人工呼吸器を使用して行われました。
エッチングされた基板の錫メッキは、水溶液(水 1 ml あたり小さじ 300 杯の結晶化クエン酸)中でローズ合金を使用して行われました。

はんだ付けプロセスには約 0.4 時間かかり、ほとんどの時間は層間ビア用の穴にワイヤ (錫メッキ、直径 XNUMX mm) をはんだ付けするのに費やされました。

基板はFLUX OFFエアゾールクリーナーで洗浄しました。
追加の蛍光灯付きワイヤレスタッチスイッチ

追加の蛍光灯付きワイヤレスタッチスイッチ

デバイス本体の設計は、78,5 次元コンピュータ支援設計エディターで実行されました。 ケース寸法 78,5mm X 12mm X XNUMXmm。
追加の蛍光灯付きワイヤレスタッチスイッチ

ケースとバッテリーコンパートメントカバーの完成したモデルは STL 形式で保存され、その後、SLA プリンターで印刷できるようにこれらのモデルを準備する必要がありました (サポートの追加、方向付け)。 家庭用SLAプリンタの印刷領域は小さいため、この段階で小さな問題が発生しました。 印刷時間に対して最適な位置にあるデバイスケースのモデルが印刷領域の寸法に適合しませんでした。 モデルを 45 度に配置した場合も、サポートの重量がボディ モデルの重量と同じになるという残念な結果が得られました。 後処理の事実に事前に同意した上で、モデルを垂直に印刷し、前面の一方にサポートを作成することが決定されました。 ボディの印刷には、5 ミクロンのレイヤー設定で 50 時間かかりました。 次に、非常に目の細かいサンドペーパーで加工を行いました(番号はわからないので書きません:))。 バッテリー カバーの印刷には 40 分かかりました。
追加の蛍光灯付きワイヤレスタッチスイッチ

Aliexpress のガラスパネルはプラスチックのフレームがすでに接着された状態で販売されており、フレームを取り外すのに問題はありませんでした。 通常のヘアドライヤーで予熱した後、ガラスパネルを取り外しました。
追加の蛍光灯付きワイヤレスタッチスイッチ

追加の蛍光灯付きワイヤレスタッチスイッチ

LED バックライトのディフューザーは、アクリル系粘着剤 3M 9088-200 を使用した両面テープで作成しました。 蛍光灯の場合は、中国の粘着テープと国内企業ルミノフォーの粘着紙をテープ状にカットしたものから選択できるいくつかの材料がありました。 国内メーカーを選んだのですが、私の感覚によれば、より明るく長く輝いてくれました。 蛍光顔料を塗布した正方形の紙を 3M 9088-200 両面テープで上に貼り付けました。

ガラスは、3M VHB 4910 アクリル接着剤を使用した両面テープを使用してスイッチ本体に接着されました。
追加の蛍光灯付きワイヤレスタッチスイッチ

カバーはネジM1,4×5mmで固定しました。

装置の価格は890ルーブルでした。

続いてプログラム部分です。 いくつかの問題がありました。 TTP223 センサー チップは、安定した 3.3 V 電源ではうまく機能しますが、十分に放電したバッテリーから直接電力を供給するとあまりうまく機能しないことがわかりました。 約 2.5V の電源でデバイスを起動したとき、さらに Mysensors プレゼンテーションを実行するときに追加の「ドローダウン」が発生した後、TTP223 マイクロ回路 (キャリブレーション直後) がアクティブなトリガーを備えていたため、MK の中断を引き起こしました。

マイクロ回路への電源回路が変更され (gpio MK を備えた電源管理 TTP223)、追加のアースが供給され、rgb LED ライン (静電容量センサー ボードの反対側を走る) 上の抵抗器がより高い抵抗に置き換えられました。 これもソフトウェアに追加されました。Mysensors フレームワークを開始してプレゼンテーションを作成した後、容量性マイクロ回路の電源をアクティブ化します。 電源投入時の TTP223 チップの自動キャリブレーションの遅延が XNUMX 倍になりました。 これらすべての変更により、この問題は完全に解消されました。

プログラム コードを表示する前に、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()
{

}

タッチスイッチプログラムのテストコード: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();
}

MyBoardNRF5.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

マイボードNRF5.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

スイッチには、デバイスの背面にタッチ ボタンとタクト ボタンがあります。 このタクト ボタンは、サービス モード、無線バインディング モード、およびデバイスのリセットに使用されます。 ボタンにはアイロン跳ね返り防止機能が付いています。 静電容量センサーのラインとタクトボタンのラインはショットキーダイオードを介してアナログピンp0.05に接続されており、静電容量センサーとタクトボタンからMKピンp0.25とp0.27へのラインもあります。ピン p0.05 で割り込みをアクティブにした後の状態の読み取り用の .0.05。XNUMX。 ピン pXNUMX では、EVENTS_UP を介したコンパレータ (NRF_LPCOMP) による割り込みがアクティブになります。 問題を解決するためのインスピレーションを受け取りました ここで и ここで.

スイッチは、スマート ホーム コントローラー Majordomo によって管理される Mysensors ネットワークに追加されました (プロジェクトのウェブサイト)

statusUpdate メソッドにスイッチを追加するための PHP コード

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

結果はビデオでご覧ください

追加の蛍光灯付きワイヤレスタッチスイッチ

その後、昇圧コンバーターを備えたオプションが作成されましたが、これは TTP223 容量性マイクロ回路の動作とは関係なく、バッテリー寿命全体にわたってキーを押したときに良好で均一な照明が求められていました。

見て追加の蛍光灯付きワイヤレスタッチスイッチ

追加の蛍光灯付きワイヤレスタッチスイッチ

プロジェクトの Github - github.com/smartboxchannel/EFEKTA_WIRELESS_TOUCH_SWITCH

ロシア語を話す コミュニティサイト マイセンサー

電報チャット マイセンサー — Mysensors、ヒント、トリック、ボードのインストール、Arduino IDE での atmega 328、stm32、nRF5 マイクロコントローラーの操作に関する問題の迅速な解決策 — @mysensors_rus

写真が少ない追加の蛍光灯付きワイヤレスタッチスイッチ

追加の蛍光灯付きワイヤレスタッチスイッチ

追加の蛍光灯付きワイヤレスタッチスイッチ

追加の蛍光灯付きワイヤレスタッチスイッチ

追加の蛍光灯付きワイヤレスタッチスイッチ

出所: habr.com

コメントを追加します