I am trying to create a sub routine, similar to"BlinkWithoutDelay"....

With the exception, that I need to create a "YELLOW" color by using a duty cycle of 18ms on, 8ms off, and still be able to check inputs from 2 other pins, that will designate the LED switch from either a RED, or GREEN, depending on the status of the other two inputs. This should be all logical, obviously, and should allow the changing of the color, for an "Automatic Block Control" Example -

input 1 is reading the status of next block = HIGH if occupied, LOW if empty.

HOWEVER... the "HOME" Block signal, which this is written for, must check to see if it's OWN block is occupied, called "Occupancy_Status", which of course is read as a first priority. HIGH = Occupied, LOW = EMPTY.

If the block forward (NEXT BLOCK), is occupied, then it checks to see if its OWN "HOME BLOCK" is empty or occupied. If it is "OCCUPIED" this "HOME BLOCK(each ATtiny85 is its own 'HOME BLOCK' a home block control). then the block is immediately turned in to a yellow signal, and then when the block behind it checks the status of the forward block "HOME" Status goes to yellow, it checks its "OWN HOME STATUS", and looks to see if the Block is occupied, or empty, it will set the LED to GREEN, if its own "HOME BLOCK is empty, or stays RED being occupied itself. It keeps checking forward Status, to see which MODE, or COLOR it is in, an

Diagram - ---------------------[BLOCK 1]-----------------------------------------[BLOCK 2]----------etc...
| | | | | |
OUTPUT | | |(INPUT) (OUTPUT)| | | (INPUT)
| | | | | |
---To Previous Block INPUT---- | | |--FROM NEXT BLOCK STATUS OUTPUT----- | | | --NEXT BLOCK--(etc) --->
| |
| |
[INPUT from HOME Block Sensors] [INPUT from HOME Block Sensors]
[HOME BLOCK OCCUPANCY STATUS] [HOME BLOCK OCCUPANCY STATUS]
HIGH = OCCUPIED HIGH = OCCUPIED
LOW = EMPTY LOW = EMPTY

IF THIS DIAGRAM DOESN'T MAKE SENSE, I'LL UPLOAD A COLORED DIAGRAM SHORTLY, LET ME KNOW.

This is an Automatic Block Control(ATC) for Train Traffic on main lines that are NOT CTC controlled(Central Train Control)
The controlling block, in a controlled routing system, is where your diverging routes are 'SET" for Direction, and the BLOCK sensors. along with the BLOCK STATUS from the FORWARD or NEXT BLOCK signal STATUS, determines the proceeding Block Signal color.

The combination of a forward block being occupied, and as long as the previous block is NOT occupied, that block will change to "YELLOW' unless it is OCCUPIED, at which point it will stay RED Until it is cleared.

If this isn't as clear as I hoped it would be, please ask for clarification. Each block is controlled mainly by these 2 signals, and then all that is necessary needed is the ability to make a duty cycle be maintained so that it appears to be a YELLOW signal after it HOME block is cleared, and the next block is OCCUPIED. This should automatically cascade back through all of the needed signals on each independent selected route between CTC sections. Holding a GREEN or a RED signal is easy. HIGH or LOW. High being GREEN, and LOW being RED. This single output pin should control all 3 colors needed.

If the block is clear, it will show a GREEN. If it is OCCUPIED, it will show a RED. The previous signal should read this output, and then check the TRACK OCCUPANCY pin, to see if it is FULL, or EMPTY, and display the appropriate color on the signal head.

I fear I am complicating a simple operation, and I have developed a mind block on why I should do this or that to make it work... HELP!!!!!! lol!!!!

THANK YOU IN ADVANCE FOR HELPING ME UNDERSTAND WHAT I MUST DO TO MAKE THIS WORK. THE REMAINING PROGRAMMING IS DEPENDANT ON THIS SUBROUTINE, AND ARE EASILY IMPLEMENTED.
I have gotten confused in how to write it so it sequences properly.

Use the [ pre ] tag to make a text diagram.

Have you discovered "Planning and Implementing an Arduino Program"? Use Google to search. It is on this forum somewhere.

With the exception, that I need to create a "YELLOW" color by using a duty cycle of 18ms on, 8ms off, and still be able to check inputs from 2 other pins, that will designate the LED switch from either a RED, or GREEN...

Can you clarify? I assume you have a bicolour LED -- red and green -- and would like it to be red, yellow or green. What do you mean when you say "18ms on, 8ms off"?

When showing yellow are you driving on one of the two (e.g. green) on all the time and the other (red) needs to be driven 18/8?

