Step 21: 3D - Follow the Bouncing Ball (this includes Firmata)

Here is the 3D bouncing ball Processing  and Adruino code.

This will run X,Y,Z stepper motors.

The Arduino code follows, this is the  code from Step 13 with the Z axis added.

///////////////////////////////PROCESSING /////////////////////////////

 /////////////////// *********PROCESSING with FIRMATA*********

 * Bounce_3D_0
 * When the shape hits a boundry it reverses its direction.
 There are X,Y, Z bounds
 Direction is outputed -
     Processsing -> Firmata -> Arduino -> Drivers -> Steppers
 *Modified for 3D
 NOTE:  0,0,0   - top left corner (facing the computer monitor)
        negative Z axis points 'into' the computer monitor
        positive Y axis points down
        positive X axis points to the right
 import processing.serial.*;
import cc.arduino.*;

Arduino arduino;

//Serial myPort;  // Create object from Serial class
      // Data received from the serial port
int ledPin = 13;
int XstepPin = 10;
int XdirPin = 7;
int YstepPin = 2;
int YdirPin = 3;
int ZstepPin = 19;
int ZdirPin = 18;
int size = 40;       // Width of the shape
float xpos, ypos, zpos;    // Starting position of shape  
float depth;

float xspeed = 2.5;  // Speed of the shape
float yspeed = 2;  // Speed of the shape
float zspeed = 3;

int xdirection = 1;  // Left or Right
int ydirection = 1;  // Top to Bottom
int zdirection = 1;  //front or back

void setup()
  size(200, 200, P3D);
  // Set the starting position of the shape
  xpos = width/2;
  ypos = height/2;
  zpos = -height/2; //note that Zaxis goes 'into' the screen
  depth = -height;
    //setup communication with Arduino
  arduino = new Arduino(this, Arduino.list()[0], 57600); // v1
  arduino.pinMode(ledPin, Arduino.OUTPUT);
  arduino.pinMode(XstepPin, Arduino.OUTPUT);
  arduino.pinMode(XdirPin, Arduino.OUTPUT);
  arduino.pinMode(YstepPin, Arduino.OUTPUT);
  arduino.pinMode(YdirPin, Arduino.OUTPUT);
  arduino.pinMode(ZstepPin, Arduino.OUTPUT);
  arduino.pinMode(ZdirPin, Arduino.OUTPUT);

void draw()

