In an era when energy efficiency and home customization are becoming increasingly important, traditional lighting management through infrared systems shows significant limitations, including the need for direct visibility and susceptibility to interference. This article addresses these challenges by introducing an innovative light intensity control system for medium-power LED lamps.

LED technology has a higher efficiency than any conventional lamp; therefore, we developed a design that allows the light intensity of diodes to be varied without affecting their efficiency and keeping into account the specifications that are reported by the manufacturer. This variation could also be controlled linearly with a potentiometer, but we preferred to opt for remote control (more practical and convenient). One chance was to use an IR remote control but — as mentioned in the teaser — it would work only under conditions where it was possible to have the IR beam in a direct line. With the above considerations in mind, we preferred to opt for LoRa (Long Range) technology for both transmission and reception, overcoming this limitation in that it can work in any environmental conditions (near, far and with architectural barriers).

It is a point-to-point wireless communication technology that uses the free band used in Europe at 868 MHz. There are a number of 868-MHz LoRa transceiver modules on the market that can do the trick but, due to issues of price, ease of control and small size, we opted for a breakout board called RFM95W (from now on, for convenience, we will call it LoRa module).

Once we had decided what to use to control the LED light source, it remained to address how to keep its characteristics intact, even having the need to vary the light intensity. In this regard, it was thought that the best technique was pulse-width modulation (PWM).

Subscribe
Tag alert: Subscribe to the tag LoRa and you will receive an e-mail as soon as a new item about it is published on our website!

RTX Block Diagram

Figure 1 shows the block diagram of both the TX and RX sections of the project. Using the transmitter as a remote control (thus portable), one necessarily had to power it with a battery (BT1); in our case, a chargeable Lithium cell (ICR14500) was chosen. Considering that the voltage delivered by a Lithium battery can range from 3 V (depleted) to 4.2 V (fully charged), to comply with the power supply characteristics of the LoRa module (U3), which range from a minimum of 1.8 V to a maximum of 3.7 V, we introduced a 3.3 V voltage regulator (U2), so to have a stable voltage that would allow us to control the power supply both when charging the battery and when powered directly from the battery itself.

Figure 1: Block diagram of the LoRa transmitter and receiver.

The LoRa module is controlled by the ATmega328 microcontroller (U1), whilst the LCD allows us to display the numerical figure, expressed as a percentage of the LED light intensity. Increasing or decreasing this figure is done by individually pressing the two mini-keys S1 and S2. The block diagram of the receiver consists of a power input (J2), whose range is 9…12 V DC (important is to keep within this power range).

The voltage regulators U3 (5 V) and U4 (3.3 V), respectively, provide power for the PWM module and the LoRa module (U2), which, as explained earlier, must be supplied with no more than 3.7 V; in addition, the 3.3 V regulator powers the ATmega328 microcontroller, which is dedicated to controlling the LoRa module and generating the waveform for PWM modulation.

To keep in memory the numerical data received from the transmitter (which defines the light intensity of the LEDs), even when we turn off the receiver, we included an EEPROM memory (IC1). Given the power consumption of the LEDs, which, as we will see later, can be around 80 mA each, it was not possible to connect the output of the PWM modulation, generated by the microcontroller, directly to the LEDs; for this purpose, we inserted an interface referred to as PWM and IC2.

Transmitter

This device — whose prototype is shown in Figure 2 — is powered by a 3.6-V, 800-mAh battery (BT1) that can be charged via the micro-USB port (J1) connected to a common 5 V USB socket — see the schematic in Figure 3. LD1 LED, in combination with the lighting of LD3 LED, indicates that the transmitter is powered, and the battery is being charged. When LD3 LED turns off, it indicates that the charging of the battery BT1 is completed.

Figure 2: Prototype of the assembled transmitter, shown on both sides.

The charging current is controlled by U2 and determined by the value of R2; by applying the formula given in the manufacturer’s datasheet (IREG = 1000V/RPROG), we can define its value, which is normally around one-tenth of the battery’s capacity. Although the transmitter is battery-powered, we had to introduce a voltage stabilizer, consisting of IC1 (3.3 V). This way we will have a stable supply voltage that is used to power the microcontroller (U1), the LCD, and the RFM95W module.

Figure 3: Circuit diagram of the transmitter.

The 128 × 32, 0.91" OLED display allows us to view the data transmitted to the receiver to increase or decrease PWM modulation. We divided the display into two lines: on the top one, a light bar is shown, whose length is proportional to the data value transmitted to the receiver via the LoRa module.

The second line displays the data, transmitted to the receiver, in a percentage form with Power written next to it, so a 0% corresponds to the minimum of light intensity and 100% to the maximum (Figure 4).

Figure 4: The display indicates the set light intensity.

Using an ATmega328 microcontroller (U1) to control the LCD and the LoRa module, programming of the microcontroller can be done in the Arduino development environment (IDE), taking advantage of the libraries needed to control LoRa communication and the 0.91" OLED display.

For this project, we preferred to use the Microchip Studio IDE, making use of Microchip’s MPLAB PICkit 4 programmer to load the sketch. We will see in the appropriate section how to proceed with programming. The LoRa module, a RFM95W breakout board (U3), is used to transmit the data that allows us to vary the PWM modulation rate.

Dip switch SW2 is connected between the SPI communication BUS of the microcontroller and the LoRa module. In addition to the communication between the microcontroller U1 and the LoRa module U3, the SPI port is used for the PICKit 4 programmer connected to J2, so to program the microcontroller we must make sure that the SPI communication BUS is isolated from the LoRa module. This is achieved by putting the four dip switches of SW2 in the OFF position. This allows us to program the microcontroller correctly, without risking any errors in loading the sketch. Obviously, this operation is only required during the sketch download phase.

The two buttons S1 and S2 are used to command the increase (S1) or decrease (S2) of the PWM modulation, which, for convenience, we will call Power. This results in the transmission of the data that will allow the receiver to manage the light intensity of the LEDs.

The antenna AE1 may even be basic; working indoors, there’s no need for a professional type. It has to be tuned to 868 MHz wavelength, but even a simple copper wire about 8.6 cm long — or ¼ of the wavelength, 34.56 cm/4 — will be enough. LD2 LED shows when the battery is low (3.35 V). We measure its voltage value through R4 and R5 resistors connected to the PC2 input of the microcontroller.

To preserve the battery charge and have the longest range of the transmitter, we will proceed keeping the display on as short as possible, but enough for displaying effectively the increase and decrease in the Power value. To achieve this, the display will remain active for 26 s (more than enough time to do what is needed).

When the set time is reached, the power to the display is removed via Q2. Another help in saving energy is given to us by a function of the LoRa module called sleep. This function allows us to minimize the current draw of the module. Thanks to the two functionalities mentioned above, the full-power consumption — that is around 15 mA — drops to a value of about 3 mA.

The mini-button S1, else than having the function of incrementing the Power value, allows you to reactivate the OLED display and the LoRa module from the sleep mode. Just press it and release it.

Subscribe
Tag alert: Subscribe to the tag Wireless & Communication and you will receive an e-mail as soon as a new item about it is published on our website!

Receiver

The programming of the ATmega328 microcontroller (U1), as well as the function of the dip-switches SW1 (see the schematic on Figure 5), is done in the same way as for the transmitter. Since PWM modulation is the best solution for proper LED light intensity control, we will go into the details of the receiver keeping in mind the following values, which are:
 

  • PWM frequency 120 Hz
  • Maximum LED current 1.3 A
  • Input voltage 9…12 V
 
Figure 5: Circuit diagram of the receiver.

As you can see from the wiring diagram, the power supply consists of three stages: the first one provides the input power, via J2, which is used to power the LEDs connected to J3. Keeping in mind that the maximum current we can supply is 1.3 A, depending on the control current of the LEDs used (i.e., 80 mA) we will be able to connect a maximum of sixteen LEDs in parallel. The second stage deals with the 5 V supply, provided by the voltage stabilizer U3: it allows us to power the PWM modulation control stage, consisting of Q2, Q3, Q4 etc. (we will get into its function in more detail later).

Lastly, the 3.3 V stabilizer, which, as discussed earlier, is used to supply U1, U2 and IC1. The presence of an EEPROM (IC1), allows us to store the last received Power value, which is used to control PWM modulation. To obtain the same light intensity set before the receiver was turned off, the Power datum is loaded when the receiver is turned on again.

PWM modulation is generated by the ATmega328 microcontroller (U1), using its internal TIMER 0. At the output of pin PD5, you will find a waveform with a frequency of 120 Hz at 3.3 V. As seen above, we cannot control the LEDs directly via the PD5 output of the microcontroller, but we need an interface that can control the high current supplied to the LEDs and keep the PWM modulation frequency stable. Figure 6 shows the finished prototype of this receiving unit.

Figure 6: Prototype of the receiver, assembled and ready to use.

To achieve this, we made use of components Q1, Q2, Q3 and Q4. This pulse-shaping network allows us to control the LEDs while maintaining a stable frequency without spurious spikes (see Figure 7) that could damage the MOSFET (Q4) and the current generator, consisting of IC2, which, in this case, is used as a current limiter instead of a voltage limiter.

The maximum LED control current, which, as already written, is 1.3 A, is determined by the two resistors R3 and R4. We preferred to put two resistors in parallel, instead of using one, since some low values of SMD resistors, with power ratings above 2 W, are difficult to come by.

A special look should be taken at current limiter IC2 (a LM338 by Texas Instruments), that’s equipped with a heat sink to dissipate the power exceeding its maximum rating (1 W). Since the input voltage range can be 9…12 V, in the worst case (12 V) we’ll have a power dissipation of 8.6 W, so the use of a heat sink is mandatory.

It is beyond the scope of this article to delve into how to calculate the type of heatsink to choose, but suffice it to say that to keep the maximum operating temperature of the junction of IC2 (Tj) below 125°C, it is necessary to mount it to a cooling heatsink equal to a value of at least 6°C/W or less (the lower the value, the higher the dissipated power).

Figure 7: PWM output signal.

Microchip Studio IDE

As mentioned earlier, the programs for the transmitter and receiver module (LoRaSender and LoRaReceiver, respectively), were developed thanks to the Arduino IDE, but for programming we will use the Microchip Studio IDE. Microchip Studio works as if we were in the Arduino development environment. To program the transmitter and receiver microcontroller we could use the Arduino UNO board, following the tutorial you will find at , but, as far as we are concerned, impractical for microcontrollers with board-mounted TQFP pinouts.

Figure 8: Startup page of Microchip Studio.

Much more functional is to use a programmer such as:
 

  • ATMEL-ICE(AVR) - functional but somewhat expensive. It can be used directly in the Arduino IDE and only for microcontrollers with AVR architecture
  • MPLAB PICkit4 - programmer from Microchip definitely less expensive and, more importantly, more versatile.


Using the PICkit 4 programmer, Microchip Studio allows us to program a wide range of microcontrollers from the Microchip family and with AVR and SAM architecture. We now install the Microchip Studio Software, which you can find on the Microchip website here. Open it to load the sketch you created with the Arduino IDE.

At startup, you will land on the start page (Figure 8), click on New project and the window will appear as in Figure 9. Click on Create project from Arduino sketch, a few fields will appear for you to fill in:
 

  • Name: enter the title of the file to be created (LoRaSender or LoRaReceiver). Automatically the field Solution name will be filled in with the same title.
  • Location: is the address where the file will be saved.
  • Create new solution: leave this field unchanged, as it is a new file.
 
Figure 9: Loading a new project.

Click on the OK button to move on. The next window that will appear is shown in Figure 10. Again, fill in the fields as follows:

 

  • Sketch file: click on the three dots icon to access the folder where you have stored the Sketch file we created with the Arduino IDE. The selected file will be used to create our program in the Microchip Studio IDE.
  • Arduino IDE path: this is the location where the Arduino software resides.
  • Board: although irrelevant, we choose the Arduino UNO board.
  • Device: obviously, we’ll select ATmega328.
 
