I am using a Arduino to run my boys train set.
Im having trouble figuring out how to change the trains direction using 1 button only on the controller to scroll through 4 Void *** commands.
1 TrainStop,
2 Clockwise,
3 TrainStop,
4 AntiClockwise, then back to TrainStop again,. there are 2 train stops so the train doesn't destroy itself if its still moving when selecting clock and anticlock
I have had a look through google and im struggling to find the right function to do this, I think button count would be the best way? count up to 4 then the 5th press goes back to
If you have a suggestion on the code type that would be great, im happy to search google to find code that i can adapt to suit though i have struggled so far. (that how most of this was written)
Info on the trainset up.
I have made a controller with a potentiometer to control the trains speed. The controller also has 2 buttons which go to 1 analog pin. both buttons have different resistances allowing the buttonstate to be a output of 1 or 2 depending on which button is pressed.
The code i have so far allows the train to travel in 1 pre-written direction with variable speed.
Many thanks
const int sensorA = 2; //sensor A on trainset
const int IN1=9; // train motor pin 1
const int IN2=10; // train motor pin 2
const int ENA=6; // train speed PWM
const int LAmber=3; // left amber light on controller
const int RAmber=4; // right amber light on controller
const int RedLight=5; // red light on controller
const int SpeedDial=A1; // manual speed potentiometer on controller
const int CButton=A0; // multiple button on controller
const int CBUTTON1 = 1; //right button on controller using A0 pin
const int CBUTTON2 = 2; //left button on controller
//controller button value
const int CBUTTON1LOW = 1000;
const int CBUTTON1HIGH = 1024;
const int CBUTTON2LOW = 850;
const int CBUTTON2HIGH = 970;
// Variables will change:
int speedSensorValue = 0; // speed dial controller input value
int trainSpeed = 0;
int ledState = LOW; // ledState used to set the LEDs on the controller
int buttonState; // the current reading from the input A0 controller pin
int lastButtonState = LOW; // the previous reading from the input A0 controller pin
//Millis setup
unsigned long previousMillis = 0; // will store last time LED on controller was updated
const long interval = 1000; // interval at which to blink (milliseconds)
long lastDebounceTime = 0; // the last time the output controller pin was toggled
long debounceDelay = 50; // the debounce time; increase if the output flickers( for controller)
// speed settings
int trainSpeedMax = 180; // max speed of train
int trainStallSpeed = 55; // slowest speed of train before stalling
int trainStop = trainStop; // train stop, no value
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
// make the pushbutton's pin an input:
pinMode(IN1,OUTPUT); //motor pin 1
pinMode(IN2,OUTPUT); //motor pin 2
pinMode(CButton, INPUT_PULLUP); // sets analog pin for input on controller
}
// train direction here and light LED on controller
void AntiClockwise(){
digitalWrite(IN1,HIGH); // Backwards / anticlockwise
digitalWrite(IN2,LOW);
pinMode(RAmber,OUTPUT); //Flashes LED to show direction of train
}
// train direction here and light LED on controller
void Clockwise(){
digitalWrite(IN1,LOW); // forward / clockwise
digitalWrite(IN2,HIGH);
pinMode(LAmber,OUTPUT); //Flashes LED to show direction of train
}
// train direction here and light LED on controller
void StopDead(){
digitalWrite(IN1,LOW); // turns off motor controller
digitalWrite(IN2,LOW);
pinMode(RedLight,OUTPUT); // Lights LED to show the motor is off
}
// fade to start the train moving - something that im looking to but haven't got it to work as i want it yet
void trainFadeStart (){ //name of function to fade the train to start
for (int fadeValue = trainStallSpeed ; fadeValue <= trainSpeed; fadeValue += 1) { //fade function to speed up the train from its lowest speed to trainSpeed
analogWrite(ENA, fadeValue); //make the train fade up to the trainspeed value listed in settings
delay(30);}{ // wait for 30 milliseconds
analogWrite(ENA,trainSpeed); //once fade is complete, delay then run at trainspeed value
}
}
// fade to stop the train moving - something that im looking to but haven't got it to work as i want it yet
void trainFadeStop(){ //name of function to fade the train to a stop
for (int fadeValue = trainSpeed ; fadeValue >= trainStallSpeed; fadeValue -= 1) { //fade function to slow down the train from trainSpeed to slowest
analogWrite(ENA,fadeValue);//make the train fade down to the trainStallSpeed value listed in settings
delay(30);
analogWrite(ENA,trainStop); //once fade is complete, delay then run at trainStop value
}
}
void loop() {
// button selection on the controller
// read the state of the switch into a local variable:
int reading = analogRead(CButton);
int tmpButtonState = LOW; // the current reading from the input pin
if(reading>CBUTTON2LOW && reading<CBUTTON2HIGH){
//Read switch 2
tmpButtonState = CBUTTON2;
}else if(reading>CBUTTON1LOW && reading<CBUTTON1HIGH){
//Read switch 1
tmpButtonState = CBUTTON1;
}else{
//No button is pressed;
tmpButtonState = LOW;
}
// check to see if you just pressed the button
// (i.e. the input went from LOW to a buttonState)
// If the switch changed, due to noise or pressing:
if (tmpButtonState != lastButtonState) {
// reset the debouncing timer
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer
// than the debounce delay, so take it as the actual current state:
buttonState = tmpButtonState;
Serial.println(buttonState);
}
// save the reading. Next time through the loop,
// it'll be the lastButtonState:
lastButtonState = tmpButtonState;
// don't know if i can use this, would need it to run VOID AntiClockwise and continue to run
// switch(buttonState){
// case CBUTTON1:
// digitalWrite(ledPin, buttonState>0);
// break;
// case CBUTTON2:
// digitalWrite(ledPin, buttonState>0);
// break;
// check to see if it's time to blink the LED; that is, if the difference between the current time and last time you blinked the LED is bigger than the interval at which you want to blink the LED.
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
if (ledState == LOW) {
ledState = HIGH;
} else {
ledState = LOW;
}
// set the LED with the ledState of the variable:
digitalWrite(LAmber, ledState);
digitalWrite(RAmber, ledState);
digitalWrite(RedLight, ledState);
}
// read the analog A0 on controller and output to variable trainSpeed
speedSensorValue = analogRead(SpeedDial);
// map it to the range of the analog out:
trainSpeed = map(speedSensorValue, 0, 1023, trainStop, trainSpeedMax); //trainstop/trainspeedmax are preset at the top of the code
//just so the train will travel round the track
AntiClockwise(); //direction around track
analogWrite(ENA,trainSpeed); //runs the variable speed of the train
}