An optoelectronic system for controlling a direct current motor PART 2: SOFTWARE

An optoelectronic system for controlling a direct current motor. PART 1: Software


Introduction
Wireless infrared devices for controlling direct current (DC) motors use free-space optical communication networks. Free-space optical data links rely on electromagnetic radiation in the visible or the infrared spectrum which is sent by the transmitter to the receiver, where electric chargethe control signalis generated by a stream of photons. The signal is then amplified, demodulated and processed. In this solution, the signal is carried by the free space between the transmitter and the receiver. Various sources of electromagnetic interference with a wavelength similar to the wavelength at which the transmitter and the receiver operate can limit the applicability of the above solution. In indoor premises, electromagnetic interference is generated by heat sources, lamps and sunlight, and the number of potential disruptors is likely to increase over longer communication distances. Despite the above, numerous devices can be implemented in free-space optical communication systems, including distance sensors, slotted optical switches with aperture width of several millimeters to more than 10 centimeters, remote controls for household equipment with a range of several meters, data transmission systems used by telecommunications companies, such as VLC and FSO with data transmission speeds of up to 10 GB/s and a range of more than 10 kilometers, as well Lunar Laser Communication Demonstration (LLCD) which relies on laser light to communicate with a receiver station across a distance of several hundred kilometers (385 km).
The aim of this study was to develop and optoelectronic system for controlling a DC motor. A system that processes data from an infrared transmitter and handles tasks broken into data frames was built. The project was upgraded in successive stages, and it ultimately evolved into a small computer with a motor controller. The designed system automatically adjusts the motor's revolution and speed. The user is tasked only with conveying operational commands.
The device receives user commands (the program can be modified to support freespace optical communication networks conforming to all communication standards). The system activates the motor, counts the number of rotations and adjusts the motor's position.
The system features optoelectronic components, a DC motor and devices for controlling the motor.
The user sends commands to the motor via a remote control with an infrared diode.
The keys on the remote control have been programmed with different commands. The transmitted data are processed by the system which activates the motor and sets the desired motor speed. The task is completed, and the system is ready to process the next command. If the number of revolutions differs from the preset value, the motor's position is adjusted. If the physical position of the rotor axis is altered, the system corrects the offset to the last programmed position. The designed system can be easily adapted to various types of motors and IR controllers.
A patent application for the developed system has been submitted to the patent office.

Development of the programming algorithm
The designed system for controlling a DC motor with the use of an IR remote control should be reliable and easy to modify. The keys on the remote control are programmed with different functions, and the user is tasked only with pressing the respective key to execute a given command.
The IRremote.h library was used to write the code.
The developed software had to be easy to modify, and two programs were written for this purpose. The first program reads the value of the signal sent by the remote control, and the second program reads the duty cycle of the PWM signal.
In the first step, the IR receiver is configured and the IRremote.h library is implemented.
The following commands are used to implement the library: • IRrecv irrecv(irDiode)create the receiver object and assign a name to the receiver (irDiode); • decode_results result -decode the received data. The program returns "true" when a code is received, and "false" when a code is not received. When a code is received, data are stored in "results"; • irrecv.enableIRIn()begin the receiving process. This command will enable the timer interrupt which consumes a small amount of CPU every 50 microseconds; • irrecv.resume()when a code is received, this command must be called to reset the receiver and prepare it to receive another code.
The code for reading the remote control signal is presented in Figure 4.1. When data have been read, their value is displayed in hexadecimal base with the 0x prefix. This is followed by a 0.25 s interval during which the receiver is reset and prepared to receive another code. Digital output pins in a microcontroller have fixed values; therefore, a motor's rotational speed cannot be controlled by changing voltage. This is why a PWM signal was used. The duty cycle of a PWM signal can vary over time. The force of inertia acting on a rotating stator does not stop the motor immediately; therefore, the motor's rotational speed can be controlled. However, the motor will not be activated when the speed is too low. The value of a PWM signal can be higher than rated voltage. Average voltage cannot exceed rated voltage.
The minimum duty cycle of a PWM signal can vary in motors with the same parameters, in particular in geared motors. The system was modified by developing a program that displays the minimum duty cycle on an integrated serial monitor. A potentiometer was connected to the microprocessor's analog-to-digital converter. The microprocessor's resistance was changed to modify the signal's duty cycle and determine the minimum duty cycle that will activate the motor.
The code for determining the minimum duty cycle of a PWM signal is presented in  The direction of each pin has to be determined in every program. The following commands were used: • byte readValue = 0determine the value read from the analog-to-digital converter; • Serial.begin(9600)establish communication to display the value on the serial monitor by setting the UART baud rate; • readValue = analogRead(A4)read the value from the analog-to-digital converter; • Serial.println(readValue)transmit the measured voltage; • analogWrite(5,readValue)the read value is the duty cycle.
The main program receives the data sent by the remote control, processes that data and executes the relevant command. The program also monitors the steps performed by the motor and displays the relevant information on the computer screen.
The lines of the code that define variables and parse data are presented in Figure 4.3. Peripheral devices are configured and variables are defined in the first step of the program. Selected pins were defined and configured to default settings to increase the program's readability. The following configuration settings were used: • IRremote.hlibrary used to configure the IR receiver; • irPin 3pin 3 was defined as irPin which receives data; • RIGHT/LEFTconnections responsible for the direction of motor rotation; • MOTOR_PWM 5pin 5 was defined as MOTOR_PWM which generates a PWM signal; • GAIN 1.0proportional gain of the control loop mechanism; • MARGINupper limit of the proportional controller denoting the maximum difference in motor's rotational speed; • MIN_PWM/MAX_PWMminimum and maximum values of PWM set by the program; • val/val_tvariables denoting the previous value and the current value, which are compared in successive steps of the program; • stepvariable denoting the number of steps to be executed. When data are received and decoded, the step is set to the value that is assigned to a given data packet; • currentvariable denoting the current number of executed steps. This value is compared with the preset value; • CYCLE_PWMvariable denoting the value of PWM which is used to stop the motor; • IRrecv irrecv(irPin)create the receiver object and assigned a name to the receiver (irPin); • decode_results resultsdecode data. The program returns "true" when a code is received, and "false" when a code is not received. When a code is received, data are stored in "results".
The setup() function is called automatically when the microcontroller is activated or the reset key is pressed. This function is used to set system values, such as initial variable values, and to declare inputs and outputs. The setup() function does not return values and parameters are not input in the function.
In the developed program, the setup() function was used to set the initial values of variables, declare microcontroller inputs and outputs, establish communication, display values on the serial monitor by setting the UART baud rate, and receive information from the remote control. The function defines the input responsible for interrupts, interrupt subroutines and the effects of the interrupt service routine.
An interrupt is a signal from a peripheral device that interrupts the main program and jumps to a specific function entry inside the interrupt service routine.
A fragment of the main program with the setup() loop is presented in Figure 4.4. When the signal from pin 3 changes, the main program is interrupted and the stored instructions are executed. The received data are decoded.
The beginning of the interrupt subroutine is initiated is presented in Figure 4.5.   The state of pins 9 and 10 is examined. Val is an 8-bit variable, but only 2 bits are used. If pin 9 has a falling edge, the first bit is set at 1. If pin 10 has a falling edge, the zero bit is set at 1. The value is returned by the "return" command. The value of variable val in the decimal system is presented in Figure 4.8. The current value of the encoder is read in the next step. If the current value differs from the previous value, the system checks whether the previous value was 3 and the current value is 1, or whether the previous value was 0 and the current value is 2. If the previous value was 0, the value of the current step is increased and displayed on the serial monitor. The value of the current step is decreased if the previous value was not 0. After this step, the previous value equals the current value.
In the following step, the value of the CYCLE_PWM variable is calculated with the use of the code presented in Figure 4.9. The absolute difference between the preset steps and the current steps is multiplied by the proportional gain of the control loop mechanism. If CYCLE_PWM is lower than the minimum value of PWM, it assumes the value of MIN_PWM. If CYCLE_PWM is higher than the maximum value of PWM, it assumes the value of MAX_PWM. The program then calculates the absolute difference between the preset steps. If the difference is smaller than the MARGIN variable, PWM equals zero, the motor is stopped and the program pauses for 1 s. If the result is different, two scenarios are possible (Fig. 4.10): • if the number of current steps is smaller than the number of preset steps, the motor rotates counterclockwise, the value of PWM is the difference between 255 (the maximum value) and CYCLE_PWM. The motor's speed decreases before a full stop; • the motor rotates clockwise.

