Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Digital only executor via a Raspberry Pi Pico #830

Open
iandobbie opened this issue Nov 9, 2022 · 4 comments
Open

Digital only executor via a Raspberry Pi Pico #830

iandobbie opened this issue Nov 9, 2022 · 4 comments

Comments

@iandobbie
Copy link
Collaborator

In previous emails and now in the microscope/cockpit development meeting on 2022-11-08 it has been suggested that the programable IO components of the Raspberry Pi Pico could be used as a digital only executor with high performance and super cheap.

I have a couple of Pi Picos and I will try to knock up a test to see if this is feasible.

@juliomateoslangerak
Copy link
Contributor

I found this code I worked some 10 months ago https://github.com/juliomateoslangerak/rp2040_executor
Use the main.py script with Micropython

prog defines the 'program' to run on the PIO.
Then I sequentially load in the state machine the time and digital value into the same register. These should be coming from an array (https://docs.micropython.org/en/latest/library/array.html)

from machine import Pin
from rp2 import PIO, StateMachine, asm_pio
from time import sleep


@asm_pio(
         # set_init=PIO.OUT_LOW,
         out_init=(PIO.OUT_LOW,) * 32,
         out_shiftdir=PIO.SHIFT_LEFT,
         fifo_join=PIO.JOIN_TX,
)
def prog():
    wrap_target()
    pull()
    mov(x, osr)
    jmp(not_x, 'end')
    pull()
    out(pins, 32)
    label('loop')
    jmp(x_dec, 'loop')
    wrap()
    label('end')
    mov(pins, null)


sm = StateMachine(1, prog, freq=2000, out_base=Pin(0))

sm.active(1)
for _ in range(3):
    sm.put(1000)
    sm.put(0b00000010000000000000000000000001)  # 1000 0100 0010 0001 1000010000100001
    sm.put(1000)
    sm.put(0b00000000000000000000000000000000)  # 1000 0100 0010 0001 1000010000100001
    sm.put(1000)
    sm.put(0b00000010000000000000000000000001)  # 1000 0100 0010 0001 1000010000100001
    sm.put(1000)
    sm.put(0b00000000000000000000000000000000)  # 1000 0100 0010 0001 1000010000100001
    sm.put(0)
    sm.put(0b00000000000000000000000000000000)  # 1000 0100 0010 0001 1000010000100001
sleep(20)
sm.active(0)

One thought I had was to dedicate one core of the rp2040 for dealing with the serial com and the other for running loading data into the PIO. The main advantage would be to be able to interrupt the acquisitions upon request from the host and to deal with the logic of the program a bit more easily.

@juliomateoslangerak
Copy link
Contributor

juliomateoslangerak commented Dec 13, 2022

@juliomateoslangerak
Copy link
Contributor

An option to add Ethernet to the pico
https://github.com/Wiznet/RP2040-HAT-MicroPython
This would leave us with 16 digital lines (GP0-GP15), and the possibility to add analogue output through I2C at GP26-GP27. GP22 and GP28 still free for some added neopixel coolness.

@iandobbie
Copy link
Collaborator Author

I would worry a bit about the first I2C option as the DAC is only 12 bit. If you have a 200 um range piezo (pretty typical) then the maximum resolution is 50 nm which is pretty marginal for decent Z stacks at high NA.

The second option only does 0-5 v, so neither seem ideal, but it seems like a good solution if we can find a sensible board.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants