ARDUINO PROGRAMMING, AND INTERFACING HELP

Post all your model railway electronic problems, solutions and discoverys here.
MikeTrymTrains
Posts: 17
Joined: Mon Jul 02, 2018 9:58 pm

Re: ARDUINO PROGRAMMING, AND INTERFACING HELP

Postby MikeTrymTrains » Tue Jul 10, 2018 2:16 pm

Hi timbologist thanks for posting your code but the green lights have different on times one about four seconds the other about eight seconds. I can't see in your code what pins I needed to use. I found out by unplugging and plugging in pins. The pins are 13,12,11,10,9,8. It didn't compile until I search the internet to find what the problem was. Here is a link for others how to fix the #include <TimerOne.h> error.
If new to Arduino programming or forgot like me :D.https://www.arduino.cc/en/Guide/Libraries

timbologist
Posts: 368
Joined: Wed Sep 18, 2013 6:39 am
Location: Hazeldene Victoria Australia ( in the bush )

Re: ARDUINO PROGRAMMING, AND INTERFACING HELP

Postby timbologist » Tue Jul 10, 2018 3:31 pm

MikeTrymTrains wrote:green lights have different on times one about four seconds the other about eight seconds.

The timing I used was taken from TimberSurf's code in program 2.
MikeTrymTrains wrote:Hi timbologist thanks for posting your code but the green lights have different on times one about four seconds the other about eight seconds. I can't see in your code what pins I needed to use. I found out by unplugging and plugging in pins. The pins are 13,12,11,10,9,8. It didn't compile until I search the internet to find what the problem was. Here is a link for others how to fix the #include <TimerOne.h> error.
If new to Arduino programming or forgot like me :D.https://www.arduino.cc/en/Guide/Libraries

Sorry about that but as I said I wrote it in my own way not really thinking about others wanting to follow. This is a bit of a problem when you use direct port addressing there is no obvious indication of what pins are being used unless you actually know what pins are on what port. So it does make things a bit difficult for people to follow. When you have been writing code for over 40 years and mainly assembler things just become second nature. Sometimes you just go of in your own world where no one else can follow. :oops:
timbologist wrote:So I thought I would throw my two bobs worth anyway, and write the code as I do for my personal projects and don't worry about others following

MikeTrymTrains
Posts: 17
Joined: Mon Jul 02, 2018 9:58 pm

Re: ARDUINO PROGRAMMING, AND INTERFACING HELP

Postby MikeTrymTrains » Tue Jul 10, 2018 9:56 pm

Hi timbologist I had another look at your code and got it running how I want it to. I like the look of it. It's complex looking for me to use but it look so much nicer than my code and shorter. The code I had to change was this

Code: Select all

long mSDelaySteps[8] =
{
  10000000UL, // 10 SECOND DELAY BETWEEN FIRST AND SECOND STATE
   4000000UL, //  4 SECOND DELAY BETWEEN SECOND AND THIRD STATE
   2000000UL, //  2 SECOND DELAY BETWEEN THIRD AND FORTH STATE
   2000000UL, //  2 SECOND DELAY BETWEEN FORTH AND FIFTH STATE
   4000000UL, //  4 SECOND DELAY BETWEEN FIFTH AND SIXTH STATE
   3000000UL, //  3 SECOND DELAY BETWEEN SIXTH AND SEVENTH STATE
   2000000UL, //  2 SECOND DELAY BETWEEN SEVENTH AND EIGHTH STATE
   1000000UL, //  1 SECOND DELAY BETWEEN EIGHTH AND FIRST STATE
};
to this

Code: Select all

long mSDelaySteps[8] =
{
   6000000UL, //  6 SECOND DELAY BETWEEN FIRST AND SECOND STATE
   1000000UL, //  1 SECOND DELAY BETWEEN SECOND AND THIRD STATE
   1000000UL, //  1 SECOND DELAY BETWEEN THIRD AND FORTH STATE
   1000000UL, //  1 SECOND DELAY BETWEEN FORTH AND FIFTH STATE
   6000000UL, //  6 SECOND DELAY BETWEEN FIFTH AND SIXTH STATE
   1000000UL, //  1 SECOND DELAY BETWEEN SIXTH AND SEVENTH STATE
   1000000UL, //  1 SECOND DELAY BETWEEN SEVENTH AND EIGHTH STATE
   1000000UL, //  1 SECOND DELAY BETWEEN EIGHTH AND FIRST STATE
};
Thanks for posting it.

User avatar
roganty
Posts: 158
Joined: Wed Feb 17, 2016 11:53 am
Location: Bristol, UK
Contact:

Re: ARDUINO PROGRAMMING, AND INTERFACING HELP

Postby roganty » Tue Jul 10, 2018 11:02 pm

timbologist wrote:Hi all, it's good to see you all bouncing ideas of each other.
[...]
As can be seen from the discussion there are many different ways to achieve the same result, everybody writes differently and are different levels of knowledge-ability.

So I thought I would throw my two bobs worth anyway, and write the code as I do for my personal projects and don't worry about others following.
As can be seen it is very short, fast and efficient, And could be classed as over kill for what it is required to do.

So just remember to write your programs in a manner that you are comfortable with and can easily understand and follow.
[...]


All true, and something I agree with.
In the examples posted about I normally would have used if...else, but for some reason switch...case seemed (at the time) more logical. :shrug:



For the past few days I have been trying to work out a way of having completely configurable two or four way traffic sequence.

I think I've worked out the timing.
I think I've worked out writing it all out to the pins.

The bit I'm having trouble with is keeping variables simple enough for a user to edit, and then having a function read it and put it altogether.

Having no experience/access to Arduino, the solutions I'm coming up with may eat up all the available memory.
Plus, if anyone did want a different configuration of light sequencing, smaller leaner code could be had by modifying the examples already posted above.


Anthony
Last edited by roganty on Wed Jul 11, 2018 11:18 pm, edited 1 time in total.
Main Layout: Planning | The Build

Erikslund - a small shunting layout

timbologist
Posts: 368
Joined: Wed Sep 18, 2013 6:39 am
Location: Hazeldene Victoria Australia ( in the bush )

Re: ARDUINO PROGRAMMING, AND INTERFACING HELP

Postby timbologist » Wed Jul 11, 2018 9:42 am

MikeTrymTrains wrote:Hi timbologist I had another look at your code and got it running how I want it to. I like the look of it. It's complex looking for me to use but it look so much nicer than my code and shorter. The code I had to change was this


I'm glad you got it working the way you wanted, as I said I used the timings that TimberSurf posted in his code. Even though my code is fairly advanced with the amount of comments it is generally easy to follow accept when I hide things with this direct port addressing. Next time I will make sure I include in that part of the code what pins are connected to what port. All this information is in the data sheets for the Micro's.

When I get time I am going to look at the rest of your code you have placed here and see what I can do to it :wink:

There was a mention previously about sound there are several ways to do it without using an MP3 shield I will put something up soon about this as I have added sound to the level crossing flasher in the form of the bells clanging. I just need to add the amplifier and a speaker so it can be heard.

timbologist
Posts: 368
Joined: Wed Sep 18, 2013 6:39 am
Location: Hazeldene Victoria Australia ( in the bush )

Re: ARDUINO PROGRAMMING, AND INTERFACING HELP

Postby timbologist » Fri Jul 13, 2018 1:00 pm

insanity prevails :)
So for the sake of it I have written the traffic light sequence for the above intersection.

// USING AN ARDUINO MEGA SIMULATE THE TRAFFIC SIGNALS AT
// HUME HIGHWAY AND RING ROAD INTERSECTION
// THE INTERSECTION HAS 2 ROADS INTERSECTING
// THE HUME HIGHWAY HAS NORTH AND SOUTH THROUGH TRAFFIC
// PLUS THE NORTH AND SOUTH HAVE RIGHT HAND TURN ONTO THE RING ROAD

// THE RING ROAD GOES EAST WEST AND EACH ENTRANCE
// ONTO THE HUME HIGHWAY IS LEFT AND RIGHT TURN
// THEREFORE THE SEQUENCE IS QUIT COMPLEX
// EACH DIRECTION HAS RED, AMBER, GREEN

I have written the code, just need to wire it up and test it and do a fritzing diagram and I will post it here.

It only takes about 40 lines of code.

Compiled data
Sketch uses 3006 bytes (1%) of program storage space. Maximum is 253952 bytes.
Global variables use 1103 bytes (13%) of dynamic memory, leaving 7089 bytes for local variables. Maximum is 8192 byte

Screenshot_2018-07-13_21-53-28.png

User avatar
roganty
Posts: 158
Joined: Wed Feb 17, 2016 11:53 am
Location: Bristol, UK
Contact:

Re: ARDUINO PROGRAMMING, AND INTERFACING HELP

Postby roganty » Sun Jul 15, 2018 11:38 am

