michael080

Western Thunderer
Simon,
great start.

I would like to add that a beginner shouldn't try too much simultaneously.

All these microcontrollers need to be handled through the IDE, the Integrated Development Environment. You may want to start to install the Arduino IDE, connect an arduino and try to download a VERY SIMPLE (and probable useless) program like a blinking LED or the like. Use one of the countless examples that can be found. Try to separate handling the IDE and programming. If you jump into programming without understanding the IDE, you will have trouble isolating the problem.

happy testing,
Michael
 

simond

Western Thunderer
Thanks Michael,

Fully agree, buy one, download the IDE, and make BLINK work!

It’s a great start.

Then, connect a 1K resistor and a LED between GND and almost any pin, and make it flash. It’s very satisfying.

Then change your program so the built-in LED and the other LED flash alternately.

Probably an evening’s entertainment!

Atb
Simon
 

TimberSurf

Active Member
Count me in for the ride, I have done a few circuits and sketches and have big plans for Arduino use on my layout, animation, lighting and point motors, but other things in life have got in the way. I will pick up the gauntlet at some time in the future as the potential they have is awesome.
Here is a demo of a sketch I wrote for a level crossing, as yet not conjoined with the built model!
The tip I have recently gleaned is that there are much better (read forgiving and intuitive) third party sketch programs out there! Not proven yet, but I can only imagine there MUST be a better alternative to Arduino's IDE!
 

TimberSurf

Active Member
A very useful explanation can be had from the very beginnings, through Rudy's Arduino, detailed on his

Fun With Arduino 01 Getting Started in 6 Easy Steps website

and through video on Youtube

Rudysmodelrailway.

Well worth watching from lesson 1, for beginners and useful too for advanced features, once you are familiar with the rudiments (excuse the pun {intended}). Not sure when it will finish, but he is still adding episodes (currently up to episode 32)
 

simond

Western Thunderer
Ok, after a brief hiatus whilst I visited mum, and then home to celebrate our wedding anniversary, I'm back on the case.

probably easiest to put the sketch of Paul's traversers on here, and try to explain what I did and why. Hopefully that will give a flavour of the gentle art of programming...

The sketch is attached for anyone that wants to use it. You'll also need a wiring diagram, which looks like this;

upload_2019-6-4_18-9-12.png

And this is what the sketch looks like. I'm going to put some comments in a following post;


/*
28may19 - added detection of "wrong way" stepper wiring - if the carriage goes "up" instead of down when the program starts,
it will automatically inverts the constant "dir".


22 may 19 program to operate stepper leadscrew using A4988 driver
using an Arduino Nano

ELECTRICAL CONNECTIONS

Input pin A0 up limit switch wire colour
Input pin A1 down limit switch wire colour
Input pin A2 Down control wire colour
Input pin A3 Up control wire colour
Input pin A4 - A7 not used

Output pin 2 direction on vero
Output pin 3 step on vero
Output pin 4 Sleep on vero
Output pin 5 Reset on vero
Output pin 6 MS 3 Microstep on vero
Output pin 7 MS 2 on vero
Output pin 8 MS 1 on vero
Output pin 9 Disable on vero
Output pin 11 green led wire colour
Output pin 10 red led wire colour

SPEED

Stepper motor is normally 200 steps/turn and leadscrew is 5mm pitch
thus travel per full step is 5/200 = 0.025mm

Per Paul's post, traverser speed is 10 feet per minute
10 ft/min real = 70mm/min scale
70 mm/min = 14 revs/min with 5mm pitch
14 rpm = 2800 steps / min (single steps) = 46.67/second
stepdelay = 1/47/2 = 0.010714 seconds at full speed
needed to use 1/16 steps to get the speed down.

POSITIONS

Up, operating "up" limit switch
Down, ditto, down switch
Assumed travel = 85mm
Hence steps for full travel = 85/0.025 * 16 = 54400 - "totalsteps" -
This adjusts itself in the InitEndPos function

End of preamble =================================================================================
*/

