2023年8月17日 星期四

Node-RED with ESP32 communication via Serial Port

Purpose:

This project based on  the DS18B20 - ESP32 one Wire Bus Application video and blog ESP32 one Wire Bus  Application – DS18B20 section article, to use ESP32 to send the temperature of DS18B20 to Node-RED through the serial port. Three modes are designed in the code, DS18B20_ON, DS18B20_OFF and Node-RED modes.

Fundamental:

Node-RED is a programming tool for wiring together hardware devices, APIs and online services in new and interesting ways. It provides a browser-based editor that makes it easy to wire together flows using the wide range of nodes in the palette that can be deployed to its runtime in a single-click.
Node-RED 是 IBM 以 Node.js 為基礎,開發出來的視覺化 IOT 開發工具
透過「流程圖」方式的操作,透過 Node-RED 完成許多後端才能做的事情.

一、Install Node-RED (Windows下)

1. Go to Node.js :https://nodejs.org/en/,download recommended file.

2.Install (node-v18.17.1-x64.msi,檔案不大,大約30MB)

3.Verify Node.Js and NPM version

4.Input npm install -g --unsafe-perm node-red Install Node-RED

5. Key-In node-red start node-red service
6.打開瀏覽器,網址列輸入 http://127.0.0.1:1880/,就可以打開 Node-RED,左邊是一些功能流程的節點,每個節點都有各自的功能,中間的區域就是讓我們透過這些節點組成流程圖。


YouTube Demo:

ESP32 Code Introduction:
#include <OneWire.h>
#include <DallasTemperature.h>
#include <BluetoothSerial.h>
//--------- Flag structure --------------------------------------
typedef struct _vFlag
{
  uint8_t BTFlag = 0;
  uint8_t DC_Flag = 0;
  uint8_t CANFlag = 0;
  uint8_t I2C_Flag = 0;
  uint8_t BMP180Flag = 0;
  uint8_t DS18B20Flag = 0;
  uint8_t JSONFlag = 0;
  uint8_t LEDFlag = 1;
  uint8_t sensor_Flag = 0;
  uint8_t sensor1_Flag = 0;
  uint8_t initial_Flag = 0;
  uint8_t FunctionFlag = 3;
  uint8_t SendFlag = 0;
  uint8_t BMPCnt = 0;
} vFlag;
vFlag *flag_Ptr;
vFlag flag;
//-----   DS18B20  ------------------
#define DQ_Pin 4

OneWire oneWire(DQ_Pin);
DallasTemperature sensors(&oneWire);

byte data[12]; // buffer for data
byte address[8]; // 64 bit device address

#define LED_BUILTIN 2
BluetoothSerial SerialBT;
//----------uart--------------
#define LINE_BUFFER_LENGTH 64
//--------- uart structure --------------------------------------
typedef struct _vUart
{
  char c;
  int lineIndex = 0;
  int line1Index = 0;
  int BTlineIndex = 0;
  bool lineIsComment;
  bool lineSemiColon;
  //char *line;
  char line[128];
  //char line1[128];
  char BTline[20];
  //char R_line[20];
  //char L_line[20];
  String inputString;
  String BTinputString;
  String S1inputString;
  int V[16];
  char ctemp[30];
  char I2C_Data[80];
  int DC_Spped = 50;
  float Voltage[16];
  int Buffer[128];
  int StartCnt = 0;
  int ReadCnt = 0;
  int sensorValue = 0;
} vUart;
vUart *Uart_Ptr;
vUart Uart;

