Go Down

Topic: Re: Data Input demo sketch (Read 1 time) previous topic - next topic

germancorrea

Robin2 and J-M-L. I was reading yours posts and really was very helpfull for me.
I modified a little J-M-L example, sending_several_lines_of_characters.ino, to receive some commands from a VB.Net program.
I started changing your code

Code: [Select]

const char * labelsOfInterest[] = {"V", "I", "VPV", "PPV", "CS"};
const unsigned int maxLabelsOfInterest = sizeof(labelsOfInterest) / sizeof(*labelsOfInterest);

changed to

const char *cmds[] = {"*?", "f", "f?", "v", "v?", "i", "i?"};
const unsigned int maxCmds = sizeof(cmds) / sizeof(*cmds);



recvWithEndMarker() is same as your example but I changed a little your void parseNewData() to

Code: [Select]

void parseCalibrationData()
{
const char *delim  = " ";
char *item;
  boolean cmdFound;
int cmdIndex = 0;

item = strtok (receivedChars, delim);
cmdFound = false;
Serial.println(item); // to show cmd received in to VB.NET program

for (int i = 0; i < maxCmds; ++i)
{
if (!strcmp(cmds[i], item))
{
// {"*?", "f", "f?", "v", "v?", "i", "i?"}
cmdFound = true;
cmdIndex = i;
break; // ends the for loop as we found a cmd
} //ends if !strcmp(cmds[i], item)
}

if (cmdFound == true)
{
switch (cmdIndex)
{
case 0:
Serial.println("Calibration Software");
break;

case 1:
item = strtok(NULL, delim);
if (item != NULL)
{
frequency = atol(item);
}
break;

case 2:
item = strtok(NULL, delim);
if (item == NULL)
{
Serial.println(frequency);
}
break;

case 3:
item = strtok(NULL, delim);
if (item != NULL)
{
voltage = atol(item);
}
break;

case 4:
item = strtok(NULL, delim);
if (item == NULL)
{
Serial.println(voltage);
}
break;

case 5:
item = strtok(NULL, delim);
if (item != NULL)
{
fTotalCurrent = atol(item);
}
break;

case 6:
item = strtok(NULL, delim);
if (item == NULL)
{
Serial.println(fTotalCurrent/1000,3);
}
break;
break;

} // ends switch
} // ends if cmdFound = true
}


When I open monitor on Arduino 1.65 IDE or Serial COM11, in my case, on Atmel Studio 6.2.1563 Service Pack 2 and send any command, f? for example, everything works fine, Monitor reads f? 0. I close and open monitor several times and always works fine.
I close monitor or Serial Com11 and run my program in VB.Net, connect Serial COM11 and I send f? first time, I get ððððf? without frecuency value because if (!strcmp(cmds, item)) fails.
If I resend again same command, f?, I get  f? 0. 
I used Advanced USB Port Monitor 2.7.1.629 to spy USB communication and you can see I send f? + vblf (66 3F 0A) to arduino and I received ððððf? (F0 F0 F0 F0 66 3F 0D 0A) first time and I resend again f? + vblf (66 3F 0A) and I receive f?  0 (66 3F 0D 0A 30 0D 0A) that is wright answer
 
---------------
[2002] 20171117231914.991 (TX)
66 3F 0A                                        (f?.             )
---------------
[1983] 20171117231914.994 (RX)
F0 F0 F0 F0 66 3F 0D 0A                   (ððððf?..        )
---------------
Transfer buffer length: 0
---------------
[2005] 20171117231934.878 (TX)
66 3F 0A                                        (f?.             )
---------------
[2004] 20171117231934.883 (RX)
66 3F 0D 0A 30 0D 0A                       (f?..0..         )
---------------
Transfer buffer length: 0




How I can fix that?

I really appreciate your help

Robin2

#1
Nov 18, 2017, 09:39 am Last Edit: Nov 18, 2017, 09:41 am by Robin2
I close monitor or Serial Com11 and run my program in VB.Net, connect Serial COM11 and I send f? first time, I get ððððf? without frecuency value because if (!strcmp(cmds, item)) fails.
If I resend again same command, f?, I get  f? 0.
I'm not familiar with VB.net - it's a long time since I used Windows.

You have not posted an example of what the Arduino should be displaying.

Is your VB program opening and closing the Serial port and causing the Arduino to reset?

How have you set the serial paramters DTR and RTS in your VB program? They may be different from the Serial Monitor.

...R

PS. I am asking the Moderator to move your Post to its own Thread as it is not really relevant to this 3 year old and outdated Thread.
Two or three hours spent thinking and reading documentation solves most programming problems.

Coding Badly


germancorrea

#3
Nov 19, 2017, 01:25 am Last Edit: Nov 19, 2017, 01:36 am by germancorrea
Thanks Robin2 for your answer.
I am trying to adapt demo program and get it working fine.
I am going to send commands from my VB.Net program to set frequency to 560 Hz, set Voltage to 50 Volts or set Current to 150 mA., for example, using f 560, v 50 and i 150 (leavin a space between command and value).
When arduino receives those commands, changes those variable values. Command string ends with LineFeed (vblf = hex 0A).
But when I issue query commands with "?" as f?, v? and i?, arduino send 560, 50 and 150 values to my VB.NETprogram. I just display them in a textbox.
In my post this part correspods to void parseCalibrationData(), switch sentence.
I cann`t open VB.NET serial port and Arduino serial port at same time because they are same port. I was trying to use Virtual Serial Port Software, called VSPE, to make a virtual connection between a pair of serial ports but arduino port doesn't work even pairs are working.
I really don't know if my VB.Net program resets Arduino when it is opening Port. I don't see LED 13 switching off and on and TX LED LED 13 switching on and off as when I open port with Visual Studio. Besides that wellcome message "Arduino Ready" is not display in my program even if I call open serial port from my V.Net program.
Everything works but not nice, due to for my first cmd issued after port connection shows ððððf?, ððððv?, ðððði? and ðððð*? for *? command and ððððf, ððððv and ðððði for set commands.
Besides that, if I send same query command several times, sometimes I receive value with a space but not in same place, for example if I send f 345 and send f? repeatly some times I receive 356, 3 56 or 35 6.
I am attaching Arduino sketch and VB.Net executable.

Robin2

Everything works but not nice, due to for my first cmd issued after port connection shows ððððf?, ððððv?, ðððði? and ðððð*? for *? command and ððððf, ððððv and ðððði for set commands.

Besides that, if I send same query command several times, sometimes I receive value with a space but not in same place, for example if I send f 345 and send f? repeatly some times I receive 356, 3 56 or 35 6.

I am attaching Arduino sketch and VB.Net executable.
I am certainly not going to load an executable file. In any case I'm using Linux. And I don't like opening ZIP files.

I still don't have a clear picture of the problem.

Are those strange symbols appearing in your VB text box or are they appearing on the Arduino Serial Monitor?

Does the Arduino program work perfectly if you just send commands to it from the Serial Monitor? If so this is entirely a VB problem.

And notice how much easier it is to read text with white-space between paragraphs.

Quote
I really don't know if my VB.Net program resets Arduino when it is opening Port.
Then study your code and figure it out. It is a common problem with PC programs written by people who are not familiar with Arduinos that the PC program opens and closes the serial port instead of keeping it open. Everytime the serial port is opened the Arduino will reset which takes a few seconds. And your PC program must allow for that. I normally get my Arduino program to send "Arduino is ready" from setup() and my PC programs wait until they see that.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

germancorrea

Quote
I am certainly not going to load an executable file. In any case I'm using Linux. And I don't like opening ZIP files.
I really sorry too much.

Quote
And notice how much easier it is to read text with white-space between paragraphs.
I am taking note. Thanks

Quote
Then study your code and figure it out. It is a common problem with PC programs written by people who are not familiar with Arduinos that the PC program opens and closes the serial port instead of keeping it open. Everytime the serial port is opened the Arduino will reset which takes a few seconds. And your PC program must allow for that. I normally get my Arduino program to send "Arduino is ready" from setup() and my PC programs wait until they see that.
Certainly I am shure problem is in my VB program. My program is not resetting Arduino when its connect to Serial Port.

Looking carefully Atmel Studio Serial Port Monitor, I found DTR option was checked and in my program, serial port setting was disable.

With this change, Arduino resets when I connect my program to serial port and first part of my problem was solved.

I am going to translate my question to a VB.Net forum for space in string answer problem

Any way, thanks to J-M-L for demo code and you Robin2 for your valuable help.

I consider my question solved

zoomx

The ATmega16U2 has a bug in firmware. When you open the COM port without resetting the MCU Atmega328P the ATmega16U2 send a pulse to the Atmega328P RX line (and also to the USB lines but it's ignored, I think) that is interpreted as data depending on baud rate. If you use 9600 is ignored but starting from about 38400 it appears as character.

I doesn't appear if you use another chip as serial/USB converter, for example clones that use CH340.


Robin2

The ATmega16U2 has a bug in firmware. When you open the COM port without resetting the MCU Atmega328P the ATmega16U2 send a pulse to the Atmega328P RX line (and also to the USB lines but it's ignored, I think) that is interpreted as data depending on baud rate. If you use 9600 is ignored but starting from about 38400 it appears as character.
I have never noticed that behaviour. Do you have a test program that demonstrates it?

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

zoomx

I talked about it in the italian section here
https://forum.arduino.cc/index.php?topic=402709.0
I replicate the test code here
Code: [Select]
/*
   F0problem
   Test program to resolve the F0 problem
   When Serial port is opened in Windows
   I found an F0 in the Serial buffer
*/

//Serial input with termination section
#define INLENGTH 6          //Max string lenght over serial. Needed for input with termination
#define INTERMINATOR 13     //GetCharFromSerial routine cycle waiting for this character. Needed for input with termination

char inString[INLENGTH + 1]; //GetCharFromSerial returns this char array. Needed for input with termination
unsigned char comm; //First character received. Needed for input with termination

//SerialInputNewline
const byte numChars = 32;
char receivedChars[numChars];  // an array to store the received data
boolean newData = false;

//***********************************************************************************************
void recvWithEndMarker() {
  static byte ndx = 0;
  char endMarker = 13;   //'\r';
  char rc;

  // if (Serial.available() > 0) {
  while (Serial.available() > 0 && newData == false) {
    rc = Serial.read();
    Serial.print("recvWithEndMarker->");
    Serial.println(rc);

    if (rc != endMarker) {
      receivedChars[ndx] = rc;
      ndx++;
      if (ndx >= numChars) {
        ndx = numChars - 1;
      }
    }
    else {
      receivedChars[ndx] = '\0'; // terminate the string
      ndx = 0;
      newData = true;
    }
  }
}

void ParseMenu(char Stringa) {
  boolean IsKnownCommand = true;
  switch (Stringa) {

    case 'p':
      break;
    case 'm':

      Serial.println("Print menu");
      break;
    case 'w':
      Serial.println("Execute w");
      break;
    default:
      IsKnownCommand = false;
  }
  if (IsKnownCommand == true)
  {
    Serial.println("OK");
    EndCommand();
  } else {
    Serial.println("ERROR!");
    Serial.println(Stringa, HEX);
  }
}

//***********************************************************************************************
void EndCommand() {
  Serial.println("End command");
}

void setup() {
  Serial.begin(115200);
  Serial.println("F0problem");
}


void loop() {

  recvWithEndMarker();
  if (newData == true) {
    comm = receivedChars[0];

    Serial.print("Command->");
    Serial.print(comm);
    Serial.print(" ");
    Serial.println(comm, HEX);

    if (comm != 0xF0) {
      ParseMenu(comm);
    }
    else
    {
      //comm = 'p';
      Serial.println("Discard F0");
      Serial.println("OK");
      EndCommand();
    }
    newData = false;
  }
}

This is not a good sketch but it works.

You need a serial terminal program different from the one that is in the ide since it uses DTR and reset the MCU.

I used this one
https://sites.google.com/site/terminalbpp/
It is the same using RealTerm, go to the pins tab and clear DTR and RTS then go to the display tab, open and close many times the COM port.

You must use an Arduino with Atmega16U2, clones with CH340 doesn't have this nasty bug.
I tested also Hoodloader2 and this bug is not present.

When virtual port com is opened the Atmega16U2 sends a pulse of about 4us to the main MCU (not the PC this was a mistake).


Robin2

#9
Nov 20, 2017, 06:04 pm Last Edit: Nov 20, 2017, 06:09 pm by Robin2
I have tried your program on a genuine Mega with a 16u2 and I can't see any erroneous behaviour. I am using Linux Mint and I have tried it with minicom and putty.

Where might I expect to see this unwanted character?

And when I am writing a PC program to communicate with an Arduino I always have it wait for message from the Arduino such as Serial.println("Arduino is ready"); which would probably be sufficient to ignore any initial strange characters.

Where I have noticed unwanted characters is if the Arduino has started running and sending data before a PC program opens the serial port there may be characters in the PC's buffer which get displayed. Again, the strategy in my previous paragraph deals with that.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

zoomx

I have not tested a Mega, it should be the same but I am not sure. I used Windows 7. I noticed this behaviour the first time using a Visual Studio program but then I was able to replicate it in other terminal programs.

I believe that you have to open and close the port without using any flow control. When you open terminal, if you see "F0problem" it means that there was a reset.

If you don't see any problem maybe this happen only in Windows. This may be interesting. I have a Mega around, I will test it also.

F0 F0 F0 F0 are the same bytes that I get opening port in Windows without resettting Arduino.

Robin2

F0 F0 F0 F0 are the same bytes that I get opening port in Windows without resettting Arduino.
Send a message to Redmond :)

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

PaulS

Send a message to Redmond :)

...R
Use FU FU FU FU in the message...

Go Up