Control multiple GPIO pins on arduino

I am trying to control 9 GPIO pins with arduino mega 2560. My approach for the code is:

  1. Take a number from the user as input.
  2. If the number is greater than 1 and less than 14, choose 1 (write digital pin as high) or choose 2
    (write digital pin as low) . I have selected GPIO pins from pin 2 to pin 13.

The on off thing is working if I have a single GPIO pin, but when I want to control more pins, I modified my code and it isn't working.

This is the working part:

void setup()

{
  pinMode(13, OUTPUT);
  Serial1.begin(9600);
  while (!Serial1);
  Serial1.println("Input 1 to Turn LED on and 2 to off");

}

void loop() {

  if (Serial1.available())
  {
    int state = Serial1.parseInt();
    if (state == 1)
    {
      digitalWrite(13, HIGH);
      Serial1.println("Command completed LED turned ON");
    }
    if (state == 2)
    {
      digitalWrite(13, LOW);
      Serial1.println("Command completed LED turned OFF");
    }
  }
}

This is the modified part to control more than 1 GPIO pins"

void setup()
{
  for (int i = 2; i < 14; i++)
  {
    pinMode(i, OUTPUT);
  }
  Serial.begin(115200);
  while (!Serial);
  Serial.println("Input the pin number to turn it on or off");
}

void loop()
{
  // put your main code here, to run repeatedly:


  int pin = Serial.parseInt();
  delay(2000);   // doesnt work with or without delay

  if (pin > 1 && pin < 14)
  {
    while (Serial);
    Serial1.println("Input 1 to Turn LED on and 2 to off");
    int state = Serial1.parseInt();
    if (state == 1)

    {
      digitalWrite(13, HIGH);
      Serial1.println("Command completed LED turned ON");
    }

    if (state == 2)
    {
      digitalWrite(13, LOW);
      Serial1.println("Command completed LED turned OFF");
    }
  }
}

What is the purpose of while (Serial);

ieee488:
What is the purpose of while (Serial);

It's to hang execution forever, I assume.

That's what it'll do on a Mega (or anything else without native USB - on things with native USB, it will hang until the device is disconnected from USB).

It's clearly wrong - OP needs to review the documentation for the Serial class (and/or maybe the while syntax, depending on what he was trying to do there.

After searching it on the internet, i found a code that successfully controls pins 2 to 9, (pin 0 and 1 are being used for serial communication). I tried to modify the code so that I can control pins 10 to 30 but no success. The subtraction needs to be performed for ascii characters. When I enter 12, the arduino reads 4950, and if I subtract it from '0', it still selects pin 2 and not pin 12. I tried subtracting it from '1&', which is 4938, but this doesn't seem to work.

 char c;
void setup() {
  // put your setup code here, to run once:
  for (int i = 2; i < 10; i++)
  {
    pinMode(i, OUTPUT);
    Serial.begin(9600);
  }


}

void loop() {
  // put your main code here, to run repeatedly:
  if (Serial.available() > 0)
  {
    c = Serial.read() - '0';
    Serial.flush();
    digitalWrite(c,!digitalRead(c));

  }

}

Serial.begin(9600); move this out of the for loop
Serial.flush(); this has to do with transmitting

c = Serial.read() - '0';
If ascii 0 or 1 was received, what would happen.

Time to stop getting code from the internet.
Time to start understanding what's happening.
Learn the basics from IDE examples.

.

Have a look at the examples in Serial Input Basics - simple reliable ways to receive data.

Then decide on a format for the data you propose to send to the Arduino. For example you could send something like <7, 1> meaning make pin 7 go HIGH or <3, 0> meaning make pin 3 go LOW.

And if you need to send data for several pins in the same message you could do something like <7,1,3,0>

The program on your Arduino will be simpler if all the messages are the same length - but that does not prevent you from a more complex system that could take different amounts of data.

...R

When I enter 12, the arduino reads 4950, and if I subtract it from '0', it still selects pin 2 and not pin 12

This is because you are only reading one character at a time with

c = Serial.read() - '0';

So by sending "12" it first reads 1, then reads 2. Using that subtraction method only works for a single digit at a time. Quick fix, you can send a Hexadecimal 12 (i.e. "C") and it may work.

Google an "ASCII table" to understand what the characters translate into.

I used the serial input basics as suggested by robin2, and my pins now toggle whenever i enter the pin number. But I want to turn on/off the pins based on user input. That is I want two inputs from the user:

  1. Pin number
  2. enter 1 or 2 (to turn on and off the pins)

I have separate codes for both, they are working individually. But I have trouble combining them. Can you please help me out with it..

Code to toggle all digital pins:

// SUCCESSFULLY CONTROL GPIO PINS CONNECTED TO RELAYS
int pinNumber;
boolean newData = false;
int dataNumber=0;
const byte numChars = 32;
char receivedChars[numChars];   // an array to store the received data

void setup() 
{
  // Set all the pins to output
  for (pinNumber=0; pinNumber < 54; pinNumber++)
  {
    pinMode(pinNumber,OUTPUT);
    digitalWrite(pinNumber,LOW);
  }
  Serial.begin(9600);  // Set the baud rate to 9600
  Serial.println("<Arduino is Ready>");
  Serial.println("Enter the pin number");

}

void loop() 
{
  selectPin();
  convChar2Int();

}
void selectPin()
{
  static byte ndx = 0;
  char rc;
  char endMarker = '\n';
//  Serial.println("Enter the pin number");
  if (Serial.available() > 0) 
  {
        rc = Serial.read();
        
        if (rc != endMarker)
        {
          receivedChars[ndx] = rc;
          ndx++;
          if(ndx >= numChars)
          {
            Serial.println("You can enter a maximum of 2 digits");
          }
        }
        else
        {
          receivedChars[ndx] = '\0'; // terminate the string
          ndx = 0;
          newData = true;
        }
  }
}

void convChar2Int()
{
  if (newData == true)
  {
    dataNumber = 0;
    dataNumber = atoi(receivedChars);
    Serial.println("You Selected Pin: ");
    Serial.println(dataNumber);
    digitalWrite(dataNumber, !digitalRead(dataNumber));
    newData = false;
  }
}

Code to set the state of the pins based on user input:

void setup()
{
  pinMode(13, OUTPUT);
  Serial.begin(9600);
  while (!Serial);
  Serial.println("Input 1 to Turn LED on and 2 to off");
}

void loop() {

  if (Serial.available())
  {
    int state = Serial.parseInt();
    if (state == 1)
    {
      digitalWrite(13, HIGH);
      Serial.println("Command completed LED turned ON");
    }
    if (state == 2)
    {
      digitalWrite(13, LOW);
      Serial.println("Command completed LED turned OFF");
    }
  }
}

If you send "<4, 1>", could you make a reasonable guess at what the numbers mean? Robin2's tutorial shows how to receive data in that format, and parse it. No parseInt()s needed.

jkprog:
I used the serial input basics as suggested by robin2

Neither of your examples seems to use my examples the way they are intended to be used.

If you just want the user to enter a single number to toggle the corresponding pin then my first example shows how to receive a single character.

...R