Está en la página 1de 5

///////////////////////////////////////////////////////////////////////////

//// Gear_Cutting_Machine.ino ////


//// 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);

tooth=0; // Initialise variables
divider=19;
stopped_by_user = false;

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()

También podría gustarte