I made a full color POV (persistence of vision) display using Raspberry Pi Pico, wireless charging module and DotStar LED tape.
High-speed display is possible with PIO of Raspberry Pi Pico.
ConstitutionLED tape, Raspberry Pi Pico and reflectance sensor are mounted on the rotating part, and LED tape uses DotStar. Using the wireless charging module, the power supply to the rotating part was carried out wirelessly.
I used two Dotstar LED tapes controlled by hardwear SPIs (SPI0, SPI1).
Wireless charge module is used for power supply to the LED rotating part. It is only placed in the face-through the transmission coil to the rotation axis of the motor without almost processing.
I coded it with reference to the sample code below.https://github.com/raspberrypi/pico-examples/tree/master/pio/apa102
The two LEDs are controlled in parallel by different PIO state machines (sm0, sm1).
When a reflectance sensor detects a marker, it decreases the output, so it detects it in the interrupt and measures the time it takes to interrupt processing by one lap.
It switches the LED blink by dividing the time of one lap by 1000. LED display patterns are stored as an array in graphics.h.
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/pio.h"
#include "apa102.pio.h"
#include "graphics.h"
#define PIN_CLK0 2
#define PIN_DIN0 3
#define PIN_CLK1 14
#define PIN_DIN1 15
#define N_LEDS 24
#define SERIAL_FREQ (30 * 1000 * 1000)
// Global brightness value 0->31
#define BRIGHTNESS 2
unsigned long rotTime, timeOld, timeNow;
int numRot = 0;
int stateDiv = 0;
int numDiv = 0, numDiv2 = 0;
void gpio_callback() {
timeNow = time_us_64();
rotTime = timeNow - timeOld;
timeOld = timeNow;
numRot++;
if(numRot >= Frame ) numRot = 0;
}
void put_start_frame(PIO pio, uint sm) {
pio_sm_put_blocking(pio, sm, 0u);
}
void put_end_frame(PIO pio, uint sm) {
pio_sm_put_blocking(pio, sm, ~0u);
}
void put_bgr888(PIO pio, uint sm, uint32_t c) {
pio_sm_put_blocking(pio, sm,
0x7 << 29 | // magic
(BRIGHTNESS & 0x1f) << 24 | // global brightness parameter
c
);
}
int main() {
stdio_init_all();
gpio_set_irq_enabled_with_callback(22, GPIO_IRQ_EDGE_RISE, true, &gpio_callback);
PIO pio = pio0;
uint sm0 = 0;
uint sm1 = 1;
uint offset = pio_add_program(pio, &apa102_mini_program);
apa102_mini_program_init(pio, sm0, offset, SERIAL_FREQ, PIN_CLK0, PIN_DIN0);
apa102_mini_program_init(pio, sm1, offset, SERIAL_FREQ, PIN_CLK1, PIN_DIN1);
while (true) {
if(stateDiv == 1 && time_us_64() - timeOld > rotTime / Div * (numDiv)){
stateDiv = 0;
}
if(stateDiv == 0 && time_us_64() - timeOld < rotTime / Div * (numDiv + 1)){
stateDiv = 1;
put_start_frame(pio, sm0);
put_start_frame(pio, sm1);
for (int i = 0; i < N_LEDS; ++i) {
numDiv2 = numDiv+10;
if(numDiv2 >= Div) numDiv2 -= Div;
put_bgr888(pio, sm0, pic[numRot][numDiv][i*2]);
put_bgr888(pio, sm1, pic[numRot][numDiv2][i*2+1]);
}
put_end_frame(pio, sm0);
put_end_frame(pio, sm1);
numDiv++;
if(numDiv >= Div ) numDiv = 0;
}
}
}
graphics.h
#define Frame 10
#define NUMPIXELS 48
#define Div 1000
const uint32_t pic [Frame][Div][NUMPIXELS] = {
{
{0x050505,....},
.
.
.
{0x050505,....},
}
}
OperationHigh-speed display is possible with PIO of Raspberry Pi Pico.
Comments