Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
en:iot-open:practical:hardware:sut:stm32:emb2_1 [2024/04/21 10:12] – created ktokarzen:iot-open:practical:hardware:sut:stm32:emb2_1 [2024/04/21 11:25] (current) – [Result validation] ktokarz
Line 13: Line 13:
 Reading of the ADC is possible using the regular ''analogRead(pin)'' function. In STM32WB55 there are 16 analogue inputs, and the potentiometer is connected to the pin A4 (PC_3 in Nucleo numbering). Reading of the ADC is possible using the regular ''analogRead(pin)'' function. In STM32WB55 there are 16 analogue inputs, and the potentiometer is connected to the pin A4 (PC_3 in Nucleo numbering).
  
-<note tip>In STM32, ADC has by default a 12-bit resolution, so valid return values are 0...4095;</note>+<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)function call</note>
 ===== Prerequisites ===== ===== Prerequisites =====
 To implement this scenario, it is advised to get familiar with at least one of the following scenarios first: To implement this scenario, it is advised to get familiar with at least one of the following scenarios first:
Line 34: Line 34:
  
 //Prototypes //Prototypes
-void setPotentiometer(TwoWire&  I2CPipe, byte potValue, POT_ID potNumber); +void setPotentiometer(TwoWire&  I2CDev, byte potValue, POT_ID potNumber); 
-byte readPotentiometer(TwoWire& I2CPipe, POT_ID potNumber);+byte readPotentiometer(TwoWire& I2CDev, POT_ID potNumber);
  
 //Implementation //Implementation
-void setPotentiometer(TwoWire& I2CPipe, byte potValue, POT_ID potNumber)+void setPotentiometer(TwoWire& I2CDev, byte potValue, POT_ID potNumber)
  {    {  
-  I2CPipe.beginTransmission(DS1803_ADDRESS); +  I2CDev.beginTransmission(DS1803_ADDRESS); 
-  I2CPipe.write(potNumber); +  I2CDev.write(potNumber); 
-  I2CPipe.write(potValue);   +  I2CDev.write(potValue);   
-  I2CPipe.endTransmission(true);+  I2CDev.endTransmission(true);
  };  };
  
-byte readPotentiometer(TwoWire& I2CPipe, POT_ID potNumber) //reads selected potentiometer+byte readPotentiometer(TwoWire& I2CDev, POT_ID potNumber) //reads selected potentiometer
  {  {
   byte buffer[2];     byte buffer[2];  
-  I2CPipe.requestFrom(DS1803_ADDRESS,2); +  I2CDev.requestFrom(DS1803_ADDRESS,2); 
-  buffer[0]=I2CPipe.read(); +  buffer[0]=I2CDev.read(); 
-  buffer[1]=I2CPipe.read();+  buffer[1]=I2CDev.read();
   return (potNumber==POT_1?buffer[0]:buffer[1]);   return (potNumber==POT_1?buffer[0]:buffer[1]);
  };  };
Line 59: Line 59:
 ===== Suggested Readings and Knowledge Resources ===== ===== Suggested Readings and Knowledge Resources =====
   * [[en:iot-open:introductiontoembeddedprogramming2:cppfundamentals]]   * [[en:iot-open:introductiontoembeddedprogramming2:cppfundamentals]]
