mapamok with Arduino walkthrough

kylemcdonald edited this page Apr 4, 2013 · 2 revisions

by Cyril Diagne - @kikko_fr

Hello everyone,

This step through will try to guide you through this little experiment made with Mapamok, a 3D printer and a Stepper motor.

Here is a video of the experiment :

Mapamok + Stepper motor experiment

The main idea of this experiment is to link a physical movement of the scene to the projected scene in Mapamok, so that the projection sticks properly to the objects. Because of its clever calibration routine (using a 3D model), Mapamok is probably the ideal software for projection mapping on 3D printed objects.

In this experiment we create a projection mapping interactive turntable for 3D prints (yickes!)

/!\ If you are new to Mapamok, make sure to checkout [this excellent intro guide to Mapamok] (\)) first /!\

List of the equipment needed :

List of the software / dependencies

The setup

The object

The (only) tricky part of this experiment is to find a way to properly align the object on the plate so that it rotates around it's origin on the Y axis.

By default our 3d model is going to rotate around it's Y axis in Mapamok. So we need to make sure that the center of the plate is aligned to the X and Z center of the object. However, we won't necessarily have visual hints on the object of where exactly its X and Z origin is. So we need to create visual guide that will help us place precisely the object on the plate

To do that, the quickest / easiest way I've found so far is to open the DAE file in photoshop and outline the model's base and the X and Z axis.


Then you must print the resulting "blueprint" with correct dimensions / scale. When done, you can pierce a tiny hole where both axis cross on the printed blueprint, to help you align it to the axis of the motor and tape it to the plate. And voilà!

guide photo

Now you have a visual guide so that you can quickly put the object on the plate and make sure the object match it's printed base, being sure that the point of rotation is correct!

The electronics

Thanks to the EasyDriver The electronics is really simple, just double check that you've connected :

  • the pin 10 of the arduino to the DIR pin of the driver
  • the pin 11 of the arduino to the STEP pin of the driver.

(Or if you want to change these pin, just remember to update the arduino sketch)

Firmware installation :

  1. Mare sure you have a recent version (min 1.0) of Arduino
  2. Install these 2 Arduino librairies Streaming.h and SerialCommand.h
  3. Upload this arduino sketch to your arduino board

The software

Installation :

  1. Make sure you have a recent version (min 0071) of openFrameworks
  2. Checkout ProCamToolkit
  3. Add the ofxSerialLink addon to your openFrameworks/addons folder
  4. Checkout this fork of Mapamok in your openFrameworks/apps/myApps/ folder
  5. In "MotorControl.cpp" change the line n°17 to match your arduino address (mine is "/dev/tty.usbmodemfd121")
16: void MotorControl::setup() {
17:    bAvailable = serial.setup("/dev/tty.usbmodemfd121");
18:    ofAddListener(serial.SerialLinkEvent, this, &MotorControl::serialLinkEventHandler);
19: }

When everything is plugged in and ready, you can run the app and calibrate the projection according to Mapamok's guide.

To rotate the motor, simply adjust the slider in the second tab of the control panel : Mapamok control panel

Code explanation :

The only modification made to Mapamok's code (the CameraColorSampler class can be ignored / removed) is the addition of a MotorControl class. This class allows us to send commands to the arduino, and receive updates of the motor rotation from the arduino.

Indeed, to make sure our projection properly sticks to the rotating objects, we must wait for the arduino to report a successful mechanical rotation of the stepper before updating our projection. So the flow goes like this :

  1. User input asks for a new rotation speed X : (MotorControl.cpp)
void MotorControl::panelValueChanged(guiCallbackData& data) {
    string name = data.getXmlName();
    if(name=="motor_speed") setSpeed( getf("motor_speed") );
void MotorControl::setSpeed(int speed) {
    serial.addCommand("S", ofToString(speed));
  1. The arduino updates the rotation of the motor by a few microsteps per arduino update : (mapamokStepper.ino)
void loop() { 


  if(speed < 0.0001) return;

  digitalWrite(DIR_PIN, HIGH);

  float deg = 0.51;
  int steps = abs(deg)*(1.0/0.225);
  float usDelay = (1/speed) * 70;

  for(int i=0; i < steps; i++){
    digitalWrite(STEP_PIN, HIGH);
    digitalWrite(STEP_PIN, LOW);

    rotation += 0.225;
  1. Every software update, we send the command "R" to get a feedback of the rotation that comes in as a SerialLinkEvent : (MotorControl.cpp)
void MotorControl::update() {

    if(!bAvailable) return;

    serial.addCommand("R", "");
void MotorControl::serialLinkEventHandler(SerialLinkEventArgs& e) {

    switch (e.event) {
        case VAL_CHANGED: {
            rotation = atoi(e.args[0].c_str());
        } break;