Thank you! I've been reading a bunch of documentation on the PIO's. And they all seem to leave something out or expect my knowledge on the Pico to be more than it is making me throw my hands in the air and just get frustrated with it. This was a very basic, easily understandable, explanation of the entire concept and how it relates to the CPU clock (which not all docs I've read explain, they just seem to expect you to know that).
think that explanations of PIO, must be with examples that shows the potential of PIO, (like high frequency respond, or fast sampling) because, the clasic blinking looks very complex. Many people could not try to use PIO thanks to this.
Has the "development environment" improved in the past two years? I'm completely new to the pico, but picked one up this week with the idea that I might be able to use it for a project that I had been working on implementing completely in 7400-series logic (if only there were a "DigiKey Prime" for free overnight shipping...). I was able to do the "blink" program on the pico using the Arduino IDE, which was stupidly easy--same exact code compiled and ran, just by changing the build target to the pico--but it's unclear if it's possible to do PIO programming with similar ease in the Arduino IDE.
Jesus Christ, this is one big headache for blinking an LED. Thank you for the video Shawn, enormous work to show us how to do this, but could Raspberry Pi made it more complicate it?
Is this PIO similar to the ULP processor inside the ESP32? That module has more instructions though, including ADD and SUB math as well as boolean operations like AND, OR, ... Very useful to execute ADC routines while CPU is asleep.
I didn't know about the ULP, thanks for pointing that out! As you pointed out, the ULP is more capable than the PIO, but there are more PIOs in the RP2040.
@@ShawnHymel It can operate the ADC and I2C while CPU sleeps. That's good enough for me. docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/ulp_instruction_set.html
I have a hard time believing that someone who works for digi-key(assumption) Has never seen a "programmable peripheral" before. Maybe speak with RCN, also of digi-key who has been supporting hardware that's been doing exactly this for 8+ years. You know, the beaglebone white / black ? PRU(programmable real time unit). TI AM355x . . . I'm not saying this isn't a cool feature, but it is definitely not the first. Other than that, great video.
This is a needed video. Twi questions. Can the pio be used to implement a toggle buffer of a/d values that a normal interrupt driver does. Second is FreeRtos available much like the dual core ESP32. Thanks
The PIO/ADC is a great question. I don't have an exact answer, but my guess would be no, you cannot read ADC values from the PIO. If you look at p. 11 of the RP2040 datasheet, you'll see that the ADC is treated as a separate peripheral from the PIO, and I don't see a way for the ADC to load the PIO FIFOs without CPU intervention. However, I could be wrong on that, and I'd love to know the answer, too. I've seen some RP2040 ports of FreeRTOS, but they're all single core at the moment. I have to imagine someone will give us dual-core support, much like you find in ESP-IDF, but I have not seen it yet.
@@ShawnHymel follow up question. In a machine learning application one may have to sample the A-D at a high rate as in a glass break detector. ( See Ti app note) If one is doing tensor flow lite, then the bandwidth of the processor will be robbed by the high interrupt rate. If one uses circuit python, then interrupt speed is 50x slower than C++. Circuit Python only makes sense if the PIO can service the interrupt. This brings up the general question which I ask in humility. What is the overall design philosophy of this chip? I understand the ESP32. (BTW I was involved indirectly when this chip was developed.) Seeed Studio has an arduino m4 which lcd display which they are pushing for machine learning. I am confused about this chip. Thanks
@@glennedgar5057 I wish I knew the answer to the design philosophy question. I'm guessing only the folks at Raspberry Pi can accurately state that :) My guess is that it's aimed at more education/maker audiences, hence the cheaper M0+ cores. If they really wanted us doing advanced DSP, ML, etc. on it, they would probably have given us an M4 core with an FPU. I imagine the speed + external flash + cheap IP core is primarily intended for MicroPython/CircuitPython development by the aforementioned crowd.
I wish there was a video detailing how one can use the ws2812 Neopixels in C such that it clearly demonstrates in code how one can individually controll a specific Neopixel in a chain. Say there are 64 NP's, you can put_pixel(urgb_u32(255, 0, 0) and this would set the 0th or 1st NP red however it is not clear how you could make say the 12th pixel red or another color. The examples in the official pico-examples do not do a good job showing how to actually make this work in C at all. There is nothing on the web that really demonstrates this functionality in C.
Look at the protocol documentation in the WS2812 datasheet, then you will understand why something like void put_pixel(uint16_t pixel, uint32_t gbr) isnt possible in a low level implementation like with WS2812.pio. WS2812 and similar use a 1 wire serial protocol, that means timing is everything. The order you send data to the WS2812 decides which pixel receives it, a delay in transmission (which you will find in the datasheet of WS2812) basically means you are finished sending data and the LEDs reset with that data you just sent. Therefore you have to send that data fast enough to not trigger the reset. Lets say you want to change the 10th LED in the chain, to do that you have to make a quick for loop that sends 9x (uint32_t)0x0 and then the value for the 10th led, eg (uint32_t)0xFF000000 for R0,G255,B0. The problem with this is that now the first 9 LEDs will be turned off because you sent them 0x0. Now to how you would actually implement this so that if you send eg the 10th LED a value LED0-8 would keep the previous value. Simply make an array: uint32_t pixels[NUM_PIXELS] So to change the 10th LED to R0,G255,B0: pixels[9] = 0xFF000000 Now for loop through the array and: pio_sm_put_blocking(pio, sm, pixels[i]) After the for loop do a sleep_us(50) to make sure you trigger the reset.
There are two PRUs in the BeagleBone Black, but my understanding is that they were more like full-fledged co-processors rather than simple FSMs. As PicoNano pointed out, I think the ESP32 ULP is closer to the PIO.
Imagine my disappointment when I realized this is the last of the C/C++ series! This was so well done and I learned so much.
Great tutorial. Working on a robotics project. This series was a huge help. Even though it has been two years, I hope to see more.
Thank you! I've been reading a bunch of documentation on the PIO's. And they all seem to leave something out or expect my knowledge on the Pico to be more than it is making me throw my hands in the air and just get frustrated with it. This was a very basic, easily understandable, explanation of the entire concept and how it relates to the CPU clock (which not all docs I've read explain, they just seem to expect you to know that).
think that explanations of PIO, must be with examples that shows the potential of PIO, (like high frequency respond, or fast sampling) because, the clasic blinking looks very complex. Many people could not try to use PIO thanks to this.
Has the "development environment" improved in the past two years? I'm completely new to the pico, but picked one up this week with the idea that I might be able to use it for a project that I had been working on implementing completely in 7400-series logic (if only there were a "DigiKey Prime" for free overnight shipping...). I was able to do the "blink" program on the pico using the Arduino IDE, which was stupidly easy--same exact code compiled and ran, just by changing the build target to the pico--but it's unclear if it's possible to do PIO programming with similar ease in the Arduino IDE.
Jesus Christ, this is one big headache for blinking an LED. Thank you for the video Shawn, enormous work to show us how to do this, but could Raspberry Pi made it more complicate it?
Using PIO isn't required to blink a LED.
@@koreykaczor3254 LOL. That wasn't what he meant. He means even the simplest of tasks seems overly complicated using PIO.
Great video
you are amazing
Thank you!
Very good useful video
The code compiles, but doesn't blink :/
This PIO thing feels like it would be hell to debug.
Can the pio pins output pwm audio? if so, how can i out put audio in C++ using pio pins? Thanks
Is this PIO similar to the ULP processor inside the ESP32?
That module has more instructions though, including ADD and SUB math as well as boolean operations like AND, OR, ...
Very useful to execute ADC routines while CPU is asleep.
I didn't know about the ULP, thanks for pointing that out! As you pointed out, the ULP is more capable than the PIO, but there are more PIOs in the RP2040.
@@ShawnHymel It can operate the ADC and I2C while CPU sleeps. That's good enough for me.
docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/ulp_instruction_set.html
I have a hard time believing that someone who works for digi-key(assumption) Has never seen a "programmable peripheral" before. Maybe speak with RCN, also of digi-key who has been supporting hardware that's been doing exactly this for 8+ years. You know, the beaglebone white / black ? PRU(programmable real time unit). TI AM355x . . . I'm not saying this isn't a cool feature, but it is definitely not the first. Other than that, great video.
This is a needed video. Twi questions. Can the pio be used to implement a toggle buffer of a/d values that a normal interrupt driver does. Second is FreeRtos available much like the dual core ESP32. Thanks
The PIO/ADC is a great question. I don't have an exact answer, but my guess would be no, you cannot read ADC values from the PIO. If you look at p. 11 of the RP2040 datasheet, you'll see that the ADC is treated as a separate peripheral from the PIO, and I don't see a way for the ADC to load the PIO FIFOs without CPU intervention. However, I could be wrong on that, and I'd love to know the answer, too.
I've seen some RP2040 ports of FreeRTOS, but they're all single core at the moment. I have to imagine someone will give us dual-core support, much like you find in ESP-IDF, but I have not seen it yet.
@@ShawnHymel thanks
@@ShawnHymel follow up question. In a machine learning application one may have to sample the A-D at a high rate as in a glass break detector. ( See Ti app note) If one is doing tensor flow lite, then the bandwidth of the processor will be robbed by the high interrupt rate. If one uses circuit python, then interrupt speed is 50x slower than C++. Circuit Python only makes sense if the PIO can service the interrupt.
This brings up the general question which I ask in humility. What is the overall design philosophy of this chip? I understand the ESP32. (BTW I was involved indirectly when this chip was developed.) Seeed Studio has an arduino m4 which lcd display which they are pushing for machine learning. I am confused about this chip.
Thanks
@@glennedgar5057 I wish I knew the answer to the design philosophy question. I'm guessing only the folks at Raspberry Pi can accurately state that :) My guess is that it's aimed at more education/maker audiences, hence the cheaper M0+ cores. If they really wanted us doing advanced DSP, ML, etc. on it, they would probably have given us an M4 core with an FPU. I imagine the speed + external flash + cheap IP core is primarily intended for MicroPython/CircuitPython development by the aforementioned crowd.
I wish there was a video detailing how one can use the ws2812 Neopixels in C such that it clearly demonstrates in code how one can individually controll a specific Neopixel in a chain. Say there are 64 NP's, you can put_pixel(urgb_u32(255, 0, 0) and this would set the 0th or 1st NP red however it is not clear how you could make say the 12th pixel red or another color. The examples in the official pico-examples do not do a good job showing how to actually make this work in C at all. There is nothing on the web that really demonstrates this functionality in C.
Look at the protocol documentation in the WS2812 datasheet, then you will understand why something like void put_pixel(uint16_t pixel, uint32_t gbr) isnt possible in a low level implementation like with WS2812.pio.
WS2812 and similar use a 1 wire serial protocol, that means timing is everything.
The order you send data to the WS2812 decides which pixel receives it, a delay in transmission (which you will find in the datasheet of WS2812) basically means you are finished sending data and the LEDs reset with that data you just sent.
Therefore you have to send that data fast enough to not trigger the reset.
Lets say you want to change the 10th LED in the chain, to do that you have to make a quick for loop that sends 9x (uint32_t)0x0 and then the value for the 10th led, eg (uint32_t)0xFF000000 for R0,G255,B0.
The problem with this is that now the first 9 LEDs will be turned off because you sent them 0x0.
Now to how you would actually implement this so that if you send eg the 10th LED a value LED0-8 would keep the previous value.
Simply make an array: uint32_t pixels[NUM_PIXELS]
So to change the 10th LED to R0,G255,B0: pixels[9] = 0xFF000000
Now for loop through the array and: pio_sm_put_blocking(pio, sm, pixels[i])
After the for loop do a sleep_us(50) to make sure you trigger the reset.
@@_--_--_ thank you so much! This is very helpful!
Didn't the BeagleBone Black have two PRUs (programable real time unit) that would perform similar functionality to the Pi PIOs?
There are two PRUs in the BeagleBone Black, but my understanding is that they were more like full-fledged co-processors rather than simple FSMs. As PicoNano pointed out, I think the ESP32 ULP is closer to the PIO.