I am trying to control 9 GPIO pins with arduino mega 2560. My approach for the code is:
Take a number from the user as input.
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");
}
}
}
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));
}
}
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.
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:
Pin number
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.