Parallel I/O

I loath to post this so called question because frankly, as a very smart friend of mine one said (paraphrased) .. it's impossible to answer a question incorrectly asked.

And I'm not entirely certain what to ask.

Still first week. I can define an individual pin as in or out, and read or write accordingly.

I could probably even write my eventual project using entirely individual digititalRead/Write (X, Y); commands .. but it would be ridiculously clumsy and exceedingly bloated.

There must be a way to initialize a group of pins as as string or variable.

I'm going through various tutorials but have yet to glean how.

For example, I want to define (an arbitrary) four pins as a BCD output, and then send a single 4 bit parallel word.

Once again .. I know I'm not asking a clear question, but I don't quite know how.

Define pins (say) 0-3 as a group called X

Send hexidecimal "F" .. 1111 .. to X.

I kind of hope this is clear enough.

Jim.

Digital IO are grouped into "Ports" BC and D in the case of the UNO.

To further expand, the AVR microcontroller family was created by guys who thought the hardware should be made in a way that makes writing code for it in C easy, so everything on the microcontroller has a named constant. However, this is an advanced topic and one that Wiring (precursor to Arduino) discovered very early on solved a lot of headaches, so for a first project, using pinMode(), digitalRead() and digitalWrite(), is the way to go, despite it being clunky. I can tell you from experience, direct port manipulation is not only lighter in code, but also executes much faster.

Despite the datasheet for the ATmega328P being almost 300 pages, it's one of the best tutorials on writing code for the microcontroller.

You can define 8 pins as one group

For example, on the PORTB group
// set ALL 8 pins as output
DDRB = 0xFF

// make ALL 8 pins high at the same time
PORTB = 0xFF

// make the pins 0 to 3 high
PORTB = 0x0F

and so on...

If you're sending four bits in parallel, you still almost certainly need a clock (strobe) signal to say to the far-end "the data is ready to read", so unless absolute speed is the determining factor, you could still put the four data pins on different ports and use digitalWrite, because although

direct port manipulation is not only lighter in code, but also executes much faster.

it is much less flexible and portable.

TheMemberFormerlyKnownAsAWOL:
it is much less flexible and portable.

Agreed.

I could probably even write my eventual project using entirely individual digititalRead/Write (X, Y); commands .. but it would be ridiculously clumsy and exceedingly bloated.

Well, somehow I've been doing that for several years now, and would not describe the result as "clumsy" or "bloated". Perhaps you are imagining your program as it would be without code factoring.

A 4-bit value could be sent to PD7-PD4 pins of UNO by calling the following subroutine:

void sendBCD(byte n)  //n receives BCD value (0x00 -  0x09) from  calling routine
{
  for (int i=0, j=4; i<4; i++, j++)
  {
    digitalWrite(j, bitRead(n, i));
  }
}

Works only with consecutive pins. You should at least provide a pin offset:

void sendBCD(byte n, byte startingPin)  //n receives BCD value (0x00 -  0x09) from  calling routine
{
  for (int i=0; i<4; i++)
  {
    digitalWrite(i + startingPin, bitRead(n, i));
  }
}

OP FYI, this works with binary data too. That forum member just has a love of BCD.

aarg:
That forum member just has a love of BCD.

I also :heart: BCD.
Since we are no longer portable...

void sendBCD(byte n)  //n receives BCD value (0x00 -  0x09) from  calling routine
{
  (n & (1 << 0)) ? PORTD |= (1 << PD7) : PORTD &= ~(1 << PD7);
  (n & (1 << 1)) ? PORTD |= (1 << PD6) : PORTD &= ~(1 << PD6);
  (n & (1 << 2)) ? PORTD |= (1 << PD5) : PORTD &= ~(1 << PD5);
  (n & (1 << 3)) ? PORTD |= (1 << PD4) : PORTD &= ~(1 << PD4);
}

The ESP32 has a I2S API that allows for parallel data I/O's.

it would be ridiculously clumsy and exceedingly bloated.

Stop! Right there!

When that kind of thought arises, what you should think next is.

"Oh I'll just write a function/method/class do deal with that."

Bloat problem solved.

-jim lee

I also :heart: BCD.

Well it has its nerdy appeal, but...

Send hexidecimal "F" .. 1111 .. to X.

I kind of hope this is clear enough.

Jim.

BCD just wastes memory.
Paul

aarg:
Works only with consecutive pins. You should at least provide a pin offset:

void sendBCD(byte n, byte startingPin)  //n receives BCD value (0x00 -  0x09) from  calling routine

{
  for (int i=0; i<4; i++)
  {
    digitalWrite(i + startingPin, bitRead(n, i));
  }
}




OP FYI, this works with binary data too. That forum member just has a love of BCD.

Good idea!

Sorry, I haven't been around in a while. I could write a bad country song with these holidays .. small stroke and one of my dogs died.

Just reading your replies now - much thanks, seems as if I did compose a useful question after all.

I've hooked up a pair of HDSP-0962 displays and will practice playing with port functions.

Aarg .. I'm still dealing with the very basics of the language.

My eventual project goal is to use a pair of HPDL-1416 displays and a parallel RTC chip to fashion a ridiculous watch. It just seems to me as if it would take thousands of lines to manipulate the pins individually, where grouping them into ports would be a much more direct approach.

Either way, at the moment I'm still just learning the capabilities of the device.

Perehama - will definitely check out that manual link.

I tend to favour books over a computer screen .. you can dog ear corners, add notes in the margins, etc. Somewhat ironically, until recently I spent 30 years repairing copiers and printers - so I never owned one with a thousand available! This recently rectified, so printing manuals will likely help with the learning curve.

Jim.

it just seems

It just seems to me as if it would take thousands of lines to manipulate the pins individually, where grouping them into ports would be a much more direct approach.

No. Just no. See reply #12.

int n = 500; int e = 0; int r = 0x0C; int p = 3;
void setup() {
  DDRD = B11111100;
}

void loop() {

  PORTD = e; // write "0";
  delay(n);
  PORTD = B00000100; // write "1";
  delay(n);
  PORTD = 0x08; // write "2";
  delay(n);
  PORTD = r; // write "3";
  delay(n);
  PORTD = B00010000; // write "4";
  delay(n);
  PORTD = B00010100; // write "5";
  delay(n);
  digitalWrite (p, HIGH); // change "5" to "7" by altering B bit of display;
  delay(n);


}

Okay, this is fun! You guys have been incredibly helpful. Still just mucking about, but I feel as if I'm getting a feel for it. I have a 4 bit display weighted 8,4,2,1 on pins 5 through 2 and just getting the feel for what I can do with variables and declarations .. and the language in general. Miles to go, but it no longer looks like Sanskrit. I'm a bit stoked tonight.

Golam - I particularly like your example. I understand what it's doing, but not having much luck making it work yet. Will have to play with the syntax a bit and read up on for-next loops - but this will be quite helpful addressing consecutive pin groups.

void setup()
{

  DDRD = B00111100;
}

void loop()
{

  for (int x = 2; x <= 5; x++)
  {
    digitalWrite(x, HIGH);
    delay(1000);
  }
  PORTD = B00000000;

}

Excellent .. one more piece of the puzzle.

I've been taking various bits of example code and paring them down to simple bits that still work.

I think I should be far enough along now to start playing with math operations that I can display on a series of LEDs.

Jim.