This is an automatic translation, may be incorrect in some places. See sources and examples!
| ⚠️⚠️⚠️ ** The new version of V3 is incompatible with the previous ones, see documentation, examples and brief migration guide from v2 to v3! ** <*** ⚠️⚠️⚠️ |
|---|
A light and very functional library for an encoder with a button, encoder or buttons with Arduino
Examples of use scenarios:
Compatible with all arduino platforms (used arduino functions)
Read more detailed instructions for installing libraries here
I recommend always updating the library: errors and bugs are corrected in the new versions, as well as optimization and new features are added
through the IDE library manager: find the library how to install and click "update"
Manually: ** remove the folder with the old version **, and then put a new one in its place.“Replacement” cannot be done: sometimes in new versions, files that remain when replacing are deleted and can lead to errors!
The library supports all 4 types of * incidental * encoders, the type can be configured using setenctype (type):
eb_step4_Low - active low signal (tightening to VCC).Full period (4 phases) per click.Set by defaulteb_step4_high - an active high signal (tightening to GND).Full period (4 phases) for one clickeb_step2 - half of the period (2 phases) per clickeb_step1 - a quarter of the period (1 phase) per click, as well as encoders without fixation! Diagram
To work according to the Encoder with the button, I recommend these (link, link) Round Chinese modules with broken anti -ship chains(have the type eb_step4_low according to the classification above):
! Scheme
You can tie an encoder yourself according to the following scheme (RC filters to the encoder channels + tightening of all pens to VCC): ! Scheme
Note: by default in the library of Pino Encoder, you are configured by
Inputwith the calculation of an external luster.If you have an encoder without lifting, you can use the internalInput_pullup, indicating this in the initialization of the encoder (see the documentation below).
The button can be connected to the microcontroller in two ways and give a high or low signal when pressed.The library provides for setting up setbtnlevel (level), where the level is an active button signal:
High - the button connects the VCC.Installed by default in virt-bibliotexesLow - the button connects GND.Set by default in the main libraries! Scheme
In diagrams with microcontrollers, the connection of the GND button with a PIN suspension to VCC is most often used.The tightening can be external (Pin mode must be put Input) or internal (PIN modeInput_pullup).In "real" projects, an external lifelong is recommended, becauseIt is less susceptible to interference - the internal has too high resistance.
Be up to the library
`CPP
// Disable PressFor/Holdfor/StepFor support and Stepov counter (saves 2 bytes of RAM) #define eb_no_for
// Disable the event processor attach (saves 2 bytes of RAM) #define eb_no_callback
// Disable the encoder counter Virtencoder, Encoder, Encbutton #define eb_no_counter
// Disconnect the buffer of the encoder (saves 2 bytes of RAM) #define eb_no_buffer
/* Setting up timeouts for all classes
How to work with the documentation: Encbutton starting with version 3.0 is several libraries (classes) for various use scenarios, they inherit each other to expand functionality.Thus, the library is a “onion”, each layer of which has access to the functions of the lower layers:
virtbutton - the base class of the virtual button, provides all the possibilities of the buttonsvirtencoder - the base class of the virtual encoder, determines the fact and direction of the rotation of the enkodervirtencbutton - the base class of a virtual encoder with a button, provides an encoder poll taking into account the button, *inherits Virtbututton and Virtencoder *Button,buttont - button class, *inherits virtbutton *Encoder,Encodert - Encoder class, *inherits virtencoder *ENCBUTTON,ENCBUTTONT - ENCODER class with a button, *inherits VirtenCbutton, Virtbutton, Virtencoder *Thus, to study all the available functions of a particular library, you need to watch not only it, but also what it inherits.For example, to process the button using Button, you need to open below the description ofbutton and virtbutton.
- Virtual * - without specifying a PIN of the microcontroller, works directly with the transmitted value, for example, for a survey of the enemies buttons through pain extensors and shift registers.
`T'- version of libraries require indicating Pino constants (numbers).Pino numbers will be stored in the memory of the program, this accelerates the work and makes the code easier by 1 byte for each pin.
Note:
# Include <encbutton.h>connects all the library tools!
All libraries have a general ** function of processing ** (ticker tick), which receives the current signal from the button and encoder
true when the event occurs (for encoder -1 or -1 when turning,0 in its absence. Thus, the turn in any direction is regarded as true)isr, see documentation belowThe library processes the signal inside this function, the result can be obtained from ** functions of the survey ** events.They are of two types:
[event] - the function will return true once upon the event of an event.It will be reset after the next call call (for example, click, turning enncoder)[condition] - the function returns true, while this condition is actively (for example, the button is held)For simplicity of perception, the processing function must be placed at the beginning of the cycle, and polls do below: `CPP VOID loop () { btn.tick ();// survey
if (btn.click ()) serial.println ("click");// will display once when clicking if (btn.click ()) serial.println ("click");// The same click! } `
Unlike previous versions of the library, the survey functions are not reset inside themselves, but *inside the processing function *.Thus, in the example above, when clicking on the button in the port, the message
click ()is displayed twice.This allows you to use the survey functions several times for the current iteration of the cycle to create a complex logic of the program.
For obvious reasons, it is impossible to cause the processing function more than once per cycle - each next call will drop events from the previous one and the code will work incorrectly.So - you can’t: `CPP // you can not do it this way VOID loop () { btn.tick (); if (btn.click ()) ...
// ....
btn.tick (); if (btn.hold ()) ... } `
If you really need to get into a deaf cycle and interrogate the button there, then it can: you can: `CPP // so it is possible VOID loop () { btn.tick (); if (btn.click ()) ...
While (True) {
btn.tick ();
if (btn.hold ()) ...
if (btn.click ()) Break;
} } `
If the library is used with an connected event handler Attach () (see below), then you can call tick () anywhere and as many times as you like, the events will be processed in the handler:
`CPP
// so it is possible
VOID CB () {
switch (btn.action ()) {
// ...
} }
VOID setup () { btn.attach (CB); }
VOID loop () { btn.tick (); // ... btn.tick (); // ... btn.tick (); } `
The Encbutton - ** asynchronous ** library: it does not wait until the button is completed, and allows the program to be executed further.This means that for the correct operation of the library, the main cycle of the program should be performed as quickly as possible and not contain delays and other "deaf" cycles within itself.To ensure proper processing of the button, it is not recommended to have a main delay cycle lasting more than 50-100 ms.A few tips: -beginners: to study the lesson cycle how to write a sketch
loop ()delay () can be made asynchronous using millis () `If (! Button.busy ()) {heavy code}} `yield () (inside delay ())It makes sense only with a manual survey of events!With a connected processing function, it is enough to call the usual
tick ()between the heavy sections of the program
Also, in a loaded program, you can divide the processing and reset of events: instead of tick () use tickRAW () between heavy sections of the code and manual reset Clear ().The order is as follows:
Clear ()tickRaW () between heavy sections of code`CPP VOID loop () { if (btn.click ()) ... if (btn.press ()) ... if (btn.step ()) ...
btn.clear ();
// ...
BTN.TickRAW ();
// ...
BTN.TickRAW ();
// ...
BTN.TickRAW ();
// ...
}
`
This will allow to interview the button/encoder in a not very well written program, where the main cycle is littered with heavy code.Inside the Tickrade () Events accumulate that are dismantled once in the cycle, and then manually reset.
In this scenario, the Encoder's buffering in the interruption does not work and all events are not processed
Releasexxx
If it is difficult to get rid of the delay () inside the main cycle of the program, then on some platforms you can place your code inside it.Thus, you can even get encoder processing in a cycle with deals without using interruptions:
`CPP
// Code insertion in Delay
VOID yield () {
EB.TickRAW ();
}
VOID loop () { if.click ()) ... if (btn.turn ()) ...
eb.clear ();
// ... Delay (10); // ... DELAY (50); // ... } `
In this scenario, the Encoder's buffering in the interruption does not work and all events are not processed
Releasexxx
The library processes the button as follows:
Press, the state ofPressing and Busyhold, the stateholdingstep, triggers with the STEP period while the button holdsRelease, the removal of the statesPressing and Holding
clickReleaseholdReleaseStepReleasehold andReleaseStep mutually exclusive, if the button was withheld step -Releasehold will no longer workWaitingBusy, the processing is completed
getClicks () is discarded after the events Releasehold/Releastep, which check the preliminary clicks.In the general processor Action () Events EB_REL_Hold_C orEB_REL_STEP_CHasclicks event, and you can also interview almost all the events of the buttons that go toReleasexxxTimeout is expected - Timeout event with the specified period from the current momentTick () `The difference is
Click (n)Hasclicks (n):Click (n)will returntruein any case when the number of clicks coincides, even if more clicks are made.HasClicks (n)will returntrueonly inCranberry, if the exactly indicated number of clicks was made and there were no more clicks!It is better to see once than read a hundred times.Launch an example of Demo and go on the button, or try online symulation in Wokwi
! click
! Hold
! STEP
Online symulation is available here
tick ()Counter is a public variable of the class, you can do anything with it:
`CPP
Serial.println (eb.counter);// read
Eb.counter += 1234;// change
eb.counter = 0;// Knock
`redase.The states of the pressed button do not changetimeout () function) will work after the indicated time after turning the enkoderThe library considers the number of clicks by the button and some survey functions can separately be processed with *preliminary clicks *.For example, 3 clicks, then retention.This greatly expands the capabilities of one button.There are two options for working with such events: `CPP // 1 if (btn.hold ()) {
if (btn.getclics () == 2) serial.println ("Hold 2 Clicks");
}
// 2 if (btn.hold (2)) serial.println ("Hold 2 Clicks"); `
In the first version, you can get the number of clicks for further processing manually, and in the second - the library will do this itself if the number of clicks for action is known in advance.
In some scenarios, you need to get the state of the "here and now" button, for example, determine whether the button is held immediately after starting the microcontroller (program start).The function tick () must be called constantly in the cycle so that the button is processing with the extinguishing of the ratio of contacts and other calculations, so the design of the next type ** will not work **:
`CPP
VOID setup () {
btn.tick ();
if (btn.press ()) serial.println ("button pressed at start");
}
`
The following functions will help for such scenarios, return true if the button is pressed:
read () for libraries button and buttontReadbtn () for library libraries and encbuttontThe button survey is performed taking into account the previously configured button level (Setbtnlevel)!It is not necessary to manually invert the logic:
`CPP VOID setup () { // btn.setbtnlevel (LOW);// you can configure the level
if (btn.read ()) serial.println ("button pressed at start"); } `
Suppose you need to process the button synchronously and with the extinguishing of the rattles.For example, if the button is clamped at the start of the microcontroller, get its retention or even the pulse retention inside the setup unit, that is, before the start of the main program.You can use the state of Busy and interview the button from the cycle:
`CPP
VOID setup () {
Serial.Begin (115200);
btn.tick (); While (btn.busy ()) {
btn.tick ();
if (btn.hold ()) serial.println ("Hold");
if (btn.step ()) serial.println ("step");
}
Serial.println ("Program Start");
}
`
How it works: the first tick interrogates the button, if the button is pressed - the state of the Busy is immediately activated and the system enters the `While` cycle.Inside it, we continue to tick and get events from the button.When the button is released and all events will work - the Busy flag will drop and the program will automatically leave the cycle.You can rewrite this design to the cycle with a postcryption, more beautiful:
CPP
do {
B.tn.tick ();
if (btn.hold ()) serial.println ("Hold");
if (btn.step ()) serial.println ("step");
} While (btn.busy ());
In the classes associated with the button (Button, Encbutton) there is a function Timeout (Time) - it will once return true if the indicated time has passed after the action with the button/encoder.This can be used to preserve parameters after entering, for example:
`CPP
VOID loop () {
eb.tick ();
// ...
if.timeout ()) {
// after interaction with encoder 1 second passed
// eeprom.put (0, settings);
} } `
The Busy () function Returns True while the button processing is underway, i.e.So far, the system awaits actions and the release of timeouts.This can be used to optimize the code, for example, avoid some long and heavy parts of the program during the button processing:
`CPP
VOID loop () {
eb.tick ();
// ...
if (! eb.busy ()) {
// Potentially long and difficult code
} } `
Available in all classes ** with the ** button:
virtbuttonButtonvirtencbuttonencbuttonThe function Action () when the event occurs, the event is returned (different from scratch, which in itself is an indication of the existence of an event):
eb_press - click on the buttoneb_hold - the button is kepteb_step - impulse retentioneb_release - the button is releasedeb_click - Single clickeb_clicks - A few click signaleb_turn - turn of the encodereb_rel_hold - the button is released after holdingEB_REL_HOLD_C - the button is released after holding off the premises.clicksEB_REL_STEP - the button is released after the stepEB_REL_STEP_C - the button is released after the step with a border.clicksThe result of the function
Action ()is reset after the next calltick (), that is, is available on the entire current iteration of the main cycle
The obtained event code can be processed through switch:
`CPP
switch (eb.action ()) {
Case eb_press:
// ...
Break;
Case eb_hold:
// ...
Break;
// ... } `
To maximally reduce the weight of the library (in particular in RAM), you need to set the Timatui constants through Define (saving 1 bytes per timaut), turn off the events processor, counters-buffers and use the T-class (saving 1 byte per pin):
`CPP
#define eb_no_for
#define eb_no_callback
#define eb_no_counter
#define eb_no_buffer
#define eb_deb_time 50 // Timesout to extinguish the trim button (button)
#define eb_click_time 500 // Click Stayout (button)
#define eb_hold_time 600 // Maintenance Times (button)
#define eb_step_time 200 // Impulse retention Timesout (button)
#define EB_FAST_TIME 30 // TIMAUT RAM (ENCODER)
#include <encbutton.h>
ENCBUTTONT <2, 3, 4> EB;
`
In this case, an encoder with a button will take only 8 bytes in SRAM, and just a button - 5.
To reduce the time for checking the system flags of events (insignificantly, but pleasant), you can place all the polls in the condition by tick (), since tick () returns true only when ** events **: the events **:
`CPP
VOID loop () {
if (eb.tick ()) {
if.turn ()) ...;
if.click ()) ...;
} } `
Also, a survey of events using the Action () function is performed faster than a manual survey of individual functions of events, so the library will work in this format as efficiently as possible:
CPP
VOID loop () {
if (eb.tick ()) {
switch (eb.action ()) {
Case eb_press:
// ...
Break;
Case eb_hold:
// ...
Break;
// ...
}
} } `
For polling ** states ** buttons Pressing (), Holding (), WATING () You can place them inside the conditions of BUSY () so as not to interview them until they are guaranteed:
`CPP
if (btn.busy ()) {
if (btn.pressing ()) ...
if (btn.holding ()) ...
if (btn.waiting ()) ...
}
`
You can connect the external function-shacklerCranberry, it will be caused when any event occurs.This opportunity works in all classes ** with the ** button:
virtbuttonButtonvirtencbuttonencbutton`CPP ENCBUTTON EB (2, 3, 4);
Void callback () { switch (eb.action ()) {
Case eb_press:
// ...
Break;
Case eb_hold:
// ...
Break;
// ...
} }
VOID setup () { eb.attach (callback); }
VOID loop () { eb.tick (); } `
The library supports work with two simultaneously pressed buttons as with the third button.For this you need:
virtbuttonvirtbutton,button, encbutton + theirt- version)`CPP Button b0 (4); Button b1 (5); Virtbutton B2;// 1
VOID loop () { b0.tick ();// 2 b1.tick ();// 2 B2.Tick (B0, B1);// 3
// 4 if (b0.click ()) serial.println ("b0 click"); if (b1.click ()) serial.println ("b1 click"); if (b2.click ()) serial.println ("b0+b1 click"); } `
The library itself will “drop” unnecessary events from real buttons if they were pressed together, with the exception of the event Press.Thus, a full -fledged third button of two others with a convenient survey is obtained.
For processing an encoder in a loaded program you need:
Changesetencisr (true)loop for corrething work - events are generated in the main ticker:
`CPP
// Example for Atmega328 and Encbutton
ENCBUTTON EB (2, 3, 4);/* // ESP8266/ESP32 IRAM_ATTR VOID ISR () { eb.tickisr (); } */
VOID isr () { eb.tickisr (); } VOID setup () { Attachinterrupt (0, Isr, Change); Attachinterrupt (1, ISR, Change); eb.setencisr (true); } VOID loop () { eb.tick (); } `
Note: The use of work in the interruption allows you to correctly process the encoder position and not miss a new turn.An event with a turn obtained from an interruption will become available * after * call Tick in the main cycle of the program, which allows not to violate the sequence of the main cycle:
turn event is activated only once, regardless of the number of clicks of the encoder made between the two challenges oftick (clicks are processed in interruption)turn event will be caused as many times as there were really clicks of the encoder, this allows you to not miss the turns and not load the system in the interruption.** Boofer size - 5 unprocessed clicks of encoder **Notes:
setencisr function works only in non - virtual classes.If it is turned on, the main ticker tick simply does not interview Encoder's pins, which saves processor time.Processing occurs only in interruptionIRAM_ATTR, see documentation on your platform!)Attach () will be called from Tick (), that is, *not from interruption *!In the virtual ones there is a ticker in which it is not necessary to transmit the state of the encoder, if it is processed in an interruption, this allows you to not interview pins in idle.For example:
`CPP Virtencoder e;
VOID isr () {
E.tickisr (DigitalRead (2), DigitalRead (3));
} VOID setup () {
Attachinterrupt (0, Isr, Change);
Attachinterrupt (1, ISR, Change);
E.Setencisr (1);
} VOID loop () {
E.tick ();// Do not transmit the states of Pinov
} `
To process the button in the interruption, you need:
Low - InterruptionFallinghigh - interruptionrisingPressisr () in the interruption processor`CPP Button b (2);
/* // ESP8266/ESP32 IRAM_ATTR VOID ISR () { B.Pressisr (); } */
VOID isr () { B.Pressisr (); } VOID setup () { Attachinterrupt (0, ISR, Falling); } VOID loop () { B.tick (); } `
Note: the button is processed mainly tick (), and the function Pressisr () just informs the library that the button was pressed outside Tick ().This allows you not to miss the pressing of the button until the program was busy with something else.
You can create an array only from non -step classes (without the letter t), because Pinov numbers will have to be indicated already in the radio further in the program.For example:
`CPP
Button btns [5];
ENCBUTTON EBS [3];
VOID setup () { btns [0] .init (2);// Indicate the pin btns [1] .init (5); btns [2] .init (10); // ...
EBS [0] .init (11, 12, 13, Input); EBS [1] .init (14, 15, 16); // ... } VOID loop () { for (int i = 0; i <5; i ++) btns [i] .Tick (); for (int i = 0; i <3; i ++) EBS [i] .Tick ();
if (btns [2] .Click ()) serial.println ("BTN2 click"); // ... } `
The library supports the task of its functions for reading PIN and getting time without editing library files.To do this, you need to implement the corresponding function in your .cpp or.
bool eb_read (uint8_t pin) - for its pine reading functionvoid eb_mode (uint8_t pin, uint8_t mode) - for your analogue Pinmodeuint32_t eb_uptime () - for your analogue millis ()Example:
`CPP #include
Bool eb_read (uint8_t pin) {
Return DigitalRead (PIN);
}
VOID eb_mode (uint8_t pin, uint8_t mode) {
Pinmode (PIN, Mode);
}
uint32_t eb_uptime () {
Return Millis ();
} `
Sometimes it may be necessary to call tick () not on every iteration, but by the timer.For example, for a virtual button from the Pino Expand, when reading the Pino Expand is a long operation, and it often does not make sense to call it.You can’t do this, events will be active during the timer!
`CPP
VOID loop () {
// Timer for 50 ms
Static uint32_t tmr;
if (millis () - tmr> = 50) {
TMR = Millis ();
btn.tick (Readsomepin ());
}
// will be actively within 50 ms !!! if (btn.click ()) foo (); } `
In this situation, you need to do this: tick along the timer, process events there and drop flags at the end: `CPP VOID loop () { // Timer for 50 ms Static uint32_t tmr; if (millis () - tmr> = 50) {
TMR = Millis ();
// TIK
btn.tick (Readsomepin ());
// analysis of events
if (btn.click ()) foo ();
// Reset of the flags
btn.clear ();
} } `
Or you can connect the handler and call clear () at the end of the function:
`CPP
Void callback () {
switch (btn.action ()) {
// ...
}
// Reset of the flags btn.clear (); }
VOID loop () { // Timer for 50 ms Static uint32_t tmr; if (millis () - tmr> = 50) {
TMR = Millis ();
btn.tick (Readsomepin ());
} } `
In the case of calling the timer, the anti -departments will be partially provided by the timer itself and in the library it can be turned off (set the period 0).
For the correct operation of timeouts, conditions and a click counter, you need another approach: buffering the states read according to the timer and transfer them to the TIC in the main cycle.For example: `CPP Bool Readbuf = 0;// buffer Pina
VOID loop () { // Timer for 50 ms Static uint32_t tmr; if (millis () - tmr> = 50) {
TMR = Millis ();
Readbuf = Readsomepin ();// Reading in the buffer
}
// tick from the buffer BTN.Tick (Readbuf);
if (btn.click ()) foo (); } `
`CPP // Change the values of the variables
// Turn of the encoder if (enc.turn ()) { // Change in step 5 var += 5 * enc.dir ();
// Change in step 1 with a normal turn, 10 with fast Var += ENC.FAST ()?10: 1;
// Change in step 1 with a normal turn, 10 with pressed vAR += ENC.Pressing ()?10: 1;
// Change one variable when turning, the other - with a pressed turn if (enc.pressing ()) Var0 ++; Else Var1 ++;
// If the button is pressed - preliminary clicks are available // Choose a variable for changes in the premises.Clicks if (enc.pressing ()) {
Switch (enc.getClicks ()) {
CASE 1: VAR0 += ENC.DIR ();
Break;
CASE 2: VAR1 += ENC.DIR ();
Break;
CASE 3: VAR2 += ENC.DIR ();
Break;
}
} }
// Impulse retention at every step is increasing the variable if (btn.step ()) var ++;
// Change the direction of change in the variable after letting go from STEP if (btn.step ()) var += dir; if (btn.releastep ()) die = -dir;
// Change the selected variable using STEP if (btn.step (1)) Var1 ++;// Click-holding if (btn.step (2)) Var2 ++;// Click-Click-holding if (btn.step (3)) var3 ++;// Click-Click-Click-hold
// if you keep the STEP for more than 2 seconds - an incremental +5, so far less - +1 if (btn.step ()) { if (btn.stepfor (2000)) var += 5; Else Var += 1; }
// inclusion of the mode by the number of clicks if (btn.hasclicks ()) mode = btn.getclicks ();
// inclusion of the mode by several clicks and retention if (btn.hold (1)) mode = 1;// Click-holding if (btn.hold (2)) mode = 2;// Click-Click-holding if (btn.hold (3)) mode = 3;// Click-Click-Click-hold
// or so if (btn.hold ()) mode = btn.getclicks ();
// Button is released, look how much it was held if (btn.release ()) { // from 1 to 2 seconds if (btn.pressfor ()> 1000 && btn.pressfor () <= 2000) mod = 1; // from 2 to 3 seconds Else if (BTN.PressFor ()> 2000 && BTN.PressFor () <= 3000) Mode = 2; } `
`CPP // virtual Virtencbutton eb;// Encoder with button Virtbutton b;// button Virtencoder e;// Encoder
// Real // Encoder with button ENCBUTTON EB (ENC0, ENC1, BTN);// Encoder Pins and buttons ENCBUTTON EB (ENC0, ENC1, BTN, MODEENC);// + Pino Pino Encoder Pin (silence. Input) ENCBUTTON EB (ENC0, ENC1, BTN, MODEENC, MODEBTN);// + Pin mode buttons (silent. Input_pullup) ENCBUTTON EB (ENC0, ENC1, BTN, MODEENC, MODEBTN, BTNlevel);// + button level (silence) // template ENCBUTTON EB;// Encoder Pins and buttons ENCBUTTON EB (Modeenc);// + Pino Pino Encoder Pin (silence. Input) ENCBUTTON EB (Modeenc, Modebtn);// + Pin mode buttons (silent. Input_pullup) ENCBUTTON EB (Modeenc, Modebtn, Btnlevel);// + button level (silence)
// button Button b (pin);// PIN Button b (PIN, Mode);// + Pin mode buttons (silent. Input_pullup) Button B (PIN, Mode, Btnlevel);// + button level (silence) // template Buttont b;// PIN Buttont b (mode);// + Pin mode buttons (silent. Input_pullup) Buttont b (mode, btnlevel);// + button level (silence)
// Encoder ENCODER E (ENC0, ENC1);// Pines of Encoder ENCODER E (ENC0, ENC1, Mode);// + Pino Pino Encoder Pin (silence. Input) // template Encodert e;// Pines of Encoder Encodert E (Mode);// + Pino Pino Encoder Pin (silence. Input) `
| v2 | v3 |
|---|---|
HELD () |
Hold () |
Hold () |
Holding () |
state () |
Pressing () |
setpins () |
Init () |
Clearflags () replaced by Clear () (drop the flags of events) and reset () (drop systemic flags of processing, finish processing)In the V3, the functions of an event survey (Click, Turn ...) are not discarded immediately after their call - they are discarded at the next call Tick (), thus retain their meaning in all subsequent challenges on the current iteration of the main cycle of the program.** Therefore, tick () needs to be called only 1 time per cycle, otherwise there will be missions of actions! ** Read about thisabove.
The rest of the examples look at ** Examples **!
Full demo encbutton
`CPP // #define eb_no_for // Disable Pressfor/Holdfor/StepFor support and Stepov counter (saves 2 bytes of RAM) // #define eb_no_callback // Disable the event processor Attach (saves 2 bytes of RAM) // #define eb_no_counter // Disable the enkoder counter (saves 4 bytes of RAM) // #define EB_NO_BUFFER // Disable the buffer of the encoder (saves 1 byte of RAM)
// #define eb_deb_time 50 // Timesout to darebells button (button) // #define eb_click_time 500 // Clicks standstatics (button) // #define eb_hold_time 600 // Maintenance Times (button) // #define eb_step_time 200 // pulse retention rate (button) // #define EB_FAST_TIME 30 // Quick turn Timesout (Encoder)
#include ENCBUTTON EB (2, 3, 4); // ENCBUTTON EB (2, 3, 4, Input);// + Pino Pino mode // ENCBUTTON EB (2, 3, 4, Input, Input_pullup);// + button pins mode // ENCBUTTON EB (2, 3, 4, Input, Input_pullup, Low);// + button level
VOID setup () {
Serial.Begin (115200);
// shows the default values
eb.setbtnlevel (Low);
EB.SetClicktimeout (500);
eb.Setdebtimeout (50);
Eb.SetHoldtimeout (600);
eb.setsteptimeout (200);
eb.setencreverse (0);
eb.setenctype (eb_step4_low);
eb.setfasttimeout (30);
// throw the Encoder counter
eb.counter = 0;
}
VOID loop () {
eb.tick ();
// General rotation processing
if.turn ()) {
Serial.print ("Turn: Dir");
Serial.print (eb.dir ());
Serial.print (", fast");
Serial.print (eb.fast ());
Serial.print (", Hold");
Serial.print (eb.pressing ());
Serial.print (", Counter");
Serial.print (eb.counter);
Serial.print (", clicks");
Serial.println (eb.getClicks ());
}
// Turning rotation processing
if.left ()) serial.println ("Left");
if.right ()) serial.println ("right");
if.left ()) serial.println ("Lefth");
if.righth ()) serial.println ("righth");
// button
if.press ()) serial.println ("Press");
if.click ()) serial.println ("click");
if.release ()) {
Serial.println ("Release");
Serial.print ("Clicks:");
Serial.print (eb.getClicks ());
Serial.print (", stps:");
Serial.print (eb.getsteps ());
Serial.print (", Press for:");
Serial.print (eb.pressfor ());
Serial.print (", Hold for:");
Serial.print (eb.holdfor ());
Serial.print (", step for:");
Serial.println (eb.stepfor ());
}
// States
// serial.println (eb.pressing ());
// serial.println (eb.holding ());
// serial.println (eb.busy ());
// serial.println (eb.waiting ());
// Timesout
if (eb.timeout ()) serial.println ("Timeout!");
// Holding
if.hold ()) serial.println ("Hold");
if.hold (3)) serial.println ("Hold 3");
// Impulse retention
if.step ()) serial.println ("step");
if.step (3)) serial.println ("STEP 3");
// released after impulse deduction
if (eb.releastep ()) serial.println ("Release Step");
if (eb.releastep (3)) serial.println ("Release Step 3");
// released after holding
if.releasehold ()) serial.println ("Release Hold");
if (eb.releasehold (2)) serial.println ("Release Hold 2");
// Check for the number of clicks
if.hasclicks (3)) Serial.println ("Has 3 Clicks");
// Bring the number of clicks
if.hasclicks ()) {
Serial.print ("Has Clicks:");
Serial.println (eb.getClicks ());
}
} `
`CPP #include ENCBUTTON EB (2, 3, 4);
Void callback () {
Serial.print ("callback:");
switch (eb.action ()) {
Case eb_press:
Serial.println ("Press");
Break;
Case eb_hold:serial.println ("Hold");
Break;
Case eb_step:
Serial.println ("STEP");
Break;
Case eb_release:
Serial.println ("Release");
Break;
Case eb_click:
Serial.println ("click");
Break;
Case eb_clicks:
Serial.print ("Clicks");
Serial.println (eb.getClicks ());
Break;
Case eb_turn:
Serial.print ("turn");
Serial.print (eb.dir ());
Serial.print ("");
Serial.print (eb.fast ());
Serial.print ("");
Serial.println (eb.pressing ());
Break;
Case eb_rel_hold:
Serial.println ("Release Hold");
Break;
CASE EB_REL_HOLD_C:
Serial.print ("Release Hold Clicks");
Serial.println (eb.getClicks ());
Break;
CASE EB_REL_STEP:
Serial.println ("Release Step");
Break;
CASE EB_REL_STEP_C:
Serial.print ("Release Step Clicks");
Serial.println (eb.getClicks ());
Break;
}
}
VOID setup () {
Serial.Begin (115200);
eb.attach (callback);
}
VOID loop () {
eb.tick ();
} `
`CPP #include
Button BTN (4); Buttont <5> btnt; Virtbutton BTNV;
VOID setup () {
Serial.Begin (115200);
}
VOID loop () {
// Button
btn.tick ();
if (btn.click ()) serial.println ("btn click");
// Buttont
btnt.tick ();
if (btnt.click ()) serial.println ("BTNT CLICK");
// virtbutton
btnv.tick (! DigitalRead (4));// transmit logical value
if (btnv.click ()) serial.println ("btnv click");
} `
`CPP #include
ENCODER ENC (2, 3); ENCODERT <5, 6> ENCT; Virtencoder encv;
VOID setup () {
Serial.Begin (115200);
}
VOID loop () {
// The survey is the same for everyone, 3 ways:
// 1
// Tick will return 1 or -1, then this is a step
if (enc.tick ()) serial.println (enc.counter);
// 2
// can be interviewed through turn ()
enct.tick ();
if (enct.turn ()) serial.println (enct.dir ());
// 3
// you can not use survey functions, but get the direction directly
int8_t v = encv.tick (DigitalRead (2), DigitalRead (3));
if (v) serial.println (v);// Derive 1 or -1
} `
Create ** Issue ** when you find the bugs, and better immediately write to the mail alex@alexgyver.ru The library is open for refinement and your ** pull Request ** 'ow!
When reporting about bugs or incorrect work of the library, it is necessary to indicate: