quoting a PM
After connecting my circuit to osciloscope I see that:
input encoder pins SS,8:
SS - have about 1,2V amplitude while rotating ( I think its because Im using serial communication)
8 - have correct value, 5V amplitude
volume encoder pins 13,SCK
13 - have correct value, 5V amplitude, of course I have delete lines with LED blinking
SCK - have correct value, 5V amplitude
anyway, each step is correct on osciloscope, only in software maybe there is some trick to have one gap step between changing direction of rotation
Without a schematic of your encoder-circuit and screenshots of your oscilloscope whith explanation which curves shows what the given info can only be used to speculate.
You seem to have not yet understood that posting fast too few information is slowing down finding a solution
/* Demo-Code that uses the Rotary-library from GitHub-User https://github.com/buxtronix
* using his library https://github.com/buxtronix/arduino/tree/master/libraries/Rotary
* in combination with a timer-interrupt executed 10000 times per second
* Copyright 2023 StefanL38. Licenced under the GNU GPL Version 3.
* A T T E N T I O N !
* this demo-code uses Timer1 which is used by other libraries too.
* This means using this code can interfere with other libraries
* causing malfunction of both
*
* This demo-code uses the TimerInterrupt.h-library from here
* https://github.com/khoih-prog/TimerInterrupt/tree/master
*
* The examples in the GiPo show how to use different timers
* The demo-code simply prints the value of variable myCounter
* each time the value of the variable changes
*/
#define USE_TIMER_1 true
#if ( defined(__AVR_ATmega644__) || defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) || \
defined(ARDUINO_AVR_UNO) || defined(ARDUINO_AVR_NANO) || defined(ARDUINO_AVR_MINI) || defined(ARDUINO_AVR_ETHERNET) || \
defined(ARDUINO_AVR_FIO) || defined(ARDUINO_AVR_BT) || defined(ARDUINO_AVR_LILYPAD) || defined(ARDUINO_AVR_PRO) || \
defined(ARDUINO_AVR_NG) || defined(ARDUINO_AVR_UNO_WIFI_DEV_ED) || defined(ARDUINO_AVR_DUEMILANOVE) || defined(ARDUINO_AVR_FEATHER328P) || \
defined(ARDUINO_AVR_METRO) || defined(ARDUINO_AVR_PROTRINKET5) || defined(ARDUINO_AVR_PROTRINKET3) || defined(ARDUINO_AVR_PROTRINKET5FTDI) || \
defined(ARDUINO_AVR_PROTRINKET3FTDI) )
#endif
// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
#include "TimerInterrupt.h"
#define TIMER1_INTERVAL_MS 1
#include <Rotary.h>
// Rotary encoder is wired with the common to ground and the two
// outputs to pins 5 and 6.
const byte channel_A_Pin = SS;
const byte channel_B_Pin = 8;
Rotary rotary = Rotary(channel_A_Pin, channel_B_Pin);
const byte channel_C_Pin = MISO;
const byte channel_D_Pin = SCK;
Rotary rotary1 = Rotary(channel_C_Pin, channel_D_Pin);
unsigned long myISR_TimerFrequency = 10000;
// myCounter that will be incremented or decremented by rotation.
// as this variable is changed in an interrupt-service-routine
// this variable MUST !! be declared volatile to make sure
// that it works properly !
volatile uint8_t myCounter = 0;
uint8_t last_myCounter = 0;
volatile uint8_t myCounter1 = 0;
uint8_t last_myCounter1 = 0;
void TimerHandler1() {
unsigned char result = rotary.process();
unsigned char result1 = rotary1.process();
// depending on having detected rotation
if (result == DIR_CW) {
myCounter++;
}
else if (result == DIR_CCW) {
myCounter--;
}
// depending on having detected rotation
if (result1 == DIR_CW) {
myCounter1++;
}
else if (result1 == DIR_CCW) {
myCounter1--;
}
}
void PrintFileNameDateTime() {
Serial.println( F("Code running comes from file ") );
Serial.println( F(__FILE__) );
Serial.print( F(" compiled ") );
Serial.print( F(__DATE__) );
Serial.print( F(" ") );
Serial.println( F(__TIME__) );
}
// easy to use helper-function for non-blocking timing
boolean TimePeriodIsOver (unsigned long &startOfPeriod, unsigned long TimePeriod) {
unsigned long currentMillis = millis();
if ( currentMillis - startOfPeriod >= TimePeriod ) {
// more time than TimePeriod has elapsed since last time if-condition was true
startOfPeriod = currentMillis; // a new period starts right here so set new starttime
return true;
}
else return false; // actual TimePeriod is NOT yet over
}
unsigned long MyTestTimer = 0; // Timer-variables MUST be of type unsigned long
const byte OnBoard_LED = 13;
void BlinkHeartBeatLED(int IO_Pin, int BlinkPeriod) {
static unsigned long MyBlinkTimer;
pinMode(IO_Pin, OUTPUT);
if ( TimePeriodIsOver(MyBlinkTimer, BlinkPeriod) ) {
digitalWrite(IO_Pin, !digitalRead(IO_Pin) );
}
}
void setup() {
Serial.begin(115200);
Serial.println("Setup-Start");
PrintFileNameDateTime();
Serial.print(F("\nStarting Argument_None on "));
Serial.println(BOARD_TYPE);
Serial.println(TIMER_INTERRUPT_VERSION);
Serial.print(F("CPU Frequency = "));
Serial.print(F_CPU / 1000000);
Serial.println(F(" MHz"));
// Timer0 is used for micros(), millis(), delay(), etc and can't be used
// Select Timer 1-2 for UNO, 1-5 for MEGA, 1,3,4 for 16u4/32u4
// Timer 2 is 8-bit timer, only for higher frequency
// Timer 4 of 16u4 and 32u4 is 8/10-bit timer, only for higher frequency
ITimer1.init();
// Using ATmega328 used in UNO => 16MHz CPU clock ,
// For 16-bit timer 1, 3, 4 and 5, set frequency from 0.2385 to some KHz
// For 8-bit timer 2 (prescaler up to 1024, set frequency from 61.5Hz to some KHz
if (ITimer1.attachInterruptInterval(TIMER1_INTERVAL_MS, TimerHandler1)) {
Serial.print(F("Starting ITimer1 OK, millis() = ")); Serial.println(millis());
}
else {
Serial.println(F("Can't set ITimer1. Select another freq. or timer"));
}
}
void loop() {
BlinkHeartBeatLED(OnBoard_LED, 250);
// check if value has changed
if (last_myCounter != myCounter) {
// only if value REALLY HAS changed
byte difference = abs(last_myCounter - myCounter);
if (difference != 1) {
Serial.println("difference != 1 counter jumped !!");
}
last_myCounter = myCounter; // update last_myCounter
Serial.print("myCounter=");
Serial.println(myCounter);
}
// check if value has changed
if (last_myCounter1 != myCounter1) {
// only if value REALLY HAS changed
byte difference = abs(last_myCounter1 - myCounter1);
if (difference != 1) {
Serial.println("difference != 1 counter jumped !!");
}
last_myCounter1 = myCounter1; // update last_myCounter
Serial.print("myCounter1=");
Serial.println(myCounter1);
}
}
as I wrote to Stefan, when Im rotate in one direction all is ok, but when I go to second direction, first move is a gap, next move is read correct.
I have already connect input pins of arduino to the oscilloscope and I see:
input encoder pins SS,8:
SS - have about 1,2V amplitude while rotating ( I think its because Im using serial communication)
8 - have correct value, 5V amplitude
volume encoder pins 13,SCK
13 - have correct value, 5V amplitude, of course I have delete lines with LED blinking
SCK - have correct value, 5V amplitude
Investing maybe 10 minutes into a decent and detailed posting can speed up finding a solution a mimimum of 30 minutes. Often hours or days. So investing 10 minutes into a detailed posting is a very good investion.
If your µC is already overloaded with the code like posted in post #44
I recommend using a Seeeduino XIAO:
three times faster clock: 48 Mhz
four times bigger bitwitdh: 32 bit
bigger RAM 32kB
bigger flash 256kB
I have uploaded my sketch after disabling bootloader. All works, only with this one I have problem. On previous rotary library all works (I have tested this).
There are so many users in the forum with questions.
I have to choose which one to support.
As your very last chance to be supported
either you are able to post your complete sketch as a code-section
and
post serial printing as a code-section or I will terminate my support for you.
If you like to chat use snapchat , chatGPT or whatever