Help with Arduino code
#1
I found a sketch on CNCZone that uses an Arduino with an I2C module on the LCD, and a 4x4 matrix keypad to control a Rotary Table. The sketch allows input of a # of degrees to move the RT.
I have adapted the code to my specific setup and have it working with the exception that it won't change direction. Will the Arduino/C++ experts please take a look at the code and see if there is something obvious. As it is, I can input # 0f degrees and cause stepper movement, repeat the movement, and reset to enter different # of degrees,but the direction option doesn't work. Either direction option moves the stepper in the same direction.

Code:
/*
Degrees only
This sketch was downloaded from http://www.cnczone.com/forums/arduino/215402-cnc.html#post1461918.
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 = 1;
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(0,3);
   lcd.print("                    ");
   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;
  }
  }
   Direction = d;  
lcd.clear();  
return d;
//lcd.print(d);
//delay(2000);
}

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,

Chuck
Micromark 7x14 Lathe, X2 Mill , old Green 4x6 bandsaw
The difficult takes me a while, the impossible takes a little longer.
Reply
Thanks given by:
#2
Does the display say REV when it's supposed to be going reverse?
Reply
Thanks given by:
#3
Chuck,

We need to know the details of your stepper motor driver board. Brand, model number, schematic would be nice but probably not necessary, yet.

By the way, thanks for the link to the CNC thread. It may be useful when I get around to attaching a stepper motor to a spin indexer.

Ed

EDIT: OK, I see in the code you say it a Pololu stepper driver. I only need to know the model number now.
Reply
Thanks given by:
#4
The stepper driver details aren't the issue here. They are outputs. The outputs will work with any stepper driver and stepper configuration. The sketch is the issue. The stepper driver and stepper are working with the sketch, I just can't get the sketch to work in reverse.
I'm not trying to be a smart ass, but the stepper and driver are working. The sketch is not manipulating the inputs to reverse the stepper. That's where I need the help. Direction works one way, not the other. Dir command is either a high or low. Granted, I'm an old bugger and a crap programmer, but I usually do pretty fair on troubleshooting. I'm getting step commands, so that part is working. The sketch as it is, works, just the method of reversing direction is not working.
I want to add the keypad for input to the sketch written by Chuck Fellows and posted on HMEM. That one works, but requires entering divisions by repetitive key presses instead of a number.

Chuck
Micromark 7x14 Lathe, X2 Mill , old Green 4x6 bandsaw
The difficult takes me a while, the impossible takes a little longer.
Reply
Thanks given by:
#5
So the "the stepper and driver are working" but it's not reversing. Seems like a contradiction in terms. How do you know that the hardware is working if it doesn't reverse?
Oh, and I'm not trying to be a smart ass either. I just like to have all information available to me in order to make an intelligent reply. An easy way to test the hardware is to write some temporary code that forces it to turn in reverse. If it does, then it has to be in the original code.

Ed
Reply
Thanks given by:
#6
I'll try this again. Does the display say REV when it's supposed to be reversing?
Logan 200, Index 40H Mill, Boyer-Shultz 612 Surface Grinder, HF 4x6 Bandsaw, a shear with no name, ...
the nobucks boutique etsy shop  |  the nobucks boutique
Reply
Thanks given by:
#7
Yes, the display says REV when it's supposed to be running in the opposite direction of FWD.

Chuck
Micromark 7x14 Lathe, X2 Mill , old Green 4x6 bandsaw
The difficult takes me a while, the impossible takes a little longer.
Reply
Thanks given by:
#8
Following Vinny's lead I would check ... each step in order ...

  1. the direction input on the driver is connected to the correct output pin on the Arduino [operator error]
  2. disconnect the direction wire between the Arduino and the driver and then ...
  • put an indicator on the Arduino direction output pin (possibly a LED) and make sure it is low when FWD is in the display and high when REV is in the display [something may be wrong in the code in that what is on the display does not agree with what is on the pin] [Note that I may have the actual state ... low or high ... wrong but the salient point is that what ever it is in FWD is NOT what it is in REV]
  • tie the direction input on the driver high then enter a 'move' command on the keypad to generate stepping pulses and see what direction the table moves; then tie the direction input low, again the move command and ensure the table goes in the other direction [possibly a wiring issue ... see step (a), a defective driver or a stepper to driver wiring issue]
Arvid
Reply
Thanks given by:
#9
I tied the dir input on the stepper driver to gnd on the Arduino and it works in the reverse direction, remove the gnd and reconnect the dir output, or leave it unconnected, and it runs in the other direction. The problem is the sketch is not changing the output value per keypad input. I even changed the step and direction output pins from 12 and 13 to 2 and 3 on the Arduino. Same results.
I don't understand the whole process well enough, I guess. I'll try making a logic flow diagram of the sketch. That's what I used to do with Basic programs back in the day...
No where did I put that logic symbol drafting template...
I thank all those that have looked at the sketch and tried to help.

Chuck
Micromark 7x14 Lathe, X2 Mill , old Green 4x6 bandsaw
The difficult takes me a while, the impossible takes a little longer.
Reply
Thanks given by:
#10
That information helps Chuck.

Looking at the code:

Code:
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("      ");      
   }

The rotation function gets passed a negative number via ToMove.

The rotation function:

Code:
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);              
  }
}

has a "for" loop who's counter is compared to that negative number. I don't think the counter will ever be less than that negative number so the loop won't ever run. I think Arvid needs to verify that since it makes my brain hurt.   Blush

Ed
Reply
Thanks given by:




Users browsing this thread: 5 Guest(s)