Example Code for Arduino-Rotating 3D Cube

Last revision 2026/01/19

This comprehensive guide demonstrates how to build and program a rotating 3D cube using Arduino and a transparent OLED display. The tutorial includes detailed hardware and software setup instructions, wiring diagrams, and sample code. Perfect for enthusiasts looking to enhance their DIY electronics skills with ESP32 integration.

Hardware Preparation

  • ESP32-E (or similar) x 1
  • 1.51" Transparent OLED Display Module x1
  • Dupont Wires

Software Preparation

Wiring Diagram

Connection

Wiring Detail Diagram:
Wiring Detail Diagram1
Wiring Detail Diagram2

Note: You can refer to the FPC cable color to access the correct position.

Other Preparation Work

  1. Demos are stored in U8g2_Arduino-master > DFRobot_Demo > 1.51 inch OLED12864-SSD1309.
    sample for cube
  2. Ensure the correct U8G2 function is enabled in the code.
  3. select the library

Sample Code

/*!
 * @file Cube.ino
 * @brief Rotating 3D stereoscopic graphics
 * @n This is a simple rotating tetrahexon
 * 
 * @copyright  Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
 * @licence     The MIT License (MIT)
 * @author [Ivey]([email protected])
 * @maintainer [Fary]([email protected])
 * @version  V1.0
 * @maintainer [Fary]([email protected])
 * @version  V1.0
 * @date  2019-10-15
 * @url https://github.com/DFRobot/U8g2_Arduino
*/

#include <Arduino.h>
#include <U8g2lib.h>

#include <SPI.h>


/*
 * Display hardware IIC interface constructor
 *@param rotation:U8G2_R0 Not rotate, horizontally, draw direction from left to right
           U8G2_R1 Rotate clockwise 90 degrees, drawing direction from top to bottom
           U8G2_R2 Rotate 180 degrees clockwise, drawing in right-to-left directions
           U8G2_R3 Rotate clockwise 270 degrees, drawing direction from bottom to top
           U8G2_MIRROR Normal display of mirror content (v2.6.x version used above)
           Note: U8G2_MIRROR need to be used with setFlipMode().
 *@param reset:U8x8_PIN_NONE Indicates that the pin is empty and no reset pin is used
 * Display hardware SPI interface constructor
 *@param  Just connect the CS pin (pins are optional)
 *@param  Just connect the DC pin (pins are optional)
 *
*/
#if defined ARDUINO_SAM_ZERO
#define OLED_DC  7
#define OLED_CS  5
#define OLED_RST 6
/*ESP32 */
#elif defined(ESP32)
#define OLED_DC  D2
#define OLED_CS  D6
#define OLED_RST D3
/*ESP8266*/
#elif defined(ESP8266)
#define OLED_DC  D4
#define OLED_CS  D6
#define OLED_RST D5
/*AVR series board*/
#else
#define OLED_DC  2
#define OLED_CS  3
#define OLED_RST 4
#endif
U8G2_SSD1309_128X64_NONAME2_1_4W_HW_SPI u8g2(/* rotation=*/U8G2_R0, /* cs=*/ OLED_CS, /* dc=*/ OLED_DC,/* reset=*/OLED_RST);


//2D array: The coordinates of all vertices of the tetrahesome are stored
double tetrahedron[4][3] = {{0,20,-20},{-20,-20,-20},{20,-20,-20},{0,0,20}};
void setup(void) {
  u8g2.begin();  
}

void loop(void) {
  /*
       * firstPage will change the current page number position to 0
       * When modifications are between firstpage and nextPage, they will be re-rendered at each time.
       * This method consumes less ram space than sendBuffer
   */ 
  u8g2.firstPage();
  do {
  //Connect the corresponding points inside the tetrahethal together
  u8g2.drawLine(OxyzToOu(tetrahedron[0][0], tetrahedron[0][2]), OxyzToOv(tetrahedron[0][1], tetrahedron[0][2]), OxyzToOu(tetrahedron[1][0], tetrahedron[1][2]), OxyzToOv(tetrahedron[1][1], tetrahedron[1][2]));
  u8g2.drawLine(OxyzToOu(tetrahedron[1][0], tetrahedron[1][2]), OxyzToOv(tetrahedron[1][1], tetrahedron[1][2]), OxyzToOu(tetrahedron[2][0], tetrahedron[2][2]), OxyzToOv(tetrahedron[2][1], tetrahedron[2][2]));
  u8g2.drawLine(OxyzToOu(tetrahedron[0][0], tetrahedron[0][2]), OxyzToOv(tetrahedron[0][1], tetrahedron[0][2]), OxyzToOu(tetrahedron[2][0], tetrahedron[2][2]), OxyzToOv(tetrahedron[2][1], tetrahedron[2][2]));
  u8g2.drawLine(OxyzToOu(tetrahedron[0][0], tetrahedron[0][2]), OxyzToOv(tetrahedron[0][1], tetrahedron[0][2]), OxyzToOu(tetrahedron[3][0], tetrahedron[3][2]), OxyzToOv(tetrahedron[3][1], tetrahedron[3][2]));
  u8g2.drawLine(OxyzToOu(tetrahedron[1][0], tetrahedron[1][2]), OxyzToOv(tetrahedron[1][1], tetrahedron[1][2]), OxyzToOu(tetrahedron[3][0], tetrahedron[3][2]), OxyzToOv(tetrahedron[3][1], tetrahedron[3][2]));
  u8g2.drawLine(OxyzToOu(tetrahedron[2][0], tetrahedron[2][2]), OxyzToOv(tetrahedron[2][1], tetrahedron[2][2]), OxyzToOu(tetrahedron[3][0], tetrahedron[3][2]), OxyzToOv(tetrahedron[3][1], tetrahedron[3][2]));
  // Rotate 0.1°
  rotate(0.1);

  } while ( u8g2.nextPage() );
  //delay(50);
}
/*!
 * @brief Convert xz in the three-dimensional coordinate system Oxyz
 * into the u coordinate inside the two-dimensional coordinate system Ouv
 * @param x in Oxyz  
 * @param z in Oxyz
 * @return u in Ouv
 */
int OxyzToOu(double x,double z){

   return (int)((x + 64) - z*0.35);
}


/*!
 * @brief Convert the yz in the three-dimensional coordinate system Oxyz into the v coordinate inside 
 * the two-dimensional coordinate system Ouv
 * @param y in Oxyz  
 * @param z in Oxyz
 * @return v in Ouv
 */ 
int OxyzToOv(double y,double z){
    return (int)((y + 26) - z*0.35);
}


/*!
 * @brief  Rotate the coordinates of all points of the entire 3D graphic around the Z axis
 * @param  angle represents the angle to rotate
 *     
 *  z rotation (z unchanged)
    x3 = x2 * cosb - y1 * sinb
    y3 = y1 * cosb + x2 * sinb
    z3 = z2
 */
void rotate(double angle)
{
  double rad, cosa, sina, Xn, Yn;

  rad = angle * PI / 180;
  cosa = cos(rad);
  sina = sin(rad);
  for (int i = 0; i < 4; i++)
  {
    Xn = (tetrahedron[i][0] * cosa) - (tetrahedron[i][1] * sina);
    Yn = (tetrahedron[i][0] * sina) + (tetrahedron[i][1] * cosa);

    //Store converted coordinates into an array of coordinates
    //Because it rotates around the Z-axis, the coordinates of the point z-axis remain unchanged
    tetrahedron[i][0] = Xn;
    tetrahedron[i][1] = Yn;
  }
}

Result

Result(There are many demo screens in this example. The following are some pictures in the demo screen ):
result

Was this article helpful?

TOP