Arduino兄弟间传递信息——基于BMP180气压计

本文涉及的产品
对象存储 OSS,20GB 3个月
对象存储 OSS,内容安全 1000次 1年
对象存储 OSS,恶意文件检测 1000次 1年
简介: Arduino兄弟间传递信息——基于BMP180气压计

1.0 简介

  • BMP180气压计:气压传感器是用于测量气体的绝对压强的仪器。

image.jpeg

  • 有机发光二极管(OrganicLight-Emitting Diode,OLED),又称为有机电激光显示、有机发光半导体(OrganicElectroluminesence Display,OLED),是指有机半导体材料和发光材料在电场驱动下,通过载流子注入和复合导致发光的现象。本篇通过Arduino 01BMP180IIC采样得到气压和温度,再通过串口交互给Arduino 02,顺便 02的IIC通讯0.98寸OLED将气压和温度数据打印显示。


数字气压传感器的学习

高精度气压传感器一般是利用MEMS技术在单晶硅片上加工出真空腔体和惠斯登电桥,惠斯登电桥桥臂两端的输出电压与施加的压力成正比,经过温度补偿和校准后具有体积小,精度高,响应速度快,不受温度变化影响的特点。输出方式一般为模拟电压输出和数字信号输出两种,其中数字信号输出方式由于和单片机连接方便,是市场上的主流。


  • 工作原理:

当被测气体的压力降低或升高时,这个薄膜变形带动顶针,同时该电阻器的阻值将会改变。电阻器的阻值发生变化。从传感元件取得0-5V的信号电压,经过A/D转换由数据采集器接受,然后数据采集器以适当的形式把结果传送给计算机。


  • BMP180相关参数如下:

压力范围:300hPa - -1100hPa(海拔9000m - - 500m)电源电压:1.8v - - 3.6v (VIN), 1.62v3.6v(VDDD)LCC8封装:无铅陶瓷载体封装(LCC)

尺寸: 3.6mmx3.8x0.93mm

低功耗:5uA,在标准模式

高精度:低功耗模式下,分辨率为0.06hPa (0.5米)高线性模式下,分辨率为0.03hPa (0.25米)

含温度输出

I2C接口温度补偿

无铅,符合RoHs规范MSL 1反应时间:7.5ms待机电流:0.1uA无需外部时钟电路


2.0 实验材料

  • Arduino Uno R3开发板两块
  • BMP180气压计传感器
  • 0.98寸OLED
  • 八根公母线
  • USB数据线
  • 一台安装Arduino开发环境的电脑

3.0 实验步骤

3.1 根据原理图搭建电路

BMP180传感器为3.3V供电,采用IIC通讯其中信号输出端连接到Arduino 01弟弟的信号线SDA(uno 的A4也可以)和一根时钟线SCL(uno 的A5也可以)引脚上;Arduino 01弟弟与Arduino 02哥哥通过软串口9号和10号通讯,需对调,Arduino 02哥哥通过IIC与OLED显示器通讯,因此除了5V供电的两根线外,只需要一根信号线SDA(uno 的A4也可以)和一根时钟线SCL(uno 的A5也可以)就可以。

实验原理图:

2.jpg

实验接线图:

3.jpg

3.2 新建sketch,分别拷贝如下代码并进行保存编译上传

Arduino IDE代码所需U8g2lib库

Arduino 01弟弟代码:

