Multi serial and millis() on MEGA

Bonjour,
Merci d'avance pour votre aide, malgré plusieurs jours de recherche je n'ai pas trouver la solution a mon problème.
j'ai une Arduino nano qui me sert d'actionneur bas niveau pour des capteurs et moteurs et je veux lui envoyer des instructions et récupérer des infos via la liaison serie1 d'une MEGA et cela toutes les 200ms.
D'un autre coté j'aimerai faire un monitoring toutes les 500ms sur la liaison serie0 (USB) sur mon PC.

je me suis inspirer de de l'exemple " Use Multiple Serial Ports on the Arduino Mega" et de la fonction millis().

Quand la nano reçoit le string "comP2 R1_GPIO" elle répond par une chaine de 8 zéro ou un en random du genre.

voici le code:



unsigned long TempsMEGA2NANO;
String RecupNANO;
String EnvoiNANO;

void setup() {
  // initialize both serial ports:
  Serial.begin(1000000);
  Serial1.begin(1000000);
  TempsMEGA2NANO = millis();
  EnvoiNANO = "comP2 R1_GPIO\n";
}

void loop() {
  if (millis() - TempsMEGA2NANO > 99) {
    TempsMEGA2NANO = millis();
    Serial.println("je suis dans le millis");
    Serial1.print(EnvoiNANO);
    Serial.print("voici le RecupNANO: ");
    Serial.println(RecupNANO);
    Serial.print("voici le millis(): ");
    Serial.println(TempsMEGA2NANO);
  }

  // read from port 1:
  if (Serial1.available()) {
    RecupNANO = Serial1.readString();
  }

  // read from port 0:
  if (Serial.available()) {
    EnvoiNANO = Serial.readString(); //oui oui c'est un faux RecupNANO
  }
}

le problème c'est que j'ai un temps de réponse a seconde au lieu des 100ms de la boucle millis.
image
A la main directement avec la consol sur la nano je suis plus rapide...

Je suis donc preneur d'explication car je suis devant un mur la.

Voili voilou

Vincent

This is the english speaking forum.

If you prefer writing in french you should report your posting to a moderator to move your posting to the french speaking subforum

Use serial.read() instead of readstring()
Serial.readString() reads characters from the serial buffer into a String. The function terminates if it times out default timeout 1 second (see setTimeout()).
to make your datatransmission reliable use receiving with start and endmarkers
here is a demo-code that shows this

#define ProjectName "serial receive with start- and endmarker"

