Learn. Create. Enjoy.
Learn how to assemble the Rocket Launcher add-on for Stackr and control it with an RC transmitter and receiver—required for this project. Drive Stackr with the main sticks and use dedicated buttons to reset, fire, and adjust the launcher servo.
The easiest way to assemble the Rocket Launcher is by following the instructions in the video below.
An RC controller is required. Channels 1 and 2 drive Stackr (see the RC control tutorial). Channel 3 resets the launcher, channel 5 runs an automatic four-step fire sequence, and channel 4 steps the servo manually by 45°.
#include <SparkFun_TB6612.h>
#include <ESP32Servo.h>
#define AIN1 D5
#define BIN1 D6
#define AIN2 D4
#define BIN2 D7
#define PWMA D3
#define PWMB D8
#define STBY D2
#define CH1_LR A0
#define CH2_FWD A1
#define CH3_TPBTTN A2
#define CH5_LFTBTTN A6
#define CH4_BTMBTTN A3
Servo servo1;
const int fwdDirectionA = 1;
const int fwdDirectionB = 1;
Motor motor1 = Motor(AIN1, AIN2, PWMA, fwdDirectionA, STBY);
Motor motor2 = Motor(BIN1, BIN2, PWMB, fwdDirectionB, STBY);
int angle1 = 0;
long hori_pulse = 0;
long vert_pulse = 0;
long top_pulse = 0;
long left_pulse = 0;
long bottom_pulse = 0;
long cur_top_pulse = 0;
long cur_left_pulse = 0;
long cur_bottom_pulse = 0;
bool launcherFiring = false;
unsigned long Timer = 0;
int servoSteps = 0;
boolean valueCheck(long signal_length) {
if (signal_length >= 999 && signal_length <= 2000) {
return true;
} else {
return false;
}
}
void setup()
{
Serial.begin(115200);
ESP32PWM::allocateTimer(0);
ESP32PWM::allocateTimer(1);
ESP32PWM::allocateTimer(2);
ESP32PWM::allocateTimer(3);
servo1.setPeriodHertz(50);
servo1.attach(D10);
servo1.write(angle1);
pinMode(CH1_LR, INPUT_PULLUP);
pinMode(CH2_FWD, INPUT_PULLUP);
pinMode(CH3_TPBTTN, INPUT_PULLUP);
pinMode(CH5_LFTBTTN, INPUT_PULLUP);
pinMode(CH4_BTMBTTN, INPUT_PULLUP);
motor1.brake();
motor2.brake();
}
void loop()
{
hori_pulse = pulseIn(CH1_LR, HIGH, 25000);
vert_pulse = pulseIn(CH2_FWD, HIGH, 25000);
cur_top_pulse = pulseIn(CH3_TPBTTN, HIGH, 25000);
cur_left_pulse = pulseIn(CH5_LFTBTTN, HIGH, 25000);
cur_bottom_pulse = pulseIn(CH4_BTMBTTN, HIGH, 25000);
Serial.print(cur_top_pulse);
Serial.print(" ");
Serial.print(cur_left_pulse);
Serial.print(" ");
Serial.print(cur_bottom_pulse);
Serial.print(" ");
Serial.println(angle1);
if (abs(cur_top_pulse - top_pulse) > 500 && valueCheck(cur_top_pulse)) {
angle1 = 0;
servo1.write(angle1);
launcherFiring = false;
} else if (abs(cur_left_pulse - left_pulse) > 500 && valueCheck(cur_left_pulse) && !launcherFiring) {
launcherFiring = true;
Timer = millis();
servoSteps = 0;
} else if (abs(cur_bottom_pulse - bottom_pulse) > 500 && valueCheck(cur_bottom_pulse)) {
angle1 += 45;
angle1 = constrain(angle1, 0, 180);
servo1.write(angle1);
}
top_pulse = cur_top_pulse;
left_pulse = cur_left_pulse;
bottom_pulse = cur_bottom_pulse;
if (valueCheck(hori_pulse) && valueCheck(vert_pulse)) {
int speed = map(vert_pulse, 999, 2000, -255, 255);
int direction = map(hori_pulse, 999, 2000, -255, 255);
int left_speed = constrain(speed + direction, -255, 255);
int right_speed = constrain(speed - direction, -255, 255);
motor1.drive(right_speed);
motor2.drive(left_speed);
}
if (launcherFiring) {
if (millis() - Timer >= 500) {
Timer += 500;
angle1 += 45;
angle1 = constrain(angle1, 0, 180);
servo1.write(angle1);
servoSteps++;
if (servoSteps >= 4) {
launcherFiring = false;
}
}
}
}
RC required: Connect an RC receiver to Stackr. Button channels are detected when the pulse changes by more than 500 µs from the last reading.
Differential drive: Channels 1 and 2 control forward/back and left/right, same as other Stackr RC sketches.
int speed = map(vert_pulse, 999, 2000, -255, 255);
int direction = map(hori_pulse, 999, 2000, -255, 255);
motor1.drive(right_speed);
motor2.drive(left_speed);Channel 3 (top) — Reset: Sets the launcher servo to 0° and cancels any fire sequence in progress.
Channel 5 (left) — Auto fire: Starts launcherFiring. Every 500 ms the servo moves +45° until four steps complete (four barrel positions).
if (launcherFiring) {
if (millis() - Timer >= 500) {
angle1 += 45;
servo1.write(angle1);
servoSteps++;
if (servoSteps >= 4) {
launcherFiring = false;
}
}
}Channel 4 (bottom) — Manual step: Each button press adds 45° to the servo angle (capped at 180°).
Serial Monitor: Pulse values and angle1 print each loop to help you verify RC wiring and channel mapping.
Install SparkFun TB6612 and ESP32Servo from the Arduino Library Manager. You also need an RC transmitter and receiver mapped to the channels in the sketch.