# \[I want a node\] Digital signal repeater

**URL:** <https://forum.xod.io/t/i-want-a-node-digital-signal-repeater/3397>\
**Category:** XOD Programming Questions\
**Created:** [January 31, 2020, 11:33pm UTC](https://forum.xod.io/t/i-want-a-node-digital-signal-repeater/3397 "2020-01-31T23:33:46Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![williamobrien-sk](https://avatars.discourse-cdn.com/v4/letter/w/74df32/32.png) [@williamobrien-sk](https://forum.xod.io/u/williamobrien-sk)\
**Post date:** [January 31, 2020, 11:33pm UTC](https://forum.xod.io/t/i-want-a-node-digital-signal-repeater/3397/1 "2020-01-31T23:33:47Z")

</div>

## Digital I/O pulse repeater

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

1. port…board port to read input signal from
2. input-number…“IN” multiplier to calculate delay before outputting signal
3. input-boolean…“H/L” High (true) or Low (false) Pulse Measure
4. input-pulse… “UPD” Triggers new read

### Outputs

1. port…board port to write output signal to
2. output-number…“Time” duration of input pulse
3. 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.)

 ![delay pulses](https://canada1.discourse-cdn.com/flex027/uploads/xod/original/2X/0/0155db685542684cd1e2c7a5119bf5cd376092f1.png)

In the case of zero delay then the output pulse could start immediately after the inlet pulse finishes.

![block](https://canada1.discourse-cdn.com/flex027/uploads/xod/original/2X/8/85dad7aceed42bbf15fe918d00dce262a7d2c896.png)

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.

```auto
#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);
}

```

---

<div class="post-metadata">

**Author:** ![williamobrien-sk](https://avatars.discourse-cdn.com/v4/letter/w/74df32/32.png) [@williamobrien-sk](https://forum.xod.io/u/williamobrien-sk)\
**Post date:** [March 4, 2020, 7:14pm UTC](https://forum.xod.io/t/i-want-a-node-digital-signal-repeater/3397/2 "2020-03-04T19:14:32Z")

</div>

This arduino sketch approximates what I would like to do

byte PWM\_PIN = 3;  
byte PWM\_POUT = 12;  
int pwm\_value;  
int offset = 2; //this delays the output

void setup() {  
pinMode(PWM\_PIN, INPUT);  
pinMode (PWM\_POUT, OUTPUT);  
}

void loop() {  
pwm\_value = pulseIn(PWM\_PIN, LOW);  
delayMicroseconds (pwm\_value \* offset);  
digitalWrite (PWM\_POUT, LOW);  
delayMicroseconds (pwm\_value);  
digitalWrite (PWM\_POUT, HIGH);  
}

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.

 ![image](https://canada1.discourse-cdn.com/flex027/uploads/xod/original/2X/e/e2edf5bdce4ec441f5c02d7b8a668c8f5579f992.png)

---

<div class="post-metadata">

**Author:** ![williamobrien-sk](https://avatars.discourse-cdn.com/v4/letter/w/74df32/32.png) [@williamobrien-sk](https://forum.xod.io/u/williamobrien-sk)\
**Post date:** [March 4, 2020, 9:57pm UTC](https://forum.xod.io/t/i-want-a-node-digital-signal-repeater/3397/3 "2020-03-04T21:57:50Z")

</div>

I had a go at making a xod node based on the arduino sketch.  
 ![image](https://canada1.discourse-cdn.com/flex027/uploads/xod/original/2X/d/d767ec5ba1e9d6534a04af43ab7f58ffe9eb956a.png)

![image](https://canada1.discourse-cdn.com/flex027/uploads/xod/original/2X/3/3cf5bf9f3107dd2f29a01c870110f507e1655a5c.png)  
and included the following for the not implemented… ( I know nothing about c++ )

```auto
#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_crank>(ctx);
    if (!isValidDigitalPort(port)) {
        raiseError(ctx);
        return;
    }
emitValue<output_DONE>(ctx, 0);
    //const uint8_t port = (13);
    bool highLow = getValue<input_HU002FL>(ctx);
    uint8_t value = 0;
    uint8_t toothtime = 0;
    uint8_t retard = 0;
    uint8_t PSI = 0;
    if (highLow == 1)
    {
        value = 1;
    }
    else {
        value = 0;
    }
    //noInterrupts();
    toothtime = (ctx, pulseIn(port, value));
    emitValue<output_TIME>(ctx, (toothtime));
    
    PSI = getValue<input_PSI>(ctx);
    emitValue<output_offset>(ctx, (PSI * toothtime));
    delayMicroseconds(PSI * toothtime);
    pinMode(7, OUTPUT);
::digitalWrite(7, false);
  delayMicroseconds (toothtime);
  ::digitalWrite(7, true);
emitValue<output_DONE>(ctx, 1);
    //Interrupts();
    }

```

The input pulse and offset are calculated ok but for some reason the output pulse is registered for only 1 in ~5 of the input pulses.

 ![image](https://canada1.discourse-cdn.com/flex027/uploads/xod/original/2X/3/3b32002d153c1dbb8da14b6cfb544b3acc58ced6.png)

Is there a way to fix this?  
Thanks

---

<div class="post-metadata">

**Author:** ![gweimer](https://avatars.discourse-cdn.com/v4/letter/g/a9adbd/32.png) [@gweimer](https://forum.xod.io/u/gweimer)\
**Post date:** [March 4, 2020, 10:11pm UTC](https://forum.xod.io/t/i-want-a-node-digital-signal-repeater/3397/4 "2020-03-04T22:11:21Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![williamobrien-sk](https://avatars.discourse-cdn.com/v4/letter/w/74df32/32.png) [@williamobrien-sk](https://forum.xod.io/u/williamobrien-sk)\
**Post date:** [March 4, 2020, 10:26pm UTC](https://forum.xod.io/t/i-want-a-node-digital-signal-repeater/3397/5 "2020-03-04T22:26:27Z")

</div>

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)

 ![image](https://canada1.discourse-cdn.com/flex027/uploads/xod/original/2X/3/3cddd0a30ccf200af97ef6099a13ffadbd25a338.png)

There may be a way to write to the port diectly without using digitalwrite?

---

<div class="post-metadata">

**Author:** ![gweimer](https://avatars.discourse-cdn.com/v4/letter/g/a9adbd/32.png) [@gweimer](https://forum.xod.io/u/gweimer)\
**Post date:** [March 4, 2020, 10:38pm UTC](https://forum.xod.io/t/i-want-a-node-digital-signal-repeater/3397/6 "2020-03-04T22:38:59Z")

</div>

I’m guessing the problem is seeing the input pulses, not sending the output pulse.

---

<div class="post-metadata">

**Author:** ![williamobrien-sk](https://avatars.discourse-cdn.com/v4/letter/w/74df32/32.png) [@williamobrien-sk](https://forum.xod.io/u/williamobrien-sk)\
**Post date:** [March 4, 2020, 11:06pm UTC](https://forum.xod.io/t/i-want-a-node-digital-signal-repeater/3397/7 "2020-03-04T23:06:47Z")

</div>

Thanks gweimer, your explanation is more likely.  
You mentioned making a seperate read node to capture all inputs.

> [@gweimer](#):
>
> 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.

Any advice on how this might look like?

---

<div class="post-metadata">

**Author:** ![gweimer](https://avatars.discourse-cdn.com/v4/letter/g/a9adbd/32.png) [@gweimer](https://forum.xod.io/u/gweimer)\
**Post date:** [March 5, 2020, 2:20am UTC](https://forum.xod.io/t/i-want-a-node-digital-signal-repeater/3397/8 "2020-03-05T02:20:18Z")

</div>

Digital-read linked to your node. Your node will need to use a Boolean pin instead of Port number.

---

<div class="post-metadata">

**Author:** ![williamobrien-sk](https://avatars.discourse-cdn.com/v4/letter/w/74df32/32.png) [@williamobrien-sk](https://forum.xod.io/u/williamobrien-sk)\
**Post date:** [March 5, 2020, 9:18pm UTC](https://forum.xod.io/t/i-want-a-node-digital-signal-repeater/3397/9 "2020-03-05T21:18:36Z")

</div>

Hi I tried adding digital-read to the input of the node.

![image](https://canada1.discourse-cdn.com/flex027/uploads/xod/original/2X/6/6af2133436469f0f83dc66276d855e9848a04f64.png)

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?

.

---

<div class="post-metadata">

**Author:** ![gweimer](https://avatars.discourse-cdn.com/v4/letter/g/a9adbd/32.png) [@gweimer](https://forum.xod.io/u/gweimer)\
**Post date:** [March 5, 2020, 9:35pm UTC](https://forum.xod.io/t/i-want-a-node-digital-signal-repeater/3397/10 "2020-03-05T21:35:51Z")

</div>

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).

---

<div class="post-metadata">

**Author:** ![williamobrien-sk](https://avatars.discourse-cdn.com/v4/letter/w/74df32/32.png) [@williamobrien-sk](https://forum.xod.io/u/williamobrien-sk)\
**Post date:** [March 7, 2020, 12:02am UTC](https://forum.xod.io/t/i-want-a-node-digital-signal-repeater/3397/11 "2020-03-07T00:02:43Z")

</div>

By turning off the watch windows in debug the speed at which the input port can be sampled increases from 200 Hz to 1000 Hz before pulses are missed.

 ![image](https://canada1.discourse-cdn.com/flex027/uploads/xod/original/2X/0/0de1af13b8d85dee3cfcf90c41e4f2655d36878a.png)

I will try to use interrupts instead of pulse in to see if the port read frequency can be increased further.

---

<div class="post-metadata">

**Author:** ![system](https://canada1.discourse-cdn.com/flex027/uploads/xod/original/1X/eb7348baa04192c2ef932d1db54d44f09f8a7888.png) [@system](https://forum.xod.io/u/system)\
**Post date:** [April 21, 2020, 3:46pm UTC](https://forum.xod.io/t/i-want-a-node-digital-signal-repeater/3397/12 "2020-04-21T15:46:02Z")

</div>

Closed on April 21, 2020, 3:46pm UTC

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
