earlephilhower / arduino-pico

Raspberry Pi Pico Arduino core, for all RP2040 and RP2350 boards
GNU Lesser General Public License v2.1
1.99k stars 412 forks source link

Digital Input from pins GPIO26-29 #539

Closed Gavin-Perry closed 2 years ago

Gavin-Perry commented 2 years ago

I don't get a value with digitalRead() or gpio_get() on pins 26-28 (used 29 as input OK in DMX module. Doesn't matter if I use pull-up or pull-down always getting 0 My workaround was to use analogRead() and set a threshold (arbitrarily 400) for HIGH and LOW Ended up setting some pins with pull_up and some pull_down with no problems using analog input. Is this a RasPi problem or arduino-pico?

Minimum code gpio_set_dir(26, GPIO_IN); gpio_pull_up(26); gpio_set_dir(27, GPIO_IN); gpio_pull_up(27); gpio_set_dir(28, GPIO_IN); gpio_pull_up(28); Serial.println(gpio_get(26)); Serial.println(gpio_get(27)); Serial.println(gpio_get(28));

ALWAYS return 0 whether high or low. Is there a problem with gpio_get()?

earlephilhower commented 2 years ago

There's no real reason to use the gpio_xxx SDK calls, BTW, and you neglected to write the proper value to the pins so the code snipped you posted is incorrect and will basically never work. Use digitalRead...it took me a little to figure out the IO configs, but you don't need to. :)

I have no problem reading the 3 ADC pins as digital on the RpiPico with this simple code (I used a wire to short each pin to GND in succession as shown below...)

void setup() {
  // put your setup code here, to run once:
Serial.begin();
delay(5000);
pinMode(26, INPUT_PULLUP);
pinMode(27, INPUT_PULLUP);
pinMode(28, INPUT_PULLUP);
}

void loop() {
Serial.printf("%d %d %d\n", digitalRead(26)?1:0, digitalRead(27)?1:0, digitalRead(28)?1:0);
delay(100);
}
...
1 1 1
1 1 1
1 1 1
1 1 1
0 1 1
0 1 1
0 1 1
0 1 1
0 1 1
0 1 1
0 1 1
0 1 1
0 1 1
0 1 1
0 1 1
0 1 1
0 1 1
0 1 1
0 1 1
1 1 1
1 1 1
...
1 1 1
1 1 1
1 0 1
1 0 1
1 0 1
1 0 1
1 0 1
1 0 1
1 0 1
1 0 1
1 0 1
1 0 1
1 0 1
1 0 1
1 0 1
1 0 1
1 1 1
1 1 1
1 1 1
1 1 1
...
1 1 1
1 1 0
1 1 0
1 1 0
1 1 0
1 1 0
1 1 0
1 1 0
1 1 0
1 1 0
1 1 0
1 1 0
1 1 1
Andy2No commented 2 years ago

Isn't gpio_get() faster than digitalRead()?

It seems to me there's no point using gpio_xxx to configure the pins instead of pinMode(), though, because that's typically only done once, on startup.

earlephilhower commented 2 years ago

It's microscopically faster, but if you really cared about speed you wouldn't use the SDK call, either. You'd just read the HW register directly.

Andy2No commented 2 years ago

It hadn't occurred to me to do that... and I wouldn't immediately know how, but I could look at the SDK source code. Thanks.

I wonder if it's worth changing this to a discussion. It's something that seems to come up a lot about standard Arduinos, because their digitalRead() and digitalWrite() are quite slow. I remember seeing people trying to measure how slow, by timing loops that did it a thousand times, or similar.

Since it's faster for arduino-pico, it seems worth making this a discussion, so people can add to it if they want to, and so it can be kept more visible.

Gavin-Perry commented 2 years ago

I tried digitalRead() first, then gpio_get() only after that didn't work. gpio_set_dir(26, GPIO_IN); added when I kept getting zeros. I wondered if Arduino was calling adc_init() before my code but seemed unlikely.

Message ID: @.***>

Gavin-Perry commented 2 years ago

I've been told now that gpio_init(pin) is required for some pins. Anyone know which pins need it? Is it all and when I call a library function (vs SDK) it gets done?

earlephilhower commented 2 years ago

Check the sources here for what you need to do to set inputs and make it work. https://github.com/earlephilhower/arduino-pico/blob/master/cores/rp2040/wiring_digital.cpp

Note how you have to actually write a value to the GPIO port to allow reads to work while in pull-up/pull-down mode.