Thông báo

Collapse
No announcement yet.

Giao thức TCP/IP và Web server với AVR

Collapse
This is a sticky topic.
X
X
 
  • Lọc
  • Giờ
  • Show
Clear All
new posts

  • mới năm nhất mà lấy cái này làm đồ án em đúng là cao thủ trèo cây đu đủ rồi đó.
    Nguyên văn bởi Ngoc Anh 91 Xem bài viết
    Trong hàm HTTPSend() có đoạn:

    i = 0;
    while(i<MAX_SEGMENT_SIZE)
    {
    tmpChr = pgm_read_byte(progdata + srcDataIdx++);
    if(tmpChr == '%')
    {
    if( (i + 9) > MAX_SEGMENT_SIZE) //Neu khong con du cho trong tren buffer
    {
    srcDataIdx--;
    break;
    }
    tmpVar = pgm_read_byte(progdata + srcDataIdx + 3) - 0x30; //Tiep tuc neu du cho trong tren buffer
    if((pgm_read_byte(progdata + srcDataIdx) == 'R') && (pgm_read_byte(progdata + srcDataIdx + 1) == 'L'))
    {
    if(GetRelayState(tmpVar))
    {//checked
    dataBuffer[i++] = ' ';dataBuffer[i++] = 'c';dataBuffer[i++] = 'h';dataBuffer[i++] = 'e';
    dataBuffer[i++] = 'c';dataBuffer[i++] = 'k';dataBuffer[i++] = 'e';dataBuffer[i++] = 'd';
    }
    srcDataIdx += 4;
    }
    else
    {// Neu truong hop khac:
    dataBuffer[i++] = tmpChr;
    }
    }
    else
    {
    dataBuffer[i++] = tmpChr; //Copy data to tcp data buffer
    }
    if(srcDataIdx==dataLen)
    {
    break;
    }
    }

    Mấy anh cho em hỏi cái này nhe:
    1/ Biến srcDataIdx dùng để làm gì?
    2/ if( (i + 9) > MAX_SEGMENT_SIZE) ... Tại sao chổ này phải là (i+9) ?
    3/ tmpVar = pgm_read_byte(progdata + srcDataIdx + 3) - 0x30; ... Cái dòng này thì em mù tịt luôn??? Hai cái số +3 và 0x30 là sao vậy mấy anh?
    4/ if((pgm_read_byte(progdata + srcDataIdx) == 'R') && (pgm_read_byte(progdata + srcDataIdx + 1) == 'L')) ...Nếu chổ này dùng cho Relay1 thì phải như vậy không mấy anh: if((pgm_read_byte(progdata + srcDataIdx) == 'R') && (pgm_read_byte(progdata + srcDataIdx + 1) == 'L') && (pgm_read_byte(progdata + srcDataIdx + 2) == '1')) ???
    5/ srcDataIdx += 4; ... còn cái này là gì vậy nhỉ?
    Do em mới học năm nhất, thấy cái này hay hay định làm đồ án mà sao khó hiểu quá? mong mấy anh giúp em! Cảm ơn trước nhe!

    Điện tử viễn thông - Hutech

    Comment


    • Còn câu hỏi của bạn:
      1/ Biến srcDataIdx là chiều dài địa chỉ wed trong RAM, ( len )
      2/ if( (i + 9) > MAX_SEGMENT_SIZE) ... Tại sao chổ này phải là (i+9) ? Bạn thử đếm xem " checked" có bao nhiêu chữ cái.
      3/ tmpVar = pgm_read_byte(progdata + srcDataIdx + 3) - 0x30; ... Cái dòng này thì em mù tịt luôn??? Hai cái số +3 và 0x30 là sao vậy mấy anh?
      4/ if((pgm_read_byte(progdata + srcDataIdx) == 'R') && (pgm_read_byte(progdata + srcDataIdx + 1) == 'L')) ...Nếu chổ này dùng cho Relay1 thì phải như vậy không mấy anh: if((pgm_read_byte(progdata + srcDataIdx) == 'R') && (pgm_read_byte(progdata + srcDataIdx + 1) == 'L') && (pgm_read_byte(progdata + srcDataIdx + 2) == '1')) ??? ------ cái này tùy chương trình bạn viết
      5/ srcDataIdx += 4; ... thêm chỗ trống cho địa chỉ wed lưu trong RAM, ban đầu chúng ta có "%RL1" là 4 + thêm 4 nữa là 8 vừa đủ cho chữ " checked" dùng để check box.



      Cái này bạn có thể kiểm chứng bằng cách nạp phần mềm vào mạch rồi chạy thử, bạn thử thay đổi các giá trị trên thì wed ra một số lỗi không như ý, dùng chế độ xem mã nguồn wed để xem sẽ phát hiện ra một số ký tự bị mất hoặc có thêm khoảng trống do địa chỉ dư hoặc thiếu.

      Điện tử viễn thông - Hutech

      Comment


      • Thông suốt cả đầu óc luôn rồi anh chikichita ơi! ^^ . . . em cảm ơn anh nhiều nghe! Bắt tay vào làm thôi!

        Comment


        • Trả lời cho rõ hơn nhé:
          1/ Biến srcDataIdx dùng để làm gì?
          Biến srcDataIdx là con trỏ để chỉ đến nội dung trang web đang lưu trên bộ nhớ ROM (nên phải dùng hàm pgm_read_byte để đọc). Nội dung trang web nằm trong file webpage.h.
          Trong quá trình này (hàm HTTPsend) ta copy nội dung trang web từ bộ nhớ ROM lên buffer (dataBuffer) gửi để gửi đi qua các giao thức lớp dưới. Trong quá trình copy, khi gặp những chuỗi đặc biệt (do ta định trước) ví dụ như %RL@1, %RL@2, %AD@0, %AD@1, ... ta sẽ tiến hành thay thế bằng các giá trị tương ứng theo ý đồ của việc điều khiển. Ví dụ khi gặp %AD@0 ta thay chuỗi trên bằng giá trị đọc từ cảm biến nhiệt độ, gặp %RL@1 ta thay thế bằng chuỗi "check" nếu trạng thái Relay này đang đóng.

          Còn biến i trỏ đến buffer đích (dataBuffer) trong quá trình copy

          2/ if( (i + 9) > MAX_SEGMENT_SIZE) ... Tại sao chổ này phải là (i+9) ?
          Nếu đã hiểu nguyên lý như trên, thì có 1 vấn đề như sau: khi copy nội dung trang web từ bộ nhớ ROM sang RAM (dataBuffer) thì chiều dài trang web thường lớn hơn kích thước dataBuffer nên ta sẽ phải chia ra gửi trong nhiều lần. Như vậy sẽ có trường hợp khi ta đang copy để gửi, giả sử dataBuffer chỉ còn trống 4 byte, ta lại gặp chuỗi %RL@1 trong nội dung trang web, khi đó ta tiến hành thay thế bằng "check" thì sẽ tràn dataBuffer gây ra lỗi. Vì vậy ta cần dự trù trước là sẽ thay thế các chuỗi đặc biệt đó bởi chuỗi có chiều dài tối đa là bao nhiêu con số 9 là chiều dài của chuỗi thay thế dài nhất có thể xảy ra.

          3/ tmpVar = pgm_read_byte(progdata + srcDataIdx + 3) - 0x30;
          Vì các chuỗi đặc biệt của ta có dạng là %RL@1, %RL@2, %AD@0, %AD@1,... nên tương ứng vị trí:
          pgm_read_byte(progdata + srcDataIdx) là ký tự R trong trường hợp Relay, A trong trường hợp AD
          pgm_read_byte(progdata + srcDataIdx + 1) là ký tự L trong trường hợp Relay, A trong trường hợp AD
          pgm_read_byte(progdata + srcDataIdx + 2) là ký tự @
          pgm_read_byte(progdata + srcDataIdx + 3) chính là ký tự chỉ số thứ tự của Relay (1,2,3,4) hay của kênh AD (0,1), đang ở mã ASCII
          Mã ASCII ký tự '0' = 0x30
          Mã ASCII ký tự '1' = 0x31
          Mã ASCII ký tự '2' = 0x32
          Mã ASCII ký tự '3' = 0x33
          ...
          Do đó để chuyển từ mã ASCII sang số kiểu char, ta đơn giản trừ đi 0x30.

          4/ if((pgm_read_byte(progdata + srcDataIdx) == 'R') && (pgm_read_byte(progdata + srcDataIdx + 1) == 'L')) ...Nếu chổ này dùng cho Relay1 thì phải như vậy không mấy anh: if((pgm_read_byte(progdata + srcDataIdx) == 'R') && (pgm_read_byte(progdata + srcDataIdx + 1) == 'L') && (pgm_read_byte(progdata + srcDataIdx + 2) == '1')) ???
          Câu trả lời trên cũng giải thích cho chỗ này bạn nhé, chỉ cần nhận ra "RL" thôi (ký tự % đã được nhận ra trước đó:if(tmpChr == '%')), còn số thứ tự của nó được xác định ở câu hỏi trước.

          5/ srcDataIdx += 4; ... còn cái này là gì vậy nhỉ?
          Nhắc lại
          pgm_read_byte(progdata + srcDataIdx) là ký tự là ký tự R trong trường hợp Relay, A trong trường hợp AD
          pgm_read_byte(progdata + srcDataIdx + 1) là ký tự L trong trường hợp Relay, D trong trường hợp AD
          pgm_read_byte(progdata + srcDataIdx + 2) là ký tự @
          pgm_read_byte(progdata + srcDataIdx + 3) chính là ký tự chỉ số thứ tự của Relay (1,2,3,4) hay của kênh AD (0,1)

          Như vậy ở lần đọc kế tiếp (để copy nội dung trang web từ ROM vào dataBuffer) ta sẽ phải đọc ký tự tiếp theo ở vị trí (progdata + srcDataIdx + 4)
          Vậy nên srcDataIdx += 4; //tức là srcDataIdx = srcDataIdx + 4;

          Chúc em thành công!

          PS: Lưu ý là đoạn code em post lên là của phiên bản tương ứng với nội dụng trang web chứa các chuỗi đặc biệt là %RL@1, %RL@2, %RL@3, %RL@4, %AD@0, %AD@1,... Còn nếu dùng chuỗi %RL1, %RL2, %RL3, %RL4, %AD0, %AD1, thì code cũng thay đổi tương ứng nhé, ví dụ khi đó sẽ là:
          ...
          tmpVar = pgm_read_byte(progdata + srcDataIdx + 2) - 0x30;
          ...
          srcDataIdx += 3;
          ...
          Last edited by nttam79; 04-03-2013, 11:16.

          Comment


          • Phần khai báo SPI của avr hình như không ổn định khi mình kết hợp với DS1307. Nó gây xung đột và rất dễ bị treo.
            Attached Files
            Last edited by yamailuk; 04-03-2013, 14:08.

            Comment


            • mấy a cho e hỏi e viết đến hàm ủat và hàm timer. ping trong cmd dc mà vào trang web chưa dc vậy cần làm gì để vào dc trang web vậy

              Comment


              • e vào cmd thì ping dc. nhưng dùng hyper terminal thì nó ko hiện lên gì hết ???

                Comment


                • và khi vào cmd khi có cắm com hay ko có com nó đều ra kết quả giống nhau. e dung board ethernet của thiên minh mọi người giúp e

                  Comment


                  • Nguyên văn bởi stevenboy Xem bài viết
                    và khi vào cmd khi có cắm com hay ko có com nó đều ra kết quả giống nhau. e dung board ethernet của thiên minh mọi người giúp e
                    Nếu bạn viết đến đoạn ping được, tức là trong hàm main có đoạn này:
                    int main(void)
                    {
                    SystemInit();
                    printf("\r\nNTTam AVR network testing with enc28j60.\r\n");
                    printf("Initializing Network Interface and Stack\r\n");
                    printf("Ethernet chip init\r\n");
                    IpMyConfig.ethaddr.addr[0] = ETHADDR0;
                    IpMyConfig.ethaddr.addr[1] = ETHADDR1;
                    IpMyConfig.ethaddr.addr[2] = ETHADDR2;
                    IpMyConfig.ethaddr.addr[3] = ETHADDR3;
                    IpMyConfig.ethaddr.addr[4] = ETHADDR4;
                    IpMyConfig.ethaddr.addr[5] = ETHADDR5;
                    IpMyConfig.ip = IPADDRESS;
                    IpMyConfig.netmask = NETMASK;
                    IpMyConfig.gateway = GATEWAY;
                    netInit(IpMyConfig.ip, IpMyConfig.netmask, IpMyConfig.gateway);
                    PrintIPConfig();
                    while(1)
                    {
                    ethService();
                    }
                    return 0;
                    }
                    Thì mạch chỉ xuất thông tin ra serial port thông tin cấu hình khi khởi động thôi, bạn phải cấu hình hyper terminal đúng cổng COM, đúng baudrate (9600), kết nối cổng COM và nhấn reset thì mới thấy xuất ra. Nếu không được thì kiểm tra hardware thôi.

                    Comment


                    • dạ e cám ơn thầy. có thể do phần cứng. do e dùng kit này của Thiên Minh M32E (ATMEGA32 - Ethernet board) - www.tme.vn - Linh kien dien tu, Kit Phat trien, Mach nap, GSM, GPS, GPRS, RF,
                      có thể có 1 số phần khác nhau về phần cứng. còn phần lập trình e đã làm đến được đoạn code đó và built ko có bị lỗi.

                      Comment


                      • Thưa thầy, em muốn truyền âm thanh qua internet (tạm làm trong LAN) bằng chuẩn G.729. Em đọc đoạn đầu của khuyến nghị thì thấy đầu vào của encoder nên là PCM đều 16bit, các mã khác phải chuyển hết về mã này.
                        PCM đều 16bit là mã như thế nào ạ? Nó có phải là mã 16bit dấu chấm tĩnh không, nó được tạo ra như thế nào ạ?
                        Sau cùng, xin thầy bảo cho em thuật toán convert giữa 2 chuẩn PCM (8bit và 16bit), liệu có thể áp dụng thuật toán này để convert ADC 10bit của AVR và PCM 16bit không ạ?
                        Em cảm ơn thầy ạ.

                        Comment


                        • Nguyên văn bởi dhp11591 Xem bài viết
                          Thưa thầy, em muốn truyền âm thanh qua internet (tạm làm trong LAN) bằng chuẩn G.729. Em đọc đoạn đầu của khuyến nghị thì thấy đầu vào của encoder nên là PCM đều 16bit, các mã khác phải chuyển hết về mã này.
                          PCM đều 16bit là mã như thế nào ạ? Nó có phải là mã 16bit dấu chấm tĩnh không, nó được tạo ra như thế nào ạ?
                          Sau cùng, xin thầy bảo cho em thuật toán convert giữa 2 chuẩn PCM (8bit và 16bit), liệu có thể áp dụng thuật toán này để convert ADC 10bit của AVR và PCM 16bit không ạ?
                          Em cảm ơn thầy ạ.
                          - Quá trình biến đổi từ tín hiệu tương tự sang tín hiệu số thông qua 4 bước:
                          Filtering (lọc) -> Sampling (lấy mẫu) -> Quantizing (lượng tử hóa) -> Encoding (Mã hóa)
                          Quá trình này còn gọi là điều chế PCM (Pulse Code Modulation)

                          Filtering: Tín hiệu tương tự được lọc để giới hạn băng thông của tín hiệu, bảo đảm thõa điều kiện của định lý Nyquist (băng thông của tín hiệu analog được lấy mẫu phải nhỏ hơn hoặc bằng 1/2 tần số lấy mẫu)
                          Sampling: Ở quá trình này, tín hiệu tương tự sẽ được lấy mẫu liên tục với 1 tần số xác định (tức là số lần lấy mẫu/giây). Ví dụ trong hệ thống audio ghi trên các đĩa CD thì tần số này là 44kHz (tức là lấy mẫu 44000 lần/giây), trong hệ thống thoại (điện thoại cố định) là 8kHz.
                          Quantizing: vì giá trị của mỗi mẫu sẽ được biểu diễn bằng 1 con số (1 chuỗi nhị phân), nên số mức biên độ mà ta có thể biễu diễn được là hữu hạn, ví dụ nếu dùng 4bit ta biễu diễn được n=16 mức, 8bit biễu diễn được n=256 mức,... nên ta cần làm tròn giá trị biên độ của mỗi mẫu về các giá trị nguyên gần nhất. Quá trình này là lượng tử hóa.
                          Có 2 cách lượng tử hóa:
                          - Lượng tử hóa đều: tức là ta chia khoảng biên độ của tín hiệu ra thành n mức đều nhau.
                          - Lượng tử hóa không đều: người ta nhận thấy nếu chia đều như vậy sẽ không tốt vì nếu tín hiệu vào có biên độ nhỏ, thì sai số do quá trình lượng tử hóa sẽ lớn, vì vậy người ta chia các mức này không đều nhau, cụ thể khoảng cách giữa các mức sẽ nhỏ hơn ở vùng biên độ nhỏ, và lớn hơn ở vủng biên độ lớn. Tất nhiên việc chia không đều này phải theo 1 qui luật nhất định. Hiện nay có 2 luật dùng phổ biến cho lượng tử hóa không đều là luật A và luật u (muy).
                          Coding: mỗi mẫu với biên độ đã được lượng tử hóa sẽ được biễu diễn thành 1 chuỗi nhị phân có chiều dài N bit phù hợp với số mức lượng tử ở trên. Ví dụ trong hệ thống audio trên CD là 16bit, hệ thống thoại của ĐT cố định là 8bit, hệ thống điện thoại di động GSM là 13bit,...

                          Vậy cho câu hỏi của em: số bit của PCM độc lập với việc nó lượng tử hóa đều hay không đều. 16bit hay 8bit đều có thể lượng tử hóa đều hoặc không đều.
                          Để convert giữa các PCM có số bit mã hóa khác nhau, đơn giản là ta làm tròn để giảm bớt số mức lượng tử của nó (trong trường hợp convert từ số bit lớn hơn sang nhỏ hơn), còn nếu ngược lại, từ số bit nhỏ hơn sang lớn hơn, thông thường người ta dùng các thuật toán nội suy để tính lại các giá trị mẫu nhằm đạt chất lượng tín hiệu tốt hơn.

                          Lưu ý bộ mã G.729 mà em định làm là bộ mã âm thanh dạng voice coder, thường dùng cho VoIP, nén tín hiệu thoại dựa trên nguyên lý tiếng nói của con người, nó đòi hỏi mức độ xử lý khá cao, thầy không nghĩ các microcontroller thông thường có thể đảm đương được mà có lẽ cần 1 DSP?

                          Comment


                          • Click image for larger version

