NebraLtd / AnyBeam

Resources for the Nebra AnyBeam laser pico projectors
35 stars 6 forks source link

Can anybeam HAT project structure light for 3D scanning #22

Closed leoteo1 closed 3 years ago

leoteo1 commented 3 years ago

I am looking for a high brightness development projector for 3D structure light scanning. can anybeam HAT project structure light (sine pattern) and synchronize (vertical sync) cameras for frame trigger?

LutzKoepke commented 3 years ago

I would be interested in that too. I would like to use the anybeam HAT as a scanner to determine the dependence of the sensitivity of a photonic device (a large diameter photomultiplier) as function of its surface coordinate. Since I do not necessarily want to use a high speed FADC data acquisition (such as a RedPitaya) or oscilloscope for readout, it would be good to be able to lower the "scanning speed", i.e. the frame rate, by a lot. In principle, the hdmi settings in config.txt could be adapted by adding something like hdmi_cvt 900 720 1 4 for a frame rate of 1/s and a 5:4 screen. Would something like this be possible or does the hardware prevent to lower the framerate? I read that one can configure the hat such that one can salvage an i2c connection but no SPI. A really fast ADC (i.e. a few MHz sampling) can thus not be attached, however, there are i2c ADCs that can work with close to 200 kHz ... Of course it would be even better if one could address the Ulitmens sensor via the RPI hat directly, without going through the hdmi protocol ...

leoteo1 commented 3 years ago

LutzKoepke, did you find out any other way to project structure patterns using project?

LutzKoepke commented 3 years ago

dear leoteo1,

I admit that I have not yet bought the anybeam HAT so that I could do some "reverse engineering". Since you do not seem to need 3 colours and light intensity modulation, but a user-defined pattern, you might be better off with solutions by other vendors that offer MEMS devices that you can address directly. The anybeam solution has the advantage of price and directly coupling to the RPI. Unfortunately, I could not find specs for the Ultimems sensors http://www.ultimems.com/technologydetail/index.html#t2 , which come in 3 mirror sizes http://www.ultimems.com/en/index.html#solutions . From the pictures one sees that the mirror has 6 ? connections plus whatever is needed to drive the 3 lasers. A raspberry pi has 40 pins of which 8 are connected to ground and 4 are connected to 5V of 3.3 V power. That gives you 28 addressable pins. The anybeam hat seems to use all pins in mode 1 [https://github.com/NebraLtd/AnyBeam/tree/master/Hardware: _we use every pin availble on the Raspberry Pi. That means you don't get the standard users i2c pins, the UART(Tx/Rx)pins, the EEPROM i2c pins and the hardware SPI pins.]__ . 24 pins are used as a parallel interface to provide 8 intensity bits for each color. 4 pins are used to drive the screen. In mode 4, 18 bits are used for addressing the lasers, and GPIO 26/27 are freed for an I2C bus. In the latter case, there should be 4 additional bits available for free use. I would need to check whether one could, in principle, also drive the faster SPI bus instead of I2C (which would allow for attaching faster ADCs).

For now I only bought the Seeed Studio Grove - I2C ADC 12-bit ADC121C021 fast ADC (185000 samples/s) in order to see whether I can actually reach the readout speed that allows for sampling at the highest rate.

LutzKoepke commented 3 years ago

addendum: anybeam probably uses the "parallel display interface" : https://www.raspberrypi.org/documentation/hardware/raspberrypi/dpi/ which allows for parallel RGB displays either in RGB24 (8 bits for red, green and blue) or RGB666 (6 bits per colour) or RGB565 (5 bits red, 6 green, and 5 blue). The 4 pins that address the mirror movement are clock (GPIO 0, pin 27), enable (GPIO 1, pin 28), vsync (GPIO 2, pin 3), and hsync (GPIO 3, pin 5). There is only 1 possible assignment to the pins for the 3 x 8 bit configuration; for the 3 x 6 bit configuration, there are 2 options: the assignment of the pins could be according to mode 5 or mode 6 (note, this is a different "mode" as referred to in the anybeam manual). I think that mode=6:
image In any case, GPIO 26 (pin 37) and 27 (pin 13) are free for use as i2c bus. Probably, GPIO 10 (pin 19) ,11 (pin 23), 18 (pin 12), 19 (pin 35) are also free.

Explanation of the hysnc and vsync signals: An hsync signal means: "start at column zero" and a vsync means: "start in row 0". Lets look at an example: A 800x600 pixel screen has 480000 pixels. The time to scan the whole picture would be the period of one pixel (1/f) multiplied by the number of pixels. Since there will be 1 vsync pulse and 800 hsync pulses per picture frame, the corresponding time spent in these sync pulses needs to be added. The frame rate (= refresh rate) must be shorter than the time it takes to complete one scan.

Other things to consider: since one uses GPIO pins that are by default associated to the i2c and spi busses, one needs to turn those off:

dtparam=i2c_arm=off
dtparam=spi=off

If one wants to customize the display and change, e.g., the timing, one needs to choose:

dpi_group=2
dpi_mode=87

Whether the anyhat supports this custom setting, is not clear to me. The recommended setting in the manual is "85", meaning for hdmi_group=2: 1280x720 pixels, 60 Hz frame rate and 16:9 aspect ratio.

The timing can be changed by: dpi_timings=<h_active_pixels> <h_sync_polarity> <h_front_porch> <h_sync_pulse> <h_back_porch> <v_active_lines> <v_sync_polarity> <v_front_porch> <v_sync_pulse> <v_back_porch> <v_sync_offset_a> <v_sync_offset_b> <pixel_rep> <frame_rate> <interlaced> <pixel_freq> <aspect_ratio>

For a 800 x 480 non-interlaced display with 60 Hz framerate with 4:3 aspect ratio, one could e.g. define:

h_active_pixels = 800  (horizontal pixels  = width)
h_sync_polarity = 0    (invert hsync polarity if = 1)
h_front_porch = 40    (horizontal front padding from DE active edge)
h_sync_pulse = 48     (hsync pulse width in pixel clocks)
h_back_porch = 88    (horizontal back padding from DE active edge)
v_active_lines = 480   (vertical pixels  = width)
v_sync_polarity = 0    invert vsync polarity if = 1)
v_front_porch = 13   (vertical front padding from DE active edge)
v_sync_pulse = 3      (vsync pulse width in pixel clocks)
v_back_porch = 32   (vertical back padding from DE active edge)
v_sync_offset_a = 0
v_sync_offset_b = 0
pixel_rep = 0        
frame_rate = 60       (frame rate = refresh rate)
interlaced = 0
pixel_freq = 32000000 (=width*height*framerate = 800*480*60)
aspect_ratio = 1

dpi_timings=800 0 40 48 88 480 0 13 3 32 0 0 0 60 0 32000000 1

I assume that one is restricted to integers values in frame_rate so that pixel_freq can only be reduced to "width*height"; the maximal sampling rate of the I2C-ADC would then be a limiting factor in the resolution. Whether any of these adjustments work with the anybeam hat and the mems mirror is unclear to me ...