Teensy 4.1 SPI SCK pin13 (LED) issue

clappertown

New member
Hi,

I have a project that has to use both SPI and LED functions on Teensy 4.1 ( I already used SPI1, and SPI2 pins at back side seems not easily accessible). Based on front side pin layout, it seems pin 13 is used for both SPI and LED, and there is no extra pin can be used for SCK. This is different than Teensy 3.5/3.6 where I can use pin 14 as an alternative pin for SCK. So my question is that if there exists other pins that I can use as SCK, other than pin 13 (LED) ?

Thanks.
 
Referencing the T_4.1 card there is a single instance shown for the SPI signal SCK and that is pin #13. No ALT pins in a grayed for that signal.

Alternative would be to wire to any other pin an LED and proper resistor to get the LED feature that is tied to pin #13.

{testing}
 
Last edited:
I have wondered whether an SD card extension cable like this could be butchered to bring out the SPI2 pins (SCK2, CS2, MOSI2, MISO2) without having to solder onto the QSPI memory pads. Anyone tried that?
 
Perhaps such a PCB?

Adapter.jpg

Paul
 
Looks good.

No matter which kind of cable or PCB is used, be careful about the total power supply capacitance if it will ever be hot plugged. The Teensy 4.1 design assumes a SD card with very little capacitance. If you have several uF power supply decoupling that's discharged and you hot plug, you could end up creating a 3.3V power brown-out condition that crashes Teensy 4.1. The bootloader chip implements brown-out detection, so the hardware should automatically reboot. While that's better than just getting stuck without recovery, still probably not what you want to see when plugging in the cable.
 
OP specifically says he wants LED capability (that could be any IO pin with a couple of exceptions) but does the the LED on pin13 interfere with SCK. That is an output for SPI master, so could Teensy4 drive SCK with the led in place or would the forward voltage drag the logic 1 down too far?

I wanted to try SPI for a peripheral, so if push comes to shove I could desolder the LED.

Is that feasible?

Thanks.
 
I don't think Paul would have designed the board with a Led on pin 13 (also SPI Clock) if it was detrimental to the operation of the SCK signal.
 
Good point , it is actually marked as SPI, so I guess it should work. The led will act as an indicator of activity too which is nice.
 
Note the Arduino Uno (ATmega 328p), which was one of the main Arduino variants back in the day had the same layout, and presumably Paul laid out the Teensy 3.0 to use the same pin numbers to allow code to be imported more easily. Lets see, common pins include:

  • Pins 0/1 being RX1/TX1. Note, the UNO had a separate USB chip which monitored the UART lines, which meant you could either use the UART without connecting the USB or you could use the USB. The Teensy separates these two. I believe the later 32u4 based processors did have USB support in the chip, and like the Teensy there was no overlap between UART and USB.
  • Pins 11-13 are the SPI MOSI, MISO, and SCLK
  • Pin 13 is connected to a LED
  • Pins 14-19 can be used for analog input and have alternate names A0..A5.
  • Pins 18/19 are the I2C pins SDA/SCL.
  • Pins 3, 5, 6, 9, and 10 can do PWM. On the UNO pin 11 can do PWM, but the Teensy 3.0/3.1/3.2 doesn't support pin 11 being PWM.
The LED being on pin 13 doesn't interfere with SPI, providing you don't use the LED (SCLK is an output signal, so the LED will just blink as SPI stuff is being done).

If you need a LED and want to use SPI, your best bet is to add a LED on an otherwise unused pin.
 
Not the same layout to be precise, a similar pinout. Pin 13 having an LED caused many issues when people used it as an INPUT_PULLUP input as the LED overwhelms the internal pull-ups, so it can be problematical if not configured as an OUTPUT.
But no, it doesn't interfere with SCLK which is a push-pull output. Some third-party Arduino compatibles connect pin13 LED via a FET (to avoid loading pin 13 when used as an input), a superior design.
 
I was having some unexpected results so I made a little test to write to one pin and read another.
I do not read back the LED pin out level. Default pulldown gets all zeros, if I configure with INPUT_PULLUP I get all ones.

I'm probably tired, can't see clearly or I'm just dumb but I can't see why I'm not reading back in the output signal on pin13. The LED is blinking , as expected, but I don't get that read back in.

Code:
#define INPIN 22

void setup() {
  const uint in_pin=22;
  Serial.begin(115200);
  delay(1000);
  Serial.printf("IO pin test. \n");
  pinMode(INPIN, INPUT);
  digitalRead(INPIN);
  digitalWrite(13, HIGH);
  delay(500);
  while (1){
    digitalWrite(13,LOW);
    Serial.printf("pin%d = %d\n",INPIN,digitalReadFast(INPIN));
    delay(500);
    digitalWrite(13,HIGH);
    Serial.printf("pin%d = %d\n",INPIN,digitalReadFast(INPIN));
    delay(500);
  } // wend

Code:
IO pin test.
pin22 = 0
pin22 = 0
pin22 = 0
pin22 = 0
pin22 = 0
pin22 = 0
pin22 = 0
pin22 = 0

Can someone see what I'm missing ?

TIA.
 
Last edited:
You're not setting pin 13 to OUTPUT mode. So it's probably defaulting to INPUT and when you change the "output" value you're actually changing the mode between INPUT_PULLUP and INPUT_PULLDOWN, which would explain why the LED would be visibly toggling. But it should be brighter if the pin is properly set to OUTPUT mode.
 
You could try putting a very slight delay after digitalWrite(13,LOW); and digitalWrite(13,HIGH);
 
You're not setting pin 13 to OUTPUT mode. So it's probably defaulting to INPUT and when you change the "output" value you're actually changing the mode between INPUT_PULLUP and INPUT_PULLDOWN, which would explain why the LED would be visibly toggling. But it should be brighter if the pin is properly set to OUTPUT mode.
Thanks, I thought digitalWrite and digitalRead did the whole pin set up sage each time for every single call, which is why they are ridiculously slow, and that is why digitalWriteFast, which does no more than a single register write operation, was invented.

BTW setting it explicitly did not change the output.
 
Last edited:
You could try putting a very slight delay after digitalWrite(13,LOW); and digitalWrite(13,HIGH);
I thought of that but decided if it was just a delay issue I should get picked up the next time and I would just phase shift the alternance by 500ms.

following your suggestion , I added 15ms
digitalWrite(LED_PIN,LOW); delay(15);

This got me somewhat arbitrary alternance of the input signal.

Code:
IO pin test.
pin22 = 0
pin22 = 1
pin22 = 0
pin22 = 0
pin22 = 1
pin22 = 0
pin22 = 0
pin22 = 0
pin22 = 1
pin22 = 0
pin22 = 0
pin22 = 0
pin22 = 1
pin22 = 0
pin22 = 0
pin22 = 1
pin22 = 0
pin22 = 0
Then I upped it to 100ms and it stay at 1 for about a dozen reads the flipped to zero and stays there. Beats me!


Code:
IO pin test.
pin22 = 1
pin22 = 1
pin22 = 1
pin22 = 1
pin22 = 1
pin22 = 1
pin22 = 1
pin22 = 1
pin22 = 1
pin22 = 1
pin22 = 1
pin22 = 0
pin22 = 0
pin22 = 0
pin22 = 0
pin22 = 0
pin22 = 0
pin22 = 0
pin22 = 0
 
Make sure the input pin is properly functional: configure it as INPUT_PULLUP and make sure it only reads 0 when connected to ground, then configure it as INPUT_PULLDOWN and make sure it only reads 1 when connected to VCC.
 
Moving this to another pin gets more expected results. Without the delay the input signal is well behaved out of phase as I suggested above.

Code:
IO pin test.
pin22 = 1
pin22 = 0
pin22 = 1
pin22 = 0
pin22 = 1
pin22 = 0
pin22 = 1
pin22 = 0
pin22 = 1
pin22 = 0
pin22 = 1
pin22 = 0
pin22 = 1
pin22 = 0
Just a delay(1) after pin write before read, brings it back into line.

The claim that having a LED share the SPI pin does not affect it seems wrong in face of the evidence.
 
You're claiming that pin 13 can't be used as an output at all since it can't even drive an input pin on the same chip. That simply isn't true, otherwise any sketch that uses the SPI port to drive external hardware wouldn't work.
 
This got me somewhat arbitrary alternance of the input signal.

I tried running your program (from msg #12) with the edits discussed (msg #13 and msg #16). I connected a wire between pin 13 and 22. Here's a photo so you can see the hardware:

pin_13_22.jpg


This is the full program I tested. The code from msg #12 is missing the loop function and a close brace so it doesn't actually compile... hopefully I filled in the rest and added the stuff discussed in msg #13-16 correctly?

Code:
#define INPIN 22

void setup() {
  pinMode(13, OUTPUT);
  Serial.begin(115200);
  delay(1000);
  Serial.printf("IO pin test. \n");
  pinMode(INPIN, INPUT);
  digitalRead(INPIN);
  digitalWrite(13, HIGH);
  delay(500);
  while (1){
    digitalWrite(13,LOW);
    delay(15);
    Serial.printf("pin%d = %d\n",INPIN,digitalReadFast(INPIN));
    delay(500);
    digitalWrite(13,HIGH);
    delay(15);
    Serial.printf("pin%d = %d\n",INPIN,digitalReadFast(INPIN));
    delay(500);
  } // wend
}

void loop() {
  // put your main code here, to run repeatedly:
}

When I run this program, I can't get anything like the wrong results shown in msg #16. This is what I get in the Arduino Serial Monitor.

Code:
IO pin test.
pin22 = 0
pin22 = 1
pin22 = 0
pin22 = 1
pin22 = 0
pin22 = 1
pin22 = 0
pin22 = 1
pin22 = 0
pin22 = 1
pin22 = 0
pin22 = 1
pin22 = 0
pin22 = 1
pin22 = 0
pin22 = 1
pin22 = 0
pin22 = 1
pin22 = 0
pin22 = 1
pin22 = 0
pin22 = 1
 
Please help me to find a way to reproduce the problem. Can you show me a photo of your hardware connection and give an exact copy/paste of the full program you're running? Please give the full program, so I can just copy/paste it into Arduino IDE without any guesswork to add missing parts. I want to reproduce the same problem you're seeing, but I must be doing something different because I get the correct result when I try.
 
Hi Paul, thanks for checking this out.

The previous snip was indeed incomplete since I had stuck that code at the top of setup() from a BFS SPI test example. Since the while(1) prevents it getting any further I ignore the rest. I've isolated this in a clean new sketch.

Code:
#define INPIN 10
#define LED_PIN 13

void setup() {
  Serial.begin(115200);
  delay(1000);
  Serial.printf("IO pin test. \n");
  pinMode(INPIN, INPUT);
//  pinMode(LED_PIN, OUTPUT);
  digitalRead(INPIN);
  digitalWrite(LED_PIN, HIGH);
  delay(500);
  while (1){
    digitalWrite(LED_PIN,LOW);    delay(1);
    Serial.printf("pin%d = %d\n",INPIN,digitalReadFast(INPIN));
    delay(500);
    digitalWrite(LED_PIN,HIGH);   delay(1);
    Serial.printf("pin%d = %d\n",INPIN,digitalReadFast(INPIN));
    delay(500);
  } // wend
 

// never gets here. //

}

void loop() {
  // put your main code here, to run repeatedly:

}

Similar erratic results inputting on pin 10 sampling pin13.
Code:
IO pin test.
pin10 = 0
pin10 = 0
pin10 = 0
pin10 = 1
pin10 = 0
pin10 = 1
pin10 = 0
pin10 = 0
pin10 = 0
pin10 = 0
pin10 = 0
pin10 = 0
pin10 = 0
pin10 = 0
pin10 = 0
pin10 = 0
pin10 = 0

Circuit similar to yours but not bread board. Soldered 90deg pins with typical Arduino jump wire between pins. I'll try to do a photo later.

BTW I'm using 4.0 not 4.1
 
Last edited:
Full disclosure: I had connected a 9250 IMU and was not getting expected results. That is why I attempted the BFS example, which failed to connect to device via SPI. So pins 10..13 have had some limited 5V abuse.

I decided to back track to simple IO testing pins.10,11,12 seem fine when I drive with pin 14 instead of pin13 on output.
 
You're getting erratic results because of this:

// pinMode(LED_PIN, OUTPUT);

You can also visually confirm by watching the LED. It will light, but only very dim.

When you properly set the pin to OUTPUT mode, you'll see the LED is proper brightness, and the signal will be received properly.
 
10,11,12 seem fine when I drive with pin 14 instead of pin13 on output.

The problem was fully and correctly explained by jmarsh in msg #13.

When you use digitalWrite() with a pin that is using INPUT mode, it turns the pullup resistor on/off. That is why you will see the LED blink but only very dim.

With pins 10, 11, 12, the weak output from pullup resistor alone is able to give a proper signal. But with the LED on pin 13, this weak signal is not enough and you get erratic results. But even with pins 10, 11, 12, you are using a very weak signal because the pin is not configured for OUTPUT mode. Not good.

Again, the problem is your program. You need to configure pinMode(13, OUTPUT) before using digitalWrite() for pin 13.
 
Back
Top