3

I made a super simple arduino uno sketch to send a serial byte once every second:

void setup(){
  Serial.begin(9600);
}

void loop(){
   Serial.write(12); // send a byte with the value 12
   delay(1000);
}

My arduino is hooked up to com 3.

On the other end of the line, I have a C++ program with the following read function:

int Serial::ReadData(char *buffer, unsigned int nbChar)
{
    //Number of bytes we'll have read
    DWORD bytesRead;
    //Number of bytes we'll really ask to read
    unsigned int toRead;

    //Use the ClearCommError function to get status info on the Serial port
    ClearCommError(this->hSerial, &this->errors, &this->status);

    //Check if there is something to read
    if(this->status.cbInQue>0)
    {
        //If there is we check if there is enough data to read the required number
        //of characters, if not we'll read only the available characters to prevent
        //locking of the application.
        if(this->status.cbInQue>nbChar)
        {
            toRead = nbChar;
        }
        else
        {
            toRead = this->status.cbInQue;
        }

        //Try to read the require number of chars, and return the number of read bytes on success
        if(ReadFile(this->hSerial, buffer, toRead, &bytesRead, NULL) && bytesRead != 0)
        {
            return bytesRead;
        }

    }

    //If nothing has been read, or that an error was detected return -1
    return -1;

}

This seems to check only one time if data is available, so obviously I have to loop through it until data comes in. I did that in my main program:

#include "Serial.h"
#include <iostream>

using namespace std;

int main(void)
{
    Serial serial("COM3");

    char* c = "";
    int len = strlen(c);
    while(c == "")
    {
        serial.ReadData(c, len);
    }

    cout << "\n\n";
    system("PAUSE");
}

When I do this, my C++ program gets stuck in an infinite loop waiting for data from the arduino, and I cannot figure out why this is happening. My program never sees the data the arduino is sending.

This Serial class works and is configured properly because I can SEND all the data I want to the arduino without any problems. My issues are only with reading back from the arduino.

Can someone please help me figure out why this is not working?

  • 1
    Welcome to Arduino SE! Have you verified the Arduino code outputs the right data with the serial monitor? If so, I think this question should be migrated to another site to address the C++ code. Thanks! – Anonymous Penguin Jul 31 '14 at 0:23
  • I think your C++ program needs to know what data rate (baud) to use. – user3388 Jul 31 '14 at 0:35
  • Can you also confirm that the receiver program works if you send some "correct" data with a terminal program? The answers to those two questions will tell you whether to look at the Arduino, the receiving CPU, or the serial line. – JRobert Jul 31 '14 at 0:36
  • I want to send keypad data from Arduino to Code Composer Studio or CCS and i'm using Texas instruments (TMS320F8069). When I send the data, I hope that CCS will show the Arduino data that i already send. And the CCS will send it back. It's like a TR > RX program. But, it's not work. I mean the CCS console (serial monitor) doesn't show the data. So, can you guys help me solve this problem? Here my CCS code... const int LEN = 1; char msgg[LEN + 1]; int numBytes = 0; for(;;) { msgg [numBytes] = 0; scia_msg(msg); // Wait for inc character while(SciaRegs.SCIFFRX.bit.RXFFST !=1) { } // wait for XRDY – Amirullah S. Sep 28 '18 at 4:13
6

The problem is in your C++ program at the other end of the line (not the Arduino side):

char* c = "";
int len = strlen(c);
while(c == "")
{
    serial.ReadData(c, len);
}

Here, len is zero because that is the length of "" , the empty string! Thus, in your loop, you ask ReadData to read 0 bytes. Hence, the condition of your while loop is always true as, c never changes.

Also, the while condition seems incorrect as it is not recommended in C++ to compare 2 strings (defines as char * or char [...]) with ==. In your situation, what is important is the number of characters read by ReadData:

char c[LEN + 1];
int numBytes = 0;
while(true)
{
    numBytes = serial.ReadData(c, LEN);
    if (numBytes != -1)
    {
        // Terminate the string if we want to use c variable as a string
        c[numBytes] = 0;
        break;
    }
}

in the code above, LEN is the number of characters you want to read at one time, in you example it should be set to 1, either as a #define or as a const variable:

// either:
#define LEN 1
// or:
const int LEN = 1;

The code above also ensures that c can be used as a normal string, by adding a 0 at the end. This is mandatory only if you want to use string functions on c such as strlen, strcpy, strchr... otherwise numBytes is enough to manage the number of characters read into c.

| improve this answer | |
1
char* c = "";
while(c == "")

The variable named c is a misnomer, because it is a pointer to a string, not a character. For example c = 0x123456.

You should use a more explicit name for your variable.

This first line assigns a pointer to an empty string to the c pointer. So, the value stored at address 0x123456 == whatever pointer to a static memory address containing '\0'

Note that no memory has been allocated to hold characters. Only a pointer to char has been allocated. Thus you cannot store anything in your string!!

You could write something like: char data[2] = ""; That would allocate a pointer, and a string to hold 2 characters


The second line, while(c == "") compares a real memory pointer (e.g. 0x123456) with a compiler pointer. "" is not a real application pointer, you should not manipulate it.

So that second line relies on a compiler behavior.


If I were you I would wrap the multi-char routine into a single-char routine. For example:

int ReadChar(char *c)
{
  return ReadData(c, 1);
}

Then:

main()
{
  char c;
  ReadChar(&c);
}

On a different note, I think the compiler should catch such error. The line c == "" would never do anything useful and should be caught.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.