I have the same code in 2 different projects. The Qstring::number(data.toLong(&ok,2),16) works in one project and in the other project it does not work. Does anyone know what the reason could be? The code is as follows
1) unsigned short status;
2) long int setting;
3) bool ok;
4) QString data_selected;
5) data_selected = lineEdit_data->text(); //get the binary value
6) data_selected = QString::number(data_selected.toLong(&ok, 2), 16); //convert binary value to hex value
7) setting = data_selected.toLong(&ok, 16); //convert string to integer
In line 5 I am getting data from a lineEdit. This line works fine. I just inserted a new text edit box and displayed the data there and there I can see data. I have data as "1000000000001000". Then I execute line 6, the output of which is '8008' in first case and '0' in the other project. This is the problem. The code is exactly the same. I have copied and pasted. But in debugging I can see this difference. Please can anyone tell me why this is happening?
I thought that comment under answer was clear.
Correct code like this to detect what is the problem:
ulong setting;
bool ok;
data_selected = data_selected.trimmed(); // first try without this line
ulong value = data_selected.toULong(&ok, 2);
if (ok) {
data_selected = QString::number(value, 16);
setting = data_selected.toULong(&ok, 16);
} else {
data_selected = "convertion error";
}
Related
I'm desperatly trying to get arduino to divide a string from processing into two sets of variables. In the code below I've decided to just type the important parts but x and y does of course contain the correct values. Any solution would be appreciated. These are my two attempts so far:
Attempt 1 doesn't work at all.
1.Processing:
myPort.write(x + "," + y + "\n");
1.Arduino:
String tempX = Serial.readStringUntil(44);
String tempY = Serial.readStringUntil(10);
String x = tempX.substring(0,tempX.length() -1);
String y = tempY.substring(0,tempY.length() -1);
Attempt 2 where x works correctly but not y.
2.Processing:
String [] dataToSend = new String [2];
dataToSend [0] = x;
dataToSend [1] = y;
String joinedData = join(dataToSend, ":");
myPort.write(joinedData);
2.Arduino:
String x = Serial.readStringUntil(":");
Serial.read(); //next character is comma, so skip it using this
String y = Serial.readStringUntil('\0');
First, don't worry about combining them on the Processing side. Sending two strings one right after the other is the same as sending one long string. It's all being broken into bytes on the Serial line and nobody can tell where one print line stops and the next starts.
myport.write(x);
myport.write(',');
myport.write(y);
myport.write('\n')
will work just as good.
Then on the Arduino side you most likely want to shy away from the String class. Read the data character by character into a char array.
char myArray[howLongTheStringIs];
char x[howLongXIs];
char y[howLongYIs];
int index = 0;
This gets called over and over in loop and picks up serial data as it comes in:
while (Serial.available()){
char c = Serial.read();
myArray[index] = c; // add c to the string
myArray[++index] = 0; // null terminate our string
if(c == '\n'){ // if we are at the end of the string
handleString();
}
}
Then you have a function to parse your string there are lots of ways to do that:
If you don't know anything about the strings other than the separator use strtok:
void handleString(){
char* ptr = strtok(myArray, ":"); // get up to the ":" from the string
strcpy(x, ptr); // copy into x
ptr = strtok(NULL, "\n"); // get from the separator last time up to the next "\n"
strcpy(y, ptr); // copy into y
index = 0 // reset our index and
myArray[0] = 0; // and clear the string
}
That's all untested and uncompiled and written in the reply box, so if I made a little typo in there please forgive and correct. But something like this should work. If you already know the exact lengths of the strings (or can send them from the processing code) then the handleString method can be simpler. If you've got something short to do with x and y and don't need them after that then maybe you can just keep pointers to where they are in myArray. It all depends on what the larger picture goal of your code is. But something like this should get the job done.
I tried this code but still have problem for QString to short value for example it work well for text = 20 but it return 0 for value = 20.5.
but I need value=20. how can I solve it?
inline __int16 GetStaticToInteger(QLineEdit* lineEdit) {
QString text; __int16 nValue = 0;
nValue = QString::number(lineEdit->text().toDouble()).toShort();
return nValue;
}
'20.5' is not a valid text representation for an integer value. You can check this:
QString str("20.5");
bool ok;
short s = str.toShort(&ok);
qDebug() << ok
The output will be 'false'.
If you need an integer value you can do this:
short s = str.toDouble();
If you need your value rounded to the nearest integer use qRound:
short s = qRound(str.toDouble());
You have made it to complicated.
inline __int16 GetInteger16FromStatic(QLineEdit* lineEdit) {
QString text; __int16 nValue = qRound(lineEdit->text().toDouble());
return nValue;
}
Also Qt provides types with defined size, like qint16 to be compiler/platform independent, so you don't have to use __int16.
Hi i´m using Processing with my Arduino to use Serial comunication between them. I have trouble with this part of the code:
void draw(){
//read the string.
pot = arduino.readStringUntil(10);
//check for null values before casting to int
if(pot != null){
num = Integer.parseInt(pot);
//draw depending on values
rect(0,0,100,100);
text(pot, 0,0);
}
}
The line num = Integer.parseInt(pot); always gives me trouble. There is always a problem with the string I use. The las Error Message is NumberFormatExcepcion: For input string: "111 " The number at the end is the number i want to read (it is correct). But somehow i cant cast that string into an int. The number int the error message has always a space at the end. I tried to delet it but I can´t. I used pot = pot.substring(0, pot.length()-1); and pot = pot.replace(" ","");. But it doesnt work.
You should try to use the trim method from the String class.
if(pot != null){
pot = pot.trim()
num = Integer.parseInt(pot);
Hopefully this will help you.
I find it difficult to translate binary into picture, I use a pixmap.
transfer into the binary is correct but when I show using this program actually does not work.
this is my code:
if (binaryNumber[0]==1)ui->led16->setPixmap(QPixmap("../../picture/ball-yellow.png"));
else ui->led16->setPixmap(QPixmap("../../picture/ball-gray.png"));
if (binaryNumber[1]=1) ui->led15->setPixmap(QPixmap("../../picture/ball-yellow.png"));
else ui->led15->setPixmap(QPixmap("../../picture/ball-gray.png"));
if (binaryNumber[2]==1)ui->led14->setPixmap(QPixmap("../../picture/ball-yellow.png"));
else ui->led14->setPixmap(QPixmap("../../picture/ball-gray.png"));
if (binaryNumber[3]==1)ui->led13->setPixmap(QPixmap("../../picture/ball-yellow.png"));
else ui->led13->setPixmap(QPixmap("../../picture/ball-gray.png"));
if (binaryNumber[4]==1)ui->led12->setPixmap(QPixmap("../../picture/ball-yellow.png"));
else ui->led12->setPixmap(QPixmap("../../picture/ball-gray.png"));
bool ok2 = false;
QByteArray binaryNumber = QByteArray::number(DO.toLongLong(&ok2, 16), 2);
qDebug()<<binaryNumber<<binaryNumber[0]<<binaryNumber[1]<<binaryNumber[2 <<binaryNumber[3];
i.e
binaryNumber =1011
binaryNumber[0] = 1
binaryNumber[1] = 0
binaryNumber[2] = 1
binaryNumber[3] = 1
but when
binaryNumber =100
binaryNumber[0] = 1
binaryNumber[1] = 0
binaryNumber[2] = 0
so when i use a pixmap, then led the flame does not correspond to the binary number because array [0] is different when the size is different.
is there any simple code for me?
Your use of a QByteArray to store bits of a number is unnecessary. In C/C++, you can access the bits directly by doing a bitwise AND (&) with a mask.
template <typename T> static QPixmap setPixmap(T * p, int value, int bitNo)
{
const bool bit = value & (1<<bitNo);
p->setPixmap(bit ? QPixmap("../../picture/ball-yellow.png")
: QPixmap("../../picture/ball-gray.png"));
}
void Class::setDisplay(int val)
{
setPixmap(ui->led12, val, 0);
setPixmap(ui->led13, val, 1);
setPixmap(ui->led14, val, 2);
setPixmap(ui->led15, val, 3);
setPixmap(ui->led16, val, 4);
}
Note that QByteArray::number() returns alphanumeric characters ('0' = 48, '1' = 49 etc.), not characters with the numerical values 0, 1 etc. This is an important difference!
If you do binaryNumber = QByteArray::number(value, 2), this returns a byte array like for example "1010". Thus, binaryNumber[0] == '1', NOT binaryNumber[0] == 1:
if (binaryNumber[0]=='1')ui->led16->setPixmap(QPixmap("../../picture/ball-yellow.png"));
else ui->led16->setPixmap(QPixmap("../../picture/ball-gray.png"));
if (binaryNumber[1]=='1')ui->led15->setPixmap(QPixmap("../../picture/ball-yellow.png"));
else ui->led15->setPixmap(QPixmap("../../picture/ball-gray.png"));
if (binaryNumber[2]=='1')ui->led14->setPixmap(QPixmap("../../picture/ball-yellow.png"));
else ui->led14->setPixmap(QPixmap("../../picture/ball-gray.png"));
if (binaryNumber[3]=='1')ui->led13->setPixmap(QPixmap("../../picture/ball-yellow.png"));
else ui->led13->setPixmap(QPixmap("../../picture/ball-gray.png"));
if (binaryNumber[4]=='1')ui->led12->setPixmap(QPixmap("../../picture/ball-yellow.png"));
else ui->led12->setPixmap(QPixmap("../../picture/ball-gray.png"));
Note that your code is riddled with redundant code lines, resulting in bad quality software. You should try to write the code above in a loop or at least move out the pixmaps. Moving the pixmap initialisations in some static variables or in the constructor of the containing class results in some performance boost, too.
So your class could look similar to this: (I only included the relevant parts, of course, there also has to be the code for the UI stuff.)
class LEDNumberView
{
private:
// member variables:
QPixmap bitOn;
QPixmap bitOff;
// helper function
inline QPixmap getBitPixmap(bool bitVal)
{
return bitVal ? bitOn : bitOff;
}
public:
// constructor
LEDNumberView()
{
QString path = "../../picture/ball-%1.png";
bitOn = QPixmap(path.arg("yellow"));
bitOff = QPixmap(path.arg("gray"));
}
// call whenever you want to change the binary number displayed by the LEDs
void setBinaryNumber(int value)
{
QByteArray binaryNumber = QByteArray::number(value, 2);
ui->led16->setPixmap(getBitPixmap(binaryNumber[0] == '1'));
ui->led15->setPixmap(getBitPixmap(binaryNumber[1] == '1'));
ui->led14->setPixmap(getBitPixmap(binaryNumber[2] == '1'));
ui->led13->setPixmap(getBitPixmap(binaryNumber[3] == '1'));
ui->led12->setPixmap(getBitPixmap(binaryNumber[4] == '1'));
ui->led11->setPixmap(getBitPixmap(binaryNumber[5] == '1'));
}
};
To combine the answer of Kuba Ober with mine, write the setBinaryNumber function as he suggested. It's up to you which method of binary conversion you prefer - bit manipulation (use his method) or convert to and then work with bytes (yours).
I'm trying to print a image from a Dicom file. I pass the raw data to a convertToFormat_RGB888 function. As far as I know, Qt can't handle monochrome 16 bits images.
Here's the original image (converted to jpg here):
http://imageshack.us/photo/my-images/839/16bitc.jpg/
bool convertToFormat_RGB888(gdcm::Image const & gimage, char *buffer, QImage* &imageQt)
Inside this function, I get inside this...
...
else if (gimage.GetPixelFormat() == gdcm::PixelFormat::UINT16)
{
short *buffer16 = (short*)buffer;
unsigned char *ubuffer = new unsigned char[dimX*dimY*3];
unsigned char *pubuffer = ubuffer;
for (unsigned int i = 0; i < dimX*dimY; i++)
{
*pubuffer++ = *buffer16;
*pubuffer++ = *buffer16;
*pubuffer++ = *buffer16;
buffer16++;
}
imageQt = new QImage(ubuffer, dimX, dimY, QImage::Format_RGB888);
...
This code is a little adaptation from here:
gdcm.sourceforge.net/2.0/html/ConvertToQImage_8cxx-example.html
But the original one I got a execution error. Using mine at least I get an image, but it's not the same.
Here is the new image (converted to jpg here):
http://imageshack.us/photo/my-images/204/8bitz.jpg/
What am I doing wrong?
Thanks.
Try to get values of pixels from buffer manually and pass it to QImage::setPixel. It can be simplier.
You are assigning 16-bit integer to 8-bit variables here:
*pubuffer++ = *buffer16;
The result is undefined and most compilers just move the lower 8 bits to the destination. You want the upper 8 bits
*pubuffer++ = (*buffer16) >> 8;
The other issue is endianness. Depending to the endianness of the source data, you may need to call one of the QtEndian functions.
Lastly, you don't really need to use any of the 32 or 24-bit Qt image formats. Use 8-bit QImage::Format_Indexed8 and set the color table to grays.