Hi!
I am currently working on project aiming at connecting fuel meters, etc to the NMEA2000-network in my boat.
A part of the work is to create a simulators for the used devices. My first task is to emulate the flow meters.
They transmit pulses of which is proportional to the volume of fuel passed. The boat is equipped with two diesel engines, so four meters are needed.
In my development environment I've got one Teensy 4.1, running the target application and one Teensy 4.0 used
as an emulator for the real world devices. My concern here is the emulation of the flow meters. I am creating pulses
by using the PWM-functionality on the Teensy 4.0. When these pulses are sent to the Teensy 4.1 of the development environment everything is working as expected.
However, when a activate the target environment which is a Teensy 4.0 the pulse rates are different from the Teensy 4.1 and varies with time.
Please compare the outputs recorded in the files: PulsesTrace_from_Teensy4.0 and PulsesTrace_from_Teensy4.1.
The set PWM-frequencies are: 100, 80, 120 and 100Hz. This is seen in the output from the Teensy 4.1, but twice as
large due to the parameter CHANGE in the 'attachInterrupt'-function.
In the real world the flowmeters are driven by 12V, so therefore I let the generated pulses from the Teensy 4.0 pass
a logical voltage shifter to get the signal up to 12V. At the other end the opposite is done to get it back to 3.3V.
Furthermore, I measuring the pulses with a scope as they leave the emulator Teensy 4.0 and when arriving at the target Teensy 4.0 (3.3V side).
As can be seen in the output from the scope (Screenshot from 2022-03-22 11-50-22.png) these two frequencies are the same, 100Hz. The green colour are at the target side and the yellow at the emulator side.
Another difference is that the Teensy 4.0 uses an external SD-card reader, but on the Teensy 4.1 the builtin ditto is used.
I've provide some code related to the pulse counting instead of providing the complete code, which probably would be
too heavy to digest.
Finally, I have no idea what additional information may be of interest in order to pin this problem down.
Any responder please let me know and I'll supply it ASAP.
Rgds,
Göran
I am currently working on project aiming at connecting fuel meters, etc to the NMEA2000-network in my boat.
A part of the work is to create a simulators for the used devices. My first task is to emulate the flow meters.
They transmit pulses of which is proportional to the volume of fuel passed. The boat is equipped with two diesel engines, so four meters are needed.
In my development environment I've got one Teensy 4.1, running the target application and one Teensy 4.0 used
as an emulator for the real world devices. My concern here is the emulation of the flow meters. I am creating pulses
by using the PWM-functionality on the Teensy 4.0. When these pulses are sent to the Teensy 4.1 of the development environment everything is working as expected.
However, when a activate the target environment which is a Teensy 4.0 the pulse rates are different from the Teensy 4.1 and varies with time.
Please compare the outputs recorded in the files: PulsesTrace_from_Teensy4.0 and PulsesTrace_from_Teensy4.1.
The set PWM-frequencies are: 100, 80, 120 and 100Hz. This is seen in the output from the Teensy 4.1, but twice as
large due to the parameter CHANGE in the 'attachInterrupt'-function.
In the real world the flowmeters are driven by 12V, so therefore I let the generated pulses from the Teensy 4.0 pass
a logical voltage shifter to get the signal up to 12V. At the other end the opposite is done to get it back to 3.3V.
Furthermore, I measuring the pulses with a scope as they leave the emulator Teensy 4.0 and when arriving at the target Teensy 4.0 (3.3V side).
As can be seen in the output from the scope (Screenshot from 2022-03-22 11-50-22.png) these two frequencies are the same, 100Hz. The green colour are at the target side and the yellow at the emulator side.
Another difference is that the Teensy 4.0 uses an external SD-card reader, but on the Teensy 4.1 the builtin ditto is used.
I've provide some code related to the pulse counting instead of providing the complete code, which probably would be
too heavy to digest.
Finally, I have no idea what additional information may be of interest in order to pin this problem down.
Any responder please let me know and I'll supply it ASAP.
Code:
// Used pins.
#define PrimaryBBFlowmeterPin 2
#define ReturnBBFlowmeterPin 3
#define PrimarySBFlowmeterPin 5
#define ReturnSBFlowmeterPin 6
#define DS18B20Pin 4
// Definition of the struct holding the parameters for a fuel stream.
typedef struct FuelStreamCtrl
{
void (*PulseCntrFunc)(void); <---- Called interrupt function.
int volatile PulseCount;
int PulseCntPin;
unsigned long long DS18B20Id;
unsigned long PreviousMillis;
double NozzleDiameter,
FlowInStream,
PulseRate,
Temperature,
ElapsedTime;
}FuelStreamCtrl_t;
// Interrupt functions one for each fuel stream.
void ReadBBFlowMeterPrimary(void)
{
cli();
FuelStream[PrimaryBB].PulseCount++;
sei();
}
void ReadBBFlowMeterReturn(void)
{
cli();
FuelStream[ReturnBB].PulseCount++;
sei();
}
void ReadSBFlowMeterPrimary(void)
{
cli();
FuelStream[PrimarySB].PulseCount++;
sei();
}
void ReadSBFlowMeterReturn(void)
{
cli();
FuelStream[ReturnSB].PulseCount++;
sei();
}
// +++++++++ Define the flow stream parameters +++++++++.
FuelStream[PrimaryBB].PulseCntrFunc = ReadBBFlowMeterPrimary;
FuelStream[PrimaryBB].DS18B20Id = PrimaryBBDS18x20SensorId;
FuelStream[PrimaryBB].PulseCntPin = PrimaryBBFlowmeterPin;
FuelStream[PrimaryBB].NozzleDiameter = NozzleDiameter[CurrentlyUsedNozzle];
FuelStream[PrimaryBB].PreviousMillis = millis();
FuelStream[ReturnBB].PulseCntrFunc = ReadBBFlowMeterReturn;
FuelStream[ReturnBB].DS18B20Id = ReturnBBDS18x20SensorId;
FuelStream[ReturnBB].PulseCntPin = ReturnBBFlowmeterPin;
FuelStream[ReturnBB].NozzleDiameter = NozzleDiameter[CurrentlyUsedNozzle];
FuelStream[ReturnBB].PreviousMillis = millis();
FuelStream[PrimarySB].PulseCntrFunc = ReadSBFlowMeterPrimary;
FuelStream[PrimarySB].DS18B20Id = PrimarySBDS18x20SensorId;
FuelStream[PrimarySB].PulseCntPin = PrimarySBFlowmeterPin;
FuelStream[PrimarySB].NozzleDiameter = NozzleDiameter[CurrentlyUsedNozzle];
FuelStream[PrimarySB].PreviousMillis = millis();
FuelStream[ReturnSB].PulseCntrFunc = ReadSBFlowMeterReturn;
FuelStream[ReturnSB].DS18B20Id = ReturnSBDS18x20SensorId;
FuelStream[ReturnSB].PulseCntPin = ReturnSBFlowmeterPin;
FuelStream[ReturnSB].NozzleDiameter = NozzleDiameter[CurrentlyUsedNozzle];
FuelStream[ReturnSB].PreviousMillis = millis();
void SetUpPinIrpts(void)
{
FuelStreamIdx_t Idx = FirstFuelStreamIdx;
while(Idx < NbrOfFuelStreams)
{
// Set the digital pin as input.
pinMode(FuelStream[Idx].PulseCntPin, INPUT_PULLUP);
delayMicroseconds(100);
// Define the function to handle the interrupt.
attachInterrupt(FuelStream[Idx].PulseCntPin, FuelStream[Idx].PulseCntrFunc, CHANGE);
Idx = FuelStreamIdx_t (Idx + 1);
}
}
Rgds,
Göran