BITSian||Electronics||Linux||Vision||ML||CompArch||SoC

Cubieboard and Arduino via UART

In my last post, we saw how flexible and powerful the Cubieboard can be, with the correct knowledge of the pin multiplexing and choosing the pin functionality for your application. Given that you have 7 UART ports, and around 3 SPI ports at your disposal, you can only imagine the power that this gives you.

The company that produces the SoC on which the Cubieboard is based on, AllWinner, primarily wanted to develop this chip as a cheap alternative to Android enabled device manufacturers, such as phones, tablets and what not! And hence, the chipset and subsequently the development boards, are powerful, flexible and have ports designed for external device interfacing, including 2 camera interfaces. (However, only one can be active at one time, like front cam and back cam) But, what it makes for in these interfaces, it lacks in the number of ADC’s (Only one, for accelerometer. People argue that it has the ADC’s for the LCD screen, but involves hacking the driver files, interesting project if someone is willing me to pay for it) and PWM channels. Basically, you cannot collect data or move motors by just using the Cubieboard.

So, if you are planning to use the Cubieboard in your Embedded Design Project, you will sooner or later have the need to communicate with a daughter board, either for getting a bunch of sensor data, or performing some actuation. This post comes as a result of a similar need I had, where I had to trigger a bunch of OpenCV codes which depended on certain sensor values.

Since I could not interface my sensors on the Cubieboard, I decided to use an Arduino for measuring the sensor data and communicate the processed values to the Cubieboard via UART.

The Cubieboard has 8 UART ports in all, including the 4-pin TTL port. However, this 4 pin TTL by default is used in the following ways:

Console Messages (including bootup messages)

A getty so you can login via serial

So, I would suggest that you avoid using the TTL pins, since you would need to edit the boot and initab files in order to use them. Plus, this port comes in very handy for debugging purposes. So instead, we will configure the other GPIO pins for UART.

On the Arduino side, instead of connected pins 0 and 1 (The default UART pins) , I decided to use the SoftSerial library instead. Why? Because I wanted to hook up my Arduino to my PC via USB, whilst it communicates with the Cubieboard, for debugging purposes.

Now I will show the codes on the Arduino and the Cubieboard side respectively, after which you can safely wire up the proper pins on both sides and communicate seamlessly.

Arduino side:

As mentioned before, I won’t be using the default serial pins for interfacing and instead use the SoftSerial library to configure pins 2 and 3 instead. However, the SoftSerial library does not support baudrates above 9600. We will see how that is actually a good thing for us later. Following code snippet sends a character to both serial ports if the ADC value is above a threshold, and prints whatever value it gets from CubieBoard to the PC:

Cubieboard side:

First order of business would be to configure a UART port of our choice on the Cubieboard. For this case, UART5 is an optimal choice, it has only the Rx and Tx ports, just like the Arduino side, thus not wasting any GPIOs unnecessarily.

Now we make changes in the fex file like mentioned in my previous post and note down the pins:

Make sure to compile the fex file to an appropriate bin file, otherwise the changes will not be seen.

Just to check all the UART ports that you have, you can just list by the following command:

ls /dev/tty*

OR

dmesg|grep tty

Now for the communication part, hackers tend to use Python due to the ease with which you can perform serial communication, thanks to the PySerial library. But in my case, since I had to trigger some OpenCV based codes, I decided to go the C++ way, since I could just include a header file in the main file and save a lot of unwanted mess.

Serial Initialization function

Although you can just open the Serial Port on any linux box as a file, you need to define some flow control and flag options for the desired communication terminal since this is an asynchronous communication and follows a proper handshaking protocol(If you need more clarification on this, please mention on the comments). So we will need some standard libraries for this purpose, you can add them like this:

Next step would be to open the port with the proper flags and initialize the input and output data speed equal to the input baudrate:

//Open the port as a file
//O_RDWR = Open as read and write
//O_NOCTTY = TTY file not to be used for control purposes
fd = open(serialport, O_RDWR | O_NOCTTY)
//set the baudrate
speed_t brate = baud
//setting the input and output speed
cfsetispeed(&toptions, brate);
cfsetospeed(&toptions, brate);

Now that the serial port has been initialized with the correct options, you can just read it as a file and accordingly write the functions for them. For the complete code with the read and write functions, please refer to this link.

Now you can include this library in your main file and initialize the port like this:

serialport_init("/dev/ttyS5", 9600);

