XIAO Internal Pull-up Resistors

Hello,
Does the XIAO have an internal pull-up resistor connected to pin D2? I have some push buttons I’m working with and I can use the pull-up resistors on pins D0, D1, and D3 but not D2. Not the biggest deal if it doesn’t but I would like to know if that is the case. Thanks!

Hi @MatthewM
There is no internal pull-up resistor connected to pin D0, D1, D2, D3.
Were you use 5v or 3.3v to connect a pull-up resistor? This may cause you can’t use the pull-up resistor D2. We do the same test as you, we connected a pull-up resistor between 3.3v and D2, and tested it with a short wire instead of the button, and found that D2 can be used. How do you do the test?

I used the Arduino function “pinMode(0, INPUT_PULLUP);” for pins D0, D1, and D3 in my code. I have one side of the button go to ground and the other side go to the pin so when the button is pressed, the pin is grounded. I wasn’t sure if there were any internal pull up resistors but when I ran the code, it acts as if there are. If I change the pinMode function to “pinMode(0, INPUT);”, the processor sees the buttons as always being pressed. I have the serial monitor tell me when a button is pressed and it works fine with every pin except D2 for whatever reason. Here is the code I’m working with.

int button = 0;
void setup()
{
Serial.begin(9600);
pinMode(0, INPUT_PULLUP);
pinMode(1, INPUT_PULLUP);
pinMode(3, INPUT_PULLUP);
}

void loop()
{
button = buttonRead(); //Button 0 = null, 1 = button D0, 2 = button D1, 3 = button D3
Serial.println(button);
button = 0;
}

uint8_t buttonRead()
{
Serial.println(“Here”);
while(1) //Wait for a button to be pressed
{
if(digitalRead(0) == LOW)
{
Serial.println(“Button 1”);
delay(100);
return 1;
break;
}
if(digitalRead(1) == LOW)
{
Serial.println(“Button 2”);
delay(100);
return 2;
break;
}
if(digitalRead(3) == LOW)
{
Serial.println(“Button 3”);
delay(100);
return 3;
break;
}
}
}

I have I think the same issue, but my view is the compile software for the XIAO is broken.
I can use the INPUT_PULLUP in pinmode for D0 and D1 and they work fine with buttons.

D2 is another story. INPUT and an externally attached pullup work fine, but the INPUT_PULLUP with D2 causes the compilation to fail in different random places. The rare compile that completes does not act like it works.
The chip’s specification appears to show all pins should have the internal pullup available, so this must be a software issue from SEEED studio.

Very interesting. I never experienced any other issues when trying to use D2 with INPUT_PULLUP, but that’s because I just changed pins as soon as I found out it wouldn’t work. Since all the pins should have pullup functionalities, according to the chip’s specifications, I just assumed that maybe I had a small defect in my board. I guess that isn’t the case after all. Good to know!

Hi MatthewM
I tried the code you wrote.
The D2 internal pull-up pinMode(2, INPUT_PULLUP); worked without any problem in my environment, windows 10 and Arduino 1.8.13.
I just made the following changes to avoid compile errors.
Serial.println(“xxxxxxxx”); ----> Serial.println(“xxxxxxxx”);
“” ----> “”


//MatthewM's code
//
int button = 0;
void setup()
{
Serial.begin(9600);
pinMode(0, INPUT_PULLUP);
pinMode(1, INPUT_PULLUP);
//pinMode(3, INPUT_PULLUP);
pinMode(2, INPUT_PULLUP); //**************** use D2
}

void loop()
{
//button = buttonRead(); //Button 0 = null, 1 = button D0, 2 = button D1, 3 = button D3
button = buttonRead(); //Button 0 = null, 1 = button D0, 2 = button D1, 3 = button D2 //**************** use D2
Serial.println(button);
button = 0;
}

uint8_t buttonRead()
{
//Serial.println(“Here”);
Serial.println("Here"); //**************** to avoid compile error: stray '\342' in program

while(1) //Wait for a button to be pressed
{
if(digitalRead(0) == LOW)
{
//Serial.println(“Button 1”);
Serial.println("Button 1"); //**************** to avoid compile error: stray '\342' in program
delay(100);
return 1;
break;
}
if(digitalRead(1) == LOW)
{
//Serial.println(“Button 2”);
Serial.println("Button 2"); //**************** to avoid compile error: stray '\342' in program
delay(100);
return 2;
break;
}
//if(digitalRead(3) == LOW)
if(digitalRead(2) == LOW) //**************** use D2
{
//Serial.println(“Button 3”);
Serial.println("Button 3"); //**************** to avoid compile error: stray '\342' in program
delay(100);
return 3;
break;
}
}
}

MattewM,
Been trying to get back in for weeks. password reset issue. (the seeed store and their forum have different password systems)
So I found that my D2 pullup does work, when I can get the compiler to finish (another story to follow).
Also my D1 pullup now does not work at all, I have to add a pullup for it, and my D0 port is stuck at a hard low no matter how I program it.
These all worked OK when I first got the board, and was just struggling with the compiler. (but that is another story).
I have been an engineer designing computer and avionics boards for 40 years. I know how to handle and use such boards. I think these little guys are just fragile, maybe from ESD, or something else. I do not know what. Maybe substandard silicone die in their assemblies. Not sure why they have a metal top, but it would make good protection for sensitive parts, and they could wire-bond parts to the PCB and cover them without plastic encapsulation to save a little too. But if they are going to continue to be so fragile or short lived, seed will not and should not stay in the business.
Have you tried another unit to see if it does the same thing with your D2? My second unit is fine.
I found along the way that I had to reinstall all Seeed’s drivers from scratch on a fresh install of the latest Arduino IDE (and make the install portable because of execution restrictions at work and how the seeed extensions to the IDE wanted to run .exe code out of the AppData hidden folder).
I find their extension continues to be very unstable. Compiles only complete 10% of the time. They just hang up with arduino-builder.exe processes languishing that must be manually ended to try to start things over. This statement in a small .BAT file helps: taskkill /im arduino-builder.exe /f in case you or anyone else needs it too.
I have none of these issues with compiling when I switch boards to a standard arduino uno and run the exact same code.
I would like to see seeed fix their compiler extension and come up with less fragile sillicon. I love the XIAO’s small size, big capability, and comfortable price. I just wish it was not so frustrating to try to use. I had big plans for them, but am rethinking that idea.

And I must say I looked into the hardware spec for the M0+ and it should have the ability to apply pullups on all the IO pins. If anyone at Seeed says otherwise then it may be due to issues again with their compiler extension or the quality of the silicon they are selling, and not any limitation in the processor they advertise they are using.

Short answer: The Xiao does NOT have/enable built in pull-up resistors.

Long answer: After noticing some odd behavior while shrinking circuit that works fine on an UNO, I did some digging, and then ended up searching online and finding this thread… The code compiles just fine with the INPUT_PULLUP specified, but does not actually do what is expected.

So I tested my 3 Xiao units bare (i.e only the USB connected) with the following sketch:

void setup() {
  Serial.begin(9600);
  for (int i = 0; i < 11; i++)
    pinMode(i, INPUT);
}
void loop() {
  for (int i = 0; i < 11; i++)
    Serial.printf("%c:%i ", (char)(i + 65), analogRead(i));
  Serial.println();
  delay(100);
}

Then again, but this time replaced pinMode(i, INPUT); with pinMode(i, INPUT_PULLUP);

Using the Arduino IDE ‘Serial Plotter’ I got the following charts:

Running a similar test on an Uno/Nano output consistent values at 1023 on all analog pins when INPUT_PULLUP was used (except A6 and A7 on the Nano, which dipped a bit, but still over 1000).

I guess I will be adding some external pullups to my Xiao circuits. :roll_eyes:

[Mac OS 10.14.6 / Arduino IDE 1.8.13 / Seeed SAMD Boards 1.8.1]

I think that the pull-up resistor is effective only when digitalReading.
I changed to
analogRead (i) —> digitalRead (i)
and checked the input pins on a digital oscilloscope.

With so few pins, I rarely have a single switch per pin, thus never use digitalRead. Instead, I have multiple tact switches on a resistor ladder and use analogRead to determine which button was pressed. This works fine for Uno/Nano using the internal pull-up.

But, I did modify my test code and can confirm that when using digitalRead, all of the pins did get pulled high internally.