Closed ullibak closed 1 month ago
I always thought that the pio function was only plausible trough an external convertor?
https://arduino-pico.readthedocs.io/en/latest/sdk.html the last entry is exactly what i thought
Yes, you need pioasm.exe to convert the PIO instructions to a mixed file containing C code and assembly code. The output of this process is the file that I put into the zip file above. This is the header file "quadrature_encoder.pio.h" that is included in the .INO file in line 2. This conversion can be done by hand by calling
.\pioasm.exe quadrature_encoder.pio quadrature_encoder.pio.h
on the Windows command line. When building and compiling the Pico examples the same process is run automatically and the generated file can be found in the build directory.
From my former experience with the old Pico board (RP2040) the code from the examples that come with the Pico SDK (and the generated .h file) can be used with arduino-pico. But I was not able to do so using the new Pico 2.
A quick check of SoftwareSerial
shows that the PIOs run fine on the RP2350. Connect GP0 to GP2 and you'll get hello
coming out from the PIO input (since Quadature Encoder probably uses input on the PIOs)
#include <SoftwareSerial.h>
SoftwareSerial s(2, 3);
void setup() {
s.begin(115200);
Serial1.begin(115200);
while (1) {
Serial1.println("hello");
Serial.printf("x\n");
while (s.available()) {
Serial.printf("%c", s.read());
}
delay(100);
}
}
void loop() {
}
Your example has hardcoded PIOs and SMs which isn't legal here. Look at PIOProgram
to ensure you aren't trying to use a PIO that the core already is running, If it's interrupt-based, make sure it's properly enabled because the IRQs in the SDK and the core do not always start identically.
Many thanks! Tried your code and it works as expected. Yes it could be that a SM is already used for another purpose and I did not check this in my program. PIOProgram solves this in an elegant way. As a fast experiment, I tried different SMs on pio0 and pio1 and also different GPIO pins. No success.
Reading the C++ SDK documentation again, I found that in the examples given there, the GPIOs are initialized.
So I added pio_gpio_init()
for both GPIOs used. And suddenly, the quadrature encoder worked!
#include <hardware/pio.h>
#include "quadrature_encoder.pio.h"
int new_value, delta, old_value = 0;
const uint PIN_AB = 0;
PIO pio = pio0;
const uint sm = 0;
void setup() {
Serial.begin(115200);
pio_gpio_init(pio, PIN_AB);
pio_gpio_init(pio, PIN_AB + 1);
// we don't really need to keep the offset, as this program must be loaded at offset 0
uint offset = pio_add_program(pio, &quadrature_encoder_program);
quadrature_encoder_program_init(pio, sm, PIN_AB, 0);
}
void loop() {
// put your main code here, to run repeatedly:
new_value = quadrature_encoder_get_count(pio, sm);
delta = new_value - old_value;
old_value = new_value;
Serial.printf("position %8d, delta %6d\n", new_value, delta);
sleep_ms(500);
}
The only mayor difference between my Arduino code and the example code of the Pico SDK is that I do not call stdio_init_all()
. But this should have nothing to do with GPIOs. Or am I wrong?
Thanks again!
It definitely wouldn't set pins to PIO! 😆
That call just inits USB and printf hooks on the SDK. We do all that stuff internally, so just dropping the call is the right thing here.
Looks like with the proper IO setup you're all good, so closing for now.
Hi I am trying to run the quadrature encoder example that uses PIO functionality:
github.com/raspberrypi/pico-examples/tree/master/pio/quadrature_encoder
I have a rotary encoder attached to GPIOs 0 and 1 and tested it using VS Code and the Pico SDK 2.0 and it runs as expected. To run it on Arduino, I created a new file containing an almost exact copy of the example code (with the only exception that stdio_init_all() is not used):
I then copied the file generated by pioasm.exe (quadrature_encoder.pio.h) from the build directory of the SDK example to the directory of the .INO file. quadrature_encoder.pio.zip
The INO files compiles and uploads without errors. But the output for "position" and "delta" is always zero,
Did I overlook something or is the PIO functionality not yet implemented in arduino-pico?
Thanks!