The following code configures two UART ports on a BeagleBone Black.
// Open the given file as read/write, don't become the controlling terminal, don't block
int fileDescriptor = open(filename, O_RDWR | O_NOCTTY | O_SYNC);
if(fileDescriptor == -1) {
cerr << "open_port: Unable to open " << filename << " " << strerror(errno) << endl;
return false;
}
struct termios tty;
memset(&tty, 0, sizeof tty);
if(tcgetattr(fileDescriptor, &tty) != 0) {
cerr << strerror(errno) << endl;
return false;
}
// Baud
cfsetispeed(&tty, B115200);
cfsetospeed(&tty, B115200);
// 8-bit chars
tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8;
// Disable IGNBRK for mismatched speed tests; otherwise receive break
// as \000 chars
tty.c_iflag &= ~IGNBRK; // disable break processing
tty.c_lflag = 0; // no signaling chars, no echo
// No canonical processing
tty.c_oflag = 0; // no remapping, no delays
tty.c_cc[VMIN] = 0; // read doesn't block
tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
// Shut off xon/xoff ctrl
tty.c_iflag &= ~(IXON | IXOFF | IXANY);
// Ignore modem controls
tty.c_cflag |= (CLOCAL | CREAD);
// Enable reading
tty.c_cflag &= ~(PARENB | PARODD); // shut off parity
tty.c_cflag |= 0;
tty.c_cflag &= ~CSTOPB;
tty.c_cflag &= ~CRTSCTS;
if(tcsetattr(fileDescriptor, TCSANOW, &tty) != 0) {
cerr << strerror(errno) << endl;
return false;
}
I'm able to send data, but for some reason 0x0D's sent are received as 0x0A's. I'm fairly sure something in this port configuration is doing this.
I notice these three flags on the man page for tcsetattr:
INLCR
Translate NL to CR on input.
IGNCR
Ignore carriage return on input.
ICRNL
Translate carriage return to newline on input (unless IGNCR is set).
You might want to try explicitly setting INLCR and ICRNL to 0 ?
Related
DWORD WINAPI socketRead(void *lpVoid)
{
while (true)
{
// UDP socket
WSADATA data_s;
WORD version = MAKEWORD(2, 2);
// socket start
int wsok = WSAStartup(version, &data_s);
if (wsok != 0)
{
cout << "Can't start Winsock!" << wsok;
return 0;
}
else
{
cout << "start Winsock!\n";
}
// socket bind
SOCKET in = socket(AF_INET, SOCK_DGRAM, 0);
SOCKADDR_IN serverHint = {};
memset(&serverHint, 0, sizeof(serverHint));
serverHint.sin_family = AF_INET; // IPv4
serverHint.sin_addr.S_un.S_addr = inet_addr("192.168.0.69");
serverHint.sin_port = htons(1480);
if (bind(in, (sockaddr *)&serverHint, sizeof(serverHint)) != SOCKET_ERROR)
{
cout << "bind socket!\n";
}
else
{
cout << "can't bind socket!" << WSAGetLastError() << endl;
// socket clean
int wsokE = WSACleanup();
if (wsokE != 0)
{
cout << "Can't cleanup Winsock!" << wsokE;
}
else
{
cout << "cleanup Winsock!\n";
}
// return 0;
}
}
this is my code. I want to do UDP socket communication using winsocket.
It is trying to do udp communication with another computer.
However, I keep getting error 10049 even though I wrote down the ip address and port number correctly.
The 1480 port I wrote down in the code is what I set arbitrarily. Do I need to do other processing on the computer?
When I use the same ip and port in the incoming and outgoing confirmation program called Ezterm, the values come normally.
In conclusion, we want to receive data from "192.168.0.69".
Why code stucked in the ISR routine in msp430fg6626 microcontroller? here i performing the rs485 communiction with this uc and SN75176A max485 ic.during this i was set the buad rate at 9600 here data was successfully sent from uc and same received at the max485 ic but in receiving time data was not received at uc from max485 ic. why this occured i will share the code of same here please check and answer me.
i will share the samw code below
code was stuck in this line -> __bis_SR_register(LPM3_bits + GIE);
#include <msp430.h>
int ReceiveData;
int main(void)
{
WDTCTL = WDTPW | WDTHOLD; // Stop WDT
CTSD16CCTL0 |= CTSD16SC; // Workaround for CTSD16OFFG errata
do
{
CTSD16CTL &= ~CTSD16OFFG;
}
while (CTSD16CTL&CTSD16OFFG); // End of CTSD16OFFG workaround
while(BAKCTL & LOCKBAK) // Unlock XT1 pins for operation
BAKCTL &= ~(LOCKBAK);
UCSCTL6 &= ~(XT1OFF); // XT1 On
UCSCTL6 |= XCAP_3; // Internal load cap
// Loop until XT1 fault flag is cleared
do
{
UCSCTL7 &= ~(XT2OFFG | XT1LFOFFG | DCOFFG);
// Clear XT2,XT1,DCO fault flags
SFRIFG1 &= ~OFIFG; // Clear fault flags
}while (SFRIFG1&OFIFG); // Test oscillator fault flag
//------------ Configuring MAX485 Control Lines ---------------//
P8SEL |= BIT4; // Assign P8.4 to ~RE DE and...
P8DIR |= BIT4; // P8.4 -> DE,-> ~RE output
P8OUT &= ~(BIT4); // ~RE & DE SET TO ZERO IN RECEIVING MODE
P8SEL |= 0x0C; // Assign P8.2 to UCA0TXD and...
P8DIR |= 0x0C; // P8.3 to UCA0RXD
UCA1CTL1 |= UCSWRST; // **Put state machine in reset**
UCA1CTL1 |= UCSSEL_1; // CLK = ACLK
UCA1BR0 = 0x03; // 32kHz/9600=3.41 (see User's Guide)
UCA1BR1 = 0x00; //
UCA1MCTL = UCBRS_3|UCBRF_0; // Modulation UCBRSx=3, UCBRFx=0
UCA1CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
UCA1IE |= UCRXIE; // Enable USCI_A1 RX interrupt
__bis_SR_register(LPM3_bits + GIE); // Enter LPM3, interrupts enabled***
__no_operation(); // For debugger
while(1)
{
while (!(UCA1IFG&UCTXIFG)); // USCI_A1 TX buffer ready?
// UCA1TXBUF = 0x55; // TX -> RXed character
// __delay_cycles (160000);
}
}
// Echo back RXed character, confirm TX buffer is ready first
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_A1_VECTOR
__interrupt void USCI_A1_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_A1_VECTOR))) USCI_A1_ISR (void)
#else
#error Compiler not supported!
#endif
{
switch(__even_in_range(UCA1IV,4))
{
case 0:break; // Vector 0 - no interrupt
case 2: // Vector 2 - RXIFG
while (!(UCA1IFG&UCTXIFG)); // USCI_A1 TX buffer ready?
ReceiveData=UCA1RXBUF;
P8OUT |= BIT4; // ~RE & DE SET TO HIGH FOR TRANSMITTING MODE
__delay_cycles (16000);
UCA1TXBUF = ReceiveData; // TX -> RXed character
__delay_cycles (16000);
P8OUT |= ~(BIT4); // ~RE & DE SET TO ZERO IN RECEIVING MODE
__delay_cycles (16000);
break;
case 4:break; // Vector 4 - TXIFG
default: break;
}
}
I want to connet with Qt on windows to my PIC32 UDP server. With a test program in C, I can connect and get the answer, but with Qt it is impossible. What am I doing wrong ?
As you can see I use an ACTIVE WAITING with the while, and my slot doesn't seems to be triggered. Maybe you can see my mistake here ? I hate active waiting....
Here is my code on Qt :
void MuTweezer::run()
{
QHostAddress sender;
quint16 senderPort;
QByteArray datagram;
qint64 pendingBytes;
int cpt = 0;
// Message to send
QByteArray message("Hello that's charly");
// m_imuRcvSocket.bind(10000); why is it for in a client side !?
// SEEMS to NOT BE TRIGGERED
connect(&m_imuRcvSocket, SIGNAL(readyRead()), this, SLOT(recu()));
while(m_isRunning && cpt++ < 10)
{
// send the initial message
qint64 bytesSent= m_imuRcvSocket.writeDatagram(message, QHostAddress("192.168.0.15"), 10000);
cout << "Bytes sent : " << bytesSent << endl;
// We wait the answer from the server
while(!m_imuRcvSocket.hasPendingDatagrams());
// If there is no datagram available, this function returns -1
if((pendingBytes = m_imuRcvSocket.pendingDatagramSize()) == -1)
continue;
datagram.resize(pendingBytes);
m_imuRcvSocket.readDatagram(datagram.data(), datagram.size(),
&sender, &senderPort);
cout << "================="
<< "\nMessage from <" << sender.toString().toStdString().substr(7) << "> on port " << senderPort
<< "\nString : " << datagram.data()
<< "\nSize: " << pendingBytes << " Bytes (characters)\n"
<< "=================" <<
endl;
}
}
Here is my code on the PIC32, as you can see, once I receive a message, I send the answer, it allows me to make a bidirectionnal communication :
if(!UDPIsOpened(mySocket)){
DBPRINTF("Socket CLOSED");
continue; // go back to loop beginning
}
DBPRINTF("Socket OPEN");
if(!(lengthToGet = UDPIsGetReady(mySocket)))
continue;
// get the string
// UDPGetArray : returns the number of bytes successfully read from the UDP buffer.
if((lengthWeGot = UDPGetArray(message, lengthToGet)))
UDPDiscard(); // Discards any remaining RX data from a UDP socket.
/* Modifie it and send it back */
if(UDPIsPutReady(mySocket)){
message[20]= 'Z';
message[21]= 'i';
message[22]= 'b';
message[23]= 'o';
UDPPutArray(message, lengthWeGot);
UDPFlush();
}
Any idea ?
Try to use waitForBytesWritten and waitForReadyRead:
// to receive datagrams, the socket needs to be bound to an address and port
m_imuRcvSocket.bind();
// send the initial message
QByteArray message("Hi it's Charly");
qint64 bytesSent= m_imuRcvSocket.writeDatagram(message,
QHostAddress("200.0.0.3"),
10000);
bool datagramWritten = m_imuRcvSocket.waitForBytesWritten();
// add code to check datagramWritten
datagram.resize(50); // random size for testing
bool datagramReady = m_imuRcvSocket.waitForReadyRead() && m_imuRcvSocket.hasPendingDatagrams();
// add code to check datagramReady
m_imuRcvSocket.readDatagram(datagram.data(),
datagram.size(),
&sender,
&senderPort);
cout << "================="
<< "\nMessage from <" << sender << "> on port " << senderPort
<< "\nString : " << datagram
<< "\nSize: " << pendingBytes << " Bytes (characters)\n"
<< "=================" <<
endl;
A better alternative would be to use signals and slots as described in the documentation of QUdpSocket
if you plan to use the microprocessor as a client with UDP you need the MAC address of the destination machine otherwise it will not work. This one took me 4 hours to figure out.
I am trying to get my IP camera stream in my Qt Widget application. First, I connect to UDP port of IP camera. IP camera is streaming H.264 encoded video. After socket is bound, on each readyRead() signal, I am filling the buffer with received datagrams in order to get a full frame.
Variable initialization:
AVCodec *codec;
AVCodecContext *codecCtx;
AVFrame *frame;
AVPacket packet;
this->buffer.clear();
this->socket = new QUdpSocket(this);
QObject::connect(this->socket, &QUdpSocket::connected, this, &H264VideoStreamer::connected);
QObject::connect(this->socket, &QUdpSocket::disconnected, this, &H264VideoStreamer::disconnected);
QObject::connect(this->socket, &QUdpSocket::readyRead, this, &H264VideoStreamer::readyRead);
QObject::connect(this->socket, &QUdpSocket::hostFound, this, &H264VideoStreamer::hostFound);
QObject::connect(this->socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(error(QAbstractSocket::SocketError)));
QObject::connect(this->socket, &QUdpSocket::stateChanged, this, &H264VideoStreamer::stateChanged);
avcodec_register_all();
codec = avcodec_find_decoder(AV_CODEC_ID_H264);
if (!codec){
qDebug() << "Codec not found";
return;
}
codecCtx = avcodec_alloc_context3(codec);
if (!codecCtx){
qDebug() << "Could not allocate video codec context";
return;
}
if (codec->capabilities & CODEC_CAP_TRUNCATED)
codecCtx->flags |= CODEC_FLAG_TRUNCATED;
codecCtx->flags2 |= CODEC_FLAG2_CHUNKS;
AVDictionary *dictionary = nullptr;
if (avcodec_open2(codecCtx, codec, &dictionary) < 0) {
qDebug() << "Could not open codec";
return;
}
Algorithm is as follows:
void H264VideoImageProvider::readyRead() {
QByteArray datagram;
datagram.resize(this->socket->pendingDatagramSize());
QHostAddress sender;
quint16 senderPort;
this->socket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);
QByteArray rtpHeader = datagram.left(12);
datagram.remove(0, 12);
int nal_unit_type = datagram[0] & 0x1F;
bool start = (datagram[1] & 0x80) != 0;
int seqNo = rtpHeader[3] & 0xFF;
qDebug() << "H264 video decoder::readyRead()"
<< "from: " << sender.toString() << ":" << QString::number(senderPort)
<< "\n\tDatagram size: " << QString::number(datagram.size())
<< "\n\tH264 RTP header (hex): " << rtpHeader.toHex()
<< "\n\tH264 VIDEO data (hex): " << datagram.toHex();
qDebug() << "nal_unit_type = " << nal_unit_type << " - " << getNalUnitTypeStr(nal_unit_type);
if (start)
qDebug() << "START";
if (nal_unit_type == 7){
this->sps = datagram;
qDebug() << "Sequence parameter found = " << this->sps.toHex();
return;
} else if (nal_unit_type == 8){
this->pps = datagram;
qDebug() << "Picture parameter found = " << this->pps.toHex();
return;
}
//VIDEO_FRAME
if (start){
if (!this->buffer.isEmpty())
decodeBuf();
this->buffer.clear();
qDebug() << "Initializing new buffer...";
this->buffer.append(char(0x00));
this->buffer.append(char(0x00));
this->buffer.append(char(0x00));
this->buffer.append(char(0x01));
this->buffer.append(this->sps);
this->buffer.append(char(0x00));
this->buffer.append(char(0x00));
this->buffer.append(char(0x00));
this->buffer.append(char(0x01));
this->buffer.append(this->pps);
this->buffer.append(char(0x00));
this->buffer.append(char(0x00));
this->buffer.append(char(0x00));
this->buffer.append(char(0x01));
}
qDebug() << "Appending buffer data...";
this->buffer.append(datagram);
}
first 12 bytes of datagram is RTP header
everything else is VIDEO DATA
last 5 bits of first VIDEO DATA byte, says which NAL unit type it is. I always get one of the following 4 values (1 - coded non-IDR slice, 5 code IDR slice, 7 SPS, 8 PPS)
5th bit in 2nd VIDEO DATA byte says if this datagram is START data in frame
all VIDEO DATA is stored in buffer starting with START
once new frame arrives - START is set, it is decoded and new buffer is generated
frame for decoding is generated like this:
00 00 00 01
SPS
00 00 00 01
PPS
00 00 00 01
concatenated VIDEO DATA
decoding is made using avcodec_decode_video2() function from FFmpeg library
void H264VideoStreamer::decode() {
av_init_packet(&packet);
av_new_packet(&packet, this->buffer.size());
memcpy(packet.data, this->buffer.data_ptr(), this->buffer.size());
packet.size = this->buffer.size();
frame = av_frame_alloc();
if(!frame){
qDebug() << "Could not allocate video frame";
return;
}
int got_frame = 1;
int len = avcodec_decode_video2(codecCtx, frame, &got_frame, &packet);
if (len < 0){
qDebug() << "Error while encoding frame.";
return;
}
//if(got_frame > 0){ // got_frame is always 0
// qDebug() << "Data decoded: " << frame->data[0];
//}
char * frameData = (char *) frame->data[0];
QByteArray decodedFrame;
decodedFrame.setRawData(frameData, len);
qDebug() << "Data decoded: " << decodedFrame;
av_frame_unref(frame);
av_free_packet(&packet);
emit imageReceived(decodedFrame);
}
My idea is in UI thread which receives imageReceived signal, convert decodedFrame directly in QImage and refresh it once new frame is decoded and sent to UI.
Is this good approach for decoding H.264 stream? I am facing following problems:
avcodec_decode_video2() returns value that is the same like encoded buffer size. Is it possible that encoded and decoded date are always same size?
got_frame is always 0, so it means that I never really received full frame in the result. What can be the reason? Video frame incorrectly created? Or video frame incorrectly converted from QByteArray to AVframe?
How can I convert decoded AVframe back to QByteArray, and can it just be simply converted to QImage?
The whole process of manually rendering the frames can be left to another library. If the only purpose is a Qt GUI with live feed from the IP camera you can use libvlc library. You can find an example here: https://wiki.videolan.org/LibVLC_SampleCode_Qt
I have a TI Cortex-based Pengwyn board running embedded Linux that I am trying to use to read raw serial data from a USB-ftdi peripheral so I can process it into data packets.
To do this I've written a simple program (using Qt) and the termios framework. This works no problem on my desktop (Ubuntu VM) machine - it opens /dev/ttyUSB0, configures the serial port, reads and process the data without problems.
I run into problems when I run the same program (cross-compiled for arm obviously) on the pengwyn board... The read() function call does not populate the buffer - although it returns a non-error value, indicating the number of bytes that have been read???
(I also had to rebuilt the linux kernel for the pengwyn board to include teh USB-ftdi serial driver.)
I suspect it is a target configuration issue but I have compared the file permissions and termios settings between both the platforms and they look okay. I am new to this platform and serial/termios stuff so I have undoubtedly over-looked something but I've looked through the "Serial Programming Guide for POSIX Operating Systems" and searched for similar posts regarding arm and usb-ftdi read problems but have yet to find anything.
Any suggestions/observations?
Relevant excerpts from test program:
void Test::startRx(void)
{
bool retval = false;
m_fd = open(m_port.toLocal8Bit(),O_RDONLY |O_NOCTTY | O_NDELAY);
if (m_fd == -1)
{
qDebug() << "Unable to open: " << m_port.toLocal8Bit() << strerror(errno);
}
else
{
m_isConnected = true;
qDebug() << m_port.toLocal8Bit() << "is open...";
fcntl(m_fd, F_SETFL, 0);
struct termios options;
if (tcgetattr(m_fd, &options)!=0)
{
qDebug() << "tcgetattr() failed";
}
//Set the baud rates to 9600
cfsetispeed(&options, B9600);
cfsetospeed(&options, B9600);
//Enable the receiver and set local mode
options.c_cflag |= (CLOCAL | CREAD);
//Set character size
options.c_cflag &= ~CSIZE; /* Mask the character size bits */
options.c_cflag |= CS8; /* Select 8 data bits */
//No parity 8N1:
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
//Disable hardware flow control
options.c_cflag &= ~CRTSCTS;
//Disable software flow control
options.c_iflag &= ~(IXON | IXOFF | IXANY);
//Raw output
options.c_oflag &= ~OPOST;
//Raw input
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
//Set the new options for the port...
tcsetattr(m_fd, TCSANOW, &options);
int status;
ioctl(m_fd, TIOCMGET, &status );
qDebug() << "current modem status:" << status;
QThread* m_reader_thread = new QThread;
m_serial_port_reader = new SerialPortReader(0, m_fd);
if (m_serial_port_reader)
{
qDebug() << "creating serial port reader thread...";
m_serial_port_reader->moveToThread(m_reader_thread);
connect(m_serial_port_reader, SIGNAL(notifyRxPacketData(QByteArray *)), this, SLOT(processRxPacketData(QByteArray*)));
//connect(m_serial_port_reader, SIGNAL(error(QString)), this, SLOT(errorString(QString)));
connect(m_reader_thread, SIGNAL(started()), m_serial_port_reader, SLOT(process()));
connect(m_serial_port_reader, SIGNAL(finished()), m_reader_thread, SLOT(quit()));
connect(m_serial_port_reader, SIGNAL(finished()), m_serial_port_reader, SLOT(quit()));
connect(m_reader_thread, SIGNAL(finished()), m_reader_thread, SLOT(deleteLater()));
m_reader_thread->start();
retval = true;
}
....
void SerialPortReader::readData(int i)
{
m_socket_notifier->setEnabled(false);
if (i == m_fd)
{
unsigned char buf[BUFSIZE] = {0};
int bytesRead = read(m_fd, buf, BUFSIZE);
//qDebug() << Q_FUNC_INFO << "file decriptor:" << m_fd << ", no. bytes read:" << bytesRead;
if (bytesRead < 0)
{
qDebug() << Q_FUNC_INFO << "serial port read error";
return;
}
// if the device "disappeared", e.g. from USB, we get a read event for 0 bytes
else if (bytesRead == 0)
{
//qDebug() << Q_FUNC_INFO << "finishing!!!";
return;
}
//process data...
}
m_socket_notifier->setEnabled(true);
}