每 3 秒保存一次数据,每 5 分钟发送一个数组
save data every 3 second and send an array every 5 minutes
我有一个 MPU 连接到 wemos d1 mini。传感器发送 3 个值:X、Y 和 Z 轴。由于我的项目是太阳能供电的,因此我需要降低功耗。为此,我想每 3 秒读取一次 MPU 的 3 个值,将这些值存储在一个数组中,并在采样 5 分钟后打开 wifi 并通过 mqtt 将数组发送到我的主题。
我已经测试了代码的每一部分,一切正常。
例如,如果我尝试发送一个包含三个对象的数组,它会完美地工作
但是当我尝试发送一个包含 100 个对象的数组时它不起作用。
(注意:上面的“100”从何而来?如果我需要每5分钟发送一次数据,我这里每3秒读取一次值,我有100个采样)
希望有人能帮忙
unsigned long t_start;
void setup()
{
t_start = millis();
}
//compute the required size
const size_t CAPACITY = JSON_ARRAY_SIZE(100) + 100 * JSON_OBJECT_SIZE(3);
//allocate the memory for the document
StaticJsonDocument<CAPACITY> doc;
//MPU
const int MPU = 0x68; // I2C address of the MPU-6050
int16_t AcX, AcY, AcZ;
void loop()
{
//Create an empty array
JsonArray arr = doc.to<JsonArray>();
if (millis() - t_start >= 3000) {
for (int i = 0; i < 100; i++) {
//MPU reading
Wire.beginTransmission(MPU);
Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H)
Wire.endTransmission(false);
Wire.requestFrom(MPU, 14, true); // request a total of 14 registers
AcX = Wire.read() << 8 | Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
AcY = Wire.read() << 8 | Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
AcZ = Wire.read() << 8 | Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
//Create a JSON Object
JsonObject obj = doc.createNestedObject();
obj["AcX"] = AcX;
obj["AcY"] = AcY;
obj["AcZ"] = AcZ;
}
t_start = millis();
}
}
//MQTT PUBLISHING JSON PACKAGE
char mqttData[MQTT_BUFFER];
serializeJson(doc, mqttData);
Serial.println(mqttData);
int ret = client.publish("esp8266/JSON", mqttData);
} //end of loop
如果您想要每三秒 1 小节而不是每 3 秒 100 小节,代码应如下所示:
#define MQTT_KEEPALIVE 300
// headers ...
// setup() ...
void loop() {
//Create an empty array
JsonArray arr = doc.to<JsonArray>();
static auto t_start = millis(); // static will preserve last value even after exiting loop
int8_t count = 0;
while (count < 100) { // stays here whole 300s, so if the keep alives are needed or doing something else, it should be inside too
client.loop(); // sugested in comments
if (millis() - t_start >= 3000) {
t_start += 3000;
++count;
//MPU reading
Wire.beginTransmission(MPU);
Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H)
Wire.endTransmission(false);
Wire.requestFrom(MPU, 14, true); // request a total of 14 registers
AcX = Wire.read() << 8 | Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
AcY = Wire.read() << 8 | Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
AcZ = Wire.read() << 8 | Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
//Create a JSON Object
JsonObject obj = doc.createNestedObject();
obj["AcX"] = AcX;
obj["AcY"] = AcY;
obj["AcZ"] = AcZ;
}
// handling keep alives every X seconds as it's unlikely as long as 300s:
// if (...) sendKeepAlive();
}
// after 100 measures it'll get here:
//MQTT PUBLISHING JSON PACKAGE
char mqttData[MQTT_BUFFER];
serializeJson(doc, mqttData);
Serial.println(mqttData);
int ret = client.publish("esp8266/JSON", mqttData);
} //end of loop
但是它应该只解决代码中最明显的问题。可能还有其他的,比如缓冲区可能太小,或者......
未经测试,我没有此硬件设置
我有一个 MPU 连接到 wemos d1 mini。传感器发送 3 个值:X、Y 和 Z 轴。由于我的项目是太阳能供电的,因此我需要降低功耗。为此,我想每 3 秒读取一次 MPU 的 3 个值,将这些值存储在一个数组中,并在采样 5 分钟后打开 wifi 并通过 mqtt 将数组发送到我的主题。
我已经测试了代码的每一部分,一切正常。 例如,如果我尝试发送一个包含三个对象的数组,它会完美地工作 但是当我尝试发送一个包含 100 个对象的数组时它不起作用。
(注意:上面的“100”从何而来?如果我需要每5分钟发送一次数据,我这里每3秒读取一次值,我有100个采样)
希望有人能帮忙
unsigned long t_start;
void setup()
{
t_start = millis();
}
//compute the required size
const size_t CAPACITY = JSON_ARRAY_SIZE(100) + 100 * JSON_OBJECT_SIZE(3);
//allocate the memory for the document
StaticJsonDocument<CAPACITY> doc;
//MPU
const int MPU = 0x68; // I2C address of the MPU-6050
int16_t AcX, AcY, AcZ;
void loop()
{
//Create an empty array
JsonArray arr = doc.to<JsonArray>();
if (millis() - t_start >= 3000) {
for (int i = 0; i < 100; i++) {
//MPU reading
Wire.beginTransmission(MPU);
Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H)
Wire.endTransmission(false);
Wire.requestFrom(MPU, 14, true); // request a total of 14 registers
AcX = Wire.read() << 8 | Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
AcY = Wire.read() << 8 | Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
AcZ = Wire.read() << 8 | Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
//Create a JSON Object
JsonObject obj = doc.createNestedObject();
obj["AcX"] = AcX;
obj["AcY"] = AcY;
obj["AcZ"] = AcZ;
}
t_start = millis();
}
}
//MQTT PUBLISHING JSON PACKAGE
char mqttData[MQTT_BUFFER];
serializeJson(doc, mqttData);
Serial.println(mqttData);
int ret = client.publish("esp8266/JSON", mqttData);
} //end of loop
如果您想要每三秒 1 小节而不是每 3 秒 100 小节,代码应如下所示:
#define MQTT_KEEPALIVE 300
// headers ...
// setup() ...
void loop() {
//Create an empty array
JsonArray arr = doc.to<JsonArray>();
static auto t_start = millis(); // static will preserve last value even after exiting loop
int8_t count = 0;
while (count < 100) { // stays here whole 300s, so if the keep alives are needed or doing something else, it should be inside too
client.loop(); // sugested in comments
if (millis() - t_start >= 3000) {
t_start += 3000;
++count;
//MPU reading
Wire.beginTransmission(MPU);
Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H)
Wire.endTransmission(false);
Wire.requestFrom(MPU, 14, true); // request a total of 14 registers
AcX = Wire.read() << 8 | Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
AcY = Wire.read() << 8 | Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
AcZ = Wire.read() << 8 | Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
//Create a JSON Object
JsonObject obj = doc.createNestedObject();
obj["AcX"] = AcX;
obj["AcY"] = AcY;
obj["AcZ"] = AcZ;
}
// handling keep alives every X seconds as it's unlikely as long as 300s:
// if (...) sendKeepAlive();
}
// after 100 measures it'll get here:
//MQTT PUBLISHING JSON PACKAGE
char mqttData[MQTT_BUFFER];
serializeJson(doc, mqttData);
Serial.println(mqttData);
int ret = client.publish("esp8266/JSON", mqttData);
} //end of loop
但是它应该只解决代码中最明显的问题。可能还有其他的,比如缓冲区可能太小,或者......
未经测试,我没有此硬件设置