Search code examples
arduinobuildervcl

Serial Communication Arduino C++ Builder


I am trying to write an Application with C++ Builder which should display for example the temperature and humidity of a measurement from the Arduino. Arduino and my Application are connected via TComPort. I am using a Baudrate of 115200.

VCL Code:

AnsiString temp, hum;

ComPort1->ReadStr(temp, 5);
RichEdit1->Text = temp;

ComPort1->ReadStr(hum, 5);
RichEdit3->Text = hum;

Arduino Code:

DHT dht(10, DHT11);

void setup(void)
{
dht.begin();
Serial.begin(115200);
}

void loop(void)
{
// Measure the humidity & temperature
float h = dht.readHumidity();
float t = dht.readTemperature();

// Transform to String
String temp = String( t );
String hum =  String( h );
delay(10);
Serial.print(temp);
Serial.print(hum); 

delay(5000);

}

When I start my Application (VCL with C++ Builder) and connect to the Arduino every 5 seconds, the values should be refreshed by new values. Most of the time the 2 values are correct and it displays like it should for example Temperature: 24:00 Humidity: 55.00 But for some reason every now and then it displays something like this: Temperature: .0051 Humditiy: .00

or some other weird values. 5 seconds later the values are correct again. This happens every 20-30 seconds 1 time and i dont know why this keeps happening.


Solution

  • In the TComPort.OnRxChar event, there is a Count parameter that tells you how many bytes are available. Don't read more than that. Buffer the bytes to the side, and then read only complete values from that buffer.

    For example:

    private:
        AnsiString ComPortBuffer;
    
    void __fastcall TMyForm::ComPort1RXChar(TObject *Sender, int Count)
    {
        AnsiString s;
    
        int len = ComPort1->ReadStr(s, 5);
        if (len > 0)
        {
            if (len < 5)
                s.SetLength(len);
            ComPortBuffer += s;
        }
    
        while (ComPortBuffer.Length() >= 10)
        {
            AnsiString temp = ComPortBuffer.SubString(1, 5);
            AnsiString hum  = ComPortBuffer.SubString(6, 5);
            ComPortBuffer.Delete(1, 10);
    
            // use temp and hum as needed...
            RichEdit1->Text = temp;
            RichEdit3->Text = hum;
        }
    }