{"id":12,"date":"2009-10-31T07:45:28","date_gmt":"2009-10-31T13:45:28","guid":{"rendered":"http:\/\/nootropicdesign.com\/projectlab\/?p=12"},"modified":"2018-11-02T09:42:57","modified_gmt":"2018-11-02T14:42:57","slug":"hack-a-sketch","status":"publish","type":"post","link":"https:\/\/nootropicdesign.com\/projectlab\/2009\/10\/31\/hack-a-sketch\/","title":{"rendered":"Hack-a-Sketch"},"content":{"rendered":"<p><strong><em>Difficulty Level = 5<\/em><\/strong>  <a href=\"\/projectlab\/difficulty-levels\/\">[What&#8217;s this?]<\/a><\/p>\n<p>Here is a device I call the Hack-a-Sketch.  The screen is a normal laptop (an old one), but it has real knobs which control the stylus on the screen.<\/p>\n<div id=\"attachment_3\" style=\"width: 650px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-3\" class=\"size-full wp-image-3\" title=\"hackasketch\" src=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2009\/11\/hackasketch.jpg\" alt=\"The Hack-a-Sketch\" width=\"640\" height=\"480\" srcset=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2009\/11\/hackasketch.jpg 640w, https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2009\/11\/hackasketch-300x225.jpg 300w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><p id=\"caption-attachment-3\" class=\"wp-caption-text\">The Hack-a-Sketch<\/p><\/div>\n<p\/>\n<p\/>\nAn <a href=\"http:\/\/www.arduino.cc\/\">Arduino<\/a> board reads the inputs from two potentiometers (the knobs), and sends the information via USB to a <a href=\"http:\/\/processing.org\/\">Processing<\/a> sketch which displays the path of the stylus on the screen.  This was extremely easy to build because the Arduino is just running the StandardFirmata firmware.  No custom code on the board.  The Processing sketch was surprisingly easy to write.  Using this really did feel like using an Etch-a-Sketch.<\/p>\n<p>Here&#8217;s the Hack-a-Sketch in action.  Wait for the big finish where I erase the image&#8230;<\/p>\n<p><iframe loading=\"lazy\" width=\"640\" height=\"505\" src=\"https:\/\/www.youtube.com\/embed\/EBgm-7VwPgk\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe><\/p>\n<p\/>\n<p\/>\nHow did I erase the drawing by shaking the computer?  There&#8217;s a mercury switch hidden behind the panel holding the knobs.  When the code senses shaking, the image is slowly erased.  More shaking = more erasure.<br \/>\n<!--more--><\/p>\n<div id=\"attachment_4\" style=\"width: 650px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-4\" class=\"size-full wp-image-4\" title=\"disassembled\" src=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2009\/11\/disassembled.jpg\" alt=\"Disassembled Hack-a-Sketch exposing mercury switch to sense movement.\" width=\"640\" height=\"480\" srcset=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2009\/11\/disassembled.jpg 640w, https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2009\/11\/disassembled-300x225.jpg 300w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><p id=\"caption-attachment-4\" class=\"wp-caption-text\">Disassembled Hack-a-Sketch exposing mercury switch to sense movement.<\/p><\/div>\n<p\/>\n<p\/>\nFinally, here&#8217;s the Processing code that does all the work:<\/p>\n<pre class=\"codeblockscroll\">import processing.serial.*;\r\n\r\nimport processing.core.*;\r\nimport cc.arduino.Arduino;\r\n\r\nPImage backgroundImage;\r\nArduino arduino;\r\nint STYLUS_X_PIN = 0;\r\nint STYLUS_Y_PIN = 1;\r\nint MERCURY_SWITCH_LEFT_PIN = 8;\r\nint MERCURY_SWITCH_RIGHT_PIN = 9;\r\n\/\/ Origin is lower left corner of screen.\r\nint originX = 146;\r\nint originY = 673;\r\nint width = 740;\r\nint height = 530;\r\nint PEN_COLOR = 50;\r\nint GRAY = 217;\r\nint GRAY_ALPHA = 80;\r\nint lastX, lastY;\r\nint SMOOTH_BUFFER_SIZE = 2;\r\nint[] smoothBufferX = new int[SMOOTH_BUFFER_SIZE];\r\nint[] smoothBufferY = new int[SMOOTH_BUFFER_SIZE];\r\nint smoothBufferXSum = 0;\r\nint smoothBufferYSum = 0;\r\nint LEFT = 0;\r\nint RIGHT = 1;\r\nint SHAKE_SPEED_THRESHOLD = 300;\r\nint lastSwitchPosition;\r\nint lastSwitchPositionChange;\r\n\r\nvoid setup() {\r\n    size(1024, 768);\r\n    frameRate(24);\r\n    backgroundImage = loadImage(\"hackasketch-cropped.jpg\");\r\n    background(backgroundImage);\r\n\r\n    String[] ports = Arduino.list();\r\n    println(ports[0]);\r\n    println(ports[1]);\r\n    String port = ports[1];\r\n    try {\r\n        arduino = new Arduino(this, port, 115200);\r\n        arduino.pinMode(MERCURY_SWITCH_LEFT_PIN, Arduino.INPUT);\r\n        arduino.pinMode(MERCURY_SWITCH_RIGHT_PIN, Arduino.INPUT);\r\n    } catch (Exception e) {\r\n        println(\"Failed to find Arduino board\");\r\n    }\r\n    stroke(PEN_COLOR);\r\n}\r\n\r\nvoid draw() {\r\n    smooth();\r\n    int x, y;\r\n    if (frameCount == 1) {\r\n        \/\/ Give the Arduino some time to initialize so we can get a good first\r\n        \/\/ reading from the potentiometers.\r\n        delay(2000);\r\n        lastX = readStylusX();\r\n        lastY = readStylusY();\r\n        for(int i=0;i &lt; SMOOTH_BUFFER_SIZE;i++) {\r\n            smoothBufferX[i] = lastX;\r\n            smoothBufferXSum += lastX;\r\n            smoothBufferY[i] = lastY;\r\n            smoothBufferYSum += lastY;\r\n        }\r\n        point(originX+lastX, originY-lastY);\r\n    }\r\n\r\n    x = smoothX(readStylusX());\r\n    y = smoothY(readStylusY());\r\n    if ((x != lastX) || (y != lastY)) {\r\n        line(originX+lastX, originY-lastY, originX+x, originY-y);\r\n    }\r\n    lastX = x;\r\n    lastY = y;\r\n\r\n    if (shake()) {\r\n        erase();\r\n    }\r\n}\r\n\r\nboolean shake() {\r\n    boolean left = (arduino.digitalRead(MERCURY_SWITCH_LEFT_PIN) == Arduino.HIGH);\r\n    if (left &amp;&amp; (lastSwitchPosition != LEFT)) {\r\n        lastSwitchPosition = LEFT;\r\n        if ((millis() - lastSwitchPositionChange) &lt; SHAKE_SPEED_THRESHOLD) {\r\n            lastSwitchPositionChange = millis();\r\n            return true;\r\n        }\r\n        lastSwitchPositionChange = millis();\r\n    }\r\n    boolean right = (arduino.digitalRead(MERCURY_SWITCH_RIGHT_PIN) == Arduino.HIGH);\r\n    if (right &amp;&amp; (lastSwitchPosition != RIGHT)) {\r\n        lastSwitchPosition = RIGHT;\r\n        if ((millis() - lastSwitchPositionChange) &lt; SHAKE_SPEED_THRESHOLD) {\r\n            lastSwitchPositionChange = millis();\r\n            return true;\r\n        }\r\n        lastSwitchPositionChange = millis();\r\n    }\r\n    return false;\r\n}\r\n\r\nvoid keyPressed() {\r\n    if (key == ' ') {\r\n        erase();\r\n    }\r\n}\r\n\r\nvoid erase() {\r\n    fill(GRAY, GRAY_ALPHA);\r\n    noStroke();\r\n    rect(originX, originY-height, width+1, height+1);\r\n    stroke(PEN_COLOR);\r\n}\r\n\r\n\/\/ Read current stylus X position relative to the origin.\r\nint readStylusX() {\r\n    int reading = arduino.analogRead(STYLUS_X_PIN);\r\n    return (int)map((float)reading, 0f, 1023f, 0f, (float)width);\r\n}\r\n\r\nint smoothX(int v) {\r\n    int index = frameCount % SMOOTH_BUFFER_SIZE;\r\n    smoothBufferXSum -= smoothBufferX[index];\r\n    smoothBufferXSum += v;\r\n    smoothBufferX[index] = v;\r\n    return (int)(smoothBufferXSum \/ SMOOTH_BUFFER_SIZE);\r\n}\r\n\r\n\/\/ Read current stylus Y position relative to the origin.\r\nint readStylusY() {\r\n    int reading = arduino.analogRead(STYLUS_Y_PIN);\r\n    return (int)map((float)reading, 0f, 1023f, 0f, (float)height);\r\n}\r\n\r\nint smoothY(int v) {\r\n    int index = frameCount % SMOOTH_BUFFER_SIZE;\r\n    smoothBufferYSum -= smoothBufferY[index];\r\n    smoothBufferYSum += v;\r\n    smoothBufferY[index] = v;\r\n    return (int)(smoothBufferYSum \/ SMOOTH_BUFFER_SIZE);\r\n}<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Difficulty Level = 5 [What&#8217;s this?] Here is a device I call the Hack-a-Sketch. The screen is a normal laptop (an old one), but it has real knobs which control the stylus on the screen. An Arduino board reads the inputs from two potentiometers (the knobs), and sends the information via USB to a Processing [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"","_et_pb_old_content":"","_et_gb_content_width":"","footnotes":""},"categories":[3],"tags":[],"class_list":["post-12","post","type-post","status-publish","format-standard","hentry","category-arduino"],"_links":{"self":[{"href":"https:\/\/nootropicdesign.com\/projectlab\/wp-json\/wp\/v2\/posts\/12","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nootropicdesign.com\/projectlab\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nootropicdesign.com\/projectlab\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nootropicdesign.com\/projectlab\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/nootropicdesign.com\/projectlab\/wp-json\/wp\/v2\/comments?post=12"}],"version-history":[{"count":16,"href":"https:\/\/nootropicdesign.com\/projectlab\/wp-json\/wp\/v2\/posts\/12\/revisions"}],"predecessor-version":[{"id":1990,"href":"https:\/\/nootropicdesign.com\/projectlab\/wp-json\/wp\/v2\/posts\/12\/revisions\/1990"}],"wp:attachment":[{"href":"https:\/\/nootropicdesign.com\/projectlab\/wp-json\/wp\/v2\/media?parent=12"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nootropicdesign.com\/projectlab\/wp-json\/wp\/v2\/categories?post=12"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nootropicdesign.com\/projectlab\/wp-json\/wp\/v2\/tags?post=12"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}