その結果、中央モジュールArduino + Ethernet-nRF24L01(W5100)またはUSBaspからnRF24L01 + USBを介して調光器を制御し、ローカルボタンを使用するオプションがありました。
調光アルゴリズム
ゼロクロッシング信号はタイマーを起動します。タイマーの時間は、設定電力レベル0..100%に依存します。これは0.01 .... 0秒に対応します。 タイマーはトライアックをオンにします。
さらに、約10ミリ秒後(私が正しく理解できた場合)、トライアックイネーブル信号は削除されますが、ゼロを通過するまでトライアックは開いたままになります。 次に、サイクルが繰り返されます。
おそらく、habrの読者は、トライアックの制御のより正確なオプションも提供します...
ファームウェアコード
現時点では、ファームウェアは次のことができます。
- スイッチ上のボタンによるオン/オフ制御。
- 長い(1.5秒以上)ボタンを押すと明るさを制御できます。
- 設定された輝度の状態とレベルのリモート制御。
- リモートコントロールのオン/オフと明るさ。
電力制御間隔を報告するには、タイマー1を使用します。
バウンスやその他の一時停止を抑制する間隔を設定するには、32768 Hz内部発振器のRTCタイマーが使用されます。
ファームウェアをコンパイルするにはSDKが必要です。
主な調光器コードはこちら
// 23.07.14 #define chclient 1 // 1... #define nofloat 0 // float , 10. . #define RTCDEC 8191 //65535=2 , 32767=1 ,16383 = 0.250 ,8191 = 0.125 . : #define TIMESEND 2 // / . #define TIMEKEY 4 // . (0.125*4=0.5) #define TIMELONGKEY 3 // , TIMEKEY*TIMELONGKEY*0.125=. 3*4*0.125=1.5 #define BUTTONPIN 4 // , . #define DIMMPIN GPIO_PIN_ID_P0_2 // , . #define stepdimm 10 // #define MAXSTEP 100 // #include "../libs.h" #include "../nRFLE.c" typedef struct{ unsigned char identifier;// . int countPWM; unsigned char keymode; int Error_Message; // long count;// #if nofloat int temperature_Sensor; int Humidity_Sensor; #else float temperature_Sensor; float Humidity_Sensor; #endif } nf1; nf1 clientnf; #define DIMSTART 16000000/12/100/MAXSTEP uint16_t valuepwm=0; // void setdimmer(uint8_t value){ // valuepwm=65535-DIMSTART*(MAXSTEP-value); if(value ==0 | clientnf.keymode==0) { interrupt_control_ifp_disable(); gpio_pin_val_clear(DIMMPIN); } else interrupt_control_ifp_enable(); } uint8_t stdimm; interrupt_isr_ifp() // { timer1_stop(); if(clientnf.countPWM !=0) { timer1_set_t1_val(valuepwm); timer1_run(); } else gpio_pin_val_clear(DIMMPIN); stdimm=1; } interrupt_isr_t1() { // if (stdimm) { gpio_pin_val_set(DIMMPIN); timer1_set_t1_val(65535-100); stdimm=0; } else gpio_pin_val_clear(DIMMPIN); } void dimmon(uint8_t mode) // / { if (mode) interrupt_control_ifp_enable(); else { interrupt_control_ifp_disable(); timer1_stop(); gpio_pin_val_clear(DIMMPIN); } clientnf.keymode=mode; } unsigned long countrtc=0; // rtc unsigned char servernf[32]; interrupt_isr_rtc2() // . { countrtc++; } //====================main======================== void main() { int state=0; unsigned int count=0; //counter for loop uint8_t st=0,countpause=0,rewers=0; // for key unsigned long statesend=0,radiosend=0; // RTC--> CLKLFCTRL=1; // 0 - P0.1 P0.0. 1 - . rtc2_configure(RTC2_CONFIG_OPTION_COMPARE_MODE_0_RESET_AT_IRQ ,RTCDEC); rtc2_run(); pwr_clk_mgmt_wakeup_configure(PWR_CLK_MGMT_WAKEUP_CONFIG_OPTION_WAKEUP_ON_RTC2_TICK_IF_INT_ENABLED,0); interrupt_control_rtc2_enable(); // <-- RTC interrupt_configure_ifp(INTERRUPT_IFP_INPUT_GPINT0,INTERRUPT_IFP_CONFIG_OPTION_ENABLE | INTERRUPT_IFP_CONFIG_OPTION_TYPE_FALLING_EDGE); interrupt_control_ifp_enable(); interrupt_control_t1_enable() ; timer1_configure(TIMER1_CONFIG_OPTION_MODE_1_16_BIT_CTR_TMR,0); timer1_run(); sti(); gpio_pin_configure(BUTTONPIN,GPIO_PIN_CONFIG_OPTION_DIR_INPUT|GPIO_PIN_CONFIG_OPTION_PIN_MODE_INPUT_BUFFER_ON_PULL_UP_RESISTOR); // . gpio_pin_configure(DIMMPIN,GPIO_PIN_CONFIG_OPTION_DIR_OUTPUT); // --> #if 1 gpio_pin_val_set(DIMMPIN); delay_ms(500); gpio_pin_val_clear(DIMMPIN); delay_ms(500); #endif //<-- radiobegin(); // openAllPipe(); // /, . setChannel(100); setDataRate(2); // 1 - 250 , 2 - 1 , 3 -2 . setAutoAck(false); setCRCLength(2); // 0 - crc off ,1 - 8bit ,2 - 16bit setPALevel(3) ; // 0..3 clientnf.identifier=chclient; clientnf.countPWM=30; //main program loop while(1) { // --- if (countrtc-radiosend >=TIMESEND) { //rf_power_up(1); rf_write_tx_payload((const uint8_t*)&clientnf, 32, true); //transmit received char over RF //wait until the packet has been sent or the maximum number of retries has been reached while(!(rf_irq_pin_active() && rf_irq_tx_ds_active())); rf_irq_clear_all(); //clear all interrupts in the 24L01 rf_set_as_rx(true); //change the device to an RX to get the character back from the other 24L01 //wait a while to see if we get the data back (change the loop maximum and the lower if // argument (should be loop maximum - 1) to lengthen or shorten this time frame for(count = 0; count < 25000; count++) { if((rf_irq_pin_active() && rf_irq_rx_dr_active())) { state=1; if (clientnf.count <= 2147483646) clientnf.count++; /// else clientnf.count = 0; rf_read_rx_payload((const uint8_t*)&servernf, 32); //get the payload into data break; } //if loop is on its last iteration, assume packet has been lost. if(count == 24999) clientnf.Error_Message++; } rf_irq_clear_all(); //clear interrupts again rf_set_as_tx(); //resume normal operation as a TX if (servernf[0]==chclient){ if (servernf[1]==10) { // / dimmon(servernf[3]); } else if (servernf[1]==11) { // clientnf.countPWM=servernf[3]; setdimmer(clientnf.countPWM); } } radiosend=countrtc; } #if 1 #define dimm clientnf.countPWM #define keymode clientnf.keymode if (digitalRead(BUTTONPIN)==0){ // if (countrtc-statesend>=TIMEKEY) { if (st){ st=0; keymode=!keymode; dimmon (keymode); } else if (countpause>=TIMELONGKEY){ if (!keymode) dimmon(1); // , else { if(rewers) { if(dimm-stepdimm>=0) dimm=dimm-stepdimm; else rewers=0; }else{ if(dimm+stepdimm<=MAXSTEP) dimm=dimm+stepdimm; else rewers=1; } setdimmer(dimm); } } else countpause++; statesend=countrtc; } } else {// if (!st){ st=1; countpause=0; rewers=!rewers; // } } #endif // end loop } }
調光器ビデオデモ
私たちは何を持っています:
- COOLRF調光器。
- nrf24le1無線モジュールの形式が間違っているため、元の設置場所に収まりません。これが配線に表示される理由です。
- プルアップ抵抗器付きのボタンが接続されている取り付けプレート。
- 60W電球
すべてを順番にペイントしてみます。
まず、ビデオはボタンを介して電球を制御する方法を示しています。
短く押すと電球がオンまたはオフになり、長く押すと明るさが変わります。電球がオフになっている場合は電球がオンになり、明るさが変わります。 ボタンを放すたびに、明るさの方向が変わります。
次に、電球をコンピューター(より正確にはラップトップ)から制御する方法を確認します。 このテストでは、Arduino + Ethernet-nRF24L01を使用して調光器をリモート制御します。
26秒で、arduinoのWEBページが表示され、ワイヤレスデバイスのステータスが表示されます。
1行目は調光器で、Analog変数は現在インストールされている電力を示し、test_data変数は点灯または消灯の状態を示します。
2行目はワイヤレスセンサーであり、テストのためにここに追加されました。
調光器コントロールは、自家製のWebページ(ラップトップのWebサーバー)に表示されます。このページには、所定の明るさ10.20.50および100%のボタン、オン/オフボタン、および無線デバイスに手動でデータを送信するフィールドがあります。
このテストページはPHPで記述されており、GETリクエストをarduinki Webサーバーに送信します。 同様に、nRF24L01 + USBを介して制御できます。
私が理解しているように、COOLRFは工場で別のバージョンの調光器を設計し、デバイスダイアグラムを変更する予定ですが、ファームウェアのこの例は、おそらく小さな変更を加えても動作します。
コメントに批判や提案を受け入れます。 ありがとう
nrf24le1の以前の記事:
無線モジュールNRF24LE1をプログラムします。 レディワイヤレスクライアント
Raspberry PIおよびUSBaspを介してnRF24LE1をプログラムします