No ACL setup yet! Denying access to everyone.
en:edu:zmitac:macro:iot:labesp32

Differences

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

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
en:edu:zmitac:macro:iot:labesp32 [2020/03/11 11:38] – [Laboratory scenarios] pczekalskien:edu:zmitac:macro:iot:labesp32 [2020/03/12 11:08] (current) – [Laboratory scenarios] pczekalski
Line 47: Line 47:
 | 5   | LCD                  | GPIO5, GPIO18-19, GPIO21-23, GPIO25                                 |                                                                                                         | | 5   | LCD                  | GPIO5, GPIO18-19, GPIO21-23, GPIO25                                 |                                                                                                         |
  
 +<note important>Note - GPIOs 34, 35, 36 and 39 do not have internal pull-up nor pull-down resistors so you may use them as inputs only.</note>
  
 == DHT11 == == DHT11 ==
Line 52: Line 53:
  
 == Touch sensor == == Touch sensor ==
-This sensor uses a switch button so it simply shorts connection of the GPIO line, binary way. By the power, it requires single GPIO to operate.+This sensor uses a switch button so it simply shorts connection of the GPIO line, binary way. By the power, it requires single GPIO to operate. Note pinout on the button board. Power it from 3.3V (**__not from 5V!__**). Observe board for correct pinout. **- (minus)** stands for GND, **S** for signal from the button, remaining is **+**, note 3.3V, not 5V! 
 +<figure ButtonSensorBoard> 
 +{{:en:edu:zmitac:macro:iot:switch_button.jpg?nolink&200 |Button sensor boards}} 
 +<caption>Button sensor board</caption> 
 +</figure> 
 +<note warning>Do not power sensor with 5V even if available on the development board. Your ESP32 may not tolerate inputs higher than 3.3V!</note>
  
 === Actuators === === Actuators ===
Line 95: Line 101:
 </code> </code>
  
-**Task 1** - using the serial port to send periodically Hello World to your PC via COM port \\ +**Task 1** - using the serial port to send Hello World periodically to your PC via COM port \\ 
-Serial port communication is very useful to trace (not DEBUG!) actions taken in your implementation. Here is, how to start: +Serial port communication is handy to trace (not DEBUG!) actions taken in your implementation. Here is, how to start: 
-  * In a ''setup()'' section of the code, start your serial communication providing speed (usually 9600 or 115200 but virtually any common serial port communication speed is OK here, but please note, you need o change it accordingly in VS Code Serial Monitor tool: default is 9600 so we suggest to use it).+  * In a ''setup()'' section of the code, start your serial communication providing speed (usually 9600 or 115200 but virtually any common serial port communication speed is OK here, but please note, you need o change it accordingly in VS Code Serial Monitor tool: default is 9600, so we suggest to use it).
   * Whenever you want to send something to the console, use ''print'' or ''println'' functions.   * Whenever you want to send something to the console, use ''print'' or ''println'' functions.
-  * As serial port is bidirectional one, you can also "read" input from the serial stream but we won't use this feature in this scenario.+  * As serial port is bidirectional one, you can also "read" input from the serial stream, but we won't use this feature in this scenario.
  
 <note tip>To delay execution of the code, you can safely call ''delay(x)'' where ''x'' is a time in milliseconds to temporary stop execution of your code. It is useful in case of the ''loop()'' function to let you be able to observe results.</note> <note tip>To delay execution of the code, you can safely call ''delay(x)'' where ''x'' is a time in milliseconds to temporary stop execution of your code. It is useful in case of the ''loop()'' function to let you be able to observe results.</note>
Line 182: Line 188:
 </code> </code>
  
-A number of useful functions to handle LCD operations is presented below (but not limited to):+Some useful functions to handle LCD operations are presented below (but not limited to):
 <code c> <code c>
 ... ...
Line 194: Line 200:
  
 ** Task 6 ** - using hardware, GPIO interrupts\\ ** Task 6 ** - using hardware, GPIO interrupts\\
