全部学习汇总: g_arduino: Arduino hack笔记 (gitee.com)
以前我基于Arduino做过一个环境信息采集的小工具,采集到的信息存储到SD卡中。当时的笔记: 341_Arduino+python分析天气变化导致颈椎病发的原因_颈椎病相关数据分析python
以前的这个工具曾经辅助我从某些角度找到激发我头疼的因素。当时主要是借助于Arduino以及BME280P传感器采集了环境信息,之后存储到SD卡的文件系统中。等出现了不舒服的时候,导出里面的数据分析下为什么。之前的这个系统能够采集存储很长时间的数据,可以满足长跨度的数据分析。而且数据的记录比较详实,整个系统也可以随手放到某个角落即可。不过,数据的处理需要时不时停机导数据,这个还是很繁琐的。
既然,之前想知道我敏感的环境因素点的问题已经得到了解决,我觉得原有的系统继续留下去的意义也就不大了。对我来说,更有意义的或许是能够直观提示我环境信息的变化。最简单的就是实时显示,当然,能够判断一下几个小时内的变化给我提示则更好了。我觉得还是考虑前者,毕竟Arduino的资源有限。不过,我倒是可以把串口的功能再加回来,这样可以远程直接看数据、记录log、串口图形绘制等。其实,相当于把第一次做的东西做了一个方式留下来了。
方案的选择,首先考虑的还是Arduino UNO,这个是我手里最多的板子。传感器还是之前的BME280P。屏幕我曾经有好几个,不知道为什么用的时候一个也没翻出来。因此,又入手了一个OLED的屏幕。型号是SSD1306,分辨率128 * 64。分辨率上还是不错的。这个小屏幕到手只需几块钱,但是商家宣称的有点不少:用到的管脚少、寿命高、亮度高、功耗低等。有SPI以及IIC两种通信形式,我选择了IIC形式的,因为管脚更少也更便宜。
这样,需要做的是融合结果功能到一个程序。这还是我第一次尝试使用IIC实现一主多从的通信,为此我把我的Arduino从header部分又引出来了两个插针方便接外设。小小的东西,把IIC、IIC多从机、串口、环境传感器、显示屏、串口打印等功能全都整合在了一起。产品做久了,还真觉得这个小东西的压缩度做的足够高的。
整合了这么多功能,存储还没有百分百用完。我觉得这个存储的消耗还是很低的了。当前,这个小东西在我的书房运行了一个星期多了,运行比较可靠。
我还曾经把这个放到了一个纸盒里,把屏幕用透明胶固定了一下,从侧面伸出传感器。只可惜大宝贝瞬间就给我破坏掉了。继续“裸奔”吧,USB接一个树莓派啥的就很方便随时获取各种数据了。
代码是根据几个例程组合出来的,附加代码如下:
/*********************************************************************
This is an example for our Monochrome OLEDs based on SSD1306 drivers
Pick one up today in the adafruit shop!
------> http://www.adafruit.com/category/63_98
This example is for a 128x64 size display using I2C to communicate
3 pins are required to interface (2 I2C and one reset)
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, check license.txt for more information
All text above, and the splash screen must be included in any redistribution
*********************************************************************/
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#define OLED_RESET 4
#define SEALEVELPRESSURE_HPA (1035.00)
Adafruit_SSD1306 display(OLED_RESET);
Adafruit_BME280 bme;
void setup()
{
unsigned status;
Serial.begin(9600);
while (!Serial)
; // time to get serial running
// by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3D (for the 128x64)
status = bme.begin(0x76, &Wire);
}
void printValues()
{
Serial.print("Temperature = ");
Serial.print(bme.readTemperature());
Serial.println(" °C");
Serial.print("Pressure = ");
Serial.print(bme.readPressure() / 100.0F);
Serial.println(" hPa");
Serial.print("Approx. Altitude = ");
Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
Serial.println(" m");
Serial.print("Humidity = ");
Serial.print(bme.readHumidity());
Serial.println(" %");
}
void loop()
{
static uint32_t i = 0U;
float sensor_value;
display.clearDisplay();
delay(1000);
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0, 10);
switch (i % 3U)
{
case 0U:
sensor_value = bme.readTemperature();
display.print(sensor_value);
display.println(" 'C");
break;
case 1U:
sensor_value = bme.readPressure() / 100.0F;
display.print(sensor_value);
display.println(" hPa");
break;
case 2U:
sensor_value = bme.readHumidity();
display.print(sensor_value);
display.println(" %");
break;
default:
break;
}
display.display();
if(i % 30U == 0U)
{
printValues();
}
i++;
delay(2000);
}