roganty wrote:For the past few days I have been trying to work out a way of having completely configurable two or four way traffic sequence.

I think I've worked out the timing.
I think I've worked out writing it all out to the pins.

The bit I'm having trouble with is keeping variables simple enough for a user to edit, and then having a function read it and put it altogether.

Having no experience/access to Arduino, the solutions I'm coming up with may eat up all the available memory.
Plus, if anyone did want a different configuration of light sequencing, smaller leaner code could be had by modifying the examples already posted above.


I have been mulling this over for the last week, and I thought I'd have a go at a proof of concept.

This is using PHP, so it is not something you can install on the Arduino.

http://toys.roganty.co.uk/traffic_lights/ This shows the output of the script below

Code: Select all

<?php

/* The order the lights change
 * For example
 * n, s, e, w
 * se, n, w
 * ns, ew
 * This will only take up to four directions.
 */

$lights_order = 'ns,w,e';

//The sequence of the lights
//do not edit
$lights_seq = array(
    4, //[0] Red          0b100   4
    6, //[1] Red/Amber    0b110   6
    1, //[2] Green        0b001   1
    2, //[3] Amber        0b010   2
    );

//set all to 0
//This is not strictly needed
$ne_seq = $n_seq = $e_seq = $sw_seq = $s_seq = $w_seq = array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);

//needs a better name
//explde $lights_order by ','
//limit it to four items (the 5th contains everything else)
$light_order = explode(',', $lights_order, 5);

//Loop through each item
for( $i = 0; $i < 4; $i++ ){
   
    if( strpos( strtolower( $light_order[$i] ), 'n') !== false ){
        set_seq( $n_seq, $i );
    }
    if( strpos( strtolower( $light_order[$i] ), 'e') !== false ){
        set_seq( $e_seq, $i );
    }
    if( strpos( strtolower( $light_order[$i] ), 's') !== false ){
        set_seq( $s_seq, $i );
    }
    if( strpos( strtolower( $light_order[$i] ), 'w') !== false ){
        set_seq( $w_seq, $i );
    }
   
}

/*
 * This function adds the light sequence to the direction array
 */

function set_seq( &$dir, $i ){
   
    /* $i = 0 use 0,1,2,3
     * $i = 1 use 4,5,6,7
     * $i = 2 use 8,9,10,11
     * $i = 3 use 12,13,14,15
     */
   
    global $lights_seq;
    $j = 0;
   
    switch( $i ){
        case 0 :
            $j = 0;
            break;
        case 1 :
            $j = 4;
            break;
        case 2 :
            $j = 8;
            break;
        case 3 :
            $j = 12;
            break;
    }
   
    for( $k = 0; $k < 4; $k++ ){
        $dir[$j] = $lights_seq[$k];
        $j++;
    }
   
    return;
}

/*
 * Time to stick it all back together
 */

for( $i = 0; $i < 16; $i++ ){
   
    //North
    if( $n_seq[$i] == 0 ) //if 0 change to red
        $n_seq[$i] = $lights_seq[0]; //Red
   
    //Bit shift n and add to ne
    $ne_seq[$i] = $n_seq[$i] << 3;
   
    //East
    if( $e_seq[$i] == 0 ) //if 0 change to red
        $e_seq[$i] = $lights_seq[0]; //Red
   
    //Now add e to ne;
    $ne_seq[$i] += $e_seq[$i];
   
   
    //South
    if( $s_seq[$i] == 0 ) //if 0 change to red
        $s_seq[$i] = $lights_seq[0]; //Red
   
    //Bit shift s and add to sw
    $sw_seq[$i] = $s_seq[$i] << 3;
   
    //West
    if( $w_seq[$i] == 0 ) //if 0 change to red
        $w_seq[$i] = $lights_seq[0]; //Red
   
    //Now add w to sw;
    $sw_seq[$i] += $w_seq[$i];
   
    //Now we need to bit shift SW a bit more
    //This is so we can keep pins 0 & 1 free
    $sw_seq[$i] = $sw_seq[$i] << 2;
}

//Display the results
for( $i = 0; $i < 16; $i++ ){
    printf("%08b    %08b\r\n", $ne_seq[$i], $sw_seq[$i]);
}

?>



The idea is that you can change the ordering of the lights without having to rewrite the whole script.

The last part displaying the results would be where on the Arduino you would write to the pins and set them either high or low.
The pins used are 2 - 13
13/12/11 for North
10/9/8 for East
7/6/5 for South
4/3/2 for West

