neu-rah / ArduinoMenu

Arduino generic menu/interactivity system
GNU Lesser General Public License v2.1
952 stars 192 forks source link

Custom menuFlied to select float decimal places #237

Closed ferchinas closed 5 years ago

ferchinas commented 5 years ago

Hi Rui: I made the custom menuField to work, at least for my setup ESP32 "core:1.0.0" HW Oled i2C 0.96 u8g2 driver

The number of places for decimals is defined by the user, you can change it at any time of the execution. Each field can have a different number of decimal places.

I share an example for those who may need it

#include <menu.h>
#include <menuIO/serialOut.h>
#include <menuIO/chainStream.h>
#include <menuIO/serialIn.h>

using namespace Menu;

#define MAX_DEPTH 1
unsigned char cantDecimals = 1;
float floatVar = 10.123456;

void updateEvent_cb(eventMask e);

//-----Custom floatField----------------
#define FLOATFLIED_DECIMALS_DEFAULT 1

template<typename T>
class floatlField :public menuField<T> {                
private:
  idx_t decimals;
public:
  floatlField(constMEM menuFieldShadow<T>& shadow) :menuField<T>(shadow) { decimals = FLOATFLIED_DECIMALS_DEFAULT; }
  floatlField(
    T &value,
    constText* text,
    constText*units,
    T low,
    T high,
    T step,
    T tune,
    action a = doNothing,
    eventMask e = noEvent,
    styles s = noStyle
  ) :floatlField(*new menuFieldShadow<T>(value, text, units, low, high, step, tune, a, e, s)) {}

  Used printTo(navRoot &root, bool sel, menuOut& out, idx_t idx, idx_t len, idx_t panelNr = 0) override {
    //menuFieldShadow<T>& s=*(menuFieldShadow<T>*)shadow;
    menuField<T>::reflex = menuField<T>::target();
    idx_t l = prompt::printTo(root, sel, out, idx, len);
    bool ed = this == root.navFocus;
    //bool sel=nav.sel==i;
    if (l < len) {
      out.print((root.navFocus == this&&sel) ? (menuField<T>::tunning ? '>' : ':') : ' ');
      l++;
      if (l < len) {
        l += out.print(menuField<T>::reflex, decimals);//NOTE: this can exceed the limits!
        if (l < len) {
          l += print_P(out, fieldBase::units(), len);
        }
      }
    }
    return l;
  }

  void setDecimals(idx_t d) { decimals = d; }
  idx_t getDecimals(void) { return(decimals); }
};
//-----Custom floatField----------------END

floatlField <typeof(floatVar)>& floatFlied_Object = *new floatlField<typeof(floatVar)>(floatVar, "Min", "", 0.0, 100.0, 0.1, 1);
floatlField <typeof(cantDecimals)>& DecimalsFlied_Object = *new floatlField<typeof(cantDecimals)>(cantDecimals, "Dec", "", 0, 6, 1, 1, (Menu::callback)updateEvent_cb, updateEvent);

void updateEvent_cb(eventMask e){
  floatFlied_Object.setDecimals(cantDecimals);
  Serial.println("");Serial.print("now using '");Serial.print(cantDecimals);Serial.println("' decimals.");
 }

//---Main menu  ---------------------------------
prompt* mainData[] = {
  &floatFlied_Object,
  &DecimalsFlied_Object,
  new Exit("<Back")
};

menuNode& mainMenu = *new menuNode("Main menu", sizeof(mainData) / sizeof(prompt*), mainData);

serialIn serial(Serial);
MENU_INPUTS(in,&serial);

MENU_OUTPUTS(out,MAX_DEPTH
  ,SERIAL_OUT(Serial)
  ,NONE//must have 2 items at least
);

NAVROOT(nav,mainMenu,MAX_DEPTH,in,out);

void setup() {
  Serial.begin(115200);
  while(!Serial);
  Serial.println("Menu 4.x");
  Serial.println("Use keys + - * /");
  Serial.println("to control the menu navigation");
  nav.useUpdateEvent = true;
}

void loop() {
  nav.poll();
}
neu-rah commented 5 years ago

excellent! don't you want to do a pull request? putting this at plugin folder would be very nice even if specific to some setup (plugins can be specific). However, this one seems quite generic.

ferchinas commented 5 years ago

Made PR I'm not an expert, suggestions are welcome.

Bflorin-sk commented 4 years ago

how to make this work on arduino? its not displaying properly for me on serial monitor of IDE.

neu-rah commented 4 years ago

are you using the floatlField above?

Bflorin-sk commented 4 years ago

i am using everything as it is. and i tried to uploadit to a arduino UNO and evrithing coompiles smooth no erors but .. 11:50:30.219 -> Menu 4.x 11:50:30.219 -> Use keys + - * / 11:50:30.219 -> to control the menu navigation 11:50:30.219 -> ⸮⸮⸮⸮⸮⸮6⸮%⸮4⸮&⸮⸮⸮⸮%⸮4⸮⸮⸮⸮⸮⸮ߑϑ⸮

neu-rah commented 4 years ago

original using esp32, guess there is some discrepancies over memory allocation RAM vs FLASH

what IDE are you using?

Bflorin-sk commented 4 years ago

1.8.12

neu-rah commented 4 years ago

arduino IDE wont let you specify compiling flags (at least last time i checked) otherwise we could force everything to RAM to make a quick check... I'm quite sure this example needs some review to work on flash memory, adding to my todo list

Bflorin-sk commented 4 years ago

May 2017 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com www.r-site.net unlike native objects, pluggins can be device specific, so some pluggins might not work on all devices. all sorts of plugins may be available in the future and if you customize a component and think it of interest of others please do pull request. contrubutions and contrubutors are welcome. decimalslField - To select the number of decimal places that are printed in float and double variables types. Feb 2019 ferchinas Tested on ESP32, Oled i2c display, u8g2 driver. It could work on other devices. ***/

this is on the beginning of the example

neu-rah commented 4 years ago

indeed, as a plugin it would work for all mcu's were menu uses ram by default, not the case of AVR's

Bflorin-sk commented 4 years ago

ok as a possible improvement it is possible to make a normal expression (123.456...) of decimal number followed by a multiplier/denominator like Mega ,kilo, mili, nano.... ( 123.45 [kilo])

neu-rah commented 4 years ago

there is also an unit text available for all numeric fields, however its not dynamic

as a note, improvements like this will probably be added as plugins because existing features are already tight on tiny mcu's like atmega328

thanks for the feed back, its really appreciated

Bflorin-sk commented 4 years ago

for my case there should be no trouble because i intend to to use a ST7920 12864 display with a rotary encoder and Arduino mega as a HMI. the uno was used only for testing stuff that i intend to use.

neu-rah commented 4 years ago

meanwhile and if changing decimal places for all numeric fields is ok for you, you can change code at https://github.com/neu-rah/ArduinoMenu/blob/master/src/itemsTemplates.hpp#L37

to:

  template<typename T>
  idx_t menuField<T>::printReflex(menuOut& o) const {return o.print(reflex,3);}

here using 3 decimal places

neu-rah commented 4 years ago

Hi!

added a decimal places format field, not with a fancy unit scale print (like Mega ,kilo, mili, nano....) but allowing only specification of decimal places, was so simple that no plugin added, now its part of the lib

usage example here https://github.com/neu-rah/ArduinoMenu/blob/master/examples/handlers/handlers/handlers.ino#L140

altFIELD(decPlaces<3>::menuField,test,"Test","%",0,100,1,0.001,showEvent,anyEvent,wrapStyle)

hope it works ok, let me know if not

P.S. for now you have to download latest version 4.19.x manually, I will make a release if this works ok

