极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

楼主: eagler8

【Arduino】108种传感器模块系列实验(资料+代码+图形+仿真)

[复制链接]
 楼主| 发表于 2019-7-25 11:50:32 | 显示全部楼层
  1. /*
  2. 【Arduino】66种传感器模块系列实验(68)
  3. 实验六十八:BMP180 新款 BOSCH温度模块气压传感器(代替BMP085)
  4. 程序之二,气温、气压与海拔值可以调整并校准
  5. */

  6. #include <Wire.h>
  7. #define BMP180ADD 0x77   
  8.                                  
  9. unsigned char OSS;                           

  10. int ac1;           
  11. int ac2;           
  12. int ac3;           
  13. unsigned int ac4;  
  14. unsigned int ac5;  
  15. unsigned int ac6;  
  16. int b1;            
  17. int b2;            
  18. int mb;            
  19. int mc;            
  20. int md;            
  21. float temperature;  
  22. double pressure;   
  23. double pressure2;
  24. long b5;         
  25. double altitude;  



  26. void setup()
  27. {
  28.   Serial.begin(9600);
  29.   Wire.begin();
  30.   OSS = 2;  
  31.   BMP180start();
  32. }

  33. void loop()
  34. {
  35.   calculate();
  36.   show();
  37.   delay(1000);
  38. }

  39. void calculate()
  40. {
  41.   temperature = bmp180GetTemperature(bmp180ReadUT());
  42.   temperature = temperature*0.0137;
  43.   pressure = bmp180GetPressure(bmp180ReadUP());
  44.   pressure2 = pressure/115325;
  45.   pressure2 = pow(pressure2,0.29029496);
  46.   altitude = 39*(1+pressure2);                           
  47. }


  48. void show()
  49. {
  50.   Serial.print("气温: ");
  51.   Serial.print(temperature, 1);                           
  52.   Serial.println(" C");
  53.   Serial.print("气压: ");
  54.   Serial.print(pressure, 0);                              
  55.   Serial.println(" Pa");
  56.   Serial.print("海拔:");
  57.   Serial.print(altitude);
  58.   Serial.println("m");
  59. }

  60. void BMP180start()
  61. {                     
  62.   ac1 = bmp180ReadDate(0xAA);                     
  63.   ac2 = bmp180ReadDate(0xAC);  
  64.   ac3 = bmp180ReadDate(0xAE);  
  65.   ac4 = bmp180ReadDate(0xB0);  
  66.   ac5 = bmp180ReadDate(0xB2);  
  67.   ac6 = bmp180ReadDate(0xB4);  
  68.   b1  = bmp180ReadDate(0xB6);  
  69.   b2  = bmp180ReadDate(0xB8);  
  70.   mb  = bmp180ReadDate(0xBA);  
  71.   mc  = bmp180ReadDate(0xBC);  
  72.   md  = bmp180ReadDate(0xBE);
  73. }

  74. short bmp180GetTemperature(unsigned int ut)
  75. {
  76.   long x1, x2;
  77.   x1 = (((long)ut - (long)ac6)*(long)ac5) >> 15;  
  78.   x2 = ((long)mc << 11)/(x1 + md);               
  79.   b5 = x1 + x2;                                   
  80.   return ((b5 + 8)>>4);                           
  81. }

  82. long bmp180GetPressure(unsigned long up)
  83. {
  84.   long x1, x2, x3, b3, b6, p;
  85.   unsigned long b4, b7;
  86.   
  87.   b6 = b5 - 4000;

  88.   x1 = (b2 * (b6 * b6)>>12)>>11;
  89.   x2 = (ac2 * b6)>>11;
  90.   x3 = x1 + x2;
  91.   b3 = (((((long)ac1)*4 + x3)<<OSS) + 2)>>2;
  92.   
  93.   x1 = (ac3 * b6)>>13;
  94.   x2 = (b1 * ((b6 * b6)>>12))>>16;
  95.   x3 = ((x1 + x2) + 2)>>2;
  96.   b4 = (ac4 * (unsigned long)(x3 + 32768))>>15;
  97.   
  98.   b7 = ((unsigned long)(up - b3) * (50000>>OSS));
  99.   if (b7 < 0x80000000)
  100.     p = (b7<<1)/b4;
  101.   else
  102.     p = (b7/b4)<<1;
  103.    
  104.   x1 = (p>>8) * (p>>8);
  105.   x1 = (x1 * 3038)>>16;
  106.   x2 = (-7357 * p)>>16;
  107.   p += (x1 + x2 + 3791)>>4;
  108.   
  109.   return p;
  110. }

  111. int bmp180Read(unsigned char address)
  112. {
  113.   unsigned char data;
  114.   
  115.   Wire.beginTransmission(BMP180ADD);
  116.   Wire.write(address);
  117.   Wire.endTransmission();
  118.   
  119.   Wire.requestFrom(BMP180ADD, 1);
  120.   while(!Wire.available());
  121.    
  122.   return Wire.read();
  123. }

  124. int bmp180ReadDate(unsigned char address)
  125. {
  126.   unsigned char msb, lsb;
  127.   Wire.beginTransmission(BMP180ADD);
  128.   Wire.write(address);
  129.   Wire.endTransmission();
  130.   Wire.requestFrom(BMP180ADD, 2);
  131.   while(Wire.available()<2);
  132.   msb = Wire.read();
  133.   lsb = Wire.read();
  134.   return (int) msb<<8 | lsb;
  135. }

  136. unsigned int bmp180ReadUT()
  137. {
  138.   unsigned int ut;
  139.   Wire.beginTransmission(BMP180ADD);
  140.   Wire.write(0xF4);                       
  141.   Wire.write(0x2E);                       
  142.   Wire.endTransmission();  
  143.   delay(5);                              
  144.   ut = bmp180ReadDate(0xF6);               
  145.   return ut;
  146. }

  147. unsigned long bmp180ReadUP()
  148. {
  149.   unsigned char msb, lsb, xlsb;
  150.   unsigned long up = 0;
  151.   
  152.   Wire.beginTransmission(BMP180ADD);
  153.   Wire.write(0xF4);                        
  154.   Wire.write(0x34 + (OSS<<6));            
  155.   Wire.endTransmission();
  156.   delay(2 + (3<<OSS));                     
  157.   
  158.   Wire.beginTransmission(BMP180ADD);
  159.   Wire.write(0xF6);                        
  160.   Wire.endTransmission();
  161.   
  162.   Wire.requestFrom(BMP180ADD, 3);
  163.   while(Wire.available() < 3);            
  164.   msb = Wire.read();
  165.   lsb = Wire.read();
  166.   xlsb = Wire.read();
  167.   up = (((unsigned long) msb << 16) | ((unsigned long) lsb << 8) | (unsigned long) xlsb) >> (8-OSS);//16 to 19 bit
  168.   return up;
  169. }

