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.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| en:edu:zmitac:macro:iot:labesp32 [2020/03/11 11:38] – [Laboratory scenarios] pczekalski | en: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> | ||
| == 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. |
| + | <figure ButtonSensorBoard> | ||
| + | {{: | ||
| + | < | ||
| + | </ | ||
| + | <note warning> | ||
| === Actuators === | === Actuators === | ||
| Line 95: | Line 101: | ||
| </ | </ | ||
| - | **Task 1** - using the serial port to send periodically | + | **Task 1** - using the serial port to send Hello World periodically |
| - | Serial port communication is very useful | + | Serial port communication is handy to trace (not DEBUG!) actions taken in your implementation. Here is, how to start: |
| - | * In a '' | + | * In a '' |
| * Whenever you want to send something to the console, use '' | * Whenever you want to send something to the console, use '' | ||
| - | * As serial port is bidirectional one, you can also " | + | * As serial port is bidirectional one, you can also " |
| <note tip>To delay execution of the code, you can safely call '' | <note tip>To delay execution of the code, you can safely call '' | ||
| Line 182: | Line 188: | ||
| </ | </ | ||
| - | A number of useful functions to handle LCD operations | + | Some useful functions to handle LCD operations |
| <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. | + | 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. |
| 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' | + | You can use virtually any switch, but for this lab, we will use a switch button module. Please note correct pinout. Connect **-** to board' |
| + | |||
| + | In the beginning section of your code, define constants, structures and singletons for interrupt handling. | ||
| + | <code c> | ||
| + | ... | ||
| + | #define buttonGPIOPin 39 // | ||
| + | #define REDLED 0 | ||
| + | ... | ||
| + | </ | ||
| + | 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; | ||
| + | bool bLEDIsOn; | ||
| + | }; | ||
| + | |||
| + | ButtonPressHandler bph1 = {0, false, false}; | ||
| + | ... | ||
| + | </ | ||
| + | |||
| + | 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++; | ||
| + | } | ||
| + | ... | ||
| + | </ | ||
| + | |||
| + | 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 '' | ||
| + | <code c> | ||
| + | ... | ||
| + | pinMode(buttonGPIOPin, | ||
| + | attachInterrupt(buttonGPIOPin, | ||
| + | ... | ||
| + | </ | ||
| + | Please note the last argument of the binding function: '' | ||
| + | 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 '' | ||
| + | <code c> | ||
| + | ... | ||
| + | if (bph1.handleInterrupt) | ||
| + | { | ||
| + | ... | ||
| + | } | ||
| + | ... | ||
| + | </ | ||
| + | |||
| + | 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 '' | ||
| + | <note tip>Use '' | ||
| + | |||
| + | ** Task 7 ** - reading analog data\\ | ||
| + | In this task, you will read analogue data via integrated ADCs.\\ | ||
| + | Hardware part includes use of the " | ||
| + | __Please note correct pinout. Connect **GND** to board' | ||
| + | |||
| + | 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 '' | ||
| + | Technically, | ||
| + | Just execute '' | ||
| + | A number of useful functions is here (not limited to): | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | |||
| + | <note important> | ||
| + | |||
| + | During your exercise, you may start from informing ESP to start sampling on particular GPIOs, usually in the '' | ||
| + | <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. | ||
| + | ... | ||
| + | } | ||
| + | </ | ||
| ==== Resources ==== | ==== Resources ==== | ||
| - [[https:// | - [[https:// | ||
en/edu/zmitac/macro/iot/labesp32.1583923091.txt.gz · Last modified: by pczekalski
