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

  • sieuquay4444
    replied
    anh ơi cho em xin cái hình mạch đi mờ quá không thấy gì hết
    Nguyên văn bởi nttam79 Xem bài viết
    Xin chào tất cả mọi người.
    Mình tham gia diễn đàn đã khá lâu rồi nhưng không có đóng góp gì cho diễn đàn, mà chôm từ diễn đàn thì khá nhiều. Hôm nay thấy cắn rứt lương tâm quá nên làm 1 cái tut đóng góp cho ĐTVN.
    Mình thấy đề tài giao tiếp TCP/IP với AVR và điều khiển qua Internet được khá nhiều bạn quan tâm, tài liệu trên các diễn đàn nước ngoài cũng khá nhiều nhưng chưa có tut nào cụ thể và chi tiết, đặc biệt là hướng dẫn để mọi người có thể tự viết code được, chứ không phải copy code có sẵn. Vì vậy nên mình lôi 1 project đã làm cách đây khá lâu ra để làm cơ sở cho tut này.
    Bài 1-Hardware:
    Trong project này mình sử dụng một con ENC28J60 của Microchip để giao tiếp Ethernet. Vi điều khiển thì sử dụng Atmega32, có bộ nhớ RAM 2k, vừa đủ dùng (vì 1 frame ethernet có chiều dài max 1500bytes).
    Mọi người có thể mua 1 module phát triển Atmega32 + ENC28J60 tại TME (ATMEGA32 - Ethernet board - TMe: Linh kien, Sensors, Kit Phat trien, Mach nap 8051, PIC, AVR, ARM, EPROM, Flash...). Hay tự build 1 mạch theo sơ đồ sau:


    Mô tả:
    - Atmega32 giao tiếp với ENC28J60 qua SPI (MOSI/MISO/SCK) ngoài ra còn có chân chọn chip CS (nối với bất cứ IO nào của Atmega) và ngắt INT (nối vào ngắt ngoài VĐK).
    - ENC28J60 dùng nguồn 3V3, do đó cần 1 IC ổn áp 3V3. ENC28J60 cần 1 port RJ45 có tích hợp sẵn Transformer và LED.
    - Thêm MAX232 để dùng vào mục đích debug.
    - Thêm LCD và keypad (dùng để config hay hiển thị gì đó sau này). Nếu không cần có thể bỏ ra.

    Bài 2-Cở sở giao thức và thiết kế lưu đồ dữ liệu-Tạo project trong AVR studio:
    Chồng giao thức TCP/IP:
    Dưới đây là mô hình chồng giao thức TCP/IP


    Cụ thể hóa và lưu đồ dữ liệu vào ra của giao thức (áp dụng cho phần lập trình)


    Như vậy phần lập trình sẽ chia ra các module sau:
    - Module điều khiển ENC28J60: nằm trong file “enc28j60.c” và file header “enc28j60.h”, thêm file “enc28j60conf.h” để lưu các config.
    - Module giao thức Ethernet: gồm các file: “ethernet.c” và “ethernet.h”, thêm file "packet.h" khai báo các cấu trúc gói tin sử dụng trong bộ giao thức TCP/IP.
    - Module giao thức phân giải địa chỉ Address Resolution Protocol, gồm file “arp.c” và “arp.h”
    - Module giao thức IP gồm “ip.c” và “ip.h”
    - Module giao thức cấp phát địa chỉ IP động DHCP (Dynamic Host Configuration Protocol) gồm các file “dhcp.c” và “dhcp.h”
    - Module giao thức UDP gồm các file “udp.c” và “udp.h”
    - Module giao thức TCP gồm các file “tcp.c” và “tcp.h”
    - Module giao thức HTTP gồm các file “http.c” và “http.h”
    - Và một số các hàm hỗ trợ khác (uart, timer,…)
    Toàn bộ code viết trên AVR Studio, biên dịch với AVR-GCC

    Ta tạo 1 project mới trong AVR studio:

    Set thuộc tính cho project và chọn CPU, chọn tần số thạch anh:


    Sau khi tạo project, ta sẽ có source file đầu tiên là “ntAVRnet.c”.
    Mở file này, thêm vào hàm main, chương trình chính, nội dung hàm này sẽ được viết cuối cùng
    Code:
    //----------------------------------------------------------------------------
    // Writen by NTTam - PTITHCM
    //----------------------------------------------------------------------------
    #include <avr/io.h>
    //----------------------------------------------------------------------------
    
    int	main()
    {
    	return(0);
    }
    Tạo thêm file header cho nó: “ntAVRnet.h” có nội dung:
    Code:
    //----------------------------------------------------------------------------
    // Writen by NTTam - PTITHCM
    //----------------------------------------------------------------------------
    #ifndef NTAVRNET_H
    #define NTAVRNET_H
    
    
    #endif //NTAVRNET_H
    File này sẽ dùng để chứa các define và thông tin config chung cho toàn project

    Leave a comment:


  • sieuquay4444
    replied
    anh ơi cho em xin cái hình mạch đi mờ quá không thấy gì hết

    Leave a comment:


  • hoangtek
    replied
    Anh có thể giải thích hàm "void decode_base64". Mình vẫn chưa đăng nhập được. thank!

    Leave a comment:


  • yamailuk
    replied
    Nguyên văn bởi thanhnhuvt20 Xem bài viết
    Mình đọc hết cả luồng từ đầu chưa thấy thảo luận nhiều về vấn đề chuyền 1 chuỗi kí tự lên hiển thì trên web server. Mình mọi người giúp mình 2 cấu hỏi với.
    1/ Cách gửi 1 chuỗi kí tự lên web ( như mình đọc là thay đổi chuỗi %AD). nhưng thực sự mình chưa hiểu rõ nguyên lý lắm.
    2/Làm cách nào để cập nhật trạng thái liên tục của 1 kênh analog lên Web server mà không cần tự động làm tươi trình duyệt.
    Mong mọi người giúp đỡ mình
    1/ Không phải thay đổi chuỗi %AD mà là thay thế: Dấu % ở đây đóng vai trò là mã nhận dạng, còn AD là mã của giá trị cần thay thế (Do có nhiều thông số cần truyền đi).
    2/ Dùng Ajax
    Hello Arduino
    Arduino Ajax Web Server - YouTube

    Leave a comment:


  • thanhnhuvt20
    replied
    Mình đọc hết cả luồng từ đầu chưa thấy thảo luận nhiều về vấn đề chuyền 1 chuỗi kí tự lên hiển thì trên web server. Mình mọi người giúp mình 2 cấu hỏi với.
    1/ Cách gửi 1 chuỗi kí tự lên web ( như mình đọc là thay đổi chuỗi %AD). nhưng thực sự mình chưa hiểu rõ nguyên lý lắm.
    2/Làm cách nào để cập nhật trạng thái liên tục của 1 kênh analog lên Web server mà không cần tự động làm tươi trình duyệt.
    Mong mọi người giúp đỡ mình

    Leave a comment:


  • dorothy
    replied
    Nguyên văn bởi cowboy_188 Xem bài viết
    không biết mọi ng đã giải quyết được bài toán dùng một lúc thì mạch bị "đứng" chưa nhỉ. Mình có 2 kinh nghiệm chia sẻ


    1. Thay vì dùng ngắt ngoài để đọc từng gói tin ta có thể đọc trực tiếp và liên tục qua hàm ethGetFrame, rồi so sánh nếu len>0 thì đưa vào phân tích gói tin.

    Lưu ý thêm: trong hàm con enc28j60PacketReceive, sau khi đọc độ dài len nhớ thêm vào "len-=4;". Lý do là vì cần bỏ đi 4 byte CRC, nếu không trừ đi 4 byte này thì khi so sánh hoặc gửi trả lại gói tin sẽ bị sai. (Có thể dùng Wireshark để check lúc server trả gói tin arp, nó vẫn nhận nhưng báo sai byte)


    2. cái này quan trọng hơn và là nguyên nhân chính làm cho server bị "đứng". Vì dùng 1 lúc chip sẽ bị quá tải bộ nhớ dẫn đến ghi đè hoặc xóa các biến cũ, trong đó có biến ARPMyAddr trong file arp.c. Vì sau 1 thời gian, các bản arp ở các thiết bị client sẽ bị xóa, client khi liên lạc lại sẽ gửi gói tin arp hỏi server "địa chỉ 192.168.1.***" này là của ai, thì server sẽ không thể trả lời được gói tin arp này được do mất biến ARPMyAddr !

    Lý do là hàm con arpArpProcess có nhiệm vụ nhận và trả gói tin arp như đã nói ở trên đã bị mất biến ARPMyAddr nên nó không hiểu và loại ra khỏi điều kiện if (lúc check ip của chính server).

    Để fix vẫn đề này không khó, các bạn thay lúc check biến ARPMyAddr.ip bằng arpHeader->dipaddr == HTONL(IPADDRESS), trong đó IPADDRESS là cái ta đã define ban đầu trong thư viện ntAVRnet.h. Có một điều mình không hiểu lắm là tại sao biến ip và các biến khác của mình bị mất còn biến ARPMyAddr.ethAddr dùng cỡ nào cũng không thấy mất


    Trên đây là 1 vài kinh nghiệm khi dùng code thầy Tâm :-)
    bạn nào còn quan tâm thì có thể lưu ý
    Bạn có thể hướng đãn mình cụ thể hoặc share code chỉnh sửa cho mình được không?
    thank bạn nhiều!

    Leave a comment:


  • cowboy_188
    replied
    không biết mọi ng đã giải quyết được bài toán dùng một lúc thì mạch bị "đứng" chưa nhỉ. Mình có 2 kinh nghiệm chia sẻ


    1. Thay vì dùng ngắt ngoài để đọc từng gói tin ta có thể đọc trực tiếp và liên tục qua hàm ethGetFrame, rồi so sánh nếu len>0 thì đưa vào phân tích gói tin.

    Lưu ý thêm: trong hàm con enc28j60PacketReceive, sau khi đọc độ dài len nhớ thêm vào "len-=4;". Lý do là vì cần bỏ đi 4 byte CRC, nếu không trừ đi 4 byte này thì khi so sánh hoặc gửi trả lại gói tin sẽ bị sai. (Có thể dùng Wireshark để check lúc server trả gói tin arp, nó vẫn nhận nhưng báo sai byte)


    2. cái này quan trọng hơn và là nguyên nhân chính làm cho server bị "đứng". Vì dùng 1 lúc chip sẽ bị quá tải bộ nhớ dẫn đến ghi đè hoặc xóa các biến cũ, trong đó có biến ARPMyAddr trong file arp.c. Vì sau 1 thời gian, các bản arp ở các thiết bị client sẽ bị xóa, client khi liên lạc lại sẽ gửi gói tin arp hỏi server "địa chỉ 192.168.1.***" này là của ai, thì server sẽ không thể trả lời được gói tin arp này được do mất biến ARPMyAddr !

    Lý do là hàm con arpArpProcess có nhiệm vụ nhận và trả gói tin arp như đã nói ở trên đã bị mất biến ARPMyAddr nên nó không hiểu và loại ra khỏi điều kiện if (lúc check ip của chính server).

    Để fix vẫn đề này không khó, các bạn thay lúc check biến ARPMyAddr.ip bằng arpHeader->dipaddr == HTONL(IPADDRESS), trong đó IPADDRESS là cái ta đã define ban đầu trong thư viện ntAVRnet.h. Có một điều mình không hiểu lắm là tại sao biến ip và các biến khác của mình bị mất còn biến ARPMyAddr.ethAddr dùng cỡ nào cũng không thấy mất


    Trên đây là 1 vài kinh nghiệm khi dùng code thầy Tâm :-)
    bạn nào còn quan tâm thì có thể lưu ý

    Leave a comment:


  • chikichita
    replied
    cũng ko nghĩ đến trường hợp ni nữa
    Nguyên văn bởi yamailuk Xem bài viết
    Sao a không dùng dropbox hay driver mà đồng bộ

    Leave a comment:


  • hangidvn
    replied
    cảm ơn anh về bài viết

    Leave a comment:


  • yamailuk
    replied
    Nguyên văn bởi chikichita Xem bài viết
    mới bị gosh nhầm ổ đĩa DATA giờ đang mò mẫm lại code hihi, học lại từ đầu
    Sao a không dùng dropbox hay driver mà đồng bộ

    Leave a comment:


  • chikichita
    replied
    mới bị gosh nhầm ổ đĩa DATA giờ đang mò mẫm lại code hihi, học lại từ đầu

    Leave a comment:


  • chikichita
    replied
    lâu không vào diễn đàn rồi, vẫn thấy rôm rả quá mọi người nhỉ

    Leave a comment:


  • yamailuk
    replied
    Nguyên văn bởi mhl167 Xem bài viết
    Mình có giải thích ở trên rồi đó. Mình không có nói là chip bị treo mà là chip bị vướng lại trong hàm ethService() không thoát ra khỏi hàm ethService() nên mới bị watchdog timer reset lại chip. lưu đồ như sau:
    while(1)
    {
    start watchdog_timer();
    ethService();
    stop watchdog_timer();
    }
    mới cắm điện thì mạch chạy tốt nhưng sau 1 khoảng thời gian thì watchdog timer reset lại chip. chứng tỏ không thoát ra được hàm ethService()
    Bạn nên đọc lại giải thích của thầy một cách cẩn thận

    Leave a comment:


  • mhl167
    replied
    Mình có giải thích ở trên rồi đó. Mình không có nói là chip bị treo mà là chip bị vướng lại trong hàm ethService() không thoát ra khỏi hàm ethService() nên mới bị watchdog timer reset lại chip. lưu đồ như sau:
    while(1)
    {
    start watchdog_timer();
    ethService();
    stop watchdog_timer();
    }
    mới cắm điện thì mạch chạy tốt nhưng sau 1 khoảng thời gian thì watchdog timer reset lại chip. chứng tỏ không thoát ra được hàm ethService()

    Leave a comment:


  • yamailuk
    replied
    Nguyên văn bởi mhl167 Xem bài viết
    [MENTION=164001]yamailuk[/MENTION]:
    Mình cho timer1 sau 1 thời gian sẽ ngắt tràn, trong chương trình ngắt tràn timer1 mình gọi lại hàm ethInt() để khởi tạo lại giao thức mà vẫn bị treo trong hàm ethService() (mình thử dùng watchdog timer cho hàm ethService() thì sau 1 thời gian là chip bị reset lại, nếu hàm ethService() không bị treo thì chip sẽ không bị watchdog timer reset).
    Bạn làm thế nào khắc phục được vậy?
    Sao bạn biết chắc là chip bị treo chứ không phải giao thức?

    Leave a comment:

