Help with intergrating button toggle into DRO Sketch

Hi,

my first post so go easy on me, i have managed to get this code working after days and nights of research, merging code from old projects and tutorials online.

I would really appreciate some help.

The thing i need to change or would like to change is the toggle from MM to Inch without have to hold the monentary button down. remember button state ? i have looked at the examples and others code but cannot seem to get this working, hear is the code i have so far but have to hold the toggle button.

this is running on Arduino Mega

thanks in advance

//in progress V1.0
#include <Encoder.h>// Encoder library.
#include <LiquidCrystal_I2C.h> //IC2 LCD library.
LiquidCrystal_I2C lcd(0x20, 4, 5, 6, 0, 1, 2, 3, 7, NEGATIVE);  // Set the LCD I2C address
Encoder Rotary_1(2,3);// Connected to Digital pins 2 and 3.
Encoder Rotary_2(19,18);// Connected to Digital pins 19 and 18.


//Setup Buttons
#define reset_1 8
#define reset_2 6
#define inch_button 7

float tmpz = 0;
float tmpx = 0;

void setup() {
  lcd.begin(16, 2);
  pinMode (reset_1, INPUT_PULLUP);
  pinMode (reset_2, INPUT_PULLUP);
  pinMode (inch_button, INPUT_PULLUP);
 }
  long oldPosition_1 = -999;
  long oldPosition_2 = -999;

void loop() {
  const float inch = 25.4;                  // divide MM Reading with 25.4 to get inch reading
  
  const float Wv_z = (0.159155 * PI) / 24;  // Math formula 24 pulse/revolution encoder on z axis
                                            
  const float Wv_x = (0.159155 * PI) / 24;    // Math formula 24 pulse/revolution encoder on x axis
                                             
if (digitalRead(inch_button) == LOW) { 
  long newPosition_1 = Rotary_1.read();     //Read Rotary_1 current position
  lcd.setCursor(0, 0);
  lcd.print("Z");
  lcd.setCursor(2,0); 
  tmpz = Wv_z * newPosition_1 / inch;       //Math formula, Encoder Current position / 25.4, 4 decimals z axis
  lcd.print(tmpz, 5);                       //Print Distance Travelled in inches with 5 decimals
  lcd.print(" inch");                       
}
else { 

  lcd.setCursor(0, 0);
  lcd.print("Z");
  long newPosition_1 = Rotary_1.read();     //Read Rotary_1 current position
  if (newPosition_1 != oldPosition_1)       //If newposition is not equal to oldposition
  lcd.setCursor(2, 0);
  lcd.print(Wv_z * newPosition_1, 5);       //Math formula * Encoder reading ,5 decimals z axis
  lcd.print(" mm");
{
  lcd.print("                "); 
} 
}

if (digitalRead(inch_button) == LOW) {      //Check to see if inch button is pressed
  long newPosition_2 = Rotary_2.read();     //Read Rotary_2 current position
  lcd.setCursor(0, 1);
  lcd.print("X");
  lcd.setCursor(2,1); 
  tmpx = Wv_x * newPosition_2 / inch;       //Math formula, Encoder Current position / 25.4, 4 decimals x axis
  lcd.print(tmpx, 5);                       //Print Distance Travelled in inches with 5 decimals
  lcd.print(" inch");
}
else { 

  lcd.setCursor(0, 1);
  lcd.print("X");
  long newPosition_2 = Rotary_2.read();     //Read Rotary_2 current position
  if (newPosition_2 != oldPosition_2)       //If newposition is not equal to oldposition
  lcd.setCursor(2, 1);
  lcd.print(Wv_x * newPosition_2, 5);       //Math formula * Encoder reading ,5 decimals z axis
  lcd.print(" mm");
{
  lcd.print("                "); 
} 
}

//Reset Z Axis
  if(digitalRead(reset_1)== LOW)            //Check to see if Z is to be reset
 { 
  Rotary_1.write(0);                        //Reset Rotary_1 to 0
 } 

//Reset X Axis
  if(digitalRead(reset_2)== LOW)            //Check to see if X is to be reset
 { 
  Rotary_2.write(0);                        //Reset Rotary_2 to 0
 } 
 }

In principle, you do something like:

bool mmUnits = true;   // Global. By default, measurement is set to mm
. . . 

