Qt c++ Issue receiving data weighing scale Ohaus aviator 7000 - c++

I am trying to establisch a serial port connection to my Aviator 7000 weighing scale using Qt c++. The expected result would be a succesfull communication through the use of a byte command.
Sadly I don't receive any bytes back from the scale. below you can find what I tried so far:
const int Max_attempts = 5;
const int Max_sleep = 125;
int attemps;
attemps = 0;
while (true)
{
int enq {5};
QByteArray bytes;
bytes.setNum(enq);
m_serial->write(bytes);
m_serial->waitForReadyRead(Max_sleep);
if (m_serial->bytesAvailable() !=0)
{
qDebug() << m_serial->bytesAvailable() ;
qDebug() << "connected" << m_serial->readAll();
break;
}
attemps += 1;
if (attemps == Max_attempts)
{
qDebug() << "no connection established";
break;
}
}
Kind regards,
Tibo

According to this manual you are supposed to send a byte 0x05 but you are sending 0x35 (the character "5").
Use
bytes.append('\X05');

Related

Qt - Sending a large amount of data via QDataStream TCP

I want to benchmark a TCP Connection to an ECU (Transferrate)
For that, i want so send some Data. The amout of data can be set in my GUI from x KB to x GB.
The transferSize is calculated from the values set in the GUI. Buffer Size is 1024:
#define BENCHMARK_TRANSFER_BUFFER_SIZE 1024
void logic::TransferAndLatencyEthernetBenchmark::transferDataTcp(TCPClient& tcpclient)
{
uint32_t toSend = transferSize;
uint32_t currentSendSize = 0;
while (toSend > 0)
{
if (toSend / BENCHMARK_TRANSFER_BUFFER_SIZE >= 1)
{
currentSendSize = BENCHMARK_TRANSFER_BUFFER_SIZE;
}
else if ((toSend / BENCHMARK_TRANSFER_BUFFER_SIZE) == 0)
{
currentSendSize = toSend % BENCHMARK_TRANSFER_BUFFER_SIZE;
}
toSend -= currentSendSize;
tcpclient.sendData(transferSendBuffer, currentSendSize);
}
}
So iam calling the tcpclient.sendData(transferSendBuffer, currentSendSize) function als long as toSend > 0:
...
QDataStream out;
....
void TCPClient::sendData(uint8_t* buffer, uint32_t size)
{
qDebug() << "current send size: " << size << " - Transfer send buffer: " << (const char*)buffer;
for (int i=0; i<size; i++)
{
buffer[i] = 'a';
}
out.setDevice(socket_aurix);
out.writeBytes((const char*)buffer, size);
}
Iam pretty new on Qt (C++ in generel) and iam sure iam doing it wrong ;)
It actually works but crashed when i try so send bigger amouts of data.
What would be a better way to initialize the fill the array instead of the for loop?
What what be a better approach in generel to use QDataStream?
Many thanks.

Buffer underruns on x310 when transmitting and receiving from same channel

I'm running on an x310 across dual 10 Gigabit ethernet, outfitted with twin basic tx rx daughterboards. I'm running on UHD version 3.11.0. Ideally, I would like two simultaneous transmit and receive streams, utilizing both channels to transmit and receive. I don't want to have to use 2 x310s for 2 receive and transmit streams
When I transmit and receive at the same time on the same channel, I get a lot of U's printed out to console signaling underflows, no matter what the rate. HOWEVER, if I transmit and receive on separate channels (tx_streamer has stream_args at channel 1 and rx_streamer has stream_args at channel 0) it works just fine.
I've attached the source code of a complete but simple program that will hopefully demonstrate my problem. In this program, two threads are created: a transmit thread and a receive thread. The receive thread is constantly receiving data to a buffer and overwriting that buffer with new data. The transmit thread is constantly transmitting 0's from a prefilled buffer.
If anyone has an x310 running across 10Gbps ethernet, can you compile and run my program to test if this problem occurs not just for me?
Here's what we have already tested:
I'm running on a server system rocking two 12 core intel xeon processors. (https://ark.intel.com/products/91767/Intel-Xeon-Processor-E5-2650-v4-30M-Cache-2_20-GHz). My network card is the recommended x520 da2. Someone had previously suggested NUMA to be an issue, but I don't think this is the case as the program works when we switch to transmitting and receiving on separate channels.
Since the program works just fine when we are transmitting and receiving on separate channels, I'm led to believe this is not a CPU power issue.
I've tested only transmitting and only receiving. We can transmit at 200MS/s across both channels and we can receive at 200MS/s across both channels, but we cannot transmit and receive from the same channel. This suggests our network card is working properly and we can handle the high rate.
I've tried my program on UHD 3.10.2 and the problem still occurs
I've tried setting the tx_metadata waiting 2 second before transmitting. The problem still occurs.
I've tried running the example program txrx_loopback_from_file and that works for simultaneous receive and transmit, but I have no idea why.
From the last point, I'm lead to believe that I am somehow calling the uhd API wrong, but I have no idea where the error is. Any help would be greatly appreciated.
Thanks,
Jason
#include <iostream>
#include <iomanip>
#include <stdlib.h>
#include <vector>
#include <csignal>
#include <thread>
#include <uhd/utils/thread_priority.hpp>
#include <uhd/utils/safe_main.hpp>
#include <uhd/usrp/multi_usrp.hpp>
#include <uhd/types/tune_request.hpp>
typedef std::complex<short> Complex;
// Constants and signal variables
static bool stop_signal_called = false;
const int NUM_CHANNELS = 1;
const int BUFF_SIZE = 64000;
//function prototypes here
void recvTask(Complex *buff, uhd::rx_streamer::sptr rx_stream);
void txTask(Complex *buff, uhd::tx_streamer::sptr tx_stream, uhd::tx_metadata_t md);
void sig_int_handler(int){
std::cout << "Interrupt Signal Received" << std::endl;
stop_signal_called = true;
}
int UHD_SAFE_MAIN(int argc, char *argv[]) {
uhd::set_thread_priority_safe();
//type=x300,addr=192.168.30.2,second_addr=192.168.40.2
std::cout << std::endl;
std::cout << boost::format("Creating the usrp device") << std::endl;
uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(std::string("type=x300,addr=192.168.30.2"));
std::cout << std::endl;
//set stream args
uhd::stream_args_t stream_args("sc16");
double samp_rate_tx = 10e6;
double samp_rate_rx = 10e6;
uhd::tune_request_t tune_request(0);
//Lock mboard clocks
usrp->set_clock_source(std::string("internal"));
//set rx parameters
usrp->set_rx_rate(samp_rate_rx);
usrp->set_rx_freq(tune_request);
usrp->set_rx_gain(0);
//set tx parameters
usrp->set_tx_rate(samp_rate_tx);
usrp->set_tx_freq(tune_request);
usrp->set_tx_gain(0);
std::signal(SIGINT, &sig_int_handler);
std::cout << "Press Ctrl + C to stop streaming..." << std::endl;
//create buffers, 2 per channel (1 for tx, 1 for rx)
// transmitting complex shorts -> typedef as Complex
Complex *rx_buffs[NUM_CHANNELS];
Complex *tx_buffs[NUM_CHANNELS];
for (int i = 0; i < NUM_CHANNELS; i++){
rx_buffs[i] = new Complex[BUFF_SIZE];
tx_buffs[i] = new Complex[BUFF_SIZE];
// only transmitting 0's
std::fill(tx_buffs[i], tx_buffs[i]+BUFF_SIZE, 0);
}
//////////////////////////////////////////////////////////////////////////////
////////////////START RECEIVE AND TRANSMIT THREADS////////////////////////////
//////////////////////////////////////////////////////////////////////////////
printf("setting up threading\n");
//reset usrp time
usrp -> set_time_now(uhd::time_spec_t(0.0));
// set up RX streams and threads
std::thread rx_threads[NUM_CHANNELS];
uhd::rx_streamer::sptr rx_streams[NUM_CHANNELS];
for (int i = 0; i < NUM_CHANNELS; i++){
stream_args.channels = std::vector<size_t>(1,i);
rx_streams[i] = usrp->get_rx_stream(stream_args);
//setup streaming
auto stream_mode = uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS;
uhd::stream_cmd_t stream_cmd(stream_mode);
stream_cmd.num_samps = 0;
stream_cmd.stream_now = true;
stream_cmd.time_spec = uhd::time_spec_t();
rx_streams[i]->issue_stream_cmd(stream_cmd);
//start rx thread
std::cout << "Starting rx thread " << i << std::endl;
rx_threads[i] = std::thread(recvTask,rx_buffs[i],rx_streams[i]);
}
// set up TX streams and threads
std::thread tx_threads[NUM_CHANNELS];
uhd::tx_streamer::sptr tx_streams[NUM_CHANNELS];
// set up TX metadata
uhd::tx_metadata_t md;
md.start_of_burst = true;
md.end_of_burst = false;
md.has_time_spec = true;
// start transmitting 2 seconds later
md.time_spec = uhd::time_spec_t(2);
for (int i = 0; i < NUM_CHANNELS; i++){
//does not work when we transmit and receive on same channel,
//if we change to stream_args.channels = std::vector<size_t> (1,1), this works for 1 channel.
stream_args.channels = std::vector<size_t>(1,i);
tx_streams[i] = usrp->get_tx_stream(stream_args);
//start the thread
std::cout << "Starting tx thread " << i << std::endl;
tx_threads[i] = std::thread(txTask,tx_buffs[i],tx_streams[i],md);
}
printf("Waiting to join threads\n");
for (int i = 0; i < NUM_CHANNELS; i++){
//join threads
tx_threads[i].join();
rx_threads[i].join();
}
return EXIT_SUCCESS;
}
//////////////////////////////////////////////////////////////////////////////
////////////////RECEIVE AND TRANSMIT THREAD FUNCTIONS/////////////////////////
//////////////////////////////////////////////////////////////////////////////
void recvTask(Complex *buff, uhd::rx_streamer::sptr rx_stream){
uhd::rx_metadata_t md;
unsigned overflows = 0;
//receive loop
while(!stop_signal_called){
size_t amount_received = rx_stream->recv(buff,BUFF_SIZE,md,3.0);
if (amount_received != BUFF_SIZE){ printf("receive not equal\n");}
//handle the error codes
switch(md.error_code){
case uhd::rx_metadata_t::ERROR_CODE_NONE:
break;
case uhd::rx_metadata_t::ERROR_CODE_TIMEOUT:
std::cerr << "T";
continue;
case uhd::rx_metadata_t::ERROR_CODE_OVERFLOW:
overflows++;
std::cerr << "Got an Overflow Indication" << std::endl;
continue;
default:
std::cout << boost::format(
"Got error code 0x%x, exiting loop..."
) % md.error_code << std::endl;
goto done_loop;
}
} done_loop:
// tell receive to stop streaming
auto stream_cmd = uhd::stream_cmd_t(uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS);
rx_stream->issue_stream_cmd(stream_cmd);
//finished
std::cout << "Overflows=" << overflows << std::endl << std::endl;
}
void txTask(Complex *buff, uhd::tx_streamer::sptr tx_stream, uhd::tx_metadata_t md){
//transmit loop
while(!stop_signal_called){
size_t samples_sent = tx_stream->send(buff,BUFF_SIZE,md);
md.start_of_burst = false;
md.has_time_spec = false;
}
//send a mini EOB packet
md.end_of_burst = true;
tx_stream -> send("",0,md);
printf("End transmit \n");
}