Về tác giả

Collapse

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

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

Collapse

  • nguyendinhvan
    Trả lời cho Vấn đề về tốc độ quay
    bởi nguyendinhvan
    Sử dụng động cơ servor, hoặc lắp thêm một cái encoder vào động cơ bước. Encoder sẽ kiểm soát động cơ có quay hoặc đứng im.
    Hôm qua, 19:50
  • Andrea14
    Vấn đề về tốc độ quay
    bởi Andrea14
    Chào mọi người,

    Tôi muốn mô phỏng sự thay đổi các mùa bằng cách từ từ nghiêng một quả địa cầu 16 inch bằng một động cơ bước nhỏ. Một động cơ bước khác sẽ quay quả địa cầu theo thời gian thực. Hệ thống truyền động...
    12-12-2025, 12:42
  • bqviet
    Trả lời cho Đấu tắt điện cho máy tính bảng
    bởi bqviet
    Bqv cáo lỗi vì chưa đủ khả năng diễn giải để người đọc hiểu. Người làm kỹ thuật sâu đôi khi như thế đó. Về việc nạp pin không vào dù cell mới, khả năng cái mạch quản lý đó đã hỏng - cũng chính là nguyên nhân đám cell cũ hỏng từ đầu.
    06-12-2025, 17:17
  • nguyendinhvan
    Trả lời cho Xin hỏi về mạch thu FM/AM trong catsette
    bởi nguyendinhvan
    Theo tôi, nó chỉ là cái Tuy- ê - nơ, hoặc là khối Trung Văn Tần, nó một phần trong cái Da đì ô thôi. Vì có thấy một chỗ có ba chân hàn, giiống như chân Cờ rít sờ tăng 455 ki nô hẹc. Còn khối Tuy ê nơ thì không nhìn thây cái Di ốt Va di cáp...
    05-12-2025, 19:59
Đang tải...
X