# Arduino control for a 3 rotary table



## bmac2

I want to be able to cut the gears, and to do that I needed an indexer or dividing head. Id looked at a lot of plans for different styles of mechanical indexers and was leaning toward A Fairly Simple Dividing Head http://www.deansphotographica.com/machining/projects/divider/dividinghead.html by Dean Williams. 

Then I found Chuck Fellows 2012 thread Electronic Dividing Head using the Arduino http://www.homemodelenginemachinist.com/showthread.php?t=17896 and thought it looked like a much simpler way to go. As things worked out while looking through the surplus section at Princess Auto I found some Arduinos and shields in with the oversized TV remotes, selfie sticks and other bits of electronic detritus. Armed with my new toys I dug out and dusted off a breadboard and started trying to duplicate Chucks controller. Found a schematic for the SainSmart LCD Keypad Shield that Chuck used and after much cursing and searching for libraries I managed to get it to work. Messed around with it for a while but I just didnt like the button interface and the project want into the corner of the workshop dedicated to UFOs (Un Finished Objects). 

I havent done much in the way of programing for many years but I liked the Arduino and ordered Arduino for Dummies and started going through the exercises. Back in January while looking around on the internet I found a thread on CNC Zone for a standalone CNC rotary table controller for Sherline. I liked the use of a keypad for enter as well as the 20x4 text display. Downloaded the sketch and after messing around with a few DIY worm gears I had it running but not well and it went back to the UFO corner.


[ame="https://www.youtube.com/watch?v=-hO4id64xDU"]https://www.youtube.com/watch?v=-hO4id64xDU[/ame]


----------



## bmac2

In the end this is what I came up with. The heart of the software is from bpratl at CNC just tweaked to work with the hardware Im using.

I got things bodgered up with and stepper clamped to my 3 rotary table. 


[ame="https://www.youtube.com/watch?v=oubtFZqDJuc"]https://www.youtube.com/watch?v=oubtFZqDJuc[/ame]

/*
 4x4 matrix keypad amd a 20 x 4 LCD. Edit StepsPerRotation & TableRatio(# of turns for 360 degrees)
 5/2/2015
 */

 #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;  // 200*90=18000/360 = 50
 const int stepdelay = 1;
 float Degrees = 0;                // Degrees from Serial input
 float ToMove = 0;                 // Steps to move
 float bob = 0;
 int cho = 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 Table Control");
 lcd.setCursor(4,2);lcd.print("bpratl CNC");
 lcd.setCursor(3,3);lcd.print("updated 2015");
 delay(2000);
 lcd.init();
   cho = 0;
   char key = kpd.getKey();
   lcd.print("Enter Selection:");   
   lcd.setCursor(0,1);lcd.print("Degrees   = A");
   lcd.setCursor(0,2);lcd.print("Divisions = B");
   lcd.setCursor(0,3);lcd.print("JOG       = C");
   while(cho == 0)
   {
     key = kpd.getKey();
     switch (key)
     {
     case NO_KEY:
      break;
     case 'A':
       Degrees=getdegrees();
       lcd.clear();
       cho = 1;
       break; 
     case 'B':
       Degrees=getdivisions();  
       cho=2;
       break;
     case 'C':
       Degrees=getjog();
       lcd.clear();
       cho=3;
       break;
       }      // end case
     }      // end while cho=0
 }    // end setup

 void loop()      // MAIN LOOP
 {
   lcd.clear();  
   char key = kpd.getKey();
     bob = 0;
     lcd.setCursor(7,0);lcd.print("Total:  ");lcd.print(bob,2);   // total steps
     lcd.setCursor(0,3);lcd.print("FOR=A   REV=B    X=C");
   while(key != 'C')    // C will return to start menu
   {
     lcd.setCursor(0,0);lcd.print(abs(Degrees),2);lcd.print((char)223);
     key = kpd.getKey();
     if(key == 'A')            // FORWARD
       {
        bob = bob + Degrees;
        ToMove = (Degrees*Multiplier);
        digitalWrite(dir, LOW);
        printadvance();
       }
     if(key=='B')              // REVERSE
       {
        bob = bob - Degrees;  
        ToMove = (Degrees*Multiplier);
        digitalWrite(dir, HIGH);    // pin 13
        printadvance();
       }
   }      // end while not C loop
   lcd.init();
  setup();
 }      // end main VOID


float getjog()
{
  float Degrees = 0;
  float num = 0.00;
   char key = kpd.getKey();
   lcd.clear();
   lcd.setCursor(6,0);lcd.print("Jogging");
   lcd.setCursor(0,1);lcd.print("A=1 B=10 C=100 Steps");
   lcd.setCursor(0,2);lcd.print("Enter Degrees:");lcd.setCursor(0,3);lcd.print("OK = #       ");lcd.print((char)60);lcd.print((char)45);lcd.print(" D");

   while(key != '#')
   {
      switch (key)
      {
         case NO_KEY:
            break;
         case 'A':
            Degrees = 1;      
            lcd.setCursor(14,2);lcd.print(Degrees);
            break;
         case 'B':
            Degrees = 10;
            lcd.setCursor(14,2);lcd.print(Degrees);
            break;
         case 'C':
            Degrees = 100;
            lcd.setCursor(14,2);lcd.print(Degrees);
            break;
         case 'D':
          num=0.00;
          lcd.setCursor(14,2);lcd.print("     ");
          lcd.setCursor(14,2);
          break;
      }
      key = kpd.getKey();
   }
  return Degrees; 
}


float getdivisions()
{
  float Degrees = 0; 
  float num = 0.00;
   char key = kpd.getKey();
   lcd.clear();
   lcd.setCursor(0,1);lcd.print("Enter Division:");lcd.setCursor(0,3);lcd.print("OK = #       ");lcd.print((char)60);lcd.print((char)45);lcd.print(" D");
   lcd.setCursor(16,1);

   while(key != '#')
   {
      switch (key)
      {
         case NO_KEY:
            break;

         case '0': case '1': case '2': case '3': case '4':
         case '5': case '6': case '7': case '8': case '9':
            num = num * 10 + (key - '0');
            lcd.print(key);
            break;

        case 'D':
          num=0.00;
          lcd.setCursor(16,1);lcd.print("     ");
          lcd.setCursor(16,1);
          break;
      }
      Degrees = 360/num;
      key = kpd.getKey();
   }
  return Degrees;  //num;
}


float getdegrees()
{ 
   //int key = 0;
   float num = 0.00;
   float decimal = 0.00;
   float decnum = 0.00;
   int counter = 0;
   lcd.clear();
   //lcd.init();
   char key = kpd.getKey();
   lcd.setCursor(0,1);lcd.print("Enter Degrees:");lcd.setCursor(0,3);lcd.print("OK = #       ");lcd.print((char)60);lcd.print((char)45);lcd.print(" D");
   lcd.setCursor(15,1);
   bool decOffset = false;

   while(key != '#')
   {
      switch (key)
      {
         case NO_KEY:
            break;

         case '.':
           if(!decOffset)
           {
             decOffset = true;
           }
            lcd.print(key);
            break;   

         case 'D':
          num=0.00;
          lcd.setCursor(15,1);lcd.print("     ");
          lcd.setCursor(15,1);
          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;
      }    //end case
      decnum = num / pow(10, counter);
      key = kpd.getKey();
   }    //end while not #
    return decnum;
}      // end getdegrees

 void printadvance()      // print function
   {
     lcd.setCursor(6,1);lcd.print("Moving");
     lcd.setCursor(4,2);lcd.print("Steps  ");lcd.print(ToMove,0); 
     lcd.setCursor(13,0);lcd.print(bob,2);
     rotation(ToMove,0);
     lcd.setCursor(6,1);lcd.print("      "); 
  } 

 void rotation(float tm, int d)
   { 
     for(int i = 0; i < tm; i++) 
       { 
       digitalWrite(stp, HIGH); 
       delay(stepdelay); 
       digitalWrite(stp, LOW); 
       delay(stepdelay); 
       }
   }

void software_Reset() // Restarts program from beginning but does not reset the peripherals and registers
  {
  asm volatile ("  jmp 0");  
  }


----------



## bmac2

It was looking pretty good but I got busy with other things and didnt get back to it until now. The stepper motor is thicker than the rotary table and I didnt want to modify the table so I made up a mount that it will overhang on the mill table when mounted flat and not get in the way in the vertical position.


----------



## bmac2

The mount is pretty simple, the larger end is just drilled and bored to fit the NEMA 17 and the smaller end will be bored to slip over the graduated collar on the rotary table and be held in place with the original screws. The two end plates where center drilled then a shallow notch was milled at a (give or take) 5 deg. angle to help keep the sides aligned during soldering.


----------



## bmac2

To hold it together I ran two #4-40 screws through the center joined up with a threaded standoff. This actually worked really well as I could get the parts tightly clamped and gently tap things into alignment. The notches are not at an exact fit so solder should flow, but they keep the sides from sliding out of position.


----------



## bmac2

This was a great idea, terrible execution moment. I had inadvertently grabbed an aluminum standoff. 
Plan B, cleaned it up and this time used a steel standoff. Everything stayed in place during soldering then into the pickle jar.


----------



## bmac2

Straight out of the pickling the solder looked to have good penetration so I set it up in the mill and checked that the ends stayed parallel, then drilled and bored through both plates to maintain alignment. Nothing broke so I gave my solder joints a gold star.:thumbup:


----------



## bmac2

I had to open up the mounting holes for the stepper one size before the screws would slip in but other than that with the flexible coupler everything was turning freely. I still had the test circuit from my laser engraver set up on a bread board so I plugged it in to check it out. You can tell from the sound in the video that the stepper was not happy with the 5v .2amps that the drivers where set at but it was running smoothly. When I was playing it looked like it would accelerate up to speed then slow down before stopping. At first I thought this might be caused by the low voltage but then the light came on that the engraver uses G-code.

[ame]https://www.youtube.com/watch?v=Gnc6Lcuq-7g&feature=youtu.be[/ame]


----------



## bmac2

Theres minimal wiring involved, the serial display only uses +5, Gnd, and 2 analog ports. The stepper driver uses 2 digital ports, one for step and one for direction and the key pad matrix uses 8 digital ports. 
The A/B jumper and regulator arent necessary if the stepper voltage is 12v or less. I added it in case I end up using a different stepper or want to run the one I have at a higher voltage. In position A the DC input goes straight to the Arduino VIN. In position B it goes through a LM7809 9v regulator before going to the Arduino. Im using an old 16v laptop power supply that doesnt need any extra filtering capacitors.


----------



## bmac2

The only box I had that would fit was a 200 x 120 x 75mm waterproof plastic project box. I cut down to 50mm because I dont need the height and this would be a better fit if I ever use it hand held, and to me it just looks better. The display has a slight radius to the corners so I set it up on top of the milling vice (wont fit in) and cut out the opening with a 1/8 end mill. Flipped it around and cut the slot for the ribbon cable on the keypad, then drilled the holes for the power switch and reset button. With all the cut outs it looks like something off Dr. Who.


----------



## bmac2

Mounted the keypad, reset and power switches and epoxied standoffs for the Arduino and the display in place.


----------



## bmac2

Test fit the Arduino and display then drilled the holes for the power jack and the connector for the stepper and got them installed.


----------



## bmac2

Spliced the connector to the stepper motor wires adding another 9 to the overall length then covered everything with some split loom to protect it


----------



## bmac2

Ive read dozens of write-ups on setting the current limit on the a4988 stepper drivers and its a 50/50 split on the voltage calculation to get it right. What I did was make up a simple cable with one of the 4 leads broken out and connected to a multimeter reading the current. The manufactures spec on this motor is .64 amps so I set to give or take .6 amps.


----------



## bmac2

Buttoned up Im pretty happy with the results. The camera does not do this display justice. It is super clear and readable at most any angle.


[ame]https://www.youtube.com/watch?v=rINnNgQQcXQ&feature=youtu.be[/ame]


----------



## bmac2

The shaft on the rotary table has quite a wobble and Im thinking of replacing the flexible coupler with a spider shaft coupling like this one. 

Now I just have to fix the speed control on my Mini-Mill.:fan:


----------



## John S

Bob,
Full marks for this job, especially the keypad.
I have been asking for years [ literally ] why someone can't put one of those cheap keypads on instead of the silly 4 buttons.

As regards your coupling don't use a Lovejoy type they are not flexible enough.
Lokk instaed for an Oldham coupling which is the only coupling made that can handle misalignment in two planes.


----------



## rodw

Looks great. You may be able adjust the alignment simply by loosening and tightening stepper mounting screws. Your mount is a bit different to mine, but adjusting the brass rods that are threaded at the table end did the trick.


----------



## RonGinger

That is a fine bit of work, and a very nicely done log of its building. Excellent post, thank you.


----------



## DJP

When you get to fixing your mini mill controller, I had success by simply re soldering all connections and installing a new speed control pot. It has been solid since then.

I used a simple pot and separate switch as the combined pot/switch looked frail to me for repeated use.

The basic design seems to be OK but the quality control during assembly is the problem.


----------



## bmac2

John, Rod, Ron Thanks guys. 
John I think your right with swapping out the coupler for an Oldham Ive used them before in model boats (didnt know what they were called) but would have never thought of using one here.

Rod, I didnt want to modify the rotary table so all I did was take off the crank handle. At first I thought the shaft was bent but I put a dial indicator on it today and its just not concentric. I suppose if its one of the corners that get cut in cheaper tools. 

DJP
I havent torn down the control box yet, just enough to do a quick and dirty check of the MOSFETs. What its doing is current tripping on start-up unless the speed control is turned up very slowly. When it does start it just chugs along until the speed is high enough that its not noticeable. The boards in my mill look like something I would have worked on back in the mid 90s. I think the problem is going to be in the current limit or the pulse width modulation circuit or both. :toilet: I have been toying with scrapping the controller boards all together and building my own.

[ame]https://www.youtube.com/watch?v=i9q5FsWUf7Q&feature=youtu.be[/ame]


----------



## rodw

bmac2 said:


> John, Rod, Ron Thanks guys.
> 
> 
> Rod, I didnt want to modify the rotary table so all I did was take off the crank handle.



I have not modified the table either. Just took off the handle and utilised the mounting for the optional dividing plates. Consider shimming the stepper mounting bolts to adjust the alignment.


----------



## DJP

Your fingers are on the source of the problem. That pot with switch is very cheaply made and not robust at all. Like you I was considering ways to run the DC motor.  I attached terminals directly to the motor so that I could at least finish a task if the controller failed completely. It limped along for a long time but in frustration I finally replaced it with a pot and separate switch.

The ON/OFF switch is now on the left panel and the pot only controls speed. In the zero speed position the motor will stop. The two DC connection points were installed in case I need to run the mill using a DC power supply.

Since changing the pot and soldering some 'iffy' connections it has bee solid.


----------



## bmac2

