【问题标题】:how use the MPU 6050 in ultra low power mode如何在超低功耗模式下使用 MPU 6050
【发布时间】:2019-01-30 22:50:51
【问题描述】:

我目前正在尝试使用倾斜传感器设置发酵比重监测器。该过程可能需要数周时间,并且必须包含在无菌容器中,因此必须使用电池供电。我正在使用稍微修改过的 ESP8266-01,它进入睡眠模式,然后每小时唤醒一次以进行测量、传输数据并返回睡眠模式。我正在使用 MPU6050 作为倾斜传感器。首先,当esp关闭时,我似乎无法将mpu置于睡眠模式,它似乎总是需要大约4mA,其次,我只需要一个轴,是否可以禁用其他所有功能以进一步限制功耗?我似乎在手册中找不到任何禁用轴的内容,只能校准它们。我的代码在下面

用下面的寄存器做实验似乎没有什么区别,添加它们,完全取出它们,仍然需要大约 4mA。尝试设置为 1 以使 mpu 在循环结束时进入睡眠状态,但没有区别。 Wire.write(0x6B); Wire.write(0);

我对此很陌生,当手册在 addr 6b 中引用 bit6 时,我很难解释手册,我如何设置 bit 6?

如果我可以将 mpu 限制为仅 1 个轴,没有加速,并且在测量之间进入深度睡眠,我应该能够获得大约 0.5mA 的功耗,这让我使用单个 18650 获得良好的电池寿命。任何建议都是非常感谢!

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include "MPU6050.h"
#include "I2Cdev.h"
#include "Wire.h"

// Update these with values suitable for your network.

const char* ssid = "****";
const char* password = "******";
IPAddress server(192, 168, 1, 90);

WiFiClient espClient5;
PubSubClient client(espClient5);
long lastMsg = 0;
char msg[50];
const uint8_t scl = 5; //D1
const uint8_t sda = 4; //D2
int val;
int prevVal = 0;
String pubString;
char gravity[50];
MPU6050 mpu;
const int sleepTimeS = 10; //only 10 seconds for testing purposes, set to 
1hr when operational
int counter=0;


int16_t ax, ay, az;
int16_t gx, gy, gz;

void setup_wifi() {

  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
    Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  randomSeed(micros());

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

}

