利用三轴磁场传感器QMC5883P测量地磁通过ATMEGA328P开发板计算和OLED来显示就构成了一个电子罗盘.
整机装在一个35*35*20透明PP塑料盒子中,小巧玲珑方便携带.使用时只要将电子罗盘平放OLED平幕正前方就是
电子罗盘三角指针指示的方位.
外观图
电路图
电子罗盘外观图电路图和程序如下:
- #include <Wire.h>
- #include <U8g2lib.h>
- //SSD1306 0.96寸I2C
- U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);
- //SH1106打开下面注释
- //U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);
- #define QMC_ADDR 0x2C
- int16_t mx, my, mz;
- float heading;
- char buf[8]; //存放角度字符串
- const uint8_t cx = 64;
- const uint8_t cy = 30;
- const uint8_t r = 27;
- void QMC_Read()
- {
- uint8_t buff[6];
- Wire.beginTransmission(QMC_ADDR);
- Wire.write(0x01);
- Wire.endTransmission();
- Wire.requestFrom(QMC_ADDR,6);
- for(uint8_t i=0;i<6;i++) buff[i] = Wire.read();
- mx = (int16_t)(buff[1] << 8 | buff[0]);
- my = (int16_t)(buff[3] << 8 | buff[2]);
- }
- float CalcHeading()
- {
- float angle = atan2(my, mx) * 180.0 / PI;
- if(angle < 0) angle += 360.0;
- return angle;
- }
- void DrawCompass(float deg)
- {
- u8g2.clearBuffer();
- u8g2.drawCircle(cx, cy, r);
- float rad;
- int x1,y1,x2,y2;
- for(uint8_t i=0;i<8;i++)
- {
- rad = radians(i*45.0);
- x1 = cx + (r-4)*cos(rad);
- y1 = cy - (r-4)*sin(rad);
- x2 = cx + r*cos(rad);
- y2 = cy - r*sin(rad);
- u8g2.drawLine(x1,y1,x2,y2);
- }
- //实心三角指针不变
- float mainRad = radians(deg);
- int tipX = cx + r * cos(mainRad);
- int tipY = cy - r * sin(mainRad);
- float sideRad1 = radians(deg + 160);
- float sideRad2 = radians(deg - 160);
- int p1x = cx + (r*0.35)*cos(sideRad1);
- int p1y = cy - (r*0.35)*sin(sideRad1);
- int p2x = cx + (r*0.35)*cos(sideRad2);
- int p2y = cy - (r*0.35)*sin(sideRad2);
- u8g2.drawTriangle(tipX,tipY, p1x,p1y, p2x,p2y);
- //=====替换原来drawNum,用sprintf转字符串=====
- sprintf(buf,"%d",(int)deg);
- u8g2.drawStr(5,63,buf);
- u8g2.drawStr(25,63,"°");
- u8g2.setFont(u8g2_font_ncenB14_tr);
- u8g2.drawUTF8(4, 40, "W");
- //u8g2.drawStr(cx-4, cy-r-2, "N");
- u8g2.drawUTF8(110, 40, "E");
- u8g2.sendBuffer();
- }
- void setup()
- {
- Serial.begin(9600);
- u8g2.begin();
- Wire.begin();
- Wire.beginTransmission(QMC_ADDR);
- Wire.write(0x0B); Wire.write(0x08);
- Wire.endTransmission();
- Wire.beginTransmission(QMC_ADDR);
- Wire.write(0x0A); Wire.write(0x07);
- Wire.endTransmission();
- }
- void loop()
- {
- QMC_Read();
- heading = CalcHeading();
- DrawCompass(heading);
- delay(70);
- }
复制代码 |