I'm relatively new to the world of coding. I started out just cherry picking bits I wanted and tweaking minor things. I soon realised that there is a lot of info out there, which left me wallowing in information overload. Now I'm trying to work through the basics on a number of fronts.
Specifically I'm watching the Core Electronics Arduino Workshop on YouTube, reading through Arduino for Dummies and using the Sololearn app for structure practice.
So, enough about me. The problem I am currently having is this:
Rob at Little Wicket Railway has published two sketches parts of which I would like to combine (by the way, I have been in touch with Rob and he is happy for me to use/quote his sketches).
Specifically there is one script that drives turnouts with servos controlled from JMRI via CMRI
There is a second script that drives turnouts in slow motion using servos but activated by a pushbutton.
I have been attempting to get the slow motion action activated from JMRI. I naively thought it would just be a case of changing the input pin reference but that proved to be a bit optimistic.
I've been fiddling around for about a week now, so it's time to ask for help. If I wait until I've learnt enough I'll never get the railway built!
I have annotated the sketch with things I have tried (well, most of them. It took me a while to get into the habit of recording things as I did them).
Initially what I would like is some pointers on where I should concentrate my efforts and any specific guidance I should follow up. I'm definitely a person who learns by writing code rather than just reading other peoples work.
Here is the combined code as I have it at present. It compiles and uploads without issue but the servos persist in running at full speed.
// github.com/LittleWicketRailway/ServoControl/blob/master/Servos.ino
// github.com/LittleWicketRailway/SlowMoServos/blob/main/MillisFunctionImproved.ino
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
#include <CMRI.h>
#include <Auto485.h>
#define CMRI_ADDR 1
#define DE_PIN 2
#define numServos 4 //The number of servos connected
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(); //setup the board address 0
Auto485 bus(DE_PIN); // Arduino pin 2 -> MAX485 DE and RE pins
CMRI cmri(CMRI_ADDR, 24, 48, bus);
int Status[numServos]; //Create a table to hold the status of each turnout, signal, etc.
int Throw[numServos]; //Create a table to hold the throw value for each servo
int Close[numServos]; //Create a table to hold the close value for each servo
int CurrentPosition[4]; // added IR
int StepSize[4] = {50, 25, 15, 5}; // added IR - fourth value changed for servo (was LED) Note: Differnt values for each servos in these two lines just to see how they behave
int DelayTime[4] = {100, 150, 200, 300}; // added IR - fourth value changed for servo
unsigned long previousMillis[4]; // added IR
// for (int i = 0; i < numServos; i++) // should I replace for loops in setup and loop with a global for loop?
// int i; // tried making i global variable but this caused only servo 0 to operate
void moveServos(int inputPin, int connection) //function added, inputPin changed to DE_PIN, also added pinMode to setup. This did not change servo speed so changed back to inputPin IR
{
unsigned long currentMillis = millis();
if ((digitalRead(inputPin) != Status[connection]) && (currentMillis - previousMillis[connection] >= DelayTime[connection]))
{
previousMillis[connection] = currentMillis;
if (digitalRead(inputPin) == 1)
{
if (CurrentPosition[connection] < Close[connection]) // MaxValue changed to Close IR
{
CurrentPosition[connection] = CurrentPosition[connection] + StepSize[connection];
pwm.writeMicroseconds(connection, CurrentPosition[connection]);
}
else
{
Status[connection] = 1;
}
}
else
{
if (CurrentPosition[connection] > Throw[connection]) // MinValue changed to Throw IR
{
CurrentPosition[connection] = CurrentPosition[connection] - StepSize[connection];
pwm.writeMicroseconds(connection, CurrentPosition[connection]);
}
else
{
Status[connection] = 0;
}
}
}
}
void setup() {
Serial.begin(9600);
bus.begin(9600);
pwm.begin();
pwm.setPWMFreq(50); // This is the maximum PWM frequency
pinMode(2, INPUT); //Added to refer to CMRI input but did not work IR
// int i;
for (int i = 0; i < 5; i = i + 1) // added IR - changed i < 4 to i < 5. Tried taking this for loop out and declaring i separately (see line above) but it made no difference
{
CurrentPosition[i] = Throw[i]; // added IR - MinValue changed to Throw
}
//SET THE THROW AND CLOSE VALUES FOR EACH SERVO BASED ON THE CALIBRATION PROCESS
//Servo connection 0 - point motor
Throw[0] = 1000;
Close[0] = 1600;
//Servo connection 1 - point motor
Throw[1] = 1100;
Close[1] = 1675;
//Servo connection 2 - point motor
Throw[2] = 1200;
Close[2] = 1750;
//Servo connection 3 - point motor
Throw[3] = 1300;
Close[3] = 1800;
}
void loop() {
cmri.process();
moveServos[2, 0]; // added, inputPin ref changed to DE_PIN then 2 IR
moveServos[2, 1]; // added IR
moveServos[2, 2]; // added IR
moveServos[2, 3]; // added IR
for (int i = 0; i < numServos; i++) //duplication? IR taking this section out stops servos operating at all
{
Status[i] = (cmri.get_bit(i));
if (Status[i] == 1) {
pwm.writeMicroseconds(i, Throw[i]);
}
else {
pwm.writeMicroseconds(i, Close[i]);
}
}
}
type or paste code here
Thanks for reading this far. I'm off to do some more practice exercises.