loop()  {
. . . 
   if (digitalRead(inch_button) == LOW) {      //Check to see if inch button is pressed
      mmUnits = !mmUnits ;   // toggle mmUnits
      delay(200) ; // crude debounce 
   }


. . .

   if ( mmUnit == true ) {
   // do mm stuff
   }
   else {
   // do inch stuff
   }

}

Don't use a momentaryr button. Use a 2 way switch!

Thanks for the quick response.

I have been looking at this code

#include <LiquidCrystal_I2C.h> //IC2 LCD library.
LiquidCrystal_I2C lcd(0x20, 4, 5, 6, 0, 1, 2, 3, 7, NEGATIVE);  // Set the LCD I2C addressconst

 int switch_out = 8;
 int inchbutton = 7;
 int inchbuttonstate = 0;         
 int inchbuttonStay = 0;
 int inchbuttonChange = 0;

void setup() {
  lcd.begin(16, 2);
  pinMode(inchbutton, INPUT_PULLUP);
  pinMode(switch_out, OUTPUT);
  lcd.write("MM");
 }

void loop() {

inchbuttonstate = digitalRead(inchbutton);

if (inchbuttonstate == HIGH) {    // check if the pushbutton is pressed. if it is, the buttonState is HIGH, switch is on
if (inchbuttonChange == 1) {      //switch was just recently changed to on
    inchbuttonChange = 0;
if ( inchbuttonStay == 0 ) {
    inchbuttonStay = 1;
 digitalWrite(switch_out, HIGH);
{
    lcd.print("                "); 
} 

}
else {
    inchbuttonStay = 0;
digitalWrite(switch_out, LOW);
}
}
}
else 
{
   inchbuttonChange = 1;     // switch is off
}
}

it seems to work when i test it on the mega. but im having trouble merging this with my DRO sketch.

any help would be appriciated..

thanks.

laching switch sound good but really would like to do it by code

mr_shifta_uk:
im having trouble merging this with my DRO sketch.

Then perhaps post your DRO (whatever that means) sketch.

jubukraa:
Then perhaps post your DRO (whatever that means) sketch.

DRO - Digital Read Out

my dro sketch in in my first post

mr_shifta_uk:
Hi,

my first post so go easy on me, i have managed to get this code working after days and nights of research, merging code from old projects and tutorials online.

I would really appreciate some help.

The thing i need to change or would like to change is the toggle from MM to Inch without have to hold the monentary button down. remember button state ? i have looked at the examples and others code but cannot seem to get this working, hear is the code i have so far but have to hold the toggle button.

this is running on Arduino Mega

thanks in advance

//in progress V1.0

#include <Encoder.h>// Encoder library.
#include <LiquidCrystal_I2C.h> //IC2 LCD library.
LiquidCrystal_I2C lcd(0x20, 4, 5, 6, 0, 1, 2, 3, 7, NEGATIVE);  // Set the LCD I2C address
Encoder Rotary_1(2,3);// Connected to Digital pins 2 and 3.
Encoder Rotary_2(19,18);// Connected to Digital pins 19 and 18.

//Setup Buttons
#define reset_1 8
#define reset_2 6
#define inch_button 7

float tmpz = 0;
float tmpx = 0;

void setup() {
  lcd.begin(16, 2);
  pinMode (reset_1, INPUT_PULLUP);
  pinMode (reset_2, INPUT_PULLUP);
  pinMode (inch_button, INPUT_PULLUP);
}
  long oldPosition_1 = -999;
  long oldPosition_2 = -999;

