本帖最后由 费心LE 于 2017-1-3 22:59 编辑
首先感谢DFRobot给我机会对SIM808板的测试。
DFRobot SIM808 这块是一款集成了四频段GSM/GPRS和GPS导航技术的Arduino扩展板。可用于物联网、安保、防盗等行业,同时还支持电话通讯、短信收发、DTMF、FTP等功能。是一个多功能实用的好东西。官方提供的库方便我们更快的使用起来,适用于每个学习阶段的创客。
我这次申请的DFRobot SIM808 板子进行无人船的研发,DFRobot SIM808 带有GPS/GPRS等功能方便数据收集同时方便管理。
无人机和无人船相比,无人机有着续航时间短、信号范围小、操作不当容易发生“炸机”等缺点,对操作者的要求比较高;相对于无人船来说,它不用像无人机那样,长期待在水上,保证安全;有广阔的视野,不怕无人机那样,担心挂在树上,缠在电线上,撞在楼上等潜在危险;就算是没电的状态下,能保证电源的其他来源。
需要准备的材料:
arduino uno板
DFRobot SIM808
电子罗盘(HMC 5883L)
两个小型电机
充电宝(或者18650的电池)
太阳能电池板
升压模块
稳压模块
此次我使用双电机结构来使无人船完成前进、转向等运动(不过还有其他的方式,生活上用的船大部分都是使用舵来控制方向,电机控制前进的组合而成的),同时添加了电子罗盘,因为GPS本身没有方向,想了解前进的方向,有两种方式:一,GPS在一个方向上运动一段距离,在地图上显示出路径,即可判断方向;二,利用电子罗盘来确定方向;我选择第二种省时高效的方法。
电源方面,为了防止没电的尴尬情况,增加了太阳能电池板,能对整个系统提供供电,保证长期稳定性。
这是我做的实物图,比较简陋,为测试板,后期会逐渐加强。
太阳能电池板考虑到,船的方向的不确定性,保证机动性,采用平铺结构,能保证极大的采光面积。整部船一共增加了四个塑料瓶(还有两个在底部),左右两边的可增加船的扩展面积,保证船在海上不会翻,底部的就是增加浮力;
然后就是控制部分了:
- ///////////////lat代表经度 (latitude) /////lon代表纬度(longitude)//////
- ////////////////调用SIM808关于GPS部分
- #include <DFRobot_sim808.h>
- #include <SoftwareSerial.h>
- //#define PIN_TX 10
- //#define PIN_RX 11
- //SoftwareSerial mySerial(PIN_TX,PIN_RX);
- //DFRobot_SIM808 sim808(&mySerial);//Connect RX,TX,PWR,
- DFRobot_SIM808 sim808(&Serial);
- /////////////////罗盘部分
- #include <Wire.h>
- #include <HMC5883L.h>
- HMC5883L compass;
- /////设置
- /////罗盘设置
- float heading;
- float declinationAngle;
- float headingDegrees;
- //////////////坐标定义
- ///起始坐标
- float beginlon;//设置起始坐标经度
- float beginlat;//设置起始坐标纬度
- ////目的坐标
- float goallon;//设置目的坐标经度
- float goallat;//设置目的坐标纬度
- //////实时坐标
- float actuallon;///设置实时坐标经度
- float actuallat;///设置实时坐标经度
- /////罗盘指向
- float pointlon;//// 罗盘目标经度指向
- float pointlat;////罗盘目标纬度指向
- float comparelon;////设置经度比较值
- float comparelat;////设置纬度比较值
- float scopelon;///设置经度范围
- float scopelat;///设置纬度范围
- int ls= 7;///设置低速(low speed)
- int hs = 8 ;///设置高速(high speed)
- int motor1 = 9;///1号电机
- int motor2 = 10;///2号电机
- void setup() {
- //mySerial.begin(9600);
- Serial.begin(9600);
- //******** Initialize sim808 module *************
- while(!sim808.init()) {
- delay(1000);
- Serial.print("Sim808 init error\r\n");
- }
- //************* Turn on the GPS power************
- if( sim808.attachGPS())
- Serial.println("Open the GPS power success");
- else
- Serial.println("Open the GPS power failure");
- ////////////罗盘
- // Initialize Initialize HMC5883L
- /*Serial.println("Initialize HMC5883L");
- while (!compass.begin())
- {
- Serial.println("Could not find a valid HMC5883L sensor, check wiring!");
- delay(500);
- }/*==*/
- // Set measurement range
- compass.setRange(HMC5883L_RANGE_1_3GA);
- // Set measurement mode
- compass.setMeasurementMode(HMC5883L_CONTINOUS);
- // Set data rate
- compass.setDataRate(HMC5883L_DATARATE_30HZ);
- // Set number of samples averaged
- compass.setSamples(HMC5883L_SAMPLES_8);
- // Set calibration offset. See HMC5883L_calibration.ino
- compass.setOffset(0, 0);
- //////
- pinMode (ls,OUTPUT);
- pinMode (hs,OUTPUT);
- pinMode (motor1,OUTPUT);
- pinMode (motor2,OUTPUT);
- /////////////////////////////////输入///////////////////////////
- beginlon = 120.88;//////////////////输入起始坐标经度
- beginlat = 25.69;///////////////// 输入起始坐标纬度
- goallon =135.45;///////////////////////////////输入目的坐标经度
- goallat = 27.22;//////////////////////////////输入目的坐标纬度
- }
- void getGPS() {
- //************** Get GPS data *******************
- /*if (sim808.getGPS()) {
- Serial.print(sim808.GPSdata.year);
- Serial.print("/");
- Serial.print(sim808.GPSdata.month);
- Serial.print("/");
- Serial.print(sim808.GPSdata.day);
- Serial.print(" ");
- Serial.print(sim808.GPSdata.hour);
- Serial.print(":");
- Serial.print(sim808.GPSdata.minute);
- Serial.print(":");
- Serial.print(sim808.GPSdata.second);
- Serial.print(":");
- Serial.println(sim808.GPSdata.centisecond);
- Serial.print("latitude :");
- Serial.println(sim808.GPSdata.lat);
- Serial.print("longitude :");
- Serial.println(sim808.GPSdata.lon);
- Serial.print("speed_kph :");
- Serial.println(sim808.GPSdata.speed_kph);
- Serial.print("heading :");
- Serial.println(sim808.GPSdata.heading);
- Serial.println();
- //************* Turn off the GPS power ************
- sim808.detachGPS();
- } */
- }
- void luopan()
- {
- Vector norm = compass.readNormalize();
- // Calculate heading
- float heading = atan2(norm.YAxis, norm.XAxis);
- // Set declination angle on your location and fix heading
- // You can find your declination on: [url]http://magnetic-declination.com/[/url]
- // (+) Positive or (-) for negative
- // For Bytom / Poland declination angle is 4'26E (positive)
- // Formula: (deg + (min / 60.0)) / (180 / M_PI);
- float declinationAngle = (4.0 + (26.0 / 60.0)) / (180 / M_PI);
- heading += declinationAngle;
- // Correct for heading < 0deg and heading > 360deg
- if (heading < 0)
- {
- heading += 2 * PI;
- }
- if (heading > 2 * PI)
- {
- heading -= 2 * PI;
- }
- // Convert to degrees
- float headingDegrees = heading * 180/M_PI;
- // Output
- /* Serial.print(" Heading = ");
- Serial.print(heading);
- Serial.print(" Degress = ");
- Serial.print(headingDegrees);
- Serial.println();
- delay(500);*/
- }
- void lon()
- {
- comparelon = goallon - beginlon;////比较目的地与出发地方经度位置(目前只针对同个东经内或者同个西经内的运算)
- if(goallon > 0) { ///判断是否东经
- if(comparelon > 0)
- {
- pointlon = 270 ; ///船指向东
- }
- if(comparelon < 0)
- {
- pointlon = 90; ///船指向西
- }
- }
- if(goallon < 0) { ///判断是否西经
- if(comparelon < 0)
- {
- pointlon = 270; ///船指向东
- }
- if(comparelon > 0)
- {
- pointlon = 90; ///船指向西
- }
- }
- if(pointlon != headingDegrees )///方向不正确时,开启单电机转向
- {
- digitalWrite (ls, HIGH);////启动低速
- digitalWrite (hs, LOW);
- digitalWrite (motor1, HIGH);/////只开启一个电机,用于转向
- digitalWrite (motor2, LOW);
- }
- if(pointlon == headingDegrees )////方向正确时,全速前进
- {
- digitalWrite (ls, LOW);
- digitalWrite (hs, HIGH);////启动高速
- digitalWrite (motor1, HIGH);/////双电机开启
- digitalWrite (motor2, HIGH);
- }
- if(abs(goallon - actuallon) < 0.2)///接近目的附近,低速运行
- {
- digitalWrite (ls, HIGH);
- digitalWrite (hs, LOW);
- }
- if(abs(goallon - actuallon) < 0.02)///到达目的地附近,停止运行
- {
- digitalWrite (ls, LOW);
- digitalWrite (hs, LOW);
- digitalWrite (motor1, LOW);
- digitalWrite (motor2, LOW);
- }
- }
- void lat()
- {
- if(abs(goallon - actuallon) < 0.2)////再符合经度的条件下,执行纬度方向
- {
- comparelat = goallat - beginlat;////比较目的地与出发地方纬度位置(目前只针对同个北纬内或者同个南纬内的运算)
- if(goallat > 0) { ///判断是否北经
- if(comparelat > 0)
- {
- pointlat = 0; ///船指向北
- }
- if(comparelat < 0)
- {
- pointlat = 180; ///船指向西
- }
- }
- if(goallat < 0) { ///判断是否南纬
- if(comparelat < 0)
- {
- pointlat = 180; ///船指向南
- }
- if(comparelon > 0)
- {
- pointlon = 0; ///船指向北
- }
- }
- if(headingDegrees != pointlat)///方向不正确时
- {
- digitalWrite (ls, HIGH);////启动低速
- digitalWrite (hs, LOW);
- digitalWrite (motor1, HIGH);/////只开启一个电机,用于转向
- digitalWrite (motor2, LOW);
- }
- if(headingDegrees == pointlat)////方向正确时,全速前进
- {
- digitalWrite (ls, LOW);
- digitalWrite (hs, HIGH);////启动高速
- digitalWrite (motor1, HIGH);/////双电机开启
- digitalWrite (motor2, HIGH);
- }
- if(abs(goallat - actuallat) <2)///接近目的附近,低速运行
- {
- digitalWrite (ls, HIGH);
- digitalWrite (hs, LOW);
- }
- if(abs(goallat - actuallat) < 0.2)///到达目的地,停止运行
- {
- digitalWrite (ls, LOW);
- digitalWrite (hs, LOW);
- digitalWrite (motor1, LOW);
- digitalWrite (motor2, LOW);
- }
- }
- }
- void loop() {
- getGPS();
- luopan();
- lon();
- lat();
- }
复制代码
可从程序中看出,我使用航行的方式是如下图所示的第一种;比较低级但比较便捷,少误差;有兴趣的朋友可以自己开发第二种算法来航行;
小结:
此开发只完成小部分,有兴趣的朋友可添加数据采集的方式,如温湿度,水温,水质调查;也可用于海平面安保,鱼群跟踪等功能拓展,推荐使用SIM808拓展版,官方提供的库方便我们开发;
在实践使用中,必须格外注意整套系统的防护,在保证不翻船的情况下,可保证整个设备的完整性。同时感谢DFRobot给我这次测评机会。
本人水平有限,如果有何问题没发现或者没考虑清楚的麻烦帮我改正,谢谢
|