ESP8266+OLED屏实现cube3D效果展示

Posted perseverance52

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ESP8266+OLED屏实现cube3D效果展示相关的知识,希望对你有一定的参考价值。

ESP8266+OLED屏实现cube3D效果展示

  • 使用的是esp8266,
  • 编程环境Arduino IDE
  • 使用的oled屏幕为1.3寸的,代码中有0.96寸的代码可以选择,屏幕接口为IIC接口
  • 选择的开发板是NodeMCU1.0
    效果展示

ESP8266+OLED屏cube3D效果展示

程序源码:

#include "SH1106Wire.h" //1.3寸用这个
//#include "SSD1306Wire.h"    //0.96寸用这个
#include "OLEDDisplayUi.h"

#if defined(ESP8266)    //OLED引脚定义
const int SDA_PIN = D2; //对应nodemcu接D5或者D1,,wemosD1mini的D2
const int SDC_PIN = D1; //对应nodemcu接D6或者D2,,wemosD1mini的D5
#else
const int SDA_PIN = D1; //对应nodemcu接D5或者D1
const int SCL = D2;     //对应nodemcu接D6或者D2
#endif

const int I2C_DISPLAY_ADDRESS = 0x3c;                      //I2c地址默认

SH1106Wire display(I2C_DISPLAY_ADDRESS, SDA_PIN, SDC_PIN); // 1.3寸用这个
//SSD1306Wire     display(I2C_DISPLAY_ADDRESS, SDA_PIN, SDC_PIN);   // 0.96寸用这个

 OLEDDisplayUi ui     ( &display );

 typedef struct Vertex{
  int location[3];
}MyVertex;

typedef struct Edge{
  char connection[2];
}MyEdge;

typedef struct Object{
  int numv;
  int nume;
  MyVertex* v;
  MyEdge* e;
  float quat[4];
  float offset[3];
}MyObject;

static MyVertex mp[] ={{-20,-20,-20},{-20,20,-20},{20,20,-20},{20,-20,-20},{-20,-20,20},{-20,20,20},{20,20,20},{20,-20,20}};

static MyEdge me[] ={{0, 1}, {1, 2},{2, 3},{3, 0}, {4, 5},{5, 6},{6, 7},{7, 4},{0, 4},{1, 5},{2, 6},{3, 7}};
MyObject  obj = {8, 12, mp, me,{1,0,0,0},{0,0,0}};

//{{ -16, -16,-16}, {16, -16, -16},{16, 16, -16},{-16, 16, -16},{-16, -16,16},{16, -16, 16},{16, 16, 16}, {-16, 16, 16}}
//{{0, 1}, {1, 2},{2, 3},{3, 0}, {4, 5},{5, 6},{6, 7},{7, 4},{0, 4},{1, 5},{2, 6},{3, 7}}
//float cube[8][3]={{-20,-20,-20},{-20,20,-20},{20,20,-20},{20,-20,-20},{-20,-20,20},{-20,20,20},{20,20,20},{20,-20,20}};//立方体各点坐标
//float cube2[8][3]={{-15,-15,-15},{-15,15,-15},{15,15,-15},{15,-15,-15},{-15,-15,15},{-15,15,15},{15,15,15},{15,-15,15}};//立方体各点坐标
//int lineid[]={1,2,2,3,3,4,4,1,5,6,6,7,7,8,8,5,8,4,7,3,6,2,5,1};//记录点之间连接顺序



void oledcube(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);

void oledcube2(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);

void oledcube3(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);

float* matconv(float* a,float b[3][3]){//计算矩阵乘法
  float res[3];
  for(int i=0;i<3;i++)
    res[i]=b[i][0]*a[0]+b[i][1]*a[1]+b[i][2]*a[2];
  for(int i=0;i<3;i++)a[i]=res[i];
  return a;
}

void rotate(float* obj,float x,float y,float z){//旋转该向量
  x/=PI;y/=PI;z/=PI;
  float rz[3][3]={{cos(z),-sin(z),0},{sin(z),cos(z),0},{0,0,1}};
  float ry[3][3]={{1,0,0},{0,cos(y),-sin(y)},{0,sin(y),cos(y)}};
  float rx[3][3]={{cos(x),0,sin(x)},{0,1,0},{-sin(x),0,cos(x)}};
  matconv(matconv(matconv(obj,rz),ry),rx);
}