void loop() {
  const float inch = 25.4;                  // divide MM Reading with 25.4 to get inch reading
 
  const float Wv_z = (0.159155 * PI) / 24;  // Math formula 24 pulse/revolution encoder on z axis
                                           
  const float Wv_x = (0.159155 * PI) / 24;    // Math formula 24 pulse/revolution encoder on x axis
                                           
if (digitalRead(inch_button) == LOW) {
  long newPosition_1 = Rotary_1.read();    //Read Rotary_1 current position
  lcd.setCursor(0, 0);
  lcd.print("Z");
  lcd.setCursor(2,0);
  tmpz = Wv_z * newPosition_1 / inch;      //Math formula, Encoder Current position / 25.4, 4 decimals z axis
  lcd.print(tmpz, 5);                      //Print Distance Travelled in inches with 5 decimals
  lcd.print(" inch");                     
}
else {

lcd.setCursor(0, 0);
  lcd.print("Z");
  long newPosition_1 = Rotary_1.read();    //Read Rotary_1 current position
  if (newPosition_1 != oldPosition_1)      //If newposition is not equal to oldposition
  lcd.setCursor(2, 0);
  lcd.print(Wv_z * newPosition_1, 5);      //Math formula * Encoder reading ,5 decimals z axis
  lcd.print(" mm");
{
  lcd.print("                ");
}
}

if (digitalRead(inch_button) == LOW) {      //Check to see if inch button is pressed
  long newPosition_2 = Rotary_2.read();    //Read Rotary_2 current position
  lcd.setCursor(0, 1);
  lcd.print("X");
  lcd.setCursor(2,1);
  tmpx = Wv_x * newPosition_2 / inch;      //Math formula, Encoder Current position / 25.4, 4 decimals x axis
  lcd.print(tmpx, 5);                      //Print Distance Travelled in inches with 5 decimals
  lcd.print(" inch");
}
else {

lcd.setCursor(0, 1);
  lcd.print("X");
  long newPosition_2 = Rotary_2.read();    //Read Rotary_2 current position
  if (newPosition_2 != oldPosition_2)      //If newposition is not equal to oldposition
  lcd.setCursor(2, 1);
  lcd.print(Wv_x * newPosition_2, 5);      //Math formula * Encoder reading ,5 decimals z axis
  lcd.print(" mm");
{
  lcd.print("                ");
}
}

//Reset Z Axis
  if(digitalRead(reset_1)== LOW)            //Check to see if Z is to be reset
{
  Rotary_1.write(0);                        //Reset Rotary_1 to 0
}

//Reset X Axis
  if(digitalRead(reset_2)== LOW)            //Check to see if X is to be reset
{
  Rotary_2.write(0);                        //Reset Rotary_2 to 0
}
}

Thanks

mr_shifta_uk:
my dro sketch in in my first post

Oops sorry, not sure how I missed that.

(and my specs are on....)

lcd.print(Wv_z * newPosition_1, 5);

Why not:

lcd.print(newPosition_1 / 48.0, 5);

?

Thanks JCA34F

That freed up a few lines, all improvements welcome. Still need to figure out how to remember button state so one press would stay and update inches another press back to MM :slight_smile:

mr_shifta_uk:
That freed up a few lines, all improvements welcome. Still need to figure out how to remember button state so one press would stay and update inches another press back to MM :slight_smile:

Use a variable. :roll_eyes:

Maybe look again at the suggested solution in post #1.

6v6gt:
Maybe look again at the suggested solution in post #1.

ok so i have added the variable, and it loads up to a blank display intil you pless the toggle button, the toggle button now toggles between mm and inch but does not update the reading until you toggle mm and inch.

any help in adding this or correcting my errors would be much appriciated.

thanks.

this is what i have so far

#include <Encoder.h>// Encoder library.
#include <LiquidCrystal_I2C.h> //IC2 LCD library.
LiquidCrystal_I2C lcd(0x20, 4, 5, 6, 0, 1, 2, 3, 7, NEGATIVE);  // Set the LCD I2C address
Encoder Rotary_1(2,3);// Connected to Digital pins 2 and 3.
Encoder Rotary_2(19,18);// Connected to Digital pins 19 and 18.

 bool mmUnits = true;

//Setup Buttons
#define reset_1 8
#define reset_2 6
#define inch_button 7

  float tmpz = 0;
  float tmpx = 0;

void setup() {
  Serial.begin(9600);                             //For testing without display
  lcd.begin(16, 2);
  pinMode (reset_1, INPUT_PULLUP);
  pinMode (reset_2, INPUT_PULLUP);
  pinMode (inch_button, INPUT_PULLUP);
}
  long oldPosition_1 = -999;
  long oldPosition_2 = -999;

