element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Project Videos
  • Challenges & Projects
  • element14 presents
  • Project Videos
  • More
  • Cancel
Project Videos
Documents Raspberry Pi Auto Etch A Sketch™︎ -- Episode 372
  • Documents
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Project Videos to participate - click to join for free!
Related
Recommended
Engagement
  • Author Author: kellyhensen
  • Date Created: 20 Nov 2018 7:52 PM Date Created
  • Last Updated Last Updated: 14 Dec 2018 8:24 AM
  • Views 3666 views
  • Likes 6 likes
  • Comments 17 comments

Raspberry Pi Auto Etch A Sketch™︎ -- Episode 372

image
Raspberry Pi Auto Etch A SketchTm

element14 presents  |  daftmike's VCP Profile  |  Project Videos

 

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

In this video Mike builds an automatic Etch A SketchTm machine using stepper motors and 3D printed gears.

 

Bill of Material:

 

Product NameManufacturerQuantity
Buy Kit

Raspberry Pi 3 Model B+, BCM2837B0 SoC, IoT, PoE, NOOBS Included

RASPBERRY-PI1Buy Now

Raspberry Pi DC Stepper Motor Hat Develo

ADAFRUIT1Buy Now
3D Printer Filament, 1.75 mm, PLA, Red, 1 kgMULTICOMP1Buy Now
Stepper Motor, High Torque, DC, 0.5 N-m, 1.8 A, Two Phase, 1.75 ohm, 3.3 mHNANOTEC1Buy Now
CONTINUOUS ROTATION SERVOADAFRUIT1Buy Now

 

Arduino Flip Code:

 

/* ================================================================================


  GY-521 IMU test code for flipping the etch a sketch - daftmike 2018


  ================================================================================ */





#include <Wire.h>


#include <Servo.h>





// Servo is attached to pin 5


Servo servo;


const int servoPin = 5;





// Variables used for the IMU readings


long accelX, accelY, accelZ;


float gForceX, gForceY, gForceZ;


long gyroXCali = 0, gyroYCali = 0, gyroZCali = 0;


long gyroXPresent = 0, gyroYPresent = 0, gyroZPresent = 0;


long gyroXPast = 0, gyroYPast = 0, gyroZPast = 0;


float rotX, rotY, rotZ;


float angleX = 0, angleY = 0, angleZ = 0;


long timePast = 0;


long timePresent = 0;





// Variables used to keep track of the 'flip'


bool flipStarted = 0;


bool flipFinished = 0;


int flips = 0;


int servoDir = 90;





// String to hold the serial data from the Pi


String piMsg;





// Speed, angle and number of 'flips'


const int forwardSpeed = 60;


const int backwardSpeed = 180;


const int numFlips = 5;


const int lowAngle = -140;


const int midAngle = -120;








/*================================================================================*/





void setup() {


  Serial.begin(9600);  // start the serial port


  Wire.begin();  // start i2c


  setUpMPU();  // start IMU coms


  calibrateGyroValues();  


  timePresent = millis();  // time reference for IMU readings


}





/*================================================================================*/





void loop() {


  readAndProcessAccelData();


  readAndProcessGyroData();


  readPi();


}





/*================================================================================*/





void servoFlip() {  


  if (servoDir == 90) {


  servo.attach(servoPin);


  servoDir = forwardSpeed;


  servo.write(servoDir);


  Serial.println("flip started, servo moving forward...");


  flipStarted = 1;


  }





  if (flipStarted == 1) {





   if (servoDir == forwardSpeed && angleX < lowAngle && flips < numFlips) {


  servoDir = backwardSpeed;


  servo.write(servoDir);


  Serial.println("servo backward...");


  flips++;


  Serial.print("flip number: ");


  Serial.println(flips);


  }


   if (servoDir == backwardSpeed && angleX > midAngle && flips < numFlips) {


  servoDir = forwardSpeed;


  servo.write(servoDir);


  Serial.println("servo forward...");


  flips++;


  Serial.print("flip number: ");


  Serial.println(flips);


  }


   if (servoDir == backwardSpeed && -2 < angleX) {


  Serial.println("turning servo OFF...");


  servo.detach();


  servoDir = 90;


  flips = 0;


  flipStarted = 0;


   delay(2000);


   setUpMPU();


   calibrateGyroValues();


  }


  }


}





void readPi() {  // read data from the serial port into a string to check for messages





  if (Serial.available()) {


  piMsg = Serial.readString();





   if (piMsg == "flip") {


   servoFlip();


  }


   else if (piMsg == "cali") {


  Serial.println("calibrating gyro values...");


   setUpMPU();


   calibrateGyroValues();


  }


  }


}








void setUpMPU() {


  // power management


  Wire.beginTransmission(0b1101000);  // Start the communication by using address of MPU


  Wire.write(0x6B);  // Access the power management register


  Wire.write(0b00000000);  // Set sleep = 0


  Wire.endTransmission();  // End the communication





  // configure gyro


  Wire.beginTransmission(0b1101000);


  Wire.write(0x1B);  // Access the gyro configuration register


  Wire.write(0b00000000);


  Wire.endTransmission();





  // configure accelerometer


  Wire.beginTransmission(0b1101000);


  Wire.write(0x1C);  // Access the accelerometer configuration register


  Wire.write(0b00000000);


  Wire.endTransmission();


}





