Inconsistent results

I am trying to use Arduino Nano, RR-Cirkits BOD8 and CT coils to detect occupancy on a model train layout for the purpose of turning on LED signals. My system works perfectly sometimes but after working one or two times quits working entirely. At each occupancy event, a signal (LED) is shown on the BOD, sometimes the LEDs work, sometimes not. I have tried re-wiring, changing BOD units, adjusting sensitivity, etc. - nothing helps. I have double checked the wiring schematic and it is wired according to the sketch. It’s almost like something has to re-charge or ‘catch up’ in order for the system to work.

Any suggestions?

_4_zones.txt (3.66 KB)

int led37 = 9;  //Green led on pin 9
int led31 = 10;  //Red led on pin 10
int zone = A0;  //CT signal on A0

int green2=8;
int red2=7;
int zone2 = A1;

int green3=6;
int red3=5;
int zone3=A2;

int green4=4;
int red4=3;
int zone4=A3;


int numBlink=5;
int wait=300;
int wait2=400;
int wait3=350;

//BOD8 blue = 5v
//BOD8 green = gnd
//BOD8 black = A0
//CT on B rail
//LOW = On because led has common hot lead
//HIGH = Off  "   "



void setup() {

  pinMode(A0, INPUT);
  pinMode(led37, OUTPUT);
  pinMode(led31, OUTPUT);
  
  pinMode(A1, INPUT);
  pinMode(green2, OUTPUT);
  pinMode(red2, OUTPUT);
  
  pinMode(A2, INPUT);
  pinMode(green3, OUTPUT);
  pinMode(red3, OUTPUT);
  
  pinMode(A3, INPUT);
  pinMode(green4, OUTPUT);
  pinMode(red4, OUTPUT);  
  
 }

void loop() {
    //Start of Zone 1
  if (digitalRead(A0) == HIGH)  //No CT signal to A0 (Track vacant)
  {
    delay(1);

    if (digitalRead(A0) == LOW) //CT signal to A0 (Track occupied) 

    {
      for(int j=1; j<=numBlink; j=j+1)
      {
        digitalWrite(led37, HIGH);
        delay(1);
        digitalWrite(led31, LOW);  //Turn on Red LED
        delay(wait);
        digitalWrite(led31, HIGH);  //Turn off Red LED
        delay(wait);
      }
      }
     
     {
       digitalWrite(led31, LOW);
     }
     {
      if (digitalRead(A0) == HIGH)  //No CT signal to A0 (Track vacant)
        digitalWrite(led31, HIGH);
        digitalWrite(led37, LOW);
    }
  
  }

    //End of Zone 1
    
    //Start of Zone 2
    
      if (digitalRead(A1) == HIGH)  //No CT signal to A0 (Track vacant)
  {
    delay(1);

    if (digitalRead(A1) == LOW) //CT signal to A0 (Track occupied) 

    {
      for(int j=1; j<=numBlink; j=j+1)
      {
        digitalWrite(green2, HIGH);
        delay(1);
        digitalWrite(red2, LOW);  //Turn on Red LED
        delay(wait2);
        digitalWrite(red2, HIGH);  //Turn off Red LED
        delay(wait2);
      }
      }
     
     {
       digitalWrite(red2, LOW);
     }
     {
      if (digitalRead(A1) == HIGH)  //No CT signal to A0 (Track vacant)
        digitalWrite(red2, HIGH);
        digitalWrite(green2, LOW);
    }
  
  }

    //End of Zone 2

   //Start of zone 3
        
      if (digitalRead(A2) == HIGH)  //No CT signal to A0 (Track vacant)
  {
    delay(1);

    if (digitalRead(A2) == LOW) //CT signal to A0 (Track occupied) 

    {
      for(int j=1; j<=numBlink; j=j+1)
      {
        digitalWrite(green3, HIGH);
        delay(1);
        digitalWrite(red3, LOW);  //Turn on Red LED
        delay(wait2);
        digitalWrite(red3, HIGH);  //Turn off Red LED
        delay(wait2);
      }
      }
     
     {
       digitalWrite(red3, LOW);
     }
     {
      if (digitalRead(A2) == HIGH)  //No CT signal to A0 (Track vacant)
        digitalWrite(red3, HIGH);
        digitalWrite(green3, LOW);
    }
  
  }
  //End of zone 3
  //Start of zone 4
 
     
      if (digitalRead(A3) == HIGH)  //No CT signal to A0 (Track vacant)
  {
    delay(1);

    if (digitalRead(A3) == LOW) //CT signal to A0 (Track occupied) 

    {
      for(int j=1; j<=numBlink; j=j+1)
      {
        digitalWrite(green4, HIGH);
        delay(1);
        digitalWrite(red4, LOW);  //Turn on Red LED
        delay(wait2);
        digitalWrite(red4, HIGH);  //Turn off Red LED
        delay(wait2);
      }
      }
     
     {
       digitalWrite(red4, LOW);
     }
     {
      if (digitalRead(A3) == HIGH)  //No CT signal to A0 (Track vacant)
        digitalWrite(red4, HIGH);
        digitalWrite(green4, LOW);
    }
  
  }
  //End of zone 4
}

harrydeloach:
RR-Cirkits BOD8 and CT coils

What are those? Please post click-able links to the specs for them.

harrydeloach:
the wiring schematic

Please post that.

BOD-8-manual.pdf

Set of 8 CT (Current Transformer) coils for BOD-8. These 100:1 toroid coils sense the track current on leads passing through the hole in the middle of the coil. They connect to the BOD-8 with twisted pair cable such as CAT-3 or CAT-5 network cable.

That helps a little, thanks.

So the current transformers connect to the BOD and the BOD is connected to the Nano? Is there a common ground? Is the Nano supplying the BOD with 5V or do that share a common 5V supply?

In other words, can we have that schematic please?

There are many things that could be errors in your code.

  if (digitalRead(A0) == HIGH)  //No CT signal to A0 (Track vacant)
  {
    delay(1);

    if (digitalRead(A0) == LOW) //CT signal to A0 (Track occupied)

    {
      for(int j=1; j<=numBlink; j=j+1)

In this code, the for-loop cannot be reached unless A0 changed from HIGH to LOW during that tiny 1ms period. That sounds very unlikely to happen.

      }
     
     {
       digitalWrite(led31, LOW);
     }

Was there intended to be an “else” on that blank line?

     {
      if (digitalRead(A2) == HIGH)  //No CT signal to A0 (Track vacant)
        digitalWrite(red3, HIGH);
        digitalWrite(green3, LOW);
    }

Was that { intended to be after the if, so that the two digital writes always happen together?

It would help if you used Auto-Format on your code to correct the indentation. That would make it more readable for us and might help you spot your coding errors. Indentation is often a great way to spot where you have { and } in the incorrect places. It does not change the operation of the code in any way, just helps us humans.

From the BOD "manual":

The BOD-8 outputs lines are low during train detection so the TC-64 or other I/O
device should be configured as "Detector" for each port that is connected to a
BOD-8. This inverted input mode matches most types of detector outputs.

But what happens when no train is detected? Are the outputs pulled high or do they float? This is not described. If they float, pull-ups to 5V will be needed. The Nano's internal pull-ups should be OK, at least for testing.

Fritzing diagram for nano setup.

Can you describe what the circuit is supposed to do? I am not a train expert.

Right now, it sounds to me like when a train is detected by one of the coils, you want a signal to change from green to red, and when the train is no longer detecred, that same signal goes back to green. Each coil independantly controls a separate signal. Is that correct?

If that is correct, will the circuit have more complex functions controlling the signals later? Because if the function will always be this simple, no arduino is required. In fact it would be a waste of the arduino. A 74hc04 chip could do this, and does not require any programming.

You are correct. The only difference is that when the train enters the occupancy zone I have the red LED blinking 5 times and then goes to steady red as long as the zone is occupied. When the train leaves the zone, the red LED is turned off and the green turned on.

I eliminated the first ‘if’ and the (1) delay. It makes no difference. The sketch works well most of the time, but still doesn’t work all the time. I am currently in the progress of hard wiring everything to get rid of the breadboard because I suspect some of the problems is in the wiring.

Ok, if that does not fix it, post your updated code, auto-formatted, a proper schematic and maybe some bright, sharp pictures of the circuit.

I find that breadboards can be a reliable and stable way to prototype a circuit. But I use high quality breadboards, which I take good care of. I have also seen many examples on this forum of cheap breadboards, and breadboards that have been abused, causing many problems.

The only difference is that when the train enters the occupancy zone I have the red LED blinking 5 times and then goes to steady red as long as the zone is occupied.

OK then, an Arduino is probably the easiest way to achieve that. It would be very complex to achieve with simple logic chips like 74hc04.

However, you may need to re-code your sketch for the final version, in case more than one train is detected on different tracks in a short space of time. Right now, while those 5 blinks are happening, the Arduino cannot detect if another train is detected. But that can be achieved with some changes to the sketch. Maybe cross that bridge when you come to it :wink:

Actually, I have tested with two trains entering different detection zones, one after the other, and the system works on both zones. Also let one train sit on a zone with another entering and leaving another zone and the system works. I still have the problem of sometimes it works, other times not. Haven't finished hard wiring yet though.

Yes, but none of those tests is the scenario I described.

Completed hard wiring and installing the first zone signals today. Changed the (1) delay to (1000) delay for all 4 zones in the sketch and everything works perfectly (although only one zone working) now. Will add additional zones soon and will advise.