找回密码
 马上注册

QQ登录

只需一步,快速开始

查看: 19117|回复: 21

PC&NXT蓝牙数据传递

[复制链接]
发表于 2011-2-18 21:07:11 | 显示全部楼层 |阅读模式
本帖最后由 junf 于 2011-2-28 20:32 编辑

最近在做创新大赛,需要PC与NXT互联,目前已经找到了PC向NXT传字符串代码http://www.cmnxt.com/thread-4358-2-1.html,感谢作者grant7788

现在需要PC向NXT发数字或者是在NXC中处理字符串方法(根据传感器写字符串,读取字符串,判断比较),原程序如下:
task main()
{
    string in;
    while(true)
    {
        ReceiveRemoteString(MAILBOX1, true, in);
        TextOut(10,LCD_LINE3,in);
        Wait(100);
    }
}

还需要NXT向PC发字符串或者数字两端代码(使用C/C++&NXC)

另在grant7788帖子里读取电量程序中
byteOut[3] = 0xB;        // 0x0B为读回电池状态
0xB应该表示的是一串地址,网上看到可以直接读取传感器数值,请问直接地址应该是什么?是否该完地址就能直接变为读传感器程序?(如果我理解有误,请纠正)

PS:附件是一个公开代码的有PC读NXT传感器功能的程序,源程序使用C#编的,如果有看的懂得帮忙解释一下或者用C++翻译一下,谢谢。

onbrick_源文件.zip

273.75 KB, 下载次数: 32

onbrick_pc.zip

356.83 KB, 下载次数: 23

如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
发表于 2011-2-18 23:17:31 | 显示全部楼层
楼主,所有相关的命令字的意义,以及返回值等等,都在乐高的蓝牙编程手册里。
在乐高Mindstorm官网上有的,蓝牙相关的有4个PDF,你去看一下。
你要的内容应该在:"Appendix 2-LEGO MINDSTORMS NXT Direct commands.pdf"这个文件里。
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2011-2-18 23:33:56 | 显示全部楼层
本帖最后由 grant7788 于 2011-2-18 23:34 编辑

楼主,我最近对Python比较有兴趣,把之前写到一半的类库改了一下。
读mailbox message的代码片段如下:
  1.     # read message string from NXT
  2.     def btreadmessage(self, mailbox = 0):
  3.         if self.serial.isOpen():
  4.             senddata = bytes([0x5, 0x0, 0x0, 0x13]) # 0xa, 0x0, 0x1])
  5.             senddata = senddata + chr(mailbox + 0xa).encode() + bytes([0x0, 0x1])
  6.             i = self.serial.write(senddata)
  7.             print("%d bytes read from mailbox!" % i)
  8.             time.sleep(1)
  9.             n = self.serial.inWaiting()
  10.             if n:
  11.                 readdata = self.serial.read(n)
  12.                 readdata = readdata[5:]
  13.                 return(readdata)
  14.             else:
  15.                 return("")
复制代码
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2011-2-18 23:35:02 | 显示全部楼层
调用的相关代码如下:
  1. import sys,time
  2. import serial
  3. from btcommcls import *

  4. btport = BTComm("COM8")
  5. if (btport.btopen() != 0):
  6.     print ("Error open Bluetooth port!")
  7. else:
  8.     s = btport.btreadmessage(0)
  9.     print(s)
  10. btport.btclose()
复制代码
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2011-2-18 23:37:28 | 显示全部楼层
详细情况可以看代码或是看我上面说的那份PDF文档。总共12页而已,和你的任务有关的大概只有一、两页。
注意几件事情:
1. 读取mailbox的内容时,和读取电压或是firmware的代码类似,是要先发命令下去,然后读回来数据。
2. 发命令时,mailbox的值是从十进制的10,或是说16进制的0xa开始的。而不是0x0开始(向从机发信息是从0x0开始)。
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2011-2-19 00:23:57 | 显示全部楼层
NXT端使用函数:
  1.     RemoteMessageWrite (0, MAILBOX1, "Hello, cmnxt!");
复制代码
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

 楼主| 发表于 2011-2-19 10:01:13 | 显示全部楼层
回复 grant7788 的帖子

请问PC接受用C/C++应该怎么写。。。
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2011-2-19 10:27:48 | 显示全部楼层
junf 发表于 2011-2-19 10:01
回复 grant7788 的帖子

请问PC接受用C/C++应该怎么写。。。

我提供你Python的类库的全部源码:
  1. #btcommcls.py
  2. # class to handle the communication via bluetooth with NXT
  3. # need pyserial, download from: http://pyserial.sourceforge.net/
  4. # by Grant, 2011-2-13

  5. import sys, time
  6. import serial

  7. class BTComm:
  8.     def __init__(self, comport = "COM8"):
  9.         self.serial = serial.Serial()
  10.         self.serial.port = comport #"COM8"
  11.         self.serial.baudrate = 96000
  12.         self.serial.timeout = 3
  13.         self.serial.bytesize = 7
  14.         self.serial.parity = 'O'
  15.         self.serial.stopbits = 1

  16.     def btopen(self):
  17.         try:
  18.             self.serial.open()
  19.             if self.serial.isOpen():
  20.                 print("Bluetooth connection ok!")
  21.                 return(0)
  22.             else:
  23.                 return(-1)
  24.         except Exception as ex:
  25.             print("Error!\n%s" % ex)
  26.             if self.serial.isOpen():
  27.                 self.serial.close()

  28.     def btclose(self):
  29.         if self.serial.isOpen():
  30.             self.serial.close()

  31.     # read message string from NXT
  32.     def btreadmessage(self, mailbox = 0):
  33.         if self.serial.isOpen():
  34.             # senddata = bytes([0x5, 0x0, 0x0, 0x13, 0xa, 0x0, 0x1])
  35.             senddata = bytes([0x5, 0x0, 0x0, 0x13]) # 0xa, 0x0, 0x1])
  36.             senddata = senddata + chr(mailbox + 0xa).encode() + bytes([0x0, 0x1])
  37.             print("Senddata = %s" % senddata)
  38.             i = self.serial.write(senddata)
  39.             print("%d bytes write to mailbox!" % i)
  40.             time.sleep(1)
  41.             n = self.serial.inWaiting()
  42.             print("%d bytes read from mailbox!" % n)
  43.             if n:
  44.                 readdata = self.serial.read(n)
  45.                 # readdata = readdata[5:]
  46.                 return(readdata)
  47.             else:
  48.                 return("")
  49.             
  50.     # send a message string to NXT (by default: mailbox 1).
  51.     def btsendmessage(self, strMessage, mailbox = 0):
  52.         if self.serial.isOpen():
  53.             ilength = len(strMessage)
  54.             senddata = bytes([0x0, 0x80, 0x9])
  55.             senddata = (chr(ilength+5)).encode() + senddata
  56.             senddata = senddata + chr(mailbox).encode() + (chr(ilength+1)).encode()
  57.             senddata = senddata + strMessage.encode() + b'\0'
  58.             icount = self.serial.write(senddata)
  59.             return(icount)

  60.     # send a logic value (0 / 1) to NXT.
  61.     def btsetlogic(self, bLogic, mailbox = 0):
  62.         if self.serial.isOpen():
  63.             senddata = bytes([0x6, 0x0, 0x80, 0x9])
  64.             senddata = senddata + chr(mailbox).encode() + chr(0x2).encode()
  65.             senddata = senddata + (chr(bLogic)).encode()
  66.             senddata = senddata + (chr(0x0)).encode()
  67.             icount = self.serial.write(senddata)
  68.             return(icount)

  69.     # send a value to NXT. not ready yet.
  70.     def btsendvalue(self, value, mailbox = 0):
  71.         if self.serial.isOpen():
  72.             senddata = bytes([0x6, 0x0, 0x80, 0x9])
  73.             senddata = senddata + chr(mailbox).encode() + chr(0x5).encode()
  74.             for i in range(4):
  75.                 senddata = senddata + (chr(value & 0xff)).encode('latin-1')
  76.                 value = int(value / 256)
  77.             # senddata = senddata + (chr(value)).encode()
  78.             senddata = senddata + (chr(0x0)).encode()
  79.             icount = self.serial.write(senddata)
  80.             return(icount)

  81.     # function to read back the voltage of battery, in mili-volt
  82.     def btreadnxtbattery(self):
  83.         if self.serial.isOpen():
  84.             self.serial.write(bytes([0x2, 0x0, 0x0, 0xb]))
  85.             time.sleep(1)
  86.                
  87.             n = self.serial.inWaiting()
  88.             if n:
  89.                 c = self.serial.read(n)
  90.                 batterymilivolt = c[n-2] + c[n-1]*256
  91.                 return(batterymilivolt)
  92.             else:
  93.                 print("No data back from serial port!")
  94.                 return(0)
  95.         else:
  96.             print("Bluetooth port connect fail!")
  97.             return(-1)

  98.     # function to read back the firmware version.
  99.     def btgetfirmwareversion(self):
  100.         if self.serial.isOpen():
  101.             senddata = bytes([0x2, 0x0, 0x01, 0x88])
  102.             self.serial.write(senddata)
  103.             time.sleep(1)

  104.             n = self.serial.inWaiting()
  105.             if n:
  106.                 c = self.serial.read(n)
  107.                 firmwareversion = str(c[8]) + "." + str(c[7])
  108.                 return(firmwareversion)
  109.             else:
  110.                 return("")
  111.             
