Add a time out and redirection with Serial.read

I am sending a reset routine to a 3018 CNC board that is Arduino based. The routine waits for the CNC board to respond with a "Ready" reply.
The routine works fine.
However, if I fail to connect it or forget to turn the CNC ON, the routine just sits there with the message "Connecting/Resetting Board" .
What can I add to the following routine so after a time period eg. 10 seconds, if the board does not reply, the routine returns to the main menu?

void resetcancel()
{
  tft.fillScreen(BLACK);
  tft.setCursor(50, 160);
  tft.setTextSize(2);
  tft.setTextColor(WHITE);
  tft.print(" Connecting/Resetting Board ");
  Serial1.println((char) 0x18);
  delay(200);
  Serial1.println("$X");
  delay(200);
  while (Serial1.available() <= 0)
  {
    delay(10);
  }
  while (Serial1.available())
  {
    RxString += char(Serial1.read());

    delay(10);
  }
  tft.setCursor(0, 60);
  tft.print(RxString);
  delay(200);
  RxString = "";

  tft.fillRect(0, 0, 300, 200, BLACK);
  startmenu();
}

Add a bit of code where you wait for something from Serial. If more than 10 seconds just keep going. Something like...

  unsigned long start = millis();
  
  while (Serial1.available() <= 0 && millis() - start < 10000)
  {
    delay(10);
  }
  

Thanks for the reply. Works great. Is it possible to print a message that it has not connected if that occurs but not print a message if the read is successful?
I’m not sure how to apply that to a millis() number if it is indeed possible using an if else routine.

Sure... anything is possible.

Maybe after this bit...

Something like this...

if (RxString.length() == 0)
  Serial.println("No data received");
else
{
  Serial.print("Data received = ");
  Serial.println(RxString);
}

Thanks. I added this but it drops straight through to "Connection" made even if disconnected.

void resetcancel()
{
  unsigned long start = millis();
  tft.fillScreen(BLACK);
  tft.setCursor(50, 160);
  tft.setTextSize(2);
  tft.setTextColor(WHITE);
  tft.print(" Connecting/Resetting Board ");
  Serial1.println((char) 0x18);
  delay(200);
  Serial1.println("$X");
  delay(200);
  while (Serial1.available() <= 0  && millis() - start < 10000) 
  {
    delay(10);
  }
  while (Serial1.available())
  {
    RxString += char(Serial1.read());
    delay(10);
  }

  if (RxString.length()== 0)
  {
    tft.setCursor(60, 200);
    tft.print("No connection");
  }
  else
  {
    tft.setCursor(60, 200);
    tft.print("Connection made");
    tft.setCursor(0, 60);
    tft.print(RxString);
    delay(200);
    RxString = "";
  }
  delay(2000);
  tft.fillRect(0, 0, 300, 200, BLACK);
  startmenu();
}

looks like you're send a reset and want to wait a limited amount of time for a response

consider
output:

loop: reset
resetCancel: send some cmd to reset device
 timeout - not connected
loop: reset
resetCancel: send some cmd to reset device
resetCancel: 
 received response - connected

Code:

char buf [80];

unsigned long msec;
unsigned long msecLst;
unsigned long msecPeriod = 2000;

// -----------------------------------------------------------------------------
void
resetCancel (void)
{
    // send reset cmd
    Serial.println ("resetCancel: send some cmd to reset device");

    // wait for response
    msecLst = millis ();
    while ( (millis() - msecLst) < msecPeriod)  {
        if (Serial.available ())  {
            int n   = Serial.readBytesUntil ('\n', buf, sizeof(buf)-1);
            buf [n] = '\0';

            Serial.println (" received response - connected");
            return;
        }
    }

    Serial.println (" timeout - not connected");
}

// -----------------------------------------------------------------------------
void
loop (void)
{
    if (Serial.available ())  {
        int n   = Serial.readBytesUntil ('\n', buf, sizeof(buf)-1);
        buf [n] = '\0';

        if (! strcmp ("reset", buf))
            resetCancel ();
    }
}

// -----------------------------------------------------------------------------
void
setup (void)
{
    Serial.begin (9600);
}

What does RxString contain? Can you print it out and its length.

When connected, RxString returns

When disconnected there is no Data from RxString.

Post all your code.

Here's all I've written so far;

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <MCUFRIEND_kbv.h>
#include <XPT2046_Touchscreen.h>   //.kbv

MCUFRIEND_kbv tft;

#define BLACK 0x0000
#define RED 0xF800
#define WHITE 0xFFFF