Bflorin-sk commented 4 years ago
17:27:01.853 -> [-] Alert test
17:27:01.853 -> [-] Name                                
17:27:01.853 -> [-] Hex 0x11
17:27:03.978 -> ========
17:27:03.978 -> Event for target: 0x55A
17:27:03.978 -> nav level:0 path:[3]
17:27:03.978 -> 128 selBlurEvent
17:27:03.978 -> 
17:27:03.978 -> ========
17:27:03.978 -> Event for target: 0x55A
17:27:03.978 -> nav level:0 path:[3]
17:27:03.978 -> 32 blurEvent
17:27:03.978 -> 
17:27:03.978 -> ========
17:27:03.978 -> Event for target: 0x55A
17:27:03.978 -> nav level:0 path:[2]
17:27:03.978 -> 16 focusEvent
17:27:03.978 -> 
17:27:03.978 -> ========
17:27:03.978 -> Event for target: 0x55A
17:27:03.978 -> nav level:0 path:[2]
17:27:03.978 -> 64 selFocusEvent
17:27:04.013 -> 
17:27:04.013 -> 
17:27:04.013 -> Main menu
17:27:04.013 -> [3]>Test 55.000%
17:27:04.013 -> [4] Sub-Menu
17:27:04.013 -> [5] Led: Off
17:27:04.013 -> [6] LED On
17:27:04.013 -> [7] LED Off
17:27:04.013 -> [8] Select Zero
17:27:04.013 -> [9] Choose Last
17:27:04.013 -> [-] Alert test
17:27:04.013 -> [-] Name                                
17:27:08.029 -> ========
17:27:08.029 -> Event for target: 0x55A
17:27:08.029 -> nav level:0 path:[2]
17:27:08.029 -> 4 exitEvent
17:27:08.029 -> 
17:27:08.029 -> suspending menu!
17:27:08.029 -> suspended...
Bflorin-sk commented 4 years ago

ok i testedit on my device Mega +encoder+12864 and its wierd

Bflorin-sk commented 4 years ago

it differs from the example i used were first i set the decade and then the units this example setts everithing before the "," by counting with the encoder then everyting the same after the ",".

Bflorin-sk commented 4 years ago
#include <Arduino.h>

/********************
Arduino generic menu system
U8G2 menu example
U8G2: https://github.com/olikraus/u8g2
Oct. 2016 Stephen Denne https://github.com/datacute
Based on example from Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
Original from: https://github.com/christophepersoz
menu on U8G2 device
output: Wemos D1 mini OLED Shield (SSD1306 64x48 I2C) + Serial
input: Serial + encoder
mcu: nano328p
*/

#include <menu.h>  //menu macros and objects
#include <menuIO/u8g2Out.h>
#include <TimerOne.h>
#include <ClickEncoder.h>
#include <menuIO/clickEncoderIn.h> 
#include <menuIO/keyIn.h>
#include <menuIO/chainStream.h> // concatenate multiple input streams (this allows adding a button to the encoder)
#include <menuIO/serialOut.h>
#include <menuIO/serialIn.h>

using namespace Menu;

#define LEDPIN LED_BUILTIN

// #define USE_PCD8544
//#define USE_SSD1306

//#define(USE_PCD8544)
  // rotary encoder pins
   #define encA    A0
   #define encB    A1
   #define encBtn  A2
   #define encSteps 2

ClickEncoder clickEncoder = ClickEncoder(encA, encB, encBtn, encSteps);
ClickEncoderStream encStream(clickEncoder, 1);
//ClickEncoder clickEncoder(encA,encB,encBtn,2);
//ClickEncoderStream encStream(clickEncoder,1);
//MENU_INPUTS(in,&encStream);

void timerIsr() {clickEncoder.service();}
result doAlert(eventMask e, prompt &item);
result showEvent(eventMask e,navNode& nav,prompt& item) {
  Serial.print("event: ");
  Serial.println(e);
  return proceed;
}

//#define U8G2_16BIT///////////
  #include <SPI.h>
  #define USE_HWSPI
 // #define U8_DC 9
 // #define U8_CS 10
 // #define U8_RST 8
  #define fontName u8g2_font_6x10_tr
  //#define fontName u8g2_font_chikita_tr

  #define fontX 6
  #define fontY 12
  #define offsetX 0
  #define offsetY 0
  #define U8_Width 128
  #define U8_Height 64

  //U8G2_ST7920_128X64_1_HW_SPI u8g2(U8G2_R0, /* CS=*/ 10, /* reset=*/ 8);
    U8G2_ST7920_128X64_1_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* CS=*/ 10, /* reset=*/ 8); /////not working// working for arduino mega
    //U8G2_ST7920_128X64_1_HW_SPI u8g2(U8G2_R0, /* CS=*/ 10, /* reset=*/ 8);

