Writing to port D

I want to write a keyboard scan routine. 4 bits of port D should go lines 1-4 in the sketch.
5-12 go to (pulled up) inputs, to see which diode is pulled down.
Do the inputs sense 0.7V as a "0"?

I'd like to write the scan pattern { 4,8,16,32 }; directly to PORTD without any delays or glitches between the writes. How do I manipulate PORTD with the appropriates writes?
Is PORTD memory mapped I/I on an AVR?

Set the bit2 ON without changing the other bits:

PORTD |= 4;

Knew it was that easy :slight_smile: Do I have to set the DDRD first?
This was my initial code but I didn't see any signal on pin D2:

int select=4; // skip D0,D1 (since they are Tx/Rx)
void setup() {
  // put your setup code here, to run once:
  DDRD = DDRD | B11111100;

}

void loop() {
  // put your main code here, to run repeatedly:
  PORTD |= select;
  select<<1;
  if(select==64)
    select=4;
}

Ah, could it be I'm seeing a programming error?

yes, of course.

Note that the code only set selected bits ON (1), but don't clear unused bits to the Off (0) state

So your code will put D2 to constant HIGH state, not to periodical signal.

Yes, thanks. Found the error (hopefully):

int select=4; // skip D0,D1 (since they are Tx/Rx)
void setup() {
  // put your setup code here, to run once:
  DDRD = DDRD | B11111100;

}

void loop() {
  // put your main code here, to run repeatedly:
  PORTD &= B00000011;
  PORTD |= select;
  select=select<<1;
  if(select==64)
    select=4;
}

At the moment the loop runs as fast as it could. I'm hesistant to use "delay". How fine is delay granularity? How can I insert "precise" timing intervals?

1 Like

The most efficient way is with hardware timers. But this is a very broad topic and I can't explain it with my bad English

Well that was an error, for sure.

You can write

  select <<= 1;

also.

For simple timing that is often accurate enough, delay() can be used for ms (milliseconds) and delayMicroseconds() can be used for us (microseconds).

Noting else happens during that time, which is why you will find people helping you to learn how not to do that. Delay.

 delay(50);   // do nothing for 0.050 seconds.

 delayMicroseconds(1000);  // do nothing for 0.001 seconds.

HTH

a7

select <<= 1; yes I know, thanks. (45 years experience in C programming)

What are appropriate frequencies for keyboard scanning? In this case it is a musical keyboard.

I wondered if it might be musical. In that case, you want to begin at the beginning to ferret out and avoid any (any) delays between pressing a key and getting on with what the program is going to do with that key.

Work backwards from trying to do a complete scan in, say, 200 us.

It may be that you will want/need to use the timer/counter features of the microprocessor, it's arcane but totally knowable stuff.

a7

To scan the above keyboard matrix, I'm thinking of using PORTD for the 4 drive lines. For scanning the 8 input lines I'd rather use a port with 8 consecutively available data line, this doesn't seem to exist. So do I have to split the input over PORT D (D6-D7) and PORT B (D8-D13)?

???

What other options do you have?

Other options? That's why I was asking. PORTC only gives me 6 pins of DATA input.

I'm saying that if you don't have a single full 8-bit port - you will have to split input to two or three ports anyway...
So I don't understand what is your question about.

Yes, or move to a MEGA2560. I like these

https://www.amazon.com/SongHe-ATMEGA2560-16AU-Pinheaders-Compatible-Mega2560/dp/B07TGF9VMQ

shop around, I got 3 for $30 delivered.

If you do stick with split port, write a tiny layer of software that lets higher levels think they have a real 8 but port - put all the machinations for doing the split in one place, to get right and exploit everywhere.

You can also use the analog pins for digital purposes. Be careful not to use up pins that you may want for I2C or SPI or whatever.

a7

Depends on a lot of factors, CPU supply voltage and input specifications. Why not build a test circuit with only one key and one diode, use software and a DMM to be 100% sure?

Is it a human being pressing the buttons? If so, the microseconds speed of port write functions like digitalRead() are already orders of magnitude faster than you need. Why put yourself through the pain and also produce non-portable code, for an invisible speed gain?

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