(Resolved) Problem with Serial Controlled I/O

UPDATE:
I have partially found a solution. And I now know how to fix the problem, I just need to know what to write. If I add a delay, say 500 milliseconds, it works OK as long as the user inputs the data before that delay is over. It works, but I don't like that, I don't want delays, it needs to work with the user. As in wait for them to input the full string and then move on.

Updated Code Piece: This is the command 'pinConfig', the problem is the lack of wait time

    if (commandIn == "pinConfig") //the user wants to configure a pin
    {
      Serial.println("CHOOSE A PIN [2-13]"); //Pins 0-1 are not for user use    
      lcd.clear();
      lcd.print("CHOOSE PIN: 2-13"); //show some info on the LCD
      String serialPin;
      Serial.flush();     
      delay(500); //this delay sort of fixes the problem but I don't like it
      serialPin = Serial.readString(); //serialPin reads the raw input    
      Serial.flush();    
      static int pinNumberSerial = serialPin.toInt(); //pinNumberSerial gets the integer version of the input      
      Serial.print("'");
      Serial.print(serialPin); //The pin number should show up on serial, but it is always zero
      Serial.println("'"); //the quotes are so I can tell if there is nothing there
    }

Hello Community! I have a circuit takes in commands from the serial monitor, and can configure individual pins 2-13 from serial. All of the other commands work, except the 'configure pin' command; it should be the way described below:

How it Should Work:

  1. User types in "pinConfig".
    SCREEN: "CHOOSE A PIN [2-13]"
  2. User types in a pin number (lets say 5).
    SCREEN: "PIN 5 CONFIGURE"
    SCREEN: "INPUT OR OUTPUT [1/2]"
  3. User types in a setting (lets say 1).
    SCREEN: "PIN 5 NOW INPUT"
  4. User is happy and gets ice cream.

How it Really Works:

  1. User types in "pinConfig"
    SCREEN: "CHOOSE A PIN [2-13]"
  2. User types in a pin number (lets say 3)
    SCREEN: nothing
  3. User Resets and tries Everything Again.
    SCREEN: nothing
  4. User checks code and researches, then tries again
    SCREEN: nothing
  5. User gives up and goes to forum

As you can see, this code has a problem with accepting pin numbers after text, I think. I know that it can get to the command, but it wont do anything after the command is started. I've tried multiple attempts, but I cant get any further. Any help is appreciated. Thanks!

The Code:

//Created: April 3, 2016 by mike44449

#include <LiquidCrystal.h>
LiquidCrystal lcd(44, 45, 32, 34, 36, 38);  //Pins for Mega 2560

String SerialCommand, commandIn;
int pinNumber = 0;
int pinState;
int pinConfig;
int pinRead;
const int backlight = 53; //Connect the base of the transistor to 53

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

  pinMode(backlight, OUTPUT);
  digitalWrite(backlight, HIGH); // turn on the backlight
  
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW); //turn off the onboard LED

  Serial.println("Welcome to the Digital Workstation! v1.5"); //Display some commands and information
  Serial.println("\nCOMMANDS:");
  Serial.println("pinConfig  - SPECIFY A PIN"); //choose a pin to modify
  Serial.println("allON  - ALL PINS HIGH"); //all pins on
  Serial.println("allOFF  - ALL PINS LOW"); //all pins off
  Serial.println("allIN - ALL PINS INPUT"); //all pins are inputs
  Serial.println("allOUT  - ALL PINS OUTPUT"); //all pins are output
  Serial.println("readAll - READ ALL PINS"); //display a summary of pin readings
  Serial.println("backlightON - TURN ON BACKLIGHT"); //turn on the backlight
  Serial.println("backlightOFF  - TURN OFF BACKLIGHT"); //turn off the backlight
  Serial.println("\n--------------------------------------------");
  
  lcd.begin(16, 2);
  
  lcd.print("Welcome!");
  lcd.setCursor(0,1);
  lcd.print("v1.5");
  delay(1500);
  lcd.clear();
  
  lcd.print("ENTER SERIAL"); //flash some instructions for 2 seconds
  delay(2000);
  lcd.clear();
  
  Serial.println("ENTER COMMAND");
}