void loop() {
  if (digitalRead(inch_button) == LOW) {      //Check to see if inch button is pressed 
   mmUnits = !mmUnits ;   // toggle mmUnits 
   delay(200) ; // crude debounce 
 
  
  if  (digitalRead(inch_button) == LOW) { 
}
  if ( mmUnits == true ) {
  long newPosition_1 = Rotary_1.read();           //Read Rotary_1 current position
  lcd.setCursor(0, 0);
  lcd.print("Z");
  lcd.setCursor(2,0); 
  lcd.print(newPosition_1 / 2400.0 / 25.4, 6);      //Encoder position divided steps per revolution divided by 25.4(inch) with 6 decimals
  Serial.print (newPosition_1 / 2400.0 / 25.4, 6);  //For testing without display
  Serial.print(" INCH");//For testing             //For testing without display
  Serial.print("\n");//For testing                //For testing without display
  lcd.print(" INCH");                       
}
else {   
  lcd.setCursor(0, 0);
  lcd.print("Z");                                 
  long newPosition_1 = Rotary_1.read();           //Read Rotary_1 current position
  if (newPosition_1 != oldPosition_1)             //If newposition is not equal to oldposition
  lcd.setCursor(2, 0);
  lcd.print(newPosition_1 / 2400.0, 6);             //Encoder position divided steps per revolution (MM) with 6 decimals 
  Serial.print(newPosition_1 / 2400.0, 5);          //For testing without display
  Serial.print(" MM");                            //For testing without display
  Serial.print("\n");                             //For testing without display
  lcd.print(" MM");
{
  lcd.print("                "); 
} 
}
if (digitalRead(inch_button) == LOW) {            //Check to see if inch button is pressed
  long newPosition_2 = Rotary_2.read();           //Read Rotary_2 current position
  lcd.setCursor(0, 1);
  lcd.print("X");
  lcd.setCursor(2,1); 
  lcd.print(newPosition_2 / 2400.0 / 25.4, 6);      //Encoder position divided steps per revolution divided by 25.4(inch) with 6 decimals
  lcd.print(" INCH");
}
else { 
  lcd.setCursor(0, 1);
  lcd.print("X");
  long newPosition_2 = Rotary_2.read();           //Read Rotary_2 current position
  if (newPosition_2 != oldPosition_2)             //If newposition is not equal to oldposition
  lcd.setCursor(2, 1);
  lcd.print(newPosition_2 / 2400.0, 6);             //Encoder position divided steps per revolution (MM) with 6 decimals
  lcd.print(" MM");
{
  lcd.print("                "); 
} 
}
//Reset Z Axis
  if(digitalRead(reset_1)== LOW)                  //Check to see if Z is to be reset
 { 
  Rotary_1.write(0);                              //Reset Rotary_1 to 0
 } 
//Reset X Axis
  if(digitalRead(reset_2)== LOW)                  //Check to see if X is to be reset
 { 
  Rotary_2.write(0);                              //Reset Rotary_2 to 0
 } 
 }
}

Well, you still have this code which needs the button to be pressed and, if it detects it has been pressed, assumes that the units are inches.:

if (digitalRead(inch_button) == LOW) {            //Check to see if inch button is pressed
  long newPosition_2 = Rotary_2.read();           //Read Rotary_2 current position
  lcd.setCursor(0, 1);
  lcd.print("X");
  lcd.setCursor(2,1);
  lcd.print(newPosition_2 / 2400.0 / 25.4, 6);      //Encoder position divided steps per revolution divided by 25.4(inch) with 6 decimals
  lcd.print(" INCH");
}
else {
  lcd.setCursor(0, 1);
  lcd.print("X");
  long newPosition_2 = Rotary_2.read();           //Read Rotary_2 current position
  if (newPosition_2 != oldPosition_2)             //If newposition is not equal to oldposition
  lcd.setCursor(2, 1);
  lcd.print(newPosition_2 / 2400.0, 6);             //Encoder position divided steps per revolution (MM) with 6 decimals
  lcd.print(" MM");
{
  lcd.print("                ");
}
}

You could change this:

