/* * Code to control a loco, by ramping speed gradually to simulate a loco under load * By modifying this code you can control locos very easily including direction * * Written by BigAlNaAlba based on code from Ahmad Shamshiri * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . * */ const int MotorPinA = 12; //Motor A pin assignments const int MotorSpeedPinA = 3; const int MotorBrakePinA = 9; const int MotorPinB = 13; //Motor B pin assignments const int MotorSpeedPinB = 11; const int MotorBrakePinB = 8; const int GreenLEDpin = 10; // The LED simply illuminates when accelerating or at full speed const int CW = HIGH; //Clockwise Direction const int CCW = LOW; //Counter Clockwise Direction int targetSpeed = 15; //The desired speed, actually the number of PWM duty cycles in 1/255ths int currentSpeed = 0; //The speed right now int accelerationSeconds = 1; //The delay in seconds in changing speed bool speedUp = true; //Go faster, or now int dwellSeconds = 15; //The number of seconds to dwell when full speed is reached before slowing down int pauseSeconds = 10; //The number of seconds to stop when speed falls to zero int currentSeconds = 0; //The seconds counter // * Note: I used the word seconds here, but this really ought to be called TimeFrame instead, // because it may not be a full second or more than a full second const int showComments = 1;// show comments in serial monitor (used for debug) void setup() { // initialize digital pin LED_BUILTIN as an output. pinMode(LED_BUILTIN, OUTPUT); pinMode(GreenLEDpin, OUTPUT); // motor A pin assignment pinMode(MotorPinA, OUTPUT); pinMode(MotorSpeedPinA, OUTPUT); pinMode(MotorBrakePinA, OUTPUT); // motor B pin assignment pinMode(MotorPinB, OUTPUT); pinMode(MotorSpeedPinB, OUTPUT); pinMode(MotorBrakePinB, OUTPUT); } void loop() { //Apply Brake if current speed < 1 if (currentSpeed <1) { digitalWrite(LED_BUILTIN, HIGH); brake('A',1); } else { moveMotor('A', CCW, currentSpeed); digitalWrite(LED_BUILTIN, LOW); brake('A',0); } //Ramp speed up if (speedUp == true) { digitalWrite(GreenLEDpin, HIGH); if(currentSpeed < targetSpeed){currentSpeed ++;} if (currentSpeed >= targetSpeed)//At speed so start to count dwell seconds { if (currentSeconds <= dwellSeconds){currentSeconds++;} } if(currentSeconds >= dwellSeconds)//Start to slow down { speedUp = false; currentSeconds = 0; } } //Slow speed down if (speedUp == false) { digitalWrite(GreenLEDpin, LOW); if(currentSpeed > 0){currentSpeed --;} if (currentSpeed <= 0)//Stopped so start to count dwell seconds { if (currentSeconds <= pauseSeconds){currentSeconds++;} } if(currentSeconds >= pauseSeconds)//Start to speed up { speedUp = true; currentSeconds = 0; } } //Delay between changing speed delay(accelerationSeconds * 1000); }// loop end /* * * Written by Ahmad Shamshiri August 29 2018 at 20:59 in Ajax, Ontario, Canada * moveMotor controls the motor @param motor is char A or B refering to motor A or B. @param dir is motor direction, CW or CCW @speed is PWM value between 0 to 255 Example 1: to start moving motor A in CW direction with 135 PWM value moveMotor('A', CW, 135); Example 2: to start moving motor B in CCW direction with 200 PWM value moveMotor('B', CCW, 200); */ void moveMotor(char motor, int dir, int speed) { int motorPin; int motorSpeedPin; if(motor =='A') { motorPin = MotorPinA; motorSpeedPin = MotorSpeedPinA; }else{ motorPin = MotorPinB; motorSpeedPin = MotorSpeedPinB; } digitalWrite(motorPin, dir);// set direction for motor analogWrite(motorSpeedPin, speed);// set speed of motor }//moveMotor end /* * brake, stops the motor, or releases the brake * @param motor is character A or B * @param brk if 1 brake, if 0, release brake * example of usage: * brake('A', 1);// applies brake to motor A * brake('A', 0);// releases brake from motor A */ void brake(char motor, int brk) { if(motor =='A') { digitalWrite(MotorBrakePinA, brk);// brake delay(1000); }else{ digitalWrite(MotorBrakePinB, brk);// brake delay(1000); } }