Device configuration and tests
The device has to be configured before tests. Remote control keys are programmed, and the value of MIN_PWM which activates the rotor shaft is set. These tasks were accomplished with the use of: • a program that reads the signal from the remote control; • a program that sets the minimum value of the duty cycle.
The device was connected to a computer and power supply, and the program reading the signal from the remote control was uploaded to the microcontroller. The serial monitor was turned on, and four selected keys were pressed. The displayed values (Fig. 5.1) were input in the appropriate lines of the code (Fig. 5.2).  To determine the minimum duty cycle, the program was uploaded to the microcontroller, and the serial monitor was turned on. Before this step, a potentiometer was connected to the microcontroller's A4 output and the system was powered. The potentiometer should be set to a minimum value upon connection.
The potentiometer dial was slowly rotated when the motor began to move. The potentiometer was then restored to the lowest value, and the test was repeated several times.
The average result was entered in the appropriate line of the code (Fig. 5.3). The system was tested in the motor's operating environment. The motor's load was simulated with the worm gear. The tests were conducted to verify the initial assumptions and introduce the required modifications. The motor's operation was simulated in an indoor environment. The results were used to predict the motor's behavior during operation.
The system was supplied with power, connected to a computer, and a multimeter was connected to the IR receiver output. The program for reading data from the remote control was uploaded to the microcontroller. The impact of potentially disruptive factors that could cause errors in data acquisition was tested, including: • fluorescent lamps; • heaters; • sunlight; • 60 W incandescent light bulb; • different remote control.
The monitored values were displayed on the serial monitor when the microcontroller did not communicate with the remote control. Minor voltage fluctuations were incidentally noted at the receiver output. Communication with a remote control operating in a different wireless standard was tested. The result was positive, which indicates that the designed system can be operated with the use of different remote controls or several remote controls.
The impact of the identified disruptions on the system's operation was tested in the next step. The main program was uploaded. After compilation, the program occupied 27% of the program memory and 22% of dynamic memory, which implies that the program can be expanded.
Data were transmitted correctly by the remote control, and the motor performed the desired number of rotations. The delay in data receipt did not exceed the delays noted in other devices that rely on the same technology. The only exception was the test where data transmission was disrupted by a different remote control. In this case, data receipt was delayed, but it had no effect on motor rotation. The above resulted from similar transmission wavelengths in IR remote controls.
The system's operation during command execution was tested. A command signal was sent, and a second signal was transmitted before the first command was executed. The value of the second signal was added to the value of the first signal. However, the current value and the time when the data frame was received remain unknown. A data receipt diode or a display presenting the number of motor rotations should be added in successive stages of system development. The previous value was subtracted during the transmission of data with a negative value. The motor rotated in the opposite direction if the transmitted value was higher than the previous value, which slightly affected the motor's stop position relative to the initial position. The maximum value approximated 20°, and it was determined by the encoder's structural design.
During operation, a motor can be subjected to vibration or other environmental factors that can affect the position of the rotor shaft. A minor change in the rotor angle was noted when manual force was applied. The motor began to adjust its rotor position when the displacement exceeded the boundary value of 20°, which is consistent with the initial assumptions. The rotor shaft also returned to its initial position when forcefully turned.
The number of motor rotations displayed on the serial monitor was checked during each test. Messages were displayed correctly. A display should be incorporated in successive stages of project development to monitor the system's performance without the use of a computer.

Conclusions
An optoelectronic system for controlling a DC motor was designed. The developed system processes data from the IR transmitter and handles tasks broken into data frames. The system receives user commands (the program can be modified to support free-space optical communication networks conforming to all communication standards), activates the motor, counts the number of rotations and adjusts the motor's position.
The designed system was built around an Arduino microcontroller which is relatively cheap, enables system modifications in the design stage and can be easily adapted during programming, which saves time and facilitates project performance. The Arduino environment can be also extended through the use of libraries which facilitate the incorporation of new modules, including modules without memory that can be easily adapted to the project's needs.
The developed system can be upgraded and modified in the future. The following solutions could be considered: • the parameters of the DC motor could be displayed on an LCD screen; • three motors could be mounted on the same frame to build a robotic arm or a plotter; • a proportional integral derivative controller could be incorporated into the program to control motor rotation; • the code for receiving user commands could be expanded; • a rotating encoder with a larger number of slits could be applied to increase control precision; • rotational speed could be measured during the motor's operation.