Контроль двух нагрузок по бесконтактному датчику тока SCT-013-100
- Войдите на сайт для отправки комментариев
Хочу поделится своим проектом, возможно кому нибудь пригодится.
Суть моего проекта сделать устройство для вкл./откл. двух нагрузок при запитки этих нагрузок от генератора ( что-бы не перегружать его).
Состав:
1. Arduino Nano
2. LCD 16x2 I2C
3. Стабилизатор напряжения на LM317T
4. Пару реле с обвязкой
5. Бесконтактный датчик тока SCT- 013-100A
6. Две кнопки без фиксации
7. Пьезопищалка
8. Резисторы, транзисторы, конденсаторы и разъёмы.
Возможности.
Можно задать уставки (мощность нагрузки) для первого и второго канала управления.
Понимает подключен ли датчик тока.
Есть два входа контроля состояния контакторов (вкл./выкл.)
Отключение звука при неисправностях
Показывает время работы с момента вкл. устройства в минутах
Вот пару видео по моему устройству
Устройство
По датчику тока
Код
https://drive.google.com/open?id=0BxCXdPdJNbotNnJqWmdqQ2RrOU0
Плата lay6
https://drive.google.com/open?id=0BxCXdPdJNbotSnRleUJQRHQzdkE
// Код для управления двумя нагрузками (через реле+контактор) от датчика тока для генератора на 25А // Назначение входов/выходов // A1 - вход от датчика тока int RelayPin1 = 2;// pin 2 - выход управления реле 1 int RelayPin2 = 3;// pin 3 - выход управления реле 2 int StatusPin1 = 8;// pin 8 - вход состояния контактора нагрузки №1 int StatusPin2 = 7;// pin 7 - вход состояния контактора нагрузки №2 int CurrentMax = 23;// Максимальная уставка по току А const int Load1Pin = A2;// pin A2 - вход выбора нагрузки №1 const int Load2Pin = A0;// pin A3 - вход выбора нагрузки №2 int Load1Value = 0;// Переменная для АЦП А2 int Load2Value = 0;// Переменная для АЦП А0 float Load1 = 0;// Нагрузка №1 float Load2 = 0;// Нагрузка №2 int StatusCurrentPin = 9;// pin 9 - вход включения в разъём датчика тока int LCDCLEAR; int button1 = 0; int button2 = 0; int button3 = 0; int buttonPin = 10; #include "EmonLib.h" // Include Emon Library EnergyMonitor emon1; // Create an instance #include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x3F, 16, 2); //------------------------------------------------------------------------------------------------- unsigned long time; //================================================================================================= uint8_t tochki[8] = {B0, B00000, B0, B0, B0, B0, B10101}; uint8_t bukva_P[8] = {0x1F, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}; uint8_t bukva_Ya[8] = {B01111, B10001, B10001, B01111, B00101, B01001, B10001}; uint8_t bukva_L[8] = {0x3, 0x7, 0x5, 0x5, 0xD, 0x9, 0x19}; uint8_t bukva_Lm[8] = {0, 0, B01111, B00101, B00101, B10101, B01001}; uint8_t bukva_Mz[8] = {0x10, 0x10, 0x10, 0x1E, 0x11, 0x11, 0x1E}; uint8_t bukva_I[8] = {0x11, 0x13, 0x13, 0x15, 0x19, 0x19, 0x11}; uint8_t bukva_D[8] = {B01111, B00101, B00101, B01001, B10001, B11111, 0x11}; uint8_t bukva_G[8] = {B11111, B10001, B10000, B10000, B10000, B10000, B10000}; uint8_t bukva_IY[8] = {B01110, B00000, B10001, B10011, B10101, B11001, B10001}; uint8_t bukva_Z[8] = {B01110, B10001, B00001, B00010, B00001, B10001, B01110}; uint8_t bukva_ZH[8] = {B10101, B10101, B10101, B11111, B10101, B10101, B10101}; uint8_t bukva_Y[8] = {B10001, B10001, B10001, B01010, B00100, B01000, B10000}; uint8_t bukva_B[8] = {B11110, B10000, B10000, B11110, B10001, B10001, B11110}; uint8_t bukva_CH[8] = {B10001, B10001, B10001, B01111, B00001, B00001, B00001}; uint8_t bukva_IYI[8] = {B10001, B10001, B10001, B11001, B10101, B10101, B11001}; uint8_t bukva_TS[8] = {B10010, B10010, B10010, B10010, B10010, B10010, B11111, B00001}; uint8_t bukva_YU[8] = {B10111, B10101, B10101, B11101, B10101, B10101, B10111}; uint8_t bukva_U[8] = {B10001, B10001, B01010, B00100, B00100, B01000, B10000}; #include "pitches.h" int melodyErr[] = { NOTE_A6, NOTE_C7, NOTE_D7, NOTE_F7, NOTE_G7, NOTE_A7, NOTE_C8, NOTE_DS8, NOTE_A6, NOTE_C7, NOTE_D7, NOTE_F7, NOTE_G7, NOTE_A7, NOTE_C8, NOTE_DS8}; int noteDurationsErr[] = { 2,3,4,5,6,7,8,2,9,8,7,6,5,4,3,6}; // notes in the melody: int melody[] = { NOTE_C4, NOTE_G3, NOTE_G3, NOTE_A3, NOTE_G3, 0, NOTE_B3, NOTE_C4 }; // note durations: 4 = quarter note, 8 = eighth note, etc.: int noteDurations[] = { 4, 8, 8, 4, 4, 4, 4, 4 }; //=============================================================================================== void setup() { lcd.init(); // initialize the lcd lcd.backlight(); //--------------------------------------------------------------------------------------------- pinMode (RelayPin1, OUTPUT); pinMode (RelayPin2, OUTPUT); pinMode (StatusPin1, INPUT); pinMode (StatusPin2, INPUT); pinMode (Load1Pin, INPUT); pinMode (Load2Pin, INPUT); pinMode (StatusCurrentPin, INPUT); pinMode (buttonPin, INPUT); digitalWrite (RelayPin1, HIGH); digitalWrite (RelayPin2, HIGH); Serial.begin(9600); //-------------------------------------------------------------------------------------------- emon1.current(1, 60.6); // Current: input pin, calibration. //-------------------------------------------------------------------------------------------- genich ();// Версия платы lcd.setCursor(0, 1); lcd.print(" Current_V6_LSD");// Версия ПО melodi (); //uint32_t start_time = millis();//задержка 5 с. //while ((millis() - start_time) < 5000);// //============================================================================================ // Установка тока(мощности) потрябляемой нагрузкой №1 Load1Value = analogRead(Load1Pin); Load1 = map(Load1Value, 0, 269, 0, 255);// Значения 269 подбираем с помощью скеча RezistCalib //-------------------------------------------------------------------------------------------- lcd.clear(); lcd.setCursor(0, 0); if (Load1 <= 43) { Load1 = 2.28; nagruzka1 (); lcd.print("=0.5kW"); } if (Load1 >= 44 && Load1 <= 87) { Load1 = 4.55; nagruzka1 (); lcd.print("=1kW"); } if (Load1 >= 88 && Load1 <= 131) { Load1 = 6.82; nagruzka1 (); lcd.print("=1.5kW"); } if (Load1 >= 132 && Load1 <= 175) { Load1 = 9.09; nagruzka1 (); lcd.print("=2kW"); } if (Load1 >= 176 && Load1 <= 219) { Load1 = 11.37; nagruzka1 (); lcd.print("=2.5kW"); } if (Load1 >= 220) { Load1 = 13.64; nagruzka1 (); lcd.print("=3kW"); } //============================================================================================= // Установка тока(мощности) потрябляемой нагрузкой №2 Load2Value = analogRead(Load2Pin); Load2 = map(Load2Value, 0, 175, 0, 255); //--------------------------------------------------------------------------------------------- lcd.setCursor(0, 1); if (Load2 <= 43) { Load2 = 2.28; nagruzka2 (); lcd.print("=0.5kW"); } if (Load2 >= 44 && Load2 <= 87) { Load2 = 4.55; nagruzka2 (); lcd.print("=1kW"); } if (Load2 >= 88 && Load2 <= 131) { Load2 = 6.82; nagruzka2 (); lcd.print("=1.5kW"); } if (Load2 >= 132 && Load2 <= 175) { Load2 = 9.09; nagruzka2 (); lcd.print("=2kW"); } if (Load2 >= 176 && Load2 <= 219) { Load2 = 11.37; nagruzka2 (); lcd.print("=2.5kW"); } if (Load2 >= 220) { Load2 = 13.64; nagruzka2 (); lcd.print("=3kW"); } //---------------------------------------------------------------------------------------------- delay(5000); lcd.clear(); //---------------------------------------------------------------------------------------------- } void loop() { //********************************************************************************************** int StatusCurrent = digitalRead(StatusCurrentPin);// if (StatusCurrent == LOW) {// Делаем проверку подключения датчика тока if (LCDCLEAR == 1)// После включения датчика тока делаем очистку экрана и обнуляем переменную очистки экрана LCDCLEAR { lcd.clear(); LCDCLEAR = 0; button3 = 0; } //********************************************************************************************** double Irms = emon1.calcIrms(2000);;// Считываем показания с датчика тока //---------------------------------------------------------------------------------------------- lcd.setCursor(0, 0); lcd.print("I ="); lcd.print(Irms);//Выводим среднеквадратичное значение тока lcd.print("A "); //--------------------------------------------------------------------------------------------- lcd.setCursor(10, 0); time = millis(); lcd.print(time / 100000);// выводим в минутах время работы контроллера с моента запуска lcd.setCursor(13, 0); lcd.print("min"); //--------------------------------------------------------------------------------------------- Serial.println("Irms:"); Serial.println(Irms);// Выводим показания датчика тока в монитор //--------------------------------------------------------------------------------------------- if (Irms <= CurrentMax) { // Проверяем условие №1 превышения максимального тока Serial.println("currentMAX--OK");// Выводим в монитор об успешном прохождении условия №1 int val12 = Irms + Load1;// Делаем расчет тока при включении нагрузки №1 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ if (val12 <= CurrentMax) {// Проверяем условие №2 превышения максимального тока Serial.println("val12--OK");//Выводим в монитор об успешном прохождении условия №2 if (digitalRead(RelayPin1) == HIGH && digitalRead(StatusPin1) == HIGH)// Проверяем условие №3 состояние выхода реле1, если выключен то включаем иначе пропускаем { digitalWrite(RelayPin1, LOW);// Включаем реле 1 Serial.println("RELAY1--ON");// Выводим в монитор о включении реле 1 lcd.setCursor (9, 1); lcd.print(" ");// Затираем надпись "КМ9" button1 = 0; if (digitalRead(StatusPin2) == HIGH)// Проверяем если второй контактор в норме то { lcd.setCursor (0, 1); lcd.print(" ");// затираем надпись "НЕИСПР." } } else { if (digitalRead(RelayPin1) == HIGH && digitalRead(StatusPin1) == LOW) { neicpravKM9 (); if (digitalRead(buttonPin) == HIGH) button1 = 1; if (button1 == 0) { melodiErr (); } } } } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ else if (val12 >= CurrentMax)Serial.println("val12--NO"); // Выводим в монитор о не прохождении условия №2 //------------------------------------------------------------------------------------------------ if (digitalRead(StatusPin1) == LOW && digitalRead(RelayPin1) == LOW)// Проверяем условие №4 состояние о включении контактора №1 { neicpravKM9 (); if (digitalRead(buttonPin) == HIGH) button1 = 1; if (button1 == 0) { melodiErr (); } } //------------------------------------------------------------------------------------------------ double Irms = emon1.calcIrms(2000);// Считываем показания с датчика тока //------------------------------------------------------------------------------------------------ if (Irms <= CurrentMax) // Проверяем условие №5 превышения максимального тока { Serial.println("currentMAX2--OK");//Выводим в монитор об успешном прохождении условия int val7 = Irms + Load2;// Делаем расчет тока при включении нагрузки №2 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ if (val7 <= CurrentMax) // Проверяем условие №6 превышения максимального тока { Serial.println("val7--OK");//Выводим в монитор об успешном прохождении условия if (digitalRead(RelayPin2) == HIGH && digitalRead(StatusPin2) == HIGH) // Проверяем условие №7 состояние выхода реле 2, если выключен то включаем иначе пропускаем { digitalWrite(RelayPin2, LOW);//Включаем реле 2 Serial.println("RELAY2--ON");//Выводим в монитор о включении реле 2 lcd.setCursor (12, 1); lcd.print(" ");// Затираем надпись "КМ8" button2 = 0; if (digitalRead(StatusPin1) == HIGH)// Проверяем если второй контактор в норме то { lcd.setCursor (0, 1); lcd.print(" ");// затираем надпись "НЕИСПР." } } else { if (digitalRead(RelayPin2) == HIGH && digitalRead(StatusPin2) == LOW) { neicpravKM8 (); if (digitalRead(buttonPin) == HIGH) button2 = 1; if (button2 == 0) { melodiErr (); } } } } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ else if (val7 >= CurrentMax)Serial.println("val7--NO"); // Выводим в монитор о не прохождении условия №6 } //--------------------------------------------------------------------------------------------------------------------------------------------- if (digitalRead(StatusPin2) == LOW && digitalRead(RelayPin2) == LOW) // Проверяем условие №8 состояние о включении контактора №2 { neicpravKM8 (); if (digitalRead(buttonPin) == HIGH) button2 = 1; if (button2 == 0) { melodiErr (); } } } //==================================================================================================================================================================================== else double Irms = emon1.calcIrms(2000);// Считываем показания с датчика тока if (Irms >= CurrentMax) // Проверяем условие №9 превышения максимального тока { Serial.println("currentMAX--NO");// Выводим в монитор о не прохождении условия №1 if (digitalRead(RelayPin1) == LOW) // Переход с условия №9. Проверяем условие №10 состояние выхода реле №1 { digitalWrite(RelayPin1, HIGH);// Выключаем реле 2 Serial.println("RELAY1--OFF");// Выводим в монитор о выключении реле №1 } else { //delay(10000); double Irms = emon1.calcIrms(2000);// Считываем показания с датчика тока if (Irms >= CurrentMax) // Проверяем условие №11 превышения максимального тока { if (digitalRead(RelayPin2) == LOW) // Переход с условия №11. Проверяем услови №12 состояние выхода реле 2 { digitalWrite(RelayPin2, HIGH);// Выключаем реле 2 Serial.println("RELAY2--OFF");// Выводим в монитор о выключении реле №2 } } } } } //****************************************************************************************************************************** else { datchik_ne_podklychen (); if (digitalRead(buttonPin) == HIGH) button3 = 1; if (button3 == 0) { melodiErr (); } } } //******************************************************************************************************************************* void datchik_ne_podklychen () { lcd.clear(); lcd.createChar(0, bukva_I); lcd.createChar(5, bukva_L); // создаем символы и записываем их в память LCD lcd.createChar(1, bukva_D); lcd.createChar(2, bukva_CH); lcd.createChar(3, bukva_P); lcd.createChar(4, bukva_YU); lcd.setCursor (3, 0); lcd.write(1); lcd.print("AT"); lcd.write(2); lcd.write(0); lcd.print("K "); lcd.print("HE"); lcd.setCursor (1, 1); lcd.write(3); lcd.print("O"); lcd.write(1); lcd.print("K"); lcd.write(5); lcd.write(4); lcd.write(2); lcd.print("EH !!!"); digitalWrite(RelayPin1, HIGH);// Выключаем реле 1 digitalWrite(RelayPin2, HIGH);// Выключаем реле 2 uint32_t start_time = millis();//задержка 1 с. while ((millis() - start_time) < 1000);// LCDCLEAR = 1; } //----------------------------------------------------------------------------------------------------------------------------------------------------- void genich () { lcd.clear(); lcd.createChar(0, bukva_G); // создаем символы и записываем их в память LCD lcd.createChar(1, bukva_IYI); lcd.createChar(2, bukva_CH); lcd.setCursor (2, 0); lcd.write(0); lcd.print("EH"); lcd.write(1); lcd.write(2); lcd.print(" rev.6"); } //----------------------------------------------------------------------------------------------------------------------------------------------------- void neicpravKM9 () { lcd.createChar(0, bukva_I); lcd.createChar(1, bukva_P); lcd.setCursor (0, 1); lcd.print("HE"); lcd.write(0); lcd.print("C"); lcd.write(1); lcd.print("PAB."); lcd.print("KM9"); digitalWrite(RelayPin1, HIGH); Serial.println("Oshibka1");// Выводим в монитор о неисправности контактора №1 //if (digitalRead(StatusPin1) == HIGH)lcd.clear(); } //----------------------------------------------------------------------------------------------------------------------------------------------------- void neicpravKM8 () { lcd.createChar(0, bukva_I); lcd.createChar(1, bukva_P); lcd.setCursor (0, 1); lcd.print("HE"); lcd.write(0); lcd.print("C"); lcd.write(1); lcd.print("PAB."); lcd.setCursor(12, 1); if (digitalRead(StatusPin1) == LOW && digitalRead(StatusPin2) == LOW) { lcd.print(","); } else lcd.print(" "); lcd.setCursor(13, 1); lcd.print("KM8"); digitalWrite(RelayPin2, HIGH); Serial.println("Oshibka2");// Выводим в монитор о неисправности контактора №2 //if (digitalRead(StatusPin2) == HIGH)lcd.clear(); } //----------------------------------------------------------------------------------------------------------------------------------------------------- void nagruzka1 () { lcd.createChar(0, bukva_G); // создаем символы и записываем их в память LCD lcd.createChar(1, bukva_U); lcd.createChar(2, bukva_Z); lcd.setCursor (0, 0); lcd.print("HA"); lcd.write(0); lcd.print("P"); lcd.write(1); lcd.write(2); lcd.print("KA 1"); } //----------------------------------------------------------------------------------------------------------------------------------------------------- void nagruzka2 () { lcd.createChar(0, bukva_G); // создаем символы и записываем их в память LCD lcd.createChar(1, bukva_U); lcd.createChar(2, bukva_Z); lcd.setCursor (0, 1); lcd.print("HA"); lcd.write(0); lcd.print("P"); lcd.write(1); lcd.write(2); lcd.print("KA 2"); } //----------------------------------------------------------------------------------------------------------------------------------------------------- void melodi () { for (int thisNote = 0; thisNote < 8; thisNote++) { // to calculate the note duration, take one second // divided by the note type. //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc. int noteDuration = 1000 / noteDurations[thisNote]; tone(11, melody[thisNote], noteDuration); // to distinguish the notes, set a minimum time between them. // the note's duration + 30% seems to work well: int pauseBetweenNotes = noteDuration * 1.30; delay(pauseBetweenNotes); // stop the tone playing: noTone(11); } } //----------------------------------------------------------------------------------------------------------------------------------------------------- void melodiErr () { for (int thisNote = 0; thisNote < 16; thisNote++) { // to calculate the note duration, take one second // divided by the note type. //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc. int noteDurationErr = 1000 / noteDurationsErr[thisNote]; tone(11, melodyErr[thisNote], noteDurationErr); // to distinguish the notes, set a minimum time between them. // the note's duration + 30% seems to work well: int pauseBetweenNotes = noteDurationErr /10; delay(pauseBetweenNotes); // stop the tone playing: noTone(11); } }Ноты
продашь девайс?
продашь девайс?
Добрый вечер.
Именно этот девайс нет..... он сделан под заказ.
У Вас есть какие-то трудности с повторением этого устройства ?
Спрашивайте, у меня тайн нет.
А вообщем могу повторить сей девайс....под Ваши задачи.
Библиотека Emonlib:
https://drive.google.com/open?id=0BxCXdPdJNbotS2xWcXZDcFJJNFk
fixedip поясни пж кое что по своему коду:
На каком основаниии выбрал число калибровки 60,6?
И опять же:
Откуда берется число 2000?
Добрый вечер)
топик еще жив?)
интересует точность прибора
не сверялись с токовыми клещами?
https://youtu.be/7UTS8B26mkc
fixedip поясни пж кое что по своему коду:
На каком основаниии выбрал число калибровки 60,6?
И опять же:
Откуда берется число 2000?
Извеняюсь за столь долгий ответ.... но уведомление пришло только сейчас о вашем вопросе
Как я помню 60.6 один из 3-х поправочных значений в библиотеке (он был выбран эксперементальным путем)
2000 - это кол-во витков на обмотке датчика