Final Connections:

Now that we have configured the UART pins and written the appropriate code on both ends, time to hook them up. Following are the pin outs:

Cubieboard

Arduino

Rx – Port H, pin 7

Rx – pin 2

Tx – Port H, pin 6

Tx – Pin 3

The possibilities from here are endless, you can send commands from the Board to the Arduino and use them to control motors or actuators. In case you need further clarifications on any of these, feel free to drop a comment here!

NOTE: I mentioned before that the 9600 baudrate on the Arduino is actually a blessing in disguise for us, that is because Arduino supports only 2 pin UART, which is actually not at all ideal for a full duplex communication. Imagine this scenario, the Arduino sends some data and triggers a code on the Cubieboard, now any data that the Arduino sends while the Cubieboard is still executing the code will be lost because of the lack of proper data control pins. A quick fix around this would be to run a thread which accumulates the sensor data in a buffer on the board, or to time your code properly so that it finishes executing before the next data comes in

I just checked the available pin out on the Cubieboard and I completely missed that the PH06 is actually muxed and used up in the Cubieboard’s SATA pin out. So I’d suggest that you use the UART 2 or 3, those pin out are still available

Well, is this the message you got from dmesg? If yes and there was no mention of where it can be accessed, then you might have to re compile the kernel again on changing the config file. In any case can you tell me what device is this?

hi , i use a cubieboard 2
i have configurate my UART5 on the pin PH15 and PH14
when i lanch dmesg|grep tty i have the UART5 on ttyS2
but i don’t know how can i send and receive data, i have checked your C code but with my oscilloscope i have neither signal, can you help me please?

thank you for your reply.
I have install minicom and connect my pin PH15, PH14 GND and 5V with a FTDI for check data on the terminal on the PC but i have nothing. With the oscilloscope also i have nothing.

abhinavgupta said: November 21, 201310:13 pm

You do not have to connect 5V anywhere! You just need to connect the RX TX and GND line. In fact attaching the 5V lines might damage the board!

Dimi Henri said: November 22, 20136:06 pm

OK thank you i have find the problem, i have not the juste MUX for the UART now i have change that and its good. thank you for your help

Thanks for your help. I have now fixed the missing muxes and it is working for me now.
Meanwile I am running in another problem which costs me a lot of time to discover it.
In the default config of minicom there is the hardware flow enabled and when you are not disable it it will not work.
My problem was that I have not realized that I have forgotten to save the minicom config.
So all the time there was the hardware flow enabled and a have not connected it in hardware.
After disabling the hardware flow in minicom the UARTs are working very well for me.

Willy said: May 6, 20145:07 pm

Hello,

I am trying to use UART connection between arduino and cubieboard 2 . I have changed the uart_para5 on script.bin as stated above, but there is no pin ph6. I have seen the cubieboard pin defintion and there is no matching pin between the on on script.bin and the one from cubieboard pin definition.

You are right, the ports defined by the default fex file has PH06, and as you pointed out correctly, the mux table shows PI10 as a pin with UART5-TX. To enable the UART 5 for your case, I suggest making the UART 5 para something like this:

Thank you for your clear answer. I am trying to create the main program now. could you give me example to receive and send serial to arduino? In your program you have already stated command to receive and send: int serialport_read_until(int fd, char* buf, char until) and int serialport_write(int fd, const char* str). but I don’t know what to insert on the fd, buf, and until (or str).

Lilian said: May 16, 20148:18 pm

I would be interested by an example of using too. I can’t read anything but the writing works well.
Thank You for your sharing.

milton ortiz said: May 9, 20147:29 am

any schematic on how to find the pins to be used in cb2? i cannot find ph6 in the docs, i can’t even find port h. your help would be appreciated

Hello, I’m using cubie2. I want to make the cubie to receive gps data given by arduino via serial5 in cubie and print it out using cout(I’m using Qt Creator for the programming). but as I tried your coding, it returns an error that says the serial port cannot be opened, permission denied. could you help me please? Thanks before.

hello, i need help.
i did all your steps, edited script.bin, i used pi10 and pi11 for cubie2, reboot but when “dmesg|grep tty” just uart0:ttys0 is enabled, do i missed something? anything left to enable uart5? i am newbie in this.
thanks in advance

Which distribution are you using? It could be because your .config file in the linux must not be allowing multiple instances of the serial driver file. Were you able to resolve the issue or still stuck?