arduino - 可以用 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
解决方案
只需实现一个简单的串行协议。无需结合您的草图和 Firmata。
如果您的 PI 的工作是可视化并提供用户界面,那么它所要做的就是不断接收值并按需发送命令。
您的 Arduino 不断发送值并检查它是否收到命令。
推荐阅读
- python - 用随机值替换空值
- power-automate - Power Automate Flow - 防止流电子邮件中的 SharePoint 多行文本列换行
- android - 在 SIGSEGV /SEGV_MAPERR 崩溃之前登录到 Logcat
- javascript - 启用或禁用另一个页面上的按钮
- ios - StreamProvider - Flutter - 如何在用户登录时更新流
- extract - 是否可以将文件添加到文件夹后立即重命名?
- python - 将所有 postgresql 表下载到 pandas
- c++ - 如何在 SDL2 中制作相机变焦效果?
- python - 如何检查字符串是否在 pymongo.collection.collection 对象中
- powershell - 使用 PowerShell 启用 DNS 服务器清理