/*ПРОГРАМА ДЛЯ ВИМІРЮВАННЯ ПАРАМЕТРІВ ЕЛЕКТРИЧНОЇ МЕРЕЖІ Контролер - Arduino Nano Ethernet модуль - ENC28J60 Датчик струму - ACS712 30A GY-712 Трансформатор для виміровання напруги - 220/12В Розробка - LIC CONTROL http://lic.com.ua Схема: http://lic.com.ua/article08.htm З'єднування Arduino Nano <-> ENC28J60 D2 - INT D3 - RESET D10 - CS D11 - SI (ST) D12 - SO D13 - SCK З'єднайте Arduino Nano и ENC28J60 по цій схемі. Підключить Ethernet модуль в локальну комп'ютерну мережу. Завантажте програму в контролер та в пошуковому полі браузера наберіть http://192.168.100.10/ и натисніть Enter. Ваш ком'ютер обов'язково повинен бути підключеним до Інтернету. Якщо ви зробили все правильно, з'явиться сторінка з демонтстраціними графіками Після цього можна підключити датчик струму - ACS712 30A GY-712 і трансформатор і підібрати коєфіцієнти kI,kV для отримання правильних даних. */ #include #define DEMO true //втсновіть false для реального виміровання const char page1[] PROGMEM = "\n" "\n" "\n" "WEB MONITOR\n" "\n" "\n" "\n" "\n" "\n" ; const char page2[] PROGMEM = "\n" "\n" "\n" "
\n" "\n" "\n" ; const char page3[] PROGMEM = "HTTP/1.1 200 OK\n" "Content-Type: text/html\n" "Pragma: no-cache\n" "Connection: close\r\n\r\n" ; int IPin = A1; //Аналоговий вхід для виміровання струму int VPin = A0; //Аналоговий вхід для виміровання напруги double I=0.0, I1 = 0.0, I2 = 0.0; //Поточне та сумарне значення струму double V=0.0, V1 = 0.0, V2 = 0.0; //Поточне та сумарне значення напруги float S = 0.0; //Повна потужність float P = 0.0; //Активна потужність float Q = 0.0; //Реактивна потужність float P1 = 0.0; //Миттєва потужність float kI = 0.07398; //Коэфіціент виміровання струму, слід підібрати експериментально float kV = 0.97656; //Коэфіціент виміровання напруги, слід підібрати експериментально //Унікальна mac-адреса Ethernet модуля byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; //Всановіть зручну для вас адресу яка зараз вільна в вашій локальній мережі IPAddress ip(192, 168, 100, 10); EthernetServer server(80); String result=""; unsigned long time1 = 0, count=0, count1=0; unsigned long t1 = 0; boolean Restart = true; //Перезапуск мікросхеми ENC28J60 void resetENC28J60() { digitalWrite(3, LOW); delay(200); digitalWrite(3, HIGH); delay(100); } //Процедура вимірювання струму та напруги void MesureData() { float angle = 2*M_PI*count/100.0; if (!DEMO) { I1 = kI*(analogRead(IPin) - 512); //миттєве значення струму,А } else { I1 = sqrt(2.0)*100.0*sin(angle); //миттєве значення струму,А (в DEMO режимі) } if (!DEMO) { V1 = kV*(analogRead(VPin) - 512); //миттєве значення напруги,В } else { float d = 30.0; //зміщення синусоїди струму в градусах angle += 2.0*M_PI * d/360.0; V1 = sqrt(2.0)*220.0*sin(angle); //миттєве значення напруги,В (в DEMO режимі) } I2 += pow(I1,2); V2 += pow(V1,2); P1 += I1 * V1; count++; if (count > 1000) { I = sqrt(I2/count); //середньоквадратична величина струму, А V = sqrt(V2/count); //середньоквадратична величина напруги,В S = I * V; //повна потужність, ВА P = P1/count; //активна потужність, Вт float _Q = pow(S,2)-pow(P,2); if (_Q>0.0) Q = sqrt(_Q); //реактивна потужність, вар else Q = 0.0; P1 = 0.0; V2 = 0.0; I2 = 0.0; count = 1; t1 = millis(); } if (DEMO) { //Виводимо результати на графік. Значення потужності, для зручності відображення виводится поділеним на 100. if ((count % 5)==0) Serial.println("U:"+String(V1)+", I:"+String(I1)+", Urms:"+String(V)+", Irms:"+String(I)+", P/100:"+String(P/100.0)+", S/100:"+String(S/100.0)); } } //Процедура відправки в мережу даних, що зберігаються в PROGMEM void printProgStr (EthernetClient client, const char * str){ char c; if (!str) return; while ((c = pgm_read_byte(str++))) client.print (c); } //Формуємо JSON рядок даних для відправки його через мережу в браузер String DataToBrowser() { int t = int((millis()-time1)/1000); String s = String(t)+", "+String(V,1)+", "+ String(I,1)+", "+String(S/1000.0,2)+", "+ String(P/1000.0,2); return s; } //Початкові установки та ініціалізація void setup() { Serial.begin(9600); resetENC28J60(); Ethernet.begin(mac, ip); server.begin(); Serial.print("START SERVER AT:"); Serial.println(Ethernet.localIP()); } //Головний цикл виконання програми void loop() { MesureData(); EthernetClient client = server.available(); if (client) { result=""; while (client.connected()) { if (client.available()) { char c = client.read(); result+=c; if (c == '\n') { int y=result.indexOf("dat"); if ((y>0) and (!Restart)) { printProgStr(client, page3); String s = DataToBrowser(); client.println(s); } else { printProgStr(client, page1); printProgStr(client, page2); Restart = false; time1 = millis(); } break; } } } delay(1); client.stop(); } if (DEMO) delay(10); }