DIY Laser Projector - Built from an old hard drive

1,368,065
0
Published 2023-05-09
#diy #laser #arduino #technology #programming
In this video I design and build a portable laser text projector. It's battery operated and can display messages over 90 feet away. I can even connect to it wirelessly using bluetooth.

Original code and 3D files:
github.com/BenMakesEverything/LaserText
Better code:
github.com/BenMakesEverything/lasertext_v1-1

Intro music: Artificial Intelligence - Cyberwalker (via YouTube Creator Music)
Music in coding section: Stay Retro - AlexiAction (via Pixabay)

All Comments (21)
  • @RealNovgorod
    Interrupts on Arduino introduce random ~10µs jitter, which is roughly consistent with the jitter amount in your tests. For tight timing, try to disable interrupts during the laser toggling and instead wait for the sync pulses from the photodiode by directly reading the pin register in a blocking while loop. The serial communication can be done between frames while waiting for the frame sync (if necessary, this will add one more disk rotation with laser off as a "blanking" interval).
  • When I was a kid, my dad built a cool persistence of vision display with LEDs. Not a projector, but it made it look as though a LED marquee display was floating in the air over the device. It used those same optical transistor switches. This was in the early 90's, he envisioned miniaturizing it into a small ball to be used as a christmas tree ornament. He never moved further than the prototype, and a few years later similar devices were available retail.
  • @martyp7401
    Hey great video, i'm just a layman hobbyist but the way you work through your project outlining the errors and mistakes you encounter along the way and rectify them (rather than editing them out) really makes your content shine with extra value for me!
  • I love the retrofuturistic cyberpunk aesthetic of the scan lines and slight wobble. There's also a lot of tricks in both software and hardware to get better resolution. Definitely look into faster chips, the ESP32 is great in that regard. You could also use a shift register or serial control chip and external clock to control the beam pwm. Basically write your bytes into a register, and clock out bit by bit directly to the beam control. That will give tighter temporal accuracy as well.
  • @hiteshhere
    Dude, This is AWESOME !! To me the flickering and wobbling add a special sci-fi vibe to your texts rather than a flaw. Loved it. All the best. Keep going.
  • @mr_ambo24
    I love finding new channels like this. I can’t wait to see what he makes. It’s really fun watching a channel evolved from just a few videos
  • @makergiovanni
    One of the best projects I have seen in the last months. Amazing!
  • @Scrogan
    If you don’t use tarduino delay functions but rather use noops and direct port writing you should be able to get a laser toggle every 2-4 clock cycles. You may want to invest in a MOSFET gate driver IC though.
  • Really neat project, thanks for sharing- the parallax effect when shining it into the corner of the room was especially neat, really different to how a normal projector looks
  • @D1zZit
    This is a super well done video! Extremely informational, but you did a great job of breaking down some of the more advanced concepts and presenting them in an easy to understand manner. Such an incredibly cool project as well!
  • @CharonSin
    I love the gritty analog look and the wobble effect!! Very retro sci-fi.
  • @AJMansfield1
    Impressive results! I wouldn't have expected a 3D print to be stable enough, it's nice to see that a commercially-made polygonal mirror isn't the only option. But you don't actually need a faster CPU: The arduino you're using would be perfectly capable of precise 62.5 ns resolution pulses -- i.e. the full 16 MHz system clock rate -- if you exploited the Atmega328p's powerful Timer/Counter peripherals for the task. Here's how I'd do it: - Set up the 16-bit Timer1 peripheral in free-running mode (WGM mode 0) and with full system clock rate (i.e. no clock divider). This timer will just count up continuously; the fact it'll overflow from 0xFFFF back to zero every 4.096 ms is of no consequence as long as that's longer than a single scan line. - Wire the per-scan-line trigger to the ICP1 pin. This way, the input capture module can record the exact "start time" for each scan line in hardware before triggering the input capture interrupt to set up at the start of the scan line. - Wire the laser to an additional XOR gate, whose inputs are wired to the OC1A and OC1B pins. The output compare channels will be used in 'toggle' mode so that, in conjunction with the XOR gate, they can effectively act as a single output with a two-element buffer, rather than two separate outputs with only single-element buffers. - The main task of the input capture interrupt (TIMER1_CAPT) is to copy ICR1 into a register, and then copy of the next line of the image into a separate buffer, adding that ICR1 value to each element of the buffer to offset it to the measured start time of the scan line (using 16-bit unsigned arithmetic so it overflows back to zero the same way the timer does). Aside from that, it's just a bit of bookkeeping at the start to reset the outputs to a known state (set COM mode to 'clear' and trigger FOC), and a bit more at the end to prime the output compare modules (set OCR1A and OCR1B with the first two values from the buffer, set COM modes back to 'toggle', and enable both compare match interrupts). - The compare match interrupts (TIMER1_COMPA and TIMER2_COMPB) then have a very simple task: each time their channel finishes triggering, retrieve the next value from the scan buffer and put it in their OCR register. That should be the absolute first thing the interrupts do, and then after that there's only some light bookkeeping, to clear their interrupt enable bit if the next next value would be past the end of the buffer. - The interrupt for the index trigger is even simpler still: all it needs to do is reset the value of the row counter back to zero... and I guess you could flop image buffers here too; change the pointer the scan line interrupt uses to find the image to point to the frame that was being rendered while the previous frame was being displayed. The way I'm proposing to use the interrupts here is in a sense the most fundamental design pattern used for serious interrupt-driven embedded programming. Almost all hardware peripherals are specifically designed around this usage pattern, understanding that fact can make the rationale for their designs much easier to understand. Even though an interrupt seems instant compared to polling, there's still too many sources of jitter to rely on them to take actions that require precise timing. Rather, their responsibility is just to refill a hardware buffer from a software buffer before the hardware runs dry, or empty an hardware buffer before it overflows -- something that still has to be done "right away" rather than "next time the control loop feels like checking", but that way an extra microsecond or two of delay waiting for another interrupt to finish doesn't compromise the timing accuracy. This pattern is actually used twice as I describe it above, both copying data from the ICR1 register to use to populate the scan buffer, and of course moving data from the scan buffer to the OCR registers. With the design, you'd inherently have the full 62.5 ns precision of the full-speed system clock, and using both channels together means pulses could be as short as a single clock cycle, too. The interrupt execution time would limit the rate at which you could continuously switch it on and off, but even with minimal effort I'd expect at least 100 kHz. With high effort (i.e. implementing the compare match interrupts with hand-written assembly code) it'd be entirely plausible to achieve a maximum continuous pulse rate better than 1 MHz.
  • @awardfoto1
    Content like this still makes Youtube great.
  • @ed.puckett
    This is a fascinating project. I also wanted to mention that your style of code walkthrough was very effective. Best wishes to you, and keep up the good work!!
  • Instantly one of my favorite channels now! You know what? Make a hologram with it? Some holographic projectors use an array of speakers on top and bottom, to create a levitation field. Then they use a small white bead(sphere) as a "pixel" representation. Then there is a camera that tracks the small sphere and projects a laser light on it. The resulting image is a actual physically interactable 3D hologram!
  • @Gold171
    Excellent production quality for a small Youtube channel. Engaging and interesting from beginning to end. Nice work.
  • @claws61821
    This is a really awesome project, Ben, and a nice combination of old and new projection techniques! I can tell you that one part of the causes for the shuttering effect you noted actually is the carousel that you built, as each transition causes the image to "break" for a split second. You'll also get closer and more uniformly focused lines if you anchor the pivot point for your mirrors at the center height of those mirrors and in line with your laser. An interesting point to note is that a lot of larger home theater projectors use micromirror devices with broad 2D micromirror arrays within, one for each raster pixel art either the intended full resolution or some simple fraction thereof (and then vertical and horizontal servos in the latter case to multiply the apparent pixels); but many pico projectors use a module with just a single micromirror on centered vertical and horizontal pivots. My own limited understanding says that's identical in concept to the galvos in light show projectors and they just use tighter control. It might be fun to see what you can do with that knowledge.
  • @dennisdecoene
    Love this. Also kudo's for explaining your struggles to get this going and for your tenacity.
  • @komojo
    I've seen a few different variations of this type of design, and I actually tried to make my own a few years ago! At one point I used a mini disco ball to get the mirrors. The version I made was wobbly with similar problems to your first prototype but I never took the next step to fix all the issues. I'm impresses that you stuck with it and actually got it working that well. Nice work!