PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Arduino-Lib erstellen



HaWe
29.11.2018, 13:34
hallo,
ich habe einen eigenen Code für eine spezielle Funktion (ButtonClass zur Erkennung von 1x kurz, 2x kurz oder 1x lang gedrückt) und möchte dafür eine C++ Arduino-Lib erstellen.
Ich kann mich erinnern, hier sogar einmal eine Anleitung für Arduino Libs irgendwo gesehen zu haben, finde sie aber leider nicht mehr.
Kann und möchte mir dabei jemand u.U. helfen?
(Code ist ntl open-source)

Moppi
29.11.2018, 14:18
Gerne, ich wusste gar nicht, dass es das mal gab: https://www.roboternetz.de/community/threads/65187-Tutorial-Erstellen-einer-Arduino-Bibliothek?p=601647&viewfull=1#post601647

MfG
Moppi

HaWe
29.11.2018, 14:53
dankeschön, genau das war die Anleitung!

Ich habe da mal was vorbereitet, hier ist der Beispielcode ohne libs, mit integrierter Klasse:
(wer es ausprobieren will: Btn Pins sind hier D4 und D5, ggf anpassen!)



// Button Press Object
// (C) 2018 by HaWe

// This example code is in the public domain for private use.
// Use for professional or business purpose only by personal written permission
// by the author.

class tButton {

protected:

byte pin;
int mode;
uint32_t aktMillis, aktMillis2, intervallMillis;
int8_t level, dnstate, dnstate2, upstate, btnstate, oldbtnstate;

int8_t dtimer() {
if (millis()-aktMillis >= 6*intervallMillis) {
return 3;
}
else
if (millis()-aktMillis >= intervallMillis) {
return -1;
}
else
return 0;
}

int8_t dtimer2() {
if (millis()-aktMillis2 >= 400) {
return -1;
}
else
return 0;
}

public:

tButton () :
pin(0xFF), aktMillis(0), aktMillis2(0), intervallMillis(100),
mode(INPUT_PULLUP),
level(0), dnstate(0), dnstate2(0), upstate(0), oldbtnstate(0), btnstate(0)
{ }

void init(byte _pin, int _mode, uint32_t _intervallMillis) {
pin = _pin;
mode = _mode;
intervallMillis = _intervallMillis;
pinMode(pin, mode);
}


byte click() {

btnstate=digitalRead(pin);
if(mode==INPUT_PULLUP) btnstate=!btnstate;

if(level==0) {
dnstate=0;
if(!oldbtnstate && btnstate) { // 1st new btn down:
aktMillis=millis(); // restart btn down timer
dnstate=dtimer();
level=1; // for button stroke: next level
}
}

if(level==1) { // either btn stroke happened

//Serial.println("level1"); Serial.println(dnstate);
dnstate=dtimer();
if(!btnstate){ // 1st btn up
if(dnstate){
aktMillis2=millis();
if(dnstate==3) { // long press: finished !!
btnstate=0;
oldbtnstate=0;
level=0;
aktMillis=millis();
upstate=0;
return 3;
}
else level=2; // short press: next level
}
}
}

if(level==2) { // short press happened

//Serial.println("level2"); Serial.println(dnstate);
upstate=dtimer2(); // check btn up pause

btnstate=digitalRead(pin);
if(mode==INPUT_PULLUP) btnstate=!btnstate;

//Serial.print("upstate="); Serial.println(upstate);

if(btnstate) { // second btn click during pause: double click!
dnstate2=1;
//Serial.print(" dnstate2="); Serial.println(dnstate2);
}
while(btnstate) { // debounce after double click
btnstate=digitalRead(pin);
if(mode==INPUT_PULLUP) btnstate=!btnstate;
}

if(upstate==0 && dnstate2) { // if double click: next level
level=3;
}
else
if(upstate==-1) { // btn up pause reached:
//Serial.println(millis()-aktMillis2); // single press finished !!
dnstate=1;
dnstate2=0;
//Serial.println(dnstate);
btnstate=0;
oldbtnstate=0;
level=0;
aktMillis=millis();
aktMillis2=millis();
upstate=0;
return 1;
}
}

if(level==3) { // double click

//Serial.println("level3");
dnstate=2; // double click finished !!
dnstate2=0;
//Serial.println(dnstate);
btnstate=0;
oldbtnstate=0;
aktMillis=millis();
aktMillis2=millis();
level=4; // next level after double click
return dnstate;
}

if(level==4) { // extra wait after double click
upstate=dtimer2();
if(upstate==-1) {
level=0;
dnstate=0;
aktMillis=millis();
aktMillis2=millis();
//Serial.println("level4 extra wait finished");
}
}

oldbtnstate=btnstate;
return 0;

}
};


//------------------------------------------------------------------------

tButton btn1;
tButton btn2;

void setup() {
Serial.begin(115200);
delay(2000);
pinMode(D7, OUTPUT); // debug

Serial.println("Serial started\n");
btn1.init(D4, INPUT_PULLUP, 50);
btn2.init(D5, INPUT_PULLUP, 50);
}

//------------------------------------------------------------------------

void loop() {
int8_t btn;

btn=btn1.click();
if(btn) {
Serial.print("btn1.click()=");
Serial.println(btn);
}
btn=btn2.click();
if(btn) {
Serial.print("btn2.click()=");
Serial.println(btn);
}
// delay(10); // debug
}



Fortsetzung folgt...

- - - Aktualisiert - - -

hier kommt jetzt das, was ich versucht habe als .h und .cpp file zu erstellen.
Ich bin mir absolut nicht sicher, ob das gar nicht korrekt ist und ggf nur zufällig mit Fehlern funktionieren könnte, daher erst mal die Bitte zur Durchsicht:

ButtonClass.cpp


// Button Press Object
// (C) 2018 by HaWe

// This example code is in the public domain for private use.
// Use for professional or business purpose only by personal written permission
// by the author.

// ButtonClass.cpp


#include "ButtonClass.h"



int8_t tButton::dtimer() {
if (millis()-aktMillis >= 6*intervallMillis) {
return 3;
}
else
if (millis()-aktMillis >= intervallMillis) {
return -1;
}
else
return 0;
}

int8_t tButton::dtimer2() {
if (millis()-aktMillis2 >= 400) {
return -1;
}
else
return 0;
}



void tButton::init(byte _pin, int _mode, uint32_t _intervallMillis) {
pin = _pin;
mode = _mode;
intervallMillis = _intervallMillis;
pinMode(pin, mode);
}


int8_t tButton::click() {

btnstate=digitalRead(pin);
if(mode==INPUT_PULLUP) btnstate=!btnstate;

if(level==0) {
dnstate=0;
if(!oldbtnstate && btnstate) { // 1st new btn down:
aktMillis=millis(); // restart btn down timer
dnstate=dtimer();
level=1; // for button stroke: next level
}
}

if(level==1) { // either btn stroke happened

//Serial.println("level1"); Serial.println(dnstate);
dnstate=dtimer();
if(!btnstate){ // 1st btn up
if(dnstate){
aktMillis2=millis();
if(dnstate==3) { // long press: finished !!
btnstate=0;
oldbtnstate=0;
dnstate=0;
aktMillis=millis();
aktMillis2=millis();
upstate=0;
level=4; // extra wait
return 3;
}
else level=2; // short press: next level
}
}
}

if(level==2) { // short press happened

//Serial.println("level2"); Serial.println(dnstate);
upstate=dtimer2(); // check btn up pause

btnstate=digitalRead(pin);
if(mode==INPUT_PULLUP) btnstate=!btnstate;

//Serial.print("upstate="); Serial.println(upstate);

if(btnstate) { // second btn click during pause: double click!
dnstate2=1;
//Serial.print(" dnstate2="); Serial.println(dnstate2);
}
while(btnstate) { // debounce after double click
btnstate=digitalRead(pin);
if(mode==INPUT_PULLUP) btnstate=!btnstate;
}

if(upstate==0 && dnstate2) { // if double click: next level
level=3;
}
else
if(upstate==-1) { // btn up pause reached:
//Serial.println(millis()-aktMillis2); // single press finished !!
dnstate=0;
dnstate2=0;
//Serial.println(dnstate);
btnstate=0;
oldbtnstate=0;
level=0;
aktMillis=millis();
aktMillis2=millis();
upstate=0;
return 1;
}
}

if(level==3) { // double click

//Serial.println("level3");
dnstate=0; // double click finished !!
dnstate2=0;
//Serial.println(dnstate);
btnstate=0;
oldbtnstate=0;
aktMillis=millis();
aktMillis2=millis();
level=4; // next level after double click
return 2;
}

if(level==4) { // extra wait after double click
upstate=dtimer2();
if(upstate==-1) {
level=0;
dnstate=0;
aktMillis=millis();
aktMillis2=millis();
//Serial.println("level4 extra wait finished");
}
}

oldbtnstate=btnstate;
return 0;

};



- - - Aktualisiert - - -

ButtonClass.h


// Button Press Object
// (C) 2018 by HaWe

// This example code is in the public domain for private use.
// Use for professional or business purpose only by personal written permission
// by the author.

#ifndef __BTNCLASS__
#define __BTNCLASS__



#include <Arduino.h>

class tButton {

protected:

byte pin;
int mode;
uint32_t aktMillis, aktMillis2, intervallMillis;
int8_t level, dnstate, dnstate2, upstate, btnstate, oldbtnstate;

signed char dtimer();

signed char dtimer2();

public:

tButton () :
pin(0xFF), aktMillis(0), aktMillis2(0), intervallMillis(100),
mode(INPUT_PULLUP),
level(0), dnstate(0), dnstate2(0), upstate(0),
oldbtnstate(0), btnstate(0)
{ }

void init(byte _pin, int _mode, uint32_t _intervallMillis) ;

int8_t click() ;

};

//----------------------------------------------------------------

#endif



- - - Aktualisiert - - -

mit diesem testcode:



// Button Press Lib Testcode
// (C) 2018 by HaWe

// This example code is in the public domain for private use.
// Use for professional or business purpose only by personal written permission
// by the author.

// ButtonClass.cpp


#include <ButtonClass.h>


tButton btn1;
tButton btn2;


void setup() {
Serial.begin(115200);
delay(2000);
pinMode(13, OUTPUT); // for debug

Serial.println("Serial started\n");
btn1.init(4, INPUT_PULLUP, 50); // adjust!
btn2.init(5, INPUT_PULLUP, 50); // adjust!
}

//------------------------------------------------------------------------

void loop() {
int8_t btn;

btn=btn1.click();
if(btn) {
Serial.print("btn1.click()=");
Serial.println(btn);
}
btn=btn2.click();
if(btn) {
Serial.print("btn2.click()=");
Serial.println(btn);
}
// delay(10); // debug
}



Scheint jetzt zu gehen - ob wirklich alles korrekt definiert ist?

Moppi
30.11.2018, 08:32
Ob es richtig ist, kann ich Dir leider auch nicht sagen, aber wenn es funktioniert und er Compiler keine Fehler oder Warnungen ausgibt, dann müsste ja alles in Ordnung sein.

MfG