Search models, users, collections, and posts

Mini Moving Head Projector

Print Profile(2)

All
A1
H2S
P2S
X1
X1 Carbon
H2D
P1S
P1P
X1E
H2D Pro
H2C
X2D
A2L
A1 mini

0.2mm layer, 2 walls, 15% infill
0.2mm layer, 2 walls, 15% infill
6.4 h
4 plates
4.0(1)

A1 mini version
A1 mini version
5.4 h
4 plates

Open in Bambu Studio
Boost
44
107
3
1
83
22
Released 

Description

Content has been automatically translated.
Show original

Here is a functional mini moving head projector. Everything works thanks to 2 servo motors controlled by a joystick, and for the light, it is a simple RGB LED that changes color using the joystick button

If you have any questions, feel free to leave a comment, I will answer them as quickly as possible

I plan to release a tutorial video soon (like for the LED panel) so to not miss its release, it's this way 👉 https://www.youtube.com/@Tim_bricolage

Here is the tutorial video: https://youtu.be/61YztvEllS4

It supports me and makes me want to release more projects

For printing, 15% infill is sufficient, 0.2mm layer height. All models require supports

Required materials:

-2 tips (white crosses)

-2 100 Ω resistors (for the green and blue LED)

-1 220 Ω resistor (for the red LED)

-1 RGB LED

-1 joystick

-2 servo motors

-1 Arduino breadboard

-1 Arduino board (Mega 2560)

-Cables

For wiring:

There are 2 types of RGB LEDs, one with the longest pin that must be connected to 5V (like mine) and the second type must be connected to GND. So check

Once the connections are done, it looks like this:

For the program to copy and paste into Arduino IDE:

#include <Servo.h>


 

Servo servoBase;

Servo servoTilt;


 

const int joyXPin = A0;

const int joyYPin = A1;

const int joyBtnPin = 2;


 

const int ledR = 12;

const int ledG = 13;

const int ledB = 11;


 

float angleBase = 90;

float angleTilt = 90;


 

const int deadZone = 50;

const int fullPush = 250; // joystick must exceed ±250 from center

const float maxSpeed = 3; // max servo speed


 

const int colors[][3] = {

  {255, 0, 0},    // Red

  {0, 255, 0},    // Green

  {0, 0, 255},    // Blue

  {255, 255, 0},  // Yellow

  {0, 255, 255},  // Cyan

  {255, 0, 255},  // Magenta

  {255, 255, 255} // White

};

const int colorCount = sizeof(colors) / sizeof(colors[0]);

int currentColor = 0;


 

bool lastButtonState = HIGH;

bool baseActive = false;

bool tiltActive = false;


 

void setup() {

  Serial.begin(9600);


 

  pinMode(joyBtnPin, INPUT_PULLUP);

  pinMode(ledR, OUTPUT);

  pinMode(ledG, OUTPUT);

  pinMode(ledB, OUTPUT);


 

  updateLEDColor();

}


 

void loop() {

  int joyX = analogRead(joyXPin);

  int joyY = analogRead(joyYPin);


 

  int offsetX = joyX - 512;

  int offsetY = joyY - 512;


 

  // --- Servo Base (left/right rotation with threshold) ---

  if (abs(offsetX) > fullPush) {

    if (!baseActive) {

      servoBase.attach(9);

      baseActive = true;

    }


 

    float speedX = map(abs(offsetX), fullPush, 512, 0, maxSpeed);

    if (offsetX < 0) speedX = -speedX;


 

    angleBase += speedX;

    angleBase = constrain(angleBase, 0, 180);

    servoBase.write((int)angleBase);

  } else if (baseActive) {

    servoBase.detach();

    baseActive = false;

  }


 

  // --- Servo Tilt (smooth up/down) ---

  if (abs(offsetY) > deadZone) {

    if (!tiltActive) {

      servoTilt.attach(10);

      tiltActive = true;

    }


 

    float speedY = map(abs(offsetY), deadZone, 512, 0, maxSpeed);

    if (offsetY < 0) speedY = -speedY;


 

    angleTilt += speedY;

    angleTilt = constrain(angleTilt, 0, 180);

    servoTilt.write((int)angleTilt);

  } else if (tiltActive) {

    servoTilt.detach();

    tiltActive = false;

  }


 

  // --- LED color change ---

  bool btnState = digitalRead(joyBtnPin);

  if (lastButtonState == HIGH && btnState == LOW) {

    currentColor = (currentColor + 1) % colorCount;

    updateLEDColor();

    Serial.print("Color changed: ");

    Serial.println(currentColor);

    delay(200);

  }

  lastButtonState = btnState;


 

  delay(20);

}


 

void updateLEDColor() {

  analogWrite(ledR, colors[currentColor][0]);

  analogWrite(ledG, colors[currentColor][1]);

  analogWrite(ledB, colors[currentColor][2]);

}


 

Comment & Rating (3)

(0/1000)

License

This user content is licensed under a Standard Digital File License.

You shall not share, sub-license, sell, rent, host, transfer, or distribute in any way the digital or 3D printed versions of this object, nor any other derivative work of this object in its digital or physical format (including - but not limited to - remixes of this object, and hosting on other digital platforms). The objects may not be used without permission in any way whatsoever in which you charge money, or collect fees.