Have you thought about using PWM (analogWrite) to drive both and adjusting the duty cycles to achieve the color you want? This would take little to no processor time.

If you still want to do it the other way, please clarify re the above.

Thanks for responding! YES… I DID look at the code in that forum. I am using a SINGLE Bi-Color LED, thus, a SINGLE PIN for output. It drives a pair of Inverters, so that no high current pulse can harm the output of the Arduino. I am confused by the code. I am sorry, I am relatively a beginner, and I am trying to learn, as I go. At 64 yrs old, I need to do that, so I understand thing better. ONE STEP AT A TIME, and then write the code, and debug it. It is the best way for me to learn this.

I started with reading all of the inputs and storing them in a int variable. I then went to comparing each input, and selecting the appropriate output for the “SIGNAL LED”, and telling the PREVIOUS BLOCK, what the STATUS was, as to configure the previous block to show the appropriate signal color. There is only a few variables to use, and these are automatic. The ATC Block signals on the main line between CTC(CENTRAL TRAIN CONTROL), Sets the starting block up for a green, sets all the turnouts the proper direction, with the proper signal tower, and routes the train through the controlled area, and starts the ATC signal operation as it enters the first ATC block. The output from the direction control is read, and is used by each side of CTC, to determine control of traffic direction.( In each case, westbound,/eastbound).

Setting a GREEN, or RED, is easy. When a BLOCK is put in the “YELLOW” state, where the LED is running a duty cycle of 18ms HIGH, and 8 ms LOW needs to be established, and that is where it REALLY CONFUSES ME…

Is there a way to simplify this, to learn how it works, THEN add to the code, to make it a final testing program, to debug, and see how it works.

ALL variables, and constants are declared as GLOBAL, as there is only a single signal head being controlled. A manual setting is not needed, as it should automatically go in to a GREEN mode, given no traffic is occupying any of the blocks. ALL ATC signals, should run the first block test, and if the block is clear, then they will all fall in line as green until either the next block is occupied, and depending on if the train goes into the next block, and occupies ANY part of the previous block, it will also turn RED, and the previous block will monitor its status, and go to a YELLOW LED signal, when its HOME block, meaning its own block detector, is clear. After the train hits the 3rd block on its journey, and overlaps into the previous block, the 2nd block will stay RED, and the 1st Block will turn YELLOW, until 2 blocks forward are clear, and then turns GREEN. This Duty Cycle of pulses, causes the combination of RED and GREEN cycling, to display a YELLOW color, showing the next block is occupied, and the previous block is GREEN, allowing another train to enter it. Turning it RED, until the process is changed in the forward block… ATC… it should fall in line, for as many ATC signal heads are needed to complete a route between CTC areas.

I hope that makes sense to you.

I guess I am asking you to help me understand how to make this YELLOW cycling part of the program, while it checks the other 2 inputs, to determine what the color of the PREVIOUS blocks should be.
I think I have all of that figured out. I cannot understand how to create this duty cycle, without messing up the whole timing thing for the display LED.

I look forward to your help in this matter. You don’t have to WRITE it for me completely. Get me to the point where I can understand how to implement it, and THEN I can make it operate properly, with adjustments to the duty cycle.

Can ya’ll help me get through this? A little hand holding is very much appreciated!!!

Thanks again…

PS - I am not familiar with the {pre} concept. I am ignorant of these things at this time. I ALSO look forward to the help I get here… IT IS AWESOME and VERY EDUCATIONAL!!! I NEED TO LEARN AS MUCH AS I CAN AS FAST AS I CAN, and the BEST way for me to do so, is to get the starting help, and try it, and then implement it, and ask why it doesn’t work, so I can learn the changes I am making to complete the project…

You can try this code and adapt it to your project if it works for you. Note that if you use delay() elsewhere in your code you’ll likely ruin the effort to time the r/g cycling here. You need to call this at least once every 8mS min for it to function properly:

const byte pinLED = 2;

void setup() 
{
    pinMode( pinLED, OUTPUT );

}//setup

void loop() 
{
    YellowLED();

    //do other stuff here
    //.
    //.
    //.
    
}//loop

void YellowLED( void )
{
    static bool
        bState = false;
    static unsigned long
        timeDelay = 0,
        timeYellow = 0;
    unsigned long
        timeNow;

    //timing pin timing
    //grab the current micro(second)s count value
    timeNow = micros();
    //if the difference between now and last time is less than our desired delay
    //just return
    if( (timeNow - timeYellow) < timeDelay )
        return;

    //delay time has expired; set up timer for next period
    timeYellow = timeNow;

    //check state
    if( bState )
    {
        //if bState is true, pin is "high" now; set it low and set up
        //for the 8mS (8000uS) time delay
        digitalWrite( pinLED, LOW );
        bState = false;
        timeDelay = 8000ul;
        
    }//if
    else
    {
        //bState is false meaning pin is low now; set it high and set
        //up for the 18mS (18000uS) delay
        digitalWrite( pinLED, HIGH );
        bState = true;
        timeDelay = 18000ul;
        
    }//else
            
}//YellowLED