// MACRO-START * MACRO-START * MACRO-START * MACRO-START * MACRO-START * MACRO-START *
https://forum.arduino.cc/t/comfortable-serial-debug-output-short-to-write-fixed-text-name-and-content-of-any-variable-code-example/888298
#define dbg(myFixedText, variableName) \
  Serial.print( F(#myFixedText " "  #variableName"=") ); \
  Serial.println(variableName);

#define dbgi(myFixedText, variableName,timeInterval) \
  { \
    static unsigned long intervalStartTime; \
    if ( millis() - intervalStartTime >= timeInterval ){ \
      intervalStartTime = millis(); \
      Serial.print( F(#myFixedText " "  #variableName"=") ); \
      Serial.println(variableName); \
    } \
  }

#define dbgc(myFixedText, variableName) \
  { \
    static long lastState; \
    if ( lastState != variableName ){ \
      Serial.print( F(#myFixedText " "  #variableName" changed from ") ); \
      Serial.print(lastState); \
      Serial.print( F(" to ") ); \
      Serial.println(variableName); \
      lastState = variableName; \
    } \
  }

#define dbgcf(myFixedText, variableName) \
  { \
    static float lastState; \
    if ( lastState != variableName ){ \
      Serial.print( F(#myFixedText " "  #variableName" changed from ") ); \
      Serial.print(lastState); \
      Serial.print( F(" to ") ); \
      Serial.println(variableName); \
      lastState = variableName; \
    } \
  }
// MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END *

//Array for storing serial received data
// the constant numChars limits the receivable characters
// set to a value that is 2 bytes HIGHER than your maximum number of
// characters as the longest character-sequence

const unsigned int maxNumChars = 128;
char receivedChars[maxNumChars];
boolean newData = false;
char MyDelimiter;

#include <SafeString.h>
createSafeString(inputString_SS, maxNumChars);
createSafeString(valueString_SS, 8);
createSafeString(myID_SS, 8);

createSafeString(theStringToSend_SS, maxNumChars);

int myIntValue1 = 100;
int myIntValue2 = -200;
int myIntValue3 = 30000;
float myFloatValue = -123.45;

const char delimiterChar = ',';

const char myEndMarker   = '>';


const long baudrate = 115200;

byte inputCounter;

void setup() {
  // demonstration how you can add characters to a SafeString
  // in different ways
  theStringToSend_SS = "<"; // the start-marker
  theStringToSend_SS += "ABC"; // concenating a string-constant
  theStringToSend_SS += ","; // concenating a character-constant
  theStringToSend_SS += myIntValue1; // concenating an integer
  theStringToSend_SS += delimiterChar; // concenating a chat
  theStringToSend_SS += myIntValue2; // concenating an integer
  theStringToSend_SS += delimiterChar; 
  theStringToSend_SS.print(myIntValue3); // you can even use the print-function
  theStringToSend_SS += ","; // concenating a character-constant
  theStringToSend_SS.print(myFloatValue); // concenating a float  
  theStringToSend_SS += myEndMarker;

  // the variable "theStringToSend_SS" is used to create a character-sequence 
  // that will be printed to the serial monitor
  // you can then mark & copy this character-sequence
  // then paste it into send-input of the serial monitor for testing it

  Serial.begin(baudrate); // adjust baudrate in the serial monitor to match the number
  Serial.println( F("Setup-Start") );
  printFileNameDateTime();
  Serial.println( F("mark, copy & paste the character-sequence of the next line") );
  Serial.println(theStringToSend_SS);
  Serial.println();
}


void extractTokens() {
  int MyTokenNr = 0;
  int startAtPos = 0;
  MyDelimiter = ',';

  Serial.println("Start extracting...");
  Serial.println("each token is between a leading and trailing #");
  // if no more tokens where found the result of inputString_SS.stoken() is -1
  // otherwise the result is the StartPosition where the next token shall be searched
  while (startAtPos >= 0) {
    startAtPos = inputString_SS.stoken(valueString_SS, startAtPos, MyDelimiter); 
    MyTokenNr++; // increase variable by 1 for each token extracted
    Serial.print("extracted token no ");
    Serial.print(MyTokenNr);
    Serial.print(" #");
    Serial.print(valueString_SS);
    Serial.println("#");

    valueString_SS.trim(); // delete spaces
    assignValue(MyTokenNr,valueString_SS);
  }
  Serial.println("finished extracting");
  printDbg();
}


// for "handing over a SafeString to a function you have 
// to do it by reference which means add a apmersand "&" behind the
// variable-type
// p_RefToSS is a pointer to that place in RAM where the "handed over"
// string is stored
void assignValue(int p_MyTokenNr, SafeString& p_RefToSS) {

  // depending on variable "p_MyTokenNr" type-cast the character-sequence 
  // to the correct variable-type and to the variable
  switch (p_MyTokenNr) {
    case 1:
      myID_SS = p_RefToSS;
      break; // IMMIDIATELY jump down to END_OF_SWITCH

    case 2:
      // convert number stored in "p_RefToSS" to an integer
      // and store this value in variable "myIntValue1"
      p_RefToSS.toInt(myIntValue1);
      break; // IMMIDIATELY jump down to END_OF_SWITCH

    case 3:
      // convert number stored in "p_RefToSS" to an integer
      // and store this value in variable "myIntValue2"
      p_RefToSS.toInt(myIntValue2);
      break; // IMMIDIATELY jump down to END_OF_SWITCH

    case 4:
      // convert string into integer-value 
      // and store this value in variable "myIntValue3"
      p_RefToSS.toInt(myIntValue3);
      break; // IMMIDIATELY jump down to END_OF_SWITCH

    case 5:
      // convert string into float-value 
      // and store this value in variable "myFloatValue"
      p_RefToSS.toFloat(myFloatValue);
      break; // IMMIDIATELY jump down to END_OF_SWITCH
  } // END_OF_SWITCH
  //printDbg();
}


void printDbg() {
  dbg (" 0:", myID_SS);
  dbgc(" 1:", myIntValue1);
  dbgc(" 2:", myIntValue2);
  dbgc(" 3:", myIntValue3);
  dbgc(" 4:", myFloatValue);
}


void printFileNameDateTime() {
  Serial.print( F("File   : ") );
  Serial.println( F(__FILE__) );
  Serial.print( F("Date   : ") );
  Serial.println( F(__DATE__) );
  Serial.print( F("Project: ") );
  Serial.println( F(ProjectName) );
}


void recvWithStartEndMarkers() {
  static boolean recvInProgress = false;
  static unsigned int ndx = 0;
  char startMarker = '<';
  char endMarker   = '>';
  char rc;

  // If data is in the receive-buffer .available() > 0
  // .available() returns how MANY bytes are in the receive-buffer
  while (Serial.available() > 0 && newData == false) {
    rc = Serial.read();

    if (recvInProgress == true) { // if startmarker is found set flag to true
      if (rc != endMarker) {      // if the received byte is NOT the endmarker
        receivedChars[ndx] = rc;  // append the received byte at the end of char-array
        ndx++;                    // increase array-index by 1
        if (ndx >= maxNumChars) {    // if message is longer than max number of chars the arraybuffer can hold
          ndx = maxNumChars - 1;     // reduce array-index => byte is trhown away
        }
      } // if (rc != endMarker) {
      else { // it IS the endmarker
        receivedChars[ndx] = '\0'; // terminate the string through adding a zero
        recvInProgress = false;    // receiving of command is finished
        ndx = 0;
        newData = true;            // command is ready to be used
      }
    } // if (recvInProgress == true) {

    else if (rc == startMarker) {  // if the byte is the startmarker
      recvInProgress = true;       // set boolean flag receive in progress to true
    }
  } // while (Serial.available() > 0 && newData == false) {
}


void loop () {
  int numberOfValues;
  
  recvWithStartEndMarkers(); // non-blocking checking if serial data is received
  // receive with Start- / Endmarker means the data must have
  // a leading "<" and a trailing ">" for switching newData to true
  if (newData) { // if a valid character-sequence is received
    inputString_SS.print(receivedChars);
    numberOfValues = 1;

    for (int Idx = 0; Idx < maxNumChars; Idx++) {
      // whenever a separator is found this means after the separator comes a new value
      if (receivedChars[Idx] == ',') {
        numberOfValues++;
      }
    }
    Serial.print("Data received #"); // leading #
    Serial.print(inputString_SS);
    Serial.println("#");             // trailing # for exact identification of the received characters
    Serial.print("number of values=");             // trailing # for exact identification of the received characters
    Serial.print(numberOfValues);             // trailing # for exact identification of the received characters
    Serial.println();             // trailing # for exact identification of the received characters
    extractTokens();    
    newData = false;
  }
}

best regards Stefan

Pas de double ou triple post svp. Lisez les règles d’usage du forum.

cf Les bonnes pratiques du Forum Francophone