#include <LiquidCrystal_I2C.h> #include <Wire.h> LiquidCrystal_I2C lcd(0x27, 16, 2); #define clk 2 #define dt 3 #define sw 4 #define pwm 9 #define currentsense A0 #define voltagesense A1 char screen = 0; char arrowpos = 0; float power = 0; float current = 0; float curcurrent = 0; float curpower = 0; float curvoltage = 0; float curcurrentraw = 0; float zerocurrent = 514; float curvoltraw = 0; int counter = 0; volatile boolean currentmode = false; volatile boolean powermode = false; volatile boolean TurnDetected = false; volatile boolean up = false; volatile boolean button = false; const unsigned char PS_128 = (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); byte customChar1[8] = { 0b10000, 0b11000, 0b11100, 0b11110, 0b11110, 0b11100, 0b11000, 0b10000 }; byte customChar2[8] = { 0b00100, 0b01110, 0b11111, 0b00000, 0b00000, 0b11111, 0b01110, 0b00100, }; ISR(PCINT2_vect) { if (digitalRead(sw) == LOW) { button = true; } } void isr0 () { TurnDetected = true; up = (digitalRead(clk) == digitalRead(dt)); } void setup() { Serial.begin(115200); lcd.begin(); pinMode(sw, INPUT_PULLUP); pinMode(clk, INPUT); pinMode(dt, INPUT); pinMode(pwm, OUTPUT); pinMode(currentsense, INPUT); digitalWrite(pwm, LOW); //Tắt Mosfet ADCSRA &= ~PS_128; ADCSRA |= (1 << ADPS1) | (1 << ADPS0); PCICR |= 0b00000100; PCMSK2 |= 0b00010000; // turn o PCINT20(D4) attachInterrupt(0, isr0, RISING); //Tạo tín hiệu điều khiển PWM /*Thao khảo thêm chi tiết về điề khiển PWM * https://sites.google.com/site/qeewiki/books/avr-guide/pwm-on-the-atmega328 * https://en.wikipedia.org/wiki/Pulse-width_modulation */ TCCR1A = 0; TCCR1A = (1 << COM1A1) | (1 << WGM11); TCCR1B = 0; TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS10); ICR1 = 2047; OCR1A = 0; lcd.createChar(0, customChar1); lcd.createChar(1, customChar2); lcd.clear(); lcd.print(" ADJ CONST LOAD"); delay(2000); screen0(); lcd.setCursor(0, 0); lcd.write((uint8_t)0); } void loop() { if (currentmode) { curcurrentraw = analogRead(currentsense); curcurrent = ((curcurrentraw - zerocurrent) * (5.0 / 1023.0) / 0.100); //Serial.print(zerocurrent); //Serial.print(" "); Serial.print(curcurrentraw); Serial.print(" "); Serial.println(curcurrent); if (counter == 5000) { lcd.setCursor(4, 1); lcd.print(curcurrent); lcd.print("A "); counter = 0; } //Giám sát mosfet khi dòng thay đổi if (curcurrent < current) { OCR1A++;// Tăng độ rộng tín hiệu xung lên mosfet } else { OCR1A = OCR1A - 1; //Giảm độ rộng tín hiệu xung lên mosfet } counter++; delayMicroseconds(100); } if (powermode) { curcurrentraw = analogRead(currentsense); curcurrent = ((curcurrentraw - zerocurrent) * (5000.00 / 1023.00) / 100.00); curvoltraw = analogRead(voltagesense); curvoltage = curvoltraw * (5000.00 / 1023.00) * 7.20 /1000.00; curpower = curvoltage * curcurrent; // Serial.println(curpower); if (counter == 5000) { lcd.setCursor(4, 1); lcd.print(curpower); lcd.print("W "); counter = 0; } if (curpower < power) { OCR1A++; } else { OCR1A = OCR1A - 1; } counter++; delayMicroseconds(100); } if (TurnDetected) { delay(200); switch (screen) { case 0: switch (arrowpos) { case 0: if (!up) { screen0(); lcd.setCursor(0, 1); lcd.write((uint8_t)0); arrowpos = 1; } break; case 1: if (up) { screen0(); lcd.setCursor(0, 0); lcd.write((uint8_t)0); arrowpos = 0; } break; } break; case 1: switch (arrowpos) { case 0: if (!up) { screen1(); lcd.setCursor(0, 1); lcd.write((uint8_t)0); arrowpos = 1; } break; case 1: if (up) { screen1(); lcd.setCursor(0, 0); lcd.write((uint8_t)0); arrowpos = 0; } else { screen1(); lcd.setCursor(7, 1); lcd.write((uint8_t)0); arrowpos = 2; } break; case 2: if (up) { screen1(); lcd.setCursor(0, 1); lcd.write((uint8_t)0); arrowpos = 1; } break; } break; case 2: if (up) { power = power + 0.1; lcd.setCursor(7, 0); lcd.print(power); lcd.print("W"); lcd.write((uint8_t)1); lcd.print(" "); } else { power = power - 0.1; if (power < 0) { power = 0; } lcd.setCursor(7, 0); lcd.print(power); lcd.print("W"); lcd.write((uint8_t)1); lcd.print(" "); } break; case 4: switch (arrowpos) { case 0: if (!up) { screen4(); lcd.setCursor(0, 1); lcd.write((uint8_t)0); arrowpos = 1; } break; case 1: if (up) { screen4(); lcd.setCursor(0, 0); lcd.write((uint8_t)0); arrowpos = 0; } else { screen4(); lcd.setCursor(7, 1); lcd.write((uint8_t)0); arrowpos = 2; } break; case 2: if (up) { screen4(); lcd.setCursor(0, 1); lcd.write((uint8_t)0); arrowpos = 1; } break; } break; case 5: if (up) { current = current + 0.1; lcd.setCursor(9, 0); lcd.print(current); lcd.print("A"); lcd.write((uint8_t)1); lcd.print(" "); } else { current = current - 0.1; if (current < 0) { current = 0; } lcd.setCursor(9, 0); lcd.print(current); lcd.print("A"); lcd.write((uint8_t)1); lcd.print(" "); } break; } TurnDetected = false; } if (button) { delay(200); switch (screen) { case 0: if (arrowpos == 0) { screen = 1; screen1(); lcd.setCursor(0, 0); lcd.write((uint8_t)0); } else { screen = 4; screen4(); lcd.setCursor(0, 0); lcd.write((uint8_t)0); } break; case 1: switch (arrowpos) { case 0: screen = 2; screen2(); break; case 1: powermode = true; screen = 3; screen3(); break; case 2: screen = 0; screen0(); lcd.setCursor(0, 0); lcd.write((uint8_t)0); break; } break; case 2: screen = 1; screen1(); lcd.setCursor(0, 0); lcd.write((uint8_t)0); break; case 3: powermode = false; OCR1A = 0; counter = 0; screen = 1; screen1(); lcd.setCursor(0, 0); lcd.write((uint8_t)0); break; case 4: switch (arrowpos) { case 0: screen = 5; screen5(); break; case 1: screen = 6; screen6(); currentmode = true; counter = 0; break; case 2: screen = 0; screen0(); lcd.setCursor(0, 0); lcd.write((uint8_t)0); break; } break; case 5: screen = 4; screen4(); lcd.setCursor(0, 0); lcd.write((uint8_t)0); break; case 6: screen = 4; screen4(); lcd.setCursor(0, 0); lcd.write((uint8_t)0); currentmode = false; OCR1A = 0; break; } arrowpos = 0; button = false; } } void screen0() { lcd.clear(); lcd.setCursor(1, 0); lcd.print("Power Mode"); lcd.setCursor(1, 1); lcd.print("Current Mode"); } void screen1() { lcd.clear(); lcd.setCursor(1, 0); lcd.print("Power:"); lcd.print(power); lcd.print("W"); lcd.setCursor(1, 1); lcd.print("Start"); lcd.setCursor(8, 1); lcd.print("Back"); } void screen2() { lcd.clear(); lcd.setCursor(1, 0); lcd.print("Power:"); lcd.print(power); lcd.print("W"); lcd.write((uint8_t)1); } void screen3() { lcd.clear(); lcd.print("Set:"); lcd.print(power); lcd.print("W"); lcd.setCursor(0, 1); lcd.print("Cur:"); lcd.print(curpower); lcd.print("W"); lcd.setCursor(11, 1); lcd.write((uint8_t)0); lcd.print("STOP"); } void screen4() { lcd.clear(); lcd.setCursor(1, 0); lcd.print("Current:"); lcd.print(current); lcd.print("A"); lcd.setCursor(1, 1); lcd.print("Start"); lcd.setCursor(8, 1); lcd.print("Back"); } void screen5() { lcd.clear(); lcd.setCursor(1, 0); lcd.print("Current:"); lcd.print(current); lcd.print("A"); lcd.write((uint8_t)1); } void screen6() { lcd.clear(); lcd.print("Set:"); lcd.print(current); lcd.print("A"); lcd.setCursor(0, 1); lcd.print("Cur:"); lcd.print(curcurrent); lcd.print("A"); lcd.setCursor(11, 1); lcd.write((uint8_t)0); lcd.print("STOP"); }Nguồn: https://www.instructables.com/id/DIY-Adjustable-Constant-Load-Current-Power/
Thứ Năm, 28 tháng 3, 2019
Bộ tải giả cho Battery (Chỉnh dòng và Công suất)
Sử dụng board mạch Arduino Nano, cảm biến dòng ACS712, LCD, Encoder và vài linh kiện khác để xây dựng lên bộ điều chỉnh dòng/công suất làm bộ tải giả cho Battery. Bộ này có thể xử lý tối đa nguồn vào 30V và 20A (tùy thuộc vào cảm biến dòng và cầu phân áp), dòng tải cao nhớ phải có tản nhiệt.
Đăng ký:
Đăng Nhận xét (Atom)
Bài đăng nổi bật
Popular Posts
-
Đây là file Firmware (đã được unpack) và log của Box FPT khi chạy Firmware mới nhất. Download Firmware unpack: https://mega.nz/#!s0xSAAra!V...
-
Bữa rồi mình có đi chợ Nhật Tảo chơi mua được em "đồng nát" WR841N version 9.1, tính về cài OpenWRT mà không được toàn báo lỗi 180...
-
Bài viết này mình sẽ tập trung duy nhất về thiết bị xem truyền hình FPT HD (phiên bản chạy linux thuần của FPT sử dụng chip Sigma nhé)...
Không có nhận xét nào:
Đăng nhận xét
Cám ơn bạn đã để lại nhận xét