How to condense (make more efficient) coding with port manipulations?

Im trying to program an arduino board for testing different pin combinations but im unsure if there is a faster way of writing the code instead of typing the same code over and over again. The Bxxxxxxxx changes for the different combinations. Any advice or coding examples are appreciated thanks.

EDIT: pls read the updated posting below :slight_smile:

Some of the repetition seems unnecessary but anyway you could create a function and pass as a parameter the values which change.
You could also read the port directly and use bit masking instead of multiple digitalRead() statements.

I can't tell what your code is supposed to be doing.
Why do you write PORTK using direct port IO, and then read it one bit at a time with digitalRead()?

if ((PORTK & INTERESTING_BITS_MASK) == PARTICULAR_VALUE_OF_BITS) {
   ...
}

Working with bits is much easier if you learn Hexadecimal, with a little practice, you learn to recognize bit patterns lots quicker than trying to count 1s and 0s, like 11 1101 0111 1100 = 3D7C.
3 D 7 C

Delta_G:
A picture of your code? Really? You couldn't copy and paste it? It's TEXT!!! Why in the world would you post a picture of it?

Yeah, what he said.

Hi all,
I'm new to Arduino Programming. I just took over a Arduino project from a previous intern who couldn't finish it. I'm having trouble in understanding some codes like DDRK and Bxxxxxxxx, if anyone can explain what it means to me? As well as any ways to condense the coding and simplify it? The purpose of this coding is to test Torque Signal Conditioner Unit (TSCU) and Autofeather Unit (AFU) for different possible connections when the TSCU and AFU plug is plugged into the Arduino board.
For example, the TSCU plug has 10 pins and 61 possible connection combinations (Referred to as Class). For TSCU class 4, the connections are 1-7 2-8 3-9 5-6 and when a class 4 configured TSCU plug is plugged to the Arduino, the LCD should print out "class 1".

Sorry for the mess of codes, please help and tell me if more details needed, can't post full length of code due to character limitation but its really lengthy and tedious. Thanks

/*
  
  *PLUG TESTER* 
  
  LiquidCrystal Library
  
 This sketch prints out
 * Plug Type
 * Class
 to the LCD
*/

// include the library code:
#include <LiquidCrystal.h>

// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
const int rs = 13, en = 12, d4 = 11, d5 = 10, d6 = 9, d7 = 8;

// Left with 7,6,5,4,3,2 & A1,A2,A3,A4,A5 (11 PINS)
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
int i = 1;

void setup() {
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  
  ///////////////////////////////////
  //  STANDARD START UP MESSAGE :  //
  ///////////////////////////////////
  lcd.print("=== PWC(SEA) ===");
  lcd.setCursor(0, 1);
  lcd.print("Plug Identifier");
  delay(2000);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("STARTING UP...");
  delay(300);
  lcd.clear();
  
  ///////////////////////////////////
  // PLUG CONFIGS INSERT THEM HERE //
  ///////////////////////////////////
  //    FINALIZED - CONNECTIONS    //
  ///////////////////////////////////

  //TEST CONNECTION 
}
void loop() {
    while (i==1){
      DDRL = DDRL | B10000000;
      PORTL = B10000000;
      if (digitalRead(45) == HIGH){
        if (digitalRead(49) == HIGH) {
          lcd.clear();
          lcd.print("TYPE: OFFSET");
          lcd.setCursor(0, 1);
          lcd.print("CLASS: 15");
          delay(1000);
          break;
        }
      }
      
      ///////////////////////////////////
      //          TSCU OFFSET          //
      ///////////////////////////////////
      // 4 CONNECTIONS - OFFSET
      
      DDRK = DDRK | B00010111;
      PORTK = B00010111; 
      if (digitalRead(68) == HIGH && digitalRead(69) == HIGH && digitalRead(53) == HIGH && digitalRead(67) == HIGH){
        if (digitalRead(62) == HIGH && digitalRead(63) == HIGH && digitalRead(64) == HIGH && digitalRead(66) == HIGH) {
          lcd.clear();
          lcd.print("TYPE: OFFSET");
          lcd.setCursor(0, 1);
          lcd.print("CLASS: 4");
          delay(1000);
          break;
        }
      }
      DDRK = DDRK | B00010111;
      PORTK = B00010111; 
      if (digitalRead(67) == HIGH && digitalRead(52) == HIGH && digitalRead(51) == HIGH && digitalRead(68) == HIGH){
        if (digitalRead(62) == HIGH && digitalRead(63) == HIGH && digitalRead(64) == HIGH && digitalRead(66) == HIGH) {
          lcd.clear();
          lcd.print("TYPE: OFFSET");
          lcd.setCursor(0, 1);
          lcd.print("CLASS: 58");
          delay(1000);
          break;
        }
      }

      // 3 CONNECTIONS - OFFSET

      DDRK = DDRK | B00000111;
      PORTK = B00000111; 
      if (digitalRead(68) == HIGH && digitalRead(69) == HIGH && digitalRead(53) == HIGH && digitalRead(65) == HIGH){
        if (digitalRead(62) == HIGH && digitalRead(63) == HIGH && digitalRead(64) == HIGH) {
          lcd.clear();
          lcd.print("TYPE: OFFSET");
          lcd.setCursor(0, 1);
          lcd.print("CLASS: 1");
          delay(1000);
          break;
        }
      }
      DDRK = DDRK | B00000111;
      PORTK = B00000111; 
      if (digitalRead(68) == HIGH && digitalRead(69) == HIGH && digitalRead(53) == HIGH && digitalRead(66) == HIGH){
        if (digitalRead(62) == HIGH && digitalRead(63) == HIGH && digitalRead(64) == HIGH) {
          lcd.clear();
          lcd.print("TYPE: OFFSET");
          lcd.setCursor(0, 1);
          lcd.print("CLASS: 2");
          delay(1000);
          break;
        }
      }
      DDRK = DDRK | B00000111;
      PORTK = B00000111; 
      if (digitalRead(68) == HIGH && digitalRead(69) == HIGH && digitalRead(53) == HIGH){
        if (digitalRead(62) == HIGH && digitalRead(63) == HIGH && digitalRead(64) == HIGH) {
          lcd.clear();
          lcd.print("TYPE: OFFSET");
          lcd.setCursor(0, 1);
          lcd.print("CLASS: 3");
          delay(1000);
          break;
        }
      }
      DDRK = DDRK | B00001011;
      PORTK = B00001011; 
      if (digitalRead(68) == HIGH && digitalRead(69) == HIGH && digitalRead(53) == HIGH){
        if (digitalRead(62) == HIGH && digitalRead(63) == HIGH && digitalRead(65) == HIGH) {
          lcd.clear();
          lcd.print("TYPE: OFFSET");
          lcd.setCursor(0, 1);
          lcd.print("CLASS: 5");
          delay(1000);
          break;
        }
      }
      DDRK = DDRK | B00010011;
      PORTK = B00010011; 
      if (digitalRead(68) == HIGH && digitalRead(69) == HIGH && digitalRead(53) == HIGH){
        if (digitalRead(62) == HIGH && digitalRead(63) == HIGH && digitalRead(66) == HIGH) {
          lcd.clear();
          lcd.print("TYPE: OFFSET");
          lcd.setCursor(0, 1);
          lcd.print("CLASS: 6");
          delay(1000);
          break;
        }
      }
      DDRK = DDRK | B00010011;
      PORTK = B00010011; 
      if (digitalRead(68) == HIGH && digitalRead(69) == HIGH && digitalRead(53) == HIGH){
        if (digitalRead(62) == HIGH && digitalRead(63) == HIGH && digitalRead(66) == HIGH) {
          lcd.clear();
          lcd.print("TYPE: OFFSET");
          lcd.setCursor(0, 1);
          lcd.print("CLASS: 6");
          delay(1000);
          break;
        }
      }
      DDRK = DDRK | B00010011;
      PORTK = B00010011; 
      if (digitalRead(68) == HIGH && digitalRead(69) == HIGH && digitalRead(67) == HIGH){
        if (digitalRead(62) == HIGH && digitalRead(63) == HIGH && digitalRead(66) == HIGH) {
          lcd.clear();
          lcd.print("TYPE: OFFSET");
          lcd.setCursor(0, 1);
          lcd.print("CLASS: 8");
          delay(1000);
          break;
        }
      }
      DDRK = DDRK | B00001011;
      PORTK = B00001011; 
      if (digitalRead(68) == HIGH && digitalRead(69) == HIGH && digitalRead(67) == HIGH){
        if (digitalRead(62) == HIGH && digitalRead(63) == HIGH && digitalRead(65) == HIGH) {
          lcd.clear();
          lcd.print("TYPE: OFFSET");
          lcd.setCursor(0, 1);
          lcd.print("CLASS: 9");
          delay(1000);
          break;
        }
      }
      DDRK = DDRK | B00010101;
      PORTK = B00010101; 
      if (digitalRead(68) == HIGH && digitalRead(69) == HIGH && digitalRead(53) == HIGH){
        if (digitalRead(62) == HIGH && digitalRead(64) == HIGH && digitalRead(66) == HIGH) {
          lcd.clear();
          lcd.print("TYPE: OFFSET");
          lcd.setCursor(0, 1);
          lcd.print("CLASS: 10");
          delay(1000);
          break;
        }
      }
     
      
      else {
        lcd.clear();
        lcd.print("=NO CLASS FOUND=");
        lcd.setCursor(0,1);
        lcd.print("= PLEASE RETRY =");
        delay(50);
        break;
      }
    }
  }

