Hardware I/O updates #4931

Merged
merged 9 commits into from Apr 20, 2017

Conversation

Projects
None yet
2 participants
@gohai
Contributor

gohai commented Feb 22, 2017

Different updates to the IO library that came up while writing the chapter on Hardware I/O.

gohai added some commits Feb 22, 2017

IO: Rename the (publicly listed) waitForInterrupt function to waitFor
This function is used like this:
GPIO.waitFor(pin number, rising/falling/change, timeout or -1)

While it's using an interrupt internally, in the way it is used it doesn't relate to the interrupt functions (attachInterrupt, etc) at all. To prevent confusion, rename it to waitFor. (Another possible name would be waitForPin.)
IO: Remove the RPI (Raspberry Pi) class
This provided constants that translated from the physical header pin numbers to GPIO lines. Instead, we (and the majority of other Pi related documentation out there) now just use GPIO numbers exclusively.

The class hasn't been used in examples since a few versions, and also wasn't ever properly documented in the reference, so unlikely that many people will notice.

@gohai gohai changed the title from IO: Rename the (publicly listed) waitForInterrupt function to waitFor to Hardware I/O updates Feb 22, 2017

@gohai

This comment has been minimized.

Show comment
Hide comment
@gohai

gohai Feb 22, 2017

Contributor

@benfry What kind of vibes are you getting from GPIO.waitFor? Or just GPIO.wait? GPIO.waitPin?

Contributor

gohai commented Feb 22, 2017

@benfry What kind of vibes are you getting from GPIO.waitFor? Or just GPIO.wait? GPIO.waitPin?

@benfry

This comment has been minimized.

Show comment
Hide comment
@benfry

benfry Feb 23, 2017

Member

Are there other things you'd be waiting on other than interrupts? Is there a simpler way of saying "interrupt" or is that the language that folks will see/use in this context 100% of the time anyway?

Member

benfry commented Feb 23, 2017

Are there other things you'd be waiting on other than interrupts? Is there a simpler way of saying "interrupt" or is that the language that folks will see/use in this context 100% of the time anyway?

@gohai

This comment has been minimized.

Show comment
Hide comment
@gohai

gohai Feb 24, 2017

Contributor

@benfry Thinking that interrupt might be a bit of a misnomer because the fact that it uses (waits for) an interrupt is just implementation detail... instead of using this function the user could just as well write

int start = millis();
while (GPIO.digitalRead(pin) == value && millis()-start < timeout) {
  // relax
}

The function would just make this more readable by turning it into

// some GPIO code
GPIO.waitFor(pin, value);
// more GPIO code

Which can be optionally abort after a timeout as to not block program execution forever

// some GPIO code
GPIO.waitFor(pin, value, 10);
// more GPIO code

Right now the function returns a boolean indicating success or failure, but I guess a way nicer way would be to throw an exception. This way a giant block of GPIO code could just be wrapped in a big try {} catch {}, and the various points where the program waits for some line to go high or low could each have their own allowance in terms of how much time they can spend waiting.

Contributor

gohai commented Feb 24, 2017

@benfry Thinking that interrupt might be a bit of a misnomer because the fact that it uses (waits for) an interrupt is just implementation detail... instead of using this function the user could just as well write

int start = millis();
while (GPIO.digitalRead(pin) == value && millis()-start < timeout) {
  // relax
}

The function would just make this more readable by turning it into

// some GPIO code
GPIO.waitFor(pin, value);
// more GPIO code

Which can be optionally abort after a timeout as to not block program execution forever

// some GPIO code
GPIO.waitFor(pin, value, 10);
// more GPIO code

Right now the function returns a boolean indicating success or failure, but I guess a way nicer way would be to throw an exception. This way a giant block of GPIO code could just be wrapped in a big try {} catch {}, and the various points where the program waits for some line to go high or low could each have their own allowance in terms of how much time they can spend waiting.

@benfry

This comment has been minimized.

Show comment
Hide comment
@benfry

benfry Feb 24, 2017

Member

Yeah, that's what I'm trying to get at… the waitFor() syntax reads much better and seems more on-point.

We go out of our way to avoid exceptions for day-to-day functions—they're only in the API for advanced features like createInput() or createOutput() which are interfacing with Java code anyway. Does it require an exception or are you just going from how InterruptedException is typically used in Java?

Member

benfry commented Feb 24, 2017

Yeah, that's what I'm trying to get at… the waitFor() syntax reads much better and seems more on-point.

We go out of our way to avoid exceptions for day-to-day functions—they're only in the API for advanced features like createInput() or createOutput() which are interfacing with Java code anyway. Does it require an exception or are you just going from how InterruptedException is typically used in Java?

@gohai

This comment has been minimized.

Show comment
Hide comment
@gohai

gohai Feb 25, 2017

Contributor

I wouldn't require the exception to be handled by the sketch code, but - thinking aloud - this would be the simplest case:

GPIO.waitFor(4, GPIO.RISING);

Pin never rises? Well, then we're stuck here forever. Not the end of the world. Hit stop, figure out what's going on, etc. If we want to handle this case, and not use exceptions, then I fear people will have to use it like this:

boolean successful = GPIO.waitFor(4, GPIO.RISING, 10);
if (successful == false) {
  println("Pin did not rise");
  return false;
}

Which might be okay once, but not so nice if there are multiple of these after each other. If waitFor would throw an exception we could do this more concise

GPIO.waitFor(4, GPIO.RISING, 10);
GPIO.digitalWrite(5, GPIO.LOW); // or something
GPIO.waitFor(4, GPIO.FALLING, 10);
// ...

And if one of these ever takes longer than the 10 milliseconds we get a nice big error in the message area, that immediately points the user to the right line, and says "something here took longer than you said it would". Wish I had this when coding Arduino :)

And the most advanced users could still use something more elaborate like

try {
  GPIO.waitFor(4, GPIO.RISING, 10);
  GPIO.digitalWrite(5, GPIO.LOW); // or something
  GPIO.waitFor(4, GPIO.FALLING, 10);
  return true;
} catch (Exception e) {
  println("Could not initialized hardware, check wiring...");
  return false;
}

Looks good?

And about the name? GPIO.wait / GPIO.waitFor / GPIO.waitPin?

Contributor

gohai commented Feb 25, 2017

I wouldn't require the exception to be handled by the sketch code, but - thinking aloud - this would be the simplest case:

GPIO.waitFor(4, GPIO.RISING);

Pin never rises? Well, then we're stuck here forever. Not the end of the world. Hit stop, figure out what's going on, etc. If we want to handle this case, and not use exceptions, then I fear people will have to use it like this:

boolean successful = GPIO.waitFor(4, GPIO.RISING, 10);
if (successful == false) {
  println("Pin did not rise");
  return false;
}

Which might be okay once, but not so nice if there are multiple of these after each other. If waitFor would throw an exception we could do this more concise

GPIO.waitFor(4, GPIO.RISING, 10);
GPIO.digitalWrite(5, GPIO.LOW); // or something
GPIO.waitFor(4, GPIO.FALLING, 10);
// ...

And if one of these ever takes longer than the 10 milliseconds we get a nice big error in the message area, that immediately points the user to the right line, and says "something here took longer than you said it would". Wish I had this when coding Arduino :)

And the most advanced users could still use something more elaborate like

try {
  GPIO.waitFor(4, GPIO.RISING, 10);
  GPIO.digitalWrite(5, GPIO.LOW); // or something
  GPIO.waitFor(4, GPIO.FALLING, 10);
  return true;
} catch (Exception e) {
  println("Could not initialized hardware, check wiring...");
  return false;
}

Looks good?

And about the name? GPIO.wait / GPIO.waitFor / GPIO.waitPin?

gohai added some commits Feb 24, 2017

IO: Introduce a variant of waitFor that doesn't take a timeout
This simplifies the semantic of the variant with three arguments, since we now don't have the "-1 means wait forever" case any longer.
IO: Make waitFor throw an exception in case of a timeout
Previously, it returned a boolean indicating success. But the code on the caller-side will be nicer to read with exceptions.
@benfry

This comment has been minimized.

Show comment
Hide comment
@benfry

benfry Feb 28, 2017

Member

Would a callback be better? We have lame callbacks by using (public) function names (see selectInput() et al), at least until we can make use of the Java 1.8 syntax.

Member

benfry commented Feb 28, 2017

Would a callback be better? We have lame callbacks by using (public) function names (see selectInput() et al), at least until we can make use of the Java 1.8 syntax.

@gohai

This comment has been minimized.

Show comment
Hide comment
@gohai

gohai Mar 2, 2017

Contributor

I still believe the error in the message area (that can optionally be circumvented with try {} catch {} by people in the know) would be best. It's really meant as a last-resort thing anyway, and because I think it's important to not silently ignore these errors. (So much room for mistakes: picking the wrong pin on the header, cabling issues, ...)

Contributor

gohai commented Mar 2, 2017

I still believe the error in the message area (that can optionally be circumvented with try {} catch {} by people in the know) would be best. It's really meant as a last-resort thing anyway, and because I think it's important to not silently ignore these errors. (So much room for mistakes: picking the wrong pin on the header, cabling issues, ...)

gohai added some commits Mar 13, 2017

IO: Update I2CScreen example
Hardcode i2c interface, add background, fix indentation
IO: Invert OLED example
This makes bright pixels be illuminated on the display.

@benfry benfry merged commit 6919bef into processing:master Apr 20, 2017

@gohai gohai deleted the gohai:io-changes branch Apr 23, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment