0

So, I'm not sure what is causing this, but maybe I'm overlooking something simple. I have a simple program designed to read the analog input at 640 Hz, it looks like this:

int Ch0 = 0;
int count = 0;
unsigned long startTime;
unsigned long currentTime;
bool startedReading = false;


void setup() {
  //set up pin(s)
   pinMode(Ch0, INPUT);

  //begin serial at 115200bps
  Serial.begin(115200);
}

...

//if the current time exceeds the start time by one second, set the start time equal to current time, print the count, set count equal to zero
if (currentTime - startTime >= 1000) {
  startTime = currentTime;
  Serial.println("time");
  count = 0;
}



//read input, delay some microseconds as a means of controlling sampling rate, bring count up by one
//should read somewhere along the lines of 640-ish Hz
analogRead(Ch0);
delayMicroseconds(1230);
Serial.println(count);
count++;

And this all works fine and dandy in the Arduino IDE, I pull up the Serial Monitor, and it prints every number 1-640 and then says time, with good consistency. Yet, when I open up a Visual Studio program and call the command:

EDIT: Added entire data received event method

private: System::Void serialPort1_DataReceived(System::Object^  sender, System::IO::Ports::SerialDataReceivedEventArgs^  e) {
    if (!this->reading) return;
    else 
    {
         try
         {
            //get incoming port and read
            SerialPort^ sp = (SerialPort^)sender;
            String^ sInData = sp->ReadLine();
            //parse read data
            double inData = double::Parse(sInData);

            //write data to debugger for testing
            Debug::WriteLine(inData);


            //start populating the "in" array
            AppendIn(inData);
          }
          catch (Exception^ e)
          {
            Debug::WriteLine(e->Message);
          }
    }
}

Aside from the obvious error that occurs when I try to parse the string "time" to indicate when 1 second has elapsed, everything works fine. Except for the fact that the numbers feed into the debugger very slowly. As in, it'll take roughly 4-5 seconds to read through all 640 reads of the count integer and then it throws the time at me. Thus, this leads me to conclude that Arduino is indeed calculating that 1 second has elapsed and then sending that over, but the output is essentially the same, the only difference being that the message takes exactly 1 second to read on the Arduino IDE and over 4 seconds to read in real time in Visual Studio.

Maybe it has something to do with the way I'm reading the data in VS? I have it set up to constantly monitor the stream by calling that read method every as an event when data is received over the serial. No data at all is being lost, it's just very slow...and only in VS. Thanks in advance for any help you can give, but I'm at a bit of a loss.

0

I have it set up to constantly monitor the stream by calling that read method every as an event when data is received over the serial.

I suspect that is the issue. Waiting for an incoming "serial data available" event and then processing it, is likely to be slow. I would rework how you get serial data. You haven't shown that bit but maybe you can use a larger buffer.

  • Hmmm, I'm not entirely sure what you mean by "how I get serial data," but I did include the rest of the event if that's what you mean. The method is attached to the OnDataReceived event of a serial port control in a c++ Windows form if that sheds any more light on it also. That said, I took your suggestion and cranked the read buffer size to16384 (4x what it was before), but there weren't any noticeable speed improvements. So it might have something having to do with firing an event 640 times a second. Though, I'll have to see what other way I could read continuously then. – Scorch Jun 21 '16 at 0:42
  • I don't know exactly how the Windows functions work in this case. Can you provide a reference? (link). What I suspect is happening is that the event is called on the first incoming byte, and ReadLine is waiting for an entire line (and timing out after a couple of seconds). – Nick Gammon Jun 21 '16 at 1:23
  • I think you might be right, according to this page, it does read up until the new line character. In the mean time, I'll try messing around with some of the properties referenced on this page. msdn.microsoft.com/en-us/library/… – Scorch Jun 21 '16 at 14:02
  • Ok, looks like I'll have to double comment because I can only edit comments for 5 minutes, but I went through and disabled the timeout, then tried changing the ReadLine() command to each of the other alternative reads (there were only about 5 or so, so it wasn't too difficult to test them all) and it seems like it's working perfectly now. I seem to be getting the best speed out of ReadExisting(), granted with marginally less accuracy. It's a little difficult to tell if it's still reading at exactly 640 Hz, but it's very close if it's not. Thanks a ton for the help! – Scorch Jun 21 '16 at 14:25

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.