复制代码



如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2011-2-19 10:30:00 | 显示全部楼层
再提供你VC下的类库的源码,但是不完整,不过SendMessage之类的是完整的。

头文件:
  1. #if !defined _NXT_BT_H_
  2. #define _NXT_BT_H_

  3. #include <windows.h>

  4. class CNXT_BT_Class
  5. {
  6. public:
  7.         CNXT_BT_Class();                                                // 构造函数,设置串口基本参数,打开串口
  8.         CNXT_BT_Class(char* strComPortName);        // 构造函数,设置串口基本参数,打开串口
  9.         ~CNXT_BT_Class();                                                // 析构函数,关闭串口,释放内存

  10. private:
  11.         HANDLE hCom;                // 文件句柄,指向蓝牙虚拟的串口
  12.         int iRetCode;                // 保存返回值,以备查询。无错误时为0

  13.         char* strComPort;        // 代表串口的字符串。在我的电脑上应该是"COM8"
  14.         int iBaudRate;                // 波特率

  15.         int iMailBoxIdx;        // NXT对应的mailbox

  16.         unsigned char byteIn[64];                // 输入用字符串
  17.         unsigned char byteOut[64];                // 输出用字符串
  18.         unsigned char byteTemp[256];        // 临时用字符串

  19. public:
  20.         int SetMailBoxIndex(int iMailBoxIndex);        // 设置NXT mailbox。构造函数中默认设成mailbox 1 (对应值为0)
  21.         int BTSendLogic(bool bLogic);                        // 设置NXT mailbox的logic value。用于NXT-G中蓝牙设成logic时,true/false
  22.         int BTSendMessage(char* strMessage);        // 发送字符串
  23.         int BTReadMessage();                                        // 读回字符串
  24.         int GetBatteryLevel();                                        // 读回电池电量,毫伏
  25.         int GetFirmwareVersion(double* ProtocolVer, double* FirmwareVer); // 读回NXT firmware值,尚未写好。
  26. };

  27. #endif
复制代码
程序文件:
  1. #include "NXT_BT.H"
  2. #include <windows.h>
  3. #include <string.h>
  4. #include <stdio.h>

  5. CNXT_BT_Class::CNXT_BT_Class()
  6. {
  7.         int iRetVal;
  8.         DWORD iErrCode;

  9.         strComPort = new char[strlen("COM8")];
  10.         strComPort = "COM8";
  11.         iBaudRate = 96000;

  12.         iMailBoxIdx = 0;

  13.         hCom=CreateFile("COM8", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
  14.         if(hCom==(HANDLE)-1)
  15.         {
  16.                 iRetCode = -1;
  17.                 return;
  18.         }
  19.         COMMTIMEOUTS TimeOuts;
  20.         //设定读超时
  21.         TimeOuts.ReadIntervalTimeout=MAXDWORD;
  22.         TimeOuts.ReadTotalTimeoutMultiplier=0;
  23.         TimeOuts.ReadTotalTimeoutConstant=0;
  24.        
  25.         //设定写超时
  26.         TimeOuts.WriteTotalTimeoutMultiplier=100;
  27.         TimeOuts.WriteTotalTimeoutConstant=500;
  28.         iRetVal = SetCommTimeouts(hCom,&TimeOuts); //设置超时
  29.        
  30.         DCB dcb;
  31.         iRetVal = GetCommState(hCom,&dcb);
  32.         // 设定串口参数
  33.         dcb.BaudRate = iBaudRate;        //波特率为9600
  34.         dcb.ByteSize = 7;                        //每个字节有7位
  35.         dcb.Parity = 2;                                //偶校验
  36.         dcb.StopBits = 0;                        //无停止位
  37.         iRetVal = SetCommState(hCom, &dcb);
  38.         if (iRetVal == 0)
  39.         {
  40.                 iErrCode = GetLastError();
  41.                 iRetCode = iErrCode;
  42.                 CloseHandle(hCom);
  43.                 return;
  44.         }
  45.        
  46.         PurgeComm(hCom,PURGE_TXCLEAR|PURGE_RXCLEAR);
  47.         iRetCode = 0;
  48.         return;
  49. }

  50. CNXT_BT_Class::CNXT_BT_Class(char* strComPortName)
  51. {
  52.         int iRetVal;
  53.         DWORD iErrCode;

  54.         strComPort = new char[strlen(strComPortName)];
  55.         strComPort = strComPortName;
  56.         iBaudRate = 96000;

  57.         iMailBoxIdx = 0;

  58.         hCom=CreateFile("COM8", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
  59.         if(hCom==(HANDLE)-1)
  60.         {
  61.                 iRetCode = -1;
  62.                 return;
  63.         }
  64.         ::Sleep(100); // wait the device ready

  65.         COMMTIMEOUTS TimeOuts;
  66.         //设定读超时
  67.         TimeOuts.ReadIntervalTimeout=MAXDWORD;
  68.         TimeOuts.ReadTotalTimeoutMultiplier=0;
  69.         TimeOuts.ReadTotalTimeoutConstant=0;
  70.        
  71.         //设定写超时
  72.         TimeOuts.WriteTotalTimeoutMultiplier=100;
  73.         TimeOuts.WriteTotalTimeoutConstant=500;
  74.         iRetVal = SetCommTimeouts(hCom,&TimeOuts); //设置超时
  75.        
  76.         DCB dcb;
  77.         iRetVal = GetCommState(hCom,&dcb);
  78.         // 设定串口参数
  79.         dcb.BaudRate = iBaudRate;        //波特率为9600
  80.         dcb.ByteSize = 7;                        //每个字节有7位
  81.         dcb.Parity = 2;                                //偶校验
  82.         dcb.StopBits = 0;                        //无停止位
  83.         iRetVal = SetCommState(hCom, &dcb);
  84.         if (iRetVal == 0)
  85.         {
  86.                 iErrCode = GetLastError();
  87.                 iRetCode = iErrCode;
  88.                 CloseHandle(hCom);
  89.                 return;
  90.         }
  91.        
  92.         PurgeComm(hCom,PURGE_TXCLEAR|PURGE_RXCLEAR);
  93.         iRetCode = 0;
  94.         return;
  95. }

  96. CNXT_BT_Class::~CNXT_BT_Class()
  97. {
  98.         if (hCom)
  99.         {
  100.                 CloseHandle(hCom);
  101.         }
  102. }

  103. int CNXT_BT_Class::SetMailBoxIndex(int iMailBoxIndex)
  104. {
  105.         iMailBoxIdx = iMailBoxIndex;
  106.         return iMailBoxIdx;
  107. }

  108. int CNXT_BT_Class::BTSendLogic(bool bLogic)
  109. {
  110.         DWORD iBytes;
  111.         BOOL bRetVal;

  112.         byteOut[0] = 0x6;        // 消息长度6字节
  113.         byteOut[1] = 0x0;        // NXT为0
  114.         byteOut[2] = 0x80;        // 需要回复。如不需要回复为0x80
  115.         byteOut[3] = 0x9;        // 0x09为发送消息
  116.         byteOut[4] = 0x0;
  117.         byteOut[5] = 0x2;
  118.         byteOut[6] = bLogic;
  119.         byteOut[7] = 0x0;
  120.        
  121.         bRetVal = WriteFile(hCom, byteOut, 8, &iBytes, NULL);
  122.         return bRetVal;
  123. }

  124. int CNXT_BT_Class::BTSendMessage(char* strMessage)
  125. {
  126.         DWORD iBytes;
  127.         BOOL bRetVal;
  128.         int iMsgLength;

  129.         iMsgLength = strlen(strMessage);
  130.         byteOut[0] = iMsgLength + 5;                        // 消息长度
  131.         byteOut[1] = 0x0;                                                // NXT为0
  132.         byteOut[2] = 0x80;                                                // 不需要回复。如需要回复为0x0
  133.         byteOut[3] = 0x9;                                                // 0x09为通过Bluetooth发送信息给NXT
  134.         byteOut[4] = 0x0;                                                // Box Number ---- 1
  135.         byteOut[5] = iMsgLength + 1;                        // 发送的字符串的字节数
  136.         for (int i=0; i<iMsgLength; i++)
  137.         {
  138.                 byteOut[6+i] = *(strMessage+i);
  139.         }
  140.         byteOut[iMsgLength+6] = '\0';

  141.         bRetVal = WriteFile(hCom, byteOut, iMsgLength+7, &iBytes, NULL);
  142.         return iBytes;
  143. }

  144. int CNXT_BT_Class::BTReadMessage()
  145. {
  146.         int iRetVal;
  147.         DWORD iBytes;

  148.         iRetVal = ReadFile(hCom, &byteIn[0], 1, &iBytes, NULL);        // 返回消息字节数
  149.         iRetVal = ReadFile(hCom, &byteIn[1], 1, &iBytes, NULL);        // NXT为0

  150.         for (int i=2; i<=byteIn[0]+1; i++)
  151.         {
  152.                 iRetVal = ReadFile(hCom, &byteIn[i], 1, &iBytes, NULL); // 读回全部消息
  153.         }
  154.         return byteIn[0]+3;
  155. }

  156. int CNXT_BT_Class::GetBatteryLevel()
  157. {
  158.         int iBatteryLevel;
  159.         BOOL bRetVal;
  160.         DWORD iBytes;

  161.         // 以下发命令到NXT主机
  162.         byteOut[0] = 0x2;        // 消息长度2字节
  163.         byteOut[1] = 0x0;        // NXT为0
  164.         byteOut[2] = 0x0;        // 需要回复。如不需要回复为0x80
  165.         byteOut[3] = 0xB;        // 0x0B为读回电池状态
  166.         bRetVal = WriteFile(hCom, byteOut, 4, &iBytes, NULL);
  167.         ::Sleep(800);                // 给NXT准备的时间。经测试,至少700ms

  168.         // 从NXT主机读回数据,前两字节代表消息长度
  169.         bRetVal = ReadFile(hCom, &byteIn[0], 1, &iBytes, NULL);        // 返回消息字节数
  170.         bRetVal = ReadFile(hCom, &byteIn[1], 1, &iBytes, NULL);        // NXT为0

  171.         for (int i=2; i<=byteIn[0]+1; i++)
  172.         {
  173.                 bRetVal = ReadFile(hCom, &byteIn[i], 1, &iBytes, NULL); // 读回全部消息
  174.         }
  175.         iBatteryLevel = byteIn[5] + byteIn[6]*256;                // 换算成电压
  176.         return iBatteryLevel;
  177. }

  178. int CNXT_BT_Class::GetFirmwareVersion(double* ProtocolVer, double* FirmwareVer)
  179. {
  180.         BOOL bRetVal;
  181.         DWORD iBytes;

  182.         // 以下发命令到NXT主机
  183.         byteOut[0] = 0x2;        // 消息长度2字节
  184.         byteOut[1] = 0x0;        // NXT为0
  185.         byteOut[2] = 0x1;        // 需要回复。如不需要回复为0x80
  186.         byteOut[3] = 0x88;        // 0x0B为读回电池状态
  187.         bRetVal = WriteFile(hCom, byteOut, 4, &iBytes, NULL);
  188.         ::Sleep(800);                // 给NXT准备的时间。经测试,至少700ms

  189.         // 从NXT主机读回数据,前两字节代表消息长度
  190.         for (int i=0; i<7; i++)
  191.         {
  192.             bRetVal = ReadFile(hCom, &byteIn[i], 1, &iBytes, NULL);        // 返回消息字节数
  193.                 // printf("Byte %d = %d\n", i, byteIn[i]);
  194.         }

  195.         *ProtocolVer = byteIn[4] + (double)(byteIn[3])/100.0;                // Protocol Version
  196.         *FirmwareVer = byteIn[6] + (double)(byteIn[5])/100.0;                // Firmware Version
  197.         return 1;
  198. }
复制代码
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2011-2-19 10:32:23 | 显示全部楼层
本帖最后由 grant7788 于 2011-2-19 10:34 编辑

以上两帖请对照看一下,再看一下我在2#回复你的那个文档,
试试自己把ReadMessage的函数用VC实现一下吧。(VC代码中目前的ReadMessage是错的)

实际上我前面两帖的内容,在论坛里全部发过了。
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

 楼主| 发表于 2011-2-19 22:54:21 | 显示全部楼层
回复 grant7788 的帖子

读了那pdf,实在看不懂,能麻烦帮忙写一下C++收信息的完整的程序吗?
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2011-2-19 23:25:06 | 显示全部楼层
junf 发表于 2011-2-19 22:54
回复 grant7788 的帖子

读了那pdf,实在看不懂,能麻烦帮忙写一下C++收信息的完整的程序吗?

英文这一关,总归要过的。85%的代码已经放在你的面前了,自己总归要看懂、自己实现吧?
你可以试着读、试着写,有什么不懂的来回帖问。
你的指导老师难道告诉你说;找段代码抄了就好了?
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2011-2-20 09:29:56 | 显示全部楼层
grant7788 发表于 2011-2-19 23:25
英文这一关,总归要过的。85%的代码已经放在你的面前了,自己总归要看懂、自己实现吧?
你可以试着读、试 ...

就是就是!蒋!你不用辛苦啦!我找到了vb与nxt互联的代码了!
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2011-2-20 14:20:20 | 显示全部楼层
jerryyuzhihao 发表于 2011-2-20 09:29
就是就是!蒋!你不用辛苦啦!我找到了vb与nxt互联的代码了!

是,VB下应该也是一样的。不过VB对字符串的处理没有VC或是Python这么方便。还是那句话,编程思想和数据结构搞清楚之后,用什么语言实现其实都差不多。
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

 楼主| 发表于 2011-2-21 21:55:32 | 显示全部楼层
本帖最后由 junf 于 2011-2-21 22:01 编辑

回复 grant7788 的帖子

我自己看了pdf编程,改了读电量程序变为读信息(图一)


但是返回的字符数byte0总是-108,我不清楚哪里出错了(图二)


NXT上用的是
task main()
{   while(true)
    {
        RemoteMessageWrite (0, MAILBOX1, "Hello, cmnxt!");
    }
}

麻烦指教
1.JPG
2.JPG
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

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

本版积分规则

手机版|中文乐高 ( 桂ICP备13001575号-7 )

GMT+8, 2024-12-22 20:16 , Processed in 0.227468 second(s), 21 queries .

Powered by Discuz! X3.5

Copyright © 2001-2020, Tencent Cloud.

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