Arduino DAC Signal Generator project
Posted on Jun 30, 2017 12707
The triangular mathematical signal is a continuous function in time that starts from the average width increases to a maximum width and goes down to the bottom at a constant rate. This programming can be implemented with a loop that will increase a variable by 1 until the variable gets the maximum approximate value we have (256) and gives it to the output. As soon as it reaches this value it will decrease until it reaches the minimum value that is 0.
Once it reaches 0 it starts to rise again and the process repeats continuously. The integer value of the variable loop is assigned to the PORTD register which converts the value to the binary and gives a high (5 volt) voltage to the corresponding pin outputs. For example, if PORTD is set to 127 (11110000), then the first 4 pin (4-7) will be voltage while the other 4 (0 - 3) will be in low mode. So if this loop is running continuously at the output we have a triangular signal.
The sine signal is the most difficult of the four signals because it is not enough to have a variable that increases because the halftone has certain values at any moment. Thus, a 255-position auxiliary panel is used which takes sine values in a range from 0 to 255, so that a signal approaching the sine signal is displayed at the output. After we have the value table, then the process is the same as the triangular signal, except that instead of PORTD taking the loop variable values, it takes the values of the table and the loop variable is used as a table of increase in the table.
Square pulse is very easy to implement as long as we give output 0 for one period and 255 for the next one continuously.
We could say that the saw signal is a triangular signal case since the only difference is that the saw signal after reaching the maximum voltage level instead of decreasing is zero. This is done by using a loop for which continuously increases a i variable from 0 to 255 whose value is assigned to the PORTD register. So we have a saw signal at the exit.
DAC with R-2R grid
A circuit that receives a digital input and converts it to analog voltage or current is called a digital signal converter to an analogue. Such a circuit was used in the present application to convert the values output to PORTD, which is an output port for the values of the sine signal and the sawtooth signal.
In such a system, each digital input corresponds to a certain analog output. It is a circuit that takes as a digital input 8 bit ie numbers from 0 (00000000) to 255 (11111111) and as output produces a voltage of 0-5V.
The mathematical explanation is quite simple: if we want an 8 bit DAC to output 5V at 255 execution steps each step will be 5/255 = 0.019V. Thus the output voltage of such a DAC will equal the multipl
ication of the binary input on the pitch. Example for input number 129 (1000 0001) the output voltage would be 129X0.019 = 2.451V In the circuit that we constructed we made and used an 8-bit DAC R-2R.
This circuit is an 8 bit digital to analogue converter. Each of the eight bits contributes to the resulting output voltage. If all 8 bits are in HIGH mode then the output is approximately equal to the reference voltage. If we change the most important bits in LOW mode then we will have about half of that trend. More specifically for a 8bit DAC if all 8 bit is HIGH then we get 255/256 reference voltage. If it becomes active, the most significant digit in LOW mode gives us 127/256 of reference voltages. Generally for every bit of X value between 0-255 the DAC will give X / 255 reference voltage.
The digital data enters through 8 input lines (D0-D7) and adheres to convert to the equivalent analog voltage (Vout) on the R-2R network. Most DACs are based on this philosophy. The R-2R circuit is made of a set of resistors having 2 values. One is the double of the other. In the circuit that we implemented, we used resistors of 10KΩ and 20KOΩ. Below is the circuit implemented in Raster and its connection to the Arduino board.
- 4 LED for selected signal indication
- 8 Resistance 5ΩΩ (5% tolerance) Circuit R-2R
- 8 Resistance 10KΩ (1% tolerance) Circuit R-2R
- 2 Potentiometers for frequency and duty-cycle
- 1 Button for selecting signal type
- 6 Resistance 10KΩ (1% tolerance)
- 20 Cable for Connections
- 1 Raster Circuit implementation
- 1 Arduino Uno Implementation board
- 1 Oscilloscope for viewing the waveforms
Logic of the program
The program can be downloaded by clicking here and it consists of three parts and is as follows:
- 1. Statement of global variables.
- 2. Set-up function in which the program's default settings are related to the board and value output in the variables (example output values in the sine table).
- 3. Loop function in which, it is executed continuously for as long as the main program works.
The variables used:
- sine : A table of 255 positions which takes sine values from 0 to 255. It serves to output sine values to the PORT register.
- OutputArray : Table with 8 positions to be defined as outputs. These 8 outputs are used to give the 4 signals of the generator. Pins D0-D7
- ledArray : Table 4 places defined as exits. They are connected with 4 LEDs that serve to show more signal there at the output each time. Pins D8-D11
- Signal: Variable which takes values from 0-4 and determines which case case will run each time.
- buttonPin: Variable which gets a value that is the location of the pin to which the button for signal change is connected. Pin D12
- buttonState: Input variable, which takes the status of the button (LOW - pressed, HIGH - not pressed).
- PotFunc: Variable that gets a value (0 in our case) which is the input potentiometer of the potentiometer. Pin - A0 (Analog Input).
- wave (value): Variable which takes the value of the potentiometer state.
- PotGain: Variable that gets a value (1 in our case) which is the input potentiometer of the potentiometer. Pin - A1 (Analog Input).
- val1 (value): Variable which takes the value of the potentiometer status.
The Setup function
This function defines the functions of the Arduino boards Pin and initializes the variables. In particular, digital pin 0 to 11 is defined as outputs. Digital Pin 0-7 has to do with the output of the circuit and give us each time a sequence of bits that get states such that the analog signal (triangular, sine, square, saw) appears at the output. Pin 8-11 gives output for the 4 leds that are used as signaling indicators for the most signal there is at the output each time.
Digital pin 12 is defined as input and gets a value from the toggle button. When the button is pressed then there is a 5V voltage in Pin, so it is in High state and when it is not pressed then there is no voltage and so it is in low mode. Analog Pin 0 and 1 are defined as inputs that take values from the internal resistance of 2 potentiometers that regulate the intensity and frequency of the signals each time.
The Loop function
After the global variables are set and the setup function is executed, from the moment the loop function runs "continuously", in an endless loop for as long as the arduino is running or until it restarts. The code of this function is also the main program. The loop is initially run and one-case control of the signal function that gets the value from the toggle button. Initially the signal is 0 and so nothing happens (default case status). If the button is pressed once, it enters the first case and the code begins to execute, which gives the output a triangular signal and illuminates the appropriate LED (active_led) signal.
At the same time the 2 potentiometers for frequency and amplitude changes are checked and with the map function we adjust the values we get from the potentiometers to the range we are interested in working on. Also with the delay function we define a delay in the loop so that we can change the frequency in the signals. Along with all of this, the switching switch is controlled so that if the next case is pressed, the only one that changes is the output signal and the signal indicator light. The same happens every time you press the button until the signals are over and the program comes to the default state.