//********************************************************** //********************************************************** //********************************************************** // Curtain Stepper Driver //********************************************************** //********************************************************** //********************************************************** // This program creates the control signal for a Stepper // Motor. The output is generalized for half, single, and // torque stepping modes. Delay (rotation speed), Rotation // Direction, Enable/Disable, are given by input pins // extrnally // // Coil outputs are fed to an H-Bridge for Biploar Motors or // to a ULN2803 (or ULN2003) Darlington Array chip, which // drive the coils directly // // This program was made to Controls the opening and // closing of a curtain, or a set of blinds. This is // accomplished by controlling a geared Stepper Motor. // The Stepper motor drives a nut along the length of // a threaded rod which is attached to the curtain // pull string or will drive the blind rod directly. // // Inputs- // Firmware Defined: // Rotation Speed => delay - Time between steps // Steps Taken => rotations - not individual steps, walks through entire array. // If 'rotations' == 12 the motor will complete 1 rotation // To rely wholly on Limit Switches set Rotations high // // Defined by Input Pins: // PD0 => (0x01): ccw - rotation direction // PD1 => (0x02): singlep - halfstep vs (single or torque) // PD2 => (0x04): torquep - single vs torque // PD3 => (0x08): Delay - low = 1ms; high = 500ms // PD4 => (0x10): Limit Switch #1 - indicates the end of clockwise movement // PD5 => (0x20): Limit Switch #2 - indicates the end of counter-clockwise movement // PD6 => (0x40): NewJob - Signal enables motor to turn defined ammount. // // Outputs- // Motor Turns to predefined position // // PB0 => (0x01): Coil 4 - // PB1 => (0x02): Coil 3 - // PB2 => (0x04): Coil 2 - // PB3 => (0x08): Coil 1 - // PB4 => (0x10): // PB5 => (0x20): // PB6 => (0x40): // PB7 => (0x80): // // //********************************************************** //********************************************************** //********************************************************** //********************************************************** // #Includes //********************************************************** #include // Defines pins, ports, etc to make programs easier to read #define F_CPU 20000000UL // Sets up the default speed for delay.h #include // Allows for delay to be used #include // Enables IO //#include // ??? Interrupts ??? //********************************************************** // #defines Pin Definitions //********************************************************** //#define B1 _BV(PB0) //********************************************************** // Function Prototypes //********************************************************** int SetDelay(int); //int halfstep(int, int, int); int singlestep(int, int, int); void WaitState(int); //int torquestep(int, int, int); //********************************************************** // Main Program //********************************************************** int main(){ // ***** Define IO ***** DDRB = 0xFF; //_BV(PB4); // enable output on port B, pin 4 DDRD = 0x00; // PortD is an INPORT PORTB = 0x00; // Set PortB = 0 // ***** Variable Declarations int ccw; // 1 = clockwise, 0 = ccw int steps = 7; // number to steps to walk through the array minus 1 int singlep; // To set half stepping leave low PD1, to set torque or single stepping set PD1 high int torquep; // To set single stepping leave PD2 low, to set torque stepping set PD2 high int delay = 1; // initial value for delay, can be changed int NewJob = 0; // Waits for a high, then turns once recieved int multiplier = 50; // 50 = 12 complete turns of the shaft = 1/2 inch int rotations = multiplier*12-1; // # of times to repeat step loop (12-1 times = 1 rotation) // // (x*12-1) = x rotations // ***** MAIN Loop ***** while(1) // Endless loop, same as "for(;;)" { // Read PD0 - Turn Clockwise or counter clockwise? //singlep = (PIND & 0x02); // Read PD1 - Do single stepping or half stepping (single = 1, half = 0) //torquep = (PIND & 0x04); // Read PD2 - Torque stepping or single stepping (torque = 1, single = 0 ) NewJob = (PIND & 0x40); // Read PD6 - New Job start turning delay = SetDelay(delay); if(NewJob == 0x40) // If PD6 == 1 begin turning { ccw = (PIND & 0x01); /*if(singlep != 0x02) // HALF STEPPING { halfstep(ccw, rotations, delay); // *** Function Call returns a "1" *** } else if((singlep == 0x02) && (torquep == 0x04)) // TORQUE STEPPING { torquestep(ccw, rotations, delay); // *** Function Call returns a "1" *** } else // (Singlep == 0x02) && (torquep == 0x00) // SINGLE STEPPING { */ for(int count = 0; count < 55; count++) // ********** To travel the entire Rod Test ********* { singlestep(ccw, rotations, delay); // *** Function Call returns a "1" *** } //} } PORTB = 0x00; // Turn off the current to the coils when finished } // End of While loop return(0); } //********************************************************** // Set the Delay //********************************************************** int SetDelay(int delay) { int determine; determine = (PIND & 0x08); // Read PD3 & PD4 - Delay pins if(determine == 0x00) // Pins read - (0,0) - (pd4,pd3) { delay = 100; } /*(else if(determine == 0x08) // Pins read - (0,1) - (pd4,pd3) { delay = 10; } else if(determine == 0x10) // Pins read - (1,0) - (pd4,pd3) { delay = 500; }*/ else // if (determine == 0x08) // Pins read - (1,1) - (pd4,pd3) { delay = 100; } return (delay); } //********************************************************** // Simulated WaitState //********************************************************** void WaitState(int delay) { for(int i = 0; i < delay ; i++) { for(int j = 0; j < delay ; j++) { for(int k = 0; k < delay ; k++) { } } } for(int i = 0; i < delay ; i++) { for(int j = 0; j < delay ; j++) { for(int k = 0; k < delay ; k++) { } } } for(int i = 0; i < delay ; i++) { for(int j = 0; j < delay ; j++) { for(int k = 0; k < delay ; k++) { } } } } //********************************************************** // Half Stepping //********************************************************** /* int halfstep(int ccw, int rotations, int delay) { const uint8_t clockwise[] = {0x08, 0x0c, 0x04, 0x06, 0x02, 0x03, 0x01, 0x09}; // Half stepping, set steps = 7 int steps = 7; // # of variables in the clockwise array int LS1 = 0; // Limit Switch PD5 == 0x0 int LS2 = 0; if (ccw == 0x01) // If PD0 == 1 turn clockwise { for(int x = 0; (x <= rotations); x++) // # of times to do step sequence { LS1 = (PIND & 0x10); // read the limit switch if(LS1 == 0x10) { return (1); } for(int i = steps; i >= 0; i-- ) // Turn Clockwise { PORTB = clockwise[i]; _delay_ms(delay); } } } else // If PD0 == 0 turn counterclockwise { for(int x = 0; (x <= rotations); x++) // # of times to do step sequence { LS2 = (PIND & 0x20); // read the limit switch if(LS2 == 0x20) { return (1); } for(int i = 0; i <= steps; i++ ) // Turn Counter-Clockwise { PORTB = clockwise[i]; _delay_ms(delay); } } } return (1); } */ //********************************************************** // Single Stepping //********************************************************** int singlestep(int ccw, int rotations, int delay) { const uint8_t single[] = {0x08, 0x04, 0x02, 0x01}; // Single stepping, set steps = 3 int steps = 3; // # of variables in the clockwise array int LS1 = 0; // Limit Switch PD5 == 0x0 int LS2 = 0; if (ccw == 0x01) // If PD0 == 1 turn clockwise { for(int x = 0; x <= rotations; x++) // # of times to do step sequence { LS1 = (PIND & 0x10); // read the limit switch PD5 if(LS1 == 0x10) { return (1); } for(int i = steps; i >= 0; i-- ) // Turn Clockwise { PORTB = single[i]; //WaitState(delay); for (int ii = 0; ii < 13; ii++) { _delay_us(delay); } } } } else // If PD0 == 0 turn counterclockwise { for(int x = 0; x <= rotations; x++) // # of times to do step sequence { LS2 = (PIND & 0x20); // read the limit switch PD5 if(LS2 == 0x20) { return (1); } for(int i = 0; i <= steps; i++ ) // Turn Counter-Clockwise { PORTB = single[i]; //WaitState(delay); for (int ii = 0; ii < 13; ii++) { _delay_us(delay); } } } } return (1); } //********************************************************** // Torque Stepping //********************************************************** /*int torquestep(int ccw, int rotations, int delay) { const uint8_t torque[] = {0x0c, 0x06, 0x03, 0x09}; // Torque stepping, set steps = 3 int steps = 3; // # of variables in the clockwise array int LS1 = 0; // Limit Switch PD5 == 0x0 int LS2 = 0; if (ccw == 0x01) // If PD0 == 1 turn clockwise { for(int x = 0; x <= rotations; x++) // # of times to do step sequence { LS1 = (PIND & 0x10); // read the limit switch PD5 if(LS1 == 0x10) { return (1); } for(int i = steps; i >= 0; i-- ) // Turn Clockwise { PORTB = torque[i]; _delay_ms(delay); } } } else // If PD0 == 0 turn counterclockwise { for(int x = 0; x <= rotations; x++) // # of times to do step sequence { LS2 = (PIND & 0x20); // read the limit switch PD5 if(LS2 == 0x20) { return (1); } for(int i = 0; i <= steps; i++ ) // Turn Counter-Clockwise { PORTB = torque[i]; _delay_ms(delay); } } } return (1); } */