void cube3d2(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y){
float cube[8][3]={{-20,-20,-20},{-20,20,-20},{20,20,-20},{20,-20,-20},{-20,-20,20},{-20,20,20},{20,20,20},{20,-20,20}};//立方体各点坐标
float cube2[8][3]={{-15,-15,-15},{-15,15,-15},{15,15,-15},{15,-15,-15},{-15,-15,15},{-15,15,15},{15,15,15},{15,-15,15}};//立方体各点坐标
int lineid[]={1,2,2,3,3,4,4,1,5,6,6,7,7,8,8,5,8,4,7,3,6,2,5,1};//记录点之间连接顺序
  for(int k=0;k<142;k++){
    display->clear();
    for(int i=0;i<8;i++){rotate(cube[i],0.5f,0.3f,0);rotate(cube2[i],0.5f,0.3f,0);}//旋转每个点
  for(int i=0;i<24;i+=2){//绘制立方体
    display->drawLine(64+cube[lineid[i]-1][0],32+cube[lineid[i]-1][1],64+cube[lineid[i+1]-1][0],32+cube[lineid[i+1]-1][1]);
    display->drawLine(64+cube2[lineid[i]-1][0],32+cube2[lineid[i]-1][1],64+cube2[lineid[i+1]-1][0],32+cube2[lineid[i+1]-1][1]);
  }
  delay(80);
display->display();
}
}

void cube3d3(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y){
float cube[8][3]={{-20,-20,-20},{-20,20,-20},{20,20,-20},{20,-20,-20},{-20,-20,20},{-20,20,20},{20,20,20},{20,-20,20}};//立方体各点坐标
float cube2[8][3]={{-15,-15,-15},{-15,15,-15},{15,15,-15},{15,-15,-15},{-15,-15,15},{-15,15,15},{15,15,15},{15,-15,15}};//立方体各点坐标
int lineid[]={1,2,2,3,3,4,4,1,5,6,6,7,7,8,8,5,8,4,7,3,6,2,5,1};//记录点之间连接顺序
  for(int k=0;k<142;k++){
    display->clear();
    for(int i=0;i<8;i++){rotate(cube[i],0.5f,0.3f,0);rotate(cube2[i],0.5f,0.3f,0);}//旋转每个点
  for(int i=0;i<24;i+=2){//绘制立方体
    display->drawLine(64+cube[lineid[i]-1][0],32+cube[lineid[i]-1][1],64+cube[lineid[i+1]-1][0],32+cube[lineid[i+1]-1][1]);
   // display->drawLine(64+cube2[lineid[i]-1][0],32+cube2[lineid[i]-1][1],64+cube2[lineid[i+1]-1][0],32+cube2[lineid[i+1]-1][1]);
  }
  delay(80);
display->display();
}
ui.nextFrame();
  //ui.switchToFrame(2);//切换到第一个画面
 // ui.transitionToFrame(0);
}

 FrameCallback frames[] = {oledcube,cube3d3,cube3d2}; //
//页面数量,图形绘制回调函数数组,

const int numberOfFrames = 3; // 显示16屏内容信息

void setup()   {
  Serial.begin(9600);
  display.init();
  display.clear();
  display.display();
  //    display.flipScreenVertically(); //屏幕翻转
  // display.mirrorScreen();//使用分光棱镜显示需要用到此函数
  display.setContrast(240); //屏幕亮度
  delay(1000);
 ui.setTargetFPS(80);                   //刷新频率
  ui.disableAllIndicators();             //不显示页码小点。
 ui.enableAutoTransition();
  ui.setFrameAnimation(SLIDE_LEFT);           //切屏方向
  ui.setAutoTransitionForwards();//设置自动过渡方向,
  ui.setFrames(frames, numberOfFrames);       // 设置框架和显示屏幕内容数
  ui.setTimePerFrame(5000);                   //设置切换时间
  ui.setTimePerTransition(500);//设置转场大约所需要时间
  // ui.setOverlays(overlays, numberOfOverlays); //设置覆盖的画面数  
  ui.init();// UI负责初始化显示
 
  moveObject(obj,64,32,0);
  renderObject(obj);

}
 
static float qdelta[4]={0.999847695f,以上是关于ESP8266+OLED屏实现cube3D效果展示的主要内容,如果未能解决你的问题,请参考以下文章

esp8266+OLED屏显示cube水平旋转效果

ESP8266嵌套Cube3D旋转动画(嵌套)

ESP8266 +0.96“ I2C OLED 表盘时钟

ESP8266 NodeMCU驱动OLED屏(SSD1306,4PIN,IIC)

ESP8266 NodeMCU驱动OLED屏(SSD1306,4PIN,IIC)

ESP8266 NodeMCU驱动OLED屏(SSD1306,4PIN,IIC)