You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在液体加注的while循环中实现按键暂停/恢复功能?

液体加注循环中暂停/恢复功能失效的解决方案

问题概述

实现了通过while循环控制液体加注至目标重量的Mezclas::echarLiquido函数,尝试添加暂停/恢复功能但未生效,但同个暂停按键在液体耗尽的逻辑中可正常触发恢复操作。

原代码(含语法错误)

void Mezclas::echarLiquido(int16_t pesoPorechar)
{
  // Encender la bomba correspondiente
  encenderBombaCorrespondiente();

  unsigned long tiempoInicioMezcla = millis(); 
  unsigned long tiempoUltimaVariacion = millis();
  pesoLiquido = PesoActual();
  pesoRelative = 0;
  EEPROM.get(PESO_RELATIVO_ADDRESS, pesoRelative);
  // Mostrar el mensaje adecuado en el LCD
  mostrarLiquido();
  delay(50);

  // Condition to attempt the weight goal
  while (pesoRelative < pesoPorechar)
  {
    // Pause button is pressed
    if(botonPausa.pulsado())
    {
      delay(20);
      pausarReanudarMezcla();
    }

    // Resuming the function
    if (enPausa)
    {
      esperarParaReanudar();
    }

    // Condition of the time error pomp 
    if (millis() - tiempoInicioMezcla > tiempoErrorBomba)
    {
      lcd.clear();
      delay(20);
      lcd.setCursor(1,0);
      lcd.print("ERROR BOMBA");
      delay(8000);
      apagarBombas();
      return;
    }
    
    mostrarLiquido();
    
    int16_t nuevoPesoActual = PesoActual();
   
    
    if (nuevoPesoActual != pesoLiquido)
    {
      tiempoUltimaVariacion = millis(); // Reiniciar el temporizador si hay cambio en el peso
    }
    
    // if the weight don't increase it mean's the liquid is exhausted
    if (millis() - tiempoUltimaVariacion > 15000) // Si no hay cambio en el peso por 5 segundos
    {
      mostrarAgotado();
      apagarBombas();

      // wait until the pause button is pressed to continue and resuming 
      while (!botonAgotado.pulsado())
      {
        delay(300);
      }

      // Reiniciar la bomba correspondiente
      encenderBombaCorrespondiente();

      // Reiniciar el tiempo de última variación
      tiempoUltimaVariacion = millis();
    }
     // resuming the section of the liauid measurement
    nuevoPesoActual = PesoActual();
    pesoRelative += nuevoPesoActual - pesoLiquido;
    pesoLiquido = nuevoPesoActual;
    EEPROM.put(PESO_RELATIVO_ADDRESS, pesoRelative);
    updateProgressBar(pesoRelative, pesoPorechar, 1); 
    delay(500);
 }

  // The end of the function 
  pesoLiquido = PesoActual();
  EEPROM.put(PESO_ACEITE_ACTUAL_ADRESS, pesoLiquido);
  EEPROM.put(PESO_RELATIVO_ADDRESS, 0);
  
  // Apagar la bomba correspondiente
  apagarBombas();

  delay(1000);

// 语法错误:C++不允许函数嵌套定义,此处两个函数不能放在echarLiquido内部
void Mezclas::pausarReanudarMezcla()
{
  enPausa = !enPausa;
  if (enPausa)
  {
    Pantallamezcla(8);
  }
  else
  {
    Pantallamezcla(9);
    delay(3000);
  }
}

void Mezclas::esperarParaReanudar()
{
  while (enPausa)
  {
    // Esperar hasta que se reanude la mezcla
    if (botonPausa.pulsado())
    {
      pausarReanudarMezcla();
    }
  }
}

} // 多余的闭合括号

问题分析

  1. 语法错误:C++不允许函数嵌套定义,pausarReanudarMezcla和esperarParaReanudar被错误地放在了echarLiquido函数内部,导致编译失败,功能根本无法运行。
  2. 暂停时未停止油泵:进入暂停状态后,油泵仍在运行,导致液体继续加注,违背暂停的预期。
  3. 阻塞式延迟影响按键响应:主循环中的delay(500)会阻塞程序,导致暂停按键的检测不及时;esperarParaReanudar中的循环没有添加短延迟,可能导致CPU占用过高,同时按键检测可能受抖动影响。
  4. 恢复逻辑缺失油泵重启:恢复时没有重新开启油泵,导致暂停后无法继续加注。

修复方案

