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 NodeMCU驱动OLED屏(SSD1306,4PIN,IIC)