void callback(char* topic, byte* payload, unsigned int length) { //not 
required in this application
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Create a random client ID
    String clientId = "test";
    clientId += String(random(0xffff), HEX);
    // Attempt to connect
    if (client.connect(clientId.c_str())) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish("AliveRegister", "FermentMon");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

#define ONE_WIRE_BUS 2  //  D4 on physical board

 OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature DS18B20(&oneWire);
float prevTemp = 0;

void setup() {
  counter = 0;
  Serial.begin(9600);
  Wire.begin(0,2);
  Wire.write(0x6B); //PWR_MGMT_1 register
  Wire.write(0); // set to zero wakes teh 6050
  Wire.endTransmission(true);
 delay(100);
  setup_wifi();
  client.setServer(server, 1883);
  client.setCallback(callback);
 if (!client.connected()) {
    reconnect();
  }
  Serial.println("Initialize MPU");
  mpu.initialize();
  Serial.println(mpu.testConnection() ? "Connected" : "Connection failed");
 float temp;
  DS18B20.requestTemperatures();
  temp = DS18B20.getTempCByIndex(0); // first temperature sensor
  char buff[100];
  dtostrf(temp, 0, 2, buff);
  temp = temp + 0.5;
  int tRound = int(temp);
   client.publish("Fermenter/temperature", buff);
    Serial.print("Fermenter Temperature: ");
    Serial.println(temp);
    prevTemp = tRound;

  mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
  val = map(ax, -17000, 17000, 0, 180);
    pubString = String(val);
    pubString.toCharArray(gravity, pubString.length() + 1);
    client.publish("Fermenter/angle", gravity);
    Serial.print("Gravity angle: ");
    Serial.println(val);
    delay(500);
//    counter = counter+1;
    Serial.println("sleep mode");
    Wire.write(0x6B); //PWR_MGMT_1 register
    Wire.write(1); // set to zero wakes teh 6050
    // sleep
    ESP.deepSleep(sleepTimeS * 1000000);
    delay(2000);

  }


void loop() {

  client.loop();

      } 

【问题讨论】:

    标签: sleep esp8266 mpu6050


    【解决方案1】:

    我对此很陌生,当手册在 addr 6b 中引用 bit6 时,我很难解释手册,我如何设置 bit 6?

    设置一点很简单。 使用以下功能来避免任何头脑风暴。

    // Write register bit
    void writeRegisterBit(uint8_t reg, uint8_t pos, bool state)
    {
      uint8_t value;
      value = readRegister8(reg);
    
      if (state)
      {
        value |= (1 << pos);
      } 
     else
      {
        value &= ~(1 << pos);
      }
    
      writeRegister8(reg, value);
    }
    
    // Write 8-bit to register
    void writeRegister8(uint8_t reg, uint8_t value)
    {
      Wire.beginTransmission(MPU_addr);
    
    #if ARDUINO >= 100
      Wire.write(reg);
      Wire.write(value);
    #else
      Wire.send(reg);
      Wire.send(value);
    #endif
      Wire.endTransmission();
    }
    

    示例用法:writeRegisterBit(MPU6050_REG_INT_PIN_CFG, 5, 1); //Register 37;Interrupt Latch Enable

    对于您的应用程序:

    void acclSetSleepEnabled(bool state)
    {
      writeRegisterBit(MPU6050_REG_PWR_MGMT_1, 6, state);
    }
    

    如果我可以将 mpu 限制为仅 1 个轴,没有加速,并且在两次测量之间进入深度睡眠,我应该能够获得大约 0.5mA 的功耗,这让我使用单个 18650 获得良好的电池寿命

    要进入低功耗加速度计模式,请使用以下函数:

    void lowPowerAccel(uint8_t frequency) {
      uint8_t value;
      value = readRegister8(MPU6050_REG_PWR_MGMT_2);
      value &= 0b00111000;
      value |= (frequency << 6) | 0b111;
      writeRegister8(MPU6050_REG_PWR_MGMT_2, value);
    
      value = readRegister8(MPU6050_REG_PWR_MGMT_1);
      value &= 0b10010111;
      value |= 0b00111000;
      writeRegister8(MPU6050_REG_PWR_MGMT_1, value);
    }
    

    这个lowPowerAccel 函数也将陀螺仪置于待机模式。该函数需要一个唤醒频率参数。 这定义如下:

    /*
      * LP_WAKE_CTRL | Wake-up Frequency
      * -------------+------------------
      * 0            | 1.25 Hz
      * 1            | 2.5 Hz
      * 2            | 5 Hz
      * 3            | 10 H
    
    */
    
    #define  LP_WAKE_CTRL_1_25        0x00
    #define  LP_WAKE_CTRL_2_5         0x01
    #define  LP_WAKE_CTRL_5           0x02
    #define  LP_WAKE_CTRL_10          0x03
    
    

    希望我能回答你的一些问题。 祝你好运! :)

    【讨论】:

      【解决方案2】:

      您是否在为 MPU6050 使用分线板?例如GY-521。他们通常使用会消耗额外功率的线性稳压器和 LED。可能需要移除这些并从直接电源运行 IMU。

      MPU6050 中的每个寄存器都是 8 位宽。将单个位设置为所需值时,您可以使用按位操作(此处不实用,因为我们不直接与寄存器交互)或直接将寄存器中的所有位设置为寄存器的新状态,例如0b00100000 ~ 0x20。尝试使 MPU6050 进入睡眠状态时,不应将 1 写入 0x6B,而应写入 0x20。

      https://www.invensense.com/wp-content/uploads/2015/02/MPU-6000-Register-Map1.pdf

      参考第 40-42 页,如果您想更进一步,您可以在设备处于活动状态时禁用温度传感器、加速度计和冗余陀螺仪轴以节省电量。

      【讨论】:

        猜你喜欢
        • 2015-01-05
        • 2021-10-29
        • 1970-01-01
        • 2019-07-03
        • 2022-10-17
        • 1970-01-01
        • 1970-01-01
        • 2017-09-22
        • 2015-01-07
        相关资源
        最近更新 更多