一、GY-26参考手册
1.1概述
GY-26是一款低成本平面数字罗盘模块。输入电压低,功耗小,体积小。其工作原理是通过磁传感器中两个相互垂直轴同时感应地球磁场的磁分量从而得出方位角度,此罗盘以RS232协议,及IIC协议与其他设备通信。该产品精度高,稳定性高。并切具有重新标定的功能,能够在任意位置得到准确的方位角,其输出的波特率是9600bps,有连续输出与询问输出两种方式,具有磁偏角补偿功能,可适应不同的工作环境。
1.2产品特点
(1)、体积小
(2)、高性价比
(3)、串口及IIC输出格式
1.3产品应用
(1)、手持式仪器仪表
(2)、机器人导航、定位
(3)、航行系统
(4)、船用自动舵
(5)、八木天线定位
(6)、车载GPS导线
(7)、航模定向
1.4技术参数
名称 | 参数 |
测量范围 | 0°~ 360° |
分辨率 | 0.1 ° |
测量精度 | 1 ° |
重复精度 | 1 ° |
响应频率 | 25 HZ |
工作电压 | 3~5 V |
工作电流 | 5 V--15mA 3V--8 mA |
工作温度 | -20°~ 85° |
储存温度 | -40°~ 125° |
尺寸 | 25.6mm×25.6mm |
1.5串口通信协议
(1)、串口通信参数
波特率:9600 bps 校验位:N 数据位:8 停止位:1
(2)、模块输出格式,每帧包含8个字节:
①.Byte0: 0x0D (ASCII码 回车)
②.Byte1: 0x0A (ASCII码 换行)
③.Byte2: 0x30~0x33 角度百位 (ASCII 0~3)
④.Byte3: 0x30~0x39 角度十位 (ASCII 0~9)
⑤.Byte4: 0x30~0x39 角度个位 (ASCII 0~9)
⑥.Byte5: 0x2E (ASCII码小数点)
⑦.Byte6: 0x30~0x39角度小数位(ASCII 0~9)
⑧.Byte7: 0x00~0xFF校验和 (仅低8bit)
注:校验和 Byte7 =(Byte0+ Byte1+…….Byte6)结果仅取低8bit
例:一帧数据 <0x0D-0x0A-0x33-0x35-0x39-0x2E-0x36-0x1C> = 359.6°
(3)、命令字节,由外部控制器发送至模块(十六进制)
①. 0x31:进行一次角度测量--------返回值参考输出格式
②.0xC0:校准磁场开始---------返回值参考输出格式(000.0度) ③.0xC1 :校准磁场结束--------------返回值参考硬铁补偿‘ ② ’
④.0xA0-0XAA-0XA5-0XC5 :
恢复出厂设定----------------------返回值参考输出格式(000.0度)
⑤. 0xA0-0XAA-0XA5-IIC_ADDR :
模块的IIC地址修改-------------返回值参考输出格式(000.0度)
IIC地址范围参考“IIC通信协议(3)”
⑥. 0x03 + 磁偏高8位 :
磁偏角设定,正北方向设定--返回值参考输出格式(000.0度)
⑦. 0x04 + 磁偏低8位 :
磁偏角设定,正北方向设定--返回值参考输出格式(000.0度)
例:发送0XC0至模块时,模块应答以下1帧
<0x0D-0x0A-0x30-0x30-0x30-0x2E-0x30-0x05> 表示成功
Led灯亮起,进入校准
例:发送0x03,0x00,0x04,0x64至模块时,模块应答以下1帧(4次)
<0x0D-0x0A-0x30-0x30-0x30-0x2E-0x30-0x05> 表示成功
磁偏角被修改为10.0度
1.6 IIC通信协议
(1)、进行IIC通信时,模块相当于24C04,EEPROM存储器,通信非常简单。
模块内部对应地址的数据(相当EEPROM各地址的数据),映射各参数
请参考下表
模块内部地址 | 地址的数据含义 |
0x00 | 未用到 |
0x01 | 角度值高8位 |
0x02 | 角度值低8位 |
0x03 | 磁偏角高8位 |
0x04 | 磁偏角低8位 |
0x05 | 未用到 |
0x06 | 未用到 |
0x07 | 校准等级值 |
实际当前角度值为上表“角度值高8位”与“角度值低8位”合成的16位数据,数据范围0-3599(因为分辨率为0.1°)
实际当前磁偏角值为“磁偏角高8位”与“磁偏角低8位”合成的16位数据,数据范围0-3599(因为分辨率为0.1°)
(2)、模块的命令表, 经IIC总线写入模块中
命令值 | 作用 |
0x00+ 0x31 | 角度测量 |
0x00+ 0xC0 | 校准 |
0x00+ 0xC1 | 停止校准 |
0x00+(0xA0+0XAA+0XA5+0XC5) | 恢复出厂设置 |
0x00+(0xA0+0XAA+0XA5+IIC_ADDR) | IIC地址修改 |
0x03 + 磁偏高8位值 | 磁偏角修改 |
0x04 + 磁偏低8位值 | 磁偏角修改 |
磁偏角的值,范围0-3599(因为分辨率为0.1°),是由2个8位的数据组成,当修改模块磁偏角时,分为高8位值,低8位值,写入模块。
(3)、模块的IIC地址可修改,出厂默认是0xe0。模块上电时led对应IIC地址闪动,闪动的次数由模块上电led亮起,led灭掉开始记。若模块上电立即向模块发送命令,则led不闪动。向模块写入地址时,模块只接收以下16个数据地址,其他无效
模块地址 | Led闪动次数 |
0xe0 | 0 |
0xe2 | 1 |
0xe4 | 2 |
0xe6 | 3 |
0xe8 | 4 |
0xea | 5 |
0xec | 6 |
0xee | 7 |
0xf0 | 8 |
0xf2 | 9 |
0xf4 | 10 |
0xf6 | 11 |
0xf8 | 12 |
0xfa | 13 |
0xfc | 14 |
0xfe | 15 |
1.7术语说明
(1)、磁偏角
磁北线与真北线之间的夹角(如图),地球表面任一点的磁子午圈同地理子午圈的夹角。不同的地点磁偏角不同,同一地点不同的时间磁偏角也不同。模块的磁偏角=原始角度+设定磁偏角度,即顺时针加上。例如:磁偏角为0的100度,此时更改磁偏角为10度,那么模块输出为100+10=110度。
(2)、硬铁补偿,磁场校准
当电子指南针使用的环境发生改变时,由于受到周围磁场的影响,输出的角度也将会受到干扰,为了消除干扰,需要进行环境磁场校准。本模块的校准方法有三种种 如下:
- 在模块的第9(CAL)引脚,接一按键至电源负极(GND),当第一次按下按键时,进入校准状态,LED常亮起。保持模块水平,缓慢旋转1周(旋转1周时间大约1分钟)。再次按下按键LED灭,校准结束。
- 控制器串口发送数据0XC0至模块后LED常亮起,模块应答成功数据。保持模块水平,缓慢旋转1周(旋转1周时间大约1分钟)。发送数据0XC1至模块,LED灭,校准结束。此时模块模块应答本次校准的等级(0级~9级,级数越大说明校准越好),应答一帧格式为:
Byte0: 0x0D (ASCII码 回车)
Byte1: 0x0A (ASCII码 换行)
Byte2: 0x30 (ASCII码0 )
Byte3: 0x30 (ASCII码0 )
Byte4: 0x30 (ASCII码0 )
Byte5: 0x2E (ASCII码小数点)
Byte6: 0x30~0x39 校准等级 (ASCII 0~9)
Byte7: 0x00~0xFF校验和 (仅低8bit)
注:校验和 Byte7 =(Byte0+ Byte1+…….Byte6)结果仅取低8bit
例:发送0XC1至模块时,模块应答以下1帧
<0x0D-0x0A-0x30-0x30-0x30-0x2E-0x39-0x0E> 表示成功校准等级9
③. 控制器经IIC总线发送数据0x00+ 0xC0至模块后LED常亮起保持模块水平,缓慢旋转1周(旋转1周时间大约1分钟)。发送数据0x00+0XC1至模块,LED灭,校准结束。
1.8结束
(1)、模块参数都是基于一个标准5V状态下测试的。建议使用纹波较小的电源供给。
(2)、模块测量时LED的闪动对应测量的频率。校准时LED常亮。
(3)、模块测量时和校准时,保持水平,将获得最好的准确度,测量时应远离磁体尽量30厘米以上。
(4)、模块内部有记忆功能,可掉电记忆校准系数及磁偏角。
(5)、恢复出厂设定,即恢复出厂时的校准系数及磁偏角度,并不会修改模块当前的IIC地址。
(6)、模块输入输出的高低电平3-5V,可以直接与单片机串口,单片机IO连接,可以直接与PL2303,CH340,FT232等芯片连接,但不能与电脑串口直接连接。
二、程序源码
#include "gy26_usart.h"
uint8_t adj_angle_start = 0xC0;
uint8_t adj_angle_stop = 0xC1;
uint8_t check[8] = {0};
int angle = 0;
int check_first = 0;//初始测量角度
uint8_t adj_angle_work = 0x31;
uint8_t duty_cycle = 0;//调整占空比
int check_angle = 0;//测量过程中的角度(差值)
//测量磁偏角,并驱动电机旋转180度
void measure_angle(void)
{
uint8_t i = 0;
uint8_t angle_hundred = 0;//滤波处理
uint8_t angle_ten = 0;//滤波处理
uint8_t angle_uint = 0;//滤波处理
uint8_t flag = 0;
uint8_t flag1 = 0;//防止开始角度为0度左右,后面角度抖动到360度直接造成小车停止
check_first = check_first_angle();//初始角度测量
if(check_first<30)
flag1=1;
duty_cycle = 60;//初始占空比设置
//开始测量角度
while(1)
{
HAL_UART_Transmit(&huart1,&adj_angle_work,1,100);
HAL_Delay(20);
ASC_TEN();//将角度转为十进制
if(check_first>=180 && angle<=180)//360到1度之间的转换
{
check_first=check_first - 180;
angle=angle + 180;
flag = 1;
}
if(flag==1 && angle<180)
{
angle=angle + 180;
}
if(flag1==1 && angle>330)
{
continue;//直接进入下次循环,防止开始角度为0度左右,后面角度抖动到360度直接造成小车停止
}
check_angle = abs(angle - check_first);//求角度的差值(绝对值)
if(check_angle>=100)
{
angle_hundred++;
if(angle_hundred>3)//四次后执行该操作
duty_cycle = 30;//旋转到100度后更改占空比
}
if(check_angle>=170)
{
angle_ten++;
if(angle_ten>3)//四次后执行该操作
{
duty_cycle = 0;//旋转到180度后更改占空比
break;
}
}
}
}
void ASC_TEN(void)//ASCLL码与十进制之间的转换
{
//将测得的角度值转化为十进制
check[2] = check[2]<<4;//百位左移四位0xx0
check[2] = check[2]>>4;//百位右移四位0x0x
check[3] = check[3]<<4;//十位左移四位0xx0
check[3] = check[3]>>4;//十位右移四位0x0x
check[4] = check[4]<<4;//个位左移四位0xx0
check[4] = check[4]>>4;//个位右移四位0x0x
angle = check[2]*100+check[3]*10+check[4];
}
int abs(int x)//绝对值计算
{
if(x<0)
x=-x;
return x;
}
int check_first_angle(void)//初始角度测量
{
int x = 0;//赋初值
HAL_UART_Transmit(&huart1,&adj_angle_work,1,200);//第一遍
HAL_Delay(20);
ASC_TEN();//将角度转为十进制
x = x + angle;
HAL_UART_Transmit(&huart1,&adj_angle_work,1,200);//第二遍
HAL_Delay(20);
ASC_TEN();//将角度转为十进制
x = x + angle;
HAL_UART_Transmit(&huart1,&adj_angle_work,1,200);//第三遍
HAL_Delay(20);
ASC_TEN();//将角度转为十进制
x = x + angle;
x = x/3;//初始角度求平均
return x;
}
对应.h文件:
#ifndef __GY26_USART_H__
#define __GY26_USART_H__
#include <stm32f4xx.h>
#include <usart.h>
#include <math.h>
extern uint8_t adj_angle_start;
extern uint8_t adj_angle_stop;
extern uint8_t check[8];//返回校验帧
extern int angle;//十进制表示的角度值
extern int check_first;
extern int check_angle;
extern uint8_t adj_angle_work;
extern uint8_t duty_cycle;//占空比
void measure_angle(void);
void ASC_TEN(void);
int abs(int x);
int check_first_angle(void);//初始角度测量
#endif //__GY26_USART_H__
第一次写这方面的文章,欢迎大家来讨论。
完整工程文件下载: