SPI pin as Digital?

Status
Not open for further replies.

djex81

Active member
Hello, I'm looking to use SPI for my 74HC165 chips to detect button presses using the schematic and code found here: http://www.gammon.com.au/forum/?id=11979

The schematic on that site only uses MISO and SCK SPI pins. My question is if I activate SPI do the MOSI and CS pins on the Teensy go to waste? or can I still use them as digital pins?
 
That code is 2013 and looks like it refers to bit banging the exchange in the second code snippet? If it can work manually and not using the SPI engine for the transfer then the bit bang code is in charge of the pins used and anything unused would be available. It seems to permanently set the CS to avoid working with that pin - so the behavior expected may be unique to that chip. But that bitbang code may be processor specific and not work on a 32 bit ARM Teensy.

With normal hardware SPI - As a read device it needs MISO to get the data, but the data clocks out of MISO as the data from the Master is presented on MOSI when normal SPI is used - using SPITransfer(). The comments and first code block refer to that - though that old code may not work with current SPI library as presented.
 
On Teensy, ShiftIn is *way* faster than I2C.
On Teensy 4, it can happen that it is too fast for the chips.. You will see no markable difference to hardware SPI.
(did not look at the datasheet for yor chip)

When I wrote shiftOut, for Teensy 4, during the beta-phase, I had to add delays...
shiftIn has no delays. So, as said, it might be too fast ..
 
On Teensy, ShiftIn is *way* faster than I2C.
On Teensy 4, it can happen that it is too fast for the chips.. You will see no markable difference to hardware SPI.
(did not look at the datasheet for yor chip)

When I wrote shiftOut, for Teensy 4, during the beta-phase, I had to add delays...
shiftIn has no delays. So, as said, it might be too fast ..

I had not seen that before - interesting - it might clock near or above 60 MHz for each byte?

Did not look at the data sheet either to see how fast it can cycle - or the daisy chain setup - without sending a 'start' command if the chip just cycles out bit, it isn't clear how the bit position would be tracked - especially across 57 buttons. But that would read very quickly - even if only 40 MHz or so net throughput for 64 bits (8*8).
 
I measured it now.

oops... 16.3MHz with T4 @ 600MHz.

Check the datasheet, if the chip can handle that.
pic_18_2.png

Code:
void setup() {
  pinMode(12, OUTPUT);
  for (;;) shiftIn(0,12,MSBFIRST);
}


void loop() {}
 
Tim, it has to do a bit more than reading pins - it must toggle the clock pin & shifting.
So it results in 16Mhz "only". Might be still too fast.


For shiftOut I added code with "smart wait" that results in 10MHz max.
 
Last edited:
On Teensy, ShiftIn is *way* faster than I2C.
On Teensy 4, it can happen that it is too fast for the chips.. You will see no markable difference to hardware SPI.
(did not look at the datasheet for yor chip)

When I wrote shiftOut, for Teensy 4, during the beta-phase, I had to add delays...
shiftIn has no delays. So, as said, it might be too fast ..

Interesting. So shiftin() seems like the way to go for performance. I was concerned polling 57 inputs (64 using 8 x 75HC165) would take too long and possibly miss button presses? So basically I would be shifting out 64 bits when the 74HC165 are daily chained together? Sorry I'm a bit new and am still learning. I was able to get two daisy chained 74HC595's working good with 16 LEDs using shiftout however how would I go about reading in a value in the case of the 74HC165s? Would it work in a similar fashion? I think there is Arduino article I seen somewhere explaining it. Maybe I'll go and find that.
 
Tim, it has to do a bit more than reading pins - it must toggle the clock pin & shifting.
So it results in 16Mhz "only". Might be still too fast.


For shiftOut I added code with "smart wait" that results in 10MHz max.

There is overhead with the tests and I/O write/read, mask shift and test - I should have looked more at the code before guessing speed. Also it isn't using FAST versions ( given the pin isn't CONST ) of digitalWrite or Read. The read wouldn't have to test - it could just assign the bit.

So it could run faster - but that would be more likely to be too fast for the chip. 10 to 16 MHz is much faster than 400KHz for i2c - even if it ran faster like 2-4 MHz that has CMD and ADDR overhead.
 
The schematic is using three pins

