/*************************************************************************** source::worx PiGPIO Copyright © 2022 c.holzheuer chris@sourceworx.org This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. ***************************************************************************/ #include #include #include #ifdef Q_OS_LINUX #include //#include //#include "/usr/include/pigpio.h" #include PiGPIO::PiGPIO() { //::gpioInitialise(); // Connect to Pi. constexpr char* optHost = nullptr; constexpr char* optPort = nullptr; PI = ::pigpio_start( optHost, optPort ); qDebug() << " -- PiGPIO::PiGPIO(): " << PI; if( PI < 0 ) qDebug() << "-- PiGPIO::PiGPIO() FAIL"; } PiGPIO::~PiGPIO() { ::pigpio_stop( PI ); } //---------------------------------------------- /** * @brief Implementierung für Linux */ PiGRotaryDial::PiGRotaryDial( unsigned dialA, unsigned dialB, unsigned button, QObject* parent ) : QObject( parent ), _dialA( dialA ), _dialB( dialB ), _button( button ) { _Pi = PiGPIO::Instance().PI; //_mode = mode; //_cb = cb_func; _levA = 0; _levB = 0; _step = 0; ::set_mode( _Pi, _dialA, PI_INPUT ); ::set_mode( _Pi, _dialB, PI_INPUT ); ::set_mode( _Pi, _button, PI_INPUT ); // pull up is needed as encoder common is grounded ::set_pull_up_down( _Pi, _dialA, PI_PUD_UP ); ::set_pull_up_down( _Pi, _dialB, PI_PUD_UP ); ::set_pull_up_down( _Pi, _button, PI_PUD_UP ); _glitch = 1000; ::set_glitch_filter( _Pi, _dialA, _glitch ); ::set_glitch_filter( _Pi, _dialB, _glitch ); ::set_glitch_filter( _Pi, _button, _glitch ); _oldState = ( ::gpio_read( _Pi, _dialA ) << 1) | ::gpio_read( _Pi, _dialB ); // monitor encoder level changes //int callback_ex(int pi, unsigned user_gpio, unsigned edge, CBFuncEx_t f, void *userdata) // typedef void (*CBFuncEx_t)(int pi, unsigned user_gpio, unsigned level, uint32_t tick, void * userdata); _callbackIdA = ::callback_ex( _Pi, _dialA, EITHER_EDGE, PiGPIOPulse, this ); _callbackIdB = ::callback_ex( _Pi, _dialB, EITHER_EDGE, PiGPIOPulse, this ); _callbackIdC = ::callback_ex( _Pi, _button, EITHER_EDGE, PiGPIOPulse, this ); } PiGRotaryDial::~PiGRotaryDial() { if( _callbackIdA >= 0 ) { ::callback_cancel( _callbackIdA ); _callbackIdA = -1; } if( _callbackIdB >= 0 ) { ::callback_cancel( _callbackIdB ); _callbackIdB = -1; } if( _callbackIdC >= 0 ) { ::callback_cancel( _callbackIdC ); _callbackIdC = -1; } ::set_glitch_filter( _Pi, _dialA, 0 ); ::set_glitch_filter( _Pi, _dialB, 0 ); ::set_glitch_filter( _Pi, _button, 0 ); } void PiGRotaryDial::setGlitchFilter( int glitch ) { if( _glitch == glitch ) return; _glitch = glitch; ::set_glitch_filter( _Pi, _dialA, glitch ); ::set_glitch_filter( _Pi, _dialB, glitch ); ::set_glitch_filter( _Pi, _button, glitch ); } void PiGRotaryDial::pulse( unsigned gpio, unsigned level ) { if( level == PI_TIMEOUT ) return; if( gpio == _button ) return handleClick( level ); if( gpio == _dialA ) _levA = level; else _levB = level; // sourceworx proudly presents: // den primitivstmöglichen Auslese-algorithmus // für Rotary-Dials. // Die klugen Varianten stehen hier: // https://www.best-microcontroller-projects.com/rotary-encoder.html // https://web.engr.oregonstate.edu/~traylor/ece473/student_projects/ReadingEncoderSwitches.pdf // wenn sich was geändert hatte ... if( gpio == _dialB && level == 1 ) { // bestimmt der andere Kontakt die // die Drehrichtung int delta = _levA ? -1 : +1; //qDebug() << "###### EMIT: " << delta; emit deltaChanged( delta ); } } void PiGRotaryDial::handleClick( unsigned level ) { if( !_pressed && level == 0 ) { _pressed = true; return; } if( _pressed && level == 1 ) { _pressed = false; emit clicked(); } } #endif // Q_OS_LINUX /*************************************************************************** source::worx PiGPIO Copyright © 2022 c.holzheuer chris@sourceworx.org This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. ***************************************************************************/ #ifdef Q_OS_WIN PiGPIO::PiGPIO() { } PiGPIO::~PiGPIO() { } PiGRotaryDial::PiGRotaryDial( unsigned dialA, unsigned dialB, unsigned button, QObject* parent ) : QObject( parent ), _dialA( dialA ), _dialB( dialB ), _button( button ) { } PiGRotaryDial::~PiGRotaryDial() { } void PiGRotaryDial::setGlitchFilter( int ) { } void PiGRotaryDial::pulse( unsigned, unsigned ) { } #endif //Q_OS_WIN /*************************************************************************** source::worx PiGPIO Copyright © 2022 c.holzheuer chris@sourceworx.org This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. ***************************************************************************/ void PiGRotaryDial::PiGPIOPulse( int pi, unsigned gpio, unsigned level, uint32_t tick, void *user ) { Q_UNUSED( pi ); Q_UNUSED( tick ); // Need a static callback to link with C. PiGRotaryDial* mySelf = static_cast( user ); if( mySelf ) mySelf->pulse( gpio, level ); // Call the instance callback. } /* void PiGRotaryDial::setPosition( int position ) { _step = position * 4; } int PiGRotaryDial::position() { return _step / 4; } */