Use D0 and D1 as digital inputs AND serial

I'm in the classic scenario of "I need to use all of the pins on my Yun, including D0 and D1." However, I also need to be able to take data and write it to an folder on the Linux side.

I see on the schematic that GPIO23 on the SoC can Tri-State the Max33 which interfaces between the U32U4 and the SoC. Is there any way to directly control this pin? I'd like to have it go high for a period of time and then drop low again. I'm decent at programming on the Arduino side, but have little to no Linux experience, so a play-by-play instruction would be of great help here.

OR if you know of another way of shutting down the Bridge and restarting it so that I can use my pins as both digital inputs and a serial connection to the SoC, that would work as well.

GPIO23 can only be controlled from the Linux side, it cannot be controlled from the sketch. Personally, I think you are heading for trouble trying to disconnect/reconnect the serial port like that, I'll bet it's going to cause more problems than it solves. Not only might the Bridge process get confused (either the sketch or Linux side) but how are you going to prevent your circuits that you will be reading on those pins from interfering with the the serial lines?

Personally, I would leave them alone and look for other ways to accomplish your goal: maybe use a shift register to expand your inputs or outputs, maybe use a multiplexing scheme, or look for other pins which can have a dual purpose? Are you already using the SCL/SDA lines? Or the MISO/MOSI/SCL pins on the six pin ICSP connector?

To prevent my inputs from interfering with the serial lines, they're high impedance until called. However, as I've read more I think you're right that it's best avoided. I spent some time writing a Bridge.end() today which appears to work when the pins are configured as digital outputs, but seems to have no affect if they're digital inputs. Anyways, I found that was also best avoided because starting and stopping Bridge was having adverse affects on my timing requirements.

I've actually got shift registers and multiplexers running already to drop my pin count down to 20. However, I had not considered using the SCL/SDA lines, or any on the ICSP header. Aren't the SCL/SDA lines already technically in use because they're hardwires to pins 2 and 3?

The SPI lines on the ICSP connector may be a good last resort, though I'd really like for those SCL/SDA lines on the main headers to work.

Alternatively, is there a different way to connect the two chips other than the Bridge? Perhaps there's a better way to write to the SoC.

If you are already multiplixing I/O using shift registers, why not add one more stage and actually have some expansion space?

You’re right about the SCL/SDA pins and D2/D3, I hadn’t thought it through before posting that. If you want to use the ICSP pins to get four more I/O, you can use these pin numbers:

  • 14 - MISO
  • 15 - SCK
  • 16 - MOSI
  • 17 - SS

As an alternative Linux communications method, you could plug a USB cable from the microUSB connector to the host USB-A connector. You would then lose the Bridge functionality, and lose the use of the USB serial port for debug or other communications, but could write your own communications between Serial on the sketch, and the corresponding tty port on the Linux side. Once you’ve done that, you can set GPIO23 to disable that level shifter, and that should free up D0 and D1. Do a search on “/sys/class/gpio” for some ideas on how to control the GPIO line. A GPIO line needs to be exported before it can be accessed, but it looks like GPIO23 is already exported by default. So from the Linux SSH command line, to control the line state you would echo either 0 or 1 to the /sys/class/gpio/gpio23/value:

echo 0 > /sys/class/gpio/gpio23/value
echo 1 > /sys/class/gpio/gpio23/value

ShapeShifter: If you want to use the ICSP pins to get four more I/O, you can use these pin numbers:

  • 14 - MISO
  • 15 - SCK
  • 16 - MOSI
  • 17 - SS

Now I understand why a reading of pin 14 didn't give me the reading for A0 like I thought it would! :)

ShapeShifter: As an alternative Linux communications method, you could plug a USB cable from the microUSB connector to the host USB-A connector. You would then lose the Bridge functionality, and lose the use of the USB serial port for debug or other communications, but could write your own communications between Serial on the sketch, and the corresponding tty port on the Linux side.

This sounds intriguing, but I have no idea where to begin with programming something like this... would it require programming some logic on both sides of the board? Also, could this potentially be a faster method of communication than using the Bridge? I could definitely live without the USB serial port, and I could use a little extra speed between the chips.

kyle7125: Now I understand why a reading of pin 14 didn't give me the reading for A0 like I thought it would! :)

I'm away from my computer right now, so I can't look up the digital pin equivalent of A0, but yes, it's definitely NOT 14. ;) The symbol A0 should be defined as the integer equivalent of the pin number to use for a digital read, so you should just be able to do digitalRead(A0) without worrying about the underlying pin number.

If you dig down into the internals of the Arduino IDE files, you will find the header file that makes the pin definitions for the Yun. That header file simply includes the Leonardo header file, so that's the one you actually want to read. In it, you can see which pins are actually readable for digital and analog inputs: there are more of them than you would think. For example, several of the digital shield pins can actually be used as additional analog inputs. It's good information to know.

This sounds intriguing, but I have no idea where to begin with programming something like this... would it require programming some logic on both sides of the board? Also, could this potentially be a faster method of communication than using the Bridge? I could definitely live without the USB serial port, and I could use a little extra speed between the chips.

There is some discussion about doing that on this forum, a bit of searching should turn up the information - there is a specific USB device driver you need to load for it to be recognized, and it will also say which tty name to use from the Linux side.

It will create a basic serial data stream between both sides. You will have to work out your own communications protocol to define what commands and data are sent, and how they will be transmitted/received. It's not rocket science, but it is a somewhat advanced topic and not a trivial exercise.

Depending on how you encode and and the data, you can get faster throughput than using the Bridge, as you can write special purpose code that is more efficient. That's because the Bridge does a lot of different things, and the protocol needs to be able to handle a variety of different data streams. Skipping the Bridge and using a direct serial connection is the fastest way to send data between the two processors, but of course you lose all of the power and flexibility that the Bridge library offers.