Go Down

Topic: Delay when receive data from Arduino Nano in first time plug USB cable (Read 863 times) previous topic - next topic

nhatnam06dt1

Dear all!
I have a problem. Help me please.
Please look at my code.
+ Arduino code:
Code: [Select]

#include <FreqMeasure.h>
void setup() {
  Serial.begin(9600);
  FreqMeasure.begin();
}
double frequency=0;
int timeSetZeroFreq=0;
void loop() {
  if(Serial.available()>0)
  {
    switch(Serial.read())
    {
      case 0xA1:
            Serial.write(0xB1);
            delay(10);
            break;
      case 0xA4:
        {
            readFreq();
            byte *frequencyArray = (byte *) &frequency;
            Serial.write(0xB4);
            delay(10);
            Serial.write(frequencyArray[0]);
            delay(10);
            Serial.write(frequencyArray[1]);
            delay(10);
            Serial.write(frequencyArray[2]);
            delay(10);
            Serial.write(frequencyArray[3]);   
            delay(10);
            //Serial.write(frequencyArray,4);     
        }
            break;
      case 0xA8:
        {
            int voltage = analogRead(A0);
            byte * voltageArray = (byte *) &voltage;
            Serial.write(0xB8);
            delay(10);
            Serial.write(voltageArray[0]);
            delay(10);
            Serial.write(voltageArray[1]);
            delay(10);
            //Serial.write(voltageArray,2);
        }
            break;
      default:
            Serial.write(0xC1);
            break;
    }
  }
}
float readFreq()
{
  if (FreqMeasure.available())
      {
        double f = FreqMeasure.read();
        frequency = F_CPU / f;
      }
  else
  {
    timeSetZeroFreq = timeSetZeroFreq + 1;
    if(timeSetZeroFreq>50)
    {
      frequency = 0;
      timeSetZeroFreq = 0;
    }
  }
  return frequency;
}

+ Code in my project (written in C++ use SerialPort Class of Microsoft)
Code: [Select]

int main()
{
//initial serial port
SerialPort ^portSerial = gcnew SerialPort();
portSerial->BaudRate = L"COM3";
portSerial->Parity = Parity::None;
portSerial->StopBits = StopBits::Two;
portSerial->DataBits = 8;
portSerial->Handshake = Handshake::None;
portSerial->ReadTimeout = 500;
portSerial->WriteTimeout = 500;
portSerial->Open();
//send request
array<unsigned char>^request={0xA1};
while(1)
{
try
{
portSerial->Write(request,0,1);
//Read respond
       portSerial->ReadByte();
}
catch (System::Exception ^ex)
{
Console::WriteLine("Send Request Error: {0}",ex->Message);
}
}
}

-->My problem: In first time plug USB cable, function portSerial->ReadByte() error TimeOutException. After sending request in the 3rd (use while(1)), data received is true. More detail:
portSerial->Write(request,0,1) in the first time -> portSerial->ReadByte() error timeout
portSerial->Write(request,0,1) in the secondtime -> portSerial->ReadByte() error timeout
portSerial->Write(request,0,1) in the third time -> portSerial->ReadByte() = B1 ->right

But my problem occurs the first time you plug the USB cable. If do not disconnect the USB cable, then everything works normally.

PeterH

When the serial port is opened the Arduino will usually reset. When the Arduino starts up, the bootloader runs and waits for a moment in case you are about to upload a new sketch. It is only after the bootloader has timed out that your sketch gets to run. Because the sketch is not running when your 'C' program sends the command, it does not send a response hence the timeout. I recommend you put a delay of a second or two after opening the port before you start sending commands.

You code does not seem to make any provision for the Arduino being disconnected while the program is running - if you want it to run long term, it would need to handle serial port failures and re-open the port as necessary.
I only provide help via the forum - please do not contact me for private consultancy.

nhatnam06dt1

Thank you!
At first I think so. But when I use Serial Monitor to send command (on Arduino soft) at In first time plug USB cable --> Board reply immediately
Then I open the my project and send command --> it still fails time out as I said.
As you say, I have set portSerial->ReadTimeOut = 5000 (5s) but it still fails.
But my problem occurs the first time you plug the USB cable.

PeterH


Thank you!
At first I think so. But when I use Serial Monitor to send command (on Arduino soft) at In first time plug USB cable --> Board reply immediately
Then I open the my project and send command --> it still fails time out as I said.
As you say, I have set portSerial->ReadTimeOut = 5000 (5s) but it still fails.
But my problem occurs the first time you plug the USB cable.



When you open the Arduino serial monitor the board will reset. By the time you have typed the command sequence in to the serial monitor, the reset will be complete and the Arduino will be ready to respond.

Your application does the same thing but without any delay between opening the serial port (and making the Arduino reset as a result) and sending the first command. It doesn't matter how long you set the timeout; that first command was never received and the Arduino is never going to respond to it. Watch the Arduino and see how long it takes to complete a reset and begin running your sketch. Put in a delay a bit longer than that in your application, between opening the serial port and sending the first command.
I only provide help via the forum - please do not contact me for private consultancy.

nhatnam06dt1

#4
Jan 23, 2013, 02:10 am Last Edit: Jan 23, 2013, 02:17 am by nhatnam06dt1 Reason: 1
Thank! you're right. I'm put Sleep(2000) between opening the serial port and sending the first command ->it works normally
In case, I scan the COM port on the computer to find out portName of Arduino
Assuming my PC has the following ports
+ COM1
+ COM2
+ COM3
+ COM4 (Arduino)
I want to find the COM port of the Arduino. I will send the command to all COM ports, then receive respond
Check if respond properly to the value set under Arduino ->port Aruino found.
Code: [Select]

SerialPort ^portSerial = gcnew SerialPort();
portSerial->BaudRate = 9600;
portSerial->Parity = Parity::None;
portSerial->StopBits = StopBits::Two;
portSerial->DataBits = 8;
portSerial->Handshake = Handshake::None;
portSerial->ReadTimeout = 500;
portSerial->WriteTimeout = 500;
array<unsigned char>^request={0xA1};//respond will 0xB1 from arduino
listSerialPorts = portSerial->GetPortNames();
for each(String^ port in listSerialPorts)
{
portSerial->portSerial->PortName = port;
portSerial->Open();
Sleep(2000);
portSerial->Write(request,0,1);
rspFromBoard = portSerial->ReadByte();
if(rspFromBoard == 0xB1)
{
Console::WriteLine("Port Arduino Found");
}
}

->>>So happens in case of Sleep (2000) was repeated. It will create big delay in my app
In this case, how do I do?

PeterH

The delay only happens once, at startup. Is that a problem?

If it is, you could change your code so that it opens all the serial ports, wait 2 seconds and then sends a command to each one in turn - that way you would only have to wait for one delay.
I only provide help via the forum - please do not contact me for private consultancy.


PaulS

If you want to talk to any Arduino (such as the Leonardo), you'll need to add
Code: [Select]
portSerial->DtrEnable = true;
to the C++ code.

Go Up