Coil Read Function Jumping to Threshold Value?

I'm trying to use a coil to sense DCC current (which in this context is similar to AC), to tell me when a certain section of my model train track is occupied. False negatives don't matter, as the program will keep checking until it gets a positive. The coil is wired in as per below:

The blue wire attached to the green wire through the coil goes from the track bus to the section of track in question. The wires from the coil board go to the +5V from the Arudino, the gnd of the arduino and pin A0 of the Arduino. The latter is defined in my code as OCC_PIN.

Whenever it reaches the section of the code where the coil is read, I get a false positive almost immediately. This is what puzzles me, as I've run a test sketch on this coil, in this exact configuration. When I ran it, I saw that it showed a reading of 0 until a loco was placed on the tracks (to complete the circuit).

In the actual program, which automatically switches power to the correct turntable track for the locomotive I'm currently running, I have a function which reads the coil. It returns true if the reading is above a certain threshold, and false otherwise:

boolean readTrack(){
  /* Reads the current sensor on the wire between the
   *  track bus and the relay bank.  This will sense if
   *  there is a locomotive present.
   */
  int readVal = analogRead(OCC_SENSOR);
  disNumLed(readVal);
  if (readVal >= 6){
    return true;
  } else {
    return false;
  }
}

The disNumLed function takes a number and displays it on a LED display on the control panel. Now here's where it gets weird. After I put in the line to display the value of readVal, I saw that the value being read wasn't actually the value from the coil. Originally, the readVal variable was being compared to >= 5 in the if statement. When that was the case, the number that was displayed on the LED display changed to 5 after a few calls to the function (from the main loop). After I changed it to 6 (as per the above code), the number that it jumped to was a 6. In all of these cases, there were no locomotives on the track, so it should have been reading 0 for the whole thing, rather than jumping to the exact value required to return a false positive. Given that it's jumping to the comparison value, I suspect this is a problem with the programming somehow, rather than one with the sensor. Can someone please shed some light on what's going on?

Here's the full body of my main loop() function, if that will help. The readTrack() function is only called in the if(arriveMode) if statement.

void loop() {
  // put your main code here, to run repeatedly:
  //Check if the buttons have been pushed.
  clockwButton.tick();
  cclockButton.tick();
  memButton.tick();
  /* Has a loco been selected?  If so, and it's not 0, then get the loco track.
   *  getLocoTrack returns -1 if that loco address isn't in the array of locos
   *  around the turntable.  Need to check for this at some point.
   */
  if (baseET.receiveData()){
    //We've received data from the base station.  A loco has been called.
    if ((baseData.controllerID == -1) && (baseData.locoAddress != 0)){
      //ControllerID of -1 is used to indicate it's for the staging controller.
      //Handset sends out an address of 0 on startup  - need to ignore it.
      currLoco = baseData.locoAddress; //set the current loco address
      /* Check if the locomotive should be in the turntable.  -1 from the
       *  getLocoTrack function indicates it's one of the BVLC locos.  I.e. 
       *  it's not the PRM one.  If it's equal to the value in locoOut, then
       *  it's the BVLC loco in staging, and doesn't need any action taken.
       *  
       *  Remember, the turntable bridge will be aligned with the exit track
       *  by default.
       */
       currLocoTrack = getLocoTrack(currLoco);
    }
  }
  if ((!arriveMode) && (!departMode)){
    //Then we're listening to see if a departure or arrival will occur.
    if ((currLocoTrack > 0) && (trackOccupancy[currLocoTrack])){
      /*Then we've received an address that's around the turntable, and the
       * loco is on its track.  Needs to depart.
       * 
       * Also, arriveMode needs to clear these variables at the end to prevent
       * false triggering.
       */
       departMode = true;
       disNumLed(currLoco);
    }
    if ((currLocoTrack > 0) && (readExit())){
      /* Then the incoming loco is valid, and it has tripped the sensor
       *  on the exit track.
       */
       arriveMode = true;
       disNumLed(currLoco);
    }
  }
  if (departMode){
    /*  Then a loco is departing.  By this point, we already have the following
     *   information:
     *   - Loco address
     *   - Track number
     *   - That loco is around the turntable
     */
     //Turn on track power, if not already on.
     if (!trackPowered) {
      setTrackPower(currLocoTrack, true);
     }
     //Turn off and reset when exit track sensor is tripped.
     if (readExit()){
      //Turn off power
      setTrackPower(currLocoTrack, false);
      //Record occupancy status and save it
      trackOccupancy[currLocoTrack] = false;
      saveOccupancy();
      //Turn off LED display
      dispLED.clearDisplay(0);
      //Exit departure mode
      departMode = false;
      //Pause to allow loco to clear sensor
      progRest();
     }
  }
  if (arriveMode){
    /*  Then a loco is arriving.  By this point, we already have the following
     *   information:
     *   - Loco address
     *   - Track number
     *   - It is on the turntable bridge.
     */
     //Turn on the track power, if it isn't already
     if (!trackPowered){
      setTrackPower(currLocoTrack, true);
     }
     //Listen to see if loco has just arrived on the track
     if (readTrack() && trackPowered){
      //Then the loco has just arrived on the track.
      progRest();
      /* It's now been 30 seconds since the locomotive arrived.  
       *  Turn off track power and reset.
       */
      setTrackPower(currLocoTrack, false);
      //Record occupancy status and save it.
      trackOccupancy[currLocoTrack] = true;
      saveOccupancy();
      //Turn off LED display
      dispLED.clearDisplay(0);
      //Clear variables to prevent false triggering
      currLoco = 0;
      currLocoTrack = 0;
      //Reset flags
      arriveMode = false;
     }
  }
}

Hi,

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Can you post link to specs/data of the current transformer please?

Thanks.. Tom.... :slight_smile:

Hi,
If you current transformer gives a output of 1/2 Vcc or 2.5Vdc, then the reading will be, zero current at 512 count.
So the;

  if (readVal >= 6)

will always be true.

Tom... :slight_smile:

When I tested it, I got readings of 0 with an open circuit (no locomotive), and readings of >=5 when there was a locomotive on the track. That was with a test sketch that just took a reading from the analog pin and showed it on the LED display. Exactly the same wiring, which is just three wires. VCC to the +5v output from the Arduino, gnd to the ground of the Arduino, output to pin A0.

Do you have a link to the sensor?

Is it this?
http://henrysbench.capnfatz.com/henrys-bench/arduino-current-measurements/ta12-100-arduino-ac-current-sensor-tutorial/

What do you measure with a DVM AC voltage?

I haven't followed any tutorials for it, and I'm not sure what you mean by DVM AC voltage. It's the first time I've used one of these sensors, and all I am trying to do is detect if there is a current, or if there is not a current. That's all. If there is a current, then there's a train on the tracks, and if not, then no train.

The function literally just reads the analog value from the coil and makes a decision from that. I'm not trying to do anything fancy.

Hi,
What do you measure Vac and Vdc on the output pin of the transformer, with no current flowing?

Current transformer spec/data please?

Thanks.. Tom.. :slight_smile:

Take an AC volt meter (DVM) and measure the output voltage of the sensor when current is flow through your green wire.

I can take that reading, but I'm a little confused. The problem is that it is giving a false positive when there is no current through the green wire - it's an open circuit.

We need to understand what your sensor is doing and what it is designed to do.

Time here to sleep, Australia can take over. :sleeping:

Hi

Current transformer spec/data please?

Or where did you buy it?

Tom... :slight_smile:
PS. Once we know the type of sensor, we can then explain how to use it.

I was trying to look through my emails to find where I’d ordered it. I’d actually bought it locally, and I’ve been able to track down the specs. It’s an Octopus Non-Invasive AC Current Sensor, which I believe are referred to as ‘Linker’ when sold by Jaycar Electronics here in Australia. The specs are here: https://www.elecfreaks.com/wiki/index.php?title=Octopus_Non-invasive_AC_current_sensor_(TA12-100)_Brick. According to the markings on the coil, it’s a TA12-100 (not the others listed in the table), and also has the markings ‘1 SGS 3’ below the model number.

I also found a page a little while back outlining how to use these coils with an Arduino for DCC voltage - DCC - Current Sensing. I was a bit hesitant about using this circuit, though, as it doesn’t say if the output is analog or digital (although I suspect it’s the latter) and it requires modification of the Octopus board. But given that a simple AnalogRead doesn’t seem to be working, I may have to give this a try.

You need further hardware. You are taking an AC current sensor and feeding AC to the Arduino pin unless you have other components off picture?

If not, you require to rectify the AC to DC using a diode etc as per the diagram on the example site you mentioned. The description on that site shows the board in your picture as only containing the transformer and the ‘burden’ resistors which you need to remove. There is no rectification on the board according to the site. The other links to sensors site return dead.

I would also suggest you reduce the number of turns of your wire coil down to 2 or 3 and experiment from there. Test the output with a DVM and make sure it doesn’t go above 5v in its raw state.

But if the coil is powered by a 5V supply, wouldn't it not go above that? I thought the coil was sensing current, not generating it.

The basic premise is, you are trying to measure an AC current and return a suitable DC signal voltage to be measured by the Arduino pin.

Can you answer the component questions please, that would eliminate any confusion.

I was going by the information on the site you posted the link to. It mentions the resistors and that the modules don't use the V pin. Just why I haven't established. reading the site.

I don't have any extra components off-picture. Just direct connections to A0 and the power supply. That link I provided is something I'm considering as a possible solution.

You didn't answer my question regarding any other components on the board just to verify it is a raw transformer.

Not to insult, but you do understand the premise of AC to DC is required? The Arduino pin requires up to 5v DC to give a measurement.

What does a DVM show as voltage on the pin to A0

I think I'm learning that now. It is the first time I've used one of these things. And yes, there is just a direct connection to pin A0 on the Arduino, with no additional components.

OK let's approach it this way. You need a voltmeter (DVM) or multimeter to read the output voltage being supplied to A0 by your module. Either AC or DC. (edit: establish whether it is)
Both without and with a train on your track section. This is just to establish exactly what you are getting from the module. No point trying to read it in software if it doesn't match your expectations.

I took those readings earlier. Didn't get anything with DC voltage. With AC voltage, I got a maximum of 2v without a train, and 36v with a train.

I know I'm missing something here. The way the module was packaged, I was under the impression it could be plugged straight in :(.