Name:	sss.png
Views:	1
Size:	45.9 KB
ID:	1375105
                            e đã khai báo lại như vậy
                            #define IPADDRESS IPDOT(10,0,0,7)
                            #define NETMASK IPDOT(255,0,0,0)
                            #define GATEWAY IPDOT(10,0,0,2)
                            Nhưng khi ping thì nó vẫn giống như khi chưa có com. về phần cứng thì bỏad của e chỉ ko có LCD e nghĩ cái đó cũng ko ảnh hưởng. Tại e cũng chỉ mới học về phần này mong dc thầy giúp đỡ.

                            Comment


                            • Ủa, sao em khai báo IP cho máy tính giống với IP của mạch à, liên quan gì tới COM??? COM port (dùng uart) và ping là hai vấn đề hoàn toàn không dính dáng gì đến nhan hết. Em đang mong nhận được gì ở Hyper terminal? Cổng COM là để kết nối với uart của VĐK thôi chứ (dùng hyper terminal để nhận). Em định dùng Hyper terminal để ping à?

                              Comment


                              • E đã chỉnh lại và ping được rồi. do lúc đầu e hok biết nên e khia báo IP giống nhau nên khi ping nó giống.E đã làm dc rùi thanks thầy. đề tài của e là điều khiển xe wa mạng internet tìm được tài liệu này của thầy giúp e rất nhiều.

                                Comment

                                Về tác giả

                                Collapse

                                nttam79 Tìm hiểu thêm về nttam79

                                Bài viết mới nhất

                                Collapse

                                Đang tải...
                                X