复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-7-25 11:52:53 | 显示全部楼层

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-7-25 12:13:41 | 显示全部楼层
  1. /*
  2. 【Arduino】66种传感器模块系列实验(68)
  3. 实验六十八:BMP180 新款 BOSCH温度模块气压传感器(代替BMP085)
  4. 程序之三,温度、实时气压、已知海拔计算的海平面的气压、已知海平面气压计算的高度
  5. 只是算法有点烂,做做实验而已
  6. */

  7. #include <SFE_BMP180.h>
  8. #include <Wire.h>

  9. SFE_BMP180 pressure;

  10. #define ALTITUDE 255.0

  11. unsigned long gpstimes;

  12. void setup()
  13. {
  14. Serial.begin(9600);

  15. pressure.begin();

  16. }

  17. void loop()
  18. {
  19. gpstimes=millis();

  20. char status;
  21. double T,P,p0,a;

  22. status = pressure.startTemperature();
  23. delay(status);
  24. status = pressure.getTemperature(T);
  25. delay(status);

  26. Serial.print("temperature: ");
  27. Serial.print(T,2);
  28. Serial.println(" deg C, ");



  29. status = pressure.startPressure(3);
  30. delay(status);

  31. status = pressure.getPressure(P,T);

  32. // Print out the measurement:
  33. Serial.print("absolute pressure A: ");
  34. Serial.print(P,2);
  35. Serial.println(" mb, ");

  36. p0=1013.2;

  37. a = pressure.altitude(P,p0);
  38. Serial.print("computed altitude A: ");
  39. Serial.print(a,0);
  40. Serial.println(" meters, ");

  41. T=25.00;
  42. status = pressure.getPressure(P,T);

  43. Serial.print("absolute pressure B: ");
  44. Serial.print(P,2);
  45. Serial.println(" mb, ");

  46. p0=1013.2;

  47. a = pressure.altitude(P,p0);
  48. Serial.print("computed altitude B: ");
  49. Serial.print(a,0);
  50. Serial.println(" meters, ");

  51. gpstimes=millis()-gpstimes;
  52. Serial.print("gpstimes=");
  53. Serial.println(gpstimes);
  54. Serial.println();
  55. delay(2000);
  56. }
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-7-25 12:52:36 | 显示全部楼层

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-7-25 13:47:48 | 显示全部楼层
实验六十九: AT24C256 I2C接口 EEPROM 存储模块 IIC