// define menu colors --------------------------------------------------------
//each color is in the format:
//  {{disabled normal,disabled selected},{enabled normal,enabled selected, enabled editing}}
// this is a monochromatic color table
const colorDef<uint8_t> colors[6] MEMMODE={
  //{{0,0},{0,1,1}},//bgColor
  //{{1,1},{1,0,0}},//fgColor
  //{{1,1},{1,0,0}},//valColor
  //{{1,1},{1,0,0}},//unitColor
  //{{0,1},{0,0,1}},//cursorColor
  //{{1,1},{1,0,0}},//titleColor

  {{0,0},{0,1,1}},//bgColor
  {{1,1},{1,0,0}},//fgColor
  {{1,1},{1,0,0}},//valColor
  {{1,1},{1,0,0}},//unitColor
  {{0,1},{0,0,1}},//cursorColor
  {{1,1},{1,0,0}},//titleColor
};

float test=55;

int ledCtrl=HIGH;

result myLedOn() {
  ledCtrl=HIGH;
  return proceed;
}
result myLedOff() {
  ledCtrl=LOW;
  return proceed;
}

TOGGLE(ledCtrl,setLed,"Led: ",doNothing,noEvent,noStyle//,doExit,enterEvent,noStyle
  ,VALUE("On",HIGH,doNothing,noEvent)
  ,VALUE("Off",LOW,doNothing,noEvent)
);

int selTest=0;
SELECT(selTest,selMenu,"Select",doNothing,noEvent,noStyle
  ,VALUE("Zero",0,doNothing,noEvent)
  ,VALUE("One",1,doNothing,noEvent)
  ,VALUE("Two",2,doNothing,noEvent)
);

int chooseTest=-1;
CHOOSE(chooseTest,chooseMenu,"Choose",doNothing,noEvent,noStyle
  ,VALUE("First",1,doNothing,noEvent)
  ,VALUE("Second",2,doNothing,noEvent)
  ,VALUE("Third",3,doNothing,noEvent)
  ,VALUE("Last",-1,doNothing,noEvent)
);

// //customizing a prompt look!
// //by extending the prompt class
// class altPrompt:public prompt {
// public:
//   altPrompt(constMEM promptShadow& p):prompt(p) {}
//   Used printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t panelNr) override {
//     return out.printRaw(F("special prompt!"),len);;
//   }
// };

MENU(subMenu,"Sub-Menu",doNothing,noEvent,noStyle
  ,OP("Sub1",doNothing,noEvent)
 // ,altOP(altPrompt,"",doNothing,noEvent)
  ,EXIT("<Back")
);

uint16_t hrs=0;
uint16_t mins=0;

//define a pad style menu (single line menu)
//here with a set of fields to enter a date in YYYY/MM/DD format
altMENU(menu,timeMenu,"Time",doNothing,noEvent,noStyle,(systemStyles)(_asPad|Menu::_menuData|Menu::_canNav|_parentDraw)
  ,FIELD(hrs,"",":",0,11,1,0,doNothing,noEvent,noStyle)
  ,FIELD(mins,"","",0,59,10,1,doNothing,noEvent,wrapStyle)
);

char* constMEM hexDigit MEMMODE="0123456789ABCDEF";
char* constMEM hexNr[] MEMMODE={"0","x",hexDigit,hexDigit};
char buf1[]="0x11";

MENU(mainMenu,"Main menu",doNothing,noEvent,wrapStyle //
  ,OP("Op1",doNothing,noEvent)
  ,OP("Op2",doNothing,noEvent)
  ,OP("Op3",doNothing,noEvent)
 // ,FIELD(test,"Test","%",0,100,10,1,doNothing,noEvent,wrapStyle)//seteaza o val in procente decimale si dupaia unitati ////////////////////////////////////////////////////////////////////
 ,altFIELD(decPlaces<3>::menuField,test,"Test","%",0,100,1,0.001,showEvent,anyEvent,wrapStyle) //works ok//////////////////////////////////////////////////////////////////////////////////
  ,SUBMENU(timeMenu)
  ,SUBMENU(subMenu)
  ,SUBMENU(setLed)
  ,OP("LED On",myLedOn,enterEvent)
  ,OP("LED Off",myLedOff,enterEvent)
  ,SUBMENU(selMenu)
  ,SUBMENU(chooseMenu)
  ,OP("Alert test",doAlert,enterEvent)
  ,EDIT("Hex",buf1,hexNr,doNothing,noEvent,noStyle)
  ,EXIT("<Exit")
);

#define MAX_DEPTH 2

 //encoderIn<encA,encB> encoder;//simple quad encoder driver
