chipstastegood
This may be a simple question to answer.

I have a flow meter sensor, specifically this one: https://www.adafruit.com/products/833

The recommended way to read from this sensor is to connect it to an input pin on an Arduino that supports IRQ. I'm using Arduino Mega so I have several input pins that support IRQs. The sensor itself outputs a pulse as it spins to detect flow (485 pulses per litre).

So when programming this using the standard Arduino IDE, it's a simple IRQ handler that increments a variable and counts how many pulses have been received over time.

My question is, when I use OpenPLC to write an algorithm to read from this same sensor, how do I handle triggering my code on an interrupt?

I know that I can define a task to run on an "Interrupt" (as opposed to "Cyclic"). However, will this do what I want? How would the task know to run when a pulse comes in on a specific input?

Related to this, if I have 5 sensors like this, do I need to create 5 different tasks to read from them?

Thanks!

Quote 0 0
thiagoralves

Although the PLCOpenEditor supports the creation of new tasks, currently OpenPLC only supports the main cyclic task. The other tasks you create will just be ignored. One way to do that is to slightly modify the actual arduino firmware in order to do the readings and save that in one of the analog input buffers (as if it was coming from an analog read). Just create an IRQ handler to increment a global unsigned int called pulse_count, that counts your pulses. Then, inside the updateInputs() function, in the second for loop (line 130), change it to something like this:


for (int i = 0; i < sizeof(pinMask_AIN); i++)
{
  if (i == 0)
  {
    input_data.analog[i] = pulse_count;
  }
  else
  {
    input_data.analog[i] = analogRead(pinMask_AIN[i]) * 64;
  }
}


That way, your first analog input (%IW0 on OpenPLC) will be holding your pulse count, while the other inputs will be your analog inputs. You can use this same approach to include as many pulse counters as you want.

Quote 1 0
chipstastegood
Oh I see. So I'd have to modify the OpenPLC Arduino firmware to do this.

I am new to OpenPLC firmware and modifying. Where would I get the source code for this? I looked at the ZIP files for Arduino input, output, and CPU but not sure what those are used for.

In my system, I will have a Raspberry PI where all the logic will be plus an Arduino board for I/O only.
Quote 0 0
chipstastegood
The Arduino board I am going to use for I/O is an Arduino Mega (perhaps overkill but I wanted to make sure I had enough I/O pins since I need lots of inputs and outputs).
Quote 0 0
thiagoralves
Just go to the Arduino page on the "getting started" section.
http://www.openplcproject.com/getting-started-arduino
Quote 0 0
chipstastegood
Ok got it! That was easy.
Quote 0 0
darrylb123
Hello,
I am using a pulse flowmeter much like chipstastegood and the suggestion works fine. I need to be able to reset the count from within openplc so I tried using the holding register of AOUT 0. So that logic in openplc could write a reset value. I only ever read 0 from the hreg. I also update AIN 0 and that comes through.
for (int i = 1; i < NUM_HOLDING_REGISTERS; ++i) // Don't write AO0
{
analogWrite(pinMask_AOUT[i], (modbus.Hreg(i) / 256));
}
modbus.Hreg(0,count);
modbus.Ireg(0,count);

Does openplc read it's own internal buffers for modbus AOUT, rather than reading the slave value?
Quote 0 0
thiagoralves
I think the easiest way to do this is to have the reset logic on the Arduino itself. Just use one of the coils outputs to serve as a triggering logic to reset the pin. Suppose you decide to use coil 0 for this, then just add a line in the loop at the end, something like this (not tested):
if (modbus.Coil(0) == 1)
{
    count = 0;
}

Then every time you set your coil 0 (QX100.0) to true on your ladder logic, your count variable will be reset.
Quote 0 0