Arduinos - applications & stuff

Discussion in 'Techniques' started by simond, 29 May 2019.

  1. michl080

    michl080 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 likes this.
  2. simond

    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
     
  3. TimberSurf

    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!
     
    Focalplane and simond like this.
  4. TimberSurf

    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)
     
    Focalplane likes this.
  5. simond

    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 ====================================================================================================
     

    Attached Files:

    3 LINK, michl080 and BrushType4 like this.
  6. Focalplane

    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.
     
  7. simond

    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
     
  8. simond

    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: 8 June 2019
  9. simond

    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: 8 June 2019
    John Baker, michl080 and BrushType4 like this.
  10. BrushType4

    BrushType4 Western Thunderer

    Thanks Simon. I think I’ll get one of these and have a play.
     
  11. simond

    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
     
  12. John Baker

    John Baker Member

    I shall be buying one too....been thinking for a while that I want one to control the power, point switching and interlocking of signals etc. on my non-existent layout (but will exist one day.....probably when daughter has gone off to university. In about 17.5 years time.)
     
  13. simond

    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
     
  14. simond

    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: 16 June 2019
    BrushType4 likes this.
  15. simond

    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: 16 June 2019
  16. simond

    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
     
    JimG, adrian and Focalplane like this.
  17. ColinM

    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.
     
  18. simond

    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
     
  19. Osgood

    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
     
    adrian likes this.
  20. simond

    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
     
    Osgood likes this.