//glass box                  //note: line(x1, y1, z1, x2, y2, z2)
line(0,0,depth,  width,0,depth);           
line(0,height,depth,  width,height,depth);
line(0,0,depth,  0,height,depth);
line(width,0,depth,  width,height,depth);
line(0,0,0,  0,0,depth);
line(0,height,0, 0,height,depth);
line(width,0,0,  width,0,depth);
line(width,height,0,  width,height,depth);

  // Update the position of the shape
  xpos = xpos + ( xspeed * xdirection );
  ypos = ypos + ( yspeed * ydirection );
  zpos = zpos + ( zspeed * zdirection );
  // Test to see if the shape exceeds the boundaries of the screen
  // If it does, reverse its direction by multiplying by -1
  if (xpos > width-size || xpos < 0) {
    xdirection *= -1;
  if (ypos > height-size || ypos < 0) {
    ydirection *= -1;
  if (zpos < -height-size || zpos > 0) {  //note that Zaxis goes 'into' the screen
    zdirection *= -1;

  // Draw the shape

translate(xpos, ypos, zpos);


    //  X
  if (xdirection >= 0){
    arduino.digitalWrite(ledPin, Arduino.HIGH);             
    arduino.digitalWrite(XdirPin, Arduino.HIGH);
    arduino.digitalWrite(ZdirPin, Arduino.HIGH);
        arduino.digitalWrite(ledPin, Arduino.LOW);             
        arduino.digitalWrite(XdirPin, Arduino.LOW);
        arduino.digitalWrite(ZdirPin, Arduino.LOW);

     //  Y 
  if (ydirection >= 0){              
    arduino.digitalWrite(YdirPin, Arduino.HIGH);
        arduino.digitalWrite(YdirPin, Arduino.LOW);
     //  Z   
if (zdirection >= 0){             
    arduino.digitalWrite(ZdirPin, Arduino.HIGH);
        arduino.digitalWrite(ZdirPin, Arduino.LOW);


// Wiring/Arduino code:// simmple digital firmata
  //Supports as many digital inputs and outputs as possible.

  //This example code is in the public domain.


#define XstepPin 10
#define XdirPin 7

#define YstepPin 2
#define YdirPin 3

#define ZstepPin 19
#define ZdirPin  18

byte previousPIN[2];  // PIN means PORT for input
byte previousPORT[2];

void outputPort(byte portNumber, byte portValue)
// only send the data when it changes, otherwise you get too many messages!
    if(previousPIN[portNumber] != portValue) {
        Firmata.sendDigitalPort(portNumber, portValue);
        previousPIN[portNumber] = portValue;
        Firmata.sendDigitalPort(portNumber, portValue);

void setPinModeCallback(byte pin, int mode) {
    if(pin > 1) { // don't touch RxTx pins (0,1)
        pinMode(pin, mode);

void digitalWriteCallback(byte port, int value)
    byte i;
    byte currentPinValue, previousPinValue;

    if(value != previousPORT[port]) {
        for(i=0; i<8; i++) {
            currentPinValue = (byte) value & (1 << i);
            previousPinValue = previousPORT[port] & (1 << i);
            if(currentPinValue != previousPinValue) {
                digitalWrite(i + (port*8), currentPinValue);
        previousPORT[port] = value;

void setup()
    Firmata.setFirmwareVersion(0, 1);
    Firmata.attach(DIGITAL_MESSAGE, digitalWriteCallback);
    Firmata.attach(SET_PIN_MODE, setPinModeCallback);

void loop()
    outputPort(0, PIND &~ B00000011); // pins 0-7, ignoring Rx/Tx pins (0/1)
    outputPort(1, PINB); // pins 8-13
    while(Firmata.available()) {

//added stepper sequence to firmata code
digitalWrite(XstepPin,HIGH);    //take steps
delayMicroseconds(1000); //  <<<<<< USE TO CHANGE STEPPER SPEED???? <<<<<<<<



<br>If anybody wants to buy this, let me know. <br> <br>-Marc <br> <br>
<p>You're a genius! Very nicely done!</p>
For how much?
I'd have to say $200 for the mechanical structure - Or $600 for the full set- up, there is quite a bit of hardware involved. <br> <br>You may be better off with something from Makerbot, it debends what you have planned.
Excellent work and progress!!! I&nbsp;think I&nbsp;read your instuctable a year ago, and you just add your progress to the same instructable?<br /> <br /> I&nbsp;just want to clarify something... You have ONE arduino with a ATMega168 controlling 3 steppers and the extruder?&nbsp;<br />
<em>&nbsp;You have ONE arduino with a ATMega168 controlling 3 steppers and the extruder?</em><br /> <br /> Nope - I tried that, but I ended up using two &nbsp;Arduinos. &nbsp;One to control the X,Y,Z steppers and the other to control the 4th stepper on the extruder.<br /> <br /> Thanks for your kind comments!<br /> <br /> -Marc<br />
Thanks that helps a lot! <br /> Which firmware did you use?&nbsp;I am using this:&nbsp;<br /> http://sourceforge.net/projects/reprap/files/Arduino%20Firmware/v1.3<br /> <br /> Thanks
<em>Which firmware did you use? I am using this: http://sourceforge.net/projects/reprap/files/Arduino%20Firmware/v1.3</em><br> <br> Hi OuZo -&nbsp;<br> <br> I've been offline for a bit, so I am replying almost 2 months late!<br> <br> I do&nbsp;believe&nbsp;that is the firmware I used, I found it&nbsp;necessary&nbsp;to&nbsp;disable&nbsp;all the&nbsp;end-stops.&nbsp;<br> <br> Also -&nbsp;<br> For the extruder I used a stepper motor controlled by it's own Arduino. &nbsp;The RepRap code was meant for a DC motor controlled by a PWM driver. &nbsp;I simply wired the PWM output from the Master Arduino an input on the Slave Arduino. &nbsp;Whenever the slave saw anything on this input it would turn on the stepper motor. &nbsp;I did not adjust the speed at all, but you certainly could.<br> <br> If the code would be useful for you, I could dig it up. &nbsp;It is not on the machine I am currently using.<br> <br> I hope you are having great success!<br> <br> -Thanks,<br> Marc<br> <br> <br>
There is a book coming out from the creators of Processing - <br /> <br /> Getting started with Procssing<small><big> <span> ~ </span></big></small><span><span class="contributorNameTrigger"><a href="http://www.amazon.com/Casey-Reas/e/B001JRWKOC/ref=ntt_athr_dp_pel_1" rel="nofollow"><small><big>Casey Reas</big></small></a></span><small><span class="contributorNameTrigger" /><big> </big></small> <div class="buying" id="contributorContainer1" style="margin: 0.0pt;padding: 0.0pt;display: none;"> <div style="float: left;"> <div><small><big><b class="h3color">Casey Reas</b> (Author) </big></small></div> <div><small><big><b class="h3color">&rsaquo;</b> </big></small><a href="http://www.amazon.com/Casey-Reas/e/B001JRWKOC/ref=ntt_athr_dp_pel_pop_1" rel="nofollow"><small><big> Visit Amazon's Casey Reas Page</big></small></a></div> <div style="margin: 1.0px 0.0pt 0.0pt 1.0em;"><small><big><span>Find all the books, read about the author, and more.</span></big></small></div> <div class="tiny" style="margin: 10.0px 0.0pt 0.0pt;"><small><big> See </big></small><a href="http://www.amazon.com/s/ref=ntt_athr_dp_sr_pop_1?_encoding=UTF8&amp;sort=relevancerank&amp;search-alias=books&amp;field-author=Casey%20Reas" rel="nofollow"><small><big>search results</big></small></a><small><big> for this author </big></small></div> <div class="tiny" style="margin: 2.0px 0.0pt 0.0pt;"><small><big>Are you an author? </big></small><a href="http://authorcentral.amazon.com/gp/landing/ref=ntt_atc_dp_pel_1" rel="nofollow"><small><big> Learn about Author Central</big></small></a></div> </div> </div> <small><big> (Author), </big></small><a href="http://www.amazon.com/s/ref=ntt_athr_dp_sr_2?_encoding=UTF8&amp;sort=relevancerank&amp;search-alias=books&amp;field-author=Ben%20Fry" rel="nofollow"><small><big>Ben Fry</big></small></a></span><small><big><span> (Author) </span></big></small><br /> <br /> http://www.amazon.com/Getting-Started-Processing-Casey-Reas/dp/144937980X/ref=sr_1_7?ie=UTF8&amp;s=books&amp;qid=1273194179&amp;sr=8-7<br /> <br /> <br />
&nbsp;How does a processing code works?
If you want to write code to make stuff - check out<br /> <br /> <a href="http://openscad.org/" rel="nofollow">http://openscad.org/</a><br /> <br />
PLA filament is available here:<br /> <br /> <a href="https://ultimachine.com/" rel="nofollow">https://ultimachine.com/</a><br /> <br />
MAKERBOT&nbsp;FTW!<br />
Yes - I should have included a makerbot link<br /> <br /> <a href="http://www.makerbot.com/" rel="nofollow">http://www.makerbot.com/</a><br /> <br /> -Marc
need&nbsp; processing-arduino library for this step to work<br /> <br /> <a href="http://www.arduino.cc/playground/Interfacing/Processing" rel="nofollow">http://www.arduino.cc/playground/Interfacing/Processing</a>
It draws things! (?) Good job!
Yup!<br />
congratulations, this is an authentic science homemade lab!, the great innovations starts on sites like yours, go ahead, and we will follow closely your advances, great work!!!.......<br />
I'm not sure why you are going to all the trouble of writing such basic firmware and/or processing code when you can use the tried-and-tested firmware from the reprap project, with full support for G-Codes!.&nbsp;&nbsp; see http://objects.reprap.org/wiki/Getting_Started_with_the_Arduino_GCode_Firmware&nbsp; you can then have your repstrap draw anything that you want with a STL file, or any format that can be converted to GCode instructions.&nbsp;&nbsp; <br />
<em> <div><span style="font-size: 9.0pt;">Good point!&nbsp;&nbsp;&nbsp;</span></div> <div><span style="font-size: 9.0pt;">The RepRap project is inspirational and fantastic.&nbsp; But I have been having some&nbsp;trouble running their Firmware and Host Software.&nbsp; &nbsp;I&nbsp;decided that in the short term, I would&nbsp;rather work&nbsp;on some basic functionality then wrangle with the complete RepRap toolchain.<br /> <br /> Also &nbsp;-</span></div> <div><span style="font-size: 9.0pt;">Drawing on a piece of paper with a marker doesn't serve much of a purpose.&nbsp; But it shows that the system is working.&nbsp; <br /> <br /> So what is next? <br /> I haven't decided if&nbsp;I will move forward with the development I've documented in this Instructable, or go back to using existing RepRap code.&nbsp; I am not an experienced programmer, so I may continue on this path to gain some understanding.<br /> <br /> Also - <br /> I think there is a tremendous potential for crossover between the RepRap project and Instructables.&nbsp; I'm hoping that this will draw more people to the RepRap webpage <a href="http://reprap.org/bin/view/Main/WebHome"><font color="#800080">http://reprap.org/</font></a>&nbsp;.&nbsp; Imagine if there were 50,000 hobbyists working on this?<br /> <br /> Thanks again - <br /> Your question made me&nbsp;think!<br /> -Marc</span></div> </em>
Hi, I'm watching your instructable with much interest. Is very good for learning the principles. Look also here:<br /> <a href="http://www.sensi.org/~svo/motori/" rel="nofollow">Motori the plotter</a> - maybe you will find good ideas there.<br /> <br /> Vasi<br />
Thanks Vasi - I&nbsp;am glad you have found this useful!<br /> -Marc
A friend of mine is working with the XMEGA.&nbsp; This would be an awsome micro for projects like this.&nbsp; His dev board is here: http://cgi.ebay.com/Atmel-AVR-XMEGA-ATXMEGA-Development-Evaluation-Board_W0QQitemZ260488815978QQcmdZViewItemQQptZLH_DefaultDomain_0?hash=item3ca657e56a<br /><br />
Thanks for mentioning my humble little board! I'm working on an instructable for it. I'll probably need your help navigating the site and making it as AWESOME&nbsp;as all of yours. ;-)<br />
No problem - although it might not help much.<br /> <br /> Your webpage suggests you are planning to build a girl robot to take to the prom (although I didn't read any of the text).&nbsp; &nbsp;<a href="http://www.bostonandroid.com/">http://www.bostonandroid.com/</a>&nbsp;<br /> <br /> Also - Congrats on the new baby!!!<br /> <br />

About This Instructable


94 favorites


Bio: Married to Domestic_Engineer (but I call her Meghan).
More by marc.cryan: Cheapest, Bestest computer around, in beginning of 2015 Cryan Family Gothic Green House Small e-reader with oled + arduino, test
Add instructable to: