Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //////////////////////////////////////////////////////////////////////////////
- // This Arduino example demonstrates bidirectional operation of a
- // 28BYJ-48, which is readily available on eBay, using a ULN2003
- // interface board to drive the stepper. The 28BYJ-48 motor is a 4-
- // phase, 8-beat motor, geared down by a factor of 64. One bipolar
- // winding is on motor pins 1 & 3 and the other on motor pins 2 & 4.
- // Refer to the manufacturer's documentation of Changzhou Fulling
- // Motor Co., Ltd., among others. The step angle is 5.625/64 and the
- // operating Frequency is 100pps. Current draw is 92mA.
- //////////////////////////////////////////////////////////////////////////////
- // Motor step angle = 5.625 degrees ==> 64 pulses per internal rev
- // Gear reduction = 1/64 ==> 4096 pulses per external rev
- //////////////////////////////////////////////////////////////////////////////
- // Motor pins: blue=1, pink=2, yellow=3, orange=4
- int motorPin[4] = {8, 9, 10, 11};
- // One counter-clockwise internal revolution going down the rows
- int ccw[8][4] =
- {
- {HIGH, LOW, LOW , LOW},
- {HIGH, HIGH, LOW , LOW},
- {LOW , HIGH, LOW , LOW},
- {LOW , HIGH, HIGH, LOW},
- {LOW , LOW, HIGH, LOW},
- {LOW , LOW, HIGH, HIGH},
- {LOW , LOW, LOW, HIGH},
- {HIGH, LOW, LOW, HIGH}
- };
- // Global variables used by the stepper algorithm
- long ip, np, npMin;
- double phi0, t, t0, dtpp;
- //////////////////////////////////////////////////////////////////////////////
- void setup() {
- // Basic constants
- double pi = 4*atan(1.0); // Pi = 3.1415927
- double inch2cm = 2.54; // One inch is 2.54 cm
- double secSidDay = 86164.1; // Seconds in a siderial year
- double eRot = 2*pi/secSidDay; // Earth's rotation in radians per sec
- // Motor characteristics
- int ppir = 64; // Pulses per internal rev (360/5.625)
- int ppr = 64*ppir; // Pulses per revolution (gear reduction factor = 64)
- // Barndoor geometry - initialized in setup
- double tpi; // Threads per inch of the screw
- double beam; // Hinge to T-nut/cap nut in cm
- double y0; // Initial vertical T-nut position in cm
- double y1; // Final vertical T-nut position in cm
- tpi = 20;
- beam = 19.6;
- y0 = 3.0;
- y1 = 1.0;
- double cmpr = inch2cm/tpi; // cm per revolution (1 thread of the screw)
- double phipr = cmpr/beam; // Angle (phi) difference per revolution (in radians)
- double dtpr = phipr/eRot; // The time it takes the sky to rotate that much
- dtpp = dtpr/ppr; // Pulse time in sec, nominal value = 6471.8 mu
- phi0 = y0/beam; // Initial angle between the beams (approximate)
- np = (y0/inch2cm)*tpi*ppr; // Number of pulses needed from y0 down to 0
- npMin = (y1/inch2cm)*tpi*ppr; // Turn off at the last y1 cm
- ip = 0; // Pulse counter
- // Declare the motor pins as outputs
- for (int j = 0; j < 4; j++)
- pinMode(motorPin[j], OUTPUT);
- analogReference(DEFAULT);
- t = micros(); // Time in microseconds. Note, the math above is in seconds.
- t0 = t;
- ip = 0;
- } //void setup end
- //////////////////////////////////////////////////////////////////////////////
- void loop(){
- // We don't need this outer loop, let's write our own for better control
- // so this only gets called once
- while (ip + npMin <= np) {
- int ic = ip % 8; // Internal cycle index
- double dt, dt1;
- // Determine dt
- dt = dtpp;
- // Compensate for the fact that we are using a straight screw
- double fac = cos((phi0*(np - ip))/(2*np));
- dt = dt/fac;
- // Step the motor
- for (int j = 0; j < 4; j++) {
- digitalWrite(motorPin[3-j], ccw[ic][j]);
- }
- // Update the timeline
- t = t + 1000000*dt;
- // Delay to regulate the speed.
- // delayMicroseconds() is accurate up to a few milliseonds so delay
- // in 1 ms chunks. Note also that micros() cycles in 70 minutes.
- while (t > micros() + 1000)
- delayMicroseconds(1000);
- dt1 = t - micros();
- if (dt1 > 0)
- delayMicroseconds(dt1);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement