Arduino RT Controller with keypad

Help Support HMEM:

chucketn

Senior Citizen
Joined
Dec 17, 2009
Messages
1,309
Reaction score
156
Location
Near Jonesborough, TN
I found a sketch on CNCZone to control a RT with the Arduino that incorporates a 4x4 matrix keypad for input of #degrees of movement. It uses an I2C interface on the LCD to save inputs for the keypad. I have adapted the sketch to my setup, and it works well enough to make it a permanent setup.
I do have one problem I need help with. I can't get it to change direction of rotation. Could I get the Arduino/C++ experts to look at the attached sketch and see if they can spot the problem, please?


Code:
/*
Degrees only
This sketch was downloaded from [URL]http://www.cnczone.com/forums/arduino/215402-cnc.html#post1461918[/URL].
It is the first sketch in the thread. I have modified it to match my setup.
Sketch works to set # of degree to rotate, but I cannot get it to change direction.
A program for controlling a single stepper motor driving a rotary table.
Uses a 4x4 matrix keypad for entry of degrees and direction to move the table.
Serial I2C display, Pololu stepper driver.
*/

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'.','0','#','D'}
};
byte rowPINS[ROWS] = {11,10,9,8};
byte colPINS[COLS] = {7,6,5,4};
Keypad kpd = Keypad(makeKeymap(keys),rowPINS,colPINS, ROWS, COLS);
LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x20 for a 16 chars and 2 line display
 //setup vars
const int stp = 12;  //connect pin 12 to step
const int dir = 13;  // connect pin 13 to dir
const int StepsPerRotation = 200; //Set Steps per rotation of stepper
const int TableRatio = 90; //ratio of rotary table
const int Multiplier = (StepsPerRotation * TableRatio)/360;
const int stepdelay = 1;
 float Degrees = 0;                //Degrees from Serial input
 float ToMove = 0;                 //Steps to move
 int Direction = 0;
 int repeat = 0;
 
 
void setup()
{
  lcd.init();                      // initialize the lcd 
  pinMode(stp, OUTPUT);
  pinMode(dir, OUTPUT); 
 
  // Print welcome message to the LCD.
  lcd.backlight();
  lcd.print("Rotary Control");
  lcd.setCursor(0,2);
  lcd.print("by sloucs,on CNCZone");
  lcd.setCursor(0,3);
  lcd.print("Modified by Chucketn" );
  delay(2000);
  
}
void rotation(float tm, int d)
{   
  if(d == 0)
  {
    digitalWrite(dir, LOW);
  }
  else
  {
    digitalWrite(dir, HIGH);
  }
  
  for(int i = 0; i < tm; i++)  
   {    
    digitalWrite(stp, HIGH);   
    delay(stepdelay);               
    digitalWrite(stp, LOW);  
    delay(stepdelay);              
   }
}
float GetNumber()
{
   float num = 0.00;
   float decimal = 0.00;
   float decnum = 0.00;
   int counter = 0;
   char key = kpd.getKey();
   lcd.print("Rotary Control");
   lcd.setCursor(0,2);lcd.print("Enter Deg & Press #");
  
   lcd.setCursor(8,1);
   bool decOffset = false;
   while(key != '#')
   {
      switch (key)
      {
         case NO_KEY:
            break;
            
         case '.':
           if(!decOffset)
           {
             decOffset = true;
           }
            lcd.print(key);
            break;   
           
         case '0': case '1': case '2': case '3': case '4':
         case '5': case '6': case '7': case '8': case '9':
         if(!decOffset)
         {
            num = num * 10 + (key - '0');
            lcd.print(key);
         }
         else if((decOffset) && (counter <= 1))
         {
            num = num * 10 + (key - '0');
            lcd.print(key);
            counter++;
         }
            break;
      }
      decnum = num / pow(10, counter);
      key = kpd.getKey();
   }
  return decnum;
}
int GetDirection()
{
  int d = 0;
  lcd.setCursor(0,2);
  lcd.print("                    ");
  
  lcd.setCursor(0,3);
  lcd.print("    FWD[A] REV[B]");
  while(d == 0)
  {
  char key = kpd.getKey();
  if(key == 'A')
  {
    d = 1;
  }
  else if(key == 'B')
  {
    d = -1;
  }
  }
     
lcd.clear();  
return d;
}
void loop()
{
    if(repeat == 0)
    {
      Degrees = GetNumber();
      Direction = GetDirection();
    }
    
    Degrees = Degrees * Direction;
    if(Degrees < 0)
    {
      ToMove = (Degrees*Multiplier)*-1;
      lcd.setCursor(0,0);
      lcd.print("REV");
      lcd.print(abs(Degrees),2);
      lcd.print((char)223);
      lcd.setCursor(8,1);
      lcd.print("Moving");
      rotation(ToMove,0);
      lcd.setCursor(8,1);
      lcd.print("      ");      
    }
    else
    {
      ToMove = Degrees*Multiplier;
      lcd.setCursor(0,0);
      lcd.print("FWD  ");
      
      lcd.print(Degrees,2);
      lcd.print((char)223);
      lcd.setCursor(8,1);
      lcd.print("Moving ");
      rotation(ToMove,1);
      lcd.setCursor(8,1);
      lcd.print("      "); 
    }
    lcd.setCursor(0,1);
    lcd.print("To Cont  Press [A]");
    lcd.setCursor(0,2);
    lcd.print("To Reset Press [D]");
    char key = kpd.getKey();
    while(key != 'D')
    {
      key = kpd.getKey();
      if(key == 'A')
      {
        if(Degrees < 0)
        {
          ToMove = (Degrees*Multiplier)*-1;
          lcd.setCursor(8,1);
          lcd.print("Moving");
          rotation(ToMove,0);
          lcd.setCursor(8,1);
          lcd.print("      ");          
        }
        else
        {
          ToMove = Degrees*Multiplier;
          lcd.setCursor(8,1);
          lcd.print("Moving");
          rotation(ToMove,1);
          lcd.setCursor(8,1);
          lcd.print("      ");          
        }
      }
    }
    lcd.clear();
    
}
Thanks in advance. The same thread has modified the code to select movement by divisions or degrees, but I can't get that one to move at all.

Chuck
 

Latest posts

Top