-Handling external sensors that interface physics, like i.e. button, requires asynchronous approach and hardware interrupts. One can implement easily a button handler that executes some code when the button is pressed. Actually, interrupt handler routine should be kept as simple and quick, as possible, so here the approach is to set a "do action" flag, then handle it in the regular ''loop()'' code.+Handling external sensors that interface physics, like, i.e. button, requires asynchronous approach and hardware interrupts. One can implement easily a button handler that executes some code when the button is pressed. Interrupt handler routine should be kept as simple and quick, as possible, so here the approach is to set a "do action" flag, then handle it in the regular ''loop()'' code.
  
 The task is to implement a code that handles asynchronously and implements bistable switch: the first click causes red led to switch on, next to switch it off and so on. Parallel, you should count the number of clicks and present them over the serial port (but only when button has been pressed, not continuously. The task is to implement a code that handles asynchronously and implements bistable switch: the first click causes red led to switch on, next to switch it off and so on. Parallel, you should count the number of clicks and present them over the serial port (but only when button has been pressed, not continuously.
  
-You can use virtually any switch but for this lab, we will use a switch button module. Please note correct pinout. Connect **-** to board's GND, **+** to 3.3V (__**NOT 5V!**__) and **S** to the chosen GPIO port. Do not use GPIOs that are used by LED, LCD and JTAG even, if they're exposed on the connectors.+You can use virtually any switch, but for this lab, we will use a switch button module. Please note correct pinout. Connect **-** to board's GND, **+** to 3.3V (__**NOT 5V!**__) and **S** to the chosen GPIO port. Do not use GPIOs that are used by LED, LCD and JTAG even, if they're exposed on the connectors. 
 + 
 +In the beginning section of your code, define constants, structures and singletons for interrupt handling.  
 +<code c> 
 +... 
 +#define buttonGPIOPin 39   //sensor board is connected to the GPIO 39 
 +#define REDLED 0 
 +... 
 +</code> 
 +Here the approach is to keep all data related to the handler and interrupt as a separate structure, but you may choose to use plain variables: 
 +<code c> 
 +... 
 +struct ButtonPressHandler { 
 +  int numberOfClicks; 
 +  bool handleInterrupt;  //A flag, showing there is a need to do the action 
 +  bool bLEDIsOn;         //Digital twin variable for the LED state. 
 +}; 
 + 
 +ButtonPressHandler bph1 = {0, false, false}; 
 +... 
 +</code> 
 + 
 +Then declare a function that will be called, when an interrupt has been triggered. Keep this function shortest possible, not to block code execution in the main loop thus not to interfere and starve other tasks: 
 +<code c> 
 +... 
 +void IRAM_ATTR InterruptHandler(){ 
 +  bph1.handleInterrupt = true; 
 +  bph1.numberOfClicks++; 
 +} 
 +... 
 +</code> 
 + 
 +To bind the physical action and virtual one need to bind a handler to the interrupt, in the context of the GPIO (usually in the ''setup()'' section of the code).  
 +<code c> 
 +... 
 +  pinMode(buttonGPIOPin, INPUT_PULLUP); 
 +  attachInterrupt(buttonGPIOPin, InterruptHandler, FALLING); 
 +... 
 +</code> 
 +Please note the last argument of the binding function: ''FALLING'' - this one means that ''InterruptHandler'' will be executed when ''buttonGPIOPin'' changes its state from 1 to 0. 
 +You will observe, however, that action is triggered actually when you push the button, not release it. The reason is the button board is constructed the way that pushing the button shorts it with GND, not Vcc thus works in opposite logic than expected.\\ There are 5 modes that define the moment the interrupt routine is executed: 
 +  * LOW - when a pin is low (GND) 
 +  * HIGH - when a pin is high (Vcc) 
 +  * CHANGE - when a pin changes from 1 to 0 or opposite 
 +  * FALLING - when a pin changes from 1 to 0 
 +  * RISING - when a pin changes from 0 to 1 
 + 
 +Finally, in the ''loop()'' section of your source code, you need to handle all actions that should be taken, when the interrupt was triggered, testing interrupt flag that is set in the interrupt handling function, previously: 
 +<code c> 
 +... 
 +if (bph1.handleInterrupt) 
 +{ 
 +... 
 +} 
 +... 
 +</code> 
 + 
 +You may observe that for single button press an interrupt is triggered not once but many times. That is natural because of the physical switch connection oscillations. To avoid it, introduce the minimum time that is necessary between subsequent interrupt triggers. a function ''micros()'' will help you here. 
 +<note tip>Use ''micros()'' not ''millis()'' as ADC conversion is pretty quick and usually takes less than a ms.</note> 
 + 
 +** Task 7 ** - reading analog data\\ 
 +In this task, you will read analogue data via integrated ADCs.\\ 
 +Hardware part includes use of the "Joystick" sensor, composed of two potentiometers (one per axis) and a button (we do not use it here). 
 +__Please note correct pinout. Connect **GND** to board's GND, **5V** to 3.3V (**NOT 5V!**) even if on-board print states 5V.!__. Analogue resistance (voltage divider) goes through VRx and VRy.\\ 
 + 
 +ESP32 has 15 channels exposed (18 total) of the up to 12-bit resolution ADCs. Reading of the raw data (12-bit resolution is the default, 8 samples per measure as default) is easy using ''analogRead()'' function. \\ 
 +Technically, under the hood on the hardware level, there are two ADCs (ADC1 and ADC2). ADC 1 uses GPIOs 32 through 39. ADC2 GPIOs 0,2,4, 12-15 and 25-27. Note, ADC2 is used for WiFi purposes so you cannot use it when WiFi communication is enabled (so cannot you use GPIOs). Other limitations include use of GPIOs 0, 2, 4 an 15 in ESP WROVER KIT as mentioned above (those are already bound to other hardware). \\ 
 +Just execute ''analogRead(GPIO)''.\\ 
 +A number of useful functions is here (not limited to): 
 +  * ''analogReadResolution(res)'' - where ''res'' is a value between 9 and 12 (default 12). For 9-bit resolution, you get 0..511 values, for 12-bit resolution, it is 0..4095 respectively.  
 +  * ''analogSetCycles(ccl)'' - where ''ccl'' is number of cycles per ADC sample. Default is 8, valid number is between 1 and 255. 
 +  * ''analogSetClockDiv(divider)'' - sets base clock divider for the ADC. That has an impact on the speed of conversion. 
 +  * ''analogSetAttenuation(a)'' and ''analogSetPinAttenuation(GPIO,a)'' - sets input attenuation (for all channels or for selected channel). Default is ''ADC_11db''. This paremeter reflects dynamic scalling of the input value: 
 +    * ''ADC_0db'' - no attenuation (1V on input = 1088 reading on ADC), so full scale is 0..1.1V 
 +    * ''ADC_2_5db'' - 1.34 (1V on input = 2086 reading on ADC), so full scale is 0..1.5V 
 +    * ''ADC_6db'' - 1.5 (1V on input = 2975 reading on ADC), so full scale is 0..2.2V 
 +    * ''ADC_11db'' - 3.6 (1V on input = 3959 reading on ADC), so full scale is 0..3.9V 
 + 
 +<note important>Do not execute consequent way ''analogRead()''. As technically all channels use same two registers (ADC1 and ADC2) you need to give it some time to sample (i.e. ''delay(100)'' between consecutive reads on different channels).</note> 
 + 
 +During your exercise, you may start from informing ESP to start sampling on particular GPIOs, usually in the ''setup()'' function: 
 +<code c> 
 +... 
 +#define VRxPIN 25 
 +#define VRyPIN 26 
 +... 
 +void setup() 
 +{ 
 +... 
 +  adcAttachPin(VRxPIN); 
 +  adcAttachPin(VRyPIN); 
 +  // here you can also change clock divider, number of cycles per sample and so on. 
 +... 
 +} 
 +</code>
 ==== Resources ==== ==== Resources ====
   - [[https://www.espressif.com/en/products/hardware/esp-wrover-kit/resources|ESP32 WROVER kit starting page]]   - [[https://www.espressif.com/en/products/hardware/esp-wrover-kit/resources|ESP32 WROVER kit starting page]]
en/edu/zmitac/macro/iot/labesp32.1583923091.txt.gz · Last modified: by pczekalski