查看: 9990|回复: 5

转载-- 自制基于Arduino移动式城市环境信息采集器

[复制链接]
  • TA的每日心情
    开心
    2013-8-30 14:12
  • 签到天数: 8 天

    连续签到: 1 天

    [LV.3]偶尔看看II

    发表于 2013-4-24 08:47:05 | 显示全部楼层 |阅读模式
    分享到:
    制作灵感来源于国外一个叫做 urban feeds 的项目。仪器能够采集:
    • 温度
    • 湿度
    • CO2浓度
    • O3浓度
    • 光照强度
    • 人流量
    • 大于1微米空气悬浮粒子
    • 大于2.5微米空气悬浮粒子
    • 日期时间
    • 位置信息
    采用SD卡存储数据,锂电池供电,外观如图: 2011-12-10 09:06 上传
    下载附件 (177.88 KB)




    全部配件包括:
    • 密封盒 1个 115×90×55
      2011-12-10 10:08 上传
      下载附件 (17.52 KB)


    • arduino UNO核心板 1块
      2011-12-10 10:12 上传
      下载附件 (26.94 KB)


    • SD卡模块1个及SD卡1张(容量不限,但由于FAT16文件分区格式的限制单个分区应小于2G)
      2011-12-10 10:18 上传
      下载附件 (13.66 KB)


      2011-12-10 10:18 上传
      下载附件 (11.2 KB)


      2011-12-10 23:43 上传
      下载附件 (17.55 KB)


    • SHT10温湿度传感器 1个
      2011-12-10 10:34 上传
      下载附件 (16.85 KB)


    • BH1750FVI光照传感器 1个
      2011-12-10 10:37 上传
      下载附件 (23.67 KB)


    • MG811二氧化碳(CO2)传感器(无需底板) 1个
      2011-12-10 11:29 上传
      下载附件 (3.78 KB)


    • MQ131臭氧(O3)传感器(无需底板) 1个
      2011-12-10 11:29 上传
      下载附件 (3.12 KB)


    • 七星座 2个
      2011-12-10 11:29 上传
      下载附件 (11.39 KB)


    • DSM501A粉尘传感器 1个
      2011-12-10 11:32 上传
      下载附件 (18.56 KB)


    • SIRF II GPS模块 1个
      2011-12-10 11:50 上传
      下载附件 (17.44 KB)


    • HC-SR501 人体红外感应模块 1个
      2011-12-10 11:50 上传
      下载附件 (17.2 KB)


    • 0.5A 单锂电池充电、升压板(保护+充电+升压+充电指示)  1块
      2011-12-10 11:55 上传
      下载附件 (25.42 KB)


    • 606168P 聚合物锂电池 3.7V 2800mAH 1块
      2011-12-10 11:51 上传
      下载附件 (15.17 KB)


    • CA3140 阻抗变换 1个
    • 二极管1N4007 1个
    • 3mm 发光二极管LED 绿(颜色随意) 1个
    • 电容 10nF(104贴片) 1个
    • 电阻 220 1个、10K(104贴片) 1个、22K 1个、10K 2个、1K 1个
    • 双面洞洞板 2×8cm 1块
    • 单排针 间距2.54mm 高11mm和高17mm 若干
    • 彩色杜邦线建议最短20cm 若干
    • KN3-3 拨动开关(六脚) 1个
    • M3螺母 若干
    • 6+12 M3铜柱子 若干
    • M3螺丝 包括10mm和6mm(非必需) 若干
    • M3空心铜柱(非必需) 若干


    电路部分:
    • SD卡接法请参考:arduino学习笔记18 - SD卡读写实验
    • SHT10 data脚接D8,clock脚接D9
    • BH1750FVI 是I2C协议,参见:arduino学习笔记27 - DS1307 RTC时钟芯片与DS18B20数字温度传感器实验中DS1307 与UNO板的接法
    • MG811二氧化碳传感器阻抗变换电路如图,接A3:
      2011-12-10 22:17 上传
      下载附件 (27.3 KB)


      2011-12-10 22:20 上传
      下载附件 (6.35 KB)


    • MQ131臭氧传感器辅助电路如图,接A2:
      2011-12-10 22:24 上传
      下载附件 (18.59 KB)


    • DSM501A粉尘传感器接线如图,接输出1接D7,输出2接D6:
      2011-12-10 22:30 上传
      下载附件 (36.38 KB)


    • SIRF II GPS模块TX接D0,RX接D1
    • HC-SR501 人体红外感应模块输出接A1
    • 发光二极管串联220欧姆电阻接在电源地和D2之间
    • 锂电池充电、升压板与锂电池接法按板子说明连接
    • 六角拨动开关一组控制仪器电源开关,一组控制锂电池充电开关,两组控制状态互斥如示意图:
      2011-12-10 22:47 上传
      下载附件 (6.02 KB)


    • 电源供电从锂电池充电、升压板升压输出端+5v经拨动开关仪器电源一组连接到UNO Vin脚;电池充电从UNO +5v输出经拨动开关仪器充电一组接到锂电池充电、升压板充电输入端
    • 从锂电池充电、升压板充电输入端引出线到A0并为A0设置10K下拉电阻
    • 所有传感器(除SD卡、温湿度)的+5v输入接UNO Vin脚,SD卡和温湿度传感器接UNO +5v输出脚;所有传感器的GND和锂电池充电、升压板的充电输入、+5V升压输出的GND接UNO GND脚


    仪器组装:

    2011-12-10 23:39 上传
    下载附件 (37.62 KB)


    2011-12-10 23:39 上传
    下载附件 (35.71 KB)


    2011-12-10 23:39 上传
    下载附件 (31.95 KB)



    DSM501A粉尘传感器 需垂直安装
    仪器内部:
    2011-12-10 23:48 上传
    下载附件 (37.42 KB)


    2011-12-10 23:51 上传
    下载附件 (62.51 KB)





    程序代码:

    • //davidce 20111211
    • // Include
    • #include <SHT1x.h>
    • #include <SD.h>
    • #include <Wire.h>
    • // Digital pin
    • // SHT1x
    • #define ShtDataPin  8  //data
    • #define ShtClockPin 9  //clock
    • SHT1x sht1x(ShtDataPin, ShtClockPin);
    • // system light
    • #define systemLightPin 2
    • //DSM501A DUST
    • #define DSMPin2_5  6
    • #define DSMPin1_0  7
    • //SD card
    • File myFile;
    • #define SD_CSPin  10
    • char filename[] = "result.txt";
    • String order= "";
    • //GPS
    • #define rxPin 0                    // RX PIN
    • #define txPin 1                    // TX TX
    • // Analog pin
    • const int powerInPin = A0;    // check power state for the bettery charge
    • const int infrRayPin = A1;    //infrared ray
    • const int o3Pin = A2;          //MQ131
    • const int co2Pin = A3;          //MQ811
    • // Variable
    • boolean inCharge = false;      //bettery charging mark
    • const unsigned long warmTime = 60000;     //system warmming 60000 ms
    • const unsigned long scanTime = 0;     //get data fre scanTime = scanTime + flashTime
    • const unsigned long flashTime = 250;
    • unsigned long previousMillis = 0;        //前一次判断时间点
    • unsigned long partMillis=0;              //到溢出时计算的时间
    • const unsigned long sectev = 30;           // 时间间隔(秒)
    • const unsigned long interval = 30000;           // 时间间隔(毫秒) = sectev * 1000
    • const unsigned long mintev = 30000000; // 时间间隔(微秒) =interval * 1000
    • //BH1750 IIC Mode
    • const int BH1750address = 0x23; //setting i2c address
    • byte buff[2];
    • //GPS
    • int byteGPS = -1;
    • char linea[300] = "";
    • char comandoGPR[7] = "$$GPRMC";
    • int cont=0;
    • int bien=0;
    • int conta=0;
    • int indices[13];
    • void setup() {
    •   if(!SD.begin(SD_CSPin))
    •   {
    •     return;
    •   }
    •   // read the value from the power
    •   int powerValue = analogRead(powerInPin); // variable to store the value coming from the power
    •   if(powerValue>1000)
    •   {
    •     inCharge=true;
    •     Serial.begin(4800);  //port speed for GPS
    •   }
    •   else
    •   {
    •     //check if the log file exists and add name of items to the new file
    •     if (!SD.exists(filename))
    •     {
    •       myFile = SD.open(filename, FILE_WRITE);
    •       if (myFile)
    •       {
    •         myFile.print("date_UTC");
    •         myFile.print(9,BYTE);
    •         myFile.print("time_UTC");
    •         myFile.print(9,BYTE);
    •         myFile.print("lat");
    •         myFile.print(9,BYTE);
    •         myFile.print("lon");
    •         myFile.print(9,BYTE);
    •         myFile.print("temp_C");
    •         myFile.print(9,BYTE);
    •         myFile.print("hum_PER");
    •         myFile.print(9,BYTE);
    •         myFile.print("pcs_1");
    •         myFile.print(9,BYTE);
    •         myFile.print("pcs_2_5");
    •         myFile.print(9,BYTE);
    •         myFile.print("peop_tra");
    •         myFile.print(9,BYTE);
    •         myFile.print("O3");
    •         myFile.print(9,BYTE);
    •         myFile.print("CO2");
    •         myFile.print(9,BYTE);
    •         myFile.println("light_lx");
    •         myFile.close();
    •       }
    •     }
    •     for (int i=0;i<300;i++)
    •     {       // Initialize a buffer for received data
    •       linea=' ';
    •     }
    •     pinMode(systemLightPin, OUTPUT);
    •     pinMode(DSMPin2_5, INPUT);
    •     pinMode(DSMPin1_0, INPUT);
    •     pinMode(rxPin, INPUT);
    •     pinMode(txPin, OUTPUT);
    •     Wire.begin();
    •     Serial.begin(4800);  //port speed for transform
    •     digitalWrite(systemLightPin, HIGH);
    •     delay(warmTime);
    •   }
    • }
    • void loop(){
    •   if(!inCharge)                  // work state
    •   {
    •     float temp_c =sht1x.readTemperatureC();
    •     float humidity = sht1x.readHumidity();
    •     unsigned long currentMillis;
    •     boolean goloop=true;
    •     partMillis=0;
    •     unsigned long duration1_0=0;
    •     unsigned long duration2_5=0;
    •     long temp1_0=0;
    •     long temp2_5=0;
    •     unsigned long rayMark=0;        //人流量计数
    •     double rayFreq = 0.0;        //人流量频率
    •     while(goloop)      //loop
    •     {
    •       currentMillis = micros();
    •       if(currentMillis<previousMillis)
    •       {
    •         partMillis = 4294967295 -  previousMillis +1;
    •         previousMillis = 0;
    •       }
    •       if(currentMillis - previousMillis - partMillis < mintev)
    •       {
    •         //1.0
    •         if(temp1_0==0)
    •         {
    •           temp1_0=-1;
    •           temp1_0=pulseIn(DSMPin1_0, LOW);
    •         }
    •         if(temp1_0>0)
    •         {
    •           duration1_0 =duration1_0 + temp1_0;
    •           temp1_0=0;
    •         }
    •         //2.5
    •         if(temp2_5==0)
    •         {
    •           temp2_5=-1;
    •           temp2_5=pulseIn(DSMPin2_5, LOW);
    •         }
    •         if(temp2_5>0)
    •         {
    •           duration2_5 =duration2_5 + temp2_5;
    •           temp2_5=0;
    •         }
    •       }
    •       else
    •       {
    •         goloop=false;
    •         previousMillis=currentMillis;
    •       }
    •       //human transform
    •       int rayState = analogRead(infrRayPin);
    •       if(rayState>500)
    •       {
    •         rayMark = rayMark + 1;
    •       }
    •     }
    •     double per =double(duration1_0)/double(interval);// had multiply 1000
    •     int pcs1_0 = -1;
    •     pcs1_0 =  per * 50.0;
    •     per =double(duration2_5)/double(interval);// had multiply 1000
    •     int pcs2_5 = -1;
    •     pcs2_5 =  per * 50.0;
    •     rayFreq = double(rayMark) /double(sectev);
    •     // light
    •     uint16_t lightval=0;
    •     BH1750_Init(BH1750address);
    •     delay(200);
    •     if(2==BH1750_Read(BH1750address))
    •     {
    •       lightval=((buff[0]<<8)|buff[1])/1.2;
    •     }
    •     //MQ131
    •     int O3v=analogRead(o3Pin);
    •     float O3ppb=float(O3v) * 0.0049;    //not realy value
    •     float O3mg_m3 = O3ppb * 48 / 22.4 / 1000;  //need ajaust
    •     //MG811
    •     int CO2v=analogRead(co2Pin);
    •     float CO2ppb=float(CO2v) * 0.0049;    //not realy value
    •     //GPS
    •     String datestr = "";    //date UTC (ddmmyy)
    •     String timestr = "";    //time UTC (hhmmss.sss)
    •     String latstr = "";    //Latitude (ddmm.mmmm)
    •     String lonstr = "";    //Longitude (dddmm.mmmm)
    •     boolean isGPSOK = false;
    •     bien=0;
    •     while(bien!=6)
    •     {
    •       byteGPS=Serial.read();
    •       if(byteGPS == -1)
    •       {
    •         delay(100);
    •       }
    •       else
    •       {
    •         linea[conta]=byteGPS;        // If there is serial port data, it is put in the buffer
    •         conta++;
    •         if(byteGPS==13)
    •         {
    •           cont=0;
    •           bien=0;
    •           for (int i=1;i<7;i++)
    •           {     // Verifies if the received command starts with $$GPRMC
    •             if (linea==comandoGPR[i-1])
    •             {
    •               bien++;
    •             }
    •           }
    •           if(bien==6)  // If yes, continue and process the data
    •           {
    •             for (int i=0;i<300;i++)
    •             {
    •               if (linea==',')
    •               {    // check for the position of the  "," separator
    •                 indices[cont]=i;
    •                 cont++;
    •               }
    •               if (linea=='*')
    •               {    // ... and the "*"
    •                 indices[12]=i;
    •                 cont++;
    •               }
    •             }
    •             String dataString;
    •             int outindex;
    •             outindex=1;
    •             for (int j=indices[outindex];j<(indices[outindex+1]-1);j++)
    •             {
    •               if(linea[j+1]=='A')
    •               {
    •                 isGPSOK = true;
    •               }
    •             }
    •             outindex=8;  //Date UTC (ddmmyy)
    •             dataString="";
    •             for (int j=indices[outindex];j<(indices[outindex+1]-1);j++)
    •             {
    •               dataString = dataString + linea[j+1];
    •             }
    •             datestr=dataString;
    •             outindex=0;  //time UTC (hhmmss.sss)
    •             dataString="";
    •             for (int j=indices[outindex];j<(indices[outindex+1]-1);j++)
    •             {
    •               dataString = dataString + linea[j+1];
    •             }
    •             timestr=dataString;
    •             outindex=2;  //Latitude (ddmm.mmmm)
    •             dataString="";
    •             for (int j=indices[outindex];j<(indices[outindex+1]-1);j++)
    •             {
    •               dataString = dataString + linea[j+1];
    •             }
    •             latstr=dataString;
    •             outindex=4;  //Longitude (dddmm.mmmm)
    •             dataString="";
    •             for (int j=indices[outindex];j<(indices[outindex+1]-1);j++)
    •             {
    •               dataString = dataString + linea[j+1];
    •             }
    •             lonstr=dataString;
    •           }
    •           // Reset the buffer
    •           conta=0;
    •           for (int i=0;i<300;i++)
    •           {
    •             linea=' ';
    •           }
    •         }
    •       }
    •     }
    •     //output result
    •     Serial.print(datestr);
    •     Serial.print(9,BYTE);
    •     Serial.print(timestr);
    •     Serial.print(9,BYTE);
    •     Serial.print(latstr);
    •     Serial.print(9,BYTE);
    •     Serial.print(lonstr);
    •     Serial.print(9,BYTE);
    •     Serial.print(temp_c);
    •     Serial.print(9,BYTE);
    •     Serial.print(humidity);
    •     Serial.print(9,BYTE);
    •     Serial.print(pcs1_0);
    •     Serial.print(9,BYTE);
    •     Serial.print(pcs2_5);
    •     Serial.print(9,BYTE);
    •     Serial.print(rayFreq);
    •     Serial.print(9,BYTE);
    •     Serial.print(O3ppb);
    •     Serial.print(9,BYTE);
    •     Serial.print(CO2ppb);
    •     Serial.print(9,BYTE);
    •     Serial.println(lightval,DEC);
    •     //writer the result to SD card
    •     myFile = SD.open(filename, FILE_WRITE);
    •     if (myFile)
    •     {
    •       // to sd file
    •       myFile.print(datestr);
    •       myFile.print(9,BYTE);
    •       myFile.print(timestr);
    •       myFile.print(9,BYTE);
    •       myFile.print(latstr);
    •       myFile.print(9,BYTE);
    •       myFile.print(lonstr);
    •       myFile.print(9,BYTE);
    •       myFile.print(temp_c);
    •       myFile.print(9,BYTE);
    •       myFile.print(humidity);
    •       myFile.print(9,BYTE);
    •       myFile.print(pcs1_0);
    •       myFile.print(9,BYTE);
    •       myFile.print(pcs2_5);
    •       myFile.print(9,BYTE);
    •       myFile.print(rayFreq);
    •       myFile.print(9,BYTE);
    •       myFile.print(O3ppb);
    •       myFile.print(9,BYTE);
    •       myFile.print(CO2ppb);
    •       myFile.print(9,BYTE);
    •       myFile.println(lightval,DEC);
    •       myFile.close();
    •       //flash the light
    •       if(isGPSOK)
    •       {
    •         digitalWrite(systemLightPin, HIGH);
    •         delay(flashTime);
    •         digitalWrite(systemLightPin, LOW);
    •       }
    •       else
    •       {
    •         digitalWrite(systemLightPin, LOW);
    •         delay(flashTime);
    •         digitalWrite(systemLightPin, HIGH);
    •       }
    •     }
    •     delay(scanTime);
    •   }
    •   else               //bettery charging and data translation
    •   {
    •     while(Serial.available() > 0)
    •     {
    •       int incomingByte = Serial.read();
    •       if(incomingByte==10)    //order end
    •       {
    •         if(order == "list")
    •         {
    •           myFile = SD.open(filename);
    •           if (myFile)
    •           {
    •             while (myFile.available())
    •             {
    •               Serial.write(myFile.read());
    •             }
    •             myFile.close();
    •           }
    •           else
    •           {
    •             Serial.println("open file failure.");
    •           }
    •         }
    •         else if(order.length()>0)
    •         {
    •           Serial.println("The available command is:");
    •           Serial.println("list");
    •         }
    •         //reset order
    •         order="";
    •       }
    •       else
    •       {
    •         if(incomingByte!=13)
    •         {
    •           order = order + char(incomingByte);
    •         }
    •       }
    •     }
    •   }
    • }
    • int BH1750_Read(int address)
    • {
    •   int i=0;
    •   Wire.beginTransmission(address);
    •   Wire.requestFrom(address, 2);
    •   while(Wire.available())
    •   {
    •     buff = Wire.receive();  // receive one byte
    •     i++;
    •   }
    •   Wire.endTransmission();
    •   return i;
    • }
    • void BH1750_Init(int address)
    • {
    •   Wire.beginTransmission(address);
    •   Wire.send(0x10);//1lx reolution 120ms
    •   Wire.endTransmission();
    • }

    复制代码


      代码说明:
    • 传感器需要预热时间,在变量warmTime 中设置,这里设置为60秒
    • 仪器根据inCharge 变量判断系统处于采集状态或充电状态,在采集状态时如插上usb可通过arduino IDE的串口监视实现数据显示;仪器通过arduino的usb口充电,在充电的同时可通过arduino IDE的串口监视实现交互,如输入list命令可列出SD卡存储的数据
    • DSM501A灰尘传感器有两路输出分别对应不同的灰尘粒径检出量,检测到灰尘是在输出口产生时间不等的低脉冲,通过计算30秒内的低脉冲率和对于关系得到灰尘粒子量(请参考DSM501A datasheet),程序中通过micros()函数提供计时,micros()每70分钟左右会归零,通过 4294967295 -  previousMillis +1 得出归零前的计数加到归零后的计数上实现连续计数
    • 程序通过pulseIn()返回低脉冲时间,虽然pulseIn()函数可以设置超时(默认1秒)但并不产生中断,代码中通过轮询pulseIn()的返回变量的值判读pulseIn()是否完成读取
    • 人体红外线模块的脉冲电平是3.3v,通过模拟读取时设置读数大于500为有输出
    • 当GPS模块可靠定位时系统状态灯常灭,采集数据时亮250ms;GPS不可靠定位时系统状态灯常亮,采集数据时灭250ms,GPS上集成电池,定位可靠与非都有日期时间输出(UTC时间,中国时区 +8小时)
    • BH1750光照传感器在太阳光直接照射的情况下有可能爆表(输出为0),建议避免强光直射


    关于传感器标定:
    每个传感器在出厂后的性能是不同的,在实际的应用中需要进行标定。仪器中需要标定的传感器是MG811二氧化碳、MQ131臭氧和DSM501A灰尘传感器,其它的传感器是数字输出,在出厂前经过标定。标定方法参考:
    • MG811二氧化碳标定可参考:http://www.instructables.com/id/ ... 12/C02-Calibration/ 中的方法,另外二氧化碳是温室气体,特性稳定,所以在全球很长时间都是均匀分布在同一水平,全球二氧化碳实时浓度见:http://co2now.org/,可以参考此网站上的值作为标定浓度之一,同时呼吁大家节能减排,减少温室气体排放
    • MQ131臭氧传感器标定需要在标准条件50ppb浓度臭氧下进行,请参考datasheet中说明
    • DSM501A灰尘传感器标定也可参考datasheet中的说明,需要注意的是DSM501A灰尘传感器测量粒子浓度与PM2.5、PM10和TSP(PM100)的检测原理和概念不同,不可混淆,只可做参考
      在仪器中以上传感器均未做标定,MQ131、MG811的输出值为对应的电压值


    数据采集与展示:
    固定采集:
    • 温湿度曲线:
      2011-12-12 12:01 上传
      下载附件 (58.34 KB)


    • 灰尘粒子曲线:
      2011-12-12 12:01 上传
      下载附件 (75.42 KB)


    • 气体浓度曲线:
      2011-12-12 12:01 上传
      下载附件 (73.85 KB)




    移动采集:
    • 采集路线:
      2011-12-12 12:10 上传
      下载附件 (49.23 KB)


    • 温度分布:
      2011-12-12 12:10 上传
      下载附件 (45.24 KB)


    • 湿度分布:
      2011-12-12 12:10 上传
      下载附件 (45.04 KB)


    • CO2分布:
      2011-12-12 12:10 上传
      下载附件 (45.12 KB)


    • 1微米以上粒子:
      2011-12-12 12:10 上传
      下载附件 (45.17 KB)




    图中红色代表高值,蓝色代表低值。

    下一步工作:
    MQ系列传感器辅助电路类似,仪器只需更换传感器探头和标定可实现其它气体测量
    由于MQ131和MG811属于加热型传感器耗电量大,2800mAh的锂电池只能连续工作3.5小时左右,同时二氧化碳和臭氧气体不适合移动观测,下一步打算将两种气体传感器设置在固定监测仪器上,在留出的面板位置上安装1602液晶显示,仪器同时实现便携式GPS功能。

    致谢:
    仪器在制作过程中得到极客工坊论坛和Arduino 与 ADK(1277738)QQ群热心网友的大力帮助,他们早出晚归,谈天论地,不分主题,有问必答,畅所欲言,谢谢大家!!


    完。
    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    2014-7-16 09:10
  • 签到天数: 361 天

    连续签到: 1 天

    [LV.8]以坛为家I

    发表于 2013-4-24 08:48:35 | 显示全部楼层
    楼主辛苦了,其实我就是来看看
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2023-9-15 06:28
  • 签到天数: 3747 天

    连续签到: 60 天

    [LV.Master]伴坛终老

    发表于 2013-4-24 09:19:23 | 显示全部楼层
    动手能力很强啊!涉猎范围广!赞一个
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2013-8-30 14:12
  • 签到天数: 8 天

    连续签到: 1 天

    [LV.3]偶尔看看II

     楼主| 发表于 2013-4-24 12:49:07 | 显示全部楼层
    dwwzl 发表于 2013-4-24 09:19
    动手能力很强啊!涉猎范围广!赞一个

    转发转发----------------------------------
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2017-7-21 12:58
  • 签到天数: 907 天

    连续签到: 2 天

    [LV.10]以坛为家III

    发表于 2013-6-2 09:34:40 | 显示全部楼层
    很有实用价值的东西!!!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2022-10-10 06:47
  • 签到天数: 1313 天

    连续签到: 3 天

    [LV.10]以坛为家III

    发表于 2013-6-2 12:24:19 | 显示全部楼层
    很牛叉的东西!!!!!!!!!!!!!!
    回复 支持 反对

    使用道具 举报

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

    本版积分规则

    关闭

    站长推荐上一条 /5 下一条



    手机版|小黑屋|与非网

    GMT+8, 2024-12-21 01:42 , Processed in 0.169427 second(s), 25 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.