loading
I came across a bunch of stepper motors and I have since been looking for a project to do with the kids.

An old Telecran (French for Etch-a-Sketch) later, we are in business !

What I used for this project:
- an arduino Uno
- 2 stepper motors
- 2 easydrivers v44 (by www.sparkfun.com)
- various Fishertechnik parts (http://www.fischertechnik.com)
- a push button.

Optional parts:
- a sensor shield + 2 push buttons
- a Nintendo Wii Nunchuck
- a WiiChuck adapter

And also:
- hot glue gun

Step 1: Mechanics

The mechanical part has been done with some Fishertechniks parts.

I had to drill into the stepper cogs as the axis of the steppers were 5mm where the FT standard is 4 mm.

The other cogs were simply hot glued onto the Telecran (Etch-a-sketch) knobs.

The rest is best explained in pictures...

Step 2: Steppers

Some details of the motors and the final assembly.

Step 3: Arduino

To drive the steppers I used a couple of easy driver board from Sparkfun.

Very straight forward. Note the emergency button that allows to put the motors to sleep in case of a runaway sketch.

I added a sensor shield to the arduino for convenience as I have a couple of push buttons (with a pull-up resistor) already cabled.

WiiChuck adapter is one of my favorite. Although the Nunchuck is a little more difficult to program than it may first appear.

Step 4: Schematics


Step 5: Code - Sketch

If NUNCHUCK is defined then the code will be compiled with Nunchuck support.
The motors are then controlled exclusively with the Wii Nunchuck.

if NUNCHUCK is not defined, then a pre-defined drawing is executed.
Said drawing is controlled by the 'mode' variable modified at compile time.

This calls for a proper menu, an LCD screen etc... I leave this as an exercise to the reader.

Step 6: Calibration - Backlash

1. backlash

Backlash has been the most annoying part of this project.
It comes from all the mechanical parts involved, the biggest culprit being the Telecran itself.
I finally took backlash into account programmatically and I designed a calibration routine.
Said routine draws a cross several times using various values of backlash.
One can visually decide which value gives the best (most aligned) cross.

In my case 14 is the magic number.


2. nunchuck

When the nunchuck is activated in the code, one can open the serial interface and note the magic numbers for said nunchuck.
Mininum and maximum X and Y.
X and Y values when nunchuck is still.

Nunchuck is active when either 'c' or 'z' is pressed. 'c' is slow, 'w' is fast.

Step 7: Voila

Here are:

- some nunchuck art by one of my kids.

- a sin(x)/x 2D plot.

- a sin(x)/x 3D plot.

- a checker (challenging the backlash algo).

- some 'maisons' (houses in French) teaching programming to my elder : a function, a parameter, a loop...

<p>HI would 12v 4wire stepper need a transistor? 2N2222? I'm keen on making this to control x and y tracks.<br><br>any help would be appreciated :)</p>
Ohh Great Idea, Perfect project for an introduction into CNC. <br><br>Have you tried running G-Code through the Arduino chip onto the Etch-a-Sketch? <br>
<p>I have... just posted: </p><p>https://www.instructables.com/id/Etch-a-Sketch-LOGO-EASiLOGO/</p>
Sounds like a good extension of the project indeed ! <br>I like those arduino projects to be not connected directly to a PC though (otherwise it's cheating, isn't it ? ;-) )<br><br>So I'd probably use a SD card and a LCD to navigate through the G-Code files to print... and I'd support *very* basic G-Code as well !<br><br>A good suggestion for a follow-up Instructable... thanks !
I look forward to seeing it, make sure you post the code when you do it.
<p>We made a similar project for school. Here are some pictures and our sketch is available upon request.</p>
<p>/*******************************************************************************<br> * This is the final project for Instruments &amp; Measurements II - ME-362 *<br> * by Stephen Nyberg and Jacob Oldham *<br> * *<br> * An Etch-A-Sketch is controlled by two stepper motors which are * <br> * controlled using various input sensors. *<br> *******************************************************************************/<br>#include &lt;AccelStepper.h&gt; // This is the library used to control to control the <br> // two stepper motors with the use of two EasyDrivers.<br>/* Stepper motor and EasyDriver hookup.<br> Each stepper motor is connected to an EasyDriver, the &quot;X&quot; is for the horizontal<br> control and the &quot;Y&quot; is for the vertical control. The shaft of the stepper<br> motors are connected to the EAS dial shafts directly. Using a 12 volt power<br> supply at the barrel jack of the Arduino, the Vin from the Arduino supplies the<br> full 12 volts to the EasyDriver. The corresponding step and direction pins are<br> attached to the digital outputs noted below as well as the stopPins are attached<br> to the &quot;SLP&quot; pins of the EasyDrivers. These pins are also attached to a<br> mechanical switch to ground. This allows the current to be bypassed manually or<br> in the code to turn off the motors incase of runaway or during troubleshooting<br> as well as bypass the current from the EasyDrivers when the stepper motors are <br> not moving to keep the EasyDrivers cool. */<br><br>int XdirPin = 7;<br>int XstepPin = 4;<br>int YdirPin = 2;<br>int YstepPin = 5 ;<br>int XstopPin = 12;<br>int YstopPin = 13;<br><br>AccelStepper stepperx(1, XstepPin, XdirPin); // (1) is to dentote that a dirver is used,<br>AccelStepper steppery(1, YstepPin, YdirPin); // followed by the step and direction pins<br><br>/* Wii Nunchuck hookup.<br> The Wii Nunchuck has a 2 axis joy stick, a 3 axis accelerometer and 2 buttons which<br> can communicate to the Arduino with I2C. You can use an adapter or jumpers can be <br> plugged directly into the controller. Here are the pins for the controller:<br> <br> _______<br> | 1 2 3 |<br> | |<br> | 6 5 4 |<br> |_-----_|<br> <br> 1 - (dat) - data ________ to analog pin A4 or SDA<br> 2 - (att) - nothing <br> 3 - (pwr) - 3.3+v _______ to 3.3V power<br> 4 - (clk) - clock _______ to analog pin A5 or SCL<br> 5 - (nc) - nothing<br> 6 - (gnd) - ground ______ to ground<br> <br> Because we are using I2C to communicate with the nunchuck, the Wire.h library needs<br> to be included as well, the ArduinoNunchuck.h library makes getting the data much <br> more easy. <br> <br> The nunchuck part of this code was based on;<br> ArduinoNunchukDemo.ino<br> Copyright 2011-2013 Gabriel Bianconi, http://www.gabrielbianconi.com/<br> Project URL: http://www.gabrielbianconi.com/projects/arduinonunchuk/ <br>*/<br><br>#include &lt;Wire.h&gt; // library for I2C communication<br>#include &lt;ArduinoNunchuk.h&gt; // library to receive data from Wii nunchuck<br>ArduinoNunchuk nunchuk = ArduinoNunchuk(); // creates nunchuck object for the library<br><br>/* Nintendo DS Touch Pad hookup.<br> The touchpad operates similar to two potentiometers, one for the horizontal axis and<br> one for the vertical access, however there are only 4 connections instead <br> of 6 because they are shared meaning the connections have to be switched between <br> inputs and outputs and only one axis can be read at time. The x and y names below <br> are what is called out on the breakout board and are assigned to the corresponding pins <br> they are attached to on the Arduino. The colors in the comments correspond to the <br> color of the cable on the ribbon cable used to easy in connection. */<br><br>int y1 = A2; //red<br>int x2 = A3; //orange<br>int y2 = 3; //yellow<br>int x1 = 8; //green<br><br>/* An RGB LED was used to indicate the current input being used to control the EAS.<br> The common lead is attached to 5 volts the red, blue and green leads are attached <br> to the corresponding pins though a 330 ohm resistor. */<br><br>int RedLED = 9;<br>int GreenLED = 10;<br>int BlueLED = 11;<br><br>/* linear potentiometers are attached between 5 volts and the output to the <br> corresponding analog inputs */<br>int XPotPin = A0;<br>int YPotPin = A1;<br><br>int Xpot, Ypot, x, y, RawX, RawY; // define other variables to be used later in the sketch<br>int Xspeed, Yspeed, step;<br>int cButtonMode = 0;<br><br>void print(){ // This print function aids in trouble shooting and pints the <br> // input mode as well as the speed of each motor<br> Serial.print(cButtonMode);<br> Serial.print('\t');<br> Serial.print(RawX);<br> Serial.print('\t');<br> Serial.print(RawY);<br> Serial.print('\t');<br> Serial.print(Xpot);<br> Serial.print('\t');<br> Serial.print(Ypot);<br> Serial.print('\t');<br> Serial.print(Xspeed);<br> Serial.print('\t');<br> Serial.println(Yspeed);<br> <br> // *** NOTE 1 ***<br> // these two functions are called as often as possible to make the speed of the <br> // steppers quicker and more smooth.<br> stepperx.runSpeed();<br> steppery.runSpeed();<br>}<br><br>void setup(){<br> Serial.begin(9600); // sets the BAUD rate for the serial printing<br> nunchuk.init(); // required for the nunchuck <br> pinMode(XdirPin, OUTPUT);<br> pinMode(XstepPin, OUTPUT);<br> pinMode(YdirPin, OUTPUT);<br> pinMode(YstepPin, OUTPUT);<br> pinMode(RedLED, OUTPUT);<br> pinMode(GreenLED, OUTPUT);<br> pinMode(BlueLED, OUTPUT);<br> pinMode(XstopPin, OUTPUT);<br> pinMode(YstopPin, OUTPUT);<br> stepperx.setMaxSpeed(32000); // Sets the max speed (micro-steps per second) for the stepper motors<br> steppery.setMaxSpeed(32000); // default is 32000<br>}<br><br>void loop(){<br> nunchuk.update(); // comunicates to the nunchuck <br> // see NOTE 1 above<br> stepperx.runSpeed();<br> steppery.runSpeed();<br> stepperx.runSpeed();<br> steppery.runSpeed();<br> <br> /* Selects the mode to control (0 to 3) *****/<br> int mode = nunchuk.cButton; // reads the value of the nunchuck 'C' button<br> if (mode==1){ // If the button pressed, mode will = 1 and <br> cButtonMode = cButtonMode + 1; // cButtonMode will change from 0 to 1 to 2 <br> delay(200); // to 3 and then repeat.<br> if (cButtonMode == 4){<br> cButtonMode = 0;<br> }<br> }<br> // see NOTE 1 above<br> stepperx.runSpeed();<br> steppery.runSpeed();<br> stepperx.runSpeed();<br> steppery.runSpeed();<br> //////////////////////////////////////////////////////////////////////////////<br> if (cButtonMode == 0){ // Linear potentiometers<br> // see NOTE 1 above<br> stepperx.runSpeed();<br> steppery.runSpeed();<br> // The LED will be green when the linear potentiometers are controlling.<br> analogWrite(RedLED, 0);<br> analogWrite(GreenLED, 80);<br> analogWrite(BlueLED, 0);<br> RawX = analogRead(XPotPin);<br> RawY = analogRead(YPotPin);<br> // The raw values from the pots are mapped from -6 to 6<br> Xpot = map(analogRead(XPotPin),3,1023,-6,6);<br> Ypot = map(analogRead(YPotPin),3,1023,-6,6);<br> // The maped values are sent to a function that sets the speed and direction of the steppers<br> speedDir(Xpot,Ypot);<br> // see NOTE 1 above<br> stepperx.runSpeed();<br> steppery.runSpeed();<br> stepperx.runSpeed();<br> steppery.runSpeed();<br> }<br> //////////////////////////////////////////////////////////////////////////////<br> if (cButtonMode == 1){ // DS touch pad<br> // see NOTE 1 above<br> stepperx.runSpeed();<br> steppery.runSpeed();<br> // The LED will be blue when the touch pad is controlling.<br> analogWrite(RedLED, 0);<br> analogWrite(GreenLED, 0);<br> analogWrite(BlueLED, 100);<br> RawX = readX();<br> RawY = readY();<br> // When the touch pad is not being touched, the reading goes to 1023<br> // The X and Y also have to be read separately. The following if/else <br> // statements map usable range of the touchpad from -3 to 3 and multiply<br> // that value by 2 to match -6 to 6 of the other sensors but with lower <br> // resolution steps making control better.<br> if (readY() &gt; 955){<br> Ypot = 0;<br> }<br> else{<br> Ypot = 2*map(readY(),160,735,3,-3);<br> }<br> if (readX()&gt;955){<br> Xpot = 0;<br> }<br> else{<br> Xpot = 2*map(readX(),135,860,-3,3);<br> }<br> // The mapped values are sent to a function that sets the speed and direction of the steppers<br> speedDir(Xpot,Ypot);<br> // see NOTE 1 above<br> stepperx.runSpeed();<br> steppery.runSpeed();<br> stepperx.runSpeed();<br> steppery.runSpeed();<br> }<br> //////////////////////////////////////////////////////////////////////////////<br> if (cButtonMode == 2){ // Wii joy stick<br> // see NOTE 1 above<br> stepperx.runSpeed();<br> steppery.runSpeed();<br> // The LED will be white-ish when the joy stick is controlling.<br> analogWrite(RedLED, 40);<br> analogWrite(GreenLED, 20);<br> analogWrite(BlueLED, 50);<br> RawX = nunchuk.analogX;<br> RawY = nunchuk.analogY;<br> // The raw values from the joy stick are mapped from -6 to 6<br> Xpot = map(nunchuk.analogX,19,218,-6,6); // default (19,218)<br> Ypot = map(nunchuk.analogY,30,220,-6,6); // default (30,220)<br> // The mapped values are sent to a function that sets the speed and direction of the steppers<br> speedDir(Xpot,Ypot);<br> // see NOTE 1 above<br> stepperx.runSpeed();<br> steppery.runSpeed();<br> stepperx.runSpeed();<br> steppery.runSpeed();<br> }<br> //////////////////////////////////////////////////////////////////////////////<br> if (cButtonMode == 3){// Wii accelerometer<br> // see NOTE 1 above<br> stepperx.runSpeed();<br> steppery.runSpeed();<br> // The LED will be red when the accelerometer is controlling.<br> analogWrite(RedLED, 100);<br> analogWrite(GreenLED, 0);<br> analogWrite(BlueLED, 0);<br> RawX = nunchuk.accelX;<br> RawY = nunchuk.accelY;<br> // The raw values from the accelerometer are mapped from -6 to 6<br> Xpot = map(nunchuk.accelX,297,690,-6,6); // default (297,700)<br> Ypot = map(nunchuk.accelY,294,690,-6,6); // default (294,695)<br> // The mapped values are sent to a function that sets the speed and direction of the steppers<br> speedDir(Xpot,Ypot);<br> // see NOTE 1 above<br> stepperx.runSpeed();<br> steppery.runSpeed();<br> stepperx.runSpeed();<br> steppery.runSpeed();<br> }<br> // see NOTE 1 above<br> stepperx.runSpeed();<br> steppery.runSpeed();<br> stepperx.runSpeed();<br> steppery.runSpeed();<br> print(); // calls the print function serial printing data<br>}<br><br>void speedDir(int Xpot,int Ypot){ <br> // this function takes the mapped values and determines the direction and speed<br> // speed of the motors.<br> int step;<br> // if the value is positive, step forward, if negative, step back<br> if(Xpot&gt;0){<br> for(Xpot != 0; step = 0; step++);<br> }<br> else{<br> for(Xpot != 0; step = 0; step--);<br> }<br> if(Ypot&gt;0){<br> for(Ypot != 0; step = 0; step++);<br> }<br> else{<br> for(Ypot != 0; step = 0; step--);<br> }<br> // takes the value from -6 to 6 and multiplies to get a micro-steps per second speed<br> Xspeed=Xpot*3000;<br> Yspeed=Ypot*3000;<br> // if the speed is 0 (when the motor is not moving) sets the stop to ground allowing<br> // current to bypass the driver reducing driver temperature. applies power to the <br> // driver when motor needs to move.<br> if (Xspeed == 0){<br> digitalWrite(XstopPin,LOW);<br> }<br> else{<br> digitalWrite(XstopPin,HIGH);<br> }<br> if (Yspeed == 0){<br> digitalWrite(YstopPin,LOW);<br> }<br> else{<br> digitalWrite(YstopPin,HIGH);<br> }<br> // sets the speed of the motors<br> stepperx.setSpeed(Xspeed);<br> steppery.setSpeed(Yspeed);<br> // see NOTE 1 above<br> stepperx.runSpeed();<br> steppery.runSpeed();<br> stepperx.runSpeed();<br> steppery.runSpeed(); <br> stepperx.runSpeed();<br> steppery.runSpeed(); <br> stepperx.runSpeed();<br> steppery.runSpeed(); <br> stepperx.runSpeed();<br> steppery.runSpeed();<br>}<br><br>int readY(){ // Reads the vertical position from the touch pad<br> pinMode(y1, INPUT);<br> pinMode(x2, OUTPUT);<br> pinMode(y2, INPUT);<br> pinMode(x1, OUTPUT);<br><br> digitalWrite(x2, LOW);<br> digitalWrite(x1, HIGH);<br> // see NOTE 1 above<br> stepperx.runSpeed();<br> steppery.runSpeed();<br> delay(5); //pause to allow lines to power up<br> // see NOTE 1 above<br> stepperx.runSpeed();<br> steppery.runSpeed();<br> return analogRead(y1); // returns the raw vertical value<br>}<br><br>int readX(){ // Reads the horizontal position from the touch pad<br> pinMode(y1, OUTPUT);<br> pinMode(x2, INPUT);<br> pinMode(y2, OUTPUT);<br> pinMode(x1, INPUT);<br><br> digitalWrite(y1, LOW);<br> digitalWrite(y2, HIGH);<br> // see NOTE 1 above<br> stepperx.runSpeed();<br> steppery.runSpeed();<br> delay(5); //pause to allow lines to power up<br> // see NOTE 1 above<br> stepperx.runSpeed();<br> steppery.runSpeed();<br> return analogRead(x2); // returns the raw horizontal value<br>}</p>
Do both your steppers move simultaneously, or do they alternate taking small steps?
They alternate taking small steps.<br><br> int i;<br> for(i=0; i&lt;=abs(den); i++)<br> {<br> move(mot0, len * res * sign(num));<br> move(mot1, res * sign(den));<br> }<br><br>N.
I'm impressed by how smooth the lines appear. Just really small steps I guess.
next: add a vibrating tray to it that can erase it quickly.
Just found one of these at the car boot, but it is leaking a bit.<br><br>It appears that the mystery powder is either brass or gold, not sure which..<br><br>Might be useable as a conducting adhesive? <br><br>
Nice i made one of these in the past sadly my roommates destroyed it but i'm glad i'm not the only one who still does this kind of stuff
Your roomates are a bunch of a-holes. I see plenty of their likes working at Mc Donald's.
Stupid yes, a-hole not as much, it was a project for a class and we were partners and i had to respond to a family emergency and he forgot to disconnect the motors from the shafts for transport and broke the coupling and one of the motors
Do you have a picture ? Should be inspiring.
Sadley no i didn't have a camera im a poor college student cant afford it. but he it a picture of it half rebuilt (one motor back on with rootmate resistant coupling) waiting to get second coupler in<br>Link: https://www.instructables.com/file/FIXLAZ8GOZIQGH6/<br>darn image upload thing not working
there's one instructable already done by someone whoever its not Arduino based.
Yep. Also google etch-a-sketch + arduino to get more projects like this one.
Excellent idea. May have to try this out one day.
Nice project. .Enjoyed reading.
Thanks. Appreciated.

About This Instructable

19,298views

60favorites

License:

More by nicoo:Hacked roomba + arduino snowballs into a Eurobot 2013 entry... Flashing bootloader into Arduino UNO R3 Arduino Sprinkler System + Web control 
Add instructable to: