arduino 3 phase motor speed control · โปรแกรม Arduino NANO ขับโมดูล TM-35 เวอร์ชั่นปี 2019 // 3 phase PWM sine // (c) 2016 C. Masenas // ดัดแปลงเพิ่มเติม จากต้นฉับ DDS generator ของ KHM 2009 / Martin Nawrath // Modified Y2018 By Seree2004 #include //เรียกโปรแกรมคำสั่งการใช้งานจอแสดงผล LCD เข้ามาร่วมด้วย // ตารางข้อมูลซายเวฟ ชุดละ 256 ตัว //Amplitude_245 PROGMEM const unsigned char Sine_Table[256] = {123,126,129,132,135,137,140,143,146,149,152,155,158,161,164,167,169,172,175,178,180,183,185,188,191,193,195,198,200,203,205,207, 209,211,213,215,217,219,221,223,224,226,228,229,231,232,233,234,236,237,238,239,240,241,241,242,243,243,244,244,244,245,245,245, 245,245,245,245,244,244,244,243,243,242,241,241,240,239,238,237,236,234,233,232,231,229,228,226,224,223,221,219,217,215,213,211, 209,207,205,203,200,198,195,193,191,188,185,183,180,178,175,172,169,167,164,161,158,155,152,149,146,143,140,137,135,132,129,126, 123,119,116,113,110,108,105,102,99,96,93,90,87,84,81,78,76,73,70,67,65,62,60,57,54,52,50,47,45,42,40,38, 36,34,32,30,28,26,24,22,21,19,17,16,14,13,12,11,9,8,7,6,5,4,4,3,2,2,1,1,1,0,0,0, 0,0,0,0,1,1,1,2,2,3,4,4,5,6,7,8,9,11,12,13,14,16,17,19,21,22,24,26,28,30,32,34, 36,38,40,42,45,47,50,52,54,57,60,62,65,67,70,73,76,78,81,84,87,90,93,96,99,102,105,108,110,113,116,119}; // เปลี่ยนวิธีการสั่งเซทค่าของรีจีสเตอร์ภายในของ Arduino ใหม่เพื่อให้เรียกใช้ง่ายขึ้น #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) // เปลี่ยนชื่อเรียกขาของ Arduino ใหม่เพื่อให้จำง่ายในการต่อวงจร #define PWM_OUT_UL 6 // PWM1 UL output #define PWM_OUT_UH 5 // PWM1 UH output #define PWM_OUT_VL 9 // PWM2 VL output #define PWM_OUT_VH 10 // PWM2 VH output #define PWM_OUT_WL 11 // PWM3 WL output #define PWM_OUT_WH 3 // PWM3 WH output #define testPin 13 // Test OutPut เพื่อกระพริบหลอดไฟ LED #define enablePin 8 // เพื่อปิด/เปิดภาค Power Driver #define single_3ph 12 //เพือตัวจั้มเปอร์ ให้เป็นแบบ ซิงเกิลเฟส หรือ แบบ 3 เฟส #define FAULT_DETECT 2 //เพื่อตรวจรับสัญญาณผิดพลาดต่างๆจะได้ปิดภาค Power Driver ก่อนที่จะทำให้อุปกรณ์เสียหาย #define FREQ_POT 0 // เพื่อเต่อกับวอลลุ่มปรับความถี่ analog input A0 //#define CURRENT_POT 1 // สำรองไว้ analog input A1 #define WATER 1 // สวิตช์ลูกลอย #define USER1 6 // สำรองไว้ analog input A6 #define USER2 7 // สำรองไว้ analog input A7 // ตั้งชื่อการกำหนดค่า DeadTime #define DT_LOW 5 // DeadTime Low Side #define DT_HIGH DT_LOW*2 // DeadTime High Side // ตั้งชื่อการกำหนดค่าของ วอลลุ่มปรับความเร็วรอบ (Hz)ต่ำสุดและสูงสุด #define FREQ_MIN 7 // default: 15 #define FREQ_MAX 60 // default: 90 #define MAX_AMP_AT 50 // ให้ความแรง Amplitude สูงสุดที่ 50 Hz // เปลี่ยนชื่อเรียกค่าตายตัวของตัวปรับวอลลุ่มของ Arduino ซึ่งเป็นความสามารถของ MCU ในแต่ละเบอร์อาจต่างกัน #define POT_MIN 0 // default: 0 #define POT_MAX 1023 // default: 1023 #define MAX_Amplitude 64 #define TABLE_DIV 64 // การตั้งชื่อตัวแปรต่าง ๆ ที่ใช้ในตัวโปรแกรม volatile float freq = 15; const float refclk = 3921 ; // ค่าตายตัวที่ได้มาจากการคำนวน คริสตอลที่ใช้ 16 MHz/8/510/256 = 15.318 // ตั้งชื่อตัวแปรที่ใช้ในการคำนวนรอบของสัญญาณซายเวฟและต่อเนื่องกันอย่างสมบูรณ์ interrupt service declared as voilatile volatile unsigned long sigma; // phase accumulator volatile unsigned long delta; // phase increment volatile unsigned long c4ms; // counter incremented every 4ms //ตั้งชื่อตัวแปรต่าง ๆ byte character1[8] = {0,18,18,18,18,18,27,0}; byte character2[8] = {0,14,17,29,21,21,25,0}; byte character3[8] = {0,4,4,4,4,4,6,0}; byte character4[8] = {0,2,31,1,29,19,25,0}; byte character5[8] = {1,15,6,9,14,1,6,0}; byte phase0, phase1, phase2, freq_old, freq_new,temp,temp2,Amplitude; unsigned int temp_ocr0a, temp_ocr0b, temp_ocr1a, temp_ocr1b, temp_ocr2a, temp_ocr2b; unsigned int SW_WATER = 0; bool single = false; bool testPin_status = false; // ตั้งชื่อค่าตายตัวที่เรากำหนดในการต่อขาต่าง ๆ ของ Arduino เข้ากับจอ LCD เพื่อให้จำง่าย const int RS = 7, EN = 4, D4 = A2, D5 = A3, D6 = A4, D7 = A5; // แล้วสั่งให้กำหนดตามนี้ได้เลย LiquidCrystal lcd(RS, EN, D4, D5, D6, D7); //*********** เปลี่ยน Version ที่นี่ **************************** char My_Version[] = "TM35V-21-01-2019"; //********************************************************* // เริ่มต้นตัวโปรแกรมโดยคำสั่งตั้งค่าต่าง ๆ ก่อน void setup(){ //------------------------------------ pinMode(FAULT_DETECT,OUTPUT); digitalWrite(FAULT_DETECT, LOW); //------------------------------------ pinMode(enablePin, OUTPUT); // สั่งเซตให้เป็นขาสัญญาณออก digitalWrite(enablePin, LOW); // สั่งให้ขานี้ ปิด (เป็น0) เพื่อทำให้ภาค Power Drive อย่าเพิ่งทำงานตอนนี้ pinMode(testPin, OUTPUT); // สั่งเซตให้เป็นขาสัญญาณออก pinMode(single_3ph, INPUT_PULLUP); // สั่งเซตให้เป็นขารับสัญญาณเข้า และ พูลอัพ pinMode(PWM_OUT_UL, OUTPUT); // สั่งเซตให้เป็นขาสัญญาณออก pinMode(PWM_OUT_UH, OUTPUT); // สั่งเซตให้เป็นขาสัญญาณออก pinMode(PWM_OUT_VL, OUTPUT); // สั่งเซตให้เป็นขาสัญญาณออก pinMode(PWM_OUT_VH, OUTPUT); // สั่งเซตให้เป็นขาสัญญาณออก pinMode(PWM_OUT_WL, OUTPUT); // สั่งเซตให้เป็นขาสัญญาณออก pinMode(PWM_OUT_WH, OUTPUT); // สั่งเซตให้เป็นขาสัญญาณออก if (digitalRead(single_3ph) == LOW){single = true;} // ตรวจสอบว่าขาจั้มเปอร์จั้มเป็นซิงเกิลเฟสหรือเปล่า ถ้าจั้มก็บอกว่า จริง ถ้าไม่จ้ัมก็บอกว่า เท็จ lcd.begin(16,2); // เริ่มเปิดใช้งานจอแสดงผล LCD lcd.createChar(0,character1); lcd.createChar(1,character2); lcd.createChar(2,character3); lcd.createChar(3,character4); lcd.createChar(4,character5); lcd.setCursor(5, 0); // สังให้แสดงผลคอลั่มที่ 5 ในบรรทัดแรก (0) lcd.write(byte(0)); lcd.write(byte(1)); lcd.write(byte(1)); lcd.write(byte(2)); lcd.write(byte(3)); lcd.write(byte(4)); lcd.setCursor(0, 1); for (temp=0; temp <= 16; temp++){ lcd.print(My_Version[temp]); delay(200); } delay(1000); // หน่วงเวลาให้แสดงผลนี้ เป็นเวลานาน 3 วินาที //----------------------------------------------------------------------------- if (single == true){ // ถ้าตัวจั้มเปอร์เป็นจริงก็ให้แสดงผล ที่ คอลั่ม 13 บรรทัดแรก 1PH lcd.setCursor(11, 0); lcd.print("~J1PH"); } else{ lcd.setCursor(11, 0); // หรือถ้าตัวจั้มเปอร์เป็นเท็จ ก็ให้แสดงผลที่ คอลั่ม 13 บรรทัดแรก 3PH lcd.print("~J3PH"); } //---------------------------------------------------------------------------- lcd.setCursor(0, 0); // แสดงผลที่คอลั่ม 1 บรรทัดแรก คำว่า Amplitude รอไว้ก่อนเพื่อให้ค่าจริงมาต่อ lcd.print("Amplitude:"); lcd.setCursor(0, 1); // แสดงผลที่คอลั่ม 1 บรรทัด 2 คำว่า Frequency รอไว้ก่อนเพื่อให้ค่าจริงมาต่อ lcd.print("Frequency:"); //----------------------------------------------------------------------------- // ไปเรียกโปรแกรมการตั้งค่า ไทม์เเมอร์ เพื่อกำหนดค่าการสร้างสัญญาณ PWM 3 ชุด โดยใช้ตัวไทม์เมอร์ของ Arduino ทั้ง 3 ตัว Setup the timers setup_timer0(); setup_timer1(); setup_timer2(); // ส่วนนี้เป็นการคำนวนตามสูตรเพื่อ ให้ได้สัญญาณซายเวฟครบวงรอบต่อเนื่องต้องใช้ความละเอียดถึง 32 บิต และจะได้ผลลับที่ 8 บิต สูงสุด แต่เวลาใช้งานจะต้องเลื่อนบิตกลับมาใชั 8 บิตล่าง delta = pow(2,32)*freq/refclk ; //----------------------------------------------------------------------------- digitalWrite(FAULT_DETECT, HIGH); pinMode(FAULT_DETECT, INPUT_PULLUP); // สั่งเซตให้เป็นขารับสัญญาณเข้า และ พูลอัพ attachInterrupt(0, fault, LOW); //----------------------------------------------------------------------------- freq_old = 5; //----------------------------------------------------------------------------- digitalWrite(enablePin, HIGH); // เปิด ภาค Power Drive ให้เริ่มทำงานได้ freq_new = map(analogRead(FREQ_POT), POT_MIN, POT_MAX, FREQ_MIN, FREQ_MAX); changeFreq_ramp(freq_new); freq_old = freq_new; } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void loop(){ if (testPin_status){ freq_new = map(analogRead(FREQ_POT), POT_MIN, POT_MAX, FREQ_MIN, FREQ_MAX); SW_WATER = map(analogRead(WATER), POT_MIN, POT_MAX, 0, 100); if (freq_new != freq_old){ changeFreq(freq_new); freq_old = freq_new; } if (SW_WATER >= 15){ digitalWrite(enablePin, LOW); // ปิด ภาค Power Drive ให้หยุดทำงาน digitalWrite(testPin, HIGH); cbi (TIMSK2,TOIE2); // หยุดพการทำงานของไทม์เมอร์ 2 disable timer2 overflow detect OCR0A=0; OCR0B=0; OCR1A=0; OCR1B=0; OCR2A=0; OCR2B=0; detachInterrupt(0); lcd.setCursor(10, 1); lcd.print("!WAIT!"); //-------------------หยุดรอจนกว่าสวิตช์ลูกลอยเปิด------------------ while(map(analogRead(WATER), POT_MIN, POT_MAX, 0, 100) >= 15); //------------------------------------------------------------ freq_old = 5; freq_new = map(analogRead(FREQ_POT), POT_MIN, POT_MAX, FREQ_MIN, FREQ_MAX); digitalWrite(enablePin, HIGH); // เปิด ภาค Power Drive ให้เริ่มทำงาน attachInterrupt(0, fault, LOW); changeFreq_ramp(freq_new); freq_old = freq_new; } } delay(10); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- // ชุดคำสั่งในการเปลี่ยนความถี่ void changeFreq(float _freq){ temp2 = _freq; Amplitude = temp2 + 20; if (Amplitude >= MAX_Amplitude){Amplitude = MAX_Amplitude;} // ล๊อค Amplitude lcd.setCursor(10, 0); lcd.print(Amplitude); lcd.setCursor(10, 1); lcd.print(temp2); lcd.print(" Hz "); cbi (TIMSK2,TOIE2); // หยุดการทำงานของไทม์เมอร์ 2 disable timer2 overflow detect freq = _freq; delta=pow(2,32)*freq/refclk; // อัพเดทความถี่ใหม่ update phase increment sbi (TIMSK2,TOIE2); //เปิดให้ไทม์เมอร์ 2 ทำงาน enable timer2 overflow detect while(c4ms); } //---------------------------------------------------------------------------- // ชุดคำสั่งในการเปลี่ยนความถี่_RAMP void changeFreq_ramp(float _freq){ if (_freq > freq_old){ for (temp2 = freq_old; temp2 <= _freq; temp2++){ Amplitude = temp2 +20; if (Amplitude >= MAX_Amplitude){Amplitude = MAX_Amplitude;} // ล๊อค Amplitude lcd.setCursor(10, 0); lcd.print(Amplitude); lcd.setCursor(10, 1); lcd.print(temp2); lcd.print(" Hz "); cbi (TIMSK2,TOIE2); // หยุดการทำงานของไทม์เมอร์ 2 disable timer2 overflow detect freq = temp2; delta=pow(2,32)*freq/refclk; // อัพเดทความถี่ใหม่ update phase increment sbi (TIMSK2,TOIE2); //เปิดให้ไทม์เมอร์ 2 ทำงาน enable timer2 overflow detect while(c4ms); } } } //------------------------------------------------------------------------------ // ชุดคำสั่งในการตั้งค่า ไทม์เมอร์ ตัวแรก (0) // timer0 setup // set prescaler to 8, PWM mode to phase correct PWM, 16000000/512/8 = 3.9kHz clock void setup_timer0(void){ // Timer0 Clock Prescaler to :ตั้งค่าไทม์เมอร์ให้ หารอีก 8 เพื่อจะได้ความถี่ PWM ขนาด 3.9 Khz ให้เหมาะกับ IPM เบอร์เก่า ๆ cbi (TCCR0B, CS00); sbi (TCCR0B, CS01); cbi (TCCR0B, CS02); // Timer0 PWM Mode set to Phase Correct PWM cbi (TCCR0A, COM0B0); // ตั้งค่าให้ชุดส่งสัญญาณช่อง แรก (OCR0B) ให้ส่งสัญญาณออกเป็น Sine PWM ปรกติ + sbi (TCCR0A, COM0B1); sbi (TCCR0A, COM0A0); // ตั้งค่าให้ชุดส่งสัญญาณช่อง แรก (OCR0A) ให้ส่งสัญญาณออกเป็น Sine PWM กลับเฟส Invert เป็น - sbi (TCCR0A, COM0A1); sbi (TCCR0A, WGM00); //ตั้งค่าให้สัญญาณพัลซ์ทุกลูกอยู่แนวเดียวกันเสมอในทุกเฟส (Mode 1 / Phase Correct PWM) cbi (TCCR0A, WGM01); cbi (TCCR0B, WGM02); } //------------------------------------------------------------------------------ // timer1 setup // set prescaler to 8, PWM mode to phase correct PWM, 16000000/512/8 = 3.9kHz clock ให้เหมาะกับ IPM เบอร์เก่า ๆ void setup_timer1(void){ // Timer1 Clock Prescaler to :ตั้งค่าไทม์เมอร์ให้ หารอีก 8 เพื่อจะได้ความถี่ PWM ขนาด 3.9 Khz cbi (TCCR1B, CS10); sbi (TCCR1B, CS11); cbi (TCCR1B, CS12); // Timer1 PWM Mode set to Phase Correct PWM cbi (TCCR1A, COM1B0); // ตั้งค่าให้ชุดส่งสัญญาณช่อง 2(OCR1B) ให้ส่งสัญญาณออกเป็น Sine PWM ปรกติ + sbi (TCCR1A, COM1B1); sbi (TCCR1A, COM1A0); // ตั้งค่าให้ชุดส่งสัญญาณช่อง 2(OCR1A) ให้ส่งสัญญาณออกเป็น Sine PWM กลับเฟส Invert เป็น - sbi (TCCR1A, COM1A1); sbi (TCCR1A, WGM10); //ตั้งค่าให้สัญญาณพัลซ์ทุกลูกอยู่แนวเดียวกันเสมอในทุกเฟส (Mode 1 / Phase Correct PWM) cbi (TCCR1A, WGM11); cbi (TCCR1B, WGM12); cbi (TCCR1B, WGM13); } //------------------------------------------------------------------------------ // timer2 setup // set prescaler to 8, PWM mode to phase correct PWM, 16000000/512/8 = 3.9kHz clock ให้เหมาะกับ IPM เบอร์เก่า ๆ void setup_timer2(void){ // Timer1 Clock Prescaler to :ตั้งค่าไทม์เมอร์ให้ หารอีก 8 เพื่อจะได้ความถี่ PWM ขนาด 3.9 Khz // Timer2 Clock Prescaler to : /8 cbi (TCCR2B, CS20); sbi (TCCR2B, CS21); cbi (TCCR2B, CS22); // Timer2 PWM Mode set to Phase Correct PWM cbi (TCCR2A, COM2B0); // ตั้งค่าให้ชุดส่งสัญญาณช่อง 3(OCR2B) ให้ส่งสัญญาณออกเป็น Sine PWM ปรกติ + sbi (TCCR2A, COM2B1); sbi (TCCR2A, COM2A0); // ตั้งค่าให้ชุดส่งสัญญาณช่อง 3(OCR2A) ให้ส่งสัญญาณออกเป็น Sine PWM กลับเฟส Invert เป็น - sbi (TCCR2A, COM2A1); sbi (TCCR2A, WGM20); //ตั้งค่าให้สัญญาณพัลซ์ทุกลูกอยู่แนวเดียวกันเสมอในทุกเฟส (Mode 1 / Phase Correct PWM) cbi (TCCR2A, WGM21); cbi (TCCR2B, WGM22); } //------------------------------------------------------------------------------ // ส่งInterrupt Service Routine attached to INT0 vector void fault(){ digitalWrite(enablePin, LOW); // สั่งให้ขานี้ ปิด (เป็น0) เพื่อทำให้ภาค Power Drive อย่าเพิ่งทำงานตอนนี้ digitalWrite(testPin, HIGH); cbi (TIMSK2,TOIE2); // หยุดพการทำงานของไทม์เมอร์ 2 disable timer2 overflow detect OCR0A=0; OCR0B=0; OCR1A=0; OCR1B=0; OCR2A=0; OCR2B=0; lcd.clear(); lcd.setCursor(0, 0); // สังให้แสดงผลคอลั่มที่ 1 ในบรรทัดแรก (0) lcd.print("!!Detect Error!!"); // แสดงผล Error lcd.setCursor(0, 1); // สังให้แสดงผลคอลั่มที่ 1 ในบรรทัด 2 (1) lcd.print(" Pls Switch OFF "); while(1){}; // หยุดการทำงานตลอดไป จนกว่าจะ รีเซต หรือปิด เปิด ไฟเข้าเครื่องใหม่ } //------------------------------------------------------------------------------ //การที่จะได้สัญญาณ ซายเวฟ ที่มีความถี่แม่นยำตามที่เราตั้งค่าต่าง ๆ ไว้ ต้องอาศัยการนับเวลาของตัวไทม์ เมอร์ 2 และเมื่อนับครบตามที่เราตั้งไว้ต้องมาทำตามคำสั่งชุดนี้ // Timer2 Interrupt Service at 31372,550 KHz = 32uSec // this is the timebase REFCLOCK for the DDS generator // runtime : 8 microseconds ( inclusive push and pop) ISR(TIMER2_OVF_vect) { // สูตรการคำนวน ความถี่กลับมา แล้วเลื่อน จาก 32 บิต กลับมาใช้เพียง 8 บิตล่าง sigma=sigma+delta; // soft DDS, phase accu with 32 bits phase0=sigma >> 24; // use upper 8 bits for phase accu as frequency information //ชุดคำสั่งนี้แบ่งเป็น 2 ส่วน ชุดแรกเพื่อ ส่งสัญญาณ ซายเวฟ ทั้ง 3 คู่ ให้มีเฟสต่างกัน 0-90-180 เพื่อใช้กับมอร์เตอร์ซิงเกิ้ลเฟส และ ชุดต่อมา สำหรับ 3 เฟส 0-120-120 if (single == true){ // ถ้าจั้มเปอร์เป็นจริง ให้ทำงานส่วนนี้ คือแบบซิงเกิลเฟส phase1 = phase0 +127 ; // ค่าเฟส 1 phase2 = phase0 +63 ; // ค่าเฟส 2 //สำหรับแบบซิงเกิ้ลเฟส เฟสคู่ที่ 0 กับ เฟสคู่ที่ 1 จะกลับกัน เพื่อให้มอร์เตอร์ หมุนทิศทางเดียวกันทั้งแบบ ซิงเกิ้ล และ แบบ 3 เฟส // นำค่าที่อ่านได้จากตาราง ซายเวฟ + ความแรงของสัญญาณ (Amplitude) + เฟส + ค่า DeadTime ออกไปที่ ขาสัญญาณออกทั้ง 3 คู่ // OCR0A=(uint8_t)pgm_read_byte_near((Sine_Table + ADD_AMPD) + phase1)+DT_LOW; temp_ocr0a = pgm_read_byte_near(Sine_Table + phase1) * (Amplitude) / (TABLE_DIV) + DT_HIGH; temp_ocr0b = pgm_read_byte_near(Sine_Table + phase1) * (Amplitude) / (TABLE_DIV) + DT_LOW; temp_ocr1a = pgm_read_byte_near(Sine_Table + phase0) * (Amplitude) / (TABLE_DIV) + DT_HIGH; temp_ocr1b = pgm_read_byte_near(Sine_Table + phase0) * (Amplitude) / (TABLE_DIV) + DT_LOW; temp_ocr2a = pgm_read_byte_near(Sine_Table + phase2) * (Amplitude) / (TABLE_DIV) + DT_HIGH; temp_ocr2b = pgm_read_byte_near(Sine_Table + phase2) * (Amplitude) / (TABLE_DIV) + DT_LOW; OCR0A=(uint8_t) temp_ocr0a; // pin D6 OCR0B=(uint8_t) temp_ocr0b; // pin D5 OCR1A=(uint8_t) temp_ocr1a; // pin D9 OCR1B=(uint8_t) temp_ocr1b; // pin D10 OCR2A=(uint8_t) temp_ocr2a; // pin D11 OCR2B=(uint8_t) temp_ocr2b; // pin D3 } //---------------------- ถ้าจั้มเปอร์เป็นเท็จ ให้ทำงานส่วนนี้ คือแบบ 3 เฟส ที่มีเฟสต่างกัน 120 องศา------------------------------------------------------------------ else{ phase1 = phase0 +85 ; // ค่าเฟส 1 phase2 = phase0 +170 ; // ค่าเฟส 2 // นำค่าที่อ่านได้จากตาราง ซายเวฟ + ความแรงของสัญญาณ (Amplitude) + เฟส + ค่า DeadTime ออกไปที่ ขาสัญญาณออกทั้ง 3 คู่ temp_ocr0a = pgm_read_byte_near(Sine_Table + phase0) * (Amplitude) / (TABLE_DIV) + DT_HIGH; temp_ocr0b = pgm_read_byte_near(Sine_Table + phase0) * (Amplitude) / (TABLE_DIV) + DT_LOW; temp_ocr1a = pgm_read_byte_near(Sine_Table + phase1) * (Amplitude) / (TABLE_DIV) + DT_HIGH; temp_ocr1b = pgm_read_byte_near(Sine_Table + phase1) * (Amplitude) / (TABLE_DIV) + DT_LOW; temp_ocr2a = pgm_read_byte_near(Sine_Table + phase2) * (Amplitude) / (TABLE_DIV) + DT_HIGH; temp_ocr2b = pgm_read_byte_near(Sine_Table + phase2) * (Amplitude) / (TABLE_DIV) + DT_LOW; OCR0A=(uint8_t) temp_ocr0a; // pin D6 OCR0B=(uint8_t) temp_ocr0b; // pin D5 OCR1A=(uint8_t) temp_ocr1a; // pin D9 OCR1B=(uint8_t) temp_ocr1b; // pin D10 OCR2A=(uint8_t) temp_ocr2a; // pin D11 OCR2B=(uint8_t) temp_ocr2b; // pin D3 } if (c4ms++ == 500){ c4ms = 0; digitalWrite(testPin, testPin_status); testPin_status = !testPin_status; } } //จบโปรแกรมแล้วครับใครจะเขียนเพิ่มเติมอะไรได้ครับ แต่อย่าลืมให้เครดิตผู้ที่เขียนต้นฉบับด้วยครับsompong-tungmepol: Analog Control Arduino รับลิงก์ Facebook X Pinterest อีเมล แอปอื่นๆ มกราคม 19, 2564 sompong-tungmepol: Analog Control Arduino รับลิงก์ Facebook X Pinterest อีเมล แอปอื่นๆ ความคิดเห็น
A Trip to Nepal Buddha birth place & India Buddha gaya มกราคม 19, 2564 #ถ้าเธอทำตนให้นิ่งเงียบได้เหมือนกังสดาลที่ตัดขอบปากออกแล้วเธอก็จะบรรลุนิพพานได้การโต้เถียงกันก็จะไม่มีแก่เธอ อ่านเพิ่มเติม
ความดับทุกข์#อนิมิตตวิโมกข์#อัปปณิหิตวิโมกข์#สุญญตวิโมกข์#เธออย่าได้กล่า...เข้าสู่ระบบหรือลงทะเบียน หน้าแรก เว็บบอร์ด > พุทธศาสนา > พระไตรปิฎก > เรื่องเด่นคนกิเลสหนากับการบรรลุธรรม ในห้อง 'พระไตรปิฎก' ตั้งกระทู้โดย rachotp, 4 พฤศจิกายน 2021. แท็ก: เพิ่มแท็ก rachotp rachotp เป็นที่รู้จักกันดี สมาชิก Premium ผู้สนับสนุนเว็บพลังจิต วันที่สมัครสมาชิก:9 ตุลาคม 2020 โพสต์:1,214 กระทู้เรื่องเด่น:251 ค่าพลัง:+23,278 A.PNG การบรรลุธรรมของคนที่มีกิเลสหนา เรื่องน่าคิดจากพระไตรปิฎก หลายท่านอาจจะสงสัยว่า “คนที่มีกิเลสหนา บรรลุธรรมไม่ได้” และเชื่อกันมาแบบนี้ แต่พระพุทธเจ้าตรัสถึงเรื่องนี้ไว้ในพระสูตรที่มีชื่อว่า วิตถารสูตร ถึงการบรรลุธรรมของคนที่มีกิเลสหนา ไว้ว่า… บุคคลบางคนในโลกนี้ ตามปกติเป็นผู้มีความกำหนัดยินดีในกาม (ราคะ) ย่อมได้เสวยทุกข์โทมนัสอันเกิดจากความกำหนัดยินดีในกามตลอด เป็นผู้มีความโกรธ (โทสะ) รุนแรง ย่อมได้เสวยทุกข์โทมนัสที่เกิดจากความโกรธตลอด เป็นผู้ที่มีความหลง (โมหะ) รุนแรง ย่อมได้เสวยทุกข์โทมนัสที่เกิดจากความหลงตลอด G.PNG แต่อินทรีย์ 5 ประการ ได้แก่ ศรัทธา วิริยะ สติ สมาธิ และปัญญา เหล่านี้มีความแรงกล้า เขาย่อมบรรลุธรรมอย่างฉับพลัน แต่หากคนผู้นั้นมีกิเลสเป็นราคะ โทสะ และโมหะเบาบาง ไม่ได้มีความทุกข์โทมนัสจากราคะ โทสะ และโมหะ แต่อินทรีย์ทั้ง 5 ประการนี้อ่อน เขาย่อมได้บรรลุมรรคผลล่าช้า การบรรลุธรรมจึงขึ้นอยู่กับอินทรีย์ 5 ประการ F.PNG ระดับของการบรรลุธรรม การบรรลุธรรมของคนที่มีกิเลสหนาถึงจะขึ้นอยู่กับอินทรีย์ 5 แต่ก็มีความช้าและความเร็วแตกต่างกันไป พระพุทธเจ้าทรงจัดระดับไว้ 4 ระดับด้วยกันคือ 1) ทุกขาปฏิปทา ทันธาภิญญา หมายถึง ผู้ที่มีกิเลสหนา แต่มีอินทรีย์ 5 ประการบาง จึงบรรลุธรรมได้ช้า 2) ทุกขาปฏิปทา ขิปปาภิญญา หมายถึง ผู้ที่มีกิเลสหนา แต่มีอินทรีย์ 5 ประการแรงกล้า จึงบรรลุธรรมได้ไว 3) สุขาปฏิปทา ทันธาภิญญา หมายถึง ผู้ที่ไม่มีกิเลส แต่มีอินทรีย์ 5 ประการบาง จึงบรรลุธรรมช้า 4) สุขาปฏิปทา ขิปปาภิญญา หมายถึง ผู้ที่ไม่มีกิเลส และมีอินทรีย์ 5 ประการแรงกล้า จึงบรรลุธรรมได้ไว H.png ทำไมการบรรลุธรรมจึงเกี่ยวข้องกับอินทรีย์ 5 ประการ? อินทรีย์ 5 ได้แก่ ศรัทธา วิริยะ สติ สมาธิ และปัญญา เป็นองค์ธรรมที่ช่วยให้โลภะ โทสะ และโมหะ ลดลง เมื่อมีความเชื่อมั่น (ศรัทธา) ต่อคำสอนของพระพุทธเจ้า จะเกิดความเพียร (วิริยะ) การระลึกรู้ได้ก็จะตามมา (สติ) เมื่อเกิดการระลึกได้สมาธิก็จะตามมา เมื่อมีสมาธิผลที่ได้คือปัญญา ผู้บรรลุอรหันต์ล้วนผ่านองค์ธรรม 5 ประการนี้ D.PNG ตัวอย่างเช่น เจ้าหญิงอภิรูปนันทา เป็นสตรีชนชั้นสูงที่มีความงามเป็นเลิศ จึงมีอุปนิสัยรักสวยรักงาม พอผนวชเป็นภิกษุณี ก็ยังไม่ทรงละอุปนิสัยรักสวยรักงามอยู่ดี พระพุทธเจ้าทรงต้องการโปรดเจ้าหญิงอภิรูปนันทาให้ทราบถึงโทษของการรักสวยรักงาม พระพุทธเจ้าทรงเนรมิตสตรีนางหนึ่งขึ้นมาให้มีความงามประดุจนางฟ้า เจ้าหญิงทรงหลงใหลแล้วชมว่า สตรีนางนี้ช่างมีความงดงามมากกว่าสตรีใดๆที่้เคยพบเห็นมา ไม่นานสตรีนางนี้ก็ค่อยๆ แก่ลง แล้วตายกลายสภาพเป็นศพ และเริ่มเน่าส่งกลิ่นเหม็น แล้วกลายเป็นโครงกระดูกในที่สุด E.PNG เมื่อเจ้าหญิงอภิรูปนันทาทอดพระเนตรดังนั้นแล้วทรงเชื่อ (ศรัทธา) ในคำสอนของพระพุทธเจ้าแล้วว่าการยึดติดในความงามเป็นสิ่งที่เที่ยง แท้ที่จริงแล้วมันเป็นสิ่งที่ไม่เที่ยง เมื่อเจ้าหญิงทรงพิจารณาร่างของสตรีนางนั้นด้วยความตั้งใจ (วิริยะ) เมื่อทรงสังเกตพินิจพิจารณาจนถึงตอนที่สตรีนางนั้นสิ้นลม การระลึกรู้ (สติ) ถึงคำสอนของพระพุทธเจ้าก็บังเกิดขึ้นในบัดนั้นทันที พอทรงมีสติพิจารณาใคร่ครวญอย่างถี่ถ้วนดีแล้ว จึงบังเกิดความสงบ (สมาธิ) ขึ้น เจ้าหญิงอภิรูปนันทาเกิดความเข้าพระทัยว่า สิ่งที่พระนางหลงใหล (โลภะ) ในความงามนั้น เป็นความเขลาเบาปัญญา ทำให้พระนางตรึงอยู่ในกระแสแห่งการเวียนว่ายตายเกิดต่อไป B.PNG พระนางทรงข้ามฝั่งแห่งน่านน้ำอวิชชามาถึงฝั่งแห่งวิชชา อันเกิดจากการพิจารณาร่างของสตรีซึ่งถูกเนรมิต จนทำให้พระนางบรรลุธรรม เจ้าหญิงอภิรูปนันทา เป็นตัวอย่างที่ทำให้เห็นว่าคนที่มีกิเลสหนา ที่บรรลุธรรมได้นั้นมีอยู่จริง แต่อินทรีย์ 5 ประการของพระนางถึงพร้อม พระพุทธเจ้าทรงเห็นจึงได้มาโปรดพระนางด้วยวิธีนี้จนพระนางบรรลุธรรม C.PNG Credit: ขอขอบพระคุณที่มาจาก วิตถารสูตร ว่าด้วยปฏิปทาโดยพิสดาร พระไตรปิฎกเล่มที่ ๒๑ พระสุตตันตปิฎกเล่มที่ ๑๓ [ฉบับมหาจุฬาฯ] อังคุตตรนิกาย จตุกกนิบาต "นะโม วิมุตตานัง นะโม วิมุตติยา" "ชินะปัญชะระ ปะริตตังมัง รักขะตุสัพพะทา" "มะอะอุ นะโม วิมุตตานัง นะโมวิมุตติยา ราหุ สุริยัง จันทัง ปะมุจจะสุ" "พุท ธะ สัง วิ หะ ระ ตัง ปุญ ญัง วะ ทา มิ" กรกฎาคม 03, 2566 อ่านเพิ่มเติม
ความคิดเห็น
แสดงความคิดเห็น