// encoderInStream<encA,encB> encStream(encoder,4);// simple quad encoder fake Stream
//encoder<encA,encB> encoder;//simple quad encoder driver
 //encoderInStream<encA,encB> encStream(encoder,4);// simple quad encoder fake Stream

//a keyboard with only one key as the encoder button
keyMap encBtn_map[]={{-encBtn,defaultNavCodes[enterCmd].ch}};//negative pin numbers use internal pull-up, this is on when low
 keyIn<1> encButton(encBtn_map);//1 is the number of keys

//menuIn* inputsList[]={&encBuitton,&Serial};
//chainStream<2> in(inputsList);//1 is the number of inputs

//serialIn serial(Serial);
//MENU_INPUTS(in,&serial);
MENU_INPUTS(in,&encStream,&encButton);//,&serial);////////////////////////  ////  ///

MENU_OUTPUTS(out,MAX_DEPTH
  ,U8G2_OUT(u8g2,colors,fontX,fontY,offsetX,offsetY,{0,0,U8_Width/fontX,U8_Height/fontY})
  ,SERIAL_OUT(Serial)
);

NAVROOT(nav,mainMenu,MAX_DEPTH,in,out);

////
result alert(menuOut& o,idleEvent e) {
  if (e==idling) {
    o.setCursor(0,0);
    o.print("alert test");
    o.setCursor(0,1);
    o.print("[select] to continue...");
  }
  return proceed;
}

result doAlert(eventMask e, prompt &item) {
  nav.idleOn(alert);
  return proceed;
}

result idle(menuOut& o,idleEvent e) {
  switch(e) {
    case idleStart:o.setCursor(0,0);o.print("suspending menu!");break;
    case idling:o.setCursor(0,1);o.print("suspended...");break;
    case idleEnd:o.setCursor(0,2);o.print("resuming menu.");break;
  }
  return proceed;
}
////
//result alert(menuOut& o,idleEvent e) {
//  if (e==idling) {
//    o.setCursor(0,0);
//    o.print("alert test");
//    o.setCursor(0,1);
//    o.print("press [select]");
//    o.setCursor(0,2);
//    o.print("to continue...");
//  }
//  return proceed;
//}

//result doAlert(eventMask e, prompt &item) {
//  nav.idleOn(alert);
//  return proceed;
//}

//when menu is suspended
//result idle(menuOut& o,idleEvent e) {
//  o.clear();
 // switch(e) {
 //   case idleStart:o.println("suspending menu!");break;
//    case idling:o.println("suspended...");break;
//    case idleEnd:o.println("resuming menu.");break;
//  }
//  return proceed;
//}

void setup() {
  Serial.begin(115200);
  while(!Serial);
  Serial.println("menu 4.x test");Serial.flush();
  clickEncoder.setAccelerationEnabled(true);
  clickEncoder.setDoubleClickEnabled(false); // Disable doubleclicks makes the response faster.  See: https://github.com/soligen2010/encoder/issues/6
  encButton.begin();/////////////////////////////////////////////////////////y dont konoo
  // encoder.begin();
  // pinMode(LEDPIN,OUTPUT);//cant use pin 13 when using hw spi
  // and on esp12 i2c can be on pin 2, and that is also led pin
  // so check first if this is adequate for your board
 // #if defined(USE_HWSPI)
    SPI.begin();
    u8g2.begin();
 // #elif defined(USE_HWI2C)
  //  Wire.begin();
   // u8g2.begin();
  //#else
  //#error "please choose your interface (I2c,SPI)"
 // #endif
  u8g2.setFont(fontName);
  // u8g2.setBitmapMode(0);

  // disable second option
  //mainMenu[1].enabled=disabledStatus; //it makes second line Op2/mainMenu[1] or first line Op1/mainMenu[0]... of main menu unselectable if //uncommented
// nav.idleTask=idleON();//point a function to be used when menu is suspended

nav.idleOn();////sets menu to Idle at powerup.

  Serial.println("setup done.");Serial.flush();

  Timer1.initialize(1000);
  Timer1.attachInterrupt(timerIsr);
}