How to use Native Host Message in Native Application For Chrome Native Messaging Extension

I am working on Chrome Extension with Native Host messaging. I am not able to use message text in my host application. Everything working fine from the establishing connection to get response in extension.
I need to use Message text in my application for further use/execution in simple text datatype (string/char). I know message is in UTF8 encoded form i tried to decode but still getting problem, can any one help me out?
When i decode message chrome extension console show Error: "Error when communicating with the native messaging host." and if i use that message text after "cout" same error is there "Error when communicating with the native messaging host". Direct sending and receiving message works fine for me.
Code is something like this :
std::string mycode(std::string data){
data= data+"abc"; //changing text to any thing.
cout<< data;
anotherFunction(data);//killing processes using string data
}
int main(int argc, char* argv[])
{
std::cout.setf( std::ios_base::unitbuf );
while (true)
{
unsigned int ch, inMsgLen = 0, outMsgLen = 0;
std::string input = "", response = "";
std::cin.read((char*)&inMsgLen, 4);
if (inMsgLen == 0)
{
break;
}
else
{
for (int i=0; i < inMsgLen; i++)
{
ch = getchar();
input += ch;
}
}
response.append("{\"echo\":").append(input).append("}");
outMsgLen = response.length();
std::cout.write((char*)&outMsgLen, 4);
std::cout << response;
cout<< input;
//using "input" variable for further user
mycode(input);
}
return 0;
}
That's wrong, did you read the docs ?
Try something like this...
_setmode( _fileno( stdin ), _O_BINARY );
_setmode( _fileno( stdout ), _O_BINARY );
char cBuffer[65536] = {0};
while(true)
{
unsigned int uiSize = 0;
std::cin.read((char*)&uiSize, sizeof(unsigned int));
if(uiSize != 0 && uiSize < 65536)
{
memset(cBuffer, 0, 65536);
std::cin.read(cBuffer, uiSize);
std::string strIn(cBuffer);
std::string strOut = "{\"result\":\"This is a Test\"}";
uiSize = strOut.length();
std::cout << char(((uiSize>>0) & 0xFF));
std::cout << char(((uiSize>>8) & 0xFF));
std::cout << char(((uiSize>>16) & 0xFF));
std::cout << char(((uiSize>>24) & 0xFF));
std::cout << strOut.c_str();
}
else
break;
}
You need to set the io to binary, otherwise things like this could happen...
if a byte with the value 00011010 (CTRL ALT Z = 26) is present it will be treated as a EOF and end the communication. :)

Trouble communicating between 2 sockets

