极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 32571|回复: 12

新款到货的OCROBOT ALPHA开发板 :ESP8285 + ADS1015 (内含4路ADC 读取程序实例!)

[复制链接]
发表于 2018-4-18 13:47:14 | 显示全部楼层 |阅读模式
本帖最后由 wing 于 2018-4-27 22:28 编辑

重要的事情要写在最前面:ADC程序在10楼


先上个图,介绍和体验楼下再补~~~~





嗯嗯,大神很快就看到重点了  

那么先来分享下更多图



除了8285之外还有锂电





是的8285的ADC并没有标出来






下面会逐步开始试用了

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

 楼主| 发表于 2018-4-18 13:47:55 | 显示全部楼层
本帖最后由 wing 于 2018-4-21 21:38 编辑

下面来看看开发环境配置,开发板管理安装OCROBOT ESP8266 0.1.2版本



选择开发板为OCROBOT ESP8285




首先来试试RSSI程序,代码如下

  1. //ESP8285获取WIFI信号强度
  2. #include "ESP8266WiFi.h"

  3. void setup() {
  4.   Serial.begin(115200);

  5.   // Set WiFi to station mode and disconnect from an AP if it was previously connected
  6.   WiFi.mode(WIFI_STA);
  7.   WiFi.disconnect();
  8.   delay(100);

  9.   Serial.println("Setup done");
  10. }

  11. void loop() {
  12.   Serial.println("scan start");

  13.   // WiFi.scanNetworks will return the number of networks found
  14.   int n = WiFi.scanNetworks();
  15.   Serial.println("scan done");
  16.   if (n == 0)
  17.     Serial.println("no networks found");
  18.   else
  19.   {
  20.     Serial.print(n);
  21.     Serial.println("OCIDE012 networks found");
  22.     for (int i = 0; i < n; ++i)
  23.     {
  24.       // Print SSID and RSSI for each network found
  25.       Serial.print(i + 1);
  26.       Serial.print(": ");
  27.       Serial.print(WiFi.SSID(i));
  28.       Serial.print(" (");
  29.       Serial.print(WiFi.RSSI(i)); //信号强度
  30.       Serial.print(")");
  31.       Serial.println((WiFi.encryptionType(i) == ENC_TYPE_NONE)?" ":"*");
  32.       delay(10);
  33.     }
  34.   }
  35.   Serial.println("");

  36.   // Wait a bit before scanning again
  37.   delay(30000);
  38. }

复制代码


本程序的实现的功能是扫描周围的WIFI信号,并且通过串口输出各个WIFI的信号数值。运行结果:





回复 支持 反对

使用道具 举报

发表于 2018-4-18 20:20:11 | 显示全部楼层
。。。。。我居然忘了画丝印。。。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-4-21 21:43:30 | 显示全部楼层

在OC自家的IDE环境下开发过程顺畅,不过在官方版本的Arduino IDE就不那么顺利了,本次测试所用的版本是1.6.12

开发板型号如下



和二楼相同的程序,就无法通过了



之后会再测测其他版本看看哪个能适配

PS:图片均为一比一截屏,点击可以放大
回复 支持 反对

使用道具 举报

发表于 2018-4-22 11:04:13 | 显示全部楼层
吓屎了。。。看了下新图纸。。。ADC丝印加了。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-4-22 20:05:01 | 显示全部楼层
本帖最后由 wing 于 2018-4-22 20:07 编辑

其实我个人来说找找ADC编号是一个好玩的小游戏,所以我完全不在乎那个印。
当然就产品来说总是要不断完善的。

那么继续来做下一个实验,这次是AP+网页服务,主页面以SPIFFS文件保存,8285内置1M闪存,设置为1M(512K SPIFFS)

