SIGNAL GENERATION AND GETTING SIGNALS IN EMBEDDED SYSTEMS
SIGNAL GENERATION AND GETTING SIGNALS IN EMBEDDED SYSTEMS
Peter Safir
Bachelor of Science, The Azrieli College of Engineering in Jerusalem (JCE)
Israel, Jerusalem
ABSTRACT
In this article, I would like to talk about how to implement a wave generator with an embedded system[1]. I would also like to talk about signal receiving, and signal generation, as well as to discuss use of some algorithms. I would also like to discuss ready-made libraries for generating digital signals in an Arduino environment[2].
INTRODUCTION
Knowledge of signal generation is very important for a development engineer. Every science lab, hobbyist lab, or engineering lab must have a good signal generator. You cannot do without test signals when creating a prototype. When debugging any device, for example, you will also need a signal generator. But a signal generator is an expensive piece of equipment: and not everyone can afford it. But you do not always need an expensive signal generator. You can easily build your own signal generator with an embedded system like for example the development board Arduino[2] or any FPGA[3]. If you need a PWM you can easily do create one. The point is, that the Arduino[2] development board generates a signal with an internal timer and transmits using separate pins. With PWM we can also generate different analog signals such as sine. This is how the DAC[4] works. It is also very easy to filter incoming signals. The same Arduino[2] development board includes a lot of ready-made open sourse[5] libraries which are flexible and you can easily integrate them into your projects.
SIGNAL GENERATION
When choosing a signal, you must consider its application, signal form and frequency.
[Hz] (1.1)
First, I want to talk about a built-in signal generation and reading function included in the Arduino core development board.
Its function is to generate a square signal is tone(). Below are are the parameters that tone(pin, frequency, duration) uses. Let us look at them in more detail:
- pin-determines which digital pin we will generate on our digital signal.
- frequency - this parameter transmits the required frequency of the function in the range of 31-65.535 Hz.
- duration – is the duration of the generated signal. It is measured in milliseconds. The parameter is optional: but if it is not passed to the function, the signal will be generated without stopping.
To stop the signal, you can use the noTone() function. Note that the tone() function uses Timer_2 to generate the signal and if you use it to generate other signals, for example, PWM[6] it will change the generation frequency. During the pauses between the tone() function calls, the Timer_2 will be released and you can use it for other processes. A very important point is that the signal is generated using only one digital pin on timer 2 and if you want to transfer the signal onto another pin you will have to disable it with the noTone() function, and only then will you be able to enable it on the other pin.
Very often we have to change the voltage on a device, step by step, e.g. to run the motor smoothly and to dim the LED. The PWM[6] helps us to do this. To create a PWM there is a built-in function analogWrite(pin, duty). This function has two parameters:
- pin - pin number where we will genirate our PWM.
- duty- is the occupancy of PWM. Usually it has 8 bits [0...255].
The frequency is generated by internal timers, so to change the frequency on PWM to the required pin you will need to change the frequency in the timer itself using its connected pin.
The Sinusoidal Pulse Width Modulation (SPWM). This signal is somewhat similar to a normal PWM signal, but inside it the fill factor is controlled, so as to obtain an average voltage similar to that of a sinusoidal wave. For example, at a duty cycle of 100% the average output voltage will be 5V, but at a duty cycle of 50% it will only be 2.5V, so by controlling the duty cycle we can get predetermined variable values of the average voltage, i.e. a sine wave. So, by using the digital signal we can get an analog sine at the output.
We cannot always use the built-in signal generation functions. All of the above functions are operated by timers. This is, after all, a hardware solution not a software solution and therefore takes resources. But we can implement the functions ourselves with the right code and we can write and develop our own signal generators. There are three time functions in Arduino that can be used to generate a square wave.
- delay()
- millis()
- micros()
The function delay() takes values in seconds, but I do not recommend using it because it is a program function, and until it fails completely, the whole program will stand still. The functions millis() and micros() are more robust because they return the time elapsed since your program started, and this gives you the benefit of a more flexible uptime. These functions are generally better for generating signals, since they can operate properly without slowing down the whole program. Moreover, these functions are not tied to any pins and you can use them to output your signals to any pin of the development board.
GETTING SIGNALS
In order to get the input signal, we need to measure the time between the edges of the pulse. We have to track the time of the edge change from HIGH to LOW or LOW to HIGH. The Arduino has two built-in functions for measuring the square wave.
The first function is pulseIn() and the second is pulseInLong(). These functions take parameters like these.
- pin - select the pin where we want to get the signal.
- value - on which edge of the pulse we will measure. HIGH or LOW.
- timeout - pulse waiting time. Measured in milliseconds. It is not necessary to set this parameter. The default value is 1 second.
If we set value = HIGH, in this case the expected change for the function will be from LOW to HIGH. If there is no edge change during timeout, then function returns 0 and stops executing.
Of course, we can write our own code to measure the square wave. The algorithm is quite simple. The program expects the signal to change from HIGH to LOW or from LOW to HIGH. When we get an edge change, we use millis() or micros() to count down the time until the next edge change. This time is known as the frequency of the signal.
CONCLUSION
As we see, there is very little difficulty in creating or reading signals on the Arduino development board, or on any other embedded system. We can use a ready-made solution from the manufacturer, or we can write our own basic code. And as you can see, there are two types of libraries available. One is completely software based and the other uses the hardware of the embedded system.
References:
- Peter Marwedel, Embedded System Design: Embedded Systems Foundations of Cyber-Physical Systems 2nd ed. 2011 Edition, Springer Verlag.
- J. M. Hughes, Arduino: A Technical Reference: A Handbook for Technicians, Engineers, and Makers 1st Edition, June 14, 2016, O'Reilly Media, ISBN-10 1491921765.
- Hideharu Amano, Principles and Structures of FPGAs,1st ed. 2018 Edition, Springer Verlag.
- Rudy J. van de Plassche, CMOS Integrated Analog-to-Digital and Digital-to-Analog Converters 2nd Edition, Edition 2nd, May 31, 2003, Publisher Springer, ISBN-10 1571812776.
- Fabio Kon, Paulo Meirelles, Nelson Lago, Antonio Terceiro, Christina Chavez, Manoel Mendonça, Free and Open Source Software Development and Research: Opportunities for Software Engineering, Date of Conference: 28-30 September 2011, Print ISBN:978-1-4577-2187-8, Publisher: IEEE, DOI: 10.1109/SBES.2011.19.
- Dogan Ibrahim, Designing Embedded Systems with 32-Bit PIC Microcontrollers and MikroC 1st Edition - August 22, 2013, Newnes, DOI https://doi.org/10.1016/C2011-0-06919-3.
- Richard G. Lyons, Understanding Digital Signal Processing 2nd Edition, January 1, 2004, Publisher Prentice Hall, ISBN-10 0131089897.