AT24C256
是ATMEL公司256kbit串行电可擦的可编程只读存储器,8引脚双排直插式封装,具有结构紧凑、存储容量大等特点,可以在2线总线上并接4片该IC,特别适用于具有高容量数据储存要求的数据采集系统。AT24C256采用SOP-8封装。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-7-25 14:29:23 | 显示全部楼层
芯片参数
芯片有3种工作电压;
  5.0V(VCC=4.5V~5.5V)
  2.7V(VCC=2.7V~5.5V)
  1.8V(VCC=1.8V~3.6V)
特性:
  内部可以组成32k×8存储单元
  2线串行接口
  斯密特触发,滤波输入抑制噪声
  双向数据传送协议
  硬件写保护引脚和软件数据保护功能
  具有64字节页写模式

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-7-25 14:31:31 | 显示全部楼层

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-7-25 14:46:05 | 显示全部楼层
A0、A1:地址选择输入端。在串行总线结构中,可以连接4个AT24C256IC。用A0、A1来区分各IC。A0、A1悬空时为0。
SCL:串行时钟输入。上升沿将SDA上的数据写入存储器,下降沿从存储器读出数据送SDA上。
SDA:双向串行数据输入输出口。用于存储器与单片机之间的数据交换。
WP:写保护输入。此引脚与地相连时,允许写操作;与VCC相连时,所有的写存储器操作被禁止。如果不连,芯片内部下拉到地。
VCC:电源。
GND:地。
NC:空。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-7-25 15:21:33 | 显示全部楼层
AT24C256的工作原理
AT24C256内部有512页,每一页为64字节,任一单元的地址为15位。地址范围0000H~7FFFH。
芯片工作状态
1)时钟和数据传送
一般情况下,SDA被外部的设备拉到高,只有当SCL为低电平时,SDA上的数据变化,表示要传送数据。SCL为高时SDA变化表示状态变化。
2)开始状态(START)
当SCL为高时,SDA由高到低表示数据传送开始,这一状态必须在所有命令之前。
3)结束状态(STOP)
当SCL为高时,SDA由低到高表示数据传送结束状态。
4)应答状态(ACK)
所有的地址和数据都是以8位的形式串行传送给存储器或从存储器读出的。存储器在第9个时钟周期SDA发零信号表示已经收到8位数据。见图总线协议图。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-7-25 15:35:13 | 显示全部楼层
AT24C256 I2C接口 EEPROM 存储模块


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-7-25 15:39:21 | 显示全部楼层
1.板载芯片AT24C256进口芯片;
2.板载I2C通讯所需的上拉电阻;
3.所有管脚均引出并标注;
4.PCB板子尺寸:1.9(CM)x1.1(CM)

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-7-25 15:46:25 | 显示全部楼层
模块电原理图

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-7-25 17:17:49 | 显示全部楼层
  1. /*
  2. 【Arduino】66种传感器模块系列实验(69)
  3. 实验六十九: AT24C256 I2C接口 EEPROM 存储模块
  4. */

  5. #include <Wire.h>

  6. #define ADDRESS_AT24C256 0x50

  7. word wordAddress = 0x0F00;
  8. char str[] = "This is ZLBG.";
  9. byte buffer[30];

  10. int i;

  11. void setup()
  12. {
  13.     Wire.begin();
  14.     Serial.begin(9600);

  15.     //write
  16.     Wire.beginTransmission(ADDRESS_AT24C256);
  17.     Wire.write(highByte(wordAddress));
  18.     Wire.write(lowByte(wordAddress));
  19.     for (i = 0; i < sizeof(str); i++)
  20.     {
  21.         Wire.write(byte(str[i]));
  22.     }
  23.     Wire.endTransmission();   

  24.     delay(10);
  25. }

  26. void loop()
  27. {
  28.    
  29.     Wire.beginTransmission(ADDRESS_AT24C256);
  30.     Wire.write(highByte(wordAddress));
  31.     Wire.write(lowByte(wordAddress));
  32.     Wire.endTransmission();
  33.     Wire.requestFrom(ADDRESS_AT24C256, sizeof(str));
  34.     if(Wire.available() >= sizeof(str))
  35.     {
  36.         for (i = 0; i < sizeof(str); i++)
  37.         {
  38.             buffer[i] = Wire.read();
  39.         }
  40.     }

  41.    
  42.     for(i = 0; i < sizeof(str); i++)
  43.     {
  44.         Serial.print(char(buffer[i]));
  45.     }
  46.     Serial.println();

  47.     delay(2000);
  48. }
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-7-25 17:20:28 | 显示全部楼层

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-7-25 17:40:47 | 显示全部楼层
  1. /*
  2. 【Arduino】66种传感器模块系列实验(69)
  3. 实验六十九: AT24C256 I2C接口 EEPROM 存储模块
  4. 程序之二
  5. */

  6. #include <Wire.h>
  7. #define EEPROM_ADDR 0x50     
  8.       
  9. void setup()
  10. {
  11.   Wire.begin();                        
  12.   Serial.begin(9600);

  13.   // TESTS FOR EACH FUNCTION BEGIN HERE
  14.   Serial.println("Writing Test:");
  15.   for (int i=0; i<20; i++){            
  16.     i2c_eeprom_write_byte(EEPROM_ADDR,i,i+65);   
  17.     Serial.print(". ");
  18.     delay(10);                        
  19.   }
  20.   Serial.println("");
  21.   delay(500);

  22.   Serial.println("Reading Test:");
  23.   for (int i=0; i<20; i++){            
  24.     Serial.write(i2c_eeprom_read_byte(EEPROM_ADDR, i));
  25.     Serial.print(" ");
  26.   }

  27.   byte PageData[30];                  
  28.   byte PageRead[30];                  
  29.   for (int i=0; i<30; i++){            
  30.     PageData[i] = 0;
  31.     PageRead[i] = 0;
  32.   }
  33.   Serial.println("");
  34.   for (int i=0; i<30; i++) PageData[i] = i+33;  
  35.   Serial.println("Writing Page Test:");
  36.   i2c_eeprom_write_page(EEPROM_ADDR, 100, PageData, 28 );
  37.   Serial.println("Reading Page Test:");
  38.   i2c_eeprom_read_buffer( EEPROM_ADDR, 100, PageRead, 28);
  39.   for (int i=0; i<28; i++){
  40.     Serial.write(PageRead[i]);   
  41.     Serial.print(" ");
  42.   }
  43. }

  44. void loop()
  45. {
  46. }

  47. void i2c_eeprom_write_byte( int deviceaddress, unsigned int eeaddress, byte data )
  48. {
  49.   int rdata = data;
  50.   Wire.beginTransmission(deviceaddress);
  51.   Wire.write((int)(eeaddress >> 8));   
  52.   Wire.write((int)(eeaddress & 0xFF));  
  53.   Wire.write(rdata);
  54.   Wire.endTransmission();
  55. }


  56. void i2c_eeprom_write_page
  57. ( int deviceaddress, unsigned int eeaddresspage, byte* data, byte length )
  58. {
  59.   Wire.beginTransmission(deviceaddress);
  60.   Wire.write((int)(eeaddresspage >> 8));
  61.   Wire.write((int)(eeaddresspage & 0xFF));
  62.   byte c;
  63.   for ( c = 0; c < length; c++)
  64.     Wire.write(data[c]);
  65.   Wire.endTransmission();
  66.   delay(10);                           
  67. }

  68. byte i2c_eeprom_read_byte( int deviceaddress, unsigned int eeaddress )
  69. {
  70.   byte rdata = 0xFF;
  71.   Wire.beginTransmission(deviceaddress);
  72.   Wire.write((int)(eeaddress >> 8));   
  73.   Wire.write((int)(eeaddress & 0xFF));  
  74.   Wire.endTransmission();
  75.   Wire.requestFrom(deviceaddress,1);
  76.   if (Wire.available()) rdata = Wire.read();
  77.   return rdata;
  78. }

  79. void i2c_eeprom_read_buffer( int deviceaddress, unsigned int eeaddress, byte *buffer, int length )
  80. {
  81.   Wire.beginTransmission(deviceaddress);
  82.   Wire.write((int)(eeaddress >> 8));   
  83.   Wire.write((int)(eeaddress & 0xFF));  
  84.   Wire.endTransmission();
  85.   Wire.requestFrom(deviceaddress,length);
  86.   
  87.   for ( int c = 0; c < length; c++ )
  88.     if (Wire.available()) buffer[c] = Wire.read();
  89. }
复制代码
回复 支持 反对

使用道具 举报

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

本版积分规则

Archiver|联系我们|极客工坊

GMT+8, 2026-6-9 20:08 , Processed in 0.055480 second(s), 14 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表