CHƯƠNG 3. Kết quả thực nghiệm
3.2 Thiết kế mạch trên Proteus
Hình 3.12 Mô phỏng Proteus Chân 2 của ARDUINO vào chân D7 của màn hình LCD Chân 3 của ARDUINO vào chân D6 của màn hình LCD Chân 4 của ARDUINO vòa chân D5 của màn hình LCD Chân 5 của ARDUINO vào chân D4 của màn hình LCD Chân 6 của ARDUINO vào chân ENA của L298
Chân 7 của ARDUINO vào nút chạy động cơ Chân 8 của ARDUINO vào nút dừng động cơ Chân 9 của ARDUINO vào chân IN2 của L298 Chân 10 của ARDUINO vào chân IN1 của L298
Chân 11 của ARDUINO vào chân E của mành hình LCD Chân 12 của ARDUINO vào chân RS của màn hình LCD Chân OUT1 của L298 nối với chân dương của ACS712 Chân OUT2 của L298 nối với động cơ
Chân âm của ACS712 nối với động cơ
Chân ACC của ACS712 vào dương nguồn 5V Chân GND của ACS712 nối với âm nguồn
Chân SENSA và chân SENSB của L298 nối với âm nguồn Chân A0 của ARDUINO nối với chân VOUT của ACS712
*Viết code chương trình cho Arduino
Khởi động phần mềm Arduino IDE và soạn code. Sau khi lập trình xong, nhấn để biên dịch code sau vài giây phần mềm sẽ biên dịch cho ta 1 file hex của chương trình.
#include <PID_v1.h>
#include <Wire.h>//thu vien ket noi i2c
#include <LiquidCrystal_I2C.h>//thu vien rieng cho LCD i2C
#define CURRENTSENSOR A0
#define BUTTONSET A3
#define BUTTONUP A2
#define BUTTONDOWN A1
#define PIN_OUTPUT 6// ENA L298N
#define MOTORA 10//IN1
#define MOTORB 9//IN2
#define BUTTONSTOP 8// CHan 8 arduino
#define BUTTONRUN 7//Chan 7 arduino
#define LED A4
#define BUZZER A5 byte RunMode=0; //stop
LiquidCrystal_I2C LCDDisplay(0x27,20,4);//khai bao dia chi i2C //Define Variables we'll be connecting to
double Setpoint=170, Input, Output; // Setpoint in mA //Specify the links and initial tuning parameters
double Kp=0.12222, Ki=8.9, Kd=0;//thong so bo dieu khien PID MyPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
byte SetupMode=0;
float CurrentmA;
unsigned long TimeCount;
float LimitCurrent=1000; // dòng điện giới hạn byte Arlarm=0;
byte LEDState=0;
void OnLED() {
digitalWrite(LED,HIGH);
digitalWrite(BUZZER,HIGH);
LEDState=1;
}
void OffLED() {
digitalWrite(LED,LOW);
digitalWrite(BUZZER,LOW);
LEDState=0;
}
void DisplayParameter() {
int DisplayValue;
DisplayValue=(int)Setpoint;
LCDDisplay.setCursor(4,2);
if(DisplayValue<1000) LCDDisplay.print(" ");
if(DisplayValue<100) LCDDisplay.print(" ");
if(DisplayValue<10) LCDDisplay.print(" ");
LCDDisplay.print(DisplayValue);
DisplayValue=(int)LimitCurrent;
LCDDisplay.setCursor(14,2);
if(DisplayValue<1000) LCDDisplay.print(" ");
if(DisplayValue<100) LCDDisplay.print(" ");
if(DisplayValue<10) LCDDisplay.print(" ");
LCDDisplay.print(DisplayValue);
}
void DisplayCurrent() {
int DisplayValue;
DisplayValue=(int)CurrentmA;
LCDDisplay.setCursor(4,1);
if(DisplayValue<1000) LCDDisplay.print(" ");
if(DisplayValue<100) LCDDisplay.print(" ");
if(DisplayValue<10) LCDDisplay.print(" ");
LCDDisplay.print(DisplayValue);
}
void DisplayMain() {
LCDDisplay.clear();
LCDDisplay.print(" DO AN 1 ");
LCDDisplay.setCursor(0,1);
LCDDisplay.print("FB: mA");
LCDDisplay.setCursor(0,2);
LCDDisplay.print("SET: mA CB: mA");
LCDDisplay.setCursor(0,3);
LCDDisplay.print("DONG CO:");
}
void ReadSensor() {
unsigned int x = 0;
float AcsValue = 0.0, Samples = 0.0, AvgAcs = 0.0, AcsValueF = 0.0;
for (int x = 0; x < 150; x++) { //Get 150 samples
AcsValue = analogRead(CURRENTSENSOR); //Read current sensor values Samples = Samples + AcsValue; //Add samples together
delay (3); // let ADC settle before following sample 3ms }
AvgAcs = Samples / 150.0; //Taking Average of Samples Serial.print("ADC:");
Serial.println(AvgAcs);
AcsValueF = (2.523 - (AvgAcs * (5.0 / 1024.0)) ) / 0.100; //acs712 20A //Serial.println(AcsValueF);//Print the read current on Serial monitor
if(AcsValueF<0) CurrentmA=AcsValueF*(-1000); // chuyen doi sang mA else CurrentmA=AcsValueF*1000; // chuyen doi sang mA
}
void Stop() {
digitalWrite(MOTORA,LOW);
digitalWrite(MOTORB,LOW);
LCDDisplay.setCursor(8,3);
LCDDisplay.print("DUNG ");
}
void RunFW() {
digitalWrite(MOTORA,HIGH);
digitalWrite(MOTORB,LOW);
LCDDisplay.setCursor(8,3);
LCDDisplay.print("CHAY ");
}
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(CURRENTSENSOR,INPUT);
pinMode(BUTTONSET,INPUT_PULLUP);
pinMode(BUTTONUP,INPUT_PULLUP);
pinMode(BUTTONDOWN,INPUT_PULLUP);
pinMode(MOTORA,OUTPUT);
pinMode(MOTORB,OUTPUT);
pinMode(BUTTONSTOP,INPUT_PULLUP);
pinMode(BUTTONRUN,INPUT_PULLUP);
pinMode(LED,OUTPUT);
pinMode(BUZZER,OUTPUT);
OffLED();
Stop();
LCDDisplay.init();
LCDDisplay.backlight();
LCDDisplay.begin(20, 4);
DisplayMain();
Stop();
DisplayParameter();
TimeCount=millis();
}
void loop() {
// put your main code here, to run repeatedly:
int ADCValue=0;
if(millis()-TimeCount>500) {
if(Arlarm==1) {
if(LEDState==1) OffLED();
else OnLED();
} }
if(digitalRead(BUTTONSTOP)==LOW) {
delay(250);
while(digitalRead(BUTTONSTOP)==LOW);
Stop();
RunMode=0;
}
if(digitalRead(BUTTONRUN)==LOW) {
delay(250);
while(digitalRead(BUTTONRUN)==LOW);
if(RunMode==0) {
RunMode=1;
RunFW();
Arlarm=0;
} }
if(SetupMode==0) {
ReadSensor();
DisplayCurrent();
if(CurrentmA>LimitCurrent) {
Stop();// qua tai dung dong co Arlarm=1;
RunMode=0;
}
Input = (double)CurrentmA;
//turn the PID on
MyPID.SetMode(AUTOMATIC);
MyPID.Compute();
Serial.print("Input:");
Serial.print(Input);
Serial.print(" mA Output:");
Serial.print(Output);
Serial.println(" PWM");
//TCCR0B = (TCCR0B & 0b11111000) | 0x01; // 62KHz analogWrite(PIN_OUTPUT, (int)Output);
}
if(digitalRead(BUTTONSET)==LOW) {
delay(250);
while(digitalRead(BUTTONSET)==LOW);
SetupMode++;
if(SetupMode==3) SetupMode=0;
if(SetupMode==0) {
LCDDisplay.noBlink();
}
else if(SetupMode==1) {
LCDDisplay.setCursor(5,2);
LCDDisplay.blink();
}
else if(SetupMode==2) {
LCDDisplay.setCursor(15,2);
LCDDisplay.blink();
} }
if(digitalRead(BUTTONUP)==LOW) {
delay(250);
while(digitalRead(BUTTONUP)==LOW);
if(SetupMode==1) {
Setpoint=Setpoint+100;
if(Setpoint>9999) Setpoint=9999;
DisplayParameter();
LCDDisplay.setCursor(5,2);
}
else if(SetupMode==2) {
LimitCurrent=LimitCurrent+100;
if(LimitCurrent>9999) LimitCurrent=9999;
DisplayParameter();
LCDDisplay.setCursor(15,2);
} }
if(digitalRead(BUTTONDOWN)==LOW) {
delay(250);
while(digitalRead(BUTTONDOWN)==LOW);
if(SetupMode==1) {
Setpoint=Setpoint-100;
if(Setpoint<1) Setpoint=1;
DisplayParameter();
LCDDisplay.setCursor(5,2);
}
else if(SetupMode==2) {
LimitCurrent=LimitCurrent-100;
if(LimitCurrent<1) LimitCurrent=1;
DisplayParameter();
LCDDisplay.setCursor(15,2);
} } }
Biên dịch code sau vài giây phần mềm sẽ biên dịch cho ta 1 file hex của chương trình. Sau khi tạo được file hex t nạp file vào linh kiện Arduino trong proteus để chạy mô phỏng hệ thống.