程序代码如下

  1. //8266 AP +ws  wifi ssid=ESP8285xxxxxxxx pwd=ap20180422 访问 http://192.168.128.1/h5c_001.html 可见网页  
  2. //页面使用SPIFFS文件保存


  3. #include <ESP8266WiFi.h>
  4. #include <ESP8266WebServer.h>
  5. #include <FS.h>      //文件系统库SPIFFS

  6. ESP8266WebServer server ( 80 );

  7. //OCIDE 0.1.2 似乎并不会超前定义函数 所以请留意函数的顺序

  8. void handleNotFound() {  //404页面
  9.   String message = "File Not Found\n\n";
  10.   message += "URI: ";
  11.   message += server.uri();
  12.   message += "\nMethod: ";
  13.   message += ( server.method() == HTTP_GET ) ? "GET" : "POST";
  14.   message += "\nArguments: ";
  15.   message += server.args();
  16.   message += "\n";

  17.   for ( uint8_t i = 0; i < server.args(); i++ ) {
  18.     message += " " + server.argName ( i ) + ": " + server.arg ( i ) + "\n";
  19.   }

  20.   server.send ( 404, "text/plain", message );  // 返回信息给浏览器(状态码,Content-type, 内容)
  21. }


  22. void ch_page() {  //主页面
  23.   if(SPIFFS.exists("/h5c_001.html")){  //如果文件存在
  24.     File file = SPIFFS.open("/h5c_001.html", "r");              //打开文件
  25.     size_t sent = server.streamFile(file, "text/html");  //发送内容
  26.     file.close();          //关闭文件
  27.     return;
  28.   }
  29.   else
  30.   {
  31.     handleNotFound(); //404
  32.   }
  33. }


  34. void setup() {
  35.   SPIFFS.begin();
  36.   
  37.   // 设置内网
  38.   IPAddress softLocal(192,168,128,1);
  39.   IPAddress softGateway(192,168,128,1);
  40.   IPAddress softSubnet(255,255,255,0);
  41.   WiFi.softAPConfig(softLocal, softGateway, softSubnet);
  42.   String apName = ("ESP8285_"+(String)ESP.getChipId());
  43.   const char *softAPName = apName.c_str();
  44.   WiFi.softAP(softAPName, "ap20180422");
  45.   IPAddress myIP = WiFi.softAPIP();

  46.   //请求响应对象
  47.   server.on ( "/inline", []() {server.send ( 200, "text/plain", "this works as well" );} ); //这句意义重大:当主页不正常时,至少能通过inline显示一个“好”页面
  48.   server.on ( "/h5c_001.html", ch_page );
  49.   server.onNotFound ( handleNotFound );
  50.   server.begin();

  51. }

  52. void loop() {
  53.   server.handleClient();
  54. }

复制代码


在OCIDE编译和上存程序都没有问题,不过上存页面文件就出错了,当然这个功能在8266那时我就没配置成功过
然而强强好像弄成功了




然后回到官方的Arduino 1.6.12,这次选择esp8266版本为2.1.0


值得留意的是这个版本并木有8285这个型号的开发板,所以我用8266来代替


代码能编译,不过程序无法上存,页面文件也上存不了

还是官方的Arduino 1.6.12,这次把esp8266版本升级到2.3.0


2.3.0开始有8285选项了


代码编译的时候提示“建构已经变更,全部重新建构”
看来是大版本更新,然而还是程序和文件都无法上存

我有一种猜测:把GPIO 0接地,强制进入上存模式,再上存。所以这里还想请教下毅神,GPIO 0有没有接出来呢?

虽然官方版本的arduino全灭,不过OCIDE还是把程序上存成了,那么现在接上锂电模块,看看程序除了主页以外的功能是否正常


首先WIFI是能连接上的 。嗯,我看到了一丝曙光


然后inline页面也可以正常显示


当然这里不会是最后,关键的ADC功能还没玩到呢,那么之后还有更多的测试,敬请期待

另外,希望毅神帮忙看看,有没有办法让这板子强制进入上存模式(GPIO 0接地)


回复 支持 反对

使用道具 举报

发表于 2018-4-22 21:55:44 | 显示全部楼层
wing 发表于 2018-4-22 20:05
其实我个人来说找找ADC编号是一个好玩的小游戏,所以我完全不在乎那个印。
当然就产品来说总是要不断完善 ...

GPIO0没有接出来~~~LED下方的圆形mark点,右侧的黑色零件管脚就是GPIO0
回复 支持 反对

使用道具 举报

发表于 2018-4-22 22:02:03 | 显示全部楼层
弘毅 发表于 2018-4-18 20:20
。。。。。我居然忘了画丝印。。。