int initialise = 0; // marker for position not found
int microsteps = 16; // can be 1 2 4 8 or 16 - use 16 for slow speed

bool setdir = LOW; // direction variable. LOW or HIGH. If it goes the wrong way, reverse this. It should go down (left, near) when turned on
bool dir = setdir; // temporary direction variable. LOW or HIGH.
bool pos = LOW; // position variable. LOW or HIGH. LOW = left, near, etc.

int startspeed = 30; // speed in mm/min
int fullspeed = 70; // speed in mm/min (avoiding decimals from m/sec)
int stepsturn = 200; // 200 steps per rev
int pitch = 5; // pitch of leadscrew
int totaltravel = 85; // mm

long totalsteps = 54400; //totaltravel * stepsturn * microsteps / pitch; // steps for full travel 54400 as a guess

int fullstepdelay = 600; // (30000000 * pitch * microsteps/ stepsturn / fullspeed); // microseconds
int startstepdelay = 3500; // (30000000 * pitch * microsteps/ stepsturn / startspeed); // microseconds
int stepdelay = 600; // this is used in the initialisation and then changes during cycle

int accelsteps = startstepdelay - fullstepdelay; // about 2900
int stepincrement = 1; // ((startstepdelay - fullstepdelay ) / accelsteps);


// End of Declaration ================================================================================


void setup() { //

Serial.begin (115200);

pinMode(A0, INPUT_PULLUP); // up limit switch
pinMode(A1, INPUT_PULLUP); // down limit switch

pinMode(A2, INPUT_PULLUP); // down control switch
pinMode(A3, INPUT_PULLUP); // up control switch

pinMode(2, OUTPUT); // Direction
pinMode(3, OUTPUT); // Step
pinMode(4, OUTPUT); // Sleep
pinMode(5, OUTPUT); // Reset
pinMode(6, OUTPUT); // Microstep 3
pinMode(7, OUTPUT); // Microstep 2
pinMode(8, OUTPUT); // Microstep 1
pinMode(9, OUTPUT); // Disable
pinMode(10, OUTPUT); // red led
pinMode(11, OUTPUT); // green led

digitalWrite(4, HIGH);
digitalWrite(5, HIGH);
digitalWrite(9, LOW); // hold sleep reset & disable off

if (microsteps == 2) { // half microstepping
digitalWrite (8, HIGH);
digitalWrite (7, LOW);
digitalWrite (6, LOW);
}
else if (microsteps == 4) { // quarter
digitalWrite (8, LOW);
digitalWrite (7, HIGH);
digitalWrite (6, LOW);
}
else if (microsteps == 8) { // eighth
digitalWrite (8, HIGH);
digitalWrite (7, HIGH);
digitalWrite (6, LOW);
}
else if (microsteps == 16) { // sixteenth
digitalWrite (8, HIGH);
digitalWrite (7, HIGH);
digitalWrite (6, HIGH);
}
else {
microsteps = 1;
digitalWrite (8, LOW);
digitalWrite (7, LOW);
digitalWrite (6, LOW);
}

Serial.println ("setup completed");
Serial.print ("microsteps = ");
Serial.println (microsteps);
Serial.print ("stepdelay = ");
Serial.println (stepdelay);

Serial.print ("totalsteps = ");
Serial.println (totalsteps);

Serial.print ("accelsteps = ");
Serial.println (accelsteps);

Serial.print ("fullstepdelay ");
Serial.println (fullstepdelay);

Serial.print ("startstepdelay ");
Serial.println (startstepdelay);

Serial.print ("stepincrement ");
Serial.println (stepincrement);


// confirmation on screen

}
// End of Setup =======================================================================================



void loop() { // this is the main body of the program and will run until the power is turned off

// checkconnections(); // remove first pair of // to test button connections. Ensure "serial monitor" is on
// runstepper (); // remove first pair of // to test motor connections



if (initialise == 0) { // Hoist position not known.
InitEndPos();
}


if (digitalRead(A2) == LOW) { // DOWN control switch pressed
// need to add de-bounce here
if (pos == HIGH) {
GoDown(totalsteps);
}
}

if (digitalRead(A3) == LOW) { // UP control switch pressed
// need to add de-bounce here
if (pos == LOW) {
GoUp(totalsteps);
}
}

} // end of main loop =============================================================================


void GoDown(long gosteps) { // function to go to down position

digitalWrite(10, HIGH); // Turn on RED led
digitalWrite(11, LOW); // Turn off GREEN led
digitalWrite(2, dir); // go down

long stp = 0;
stepdelay = startstepdelay;
Serial.print ("stepdelay = ");
Serial.println (stepdelay );
while (stp < gosteps) {
if (stp < accelsteps) {
stepdelay = stepdelay - stepincrement;
}
if (stp > (gosteps - accelsteps)) {
stepdelay = stepdelay + stepincrement;
}
digitalWrite(3, HIGH);
delayMicroseconds (2);
digitalWrite(3, LOW);
delayMicroseconds (stepdelay);
// Serial.println (stepdelay);
stp ++;

}
digitalWrite(11, HIGH); // Turn on GREEN led
digitalWrite(10, LOW); // Turn off RED led
pos = LOW;
Serial.println ("DOWN, LEFT, NEAR");

}


// End of GoDown Function ================================================================================


void GoUp(long gosteps) { // function to go to up position - it's the same as the GoDown with the "!" in front of "dir",
// and modified comments.

digitalWrite(10, HIGH); // Turn on RED led
digitalWrite(11, LOW); // Turn off GREEN led
digitalWrite(2, !dir); // go up

long stp = 0;
stepdelay = startstepdelay;

while (stp < gosteps) {
if (stp < accelsteps) {
stepdelay = stepdelay - stepincrement;
}
if (stp > (gosteps - accelsteps)) {
stepdelay = stepdelay + stepincrement;
}
digitalWrite(3, HIGH);
delayMicroseconds (2);
digitalWrite(3, LOW);
delayMicroseconds (stepdelay);
// Serial.println (stepdelay);
stp ++;
}
digitalWrite(11, HIGH); // Turn on GREEN led
digitalWrite(10, LOW); // Turn off RED led

pos = HIGH;
Serial.println ("UP, RIGHT, FAR");

} // End of GoUp Function ================================================================================


void InitEndPos() { // function to initialise Down & Up positions & steps to travel ==========================================

// table will drive one way until it hits a switch.
// ideally down/near/left every time it is turned on, but in case it goes up, it will stop and reverse slowly til it hits the down switch.
// once it has found the down limit switch, it will then go quickly most of the way to the other extreme, slowly til it hits the switch and stop there.
// it then "knows" where the end stops are, sets the "initialise" variable to HIGH and goes into the main loop

while (digitalRead(A1) == HIGH) { // down limit switch not pressed
InitDown (1); // find down position and stop - this is slow because it may be "anywhere"
if (digitalRead(A0) == LOW) { // up limit switch has been pressed before the down switch - ie carriage went up, not down
Serial.println ("wrong way - inverting dir ");
Serial.print ("dir =");
Serial.println (dir);
InitUp (50); // back off from the switch - so up is down and vice versa...
dir = !dir; // inverts dir
Serial.print ("dir =");
Serial.println (dir);
delay (1000); // wait, then start again
}
}
totalsteps = 0; // assign zero point
Serial.println ("detected limit switch - down position");

InitUp (50000); // swift travel most of the way to the up/right/far position
totalsteps = 50000;
while (digitalRead(A0) == HIGH) { // up limit switch not pressed
GoUp (1); // find up position and stop
totalsteps = totalsteps + 1; // count the steps!
Serial.print ("totalsteps = ");
Serial.println (totalsteps); // this is about 200 steps x 16 microsteps x 17 turns = 54400
}

initialise = 1; // clear uninitialised flag
Serial.println ("detected limit switch - up position");
Serial.print ("totalsteps = ");
Serial.println (totalsteps);
Serial.print ("accelsteps = ");
Serial.println (accelsteps);

Serial.print ("stepincrement = ");
Serial.println (stepincrement);
pos = HIGH;
Serial.println ("UP, RIGHT, FAR");

} // end of InitEndPos ===============================================================================