Those commands relate to direct port manipulation.

The Arduino board has registers for the input/outputs which you can set using “pinmode” to set as inputs or outputs. You can access these port registers directly using those DDR type commands as a short cut .

Google “port manipulation Arduino” for some guides on how to do this

Many times in the past I have encountered your situation and have just thrown out what someone else started, and begun from the original specifications. I have also given the same advice to others who encounter the same situation.

I am giving you the same advice. Don't be wasting hours and days on something that may be fatally flawed in the first place.

Paul

Delta_G:
Arduino Reference - Arduino Reference

Those are just binary numbers. It's better to write them with the normal 0bxxxxxx syntax. But there's an Arduino header that defines all these that start with the capital B.

Integer Constants - Arduino Reference

Is there a simpler way to write these codes? The port manipulations make it hard to try to catagorize the different classes.

For example, the TSCU plug has 10 pins and 61 possible connection combinations (Referred to as Class). For TSCU class 4, the connections are 1-7 2-8 3-9 5-6 and when a class 4 configured TSCU plug is plugged to the Arduino, the LCD should print out "class 1".

I assume that should be "LCD should print out "class 4""?
So you have 10 connections to the Arduino, and your job is to figure out which pins are connected to "each other", and match that info against "known classes" (of which there are 61)? That's a relatively thorny problem!

Don't be wasting hours and days on something that may be fatally flawed in the first place.

I agree. I don't like that existing code - it really bothers me that it checks for 1 bits but not 0 bits, in addition to its verbosity and lack of clarity.
It'd be good to start with some sort of table describing which connections make up each class...

westfw:
I assume that should be "LCD should print out "class 4""?
So you have 10 connections to the Arduino, and your job is to figure out which pins are connected to "each other", and match that info against "known classes" (of which there are 61)? That's a relatively thorny problem!I agree. I don't like that existing code - it really bothers me that it checks for 1 bits but not 0 bits, in addition to its verbosity and lack of clarity.
It'd be good to start with some sort of table describing which connections make up each class...

Yea typo should be class 4. I do have a table listing the classes and connections however i can't post it due to its classified nature sorry. Do you have any suggestions? Currently I'm attempting to use Arrays to do it, not sure if there is a better method out there.

Little bit confused.
“For example, the TSCU plug has 10 pins and 61 possible connection combinations (Referred to as Class). For TSCU class 4, the connections are 1-7 2-8 3-9 5-6”
So what happened to 4 and 10?

As noted earlier, starting with someone else’s failed attempt is most likely just a further waste of time.

So the code is working and you just need to finish adding the rest of the combinations in?

Going back to the confused part.
If a human was to test the part, would they stick a conductivity meter probe on connection 1 and then move the other probe too connections 2-10 until they found a link or not and then write down which pin was linked and then repeat for each additional pin?

If so that’s what I would do in code.
Make array of pins, set one high and read the rest.
“Build” a char variable as a map of the reads.

Now you litterally have a variable containing “17283956” so then you just need 60 if statements to match up for the correct “Class” for that variable.

Slumpert:
Little bit confused.
“For example, the TSCU plug has 10 pins and 61 possible connection combinations (Referred to as Class). For TSCU class 4, the connections are 1-7 2-8 3-9 5-6”
So what happened to 4 and 10?

As noted earlier, starting with someone else’s failed attempt is most likely just a further waste of time.

So the code is working and you just need to finish adding the rest of the combinations in?

Means that for that class pins 4 and 10 are not needed, 1-7 means that a jumper cable connects pin 1 and 7 together. Im scrapping the previous person's work and redoing it by using Arrays.

I plan to make an array of pins as what u mentioned and read the rest however I'm having trouble with the part after reading. How would you suggest to "build a char variable as a map of the reads to show '17283956' "? Is it possible to build a list of 1 column "Class No" and another column of connections (eg"17283956"), if so whats the way to go about doing it? Is there a page or tutorial that shows it? That way can possibly get the array to read through the list and print out the class number by matching the connection. Thereby throwing away the 60 if statements.

Thanks

diddle pin 1; see if it's shows up as connected to some other pin. (can more than one pin be connected together ?) Fill in a byte in your "string", index 0, with the ascii representation of the other pin. If it's not connected anywhere, fill in 'x'
Repeat for all the other pins. You should wind up with a 10-digit string.

For TSCU class 4, the connections are 1-7 2-8 3-9 5-6"

That should yield (remembering that if pin 1 is connected to 7, pin 7 is also connected to pin 1):

pin   : 123456789A
result: 789x65123x

So you'd want to have a table of all 61 possible classes, each a 10-digit string, indexed by the class:

typedef struct _cst {
   char connectionString[11];
} connectionString_type;

connectionString_type classtable[61] = {
   {""},   //0 Fill in all the other classes!
   {""},   //1
   {""},
   {""},
   {"789x65123x"},  // 4: Here's your example.
   {""}
// :
};

Then you just loop through the table doing string compares, and if you get a match, then that index is your class number.
For extra credit, don't check the pins you've already found to be connected, and have a string like
"789x6ccccx" instead. Faster, and easier to read, easier to write.
Also consider putting the table in PROGMEM.
Watch your 0-based arrays vs 1-based pin numbering.
Document how it's supposed to work (look at how difficult it is to understand what your predecessor was trying to do!)
Hope there aren't any plane crashes that end up being your program's fault!

Marcuswdf:
Thereby throwing away the 60 if statements.

Westfw gave you a very good example of how to use a table and the formulated value as a lookup, but I think that method would need expanding as you have 61 combinations but likely way, way less “Class”s.

Instead of just using
{"789x65123x"}, // 4: Here's your example.

Have another table of “Class”s so that when you find "789x65123x" in position 4, you lookup position 4 on the “Class” table to get the needed value.

Second option might be to research how those parts are put into classifications in the first place. You might find that there is a “logical” method and instead of having to brute force lookup every combination, you could apply the logic and calculate the “Class” for your given combinations. (Again assuming way less than 61 Class’s)

Hi westfw,
Thanks for the helpful advice. I'm still unsure of how the code for reading, joining the values into 789x65123x and reading the values into
pin : 123456789A
result: 789x65123x
Also not all the combinations have so many connections, some have just for example 2-6 only (pin 2 connected to pin 6), all these combinations are unique to each class so each class would have its on unique connections. Also, some classes have a 3way connection eg 1-2,3-5-9 and some have 5-6,6-8,7-10. Would this method still work?
For your example code, is it placed in voidsetup or above it?
Also what does this mean?:
typedef struct _cst {
char connectionString[11];
} connectionString_type;