/**************************************************************************************/
/**********************DFRobot.com*****************************/
/***write by Tom Riddler          Jun.16.14***/
/***if you got any progream,please contact me terminaterfxy@hotmail.com***/
#include <SoftwareSerial.h>
SoftwareSerial mySerial(9, 10); // RX, TX
#include <Wire.h>
#define BMP180ADD 0x77  // I2C address of BMP180  
//write is (0xEE)     read is (0xEF)
unsigned char OSS;
/**********************MSB      LSB******/
int ac1;           // 0xAA     0xAB
int ac2;           // 0xAC     0xAD
int ac3;           // 0xAE     0xAE
unsigned int ac4;  // 0xB0     0xB1
unsigned int ac5;  // 0xB2     0xB3
unsigned int ac6;  // 0xB4     0xB5
int b1;            // 0xB6     0xB7
int b2;            // 0xB8     0xB9
int mb;            // 0xBA     0xBB
int mc;            // 0xBC     0xBD
int md;            // 0xBE     0xBF
float temperature;
int Temperature;
double pressure;
int Pressure;
double pressure2;
long b5;
double  altitude;
int Altitude;
int sensorA0 = 0;
int sensorA1 = 0;
int sensorA2 = 0;
int sensorA3 = 0;
int sensorA4 = 0;
int sensorA5 = 0;
void setup()
{
  mySerial.begin(9600);
  Serial.begin(9600);
  Wire.begin();
  OSS = 2;  // Oversampling Setting           0: single    1: 2 times    2: 4 times   3: 8 times
  BMP180start();
}
void loop()
{
  calculate();//BMP180计算
  delay(500);
  Temperature=temperature/1,Pressure=pressure/1,Altitude=altitude/1;//双精度浮点数转为整形输出
  sensorA0 = analogRead(A0);
  sensorA1 = analogRead(A1);
  sensorA2 = analogRead(A2);
  sensorA3 = analogRead(A3);
  sensorA4 = analogRead(A4);
  sensorA5 = analogRead(A5);
  Serial.println("A0:" + String(Temperature) + ";A1:" + String(Pressure) + ";A2:" + String(Altitude) + ";A3:" + String(sensorA3) + ";A4:" + String(sensorA4) + ";A5:" + String(sensorA5));
  mySerial.println("A0:" + String(Temperature) + ";A1:" + String(Pressure) + ";A2:" + String(Altitude) + ";A3:" + String(sensorA3) + ";A4:" + String(sensorA4) + ";A5:" + String(sensorA5));
  show();
  delay(1000);
}
/** calculate centure **/
void calculate()
{
  temperature = bmp180GetTemperature(bmp180ReadUT());
  temperature = temperature * 0.1;
  pressure = bmp180GetPressure(bmp180ReadUP())/1000;
  pressure2 = 1000*pressure / 101325;
  pressure2 = pow(pressure2, 0.19029496);
  altitude = 44330 * (1 - pressure2);                        //altitude = 44330*(1-(pressure/101325)^0.19029496);
}
/** print reslut **/
void show()
{
  Serial.print("Temperature: ");
  Serial.print(temperature, 1);                            //10 hexadecimal
  Serial.println(" C");
  Serial.print("Pressure: ");
  Serial.print(pressure, 0);                               //10 hexadecimal
  Serial.println(" Pa");
  Serial.print("altitude:");
  Serial.print(altitude);
  Serial.println("m");
}
/**BMP180 satrt program**/
void BMP180start()
{ /*MSB*/
  ac1 = bmp180ReadDate(0xAA);                      //get full data
  ac2 = bmp180ReadDate(0xAC);
  ac3 = bmp180ReadDate(0xAE);
  ac4 = bmp180ReadDate(0xB0);
  ac5 = bmp180ReadDate(0xB2);
  ac6 = bmp180ReadDate(0xB4);
  b1  = bmp180ReadDate(0xB6);
  b2  = bmp180ReadDate(0xB8);
  mb  = bmp180ReadDate(0xBA);
  mc  = bmp180ReadDate(0xBC);
  md  = bmp180ReadDate(0xBE);
}
/***BMP180 temperature Calculate***/
short bmp180GetTemperature(unsigned int ut)
{
  long x1, x2;
  x1 = (((long)ut - (long)ac6) * (long)ac5) >> 15; //x1=((ut-ac6)*ac5)/(2^15)
  x2 = ((long)mc << 11) / (x1 + md);              //x2=(mc*2^11)/(x1+md)
  b5 = x1 + x2;                                   //b5=x1+x2
  return ((b5 + 8) >> 4);                         //t=(b5+8)/(2^4)
}
/***BMP180 pressure Calculate***/
long bmp180GetPressure(unsigned long up)
{
  long x1, x2, x3, b3, b6, p;
  unsigned long b4, b7;
  b6 = b5 - 4000;
  x1 = (b2 * (b6 * b6) >> 12) >> 11;
  x2 = (ac2 * b6) >> 11;
  x3 = x1 + x2;
  b3 = (((((long)ac1) * 4 + x3) << OSS) + 2) >> 2;
  x1 = (ac3 * b6) >> 13;
  x2 = (b1 * ((b6 * b6) >> 12)) >> 16;
  x3 = ((x1 + x2) + 2) >> 2;
  b4 = (ac4 * (unsigned long)(x3 + 32768)) >> 15;
  b7 = ((unsigned long)(up - b3) * (50000 >> OSS));
  if (b7 < 0x80000000)
    p = (b7 << 1) / b4;
  else
    p = (b7 / b4) << 1;
  x1 = (p >> 8) * (p >> 8);
  x1 = (x1 * 3038) >> 16;
  x2 = (-7357 * p) >> 16;
  p += (x1 + x2 + 3791) >> 4;
  return p;
}
/*** Read 1 bytes from the BMP180  ***/
int bmp180Read(unsigned char address)
{
  unsigned char data;
  Wire.beginTransmission(BMP180ADD);
  Wire.write(address);
  Wire.endTransmission();
  Wire.requestFrom(BMP180ADD, 1);
  while (!Wire.available());
  return Wire.read();
}
/*** Read 2 bytes from the BMP180 ***/
int bmp180ReadDate(unsigned char address)
{
  unsigned char msb, lsb;
  Wire.beginTransmission(BMP180ADD);
  Wire.write(address);
  Wire.endTransmission();
  Wire.requestFrom(BMP180ADD, 2);
  while (Wire.available() < 2);
  msb = Wire.read();
  lsb = Wire.read();
  return (int) msb << 8 | lsb;
}
/*** read uncompensated temperature value ***/
unsigned int bmp180ReadUT()
{
  unsigned int ut;
  Wire.beginTransmission(BMP180ADD);
  Wire.write(0xF4);                       // Write 0x2E into Register 0xF4
  Wire.write(0x2E);                       // This requests a temperature reading
  Wire.endTransmission();
  delay(5);                               // Wait at least 4.5ms
  ut = bmp180ReadDate(0xF6);               // read MSB from 0xF6 read LSB from (16 bit)
  return ut;
}
/*** Read uncompensated pressure value from BMP180 ***/
unsigned long bmp180ReadUP()
{
  unsigned char msb, lsb, xlsb;
  unsigned long up = 0;
  Wire.beginTransmission(BMP180ADD);
  Wire.write(0xF4);                        // Write 0x34+(OSS<<6) into register 0xF4
  Wire.write(0x34 + (OSS << 6));           // 0x34+oss*64
  Wire.endTransmission();
  delay(2 + (3 << OSS));                   // Wait for conversion, delay time dependent on OSS
  Wire.beginTransmission(BMP180ADD);
  Wire.write(0xF6);                        // Read register 0xF6 (MSB), 0xF7 (LSB), and 0xF8 (XLSB)
  Wire.endTransmission();
  Wire.requestFrom(BMP180ADD, 3);
  while (Wire.available() < 3);            // Wait for data to become available
  msb = Wire.read();
  lsb = Wire.read();
  xlsb = Wire.read();
  up = (((unsigned long) msb << 16) | ((unsigned long) lsb << 8) | (unsigned long) xlsb) >> (8 - OSS); //16 to 19 bit
  return up;
}

Arduino 02哥哥代码:

#include <U8g2lib.h>
#include <Wire.h>
U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);
#include <SoftwareSerial.h>
SoftwareSerial mySerial(9, 10); // RX, TX
String message_c;
const char* message;
int sensorA0;
int sensorA1;
int sensorA2;
int sensorA3;
int sensorA4;
int sensorA5;
void setup()
{
  Serial.begin(9600);
  while (Serial.read() >= 0) {}              //清空串口0缓存
  mySerial.begin(9600);
  mySerial.listen();
  u8g2.begin();
  u8g2.enableUTF8Print();
}
void loop()
{
  if (mySerial.available())
  {
    String message_c = mySerial.readString(); //串口1接收字符串
    //    Serial.print(message_c);                           //串口0打印串口1接收的字符串
    //    Serial.println(message_c.length());           //串口0打印串口1接收的字符串长度
    message = message_c.c_str();                //由于sscanf只能识别const char*类型字符串,将String类型字符串转成const char*类型
    sscanf(message, "A0:%d;A1:%d;A2:%d;A3:%d;A4:%d;A5:%d", &sensorA0, &sensorA1, &sensorA2, &sensorA3, &sensorA4, &sensorA5); //串口1接收字符串格式为435;25.25
    Serial.print("sensorA0=");
    Serial.print(sensorA0);
    Serial.print(", sensorA1=");
    Serial.print(sensorA1);
    Serial.print(", sensorA2=");
    Serial.print(sensorA2);
    Serial.print(", sensorA3=");
    Serial.print(sensorA3);
    Serial.print(", sensorA4=");
    Serial.print(sensorA4);
    Serial.print(", sensorA5=");
    Serial.println(sensorA5);
    //    while (mySerial.read() >= 0) {};  //清空串口1缓存,保证字符串的长度稳定
  }
  u8g2.firstPage();
  do
  {
    page1();
  } while (u8g2.nextPage());
  delay(100);
}
void page1() {
  u8g2.setFont(u8g2_font_timB10_tf);
  u8g2.setFontPosTop();
  u8g2.setCursor(2, 10);
  u8g2.print("A0:");
  u8g2.setCursor(25, 10);
  u8g2.print(sensorA0);
  u8g2.setCursor(45, 10);
  u8g2.print("°C");
  u8g2.setCursor(2, 30);
  u8g2.print("A1:");
  u8g2.setCursor(25, 30);
  u8g2.print(sensorA1);
  u8g2.setCursor(45, 30);
  u8g2.print("Kpa");
  u8g2.setCursor(2, 50);
  u8g2.print("A2:");
  u8g2.setCursor(25, 50);
  u8g2.print(sensorA2);
  u8g2.setCursor(45, 50);
  u8g2.print("m");
  u8g2.setCursor(77, 10);
  u8g2.print("A3:");
  u8g2.setCursor(100, 10);
  u8g2.print(sensorA3);
  u8g2.setCursor(77, 30);
  u8g2.print("A4:");
  u8g2.setCursor(100, 30);
  u8g2.print(sensorA4);
  u8g2.setCursor(77, 50);
  u8g2.print("A5:");
  u8g2.setCursor(100, 50);
  u8g2.print(sensorA5);
  u8g2.drawVLine(75, 4, 60);
  u8g2.drawHLine(1, 25, 127);
  u8g2.drawHLine(1, 45, 127);
  u8g2.drawFrame(1, 1, 127, 63);
}

3.3 实验现象

打开窗口监视,观察OLED显示屏和串口的数据是否一致 ,然后手动捂热BPM180 ,观察其两者动态变化 😃😃😃

视频演示

4.png

BMP180兄弟互联

5.jpg

4.0 总结

  • 本篇通过Arduino 01弟弟通过IIC与BMP180通讯采样得到气压和温度,再通过串口交互给Arduino 02哥哥,顺便 Arduino 02哥哥的IIC通讯0.98寸OLED将气压和温度数据打印显示。。难度综合性强,值得新手一试!!!😃😃😃
  • 在以后的博文中我们将学会用arduino常用传感器和执行器,从而实现对外部世界进行感知,充分认识这个有机与无机的环境,科学地合理地进行创作和发挥效益,然后为人类社会发展贡献一点微薄之力
相关实践学习
借助OSS搭建在线教育视频课程分享网站
本教程介绍如何基于云服务器ECS和对象存储OSS,搭建一个在线教育视频课程分享网站。
目录
相关文章
|
6月前
|
vr&ar C# 图形学
从零开始的PICO开发教程(4)-- VR世界 射线传送、旋转和移动
这篇文章是PICO开发系列教程的第四部分,详细介绍了在VR世界中实现射线传送、视角旋转和人物移动的方法,包括使用Teleportation组件进行区域传送和锚点传送,通过Snap Turn Provider组件实现视角快速旋转,以及创建PlayControl脚本来控制人物移动,并通过手柄与脚本组件的交互来增强VR体验。
|
算法
《编程原本 》一第2章 变换及其轨道
本节书摘来自华章出版社《编程原本 》一书中的第2章,作者(美)斯特潘诺夫(Stepanov, A.),(美)麦克琼斯(McJones, P.),更多章节内容可以访问云栖社区“华章计算机”公众号查看
1019 0
|
存储 编解码 Linux
荔枝派Zero(全志V3S)驱动开发之RGB LCD屏幕显示bmp图片
了解 framebuffer 字符设备 了解 bmp图片格式 通过操作 /dev/fb0 字符设备来实现在 RGB LCD 屏幕上显示 bmp 图片。
465 1
|
Android开发 索引
第八章 Libgdx输入处理(3)输入设备
Android游戏开发群:290051794 Libgdx游戏开发框架交流群:261954621      简介 在Android中,Libgdx支持的主要输入设备为触摸屏和键盘。
946 0
|
9月前
动图搞懂三极管的工作原理
动图搞懂三极管的工作原理
73 0
|
Web App开发 数据采集 移动开发
客户端骨架屏详解
客户端骨架屏详解

热门文章

最新文章