isValueReceivedOnFaceExpired Broken?

I’m new here, so I could well be missing something, but isValueReceivedOnFaceExpired seems broken to me.

The tutorials tell us to use it to sense neighbours, but I can’t relate the name of it and the boolean return value to what seems to be three states it’s trying to represent.

First, the name - isValueReceivedOnFaceExpired - clearly needs to return a boolean value. Is the Value Received Expired? Yes, it is expired, or No, it has not expired.

But then we’re told that No (or False) means it has no neighbour.
So, uh, what if a Value received on a Face has not in fact expired, does it return ‘No Neighbour’?

And if a Value received on a Face doesn’t expire, or always expires by the time this is called, then why call it this in the first place?

When you connect 2 Blinks together, they start exchanging values (the face value). At this point, calling isValueReceivedOnFaceExpired() should return false as it always has a fresh value it just received from the other connected Blink.

Then if you disconnect the 2 Blinks, they will stop exchanging the values and then isValueReceivedOnFaceExpired() should return true as it will notice that it did not recently receive any value on that face (as there is no Blink connected to it now).

So, generally: If isvalueReceivedOnFaceExpired() returns false, there is a Blink connected to that face. If it returns true, there is not.

(As always, there are some details around this but they are irrelevant most of the time).

1 Like

And, to clarify, this is incorrect. If it returns false, there is a connected Blink (the value is not expired so some Blink on the other end must be transmitting it). Conversely, if it returns true, the value is expired and there should not be a Blink connected to that face.

Ok; so the information I was missing is that on connection, Blinks will actually transmit a value on each face, just not necessarily a user-generated value? So there’ll be a frame or two delay in ‘noticing’ a connected neighbour, even if you poll this every iteration of the loop.

So isValueReceivedOnFaceExpired is literally accurate, but the literal meaning is not really used as such. It’s a bit like having a function called doesShoeFit and using a value of true to mean that someone is awake, since they don’t put their shoes on when they’re asleep :-p

All of which still leads me to think it’s broken; if we don’t really use it to tell if a value on a face has expired, why not call it something more meaningful like hasNeighbour…?

It is a user generated value with the default being 0 before the user sets anything and whatever was set with setValueSentOnface() afterwards. Note that it does not just send the value on connection. Connected Blinks will keep sending values to each other back and forth (after the initial send which might happen simultaneously, they coordinate to send a value as soon as they get a value form the other peer (or on a timeout).

I disagree here. What the function tells you is if the value expired. There is a delay (op to 200 ms if I am not mistaken) where a Blink might be connected but a value might be expired or it is disconnected and a value did not expire yet. So value expired is a lot more precise than has neighbor. It just so happens that this difference can be ignored virtually all the time so one is a proxy to the other.

See above. The reason you can use it to detect if a blink has a neighbor is because the time window where that is not true is very very small. Value expired is a lot more precise.

You seem to be putting forward arguments that agree with me :slight_smile:

What I said was “So isValueReceivedOnFaceExpired is literally accurate, but the literal meaning is not really used as such”. You said “It just so happens that this difference can be ignored virtually all the time” - which is exactly what I’m saying.
I haven’t yet heard of a case where you’d call this function with the intention of using it as it is literally meant; if such a case exists, it seems to be so rare as to support my argument that this is not really well-named - or at the least, that a hasNeighbour function should exist since it’s used so many times in every app I’ve seen.

My point was that isValueOnFaceExpired() is strictly correct while isNeighborConnectedOnface() is not. So the name is correct even if the only usage is to detect if a Blink is connected. Even relying on this assumption has issues from time to time due to the nature of propagating data through IR links.

But, of course, you can always do:

bool isNeighborConnectedOnFace(byte face) {
    return !isValueReceivedOnFaceExpired(face);
}