임베디드 보드/아두이노

전압/전류 Data 전송 From Arduino to Node-RED

ZEROWIN.TECH 2020. 8. 13. 10:48
728x90

전류 / 전압 데이터를 Node-RED 서버로 전송합니다. 

Node-RED에서 데이터를 그래프 / 게이지 / 텍스트로 표시하여 사용자가 쉽게 확인 할 수 있도록 Dashboard를 구성합니다.

 

Node-RED

아래 저장한 파일을 Node-RED에서 불러옵니다.  프로젝트 진행했던 node 전체를 불러올수 있습니다.

 

flows (4).json
0.01MB

프로그래밍 / 설명

아두이노 + ESP8266 WIFI 프로그래밍

 

아두이노보드에서 10002 포트를 UDP SERVER 용도로 오픈합니다. 그리고 Node-RED 에서 요청이 오면 전류/전압 데이터로 응답합니다.

#include <Wire.h>
#include <Adafruit_INA219.h>

Adafruit_INA219 ina219;

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2); // LCD I2C 주소를설정한다. 16칸2줄LCD 사용
// 0x27 대신 스캐닝 된 주소를 넣는다.

#include "WiFiEsp.h"
#include <WiFiEspUdp.h>

// Emulate Serial1 on pins 6/7 if not present
#ifndef HAVE_HWSERIAL1
#include "SoftwareSerial.h"
SoftwareSerial Serial1(3, 2); // RX, TX
#endif

char ssid[] = "ZEROWIN";         // your network SSID (name)
char pass[] = "zzzzzzzz";        // your network password
int status = WL_IDLE_STATUS;     // the Wifi radio's status

WiFiEspUDP Udp;

unsigned int localPort = 10002;  // local port to listen on

char packetBuffer[32];          // buffer to hold incoming packet

void setup(void) 
{
  Serial.begin(115200);
  while (!Serial) {
      // will pause Zero, Leonardo, etc until serial console opens
      delay(1);
  }

  // initialize serial for ESP module
  Serial1.begin(9600);
  // initialize ESP module
  WiFi.init(&Serial1);

  // check for the presence of the shield
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    // don't continue
    while (true);
  }

  // attempt to connect to WiFi network
  while ( status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network
    status = WiFi.begin(ssid, pass);
  }

  Serial.println("You're connected to the network");
  
  printWifiStatus();

  uint32_t currentFrequency;
    
  // Serial.println("Hello!");
  
  // Initialize the INA219.
  // By default the initialization will use the largest range (32V, 2A).  However
  // you can call a setCalibration function to change this range (see comments).
  if (! ina219.begin()) {
    Serial.println("Failed to find INA219 chip");
    while (1) { delay(10); }
  }
  // To use a slightly lower 32V, 1A range (higher precision on amps):
  //ina219.setCalibration_32V_1A();
  // Or to use a lower 16V, 400mA range (higher precision on volts and amps):
  //ina219.setCalibration_16V_400mA();

  Serial.println("Measuring voltage and current with INA219 ...");

  lcd.init();
  lcd.backlight();                // 백라이트를켠다. (lcd.noBacklight() 는 백라이트 끈다.)
  lcd.write(12);

  Serial.println("\nStarting connection to server...");
  // if you get a connection, report back via serial:
  Udp.begin(localPort);
  
  Serial.print("Listening on port ");
  Serial.println(localPort);
}

void printWifiStatus()
{
  // print the SSID of the network you're attached to
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength
  long rssi = WiFi.RSSI();
  Serial.print("Signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}

#define MAX_NUM_CURRENT 10
float average_current[MAX_NUM_CURRENT] = { 0, };

int loop_count = 0;
void loop(void) 
{

  loop_count += 1;

  lcd.clear(); // 화면을 지운다.
  
  float shuntvoltage = 0;
  float busvoltage = 0;
  float current_mA = 0;
  float loadvoltage = 0;
  float power_mW = 0;

  shuntvoltage = ina219.getShuntVoltage_mV();
  busvoltage = ina219.getBusVoltage_V();
  current_mA = ina219.getCurrent_mA();
  power_mW = ina219.getPower_mW();
  loadvoltage = busvoltage + (shuntvoltage / 1000);
  
  Serial.print("Load Voltage:  "); Serial.print(loadvoltage); Serial.println(" V");
  Serial.print("Current:       "); Serial.print(current_mA);  // Serial.println(" mA");
  
  average_current[loop_count % MAX_NUM_CURRENT] = current_mA;

  double total = 0;
  for(int i = 0; i < MAX_NUM_CURRENT; i++)
  {
     total += average_current[i];
  }

  
  double average = total / MAX_NUM_CURRENT;
  if(loop_count < MAX_NUM_CURRENT) average = total / loop_count;

  Serial.print(","); Serial.print(average);
  Serial.println(" mA");
  

  char temp[64] = { 0x00, };
  sprintf(temp, "Current: %d.%dmA", 
    (int)average, (int)(average*10) % 10);
  lcd.setCursor(0, 0);
  lcd.print(temp);        // 읽은 문자를 LCD에 써라.

    memset(temp, 0x00, 64);
  sprintf(temp, "Voltage: %d.%d V", 
    (int)loadvoltage, (int)(loadvoltage*10) % 10);
  lcd.setCursor(0, 1);
  lcd.print(temp);        // 읽은 문자를 LCD에 써라.

/*
  Serial.println("UDP Send...");
    // send a reply, to the IP address and port that sent us the packet we received
    Udp.beginPacket("192.168.0.3", 50000);
    Udp.write(temp);
    Udp.endPacket();

*/

// if there's data available, read a packet
  int packetSize = Udp.parsePacket();
  if (packetSize) {
    Serial.print("Received packet of size ");
    Serial.println(packetSize);
    Serial.print("From ");
    IPAddress remoteIp = Udp.remoteIP();
    Serial.print(remoteIp);
    Serial.print(", port ");
    Serial.println(Udp.remotePort());

    // read the packet into packetBufffer
    int len = Udp.read(packetBuffer, 32);
    if (len > 0) {
      packetBuffer[len] = 0;
    }

      Serial.print("Contents:"); Serial.println(packetBuffer);
  
      // send a reply, to the IP address and port that sent us the packet we received
      Udp.beginPacket(Udp.remoteIP(), Udp.remotePort() + 1);
  
      memset(temp, 0x00, 64);
      sprintf(temp, "{ \"current\":%d.%d,\"voltage\":%d.%d }", 
        (int)average, (int)(average*10) % 10,    
        (int)loadvoltage, (int)(loadvoltage*10) % 10);    
      Udp.write(temp); // ReplyBuffer);
      Udp.endPacket();

      delay(5);
      Udp.stop();

      delay(5);
      Serial.println("\nStarting connection to server...");
      // if you get a connection, report back via serial:
      Udp.begin(localPort);
      
      Serial.print("Listening on port ");
      Serial.println(localPort);      

  }
  
  
  delay(100);
}

Node-RED

UDP 통신을 이용한 아두이노보드에 전압/전류 데이터를 요청하고 응답을 받습니다.

 

테스트 영상