【问题标题】:Holding value after printing from mqtt从 mqtt 打印后保持值
【发布时间】:2021-03-16 14:16:23
【问题描述】:

我有一个问题要问大家,打印后是否可以在内存中保存一个值。我举个例子:

Nodered 创建的界面有一个滑块,其数字从 20 到 30。你滑动它并选择一个像 25 这样的值,然后将该值发送回 arduino 或 esp 串行监视器,有一个命令可以创建一个该数字 25 的变量。好吧,一切都很好,但我知道当您发送数字时,它会触发变量 1 次。而且我需要一个可以在使用时记住该值的函数

我正在建造一个温室(多么原始),我想无线使用它,比如在温度为 22 摄氏度、光照百分比为 10% 以及时间为 19:00 至 22:00 时设置植物浇水给它浇水

问题是如何使用节点中滑块设置的变量在设置的确切温度下给植物浇水

这是我将在mqttFloodInterval 末尾使用的代码,我可以设置从 nodered 获取的变量

void mqttCallback(char* topic, byte* message, unsigned int length) {
  Serial.print("MQTT message received on topic: ");
  Serial.print(topic);
  Serial.print(". Message: ");
  String messageTemp;
  for (int i = 0; i < length; i++) {
    Serial.print((char)message[i]);
    messageTemp += (char)message[i];
  }
  Serial.println();
  Serial.println(messageTemp);
  if (String(topic) == mqttFloodInterval) {
    Serial.print("*** (Flood Interval Received)");
  }
  
}

为 ocrdu 编辑类似这样的东西:

if (String(topic) == mqttFloodInterval) {
    Serial.print("*** (Flood Interval Received)");
   mqttFloodInterval = wtrtemp;
  }
   if(wtrtemp == 23){
 digitalWrite(RELAY_PIN, HIGH); // turn on pump 5 seconds
     delay(5000);
  } 
     else {
     
       digitalWrite(RELAY_PIN, LOW);  // turn off pump 5 seconds
      delay(5000);
  }

然后做所有的 if 就像 if(wtrtemp == 24), if(wtrtemp == 25).... 等等

【问题讨论】:

  • 这个问题很难理解你想要完成的事情。我想在您的脑海中,阅读这个问题时很清楚,因为您是该项目的构造者并且心中有一个目标。但是我强烈建议您尝试告诉您您正在尝试做什么以及您遇到的当前问题,就像您向以前从未见过这样的系统的人解释它:)
  • Serial.print("*** (Flood Interval Received)"); 在此命令之后,我可以打开 LED 或其他东西,但是如果我将其设置为 25,则我需要将值保存在程序内存中,假设该数字应保存在内存中稍后使用,例如当传感器百分比值降至 25 以下时,某些命令将生效以打开继电器 5 秒以给植物浇水。问题是,当您发送低于我在开始时编写的命令的值时,它会触发程序一次并触发它。我需要一个可以保存该值以供以后使用的函数。
  • 因为当您使用滑块时,它只会发送一次值。滑块用于选择为植物浇水应达到的温度
  • 这是我在这个项目中面临的最大问题,它将决定程序的成败:D

标签: c++ arduino raspberry-pi adc


【解决方案1】:

再一次,我并没有完全理解你的目标到底是什么,所以我在下面的代码中给了你两个选项。如果您从//*option 1 中选择代码 sn-ps,您将能够一次将一个温度存储到您的 esp32 的全局内存中,这是最简单的,因此如果可行,请选择此选项。

//*option 2 是用于存储在全局内存中的温度值列表,因此如果您希望使用大量温度以供将来参考,这将是您的选择。

//----Two options choose one of them you prefer----//
//----whichever option you choose use the same option for all the code below----//

//*option 1
//store a single temperature value to a global variable
int global_memory_single_temperature = -1; //-1 not defined yet

//*option 2
//if you want to store multiple values, lets say 500 values use this:
int global_memory_multiple_temperature[500];
int current_temperatureValue = 0;


void setup()
{
  Serial.begin(115200);
}
void loop()
{

  //this happens some time in the future after you have recieved a value
  if (String(topic) == mqttFloodInterval)
  {
    Serial.print("*** (Flood Interval Received)");

    //----Two options choose one of them you prefer----//

    //*option 1
    //store a single wtrtemp to a global variable
    global_memory_single_temperature = wtrtemp;

    //*option 2
    //if you would like to store alot of temperatures for later use:
    global_memory_multiple_temperature[current_temperatureValue++];

    mqttFloodInterval = wtrtemp;
  }

  //Below can happen once your timer? i think hits the goal timer..

  //*if you choose option 1:
  //Later to check what the wtrtemp was use this:
  if (global_memory_single_temperature == 23)
  {
    digitalWrite(RELAY_PIN, HIGH); // turn on pump 5 seconds
    delay(5000);
  }
  else
  {

    digitalWrite(RELAY_PIN, LOW); // turn off pump 5 seconds
    delay(5000);
  }

  //*if you choose option 2:
  //or if you want to use multiple temperatures that are stored use this:
  for (int i = 0; i < current_temperatureValue; i++)
  {
    //this will loop through all previous stored temperatures and do the stuff below
    int currentWtrTempValue = global_memory_multiple_temperature[i];
    if (currentWtrTempValue == 23)
    {
      digitalWrite(RELAY_PIN, HIGH); // turn on pump 5 seconds
      delay(5000);
    }
    else
    {

      digitalWrite(RELAY_PIN, LOW); // turn off pump 5 seconds
      delay(5000);
    }
  }
}

-顺便说一句,我希望你已经在草图的 setup() 部分中有这个部分。

void setup() {
  pinMode(RELAY_PIN, OUTPUT);    // sets the relay pin available for digitalWrites...
}

【讨论】:

    【解决方案2】:

    String messageTemp 仅在 mqttCallback() 函数内部可用,如果我理解正确,这不是你想要的。

    如果您将messageTemp 设为全局,通过将String messageTemp; 行移动到代码顶部,就在setup() 之前,您就可以在代码中的任何地方使用它。

    请注意,您现在必须在从mqttCallback() 获取新数据之前将其清空,否则新数据将添加到您在messageTemp 中已有的数据中。

    您可以通过在 mqttCallback() 函数中删除 String messageTemp; 的位置添加行 messageTemp.remove(0); 来做到这一点。

    这同样适用于在mqttCallback() 函数中创建的其他Strings。

    【讨论】:

    • 我不是 100% 确定这是答案,但我明天会尝试。我在想,在函数 (if) 之后,我可以设置一个像 wtrtemp 这样的变量,然后执行另一个 if 函数来询问 wtrtemp 是否为 22C 并且光照 >10。 wtrtemp = 22 但就像我说的那样,我认为如果从 mqqt 得到一个答案,它只需要一次,也许用你的代码我可以做到这一点
    • 我编辑了上面的代码,说明我的想法
    猜你喜欢
    • 2018-05-02
    • 2013-12-30
    • 1970-01-01
    • 2012-06-09
    • 2014-03-01
    • 2017-03-03
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    相关资源
    最近更新 更多