Need to control 37 digital I/O pins with different states at once

Hi Guys,

Im new to arduino and took on a big project.

I need to control 37 IO digital pins. I am using a GUI made in C# which sends the data like this:

string data3 = "6;13;14;19;21;22;28;39;40;41;42";
sendint = data3.Split(';').Select(n => Convert.ToInt32(n)).ToArray();
sendbytes = data3.Select(x => (byte)x).ToArray(); 
serialPort1.Write(sendbytes, 0, sendbytes.Length);

And here is my Arduino code:

#include<Servo.h>    // Serial library 
#include <SPI.h>     // SPI library
#include <Wire.h>    // I2C library

//#define ADDRESS 0x00

int bytes;
int count = 0;

int newArray[36];

void setup() {

  Serial.begin(9600);             // initialize serial communication with computer
  pinMode(SS, OUTPUT);
  
  //GPIO pins for testing
  pinMode(0, OUTPUT);     //RX0
  pinMode(1, OUTPUT);     //TX0
  pinMode(2, OUTPUT);    //PWM2
  pinMode(3, OUTPUT);    //PWM3
  pinMode(4, OUTPUT);    //PWM4
  pinMode(5, OUTPUT);    //PWM5
  pinMode(6, OUTPUT);     //PWM6
  pinMode(7, OUTPUT);    //PWM7
  pinMode(8, OUTPUT);    //PWM8 
  pinMode(9, OUTPUT);    //PWM9
  pinMode(10, OUTPUT);   //PWM10
  pinMode(11, OUTPUT);   //PWM11
  pinMode(12, OUTPUT);   //PWM12
  pinMode(13, OUTPUT);   //PWM13
  pinMode(14, OUTPUT);   //TX3
  pinMode(15, OUTPUT);   //RX3
  pinMode(16, OUTPUT);   //TX2
  pinMode(17, OUTPUT);   //RX2
  pinMode(18, OUTPUT);   //TX1
  pinMode(19, OUTPUT);   //RX1
  pinMode(20, OUTPUT);   //20
  pinMode(21, OUTPUT);   //21
  pinMode(22, OUTPUT);   //22
  pinMode(23, OUTPUT);   //23
  pinMode(24, OUTPUT);   //24
  pinMode(25, OUTPUT);   //25
  pinMode(26, OUTPUT);   //26
  pinMode(27, OUTPUT);   //27
  pinMode(28, OUTPUT);   //28
  pinMode(29, OUTPUT);   //29
  pinMode(30, OUTPUT);   //30
  pinMode(31, OUTPUT);   //31
  pinMode(32, OUTPUT);   //32
  pinMode(33, OUTPUT);   //33
  pinMode(34, OUTPUT);   //34
  pinMode(35, OUTPUT);   //35
  pinMode(36, OUTPUT);   //36
  pinMode(37, OUTPUT);   //37
  pinMode(38, INPUT);    //38  // New input for Arduino device, ill change with time
}

void loop() 
{                  // Establishes the HIGH/LOW state for the I/O pins
 
 while(Serial.available() > 0)
 {
  bytes = Serial.read(); //- '0'; // Starts reading the buffer 1 byte at a time
  
  newArray[bytes] = 1; 
  
    for (int j = 0; j <= 36; j++)
    {
      if (newArray[j] != 1)
      {
        newArray[j] == 0; 
      }
    }
 } // end of while loop

 for(int i = 0; i <= 36; i++){
  if(newArray[i] == 1){
    digitalWrite(newArray[i], LOW);
  }
  else if (newArray[i] == 0){
      digitalWrite(newArray[i], HIGH);
  }
 } 
}

Basically, I cant seem to use the information properly.
I have an array that holds all IO pins needed. The ones that need to be turned on =1 and the ones that don't =0. Goes through a for loop to go through each index of the array and puts them in their digitalWrite().

Any help would be awesome!!
I do have a technical background so feel free to go nerdy.

What does the improperly posted code actually do that is not what you want?

Read the forum guidelines to see how to properly post code and some information on how to get the most from this forum.
Use the IDE autoformat tool (ctrl-t or Tools, Auto format) before posting code in code tags.

Please go back and fix your original post by highlighting the code and clicking the </> in the menu bar.
code tags new

I don't know how well your serial receive code will work. That for loop may execute faster than data comes in. Have you printed the data that comes in from the serial port? Was it what you expected?

The serial input basics tutorial may have information of interest.

Hi GroundFungus, Sorry about that. I fixed it up.

Do you know of a better way for the Serial receive section of my code?
I cant really think of a better solution.
I store the incoming bytes in an array and iterate through it based on the index of the INT byte that was received from my GUI.

Hi,
What model Arduino are you using?
Most models use pin0 and pin1 for programming and serial monitor, so you will have to avoid those.
Have you looked at port expanders?
Google.

arduino port expander

There are a number of ICs that would make your project layout easier.

What is your project, what are the output pins driving?

Thanks.. Tom... :smiley: :+1: :coffee: :australia:

Once you get your code formatted so that it is easier to read, then there are 3 (maybe more) areas you need to figure out:

  1. How to format up the message to send to the Arduino. It looks like you've decided on semi-colon separated values. What determines whether the i/o pin should be high or low? Do you send the same pin number again - i.e. toggle it. What about sending an ASCII hexadecimal string (so it's human readable -ish). You can encode 4 pins in 0-9 & A-F.
  2. How will the Arduino detect the start of a new packet of data? There's a forum topic called Serial Input Basics which may help you out as mentioned by @groundFungus
  3. How are you going to update the pins on the Arduino. You could update every pin each time round or are you only going to update a pin that has been told to change state?

Hi, it seems like there is still a lot for me to know.

  1. each # in data is one IO pin. What I am doing is sending the whole command of which IO pins need to be high or LOW. I have 36 and they all need to be turned on or off independently while other pins are still active.

  2. I am still trying to figure that out. I was going to create a dynamic array.

 int count = 0;
 int* myArray;
 int arrSize;
 myArray=(int*)calloc(arrSize,sizeof(int));

Once count > arrSize then that would be the end of the command.

  1. I am storing everything in arrays.
    Basically, the bytes coming in would be an index and for each one called from command will =1 while the others (not called) will =0;

It becomes difficult when I have (digitalWrite(newArray[i]) because I don't know how to save this for each IO pin.

Im using an Arduino Mega 2560.
it comes with some I/O pins dedicated to some features. For the ones that are, I am avoiding them.

It's more of a testing program that I am creating for a school project.
I am trying to avoid port expansion and trying to stick solely to the Arduino and my GUI.

You may need to be careful here. If I understand your message format correctly, if you wanted to turn all the outputs off (or on) at the same time, then you would have a string something like:

data3 = "0;1;2;3;4 ... 35;36" // i.e. every output separated by a semi-colon

If so, you may have issues with overflowing the Arduino UART receive buffer. I think it's a 64 char/byte buffer.

The command being sent by my GUI data (data3) are the ones that I will want to go to a HIGH state.

To avoid overloading the serial port. I send the ones I want HIGH.
and from the arduino code am able to tell which ones will be LOW by having the index that are != 1 to be =0.

The problem I am seeing is, my serial.read command is running slower than the for loops, causing a mix match of data.

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