void loop() {
  nav.doInput();
  // digitalWrite(LEDPIN, ledCtrl);
  if (nav.changed(0)) {//only draw if menu changed for gfx device
    //change checking leaves more time for other tasks
    u8g2.firstPage();
    do nav.doOutput(); while(u8g2.nextPage());
  }

  nav.doInput();
  if (nav.sleepTask) {
    u8g2.firstPage();
    do {
 u8g2.setFont(u8g2_font_4x6_tn);
    //u8g2.setFont(u8g2_font_inb16_mr);   // draw the current pixel width
    u8g2.drawBox(0,55,1+test,2);
    u8g2.setCursor(2+test , 58);
    u8g2.print(test);          // this value must be lesser than 128 unless U8G2_16BIT is set

    //u8g2.setFont(u8g2_font_unifont_t_symbols);

    //u8g2.setCursor(2+test, 32);
     u8g2.setFont(u8g2_font_4x6_tr);
    u8g2.drawStr(test-1, 64,"^"); ///this should become setpoint
    u8g2.setCursor(2+test , 64);
    u8g2.print(test,3); 

   u8g2.setFont(u8g2_font_6x10_tr);
    } while ( u8g2.nextPage() );
  } else {
    if (nav.changed(0)) {

      u8g2.firstPage();

      do nav.doOutput(); while(u8g2.nextPage());
    }
  }
   nav.timeOut=300;  //menu goes idle after 300seconds of not useage
  delay(25);//simulate other tasks delay
    }

//}

//}
Bflorin-sk commented 4 years ago

ok its very nice actually and it works great (my mistake forgot to change from int test to float test) but.... i have no control of the amount of zeroes after ",". or do I? or somthing like i write(1234567) and then move the "," where i need it like (1,234567),(12,34567),(123,4567) as means of inputing a value, or just something like 1.2345*10^3 scientific calculator format.

neu-rah commented 4 years ago

yes you do, on this part decPlaces<3> change the number to desired places

neu-rah commented 4 years ago

the implementation is quite trivial, it took me some time to find the better way

      template<uint8_t dps>//here a template parameter for the number of places
      struct decPlaces {
        template<typename T>
        struct menuField:Menu::menuField<T> {//and here we are reusing the old menuField class
          using Menu::menuField<T>::menuField;//even reusing the constructor as extra parameter are on outside template
          idx_t printReflex(menuOut& o) const override;//only to change the way it prints out
        };
      };

and the we can implement the printing to whatever we want

  template<uint8_t dps>
  template<typename T>
  idx_t decPlaces<dps>::menuField<T>::printReflex(menuOut& o) const {
    return o.print(Menu::menuField<T>::reflex,dps);//just by changing here what its printed
  }
Bflorin-sk commented 4 years ago
,altFIELD(decPlaces<3>::menuField,test,"Test","%",0,100,1,0.001,showEvent,anyEvent,wrapStyle)//works ok
,altFIELD(decPlaces<4>::menuField,test,"Test","%",0,100,1,0.0001,showEvent,anyEvent,wrapStyle)//works ok

it works

Bflorin-sk commented 4 years ago

but... still... lets say in my case i can only change value by selecting befor or after "'," and incrementing (counting by encoder ) to the desired value if i have 55.0000 and want to change it to 55.4321 it is a lot of counting by manual encoder so ... i was thinking of something like this

55.4000 55.4300 .. 55.4321 {confirm by pressing ... stuff... encButton}.

neu-rah commented 4 years ago

if you are using serial input you can type in the value for the field (nor checked with floats)...

clickencoder can use acceleration, rotating to same direction increases the stepping

Bflorin-sk commented 4 years ago

something like ,FIELD(test,"Test","%",0,100,10,1,doNothing,noEvent,wrapStyle

Bflorin-sk commented 4 years ago

off coures here are only 2 digits

neu-rah commented 4 years ago

you're welcome to join us at https://gitter.im/ArduinoMenu/Lobby

Bflorin-sk commented 4 years ago

if you are using serial input you can type in the value for the field (nor checked with floats)...

clickencoder can use acceleration, rotating to same direction increases the stepping

it seems i cant get acceleration working at first i thought my hardware debouncer is overkill . but.. i changed it and the same whatever speed i turn the encoder it does not accelerate (change rate)

neu-rah commented 4 years ago

are you using the clickencoder (https://github.com/0xPIT/encoder)?

if not working please open a new issue, we are getting off topic here