Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 15 of 15

Thread: SPI pin as Digital?

  1. #1
    Junior Member
    Join Date
    Jul 2016
    Posts
    11

    SPI pin as Digital?

    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?

  2. #2
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    13,501
    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.

  3. #3
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    7,995

  4. #4
    Junior Member
    Join Date
    Jul 2016
    Posts
    11
    Quote Originally Posted by Frank B View Post
    I need to detect around 57 button inputs. So I will have 8 x 74HC165. I'm looking for a way to poll the inputs quickly and I figured if I could do it using SPI that I could avoid slow downs. I am now looking at possibly using 4 x MCP23017 IO expanders over I2C. This might be a better choice?

  5. #5
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    7,995
    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 ..

  6. #6
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    13,501
    Quote Originally Posted by Frank B View Post
    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).

  7. #7
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    7,995
    I measured it now.

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

    Check the datasheet, if the chip can handle that.
    Click image for larger version. 

Name:	pic_18_2.png 
Views:	17 
Size:	12.5 KB 
ID:	23229

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

  8. #8
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    7,995
    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 by Frank B; 01-12-2021 at 09:08 PM.

  9. #9
    Junior Member
    Join Date
    Jul 2016
    Posts
    11
    Quote Originally Posted by Frank B View Post
    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.

  10. #10
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    13,501
    Quote Originally Posted by Frank B View Post
    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.

  11. #11
    Senior Member manicksan's Avatar
    Join Date
    Jun 2020
    Location
    Sweden
    Posts
    228
    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...gestion-needed

  12. #12
    Junior Member
    Join Date
    Jul 2016
    Posts
    11
    Quote Originally Posted by manicksan View Post
    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...gestion-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.

  13. #13
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    23,785
    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.


    Quote Originally Posted by djex81 View Post
    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.

  14. #14
    Junior Member
    Join Date
    Jul 2016
    Posts
    11
    Quote Originally Posted by PaulStoffregen View Post
    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.

  15. #15
    Senior Member manicksan's Avatar
    Join Date
    Jun 2020
    Location
    Sweden
    Posts
    228
    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.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •