感谢资磁!
自立下flag已经过去了3个多月,整天画图奔波忙到吐。然后。。。然后就忘记发帖了(跪)
香蕉君可能会迟到,但他从不缺席(误)。
项目说明:
1.搭载仓鼠一只。
2.携带心率血氧传感器对其记录在强加速度下生物体征数据的变化。
3.携带气压传感器测量高度海拔与温度。
4.携带三轴加速度计完成开伞和飞行数据测量。
5.携带sd卡模块记录全部数据。
6.搭载宏天云图传及高清运动相机,实时完成火箭航拍并记录影像。
7.搭载miniDV(夜视)监测生物舱装况并记录影像。
传感器及电子元件清单
注:图中一些元件并没有用到(如hx711用作试车台推力计)
arduino尽管性能不佳,但如此小巧简单还是用作航电开发板的首选。。嗯。老板来两片
mpu6050,强大。@彩虹之巅,详见XXXXXXXXXXXXXXXXXXXXXXXX/t/55025(很多同学反映GitHub上面下载的库文件会带有网页地址,影响程序编译,整理了一下贴过来方便大家使用)
max30102,心率血氧模块,非常小巧好用。上资料:
MH-ET LIVE _MAX30102 Ardunio.zip
bmp180,非常常见的气压计。上代码:
//Arduino 1.0+ Only //Arduino 1.0+ Only /*Based largely on code by Jim Lindblom Get pressure, altitude, and temperature from the BMP085. Serial.print it out at 9600 baud to serial monitor. */ #include <wire.h> #define BMP085_ADDRESS 0x77 // I2C address of BMP085 const unsigned char OSS = 0; // Oversampling Setting // Calibration values int ac1; int ac2; int ac3; unsigned int ac4; unsigned int ac5; unsigned int ac6; int b1; int b2; int mb; int mc; int md; // b5 is calculated in bmp085GetTemperature(...), this variable is also used in bmp085GetPressure(...) // so ...Temperature(...) must be called before ...Pressure(...). long b5; void setup(){ Serial.begin(9600); Wire.begin(); bmp085Calibration(); } void loop() { float temperature = bmp085GetTemperature(bmp085ReadUT()); //MUST be called first float pressure = bmp085GetPressure(bmp085ReadUP()); float atm = pressure / 101325; // "standard atmosphere" float altitude = calcAltitude(pressure); //Uncompensated caculation - in Meters Serial.print("Temperature: "); Serial.print(temperature, 2); //display 2 decimal places Serial.println("deg C"); Serial.print("Pressure: "); Serial.print(pressure, 0); //whole number only. Serial.println(" Pa"); Serial.print("Standard Atmosphere: "); Serial.println(atm, 4); //display 4 decimal places Serial.print("Altitude: "); Serial.print(altitude, 2); //display 2 decimal places Serial.println(" M"); Serial.println();//line break delay(1000); //wait a second and get values again. } // Stores all of the bmp085's calibration values into global variables // Calibration values are required to calculate temp and pressure // This function should be called at the beginning of the program void bmp085Calibration() { ac1 = bmp085ReadInt(0xAA); ac2 = bmp085ReadInt(0xAC); ac3 = bmp085ReadInt(0xAE); ac4 = bmp085ReadInt(0xB0); ac5 = bmp085ReadInt(0xB2); ac6 = bmp085ReadInt(0xB4); b1 = bmp085ReadInt(0xB6); b2 = bmp085ReadInt(0xB8); mb = bmp085ReadInt(0xBA); mc = bmp085ReadInt(0xBC); md = bmp085ReadInt(0xBE); } // Calculate temperature in deg C float bmp085GetTemperature(unsigned int ut){ long x1, x2; x1 = (((long)ut - (long)ac6)*(long)ac5) >> 15; x2 = ((long)mc << 11) (x1 + md); b5 =" x1 + x2;" float temp =" ((b5 + 8)">>4); temp = temp /10; return temp; } // Calculate pressure given up // calibration values must be known // b5 is also required so bmp085GetTemperature(...) must be called first. // Value returned will be pressure in units of Pa. long bmp085GetPressure(unsigned long up){ long x1, x2, x3, b3, b6, p; unsigned long b4, b7; b6 = b5 - 4000; // Calculate B3 x1 = (b2 * (b6 * b6)>>12)>>11; x2 = (ac2 * b6)>>11; x3 = x1 + x2; b3 = (((((long)ac1)*4 + x3)<<oss) + 2)>>2; // Calculate B4 x1 = (ac3 * b6)>>13; x2 = (b1 * ((b6 * b6)>>12))>>16; x3 = ((x1 + x2) + 2)>>2; b4 = (ac4 * (unsigned long)(x3 + 32768))>>15; b7 = ((unsigned long)(up - b3) * (50000>>OSS)); if (b7 < 0x80000000) p =" (b7<<1)/b4;" else x1 =" (p">>8) * (p>>8); x1 = (x1 * 3038)>>16; x2 = (-7357 * p)>>16; p += (x1 + x2 + 3791)>>4; long temp = p; return temp; } // Read 1 byte from the BMP085 at 'address' char bmp085Read(unsigned char address) { unsigned char data; Wire.beginTransmission(BMP085_ADDRESS); Wire.write(address); Wire.endTransmission(); Wire.requestFrom(BMP085_ADDRESS, 1); while(!Wire.available()) ; return Wire.read(); } // Read 2 bytes from the BMP085 // First byte will be from 'address' // Second byte will be from 'address'+1 int bmp085ReadInt(unsigned char address) { unsigned char msb, lsb; Wire.beginTransmission(BMP085_ADDRESS); Wire.write(address); Wire.endTransmission(); Wire.requestFrom(BMP085_ADDRESS, 2); while(Wire.available()<2) ; msb =" Wire.read();" lsb =" Wire.read();" return (int) msb<<8 | lsb; } read the uncompensated temperature value unsigned int bmp085readut(){ unsigned int ut; write 0x2e into register 0xf4 this requests a temperature reading wire.begintransmission(bmp085_address); wire.write(0xf4); wire.write(0x2e); wire.endtransmission(); wait at least 4.5ms delay(5); read two bytes from registers 0xf6 and 0xf7 ut =" bmp085ReadInt(0xF6);" return ut; read the uncompensated pressure value unsigned long bmp085readup(){ unsigned char msb, lsb, xlsb; unsigned long up =" 0;" write 0x34+(oss<<6) into register 0xf4 request a pressure reading w oversampling setting wire.write(0x34 + (oss<<6)); wait for conversion, delay time dependent on oss delay(2 + (3<<oss)); read register 0xf6 (msb), 0xf7 (lsb), and 0xf8 (xlsb) xlsb =" bmp085Read(0xF8);" up =" (((unsigned long) msb << 16) | ((unsigned long) lsb << 8) | (unsigned long) xlsb) ">> (8-OSS); return up; } void writeRegister(int deviceAddress, byte address, byte val) { Wire.beginTransmission(deviceAddress); // start transmission to device Wire.write(address); // send register address Wire.write(val); // send value to write Wire.endTransmission(); // end transmission } int readRegister(int deviceAddress, byte address){ int v; Wire.beginTransmission(deviceAddress); Wire.write(address); // register to read Wire.endTransmission(); Wire.requestFrom(deviceAddress, 1); // read a byte while(!Wire.available()) { // waiting } v = Wire.read(); return v; } float calcAltitude(float pressure){ float A = pressure/101325; float B = 1/5.25588; float C = pow(A,B); C = 1 - C; C = C /0.0000225577; return C; }</2)></ 0x80000000)></oss) + 2)></ 11)></wire.h>
sd卡模块(注意带电平转换)
继电器模块(可用三极管代替)
gps模块(需要sim800c支持gprs数据传输至onenet云,然后运存又炸了,然后就需要2560,然后。。就没有然后了。最后搞了个tcl的成品gps+北斗跟踪器)
在这里还是讲述一下这个悲伤的故事叭= =
测试123 qwq(因为在室内。。根本搜不到星)
后来在室外也搜不到,,商家的陶瓷天线我认为一点用都没有。。。
故接上了3m长的强大天线= =(收到了信号√)
资料包XXXXXXXXXXXXXXXXXXXXXXXX/t/83599
因为要远程监控轨迹,所以就用到了物联网数据整合利器onenet平台XXXXXXXXXXXXXXXXXXXXXXXXX/
申请项目找到自己设备的key然后把key填写至sim800c或其他gprs模块的代码中去,就可以实时记录项目数据了
代码:
#include <timerone.h> #define DebugSerial Serial #define GprsSerail Serial3 #define GpsSerial Serial2 struct { char GPS_Buffer[80]; bool isGetData; //是否获取到GPS数据 bool isParseData; //是否解析完成 char UTCTime[11]; //UTC时间 char latitude[11]; //纬度 char N_S[2]; //N/S char longitude[12]; //经度 char E_W[2]; //E/W bool isUsefull; //定位信息是否有效 } Save_Data; const unsigned int gpsRxBufferLength = 600; char gpsRxBuffer[gpsRxBufferLength]; unsigned int gpsRxCount = 0; #define Success 1U #define Failure 0U int L = 13; //LED指示灯引脚 unsigned long Time_Cont = 0; //定时器计数器 const unsigned int gprsRxBufferLength = 600; char gprsRxBuffer[gprsRxBufferLength]; unsigned int gprsBufferCount = 0; char OneNetServer[] = "api.heclouds.com"; //不需要修改 char device_id[] = "3225187"; //修改为自己的设备ID char API_KEY[] = "R9xO5NZm6oVI4YBHvCPKEqtwYtMA"; //修改为自己的API_KEY char sensor_gps[] = "location"; void setup() { pinMode(L, OUTPUT); digitalWrite(L, LOW); Save_Data.isGetData = false; Save_Data.isParseData = false; Save_Data.isUsefull = false; DebugSerial.begin(9600); GprsSerail.begin(9600); GpsSerial.begin(9600); //定义波特率9600 Timer1.initialize(1000); Timer1.attachInterrupt(Timer1_handler); initGprs(); DebugSerial.println("\r\nsetup end!"); } void loop() { gpsRead(); //获取GPS数据 parseGpsBuffer();//解析GPS数据 printGpsBuffer();//输出解析后的数据 ,包括发送到OneNet服务器 } void printGpsBuffer() { if (Save_Data.isParseData) { Save_Data.isParseData = false; DebugSerial.print("Save_Data.UTCTime = "); DebugSerial.println(Save_Data.UTCTime); if(Save_Data.isUsefull) { Save_Data.isUsefull = false; DebugSerial.print("Save_Data.latitude = "); DebugSerial.println(Save_Data.latitude); DebugSerial.print("Save_Data.N_S = "); DebugSerial.println(Save_Data.N_S); DebugSerial.print("Save_Data.longitude = "); DebugSerial.println(Save_Data.longitude); DebugSerial.print("Save_Data.E_W = "); DebugSerial.println(Save_Data.E_W); postGpsDataToOneNet(API_KEY,device_id,sensor_gps,Save_Data.longitude,Save_Data.latitude); } else { DebugSerial.println("GPS DATA is not usefull!"); } } } void parseGpsBuffer() { char *subString; char *subStringNext; if (Save_Data.isGetData) { Save_Data.isGetData = false; DebugSerial.println("**************"); DebugSerial.println(Save_Data.GPS_Buffer); for (int i = 0 ; i <= 6 ; i++) { if (i ="= 0)" { if ((substring =" strstr(Save_Data.GPS_Buffer, ",")) == NULL)" errorlog(12); 解析错误 } else substring++; if ((substringnext =" strstr(subString, ",")) != NULL)" { char usefullbuffer[2]; switch(i) { case 1:memcpy(save_data.utctime, substring, substringnext - substring);break; 获取utc时间 case 2:memcpy(usefullbuffer, substring, substringnext - substring);break; case 3:memcpy(save_data.latitude, substring, substringnext - substring);break; 获取纬度信息 case 4:memcpy(save_data.n_s, substring, substringnext - substring);break; 获取n s case 5:memcpy(save_data.longitude, substring, substringnext - substring);break; case 6:memcpy(save_data.e_w, substring, substringnext - substring);break; 获取e w default:break; } substring =" subStringNext;" save_data.isparsedata =" true;" if(usefullbuffer[0] ="= 'A')" save_data.isusefull =" true;" else if(usefullbuffer[0] ="= 'V')" } else errorlog(13); } } } void gpsread() { while (gpsserial.available()) { gpsrxbuffer[gpsrxcount++] =" GpsSerial.read();" if (gpsrxcount ="= gpsRxBufferLength)clrGpsRxBuffer();" char* gps_bufferhead; char* gps_buffertail; if ((gps_bufferhead =" strstr(gpsRxBuffer, "$GPRMC,")) != NULL || (GPS_BufferHead = strstr(gpsRxBuffer, "$GNRMC,")) != NULL )" if (((gps_buffertail =" strstr(GPS_BufferHead, "\r\n")) != NULL) && (GPS_BufferTail "> GPS_BufferHead)) { memcpy(Save_Data.GPS_Buffer, GPS_BufferHead, GPS_BufferTail - GPS_BufferHead); Save_Data.isGetData = true; clrGpsRxBuffer(); } } } void clrGpsRxBuffer(void) { memset(gpsRxBuffer, 0, gpsRxBufferLength); //清空 gpsRxCount = 0; } double longitudeToOnenetFormat(char *lon_str_temp) { double lon_temp = 0; long lon_Onenet = 0; int dd_int = 0; long mm_int = 0; double lon_Onenet_double = 0; lon_temp = atof(lon_str_temp); lon_Onenet =lon_temp*100000; //转换为整数 dd_int = lon_Onenet/10000000; //取出dd mm_int = lon_Onenet%10000000; //取出MM部分 lon_Onenet_double = dd_int + (double)mm_int/60/100000;//换算为Onenet格式 return lon_Onenet_double; } double latitudeToOnenetFormat(char *lat_str_temp) { double lat_temp = 0; long lat_Onenet = 0; int dd_int = 0; long mm_int = 0; double lat_Onenet_double = 0; lat_temp = atof(lat_str_temp); lat_Onenet =lat_temp*100000; //转换为整数 dd_int = lat_Onenet/10000000; //取出dd mm_int = lat_Onenet%10000000; //取出MM部分 lat_Onenet_double = dd_int + (double)mm_int/60/100000;//换算为Onenet格式 return lat_Onenet_double; } void postGpsDataToOneNet(char* API_VALUE_temp,char* device_id_temp,char* sensor_id_temp,char* lon_temp,char* lat_temp) { char send_buf[400]= {0}; char text[100] = {0}; char tmp[25] = {0}; char lon_str_end[15] = {0}; char lat_str_end[15] = {0}; dtostrf(longitudeToOnenetFormat(lon_temp),3,6, lon_str_end); //转换成字符串输出 dtostrf(latitudeToOnenetFormat(lat_temp),2,6, lat_str_end); //转换成字符串输出 //连接服务器 memset(send_buf, 0, 400); //清空 strcpy(send_buf, "AT+CIPSTART=\"TCP\",\""); strcat(send_buf, OneNetServer); strcat(send_buf, "\",80\r\n"); if (sendCommand(send_buf, "CONNECT", 10000, 5) == Success); else errorLog(7); //发送数据 if (sendCommand("AT+CIPSEND\r\n", ">", 3000, 1) == Success); else errorLog(8); memset(send_buf, 0, 400); //清空 /*准备JSON串*/ //ARDUINO平台不支持sprintf的double的打印,只能转换到字符串然后打印 sprintf(text,"{\"datastreams\":[{\"id\":\"%s\",\"datapoints\":[{\"value\":{\"lon\":%s,\"lat\":%s}}]}]}" ,sensor_id_temp,lon_str_end,lat_str_end); /*准备HTTP报头*/ send_buf[0] = 0; strcat(send_buf,"POST /devices/"); strcat(send_buf,device_id_temp); strcat(send_buf,"/datapoints HTTP/1.1\r\n");//注意后面必须加上\r\n strcat(send_buf,"api-key:"); strcat(send_buf,API_VALUE_temp); strcat(send_buf,"\r\n"); strcat(send_buf,"Host:"); strcat(send_buf,OneNetServer); strcat(send_buf,"\r\n"); sprintf(tmp,"Content-Length:%d\r\n\r\n", strlen(text));//计算JSON串长度 strcat(send_buf,tmp); strcat(send_buf,text); if (sendCommand(send_buf, send_buf, 3000, 1) == Success); else errorLog(9); char sendCom[2] = {0x1A}; if (sendCommand(sendCom, "\"succ\"}", 3000, 1) == Success); else errorLog(10); if (sendCommand("AT+CIPCLOSE\r\n", "CLOSE OK", 3000, 1) == Success); else errorLog(11); if (sendCommand("AT+CIPSHUT\r\n", "SHUT OK", 3000, 1) == Success); else errorLog(11); } void initGprs() { if (sendCommand("AT\r\n", "OK", 3000, 10) == Success); else errorLog(1); // 如果输入 AT+CREG? <cr>则返回+CREG: <mode>, <stat> [ ,<lac>,<ci> ] // 注: <mode>的值共有三个选项,分别是 0 or 1 or 2, 其中0 代表关闭网络注册结果 // 码, 1 代表当网络注册状态改变时激活网络注册结果码, 2 代表激活网 // 络注册结果码同时显示区域和小区信息. // <stat>的返回值共有三个,分别是 0, 1, 2,3,4,5 , 其中 0 代表没有注册网络同时 // 模块没有找到运营商, 1代注册到了本地网络, 2 代表找到运营商但没 // 有注册网络, 3 代表注册被拒绝, 4 代表未知的数据, 5代表注册在漫游 // 状态. // <lac>表示所属网络区域代码,十六进制格式显示,如: “ 279C” // <ci>表示所属网络的小区 ID,十六进制格式显示,如: “ 0EB2” Tech-Link T&E if (sendCommand("AT+CREG?\r\n", "+CREG: 0,1", 3000, 10) == Success); else errorLog(2); if (sendCommand("AT+CGCLASS=\"B\"\r\n", "OK", 3000, 2) == Success); else errorLog(3); if (sendCommand("AT+CGDCONT=1,\"IP\",\"CMNET\"\r\n", "OK", 3000, 2) == Success); else errorLog(4); if (sendCommand("AT+CGATT=1\r\n", "OK", 3000, 2) == Success); else errorLog(5); if (sendCommand("AT+CLPORT=\"TCP\",\"2000\"\r\n", "OK", 3000, 2) == Success); else errorLog(6); } void(* resetFunc) (void) = 0; //制造重启命令 void errorLog(int num) { DebugSerial.print("ERROR"); DebugSerial.println(num); while (1) { digitalWrite(L, HIGH); delay(300); digitalWrite(L, LOW); delay(300); if (sendCommand("AT\r\n", "OK", 100, 10) == Success) { DebugSerial.print("\r\nRESET!!!!!!\r\n"); resetFunc(); } } } unsigned int sendCommand(char *Command, char *Response, unsigned long Timeout, unsigned char Retry) { clrGprsRxBuffer(); for (unsigned char n = 0; n < retry; n++) { debugserial.print("\r\n---------send at command:---------\r\n"); debugserial.write(command); gprsserail.write(command); time_cont =" 0;" while (time_cont < timeout) { gprsreadbuffer(); if(strstr(gprsrxbuffer, response) !=" NULL)" { debugserial.print("\r\n="=========receive AT Command:==========\r\n");" debugserial.print(gprsrxbuffer); 输出接收到的信息 clrgprsrxbuffer(); return success; } } } debugserial.print("\r\n="=========receive AT Command:==========\r\n");" debugserial.print(gprsrxbuffer); clrgprsrxbuffer(); return failure; } void timer1_handler(void) { time_cont++; void gprsreadbuffer() { while (gprsserail.available()) gprsrxbuffer[gprsbuffercount++] =" GprsSerail.read();" if (gprsbuffercount ="= gprsRxBufferLength)clrGprsRxBuffer();" void clrgprsrxbuffer(void) memset(gprsrxbuffer, 0, gprsrxbufferlength); 清空 gprsbuffercount =" 0;" }< pre></ retry; n++)></ci></lac></stat></mode></ci></lac></stat></mode></cr></= 6 ; i++)></timerone.h>
当然喽。2560!328p相继去世
小朋友就应该有小朋友的亚子(误)
宏天云图传(来自邪恶疯狂推销员 绝对零度 )
2w图传配备1280p高清小蚁运动相机
调试(用的雪花屏减少信号干扰)
玛德线断了
自奸商零度了解小蚁相机的信号传输方式不同,连接线比普通micro usb多一根(普通为黑白绿红,坑爹线为黑白黄绿红)
那么。。注入灵魂
小部件比如开关什么的就不列举了
接线图及电子元件测绘
现在来整合一下max30102和bmp180的程序
开局失利= = 刚一上来内存就爆了qaq
我日你仙人板板
官方明示不得使用mega328p
无奈去掉了血氧浓度测试这个功能(有兴趣的盆友可以用2560畅玩)
阉割成太监:
搞了一下午终于小有成就
嗯。看起来好像没什。。。。
我@#¥%%#@¥%……(此处应该有脏话)
崩溃
I2c通信失败
在哥们的帮助下排错= =(转眼就忙到了凌晨)
天。。粗心漏了一段代码
终于,功夫不负有心人
源汁源味
实在是没有精力搞sd卡数据写入了(大家闲着可以搞一搞),然后在小箱子里翻到了这个神器(某宝搜索串口数据储存器)
只要接电源和数据线路(txd反接rxd这样)就可以完成数据写入了(最大支持32GbU盘或tf卡)
资料如下
布线做航电
此乃精工雕琢,集天地之精华之纸模(雾)
糙汉子一枚略略略粗糙orz
根据纸模的大致结构就可以进行3d建模了
肝肝肝。肝就对了
day one
day two
day three
day four
day five
!!!!
看了看时间,已是凌晨3点
一阵反胃。赶忙跑到厕所,那一天真的画吐了
洗了个澡回到电脑前,揉揉眼睛看着努力的成果,开心得笑了,可能这就是diy的乐趣吧
/****************************************************************************************/
我是航天员刘培强
当老爷供着
七夕了,送根黄瓜
小崽子在我给它量体征的时候咬了我一口跑路了,害的我在床下逮了半个小时
感谢@零度 提供的3d打印服务w
补更完毕
待续,感谢关注
非常人道的测试:把仓鼠绑自行车后轮上,然后码表定速骑
这种加速度的话人是肯定承受不了的,大概20几个g,小动物在短时间内应该没什么大问题
鼠鼠吓尿会不会造成航电报废2333
所以专门为小鼠制作了一套航天服,具有抗荷防水的功能,连接件见正文最下方3图,分别是头盔、腰带、手套环这个问题早就考虑到了233
失踪人口回归前来更新(汗)
3D打印航电 @零度(此楼更新中)
这里出了点小插曲。。。除了打印软件抽风外,散热风扇也坏掉了
经过一番调整之后恢复了正常
装零件
可能由于调试原因,一个部件打坏了。还有几个部件需要做出调整
塞不进去(无助= =)
还有就是。。这哥们好像变胖了= =
只能再做一套航天服了
航电舱与发动机段连接件(因为没有57的酚醛棒料了,只能打印一个喽)
大一真是忙的一批,好不容易结了几门课终于有时间回来更新了
今天调试了一下GPS/北斗模块,让我的小奴隶去给物联卡交了个话费
这里就出现问题了= =、
但是
原因是这样的,如果你的物联卡不是本省的。。就不会在营业厅的终端上查找到。
也就是说不能在实体店进行缴费活动,只能在网上营业厅缴费
缴费过后,插进模块开始测试
让用放大镜看看这是个什么品种的憨批
?????????????
指示灯显示正常
响应很快,精度很好(误差在一米左右的范围)
(未完)
火箭发动机(此楼更新中)
感谢@御坂18650 毛妹贡献的57航箭
经毛妹测试,使用KNSB燃料可获得800N的推力
57外径航箭测绘
当时还没用熟soildworks。。emm就用AutoCAD先跑一跑
航箭气动自旋1200r/min,这还怎么航拍。。(对方并不想理你并向你丢了一只高能自爆螺旋拐弯狗.jpg)
所以用铝板把气动槽填♂满了嘤
用剪板器ctrl+c
金属粘黏剂ctrl+v
粘贴完毕之后敲敲打打,胶水填缝
最后用角磨机磨平alt+f4(误)
燃料隔热层
因为小动物比较脆弱,所以在此选择比较温和的燃料,也是非常普遍的业余固体燃料-KNSB
隔热层使用pvc排水管道
切割切割。。
鸭累!欧拉欧拉欧拉欧拉!(突然中二)
车削外壁
值得注意的是,PVC管道十分脆弱,因此在使用卡盘时要在内壁垫一个坚固的实体
就是你啦(掏出)
雪花飘飘,北风萧萧(雾)
(未完)
时段 | 个数 |
---|---|
{{f.startingTime}}点 - {{f.endTime}}点 | {{f.fileCount}} |
200字以内,仅用于支线交流,主线讨论请采用回复功能。