-  * [[en:iot-open:hardware2:esp32|]] +  * [[en:iot-open:hardware2:stm32|]] 
-  * [[en:iot-open:practical:hardware:sut:esp32|]]+  * [[en:iot-open:practical:hardware:sut:stm32|]]
   * [[en:iot-open:embeddedcommunicationprotocols2:twi|]]   * [[en:iot-open:embeddedcommunicationprotocols2:twi|]]
   * [[https://www.analog.com/en/products/ds1803.html| DS1803 documentation (external link)]]   * [[https://www.analog.com/en/products/ds1803.html| DS1803 documentation (external link)]]
Line 66: Line 66:
  
 ==== Task to be implemented ==== ==== 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 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).+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 ==== ==== 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 these steps, we present only 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 present in other scenarios. Remember to include the functions above in your code unless you want to integrate them with your solution.+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 ==== ==== Steps ====
-Below, we assume that you have embedded functions handling operations on the digital potentiometer as defined above in your source file. Remember to add ''Wire.h'' include! +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 ''Wire.h'' library. 
-<note tip>Note: Step presents some stub code for displaying data on an OLED display.</note>+<note tip>Note: Steps 4 and present some code for displaying data on an OLED display.</note>
 === Step 1 === === Step 1 ===
-Define I2C bus GPIOs: clock (SCL) uses GPIO 4 and data (SDA) GPIO 5. ADC uses GPIO 7. Digital potentiometer chip DS1803 uses 0x28 I2C address. All definitions are present in the following code:+Define ADC pin and Digital potentiometer chip DS1803 I2C address. All definitions are present in the following code:
 <code c> <code c>
-#define SCL 4 +#define POT_ADC A4
-#define SDA 5 +
-#define POT_ADC 7+
 #define DS1803_ADDRESS 0x28 #define DS1803_ADDRESS 0x28
 </code> </code>
 +
 === Step 2 === === Step 2 ===
 Declare an array of readings that fits an OLED display. Adjust for ePaper resolution (horizontal) if using it. OLED is 128x128 pixels: Declare an array of readings that fits an OLED display. Adjust for ePaper resolution (horizontal) if using it. OLED is 128x128 pixels:
Line 87: Line 87:
 static int16_t aGraphArray[128];  static int16_t aGraphArray[128]; 
 </code> </code>
 +
 === Step 3 === === Step 3 ===
 Include functions present in the PREREQUISITES section. Include functions present in the PREREQUISITES section.
 +
 === Step 4 === === Step 4 ===
-Initialise the I2C bus and configure ADC's GPIO as input:+Initialise the I2C bus and configure ADC's GPIO as input. Change the ADC resolution to 12-bits.
 <code c> <code c>
-  Wire.begin(SDA,SCL); +  Wire.begin();
-  delay(100);+
   pinMode(POT_ADC, INPUT);   pinMode(POT_ADC, INPUT);
 +  analogReadResolution(12);
 </code> </code>
  
 === Step 4 === === Step 4 ===
-Read the loopback characteristics of the digital potentiometer to ADC loop and store it in the array:+Perform the loop that sets 128 values (scaled to the range 0 to 256) on the potentiometer's output and read the value back from the digital potentiometer via ADC input. Store readings in the array:
 <code c> <code c>
 for(byte i=0; i<128; i++) for(byte i=0; i<128; i++)
   {    { 
-    setPotentiometer(I2CPipe, 2*i, POT_1); +    setPotentiometer(Wire, 2*i, POT_1); 
     aGraphArray[i]=analogRead(POT_ADC);     aGraphArray[i]=analogRead(POT_ADC);
   }   }
 </code>  </code> 
 +<note>
 +We use 128 values because the OLED display's resolution is 128x128 pixels.
 +</note>
  
 === Step 5 === === Step 5 ===
 Display on the OLED. Assume the following handler to the pointer to the display controller class:  Display on the OLED. Assume the following handler to the pointer to the display controller class: 
 <code c> <code c>
-SSD1306Wire& display+Adafruit_SSD1351 oled
 </code>  </code> 
-More information in the scenario [[en:iot-open:practical:hardware:sut:esp32:emb7_1|]]. +More information on OLED display is in the scenario [[en:iot-open:practical:hardware:sut:stm32:emb7_1|]]. 
-Note, ADC measures in the 12-bit mode (we assume such configuration, adapt ''factor'' if using other sampling resolution), so values stored in an ''aGraphArray'' array are between 0 and 4095. +Note, ADC measures in the 12-bit mode (we assume such configuration, adapt ''factor'' if using other sampling resolution), so values stored in an ''aGraphArray'' array are between 0 and 4095.
 <code c> <code c>
- float factor = 63./4095.;+ float factor = 128./4095.;
  for(byte x=0;x<128;x++)  for(byte x=0;x<128;x++)
   {   {
-    int16_t y=63-round(((float)aGraphArray[x])*factor);+    int16_t y=128-round(((float)aGraphArray[x])*factor);
     display.setPixel(x,y);     display.setPixel(x,y);
   }   }
Line 124: Line 129:
 </code> </code>
 ==== Result validation ==== ==== Result validation ====
-A relation between the potentiometer set value and ADC reading should be almost linear from 0V up to about 3V. It becomes horizontal because the ESP32 chip limits the ADC range to 3V, so going beyond 3V (and due to the electronic construction as in figure {{ref>figuredigipot}} it may go to about 3.3V) gives no further increase but rather a reading of the 4096 value (which means the input voltage is over the limit). For this reason, your plot may be finished suddenly with a horizontal instead of linearity decreasing function. It is by design. ADC input of the ESP32 can tolerate values between 3V and 3.3V. The linear correlation mentioned above is never perfect, either because of the devices' implementation imperfection (ESP32's ADC input and digital potentiometer output) or because of the electromagnetic noise. There are many devices in our lab room.+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' implementation imperfection (STM32's ADC input and digital potentiometer output) or because of the electromagnetic noise. There are many devices in our lab room.
  
 ===== FAQ ===== ===== FAQ =====
en/iot-open/practical/hardware/sut/stm32/emb2_1.1713694362.txt.gz · Last modified: 2024/04/21 10:12 by ktokarz
CC Attribution-Share Alike 4.0 International
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0