This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revision | |||
| en:iot-open:practical:hardware:sut:stm32:emb2_1 [2024/04/21 14:23] – [Steps] ktokarz | en:iot-open:practical:hardware:sut:stm32:emb2_1 [2024/04/21 14:25] (current) – [Result validation] ktokarz | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | ====== STM_2: Using a digital potentiometer ===== | ||
| + | Digital potentiometer DS1803 is an I2C-controlled device that digitally controls the resistance between the outputs as in a real turning potentiometer.\\ While in the turning potentiometers, | ||
| + | DS1803 has two digital potentiometers controlled independently. We use just one with the lower cardinal number (index 0). In our example, it is a 100k spread between GND and VCC, and its output is connected to the ADC (analogue to digital converter) input of the STM32 SoC. This way, the potentiometer' | ||
| + | The device' | ||
| + | The digital potentiometer in our laboratory node forms then a loopback device: it can be set (also read) via I2C, and the resulting voltage can be measured on the separate PIN (ADC) {{ref> | ||
| + | <figure figuredigipot> | ||
| + | {{ : | ||
| + | < | ||
| + | </ | ||
| + | <note tip>The potentiometer has an 8-bit resolution, so the resistance step is 100k/ | ||
| + | |||
| + | Reading of the ADC is possible using the regular '' | ||
| + | |||
| + | <note tip>In STM32, ADC has a 12-bit resolution but the AnalogRead() function uses a 10-bit resolution by default, so valid return values are 0...1023. If you want to have full 12-bit resolution use analogReadResolution(12); | ||
| + | ===== Prerequisites ===== | ||
| + | To implement this scenario, it is advised to get familiar with at least one of the following scenarios first: | ||
| + | * [[en: | ||
| + | * [[en: | ||
| + | * [[en: | ||
| + | They enable you to present the data on the display (i.e. readings). | ||
| + | |||
| + | To handle communication with the DS1803 digital potentiometer, | ||
| + | < | ||
| + | #include < | ||
| + | </ | ||
| + | <note important> | ||
| + | |||
| + | Below, we present a sample control library that you need to include in your code: | ||
| + | <code c> | ||
| + | |||
| + | enum POT_LIST {POT_1 = 0xA9, POT_2=0xAA, POT_ALL=0xAF}; | ||
| + | typedef enum POT_LIST POT_ID; | ||
| + | |||
| + | // | ||
| + | void setPotentiometer(TwoWire& | ||
| + | byte readPotentiometer(TwoWire& | ||
| + | |||
| + | // | ||
| + | void setPotentiometer(TwoWire& | ||
| + | | ||
| + | I2CDev.beginTransmission(DS1803_ADDRESS); | ||
| + | I2CDev.write(potNumber); | ||
| + | I2CDev.write(potValue); | ||
| + | I2CDev.endTransmission(true); | ||
| + | }; | ||
| + | |||
| + | byte readPotentiometer(TwoWire& | ||
| + | { | ||
| + | byte buffer[2]; | ||
| + | I2CDev.requestFrom(DS1803_ADDRESS, | ||
| + | buffer[0]=I2CDev.read(); | ||
| + | buffer[1]=I2CDev.read(); | ||
| + | return (potNumber==POT_1? | ||
| + | }; | ||
| + | </ | ||
| + | |||
| + | <note important> | ||
| + | ===== Suggested Readings and Knowledge Resources ===== | ||
| + | * [[en: | ||
| + | * [[en: | ||
| + | * [[en: | ||
| + | * [[en: | ||
| + | * [[https:// | ||
| + | ===== Hands-on Lab Scenario ===== | ||
| + | |||
| + | ==== Task to be implemented ==== | ||
| + | Iterate over the potentiometer settings, read related voltage readings via ADC, and present them in graphical form (as a plot). As the maximum resolution of the potentiometer is 256, you can use a plot of 256 points or any other lower value covering all ranges. Present graph (plot) on either ePaper or OLED display, and while doing the readings, you should present data in the LCD (upper row for a set value, lower for a reading of the ADC). | ||
| + | |||
| + | |||
| + | ==== Start ==== | ||
| + | Check if you can see all the displays. Remember to use potentiometer 1 (index 0) because only this one is connected to the ADC input of the ESP32 MCU. In steps 1-3, we present how to handle communication with a digital potentiometer and how to read the ADC input of the MCU. Methods for displaying the measurements and plotting the graph are presented in steps 4 and 5. Remember to include the functions above in your code unless you want to integrate them with your solution. | ||
| + | |||
| + | ==== Steps ==== | ||
| + | Below, we assume that you have embedded functions handling operations on the digital potentiometer as defined above in your source file. Remember to include the '' | ||
| + | <note tip> | ||
| + | === Step 1 === | ||
| + | Define ADC pin and Digital potentiometer chip DS1803 I2C address. All definitions are present in the following code: | ||
| + | <code c> | ||
| + | #define POT_ADC A4 | ||
| + | #define DS1803_ADDRESS 0x28 | ||
| + | </ | ||
| + | |||
| + | === Step 2 === | ||
| + | Declare an array of readings that fits an OLED display. Adjust for ePaper resolution (horizontal) if using it. OLED is 128x128 pixels: | ||
| + | <code c> | ||
| + | static int16_t aGraphArray[128]; | ||
| + | </ | ||
| + | |||
| + | === Step 3 === | ||
| + | Include functions present in the PREREQUISITES section. | ||
| + | |||
| + | === Step 4 === | ||
| + | Initialise the I2C bus and configure ADC's GPIO as input. Change the ADC resolution to 12-bits. | ||
| + | <code c> | ||
| + | Wire.begin(); | ||
| + | pinMode(POT_ADC, | ||
| + | analogReadResolution(12); | ||
| + | </ | ||
| + | |||
| + | === Step 4 === | ||
| + | Perform the loop that sets 128 values (scaled to the range 0 to 256) on the potentiometer' | ||
| + | <code c> | ||
| + | for(byte i=0; i<128; i++) | ||
| + | { | ||
| + | setPotentiometer(Wire, | ||
| + | aGraphArray[i]=analogRead(POT_ADC); | ||
| + | } | ||
| + | </ | ||
| + | < | ||
| + | We use 128 values because the OLED display' | ||
| + | </ | ||
| + | |||
| + | === Step 5 === | ||
| + | Display on the OLED. Assume the following handler to the pointer to the display controller class: | ||
| + | <code c> | ||
| + | Adafruit_SSD1351 oled | ||
| + | </ | ||
| + | More information on OLED display is in the scenario [[en: | ||
| + | Note, ADC measures in the 12-bit mode (we assume such configuration, | ||
| + | <code c> | ||
| + | float factor = 128./4095.; | ||
| + | | ||
| + | { | ||
| + | int16_t y=128-round(((float)aGraphArray[x])*factor); | ||
| + | display.setPixel(x, | ||
| + | } | ||
| + | display.display(); | ||
| + | </ | ||
| + | ==== Result validation ==== | ||
| + | A relation between the potentiometer set value and ADC reading should be almost linear from 0V up to the maximum. The linear correlation is never perfect, either because of the devices' | ||
| + | |||
| + | ===== FAQ ===== | ||
| + | **The ADC readings are changing slightly, but I have not changed the potentiometer value. What is going on?**: The ADC in ESP32 is quite noisy, mainly when using WiFi parallelly. Refer to the Coursebook and ESP32 documentation on how to increase measurement time that will make internally many readings and return to you an average. Use the '' | ||
| + | <WRAP noprint> | ||
| + | ===== Project information ===== | ||
| + | {{: | ||
| + | This Intellectual Output was implemented under the Erasmus+ KA2.\\ | ||
| + | Project IOT-OPEN.EU Reloaded – Education-based strengthening of the European universities, | ||
| + | Project number: 2022-1-PL01-KA220-HED-000085090. | ||
| + | |||
| + | **__Erasmus+ Disclaimer__**\\ | ||
| + | This project has been funded with support from the European Commission. \\ | ||
| + | This publication reflects the views of only the author, and the Commission cannot be held responsible for any use that may be made of the information contained therein. | ||
| + | |||
| + | **__Copyright Notice__**\\ | ||
| + | This content was created by the IOT-OPEN.EU Reloaded consortium, 2022, | ||
| + | The content is Copyrighted and distributed under CC BY-NC [[https:// | ||
| + | <figure label> | ||
| + | {{: | ||
| + | </ | ||
| + | </ | ||