void InitDown(long gosteps) { // function to go to down position without acceleration or deceleration =========================

digitalWrite(10, HIGH); // Turn on RED led
digitalWrite(11, LOW); // Turn off GREEN led
digitalWrite(2, dir); // go down

int stp = 0;

while (stp < gosteps) {
digitalWrite(3, HIGH);
delayMicroseconds (2);
digitalWrite(3, LOW);
delayMicroseconds (stepdelay);

stp ++;

}
digitalWrite(11, HIGH); // Turn on GREEN led
digitalWrite(10, LOW); // Turn off RED led
pos = LOW;

}

void InitUp(long gosteps) { // function to go to up position without acceleration or deceleration ================================

digitalWrite(10, HIGH); // Turn on RED led
digitalWrite(11, LOW); // Turn off GREEN led
digitalWrite(2, !dir); // go up

long stp = 0;


while (stp < gosteps) {

digitalWrite(3, HIGH);
delayMicroseconds (2);
digitalWrite(3, LOW);
delayMicroseconds (stepdelay);

stp ++;
}
digitalWrite(11, HIGH); // Turn on GREEN led
digitalWrite(10, LOW); // Turn off RED led
pos = HIGH;

} // =================================================================================================


void checkconnections () { // simple function to check the buttons are connected correctly.
// Only runs if you remove the "//" in the Loop
// Don't forget to put the "//" back again!

for (int n = 0; n < 2000; n++) {

bool j = digitalRead (A3);
Serial.print ("pin A3 =");
Serial.println (j);
j = digitalRead (A2);
Serial.print ("pin A2 =");
Serial.println (j);
j = digitalRead (A0);
Serial.print ("pin A0 =");
Serial.println (j);
j = digitalRead (A1);
Serial.print ("pin A1 =");
Serial.println (j);
Serial.println ("");
Serial.println (n);
Serial.println ("");

delay (500);
}
// the function will call 2000 time and then hand back to the loop, and get called again!
// whilst this function call is not "commented out" by the "//" in the call in Loop, the program can run but badly!

} // end of checkconnections function =======================================================================


void runstepper () { // function to check that the stepper motor is working ==============================================
// Only runs if you remove the "//" in the Loop
// Don't forget to put the "//" back again!

runstepper: // this is a label for the "goto" at the end of this function. ie, it is a closed loop, no escape!

stepdelay = 3500;
int increment = 1;

Serial.println ("accel");
for (int m = 0; m < 3200; m++) { // one turn accelerating
digitalWrite(3, HIGH);
delayMicroseconds (10);
digitalWrite(3, LOW);
delayMicroseconds (stepdelay);
stepdelay = stepdelay - increment;
}
Serial.println (stepdelay);
Serial.println ("const");

for (int m = 0; m < 6400; m++) { // two turns at constant speed
digitalWrite(3, HIGH);
delayMicroseconds (10);
digitalWrite(3, LOW);
delayMicroseconds (stepdelay);
}
Serial.println ("decel");
for (int m = 0; m < 3200; m++) { // one turn decelerating
digitalWrite(3, HIGH);
delayMicroseconds (10);
digitalWrite(3, LOW);
delayMicroseconds (stepdelay);
stepdelay = stepdelay + increment;
}
Serial.println (stepdelay);
Serial.println ("reverse");
dir = !dir; // the "!" means "not" - this will reverse the rotation
digitalWrite (2, dir);

goto runstepper;

// this function is a closed loop and will repeat until turned off
// whilst this function call is not "commented out" by the "//" in the call in Loop, none of the rest of the program can run

} // end of runstepper function =====================================================================================

// end of sketch ====================================================================================================
 

Attachments

  • moor_street_traversers_28may19.ino
    13.9 KB · Views: 8

Focalplane

Western Thunderer
To add to Simon's post, let me add that I am a complete novice so I am progressing slowly and carefully. I have faith in the finished article but I know that a lot depends on me crossing the "t"s and dotting the "i"s. I feel sure we'll get there in the end but I would prefer not to burn out some electronics along the way. After all, I invested in them! I am waiting until my head is aligned with the planets, so to speak, and then can expect a positive outcome. Meantime I am doing some mundane wiring, etc.
 

simond

Western Thunderer
Ok, so what’s going on?

The preamble as I have called it, is not needed by the Arduino, but it’s pretty important for me! Major release/revisions are key. Also, what am I trying to do, how is it connected up, why are some of the constants set to the values they are, and so on, will all be of little interest today, but if I come back to the sketch next year...

Noteworthy points -
Use of /* to start a multi line comment, and */ to end it.
Use of lines of symbols to visually break up the text.

The declaration is not “formally” part of the Arduino Sketch structure either, but it’s handy to put all these definitions of terms together in one place, and if they include global variables, they must precede the “setup”.

The definitions of the variable types are found in the Arduino reference, you’ll want the web page open when programming anyway.

Noteworthy points:

Use of // to put a comment on any line, lots of comments, makes debugging much easier. Adding notes of the wire colour, for example.
Use of ; Almost every line of code is terminated by a semicolon. Miss one out at your peril! Usually easy to find, as the compiler will often highlight the row below, occasionally, there will be some abstruse error message. My reaction is to go looking for the missing ;

void setup(){

This is an obligatory part of the formal structure, as is the following section, loop. Rather than the semicolon, this line has a curly brace at the end, {, which is a dead giveaway, there’s a matching one at the other end of the section. Miss them at your peril also. Or get them out of order, causes some odd results. Happily, the programming environment helps in two ways, there’s an auto-format command in the tools menu, which manages all the indents correctly for you, and there’s a feature when you select the end of a bracketed function, it posts a little highlight of the line at the start of the said function.

Serial begin - this tells the Arduino to open a serial connection to the serial monitor which you can open on the computer that’s running the IDE. It’s in the tools menu. This means you can print comments to a window on your computer as the Arduino is running its program, which is immensely useful for discovering that you didn’t program it quite the way that you thought you had. You can also use the serial connection to give instructions to the Arduino whilst programs are running. It’s a bit clunky, but can be useful. The number is the speed of the connection.

Pinmode - tells the Arduino what you are using the pin for - input pull-up is neat. There is a pull up resistor that makes the pin logically “high”, and I& you then connect the pin to ground through a switch, it goes “low”. You can therefore use a Boolean variable to describe the state of the pin, and the program can branch or act on that variable. (Other inputs are available.). “Output” is pretty obvious, just remember there are limits to how much current each output pin can supply.

There are a series of “if” statements - worth noting that if you want to test a variable, you must use a double equals “==“ because if you use a single “=“ it will be treated as an assignation, which means you get daft results.

“If x = 3 do some function”, will set x to the value 3, and as a result, will carry out the function, whatever the value of x was before it got to that line, whereas “if x == 3 do some function” will only do the function if x was 3.

The groups of lines following each of the if statements set the three command lines of the stepper driver to the required combination for each microstepping selection. I wrote that little block of code a year or so ago, and just copied it in here. As microstepping will always be 1/16 in this sketch, I could have removed the other blocks, but the sketch isn’t running into memory limits, so I left it.

Each block ends with the closing curly brace, }.

The setup concludes by printing all the variables onto the monitor screen which confirms I’ve set them up, and that the program has processed to this point, and that seems like a good point to break.

More soon
Simon
 

simond

Western Thunderer
Ok, the loop();

This is really very simple. It does what it says on the can, until the program is stopped externally, or a goto causes a stop.

There are five sub programs that the loop can call in this sketch. Let’s ignore the first two at this point.

So Paul turns the layout on, and the two traversers and the hoist are in positions unknown (this doesn’t have to be the case, but it a pretty safe assumption) so they have to set themselves into a known state. There is a variable, set right at the beginning, which is tested

If (initialise == 0) {
InitEndPos();
}

These three lines have lots of significance.
Firstly, it’s an “if” statement, so the sketch is branching, dependent on the value of the variable “initialise”
(Note the double == as noted earlier, we want to test it, not to assign a value.)
The end of the if statement is an opening brace.
Then the statement(s) that is/are carried out if the condition is true - these statements end in the normal semicolon.
Then the closing brace, signifying the end of the conditional section.

If initialise is zero (Boolean “LOW”) then a function is called. The function is called “InitEndPos()”. This is a really neat thing about C language. When they wrote it, they didn’t think that I’d need such a function, so they didn’t include one.

But I could. You’ll find it lower down in the program. It does some stuff, and when it has completed its stuff, it comes back to the same place. The last line of the function sets the variable “initialise” to HIGH, so it won’t call this function again until the sketch is restarted.

This “function call” approach is a fundamental part of this style of programming. Functions can call functions. The same function can be called multiple times from different places within your sketch, it will always return to the place it was last called from and then execute the next line.

Following the InitEndPos() function, then there are two more, similar groups of lines, each with an if statement testing the state of the up and down buttons, and then checking whether the position is appropriate for the received command, and if so, going to one of the two (almost identical) functions that will either go from “down” to “up” or vice versa.

Brief philosophical bit; there are loads of ways of skinning this particular cat, there usually are. I could have checked the position before testing the button, but doing it this way felt more logical. The other thing I could have done would be to have a single function for moving the motor, and simply passing a variable to it to tell it which way to go. Didn’t think of it til now... I just copied the routine and put a “!” in front of the direction variable. The exclamation mark inverts a Boolean variable, meaning that if “dir” caused it to go down, then “!dir” will make it go up.

And then we’ve got to the end of the loop, and it goes around again. And again.

More soon.
Simon
 
Last edited:

simond

Western Thunderer
Going down, sir?

Two birds with one stone, as going up is just the reverse of going down :)

Void GoDown (long gosteps){
...
}


“Void” is an Arduino keyword to define a function that does not return a value.

“gosteps” is the variable to which we assigned a value in InitEndPos(). It is the total distance, in stepper pulses, from one end stop to the other. The value is the distance in mm, divided by the screw pitch in mm/rev, multiplied by 200 steps per rev, multiplied by 16 microsteps per step. 85/5 x 200 x 16 = 54400. So it is bigger than the biggest integer that the Arduino can handle (int must be between -32,768 and 32,767, and will roll over if it exceeds these limits), hence it needs to be defined as “long”.

To operate the stepper, via an A4988, we need to issue a direction instruction, hold various pins in the HIGH state, a couple in the LOW state, and then cycle the step pin at a controlled rate.

The various pins are already set by the Setup() so we only need to concern ourselves with the direction, and speed.

What I wanted to do was to arrange a slow start, gentle acceleration, constant speed for most of the distance, gentle deceleration, and then stop. This took a fair bit of fiddling around, as the variable that can be varied is the delay between issuing step commands, thus the longer the delay, the faster it goes. This is achieved by having a set delay time for normal running, a set delay time for running at minimum speed (ie first step and last step) and decrementing or incrementing between the two. This means that the ramp period is a fixed integer number of steps, which means it’s easy to work out when to start decelerating. “Stepincrement” was defined as 1 at the end of the declarations, right back at the start of the program. Flat out it’s 600us, dead slow it’s 3500us. Slower than this, it’s very obviously jumping at each pulse, so I think this is a practical minimum speed with this setup. “us” should be “Mu-s” as in “microseconds” but the iPad doesn’t do it without much fiddling. I can have icons and pictograms for everything from Donald’s quiff to a duck, but weird symbols are all Greek to it. Education, nah...

(There are other stepper drivers that will do 1/256 microsteps, this should allow a slower speed. Alternatively, a geared stepper or a slower pitch screw could be used, if it’s too quick. The alternative driver is a drop-in replacement, hardware wise, and the software changes to accommodate it would be minimal, so it the speed is an issue, that would be my first go-to.)

So the core of this function is a few lines that digitalWrites pin 3 HIGH, waits 2 microseconds, then writes it LOW again, then waits a variable length of time, then does it again.

These are wrapped in a loop which counts from zero to “gosteps” ie, the total travel, with a couple of conditions to work out if the speed is ramping up, constant, or ramping down.

And these are wrapped in a couple of lines to turn the green signal off, turn the red on, and set the direction before starting to move, and to turn the red off and the green on, when it has stopped moving, and to set a variable for which end of travel it is. This is tested when buttons are pressed. You don’t want to try to go down if you are already at the lower end stop.

It would be trivially easy to have another pin doing exactly the same as the green, and connecting this to a relay controlling the track supply, to prevent conflicting movements, but given that Paul will use DCC, this will turn off any sounds he may have, and can lead to unpredictable loco movements when the relay turns on again, so not recommended!


I think there’s enough explanation here for anyone to dig through the other bits of the program and understand what I’ve done, so I’ll not write a description of the rest. If anyone has any questions, please feel free to post them, and I’ll try to answer.

And if anyone wants to post other programs, or links to other sites, please do so. There are a couple of very helpful threads on RMWeb, I will link to them, and as I have resuscitated my arduinomojo I shall see if I can finish my control panel project over the next week or so - I hope to make progress today as it’s blowing a hoolie outside, and I’ve no desire to be out in it!

Hope this has been of interest to the WT crowd, let’s see some more!

Atb
Simon
 
Last edited:

simond

Western Thunderer
Phil,

Delighted that is been of interest, hopefully of help. Quid pro quo, you helped me loads with my laser!

Get one, load the IDE onto your laptop, load “blink” (from the “examples” folder) and upload it.

It flashes a LED. How simple, yet how satisfying is that?

Then, as the man said, “ the world’s your lobster”

:)
Simon
 

simond

Western Thunderer
Quick update. I managed to kill a pin on my spare Arduino Nano earlier in the week. Having been told that I had spent too much money on Arduinos by some contributors on the RMWeb thread, I looked at Amazon, as advised. They were determined that I should pay for Prime, which I didn’t want to do, so I went to eBay and bought 5 from 3D-maker. £16 inc postage.

https://www.ebay.co.uk/itm/Arduino-Nano-V3-0-Compatible-Board-Atmega328P-16Mhz-Mini-USB-Multipack

Delivered yesterday, packed in antistatic film, excellent service. Usual disclaimers of course. Presume they’ll work fine. Will report in due course.

Atb
Simon
 

simond

Western Thunderer
ok, I have been asked to provide chapter and verse as LBSC would have said, so here is a new layout for a stepper controller with a Nano.



nano tt stepper board mk2.JPG

explanation and pix to follow
atb
Simon
 
Last edited:

simond

Western Thunderer
Pictures...

image.jpg

Hopefully it’s clear that the diagram above, and the board, are the same thing. The diagram is conveniently drawn in Excel, using the rows to represent the copper tracks of the stripboard, each cell is a hole in the board. The “o” are pins. The “x” are where the copper is removed to make a break in the strip, as can be seen below. (Twiddle a suitable drill in a pinchuck) And the “O” are the fixing holes.

image.jpg

The stepper is driven be the A4988 driver board which plugs into the 2x8 sockets on the right or the diagram, and outputs to the 4 pins on the far right. It’s supplied with power from the same source as my DCC through the two pins lower right. The round thing is a capacitor (25V 1000uF) which is optional, but smooths the supply. I do know what the symbol for an electrolytic is, I wanted to ensure I left physical space for it! Adjacent to that is a 7805 regulator which will supply the whole board if a jumper is fitted to the two pins between them.

There are three LEDs on the board. The left hand one is yellow and indicates the bridge track polarity relay is triggered, the green and red in the centre are to confirm the tracks are /are not aligned as far as the software is concerned. There is a link from pin 11 to the green led output pin on the upper left of the board. This six pin connector goes to the small control panel I made years ago. It won’t be used, normally, but is handy for setting up and debugging.

There are two 4-pin connectors lower left. The bottom one is the i2c connection to the main control panel. The upper one connects to the bridge track relay, and the opto sensor that detects the table at a given point in its rotation, a zero position reference, which is actually, and deliberately between tracks. There’s a small bead capacitor across the opto’s output, to smooth it, so it’s read by the Arduino analogRead command.

The scribble on top of the board reminds me which way round to fit the Arduino.

More soon
Simon
 
Last edited:

simond

Western Thunderer
Wiring complete & components fitted

image.jpg

Top side, the 7805 regulator, two caps, a bicolour and a yellow led, and a resistor. All the wiring has been metered to check continuity.

image.jpg

Next step is to check that there are no whiskers or shorts.

Did that.

Then powered it up without the Arduino & A4988 inserted, checked the LEDs.

Next I’ll check the external switches, then I’ll insert an Arduino...

More soon
Simon
 

ColinM

New Member
Simon,

Many thanks for the sketch and notes. I have built a turntable controller in the past Using the methodology in Tender's thread over on RMWeb, although I changed it to work as Non-DCC using push buttons. This was using an Arduino UNO and the Adafruit stepper controller.

I am interested in using your ideas with the A4988 controller. However I have a traverser that is 18” wide in a 24” baseboard, but it is 54” long (to take 5 coaches plus loco). The table runs on 2 drawer runners. My current mechanical linkage causes some issues with the table twisting, so I imagine that one motor on a lead screw at the centre would not be positive enough, and I was thinking of using two devices, one at each end.

I have seen you mention keeping two steppers and lead screws “in sync” (that might have been on your RMWeb thread), but I’m not sure how you would do this. I am presuming that the output from the Nano to the A4988 could parallel to a second A4988 thus giving the same control to both steppers.
Do you know if this would be possible?

Regards,

Colin.
 

simond

Western Thunderer
Colin,

Happy to have helped.

With the proviso that I haven’t done it, yes it will work. The input and output impedance are very high, so the high / low voltages would let you drive several stepper controllers from a single pin.

However, I would not do it. I would arrange that everything except the step pins on the stepper drivers was connected in parallel (direction, enable, microsteps, etc) but I’d have separate step pins. These would normally be driven from consecutive program steps, but would allow the program to include a function to get the stepper motors in the correct relative positions should they ever get misaligned, eg because of an obstruction causing lost steps.. Some form of manual control, either from push buttons, or from the serial monitor.

Hope this is useful
Simon
 

Osgood

Western Thunderer
Thought I'd best look at this thread to see what it was all about.
Gulp.

Started by finding out why the strange name - found two results:

1)
The name Arduino comes from a bar in Ivrea, Italy, where some of the founders of the project used to meet.
The bar was named after Arduin of Ivrea, who was the margrave of the March of Ivrea and King of Italy from 1002 to 1014.



2)
Arduino.jpg
 

simond

Western Thunderer
Hi Tony

If you'd asked me who "Arduin of Ivrea" was, I'd have suggested a fantasy character in the genre of Lord of the Rings...

so thanks for that - you learn something new every day!

cheers
Simon
 
Top