Dear Forum Arduino members,
I am using Arduino Mega, Ramps 1.6 (or 1.4) and 128*64 LCD. I want to show the encoder value on the LCD screen with the following code. I am getting some values of the encoder but it is not working properly.
I can print text on the LCD. I can also read the encoder value on the serial print without any problems. However, when I join these two projects, I see that the encoder is skipping some values.
I need your help in this direction.
//Arduino Mega
//RepRap Ramps 1.6
//RepRapDiscount Full Graphic Smart Controller
//https://forum.arduino.cc/t/showing-encoder-value-on-lcd/1130690
#include <Arduino.h>
#include <U8g2lib.h>
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif
//LCD Encoder Pins - https://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller
#define CLK 31 //Enc Btn 2
#define DT 33 //Enc Btn 1
#define SW 35 //Enc Btn
//LCD Screen Pins - https://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller
#define SCK 23 //LCD Data Bus 4bit Mode
#define MOSI 17 //LCD RS/CS (Enable Trigger)
#define CS 16 //LCD SID//RW Control
U8G2_ST7920_128X64_F_SW_SPI u8g2(U8G2_R0,SCK,MOSI,CS,U8X8_PIN_NONE);
int enc_counter = 0;
int enc_state;
int enc_laststate;
String enc_text;
void u8g2_prepare(void) {
u8g2.setFont(u8g2_font_7x14_tf);
u8g2.setFontRefHeightExtendedText();
u8g2.setDrawColor(1);
u8g2.setFontPosTop();
u8g2.setFontDirection(0);
}
void setup() {
pinMode(10,OUTPUT);
pinMode(9,OUTPUT);
digitalWrite(10,0);
digitalWrite(9,0);
u8g2.begin();
pinMode(CLK,INPUT_PULLUP);
pinMode(DT,INPUT_PULLUP);
pinMode(SW,INPUT_PULLUP);
enc_laststate = digitalRead(CLK);
}
void loop() {
enc_state = digitalRead(CLK);
if(enc_state != enc_laststate)
{
if(digitalRead(DT) != enc_state)
{
enc_counter++;
}
else
{
enc_counter--;
}
}
if((digitalRead(SW) != 1) && (enc_counter != 0))
{
enc_counter=0;
}
enc_laststate=enc_state;
enc_text="Encoder: "+String(enc_counter);
u8g2.firstPage();
do {
u8g2.setFont(u8g2_font_7x14_tf);
u8g2.drawStr(5,15,enc_text.c_str());
} while( u8g2.nextPage() );
}
In the future, I want to create a simple menu for my custom project and run my stepper motors depending on the values selected on the screen menu.
Thank you.
bkarpuz
Won't that slow things down?
It must be slowing down for sure but even when I rotate the encoder slowly, it usually does not update its value.
On the other hand, when I upload the Marlin Firmware, I see that the encoder does not skip any menu items and works properly.
This makes me think there is something wrong.
Thank you.
bkarpuz
I can recommend the Encoder library . That library uses interrupts so will read faster since you don't need to poll the inputs. The Encoder library needs 1 or 2 of the hardware interrupts (Mega has 6).
Mega hardware serial pins:
Arduino Mega 2, 3, 18, 19, 20, 21
3 Likes
gcjr
May 25, 2023, 8:21am
5
won't this get in the way of updating enc_counter
?
1 Like
bkarpuz:
u8g2.nextPage()
As far as I understand, I should not use do-while loop and just use
u8g2.setFont(u8g2_font_7x14_tf);
u8g2.drawStr(5,15,enc_text.c_str());
and It would be better if I use it righ here
if(enc_state != enc_laststate)
{
if(digitalRead(DT) != enc_state)
{
enc_counter++;
}
else
{
enc_counter--;
}
//Update screen when enc_counter changes.
}
Do you think it would be useful? I wil ltry this as soon as I go back to home from work.
Thank you.
bkarpuz
gcjr
May 25, 2023, 10:35am
7
why not
void loop ()
{
enc_state = digitalRead (CLK);
if (enc_state != enc_laststate) {
enc_laststate = enc_state;
if (digitalRead (DT) != enc_state) {
enc_counter++;
}
else {
enc_counter--;
}
}
enc_text="Encoder: "+String (enc_counter);
u8g2.firstPage ();
u8g2.drawStr (5, 15, enc_text.c_str ());
}
doesn't this only need to be done once in setup()
?
I have checked a Hello World! example , which applied that line in a loop. But you are right, it should be just in void setup only.
Oh, okay gcjr , you made my path much clear. Thank you very much.
bkarpuz
Thank you very much SemperIdem , groundFungus and gcjr for your guidance, I have analized the encoder values and came up with a working code. This time, I am just updating the screen only when it is necessary. It increases/decreases the counter upon rotation of the encoder, and resets the counter (also beeps) when the encoder button is pressed.
//Arduino Mega
//RepRap Ramps 1.6
//RepRapDiscount Full Graphic Smart Controller
#include <Arduino.h>
#include <U8g2lib.h>
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif
//https://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller
//LCD Beeper Pins
#define BZR 37 //Beeper
//LCD Encoder Pins
#define CLK 31 //Enc Btn 2
#define DT 33 //Enc Btn 1
#define SW 35 //Enc Btn
//LCD Screen Pins
#define SCK 23 //LCD Data Bus 4bit Mode
#define MOSI 17 //LCD RS/CS (Enable Trigger)
#define CS 16 //LCD SID//RW Control
U8G2_ST7920_128X64_F_SW_SPI u8g2(U8G2_R0,SCK,MOSI,CS,U8X8_PIN_NONE);
int enc_counter = 0;
String enc_text = "0";
int clk_state[4] = {1, 1, 1, 1};
int dt_state[4] = {1, 1, 1, 1};
int sw_state[2] = {1, 1};
int current_clk_state = 1;
int current_dt_state = 1;
int current_sw_state = 1;
void u8g2_prepare() {
u8g2.begin();
u8g2.setFont(u8g2_font_7x14_tf);
u8g2.setFontRefHeightExtendedText();
u8g2.setDrawColor(1);
u8g2.setFontPosTop();
u8g2.setFontDirection(0);
}
void u8g2_update() {
u8g2.clearBuffer();
u8g2.drawStr(5,11,"Encoder Value");
enc_text = String(enc_counter);
u8g2.drawStr(5,23,enc_text.c_str());
u8g2.sendBuffer();
}
void beep() {
digitalWrite(BZR,HIGH);
delay(1);
digitalWrite(BZR,LOW);
}
void setup() {
pinMode(BZR,OUTPUT);
pinMode(CLK,INPUT_PULLUP);
pinMode(DT,INPUT_PULLUP);
pinMode(SW,INPUT_PULLUP);
u8g2_prepare();
u8g2_update();
Serial.begin(9600);
Serial.println(enc_counter);
}
void loop() {
current_clk_state = digitalRead(CLK);
current_dt_state = digitalRead(DT);
if((current_clk_state != clk_state[0]) || (current_dt_state != dt_state[0]))
{
//Update last 4 encoder values
for (int i = 2; i >=0; i = i - 1) {
clk_state[i+1] = clk_state[i];
dt_state[i+1] = dt_state[i];
}
clk_state[0] = current_clk_state;
dt_state[0] = current_dt_state;
if ((clk_state[0] == 1) && (dt_state[0] == 1) && (clk_state[2] == 0) && (dt_state[2] == 0))
{
if ((clk_state[1] == 1) && (dt_state[1] == 0) && (clk_state[3] == 0) && (dt_state[3] == 1))
{
//Encoder has been rotated CW
Serial.println("CW");
enc_counter = enc_counter + 1;
Serial.println(enc_counter);
u8g2_update();
}
else if ((clk_state[1] == 0) && (dt_state[1] == 1) && (clk_state[3] == 1) && (dt_state[3] == 0))
{
//Encoder has been rotated CCW
Serial.println("CCW");
enc_counter = enc_counter - 1;
Serial.println(enc_counter);
u8g2_update();
}
}
}
current_sw_state = digitalRead(SW);
if(current_sw_state != sw_state[0])
{
sw_state[1] = sw_state[0];
sw_state[0] = current_sw_state;
if ((sw_state[0] == 1) && (sw_state[1] == 0))
{
//Button has been released
Serial.println("Up");
enc_counter = 0;
Serial.println(enc_counter);
u8g2_update();
beep();
}
else if ((sw_state[0] == 0) && (sw_state[1] == 1))
{
//Button has been pressed
Serial.println("Down");
}
}
}
Note: In this update skipping of the encoder is fixed.
system
Closed
November 21, 2023, 3:26pm
10
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.