SCK LATCH and MISO

74HC165 wont work without the LATCH

see this thread where I have posted some code for reading different kind of input-stuff

https://forum.pjrc.com/threads/64473-Re-doing-my-Hammond-MIDI-controller-ideas-and-suggestion-needed

I believe the LATCH pin in the code is labeled as LOAD on the schematic. They are using a regular Digital pin for the LATCH / LOAD. Also I've taken a look at your schematics, will your method work with multiple button presses and holding a button while pressing another? I was trying to stay away from a matrix for now but maybe it's a better solution.
 
Just to take a step back and look at the "big picture" here, all of the problems you're likely to face are from the hardware running much too fast, rather than not fast enough. I know this may seem strange if you're coming from the world of ordinary 8 bit AVR & Arduino, but we see it over and over on this forum. With Teensy at 180 or 600 MHz, too much speed becomes the common problem. These problems are especially troublesome when people connect a lot of buttons in a row-column matrix and roll their own code rather than using the Keypad library, or connect lots of analog inputs through analog mux chips. Code running at this speed can easily outpace the electrical requirements.


I was concerned polling 57 inputs (64 using 8 x 75HC165) would take too long and possibly miss button presses?

All of these ways are so much faster than humans can pretty and release a button. Even I2C at only 100 kHz is more than enough.

If your code will sit and wait for the I/O, then SPI is the way to go, not because you need this speed to avoid missing anything, but because it will minimize the "wasted" time waiting which you could use for other things (or go into idle mode to save power). On Teensy 4, both bitbang and hardware SPI are capable of speeds which are (probably) much too fast for the sort of wiring you're likely to use for connecting several shift register chips. Really high frequencies, like over 15 MHz, require careful attention to wiring and grounding if the wires are long. Probably the best way is shiftIn(), and use pinMode() to configure the pins so they get the default slew rate limiting. It slows the signal by only nanoseconds, but that makes a huge improvement in the high frequency noise effects you can get with high speed SPI over long wires!

The other very common problem is mechanical chatter. Normally the Bounce library is used with buttons connected directly to pins. If your code scans the shift register very rapidly, you will need to do something similar to the Bounce library.
 
Just to take a step back and look at the "big picture" here, all of the problems you're likely to face are from the hardware running much too fast, rather than not fast enough. I know this may seem strange if you're coming from the world of ordinary 8 bit AVR & Arduino, but we see it over and over on this forum. With Teensy at 180 or 600 MHz, too much speed becomes the common problem. These problems are especially troublesome when people connect a lot of buttons in a row-column matrix and roll their own code rather than using the Keypad library, or connect lots of analog inputs through analog mux chips. Code running at this speed can easily outpace the electrical requirements.




All of these ways are so much faster than humans can pretty and release a button. Even I2C at only 100 kHz is more than enough.

If your code will sit and wait for the I/O, then SPI is the way to go, not because you need this speed to avoid missing anything, but because it will minimize the "wasted" time waiting which you could use for other things (or go into idle mode to save power). On Teensy 4, both bitbang and hardware SPI are capable of speeds which are (probably) much too fast for the sort of wiring you're likely to use for connecting several shift register chips. Really high frequencies, like over 15 MHz, require careful attention to wiring and grounding if the wires are long. Probably the best way is shiftIn(), and use pinMode() to configure the pins so they get the default slew rate limiting. It slows the signal by only nanoseconds, but that makes a huge improvement in the high frequency noise effects you can get with high speed SPI over long wires!

The other very common problem is mechanical chatter. Normally the Bounce library is used with buttons connected directly to pins. If your code scans the shift register very rapidly, you will need to do something similar to the Bounce library.

Thank you Paul for the detailed reply it was very helpful. Your right now that I think about it a bit more the Teensy is not slow at all. I'm use to working with slower chips and optimizing code to run the fastest possible. I'm using a Teesny 3.6 and so this should be plenty fast enough (too fast probably) for what I need to do.
 
I'm using 2x10x 74hc165 to scan a velocity sensitive reused keyboard from a old electric organ
Its scanned 31250 times a second, and i can play that without any problem.
You can also read multiple 74hc165 in parallell by using custom bitbang code.
 
Status
Not open for further replies.
Back
Top