📜 ⬆️ ⬇️

Dimmer programming on the radio module nrf24le1 from COOLRF

We continue the topic of programming the nrf24le1 radio modules - this time we will teach the COOLRF dimmer to work. After I published an article about programming radio modules, I was offered to participate in the development of the firmware and provided this dimmer for experiments.
The result was a dimmer control option through the central module Arduino + Ethernet-nRF24L01 (W5100) or nRF24L01 + USB from USBasp as well as using a local button.

Dimming algorithm


The zero crossing signal activates a timer, the time of which depends on the set power level of 0..100%, which corresponds to 0.01 .... 0 seconds. The timer includes a triac.
Further, after about 10 milliseconds (if I correctly figured it out), the trigger signal of the triac is removed, but the triac remains open until there is no crossing over zero. Then the cycle repeats.
Perhaps the readers of Habr will offer a more correct way to control the triac ...

Firmware code


Currently, the firmware can:

For the report of power control intervals, timer No. 1 is used.
To set the intervals for suppressing bounce and other pauses, the RTC timer on the internal generator 32768 Hz is used.

An SDK is required to compile the firmware.
')
The main dimmer code is here.
//  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 } } 



Video demonstration of the dimmer


What we have:



I will try to paint everything in order:
First, the video demonstrates the control of a light bulb through a button:
A short press turns the light off or on, a long press changes the brightness, if the light has been turned off, it turns on and the brightness changes. Each time you release the button, the direction of the brightness changes.
Further, we see how a light bulb can be controlled from a computer (more precisely, a laptop). The test uses Arduino + Ethernet-nRF24L01 for remote control of the dimmer.
At 26 seconds, you can see the arduinka WEB page, which shows the status of wireless devices:
1 line is just our dimmer, where the variable Analog shows the current installed power, and the variable test_data shows the status of the light on or off.
2 line - this is a wireless sensor, which is added here just for the test.
Dimmer control is shown on a homemade web page (web server on a laptop), on which there are buttons of a given brightness of 10,20,50 and 100%, on / off buttons, as well as fields for manually sending data to wireless devices.
This test page is written in PHP and it sends GET requests to the Arduinka web server. Similarly, you can manage and through nRF24L01 + USB.

As I understand it, COOLRF plans to design another version of the dimmer in the factory case and change the device layout, but this example of firmware, perhaps with minor changes, will also work on it.

I accept criticism and suggestions in the comments. Thank.

Previous articles on nrf24le1:
We program the radio module NRF24LE1. Ready wireless client
We program nRF24LE1 through Raspberry PI and USBasp

Source: https://habr.com/ru/post/230785/


All Articles