这次实验使用ESP32 S2 模拟触摸屏的方式绘制一个心形和渐开线。下面是工作演示视频:
首先介绍的是“笛卡尔的爱情坐标公式”:心形函数r=a(1-sinθ),常被人当做表达爱和浪漫的一种方法。并且关于这个函数的由来有一个传播很广的故事。 笛卡尔在52岁时邂逅了当时瑞典的公主,当时他是公主的数学老师,不久公主就对笛卡尔产生了爱慕之情。然而,国王知道后,非常愤怒,将他流放回法国。在那里,笛卡尔给公主写的信都会被拦截。 在笛卡尔寄出第十三封信后,笛卡尔永远离开了这个世界。在最后的一封信上,笛卡尔只写了一个公式:r=a(1-sinΘ) 国王也看不懂,于是把这封信交给了公主。这就是我们知道的极坐标下的心型函数。 这封情书至今保存在欧洲笛卡尔纪念馆里。【这一段是“读者”体,真实情况如果用震惊体来描述的话就是“天才数学家竟被女王惨无人道的折磨”参考1】 在这个公式中有2个变量:a和θ。我们首先使用网页版的绘图工具【参考2】验证一下这个公式: 上述公式的参数方程形式为: 参数方程形式: x= a*(2*sin(t)-sin(2*t)) y= a*(2*cos(t)-cos(2*t)) 0<=t<=2*pi 根据上述公式,设计代码如下:
完整代码如下:
- #include "USB.h"
- #include "USBHID.h"
- USBHID HID;
-
- #define STEP 600
- int STARTX=5000;
- int STARTY=13000;
- int STARTR=5000;
- static const uint8_t report_descriptor[] = { // 8 TouchData
- 0x05, 0x0D,
- 0x09, 0x04,
- 0xA1, 0x01,
- 0x09, 0x22,
- 0xA1, 0x02,
- 0x09, 0x42,
- 0x15, 0x00,
- 0x25, 0x01,
- 0x75, 0x01,
- 0x95, 0x01,
- 0x81, 0x02,
- 0x09, 0x30,
- 0x25, 0x7F,
- 0x75, 0x07,
- 0x95, 0x01,
- 0x81, 0x02,
- 0x09, 0x51,
- 0x26, 0xFF, 0x00,
- 0x75, 0x08,
- 0x95, 0x01,
- 0x81, 0x02,
- 0x05, 0x01,
- 0x09, 0x30,
- 0x09, 0x31,
- 0x26, 0xFF, 0x7F,
- 0x65, 0x00,
- 0x75, 0x10,
- 0x95, 0x02,
- 0x81, 0x02,
- 0xC0,
- 0x05, 0x0D,
- 0x27, 0xFF, 0xFF, 0x00, 0x00,
- 0x75, 0x10,
- 0x95, 0x01,
- 0x09, 0x56,
- 0x81, 0x02,
- 0x09, 0x54,
- 0x25, 0x0A,
- 0x75, 0x08,
- 0x95, 0x01,
- 0x81, 0x02,
- 0x05, 0x0D,
- 0x09, 0x55,
- 0x25, 0x0A,
- 0x75, 0x08,
- 0x95, 0x01,
- 0xB1, 0x02,
- 0xC0,
- };
-
- class CustomHIDDevice: public USBHIDDevice {
- public:
- CustomHIDDevice(void) {
- static bool initialized = false;
- if (!initialized) {
- initialized = true;
- HID.addDevice(this, sizeof(report_descriptor));
- }
- }
- uint16_t _onGetFeature(uint8_t report_id, uint8_t* buffer, uint16_t len)
- {
- buffer[0]=0x0a;
- return 1;
- }
- void begin(void) {
- HID.begin();
- }
-
- uint16_t _onGetDescriptor(uint8_t* buffer) {
- memcpy(buffer, report_descriptor, sizeof(report_descriptor));
- return sizeof(report_descriptor);
- }
-
- bool send(uint8_t * value) {
- return HID.SendReport(0, value, 9);
- }
- };
-
- CustomHIDDevice Device;
-
- const int buttonPin = 0;
- int previousButtonState = HIGH;
- uint8_t TouchData[9];
-
- void setup() {
- Serial.begin(115200);
- Serial.setDebugOutput(true);
- Device.begin();
- USB.begin();
- }
-
- void loop() {
- if (HID.ready()) {
- delay(1000);
- Serial.println("Finger");
- int iX,iY;
- iX=STARTX+(STARTR*(2*sin(0)-sin(0)))/3;
- iY=STARTY-(STARTR*(2*cos(0)-cos(0)));
- TouchData[0] = 0x81;
- TouchData[1] = 0x02;
- TouchData[2] = (iX)&0xFF;
- TouchData[3] = (iX)>>8&0xFF;
- TouchData[4] = (iY)&0xFF;
- TouchData[5] = (iY)>>8&0xFF;
- TouchData[6] = (millis()*10)&0xFF; TouchData[7] = (millis()*10>>8)&0xFF;
- TouchData[8] = 0x01;
- Device.send(TouchData);
- delay(20);
- TouchData[0] = 0x81;
- TouchData[1] = 0x02;
- TouchData[2] = (iX+1)&0xFF;
- TouchData[3] = (iX+1)>>8&0xFF;
- TouchData[4] = (iY)&0xFF;
- TouchData[5] = (iY)>>8&0xFF;
- TouchData[6] = (millis()*10)&0xFF; TouchData[7] = (millis()*10>>8)&0xFF;
- TouchData[8] = 0x01;
- Device.send(TouchData);
- delay(40);
-
- // touch report
- // 0: on/off + pressure
- // 1: contact id
- // 2: X lsb
- // 3: X msb
- // 4: Y lsb
- // 5: Y msb
- // 6: scan time lsb
- // 7: scan time msb
- // 8: contact count
-
- for (int i=0;i<STEP+1;i++) {
- TouchData[0] = 0x81; TouchData[1] = 0x01;
- iX=STARTX+(STARTR*(2*sin(2*PI*i/STEP)-sin(2*2*PI*i/STEP)))/3;
- iY=STARTY-(STARTR*(2*cos(2*PI*i/STEP)-cos(2*2*PI*i/STEP)));
- Serial.print(iX);Serial.print(" ");Serial.println(iY);
- TouchData[2] = ((int)(iX))&0xFF;
- TouchData[3] = ((int)(iX))>>8&0xFF;
- TouchData[4] = ((int)(iY))&0xFF;
- TouchData[5] = ((int)(iY))>>8&0xFF;
- TouchData[6] = (millis()*10)&0xFF; TouchData[7] = (millis()*10>>8)&0xFF;
- TouchData[8] = 0x01;
- Device.send(TouchData);
- delay(20);
- }
- //每隔10秒
- delay(2000);
- STARTX=STARTX+6000;
- STARTY=STARTY;
-
- }
-
- }
复制代码
渐开线的参数方程: iX=r*cos(b)+r*b*sin(b)
iY=r*sin(b)-r*b*cos(b)
- #include "USB.h"
- #include "USBHID.h"
- USBHID HID;
-
- #define STEP 100
- int STARTX = 18000;
- int STARTY = 18000;
- int STARTR = 100;
- static const uint8_t report_descriptor[] = { // 8 TouchData
- 0x05, 0x0D,
- 0x09, 0x04,
- 0xA1, 0x01,
- 0x09, 0x22,
- 0xA1, 0x02,
- 0x09, 0x42,
- 0x15, 0x00,
- 0x25, 0x01,
- 0x75, 0x01,
- 0x95, 0x01,
- 0x81, 0x02,
- 0x09, 0x30,
- 0x25, 0x7F,
- 0x75, 0x07,
- 0x95, 0x01,
- 0x81, 0x02,
- 0x09, 0x51,
- 0x26, 0xFF, 0x00,
- 0x75, 0x08,
- 0x95, 0x01,
- 0x81, 0x02,
- 0x05, 0x01,
- 0x09, 0x30,
- 0x09, 0x31,
- 0x26, 0xFF, 0x7F,
- 0x65, 0x00,
- 0x75, 0x10,
- 0x95, 0x02,
- 0x81, 0x02,
- 0xC0,
- 0x05, 0x0D,
- 0x27, 0xFF, 0xFF, 0x00, 0x00,
- 0x75, 0x10,
- 0x95, 0x01,
- 0x09, 0x56,
- 0x81, 0x02,
- 0x09, 0x54,
- 0x25, 0x0A,
- 0x75, 0x08,
- 0x95, 0x01,
- 0x81, 0x02,
- 0x05, 0x0D,
- 0x09, 0x55,
- 0x25, 0x0A,
- 0x75, 0x08,
- 0x95, 0x01,
- 0xB1, 0x02,
- 0xC0,
- };
-
- class CustomHIDDevice: public USBHIDDevice {
- public:
- CustomHIDDevice(void) {
- static bool initialized = false;
- if (!initialized) {
- initialized = true;
- HID.addDevice(this, sizeof(report_descriptor));
- }
- }
- uint16_t _onGetFeature(uint8_t report_id, uint8_t* buffer, uint16_t len)
- {
- buffer[0] = 0x0a;
- return 1;
- }
- void begin(void) {
- HID.begin();
- }
-
- uint16_t _onGetDescriptor(uint8_t* buffer) {
- memcpy(buffer, report_descriptor, sizeof(report_descriptor));
- return sizeof(report_descriptor);
- }
-
- bool send(uint8_t * value) {
- return HID.SendReport(0, value, 9);
- }
- };
-
- CustomHIDDevice Device;
-
- const int buttonPin = 0;
- int previousButtonState = HIGH;
- uint8_t TouchData[9];
-
- void setup() {
- Serial.begin(115200);
- Serial.setDebugOutput(true);
- Device.begin();
- USB.begin();
- }
-
- void loop() {
- if (HID.ready()) {
- delay(1000);
- Serial.println("Finger");
- int iX, iY;
- /*
- iX = STARTX + (STARTR * (2 * sin(0) - sin(0))) / 3;
- iY = STARTY - (STARTR * (2 * cos(0) - cos(0)));
- TouchData[0] = 0x81;
- TouchData[1] = 0x02;
- TouchData[2] = (iX) & 0xFF;
- TouchData[3] = (iX) >> 8 & 0xFF;
- TouchData[4] = (iY) & 0xFF;
- TouchData[5] = (iY) >> 8 & 0xFF;
- TouchData[6] = (millis() * 10) & 0xFF; TouchData[7] = (millis() * 10 >> 8) & 0xFF;
- TouchData[8] = 0x01;
- Device.send(TouchData);
- delay(20);
- TouchData[0] = 0x81;
- TouchData[1] = 0x02;
- TouchData[2] = (iX + 1) & 0xFF;
- TouchData[3] = (iX + 1) >> 8 & 0xFF;
- TouchData[4] = (iY) & 0xFF;
- TouchData[5] = (iY) >> 8 & 0xFF;
- TouchData[6] = (millis() * 10) & 0xFF; TouchData[7] = (millis() * 10 >> 8) & 0xFF;
- TouchData[8] = 0x01;
- Device.send(TouchData);
- delay(40);
- */
- // touch report
- // 0: on/off + pressure
- // 1: contact id
- // 2: X lsb
- // 3: X msb
- // 4: Y lsb
- // 5: Y msb
- // 6: scan time lsb
- // 7: scan time msb
- // 8: contact count
-
- for (int i = 0; i < STEP*18; i++) {
- TouchData[0] = 0x81; TouchData[1] = 0x01;
- iX = STARTX+(STARTR * cos(2*PI*i/STEP) + STARTR * (2*PI*i/STEP) * sin(2*PI*i/STEP))*3/4;
- iY = STARTY+STARTR * sin(2*PI*i/STEP) - STARTR * (2*PI*i/STEP) * cos(2*PI*i/STEP);
- Serial.print(iX); Serial.print(" "); Serial.println(iY);
- TouchData[2] = ((int)(iX)) & 0xFF;
- TouchData[3] = ((int)(iX)) >> 8 & 0xFF;
- TouchData[4] = ((int)(iY)) & 0xFF;
- TouchData[5] = ((int)(iY)) >> 8 & 0xFF;
- TouchData[6] = (millis() * 10) & 0xFF; TouchData[7] = (millis() * 10 >> 8) & 0xFF;
- TouchData[8] = 0x01;
- Device.send(TouchData);
- delay(20);
- }
- //每隔10秒
- delay(2000);
- STARTX = STARTX + 3;
- STARTY = STARTY;
-
- }
-
- }
复制代码
参考:
2.https://zuotu.91maths.com/#W3sidHlwZSI6MSwiZXEiOiIyKigxLXNpbih0aGV0YSkpIiwiY29sb3IiOiIjMDA4MGNjIiwidGhldGFtaW4iOiIwIiwidGhldGFtYXgiOiIycGkiLCJ0aGV0YXN0ZXAiOiIwLjAxIn0seyJ0eXBlIjoxMDAwLCJ3aW5kb3ciOlsiLTguMjE1MTExOTk5OTk5OTkiLCI4LjAzNDg4Nzk5OTk5OTk5MiIsIi01LjI3ODUyNzk5OTk5OTk5NSIsIjQuNzIxNDcxOTk5OTk5OTk2Il0sImdyaWQiOlsiMSIsIjEiXX1d
|