void calibrateGyroValues() {


  for (int i = 0; i < 5000; i++) {


   getGyroValues();


  gyroXCali = gyroXCali + gyroXPresent;


  gyroYCali = gyroYCali + gyroYPresent;


  gyroZCali = gyroZCali + gyroZPresent;


  }


  gyroXCali = gyroXCali / 5000;


  gyroYCali = gyroYCali / 5000;


  gyroZCali = gyroZCali / 5000;


}





void readAndProcessAccelData() {


  Wire.beginTransmission(0b1101000);


  Wire.write(0x3B);


  Wire.endTransmission();


  Wire.requestFrom(0b1101000, 6);


  while (Wire.available() < 6);


  accelX = Wire.read() << 8 | Wire.read();


  accelY = Wire.read() << 8 | Wire.read();


  accelZ = Wire.read() << 8 | Wire.read();


  processAccelData();


}





void processAccelData() {


  gForceX = accelX / 16384.0;


  gForceY = accelY / 16384.0;


  gForceZ = accelZ / 16384.0;


}





void readAndProcessGyroData() {


  gyroXPast = gyroXPresent;  // Assign Present gyro reaging to past gyro reading


  gyroYPast = gyroYPresent;  // Assign Present gyro reaging to past gyro reading


  gyroZPast = gyroZPresent;  // Assign Present gyro reaging to past gyro reading


  timePast = timePresent;  // Assign Present time to past time


  timePresent = millis();  // get the current time in milli seconds, it is the present time





  getGyroValues();  // get gyro readings


  getAngularVelocity();  // get angular velocity


  calculateAngle();  // calculate the angle


}





void getGyroValues() {


  Wire.beginTransmission(0b1101000);  // Start the communication by using address of MPU


  Wire.write(0x43);  // Access the starting register of gyro readings


  Wire.endTransmission();


  Wire.requestFrom(0b1101000, 6);  // Request for 6 bytes from gyro registers (43 - 48)


  while (Wire.available() < 6);  // Wait untill all 6 bytes are available


  gyroXPresent = Wire.read() << 8 | Wire.read();  // Store first two bytes into gyroXPresent


  gyroYPresent = Wire.read() << 8 | Wire.read();  // Store next two bytes into gyroYPresent


  gyroZPresent = Wire.read() << 8 | Wire.read();  // Store last two bytes into gyroZPresent


}





void getAngularVelocity() {


  rotX = gyroXPresent / 131.0;


  rotY = gyroYPresent / 131.0;


  rotZ = gyroZPresent / 131.0;


}





void calculateAngle() {


  // same equation can be written as


  // angleZ = angleZ + ((timePresentZ - timePastZ)*(gyroZPresent + gyroZPast - 2*gyroZCalli)) / (2*1000*131);


  // 1/(1000*2*131) = 0.00000382


  // 1000 --> convert milli seconds into seconds


  // 2 --> comes when calculation area of trapezium


  // substacted the callibated result two times because there are two gyro readings


  angleX = angleX + ((timePresent - timePast) * (gyroXPresent + gyroXPast - 2 * gyroXCali)) * 0.00000382;


  angleY = angleY + ((timePresent - timePast) * (gyroYPresent + gyroYPast - 2 * gyroYCali)) * 0.00000382;


  angleZ = angleZ + ((timePresent - timePast) * (gyroZPresent + gyroZPast - 2 * gyroZCali)) * 0.00000382;


}





void printData() {


  Serial.print("X : ");


  Serial.print(angleX);


  Serial.print("° | Y : ");


  Serial.print(angleY);


  Serial.print("° | Z : ");


  Serial.print(angleZ); Serial.println("°");





}

 

Supporting Files:

 

Click Here for access to all the supporting files you will need to replicate this build!



Attachments:
Auto-Etch-A-Sketch-master.zip
  • episode 372: raspberry pi auto etch a sketch™
  • raspberri pi
  • friday_release
  • e14presents_daftmike
  • Share
  • History
  • More
  • Cancel
Actions
  • Share
  • More
  • Cancel
  • Sign in to reply

Top Comments

  • Sean_Miller
    Sean_Miller over 6 years ago +4
    Great use of joints in Autodesk Fusion. That is a critical skill to master. It allows one's prints to do what you want with the first printed part attempt - preventing hours of rework. Surprisingly low…
  • DAB
    DAB over 6 years ago +3
    Nice build. I recently saw another post where someone used a CNC cad program to drive the stepper motors to do a similar task with the etchasketch. Adding the self erase feature was a good modification…
  • mayermakes
    mayermakes over 6 years ago +2
    Compliment on the stunnign print quality of your 3d printed parts, and awesome build!!
Parents
  • awagentx
    awagentx over 6 years ago

    where are the 3d print files and the code as mentioned in the video?

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • cstanton
    cstanton over 6 years ago in reply to awagentx

    awagentx are you going to make your own version? image

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • awagentx
    awagentx over 6 years ago in reply to cstanton

    possibly, i have a slight other idea for using motors w/ an ech-a-schetc....

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • cstanton
    cstanton over 6 years ago in reply to awagentx

    What's your idea?

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • awagentx
    awagentx over 6 years ago in reply to cstanton

    possibly an RSS display or a clock (depending on draw time)

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
Comment
  • awagentx
    awagentx over 6 years ago in reply to cstanton

    possibly an RSS display or a clock (depending on draw time)

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
Children
  • cstanton
    cstanton over 6 years ago in reply to awagentx

    I could totally see a clock working image let us know how you get on!

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube