涂鸦arduino中文社区活动
查看: 927|回复: 14

《失败的arduino探索经历》

[复制链接]

该用户从未签到

发表于 2020-6-28 09:56 | 显示全部楼层 |阅读模式
本帖最后由 老张383 于 2020-6-28 16:49 编辑

先前的想法很简单:用指南针模块GY271,主芯片HMC5883L做一个指南针,采用指南针的读数调整小车的转向,是小车沿着正南方向行驶。
file:///C:/Users/kx/AppData/Local/Temp/msohtmlclip1/01/clip_image002.jpgfile:///C:/Users/kx/AppData/Local/Temp/msohtmlclip1/01/clip_image004.jpg
file:///C:/Users/kx/AppData/Local/Temp/msohtmlclip1/01/clip_image006.jpg
但是困难重重,碰的头破血流,死的心都快有了。

HMC5883L反面.jpg HMC5883L正面.jpg
让大家看看什么是超级小白,什么哀鸣菜鸟。
使用 arduino UNO R3 单片机,指南针模块  GY271,主芯片  HMC5883L

安装Gy271库文件,包含 HMC5883L.h  HMC5883L.cpp    HMC5883L_Example.pdeHHMC5883L_Example_Ansifa.pdekeywords.txt
这里有两示例文件,HMC5883L_Example.pde HHMC5883L_Example_Ansifa.pde
1、先上传HMC5883L_Example.pde,看看运行它会出现什么状况。


#include <Wire.h>
#include <HMC5883L.h>
HMC5883L compass;
int error = 0;
void setup()
{
Serial.begin(9600);
Serial.println("Starting the I2C interface.");
Wire.begin(); // Start the I2C interface.
Serial.println("Constructing new HMC5883L");
compass = HMC5883L(); // Construct a new HMC5883 compass.
Serial.println("Setting scale to +/- 1.3 Ga");
error = compass.SetScale(1.3); // Set the scale of the compass.
if(error != 0) // If there is an error, print it out.
Serial.println(compass.GetErrorText(error));
Serial.println("Setting measurement mode to continous.");
error = compass.SetMeasurementMode(Measurement_Continuous); // Set themeasurement mode to Continuous
if(error != 0) // If there is an error, print it out.
Serial.println(compass.GetErrorText(error));
}
void loop()
{
MagnetometerRaw raw = compass.ReadRawAxis();
MagnetometerScaled scaled = compass.ReadScaledAxis();
int MilliGauss_OnThe_XAxis = scaled.XAxis;// (or YAxis, or ZAxis)
float heading = atan2(scaled.YAxis, scaled.XAxis);
float declinationAngle = 0.0457;
heading += declinationAngle;
if(heading < 0)
    heading += 2*PI;
if(heading > 2*PI)
    heading -= 2*PI;
float headingDegrees = heading * 180/M_PI;
Output(raw, scaled, heading, headingDegrees);
}
void Output(MagnetometerRaw raw,MagnetometerScaled scaled, float heading, float headingDegrees)
{
  Serial.print("Raw:\t");
  Serial.print(raw.XAxis);
  Serial.print("  ");   
  Serial.print(raw.YAxis);
  Serial.print("  ");   
  Serial.print(raw.ZAxis);
  Serial.print("  \tScaled:\t");
  Serial.print(scaled.XAxis);
  Serial.print("  ");   
  Serial.print(scaled.YAxis);
  Serial.print("  ");   
  Serial.print(scaled.ZAxis);
  Serial.print("  \tHeading:\t");

HMC5883L example 数据不变.jpg
  Serial.print(heading);
  Serial.print(" Radians  \t");
2、再看HHMC5883L_Example_Ansifa.pde,不知道这里为什么用了Ansifa。运行结果依然很八卦。

#include <Wire.h>
#include <HMC5883L.h>
HMC5883L compass;
void setup(){
Serial.begin(9600);
Wire.begin();
compass = HMC5883L();
compass.SetScale(1.3);
compass.SetMeasurementMode(Measurement_Continuous);
}
void loop()
{
MagnetometerRaw raw = compass.ReadRawAxis();
MagnetometerScaled scaled = compass.ReadScaledAxis();
float xHeading = atan2(scaled.YAxis, scaled.XAxis);
float yHeading = atan2(scaled.ZAxis, scaled.XAxis);
float zHeading = atan2(scaled.ZAxis, scaled.YAxis);
if(xHeading < 0)    xHeading +=2*PI;
if(xHeading > 2*PI)    xHeading-= 2*PI;
if(yHeading < 0)    yHeading +=2*PI;
if(yHeading > 2*PI)    yHeading-= 2*PI;
if(zHeading < 0)    zHeading +=2*PI;
if(zHeading > 2*PI)    zHeading-= 2*PI;
float xDegrees = xHeading * 180/M_PI;
float yDegrees = yHeading * 180/M_PI;
float zDegrees = zHeading * 180/M_PI;
Serial.print(xDegrees);
Serial.print(",");
Serial.print(yDegrees);
Serial.print(",");
Serial.print(zDegrees);
Serial.println(";");
delay(100);
}
看到数据一片惊喜,数据变化啦,细细一看这个变化是有规律的,周期性变化,并不随器件的转动变化,是我行我素的自我运动,串口监视器让人眼花缭乱。

HMC5883L example Ansifa 数据变亦不变.jpg
file:///C:/Users/kx/AppData/Local/Temp/msohtmlclip1/01/clip_image010.jpg         
        更有甚者,串口绘图仪可以清楚了,这种变化有极高的稳定性、抗冲击性和抗破坏性,因为拔掉时钟线和数据线,它依然不停的按自己的路子变化着。这个特点的深入研究没准还能别有他用呢。绘图仪给出的图片如下。file:///C:/Users/kx/AppData/Local/Temp/msohtmlclip1/01/clip_image012.jpg
HMC5883L example Ansifa 波形变亦不变.jpg

3、也不是完全的山穷水尽,再看从某宝买模块时送的实验程序HMC5883_example_code.ino, 当两个示例文件百般求索也没找到出路时,想起了商家也许有道,请注意这里并没有用到HMC5883L.h的库文件,商家给的这段代码也是令人沮困惑的。这是2011年的代码,年代久远IDE都换了多个版本了,Arduino没准都不认识呢。代码如下
#include <Wire.h> //I2C ArduinoLibrary
#define address 0x1E //0011110b,I2C 7bit address of HMC5883
void setup(){
//Initialize Serial and I2C communications
Serial.begin(9600);
Wire.begin();

//Put the HMC5883 IC into the correct operating mode
Wire.beginTransmission(address); //open communication with HMC5883
Wire.send(0x02); //select mode register
Wire.send(0x00); //continuous measurement mode
Wire.endTransmission();
}

void loop(){

int x,y,z; //triple axis data

//Tell the HMC5883 where to begin reading data
Wire.beginTransmission(address);
Wire.send(0x03); //select register 3, X MSB register
Wire.endTransmission();

//Read data from each axis, 2 registers peraxis
Wire.requestFrom(address, 6);
if(6<=Wire.available()){
    x = Wire.receive()<<8; //X msb
    x |= Wire.receive(); //X lsb
    z = Wire.receive()<<8; //Z msb
    z |= Wire.receive(); //Z lsb
    y = Wire.receive()<<8; //Y msb
    y |= Wire.receive(); //Y lsb
}

//Print out values of each axis
Serial.print("x: ");
Serial.print(x);
Serial.print("  y: ");
Serial.print(y);
Serial.print("  z: ");
Serial.println(z);

delay(250);
}

不但arduino不认识,重要的是Wire.h中就没有send这样的成员函数,度娘说,变啦,变啦,send变成write而receive变成read。加电修改一试成啦,本以为两块模块同时坏了,准备买新的再试,没想到一个简单的素代码竟让人快乐起来。如下图可以看出模块随运动和静止时给出的磁场强度曲线。
商家给出的示例程序图形.jpg
file:///C:/Users/kx/AppData/Local/Temp/msohtmlclip1/01/clip_image014.jpg

请注意,程序中没有用到HMC5883L.h的库函数,直接按HMC5883L手册对其寄存器进行赋值,利用I2C进行操作输出芯片获得的原始数据。手册给出模式寄存器的后两位确定了模块的状态
file:///C:/Users/kx/AppData/Local/Temp/msohtmlclip1/01/clip_image016.jpg
Wire.beginTransmission(address);//open communication with HMC5883
Wire.write(0x02); //select mode register
Wire.write(0x00); //continuous measurement mode
从而确定了模块是连续进行测量。
4、以上说明不是探索的全部,探索的过程满身已刺满荆棘!
arduino是优秀的硬件平台吗?学习arduino可以节约学习成本吗?使用arduino能够缩短开发周期吗?我只想做一个小车,参考指南针给出的方向,向南行驶5米,再向东行驶2米,并且方向的宽容度很大,一个自娱自乐的小车,看书害死人啊,每本介绍arduino的书都说arduino如何简单有趣,如何好学宜人,一个猛子扎进去方知道arduino的境界谁冷谁知道。
还拿做小车这件事说事,只想做一个依方向运动的小车耍耍,没有太高要求,但是选定了指南针模块后灾难就开始了。
如果你想用GY271模块,就要了解HMC5883L芯片,就要搜索HMC5883L的库文件,因为我们关心的是里面的例程文件,看看大师们是怎么用的,依葫芦画瓢是最基本最直接的心理,但是所找的的例程文件都玩不转,各种各样的不转,中间出现的“致命性错误”一堆一堆的,当你打开.h文件时你是什么都看不懂的,你只看到了它的成员数据和成员函数,如何操作你并不清楚,成员函数是解决问题的方法,这个方法如何使用是在源程序.cpp中,那你就需要认真研读.cpp,谈何容易,没办法你需要重新学习C++,可是C++在讲类库编写时用的对象是圆类,为了简明扼要,讲的轻松听得明白,讲解的是求圆面积和圆周长两个成员函数,类似于我们的书中超声波的的两个成员函数,让人看着清新爽快,但是解决不了应用过程中的实际问题。大学老师都是这样上课的,简单的反复讲,重复讲,遇见难题一带而过,绕着走,呵呵。
如果使用类库,还要熟悉类库,还要熟悉器件,还要完成的学完C/C++,怎么总让人产生有点上了贼船的感觉。
看着arduino的程序简洁,只是包含了若干头文件,可以建立若干对象,解决我们的一些问题,其实这只是表象,大量的源程序.cpp在后台运作,如果打开.cpp看看,大量的寄存器操作,指针操作,地址数据操作,美其名曰这是进行了二次封装。造成了如此多的困难,饶了这么多弯弯,还不如直接用51或是树莓派来的直接--努力去学习各类编程语言。
看着这么一堆arduino东东,一事无成也无颜见爹娘,还是去做那些无聊的流水灯呼吸灯去吧............

小车转向角 拷贝.jpg
小车转向角 拷贝.jpg

该用户从未签到

 楼主| 发表于 2020-6-28 10:00 | 显示全部楼层
怎么这么乱?

该用户从未签到

发表于 2020-6-28 21:33 | 显示全部楼层
看到这华强北的蓝板 + QFN 封装的芯片,第一反应就是模块有猫饼。

可以看看我这个帖子:https://www.arduino.cn/thread-97062-1-1.html

如果 QFN 芯片有虚焊的话你啥例程都跑不动,建议检查之。

该用户从未签到

发表于 2021-1-23 10:33 | 显示全部楼层
老张老师,做的小车可以跑了吗?

该用户从未签到

 楼主| 发表于 2021-1-23 10:35 | 显示全部楼层
eagler8 发表于 2021-1-23 10:33
老张老师,做的小车可以跑了吗?

放弃了,久攻不破,信心全无,惭愧啊

该用户从未签到

发表于 2021-1-23 10:41 | 显示全部楼层
老张383 发表于 2021-1-23 10:35
放弃了,久攻不破,信心全无,惭愧啊

其实是个难度挺高的项目

该用户从未签到

 楼主| 发表于 2021-1-23 17:45 | 显示全部楼层
eagler8 发表于 2021-1-23 10:41
其实是个难度挺高的项目

期望你的这次实验成果丰硕,同时开贴,很辛苦啊。
另外这两个芯片是有差别的QMC5883与HMC5883的库文件也是不同的,当然大部分还是相通的。
这个芯片在无人机制作中不可或缺
等你的好消息

该用户从未签到

发表于 2021-1-23 18:34 | 显示全部楼层
老张383 发表于 2021-1-23 17:45
期望你的这次实验成果丰硕,同时开贴,很辛苦啊。
另外这两个芯片是有差别的QMC5883与HMC5883的库文件也 ...

谢谢鼓励

该用户从未签到

发表于 2021-1-25 09:05 | 显示全部楼层
本帖最后由 eagler8 于 2021-1-25 09:29 编辑

也是第一次接触QMC5883L电子指南针罗盘模块,通过二个非常简单的程序,从串口读出了单一的方位角度的实时数值。


12.jpg


该用户从未签到

发表于 2021-1-25 09:31 | 显示全部楼层
  1. /*
  2.   【Arduino】168种传感器模块系列实验(资料代码+图形编程+仿真编程)
  3.    实验一百五十八:QMC5883L电子指南针罗盘模块 三轴磁场传感器GY-271
  4.   1、安装库:IDE--工具--管理库--搜索“QMC5883L”--安装QMC5883LCompass
  5.   2、项目:简易测量方位角度(数值在0-359度之间)并绘制波形
  6.   3、实验接线:
  7.   QMC5883L-------------- UNO
  8.   VCC------------------- 5V
  9.   GND------------------- GND
  10.   SCL ------------------- A5
  11.   SDA------------------- A4
  12.   DRDY------------------ N/C
  13. */

  14. #include <QMC5883LCompass.h>

  15. QMC5883LCompass compass;

  16. void setup() {
  17.   Serial.begin(9600);
  18.   compass.init();

  19. }

  20. void loop() {
  21.   int a;

  22.   // 读取罗盘值
  23.   compass.read();

  24.   // 返回方位角读数
  25.   a = compass.getAzimuth();

  26.   Serial.print("电子罗盘方位角: ");
  27.   Serial.print(a);
  28.   Serial.println();

  29.   delay(800);
  30. }
复制代码

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

热门推荐

字符串是否对比该使用哪个函数?
字符串是否对比该使用哪个
现有问题是, 串口接收到的数据是正常的,(通过print函数打印串口收
VSCode+PIO开发环境中添加Blinker.h的问题
VSCode+PIO开发环境中添加
我在main.c中添加就没问题,但是添加在.h文件中就会出现编译错误,在其他.c文件添加此
【干货分享】mega2560原理图PCB图纸altium designer18
【干货分享】mega2560原理
分享一下mega2560的板子 AD版本 **** 本内容被作者隐藏 **** ergo
这样写不对吗,为啥老是报错
这样写不对吗,为啥老是报
Python上位机控制WS2812B
Python上位机控制WS2812B
说在前面: 设计师对颜色有着天生的敏锐性,而工程师眼中这些都会幻化成数值。。
Copyright   ©2015-2016  Arduino中文社区  Powered by©Discuz!   
快速回复 返回顶部 返回列表