不是有各脚的丝印么?还要什么丝印
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-4-23 13:19:14 | 显示全部楼层

在毅神的帮助下终于找了GPIO 0的位置了,图上的蓝框和绿框



这里附一份全尺寸的原图



当上存程序或者上存文件之前就要让GPIO 0接地,整个上存过程都要一直保持



首先是上存程序



然后再上存页面文件



终于官方版本的Arduino 1.6.12 + ESP8266 2.3.0 环境下也能完成开发工作了



这里是程序代码,注意这里和6楼的程序在页面文件名称上有些不同

  1. //8266 AP +ws  wifi ssid=ESP8285xxxxxxxx pwd=ap20180422 访问 http://192.168.128.1/h5c_001.htm 可见网页  
  2. //页面使用SPIFFS文件保存


  3. #include <ESP8266WiFi.h>
  4. #include <ESP8266WebServer.h>
  5. #include <FS.h>      //文件系统库SPIFFS

  6. ESP8266WebServer server ( 80 );


  7. void handleNotFound() {  //404页面
  8.   String message = "File Not Found\n\n";
  9.   message += "URI: ";
  10.   message += server.uri();
  11.   message += "\nMethod: ";
  12.   message += ( server.method() == HTTP_GET ) ? "GET" : "POST";
  13.   message += "\nArguments: ";
  14.   message += server.args();
  15.   message += "\n";

  16.   for ( uint8_t i = 0; i < server.args(); i++ ) {
  17.     message += " " + server.argName ( i ) + ": " + server.arg ( i ) + "\n";
  18.   }

  19.   server.send ( 404, "text/plain", message );  // 返回信息给浏览器(状态码,Content-type, 内容)
  20. }


  21. void ch_page() {  //主页面
  22.   if(SPIFFS.exists("/h5c_001.htm")){  //如果文件存在
  23.     File file = SPIFFS.open("/h5c_001.htm", "r");              //打开文件
  24.     size_t sent = server.streamFile(file, "text/html");  //发送内容
  25.     file.close();          //关闭文件
  26.     return;
  27.   }
  28.   else
  29.   {
  30.     handleNotFound(); //404
  31.   }
  32. }


  33. void setup() {
  34.   SPIFFS.begin();
  35.   
  36.   // 设置内网
  37.   IPAddress softLocal(192,168,128,1);
  38.   IPAddress softGateway(192,168,128,1);
  39.   IPAddress softSubnet(255,255,255,0);
  40.   WiFi.softAPConfig(softLocal, softGateway, softSubnet);
  41.   String apName = ("ESP8285_"+(String)ESP.getChipId());
  42.   const char *softAPName = apName.c_str();
  43.   WiFi.softAP(softAPName, "ap20180422");
  44.   IPAddress myIP = WiFi.softAPIP();

  45.   //请求响应对象
  46.   server.on ( "/inline", []() {server.send ( 200, "text/plain", "this works as well" );} );
  47.   server.on ( "/h5c_001.htm", ch_page );
  48.   server.onNotFound ( handleNotFound );
  49.   server.begin();

  50. }

  51. void loop() {
  52.   server.handleClient();
  53. }


复制代码


页面文件名称为h5c_001.htm,位置在程序代码目录下的data文件夹中。
至于页面功能就不要太重视了,反正就是个测试。
下面是页面文件代码

  1. <html>
  2. <head>
  3.   <title>practice20180106</title>

  4. <style>
  5.      canvas {
  6.        cursor: pointer;
  7.        border: 1px solid black;
  8.      }
  9. </style>
  10.    
  11.    
  12. <script>   
  13.     function drawSomething() {
  14.         
  15.     var canvas;
  16.     var context;
  17.         
  18.     canvas = document.getElementById("canvas");
  19.     context = canvas.getContext("2d");        
  20.         
  21.     // 清除画布,准备绘制    运行前要删除注释
  22.     context.clearRect(0, 0, canvas.width, canvas.height);   

  23.     // 绘制圆圈
  24.     context.beginPath();   
  25.     context.globalAlpha = 0.85;
  26.     context.beginPath();
  27.     context.arc(100, 100, 25, 0, Math.PI*2);
  28.     context.fillStyle = "pink";
  29.     context.strokeStyle = "black";

  30.     context.lineWidth = 1;

  31.     context.fill();
  32.     context.stroke();
  33.         
  34.     // 绘制圆弧   
  35.     context.beginPath();   
  36.     context.globalAlpha = 0.85;
  37.     context.beginPath();
  38.     context.arc(150, 150, 80, Math.PI*1.3, Math.PI*1.5,false);
  39.     context.fillStyle = "blue";
  40.     context.strokeStyle = "black";

  41.     context.lineWidth = 4;

  42.     //context.fill();
  43.     context.stroke();         
  44.         

  45.         
  46.     // 绘制新圆弧   
  47.     context.beginPath();   
  48.     context.globalAlpha = 1;
  49.     context.beginPath();
  50.     context.arc(1300, 910, 500,0, Math.PI*1.5);
  51.     context.fillStyle = "blue";
  52.     context.strokeStyle = "black";

  53.     context.lineWidth = 2;

  54.     //context.fill();
  55.     context.stroke();     
  56.         
  57.         
  58.     // 绘制曲线   
  59.     context.beginPath();         
  60.     context.lineWidth = 3;
  61.     context.strokeStyle = "#cd2828";

  62.     //把笔移动到起点位置
  63.     context.moveTo(0, 240);

  64.     //创建变量,保存两个控制点以及曲线终点信息
  65.     var control1_x = 0;
  66.     var control1_y = 100;
  67.     var control2_x = 333;
  68.     var control2_y = 840;
  69.     var endPointX = 333;
  70.     var endPointY = 700;

  71.     //绘制曲线
  72.     context.bezierCurveTo(control1_x, control1_y, control2_x, control2_y, endPointX, endPointY);
  73.     context.stroke();      
  74.     }
  75.      
  76.     function canvasClick(e) {

  77.     var canvas;
  78.     canvas = document.getElementById("canvas");        

  79.     // 取得画布上被单击的点   
  80.     var clickX = e.pageX - canvas.offsetLeft;
  81.     var clickY = e.pageY - canvas.offsetTop;     
  82.    
  83.     //显示坐标         
  84.     var context;
  85.     context = canvas.getContext("2d");   

  86.     // 设置字体        
  87.     context.font = "Bold 20px Arial";
  88.     // 设置对齐方式        
  89.     context.textAlign = "left";
  90.     // 设置填充颜色        
  91.     context.fillStyle = "#008600";
  92.     // 设置字体内容,以及在画布上的位置        
  93.     context.fillText("X="+clickX+"Y="+clickY, 100, 50);     
  94.     }
  95. </script>        
  96.    

  97. </head>  

  98. <body>

  99.   <canvas id="canvas" width="1000" height="700" onmousedown="canvasClick(event)">
  100.   </canvas>

  101.   <div>
  102.     <button onclick="drawSomething()">make_round</button>
  103.   </div>
  104.   
  105. </body>
  106. </html>
复制代码


然后这里是完整的代码


所有都准备好了,那么接上锂电,打开开关,看看测试效果



至此SPIFFS文件功能也终于通过测试了,接下来应该就是期待已久的ADC了吧

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-4-27 23:19:18 | 显示全部楼层
本帖最后由 wing 于 2018-4-27 23:23 编辑

让大家久等了的 ADS1015 4路 ADC 读取程序终于出来了。
本程序还是由8285开AP,做网页服务器,
然后在SPIFFS保存一个页面,
访问这页面后会定时去获取ADS1015 的 4路 ADC数值。
本程序在官方Arduino 1.6.12上开发和编译上存,网页文件由Brackets 1.11编写。

首先是主程序

  1. //8266 AP +ws  wifi ssid=ESP8285xxxxxxxx pwd=ap20180422 访问 http://192.168.128.1/read_adc.htm 可见网页  
  2. //页面使用SPIFFS文件保存,还增加了定时异步更新当前所有adc数值


  3. #include <ESP8266WiFi.h>
  4. #include <ESP8266WebServer.h>
  5. #include <FS.h>      //文件系统库SPIFFS

  6. #include <Wire.h>               //iic接口库
  7. #include <Adafruit_ADS1015.h>   //adc库,居然是出自Ada的

  8. Adafruit_ADS1015 ads;    //定义adc变量

  9. ESP8266WebServer server ( 80 );   //定义web服务

  10. void handleNotFound() {  //404页面
  11.   String message = "File Not Found\n\n";
  12.   message += "URI: ";
  13.   message += server.uri();
  14.   message += "\nMethod: ";
  15.   message += ( server.method() == HTTP_GET ) ? "GET" : "POST";
  16.   message += "\nArguments: ";
  17.   message += server.args();
  18.   message += "\n";

  19.   for ( uint8_t i = 0; i < server.args(); i++ ) {
  20.     message += " " + server.argName ( i ) + ": " + server.arg ( i ) + "\n";
  21.   }

  22.   server.send ( 404, "text/plain", message );  // 返回信息给浏览器(状态码,Content-type, 内容)
  23. }


  24. void ra_page() {  //读取adc数值页面
  25.   if(SPIFFS.exists("/read_adc.htm")){  //如果文件存在
  26.     File file = SPIFFS.open("/read_adc.htm", "r");              //打开文件
  27.     size_t sent = server.streamFile(file, "text/html");  //发送内容
  28.     file.close();          //关闭文件
  29.     return;
  30.   }
  31.   else
  32.   {
  33.     handleNotFound(); //404
  34.   }
  35. }

  36. void adc_values() {  //返回adc值
  37.   String p= "";
  38.   int adc;
  39.   unsigned long systime;

  40.   systime=millis();       //系统时间
  41.   p= String(systime)+":";
  42.   
  43.   adc = ads.readADC_SingleEnded(0);   //获取各路adc的数值
  44.   p=p+String(adc);
  45.   adc = ads.readADC_SingleEnded(1);
  46.   p=p+","+String(adc);
  47.   adc = ads.readADC_SingleEnded(2);
  48.   p=p+","+String(adc);
  49.   adc = ads.readADC_SingleEnded(3);
  50.   p=p+","+String(adc);  

  51.   server.send(200, "text/plain", p);  //抛出返回信息  如果整个过程都没出错,应该返回这样的信息   系统运行毫秒数:0路电压,1路电压,2路电压,3路电压
  52. }


  53. void setup() {
  54.   SPIFFS.begin();  //这个文件系统实例好像在头文件里已经定义好了,无需声明直接开始工作吧
  55.   
  56.   // 设置内网
  57.   IPAddress softLocal(192,168,128,1);
  58.   IPAddress softGateway(192,168,128,1);
  59.   IPAddress softSubnet(255,255,255,0);
  60.   WiFi.softAPConfig(softLocal, softGateway, softSubnet);
  61.   String apName = ("ESP8285_"+(String)ESP.getChipId());
  62.   const char *softAPName = apName.c_str();
  63.   WiFi.softAP(softAPName, "ap20180422");
  64.   IPAddress myIP = WiFi.softAPIP();

  65.   //请求响应对象
  66.   server.on ( "/inline", []() {server.send ( 200, "text/plain", "this works as well" );} ); //这句意义重大:当主页面文件无法顺利上存时,至少能通过inline显示一个“好”页面
  67.   server.on ( "/read_adc.htm", ra_page );
  68.   server.on ( "/adc", adc_values );
  69.   server.onNotFound ( handleNotFound );
  70.   server.begin();    //启动web服务

  71.   ads.begin();  //adc开始工作吧
  72. }

  73. void loop() {
  74.   server.handleClient();
  75. }


复制代码


要提醒大家的是,arduino 1.6.13 + ESP8266 2.3.0 环境下对OC这款板子的自动上存模式支持并不怎么,所以如果要顺利上存程序和页面文件的话最好还是手动把GPIO 0 接地,具体方法请参考9楼