I have a linux machine and a Windows machine I have a C++ program witch acts as a server on the linux machine and a Qt application witch acts as a client on windows machine. I use the socket as a encryption key (basic xor encryption)
The problem is when I hit multiple times connect I get bogus strings. I think the problem is in qt application here is my code. I have tried to put a global flag busy to prevent the user from hitting the connect button manny times but this flag never gets triggered.
Why? Should I use a mutex? If yes how?
void MainWindow::performRead()
{
QTcpSocket * sock = static_cast<QTcpSocket*>(this->sender());
if (key == 0)
{
busy = true;
QString recv(sock->readLine());
key = recv.toInt();
qDebug() << "Cheia este " << key;
char * response = enc_dec("#AUTH|admin|admin",strlen("#AUTH|admin|admin"),key);
sock->write(response);
}
else
{
busy = true;
while (sock->bytesAvailable() > 0)
{
unsigned short word;
sock->read((char*)(&word),2);
qDebug()<<word;
QByteArray bts = sock->read(word);
char * decodat = enc_dec((char*)bts.data(),bts.length() - 2,key);
char testx[2];
sock->peek(&testx[0],2);
qDebug() << decodat;
}
}
busy = false;
}
void MainWindow::on_pushButton_clicked()
{
if (!busy)
{
key = 0;
QTcpSocket * sock = new QTcpSocket();
connect(sock,SIGNAL(readyRead()),this,SLOT(performRead()));
sock->connectToHost("194.110.212.46",6550);
}
else qDebug()<<"Can't you see I am busy??" << endl;
}
char * enc_dec(char * str,int len, int key)
{
unsigned char keys[2];
keys[0] = (unsigned char)key;
keys[1] = keys[0] ^ 255;
char * nou = new char[len + 1];
nou[len] = '\0';
for (int i = 0; i < len; i++)
{
char tmpy = str[i] ^ keys[i % 2];
nou[i] = tmpy;
}
return nou;
}
Your code is pretty messed up, here are my suggestions:
Do not connect the socket on every button hit - you are overwriting what you had before, and do unnecessary work - TCP connection establishment is expensive,
Maybe have a "Connect" and "Disconnect" buttons, and only allow reading from socket when connection is established,
Try making sure everything works without your "encryption" first,
Use real encryption after that.

Artema Hybrid communication with c++ on Linux

I am currently trying to integrate a POS system with an Artema Hybrid CC handheld. I am wondering if anyone else has worked on this or something similar.
I can read from the device, that is I receive the ENQ, and send back an ACK in a thread, and I keep it open for reading/writing, but everything I try to write from it simply does nothing.
Here is the code for the function to write the data:
void PayLife::sendPayLifeData(QString data) {
int len = data.length();
int i = 0;
char lrc = 0;
char stx = 0x02;
char etx = 0x03;
char ack = 0x06;
char * bytes;
int ret;
char buffer[132];
bytes = (char *) malloc(sizeof(char) * len + 10);
strcpy(bytes,data.toLatin1().data());
qDebug() << "PayLife Sending data: " << data << " of len " << QString::number(len) <<
" " << " Bytes is: " << bytes ;
while (i < len) {
lrc ^= bytes[i];
i++;
}
/* sprintf(buffer,"%c%c%s%c%c",ack,stx,bytes,etx,lrc);
for (i = 0; i < strlen(buffer); i++) {
printf("c: %X ", buffer[i]);
}
printf(" [[ %s ]] \n", buffer); */
qDebug() << "Starting";
write(this->descriptor,&ack,1);
usleep(100000);
write(this->descriptor,&stx,1);
usleep(100000);
ret = write(this->descriptor,bytes,132);
usleep(100000);
write(this->descriptor,&etx,1);
usleep(100000);
write(this->descriptor,&lrc,1);
qDebug() << "Done";
free(bytes);
}
The data argument is: E11U000008507000099VZ000000
Of course, the documentation is in German, which I don't speak, so this is as far as I have gotten. I've basically got 1 month to implement this then I have to give the device back.
If anyone has any pointers, or some example code that would be awesome.
/jason
The transport protocol looks like something standard, so maybe you should only send len bytes of the data not 132 and include the ETX character in the lrc summing ?
It might be easier and clearer to use QByteArray instead of malloc arrays or QString (QString are for user displayed strings which is not the case here):
void PayLife::sendPayLifeData(const QByteArray & data) {
static const char stx = 0x02;
static const char etx = 0x03;
static const char ack = 0x06;
QByteArray buffer = stx + data + etx;
// Calculate the xor sum on data + etx
char lrc = 0;
for(int i = 1; i < buffer.size(); ++i) {
lrc ^= buffer[i];
}
buffer += lrc;
qDebug() << "Starting";
write(this->descriptor, &ack, 1);
write(this->descriptor, buffer.data(), buffer.size());
qDebug() << "Done";
}
You should also have a look at QSerialDevice, it could allow you to implement the protocol in a more event driven way with signal and slots.