Всім привіт. Хочу поділиться одним з проектом створеним на базі 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);
}