1. 修正代码结构

将pausarReanudarMezcla和esperarParaReanudar移至echarLiquido函数外部,确保符合C++语法规范。

2. 完善暂停/恢复逻辑

  • 暂停时关闭油泵,恢复时重新开启油泵
  • 优化按键检测,添加防抖处理,避免阻塞
  • 调整延迟逻辑,确保按键响应及时

修复后的完整代码

// 修正:将函数移至echarLiquido外部
void Mezclas::pausarReanudarMezcla()
{
  enPausa = !enPausa;
  if (enPausa)
  {
    Pantallamezcla(8);
    apagarBombas(); // 暂停时关闭油泵
  }
  else
  {
    Pantallamezcla(9);
    encenderBombaCorrespondiente(); // 恢复时重新开启油泵
    delay(3000); // 给用户留够查看恢复提示的时间
  }
}

void Mezclas::esperarParaReanudar()
{
  while (enPausa)
  {
    if (botonPausa.pulsado())
    {
      delay(20); // 防抖处理
      if (botonPausa.pulsado()) // 再次确认按键按下
      {
        pausarReanudarMezcla();
      }
    }
    delay(50); // 降低CPU占用,同时保证按键响应
  }
}

void Mezclas::echarLiquido(int16_t pesoPorechar)
{
  encenderBombaCorrespondiente();

  unsigned long tiempoInicioMezcla = millis(); 
  unsigned long tiempoUltimaVariacion = millis();
  pesoLiquido = PesoActual();
  pesoRelative = 0;
  EEPROM.get(PESO_RELATIVO_ADDRESS, pesoRelative);
  mostrarLiquido();
  delay(50);

  while (pesoRelative < pesoPorechar)
  {
    // 检测暂停按键,添加防抖
    if(botonPausa.pulsado())
    {
      delay(20);
      if(botonPausa.pulsado())
      {
        pausarReanudarMezcla();
      }
    }

    // 进入暂停等待逻辑
    if (enPausa)
    {
      esperarParaReanudar();
      // 恢复后重置时间计数器,避免误触发超时错误
      tiempoInicioMezcla = millis();
      tiempoUltimaVariacion = millis();
    }

    // 油泵超时错误检测
    if (millis() - tiempoInicioMezcla > tiempoErrorBomba)
    {
      lcd.clear();
      delay(20);
      lcd.setCursor(1,0);
      lcd.print("ERROR BOMBA");
      delay(8000);
      apagarBombas();
      return;
    }
    
    mostrarLiquido();
    
    int16_t nuevoPesoActual = PesoActual();
   
    if (nuevoPesoActual != pesoLiquido)
    {
      tiempoUltimaVariacion = millis();
    }
    
    // 液体耗尽处理
    if (millis() - tiempoUltimaVariacion > 15000)
    {
      mostrarAgotado();
      apagarBombas();

      while (!botonAgotado.pulsado())
      {
        delay(50); // 优化延迟,降低CPU占用
      }

      encenderBombaCorrespondiente();
      tiempoUltimaVariacion = millis();
      tiempoInicioMezcla = millis(); // 重置超时计数器
    }
    
    nuevoPesoActual = PesoActual();
    pesoRelative += nuevoPesoActual - pesoLiquido;
    pesoLiquido = nuevoPesoActual;
    EEPROM.put(PESO_RELATIVO_ADDRESS, pesoRelative);
    updateProgressBar(pesoRelative, pesoPorechar, 1); 
    delay(500);
 }

  // 加注完成处理
  pesoLiquido = PesoActual();
  EEPROM.put(PESO_ACEITE_ACTUAL_ADRESS, pesoLiquido);
  EEPROM.put(PESO_RELATIVO_ADDRESS, 0);
  
  apagarBombas();
  delay(1000);
}

关键修改说明

  • 语法修正:将嵌套的函数移至外部,确保代码能正常编译。
  • 暂停时停泵:在pausarReanudarMezcla的暂停分支中调用apagarBombas(),恢复时调用encenderBombaCorrespondiente()。
  • 防抖处理:在按键检测时添加短延迟后再次确认,避免误触发。
  • 时间重置:恢复后重置tiempoInicioMezcla和tiempoUltimaVariacion,防止暂停期间的时间累积触发超时错误。
  • 优化CPU占用:在等待循环中添加短延迟,避免CPU满负荷运行。

内容的提问来源于stack exchange,提问作者Abdelhak El Alaoui

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 17:44:55