Yikes. 
Sorry. 
Just had it pointed out to me via YouTube that the sketch *Does Not Compile*! This was pure sloppiness on my part as all I did was bring it up in the Arduino IDE and copy / paste it into the post. 

Did I check that it worked? 

Did I check it was the right version? 
Nope. :wall:

I just tried pasting it again into this post and I when looked at it in the _Preview_ window some of the punctuation characters must have been picked up by the forum software and dropped out of the text.
This is the CORRECT sketch that does work. Ill attach it as a zip. 

View attachment Arduino_Rotary_Table_Control_2016.zip


----------



## xrayxray

Hi, Was wondering if someone could help...just spent 3 days and nights struggling with Arduino scripts to get my setup opperating and still isn't operating.
Stepper is fitted to rotary table and have a kit arduino Uno assembled....checks out with a blink script, got a 4x4 matrix keypad...blue numbers red letters off ebay and this LCD  http://www.ebay.com.au/itm/131640986477?_trksid=p2057872.m2749.l2649&ssPageName=STRK:MEBIDX:IT I have tried everything to get this working..swapped out Uno, Nano, Mega...tried all sorts of scripts anyway finally found a script that runs this LCD....seems I'm not the only one finding problems with this LCD.....here is the script  View attachment LCD Script.pdf

My question is can this script I found be merged in with the script by Bmac2..... to get my table running...I am such a novice with Arduino and was about to call it quits from the frustration...any help is gratefully received.

Cheers Mike.


----------



## bmac2

Hi Mike
First please use the sketch in the above zip file. Copy and paste from the first page won&#8217;t compile. 
I&#8217;m at work so I can&#8217;t dig into this too far but I have a couple of things you can try just off the top of my head. One that bit me in the bum the first time I tried using an I2C display (got it super cheap from China but . . . . . no manual) is that I2C devices have and address. I see in the sketch you say works with your setup they set the address to 0x3F and in the sketch I used it is set to 0x27. So it might be just a simple edit. 

Another simple one that got me is the jumper on the back of the display. It turns the display back light on and off so you can check that it&#8217;s there, mine was floating around in the antistatic bag. 
All of a sudden I&#8217;m glad I didn&#8217;t clean all those pictures off my iPod.
Hope this helps . . Bob


----------



## Foozer