Figure 10: Loading the Arduino sketch.

Clicking OK will import the Arduino sketch file into the Microchip Studio IDE. As mentioned earlier, the Microchip Studio environment has the same functions as the Arduino IDE, but with more peculiarities, which we invite you to explore further when we have finished verifying the functionality of the sketch file, saved in the new development environment.

In order for our sketch to work, one last step is missing: we need to load the needed libraries. To accomplish this, right-click on the window highlighted in red (see Figure 11); a drop-down menu will appear, in which you will find the option Add Arduino Library. Select it, then choose from the list the libraries required for your project.

Figure 11: Loading of the libraries.

For LoRaSender, the libraries to select are:

 

  • Wire.h
  • SPI.h
  • Adafruit_GFX.h
  • Adafruit_Sensor.h
  • Adafruit_SSD1306.h
  • LoRa.h

 

For LoRaReceiver, select:

 

  • Wire.h>
  • SPI.h>
  • LoRa.h>

 

Note: In order for the libraries to appear to you in the above list, you must have installed them via the library loading functions in the Arduino IDE. At this point, we have completed all the steps that allow us to load the sketch into our ATmega328 microcontroller. To load the firmware, we use the MPLAB PICkit 4 programmer.

Loading the Firmware

On the two boards, there is a 6-pin connector (J2 for the transmitter and J1 for the receiver) that we will use with our MPLAB PICkit 4 programmer to load the firmware into the microcontroller by connecting the pins as shown in Figure 12.

Figure 12: Wiring of the Microchip MPLAB PICkit4 programmer.

Please note that to load the firmware into the microcontroller, we must turn OFF SW2 dip-switch on the transmitter board and SW1 on the receiver board. Once we’ve connected the MPLAB PICkit 4 to the board, we select the type of microcontroller used by clicking on the icon located in the toolbar, and depicted by an integrated circuit circled in red (see Figure 13); a page will open that allows us to choose the type of microcontroller we are using.

If not already selected, click on the change device icon circled in green; a drop-down menu will open with a number of microcontrollers supported by Microchip Studio; choose ATmega328 and click OK. On the same page is a list of supported programmers (see list circled in purple) called Supported Tools. Click on the one you are interested in, and you will be directed to the respective web page, where you can find more details and documentation related to it.

Connect the programmer via the mini USB serial port and, if properly recognized, select it by clicking on the icon circled in yellow (previously opened via the hammer symbol). At this point, we have selected the tools we need to load our firmware. Now, just click on the icon represented by a green arrow (circled in blue). If you have selected all the tools correctly, the download of the firmware into the microcontroller will begin.

When the download is finished, in the output window at the bottom, you should read Build succeeded: this means that the download was successful.

Figure 13: Selection of the device.

LoRaSender Sketch

Before analyzing the sketch, which can be downloaded at the Elektor Labs page for this article, a small clarification should be made: in the sketch you will often see appearing a function named power, which is nothing more than the data transmitted to control pulse width modulation (PWM) which, translated, determines the LED light intensity.

The setup part of the LoRaSender sketch is not covered since there is already a brief explanation alongside the functions; moreover, some functions are part of the related library such as, for example, handling the OLED SSD1306 display (Adafruit_GFX.h, Adafruit_Sensor.h and Adafruit_SSD1306.h) and transmitting LoRa packets (LoRa.h).

As mentioned, we have a time limit of 26 s in which the display remains on. To achieve this time, we use the 16 bit TIMER 1 internal to the Atmega328 microcontroller. When the overflow value of the TIMER is reached, the ISR routine TIMER1_OVF_Vector will be called. Within the routine, until a number of 50 counts (defined by the count variable) are reached, the display will not be turned off and the LoRa module will not be put into sleep mode.

The wake_up procedure is invoked the moment the S1 mini-button is pressed and released and, as you can imagine, will turn the display back on and wake up the LoRa module (Listing 1).

