全部学习汇总: 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多从机、串口、环境传感器、显示屏、串口打印等功能全都整合在了一起。产品做久了,还真觉得这个小东西的压缩度做的足够高的。

1889_Arduino 1306 OLED屏幕的使用_数据

         整合了这么多功能,存储还没有百分百用完。我觉得这个存储的消耗还是很低的了。当前,这个小东西在我的书房运行了一个星期多了,运行比较可靠。

1889_Arduino 1306 OLED屏幕的使用_arduino_02

         我还曾经把这个放到了一个纸盒里,把屏幕用透明胶固定了一下,从侧面伸出传感器。只可惜大宝贝瞬间就给我破坏掉了。继续“裸奔”吧,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);
}