XPT2046_Touchscreen ts(53, 255);
const int TS_LANDSCAPE = 1;  //XPT2046_TouchScreen.h
const int TS_LEFT = 338, TS_RT = 3879, TS_TOP = 3767, TS_BOT = 237; //Red ST7796 Shield (landscape)
int pixel_x, pixel_y;     //Touch_getXY() updates global vars

String RxString;
String words[2] = {"Waiting GRBL ...", "Error !!!"};

bool Touch_getXY(void)
{
  bool pressed = ts.touched();
  if (pressed) {
    TS_Point p = ts.getPoint();
    if (TS_LANDSCAPE) mapxy(p.y, p.x);
    else mapxy(p.x, p.y);
    extern int x, y;  //to suit your global variables
    x = pixel_x;
    y = pixel_y;
  }
  return pressed;
}

void mapxy(int x, int y)
{
  int aspect = tft.getRotation();     //LANDSCAPE
  int tft_width = tft.width();
  int tft_height = tft.height();
  switch (aspect & 3) {  //3

    case 0:      //PORTRAIT
      pixel_x = map(x, TS_LEFT, TS_RT, 0, tft_width);
      pixel_y = map(y, TS_TOP, TS_BOT, 0, tft_height);
      break;

    case 1:      //LANDSCAPE
      pixel_x = map(y, TS_TOP, TS_BOT, 0, tft_width);
      pixel_y = map(x, TS_RT, TS_LEFT, 0, tft_height);
      break;

    case 2:      //PORTRAIT REV
      pixel_x = map(x, TS_RT, TS_LEFT, 0, tft_width);
      pixel_y = map(y, TS_BOT, TS_TOP, 0, tft_height);
      break;

    case 3:      //LANDSCAPE REV
      pixel_x = map(y, TS_BOT, TS_TOP, 0, tft_width);
      pixel_y = map(x, TS_LEFT, TS_RT, 0, tft_height);
      break;
  }
}

int x, y;

void setup()
{
  Serial.begin(115200);
  Serial1.begin(115200);
  while (!Serial1)
  {
    ;
  }

  tft.begin(0x9488);
  tft.setRotation(1);
  tft.setTextSize(2);
  ts.begin();
  tft.fillScreen(BLACK);
  tft.setCursor(0, 0);
  tft.print(words[0]);
  delay(1000);
  Serial1.println("\030"); //Send cr + lf
  delay(200);
  unsigned long start = millis();
  while (Serial1.available() <= 0 && millis() - start < 10000) ///////////////////////////////// added 25 OCT22
  {
    delay(100);
  }
  while (Serial1.available())
  {
    RxString += char(Serial1.read());
    delay(10);
  }
  tft.setCursor(0, 60);
  tft.print(RxString);
  delay(2000);
  RxString = "";
  startmenu();
}

void startmenu() {
  tft.fillScreen(BLACK);
  tft.fillRoundRect(5, 50, 190, 50, 5, RED);
  tft.setCursor(100, 5);
  tft.setTextSize(3);
  tft.setTextColor(WHITE);
  tft.print ("MAIN  CNC  MENU");
  tft.setTextColor(WHITE);
  tft.setTextSize(2);
  tft.setCursor(12, 65);
  tft.println("Connect Board");

  while (true)
  {
    if (Touch_getXY())  //.kbv call a single function
    {

      //Serial1.print(x); Serial1.print(','); Serial1.println(y);

      if (x > 0 && x < 170)
      {
        if (y > 60 && y < 100)
        {
          resetcancel();
          delay(100);
          break;
        }
      }
    }
  }
}

void resetcancel()
{
  unsigned long start = millis();
  tft.fillScreen(BLACK);
  tft.setCursor(50, 160);
  tft.setTextSize(2);
  tft.setTextColor(WHITE);
  tft.print(" Connecting/Resetting Board ");
  Serial1.println((char) 0x18);
  delay(200);
  Serial1.println("$X");
  delay(200);

  while (Serial1.available() <= 0 && millis() - start < 10000)
  {
    delay(10);
  }
  while (Serial1.available())
  {
    RxString += char(Serial1.read());
    delay(10);
  }
  if (RxString.length() == 0)
  {
    tft.setCursor(60, 200);
    tft.print("No Connection");
    Serial.print(RxString);
  }
  else
  {
    tft.setCursor(60, 200);
    tft.print("Connection made");
    tft.setCursor(0, 60);
    tft.print(RxString);
    Serial.print(RxString);
    delay(200);
    RxString = "";
  }
  delay(2000);
  tft.fillRect(0, 0, 300, 200, BLACK);
  startmenu();
}
void loop() {

}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.