COOLRFの無線モジュールnrf24le1で調光器をプログラミングする

無線モジュールnrf24le1のプログラミングのトピックを継続します-今回はCOOLRF調光器の動作を教えます。 無線モジュールのプログラミングに関する記事公開した後、ファームウェアの開発に参加するよう申し出られ、この調光器を実験用に提供しました。

その結果、中央モジュールArduino + Ethernet-nRF24L01(W5100)またはUSBaspからnRF24L01 + USBを介して調光器を制御し、ローカルボタンを使用するオプションがありました。



調光アルゴリズム



ゼロクロッシング信号はタイマーを起動します。タイマーの時間は、設定電力レベル0..100%に依存します。これは0.01 .... 0秒に対応します。 タイマーはトライアックをオンにします。

さらに、約10ミリ秒後(私が正しく理解できた場合)、トライアックイネーブル信号は削除されますが、ゼロを通過するまでトライアックは開いたままになります。 次に、サイクルが繰り返されます。

おそらく、habrの読者は、トライアックの制御のより正確なオプションも提供します...



ファームウェアコード



現時点では、ファームウェアは次のことができます。



電力制御間隔を報告するには、タイマー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 } }
      
      









調光器ビデオデモ



私たちは何を持っています:







すべてを順番にペイントしてみます。

まず、ビデオはボタンを介して電球を制御する方法を示しています。

短く押すと電球がオンまたはオフになり、長く押すと明るさが変わります。電球がオフになっている場合は電球がオンになり、明るさが変わります。 ボタンを放すたびに、明るさの方向が変わります。

次に、電球をコンピューター(より正確にはラップトップ)から制御する方法を確認します。 このテストでは、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をプログラムします



All Articles