Dragino Yun Shield, use Serial1, Serial2, or Serial3 on Mega2560?

Hi folks.

I've got an electric motorcycle data module that's based on an Arduino Mega2560. I use Serial0 for debugging as well as Serial1 and Serial3 for a serial LCD and GPS (and even an AltSoftSerial to talk serial to the motor controller). I still have Serial2 available.

I know that the Yun Shield uses Serial0 to communicate between the shield and the arduino. However If I can physically wire Serial0 on the Yun Shield board to Serial2 on the Mega2560, is it possible to get the Bridge library setup to use Serial2 vs. Serial0?

So it wasn't all that hard to do as a one-off, though it requires a change to Bridge.cpp, so I haven't spent the time to figure out a patch to submit yet.

Basically, at the end of Bridge.cpp (found in the Arduino IDE code directory e.g. /Applications/Arduino.app/Contents/Java/libraries/Bridge/src on a mac), there's a bit of code that sets up the Bridge instance:

// Bridge instance
#ifdef __AVR_ATmega32U4__
// Leonardo variants (where HardwareSerial is Serial1)
SerialBridgeClass Bridge(Serial1);
#else
SerialBridgeClass Bridge(Serial);
#endif

I wanted my Mega2560 to use Serial2 for communication to the Dragino, so I changed the last SerialBridgeClass line to:

SerialBridgeClass Bridge(Serial2);

From a hardware side:

  • before installing the Dragino Yun shield on the Mega2560, I bent pins 0 and 1 on the yun shield so they wouldn't connect to 0 and 1 on the Mega 2560.
  • I connected pins 0 and 1 on the Yun to pins 17 and 16 on the Mega2560 respectively

A couple of notes:

  • I'm actually using another shield between the Mega2560 and the Yun Shield. This shield doesn't have the separate ICSP headers, so I found that I needed to connect the ICSP header pin 2 (5V) to any 5V pin on the Mega2560. This isn't necessary when plugging the Yun shield to an arduino or a shield that supports the ICSP header.
  • Since the yun shield isn't communicating with the Arduino via the default Serial (Serial 0), you don't have to go through the hassle of setting up a new board in the Arduino IDE that the Dragino docs talk about, nor do you need to put a jumper on the ICSP header to disable Serial communication.

I've got my yun shield working great on my Mega2560 and I still get to use Serial for debugging and whatnot. :)

I'll try to figure out a more robust patch to Bridge.cpp and submit it at some point.

I don’t think you need to make any modifications to the Bridge library. The SerialBridgeClass constructor (of which the Bridge object is a instance) accepts a HardwareSerial object as a parameter. You can forget about the default 'Bridge" instance and create your own:

SerialBridgeClass Bridge2(Serial2);

Then, in setup(), call Bridge2.begin() to initialize the Bridge. Use Bridge2.put() and Bridge2.get() to set/read values from the Bridge, and pass Bridge2 as a parameter to the various class constructors that implicitly use the default Bridge instance. For example:

Process myProcess(Bridge2);  // Create a process object that talks over Bridge2
YunServer myServer(123, Bridge2);  // Create a server that listens on port 123 using Bridge2

If you really wanted to modify the bridge, I would consider using a defined symbol that you set before including any Bridge library header files. For example:

#define CUSTOM_BRIDGE_PORT Serial2
#include <Bridge.h>

Then, down at the bottom of Bridge.cpp:

// Bridge instance
#ifdef CUSTOM_BRIDGE_PORT
SerialBridgeClass Bridge(CUSTOM_BRIDGE_PORT);
#else
#ifdef __AVR_ATmega32U4__
// Leonardo variants (where HardwareSerial is Serial1)
SerialBridgeClass Bridge(Serial1);
#else
SerialBridgeClass Bridge(Serial);
#endif
#endif

This way, the code works as it did before if CUSTOM_BRIDGE_PORT is not defined, but will use the defined port if it is.

ShapeShifter:
I don’t think you need to make any modifications to the Bridge library. The SerialBridgeClass constructor (of which the Bridge object is a instance) accepts a HardwareSerial object as a parameter. You can forget about the default 'Bridge" instance and create your own:

SerialBridgeClass Bridge2(Serial2);

This works, but is a bit sub-optimal as it’s not a drop in replacement (outside of the initial setup)

Note that FileSystem.open() ignores its BridgeClass when calling FileSystem.open(), so even changing the code

File f = FileSystem.open(file_name, FILE_APPEND):

to

FileSystemClass fileSystem2(Bridge2);
File f = fileSystem2.open(file_name, FILE_APPEND);

the File is using the default Bridge class. However, since FileSystem.open is just a wrapper for File.open, I was able to get it to work by changing that to:

File f(file_name, FILE_APPEND, Bridge2);

I’m going to use this method for now since it doesn’t require hacking on IDE code. However, I’d like to figure out a way to make it more seamless.

ShapeShifter:
If you really wanted to modify the bridge, I would consider using a defined symbol that you set before including any Bridge library header files. For example:

#define CUSTOM_BRIDGE_PORT Serial2

#include <Bridge.h>




Then, down at the bottom of Bridge.cpp:



// Bridge instance
#ifdef CUSTOM_BRIDGE_PORT
SerialBridgeClass Bridge(CUSTOM_BRIDGE_PORT);
#else
#ifdef AVR_ATmega32U4
// Leonardo variants (where HardwareSerial is Serial1)
SerialBridgeClass Bridge(Serial1);
#else
SerialBridgeClass Bridge(Serial);
#endif
#endif




This way, the code works as it did before if CUSTOM_BRIDGE_PORT is not defined, but will use the defined port if it is.

Unfortunately, this doesn’t work as the FileIO.cpp file is compiled separately from the sketch, and we’d need a compiler define ("-DCUSTOM_BRIDGE_PORT") or something similar to get the FileIO.cpp file to see the define.