I will give this a try, and get back with you yay, or nay...

I will NOT be using any "DELAY" function. I know it will cause timing issues, because the Arduino is basically STUCK when you use that. NOTHING else can run, until it is done...

I will start implementing your code tonight, and add in the other functions and variables, as well as study this setup from you, and ask questions when I do not understand what an object does, or is supposed to do.

MANY HEARTFELT THANKS!!!!

Taz...

Retired_Phart:
I need to create a "YELLOW" color by using a duty cycle of 18ms on, 8ms off, and still be able to check inputs from 2 other pins

This may be from left field but, since the ratio changes the color, it implies to me the use of a PWM signal via analogWrite. Writing a 0 (zero) would have the green side on constantly while writing 255 would do the red. Or vice versa. You wouldn't get 18/8 ms (without jiggering the processor's PWM clock) but you can control the on/off time ratio, which is what you're after. If I understand correctly.

YMMV

OK, so I have known about block signalling since the age of eight or so - and that was quite a while back - so that is not the concern. Mind you, That was with four to six-aspect signals.

All this waffle and no code. Except for Blackfin's suggestion which for some curious reason uses micros() instead of millis().

I want to know what your (RP) code looks like for a start, and also how you are connecting your bi-colour LED to a single pin.

And I want to know what code you used to figure out that 8/ 18 ms ratio? Which one is red (suspect it is the 18)?

First optimisation: Generate two alternating states lasting 8 and 18 ms. At each state change, process all the LEDs together. For the red phase, set a given block LED to red if home or distant block occupied. else green, For the green phase, set to red if home block occupied. else green.

To respond specifically to the title … have a look at how functions are used in Planning and Implementing a Program. In C/C++ “function” is the term used for “sub routine”

As a more general response to the rather woolly description of the problem I suggest you should read up about the concept of a state-machine. It is a fancy name for a very useful technique in which some variables keep track of the state of the system as it progresses from one state to the next.

Some of the states that suggest themselves from your description include
NEXT_BLOCK_OCCUPIED
THIS_BLOCK_OCCUPIED
PREVIOUS_BLOCK_OCCUPIED

The code in this link should give you a sense of how this concept is used

…R

MorganS:
Use the [ pre ] tag to make a text diagram.

We live and learn... k++

With the [ pre ] tags:

iiiiiiiiii
wwwwwwwwww

Without:

iiiiiiiiii
wwwwwwwwww

Robin2:
As a more general response to the rather woolly description of the problem I suggest you should read up about the concept of a state-machine. It is a fancy name for a very useful technique in which some variables keep track of the state of the system as it progresses from one state to the next.

Some of the states that suggest themselves from your description include
NEXT_BLOCK_OCCUPIED
THIS_BLOCK_OCCUPIED
PREVIOUS_BLOCK_OCCUPIED

I do not think that is relevant as such, because the "state" of the railway is dynamic insofar as it can be determined (polled) on every pass of the loop - if necessary.

I detailed two "states" and the transactions at state change; no actions are required at any other time. States are "Red" and "Green" and based on time intervals of 8 and 18 ms. In the Red state, the LED will be red for either red or yellow, in the Green state, the LED will be green for either yellow or green. This applies for each of the LEDs, according to the relevant block states situations and they can be readily handled either by arrays or even bitmaps.

Paul__B:
I do not think that is relevant as such, because the “state” of the railway is dynamic insofar as it can be determined (polled) on every pass of the loop - if necessary.

I don’t see how the dynamic nature is at odds with a State machine - indeed that seems to me an ideal use for one.

I detailed two “states” and the transactions at state change; no actions are required at any other time. States are “Red” and “Green” and based on time intervals of 8 and 18 ms. In the Red state, the LED will be red for either red or yellow, in the Green state, the LED will be green for either yellow or green. This applies for each of the LEDs, according to the relevant block states situations and they can be readily handled either by arrays or even bitmaps.

Let’s agree to disagree. To my mind where there is no CTC the colour of the signals should be a response to the state of the railway.

…R

Just saying that the occupation of blocks are not "states" that have any need to be recorded/ remembered in this case, but ephemeral inputs that are simply read as and when required.

That is why the original description was so turgid. :grinning: