Used with the proper hardware (built using Meccano parts, motors and electronics) , enable the user to make its own gears out of solid brass . Just copy and paste the text into the Arduino editor and compile it.
Download as TXT, PDF, TXT or read online on Scribd
100%(1)100% found this document useful (1 vote)
1K views
Gear Cutting Machine Code For Arduino
Used with the proper hardware (built using Meccano parts, motors and electronics) , enable the user to make its own gears out of solid brass . Just copy and paste the text into the Arduino editor and compile it.
//// Drives a stepper motor used for a dividing head //// //// Also controls the linear carriage movement //// //// Copyright 2005,2014 A, Theberge //// //// //// //// //// //// UP - DOWN pushbuttons choose the gear size //// //// SELECT start the gear cutting process //// //// LEFT is the emergency stop //// //// RIGHT moves the carrige backwards //// //// //// //// Stepper is connected on pins D4 - D7 //// //// Geared motor is connected to D2, D3 and D9 //// //// Linear_motion_switch (input) is pin D8 //// //// //// //// October 6th 2005: Microchip PIC version by Andre Theberge //// //// Ported to Arduino on Sept 9th, 2014 by Andre Theberge //// //// //// /////////////////////////////////////////////////////////////////////////// // include the Adafruit library code: #include <Wire.h> #include <Adafruit_MCP23017.h> #include <Adafruit_RGBLCDShield.h> Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield(); // These #define sets the backlight color #define WHITE 0x7 //--------------Functions and variables declared here----------------- long divider, tooth, n_steps, m_steps; int stepper_delay, i, j, buttons; boolean stopped_by_user; long const reduction_multiplier = 95L * 400L; // 95 teeth meccano gear * 400 steps per revolution // %%% Adjust the # of steps depending on the motor chosen %%% #define Geared_Motor_A 2 // Outputs, geared motor #define Geared_Motor_B 3 #define Linear_motion_top_switch 8 // Input, limit switch to change motor dire ction #define Linear_motion_bottom_switch 9 // Input, limit switch to change motor d irection byte const POSITIONS[4] = {B01010000, // Phases for stepper motor B10010000, B10100000, B01100000}; #define Stepper_Motor_EnableA 10 #define Stepper_Motor_EnableB 11 // Controls stepper motor, sends a series of pulses at a given speed void drive_stepper(int stepper_delay, char dir, long steps) { static int stepper_state = 0; long i;
digitalWrite(Stepper_Motor_EnableA, HIGH); // Enable L293 chip (drivers are ON) digitalWrite(Stepper_Motor_EnableB, HIGH); for(i=0; i<steps; ++i) { delay(stepper_delay); DDRD = DDRD | B11110000; //Digital pins 4-7 are connected to stepper motor PORTD = (PORTD & B00001111) | (POSITIONS[ stepper_state ] & B11110000); // Write data without altering other pins if(dir!='F') stepper_state=(stepper_state+1)&(sizeof(POSITIONS)-1); else stepper_state=(stepper_state-1)&(sizeof(POSITIONS)-1); } analogWrite(Stepper_Motor_EnableA, 127); // USE PWM to reduce the current b y half on the steppers when done analogWrite(Stepper_Motor_EnableB, 127); // } // Remove any voltage on stepper motor coils void release_stepper(void) { DDRD = DDRD | B11110000; //Digital pins 4-7 are connected to stepper motor PORTD = (PORTD & B00001111) ; // Put all the stepper pins to 0 digitalWrite(Stepper_Motor_EnableA, LOW); // Disable L293 chip (drivers O FF) digitalWrite(Stepper_Motor_EnableB, LOW); } // Move carriage backwards until bottom limit switch is hit, then forward to it s original position. void carriage_Back_and_forth() {
// Move carriage backwards (cutting phase) digitalWrite(Geared_Motor_A, LOW); digitalWrite(Geared_Motor_B, HIGH); for (i=0; i<5000; i++) { // Timed delay until we reached the bottom switch %%% Adjust this delay if necessary %%% buttons = lcd.readButtons(); // Monitor pushbuttons if (buttons & BUTTON_LEFT) break; // Exit if LEFT pushbutton pressed (em ergency exit) if (digitalRead(Linear_motion_bottom_switch)==LOW) break; // Exit also if we hit limit switch (normal operation) } if (buttons & BUTTON_LEFT) { stop_motor_and_alert_user(); goto EMERGENCY_EXIT; // Exit if LEFT pushbutton pressed (emergency exit) } digitalWrite(Geared_Motor_A, LOW); // Stop motor for a bit before changing direction digitalWrite(Geared_Motor_B, LOW); delay(200); // Pause a bit
// Move carriage forward digitalWrite(Geared_Motor_A, HIGH); digitalWrite(Geared_Motor_B, LOW); for (i=0; i<5000; i++) { // Restart the motor in the opposite direction with a delay %%% Adjust this delay if necessary %%% buttons = lcd.readButtons(); // Monitor pushbuttons if (buttons & BUTTON_LEFT) break; // Exit if LEFT pushbutton pressed (em ergency exit) if (digitalRead(Linear_motion_top_switch)==LOW) break; // Exit also if we hit limit switch (normal operation) } if (buttons & BUTTON_LEFT) { stop_motor_and_alert_user(); goto EMERGENCY_EXIT; // Exit if LEFT pushbutton pressed (emergency exit) } digitalWrite(Geared_Motor_A, LOW); // Geared motor off digitalWrite(Geared_Motor_B, LOW);
EMERGENCY_EXIT: delay(100); // Wait for motors to completely stop } void stop_motor_and_alert_user() { // Stop motor digitalWrite(Geared_Motor_A, LOW); // Geared motor off digitalWrite(Geared_Motor_B, LOW); // Tell user and set flag lcd.setCursor(0,1); lcd.print("STOPPED by user "); // Update display stopped_by_user = true; } void print_gear_size() { lcd.setCursor(0,0); lcd.print("Gear size = "); // Update display lcd.print(divider); lcd.print("t "); // Pad extra spaces delay(100); // A bit of delay if the button is held down } //--------------------Setup routine--------------------------- void setup() {
// %%% Serial link used for debugging output only %%% Serial.begin(9600);
// set up the LCD's number of columns and rows: lcd.begin(16, 2); lcd.setBacklight(WHITE);
pinMode(Geared_Motor_A, OUTPUT); // Geared motor pinMode(Geared_Motor_B, OUTPUT); digitalWrite(Geared_Motor_A, LOW); // Geared motor off digitalWrite(Geared_Motor_B, LOW); pinMode(Linear_motion_top_switch, INPUT_PULLUP); // Set pull-up on switches (active low) pinMode(Linear_motion_bottom_switch, INPUT_PULLUP); pinMode(Stepper_Motor_EnableA, OUTPUT); // Stepper motor pinMode(Stepper_Motor_EnableB, OUTPUT); release_stepper(); // Stepper motor off lcd.setCursor(0, 0); // Print initialisation message on the LCD screen lcd.print(" Gear Cutter"); lcd.setCursor(0, 1); lcd.print("(c) A. Theberge"); delay(1000); // Delay so so user can read message lcd.clear(); print_gear_size(); // Print default gear size } //--------------------Loop routine--------------------------- void loop() { buttons = lcd.readButtons(); // Read pushbuttons if (buttons) { // If one pressed....
if (buttons & BUTTON_DOWN) { // Set gear size if (divider > 12) divider = divider -1; // Allow divider values as low as 12 print_gear_size(); // Update display } if (buttons & BUTTON_UP) { // Set gear size if (divider < 76) divider = divider +1; // Allow divider values as high as 76 print_gear_size(); // Update display } if (buttons & BUTTON_RIGHT) { // Move carriage forward if (digitalRead(Linear_motion_top_switch)==HIGH) { // If not at the top o f its course digitalWrite(Geared_Motor_A, HIGH); // Move the carriage by increm ents of 1/10th of a second digitalWrite(Geared_Motor_B, LOW); delay(100); // digitalWrite(Geared_Motor_A, LOW); } else { lcd.setCursor(0,1); lcd.print("Reached the top "); // Update display } }
if (buttons & BUTTON_SELECT) { // Perform the automated cutting process lcd.setCursor(0,1); lcd.print("Cut Gear Teeth "); // Update display delay(1500); // 1.5 second delay before process start )s o user can read previous message) stepper_delay=3; // Maximum rotation speed
stopped_by_user = false; // Set 'true' if user press LEFT button duri ng cutting process.
for(j=tooth; j<divider; j++) { // FOR loop to cut all the teeth lcd.setCursor(0,1); lcd.print("Cutting # "); // Which tooth we are durrently cutting lcd.print(tooth+1); lcd.print(" "); // Extra spaces to fill complete line // Do a back and from motion of the carriage carriage_Back_and_forth(); if (stopped_by_user) break; // In case of emergency stop, exit loop // Now turn dividing head to cut next tooth tooth=tooth+1; lcd.setCursor(0,1); if (tooth < divider) { lcd.print("Set-up for # "); // Which tooth we are currently cutting lcd.print(tooth+1); lcd.print(" "); // Extra spaces to fill complete line } else { lcd.print("Return to origin "); // Only after the last cut } m_steps=((tooth-1)*reduction_multiplier)/divider; // Serial.println(m_steps); // %%% For debug purpose only n_steps=((tooth*reduction_multiplier)/divider) - m_steps; // Serial.println(n_steps); // %%% For debug purpose only drive_stepper(stepper_delay,'F',n_steps); //rotate the shaft the width of a tooth if (tooth>=divider) tooth=0; // go a maximum of "divider" } // of FOR
release_stepper(); if (!stopped_by_user) { lcd.setCursor(0,1); lcd.print("Job complete "); // Only after the last cut } } // of IF statement; Enter button is pressed } // of any button pressed } // of loop()