//-------------------------------------------------
void setup()
{
  Serial.begin(9600);
  Serial.println(F("init"));
  pinMode(LED_BUILTIN, OUTPUT);
  SerialBT.begin("BT_BS18B20");// BTName

  if (oneWire.search(address))
  {
    Serial.println("Slave device found!");
    Serial.print("Device Address = ");
    Serial.println(address[0]);
  }
  else
  {
    Serial.println("Slave device not found!");
  }
  //-----DS-----------
  sensors.begin();
}
//-----------------------------------------
void loop()
{
  Serial.print(F("Main at core:"));
  Serial.println(xPortGetCoreID());
  while(1)
  {
    if(flag.LEDFlag == 1)
    {
      digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
      vTaskDelay(300);
      digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
      vTaskDelay(300);
    }
    while (Serial.available() > 0)
    {
      Uart.c = Serial.read();

      if ((Uart.c == '\n') || (Uart.c == '\r'))
      { // End of line reached
        if (Uart.lineIndex > 0)
        { // Line is complete. Then execute!
          Uart.line[Uart.lineIndex] = '\0'; // Terminate string

          processCommand(Uart.line); // do something with the command
          SerialBT.println(Uart.line);

          Uart.lineIndex = 0;
          Uart.inputString = "";
        }
        else
        {
          // Empty or comment line. Skip block.
        }
        Uart.lineIsComment = false;
        Uart.lineSemiColon = false;
        Serial.println(F("ok>"));
      }
      else
      {
        //Serial.println( c );
        if ((Uart.lineIsComment) || (Uart.lineSemiColon))
        {
          if (Uart.c == ')')
            Uart.lineIsComment = false; // End of comment. Resume line.
        }
        else
        {
          if (Uart.c == '/')
          { // Block delete not supported. Ignore character.
          }
          else if (Uart.c == '~')
          { // Enable comments flag and ignore all characters until ')' or EOL.
            Uart.lineIsComment = true;
          }
          else if (Uart.c == ';')
          {
            Uart.lineSemiColon = true;
          }
          else if (Uart.lineIndex >= LINE_BUFFER_LENGTH - 1)
          {
            Serial.println("ERROR - lineBuffer overflow");
            Uart.lineIsComment = false;
            Uart.lineSemiColon = false;
          }
          else if (Uart.c >= 'a' && Uart.c <= 'z')
          { // Upcase lowercase
            Uart.line[Uart.lineIndex] = Uart.c - 'a' + 'A';
            Uart.lineIndex = Uart.lineIndex + 1;
            Uart.inputString += (char)(Uart.c - 'a' + 'A');
          }
          else
          {
            Uart.line[Uart.lineIndex] = Uart.c;
            Uart.lineIndex = Uart.lineIndex + 1;
            Uart.inputString += Uart.c;
          }
        }
      }
    } //while (Serial.available() > 0)
    while (SerialBT.available())
    {
      String BTdata = SerialBT.readString();

      Serial.println(BTdata);
      BTprocessCommand(BTdata);
    }//while (BT.available())
 
    if(flag.DS18B20Flag == 1)
    {
      vDS18B20Task();
    }
    if(flag.DS18B20Flag == 2)
    {
      vNodeRedTask();
    }

  }
}
//-------------------------------------
void BTprocessCommand(String data)
{
 
}
//----------------------------------------
void processCommand(char *data)
{
  int len, xlen, ylen, zlen, alen;
  int tempDIO;
  String stemp;

  len = Uart.inputString.length();
  //---------------------------------------
  if (strstr(data, "VER") != NULL)
  {
    Serial.println(F("ESP32_20230710"));
  }
  if (strstr(data, "DS18B20_ON") != NULL)
  {
    flag.DS18B20Flag = 1;
    Serial.println(F("DS18B20_ON"));

  }
  if (strstr(data, "NODE-RED") != NULL)
  {
    flag.DS18B20Flag = 2;
    Serial.println(F("NODE-RED"));

  }
  if (strstr(data, "DS18B20_OFF") != NULL)
  {
    flag.DS18B20Flag = 0;
    Serial.println(F("DS18B20_OFF"));

  }
}
//-----------------------------------------
//-------------------------------------------
void vNodeRedTask()
{
  //Serial.print("Temperatures --> ");
  sensors.requestTemperatures();
  Serial.println(sensors.getTempCByIndex(0));
}
//-------------------------------------------
void vDS18B20Task()
{
  Serial.print("Temperatures --> ");
  sensors.requestTemperatures();
  Serial.println(sensors.getTempCByIndex(0));
}


//-------------------------------------------

沒有留言:

張貼留言