หากเรามองจาก ท้องฟ้า เราจะเห็น สิ่งที่เคลื่อนไหว ภายใต้ ของความคิดเรา ถ้าเรามองขึ้นไปจากใจเรา เราจะเห็น ทุกชีวิต กำลังดิ้นรน เพื่อ แสวงหา อาหาร เพื่อ หล่อเลี้ยง ชีวิตของตนเอง และ สิ่งที่ตนรัก และเป็นที่รัก ของตนเอง และแล้ว ทุกชีวิต ก็ พบว่า ความกระหายใคร่ ได้ ใคร่มี ใคร่เป็น หรือ ความทะยานอยาก นี่เอง ที่เป็นสาเหตุ ให้มนุษย์ ต้องเดินทางอยู่ ตลอดชีวิต ลองหยุดเดินทางด้วยยานพาหนะ แล้วหันมาเดินทาง ด้วยจิตวิญญาณ แล้วการ เดินทางไกล จะใกล้เข้าทุกขณะจิต หายใจเข้า ตามรู้ หายใจออก ตามรู้
วันพุธที่ 2 พฤศจิกายน พ.ศ. 2559
ระบบจุดหัวเทียนอัตโนมัติThe program structure. The program consists of 5 sections: Declaration, Setup, Interrupt actions, Interrupt Service Routine and Loop. Declaration This is where all the variables are declared and deciding what data types they are and which pins to use. In this case we are manipulating the AVR processor built in Timers, so here is also where we include the AVR codes. Setup Here we setup all the variables in the terms of resetting, pointing out the pins and deciding if they are inputs or outputs. Her w also setup the interrupt functions to be used later in the program. The AVR timer no2 are set now and the correct type of interrupt service routine to be used with the timer are set. Interrupt actions This actions will happen when the hall sensors are exposed to the magnets on the crank. Interrupts are always interrupting the loop. There is one interrupt action for the rising trigger signal and on for the falling trigger signal. When magnet no 1 that has the north facing towards the sensor, flies by, the hall latches on and triggers the interrupt “SensorOn”. Deepening on the current rpm, the different things will happen. If the rpm is below 300, the Arduino will start the ignition system 2 straight away and start charging coil no 2 . If the rpm is over 300, ignition system 1 will start after the right amount of crank time has elapsed. The timer will be initiated to be able to count up to 1 millisecond and automatically start over again. Also the RPM calculations will happen here. The second Interrupt “ SensorOff”, is like the first one, but opposite. Interrupt Service Routine This is when the timer has reached its counting compare match, in this case, one millisecond. For every time the timer has counted up to one millisecond, the variable “milliseconds” is added to one, and at the same time the program will check if something should happen. If the milliseconds is greater than the current crank time (which depends on the rpm calculations), the current coil will start to charge. After 3 more milliseconds, the coil is discharged (Spark). After this, everyting is resetted, and the sequens is ready to start over. Loop. This is where the proper cranktime (Timing advance) is calculated. The Loop is executed whenever there are no interrupts active. Arduino EIS Page 4 of 11 /*****************Simple Electronic Ignition System by Anders Stenhammar. 2016***************************/ /************Declaration**************************************/ //Necessary to be able to manipulate the AVR processor timers: #include #include //Pin definitions: const int HallPin1 = 2; // Pin nr 2 is conected to Hall sensor DO const int HallPin2 = 3; // Pin nr 3 is also conected to Hall sensor DO const int Ign1Pin = 8; // (PORTB,0) const int Ign2Pin = 11; // (PORTB,3) volatile float milliseconds; // The millisecondcounter value. (Volatile =Global variable) volatile float cranktime; // Time from 3 degrees to where the coil should start to load. volatile float cranktimeStart; // Variable to measure real cranktime. volatile float cranktimeStop; // Variable to measure real cranktime. volatile float realcranktime; // Measured real cranktime. volatile int IgnSystem; // Statusword for active ign system. volatile float dwellTime; // The time the coil should charge (default is 0,004 seconds. volatile unsigned long spark1; // Counting the number of sparks given from coil 1 volatile unsigned long spark2; // Counting the number of sparks given from coil 2 // RPM variables: volatile byte half_revolutions; volatile unsigned int rpm; volatile unsigned long timeold; /***********************************************************************************************/ void setup() { Serial.begin(250000); // Start the serial monitoring with the speed of 250000bpm dwellTime = 3; // Runningdwell: 3ms. Crankingdwell: 4ms. half_revolutions = 0; rpm = 0; timeold = 0; IgnSystem = 0; // No ignition system is active. pinMode(Ign1Pin, OUTPUT); // Initialize the Ignition 1 pin as an output. pinMode(Ign2Pin, OUTPUT); // Initialize the Ignition 2 pin as an output. bitClear(PORTB, 3); // (digitalWrite(Ign2Pin, LOW);) Turn the ignition off in case it's on bitClear(PORTB, 0); // (digitalWrite(Ign2Pin, LOW);) Turn the ignition off in case it's attachInterrupt(digitalPinToInterrupt(HallPin1), SensorOn, RISING); //Hall sensor DO for Ignition 1 attachInterrupt(digitalPinToInterrupt(HallPin2), SensorOff, FALLING); //Hall sensor DO for Ignition 2 /*************** Setup timer2*****************************/ noInterrupts(); TCCR2A = 0; // Turn off Control register for waveform generation TCCR2B = 0; // Turn off noise cancelling, turn off edge select, waveform gen mode 0, no clock source TCCR2A |= (1 << WGM21); // Turn on CTC mode (so it will start again) automatically TIMSK2 |= (1 << OCIE2A); // Set interrupt on compare match. OCR2A = 249; // ((0, 001 / 0.0000000625) / 64 ) - 1; //(0,001s=249) TCNT2 = 0; // Reset timer counter to 0 milliseconds = 0; // Reset the ms counter variable. interrupts(); } Arduino EIS Page 5 of 11 /*====================================================================================================== The interrupt action for magnet 1: The Timer starts to count up 1 ms at a time. *************************************************************************************************/ void SensorOn () { if ((rpm < 300) & (IgnSystem == 0)) { // When cranking (starting), the coil nr 2 will charge at once. bitSet(PORTB, 3); //Turn on coil 1 charging immediately, Cranking dwell will then be 1ms longer than normal. IgnSystem = 2; // Statusword to know witch system is to be hot. } if ((rpm >= 300) & (IgnSystem == 2) ) { // When running (not starting), the coil nr 1 will charge after cranktime in the ISR below. IgnSystem = 1; //Statusword to know witch system is to be hot. } TCCR2B |= (1 << CS22); // Load 64 prescaler / And this starts the timer2! cranktimeStart = micros(); // For monitoring. /********* RPM calculations: **********/ half_revolutions++; //For the RPM calculations if (half_revolutions >= 2) { rpm = 60 * 1000000 / (micros() - timeold) * half_revolutions; timeold = micros(); half_revolutions = 0; realcranktime = (cranktimeStop - cranktimeStart); } } /*====================================================================================================== The interrupt action for magnet 2: The Timer starts to count up 1 ms at a time. *******************************************************************************************************/ void SensorOff () { if ((rpm < 300) & (IgnSystem == 0)) { // When cranking (starting), the coil nr 1 will charge at once . bitSet(PORTB, 0); //Turn on coil 2 charging immediately, Cranking dwell will then be 1ms longer than normal. IgnSystem = 1; //Statusword to know witch system is to be hot. } if ((rpm >= 300) & (IgnSystem == 1) ) { // When running (not starting), the coil nr 2 will charge after cranktime in the ISR below. IgnSystem = 2; //Statusword to know witch system is to be hot. } TCCR2B |= (1 << CS22); // Load 64 prescaler / And this starts the timer2! cranktimeStart = micros(); //For diagnostics half_revolutions++; //For the RPM calculations } Arduino EIS Page 6 of 11 /*====================================================================================================== The Interrupt Service Routine for Timer2 that will be executed each time the timer reach the compare match register (1ms). *****************Milliseconds****************************************************************************/ ISR(TIMER2_COMPA_vect) { /*********Counting milliseconds************************************************************/ milliseconds++; // Increases the variable "milliseconds" by 1 at each ms (every time the ISR is executed). /************ coil charging*****************************************************************/ if (milliseconds >= cranktime) { //When the timer reaches the cranktime, then do this: if (IgnSystem == 1) { //If ignitionsystem 1 is selected and not on, then: bitSet(PORTB, 0); //Turn on coil 1 charging. } if (IgnSystem == 2) { //If ignitionsystem 2 is selected and not on, then: bitSet(PORTB, 3); //Turn on coil 2 charging. } cranktimeStop = micros(); //Stop recording the crank time } /***********Discharge coilspark*********************************************************************/ //If the milliseconds has reached the cranktime and dwelltime, then: if (milliseconds >= (cranktime + dwellTime)) { milliseconds = 0; // reset the ms counter variable //Turn off timer. TCCR2B &= ~ (1 << CS22); //clear the prescaler . TCNT2 = 0; // Reset the timer count to 0 bitClear(PORTB, 0); //Stop charging coil 1. (Gives spark) bitClear(PORTB, 3); //Stop charging coil 2. (Gives spark) //Do one of this two alternatives for monitoring: if (IgnSystem == 1) { //If ignitionsystem 1 is selected, then: Serial.println ("Spark1"); // For monitoring } if (IgnSystem == 2) { //If ignitionsystem 2 is selected, then: Serial.println ("Spark2"); // For monitoring } // If the engine has stopped or are still cranking, the IgnSystem is set to starting advance degrees. if (rpm < 300) { IgnSystem = 0; } Serial.println ("RPM"); Serial.println (rpm); // For monitoring } } Arduino EIS Page 7 of 11 /******************************************************************************************************/ void loop() { //Calculate the cranktime dependent on the rpm. (cranktime= advance time - dwellTime) /********************Cranktime calculations ******************************************************* RPM Advance Degrees Cranktime Time change -degrees BTDC from Sensor for each RPM (ms) 300 -3 180 100 -100 400 9 171 71,25 -0,2875 600 8 172 47,77777778 -0,117361111 1000 7 173 28,83333333 -0,047361111 1700 17 163 15,98039216 -0,018361345 2800 26 154 9,166666667 -0,006194296 3100 28 152 8,172043011 -0,003315412 4000 29 151 6,291666667 -0,002089307 4100 0 180 7,317073171 0,010254065 */ if (rpm <= 300) { cranktime = 0; } if ((rpm > 300) && (rpm <= 400)) { cranktime = (100 - (rpm - 300) * 0.2875) - dwellTime; } if ((rpm > 400) && (rpm <= 600)) { cranktime = (71.25 - (rpm - 400) * 0.117361111) - dwellTime; } if ((rpm > 600) && (rpm <= 1000)) { cranktime = (47.77777778 - (rpm - 600) * 0.047361111) - dwellTime; } if ((rpm > 1000) && (rpm <= 1700)) { cranktime = (28.83333333 - (rpm - 1000) * 0.018361345) - dwellTime; } if ((rpm > 1700) && (rpm <= 2800)) { cranktime = (15.98039216 - (rpm - 1700) * 0.006194296) - dwellTime; } if ((rpm > 2800) && (rpm <= 3100)) { cranktime = (9.166666667 - (rpm - 2800) * 0.003315412) - dwellTime; } if ((rpm > 3100) && (rpm <= 4000)) { cranktime = (8.172043011 - (rpm - 3100) * 0.002089307) - dwellTime; } /****************************************/ }
สมัครสมาชิก:
ส่งความคิดเห็น (Atom)
ไม่มีความคิดเห็น:
แสดงความคิดเห็น