接下来是网页文件代码

  1. <html>
  2.     <head>
  3.         <title>read adc values</title>
  4.         <!--ads1015-->
  5.         <script type="text/javascript">   
  6.         function read_adc()  //get adc values
  7.         {
  8.             var url;
  9.             url ="adc";

  10.             var xhr = new XMLHttpRequest();
  11.             xhr.open("GET", url, true);
  12.             xhr.onreadystatechange = function(e){
  13.             if (xhr.readyState == 4) {
  14.             var rtn = xhr.responseText;
  15.               document.getElementById("textarea").value+= rtn+"\n";
  16.               }
  17.             };   

  18.             xhr.send();
  19.         }
  20.             
  21.         function button_gogogo() //btn_go make anything start once
  22.         {
  23.             document.getElementById("btn_go").disabled = true;
  24.             read_adc();
  25.             self.setInterval('read_adc()',50000);
  26.         }            
  27.         </script>  
  28.         
  29.     </head>
  30.     <body>
  31.         <textarea id="textarea" rows=55 cols=65></textarea>
  32.         <input id="btn_go" type="button" value="gogogo" onclick="button_gogogo()" />   
  33.     </body>
  34. </html>   
复制代码


完整的程序压缩包

页面上有一个硕大的文本框,然后还有一个按钮,点击按钮后页面每隔一段时间就会去获取一次8285的运行时间和0~3路ADC的数值,并逐行显示在文本框上。

在手机上的样子大概是这样的


是的,拍得不怎么样,没对好焦

那么现在来说说ADC测量对象:也就是OC的锂电池,8285由锂电模块提供5V供电,然后把ADS1015的其中2路ADC分别接到18650电池的正负极,另外两个则悬空。




然后用手机连上8285开的WIFI服务,打开页面。
手机上的测试存在一个问题:当黑屏的时候,浏览器也跟着一起休眠了,无法触发页面的定时事件,也就获取不到数值了
下次改下页面弄到PC上再试过





最后简单分析下采集的数据,
测试从今天下午1点半左右开始,
留意文本框的首行
第一个数字41145,这个是8285运作的时间,单位是毫秒,也就是这时运行了41秒
第二个数字是0号ADC的数值这时是4094 这个值比较接近2的12次方,这个值在整个实验过程变化都很小,我认为它表示的是一个接近0的电压,也就是接着18650负极
第三个数字 这个数值变化也不大,应该是悬空的
第四个数字 1373,这个数值一直在慢慢减少,根据ADS1x15的资料
  //                                                                                             ADS1015  ADS1115
  //                                                                                               -------     -------
  // ads.setGain(GAIN_TWOTHIRDS);  // 2/3x gain +/- 6.144V  1 bit = 3mV      0.1875mV (default)
  // ads.setGain(GAIN_ONE);              // 1x gain   +/- 4.096V  1 bit = 2mV      0.125mV
  // ads.setGain(GAIN_TWO);             // 2x gain   +/- 2.048V  1 bit = 1mV      0.0625mV
  // ads.setGain(GAIN_FOUR);            // 4x gain   +/- 1.024V  1 bit = 0.5mV    0.03125mV
  // ads.setGain(GAIN_EIGHT);           // 8x gain   +/- 0.512V  1 bit = 0.25mV   0.015625mV
  // ads.setGain(GAIN_SIXTEEN);        // 16x gain  +/- 0.256V  1 bit = 0.125mV  0.0078125mV

默认状态下ADS1015 每一点表示3毫伏,1373*0.03=4.11 接近18650最高电压4.2,这时电池基本是满电的
第五个数字 这个数值变化也不大,应该也是悬空的

测试一直持续了将近5个小时,直到晚上六点多。
最后一行时间为19410742,换算为小时  19410742/(1000*60*60)=4.8
电压为1246,1246*0.03=3.77

当然上面的计算只是我自己的理解,还请毅毅强强多多指正。


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

发表于 2018-4-28 09:59:24 | 显示全部楼层
嗯。。。。这个ADC支持差分输入~~~
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-4-28 13:01:59 | 显示全部楼层
其实我没弄明白这个函数ads.setGain();是干什么的,看上去会影响量程和精度
回复 支持 反对

使用道具 举报

发表于 2018-4-28 13:54:49 | 显示全部楼层
wing 发表于 2018-4-28 13:01
其实我没弄明白这个函数ads.setGain();是干什么的,看上去会影响量程和精度

内部放大器放大倍率调整吧
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-4-19 13:34 , Processed in 0.046747 second(s), 20 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表