Pages: 1 ... 7 8 [9] 10 11 ... 19   Go Down
Print
Author Topic: เกี่ยวกับ Ac power line x-10  (Read 260675 times)
0 Members and 12 Guests are viewing this topic.
smitdh
Administrator
Hero Member
*****
Offline Offline

Gender: Male
Posts: 381


อาจารย์ที่ปรึกษา


« Reply #120 on: October 21, 2009, 06:24:51 PM »

- เมื่อเป็นภาครับ สัญญาณจะเข้ามาทางขา C ของ Q1 ผ่าน C9 ,R5  (High Pass)  ซึ่งถูกป้องกันแรงดันเกินด้วยซีเนอร์ 5 V เข้ามาทาง U1-1(13,12) ซึ่งทำหน้าที่ขยายสัญญาณเบื้องต้น ให้เอาพุตออกทางขา 12
- ส่วน U1-2 (11,10)  ซึ่งทำหน้าที่ขายสัญญาณอีกต่อหนึ่ง ที่เอาต์พุตของ U1-2 (ขา10) ถูกต่อไว้กับไดโอด และ C6 ทำหน้าที่เป็น Envelope Detector ซึ่งจะตัดสัญญาณ 120 KHz ทิ้งที่นี่เหลือแต่สัญญาณ ดิจิตอล
- สัญญาณที่ได้จะผ่านเข้า U1-3 (9,8) ทำหน้าที่ปรับรูปคลื่นให้คมชัดขึ้น
- U1-4 (5,6) ทำหน้าที่กลับเฟสให้ตรงกับที่เราต้องการ
« Last Edit: October 27, 2009, 02:02:42 AM by smitdh » Logged
coldman
Jr. Member
**
Offline Offline

Posts: 10


Email
« Reply #121 on: October 22, 2009, 12:06:15 PM »

สวัสดีครับ...

ตอนนี้วงจรเสร็จเรียบร้อยใช้งานได้แล้วครับ สามารถควบคุมอุปกรณ์1ตัวต่อ1จุด... ต่อไปก็จะเขียนโค้ดเพิ่มเป็นควบคุมอุปกรณ์3ตัวต่อ1จุด
ขอไปศึกษาโค้ดให้เข้าใจก่อนนะครับ  ติดขัดตรงไหนแล้วจะมาถามอีก รบกวนด้วยนะครับ
ขอบคุณมากครับ...
Logged
muiim
Jr. Member
**
Offline Offline

Posts: 67


Email
« Reply #122 on: October 26, 2009, 05:01:51 PM »

ถ้าผมเพิ่ม
#rom  0x2100={'A',0x2}        //Init EEPROM
#rom  0x2100={'A',0x3}
#rom  0x2100={'A',0x4}
(มันคือการกำหนดให้ตัวเครื่องมี 3 addressรึป่าวครับ)

