i am doing a project for pulse control , i hit a road block where my rotary encoder gets freazed or skips in one of the menu pages. so i stripped the code to the bare minimum to troubleshoot the issue. i found out by adding the oled display code is the cause. so by deleting the code related to printing the result and use the serial monitor for debugging the rotary just works perfectly. i have searched many forums and but none have the issue i have.
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Rotary.h>
Rotary r = Rotary(2, 4); // digital Pin attached to the rotary
Adafruit_SSD1306 display(128, 64, &Wire, 4); // oled library
int pulse = 0;
void setup() {
Serial.begin(9600);
r.begin(true);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3C (for the 128x64)
}
void loop() {
//the display code, if added will make the rotatry skips or gets stuck
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(2);
display.setCursor(0, 20);
display.print("Test:");
display.print(pulse);
display.display();
//the code below , the Rotary working fine and printing to the serial monitor with no issue
unsigned char result = r.process();
if (result == DIR_CCW)
{ if (pulse < 255)
{ pulse = pulse + 5;
Serial.println(pulse);
}
}
if (result == DIR_CW)
{
{ if (pulse > 1)
{ pulse = pulse - 5;
Serial.println(pulse);
}
}
}
}
first step to get help in the forum is to learn how to re-edit your post so code appears as a code-section
quickest way to insert code as a code section.
Follow this link to get an instruction how to write an good first posting in just one minute
or an even impressive first posting in just 10 minutes
StefanL38:
first step to get help in the forum is to learn how to re-edit your post so code appears as a code-section
quickest way to insert code as a code section.
Follow this link to get an instruction how to write an good first posting in just one minute
or an even impressive first posting in just 10 minutes
If the OLED reset pin is not used, you should not specify it in the setup. It will default to -1 (not used)
You should also time how long it takes to do all of your display functions. i2c isn't that fast compared to spi so you are just busy doing other things and miss some rotary pulses. You certainly do not need to call all of those display functions every time through loop.
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Rotary.h>
Rotary r = Rotary(2, 4); // digital Pin attached to the rotary
Adafruit_SSD1306 display(128, 64, &Wire); // oled library
int pulse = 0;
void setup() {
Serial.begin(9600);
r.begin(true);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3C (for the 128x64)
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(2);
display.setCursor(0, 20);
display.print("Test:");
display.print(pulse);
display.display();
}
void timeIt( int count, void (*func)() ) {
unsigned long startTime = micros();
for( int i=0; i<count; ++i ) {
func();
}
Serial.println( (micros() - startTime)/count );
}
void loop() {
int count = 10;
timeIt(count, loop1);
timeIt(count, loop2);
timeIt(count, loop3);
while(1);
}
void loop1() {
//just rotary testing
//the code below , the Rotary working fine and printing to the serial monitor with no issue
unsigned char result = r.process();
if (result == DIR_CCW)
{ if (pulse < 255)
{ pulse = pulse + 5;
Serial.println(pulse);
}
}
if (result == DIR_CW)
{
{ if (pulse > 1)
{ pulse = pulse - 5;
Serial.println(pulse);
}
}
}
}
void loop2() {
//the display code, if added will make the rotatry skips or gets stuck
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(2);
display.setCursor(0, 20);
display.print("Test:");
display.print(pulse);
display.display();
//the code below , the Rotary working fine and printing to the serial monitor with no issue
unsigned char result = r.process();
if (result == DIR_CCW)
{ if (pulse < 255)
{ pulse = pulse + 5;
Serial.println(pulse);
}
}
if (result == DIR_CW)
{
{ if (pulse > 1)
{ pulse = pulse - 5;
Serial.println(pulse);
}
}
}
}
void loop3() {
//minimized display code
display.setCursor(5, 20);
display.print(pulse);
display.display();
//the code below , the Rotary working fine and printing to the serial monitor with no issue
unsigned char result = r.process();
if (result == DIR_CCW)
{ if (pulse < 255)
{ pulse = pulse + 5;
Serial.println(pulse);
}
}
if (result == DIR_CW)
{
{ if (pulse > 1)
{ pulse = pulse - 5;
Serial.println(pulse);
}
}
}
}
blh64:
You should also time how long it takes to do all of your display functions. i2c isn't that fast compared to spi so you are just busy doing other things and miss some rotary pulses. You certainly do not need to call all of those display functions every time through loop.
thank you for the reply
minimizing the display code did not resolve the issue at all. but while looking at your code it gave me an idea in which i insert the display code inside the IF function and whalla, the encoder worked like a charm.
But,
one issue, this a code is a part of a menu and when i reach to the pulse menu, the screen goes black until i move the encoder and the info will appear. and i cannot have the static info in the setup void because it will mess-up the menu for other functions.
my observation:
if you add any code out side the IF function will freeze the rotary (not just the display code).
i do not have the issue with the other menu only with the rotary encoder could this be a rotary library issue ?
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Rotary.h>
Rotary r = Rotary(2, 4); // digital Pin attached to the rotary
Adafruit_SSD1306 display(128, 64, &Wire); // oled library
int pulse = 0;
void setup() {
Serial.begin(9600);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3C (for the 128x64)
r.begin(true);
}
void loop() {
//minimized display code
unsigned char result = r.process();
if (result == DIR_CCW)
{ if (pulse < 255)
{ pulse = pulse + 5;
Serial.println(pulse);
display.setCursor(5, 20);
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(2);
display.setCursor(0, 20);
display.print("Test:");
display.print(pulse);
display.display();
}
}
if (result == DIR_CW)
{
{ if (pulse > 1)
{ pulse = pulse - 5;
Serial.println(pulse);
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(2);
display.setCursor(0, 20);
display.print("Test:");
display.print(pulse);
display.display();
}
}
}
}