Go Down

Topic: Visual Studio to Arduino Uno serial communication (Read 2 times) previous topic - next topic

blank

Hello guys,

I wrote an application on visual studio 2008 c++ which reads .kml google earth saved path files chooses a COM port, baud rate and sends the number of points and latitude - longitude values as Strings to the board. Also wrote a sketch to read those Strings and save them in a class. I did the application some time ago when I was using an ArduinoBT but for memory reasons (my code is more than 16k) I'm now using an Arduino Uno.
Everything worked fine with the Bluetooth board, but not with Uno.

Is it that the Uno communicates with the PC through a USB cable, so I need to re-write the sketch to accept USB data packets or something?

PaulS

The exact same code on the PC should talk to the exact same sketch on the UNO.

Quote
Everything worked fine with the Bluetooth board, but not with Uno.

What kinds of problems are you having?

blank

#2
Aug 10, 2011, 08:06 pm Last Edit: Aug 10, 2011, 08:24 pm by blank Reason: 1

What kinds of problems are you having?


Uno stucks in a while (Serial.available < 1) {} and awaits for serial data. The Rx led on the board blinks just once. It's like nothing is being send

PaulS

Does the COM port that the C++ application tries to talk to match the COM port that you upload software to?

blank


Does the COM port that the C++ application tries to talk to match the COM port that you upload software to?


Yes. I'm choosing an available COM port from a comboBox on the app, COM 20, on which my Uno is registed to.

PaulS

Some applications have issues with COM port numbers greater than 9. There are some bizarre special characters that need to precede the name when the number is greater than 9.

Can you disable stuff to get the port number down to 9 or less? Bluetooth, most likely.

Or google COM port greater than 9.

blank

Got it on COM 9. Same results. Stuck in the while loop

PaulS


blank

code from the application:
Code: [Select]


public ref class Coordinates
{
public:
String^ latitude;
String^ longitude ;
public:
Coordinates()
{
latitude = "";
longitude = "";
}
property String^ Latitude
{
void set(String^ aLatitude){latitude = aLatitude;}
String^ get(){return latitude;}
}
property String^ Longitude
{
void set(String^ aLongitude){longitude = aLongitude;}
String^ get(){return longitude;}
}
};
public ref class Global
{
public:
static array<Coordinates^>^ allCoords;
};




String ^CoordString;
XmlTextReader ^rdrCoords = gcnew XmlTextReader(this->openFileDialog1->FileName);
while (rdrCoords->Read())
{
if(rdrCoords->Name->Equals("coordinates") )
{

String ^str1,^str2;

int StrSize = 0;

int CommaCounter = 0;
int K = 0;
CoordString = rdrCoords->ReadElementString("coordinates");
StrSize = CoordString->Length;
for(int i = 0; i<StrSize; i++)
if(CoordString[i] == ',')
PointsCounter+=1;
PointsCounter = PointsCounter/2;
Global::allCoords = gcnew array<Coordinates^> (PointsCounter);
str1 = CoordString->Substring(5,8);
Global::allCoords[0] = gcnew Coordinates();
Global::allCoords[0]->Longitude = str1; //double::Parse(str1, System::Globalization::CultureInfo::InvariantCulture);
for(int i = 0; i<StrSize; i++)
{
if(CoordString[i] == ',')
{
CommaCounter++;
if(CommaCounter%2 == 0)
{
K++;
if(K == PointsCounter) break;
Global::allCoords[K] = gcnew Coordinates();
str2 = CoordString->Substring(i+3,8);
Global::allCoords[K]->Longitude = str2; //double::Parse(str2, System::Globalization::CultureInfo::InvariantCulture);


}
else
{
str1 = CoordString->Substring(i+1,8);
Global::allCoords[K]->Latitude = str1;
}
}
}
for(int i = 0; i<PointsCounter; i++)
{
ListViewItem ^listItem = gcnew ListViewItem(Convert::ToString(i+1));
listItem->SubItems->Add(Global::allCoords[i]->Longitude);
listItem->SubItems->Add(Global::allCoords[i]->Latitude);
listView1->Items->Add(listItem);

}
}



String^ string_PointsCounter = Convert::ToString(PointsCounter);
SerialPort^ serialPort = gcnew SerialPort(
comboBox1->Text,
Convert::ToInt32(comboBox2->Text),
Parity::None,
8,
StopBits::One);

serialPort->Open();
serialPort->Write(Convert::ToString(string_PointsCounter->Length));
serialPort->Write(string_PointsCounter);
for (int i = 0;i<PointsCounter;i++)
{
serialPort->Write(Global::allCoords[i]->Latitude);
serialPort->Write(Global::allCoords[i]->Longitude);

}
serialPort->Close();





sketch:
Code: [Select]

#include <stdlib.h>
//void* operator new(size_t size) { return malloc(size); }
//void operator delete(void* ptr) { free(ptr); }

class Coordinates
{
private:
float latitude;
float longitude;
public:
void setLatitude(float aLatitude){latitude = aLatitude;}
void setLongitude(float aLongitude){longitude = aLongitude;}
double getLatitude(){return latitude;}
double getLongitude(){return longitude;}
};
bool comm_done1 = false;
bool comm_done2 = false;
bool comm_done3 = false;
char buffer0[8];
char buffer1[8];
char buffer2[8];
char buffer3[8];
Coordinates allCoords[18];
int times,p;
float a;
Coordinates aPoint;


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

void loop()
{

if(!comm_done3)
  {
    while(Serial.available() < 1 ){} 
    buffer0[0] = Serial.read();
    while (Serial.available() < atoi(buffer0)){}
    for(int i=0;i<atoi(buffer0);i++)
    buffer1[i] = Serial.read();
   
    times = atoi(buffer1)*16;
    if(times < 112)
    {
      while (Serial.available() < times){}
      for(int j = 0; j<times/16; j++)
       {
         for(int i=0; i<8; i++) buffer2[i] = Serial.read();
         for(int i=0; i<8; i++) buffer3[i] = Serial.read();
     
         allCoords[j].setLatitude(atof(buffer2));
         allCoords[j].setLongitude(atof(buffer3));
       }
    }
    else
    {
      p = times / 112;
      int q;
      for(int m=0;m<p;m++)
      {
        while(Serial.available() < 112){}
        for(int j = m*7;j<m*7+7;j++)
       {
         for(int i=0; i<8; i++) buffer2[i] = Serial.read();
         for(int i=0; i<8; i++) buffer3[i] = Serial.read();
     
         allCoords[j].setLatitude(atof(buffer2));
         allCoords[j].setLongitude(atof(buffer3));
         q=j;
       }
      }
       while (Serial.available() < times-p*112){}
       for(int j=q+1; j<q+1+(times-p*112)/16; j++)
       {
         for(int i=0; i<8; i++) buffer2[i] = Serial.read();
         for(int i=0; i<8; i++) buffer3[i] = Serial.read();
         
         allCoords[j].setLatitude(atof(buffer2));
         allCoords[j].setLongitude(atof(buffer3));
       }
       
      }
   
    comm_done3 = true;   
   }






my lat, long values are in this format: 12.34567, 12.34567

PaulS

Quote
serialPort->Open();
         serialPort->Write(Convert::ToString(string_PointsCounter->Length));
         serialPort->Write(string_PointsCounter);
         for (int i = 0;i<PointsCounter;i++)
         {
            serialPort->Write(Global::allCoords->Latitude);
            serialPort->Write(Global::allCoords->Longitude);

         }
         serialPort->Close();

You are aware, I hope, that opening the serial port resets the Arduino. Closing it does too. Unless you have modified the Arduino to not do this.

I'd hazard a guess that you are jamming all the serial data out before the Arduino is ready to receive any data, and then resetting the Arduino.

blank

I actually didn't know that. The exact same code, works for my BT board. I can't understand what's going wrong.

PaulS

Perhaps the ArduinoBT doesn't reset when the serial port is opened and closed.

Try modifying the C++ application to open the port once (in response to a button press?) and close it once (when the application ends?).

blank

I'll try that tomorrow and let you know of the results. Thanks for all the help!

blank

Right, its not a visual c++ issue. It has to do with the DTR/RTS lines which are activated when a COM port opens and reseting the arduino.

blank

Quote
The easiest way is to stick a larger value capacitor between gnd and the reset pin. I use a 10uF - works a treat.   It has the effect of 'swallowing' the small ground pulse transferred by the 0.1uF auto reset capacitor and preventing the board from resetting.  It avoids the current drain of holding it high with a resistor. too.


worked like a charm!

Go Up