Hi Slumpert,
There are exactly 61 classes with its own unique connection combinations however some are add-ons to the previous eg class 10: 1-2 and class 11: 1-2,3-4. How do I turn the individual readings into the string?

So far my code before your reply(incomplete,still figuring stuff out):

 #include <LiquidCrystal.h>
 const int rs=13,en=12,d4=11,d5=10,d6=9,d7=8;
 LiquidCrystal lcd(rs,en,d4,d5,d6,d7);
int  pinArray[] = {54,55,56,57,58,59,60,61,41,40};
int classArray[][2]= {{1,2634710},{2,2635710},{3,263468710},{4,56710},{5,710},{6,5668710},{7,2634},{8,2635},{9,26},{10,56}};
int i=1;
int count=0;

void setup() 
{
  lcd.begin(16,2);
 lcd.print("=== PWC(SEA) ===");
  lcd.setCursor(0, 1);
  lcd.print("Plug Identifier");
  delay(2000);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("STARTING UP...");
  delay(300);
  lcd.clear();
  for (count=0;count<10;count++) 
  {
    pinMode(pinArray[count], OUTPUT);
  }
}

void loop() 
{
  int a;
  int pincombi ="";
  int b;
  for (count=0;count<10;count++) 
  {
   digitalWrite(pinArray[count], HIGH);
   while(a<10)
   a=count+1;
   if(digitalRead(a) ==HIGH)
   {
    lcd.print(a);
    b= pincombi & a;
    lcd.print(b);
   }
  }



}

I'm still unsure of how the code for reading

You'd set up all the pins with a pull-up or pull-down resistor.
Then you change one pin to an output and write a LOW (or HIGH, if you used pulldowns.)
Then you read all of the other pins, and see which (if any) now show a "LOW" as well - they must be connected to the pin you have as an output.
Change the output pin back to an input, and go to the next pin.
I think this is essentially what the old code was doing with its PORTx manipulations, but the code to interpret the data was awful...
I'd use something like:

setAllInputs()  // set all pins as input
setoutput(currentPin)  // set the current pin to an output
for (pins)
  if pin is not currentPin
    if read(pin) == outputstate
       mark connected
 next currentpin

(all pseudocode...)

not all the combinations have so many connections, some have just for example 2-6 only (pin 2 connected to pin 6),

That's fine. You'd end up with "x6xxxx2xxx" or something...

Also, some classes have a 3way connection eg 1-2,3-5-9 and some have 5-6,6-8,7-10.

That's harder :frowning: I'm not quite sure what to suggest, especially without being able to see all of the info.
Perhaps you can un-use the relfectiveness of connection, so if pin 1 were connected to pin 5 and 10, you'd
have 5xxxAxxxx1 instead of 5xxx1xxxx1 ? Or either, as long as you're consistent? Or just handle pairs, and test the 3ways as special cases when applicable?

Also what does this mean?:
typedef struct _cst {
char connectionString[11];
} connectionString_type;

that defines a C "structure" consisting of 11 characters, so that you'd easily be able to do something like:

    if (strcmp(classes[i].connectionString, connectInfo) == 0)

instead of messing with 2d arrays. "structures" are an important part of C/C++ programming, although I guess they don't show up in Arduino code very often. ("Classes" are a kind of structure, sort of.) It'd be worth learning about...

int classArray[][2]= {{1,2634710},{2,2635710},{3,263468710},...

I think you'll need to use character arrays. An int (even a long int) is not big enough to hold 10 digits...

Hi westfw,
Would my method posted in the post work best or would yours be most efficient and effective?
How would I use your coding as Iam unsure what it is (I'm a beginner and i don't know alot) and what codes to write along with it.

setAllInputs() // set all pins as input
setoutput(currentPin) // set the current pin to an output
for (pins)
if pin is not currentPin
if read(pin) == outputstate
mark connected
next currentpin
What does "mark connected do" and how can I transform from a single pin digit to the "789x65123x" for example.

for more info i pmed you

Would my method posted in the post work best or would yours be most efficient and effective?

I'm sort-of assuming that "most efficient" is not that important.

Um, don't you have someone to help you at the place you're interning?