Listing 1: Wake-up procedure.
The control that determines the increase or decrease of the data called power is given by the S1 and S2 mini-buttons. The commands:

 

LoRa.beginPacket();

LoRa.print("A");

LoRa.print(power);

LoRa.endPacket();

 

allow us to transmit the power datum to translate it, from the receiver, into light intensity. The letter that precedes the power datum, in our case the letter A, serves us to transmit a datum that can be interpreted by the receiver as a start of reception, allowing us to filter out any radio interference that might disturb the reception of the transmitted datum. The calculation of the increment or decrement of the bar, which indicates the percentage of the power variable, is:
 

power--;

pct = power / 1.28;

v_pct = pct;

 

To increase the bar, and the percentage value related to it, we must subtract, rather than add, the variable power. This is a consequence of the function that controls the length and height of the bar, called: display.fillRect(0, 0, display.width()-counter, display.height()/8, INVERSE).

Keeping in mind that the display matrix is a 128x32 pixels, the part concerning the length of the bar is determined by display.width()-counter while the thickness by display.height()/8, so the length is determined by subtracting the value of 128, while the height of the bar is determined by the value of 32 divided by 8. In our case, then, it turns out to be 4 pixels.

The last note concerns the value of the power variable expressed as a percentage: to make the 128 pixels, inherent in the width of the display, correspond to the value of 100% we must divide it by 1.28. This is why we must have an initial float value (pct, percent), and then round it into an integer value (v_pct, percent value).

The part about decreasing the bar value is the same as the function we just saw, except that instead of having the variable power subtracted (power--), we will have the same variable incremented (power++).

LoRaReceiver Sketch

The receiver code is simple and short, but to better understand its meaning, we have broken it down into four macro areas. In setup, we read the last PWM modulation data received and stored in the EEPROM IC, so that the LEDs are illuminated with the same intensity as set at power down. Again, the variable that determines the PWM modulation data is called power. Crucial is the part:

 

TCCR0A = 0b000000;

TCCR0B = 0b000000;

TCCR0A = 0b10000011;

TCCR0B = 0b00000100;

OCR0A = 0;

 

as it determines how TIMER 0, which is internal to the ATmega328 microcontroller, is to operate for PWM modulation control. The PWM modulation data is stored in the variable OCR0A which determines the time that the PWM pulse width modulation waveform remains ON and the time that it remains OFF. To avoid uncontrollable spikes in LED light intensity, we introduced a small routine that is executed only when the receiver is turned on:

 

if (cnt == 0){

    Wire.beginTransmission(0x50);

    Wire.write(0x00);

    Wire.write(OCR0A = power);

    Wire.endTransmission();

    cnt++;

}

 

In Listing 2, we find the part about receiving the LoRa packet, which determines the value of the variable power.

Listing 2: LoRa Data Packet Reception.

Since the value of power ranges from 0 to 127, to have a value of the variable OCR0A greater, but not higher than 255, (maximum value of an 8-bit variable) we introduced a multiplicative factor of 1.71 (fatt = 1.71 variable); this allows us to have PWM modulation with a minimum, average and maximum waveform as in Figure 14. Since the LoRa module continuously updates the power datum, to minimize the number of times we store it in EEPROM, we introduced a while loop. In this case, the variable data is stored only when it differs from the previous one, thus minimizing the memory write/read cycles.

Figure 14: Examples of waveforms with different PWM duty-cycle values.

Wrapping Up

There is a wide range of medium-power LEDs on the market. With this article, we have focused on those that can be used for lighting objects, giving you a way to understand which is the best choice for your needs; in addition, we have added the possibility of remotely controlling your object, using technology that has no limitations in reception. All the materials needed for both the TX and RX units, including Gerber, PDF files for the PCBs and the software project files are available for download here.


Editors notes: Interested in LoRa and wirelress solutions? This project originally appeared in Elettronica IN.




Subscribe
Tag alert: Subscribe to the tag Wireless and you will receive an e-mail as soon as a new item about it is published on our website!