首页 > 解决方案 > 可以用 Node-red 和 Arduino 草图一起控制 Arduino 吗?

问题描述

这涉及 Arduino 和 Node-red,所以我在这里问这个!

我目前正在做一个涉及 Raspberry Pi 4、Arduino Mega 和一些电压/电流传感器的项目。传感器将通过 i2c 连接到 Arduino,因此来自传感器的值将由 Arduino 读取。除了被动读取模拟输入之外,我制作的 Arduino 草图还包括逻辑控制,继电器开关将根据传感器读数打开/关闭。

通过 Arduino 草图进行实际思考,我想在我的 Pi 上使用 Node-Red 作为可视化工具。例如,我的 Node-Red 仪表板将有一堆开关来控制继电器开关的操作,以及实时显示传感器值的仪表。

我已经阅读了关于 Firmata 和 StandardFirmata 本身就可以很好地工作,但是我将如何将 StandardFirmata 与我已经拥有的 Arduino 草图结合起来呢?

还有其他方法可以让我的理论发挥作用吗?

谢谢!!

如果需要,这是我的 Arduino 草图。

#include <Wire.h>

//using Arduino Mega 2560
//Virtual Node-red relay input IN1
const byte IN1 = 22; 
const byte IN2 = 24;
const byte IN3 = 26;
//Physical relay output K1
const byte K1 = 23; 
const byte K2 = 25;
const byte K3 = 27;
//Virtual Node-red switches
const byte Power = 28;   
const byte Charging = 30;
const byte Manual = 32;
const byte GetValues = 19;  //Interrupt Pin 19 on Mega2560

volatile int InterruptState = LOW;
//Sensor variables
float shuntvoltage_PV = 0;
float busvoltage_PV = 0;
float current_mA_PV = 0;
float loadvoltage_PV = 0;
float power_mW_PV = 0;

float shuntvoltage_Load = 0;
float busvoltage_Load = 0;
float current_mA_Load = 0;
float loadvoltage_Load = 0;
float power_mW_Load = 0;

int current_mA_Batt = 0;  

void setup()
{
  pinMode( IN1, INPUT );
  pinMode( IN2, INPUT );
  pinMode( IN3, INPUT );
  pinMode( K1, OUTPUT );
  pinMode( K2, OUTPUT );
  pinMode( K3, OUTPUT );
  pinMode( Power, INPUT );
  pinMode( Charging, INPUT );
  pinMode( Manual, INPUT );
  pinMode( GetValues, INPUT );

  attachInterrupt( digitalPinToInterrupt( GetValues ), ISR_GetValues, RISING );

  Serial.begin(9600);
}//setup

void loop()
{
  const int ST_POWER = 40;
  const int ST_CHARGING = 41;
  const int ST_MANUAL = 42;
  const int ST_CHECK_CURRS = 43;
  static byte stateControl = ST_POWER;

  switch ( stateControl )
  {
    case  ST_POWER:
      //Power
      if ( digitalRead( Power ) == HIGH ) {
        stateControl = ST_CHARGING;
      }
      break;

    case  ST_CHARGING:
      //Charging on?
      if ( digitalRead( Charging ) == LOW ) {
        //No
        stateControl = ST_MANUAL;
      }
      else {
        //Yes
        digitalWrite( K1, LOW );
        digitalWrite( K2, LOW );
        digitalWrite( K3, HIGH );
        stateControl = ST_CHARGING; //redundant, presented for illustrative purposes
      }//else
      break;

    case  ST_MANUAL:
      //Manual mode on?
      if ( digitalRead( Manual ) == LOW ) {
        //No
        stateControl = ST_CHECK_CURRS;
      }
      else {
        //Yes
        //Manual Operation of IN1, INT2, IN3
        //assumed to return false when "finished" manual operation
        //when done, go back to charging state
        if ( !HandleManualInputs() ) {
          stateControl = ST_CHARGING;
        }
      }//else
      break;

    case  ST_CHECK_CURRS:
      //Is Ipv > 0A?
      if ( current_mA_PV > 0.0 ) {
        //Yes
        digitalWrite( K2, HIGH );
        //Is Il = Ipv?
        if ( current_mA_Load == current_mA_PV ) {
          //Yes
          digitalWrite( K1, LOW );
          digitalWrite( K3, LOW );
        }//if
        //No
        //Is Il > Ipv?
        else if ( current_mA_Load > current_mA_PV ) {
          //Yes
          digitalWrite( K1, HIGH );
          digitalWrite( K3, LOW );
        }//else if
        //No
        //Is Il < Ipv?
        else {
          //Yes
          digitalWrite( K1, HIGH );
          digitalWrite( K3, LOW );
        }//else

      }//if
      //No
      //Is Il <= Ibatt?
      else if ( current_mA_Load <= current_mA_Batt ) {
        //Yes
        digitalWrite( K1, LOW );
        digitalWrite( K2, HIGH );
        digitalWrite( K3, HIGH );
      }//else if
      //No
      //Is Il > Ibatt?
      else {
        //Yes
        digitalWrite( K1, HIGH );
        digitalWrite( K2, LOW );
        digitalWrite( K3, LOW );
      }//else
      //No
      //Go back to chargin state
      stateControl = ST_CHARGING;
      break;
  }//switch
}//loop

bool HandleManualInputs( void )
{
  //"Manual Operation of IN1, IN2 and IN3"
  if ( digitalRead(Manual) == HIGH ) {
    digitalWrite( K1, LOW );
    digitalWrite( K2, LOW );
    digitalWrite( K3, LOW );
  }
}//HandleManualInputs

void ISR_GetValues( void )
{
  //"Get voltage/current of PV, Gen, Load and Batt"
  if (InterruptState = digitalRead(GetValues))
  {
    /*Serial.println("              INA219_PV  |   INA219_Load   ");
    Serial.print("Load Voltage:  "); Serial.print(loadvoltage_PV); Serial.print("      | "); Serial.print(loadvoltage_Load); Serial.println(" V");
    Serial.print("Current:       "); Serial.print(current_mA_PV); Serial.print("       | "); Serial.print(current_mA_Load); Serial.println("  mA");
    Serial.print("Power:         "); Serial.print(power_mW_PV); Serial.print("         | "); Serial.print(power_mW_Load); Serial.println("     mW");
    Serial.println("");
    Serial.print("Charge:   "); Serial.print(soc); Serial.println(" %");
    Serial.print("Voltage:   "); Serial.print(volts); Serial.println(" mV");
    Serial.print("Current:   "); Serial.print(current); Serial.println(" mA");
    Serial.println("--------------------------------------------------------");*/
    Serial.println("Values gotten");
  }
}//ISR_GetValues

这是我的 Node-red 节点的大致截图: 1

标签: arduinoraspberry-pinode-red

解决方案


只需实现一个简单的串行协议。无需结合您的草图和 Firmata。

如果您的 PI 的工作是可视化并提供用户界面,那么它所要做的就是不断接收值并按需发送命令。

您的 Arduino 不断发送值并检查它是否收到命令。


推荐阅读