if (digitalRead(inch_button) == LOW) { . . .

to:

if ( mmUnits == false ) { . . .

Incidentally, you have this:

if ( mmUnits == true ) { . . .

where the following code is related to inches. This may cause confusion and it would be better if you had:

if ( mmUnits == false ) { . . .

Also, when you post code, please use the code formatter in the IDE beforehand to structure the indentation.

OK, so with the help and support of all of you that have steered me in the right direction i now have this code doing what i want it to..... thanks (6v6gt). no doubt there will be room for improvment. i am open to sugestions.

again thanks alot

this is what i have ....and formatted in IDE :slight_smile:

#include <Encoder.h>// Encoder library.
#include <LiquidCrystal_I2C.h> //IC2 LCD library.
LiquidCrystal_I2C lcd(0x20, 4, 5, 6, 0, 1, 2, 3, 7, NEGATIVE);      // Set the LCD I2C address for 16x2 LCD
//LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);    // Set the LCD I2C address for 20x4 LCD
Encoder Rotary_z(2, 3); // Connected to Digital pins 2 and 3.
Encoder Rotary_x(19, 18); // Connected to Digital pins 19 and 18.

bool mmUnits = true;

//Setup Buttons
#define reset_z 7
#define reset_x 6
#define inch_button 8

void setup() {
  // lcd.begin(20, 4);                                //for 20x4 display
  lcd.begin(16, 2);                                   //for 16x2 display
  pinMode (reset_z, INPUT_PULLUP);
  pinMode (reset_x, INPUT_PULLUP);
  pinMode (inch_button, INPUT_PULLUP);
}

long oldPosition_1 = -999;
long oldPosition_2 = -999;

void loop() {
  if (digitalRead(inch_button) == LOW) {            //Check to see if inch button is pressed
    mmUnits = !mmUnits ;   // toggle mmUnits
    delay(200) ;
  }

  if ( mmUnits == true ) {
    lcd.setCursor(0, 0);
    lcd.print("Z");
    long newPosition_1 = Rotary_z.read();           //Read Rotary_1 current position
    if (newPosition_1 != oldPosition_1)             //If newposition is not equal to oldposition
      lcd.setCursor(2, 0);
    lcd.print(newPosition_1 / 48.0, 6);             //Encoder position divided steps per revolution (MM) with 6 decimals
    lcd.print(" MM");
    {
      lcd.print("                ");
    }
    lcd.setCursor(0, 1);
    lcd.print("X");
    long newPosition_2 = Rotary_x.read();           //Read Rotary_2 current position
    if (newPosition_2 != oldPosition_2)             //If newposition is not equal to oldposition
      lcd.setCursor(2, 1);
    lcd.print(newPosition_2 / 48.0, 6);             //Encoder position divided steps per revolution (MM) with 6 decimals
    lcd.print(" MM");
    {
      lcd.print("                ");
    }
  }

  if ( mmUnits == false ) {
    long newPosition_1 = Rotary_z.read();           //Read Rotary_1 current position
    lcd.setCursor(0, 0);
    lcd.print("Z");
    lcd.setCursor(2, 0);
    lcd.print(newPosition_1 / 48.0 / 25.4, 6);      //Encoder position divided steps per revolution divided by 25.4(inch) with 6 decimals
    lcd.print(" INCH");
  }

  if ( mmUnits == false ) {                         //Check to see if inch button is pressed
    long newPosition_2 = Rotary_x.read();           //Read Rotary_2 current position
    lcd.setCursor(0, 1);
    lcd.print("X");
    lcd.setCursor(2, 1);
    lcd.print(newPosition_2 / 48.0 / 25.4, 6);      //Encoder position divided steps per revolution divided by 25.4(inch) with 6 decimals
    lcd.print(" INCH");
  }

  if (digitalRead(reset_z) == LOW)                  //Check to see if Z is to be reset
  {
    Rotary_z.write(0);                              //Reset Rotary_1 to 0
  }

  if (digitalRead(reset_x) == LOW)                  //Check to see if X is to be reset
  {
    Rotary_x.write(0);                              //Reset Rotary_2 to 0
  }
}

Update:

The code i now have is doing what it should however it measures the backlash (not good). What i want it to do is measure linea movement,

Im going to use:

600p/r quadrature encoder
GT2 Belt Pulley Size: 16 X 16mm (DH) Teeth: 20
GT2 Idler Size: 18 X 8mm (D
H) Teeth: 20

I would be greatfull for any help in setting up the formula i need to use in the above code.

Can it even be done accurately ?

Again

Thanks in Advance

I would suggest using an unsigned long counting pulses. For display, calculations etc. then maybe convert to float. Remember that a float only keeps some 5 digits. Suppose You have made a long move and the want to add one step. That step might be lost if You use a float as the current position.

Thanks Railroader,

I dont think long travel will be a problem on my Mini Lathe.. i hope.

My setup is now:

600p/r quadrature encoder

GT2 Belt Pulley Size: 16 X 16mm (D*H) Teeth: 20

GT2 Idler Size: 18 X 8mm (D*H) Teeth: 20

Changed code to newPosition / 60.0, this now gives me on MM for every full turn using the above setup with no backlash.

Lets say a float handles 5 digits, 99 999. (Not true, it's less.) Assume 1 mm move per 600 pulses. That gives a maximum distance of 167 mm. Surely it's less, maybe 1/8 of it...….
Make a test sketch adding 1 to a float and see where the upcount stops increasing!