ADC Accuracy Issues

Testing

When using the Cortex L4’s ADC, we encountered problems with the consistency of the DU (digital units) being read on Termite (Hyperterminal). In our testing, a steady voltage was sent into the Power Measurement circuit which then dropped our 4 – 24V scale to a 0 – 3.3V, which is a far more suitable range for the MCU. When reading the values from the voltage from the DMM (Digital Multimeter) the values seemed to match those seen in previous tests but when the analogue voltage was converted to DU, the readings were unreliable and had errors up to 350mV.

The power supply seems to be supplying a reliable voltage to the power module, but to make sure we connected an oscilloscope at the two terminals of the supply shown above.

No cap, no software
DU Readings at 6VDC

The readings above show the result of sending a constant 6V DC supply into the Power Measurement circuit, the first line is the DU value and the second is DU converted back to voltage to be used to calculate the power. As shown, the DU ranges from 3571 to 3675, a difference of 104.

Assuming a DU range of 0-4095 (12-bit ADC) and a voltage range of 0-24V, these values cause an error of 507mV, an unacceptable error.

ADC before capacitor.JPG
Power Module Ripple

On the top left of the monitor, the voltage scale is shown, each of the verticle lines, in this case, represent 50mV. The oscilloscope shows that the voltage can oscillate between +90mV to -100mV, this explains the large DU jumps when reading from Termite. This wave is also very hard to read due to the large spike only occurring for a very short amount of time.

To ensure the power supply was not at fault we connected the power supply unit to the oscilloscope, spikes either side of the x-axis represent the degree to which the size of the ripple voltage.

wp-1529675587413.jpg
Power Supply Ripple

The biggest ripple shown above is less than +/- 5mV, this error is acceptable for our application. This suggests that the power module is at fault and not the power supply.

To smooth the output of the power module a capacitor was used, this is often used on rectifiers when converting from AC to DC, a ripple voltage remains and must be smoothed. The differential formula below says that the rate of change of voltage is inversely proportional to the capacitance.

dVdt

So if the capacitance increases the ripple voltage should be attenuated. To test this an 82nF capacitor was added to the output of the power module (before entering the ADC). When testing with the oscilloscope the waveform below was found.

ADC with 82nF
Power Module Ripple with 82nF

This waveform brings the ripple down to roughly +/- 40mV, 50mV better than without the capacitor. Our aim is to have a voltage accurate to within 100mV of the actual voltage so a smaller ripple was necessary. The next capacitor used was 1µF, the waveform below is what was shown on the oscilloscope.

adc-with-1uf-capacitor.jpg
Power Module Ripple with 1µF

This waveform brings the ripple down to roughly +/- 10mV, 80mV better than without the capacitor. The included capacitor has smoothed the input voltage to the ADC which should, therefore, reduce the spikes in DU read on the Hyperterminal.

DU 1u Cap.png
DU Readings with 1µF Capacitor

As shown, the DU ranges from 3661 to 3681, a difference of 20. The values above are an improvement from the non-smoothed output but further work needs to be done to achieve an accurate voltage within 100mV comfortably.

 

Software Compensation

To further improve the accuracy of the system we can use code to get the average of an array that reads in values from the ADC. First an array of integers must be made to store the DU values. Ideally, an infinite number of elements would be used for accuracy but for low power usage, only 16 elements were used.

int ADC_SamplesV[15], N;
float V_Avg = 0;
for(N = 0; N < 15; N++){
  sConfig.Channel = ADC_CHANNEL_5; // The channel that reads voltage
  HAL_ADC_ConfigChannel(&hadc1, &sConfig);
  ADC_SamplesV [N] = Read_Analog_Value(); // DU is added to the array
  V_Avg += ADC_SamplesV [N]; // the Nth element is added to the variable
  HAL_Delay(1);
}
VDU = V_Avg/N; // finds average of all 16 values

The for loop iterates through the ADC_SamplesV array, where the elements are added to a variable, V_Avg. This is done until it reaches its 15th element where it exits the array and the average is found by dividing the sum of the array, V_Avg, by the length of the array, N.

For loop Cap

As seen above, the biggest deviation between the values is 5DU, 15 better than the non-compensated system and almost 100 better than the original.

ADC Reference Voltage

Even with the capacitor on the output and the software compensation, there are still some small, unexplained jumps in DU. One reason for this may be the ADC reference voltage which can have a ripple just like the output of the power module.

In our MCU (Cortex L4), a SAR (Successive Approximation Register) approach is used. For this approach, the input voltage is found by continuously comparing the analogue input to the voltage dictated by the SAR.

Image result for sar adc schematic
SAR Type ADC

 

If the reference voltage had a ripple of 10mV this would make our reference voltage 3.31V and a given input voltage of 2V would result in an error of approximately 8 digital units. To rectify this problem a capacitor would have to be included just like before, but because these components are within the chip we are unable to solve the problem.

ADC

Introduction

For the next part of this project, we will now focus on the wind turbine. We are required to determine the voltage, current and the power being outputted by the wind turbine. To do this another micro-controller was connected to the power measurement PCB with the necessary components will be used.

The wind turbine generates a voltage between 0 and 24V,  to simulate this in the lab a power supply with a 10-ohm load was used. The power measurement PCB has been designed so that it can determine the voltage being generated using an Optocoupler and it can also determine the current by using the ACS758 current sensor. The outputs of the voltage and current are then connected into two separate ADC pins in the chip. From here the power can then be found by calculating the product of the two.

Voltage Measurement

Optocoupler

Firstly, we focused on the voltage component and the SFH6156 Optocoupler. The chip being used can only take a maximum input voltage of 3.3V into the ADC, therefore, something like a voltage divider or a Wheatstone bridge would need to be used in order to obtain a proportional voltage in 0 – 3.3V range. However, since this circuit is required to provide electrical insulation an Optocoupler was used instead.

An Optocoupler is an electronic component that interconnects two separate electrical circuits by means of a light-sensitive optical interface.

Optocoupler

The Optocoupler allows you to transmit an electrical signal between two isolated circuits. It has two parts inside the black box, an LED that emits an infrared light and a photosensitive device which detects the light from the LED. When a current is applied to the input the infrared LED begins to emit a light which is proportional to the current. The receiving photosensitive device then switches on and conducts a current the same as an ordinary transistor might.

optoisolator.jpg
Enter a caption

For our Optocoupler the input range is 0 – 24V and the output range is 0 – 3.3V however, the relationship between input and output is inversely proportional for our circuit.

Testing

We began testing this component by stepping up the voltage in steps of 1V from the power supply from 0-24V and using the multimeter, we recorded the output of this in a table in excel. We then graphed the relationship of the input of the power source (Turbine) vs the output which would be the input to the ADC as can be seen below.

Turbine vs ADC bad graph
Turbine Voltage vs ADC Voltage (0-24V)

From this graph, it can be seen that the graph is flat at the beginning but then it starts to transition into a steady slope until it reaches about 16V where it then flattens out and the change in the ADC voltage is minuscule from 16-24V.

Since we did not design the circuit ourselves as it was designed and built by a previous student, we decided we could only use this module to measure values between 4-16V accurately. This was not a problem for the lower ranges as the minimum voltage the wind turbine would usually produce was roughly 5V so ignoring the inaccuracy of the lower voltages was acceptable. As can be seen in the graph obtained below when the range is reduced, the relationship is much more linear than before however, it is still not perfect.

4-16 from first analysis
Turbine Voltage vs ADC Voltage (4-16V)

We discussed the results and the limitations of the power module with our project supervisor and during this discussion it was decided that if a larger resistor was used at the input to the optocoupler then this would allow for a wider range of values at the output. This is due to the fact that there would be less voltage and less current going into the input of the opto-coupler when a larger resistor is added. The circuit diagram for the opto-coupler we used can be seen below and we changed the value of R13 from a 3.3KΩ to a 5.6KΩ resistor.

Optocoupler circuit diagram
Optocoupler Circuit Diagram

Previously, the change in output voltage of the opto-coupler was miniscule from 16-24V as the opto-coupler had reached a point where the difference in input current made almost no difference to the output current. Therefore, by changing the resistor to a larger value the current was then reduced which allowed for more change in the output current of the opto-coupler. This then led to a larger range of output voltage of the opto-coupler when tested as can be seen in the graph below.

Full range with new resistor
Turbine Voltage vs ADC Voltage (4-24V) With New Resistor

The graph we obtained from our results was far superior to our previous results as we could now measure values from 4-24V. The relationship between the input and output was not completely linear, so we decided that using a piecewise method with several different functions for the different ranges would be a good solution to the problem.

Added 5.6k ohm resistor instead of 3.3k ohm

No capacitor = +- 100mV

added one 82nF nano capacitor(attach images) = +-45

then added 1uF (micro Farad) which worked much better  = +-10

period for all roughly 1ms (millisecond)

while (1)
{
   Value = HAL_ADC_GetValue(&amp;hadc1);
   sprintf(aTxBuffer, "Digi<span id="mce_SELREST_start" style="overflow:hidden;line-height:0;"></span>tal Value = %ld \n", Value);
   Mensa_debug_Usart1(aTxBuffer);
   sprintf(aTxBuffer, "S = %d \n \n", S);
   Mensa_debug_Usart1(aTxBuffer);
   HAL_Delay (1000);
   /* USER CODE END WHILE */
}

 

 

LED task

The project began as we were given an STM32F303VCTx microcontroller. In order to do the project at hand, we first would have to understand how to use this controller with STM32CubeMX and Attolic true studio. So we were given the task of making a group of LED’s blink in order by changing the state of the pins on the microcontroller. In order to do this, it was necessary to set and reset different GPIO pins on the microcontroller.

In order to complete this task, an array was set up with eight different parameters for the eight different LED’s. A simple for loop was then used to make the LED’s blink in order clockwise from 1-8 then anti-clockwise from 8-1. All of this was then put inside a while loop so that the LED’s would be in a constant loop blinking clockwise and anti-clockwise while the program was running.