I'm not sure how easy/hard this would be to rewrite to C/C++
The functions working on strings, I think, would be the hardest to convert.

All that is needed to finish is set up a timer to iterate through the array writing the output to the pins.


Anthony
Last edited by roganty on Sat Jan 19, 2019 11:28 pm, edited 2 times in total.
Main Layout: Planning | The Build

Erikslund - a small shunting layout

User avatar
dubdee1000
Posts: 902
Joined: Mon Mar 31, 2008 9:59 pm
Location: cwm brynbuga

Re: ARDUINO PROGRAMMING, AND INTERFACING HELP

Postby dubdee1000 » Sat Jan 19, 2019 9:31 pm

A bit more basic than some of the other designs here, but here is today's work, the hornby conveyor controlled by an arduino. The video should show a photo resistor in front of the bread board which when covered, feeds back and switches on the conveyor. It took a lot of hunting to get the code for this (its an adapted LED code), since the basic motor control code switches the motor on when the resistor is exposed and i wanted the opposite. Pleased to get this working since its going to form the basis of many of my operations, the photo resistor sitting in the track bed and when a train rumbles over, triggers something to happen.

In this case, as the colliery wagons trundle over the resistor, the conveyor will start. Once my mp3 board arrives, i'll had some realistic sounds of the conveyor clanking away and I'll switch the grains of rice for some crushed coal... :D :D

https://youtu.be/x8j7blB3Uwc

board for conveyor_bb.png


Code: Select all

int light = 0; // store the current light value

void setup() {
    // put your setup code here, to run once:
    Serial.begin(9600); //configure serial to talk to computer
    pinMode(9, OUTPUT); // configure digital pin 9 as an output 
}
void loop() {
    // put your main code here, to run repeatedly:
    light = analogRead(A0); // read and save value from PR
   
    Serial.println(light); // print current light value
 
    if(light > 450) { // If it is bright...
        Serial.println("no wagons");
        digitalWrite(9, LOW); //turn motor off
    }
    else if(light > 45 && light < 451) { // If it is average light...
        Serial.println("no wagons");
       digitalWrite(9, LOW); // turn motor off
    }
    else { // If it's dark...
        Serial.println("lets start loading");
        digitalWrite(9, HIGH); // Turn motor on
    }
    delay(1000); // don't spam the computer!
}

Giraffe
Posts: 56
Joined: Fri May 16, 2008 1:31 pm

Re: ARDUINO PROGRAMMING, AND INTERFACING HELP

Postby Giraffe » Tue Jul 09, 2019 12:39 pm

timbologist wrote:As can be seen from the discussion there are many different ways to achieve the same result, everybody writes differently and are different levels of knowledge-ability.

So I thought I would throw my two bobs worth anyway, and write the code as I do for my personal projects and don't worry about others following.


This has been the most interesting part of the thread to me. I would be intrigued as to what the "beginner" programmers thought of how I wrote my code (I am a professional Software Engineer in the software applications world, so how I write my code is possibly not idiomatic of embedded software). I will have a cracking at the 4-way traffic lights problem at some point but in the meantime, I have written some code for a simple DC controller a while back. It has a RGB illuminated rotary encoder with click button, a NeoPixel ring around the encoder to indicate speed setting and outputs a signal to an H bridge chip to run the power to the track.
With each of those different bits going on, I have used an OO approach and split the program into separate classes to deal with each bit independently.
The main sketch simply sets up an object graph, registers the interrupt function to update the object handling the encoder when the encoder moves, and the main loop simply pushes the current state of the input in to the "controller" object, which returns a state object representing the current settings, which is passed to each of the three output objects to respond to appropriately.
A quite different style to what has been presented so far, so it'd be interesting to hear what people thought. I don't normally write in C++ so please excuse all the header files with implementation code in them :oops:
One thing I never finished off was to avoid the need for the main loop to pass values between the objects. What was going to happen was that the various objects would get wired together at startup and messages would get passed between them rather than returning values back to the main loop. If the main loop can simply turn into a dumb trigger that doesn't know about what it's triggering that is really what lets you easily build sketchs like MikeTymTrains master code in a really easy way. (Maybe I'll try a version of that after the 4-way attempt :) ) but for my code it would mean I could just add a second set of controls we'd to the same arduino and just change the code to create a few more objects at the start of the sketch.

Anyway, the code: https://github.com/christopherjmorris/train-controller


Return to “Electronics”

Who is online

Users browsing this forum: No registered users and 2 guests