![画像](https://habrastorage.org/webt/nf/ev/13/nfev13d1ijvairxa-ebeg7ng7am.jpeg)
子供の誕生とともに、夜間照明についての質問が生じました。 どこかで彼らはそれが静かな睡眠に必要であると読んだ。 薄明かりですぐに眠るのに使用されます。 真夜中に悲鳴とハウリングから目を覚まし、赤ちゃんが不平を言っているのを見るのは非常に便利です(理解できる場合)。 また、薄明かりの中で、揺れたり、寝返りをつけたり、眠り続けることができます。
最初に、照明器具のテストサンプルは、1.5年間使用されていた黄色のLEDストリップ(12ボルト)から作成されました。
![画像](https://habrastorage.org/webt/an/hw/kd/anhwkdovnnwhdziqqhhbcxr0hbc.jpeg)
薄っぺらなデザインに加えて、ランプの電源ユニットをコンセントから取り外すことを毎朝悩まし始めました。 朝起きて、通りから部屋に十分な光が入ります。 したがって、ランプは毎日数時間無駄になります。 再び、半年で、中国のRGBテープコントローラーは現在の設定を忘れてしまい、操作パネルを探して作業方法を思い出させる必要がありました。 ポテンショメータとラジオの両方を使用して色を調整して、自動シャットダウンを備えた新しいランプを作ることにしました。
arduino nanoに基づくプロトタイプをすばやく組み立てました。 基本機能をデバッグします。
![画像](https://habrastorage.org/webt/fb/jy/xu/fbjyxu7k6vr2uk2wa66e2oc58yy.jpeg)
この機会にフリッツを試してみました。 気に入らなかったが、写真は鮮明で「面白い」。 どうやら新しいものは発明されていないようです。
![画像](https://habrastorage.org/webt/el/8v/pr/el8vprz7g0kiuxlvu61ac184t7a.jpeg)
「nano」を、無線トランシーバを内蔵したあまり知られていないarduino互換モジュールに置き換えました(8ビットコントローラー、パフォーマンス、およびスタッフィングは「Nana」に匹敵します)。 自宅では、868 MHzの周波数で動作する1つのデバイスが既にあり、これが2番目のデバイスになります。 製造元のWebサイトからの簡単な仕様:
簡単な特徴
![画像](https://habrastorage.org/webt/jq/6n/c-/jq6nc-tmx6s5s1xlln6t9bm1m8u.png)
![画像](https://habrastorage.org/webt/gu/1d/rl/gu1drlc_2banpoqihqjrlsiawms.jpeg)
ESP8266でも同じことをするのに大きな問題は見られません(LUAのスクリプト用の便利なオンラインファームウェアコレクターがあります)。 Bluetoothではもう少し複雑です(HM-10モジュールをフラッシュするには、安価なプログラマ、開発環境、プロトコルの理解が必要です)。 ただし、arduinoでBluetoothモジュールを使用できます。 しかし、ZUNoを使用したのは、嘘をつき、長い間待っていて、インフラストラクチャ全体が同様のデバイスを1つのネットワークに接続して管理する準備ができているためです(スマートホームネットワークコントローラーについて話している)。
arduinoで使用されるすべての脚について、モジュール内に類似物が見つかりました。
![画像](https://habrastorage.org/webt/yl/e1/nw/yle1nwmi36wleu53yyx6lunkr0y.png)
Arduino IDEからモジュールを使用するには、モジュールを構成する必要があります(設定の説明は製造元のWebサイトにあります)。 奇跡は起こりませんでした。 コンパイルしようとすると、「空の列または本文のないステートメント」の「サポートしない」というエラーが表示されました。 Adafruit_NeoPixelライブラリを使用しました。 私はそれに乗り込み、その中にいくつのサイクルがあるかを見て、閉じました。 再びメーカーのウェブサイトにアクセスして、LEDの使用例を探す必要がありました(例はすぐに見つかりました)。 だから、私は同様の問題に遭遇した最初の人ではありません。
このランプをArduinoコードで無線で制御するには、マクロを追加していくつかの機能を実装する必要があります。
ZUNO_SETUP_CHANNELS( ZUNO_SWITCH_MULTILEVEL(getRed, setRed), ZUNO_SWITCH_MULTILEVEL(getGreen, setGreen), ZUNO_SWITCH_MULTILEVEL(getBlue, setBlue), ZUNO_SWITCH_BINARY(switch_getter, switch_setter) );
このマクロは、3つのマルチレベルスイッチ(RGBコントロール)と1つのシンプルなスイッチ(シンプルなオン/オフ)を備えたZ-Waveデバイスを記述します。
機能の最も簡単な実装があります(メーカーのWebサイトの例のように)。 添付のリストで確認できます。
ケース選択
すでにケースがありました。 透明なカバーで密封されています 。 カバーの下には25個のLEDがあります。 テストは成功しました。 ランプは私の部屋に大きな明るさのマージンを持っています。 このケースのカバーは透明なので、光を少し拡散させることにしました。
![画像](https://habrastorage.org/webt/eb/dn/a2/ebdna25kb2xg3dedtuhpib2k8qe.jpeg)
透明なエポキシで満たされたスケッチ色のビーズとアクリルキューブ。 着色ビーズの塗料は、樹脂の影響で溶解しました。
![画像](https://habrastorage.org/webt/kq/gh/dn/kqghdnnc4qp4dcxa058oun_zwb4.jpeg)
最も興味深いのは、密閉されたハウジングのキャップが漏れ、ほとんどすべての樹脂が漏れたことです。 どこで蓋にぶつかったのかわかりませんが、乾燥後、亀裂がはっきりと見えます。
![画像](https://habrastorage.org/webt/1h/aa/aq/1haaaqrcyeoacbznogmwonzgb8g.jpeg)
プリント回路基板は、フォトレジスト法によって作成されました。
![画像](https://habrastorage.org/webt/me/3w/th/me3wthtnt9ybhvyzc3v_-nhvy0o.jpeg)
![画像](https://habrastorage.org/webt/oa/kh/vl/oakhvltkcldrtlncqd8kwkub_ms.jpeg)
酸洗および機械加工後
![画像](https://habrastorage.org/webt/yh/oy/zy/yhoyzyalmtvzihrg_adlie0l0k0.jpeg)
マイクロコントローラーを搭載したモジュールは、クローゼットの中にあるプロトタイプに置き換えられました(残念ではありませんが、ZUNoは保護する必要があるため)。 ZUNoの最初のバージョンですが、寸法はアンテナよりも大きくて悪く、既に購入することはできません。 テストは多かれ少なかれ成功しました。 最後のセグメントを再はんだ付けする必要がありました。 元々は間違った側にはんだ付けされていました。 ファームウェアのLEDの数を調整します。
![画像](https://habrastorage.org/webt/_j/wd/ys/_jwdyskx5_cwxqkea6xt7jbkjqk.jpeg)
![画像](https://habrastorage.org/webt/gx/qc/qa/gxqcqaaas0qbg7gy54ysyzofbnu.jpeg)
起こったことは次のとおりです。
![画像](https://habrastorage.org/webt/i7/fb/0u/i7fb0ul-f1kejvabyxrbhzmkcea.jpeg)
ラジコン
ランプ制御チャンネルのあるメインウィンドウ
![画像](https://habrastorage.org/webt/zj/r_/_0/zjr__02hc4it_fasqf-qkhi0gle.png)
LEDストリップの1つのチャンネルの明るさを調整します
![画像](https://habrastorage.org/webt/1b/80/ho/1b80hohb7oaxhwyyzga6k5osnw0.png)
常夜灯の朝のシャットダウンの設定
![画像](https://habrastorage.org/webt/yx/ar/ua/yxaruahy9rj26onaqu6tbo2uu5a.png)
おわりに
デバイスは動作しています。 コンパクトできれいです。 携帯電話を充電することで動作します。
気づいた問題から:
- アセンブリ中に、可変抵抗器のトラックの一部を切り離したため、手動モードでは1つのチャネルのみを制御できます。
- 25個のLEDのうち、正常に機能するのは20個だけです。これはたくさんあります。
夜の光のスケッチ
#include "ZUNO_NeoPixel.h" #define MAX_PIXELS 20 // NB! Z-Uno can not control more than 25 WS2811 without harming RF communications #define PIXEL_SIZE 3 // Three colors per pixel #define BUFF_SIZE (MAX_PIXELS * PIXEL_SIZE) byte pixel_buff[BUFF_SIZE]; NeoPixel pixels(pixel_buff, BUFF_SIZE); #define B_PRESSED 1 #define BUTTON_PIN 1 // Digital IO pin connected to the button. This will be #define DEF_RED 30 #define DEF_GREEN 20 byte red = DEF_RED; byte green = DEF_GREEN; byte blue = 0; #define POWER_ON 1 #define POWER_OFF 0 byte light_power = POWER_ON; byte last_light_power = POWER_OFF; ZUNO_SETUP_CHANNELS( ZUNO_SWITCH_MULTILEVEL(getRed, setRed), ZUNO_SWITCH_MULTILEVEL(getGreen, setGreen), ZUNO_SWITCH_MULTILEVEL(getBlue, setBlue), ZUNO_SWITCH_BINARY(switch_getter, switch_setter) ); void switch_setter(byte value) { Serial.println("switch"); Serial.print("value= "); Serial.println(value); if(value > 1) light_power = POWER_ON; else light_power = POWER_OFF; } byte switch_getter() { return light_power; } int getRed() { return red/2.56; } int getGreen() { return green/2.56; } int getBlue() { return blue/2.56; } void setRed(byte value) { red = value * 2,56; for(uint8_t i = 0; i < MAX_PIXELS; i++) pixels.setPixelColor(i, pixels.Color(red, green, blue)); pixels.show(); Serial.print("set red = "); Serial.println(value); } void setGreen(byte value) { green = value * 2,56; for(uint8_t i = 0; i < MAX_PIXELS; i++) pixels.setPixelColor(i, pixels.Color(red, green, blue)); pixels.show(); Serial.print("set red = "); Serial.println(value); } void setBlue(byte value) { blue = value * 2,56; for(uint8_t i = 0; i < MAX_PIXELS; i++) pixels.setPixelColor(i, pixels.Color(red, green, blue)); pixels.show(); Serial.print("set red = "); Serial.println(value); } void set_LEDS() { for(uint8_t i = 0; i < MAX_PIXELS; i++) pixels.setPixelColor(i, pixels.Color(red, green, blue)); pixels.show(); } void read_resistors() { red = (analogRead(A0) >> 2) & 0xff; green = (analogRead(A1) >> 2) & 0xff; blue = (analogRead(A3) >> 2) & 0xff; Serial.print(red); Serial.print(" "); Serial.print(green); Serial.print(" "); Serial.print(blue); Serial.print(" "); Serial.println(); set_LEDS(); } #define DEBOUNCE_ACK 10 byte check_button() { static bool oldState = HIGH; byte debounce_cnt = 0; static byte ret = 0; if(digitalRead(BUTTON_PIN) == LOW) { if(ret != B_PRESSED) while(digitalRead(BUTTON_PIN) == LOW) { if(debounce_cnt == DEBOUNCE_ACK) { ret = B_PRESSED; break; } else debounce_cnt++; delay(10); } } else { debounce_cnt = 0; ret = 0; } return ret; } void setup() { Serial.begin(9600); pixels.begin(); pixels.clear(); pinMode(BUTTON_PIN, INPUT_PULLUP); } void loop() { if(check_button() == B_PRESSED) read_resistors(); if(last_light_power != light_power) { Serial.println("set power"); if(light_power == POWER_OFF) { Serial.println("power off"); red = 0; green = 0; blue = 0; } else { Serial.println("power on"); red = DEF_RED; green = DEF_GREEN; blue = 0; } set_LEDS(); last_light_power = light_power; } }