void loop() {
  // put your main code here, to run repeatedly:
  //The next few lines of code will handle the commands, like backlight
  lcd.setCursor(0,0);
  
  commandIn = Serial.readString();
  if (commandIn != "") //white there is something in the buffer
  {
    if (commandIn == "allON") //user wants all pins on
    {
      Serial.println("ALL PINS HIGH"); //let the user know with serial and the LCD
      lcd.clear();
      lcd.print("ALL PINS HIGH");
      for(int i = 0; i <= 13; i++) //loop through and write to each pin, 0 to 13
      {
        pinMode(i, OUTPUT); //make sure each pin is counted as an output
        digitalWrite(i, HIGH);
      }
    }
    if (commandIn == "allOFF") //user wants all pins off
    {
      Serial.println("ALL PINS LOW");
      lcd.clear();
      lcd.print("ALL PINS LOW");
      for(int i = 0; i <= 13; i++)//do the same thing as above, but turn the pins off
      {
        pinMode(i, OUTPUT);
        digitalWrite(i, LOW);
      }
    }
    if (commandIn == "backlightON") //user wants the backlight on
    {
      digitalWrite(backlight, HIGH); //turn on the backlight and show some info.
      lcd.clear();
      lcd.print("BACKLIGHT ON");
      delay(500);
      lcd.clear();
      Serial.println("BACKLIGHT ON");
    }
    if (commandIn == "backlightOFF")
    {
      digitalWrite(backlight, LOW); //turn off the backlight and show some info.
      lcd.clear();
      lcd.print("BACKLIGHT OFF");
      delay(500);
      lcd.clear();
      Serial.println("BACKLIGHT OFF");
    }
                              if (commandIn == "pinConfig") //the user wants to configure a pin
                              {
                                //ask the forum, im stuck on this. For now, move on
                              }
    if (commandIn == "allIN") //the user wants all pins to be inputs
    {
      Serial.println("ALL PINS ARE INPUTS"); //let the user know with serial and the LCD
      lcd.clear();
      lcd.print("ALL PINS");
      lcd.setCursor(0,1);
      lcd.print("INPUTS");
      for(int i = 0; i <= 13; i++) //loop through and write to each pin, 0 to 13
      {
        pinMode(i, INPUT); //make sure each pin is counted as an input
      }
    }
    if (commandIn == "allOUT") //all pins to be outputs, the defualt
    {
      Serial.println("ALL PINS ARE OUTPUTS"); //let the user know with serial and the LCD
      lcd.clear();
      lcd.print("ALL PINS");
      lcd.setCursor(0,1);
      lcd.print("OUTPUTS");
      for(int i = 0; i <= 13; i++) //loop through and write to each pin, 0 to 13
      {
        pinMode(i, OUTPUT); //make sure each pin is counted as an input
      }
    }
    if (commandIn == "readAll") //display a summary of the states
    {
      Serial.println("SUMMARY: 13 PINS READ");
      
      for(int i = 0; i <= 13; i++) //loop through and read the pins
      {
        pinRead = digitalRead(i);
        if (pinRead == 1) //the pin is high
        {
          Serial.print("PIN: ");
          Serial.print(i);
          Serial.println(" | STATE: HIGH");
        }
        if (pinRead == 0) //the pin is low
        {
          Serial.print("PIN: ");
          Serial.print(i);
          Serial.println(" | STATE: LOW");
        }
      }
    }
  }
}

Serial_Controlled_PWM.ino (6.14 KB)

It is a good idea if you do two things.
First post the code you are having problems with, do not just leave a blank because we don't know what you have tried so it is hard to correct.
Second it is best to make a minimum example that just shows your problem and cuts out anything not relevant to it.

I suspect you are not doing the input thing right after the if detects pinConfig.

Well, I can understand your problem with my problem. I typed up one of the solutions that I have tried, and the comments point out what I see when I attempt to run this code:

The Code I Attempted:

    if (commandIn == "pinConfig") //the user wants to configure a pin
    {
      Serial.println("CHOOSE A PIN [2-13]");  //Pins 0-1 are not for user use
      lcd.clear();
      lcd.print("CHOOSE PIN");                    //show some info on the LCD
      Serial.flush();
      serialPin = Serial.readString();           //serialPin reads the raw input
      pinNumberSerial = serialPin.toInt();    //pinNumberSerial gets the integer version of the input
      Serial.println(pinNumberSerial);         //The pin number should show up on serial, but it dosent, it just shows a zero no matter what I input.
    }

Well in that code you are not waiting for a reply. You need a loop in that if statement that holds until a string has been entered. In the same way as you do at the start of the loop function.

How would I put a loop into that? If so, what kind of loop?

How would I put a loop into that?

commandIn = ""; // blank out old command value
while (commandIn != "") { commandIn = Serial.readString(); } // do nothing until you get a reply

OK, I have finished it. It works now, and thanks. Your idea of such a loop got me thinking and I solved it. Partial credit to you! :slight_smile:

If it got you thinking then that was my aim. Much better for you to do that than just look at a solution, so full credit I think. :slight_smile:

How about posting how you solved it so you can help others who come across this thread?

That's not a bad idea. I fixed the problem with a 'while' loop that checks to see if the string (the one that should have serial data on it) is empty. So basically,: while this string is empty, check again.

The Code: (this section can be found within the whole file on lines 166-169)

      serialPin = Serial.readString(); //get the data for the first time

      while(serialPin == "") //while we wait for input
      {
        serialPin = Serial.readString();  //check again if the string is empty
      } 

      //regular code (as if there was data in the string)

The string serialPin is made to hold a pin number between 2 and 13. Before the loop, it gets assigned
with the serial read function. After that, if it is empty, it enters the loop and checks again, if it is still empty, it repeats. It does this until its not empty, in which it exits the loop and continues on below.

I've attached below the circuit diagram and the full code below in case anyone wants it.

Serial_Controlled_PWM.ino (14.3 KB)

Thanks for that :slight_smile: +1