I have been testing UART communication in C++ with wiringPi.
The problem:
It seems that C++ isn't outputting whole data into the UART port /dev/ttyAMA0
. Perhaps I'm doing it the wrong way?
Investigations:
Note : I am using minicom, minicom --baudrate 57600 --noinit --displayhex --device /dev/ttyAMA0
to check the received data.
Also! The UART port, RX & TX pins are shorted together.
The python code worked perfectly however when I tried to implement it in C++, the data received is different.
The expected received data should be: ef 01 ff ff ff ff 01 00 07 13 00 00 00 00 00 1b
.
Language Used | Data Received from Minicom |
---|---|
Python | ef 01 ff ff ff ff 01 00 07 13 00 00 00 00 00 1b |
C++ | ef 01 ff ff ff ff 01 |
Code used
Python:
import serial
from time import sleep
uart = serial.Serial("/dev/ttyAMA0", baudrate=57600, timeout=1)
packet = [239, 1, 255, 255, 255, 255, 1, 0, 7, 19, 0, 0, 0, 0, 0, 27]
uart.write(bytearray(packet))
C++:
Note: Code compiled with g++ -Wall -O3 -o test hello.cpp -lwiringPi
#include <iostream>
#include <string.h>
#include <wiringPi.h>
#include <wiringSerial.h>
using namespace std;
int main()
{
int serial_port;
if (wiringPiSetup() == -1)
exit(1);
if ((serial_port = serialOpen("/dev/ttyAMA0", 57600)) < 0)
{
fprintf(stderr, "Unable to open serial device: %s\n", strerror(errno));
return 1;
}
cout << "Sending data to UART" << std::endl;
serialPuts(serial_port, "\xef\x01\xff\xff\xff\xff\x01\x00\x07\x13\x00\x00\x00\x00\x00\x1b");
return 0;
}
You can't use serialPuts
to send the null terminator. As with all similar functions, it will stop when the null terminator is encountered in the string. In this case I think your best option is to add a function that uses the ordinary write
function that is used internally by WiringPi's own functions.
You could make a wrapper function to make it look similar to the other calls:
#include <cstddef>
void serialWrite(const int fd, const char* data, size_t length) {
write(fd, data, length);
}
and perhaps a function template to not have to count the length of the data in the fixed data arrays manually:
template<size_t N>
void serialWrite(const int fd, const char(&data)[N], bool strip_last = true) {
serialWrite(fd, data, N - strip_last);
}
You can now use it like so:
serialWrite(serial_port, "\xef\x01\xff\xff\xff\xff\x01\x00\x07\x13\x00\x00\x00\x00\x00\x1b");
Note: There is a pull request to add a similar function (called serialPut
) to the WiringPi library that you could download instead of using the official version from the master branch version if you don't want to make your own function.