This node would read the duration of a short pulse on a digital input pin. The pulse is then copied to a digital output pin after a specified delay. The delay is based on the duration of the input pulse multiplied by a number.
Inputs
port…board port to read input signal from
input-number…“IN” multiplier to calculate delay before outputting signal
input-boolean…“H/L” High (true) or Low (false) Pulse Measure
input-pulse… “UPD” Triggers new read
Outputs
port…board port to write output signal to
output-number…“Time” duration of input pulse
output-pulse…Fires on writing complete
–
Extra info: rationale, edge-cases, details
This node is intended to intercept a trigger signal from teeth on a rotating wheel and to then output the same signal after a specified delay. (In an combustion engine crank signal pulses control ignition timing. By delaying the output the spark timing can be modified.)
In the case of zero delay then the output pulse could start immediately after the inlet pulse finishes.
This is my guess at what the layout would look like. The pulse-in node below by robertspark/components has the main elements for the pulse measurement. Suggestions on how to scaling the delay and writing the output signal would be much appreciated.
#pragma XOD error_raise enable
struct State {
};
{{ GENERATED_CODE }}
void evaluate(Context ctx) {
if (!isInputDirty<input_UPD>(ctx))
return;
const uint8_t port = getValue<input_PORT>(ctx);
if (!isValidDigitalPort(port)) {
raiseError(ctx);
return;
}
bool highLow = getValue<input_HU002FL>(ctx);
uint8_t value = 0;
if (highLow == 1)
{
value = 1;
}
else {
value = 0;
}
bool mSecs = getValue<input_mU002Fu>(ctx);
auto multi = 0.0;
if (mSecs == 1)
{
multi = 0.001;
}
else {
multi = 1.0;
}
emitValue<output_TIME>(ctx, pulseIn(port, value) * multi);
emitValue<output_DONE>(ctx, 1);
}
It seems to work ok for a typical crank sensors. The trace below is for 5% on @ 1 kHz frequency with a 2 x pulse duration offset for the repeated signal.
I think part of the problem is the UPD pin. It tells the node to ignore all other input unless there had been a pulse on the UPD pin. You want node to fire every time the physical input pin changes. You may need to create a separate read node and pass the value in to this node since nodes only “fire” when their input changes.
Thanks for the help gweimer, I will experiment some more.
The thing is that e the node reads measures the input pulses correctly but the corresponding output pulses are not registered. I guess it is something got to do with how many times the digitalwrite function can be called per second as when using lower input signal frequencies all output pulses are recorded. (as seen below)
Hi I tried adding digital-read to the input of the node.
It did not update probably as due to the digital read also having an UPD input. Is this the general idea of what was suggested?
It looks like the pulseIn function records ok without having to toggle UPD as long as the frequency is less than 200 Hz ( ~5 mS). Above 200 Hz it starts to miss pulses.
It seems that in XOD pulseIn can run 200 times a second where as in Arduino it can run thousands of times a second.
Would attaching interrupts be a better way to record high frequency pulses in XOD?
If crank is boolean like you have here, you can drop the UPD pin on your node. Node will only “fire” when one of the input pins change (like value for crank).