Node-RED 우노빅보드 스마트팜
ESP8266 + ARDUINO UDP SERVER / 전압 & 전류 데이터
ZEROWIN.ART
2020. 8. 12. 18:09
728x90
아두이노 전류전압 데이터
아두이노에서 특정 보드에 대한 전류/전압 데이터를 수집합니다.
ESP8266 WIFI 모듈을 연결하여 데이터를 서버로 전송합니다.
디지털핀 2/3번핀과 연결하여 소프트웨어 시리얼을 이용하여 통신합니다.
WiFiEsp 라이브러리
https://github.com/bportaluri/WiFiEsp
bportaluri/WiFiEsp
Arduino WiFi library for ESP8266 modules. Contribute to bportaluri/WiFiEsp development by creating an account on GitHub.
github.com
ESP8266 보드를 사용하면 WiFiEsp 라이브러리를 사용하여 Arduino 보드를 인터넷에 연결할 수 있습니다.
들어오는 연결을 수락하는 서버 또는 나가는 연결을 만드는 클라이언트 역할을 할 수 있습니다.
WiFiEsp 라이브러리는 Arduino WiFi 및 이더넷 라이브러리와 매우 유사하며 많은 함수 호출이 동일합니다.
ESP SDK 버전 1.1.1 이상 (AT 버전 0.25 이상)을 지원합니다.
* 표준 Arduino WiFi 라이브러리와 호환되는 API.
* 표준 ESP 펌웨어의 AT 명령을 사용합니다 (사용자 정의 펌웨어를 플래시 할 필요 없음).
* 하드웨어 및 소프트웨어 직렬 포트를 지원합니다.
프로그래밍
아두이노를 UDP 서버로 만들어서 클라이언트에서 데이터 요청에 응답합니다.
이 프로젝트에서는 측정하는 보드의 전압과 전류를 전송합니다.
#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());
memset(temp, 0x00, 64);
sprintf(temp, "TEST");
sprintf(temp, "Current: %d.%d mA Voltage:%d.%d V",
(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);
}