153 Bước 1. Xác định mô hình lưới động
Define Dynamic Mesh Parameters Bấm chuột trái vào Dynamic Mesh.
Chọn Models:
- Dynamic Mesh (PL-27) - In-Cylinder (PL-31) Chọn Mesh Methods:
- Smoothing (PL-28) - Layering (PL-29) - Remeshing (PL-30)
PL-27: Chọn mô hình lưới động Dynamic Mesh
PL-28: Thiết lập mô hình lưới động cho thẻ Smoothing
PL-29: Thiết lập mô hình lưới động cho thẻ Layering
154 PL-30: Thiết lập mô hình lưới động cho
thẻ Remeshing
PL-31: Thiết lập mô hình lưới động cho thẻ In-Cylinder
Bước 7. Xác định khu vực lưới biến dạng và biên di động
PL-32: Xác lập các thông số cho khu vực xi lanh
155
PL-33: Xác lập lưới biến dạng cho xi lanh
PL-34: Hiển thị lưới của không gian tính toán Bước 8. Kích hoạt phương trình năng lượng
156
PL-35: Chọn phương trình năng lượng Bước 9. Chọn mô hình độ nhớt rối
Bước 10. Chọn thông sô liên quan đến vị trí đánh lửa
Chọn menu Define -> Model ->Species ->Spark Ignition, trong cửa sổ Spark Ignition Model chọn Fixed Spark Size. Tiếp tục thiết lập các thông số trong Spark Ignition Model như sau: năng lượng đánh lửa trong trường hợp này là 143J, vị trí đánh lửa ở tọa độ (0,90,0), bắt đầu đánh lửa tại (20 độ trước điểm chết trên).
PL-36: Chọn các thông số đánh lửa
157
Bước 11. Xác định mặt phẳng để biểu diễn kết quả
PL-37: Lập mặt phẳng biểu diễn kết quả pressure
PL-38: Lập mặt phẳng biểu diễn kết quả nhiệt độ
PL-39: Lập mặt phẳng biểu diễn kết quả nồng độ C3H8
158
PHỤ LỤC 2. CODE LẬP TRÌNH ARDUINO ĐIỀU KHIỂN HỆ THỐNG PHUN XĂNG - LPG VÀ XĂNG - ETHANOL
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Average.h>
#include <TimerOne.h>
#include <EEPROM.h>
#include "maths.h"
//
#define pinLED 13
#define pinINJECTION1 9
#define pinINJECTION2 10
#define pinINJECTION3 11
#define pinTRIGGER 2
#define pinBUTTON 3
#define pinA0 A0 //
#define SIZE_BYTE 8
#define SIZE_INT 16 //
//Handy bitsetting macros
#define BIT_SET(a,b) ((a) |= (1<<(b)))
#define BIT_CLEAR(a,b) ((a) &= ~(1<<(b)))
#define BIT_CHECK(var,pos) !!((var) & (1<<(pos))) //
LiquidCrystal_I2C lcd(0x27, 16, 2); // Set the LCD address to 0x27 for a 16 chars and 2 line display
//
Average<unsigned long> aveRevTime(5);
Average<unsigned long> aveA0(10);
//
volatile unsigned long upTrigTime;
volatile unsigned long fallTrigTime;
volatile unsigned long lastFallTrigTime;
volatile unsigned long curInjTime;
volatile unsigned long curRevTime;
volatile unsigned long inj1Time;
volatile unsigned long inj2Time;
volatile unsigned long inj3Time;
volatile bool bRUN = false;
volatile byte runMode = 0;
// 0: xăng-Ethanol // 1: xăng-LPG //
unsigned int valueA0;
159 unsigned int rpm;
byte ratio;
//
unsigned long loop1000msCount = 0;
unsigned long loop1000msCounts = 0;
unsigned long loopTime = 0;
unsigned long next1000ms = 0;
unsigned long next500ms = 0;
unsigned long next250ms = 0;
unsigned long next100ms = 0;
unsigned long next50ms = 0;
//
String inputString = ""; // a string to hold incoming data //
boolean bStringComplete = false; // whether the string is complete boolean bInjection = false;
boolean bInjectionSchedule = false;
bool initialisationComplete = false; //Tracks whether the setup() functino has run completely
//
void setup() { lcd.begin();
lcd.backlight();
//
initialiseADC();
//
//lcdWrite(0,0,"A:");
lcdWrite(0,1,"A:");
lcdWrite(8,0,"|B:");
lcdWrite(8,1,"|C:");
//
pinMode(pinBUTTON,INPUT_PULLUP);
pinMode(pinLED, OUTPUT);
pinMode(pinINJECTION1,OUTPUT);
pinMode(pinINJECTION2,OUTPUT);
pinMode(pinINJECTION3,OUTPUT);
//--- Set PWM frequency for D3 & D11 --- ---
//TCCR2B = TCCR2B & B11111000 | B00000001; // set timer 2 divisor to 1 for PWM frequency of 31372.55 Hz
TCCR2B = TCCR2B & B11111000 | B00000010; // set timer 2 divisor to 8 for PWM frequency of 3921.16 Hz
//
attachInterrupt(digitalPinToInterrupt(pinTRIGGER), trig_FALL_ISR, FALLING); //2,3 attachInterrupt(digitalPinToInterrupt(pinBUTTON), button_FALL_ISR, FALLING);
//2,3 //
160 Timer1.initialize();
Timer1.attachInterrupt(injection2Stop);
//
Serial.begin(115200);
//
runMode = EEPROM.read(0);
//
initialisationComplete = true;
}
void initialiseADC() {
//This sets the ADC (Analog to Digitial Converter) to run at 1Mhz, greatly reducing analog read times (MAP/TPS) when using the standard analogRead() function //1Mhz is the fastest speed permitted by the CPU without affecting accuracy //Please see chapter 11 of 'Practical Arduino'
(http://books.google.com.au/books?id=HsTxON1L6D4C&printsec=frontcover#v=onepage
&q&f=false) for more detail BIT_SET(ADCSRA,ADPS2);
BIT_CLEAR(ADCSRA,ADPS1);
BIT_CLEAR(ADCSRA,ADPS0);
//
}
void button_FALL_ISR() { if (runMode < 1) {
runMode++;
Serial.println(runMode);
} else {
runMode = 0;
}
EEPROM.write(0,runMode);
}
void trig_FALL_ISR(){
fallTrigTime = micros();
if (curInjTime > 750) {
curRevTime = fallTrigTime - lastFallTrigTime;
lastFallTrigTime = fallTrigTime;
}
//Serial.println(upTrigTime);
attachInterrupt(digitalPinToInterrupt(pinTRIGGER), trig_UP_ISR, RISING); //2,3 }
void trig_UP_ISR(){
upTrigTime = micros();
161 unsigned long temp = upTrigTime - fallTrigTime;
curInjTime = temp;
//Serial.println(upTrigTime);
attachInterrupt(digitalPinToInterrupt(pinTRIGGER), trig_FALL_ISR, FALLING); //2,3 switch (runMode) {
case 0:
inj3Time = 0;
inj2Time = percentage(ratio,curInjTime);
inj1Time = curInjTime - inj2Time;
if (ratio < 100) { injection1Start();
} else {
injection2Start();
} break;
case 1:
inj2Time = 0;
inj3Time = percentage(ratio,(curInjTime - 350));
inj1Time = curInjTime - inj3Time;
//inj3Time = (1.35*inj3Time);
if (ratio < 100) { injection1Start();
} else {
injection3Start();
} break;
} }
void injection1Start() {
digitalWrite(pinINJECTION1,HIGH);
Timer1.setPeriod(inj1Time);
Timer1.attachInterrupt(injection1Stop);
}
void injection1Stop() {
digitalWrite(pinINJECTION1,LOW);
Timer1.stop();
if (ratio > 0) { switch (runMode) { case 0:
injection2Start();
break;
case 1:
injection3Start();
162 break;
} } }
void injection2Start() {
digitalWrite(pinINJECTION2,HIGH);
Timer1.setPeriod(inj2Time);
Timer1.attachInterrupt(injection2Stop);
}
void injection2Stop() {
digitalWrite(pinINJECTION2,LOW);
Timer1.stop();
}
void injection3Start() {
analogWrite(pinINJECTION3,255);
Timer1.setPeriod(1650);
Timer1.attachInterrupt(injection3PWM);
}
void injection3PWM() {
analogWrite(pinINJECTION3,190);
Timer1.setPeriod(inj3Time);
Timer1.attachInterrupt(injection3Stop);
}
void injection3Stop() {
analogWrite(pinINJECTION3,0);
Timer1.stop();
}
void readSensor() { readA0();
}
void readA0() {
valueA0 = analogRead(pinA0);
aveA0.push(valueA0);
ratio = map(aveA0.mean(),0,1023,0,100);
}
void loop50ms() {
if (loopTime>=next50ms) { next50ms=loopTime+5e4;
}
163 }
void loop100ms() {
if (loopTime>=next100ms) { next100ms=loopTime+1e5;
if (!bRUN) {readSensor();}
} }
void loop250ms() {
if (loopTime>=next250ms) { next250ms=loopTime+25e4;
if ((micros() - fallTrigTime) > 1e6) { //fallTrigTime = micros();
bRUN = false;
curInjTime = 0;
rpm = 0;
} else {
rpm = 12e7/curRevTime;
}
//lcdWrite(2,0,5," ",String(loop1000msCounts));
lcdWrite(0,0,7," ", (runMode==0)?"Gas-Eth":"Gas-LPG");
lcdWrite(2,1,5," ",String(ratio));
lcdWrite(11,0,5," ",String(curInjTime));
lcdWrite(11,1,5," ",String(rpm));
//Serial.print("curInjTime: ");
//Serial.print(curInjTime);
//Serial.print("\tcurRevTime: ");
//Serial.println(curRevTime);
} }
void loop500ms() {
if (loopTime>=next500ms) { next500ms=loopTime+5e5;
} }
void loop1000ms() { loop1000msCount++;
if (loopTime>=next1000ms) { next1000ms=loopTime+1e6;
//
loop1000msCounts = loop1000msCount;
loop1000msCount = 0;
} }
164 void serialCommand() {
if (bStringComplete) { // clear the string:
Serial.println(inputString);
int i = inputString.indexOf('=');
if (i > 0) {
String subString = inputString.substring(0,i);
String subString2 = inputString.substring(i+1,inputString.length());
//Serial.println(subString);
float tempx = subString2.toFloat();
//Serial.println(temp);
if (subString == "test") { Serial.println("Test KK!");
} else {
Serial.println("No cmd!");
} } else {
if (inputString == "save") { }
else if (inputString == "load") { }
else if (inputString == "print") { }
else if (inputString == "test") { }
else {
Serial.println("Nothing to do!");
} }
inputString = "";
bStringComplete = false;
} }
void loop() {
// put your main code here, to run repeatedly:
loopTime=micros();
serialCommand();
loop50ms();
loop100ms();
loop250ms();
loop500ms();
loop1000ms();
}
165 /*
SerialEvent occurs whenever a new data comes in the hardware serial RX. This routine is run between each time loop() runs, so using delay inside loop can delay response. Multiple bytes of data may be available.
*/
void serialEvent() {
while (Serial.available()) { // get the new byte:
char inChar = (char)Serial.read();
// if the incoming character is a newline, set a flag // so the main loop can do something about it:
if (inChar == '\n') {
bStringComplete = true;
} else {
// add it to the inputString:
inputString += inChar;
} } }
void lcdWrite(byte x, byte y, String text) {
lcd.setCursor(x,y);
lcd.print(text);
}
void lcdWrite(byte x, byte y, unsigned long number) {
lcd.setCursor(x,y);
lcd.print(number);
}
void lcdWrite(byte x, byte y, byte z, double number) {
lcd.setCursor(x,y);
lcd.print(number,z);
}
void lcdWrite(byte x, byte y, byte l, String text1, String text2) {
lcd.setCursor(x,y);
byte l2 = text2.length();
if (l>l2) {
for (byte i=0; i<(l-text2.length()); i++) { lcd.print(text1);
}