Arduino Pro Mini + токовий датчик GY-712 ведуть контроль перегорання ламп

Всім привіт. Хочу поділиться одним з проектом створеним на базі Arduino.

Для мене робота з струмовими датчиками GY-712 була вперше. Перед створенням цього проекту створювався тестовий блок.

Якщо вам вже цікаво, тоді продовжимо.

Тут я розповім про один модуль, так як описувати і замальовувати 7 модулів не дуже-то і легко.

Було тих завдання:

1) Лампи (ліхтарі) 50-65ВТ 220В зміна або 24В постійка;

2) Індикація роботи лампи (світлодіод на панелі);

3) Звукова індикація перегорілої лампи.

Рішення було прийнято таке:

Використовуємо струмовий датчик GY-712 5А

З причин:

1) Міряє змінний і постійний струм;

2) Легко підключається до контролера;

3) Компактний;

4) Недорогий при замовленні з Китаю.

Давайте подивимося на схему:

Як працює програма.

При старті він перевіряється, чи увімкнений тумблер, якщо ввімкнений ти видається звуковий сигнал і світлова індикація, що б датчик можна було відкалібрувати без навантаження. Якщо тумблер вимкнути то прога видасть звук + індикація.

Далі йде калібрування. Після калібрування - звуковий сигнал.

І стартує основна програма. Контроль тумблера, якщо увімкнено контроль струму навантаження лампи, якщо струм вище заданого порогу то увімкнути індикацію якщо струму немає, то вимкнути індикацію і видати звуковий сигнал.

Ось проста схема без контролю тумблера, просто світлова індикація. Це на той випадок кому просто потрібен буде світловий індикатор навантаження - але тоді можна просто намотати на ферритове кільце дроту (зробити трансформатор струму) і підключити світлодіодик.

Фото тестів:

Відео тесту:

Приклад програми для одного додатка. IDE 1.5.2

float srab = 0.650;

const int currentPin1 = 0 ;//Аналоговий вхід з датчика струму

const unsigned long sampleTime = 100000UL; // sample over 100ms, it is an exact number of cycles for both 50Hz and 60Hz mains

const unsigned long numSamples = 250UL; // choose the number of samples to divide sampleTime exactly, but low enough for the ADC to keep up

const unsigned long sampleInterval = sampleTime/numSamples; // the sampling interval, must be longer than then ADC conversion time

//const int adc_zero = 512; // relative digital zero of the arudino input from ACS712 (could make this a variable and auto-adjust it)

int adc_zero1 ;//Змінна автоматичного калібрування

float first;

void setup()

{

pinMode (13, OUTPUT) ;//Пін індикатора

pinMode (12, OUTPUT) ;//пін звуку

pinMode (2, INPUT) ;//пін входу реле (тумблер)

digitalWrite(13, LOW);

digitalWrite(12, LOW);

while (digitalRead (2) = = 0) {//Якщо увімкнено тумблер, то видати звуковий і світловий сиглак поки не вимкнуть для можливості калібрування

tone(12,2000,500);

digitalWrite(13, HIGH);

delay(500);

digitalWrite(13, LOW);

delay(500);

}

tone (12,1500,100) ;//Звук калібрування

delay(180);

tone(12,1500,100);

delay(180);

tone(12,1500,100);

//Serial.begin(9600);

adc_zero1 = determineVQ(currentPin1); //Quiscent output voltage — the average voltage ACS712 shows with no load (0 A)

digitalWrite(13, HIGH);

tone(12,1000,100);

delay(150);

digitalWrite(13, LOW);

}

void loop(){

// Serial.print(«ACS712@A2_1:»);Serial.print(readCurrent(currentPin1,adc_zero1),3);Serial.println("" mA"");

delay(300);

if (digitalRead (2) = = 0) {//Якщо увімкнено тумблер:

if (readCurrent (currentPin1,adc_zero1) > srab )//Якщо ток більший за вказаний порг спрацювання то:

{

digitalWrite (13, HIGH) ;//Увімкнути індикатор

}

else//Інакше

{

if (digitalRead (2) = = 0) {//Якщо тумблер все ще увімкнено:

digitalWrite (13, LOW) ;//Погасити індикатор

tone (12,2000,500); }//і видати звуковий сигнал

}

}

else {//Інакше

digitalWrite (13, LOW) ;////Погасити індикатор

}

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

delay(250);

}

int determineVQ(int PIN) {

//Serial.print(«estimating avg. quiscent voltage:»);

long VQ = 0;

//read 5000 samples to stabilise value

for (int i=0; i<5000; i++) {

VQ += analogRead(PIN);

delay(1);//depends on sampling (on filter capacitor), can be 1/80000 (80kHz) max.

}

VQ /= 5000;

//Serial.print(map(VQ, 0, 1023, 0, 5000));Serial.println("" mV"");

return int(VQ);

}

float readCurrent(int PIN, int adc_zero0)

{

unsigned long currentAcc = 0;

unsigned int count = 0;

unsigned long prevMicros = micros() — sampleInterval;

while (count < numSamples)

{

if (micros() — prevMicros >= sampleInterval)

{

int adc_raw = analogRead(PIN) — adc_zero0;

currentAcc += (unsigned long)(adc_raw * adc_raw);

++count;

prevMicros += sampleInterval;

}

}

float rms = sqrt((float)currentAcc/(float)numSamples) * (75.7576 / 1024.0);

return rms;

//Serial.println(rms);

}