Have found that what the supplier shows as the i2c address isn't always so.
My own 20x4 came out to be
LiquidCrystal_I2C lcd(0x3B, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address

Can run the brute force scanner to verify what arduino sees . . .

copy, compile, run


// i2c_scanner
// Version 1
//    This program (or code that looks like it)
//    can be found in many places.
//    For example on the Arduino.cc forum.
//    The original author is not know.
// Version 2, Juni 2012, Using Arduino 1.0.1
//     Adapted to be as simple as possible by Arduino.cc user Krodal
// Version 3, Feb 26  2013
//    V3 by louarnold
// Version 4, March 3, 2013, Using Arduino 1.0.3
//    by Arduino.cc user Krodal.
//    Changes by louarnold removed.
//    Scanning addresses changed from 0...127 to 1...119,
//    according to the i2c scanner by Nick Gammon
//    http://www.gammon.com.au/forum/?id=10896
// Version 5, March 28, 2013
//    As version 4, but address scans now to 127.
//    A sensor seems to use address 120.
// Version 6, November 27, 2015.
//    Added waiting for the Leonardo serial communication.
//
//
// This sketch tests the standard 7-bit addresses
// Devices with higher bit address might not be seen properly.
//
#include <Wire.h>
void setup()
{
  Wire.begin();
  Serial.begin(9600);
  while (!Serial);             // Leonardo: wait for serial monitor
  Serial.println("\nI2C Scanner");
}
void loop()
{
  byte error, address;
  int nDevices;
  Serial.println("Scanning...");
  nDevices = 0;
  for(address = 1; address < 127; address++ )
  {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    error = Wire.endTransmission();
    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");
      nDevices++;
    }
    else if (error==4)
    {
      Serial.print("Unknow error at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.println(address,HEX);
    }
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");
  delay(5000);           // wait 5 seconds for next scan
}
Suppliers link shows 

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

as the parameters for the display mentioned


----------



## xrayxray

Hi Bob,
Spent another day trying to figure it out then found out about i2c scanner...which I ran only to find out that no I2c was detected...I had switched from Uno to Mega cos Ftdi broke it's pins into the Uno...anyway then realised that SDA and SDL weren't A4 and A5...about this time I had checked out your post and scanned the I2c again with SDA and SDL in there right place and got an address of 0x3....now I have a screen with two O's and nothing else...keyboard not working...stepper not stepping....but definitely moving forward with all your help and advise...so your help is very much appreciated, as I say trying to get my head around this is difficult for me...but learnt heaps in the last 4 days.
I have to download scripts from another area where the pc is as the RT is in the Shed so plugging in and out all day for 4 days isn't ideal.
Here is a snap of what I have changed so far...
#include <LiquidCrystal.h>

/*
 4x4 matrix keypad amd a 20 x 4 LCD. 
 Edit StepsPerRotation & TableRatio(# of turns for 360 degrees)in line 29
 A4988 Stepstick/M542driver 
 5/2/2015
 */

 #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(0x3f,20,21); // set the LCD address to 0x3 for a 16 chars and 4 line display
                                   // SCL - 20, SDA - 21, VCC - +5, Gnd - Gnd 
 //setup vars
 const int stp = 2;               // connect pin 2 to step
 const int dir = 3;               // connect pin 3 to dir
 const int StepsPerRotation = 400; // Set Steps per rotation of stepper NOTE the driver is set to Half step
 const int TableRatio = 90;        // ratio of rotary table
 const int Multiplier = (StepsPerRotation * TableRatio)/360;  // 200*90=18000/360 = 50
 const int stepdelay = 1;
 float Degrees = 0;                // Degrees from Serial input
 float ToMove = 0;                 // Steps to move
 float bob = 0;
 int cho = 0;

I'm getting an Invalid library found in home/mike/Arduino/wires . /home/mike/Arduino/wires.
Sketch still compiles and error is white lettering...is this a problem ?...or just ignore ?.
I will try out Foozer's I2c brute force a little later...so thanks Foozer....much appreciated.


----------



## bmac2

Ok. Mike on a guess it sounds like it library problem. Works nuts right now but give me a day or so and Ill get together something with the libraries Im using.


----------



## xrayxray

Thanks Bob....Appreciated....another day with no luck...just walked in from the shed...8pm.....think I have tried everything...unless the LCD is faulty....I have altered the sketch to the best of my limited ability and sketch compiles and uploads without errors now but just doesn't do anything....anyway...happy friday.

Cheers.


----------



## rodw

I think you are trying to do too much at once. You said you had the screen working with one script. Fantastic! study the script until you understand it.

Then find the shortest, most basic introductory stepper motor driver script. Disconnect your stepper from the rotary table and get the stepper to move.

Then, merge the 2 introductory scripts together so you are printing stepper related stuff on the screen.

If you are going to use a matrix keyboard, get it working with a demo script.

So now with all that done, you should know a lot more about the Arduino and your hardware then you do now so you should be in a position to get the rotary table controller going.

Remember, this is not a plug and play environment. Its all dependent on the hardware. If you are still stuck then might I suggest you scrap your hardware and buy exactly what has been used in the past.

You could consider my controller as you can configure it in a setup menu so it will work with your hardware
http://www.homemodelenginemachinist.com/showthread.php?t=25091
but deviate from the hardware I list at your peril. (Although several have used Sainsmart hardware)


----------



## Foozer

In Arduino - Examples - The LCD library should have an example script with it e.g. 'Hello World'
Load it to focus just on the LCD operation. The generic script command 
LiquidCrystal_I2C lcd(0x3F);  // Set the LCD I2C address
doesn't work for the 20x4 with backpacks I use regardless of vendor . . . whereas
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address
does [provided I2C address is 0x3F]

Had one lcd that wouldn't work, screen lit up but no adj of the backlight screw would alter the brightness . So the Mega is SDA @ 20 and SCL @ 21. Get it to work with the library example and you're half way there.


----------



## xrayxray

Thanks Foozer....followed your advice and spent many hours at it again....Freetronics have a lcd sketch, the seller of the LCD have a simple sketch along with many others I tried and many other I changed trying to get a result....here is a sample of the simple sketch.



    #include <Wire.h>
    #include <LiquidCrystal.h>


    LiquidCrystal lcd( 8, 9, 4, 5, 6, 7 );

    void setup()
    {
      lcd.begin(16, 2);
      lcd.print("hello, world!");
    }

    void loop()
    {
        // your main loop code here...
    }


I got a few to compile and upload but best I got was 2...zero's on the LCD, I have a clone sainsmart lcd and a replacement for this lcd coming through the week....but at this stage I would say I should have stumbled across something that I have tried and would have worked...but not so...anyway I do appreciate every ones help...very frustrating not to get a good result....when things like this are difficult and the longer and harder you try the more your likely to confuse yourself....cheers


----------



## rodw

Did you actually try the code on the ebay listing? IT will need to be changed for the 20x4 line display.

I think you have been trying to use the wrong libraries from day dot.

Read this http://wentztech.com/radio/arduino/files/LCDI2C.html and connect the pins as they say.



		Code:
	

1	+5 Volts
2	Ground
3	Pin 4(SDA)
4	Pin 5(SDA)


Download the library and install it.

Then try this code from your ebay listing set for 20 x 4 lines. 



		Code:
	

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,20,4); //set the LCD address to 0x27 for a 16 chars and 2 line display

void setup()
{
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("b2cqshop");
lcd.setCursor(0, 1);
lcd.print("Voltage: ");
lcd.setCursor(13, 1);
lcd.print("V");
}
void loop()
{
int val;
float temp;
val=analogRead(0);
temp=val/4.092;
val=(int)temp;//
lcd.setCursor(9, 1);
lcd.print(0x30+val/100,BYTE);
lcd.print(0x30+(val%100)/10,BYTE);
lcd.print('.');
lcd.print(0x30+val%10,BYTE);
delay(100);
}


----------



## Foozer

Pulled the covers from the two units that have a 20x4 LCD display. Each is a different type of backpack [gives different address], hooked each in turn to a mega. Loaded short code


#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
//LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address //sainsmart lcd2004
LiquidCrystal_I2C lcd(0x3b, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address to units address e.g. 0x27, 0x3f etc
// other backpack changeable i2c address
void setup()
{
  lcd.begin(20,4);               // initialize the lcd 
  lcd.home ();                   // go home
  lcd.print("Hello World ");  
  lcd.setCursor ( 0, 1 );        // go to the next line
  lcd.print (" Line Two");
  lcd.setCursor ( 0, 2 );        // go to the next line
  lcd.print (" Line Three");
  lcd.setCursor ( 0, 3 );        // go to the next line
  lcd.print (" Line Four");
 }
void loop(){}
First photo backpack looks like yours I2c scanner reports address as 0x27 - Loaded script and POOF! Prints out
Second photo is the other same script just different address same POOF! as shown in third photo [bad photo] but can keep that a secret]

Using 'LiquidCrystal_I2C lcd(0x27,20,4)' in script and I get black screen on both LCD units


----------



## bmac2

Hi Mike 
Trying to post some help here but can't get the attachments to upload. I've tried on 3 different computers and no luck. 
I'll try again later tonight.


----------



## bmac2

Ok I can upload attachments
I dont think its a hardware dependency. Ive ran the sketch on an Arduino Mini, Nanos (3v and 5v), Uno (original and clone) and a Mega so 7 different platforms. The only problem I had was with the vision of the libraries I had loaded on my laptop.
The stock sketch should work without any need to edit aside from the address for the I2C display just be sure you are using the one from the zip file attached in post #24. 
First youll want to get the controller into the same room as the computer. Were going to be doing a fair bit of downloading and testing.
Checking the Libraries.
I dont know if youve installed libraries so well go the Arduino for Dummies route. Download the 2 zip files and make note of where they have been saved.
Open the Arduino IDE and click on Sketch, Include Library, Add Zip Library 
Navigate to the directory you saved the Zip files (I sound all Microsoft there) and select Keypad.zip and then click Open. Then do the same thing selecting LiquidCrystal_I2C and were done. You have to close the Arduino IDE and open it again for the changes to take effect. 

View attachment Keypad.zip


View attachment LiquidCrystal_I2C.zip


----------



## bmac2

My entire Arduino graveyard is from when I had things hooked up to an unregulated power supply. Most of which are from me working on a PWM speed control for my Mini Mill. So first lets disconnect the stepper motor. I have never blown up anything with an Arduino connected to a USB port. All we have here are logic levels, if you accidently connect an input to an output it just wont work. Connect it to 90vdc and you get a collection like mine.


----------



## xrayxray

Thanks Rodw, downloaded and installed all library files and swapped scl and sca pins to A4 and A5 ran sketch...;error was 'BYTE keyword no longer supported.'
changed scl and sca to pins 21 and 20 cos its a Mega and got same error.

Thanks Foozer...tried your sketch but changed address to 0x3F as per address scan....error was 'Positive not declared in this scope'...

Thanks Bmac....

Cheers Mike.


----------



## bmac2

This is a quick test for the key pad. Its setup to work with the same wiring used in the rotary table sketch so you dont have to make any changes. Download 4x4_Keypad_Test.zipand unzip it into your Arduino folder usually C:\Users\User\Documents\Arduino. Open the sketch _4x4_Keypad and upload it onto your Arduino. Open the serial monitor and you can test that the keys are working. If not, the only thing that can be wrong is the wiring, or the keypad is bad. I only have a 4x3 pad on hand so I had to fake the forth row but it works. 

The connections should be 
Arduino D4 to Keypad pin 1
Arduino D5 to Keypad pin 2
Arduino D6 to Keypad pin 3
Arduino D7 to Keypad pin 4
Arduino D8 to Keypad pin 5
Arduino D9 to Keypad pin 6
Arduino D10 to Keypad pin 7
Arduino D11 to Keypad pin 8

You can test the keypad with a multimeter. Pins 1-4 are the columns and 5-8 are the rows. Set the meter to ohms put 1 probe on pin 1 and the other on pin 5 you should get continuity when you press the D button. Pins 1 and 6 will be C etc. 

View attachment 4x4_Keypad_Test.zip


----------



## xrayxray

Hi Bob,
Done as requested....all libraries are installed and controller plugged into USB...no Steeper attached.


----------



## bmac2

On to the display. 
You said _I have a screen with two O's and nothing else_ so it is not completely dead. First make sure that the jumper is on the 2 pins on the small board on the back of the display. If its not you have no back light and the display will appear blank. 
Again we dont have to change any of the wiring. 
I like this utility for checking the address on I2C devices and so far its worked on everything Ive used it on. Download I2C_Scanner.zip, unzip it into your Arduino folder then open the sketch I2C_Scanner  and upload it onto your Arduino. Open the serial monitor and the address for your display should be shown in the window. If not check your wiring and run it again.

Arduino GND to Display GND
Arduino 5v to Display VCC
Arduino A4 to Display SDA
Arduino A5 to Display SCL 

View attachment I2C_Scanner.zip


----------



## xrayxray

Hi Bob,
Uploaded 4x4 keypad test and opened...no compile ...error ...POSITIVE not declared in this scope


Cheers Mike.


----------



## xrayxray

Hi Bob....well thats weird.....Scanner showing no address found......yet last few days scanner has shown address at 0x3F


----------



## bmac2

If you still get nothing the display may be toast but were going to soldier on assuming that we got the address . In the IDE goto File, Examples,LiquidCrystal I2c, HelloWorld and upload it to the Arduino.  Your display should look like the one in the picture. 
If not check the wiring using different jumpers and try again. 

I recently had some bad jumpers ruin my day on a project. Nothing like having random 35 ohm resisters in a circuit where I thought I had 4 inch jumpers.

Hopefully we can get it working to this point then all thats left is the stepper. 
Good luck . . Bob


----------



## xrayxray

Hi Bob,
Weird....scanner not showing address in serial monitor......yet the last few day when I scanned the address showed as 0x3F


----------



## xrayxray

Uploaded examples sketch and no result....blank lcd


----------



## bmac2

xrayxray said:


> Hi Bob,
> Uploaded 4x4 keypad test and opened...no compile ...error ...POSITIVE not declared in this scope
> 
> 
> Cheers Mike.



Ok thats weird, there is no reference to POSITIVE in the sketch. I just downloaded the sketch and it compiles fine. 
What version of the IDE are you using? Im using 1.6.5


----------



## xrayxray

I just tried changing address to last known address of 0x3F...still no change


----------



## xrayxray

Latest version 1.8.1.....and I'm using Linux Mint


----------



## xrayxray

just started download of 1.6.5...will give it a try


----------



## bmac2

Humm. Tomorrow Ill try setting it up on a Mega and dig out my Linux Ubuntu Lumptop (its old) and see what I get.


----------



## xrayxray

Hi Bob,
Just tried 1.6.5 compile ok with example...hello world....tried I2C scanner...no I2c device found


----------



## xrayxray

I swapped SDA and SCL back to pin 20 and pin21 from A4 and A5 and device found in scanner...address is 0x3F


----------



## Foozer

Curious - For S&G tried the posted lcd library and only one letter per line printed [kinda like two '0's] and 'positive' not declared - -  Now it's coming back to me - Went thru a few libraries till I found one that worked with the displays I had . . Using NewLiquidCrystal 1.3.4 library  - 5 meg file, too big to attach . .

Moral of the story - Not all libraries are created equal . . .

Note - IIRC the scanner program can damage the LCD if left running too long . . .


----------



## xrayxray

Thanks Bob...appreciate all your help and everyones help.

I do prefer Linux to Win...new version of mint is very good.

Cheers.


----------



## xrayxray

Hi foozer.,..tried all the library's including NewCrystal 1.3.4...I reckon it's looking more like faulty hardware...don't reckon there is much more to try.

Cheers.


----------



## Foozer

xrayxray said:


> Hi foozer.,..tried all the library's including NewCrystal 1.3.4...I reckon it's looking more like faulty hardware...don't reckon there is much more to try.
> 
> Cheers.



Could be, not that I have ever let the magic smoke out of electronic devices. Have had good luck with displays from adafruit. When it came to figuring out displays, played with OLED's, Touch screens, 16x2's and 20x4's all around the same time so the learning curve details are a bit blurred. Like they say, can be hardware dependent. What works with say the sainsmart, may not work with another supplier product tho newliquidcrystal  liquidcrystal_I2C is working here with both sainsmart and adafruit displays.
 Both seem to use the same chip PCF8574


----------



## rodw

xrayxray said:


> Thanks Rodw, downloaded and installed all library files and swapped scl and sca pins to A4 and A5 ran sketch...;error was 'BYTE keyword no longer supported.'
> 
> 
> Cheers Mike.


Mike, there is too much static on this thread. This is where you should be starting. You are not thinking about the problem or your hardware.... and just blindly following suggestions made by others based on your hardware.

Did you google the error? Get this correct demo script working first. 

They have done some stuff in the lines that look like this


		Code:
	

lcd.print(0x30+val/100,BYTE);

What they are doing is printing a decimal value without resorting to floating point maths which is not supported by lcd.print()

The problem is a BYTE is not a valid data type in C. Bytes are equivalent to char but if you use char instead of BYTE here, the Arduino will think you want to print text. Arduino must have once had a typedef for BYTE but the typedef has been removed.

Try one of these two formats instead....


		Code:
	

lcd.print(0x30+val/100);
//or
lcd.print(0x30+val/100,int);

Make sure you change all lines with BYTE in it.
See https://www.arduino.cc/en/Reference/LiquidCrystalPrint

This should work. Worst case delete the lines with compile errors as there is enough being printed in setup() to confirm it works.


----------



## xrayxray

Hi Rod, I tried earlier deleting BYTE after I googled the error...no improvement.....but this time I'm using 1.6.5 Ide and as you suggested I deleted 3 ptint lines with BYTE in them...now I have a Zero and a flashing Cursor row A Col 19.....No keypad on Sketch so now have included...#include <Keypad.h>....no improvement so have swapped keyboard wires opposite to each other still starting at pin 4 through to pin 11 and changed address to 0x3F.

Will see if I can get some more letter up.

Cheers.


----------



## rodw

I suspect that there is a mismatch somewhere that is offsetting the screen output or something.

Go back to your ebay listing and study the two links provided. The answer will be somewhere there. One is the library on github and the other is the main page. I can't help you anymore than this. Wait for your new hardware to arrive and start again with the correct library for that code. Any time I have used a LCD it has been dead simple.


----------



## Foozer

Loaded the script from post 24 and the curious began - - -
lcd.init();
Ok how to paint this picture - - -
LiquidCrystal keyword is 'init' e.g lcd.init(20,40);
Keyword 'init' doesn't exist in the newliquidcrystal keyword file,
NewLiquidCrystal keyword is 'begin' e.g lcd.begin(20,40);
Both use file name  LiquidCrystal_I2C 
e.g. LiquidCrystal_I2C lcd(0x3b,20,4); LiquidCrystal Library
 LiquidCrystal_I2C lcd(0x3B, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE) NewLiquidCrystal Library

With the LiquidCrystal library installed display doesn't print out correctly as shown on image . . .







Just a few leading letters, nothing more- That library and this display just don't want to cooperate . . .

But it worked before i installed the LiquidCrystal library, worked fine with the NewLiquidCrystal Library, kinda, sorta - gave a compile error lcd.init(20,4) a no go as the keyword is 'begin' rather than 'init' Ok can deal with that.
Changed the lcd lines to suit the library in use, complied and displayed fine

With NewLiquidCrystalDisplay library






Cheap camera bad photos . . Where was I - - Ok so NewLiquidCrystal library works, LiquidCrystal Library doesn't - BUT - having both libraries in the system was a nogo - - - Don't know why it does but arduino used the LiquidCrystal library over the other - If it complies with lcd.init(20x4) in the script its the LiquidCrystal library [uncooperative one]. Complies with lcd.begin(20x4) its the cooperative one . . . So located and deleted the uncooperative library entirely - No longer complies with the 'Tell' code, does compile with the lcd.begin(20,4) code and display works as it should. . .

So having multiple libraries with same calling code as appears to be
LiquidCrystal_I2C lcd(blah blah blah) can be a/source of grief . . .

Sorry for the mud in the water language -


----------



## xrayxray

All is not lost...removed libraries as per Foozer's suggestion and loaded a sketch that was just for the LCD and now have a functioning display....only kept Wire, Keypad and NewLiquidCrystal, here is the edited sketch I change address to 0x3F and kept everything else.

#include <Keypad.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
//LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address //sainsmart lcd2004
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address to units address e.g. 0x27, 0x3f etc
// other backpack changeable i2c address
void setup()
{
lcd.begin(20,4); // initialize the lcd
lcd.home (); // go home
lcd.print("Hello Foozer, Rodw and Bmac");
lcd.setCursor ( 0, 1 ); // go to the next line
lcd.print (" Line Two");
lcd.setCursor ( 0, 2 ); // go to the next line
lcd.print (" Line Three three");
lcd.setCursor ( 0, 3 ); // go to the next line
lcd.print (" Line Fourt five");
}
void loop(){}



I have now tried to incorporate this LCD sketch into Bmac2 sketch...no luck...wont compile...my lack of coding knowledge and started at 3.00 am now 5.00 am, so still have to sort out Keypad function which been trying to do this morning....no luck yet.
Bur happy to report it looks like the LCD is sorted and can be a guideline to get the rest functioning...if only I knew what I was doing.....but I am happy that my knowledge of Arduino has increased substantially thanks to you gents.

Cheers.


----------



## xrayxray

Also forgot to mention I changed...."lcd.init(20,4); // initialize the lcd"...to..."lcd.begin(20,4); // initialize the lcd"


Cheers.


----------



## Foozer

xrayxray said:


> Also forgot to mention I changed...."lcd.init(20,4); // initialize the lcd"...to..."lcd.begin(20,4); // initialize the lcd"
> 
> 
> Cheers.



Got the display to work, you're almost home 

Don't try to meld the two scripts together, just change/keep  the LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); and change the occurrences of lcd.init(20,4) to lcd.begin(20,4); and it should compile - Does here.


----------



## xrayxray

Time to celebrate...looks like I have a functioning controller...will try later when i connect to stepper motor.
looks like I have all functions, multiple screens...just had to swap keyboard wires around.

Had to alter other instances of LCD init() by deleting all of them bar the first one and change that one to LCDbegin.
here is a copy of the working code for my flavour of LCD.

I would like to sincerely thank all of those that posted their suggestions and help...cheers.

/*
 4x4 matrix keypad amd a 20 x 4 LCD. 
 Edit StepsPerRotation & TableRatio(# of turns for 360 degrees)in line 29
 M542 driver 
 5/2/2015
 */

 #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(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);// set the LCD address to 0x20 for a 16 chars and 4 line display
                                   // SCL - 21, SDA - 20, VCC - +5, Gnd - Gnd 
 //setup vars
 const int stp = 2;               // connect pin 2 to step
 const int dir = 3;               // connect pin 3 to dir
 const int StepsPerRotation = 400; // Set Steps per rotation of stepper NOTE the driver is set to Half step
 const int TableRatio = 36;        // ratio of rotary table
 const int Multiplier = (StepsPerRotation * TableRatio)/360;  // 200*90=18000/360 = 50
 const int stepdelay = 1;
 float Degrees = 0;                // Degrees from Serial input
 float ToMove = 0;                 // Steps to move
 float bob = 0;
 int cho = 0;

 void setup()
 {
 lcd.begin(20,4);      // initialize the lcd 
 pinMode(stp, OUTPUT);
 pinMode(dir, OUTPUT); 

 // Print welcome message to the LCD.
 lcd.backlight();
 lcd.print("Rotary Table Control");
 lcd.setCursor(4,2);
 lcd.print(" ");
 lcd.setCursor(3,3);
 lcd.print("updated 2016");
 delay(2000);

   cho = 0;
   char key = kpd.getKey();
   lcd.print("Enter Selection:");   
   lcd.setCursor(0,1);
   lcd.print("Degrees   = A");
   lcd.setCursor(0,2);
   lcd.print("Divisions = B");
   lcd.setCursor(0,3);
   lcd.print("JOG       = C");
   while(cho == 0)
   {
     key = kpd.getKey();
     switch (key)
     {
     case NO_KEY:
      break;
     case 'A':
       Degrees=getdegrees();
       lcd.clear();
       cho = 1;
       break; 
     case 'B':
       Degrees=getdivisions();  
       cho=2;
       break;
     case 'C':
       Degrees=getjog();
       lcd.clear();
       cho=3;
       break;
       }      // end case
     }      // end while cho=0
 }    // end setup

 void loop()      // MAIN LOOP
 {
   lcd.clear();  
   char key = kpd.getKey();
     bob = 0;
     lcd.setCursor(7,0);lcd.print("Total:  ");lcd.print(bob,2);   // total steps
     lcd.setCursor(0,3);lcd.print("FOR=A   REV=B    X=C");
   while(key != 'C')    // C will return to start menu
   {
     lcd.setCursor(0,0);lcd.print(abs(Degrees),2);lcd.print((char)223);
     key = kpd.getKey();
     if(key == 'A')            // FORWARD
       {
        bob = bob + Degrees;
        ToMove = (Degrees*Multiplier);
        digitalWrite(dir, LOW);
        printadvance();
       }
     if(key=='B')              // REVERSE
       {
        bob = bob - Degrees;  
        ToMove = (Degrees*Multiplier);
        digitalWrite(dir, HIGH);    // pin 13
        printadvance();
       }
   }      // end while not C loop

  setup();
 }      // end main VOID


float getjog()
{
  float Degrees = 0;
  float num = 0.00;
   char key = kpd.getKey();
   lcd.clear();
   lcd.setCursor(6,0);lcd.print("Jogging");
   lcd.setCursor(0,1);lcd.print("A=1 B=10 C=100 Steps");
   lcd.setCursor(0,2);lcd.print("Enter Degrees:");lcd.setCursor(0,3);lcd.print("OK = #       ");lcd.print((char)60);lcd.print((char)45);lcd.print(" D");

   while(key != '#')
   {
      switch (key)
      {
         case NO_KEY:
            break;
         case 'A':
            Degrees = 1;      
            lcd.setCursor(14,2);lcd.print(Degrees);
            break;
         case 'B':
            Degrees = 10;
            lcd.setCursor(14,2);lcd.print(Degrees);
            break;
         case 'C':
            Degrees = 100;
            lcd.setCursor(14,2);lcd.print(Degrees);
            break;
         case 'D':
          num=0.00;
          lcd.setCursor(14,2);lcd.print("     ");
          lcd.setCursor(14,2);
          break;
      }
      key = kpd.getKey();
   }
  return Degrees; 
}


float getdivisions()
{
  float Degrees = 0; 
  float num = 0.00;
   char key = kpd.getKey();
   lcd.clear();
   lcd.setCursor(0,1);lcd.print("Enter Division:");lcd.setCursor(0,3);lcd.print("OK = #       ");lcd.print((char)60);lcd.print((char)45);lcd.print(" D");
   lcd.setCursor(16,1);

   while(key != '#')
   {
      switch (key)
      {
         case NO_KEY:
            break;

         case '0': case '1': case '2': case '3': case '4':
         case '5': case '6': case '7': case '8': case '9':
            num = num * 10 + (key - '0');
            lcd.print(key);
            break;

        case 'D':
          num=0.00;
          lcd.setCursor(16,1);lcd.print("     ");
          lcd.setCursor(16,1);
          break;
      }
      Degrees = 360/num;
      key = kpd.getKey();
   }
  return Degrees;  //num;
}


float getdegrees()
{ 
   //int key = 0;
   float num = 0.00;
   float decimal = 0.00;
   float decnum = 0.00;
   int counter = 0;
   lcd.clear();
   //lcd.init();
   char key = kpd.getKey();
   lcd.setCursor(0,1);lcd.print("Enter Degrees:");lcd.setCursor(0,3);lcd.print("OK = #       ");lcd.print((char)60);lcd.print((char)45);lcd.print(" D");
   lcd.setCursor(15,1);
   bool decOffset = false;

   while(key != '#')
   {
      switch (key)
      {
         case NO_KEY:
            break;

         case '.':
           if(!decOffset)
           {
             decOffset = true;
           }
            lcd.print(key);
            break;   

         case 'D':
          num=0.00;
          lcd.setCursor(15,1);lcd.print("     ");
          lcd.setCursor(15,1);
          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;
      }    //end case
      decnum = num / pow(10, counter);
      key = kpd.getKey();
   }    //end while not #
    return decnum;
}      // end getdegrees

 void printadvance()      // print function
   {
     lcd.setCursor(6,1);lcd.print("Moving");
     lcd.setCursor(4,2);lcd.print("Steps  ");lcd.print(ToMove,0); 
     lcd.setCursor(13,0);lcd.print(bob,2);
     rotation(ToMove,0);
     lcd.setCursor(6,1);lcd.print("      "); 
  } 

 void rotation(float tm, int d)
   { 
     for(int i = 0; i < tm; i++) 
       { 
       digitalWrite(stp, HIGH); 
       delay(stepdelay); 
       digitalWrite(stp, LOW); 
       delay(stepdelay); 
       }
   }

void software_Reset() // Restarts program from beginning but does not reset the peripherals and registers
  {
  asm volatile ("  jmp 0");  
  }


----------



## xrayxray

Just a reminder for anyone using this code is to change table ratio...in my case it is 90 to 1.
And of course this is a code slightly modified but based on the code submitted by Bmac 2...thanks.


----------



## xrayxray

Well ..spent most of the day reading up about stepper drivers etc and  tried wiring in different configurations to run the motor I have.
I  swapped out the driver for a higher capacity than a M542 driver...just  to see if it was a faulty M542...doesn't seem to be as both drivers not  rotating motor.
I altered the code from pin 2 and pin 3 to pin13 Dir  and pin 12 Pul....at the moment wiring is pin13 to PUL+...pin 12 to  Dir+.... ground to PUL- ,Dir - and Enable -.
I must be close to getting this thing running.
Any  ideas... my connections or something with the code ?.....I notice on  the code there is .const int stp = 12;.further down the code there is  pinMode(stp, OUTPUT);Do I need to change this ?


Cheers.


----------



## Foozer

xrayxray said:


> Well ..spent most of the day reading up about stepper drivers etc and  tried wiring in different configurations to run the motor I have.
> I  swapped out the driver for a higher capacity than a M542 driver...just  to see if it was a faulty M542...doesn't seem to be as both drivers not  rotating motor.
> I altered the code from pin 2 and pin 3 to pin13 Dir  and pin 12 Pul....at the moment wiring is pin13 to PUL+...pin 12 to  Dir+.... ground to PUL- ,Dir - and Enable -.
> I must be close to getting this thing running.
> Any  ideas... my connections or something with the code ?.....I notice on  the code there is .const int stp = 12;.further down the code there is  pinMode(stp, OUTPUT);Do I need to change this ?
> 
> 
> Cheers.




More info needed - Uno or Mega? what type stepper motor? what driver? driver shield? Driver shields generally are pin specific with [grumble grumble] no consistent standard . . . So knowing the type of driver is knowing which pins the code should call . . .


----------



## rodw

Try disconnecting the enable wires to the stepper driver totally. In my experience, it is a stepper disable signal and the manual says it should not normally be connected.

Been caught myself!


----------



## xrayxray

Tried both Uno and Mega...currently Mega Connected, Nema 23 425 oz/in , Sutia M542 driver - 48 volt in, A+-red, A- Blue, B+ - green, B- black, Pul- bridged to Dir - bridged to Gnd
Pul+ to Pin 12, Dir+ to Pin13.....no Enable connection.

I have checked everything numerous times, I have looked at code and to me it looks ok...nothing jumps out at me...but really I haven't a clue,tho I wonder why Cons Int is used and others seem to use Pinmode....just an observation trying to get this sorted.



LCD and Keypad working great.

/*
 4x4 matrix keypad amd a 20 x 4 LCD. 
 Edit StepsPerRotation & TableRatio(# of turns for 360 degrees)in line 29
 M542 driver 
 5/2/2015
 */

 #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(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);// set the LCD address to 0x3F for a 20 chars and 4 line display
                                   // SCL - 21, SDA - 20, VCC - +5, Gnd - Gnd 
 //setup vars
 const int stp = 12;               // connect pin 12 to step
 const int dir = 13;               // connect pin 13 to dir
 const int StepsPerRotation = 400; // Set Steps per rotation of stepper NOTE the driver is set to Half step
 const int TableRatio = 90;        // ratio of rotary table
 const int Multiplier = (StepsPerRotation * TableRatio)/360;  // 200*90=18000/360 = 50
 const int stepdelay = 1;
 float Degrees = 0;                // Degrees from Serial input
 float ToMove = 0;                 // Steps to move
 float bob = 0;
 int cho = 0;

 void setup()
 {
 lcd.begin(20,4);      // initialize the lcd 
 pinMode(stp, OUTPUT);
 pinMode(dir, OUTPUT); 

 // Print welcome message to the LCD.
 lcd.backlight();
 lcd.print("Rotary Table Control");
 lcd.setCursor(4,2);
 lcd.print(" ");
 lcd.setCursor(3,3);
 lcd.print("updated 2016");
 delay(2000);

   cho = 0;
   char key = kpd.getKey();
   lcd.print("Enter Selection:");   
   lcd.setCursor(0,1);
   lcd.print("Degrees   = A");
   lcd.setCursor(0,2);
   lcd.print("Divisions = B");
   lcd.setCursor(0,3);
   lcd.print("JOG       = C");
   while(cho == 0)
   {
     key = kpd.getKey();
     switch (key)
     {
     case NO_KEY:
      break;
     case 'A':
       Degrees=getdegrees();
       lcd.clear();
       cho = 1;
       break; 
     case 'B':
       Degrees=getdivisions();  
       cho=2;
       break;
     case 'C':
       Degrees=getjog();
       lcd.clear();
       cho=3;
       break;
       }      // end case
     }      // end while cho=0
 }    // end setup

 void loop()      // MAIN LOOP
 {
   lcd.clear();  
   char key = kpd.getKey();
     bob = 0;
     lcd.setCursor(7,0);lcd.print("Total:  ");lcd.print(bob,2);   // total steps
     lcd.setCursor(0,3);lcd.print("FOR=A   REV=B    X=C");
   while(key != 'C')    // C will return to start menu
   {
     lcd.setCursor(0,0);lcd.print(abs(Degrees),2);lcd.print((char)223);
     key = kpd.getKey();
     if(key == 'A')            // FORWARD
       {
  void setup()
 {
 lcd.begin(20,4);      // initialize the lcd 
 pinMode(stp, OUTPUT);
 pinMode(dir, OUTPUT); 


float getjog()
{
  float Degrees = 0;
  float num = 0.00;
   char key = kpd.getKey();
   lcd.clear();
   lcd.setCursor(6,0);lcd.print("Jogging");
   lcd.setCursor(0,1);lcd.print("A=1 B=10 C=100 Steps");
   lcd.setCursor(0,2);lcd.print("Enter Degrees:");lcd.setCursor(0,3);lcd.print("OK = #       ");lcd.print((char)60);lcd.print((char)45);lcd.print(" D");

   while(key != '#')
   {
      switch (key)
      {
         case NO_KEY:
            break;
         case 'A':
            Degrees = 1;      
            lcd.setCursor(14,2);lcd.print(Degrees);
            break;
         case 'B':
            Degrees = 10;
            lcd.setCursor(14,2);lcd.print(Degrees);
            break;
         case 'C':
            Degrees = 100;
            lcd.setCursor(14,2);lcd.print(Degrees);
            break;
         case 'D':
          num=0.00;
          lcd.setCursor(14,2);lcd.print("     ");
          lcd.setCursor(14,2);
          break;
      }
      key = kpd.getKey();
   }
  return Degrees; 
}


float getdivisions()
{
  float Degrees = 0; 
  float num = 0.00;
   char key = kpd.getKey();
   lcd.clear();
   lcd.setCursor(0,1);lcd.print("Enter Division:");lcd.setCursor(0,3);lcd.print("OK = #       ");lcd.print((char)60);lcd.print((char)45);lcd.print(" D");
   lcd.setCursor(16,1);

   while(key != '#')
   {
      switch (key)
      {
         case NO_KEY:
            break;

         case '0': case '1': case '2': case '3': case '4':
         case '5': case '6': case '7': case '8': case '9':
            num = num * 10 + (key - '0');
            lcd.print(key);
            break;

        case 'D':
          num=0.00;
          lcd.setCursor(16,1);lcd.print("     ");
          lcd.setCursor(16,1);
          break;
      }
      Degrees = 360/num;
      key = kpd.getKey();
   }
  return Degrees;  //num;
}


float getdegrees()
{ 
   //int key = 0;
   float num = 0.00;
   float decimal = 0.00;
   float decnum = 0.00;
   int counter = 0;
   lcd.clear();
   //lcd.init();
   char key = kpd.getKey();
   lcd.setCursor(0,1);lcd.print("Enter Degrees:");lcd.setCursor(0,3);lcd.print("OK = #       ");lcd.print((char)60);lcd.print((char)45);lcd.print(" D");
   lcd.setCursor(15,1);
   bool decOffset = false;

   while(key != '#')
   {
      switch (key)
      {
         case NO_KEY:
            break;

         case '.':
           if(!decOffset)
           {
             decOffset = true;
           }
            lcd.print(key);
            break;   

         case 'D':
          num=0.00;
          lcd.setCursor(15,1);lcd.print("     ");
          lcd.setCursor(15,1);
          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;
      }    //end case
      decnum = num / pow(10, counter);
      key = kpd.getKey();
   }    //end while not #
    return decnum;
}      // end getdegrees

 void printadvance()      // print function
   {
     lcd.setCursor(6,1);lcd.print("Moving");
     lcd.setCursor(4,2);lcd.print("Steps  ");lcd.print(ToMove,0); 
     lcd.setCursor(13,0);lcd.print(bob,2);
     rotation(ToMove,0);
     lcd.setCursor(6,1);lcd.print("      "); 
  } 

 void rotation(float tm, int d)
   { 
     for(int i = 0; i < tm; i++) 
       { 
       digitalWrite(stp, HIGH); 
       delay(stepdelay); 
       digitalWrite(stp, LOW); 
       delay(stepdelay); 
       }
   }

void software_Reset() // Restarts program from beginning but does not reset the peripherals and registers
  {
  asm volatile ("  jmp 0");  
  } 


Cheers


----------



## xrayxray

Whoops meant to say....wonder why "Const int" is used whilst I have observed "Define "as being used in other sketches..
See I have no Idea 

Cheers.


----------



## Foozer

Similar driver - en-, dir-, pul- all to GND

dir+ to arduino pin
pul+ to arduino pin

en+ enable, pulled low to have driver process step, direction commands, pulled high to  to have driver process step, direction commands. Don't really see an enable command in the code, could be the driver used is fixed enabled.

what free pins are available? can add an enable command
top of script where defines and other int rest add 
int   Enable        = youropenpin;                           //  Stepper Enable Pin
this pin connected to the en+ of the driver

in setup add  pinMode(Enable,          OUTPUT); 
 digitalWrite(Enable,               LOW);  enable driver  command processing . .

I think that's right, can stumble through arduino


powered on stepper should resist being turned by hand
a digitalWrite(Enable,HIGH); should disable driver from processing commands and stepper should turn freely by hand . . .


----------



## xrayxray

I have -en, dir-, pul- all to gnd 

here is my pin layout...12 and 13 PWM, 22 Digital

                                   // SCL - 21, SDA - 20, VCC - +5, Gnd - Gnd 
 //setup vars
 const int stp = 12;               // connect pin 12 to step
 const int dir = 13;               // connect pin 13 to dir
 const int en  = 22;               // Stepper Enable Pin 22 this pin connected to the en+ of the driver
 const int StepsPerRotation = 400; // Set Steps per rotation of stepper NOTE the driver is set to Half step
 const int TableRatio = 90;        // ratio of rotary table
 const int Multiplier = (StepsPerRotation * TableRatio)/360;  // 200*90=18000/360 = 50
 const int stepdelay = 1;
 float Degrees = 0;                // Degrees from Serial input
 float ToMove = 0;                 // Steps to move
 float bob = 0;
 int cho = 0;

 void setup()
 {
 lcd.begin(20,4);      // initialize the lcd 
 pinMode(stp, OUTPUT);
 pinMode(dir, OUTPUT);
 pinMode(en, OUTPUT);
 digitalWrite(en, LOW);  


no turning of motor yet...locked up hard.

Cheers.


----------



## rodw

xrayxray said:


> Whoops meant to say....wonder why "Const int" is used whilst I have observed "Define "as being used in other sketches..
> See I have no Idea
> 
> Cheers.



#define (or anything starting with #) is a precompiler directive. The generate no code.

So
#define step 12 
simply means to replace the word step with the value 12 before compiling any code like a global search and replace before compiling.

A const on the other hand is actually a variable that is stored in memory somewhere but the differnence between const int step = 12; and int step2 = 13;
is that the const directive tells the compiler that this value will never change so the compiler is free to optimise generated code, possibly overlaying the variable on top of another const with the same value or leaving out some other variable management code.

The other one you see in your code is a volatile variable. This tells the compiler that this variable can be changed by another piece of code without notice so make no optimising assumptions about its value. Typically a volatile variable is used for interprocess communications. eg between an interrupt routine and the main loop.

Anyway, back to your problem. Having the stepper locked up is not a bad thing. It says the drive is powered up so it just needs a step and direction signal to move. Do me one favour,  and it may not do anything if the stepper is holding firm. Just unplug the enable connector from the DM542 and see if that changes anything. I don't think it will if you have holding torque.

I suspect the problem is that the stepdelay is too short. You have set it to 1 so that means the pulses are only 1 millisecond long if you look in the rotation() procedure. If you look in your stepper driver manual you will see some minimum step pulse times (probably in microseconds). So the LinuxCNC guys say not to go under 3500 microseconds and you are running at 1000 microseconds. I can run the DM542 at 1500 microseconds with dedicated step generation hardware. I don't think you would want to go under 10 but I would try changing the step delay to say 100 or higher before reducing it by trial and error until it stops moving and then move back to a safe value. Make sure you watch it closely, I was disheartened when after months of work , I thought nothing was moving until I saw the faintest of movement due to a miscalibrated axis.


----------



## rodw

Just to clarify, delay(x) stops for x milliseconds. There are 1000 milliseconds in a second but there are 1000000 microseconds in a second. So 1 millisecond = 1000 microseconds. You will sometimes see people using usec for microseconds.


----------



## xrayxray

Hi Rod,
Unpluged the enable connector....still has strong cogging.
Increased delay to 150...no movement at all.
Must  be getting close to this running.....i put a DMM on the pins and there  is no voltage showing on the meter...on Pul+, Dir+, and EN+...would have  thought something would have shown...in the manual it shows VCC on  PUL+, DIR+, EN+.....and controller wired to PUL-,DIR-,EN-....this is the  firast time I have seen a circuit Diagram like this...all the other  diagrams Ive seen are the way I have it now


Cheers


----------



## rodw

xrayxray said:


> Hi Rod,
> Unpluged the enable connector....still has strong cogging.
> Increased delay to 150...no movement at all.
> Must  be getting close to this running.....i put a DMM on the pins and there  is no voltage showing on the meter...on Pul+, Dir+, and EN+...would have  thought something would have shown...in the manual it shows VCC on  PUL+, DIR+, EN+.....and controller wired to PUL-,DIR-,EN-....this is the  firast time I have seen a circuit Diagram like this...all the other  diagrams Ive seen are the way I have it now
> 
> 
> Cheers



A parallel port breakout board is active low so it is wired that way. Maybe try it that way but I never had to do that with an Arduino and I am not doing it that way with my Mesa 7i76e ethernet controller with LinuxCNC.


----------



## xrayxray

Swapped connections around....no cogging now....definate motor clicking sound when Mega reset is pressed.

not sure where I go from here.


Cheers


----------



## Foozer

xrayxray said:


> Swapped connections around....no cogging now....definate motor clicking sound when Mega reset is pressed.
> Cheers



Good news is you haven't gone insane  -  YET  - -
Questions to myself -
Pin 13 IIRC that pin runs the on-board LED ? Member reading something, somewhere, sometime ago about using that pin for other than the built in LED could be iffy - - So on that side I only consider pins 2-12 as generally usable.
[0,1 are interrupts] that's Rods realm . . 
Wired as common anode [+] ? Like to keep a common GND between components so use common cathode [-]

Stepping? Begin with setting the current switch to whatever the stepper calls for 3.5, 4 amp, whatever the data sheet says. Set the steps to FULL for now.

Does the motor run? What the minimum code required to get it to turn?
// using my little cigar box test platform - Pin numbers will vary dependant upon hardware used
void setup()
{
 // put your setup code here, to run once:
pinMode(A2,OUTPUT);  // set pins to Outputs - change pin numbers to suit hardware
pinMode(2,OUTPUT);
pinMode(3,OUTPUT);
digitalWrite(A2,LOW); // enable stepper
}
void loop() {
  // put your main code here, to run repeatedly:
 digitalWrite(3,LOW); // Direction, Set to HIGH for opposite direction
digitalWrite(2,LOW);
delayMicroseconds(2000);  // slow, change number up-down to adj speed
digitalWrite(2,HIGH);
delayMicroseconds(2000);
}

Is enable pin set as an OUTPUT?
lcd.begin(20,4);      // initialize the lcd 
 pinMode(stp, OUTPUT);
 pinMode(dir, OUTPUT); 

Did I forget to mention that, to add
pinMode(enable, OUTPUT);


----------



## xrayxray

Hi Foozer,
Followed your steps, set different pins and named them step,dir,en...no change....changed code to numbering the pins rather than naming them....gave cogging when activated and no cogging when turned off.
Ran a few example sketches like blink etc to make sure Mega was working....seems ok...takes an example sketch no worries.

Think I am insane now...still no success....so I still can't work out why this is not running...nothing leaps out at me that may suggest non compliance.

Cheers.


----------



## xrayxray

I altered the pins again to46,48,50....no go.
Found an example sketch and uploaded...got the stepper moving in very small increment...but moving just the same...yahoo.
cross examined code and change pin nos again, removed const int with byte...but wouldn't compile.
will post both codes i have been workin on.
on the code with const int....I have enable connected negative ...howeve looking at the code it could be trying to connect to enable positive...I have tried compiling with pin 13 en minus sign -....won't compile...is this a reason why ?


/*
 4x4 matrix keypad amd a 20 x 4 LCD. 
 Edit StepsPerRotation & TableRatio(# of turns for 360 degrees)in line 29
 M542 driver 
 5/2/2015
 */

 #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(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);// set the LCD address to 0x20 for a 16 chars and 4 line display
                                                            // SCL - 21, SDA - 20, VCC - +5, Gnd - Gnd 

 //setup vars
 const int stepPin = 2;            // connect pin 2 to step
 const int directionPin = 3;       // connect pin 3 to dir
 const int en = 13;               // Stepper Enable Pin 13 this pin connected to the en- of the driver

 const int StepsPerRotation = 400; // Set Steps per rotation of stepper NOTE the driver is set to Half step
 const int TableRatio = 90;        // ratio of rotary table
 const int Multiplier = (StepsPerRotation * TableRatio)/360;  // 200*90=18000/360 = 50
 const int stepdelay = 150;
 float Degrees = 0;                // Degrees from Serial input
 float ToMove = 0;                 // Steps to move
 float bob = 0;
 int cho = 0;

 void setup()
 {
 lcd.begin(20,4);      // initialize the lcd 
 pinMode(2, OUTPUT);
 pinMode(3, OUTPUT);
 pinMode(13, OUTPUT);
 digitalWrite(13, LOW);  


 // Print welcome message to the LCD.
 lcd.backlight();
 lcd.print("Rotary Table Control");
 lcd.setCursor(4,2);
 lcd.print(" ");
 lcd.setCursor(3,3);
 lcd.print("updated 2016");
 delay(2000);

   cho = 0;
   char key = kpd.getKey();
   lcd.print("Enter Selection:");   
   lcd.setCursor(0,1);
   lcd.print("Degrees   = A");
   lcd.setCursor(0,2);
   lcd.print("Divisions = B");
   lcd.setCursor(0,3);
   lcd.print("JOG       = C");
   while(cho == 0)
   {
     key = kpd.getKey();
     switch (key)
     {
     case NO_KEY:
      break;
     case 'A':
       Degrees=getdegrees();
       lcd.clear();
       cho = 1;
       break; 
     case 'B':
       Degrees=getdivisions();  
       cho=2;
       break;
     case 'C':
       Degrees=getjog();
       lcd.clear();
       cho=3;
       break;
       }      // end case
     }      // end while cho=0
 }    // end setup

 void loop()      // MAIN LOOP
 {

   lcd.clear();  
   char key = kpd.getKey();
     bob = 0;
     lcd.setCursor(7,0);lcd.print("Total:  ");lcd.print(bob,2);   // total steps
     lcd.setCursor(0,3);lcd.print("FOR=A   REV=B    X=C");
   while(key != 'C')    // C will return to start menu
   {
     lcd.setCursor(0,0);lcd.print(abs(Degrees),2);lcd.print((char)223);
     key = kpd.getKey();
     if(key == 'A')            // FORWARD
       {
        bob = bob + Degrees;
        ToMove = (Degrees*Multiplier);
        digitalWrite(3, LOW);
        printadvance();
       }
     if(key=='B')              // REVERSE
       {
        bob = bob - Degrees;  
        ToMove = (Degrees*Multiplier);
        digitalWrite(3, HIGH);    // pin 3
        printadvance();
       }
   }      // end while not C loop

  setup();
 }      // end main VOID


float getjog()
{
  float Degrees = 0;
  float num = 0.00;
   char key = kpd.getKey();
   lcd.clear();
   lcd.setCursor(6,0);lcd.print("Jogging");
   lcd.setCursor(0,1);lcd.print("A=1 B=10 C=100 Steps");
   lcd.setCursor(0,2);lcd.print("Enter Degrees:");lcd.setCursor(0,3);lcd.print("OK = #       ");lcd.print((char)60);lcd.print((char)45);lcd.print(" D");

   while(key != '#')
   {
      switch (key)
      {
         case NO_KEY:
            break;
         case 'A':
            Degrees = 1;      
            lcd.setCursor(14,2);lcd.print(Degrees);
            break;
         case 'B':
            Degrees = 10;
            lcd.setCursor(14,2);lcd.print(Degrees);
            break;
         case 'C':
            Degrees = 100;
            lcd.setCursor(14,2);lcd.print(Degrees);
            break;
         case 'D':
          num=0.00;
          lcd.setCursor(14,2);lcd.print("     ");
          lcd.setCursor(14,2);
          break;
      }
      key = kpd.getKey();
   }
  return Degrees; 
}


float getdivisions()
{
  float Degrees = 0; 
  float num = 0.00;
   char key = kpd.getKey();
   lcd.clear();
   lcd.setCursor(0,1);lcd.print("Enter Division:");lcd.setCursor(0,3);lcd.print("OK = #       ");lcd.print((char)60);lcd.print((char)45);lcd.print(" D");
   lcd.setCursor(16,1);

   while(key != '#')
   {
      switch (key)
      {
         case NO_KEY:
            break;

         case '0': case '1': case '2': case '3': case '4':
         case '5': case '6': case '7': case '8': case '9':
            num = num * 10 + (key - '0');
            lcd.print(key);
            break;

        case 'D':
          num=0.00;
          lcd.setCursor(16,1);lcd.print("     ");
          lcd.setCursor(16,1);
          break;
      }
      Degrees = 360/num;
      key = kpd.getKey();
   }
  return Degrees;  //num;
}


float getdegrees()
{ 
   //int key = 0;
   float num = 0.00;
   float decimal = 0.00;
   float decnum = 0.00;
   int counter = 0;
   lcd.clear();
   //lcd.init();
   char key = kpd.getKey();
   lcd.setCursor(0,1);lcd.print("Enter Degrees:");lcd.setCursor(0,3);lcd.print("OK = #       ");lcd.print((char)60);lcd.print((char)45);lcd.print(" D");
   lcd.setCursor(15,1);
   bool decOffset = false;

   while(key != '#')
   {
      switch (key)
      {
         case NO_KEY:
            break;

         case '.':
           if(!decOffset)
           {
             decOffset = true;
           }
            lcd.print(key);
            break;   

         case 'D':
          num=0.00;
          lcd.setCursor(15,1);lcd.print("     ");
          lcd.setCursor(15,1);
          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;
      }    //end case
      decnum = num / pow(10, counter);
      key = kpd.getKey();
   }    //end while not #
    return decnum;
}      // end getdegrees

 void printadvance()      // print function
   {
     lcd.setCursor(6,1);lcd.print("Moving");
     lcd.setCursor(4,2);lcd.print("Steps  ");lcd.print(ToMove,0); 
     lcd.setCursor(13,0);lcd.print(bob,2);
     rotation(ToMove,0);
     lcd.setCursor(6,1);lcd.print("      "); 
  } 

 void rotation(float tm, int d)
   { 
     for(int i = 0; i < tm; i++) 
       { 

       digitalWrite(3, HIGH); 
       delay(stepdelay); 
       digitalWrite(3, LOW); 
       delay(stepdelay);

       }
   }

void software_Reset() // Restarts program from beginning but does not reset the peripherals and registers
  {
  asm volatile ("  jmp 0");  
  }


----------



## xrayxray

Example code...I get small movements... // testing a stepper motor with a Pololu A4988 driver board
// on an Uno the onboard led will flash with each step
// as posted on Arduino Forum at http://forum.arduino.cc/index.php?topic=208905.0

byte directionPin = 3;
byte stepPin = 2;
int numberOfSteps = 5000;
byte ledPin = 13;
int pulseWidthMicros = 50;  // microseconds
int millisbetweenSteps = 50; // milliseconds

void setup()
{

  Serial.begin(9600);
  Serial.println("Starting StepperTest");
  digitalWrite(ledPin, LOW);

  delay(2000);

  pinMode(directionPin, OUTPUT);
  pinMode(stepPin, OUTPUT);
  pinMode(ledPin, OUTPUT);


  digitalWrite(directionPin, HIGH);
  for(int n = 0; n < numberOfSteps; n++) {
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(pulseWidthMicros);
    digitalWrite(stepPin, LOW);

    delay(millisbetweenSteps);

    digitalWrite(ledPin, !digitalRead(ledPin));
  }

  delay(3000);


  digitalWrite(directionPin, LOW);
  for(int n = 0; n < numberOfSteps; n++) {
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(pulseWidthMicros);
    digitalWrite(stepPin, LOW);

    delay(millisbetweenSteps);

    digitalWrite(ledPin, !digitalRead(ledPin));
  }

}

void loop()
{

}


----------



## Foozer

Short code just to isolate and test motor operation, use pins 2,3,4.  
copy, compile, run - - 




/* 
 *  dir-, pul-, en-, all to common GND
   Pin 2 Step Control
   Pin 3 Direction Control
   Pin 4 Enable Control
*/
void setup()
{
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  digitalWrite(4, LOW); // enable stepper. set HIGH to disable, freespin
  digitalWrite(3, LOW); // Direction, Set to HIGH for opposite direction
}
void loop() 
{ 
  digitalWrite(2, LOW);
  delayMicroseconds(3000);  // slow, increase e.g. 4000 to slow down
  digitalWrite(2, HIGH);
  delayMicroseconds(3000); // decrease number, e.g 2000 to speed up
}

It should turn with just this loaded . . .


----------



## xrayxray

We HAVE ROTATION....at last.
Now we know the board, drive and motor work.


Cheers


----------



## Foozer

xrayxray said:


> We HAVE ROTATION....at last.
> Now we know the board, drive and motor work.
> 
> 
> Cheers



Found a keypad so cobbled together the pieces. Using an easydriver to run a nema 13 - easydriver wires up similar, step, dir, enable . . .all common neg. So used pin 12 for enable.

Had a little display menu carryover but
 lcd.clear();
   lcd.setCursor(0,0);
added before
   lcd.print("Enter Selection:");   cured it . . 
Works like a champ here. With stepdelay set at 1 get a slight chatter, smooth at 2 - 

D is not working as the go back, but for now it's a no nevermind . .


----------



## xrayxray

Hi Foozer, tried 4 iterations of your code adjusted in the original  version, can't get it running...check and once again no errors seem to  jump out at me.

/*
 4x4 matrix keypad amd a 20 x 4 LCD. 
 Edit StepsPerRotation & TableRatio(# of turns for 360 degrees)in line 29
 M542 driver 
 * dir-, pul-, en-, all to common GND
 Pin 2 Step Control
 Pin 3 Direction Control
 Pin 12 Enable Control
 */

 #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(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);// set the LCD address to 0x20 for a 16 chars and 4 line display
                                   // SCL - 21, SDA - 20, VCC - +5, Gnd - Gnd 
 //setup vars


 const int StepsPerRotation = 400; // Set Steps per rotation of stepper NOTE the driver is set to Half step
 const int TableRatio = 90;        // ratio of rotary table
 const int Multiplier = (StepsPerRotation * TableRatio)/360;  // 200*90=18000/360 = 50
 const int stepdelay = 2;
 float Degrees = 0;                // Degrees from Serial input
 float ToMove = 0;                 // Steps to move
 float bob = 0;
 int cho = 0;

 void setup()
 {
 lcd.begin(20,4);      // initialize the lcd 
 pinMode(2, OUTPUT);
 pinMode(3, OUTPUT);
 pinMode(12, OUTPUT);
 digitalWrite(12, LOW); // enable stepper. set HIGH to disable, freespin
 digitalWrite(3, LOW); // Direction, Set to HIGH for opposite direction




 // Print welcome message to the Lcd;
 lcd.backlight();
 lcd.print("Rotary Table Control");
 lcd.setCursor(4,2);
 lcd.print(" ");
 lcd.setCursor(3,3);
 lcd.print("updated 2016");
 delay(2000);


   cho = 0;
   char key = kpd.getKey();
   lcd.clear();
   lcd.setCursor(0,0);
   lcd.print("Enter Selection:");   
   lcd.setCursor(0,1);
   lcd.print("Degrees   = A");
   lcd.setCursor(0,2);
   lcd.print("Divisions = B");
   lcd.setCursor(0,3);
   lcd.print("JOG       = C");
   while(cho == 0)
   {
     key = kpd.getKey();
     switch (key)
     {
     case NO_KEY:
      break;
     case 'A':
       Degrees=getdegrees();
       lcd.clear();
       cho = 1;
       break; 
     case 'B':
       Degrees=getdivisions();  
       cho=2;
       break;
     case 'C':
       Degrees=getjog();
       lcd.clear();
       cho=3;
       break;
       }      // end case
     }      // end while cho=0
 }    // end setup

 void loop()      // MAIN LOOP
 {

   lcd.clear();  
   char key = kpd.getKey();
     bob = 0;
     lcd.setCursor(7,0);lcd.print("Total:  ");lcd.print(bob,2);   // total steps
     lcd.setCursor(0,3);lcd.print("FOR=A   REV=B    X=C");
   while(key != 'C')    // C will return to start menu
   {
     lcd.setCursor(0,0);lcd.print(abs(Degrees),2);lcd.print((char)223);
     key = kpd.getKey();
     if(key == 'A')            // FORWARD
       {
        bob = bob + Degrees;
        ToMove = (Degrees*Multiplier);
        digitalWrite(3, LOW);
        printadvance();
       }
     if(key=='B')              // REVERSE
       {
        bob = bob - Degrees;  
        ToMove = (Degrees*Multiplier);
        digitalWrite(3, HIGH);   
        printadvance();
       }
   }      // end while not C loop

  setup();
 }      // end main VOID


float getjog()
{
  float Degrees = 0;
  float num = 0.00;
   char key = kpd.getKey();
   lcd.clear();
   lcd.setCursor(6,0);lcd.print("Jogging");
   lcd.setCursor(0,1);lcd.print("A=1 B=10 C=100 Steps");
    lcd.setCursor(0,2);lcd.print("Enter  Degrees:");lcd.setCursor(0,3);lcd.print("OK = #        ");lcd.print((char)60);lcd.print((char)45);lcd.print(" D");

   while(key != '#')
   {
      switch (key)
      {
         case NO_KEY:
            break;
         case 'A':
            Degrees = 1;      
            lcd.setCursor(14,2);lcd.print(Degrees);
            break;
         case 'B':
            Degrees = 10;
            lcd.setCursor(14,2);lcd.print(Degrees);
            break;
         case 'C':
            Degrees = 100;
            lcd.setCursor(14,2);lcd.print(Degrees);
            break;
         case 'D':
          num=0.00;
          lcd.setCursor(14,2);lcd.print("     ");
          lcd.setCursor(14,2);
          break;
      }
      key = kpd.getKey();
   }
  return Degrees; 
}


float getdivisions()
{
  float Degrees = 0; 
  float num = 0.00;
   char key = kpd.getKey();
   lcd.clear();
    lcd.setCursor(0,1);lcd.print("Enter  Division:");lcd.setCursor(0,3);lcd.print("OK = #        ");lcd.print((char)60);lcd.print((char)45);lcd.print(" D");
   lcd.setCursor(16,1);

   while(key != '#')
   {
      switch (key)
      {
         case NO_KEY:
            break;

         case '0': case '1': case '2': case '3': case '4':
         case '5': case '6': case '7': case '8': case '9':
            num = num * 10 + (key - '0');
            lcd.print(key);
            break;

        case 'D':
          num=0.00;
          lcd.setCursor(16,1);lcd.print("     ");
          lcd.setCursor(16,1);
          break;
      }
      Degrees = 360/num;
      key = kpd.getKey();
   }
  return Degrees;  //num;
}


float getdegrees()
{ 
   //int key = 0;
   float num = 0.00;
   float decimal = 0.00;
   float decnum = 0.00;
   int counter = 0;
   lcd.clear();
   //lcd.init();
   char key = kpd.getKey();
    lcd.setCursor(0,1);lcd.print("Enter  Degrees:");lcd.setCursor(0,3);lcd.print("OK = #        ");lcd.print((char)60);lcd.print((char)45);lcd.print(" D");
   lcd.setCursor(15,1);
   bool decOffset = false;

   while(key != '#')
   {
      switch (key)
      {
         case NO_KEY:
            break;

         case '.':
           if(!decOffset)
           {
             decOffset = true;
           }
            lcd.print(key);
            break;   

         case 'D':
          num=0.00;
          lcd.setCursor(15,1);lcd.print("     ");
          lcd.setCursor(15,1);
          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;
      }    //end case
      decnum = num / pow(10, counter);
      key = kpd.getKey();
   }    //end while not #
    return decnum;
}      // end getdegrees

 void printadvance()      // print function
   {
     lcd.setCursor(6,1);lcd.print("Moving");
     lcd.setCursor(4,2);lcd.print("Steps  ");lcd.print(ToMove,0); 
     lcd.setCursor(13,0);lcd.print(bob,2);
     rotation(ToMove,0);
     lcd.setCursor(6,1);lcd.print("      "); 
  } 

 void rotation(float tm, int d)
   { 
     for(int i = 0; i < tm; i++) 
       { 

       digitalWrite(3, HIGH); 
       delay(stepdelay); 
       digitalWrite(3, LOW); 
       delay(stepdelay); 
       }
   }

void software_Reset() // Restarts program from beginning but does not reset the peripherals and registers
  {
  asm volatile ("  jmp 0");  
  }


----------



## Foozer

Something in sketch you posted that's in error. Probably something lost in the cut and paste [like a few ",s], anywho you know what works, everything works separately but not so much together - So what,s changed from separately to combined?

attached a zip file of the script combined items inclusive. Works here, should work for you . . Have a daughters washing machine broken thing to do today so won't be able to look over your combined script till later in the day. 

View attachment Arduino_Rotary_Table_Control_XRayXRay_2017.zip


----------



## xrayxray

99% success with cheating,
Hi Foozer...Kids are more important than anything else....good luck with the washing machine.

Played  around this morning adding and subtracting bits of code...use some of  Foozer's and hashed it around a bit....Success with first  upload....yahoo...just one glitch....set 90 Degrees on the controller  and rotary table turnbs 45 degrees does same for every abngle  setting...cuts it in half.

Spent rest of the day so far changing   parameters for Table Ratio, Steps per Rotation etc, checking over and  over the sketch.....wont turn table past 400 step setting with table  ratio reduced from 90...back to 72 or 36....adding in the calculation  etc...no success.

I have cheated a bit now to get 90 degrees to  turn 90 degrees....did this by editing 360 degrees on sketch back to 180  degrees ....table now turns to whatever degree setting I  choose...Awesome.

Would still like to get the sketch fixed  without the cheat but I have looked and looked with my untrained eye and  can't see anything oout of place.

Here is the sketch......big  thanks and appreciation to all those involved....I learned heaps as  well....patience from people won out in the end.


/*
 4x4 matrix keypad amd a 20 x 4 LCD. 
* dir-, pul-, en-, all to common GND
Pin 2 Step Control
Pin 3 Direction Control
Pin 4 Enable Control
 */

 #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(0x3F,20,4); // set the LCD address to 0x20 for a 16 chars and 4 line display
                                   // SCL - A5, SDA - A4, VCC - +5, Gnd - Gnd 
  LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address

 //setup vars
 const int stp = 2;               // connect pin 2 to step
 const int dir = 3;               // connect pin 3 to dir
 const int en = 12;               // connect pin 12 to en
 const int StepsPerRotation = 200; // Set Steps per rotation of stepper NOTE the driver is set to Half step
 const int TableRatio = 90;        // ratio of rotary table
 const int Multiplier = (StepsPerRotation * TableRatio)/180; 
 const int stepdelay = 2000;
 float Degrees = 0;                // Degrees from Serial input
 float ToMove = 0;                 // Steps to move
 float bob = 0;
 int cho = 0;

 void setup()
 {

 lcd.begin(20,4);

pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(12, OUTPUT);

 // Print welcome message to the LCD.
 lcd.backlight();
 lcd.print("Rotary Table Control");
 lcd.setCursor(4,2);
 lcd.print(" ");
 lcd.setCursor(3,3);
 lcd.print("updated 2016");
 delay(2000);
// lcd.begin;();
   cho = 0;
   char key = kpd.getKey();
   lcd.clear();
   lcd.setCursor(0,0);
   lcd.print("Enter Selection:");   
   lcd.setCursor(0,1);
   lcd.print("Degrees   = A");
   lcd.setCursor(0,2);
   lcd.print("Divisions = B");
   lcd.setCursor(0,3);
   lcd.print("JOG       = C       ");
   while(cho == 0)
   {
     key = kpd.getKey();
     switch (key)
     {
     case NO_KEY:
      break;
     case 'A':
       Degrees=getdegrees();
       lcd.clear();
       cho = 1;
       break; 
     case 'B':
       Degrees=getdivisions();  
       cho=2;
       break;
     case 'C':
       Degrees=getjog();
       lcd.clear();
       cho=3;
       break;
       }      // end case
     }      // end while cho=0
 }    // end setup

 void loop()      // MAIN LOOP
 {
   lcd.clear();  
   char key = kpd.getKey();
     bob = 0;
     lcd.setCursor(7,0);lcd.print("Total:  ");lcd.print(bob,2);   // total steps
     lcd.setCursor(0,3);lcd.print("FOR=A   REV=B    X=C");
   while(key != 'C')    // C will return to start menu
   {
     lcd.setCursor(0,0);lcd.print(abs(Degrees),2);lcd.print((char)223);
     key = kpd.getKey();
     if(key == 'A')            // FORWARD
       {
        bob = bob + Degrees;
        ToMove = (Degrees*Multiplier);
        digitalWrite(3, LOW);
        printadvance();
       }
     if(key=='B')              // REVERSE
       {
        bob = bob - Degrees;  
        ToMove = (Degrees*Multiplier);
        digitalWrite(3, HIGH);  
        printadvance();
       }
   }      // end while not C loop
//   lcd.begin();
  setup();
 }      // end main VOID


float getjog()
{
  float Degrees = 0;
  float num = 0.00;
   char key = kpd.getKey();
   lcd.clear();
   lcd.setCursor(6,0);lcd.print("Jogging");
   lcd.setCursor(0,1);lcd.print("A=1 B=10 C=100 Steps");
   lcd.setCursor(0,2);lcd.print("Enter Degrees:");lcd.setCursor(0,3);lcd.print("OK = #       ");lcd.print((char)60);lcd.print((char)45);lcd.print(" D");

   while(key != '#')
   {
      switch (key)
      {
         case NO_KEY:
            break;
         case 'A':
            Degrees = 1;      
            lcd.setCursor(14,2);lcd.print(Degrees);
            break;
         case 'B':
            Degrees = 10;
            lcd.setCursor(14,2);lcd.print(Degrees);
            break;
         case 'C':
            Degrees = 100;
            lcd.setCursor(14,2);lcd.print(Degrees);
            break;
         case 'D':
          num=0.00;
          lcd.setCursor(14,2);lcd.print("     ");
          lcd.setCursor(14,2);
          break;
      }
      key = kpd.getKey();
   }
  return Degrees; 
}


float getdivisions()
{
  float Degrees = 0; 
  float num = 0.00;
   char key = kpd.getKey();
   lcd.clear();
   lcd.setCursor(0,1);lcd.print("Enter Division:");lcd.setCursor(0,3);lcd.print("OK = #       ");lcd.print((char)60);lcd.print((char)45);lcd.print(" D");
   lcd.setCursor(16,1);

   while(key != '#')
   {
      switch (key)
      {
         case NO_KEY:
            break;

         case '0': case '1': case '2': case '3': case '4':
         case '5': case '6': case '7': case '8': case '9':
            num = num * 10 + (key - '0');
            lcd.print(key);
            break;

        case 'D':
          num=0.00;
          lcd.setCursor(16,1);lcd.print("     ");
          lcd.setCursor(16,1);
          break;
      }
      Degrees = 360/num;
      key = kpd.getKey();
   }
  return Degrees;  //num;
}


float getdegrees()
{ 
   //int key = 0;
   float num = 0.00;
   float decimal = 0.00;
   float decnum = 0.00;
   int counter = 0;
   lcd.clear();
   //lcd.begin();
   char key = kpd.getKey();
   lcd.setCursor(0,1);lcd.print("Enter Degrees:");lcd.setCursor(0,3);lcd.print("OK = #       ");lcd.print((char)60);lcd.print((char)45);lcd.print(" D");
   lcd.setCursor(15,1);
   bool decOffset = false;

   while(key != '#')
   {
      switch (key)
      {
         case NO_KEY:
            break;

         case '.':
           if(!decOffset)
           {
             decOffset = true;
           }
            lcd.print(key);
            break;   

         case 'D':
          num=0.00;
          lcd.setCursor(15,1);lcd.print("     ");
          lcd.setCursor(15,1);
          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;
      }    //end case
      decnum = num / pow(10, counter);
      key = kpd.getKey();
   }    //end while not #
    return decnum;
}      // end getdegrees

 void printadvance()      // print function
   {
     lcd.setCursor(6,1);lcd.print("Moving");
     lcd.setCursor(4,2);lcd.print("Steps  ");lcd.print(ToMove,0); 
     lcd.setCursor(13,0);lcd.print(bob,2);
     rotation(ToMove,0);
     lcd.setCursor(6,1);lcd.print("      "); 
  } 

 void rotation(float tm, int d)
   { 
     for(int i = 0; i < tm; i++) 
       { 
   digitalWrite(2, HIGH);
   delayMicroseconds(1000); // slow, increase e.g. 4000 to slow down
   digitalWrite(2, LOW);
   delayMicroseconds(1000); // decrease number, e.g 2000 to speed up
       }
   }

void software_Reset() // Restarts program from beginning but does not reset the peripherals and registers
  {
  asm volatile ("  jmp 0");  
  }


----------



## Foozer

const int StepsPerRotation = 200; // Set Steps per rotation of stepper 
//NOTE the driver is set to Half step

set to 400 along with flipping the switch on the driver to 400 - half steps . .

Washing  machines sheet metal Blah, thing bit me twice . . .


----------



## xrayxray

Didn't work Foozer....no response from anything...I think I have tried every possibility accept the right one.

Bad luck about your getting bit by a washing machine....hope you have had a tetanus shot lately.


----------



## xrayxray

Didn't resolve the issue...I think I have tried every combination.
Looks like I have picked up a software bug.....thought it might have been a loose connection resetting and starting the rotation by itself....not so have it switched on and it's doing a dance without any input from me....Ghost's in the machine....mmmm don't know where to look for that to be resolved.

Cheers.


----------



## Foozer

I never checked to see if a call out of 90 actually gave a 90 degree. If the controller is switched to 400 steps per revolution [half steps] and the sketch is at 200 per revolution that 90 will come out as 45..
Ghost in the machine? Disconnect all and reconnect all, make sure all share a common ground . .
No tetanus shot, If dings and scratches affect the workings don't need to be doing the workings that cause ding and scratches . Good immune system, the nicks never bother me . .Well that one on the wrist underside likes to remind me it's there every time I put my hand into my pocket . .


----------



## xrayxray

Ghost in the machine could well be a bad earth,,,,seams okay now but those Dupont wires aren't holding up to good with all the unplugging and plugging.....keeping an eye on it and will sort out better cable when it's all sorted.
I'm still thinking and looking at the code to see if I can get out of using 180 and not 360

cheers.


----------



## Foozer

use 360 . . .

M542 driver - SW5, "OFF"  - - SW6,7,8, "ON"  400 steps [half stepping for a 1.8 degree stepper]
code line in sketch 
const int StepsPerRotation = 400; // Set Steps per rotation of stepper NOTE the driver is set to Half step


----------



## xrayxray

I did the 360, switches and 400 steps...no go...only runs with 200 steps and 180, I've tried every combination since yesterday.

Mounted properly in box with decent wiring...no more ghost's in the machine.

I'm pleased... runs good tho some tweaks would be good....like in degrees in doesn't stop on 360 or even 355...keeps running...no bigy., couple of minor things that those who no how to code might look at one day.

As I have said before I do appreciate the assistance that everyone has put in and grinning and chuffed that it works....will be a great asset for my projects....now to catch up on sleep....cheers.


----------



## xrayxray

Just an update...had heaps of trouble...rotary table was possessed...would start by itself, change direction without any input from me...go from degrees to jog etc...would just spin at anytime it wanted to.
I checked wiring multiple times and re uploaded sketch a few times...didn't fix the problem till one day it dawned on me that the controller might be picking up interference...disconnected the VFD near it and sure enough no more problems...the poltergeist left the area :}
This is the first time I have actually witnessed an electronic devise affected by another electronic devise with no connection between them, this is probably why i had so much trouble along the way.... Controller is now fastened to a bracket about a meter from the VFD ....makes me wonder whether a 12 volt to 240 volt plug in inverter for cars would have an effect on a Tesla auto drive function.....anyway all is good now

Cheers.


----------



## Cogsy

Glad to hear it's all sorted, a very tricky problem to diagnose!



xrayxray said:


> ....makes me wonder whether a 12 volt to 240 volt plug in inverter for cars would have an effect on a Tesla auto drive function


 
The inverter may well chuck out a cloud of electromagnetic interference but on such a critical system the car would be very thoroughly shielded to prevent interference, just like all aircraft systems are. You could even mostly shield your controller simply by fully enclosing it within a suitably ferrous box (just some mild steel plate would work pretty well) to give you some piece of mind that it's not going to go crazy on you again..


----------



## xrayxray

Hi Al, interesting that you say a ferrous enclosure...my enclosure is aluminium.non ferrous, however still a metal...why is this so ? wouldn't the aluminium act as a shield the same as steel...I would have expected this to happen in a PVC enclosure.
Yes I guess your right about self driving cars having to be heavily shielded...lets hope so.

I haven't messed with the controller today...the frustration over days and weeks has been driving me nuts....but I still have the problem of the sketch not working more than 200 steps and a table ratio of 90, next problem to solve but having a break from it for a bit while at least it's stable now...waiting for some ebay parts to arrive to put together a new controller and swap this one out...might get the original sketch to work this time.

Cheers.


----------



## Cogsy

From my understanding, the metal needs to be ferrous to interact with the magnetic field (other than to generate an induced current, where it only needs to be a metal) to 'interrupt' (not really the right word) the magnetic field. You can do the experiment yourself just to see - grab 2 decently powerful magnets and arrange them with like poles facing each other so they repel, then drop a piece of plate between them and you will see both will stick to each side of the plate, even though without the plate they wouldn't get close to each other. Basically the magnetic fields are no longer interacting with each other and are effectively blocked by the metal. So the theory is a fully enclosed ferrous box would interrupt magnetic influence from any direction and shield your electronics. I haven't done the experiment myself but I am under the impression non-ferrous will not 'interrupt' the field in this manner. I really should try it myself just for curiosity's sake I guess...


----------



## xrayxray

Good Stuff Al... makes sense with your great explanation..rotary table still working good now it's shifted.

Cheers.


----------



## bmac2

Cogsy said:


> From my understanding, the metal needs to be ferrous to interact with the magnetic field (other than to generate an induced current, where it only needs to be a metal) to 'interrupt' (not really the right word) the magnetic field. You can do the experiment yourself just to see - grab 2 decently powerful magnets and arrange them with like poles facing each other so they repel, then drop a piece of plate between them and you will see both will stick to each side of the plate, even though without the plate they wouldn't get close to each other. Basically the magnetic fields are no longer interacting with each other and are effectively blocked by the metal. So the theory is a fully enclosed ferrous box would interrupt magnetic influence from any direction and shield your electronics. I haven't done the experiment myself but I am under the impression non-ferrous will not 'interrupt' the field in this manner. I really should try it myself just for curiosity's sake I guess...



 Actually a shield only has to be conductive and connected to ground. Pass a magnetic field over a conductor, it generates electricity. Pulse it on and off and everything else in the room goes a little nuts. We had a screen room at work used for calibration of avionics equipment and it was a fine copper mesh. This is 25 pair cable used for voice and data and the shield is aluminum. Heres a tip. Like hobby electronics? Get a buddy thats a cable splicer. To them 3 feet of cable is garbage, to me its a pot of colour coded gold!


----------



## Cromaglious

This my take on the 4th axis rotary table. Jmc-motor.com NEMA 23 285 oz. in. IHSS57-36-20 integrated closed loop stepper. Belt drive reduction, belt on order. Give it 20 to 48vdc and step and direction. Built in driver and encoder. Enough power to turn against a 3/8 end mill doing serious work.  I also have a weld positioner using a 48:1 blue ebay worm drive and a Shopsmith 12" sanding platter.  That is currently driven using a 6600 ebay driver and an old cnc3040 NEMA 23 dumb stepper .


----------



## neilw20

This is meant to be constructive, to help you. Not laying $hit on your good work. 

Look at this fragment of code...

case 'D':
    num=0.00;
    lcd.setCursor(16,1);lcd.print(" ");
    lcd.setCursor(16,1);
    break;
}
Degrees = 360/num;   // <----- Division by ZERO!! for case 'D'
key = kpd.getKey();
}
return Degrees; //num;
}'

Doing this sort of thing on micros, in my experience, NEVER needs floating point arithmetic on such a basic operation like working stepper motors.
For 200 step per rev and 90:1 for gear gives (200 * 90) / 360 gives 50 steps per degrees.
Want to move 13.5 degrees (internally counting from 0 to 3600) gives STEPS = (135 * 50) / 10 = 675;
Want to move 13.4 degrees (internally counting from 0 to 3600) gives STEPS = (134 * 50) / 10 = 670;
Want to move 0.1 degrees (internally counting from 0 to 3600) gives STEPS =  (1 * 50) / 10 = 5;
Always do the MULTIPLY FIRST, usually for better results.
Dynamically changing time delays in loops, so that it accelerates and decelerates smoothly will allow much higher speeds.
Once above the critical speed of the motor you can't just stop or start it instantly.
A stepper is torsionally loaded against a permanent magnet, like a spring, and once you yank on the spring too quickly you can loose steps because inertia wins.
https://www.google.com/search?q=ste...ast5zcAhXFmJQKHaPHDX4QsAQIPg&biw=1375&bih=751
Look at the manufacturers data sheets for motors.
Study this.. It might explain a few things
https://en.wikipedia.org/wiki/Stepper_motor


----------



## chucketn

I know this is an old thread, but I built a rt controller based on this same code from Bob Pratl way back when. I was making a 3d printed case for it and had to disassemble my working mock up to put the parts into the case. I stupidly forgot to make a schematic or sufficient notes to get it re-connected. And, now can't remember how I put it together.
In the interim, I used the Arduino Mega with other projects. Now, I find I've lost my code.
My setup used a Arduino mega, the 4x4 keypad that the late John Stevenson posted about way back when, a TB6560 driver, and a 20x4 lcd, but no I2c. I used the mega to accommodate the lcd and the keypad.
I know I shared my working code with someone on this or another forum, but I can't find it. BMac2, Foozer, anybody... Do you remember the thread, or maybe have a copy of my version of the code?
I could start over, and probably will have to, but thought I would ask.
I have searched all the forums I'm on, my email sent folder, and 3 computers... Can't find the schematic I used nor the code...
I know I had it working, because I made a set of Atlas change gears, and several other gears with it, with the components mounted on a crappy wood base...


----------



## Foozer

Don't recall seeing a mega based script, do recall your mentioning it [Stepping Motors Thread] where you said you modified a script from Bob Prati, but doesn't appear that the code was posted. Feel your pain - I've lost scripts, know I saved them, just can't find them. 

Robert


----------



## chucketn

Thanks for responding, Bob. Well, gives me something to do... Already found a 4x4 keypad test sketch. Tested it on Arduino and mega. This time I'll document as I go..., and save the code in several places.
I know I saved it before, just can't find it. And, I'm sure I shared it with someone...


----------



## Foozer

Start a thread and document your rebuild adventure.
Rebuild often comes out better than the original . . .


----------



## bmac2

Hi Chuck I do remember you mentioning that you were using a MEGA but not sure of the thread. I think you should be able to find everything you need in the Arduino Rotary Table For Dummies.

https://www.homemodelenginemachinist.com/threads/arduino-rotary-table-for-dummies.26744/


----------



## chucketn

Thanks Foozer, and Bob. I have started down that long dusty road... I have gotten the keypad to work with the mega, the display - not so much...
I loaded the "Hello World" example and can only get the back light and intensity to work. I had left the Keypad connected and tried to change the pins the display, a 20x4, connected to. I think that is what I did before.
I may just break down and buy another setup, of an ICII lcd ad a new Arduino Uno and start with the proven sketch.


----------



## bmac2

Just had a peek and on the MEGA the ICII pins are :
Mega2560 pin 20 (SDA), pin 21 (SCL)


----------



## chucketn

So I don't need a separate I2C card? Duh... Yes I do... O.k., just ordered a 20x4 lcd with I2C module attached. When that gets here I'll start again.
Sux getting old, you forget so much hard learned knowledge.
Thanks all for your help. I'll be back...


----------



## bmac2

chucketn said:


> Sux getting old, you forget so much hard learned knowledge.
> Thanks all for your help. I'll be back...



Chuck you have to look at the up side. I figure my brain cells are finally down to a manageable number.


----------



## Wizard69

bmac2 said:


> Chuck you have to look at the up side. I figure my brain cells are finally down to a manageable number.



Now that is funny!    

I understand Chucks problem though.   I do have a cure for one old age problem.  When you misplace something and can’t find it after months of looking just go down to the hardware store and buy a new one.   You will find that missy by tool within 15 minutes of getting home!!!!!


----------



## DJP

My aging aunt passed along her wisdom.... 'When you are finished using something; put it back. Do not put it down. ' 

I'm finding that she was right and it applies well to a metal machine shop.


----------



## chucketn

DJP said:


> My aging aunt passed along her wisdom.... 'When you are finished using something; put it back. Do not put it down. '
> 
> I'm finding that she was right and it applies well to a metal machine shop.



Good advice! I try, but I am so easily distracted ( oh, shiny... or I need an X to make a Y, and now I need a Z to make an X, wash, repeat...). Now, what was I doing? Mostly, if I can't remember what I was doing, I never know when I'm finished!


----------



## Qtron

neilw20 said:


> This is meant to be constructive, to help you. Not laying $hit on your good work.
> 
> Look at this fragment of code...
> 
> case 'D':
> num=0.00;
> lcd.setCursor(16,1);lcd.print(" ");
> lcd.setCursor(16,1);
> break;
> }
> Degrees = 360/num;   // <----- Division by ZERO!! for case 'D'
> key = kpd.getKey();
> }
> return Degrees; //num;
> }'
> 
> Doing this sort of thing on micros, in my experience, NEVER needs floating point arithmetic on such a basic operation like working stepper motors.
> For 200 step per rev and 90:1 for gear gives (200 * 90) / 360 gives 50 steps per degrees.
> Want to move 13.5 degrees (internally counting from 0 to 3600) gives STEPS = (135 * 50) / 10 = 675;
> Want to move 13.4 degrees (internally counting from 0 to 3600) gives STEPS = (134 * 50) / 10 = 670;
> Want to move 0.1 degrees (internally counting from 0 to 3600) gives STEPS =  (1 * 50) / 10 = 5;
> Always do the MULTIPLY FIRST, usually for better results.
> Dynamically changing time delays in loops, so that it accelerates and decelerates smoothly will allow much higher speeds.
> Once above the critical speed of the motor you can't just stop or start it instantly.
> A stepper is torsionally loaded against a permanent magnet, like a spring, and once you yank on the spring too quickly you can loose steps because inertia wins.
> https://www.google.com/search?q=ste...ast5zcAhXFmJQKHaPHDX4QsAQIPg&biw=1375&bih=751
> Look at the manufacturers data sheets for motors.
> Study this.. It might explain a few things
> https://en.wikipedia.org/wiki/Stepper_motor



