Arduino and Railway Modelling

I am trying to set up control of light functions (individual led's) via DCC Digital Command Control) and an Arduino.

Basically i am trying to create a variety of functions controlled by an on (high) - off (low) situation at a given pin.

The functions I am seeking are

A - Simple On/Off
B - Fade on to a set brightness and stay on until switched off and then fade off.
C - Flicker on (neon effect) to a set brightness and stay on until switched off and then switch off.
D - Flash.
E - Double Flash.
F - Strobe.
G - Random Flicker.

I appreciate there are sketches around showing how to pulse a led but i am struggling to find suitable ones for these situations.

Can anyone assist or point me in the direction of answers please.

Many thanks in anticipation.

You've described seven conditions, but a single digital pin can only exist in one of two states.
Are you expecting the seven effects to take place sequentially?

Hi

No i would use separate pins or indeed separate arduino's

Thank You

All those effects could be produced by modification of the blink without delay example code that comes with the Arduino IDE.
You could cover the whole lot in a single sketch.

I appreciate A, D, E and F are easily achieved by varying the blink sketch, but would very much welcome some pointers on the others.

I am not very experienced in coding arduino's.

Are you suggesting one sketch with a sort of selection menu?

Many thanks.

The technique set out in blink without delay simply shows how to perform simple actions at different times.
It doesn't matter if the action turns a thing on or writes a different PWM value, so blinks and fades are all easy to perform.
So, an array (or arrays) could store simple mnemonics for the actions and durations.

I wasn't recommending anything as complex as a menu - you could store options/scripts in EEPROM.

Hi Thank you for your continued interest and support.

I have achieved all the variations of controlling the led with the blink with delay sketch apart from fade on and fade off and flicker on and flicker off.

I have read that the use of delay should be avoided so i will try and achieve the same using the blink without delay options.

I am not familiar with how to create arrays so I am still somehwta stumped .

Please bear in mind I am a relative novice so this is all fairly new to me.

Thank you.

Start by getting an Arduino circuit working with dcc and simple on/off led switching. Post that sketch here and we can suggest code to change the simple on/off into the patterns you want.

Ok will do - may take me a while to get back to you but will do as soon as i can.

Ask of you get stuck with that code also. Google seemed to find some suitable DCC Arduino code when I did a quick search.

The patterns you want are all possible, so don't worry about that. I assume you will want to be able to configure one of those effects to any pin, in a fixed way. That should be easy enough. However, the fading, and perhaps the flickering may need to be done using an Arduino PWM pin (often marked with a ~).

Hi again

I have attached the sketch that I am using.

You will see that the DCC signal is input via Pin 2 via an optocoupler. I have done that and achieved success.

However each Pin is only set to be on or off (high or low) and it's getting the right code to get each pin to achieve the desired effect as in first post.

Each 'Arduino' is given an 'address' so it is quite possible to have several or many as desired each with several outputs.

The trigger at the DCC controller for the layout is effectively a push button via a mouse clicking on an icon.

I am not sure why the guy doesn't use pins 9, 10, 11 and 12 but I assume I could use these.

I understand what you say about PWM but if it is necessary to use PWM then that is not a problem as I could just use more 'Arduino's" and 'Addresses".

Eventually I may well use ATTiny 85 Development board due to their size. They have less outputs but that would not be an issue.

Each Item be it a switching point, light signal, carriage light or building light could have its own 'Arduino/ATTiny 85'

I am confused with lines 89-101 of the code as ideally I would like to control each pin individually whereas he seems to four lines of three Func's only but this may be something to do with the DCC signal.

The guy has several other sketches on his site (all ok for public domain) and there may be a more appropriate one than this one.

Please let me know if you need any thing further

Many thanks for your help.

PS

I have also attached a sketch he has for the ATTiny 85

Here is the link to the website for the sketches

the Sketches are in the Software page - takes a bit of delving to find them.

RB_DCC_Decoder_Function_ATtiny.ino (4.55 KB)

RB_DCC_Decoder_Function_ATtiny.ino (4.55 KB)

I noticed I have included the ATTiny sketch twice - here is the Arduino sketch

RB_DCC_Decoder_Function.ino (4.69 KB)

You can edit your previous posts, including adding/removing attachments. You should not do this when it would make the thread confusing for others reading it, but in cases like this it is fine.

Also, unless the code is very long, it is better to paste it into the post using code tags, rather than attaching .ino files. Many people read the forum on phones & tablets which cannot open a .ino attachment.

ATTiny sketch:

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// DCC Function Decoder
// Author: Ruud Boer - September 2015
// This sketch turns an ATtiny USB board into a DCC function decoder for F0 - F12
// Output pins used: 3-19 (14-19 = A0-A5)
// The DCC signal is optically separated and fed to pin 2 (=Interrupt 0).
// Optocoupler schematics: www.rudysmodelrailway.wordpress.com/software
// Many thanks to www.mynabay.com for publishing their DCC monitor and -decoder code.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// IMPORTANT: GOTO lines 15 - 28 to configure some data!
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

int decoderAddress = 1830; // This is the decoder address, change into the number you want.
#define F0_pin 1 // Define the output pin for every Function number in use
#define F1_pin 0 // Available pin numbers: 0,1,3,4,5
#define F2_pin 0
#define F3_pin 0
#define F4_pin 0
#define F5_pin 0
#define F6_pin 0
#define F7_pin 0
#define F8_pin 0
#define F9_pin 0
#define F10_pin 0
#define F11_pin 0
#define F12_pin 0
/* F13-F28 commented out 
#define F13_pin 0
#define F14_pin 0
#define F15_pin 0
#define F16_pin 0
#define F17_pin 0
#define F18_pin 0
#define F19_pin 0
#define F20_pin 0
#define F21_pin 0
#define F22_pin 0
#define F23_pin 0
#define F24_pin 0
*/

#include <DCC_Decoder.h>                      // Comment for 123d Test !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#define kDCC_INTERRUPT 0

byte Func[4]; //0=L4321, 1=8765, 2=CBA9, 3=F20-F13, 4=F28-F21
byte instrByte1;
int Address;

boolean RawPacket_Handler(byte pktByteCount, byte* dccPacket) {
  Address=0;
  if (!bitRead(dccPacket[0],7)) { //bit7=0 -> Loc Decoder Short Address
    Address = dccPacket[0];
    instrByte1 = dccPacket[1];
  }
  else if (bitRead(dccPacket[0],6)) { //bit7=1 AND bit6=1 -> Loc Decoder Long Address
    Address = 256 * (dccPacket[0] & B00000111) + dccPacket[1];
    instrByte1 = dccPacket[2];
  }

  if (Address==decoderAddress) {
    byte instructionType = instrByte1>>5;
    switch (instructionType) {
      case 4: // Loc Function L-4-3-2-1
        Func[0]=instrByte1&B00011111;
      break;
      case 5: // Loc Function 8-7-6-5
        if (bitRead(instrByte1,4)) {
          Func[1]=instrByte1&B00001111;
        }
        else { // Loc Function 12-11-10-9
          Func[2]=instrByte1&B00001111;
        }
      break;
      /*  F13-F28 commented out 
      case 6: // Future Expansions
        switch (instrByte1&B00011111) {
          case B00011110: // Loc Function F13-F20
            Func[3]=dccPacket[pktByteCount-1];
          break;
          case B00011111: // Loc Function F21-F28
            Func[4]=dccPacket[pktByteCount-1];
          break;
        }
      break;
      */
    }
    if (Func[0]&B00010000) digitalWrite(F0_pin,HIGH); else digitalWrite(F0_pin,LOW);
    if (Func[0]&B00000001) digitalWrite(F1_pin,HIGH); else digitalWrite(F1_pin,LOW);
    if (Func[0]&B00000010) digitalWrite(F2_pin,HIGH); else digitalWrite(F2_pin,LOW);
    if (Func[0]&B00000100) digitalWrite(F3_pin,HIGH); else digitalWrite(F3_pin,LOW);
    if (Func[0]&B00001000) digitalWrite(F4_pin,HIGH); else digitalWrite(F4_pin,LOW);
    if (Func[1]&B00000001) digitalWrite(F5_pin,HIGH); else digitalWrite(F5_pin,LOW);
    if (Func[1]&B00000010) digitalWrite(F6_pin,HIGH); else digitalWrite(F6_pin,LOW);
    if (Func[1]&B00000100) digitalWrite(F7_pin,HIGH); else digitalWrite(F7_pin,LOW);
    if (Func[1]&B00001000) digitalWrite(F8_pin,HIGH); else digitalWrite(F8_pin,LOW);
    if (Func[2]&B00000001) digitalWrite(F9_pin,HIGH); else digitalWrite(F9_pin,LOW);
    if (Func[2]&B00000010) digitalWrite(F10_pin,HIGH); else digitalWrite(F10_pin,LOW);
    if (Func[2]&B00000100) digitalWrite(F11_pin,HIGH); else digitalWrite(F11_pin,LOW);
    if (Func[2]&B00001000) digitalWrite(F12_pin,HIGH); else digitalWrite(F12_pin,LOW);
  }
}

void setup() {
  DCC.SetRawPacketHandler(RawPacket_Handler); // Comment for 123d Test !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  DCC.SetupMonitor( kDCC_INTERRUPT );         // Comment for 123d Test !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  pinMode(0, OUTPUT);
  pinMode(1, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
}

void loop() {
  DCC.loop();   // Comment for 123d Test !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
}

Arduino sketch:

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// DCC Function Decoder
// Author: Ruud Boer - September 2015
// This sketch turns an Arduino into a DCC function decoder for F0 - F12
// Output pins used: 3-19 (14-19 = A0-A5)
// The DCC signal is optically separated and fed to pin 2 (=Interrupt 0).
// Optocoupler schematics: www.rudysmodelrailway.wordpress.com/software
// Many thanks to www.mynabay.com for publishing their DCC monitor and -decoder code.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// IMPORTANT: GOTO lines 15 - 28 to configure some data!
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

int decoderAddress = 1830; // This is the decoder address, change into the number you want.
#define F0_pin 13 // Define the output pin for every Function number in use
#define F1_pin 14 // Available pin numbers: 3 - 19
#define F2_pin 15
#define F3_pin 16
#define F4_pin 17
#define F5_pin 18
#define F6_pin 19
#define F7_pin 3
#define F8_pin 4
#define F9_pin 5
#define F10_pin 6
#define F11_pin 7
#define F12_pin 8
/* F13-F28 commented out 
#define F13_pin 0
#define F14_pin 0
#define F15_pin 0
#define F16_pin 0
#define F17_pin 0
#define F18_pin 0
#define F19_pin 0
#define F20_pin 0
#define F21_pin 0
#define F22_pin 0
#define F23_pin 0
#define F24_pin 0
*/

#include <DCC_Decoder.h>                      // Comment for 123d Test !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#define kDCC_INTERRUPT 0

byte Func[4]; // 0=L F4-F1, 1=F9-F5, 2=F12-F9, 3=F20-F13, 4=F28-F21
byte instrByte1;
int Address;

boolean RawPacket_Handler(byte pktByteCount, byte* dccPacket) {
  Address=0;
  if (!bitRead(dccPacket[0],7)) { //bit7=0 -> Loc Decoder Short Address
    Address = dccPacket[0];
    instrByte1 = dccPacket[1];
  }
  else if (bitRead(dccPacket[0],6)) { //bit7=1 AND bit6=1 -> Loc Decoder Long Address
    Address = 256 * (dccPacket[0] & B00000111) + dccPacket[1];
    instrByte1 = dccPacket[2];
  }

  if (Address==decoderAddress) {
    byte instructionType = instrByte1>>5;
    switch (instructionType) {
      case 4: // Loc Function L-4-3-2-1
        Func[0]=instrByte1&B00011111;
      break;
      case 5: // Loc Function 8-7-6-5
        if (bitRead(instrByte1,4)) {
          Func[1]=instrByte1&B00001111;
        }
        else { // Loc Function 12-11-10-9
          Func[2]=instrByte1&B00001111;
        }
      break;
      /* F13-F28 commented out 
      case 6: // Future Expansions
        switch (instrByte1&B00011111) {
          case B00011110: // Loc Function F13-F20
            Func[3]=dccPacket[pktByteCount-1];
          break;
          case B00011111: // Loc Function F21-F28
            Func[4]=dccPacket[pktByteCount-1];
          break;
        }
      break;
      */
    }
    if (Func[0]&B00010000) digitalWrite(F0_pin,HIGH); else digitalWrite(F0_pin,LOW);
    if (Func[0]&B00000001) digitalWrite(F1_pin,HIGH); else digitalWrite(F1_pin,LOW);
    if (Func[0]&B00000010) digitalWrite(F2_pin,HIGH); else digitalWrite(F2_pin,LOW);
    if (Func[0]&B00000100) digitalWrite(F3_pin,HIGH); else digitalWrite(F3_pin,LOW);
    if (Func[0]&B00001000) digitalWrite(F4_pin,HIGH); else digitalWrite(F4_pin,LOW);
    if (Func[1]&B00000001) digitalWrite(F5_pin,HIGH); else digitalWrite(F5_pin,LOW);
    if (Func[1]&B00000010) digitalWrite(F6_pin,HIGH); else digitalWrite(F6_pin,LOW);
    if (Func[1]&B00000100) digitalWrite(F7_pin,HIGH); else digitalWrite(F7_pin,LOW);
    if (Func[1]&B00001000) digitalWrite(F8_pin,HIGH); else digitalWrite(F8_pin,LOW);
    if (Func[2]&B00000001) digitalWrite(F9_pin,HIGH); else digitalWrite(F9_pin,LOW);
    if (Func[2]&B00000010) digitalWrite(F10_pin,HIGH); else digitalWrite(F10_pin,LOW);
    if (Func[2]&B00000100) digitalWrite(F11_pin,HIGH); else digitalWrite(F11_pin,LOW);
    if (Func[2]&B00001000) digitalWrite(F12_pin,HIGH); else digitalWrite(F12_pin,LOW);

    /*//Print DCC packet bytes for testing purposes
    for (byte n=0; n<5; n++) {
      Serial.print(Func[n],BIN);
      Serial.print(" ");
    }
    Serial.println(" ");
    */
  }
}

void setup() {
  Serial.begin(38400);
  DCC.SetRawPacketHandler(RawPacket_Handler); // Comment for 123d Test !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  DCC.SetupMonitor( kDCC_INTERRUPT );         // Comment for 123d Test !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  for (byte n=3; n<20; n++) pinMode(n,OUTPUT);
}

void loop() {
  DCC.loop();   // Comment for 123d Test !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
}

I have modified the Arduino sketch to fade up and down DCC F7 = Arduino pin 3. I can't test it for you, so if you get an error messages, post them in code tags.

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// DCC Function Decoder
// Author: Ruud Boer - September 2015
// This sketch turns an Arduino into a DCC function decoder for F0 - F12
// Output pins used: 3-19 (14-19 = A0-A5)
// The DCC signal is optically separated and fed to pin 2 (=Interrupt 0).
// Optocoupler schematics: www.rudysmodelrailway.wordpress.com/software
// Many thanks to www.mynabay.com for publishing their DCC monitor and -decoder code.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// IMPORTANT: GOTO lines 15 - 28 to configure some data!
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

int decoderAddress = 1830; // This is the decoder address, change into the number you want.
#define F0_pin 13 // Define the output pin for every Function number in use
#define F1_pin 14 // Available pin numbers: 3 - 19
#define F2_pin 15
#define F3_pin 16
#define F4_pin 17
#define F5_pin 18
#define F6_pin 19
#define F7_pin 3
#define F8_pin 4
#define F9_pin 5
#define F10_pin 6
#define F11_pin 7
#define F12_pin 8
/* F13-F28 commented out
  #define F13_pin 0
  #define F14_pin 0
  #define F15_pin 0
  #define F16_pin 0
  #define F17_pin 0
  #define F18_pin 0
  #define F19_pin 0
  #define F20_pin 0
  #define F21_pin 0
  #define F22_pin 0
  #define F23_pin 0
  #define F24_pin 0
*/

#include <DCC_Decoder.h>                      // Comment for 123d Test !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#define kDCC_INTERRUPT 0

byte Func[4]; // 0=L F4-F1, 1=F9-F5, 2=F12-F9, 3=F20-F13, 4=F28-F21
byte instrByte1;
int Address;

boolean RawPacket_Handler(byte pktByteCount, byte* dccPacket) {
  Address = 0;
  if (!bitRead(dccPacket[0], 7)) { //bit7=0 -> Loc Decoder Short Address
    Address = dccPacket[0];
    instrByte1 = dccPacket[1];
  }
  else if (bitRead(dccPacket[0], 6)) { //bit7=1 AND bit6=1 -> Loc Decoder Long Address
    Address = 256 * (dccPacket[0] & B00000111) + dccPacket[1];
    instrByte1 = dccPacket[2];
  }

  if (Address == decoderAddress) {
    byte instructionType = instrByte1 >> 5;
    switch (instructionType) {
      case 4: // Loc Function L-4-3-2-1
        Func[0] = instrByte1 & B00011111;
        break;
      case 5: // Loc Function 8-7-6-5
        if (bitRead(instrByte1, 4)) {
          Func[1] = instrByte1 & B00001111;
        }
        else { // Loc Function 12-11-10-9
          Func[2] = instrByte1 & B00001111;
        }
        break;
        /* F13-F28 commented out
          case 6: // Future Expansions
          switch (instrByte1&B00011111) {
            case B00011110: // Loc Function F13-F20
              Func[3]=dccPacket[pktByteCount-1];
            break;
            case B00011111: // Loc Function F21-F28
              Func[4]=dccPacket[pktByteCount-1];
            break;
          }
          break;
        */
    }
    if (Func[0]&B00010000) digitalWrite(F0_pin, HIGH); else digitalWrite(F0_pin, LOW);
    if (Func[0]&B00000001) digitalWrite(F1_pin, HIGH); else digitalWrite(F1_pin, LOW);
    if (Func[0]&B00000010) digitalWrite(F2_pin, HIGH); else digitalWrite(F2_pin, LOW);
    if (Func[0]&B00000100) digitalWrite(F3_pin, HIGH); else digitalWrite(F3_pin, LOW);
    if (Func[0]&B00001000) digitalWrite(F4_pin, HIGH); else digitalWrite(F4_pin, LOW);
    if (Func[1]&B00000001) digitalWrite(F5_pin, HIGH); else digitalWrite(F5_pin, LOW);
    if (Func[1]&B00000010) digitalWrite(F6_pin, HIGH); else digitalWrite(F6_pin, LOW);
    //if (Func[1]&B00000100) digitalWrite(F7_pin,HIGH); else digitalWrite(F7_pin,LOW);
    if (Func[1]&B00001000) digitalWrite(F8_pin, HIGH); else digitalWrite(F8_pin, LOW);
    if (Func[2]&B00000001) digitalWrite(F9_pin, HIGH); else digitalWrite(F9_pin, LOW);
    if (Func[2]&B00000010) digitalWrite(F10_pin, HIGH); else digitalWrite(F10_pin, LOW);
    if (Func[2]&B00000100) digitalWrite(F11_pin, HIGH); else digitalWrite(F11_pin, LOW);
    if (Func[2]&B00001000) digitalWrite(F12_pin, HIGH); else digitalWrite(F12_pin, LOW);

    /*//Print DCC packet bytes for testing purposes
      for (byte n=0; n<5; n++) {
      Serial.print(Func[n],BIN);
      Serial.print(" ");
      }
      Serial.println(" ");
    */
  }
}

void fadeF7() {
  static unsigned long lastFadeTimeF7 = 0;
  static int fadeLevelF7 = 0;

  if (millis() - lastFadeTimeF7 > 10) {
    
    lastFadeTimeF7 = millis();
    
    if (Func[1]&B00000100) {
      if (fadeLevelF7 < 255) analogWrite(F7_pin, ++fadeLevelF7);
      }
    else {
      if (fadeLevelF7 > 0) analogWrite(F7_pin, --fadeLevelF7);
    }
  }
}

void setup() {
  Serial.begin(38400);
  DCC.SetRawPacketHandler(RawPacket_Handler); // Comment for 123d Test !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  DCC.SetupMonitor( kDCC_INTERRUPT );         // Comment for 123d Test !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  for (byte n = 3; n < 20; n++) pinMode(n, OUTPUT);
}

void loop() {
  DCC.loop();   // Comment for 123d Test !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  fadeF7();
}

Thank you I will try and let you know.

Hi

When compiling the sketch I am getting the following error message.
Arduino: 1.8.1 (Mac OS X), Board: "Arduino/Genuino Uno"

^
compilation terminated.
exit status 1
Error compiling for board Arduino/Genuino Uno.

??

Is that all the error? Did you scroll back?

Hi - i jumped too soon - just tried again more slowly and yes it works fine.

I assume I can adjust the rate of the fade?

If you could dome a flicker on as in a fluorescent light that would be fantastic.

Once again thank you very much for you patience.

Regards

John

johnbet:
I assume I can adjust the rate of the fade?

Hi John, glad it worked OK. Yes you can adjust the speed of the fade. That "10" figure controls it. The higher the number, the slower the fade.

I will have a think about a good way to simulate the flourescent light. Should it flicker for ever, like a faulty tube, or be on steady after a few seconds?