I want to convert a frequency on 4 inputs simultaneously to a flow rate and log it to an SD card with a time stamp. My concern is if arduino is capable of doing this taks in a reliably way. The flow meters input voltage is 12 V, so I assume that the output voltage output is 12 V with a given frequency that I want to measure and convert to a fuel flow. So far I have calculated a frequency at about 5,6 kHz at a fuel flow of 1060 L/h with an assumption of 320 [pulses/L].
My question is whether it is possible to use Arduino to log the fuel flow by counting on/off cycles (or any other way) on 4 digital inputs simputaneously. The logging should be saved to a format that can be imported to excel, containing:
Time - Flow1 - Flow2 - Flow3 - Flow4
From the manual:
The flowmeter's transmitter contains a microprocessor that linearizes the output signals, and temperature corrects the flow rates to provide accurate fuel flow and fuel temperature data. The flowmeters connect directly to the Hand-Held Monitor. This monitor displays fuel flow and fuel temperature information. Two output signals are available from the flowmeter. One output is a digital signal that communicates directly with the Fuel Flow Monitor. A Fuel Flow Communicator may be used in place of Fuel Flow Monitor for communicating with DataView. The other output is a frequency signal that will communicate directly with DataView using a xxx-yyyy Cable.
The flowmeters use two rotating gears driven by fuel flow. Magnets imbedded in the gears activate a non-intrusive sensor, which generates a pulsed output signal. Each pulse represents a known volume of fuel that is captured between the lobes of the gears. The temperature of the fuel passing through the flowmeter is also measured by the non-obtrusive sensor. Both pulse and temperature data are sent to a microprocessor in the flowmeter's transmitter. The pulse data is then compensated for temperature and linearized to provide an accurate output signal.
K-Factor
The K-Factor, expressed in units of pulses per gallon (PPG) and pulses per liter (PPL), is stamped on the flowmeter's nameplate, as shown in Illustration 8. This represents the number of pulses per gallon of #2 diesel fuel and is temperature compensated to 16°C (60°F), API.
Communicating With Other Devices
For interfacing the Flowmeter's frequency output to other devices: Frequency output is an NPN transistor that is an open collector output. Pull-up the output through a resistor to a 9-36 VDC. The maiximum sinking current is 50mA at 36 VDC. Choose a minimum sinking current of 100 mA by the selection of the pull-up resistor and Voltage to achieve a turn-off Voltage of <0.5 VDC (transistor saturated). This provides fuel flow information, but no fuel temperature information.
(I find this part a bit confusing. First, the max. sinking current is 50 mA at 36V, then one must choose a minimum sinking current of 100 mA by a pull-up resistor?)
The Arduino will be able to count pulses on four inputs at those frequencies without any problems, as long as they are 5V level signals. If your device presents 12V digital signals as you suggest, you could use a voltage divider to drop these down to 5V. However you do it, you will need to produce a 5V signal for the Arduino to read.
You will need to decide how often to log the pulse rates. Presumably you will do this on a timed basis and not log every single pulse. In that case you have full control over how much data gets logged so as long as you don't try to log hundreds of thousands of samples per second there should not be any performance problems.
I don't want to log the pulses as such, I want to count them and mathematically convert then to a flow rate and log that value.
Flow rate should be logged each second to the SD card. And it should be with high accuracy as it is for a verification porject for fuel saving. About the voltage level, I plan to use a voltage devider, two resistors of :
+12-->1667 Ohm --- 1000 ohm --> GND if that makes sense.
|
Arduino input
If this is for use in a vehicle, you need to remember that the vehicle's nominal 12V supply can be extremely noisy and may be substantially above 12V. The Arduino can be damaged by voltages that are outside the 0-5V range so make sure you condition the signal if necessary to protect the Arduino, and also filter the power supply against spikes, shield all signal wires and use an electromagnetically sealed enclosure (that the shielded wires are grounded to) aka metal box.
So far I have calculated a frequency at about 5,6 kHz at a fuel flow of 1060 L/h with an assumption of 320 [pulses/L].
1060 litres X 320 pulses in 3600 seconds
= 339200 pulses in 3600 sec
= 94.22222 Hz @ 1060L/h
You didn't specify the K factor, but it calculates to be K = 94.222 (pulses/L)
My question is whether it is possible to use Arduino to log the fuel flow by counting on/off cycles (or any other way) on 4 digital inputs simputaneously.
Yes, I also realized that I make a calculation error. I'm not sure about the K-factor as it is stamped on the flowmeter/transmitter housing and the meters are currently on a vessel in the north sea. I just assumed 320 p/L, but it's propably more like 234, which gives a frequency of 64-ish. I'm going on board to do some fuel tests and would like to have the possibillity to log fuel flow.
Thanks a lot for that code, I will review it and see if it fits my needs! I sure hope so. Does it have SD card logging or can it be achieved easily?
By the way, I should explain my setup and test procedure a bit.
I am testing fuel consumption of 2 marine engines of 2.35 MW pulling a 2240 kW generator each. One will be run in variable speed and one in constant speed and the fuel consumption will be compared.
Each engine has seperate supply and retuen lines, but are supplied from the same fueltank. Each line has its own floe meter. What I am interested in is the burn rate, meaning the difference between supply and return line. Accuracy is key and should be within 0,5%. I want to be able to log all flow rates to the same timestamp in an excel/csv/text file. Total burnrate over time for each engine must also be logged directly or at least I should have the possibillity to calculate it after test completion.
Since you only seem to want to know the total fuel consumption in a one-off test, my naive solution to this problem would be to fill the tank before the test and measure how much fuel you need to add to re-fill it afterwards. That will be far simpler and more accurate than any dodgy DIY solution with unknown calibration errors.
Aside from any inherent inaccuracies in the flow sensors and your calibration of them, how are you defining fuel flow? Fuel consumption is often measured in terms of fuel weight, but you're measuring volume. Fuel expands considerably with heat, and it will probably be getting very hot in your closed loop fuel system. Are you going to measure the temperature at the flow meter and try to estimate the effects of fuel expansion?
Communicating With Other Devices
For interfacing the Flowmeter's frequency output to other devices: Frequency output is an NPN transistor that is an open collector output. Pull-up the output through a resistor to a 9-36 VDC. The maiximum sinking current is 50mA at 36 VDC. Choose a minimum sinking current of 100 mA by the selection of the pull-up resistor and Voltage to achieve a turn-off Voltage of <0.5 VDC (transistor saturated). This provides fuel flow information, but no fuel temperature information.
(I find this part a bit confusing. First, the max. sinking current is 50 mA at 36V, then one must choose a minimum sinking current of 100 mA by a pull-up resistor?)
The minimum sinking current looks like a misprint and is more likely 100 uA. No matter, as long as after selecting an appropriate pull-up resistor, the low level of the pulse voltage is less than 0.5 VDC. If you're using a 3.3V Arduino Due, a pull-up of around 2.2K would give 1.5 mA (most of the Due's outputs are rated for 3 mA). If you're using a 5V Arduino then the same pull-up @ 5VDC would provide around 2.2 mA sinking current.
By the way, I should explain my setup and test procedure a bit.
I am testing fuel consumption of 2 marine engines of 2.35 MW pulling a 2240 kW generator each. One will be run in variable speed and one in constant speed and the fuel consumption will be compared.
Each engine has seperate supply and retuen lines, but are supplied from the same fueltank. Each line has its own floe meter. What I am interested in is the burn rate, meaning the difference between supply and return line. Accuracy is key and should be within 0,5%. I want to be able to log all flow rates to the same timestamp in an excel/csv/text file. Total burnrate over time for each engine must also be logged directly or at least I should have the possibillity to calculate it after test completion.
The volume accuracy will always be as accurate as the flow meter specification as long as no pulses are missed. However, the flow-rate is determined by using polling and measuring the pulse period. So there would be a +/- timing error or jitter which is non-accumulative. Note that measuring the period over 2 pulses would reduce this jitter by 50%. As it stands, the polling method is well within 0.5% timing error, however as you add code for data logging to SD card or other, this would change.
Connecting an accurate frequency from a pulse generator would reveal the overall accuracy, stability and determine if using interrupts is neccessary.
@PeterH
I am not making a on-off test, I am making several tests for validating new fuel saving technology in the marine sector. The flow emters I have cost over 20.000 USD per set and the tests are performed on a vessel with a fuel tank of 3400 m3 and over 10 MW of power. My problem is that the flow meters currently does not allow for PC logging, but only manual readings. This is what I am trying to make. The flow meters are accredited by a certified calibration body like NIST (however it is not NIST).
The tank method is a bit too crude for this purpose
I intend to use a 1000 ohm resistor from GND and a 1667 ohm resistor to NPN out as the voltage divider on the input to the arduino, which would be connected between the resistors, that would give me 4,5 V on the arduino input.
I'm planning on using an Uno or a MEGA2650 or maybe the new YUN which has SD card and ETHERNET and WIFI.
I have a signal generator which I can test it with. This will be my weekend project! I would like to build it to a proper system that enables inputs from 8 flow meters, supply and return on 4 engines, and logs the data either to an SD card or directly to a PC over serial, USB or ethernet and has a software interface on the PC.
I think this is a great project with real valuable use, but also quite a mouthful for me as I am by no means an expert in the programming part. But it will be a challange and I like challanges.
Looks like you're dividing down from 12V for the transistor. The values look OK (there'll be another resistor needed in series with the base).
To get started with the sample code, all that's needed to convert this to 8 flow meters is delete several inputs from the inputs[] array. Then edit the pulseConstant[] array with each flow meter's constant.
Note that there is a built in pulse generator for convenience and you can view results on the serial monitor.
It looks to me as if you and dlloyd have got the input signal conditioning part of the problem well in hand. That is the hardest part of the problem - the software will be relatively simple.
zenseidk:
The tank method is a bit too crude for this purpose
It can be as accurate as you want it to be, but I can understand that it's not exactly convenient when your engines need to be supplied from a humongous fuel tank.
Are you definitely measuring fuel consumption in terms of volume flow? How are you addressing the issue of thermal expansion of the fuel?
From the first post, I see it mentions that the device already compensates for temperature.
Are you definitely measuring fuel consumption in terms of volume flow?
I hope you don't mind, but here's an answer based on my experience (not with flow meter pulses) but with other measurement devices.
The fuel consumption is easily determined by just monitoring a running total of the pulses. Each pulse represents a specific volume consumed. The accuracy of this volume is 100% determined by the device and not the software code, as long as all pulses are counted.
The flow rate is determined by using the Arduino to measure the time interval between each pulse.
So, there is 2 types of information that the pulses provide. Conversion of flow rate to determine fuel consumption is unnecessary and prone to additional errors.
dlloyd:
From the first post, I see it mentions that the device already compensates for temperature.
Sorry, I had completely missed that. That resolves all the concerns I had about the sensors.
From the software side, as far as I can see, all that's need is a count of the number of pulses in each direction, held in a big enough variable to avoid overflows, with a bit of logic to reset the counts and subtract them when necessary to get the net fuel flow.
If it is necessary to calculate deltas over a time period I'd record the values at the start of the period and subtract them from the values at the end of the period - this avoids any potential race conditions involved in zeroing counters. I'd look at the maximum signal frequency to decide whether to use interrupts or poll the sensors.
I have gotten the program to work pretty good, but I have some issues that are related to my limited programming skills. I've managed strip away parameters I don't need and set up datalogging to the SD card. I'm currently working on getting a time stamp in. I have only managed to log 2 parameters which are both from the same input. How can I calculate and log from several inputs simultaneously? When I connect 2 inputs, I get very irregular loggings which switch between the two inputs at what seems to be random sequence, but only loggings for one input at a time.
Also, I want to have columns with titles only printed once at startup. How do I do this?
I have attached the program with the progress so far.
As it stands, for any input that rises, testing and printing would occur at the same time. The printing would be for whatever test meets the "rising" condition after a 1000 ms update interval. This timeout sets the print update interval, but note that most test results are ignored. For example, if the input is at 20 Hz, then every 20th test will be printed due to the 1000 ms update interval.
The random nature of what is printed is not due to the update interval, it is because the inputs would never be in sync, so any input can start a test at any time.
It can be determined which input has risen by looking at the "i", so I guess more conditions would be needed to print them in order.
Since this is using a polling method, it would be beneficial to increase the baud rate. Otherwise, its possible to print smaller pieces of information at a time.
In the attached file, I've made some minor changes to improve performance - Serial.begin(57600), longs changed to unsigned long, micros() used instead of millis().
Thanks a lot for that. I've now built in date and time into both serial print and SD print. I've been sitting here all day and my head is about to explode with programming I think I've made great progress so far. This is my biggest project so far and I'm learning a lot of programming.
To be sure I understand the method that the program is calculating the flow rate, it measures the time period for one single period once every defined timeinverval (1000 ms in my case) and calculates the flow from that. Correct?
I'm still not sure how I distinguish the inputs from each other in the program when I want to send the calculated value for each input to the SD and serial monitor.
I will check your corrections tomorrow, my head is filled to the brinck right now... I'm going to sleep.
To be sure I understand the method that the program is calculating the flow rate, it measures the time period for one single period once every defined timeinverval (1000 ms in my case) and calculates the flow from that. Correct?
It calculates everything for an input each time it rises. Therefore, if there are 4 inputs at 20 Hz, then there are 80 sets of calculations per second. The defined time interval (in your case 1000 ms) allows you to skip readings to slow down or lower the number of results to print. If needed, there are many more readings available to work with for things like averaging, etc.
I'm still not sure how I distinguish the inputs from each other in the program when I want to send the calculated value for each input to the SD and serial monitor.
All results are in arrays, so printing results from specific inputs is just a matter of reading the required index.
Here, this code snippit would cycle through and print all inputs:
// if the file is available, write to it:
if (dataFile) {
for (int i = 0; i < qty; i++) {
dataFile.print("FlowRate; ");
dataFile.print(flowRate[i], 3);
dataFile.print(", ");
dataFile.print("TotalVolume: ");
dataFile.println(totalVolume[i], 6);
}
dataFile.close();
}
However, I'm not sure how long this would take. If it takes longer than the time to test an input, then input pulses would be missed and cause erroneous readings. I'm starting to think the use interrupts might be needed.
Hi, just looking at the code.
If you are going to save data and import it into say Excell, why are you wasting time doing calculations that Excell can do later.
Just a thought, store time stamp and pulse period, the calculated parameters all rely on using known CONSTANTS that can be done externally.