Hi Neilw20,
newbie here, any chance of a copy of the rotary table code with your improvements, i cant write code..(yet)
i assume your code runs quicker without floating point assisting..
havent a clue what i am writing here!
am willing to pay for your efforts.
i compiled te xrayxray zipped file & original file using arduinodroid,
on samdung TabA tablet. seems to work but i keep getting diagnostic (results) exclamations: use of undeclared identifier 'getdegrees' and 2 other 'gets'! also 'printadvance' & 'rotation'
compiled ok.

i went thru all pages of this thread , no reference to this type of diagnostics results. 
Also, 
i dunno where to get that 4x4 membrane keypad, no brands seem to be mentioned anywhere..
cheers,
Qtron


----------



## Qtron

to clarify, i get the same errors on orig file & XrayXray zipped, sorry cant fnd the right page in this thread for the zipped version, the orig being on page 1.


----------



## kquiggle

You might want to try using the code re-write I did; you can download at the link below:

https://sites.google.com/site/lagadoacademy/miscellaneous-projects/stepper-motor---accelstepper-h


----------



## Qtron

Cheers Mr Kquiggle, MUCH appreciated.
I also sus'ing out YouTube's Myfordboy's "Stepindexliming23.ino comprehensive Indexer, 620 lines of code!!!
A clever dick indeed


----------



## lmeb83

I finished a prototype that is almost working well.  When I was testing it in production, it started working well, but after 2 or 3 minutes,  when no key is pressed it still shows a random keypress on the LCD or the keypad freezes and I have to unplug and plug the electrical box again. 
I suspect it may be the keypad wires or any interference caused by the environment? The milling machine? I used 3 foot long wires for the keypad, I don't know if that can be an issue. Has anybody faced a similar issue with these components?


----------



## RM-MN

3 feet of wire can make a pretty good antenna for picking up random signals.  You might have better results if you use shielded wire for all connections to the Arduino.  Quick way to find out is to use aluminum foil to wrap around the wires for shielding.


----------



## awake

One other thing to try is positioning the Arduino further from the stepper / servo drivers. Also, are the inputs for the drivers opto-isolated? If not, and if you are using a common ground for the drivers and the Arduino, you may be picking up interference there.


----------



## kquiggle

Non-shielded wire was my first thought as well, although I have a similar set-up and I am not seeing the same problem.  Also - take a look at the wire routing inside your enclosure - probably better to route some of those wires further away from the PSU.

As "awake" noted - check how you have your grounding set up.

Regarding the "freezing" issue: In a separate email to me you noted that you had made some coding changes and that out-of-memory errors might be a concern. One way you can test this is to just comment out one or more of the larger subroutines and see if the problem goes away (of course, you won't be able to use those subroutine functions while testing).

Finally - double check all your connections. A loose wire or bad solder joint can cause all kinds of problems and can be very difficult to find. One thing you can do is just wiggle various connections and see if your random keypress shows up.

God luck.


----------



## Willyb

I notice that you are using the push on type jumper wires for the connections to your Arduino. These are really only designed for prototype work with Breadboards, etc.  I find them very unreliable especially in a manufacturing environment.  A better route would be to use an Arduino Shield that breaks out each terminal to a screw connection that you can clamp each wire under.  Or just solder your wires directly to the Arduino pins and use shrink tube over the connections.  Either of these methods are better at handling everyday usage in a shop environment.
Another thing to watch is the location of your Arduino in relation to anything with A/C power. Switching power Supplies can cause interference and it is always a good idea to keep your DC away from your A/C which includes your Arduino. Always try to keep your Arduino as far away as possible from these A/C devices.
And by all means follow the other suggestion like short leads, wire shielding and proper grounds.

Good luck with your project.

Cheers
Willy


----------



## jim.dean56

If you are using shielded cable you should only ground one end of the shield.  If you ground both ends its possible to created "circulating ground current" in the shield which can cause issues in some cases.


----------



## 74Sprint

First don't forget the golden rule "only make 1 change at a time until you have that 1 fixed then go onto the next". You seem to have 2 problems, 1 software and 1 hardware. Random signals can be very hard to track down and you will need patience to solve it/them. Shielding typically is never grounded, grounding one end can cause a capacitance to build up and cause even more problems. Don't forget that shielding is to either keep signals from getting out or in. Capacitors are used for filtering (non-electrolytic) to either drain off unwanted signals or to pass them on. Since your getting random key-presses start by using either CAT5 or preferably CAT6 multi-strand ethernet cable (not solid core) it has twisted pair wires to eliminate noise. If this doesn't work use OPTO-Isolators placing them as close to the UNO as possible. OPTOs are my favorites because they are current driven and pretty much voltage immune. kquiggle's suggestion for the software is very good, try later.

Just my 2 cents worth.
Ray


----------



## bdrmachine

A cheap and quick fix maybe to put a Ferrite bead at the ends of the cables.  My Haas mill was triggering random Z axis encoder faults which forces a full reboot.  I snapped a bead on the cable and haven't seen the problem since.


----------



## lmeb83

Thank you guys for your input.
I have decided to replace the arduino with a Controllino PLC and use a C-More instead the keypad and the LCD.
I have never worked with PLCs , C-more, or modbus protocol. But I will do some research and learn.

The other option I was thinking is to use a Click PLC, but I have never programmed on ladder logic.
I´ll be posting new updates on the project.


----------



## RM-MN

Great idea.  Instead of trying to fix a minor problem, go to a completely different system and learn all the problems that that system can also create.


----------



## lmeb83

74Sprint said:


> First don't forget the golden rule "only make 1 change at a time until you have that 1 fixed then go onto the next". You seem to have 2 problems, 1 software and 1 hardware. Random signals can be very hard to track down and you will need patience to solve it/them. Shielding typically is never grounded, grounding one end can cause a capacitance to build up and cause even more problems. Don't forget that shielding is to either keep signals from getting out or in. Capacitors are used for filtering (non-electrolytic) to either drain off unwanted signals or to pass them on. Since your getting random key-presses start by using either CAT5 or preferably CAT6 multi-strand ethernet cable (not solid core) it has twisted pair wires to eliminate noise. If this doesn't work use OPTO-Isolators placing them as close to the UNO as possible. OPTOs are my favorites because they are current driven and pretty much voltage immune. kquiggle's suggestion for the software is very good, try later.
> 
> Just my 2 cents worth.
> Ray



Thank you Ray. Is there any tutorial I can follow on what OPTO isolators ti use and how to connect them?
I have most of DIGITAL (PWM) pins connected. 2 and 3 connected to one stepper driver, 4 to 11 connected to the KEYPAD, and 12, 13 connected to the other stepper driver.
And the ANALOG IN 5V connected to a breadboard  where the VCC from the LCD is connected, as well as PUL(+) and DIR (-) from both steppers drivers.
The GND connected to the LCD. A4 and A5 to the LCD.


----------



## lmeb83

RM-MN said:


> Great idea.  Instead of trying to fix a minor problem, go to a completely different system and learn all the problems that that system can also create.


You are right. I'll continue trying to fix the minor problem while I move to the PLC. Should I wrap with aluminum foil everyone of the 16 wires that I have connected to the arduino? O just the 8 from the keypad. Just wrapping the 8 seems difficult to achieve.


----------



## lmeb83

Willyb said:


> I notice that you are using the push on type jumper wires for the connections to your Arduino. These are really only designed for prototype work with Breadboards, etc.  I find them very unreliable especially in a manufacturing environment.  A better route would be to use an Arduino Shield that breaks out each terminal to a screw connection that you can clamp each wire under.  Or just solder your wires directly to the Arduino pins and use shrink tube over the connections.  Either of these methods are better at handling everyday usage in a shop environment.
> Another thing to watch is the location of your Arduino in relation to anything with A/C power. Switching power Supplies can cause interference and it is always a good idea to keep your DC away from your A/C which includes your Arduino. Always try to keep your Arduino as far away as possible from these A/C devices.
> And by all means follow the other suggestion like short leads, wire shielding and proper grounds.
> 
> Good luck with your project.
> 
> Cheers
> Willy



Thank you Willy. The Arduino Shield is a good idea. I'll get one.


----------



## lmeb83

bdrmachine said:


> A cheap and quick fix maybe to put a Ferrite bead at the ends of the cables.  My Haas mill was triggering random Z axis encoder faults which forces a full reboot.  I snapped a bead on the cable and haven't seen the problem since.



Thank you for the advice. I am new on doing this kind of projects, this is the first time I hear abour Ferrite beads.  I am using 28 AWG jumper wires. 8 for the keypad. Do I have to put a Ferrite bead on each one of the 8 wires? Just on the end that connect to the arduino? Where can I get those components and info on how to apply them to the cables?


----------



## RM-MN

You probably only need ferrite beads on one or two wires but there is no way of knowing which wires need them so best to do all 8.  If you are wrapping wires with aluminum foil you don't want to wrap all of them together.  The signals the wires carry are digital, either on or off and the spikes this can create may be picked up by other nearby wires and get interpreted as a signal.  Then the controller gets confused because it may be able to detect these spikes part of the time and not others leading to some interesting results.


----------



## willray

lmeb83 said:


> You are right. I'll continue trying to fix the minor problem while I move to the PLC. Should I wrap with aluminum foil everyone of the 16 wires that I have connected to the arduino? O just the 8 from the keypad. Just wrapping the 8 seems difficult to achieve.



Oh for crying out loud, someone take pity on the poor guy...

Look.  Based on the information you've shared with the forum, it's clear that your system has some problem(s), but not exactly what they are.  It's not even clear whether your problems are hardware or software.  Chasing silliness like wrapping aluminum foil around things before you've figured out where the problem lies, is, well silliness, and recommending it to you before helping you diagnose the problem lies is cruel.

Step 1:  Describe the problem(s) in more detail:

a) "The system freezes"

What does the system do that makes you think it freezes?  Do you know whether the Arduino program counter is still running?  Is the main loop still looping?  We need to know whether the hardware has literally taken a crap on you, or if it's off stuck in some infinite loop, confused and waiting for input, or ???

If you don't know how to diagnose these things, post what you do know, and people can help walk you through further diagnostics.

b) "displays random key presses"

What does "displays random key presses" mean?   Do you have it displaying something each time a key is pressed?  Does it get stuck displaying some key press?  Does it display key presses when no keys are being pressed?   Does it continue to display random key presses if you yank the connector for the key-pad while it's displaying a "random key press"?   Does it display random key presses even if the key pad is not connected at all after turning it on?

How are you reading the key pad?  It looks like it's just a switch matrix, so you're probably either measuring continuity between (row and column) pairs and some common line?  Or maybe injecting voltage and measuring voltage out on the row/column lines?  Are you reading the inputs as digital I/O or analog I/O?  If you're reading digital, have you tried switching to analog and looking at the actual values?  Does the key pad include pull-up/pull-down resistors?  Is it de-bounced in hardware on the board, or do you de-bounce in your software?  (if it's a bog-standard-simple keypad, and you're doing the bog-standard-simple thing for reading it, appropriate pull-ups/pull-downs and debounce will fix a /lot/ of random).

Help us out by providing a bit more information, and hopefully people will stop making random guesses about things that might be helpful.


----------



## tjwal

QUOTE="lmeb83, post: 334299, member: 40662"]Thank you Willy. The Arduino Shield is a good idea. I'll get one.[/QUOTE]

I’ve used one of these in a permanent project
https://www.seeedstudio.com/Base-Shield-V2.html
You also need their cables.  I use the longer ones and cut them so I have a connector on one end.  A simple inline splice and you have a good reliable connection.

My preference though, is to use the Nano as it has a better form factor than the Uno.  It fits nicely on a perfect board and then you can mount whatever type of connector you prefer.


----------



## lmeb83

tjwal said:


> QUOTE="lmeb83, post: 334299, member: 40662"]Thank you Willy. The Arduino Shield is a good idea. I'll get one.



I’ve used one of these in a permanent project
https://www.seeedstudio.com/Base-Shield-V2.html
You also need their cables.  I use the longer ones and cut them so I have a connector on one end.  A simple inline splice and you have a good reliable connection.

My preference though, is to use the Nano as it has a better form factor than the Uno.  It fits nicely on a perfect board and then you can mount whatever type of connector you prefer.[/QUOTE]

I thought this is the shield I needed.


----------



## tjwal

Either one will give you more reliable connections.


----------



## Willyb

I like the ones with the screw terminals but either will work.

Willy


----------



## bdrmachine

I'm not sure how you wired things up but remember ground is your reference for EVERYthing and all wires have a finite resistance.  Thru that resistance,  you get a voltage drop which changes your reference level.   That being said, ALL connections to ground should go to a common point to prevent ground loops.  This is also why you should only ground one end of a wire shield.


----------



## lmeb83

Thank you for all your suggestions and input. It's working good now. I moved the arduino away from the stepper drivers and the power supply. I used shielded wires, expansion shield for the arduino, I changed the keyboard, changed the enclosure from carbon fiber to abs.


----------



## Willyb

Congratulation on getting your Arduino Controlled Rotary Table figured out.  Looks like you have moved your Arduino into the Keyboard enclosure?  Good job.  Nice looking Shop!

Cheers
Willy


----------



## lmeb83

Willyb said:


> Congratulation on getting your Arduino Controlled Rotary Table figured out.  Looks like you have moved your Arduino into the Keyboard enclosure?  Good job.  Nice looking Shop!
> 
> Cheers
> Willy



Thank you Willy. Yes, I moved the arduino inside the keypad enclosure.


----------



## Willyb

That is a nice looking fixture on your Mill.  What do you mainly use your Arduino Control for?
Take care.

Willy


----------



## lmeb83

Willyb said:


> That is a nice looking fixture on your Mill.  What do you mainly use your Arduino Control for?
> Take care.
> 
> Willy


We mainly use to control stepper motors. We produce custom orders, and this setup will help to find the angles quickly and reduce scrap rate.


----------



## lmeb83

Anybody with experience on Automation Direct PLCs ? I am trying to do this project using a PLC and HMI from AD. If possible, I would like to use the same stepper motor kit, because it is a Nema 34 and is closed loop. I have a stepper drive STP-DRV-80100, a stepper motor STP-MTRH-34127, but I am not sure what PLC should I use. A directLOGIC, BRX, Productivity 3000 ? Thank you.


----------



## rodw

lmeb83 said:


> Anybody with experience on Automation Direct PLCs ? I am trying to do this project using a PLC and HMI from AD. If possible, I would like to use the same stepper motor kit, because it is a Nema 34 and is closed loop. I have a stepper drive STP-DRV-80100, a stepper motor STP-MTRH-34127, but I am not sure what PLC should I use. A directLOGIC, BRX, Productivity 3000 ? Thank you.



Your stepper drive is  a pretty sophisticated one that has a number of modes to support steppers as well as several different types of servos.
You don't need a PLC (an Arduino is fine), you just need to use their software to set the mode to step and direction and use the existing Arduino sketch.


----------

