Arduino Painting Machine

// June 10th, 2013 // arduino

Recently I wrote a hack for the Kinect Hacks book (about this). And I could choose a couple of o’reilly books as payment. I wasn’t really interested in programming books, so I took an arduino and some electronics books. They where quite interesting, so I thought would do something with my new knowledge.

I was always interested to remove the perfection from computer graphics. So thought it would be fun to try to make the most obvious thing first. A machine that uses a paint brush to print a drawing.

It runs on an Arduino DUE  and an Android tablet.

I had a Samsung galaxy note 10.1 laying around from a previous project, so i used that one, The nice thing about that tablet is that it comes with a pen with pressure sensitive input. So I could translate the pen pressure to the brush height/size on my machine for more interesting brush strokes.


A poor video of the machine in action:

Its far from perfect, I made a lot of mistakes . But since almost everything I’ve done for this project was a first time, I’m still happy with the result :)

Physical Setup

I only have some basic tools. A drill, a jigsaw and a grinder machine and a couple of wrenches. So I improvised a constructions with bolds and nuts that I could adjust as needed. But I learned that precision really is a thing in mechanics so next time I think I’ll have to extend my tool-set, (and make a plan before I start ;) )

For the arduino/electronics part the basic is just some stepper motor drivers (big easy driver) , stepper motors and a servo motor .
Because it was running from an Android tablet, a had to add some displays for debugging, anyway this is the setup I use now:

The same thing in real life:

Some Code stuff

Arduino

the Arduino is really a fun tool and actually quite easy. You write classes for it in basic c++ (no std etc.).
But almost all existing libraries for Arduino use delay() (a sleep that pauses the main and only thread). I don’t get why they work that way, sure It’s easy for quick testing, but it makes it impossible to do multiple things at once (like adjusting the brush height while moving the brush in my case)

So I had to write everything myself, the stepper driver, servo driver  and display drivers. so they worked on timesteps instead of sleeps.

Something like this in the main loop:

unsigned long timeCurrent=micros();
unsigned long timeElapsed=timeCurrent-timePreviuos;
timePreviuos =timeCurrent;
 
servo.updateTime(timeElapsed);
stepper.updateTime(timeElapsed);
pauze.updateTime(timeElapsed);
display.updateTime(timeElapsed);
ledDisplay.updateTime(timeElapsed);

And for example in the servo class:

void Servo::updateTime(unsigned long timeStep)
{
  currentTime+=timeStep;
 
  if(isLow)
  {
    if(currentTime>=waitLow)
    {
      currentTime=0;
      isLow =false;
      digitalWrite(_pin, HIGH); 
 
    }
  }
  else
  {
    if(currentTime>=  waitHigh)
    {
      currentTime=0;
      isLow =true;
      digitalWrite(_pin, LOW);
    }
  }
 
}

The Android-Arduino communication

The android connection to the arduino whas quite annoing. I used the naive android USB host, but unlike a regular computer, you don’t have a driver for the arduino.
So you have to handle the USB connection yourself (send controle bytes etc) and since it took me so long to get it working: a small example (not sure if this is the best way to do it…)

To make the connection:

View.OnClickListener tryConnect = new View.OnClickListener()
{
	public void onClick(View v)
	{
		manager = (UsbManager) getSystemService(Context.USB_SERVICE);
		HashMap deviceList = manager.getDeviceList();
		Iterator deviceIterator = deviceList.values().iterator();
		while (deviceIterator.hasNext())
		{
			UsbDevice device = deviceIterator.next();
			manager.requestPermission(device, mPermissionIntent);
		}
	}
};
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver()
{
	public void onReceive(Context context, Intent intent)
	{
		String action = intent.getAction();
		if (ACTION_USB_PERMISSION.equals(action))
		{
			synchronized (this)
			{
				device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
 
				if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false))
				{
					if (device != null)
					{
						connection = manager.openDevice(device);
						connection.controlTransfer(0x21, 34, 0, 0, null, 0,0);
						connection.controlTransfer(0x21, 32, 0, 0,new byte[] { (byte) 0x80, 0x25, 0x00, 0x00,0x00, 0x00, 0x08 }, 7, 0);
 
						UsbInterface usbIf = device.getInterface(1);
						for (int i = 0; i < usbIf.getEndpointCount(); i++)
						{
							if (usbIf.getEndpoint(i).getType() == UsbConstants.USB_ENDPOINT_XFER_BULK)
							{
								if (usbIf.getEndpoint(i).getDirection() == UsbConstants.USB_DIR_IN)
									epIN = usbIf.getEndpoint(i);
								else
									epOUT = usbIf.getEndpoint(i);
							}
						}
						if (epIN == null)
						{
							//fail
						}
					}
				} else
				{
					//permision denide
				}
			}
		}
	}
};

After that, I used an asynctask to send bytes to the arduino and wait for the response (when the command is finished, and android can send a new one)

connection.bulkTransfer(epOUT, new byte[] { (byte) command,servoValue,val1B256,val1B1,val2B256,val2B1,speedByte,0}, 8, 0);
new WaitForResult().execute();
 
private class WaitForResult extends AsyncTask;
{
protected String doInBackground(byte[]... params)
{
 
    String s2 = "0";
    int len = 0;
    while (len <= 0)
    {
        len = connection.bulkTransfer(epIN, buffer, 40, 5000);
        s2 = new String(buffer);
        try
        {
            Thread.sleep(5);
        }  catch (InterruptedException ie){}
    }
    return s2;
  }
  protected void onPostExecute(String result)
  {
    setResult(result);
  }
}

The full source code: (this is no production code, just some proof of concept crappy code):
https://github.com/neuroprod/npPaintingMachine

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)

11 Responses to “Arduino Painting Machine”

  1. [...] Temmerman, a freelance creative developer based in Belgium, just published a nice report on how he built a painting machine running on an Arduino Due and an Android tablet. I was always [...]

  2. tuffer weidner says:

    tell me where did you get the belts for this

  3. [...] information about the Arduino Painting Machine can be found here on Neuro Productions. Share this:TwitterFacebookLinkedInGoogle +1EmailTumblrPinterestLike this:Like Loading… This [...]

  4. [...] height/size on my machine for more interesting brush strokes. en bewegende beelden bronnen: project van Kris Temmerman Github code [...]

  5. [...] Kris Temmerman, a freelance creative developer based in Belgium, published a nice report on how he built a painting machine running on an Arduino Due and an Android tablet. [...]

  6. [...] Kris Temmerman, the creator, shares his schematics and code on his website. [...]

  7. Bajdi says:

    Schitterend project :)

  8. [...] Arduino Blog » Blog Archive » A painting machine sensing your touch says: June 11, 2013 at 7:51 am [...]

  9. a chris says:

    This is brilliant; my favourite Arduino project yet. It’s very cool that you included pressure sensitivity. This project really makes me smile!

Leave a Reply