และ code ข้างล่างคือ ส่วนที่เปรียบเทียบ address กับฟังชั่นที่สั่ง การปิด-เปิด LOAD ใช่มั้ย
void X10FuncExe(int House,int Number,int Fn)
{
int H,N,P;

   //Get Address form EEPROM House & Number
    H=read_eeprom(0);
    N=read_eeprom(1);

//Private Function
    if(H==House && N==Number)
    {
     switch(Fn)
     {
      case X10FN_ON:                        //ON
        output_high(X10OUT);
        break;
      case X10FN_OFF:                       //OFF
        output_low(X10OUT);
        break;
      case X10FN_STATUS_REQ:                     //12 ON ,13 OFF
          P=ReadPortA();
          P&=0B00000100;
          if(P==0B00000100)
             X10Write(H,N,X10FN_STATUS_ON);      //X10Write(H,N,12);
          else
             X10Write(H,N,X10FN_STATUS_OFF);
          break;
     }
    }
ดังนั่นถ้าผมจะสั่งให้มัน ควบคุมโหลด(คือ สมมุติว่าเครื่อง มีโหลดคือ X10OUT1,X10OUT2,X10OUT3
แล้วผมจะแยกการควบคุม 1 โหลด ต่อ 1 แอดเดรสยังไงครับ อาจารย์สมิทร์ ช่วยชี้แนะทีครับ)
Logged
smitdh
Administrator
Hero Member
*****
Offline Offline

Gender: Male
Posts: 381


อาจารย์ที่ปรึกษา


« Reply #123 on: October 26, 2009, 07:59:35 PM »

คำสั่ง preprocessor #rom start_address เป็นการบอกคอมไพล์เลอร์ให้เขียนข้อมูล ลงในส่วน eeprom ครับ
โดย PIC 16FXXX จะมี address อยู่ที่ 0x2100
ดูเพิ่มเติมที่ http://www.thaimicrotron.com/CCS-628/EEPROM/InEEPROM.htm

หากกำหนดแบบที่คุณกำหนดตามข้างบน มันจะทับกันเป็น 'A',0x4 ตัวเดียวครับ
ต้องกำหนดแบบเรียงต่อกันไปแบบนี้ครับ
#rom  0x2100={'A',0x2,'A',0x03','A',0x4}
เนื่องจากแอดเดรสมีขนาด 2 ไบท์ การเข้าถึง eeprom ภายในตามต่ำแหน่ง คือ 00,02,04 สำหรับแอดเดรสของอุปกรณ์ 1,2,3 ตามลำดับ

ปกติแล้ว device แต่ละตัวจะมีแอดเดรสประจำตัวค่าเดียว แต่หากต้องการให้มีมากกว่านั้น
ให้กำหนด X10OUT ทั้ง 3  X10OUT1, X10OUT2, X10OUT3

#define X10OUT1          PIN_A2
#define X10OUT2          PIN_??
#define X10OUT3          PIN_??


?? หมายถึงพอร์ตที่ว่าง อย่าลืมเซ็ทเป็นเอาต์พุตด้วย

เพื่อไม่ให้สับสนให้ copy function void X10FuncExe(int House,int Number,int Fn)
ไปเป็น 3 function
void X10FuncExeADR1(int House,int Number,int Fn)
void X10FuncExeADR2(int House,int Number,int Fn)
void X10FuncExeADR3(int House,int Number,int Fn)



โดยค่ำสังภายในจะต่างกันเล็กน้อยดั้งนี้ครับ
X10FuncExeADR1
   //Get Address form EEPROM House & Number
    H=read_eeprom(0);
    N=read_eeprom(1);

ตรง X10OUT ให้เปลี่ยนเป็น X10OUT1

X10FuncExeADR2
   //Get Address form EEPROM House & Number
    H=read_eeprom(2);
    N=read_eeprom(3);

ตรง X10OUT ให้เปลี่ยนเป็น X10OUT2

X10FuncExeADR3
   //Get Address form EEPROM House & Number
    H=read_eeprom(4);
    N=read_eeprom(5);

ตรง X10OUT ให้เปลี่ยนเป็น X10OUT3


ส่วน case X10FN_STATUS_REQ ให้ตัดทิ้งไปก่อน

ใน function main() ตรง
X10FuncExe(rHouse,rNumber,rFunction);

ให้เปลี่ยนเป็น
X10FuncExeADR1(rHouse,rNumber,rFunction);
X10FuncExeADR2(rHouse,rNumber,rFunction);
X10FuncExeADR3(rHouse,rNumber,rFunction);


Logged
muiim
Jr. Member
**
Offline Offline

Posts: 67


Email
« Reply #124 on: October 26, 2009, 10:50:22 PM »

ขอบคุณสำหรับคำชี้แนะครับ อาจารย์สมิทร์ เมื่อถามทาง output แล้ว ทีนี้จะถามทาง inputครับ จากcode
if(Key==1)
     {
       switch(D1)
       {
        case KEY_ON:
            X10WriteFn('A',X10FN_ALL_UN_ON);
            output_high(X10OUT1);
            output_high(X10OUT2);
            output_high(X10OUT3);
            break;

        case KEY_OFF:
            X10WriteFn('A',X10FN_ALL_UN_OFF);
            output_low(X10OUT1);
            output_low(X10OUT2);
            output_low(X10OUT3);
            break;

        case KEY_ON1:
            X10Write('A',02,X10FN_ON);  (ผมต้องการให้แอสเดรส A02 on)
            break;
        case KEY_OFF1:
            X10Write('A',02,X10FN_OFF); (ผมต้องการให้แอสเดรส A02 off)
            break;


           
       }
      SoundPress();
     }
 สมมุติว่าผมจะเพิ่ม สวิทช์ ผมก็เพิ่มเข้าไปในส่วนนี้ได้เลยใช่มั้ยครับ(ผมเข้าใจถูกรึป่าว)
อีกอย่างนะครับ ตรง #define นะครับ ในcodeมันเป็นแบบนี้
มีทั้ง #define SWOFF           PIN_B6
      #define SWON            PIN_B7
แล้วก็
      #define KEY_ON              0x80
      #define KEY_OFF             0x40
(ผมเลือกที่จะ define แบบไหนก็ได้ใช่มั้ยครับ)
สุดท้าย วงจรในภาครับ ภาคส่ง มันเป็น วงจรOSC แบบไหนครับ
ขอบคุณครับ
Logged
smitdh
Administrator
Hero Member
*****
Offline Offline

Gender: Male
Posts: 381


อาจารย์ที่ปรึกษา


« Reply #125 on: October 27, 2009, 02:02:18 AM »


อธิบายของเก่าก่อนนะครับ ให้ดูจากโค็ดนะครับ การที่เรากำหนด
#define SWOFF           PIN_B6
#define SWON            PIN_B7

ก็เพราะเราใช้ RB7 ,RB6 เป็นปุ่มที่ใช้ควบคุมโหลด
โดย ที่พอร์ตทั้งสองต่อ R pull down 10K ไว้ เมื่อมีการกดปุ่ม บิทนั้นจะเป็น 1
เมื่อเราอ่านพพอร์ต B เข้ามาด้วยฟังช์ชั่น
D1=ReadPortB();
เราจะสนใจบิท ที่ 6 กับ 7 จึงนำข้อมูลที่อ่านได้มา and กับ 0B11000000 (0B หมายถึง ไบนารี)
D1&=0B11000000;
เป็นการกำจัดบิท 0-5
หากค่าที่ได้เป็น 0 แสดงว่าไม่มีการกดคีย์ ให้ออกจากฟังชั่น

หากค่าที่อ่านได้ไม่ใช่ 0 เราก็จะหาต่อว่าเป็นปุ่มใด
หน่วงเวลา แล้วอ่านค่าใหม่ แต่ทีนี้เก็บไว้ในตัวแปร D2 (เป็นการ check debounce)
D2=ReadPortB();
กำจัดบิท 0-5
D2&=0B11000000;

หากค่า D1=D2 แสดงว่าไม่ใช่ bounce หรือ noise
กรณีปุ่มที่ RB7 ถูกกด ค่าจะเป็น 0B10000000  หรือ 0x80
กรณีปุ่มที่ RB6 ถูกกด ค่าจะเป็น 0B01000000  หรือ 0x40
เราจึงกำนดเป็น
#define KEY_ON              0x80
#define KEY_OFF             0x40

ดังนั้นในการตรวจสอบจึงเป็น
       switch(D1)
       {
        case KEY_ON:
            output_high(X10OUT);
            break;
        case KEY_OFF:
            output_low(X10OUT); 
            break;
       }

วิธีนี้เป็นการอ่านเข้ามาทั้งพอร์ต แล้วทำการ mark บิทที่เราสนใจเพื่อตรวจสอบ
แต่ก็เหมาะสำหรับอินพุตทั้งหมดอยู่ในพอร์ตเดียวกัน
กรณีที่อินพุตอยู่กันคนละพอร์ต เช่นบางส่วนอยู่ในพอร์ต A
ให้ใช้ฟังก์ชั่นประเภท ตรวจสอบทีละบิทเช่น value = input (PIN_A3) จะสะดวกกว่า โดยใช้หลักการเดียวกัน

//************************************************************
กรณีของคุณ ต้องใช้ปุ่ม 6 ปุ่มในการ ON/OFF เอาต์พุต 3 ตัว
#define SW1OFF          PIN_P1
#define SW1ON           PIN_P2
#define SW2OFF          PIN_P3
#define SW2ON           PIN_P4
#define SW3OFF          PIN_P5
#define SW3ON           PIN_P6

PIN_P1-PIN_P6 ไป map เอาเองแล้วกันครับ ว่าจะใช้ขาใด

ส่วนค่าของคีย์ ก็ขึ้นอยู่ว่าคุณใช้บิทใด
#define KEY1_ON              0x80
#define KEY1_OFF             0x40
#define KEY2_ON              ??
#define KEY2_OFF             ??
#define KEY3_ON              ??
#define KEY3_OFF             ??

ซึ่งถ้าใช้ปุ่มเยอะๆ น่าจะใช้แบบ Matrix key จะประหยัดพอร์ตกว่าครับ

ส่วนภาค OSC  Q1 กับ L1 เป็นแบบ Armstrong ครับ
ภาครับ L2,C3 เป็นวงจรจูน ครับ U1(4069) ใช้เป็น ภาคขยายสัญญาณ,Envelope Detector,และกลับเฟส ตามลำดับครับ
ดูที่ http://www.thaimicrotron.com/webboard2/index.php?topic=22.msg800#msg800
Logged
muiim
Jr. Member
**
Offline Offline

Posts: 67


Email
« Reply #126 on: October 27, 2009, 04:45:24 PM »

ขอบคุณสำหรับคำชี้แนะต่างๆนะครับ
ผมมีปัญหาอีกแล้ว คือว่า ผมลอง #include <16F877.h>
แล้วมัน error ครับ มันบอกว่า error ตรง #FUSE unknow keyword 'MCLR'
ยังไงดีละครับอาจารย์
Logged
smitdh
Administrator
Hero Member
*****
Offline Offline

Gender: Male
Posts: 381


อาจารย์ที่ปรึกษา


« Reply #127 on: October 27, 2009, 05:35:44 PM »

PIC16F877 ไม่มี fuse ตัวนี้ครับ ให้ลบออก แล้วลองคอมไพล์ใหม่
Logged
muiim
Jr. Member
**
Offline Offline

Posts: 67


Email
« Reply #128 on: October 27, 2009, 05:37:22 PM »

ถ้าผมแก้โดยการตัด MCLR ออกจาก#fuse คือ
#fuses XT,PUT,BROWNOUT,NOWDT,NOPROTECT,NOLVP
แล้วเพิ่ม
#define CMCON   0x1F
กับ
void InitialChip(void) ตัวนี้คือที่เข้าไปแทน
{
#asm
//Disable Comparator features
    CLRF   PORTA         //Clear Port A
    //CLRF   PORTB         //Clear Port B
   MOVLW   0x07         //Turn Comparator off and
   MOVWF   CMCON         //Enable pins for I/O
#endasm

   set_tris_a(0B11110011);
   set_tris_b(0B11000010);
}
เอาไปแทนที่ตัวเดิมคือ
void InitialChip(void)
{
   setup_comparator(NC_NC_NC_NC);   //Input Digital
   output_a(0);
   output_b(0B00000100);
   set_tris_a(0B11110011);
   set_tris_b(0B11000010);
}
มันไม่error ครับ แต่ไม่รู้ว่าถูกรึปาว
Logged
muiim
Jr. Member
**
Offline Offline

Posts: 67


Email
« Reply #129 on: October 27, 2009, 05:46:43 PM »

ถึงลบ MCLR ออก มันก็ error อยู่ครับตรงนี้แหละครับ
void InitialChip(void)
{
   setup_comparator(NC_NC_NC_NC);   //Input Digital
Logged
smitdh
Administrator
Hero Member
*****
Offline Offline

Gender: Male
Posts: 381


อาจารย์ที่ปรึกษา


« Reply #130 on: October 27, 2009, 08:30:33 PM »

ใช้ค่ำสั่งนี้แทนได้ครับ
#asm
//Disable Comparator features
    CLRF   PORTA         //Clear Port A
    //CLRF   PORTB         //Clear Port B
   MOVLW   0x07         //Turn Comparator off and
   MOVWF   CMCON         //Enable pins for I/O
#endasm

CCS ก็แปลกครับ ต่างเบอร์ พารามิเตอร์ก็ต่างกันออกไป
Logged
muiim
Jr. Member
**
Offline Offline

Posts: 67


Email
« Reply #131 on: October 27, 2009, 08:35:37 PM »

สรุปว่าผมทำถูกแล้วใช่มั้ยครับ ที่แทน
void InitialChip(void)
{
#asm
//Disable Comparator features
    CLRF   PORTA         //Clear Port A
    //CLRF   PORTB         //Clear Port B
   MOVLW   0x07         //Turn Comparator off and
   MOVWF   CMCON         //Enable pins for I/O
#endasm

   set_tris_a(0B11110011);
   set_tris_b(0B11000010);
}
ด้วยตัวนี้ครับ
Logged
smitdh
Administrator
Hero Member
*****
Offline Offline

Gender: Male
Posts: 381


อาจารย์ที่ปรึกษา


« Reply #132 on: October 27, 2009, 08:58:52 PM »

ถูกแล้วครับ
เนื่องจาก PIC16F877 CCS ไม่มีฟังก์ชั่น setup_comparator(NC_NC_NC_NC);
แต่ใน PIC16F877A ถึงจะใช้ได้ครับ

ตามความเห็นผม PIC16F877 ไม่ควรใช้แล้วครับมี error เพียบ ถึงแม้จะเปลี่ยนมาใช้ PIC16F877A ก็ยังไม่หมดปัญหา
-ชอบแฮงค์ บ่อยๆ จาก
- เวลาไฟกระชาก
- UART รับข้อมูลจำนวนมากๆ
- Timer, CCP

เอาไว้ทดลองพอได้
ให้เปลี่ยนเป็น PIC16F887 เป็นรุ่นใหม่เลยดีกว่าครับ
หรือพวก PIC18 เช่น PIC18F458

Logged
muiim
Jr. Member
**
Offline Offline

Posts: 67


Email
« Reply #133 on: October 27, 2009, 09:42:09 PM »

ขอบคุณที่แนะนำครับ งั้นผมลองหามาลองดูก่อนละกัน ส่วนการ #include น่าจะเป็นไปทางเดียวกันกับ 16F877ใช่มั้ยครับ
Logged
smitdh
Administrator
Hero Member
*****
Offline Offline

Gender: Male
Posts: 381


อาจารย์ที่ปรึกษา


« Reply #134 on: October 27, 2009, 11:30:25 PM »

หาเบอร์ไหนได้ ก็ใช้ทดลองไปก่อนครับ จะได้ไม่เสียเวลา
ถ้ามีเวลาค่อยหามาเปลี่ยน
Logged
Pages: 1 ... 7 8 [9] 10 11 ... 19   Go Up
Print
 
Jump to: