描述
<div class="document">
<p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"> </p>
<h3 class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;">* 1、项目功能介绍</h3>
<hr class="horizontal-splitline normal-bold-2">
<p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"><span style="color: #000000; font-size: 14px;">市面上仍然有一些使用 PS/2 接口的主机:比如:工控机或者示波器。但是目前市面上 PS2 鼠标已经非常少见了,特别是没有无线PS2鼠标。这次的目标是制作一个将无线鼠标转接为 PS/2的设备。</span></p>
<p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"> </p>
<p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"> </p>
<h3 class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;">*2、项目属性</h3>
<hr class="horizontal-splitline normal-bold-2">
<p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"><span style="color: #000000; font-size: 14px;">首次公开,原创。</span></p>
<p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"> </p>
<p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"> </p>
<h3 class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;">* 3、开源协议</h3>
<hr class="horizontal-splitline normal-bold-2">
<p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"><span style="color: #000000; font-size: 14px;">使用GPL3.0开源协议</span></p>
<p style="line-height: 1.8;"> </p>
<p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"><strong><span style="color: #0093e6;">请在竞赛阶段填写 ↓</span></strong></p>
<p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"> </p>
<h3 class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;">*4、硬件部分</h3>
<hr class="horizontal-splitline normal-bold-2">
<p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"><span style="color: #000000; font-size: 14px;">选择ESP32 S3 来完成工作,ESP32 S3 是外设非常丰富的SoC,出了支持 WIFI 和蓝牙之外,还支持 USB Host, 因此,这次使用它来解析USB 鼠标信息,然后转为 PS2 信号。</span></p>
<p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"> </p>
<p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt pap-left-indent-1.6em" style="line-height: 1.8;"> </p>
<h3 class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;">*5、软件部分</h3>
<hr class="horizontal-splitline normal-bold-2">
<p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"> </p>
<p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;">代码部分使用 Arduino 来编写:</p>
<p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"> </p>
<p>#include <elapsedMillis.h><br>#include <usb/usb_host.h><br>#include "show_desc.hpp"<br>#include "usbhhelp.hpp"<br>#include <esp32-ps2dev.h><br>const int CLK_PIN = 21;<br>const int DATA_PIN = 13;</p>
<p>esp32_ps2dev::PS2Mouse mouse(CLK_PIN, DATA_PIN);<br>long int Elsp=0;</p>
<p>bool isMouse = false;<br>bool isMouseReady = false;<br>uint8_t MouseInterval;<br>bool isMousePolling = false;<br>elapsedMillis MouseTimer;<br>bool bLeftBtn = false;<br>bool bRightBtn = false;<br>bool bMidBtn = false;<br>const size_t Mouse_IN_BUFFER_SIZE = 8;<br>usb_transfer_t *MouseIn = NULL;</p>
<p>int16_t mousemap(int value) {<br> if (value < -255) {<br> return -255;<br> }<br> if ((value >= -255) && (value <= 255)) {<br> return value;<br> }<br> if (value > 255) {<br> return 255;<br> }<br>}</p>
<p>boolean bLPressed=false,bRPressed=false,bMPressed=false;</p>
<p>void Mouse_transfer_cb(usb_transfer_t *transfer)<br>{</p>
<p> if (Device_Handle == transfer->device_handle) {<br> isMousePolling = false;<br> if (transfer->status == 0) {<br> if (transfer->actual_num_bytes == Mouse_IN_BUFFER_SIZE) {<br> uint8_t *const p = transfer->data_buffer;<br> ESP_LOGI("", "HID report: %02x %02x %02x %02x %02x %02x %02x %02x",<br> p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);</p>
<p> if ((bLPressed==false)&&((p[0]&0x01)!=0)) {<br> mouse.press(esp32_ps2dev::PS2Mouse::Button::LEFT);<br> ESP_LOGI("", "Left Pressed");<br> bLPressed=true;<br> }<br> if ((bRPressed==false)&&((p[0]&0x02)!=0)) {<br> mouse.press(esp32_ps2dev::PS2Mouse::Button::RIGHT);<br> ESP_LOGI("", "Right Pressed");<br> bRPressed=true;<br> }<br> if ((bMPressed==false)&&((p[0]&0x04)!=0)) {<br> mouse.press(esp32_ps2dev::PS2Mouse::Button::MIDDLE);<br> ESP_LOGI("", "Middle Pressed");<br> bMPressed=true;<br> }<br> <br> if ((bLPressed)&&((p[0]&0x01)==0)) {<br> mouse.release(esp32_ps2dev::PS2Mouse::Button::LEFT);<br> ESP_LOGI("", "Left Released");<br> bLPressed=false;<br> }<br> if ((bRPressed)&&((p[0]&0x02)==0)) {<br> mouse.release(esp32_ps2dev::PS2Mouse::Button::RIGHT);<br> ESP_LOGI("", "Right Released");<br> bRPressed=false;<br> }<br> if ((bMPressed)&&((p[0]&0x04)==0)) {<br> mouse.release(esp32_ps2dev::PS2Mouse::Button::MIDDLE);<br> ESP_LOGI("", "Middle Released");<br> bMPressed=false;<br> }<br> <br> int16_t x, y;<br> int8_t z;</p>
<p> x = p[3] << 8;<br> x = p[2] + x;<br> y = p[5] << 8;<br> y = -(p[4] + y);<br> z = -p[6];<br> ESP_LOGI("", "x: %d %x %x", x, p[2], p[3]);<br> ESP_LOGI("", "y: %d %x %x", y, p[5], p[4]);<br> ESP_LOGI("", "z: %d", z);<br> //if (millis()-Elsp>15) {<br> mouse.move(x,y,z);<br> //Elsp=millis();<br> //}</p>
<p> }<br> else {<br> ESP_LOGI("", "Mouse boot hid transfer too short or long");<br> }<br> }<br> else {<br> ESP_LOGI("", "transfer->status %d", transfer->status);<br> }<br> }<br>}</p>
<p>void check_interface_desc_boot_Mouse(const void *p)<br>{<br> const usb_intf_desc_t *intf = (const usb_intf_desc_t *)p;</p>
<p> if ((intf->bInterfaceClass == USB_CLASS_HID) &&<br> (intf->bInterfaceSubClass == 0x01) &&<br> (intf->bInterfaceProtocol == 0x02)) {<br> isMouse = true;<br> ESP_LOGI("", "Claiming a boot Mouse!");<br> esp_err_t err = usb_host_interface_claim(Client_Handle, Device_Handle,<br> intf->bInterfaceNumber, intf->bAlternateSetting);<br> if (err != ESP_OK) ESP_LOGI("", "usb_host_interface_claim failed: %x", err);<br> }<br>}</p>
<p>void prepare_endpoint(const void *p)<br>{<br> const usb_ep_desc_t *endpoint = (const usb_ep_desc_t *)p;<br> esp_err_t err;</p>
<p> // must be interrupt for HID<br> if ((endpoint->bmAttributes & USB_BM_ATTRIBUTES_XFERTYPE_MASK) != USB_BM_ATTRIBUTES_XFER_INT) {<br> ESP_LOGI("", "Not interrupt endpoint: 0x%02x", endpoint->bmAttributes);<br> return;<br> }<br> if (endpoint->bEndpointAddress & USB_B_ENDPOINT_ADDRESS_EP_DIR_MASK) {<br> err = usb_host_transfer_alloc(Mouse_IN_BUFFER_SIZE, 0, &MouseIn);<br> if (err != ESP_OK) {<br> MouseIn = NULL;<br> ESP_LOGI("", "usb_host_transfer_alloc In fail: %x", err);<br> return;<br> }<br> MouseIn->device_handle = Device_Handle;<br> MouseIn->bEndpointAddress = endpoint->bEndpointAddress;<br> MouseIn->callback = Mouse_transfer_cb;<br> MouseIn->context = NULL;<br> isMouseReady = true;<br> MouseInterval = endpoint->bInterval;<br> ESP_LOGI("", "USB boot Mouse ready");<br> }<br> else {<br> ESP_LOGI("", "Ignoring interrupt Out endpoint");<br> }<br>}</p>
<p>void show_config_desc_full(const usb_config_desc_t *config_desc)<br>{<br> // Full decode of config desc.<br> const uint8_t *p = &config_desc->val[0];<br> static uint8_t USB_Class = 0;<br> uint8_t bLength;<br> for (int i = 0; i < config_desc->wTotalLength; i += bLength, p += bLength) {<br> bLength = *p;<br> if ((i + bLength) <= config_desc->wTotalLength) {<br> const uint8_t bDescriptorType = *(p + 1);<br> switch (bDescriptorType) {<br> case USB_B_DESCRIPTOR_TYPE_DEVICE:<br> ESP_LOGI("", "USB Device Descriptor should not appear in config");<br> break;<br> case USB_B_DESCRIPTOR_TYPE_CONFIGURATION:<br> show_config_desc(p);<br> break;<br> case USB_B_DESCRIPTOR_TYPE_STRING:<br> ESP_LOGI("", "USB string desc TBD");<br> break;<br> case USB_B_DESCRIPTOR_TYPE_INTERFACE:<br> USB_Class = show_interface_desc(p);<br> check_interface_desc_boot_Mouse(p);<br> break;<br> case USB_B_DESCRIPTOR_TYPE_ENDPOINT:<br> show_endpoint_desc(p);<br> if (isMouse && MouseIn == NULL) prepare_endpoint(p);<br> break;<br> case USB_B_DESCRIPTOR_TYPE_DEVICE_QUALIFIER:<br> // Should not be config config?<br> ESP_LOGI("", "USB device qual desc TBD");<br> break;<br> case USB_B_DESCRIPTOR_TYPE_OTHER_SPEED_CONFIGURATION:<br> // Should not be config config?<br> ESP_LOGI("", "USB Other Speed TBD");<br> break;<br> case USB_B_DESCRIPTOR_TYPE_INTERFACE_POWER:<br> // Should not be config config?<br> ESP_LOGI("", "USB Interface Power TBD");<br> break;<br> case 0x21:<br> if (USB_Class == USB_CLASS_HID) {<br> show_hid_desc(p);<br> }<br> break;<br> default:<br> ESP_LOGI("", "Unknown USB Descriptor Type: 0x%x", bDescriptorType);<br> break;<br> }<br> }<br> else {<br> ESP_LOGI("", "USB Descriptor invalid");<br> return;<br> }<br> }<br>}</p>
<p>void setup()<br>{<br> //Serial.begin(115200);</p>
<p> usbh_setup(show_config_desc_full);</p>
<p> mouse.begin();<br>}</p>
<p>void loop()<br>{<br> usbh_task();</p>
<p> if (isMouseReady && !isMousePolling && (MouseTimer > MouseInterval)) {<br> MouseIn->num_bytes = Mouse_IN_BUFFER_SIZE;<br> esp_err_t err = usb_host_transfer_submit(MouseIn);<br> if (err != ESP_OK) {<br> ESP_LOGI("", "usb_host_transfer_submit In fail: %x", err);<br> }<br> isMousePolling = true;<br> MouseTimer = 0;<br> }<br>}</p>
<h3 class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;">*6、BOM清单</h3>
<hr class="horizontal-splitline normal-bold-2">
<p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"><img src="//image.lceda.cn/pullimage/gp0f9gAHYfDxpFrV9YVQCJVLEVKC7y14dcMLtzND.png" alt="" width="1535" height="448"></p>
<p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"> </p>
<h3 class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;">*7、大赛LOGO验证</h3>
<hr class="horizontal-splitline normal-bold-2">
<p style="line-height: 1.8;"> </p>
<p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"><img src="//image.lceda.cn/pullimage/VR4srxCQbPMb47KyPnp4y9zXwGn1qqA9RP1Qd3ec.jpeg" alt="" width="2736" height="3648"></p>
<h3 class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;">* 8、演示您的项目并录制成视频上传</h3>
<hr class="horizontal-splitline normal-bold-2">
<p style="line-height: 1.8;"> </p>
<p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"><span style="color: #95a5a6; font-size: 14px;">视频要求:请横屏拍摄,分辨率不低于1280×720,格式Mp4/Mov,单个视频大小限100M内;</span></p>
<p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"><span style="color: #95a5a6; font-size: 14px;">视频标题:立创电赛:{项目名称}-{视频模块名称};如立创电赛:《自动驾驶》-团队介绍。</span></p>
<p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"> </p>
<p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"><span style="font-size: 14px;">更多详情:<a href="/posts/06c94d90c2c447dfbd9ed7339ff4a5b1" target="_blank">https://diy.szlcsc.com/posts/d76d9cb41705430e9a54e7a5feed07a5</a></span></p>
<p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"> </p>
</div>
评论(0)