weldone. want to watch the video
So I decided that I wanted to be able to do repetitive moves on my Sherline cnc rotary table without using my computer and Mach3. Sherline makes a standalone controller but it's in the $400 range even on Ebay. Using an Arduino Nano, a 20x4 serial lcd, a 4x4 matrix keypad and a pololu stepper driver, I put together a simple stand alone rotary table controller. I'm using a 4amp 13.8v regulated DC power supply to power this project but I plan to use a laptop AC adapter when finished and put the controller in a 3d printed enclosure.
IMG_0007.jpgIMG_0008.jpg
I'm not a great Arduino programmer but here's the sketch:
HTML Code:/* A program for controlling a single stepper motor driving a rotary table. Uses a 4x4 matrix keypad for entry of degrees and direction to move the table. Serial I2C display, Pololu stepper driver. */ #include <Wire.h> #include <LiquidCrystal_I2C.h> #include <Keypad.h> const byte ROWS = 4; const byte COLS = 4; char keys[ROWS][COLS] = { {'1','2','3','A'}, {'4','5','6','B'}, {'7','8','9','C'}, {'.','0','#','D'} }; byte rowPINS[ROWS] = {11,10,9,8}; byte colPINS[COLS] = {7,6,5,4}; Keypad kpd = Keypad(makeKeymap(keys),rowPINS,colPINS, ROWS, COLS); LiquidCrystal_I2C lcd(0x27,20,4); // set the LCD address to 0x20 for a 16 chars and 2 line display //setup vars const int stp = 12; //connect pin 12 to step const int dir = 13; // connect pin 13 to dir const int StepsPerRotation = 400; //Set Steps per rotation of stepper const int TableRatio = 72; //ratio of rotary table const int Multiplier = (StepsPerRotation * TableRatio)/360; const int stepdelay = 1; float Degrees = 0; //Degrees from Serial input float ToMove = 0; //Steps to move int Direction; int repeat = 0; void setup() { lcd.init(); // initialize the lcd pinMode(stp, OUTPUT); pinMode(dir, OUTPUT); // Print welcome message to the LCD. lcd.backlight(); lcd.print("Rotary Table Control"); lcd.setCursor(0,2); lcd.print(" CrankyTechGuy CNC"); lcd.setCursor(0,3); lcd.print(" Copyright 2014"); delay(2000); lcd.init(); } void rotation(float tm, int d) { if(d == 0) { digitalWrite(dir, LOW); } else { digitalWrite(dir, HIGH); } for(int i = 0; i < tm; i++) { digitalWrite(stp, HIGH); delay(stepdelay); digitalWrite(stp, LOW); delay(stepdelay); } } float GetNumber() { float num = 0.00; float decimal = 0.00; float decnum = 0.00; int counter = 0; char key = kpd.getKey(); lcd.print("Rotary Table Control"); lcd.setCursor(0,2);lcd.print("Enter degrees then");lcd.setCursor(0,3);lcd.print("press [#]."); lcd.setCursor(8,1); bool decOffset = false; while(key != '#') { switch (key) { case NO_KEY: break; case '.': if(!decOffset) { decOffset = true; } lcd.print(key); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if(!decOffset) { num = num * 10 + (key - '0'); lcd.print(key); } else if((decOffset) && (counter <= 1)) { num = num * 10 + (key - '0'); lcd.print(key); counter++; } break; } decnum = num / pow(10, counter); key = kpd.getKey(); } return decnum; } int GetDirection() { int dir = 0; lcd.setCursor(0,2);lcd.print(" "); lcd.setCursor(0,3); lcd.print(" FWD[A] REV[B]"); while(dir == 0) { char key = kpd.getKey(); if(key == 'A') { dir = 1; } else if(key == 'B') { dir = -1; } } lcd.clear(); return dir; } void loop() { if(repeat == 0) { Degrees = GetNumber(); Direction = GetDirection(); } Degrees = Degrees * Direction; if(Degrees < 0) { ToMove = (Degrees*Multiplier)*-1; lcd.setCursor(0,0); lcd.print("REV "); lcd.print(abs(Degrees),2);lcd.print((char)223); lcd.setCursor(6,1); lcd.print("Moving"); rotation(ToMove,0); lcd.setCursor(6,1); lcd.print(" "); } else { ToMove = Degrees*Multiplier; lcd.setCursor(0,0); lcd.print("FWD "); lcd.print(Degrees,2);lcd.print((char)223); lcd.setCursor(6,1); lcd.print("Moving"); rotation(ToMove,1); lcd.setCursor(6,1); lcd.print(" "); } lcd.setCursor(0,2); lcd.print("Repeat[A] Cancel[B]"); char key = kpd.getKey(); while(key != 'B') { key = kpd.getKey(); if(key == 'A') { if(Degrees < 0) { ToMove = (Degrees*Multiplier)*-1; lcd.setCursor(6,1); lcd.print("Moving"); rotation(ToMove,0); lcd.setCursor(6,1); lcd.print(" "); } else { ToMove = Degrees*Multiplier; lcd.setCursor(6,1); lcd.print("Moving"); rotation(ToMove,1); lcd.setCursor(6,1); lcd.print(" "); } } } lcd.clear(); }
Similar Threads:
weldone. want to watch the video
http://free3dscans.blogspot.com/ http://my-woodcarving.blogspot.com/
http://my-diysolarwind.blogspot.com/
Question How high is the Holding force ? Looks nice
Gesendet von meinem SM-N9005 mit Tapatalk
I know nothing about writing a sketch so I have to ask will the sketch still work if I change the Tableratio and the steps for a turn to 2oo.
The stepper is a 270ozin stepper. With the worm drive system of the rotary table, holding force of the stepper isn't a huge factor.
Updated my Sketch. The controller will now allow you to choose between degrees or divisions.
Code:/* A program for controlling a single stepper motor driving a rotary table. Uses a 4x4 matrix keypad for entry of degrees and direction or number of divisions to move the table. Serial I2C display, Pololu stepper driver. */ #include <Wire.h> #include <LiquidCrystal_I2C.h> #include <Keypad.h> const byte ROWS = 4; const byte COLS = 4; char keys[ROWS][COLS] = { {'1','2','3','A'}, {'4','5','6','B'}, {'7','8','9','C'}, {'.','0','#','D'} }; byte rowPINS[ROWS] = {11,10,9,8}; byte colPINS[COLS] = {7,6,5,4}; Keypad kpd = Keypad(makeKeymap(keys),rowPINS,colPINS, ROWS, COLS); LiquidCrystal_I2C lcd(0x27,20,4); // set the LCD address to 0x20 for a 16 chars and 2 line display //setup vars const int stp = 12; //connect pin 12 to step const int dir = 13; // connect pin 13 to dir const int StepsPerRotation = 400; //Set Steps per rotation of stepper const int TableRatio = 72; //ratio of rotary table const int Multiplier = (StepsPerRotation * TableRatio)/360; const int stepdelay = 1; float Degrees = 0; //Degrees from Serial input float ToMove = 0; //Steps to move float Divisions; float current = 0; int Mode = 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(0,2); lcd.print(" CrankyTechGuy CNC"); lcd.setCursor(0,3); lcd.print(" Copyright 2014"); delay(2000); lcd.init(); Mode = GetMode(); } void software_Reset() // Restarts program from beginning but does not reset the peripherals and registers { asm volatile (" jmp 0"); } void rotation(float tm, int d) { if(d == 0) { digitalWrite(dir, LOW); } else { digitalWrite(dir, HIGH); } for(int i = 0; i < tm; i++) { digitalWrite(stp, HIGH); delay(stepdelay); digitalWrite(stp, LOW); delay(stepdelay); } } float GetNumber() { float num = 0.00; float decimal = 0.00; float decnum = 0.00; int counter = 0; char key = kpd.getKey(); lcd.setCursor(0,0);lcd.print("Enter degrees then");lcd.setCursor(0,3);lcd.print(" press [#]."); lcd.setCursor(0,30);lcd.print("Reset [D]"); lcd.setCursor(8,2); bool decOffset = false; while(key != '#') { switch (key) { case NO_KEY: break; case '.': if(!decOffset) { decOffset = true; } lcd.print(key); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if(!decOffset) { num = num * 10 + (key - '0'); lcd.print(key); } else if((decOffset) && (counter <= 1)) { num = num * 10 + (key - '0'); lcd.print(key); counter++; } break; case 'D': software_Reset(); break; } decnum = num / pow(10, counter); key = kpd.getKey(); } return decnum; } float GetDivisions() { float num = 0.00; char key = kpd.getKey(); lcd.clear(); lcd.setCursor(0,0);lcd.print("Enter Divisions then");lcd.setCursor(0,1);lcd.print(" press [#]."); lcd.setCursor(0,30);lcd.print("Reset [D]"); lcd.setCursor(8,2); 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': software_Reset(); break; } key = kpd.getKey(); // num = 360/num; } return num; } int GetMode() { int mode = 0; lcd.setCursor(0,1);lcd.print("Select Op Mode"); lcd.setCursor(0,3); lcd.print(" DIV[A] DEG[B]"); while(mode == 0) { char key = kpd.getKey(); if(key == 'A') { mode = 1; } else if(key == 'B') { mode = 2; } } lcd.clear(); return mode; } void loop() { if(Mode == 1) { Divisions = GetDivisions(); Degrees = (360/Divisions); } if(Mode == 2) { Degrees = GetNumber(); } lcd.clear(); lcd.setCursor(0,3); lcd.print("FWD[A] REV[B] CAN[C]"); char key = kpd.getKey(); while(key != 'C') { lcd.setCursor(0,0);lcd.print("POS:");lcd.print(current);lcd.setCursor(0,1);lcd.print("DPM:");lcd.print(Degrees); key = kpd.getKey(); if(key == 'A') { if(current >= 360) { current = (current + Degrees)-360; } else { current = current + Degrees; } ToMove = Degrees*Multiplier; lcd.setCursor(0,2); lcd.print(" Moving "); rotation(ToMove,2); lcd.setCursor(0,2);lcd.print(" "); lcd.setCursor(4,0);lcd.print(" "); } if(key == 'B') { if(current <= 0) { current = 360+(current - Degrees); } else { current = current - Degrees; } ToMove = Degrees*Multiplier; lcd.setCursor(0,2); lcd.print(" Moving "); rotation(ToMove,0); lcd.setCursor(0,2);lcd.print(" "); lcd.setCursor(4,0);lcd.print(" "); } } lcd.clear(); }
Pretty slick. Does the Sherline rotary table have a home switch?
No. It would be easy to add one, though I don't have many digital inputs left on the Arduino.
Hello sloucks,
Is it possible to show more of your wiring diagram? kinda hard for noob like me to trace it all back. I seem to encounter an error on the LiquidCrystal_I2C, do you know where you get the library from? The current one don't seem to be in agreement with the sketch?
I received this message when verifying:
C:\Users\Documents\Arduino\libraries\LiquidCrystal _I2C/LiquidCrystal_I2C.h:80: error: conflicting return type specified for 'virtual void LiquidCrystal_I2C::write(uint8_t)'
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino/Print.h:48: error: overriding 'virtual size_t Print::write(uint8_t)'
Hopes someone can shine a light?
Many thanks
Here is the schematic for my stepper controller. I do not know what the error you are getting is. I got the LiquidCrystal_I2C library from HERE .
RotaryStepper Schematic.jpg
Hi, the script does not compile without error.
Hi,
I have made a copy of the script from the web site and during the compilation there were errors - for example:
error: missing terminating " character
.
.
sketch_jan12a:24: error: 'Keypad' does not name a type
sketch_jan12a:26: error: 'LiquidCrystal_I2C' does not name a type
sketch_jan12a.ino: In function 'void setup()':
.
.
sketch_jan12a:95: error: 'NO_KEY' was not declared in this scope
sketch_jan12a.ino: In function 'int GetDirection()':
sketch_jan12a:130: error: 'lcd' was not declared in this scope
sketch_jan12a.ino: In function 'void loop()':
.
.
sketch_jan12a:183: error: 'kpd' was not declared in this scope
I did not have the necessary libraries.
Therefore I have download a file Indexer.zip from another thread:
http://www.cnczone.com/forums/open-s...o-based-3.html
There were also libraries and this script is ok.
Could you please advise how to compile your script?
Thank you very much for your reply.
Best regards,
Eduard.
you have libraries missing. keypad,12c
<img src="https://ivxo1q-dm2305.files.1drv.com/y4mENMmTr_Cabc7pR0FUdB6gtbADq2JbuG4_rGy0eBQvLJx19pTi6TqMUIJN0xgOyDIc0gWoxYhS38HpbSTFGdfaK-o42IOU6jczrhDpfpCOTNGL1X6hvZCbgj0y35gqmq1YGTrWwShYGV-C7lXA2esy0Pi_WfnBSyroDLSGXwce4uSr1U7op7srdi78rispHCa_K4aFlTlJPVkkNWMfgh_Tg?width=60&height=60&cropmode=none" width="60" height="60" />
Being Disabled is OK CNC is For fuN
Hello Everyone. Dear Sloucks - You make great job - gratulations. I have Arduino Uno few days and I not feel comfortable in programming that stuff. But If Members give me a little helping hand - I hope will be fine .. Im thinking to use that Sloucks unit to steering many rotated screw with encoder on the top of screw on the bottom of the screw will be moving device. Move will be around 30 inch (measurement accuracy of 0.01 inch) to top and down .I must know real position for example 15 inch from bottom move to 29 inch after that move to 14 inch and move to 29 and move to 13 inch . The cycle (one inch deeper and top if work semi automatic(by one button ) will be awesome ...Its able to do by that stuff ? Regards Victor
I downloaded the Indexer Sketch and I am having trouble compiling it as I have been getting Java stack overload errors that , being new to Arduino, I am unfamiliar with.
The error that I get is: "at java.util.regex.Pattern$Branch.match(Pattern.java: 4604)"
try a older version of arduino
<img src="https://ivxo1q-dm2305.files.1drv.com/y4mENMmTr_Cabc7pR0FUdB6gtbADq2JbuG4_rGy0eBQvLJx19pTi6TqMUIJN0xgOyDIc0gWoxYhS38HpbSTFGdfaK-o42IOU6jczrhDpfpCOTNGL1X6hvZCbgj0y35gqmq1YGTrWwShYGV-C7lXA2esy0Pi_WfnBSyroDLSGXwce4uSr1U7op7srdi78rispHCa_K4aFlTlJPVkkNWMfgh_Tg?width=60&height=60&cropmode=none" width="60" height="60" />
Being Disabled is OK CNC is For fuN