Mục lục:

Wallace - Robot tự chế DIY - Phần 5 - Thêm IMU: 9 bước
Wallace - Robot tự chế DIY - Phần 5 - Thêm IMU: 9 bước

Video: Wallace - Robot tự chế DIY - Phần 5 - Thêm IMU: 9 bước

Video: Wallace - Robot tự chế DIY - Phần 5 - Thêm IMU: 9 bước
Video: STAR WARS GALAXY OF HEROES WHO’S YOUR DADDY LUKE? 2024, Tháng mười một
Anonim
Image
Image

Chúng tôi đang tiến hành cùng với Wallace. Cái tên Wallace xuất phát từ sự kết hợp giữa "Wall-E" và từ một dự án trước đó (nhận dạng giọng nói), và khi sử dụng tiện ích "espeak", nó có vẻ hơi giống người Anh. Và giống như một người hầu hoặc quản gia. Và đó là mục tiêu cuối cùng: để dự án này biến thành một thứ gì đó hữu ích. Vì vậy, "Wallace".

Wallace có thể di chuyển xung quanh, anh ấy có thể tránh chướng ngại vật bằng cách sử dụng cảm biến khoảng cách IR (gần đây, bằng cách nào đó chúng đã chiên (?) (Phải xem xét điều đó khi tôi có cơ hội), cũng có một số cảm biến khoảng cách âm thanh (ba trong số đó đều bị hỏng giống nhau thời gian, cùng với bộ mở rộng MCP23017), và cuối cùng, có thể phát hiện những thay đổi trong dòng điện của động cơ để biết khi nào nó va vào thứ gì đó.

Ngoài các cảm biến, Wallace còn "ghi nhớ" 100 lần di chuyển và có một số phân tích thô sơ bằng cách sử dụng lịch sử chuyển động.

Mục tiêu cho đến nay đối với Wallace là cố gắng tiếp tục tiến về phía trước và biết khi nào nó bị mắc kẹt trong một số mô hình lặp lại (chẳng hạn như trong một góc) và không thực sự tiến về phía trước.

Tôi đã trải qua một số lần lặp lại cho chuyển động và điều hướng, và cơn đau đầu liên tục xảy ra trong quá trình xoay.

Vì Wallace là một robot được theo dõi, và tôi muốn giữ mọi thứ đơn giản hơn trong phần mềm (cho sau này), để xoay chuyển, tôi chỉ cần cho anh ta xoay / xoay tại chỗ. Do đó, áp dụng công suất / chu kỳ làm việc bằng nhau nhưng ngược chiều nhau cho các động cơ.

Sự cố gặp phải là do thiết kế của nền tảng robot Agent 390. Các đai đường đua có xu hướng cọ xát vào hai bên. Và tệ hơn, một bên làm như vậy nhiều hơn bên kia.

Trên sàn và đi thẳng, nó không phải là một vấn đề. Nó hiển thị trên thảm. Tôi đã chọn để Wallace tránh xa tấm thảm sau khi đường ray của nó trở nên bẩn thỉu (họ nhặt bụi bẩn cực kỳ dễ dàng).

Vấn đề thực sự là khi xoay trên sàn.

Nếu tôi yêu cầu phần mềm áp dụng chu kỳ nhiệm vụ mức cao, thì ít nhiều nó sẽ quay một cách nhất quán. Tuy nhiên, trong một chu kỳ nhiệm vụ thấp, nó có thể thực sự quay hoặc không. Hoặc nó có thể quay một chút rồi chạy chậm lại. Hành động xoay vòng dường như không thể kiểm soát được thông qua phần mềm, hoặc tốt nhất là rất khó.

Sự cố xuất hiện trong quá trình điều hướng và di chuyển xung quanh hoặc ra khỏi chướng ngại vật. Nó có thể lắc lư quá xa, hoặc nó có thể gặp khó khăn khi cố gắng thực hiện những thay đổi rất nhỏ, thậm chí không thực sự di chuyển.

Và vì vậy lời giải thích ở trên đã thúc đẩy chương trình Có thể hướng dẫn này.

Ban đầu, tôi đã muốn xử lý hoặc trì hoãn việc giới thiệu đơn vị cảm biến chuyển động (IMU), vì chúng có lỗi A) phức tạp, B) ồn ào, C) có thể xuất hiện theo thời gian, v.v. rằng chúng tôi có thể làm rất tốt bằng cách chuyển sang cảm biến laser IR thời gian bay. Và chúng tôi có thể - bằng cách sử dụng tia laser, chúng tôi có thể biết liệu robot có quay hay không, bằng cách theo dõi những thay đổi về khoảng cách.

Trên thực tế, chúng ta cũng có thể (đại loại) làm điều đó ngay bây giờ, với các cảm biến âm thanh.

Tuy nhiên, tất cả những điều đó là một cách rất gián tiếp, phức tạp để trả lời một câu hỏi đơn giản: "chúng ta đã xoay vòng hay chưa?"

Đối với tôi, dường như việc chuyển sang sử dụng cảm biến laser ToF sẽ đưa tôi lên cấp độ phần mềm tiếp theo; cụ thể là SLAM (Bản địa hóa và Ánh xạ đồng thời). Tôi vẫn chưa sẵn sàng để đến đó.

Việc thực hiện một dự án robot trong các lớp là một điều tốt, với các lớp đầu tiên (dưới) đơn giản hơn và các lớp sau (trên) trừu tượng hơn và giải quyết các vấn đề khó khăn hơn.

Các lớp có thể được coi như thế này:

  1. cơ sở cấu trúc cơ khí / khung vật lý rô bốt
  2. hệ thống truyền động thô sơ (Raspberry, Roboclaw, động cơ, hệ thống cáp, v.v., phần mềm cơ bản, điều khiển bằng bàn phím)
  3. mạch thiết yếu để hỗ trợ cảm biến (bộ dịch chuyển điện áp hai chiều, bộ mở rộng cổng, E-Stop, phân phối điện, v.v.)
  4. cảm biến tránh chướng ngại vật (acoustic, IR)
  5. định vị và chuyển động cơ bản, cơ bản - phát hiện (gia tốc kế, con quay hồi chuyển, từ kế, bộ mã hóa động cơ, bộ mã hóa bánh xe)

Bạn có thể đưa ra danh sách của riêng mình. Điểm đáng chú ý của danh sách này là bạn có thể nên làm những việc này ít nhiều theo thứ tự đó, và nếu bạn dành một chút thời gian ở mỗi lớp để mỗi lớp trở về trạng thái hoạt động tốt, thì điều đó sẽ giúp ích cho bạn sau này khi mọi thứ trở nên phức tạp hơn.

Danh sách trên có thể được ánh xạ ít nhiều tới các lớp khái niệm này trong phần mềm.

  • SLAM (Bản địa hóa và ánh xạ đồng thời)
  • Kiểm soát và Nhận thức về Chuyển động, Xoay vòng
  • Tránh chướng ngại vật cơ bản
  • Kiểm soát và phát hiện dữ liệu cảm biến
  • Chuyển động cơ bản Về phía trước, Lùi lại, Trái và Phải, Tăng tốc độ, Giảm tốc độ, Dừng lại

Như bạn có thể thấy, đối với danh sách này, các mục đầu tiên sẽ là các lớp trên, phức tạp hơn giải quyết các vấn đề và câu hỏi trừu tượng hơn, chẳng hạn như "tôi đang ở đâu" và "tôi đang đi đâu", trong khi các mục sau sẽ là các lớp phần mềm thấp hơn xử lý "cách nói / nghe cảm biến A" hoặc "cách di chuyển bánh xe này".

Bây giờ, tôi không nói rằng khi bạn bắt đầu ở một lớp, bạn sẽ hoàn thành nó và sau đó là ở lớp tiếp theo, không bao giờ quay lại lớp trước. Một dự án robot có thể giống như các phương pháp phát triển phần mềm hiện đại, lặp đi lặp lại (nhanh nhẹn, SCRUM, v.v.).

Tôi chỉ nói rằng hãy dành thời gian cho từng việc. Bạn sẽ phải cân đối số lượng cần làm ở mỗi thứ và quyết định xem bạn đang cố gắng làm gì ở một lớp nhất định có đáng để bỏ thời gian và rắc rối hay không.

Có một "xung đột" hoặc "căng thẳng" nhất định giữa hai ý tưởng hoặc phương hướng cạnh tranh.

Một là những gì tôi sẽ gọi là "plug-n-play" để giải quyết vấn đề A.

Cái còn lại là DIY (tự làm). Và đó thậm chí có thể không phải là nhãn tốt nhất cho ý tưởng khác này.

Đây là một ví dụ về từng loại, hy vọng bạn sẽ thấy sự căng thẳng hoặc mâu thuẫn giữa hai lựa chọn.

Đối với ví dụ này, hãy gộp SLAM, tránh chướng ngại vật và chuyển động cơ bản thiết yếu thành một vấn đề cần giải quyết cùng một lúc.

  1. Nếu chúng ta quyết định đi theo con đường plug-n-play, chúng ta sẽ ngay lập tức chuyển sang (tùy thuộc vào ngân sách) những thứ như la-de xoay gắn trên cùng hoặc máy ảnh độ sâu trường ảnh, hoặc la-de ToF và IMU (chủ đề của điều này Có thể hướng dẫn).
  2. Mặt khác, nếu chúng tôi muốn đi theo con đường thứ hai, chúng tôi có thể cố gắng trích xuất mọi thông tin có thể có từ một số cảm biến âm thanh hoặc cảm biến IR hoặc không có cảm biến nào cả - chúng tôi chỉ sử dụng giám sát dòng động cơ (va chạm)

Có thể nói gì về # 1 so với # 2? Có một điều là chúng ta sẽ học được nhiều hơn khi thực hiện # 2. Những hạn chế của việc chỉ có cảm biến âm thanh để làm việc, buộc chúng ta phải suy nghĩ về nhiều vấn đề hơn.

Mặt khác, nếu chúng ta quá tập trung vào việc thực hiện mọi thứ thông qua số 2, chúng ta có thể lãng phí thời gian, bởi vì chúng ta yêu cầu nhiều hơn những gì chúng ta cần từ cảm biến âm thanh.

Một khái niệm hoặc ý tưởng nữa cần suy nghĩ: Hỗn hợp phần cứng và phần mềm nào trả lời tốt nhất cho các câu hỏi "làm thế nào để" và hỗn hợp phần mềm (và phần cứng nào?) Trả lời cho câu hỏi "cái gì", "khi nào", "ở đâu". Bởi vì "làm thế nào để" thường là một câu hỏi cấp thấp hơn phụ thuộc vào "cái gì", "khi nào" và "ở đâu" để nhận được câu trả lời.

Dù sao, tất cả những điều trên chỉ là một cái gì đó để suy nghĩ về.

Trong trường hợp của tôi, sau rất nhiều nỗ lực và gặp phải vấn đề khó chịu liên tục là ma sát đường ray và không thể có được sự kiểm soát và chuyển động nhất quán, đã đến lúc phải làm một việc khác.

Vì vậy, điều này có thể hướng dẫn - một IMU.

Mục đích là nếu IMU nói rằng rô bốt KHÔNG quay, chúng tôi sẽ tăng chu kỳ làm việc. Nếu chúng ta quay vòng quá nhanh, chúng ta sẽ giảm chu kỳ nhiệm vụ.

Bước 1: Cảm biến IMU

Cảm biến IMU
Cảm biến IMU
Cảm biến IMU
Cảm biến IMU

Và vì vậy cảm biến tiếp theo của chúng tôi để thêm vào Wallace là IMU. Sau một số nghiên cứu, tôi đang sử dụng MPU6050. Nhưng tại thời điểm này, MPU9050 (và thậm chí gần đây là MPU9250) dường như là một ý tưởng tuyệt vời hơn.

Nguồn truy cập của tôi là Amazon (ở Hoa Kỳ). Vì vậy, tôi đã đặt hàng hai trong số họ.

Trên thực tế, những gì tôi nhận được (dường như không có quyền kiểm soát điều này; đó là điều tôi không thích ở Amazon) là hai MPU92 / 65. Tôi tự hỏi một chút về việc chỉ định. Hãy xem các hình ảnh; đó dường như là một chỉ định "gia đình". Trong mọi trường hợp, đó là điều tôi đang mắc kẹt.

Việc thêm nó vào rất đơn giản - lấy một bảng proto với các rãnh kết nối, hàn cảm biến vào bảng, thêm một khối đầu cuối vít 10 chân (tôi lấy từ Pololu).

Để giảm thiểu bất kỳ sự can thiệp nào, tôi đã cố gắng đặt các cảm biến này cách xa mọi thứ khác.

Điều đó cũng có nghĩa là sử dụng một số bu lông / đai ốc bằng nylon.

Tôi sẽ sử dụng giao thức I2C. Hy vọng rằng tổng chiều dài dây sẽ không quá tệ.

Có rất nhiều thông tin ở nơi khác về các kết nối cơ bản và mức điện áp, v.v., vì vậy tôi sẽ không lặp lại điều đó ở đây.

Bước 2: Mọi thứ không phải lúc nào cũng sạch sẽ, dễ dàng

Tại thời điểm viết bài này, dường như không có nhiều thông tin trực tuyến về chiếc MPU-92/65 cụ thể này. Những gì có sẵn, giống như với hầu hết các cảm biến, dường như là những ví dụ sử dụng Arduino.

Tôi cố gắng làm cho các Tài liệu hướng dẫn này khác đi một chút bằng cách trình bày một quy trình không sạch sẽ, bởi vì mọi thứ không phải lúc nào cũng hoạt động ngay lập tức.

Tôi cho rằng các Tài liệu hướng dẫn này giống với một blog hơn là A-B-C thẳng, 1-2-3 "đây là cách bạn thực hiện".

Bước 3: Thử nghiệm ban đầu

Thử nghiệm ban đầu
Thử nghiệm ban đầu
Thử nghiệm ban đầu
Thử nghiệm ban đầu

Từ hình ảnh ở bước trước, các dây màu đỏ và đen đi đến các cảm biến tất nhiên là VCC (5V) và GND. Các dây màu xanh lá cây và màu vàng là kết nối I2C.

Nếu bạn đã thực hiện các dự án I2C khác hoặc đã theo dõi loạt bài này, thì bạn đã biết về "i2cdetect" và đó là bước đầu tiên để biết liệu Raspberry có thể nhìn thấy cảm biến mới hay không.

Như bạn có thể thấy từ các hình ảnh trong bước này, nỗ lực đầu tiên của chúng tôi đã không thành công. IMU không xuất hiện (phải là id thiết bị 0x68).

Tuy nhiên, điều đáng mừng là bus I2C đang hoạt động. Chúng tôi thấy một thiết bị 0x20 và đó là bộ mở rộng cổng MCP23017 (hiện chịu trách nhiệm cho các cảm biến âm thanh HCSR04).

Không dễ nhìn thấy trong hình ảnh, nhưng tôi đã kết nối các dây màu xanh lá cây và màu vàng giống nhau từ IMU đến MCP23017 (xem phía dưới bên trái trong hình ảnh)

Chúng tôi sẽ phải thực hiện một số khắc phục sự cố.

Bước 4: Khắc phục sự cố

Image
Image
Xử lý sự cố
Xử lý sự cố
Xử lý sự cố
Xử lý sự cố

Sử dụng cài đặt liên tục trên vôn kế (một vôn kế có âm cao), tôi đã kiểm tra các kết nối VCC (5V), GND, SDA và SCL. Đó là tốt.

Lần thử tiếp theo là ngắt kết nối MCP23017 khỏi bus I2C, chỉ để lại MPU-92/65 trên bus. Điều đó đã được chứng minh là không có kết quả - "i2cdetect" sau đó không hiển thị thiết bị nào.

Vì vậy, tiếp theo, tôi đã ngắt kết nối cảm biến khỏi cực totem và nối lại dây thẳng với xe buýt hai chiều 5V-to-3V; tức là chuyển thẳng đến Raspberry. (dây ngắn hơn?).

Và Voila. Lần này có thành công. Chúng tôi thấy 0x68 hiển thị bằng cách sử dụng "i2cdetect".

Nhưng chúng tôi vẫn chưa biết tại sao nó hoạt động vào thời điểm này. Nó có thể là chiều dài của dây? Vị trí trước đây?

Lưu ý: Không có bất kỳ sự khác biệt nào cho dù ADO có được nối đất hay không. Nó có thể có điện trở kéo lên và kéo xuống trên bo mạch. Điều này cũng có thể đúng với FSYNC.

Tiếp theo, tôi kết nối lại MCP23017. Vì vậy, bây giờ chúng ta có hai thiết bị trên bus I2C. (xem hình ảnh). Succes, bây giờ chúng ta thấy cả 0x20 và 0x68 với i2cdetect.

Các video đi sâu hơn một chút về những gì đã xảy ra trong quá trình khắc phục sự cố.

Bước 5: Đọc dữ liệu của cảm biến

Image
Image
Đọc dữ liệu của cảm biến
Đọc dữ liệu của cảm biến
Đọc dữ liệu của cảm biến
Đọc dữ liệu của cảm biến

Các cách tiếp cận khác nhau

Tôi quyết định thực hiện nhiều cách tiếp cận để nhận được thông tin hữu ích từ cảm biến. Chúng đây, không theo thứ tự nào:

  1. thử một số lập trình cơ bản
  2. xem qua một số tài liệu trực tuyến về sổ đăng ký
  3. xem xét các ví dụ và / hoặc mã của những người khác

Tại sao những cách tiếp cận này? Tại sao không chỉ tìm kiếm một số thư viện hoặc mã hiện có?

Bằng cách thử nghiệm và thử một số ý tưởng, chúng ta có thể hấp thụ tốt hơn một số kiến thức không chỉ về cảm biến cụ thể này mà còn có được một số kỹ thuật, kỹ năng và cách suy nghĩ về việc giải quyết một cái gì đó mới và một cái gì đó có thể không có nhiều tài liệu; một cái gì đó có thể có rất nhiều ẩn số.

Ngoài ra, một khi chúng tôi đã thử và thử một số ý tưởng của riêng mình và đạt được một số thông tin chi tiết, chúng tôi có một vị trí tốt hơn để đánh giá mã hoặc thư viện của người khác.

Ví dụ: sau khi xem một số mã C ++ cho MPU9250 trong github, tôi nhận ra rằng nó buộc tôi phải sử dụng ngắt, điều mà tôi chưa muốn làm.

Ngoài ra, nó đi kèm với những thứ bổ sung như hiệu chuẩn; một lần nữa, một cái gì đó tôi vẫn chưa quan tâm đến.

Có thể là những gì tôi cần làm để trả lời câu hỏi đơn giản "robot quay có hay không" có thể được trả lời rất đơn giản bằng cách chỉ đọc một số đăng ký.

Đăng ký

Tại thời điểm viết bài này, dường như không có nhiều khả năng trên cảm biến này. Trên thực tế, nếu bạn nhìn vào những hình ảnh đi kèm với Sản phẩm có thể hướng dẫn này và xem kỹ các chữ khắc trên các con chip thực tế, tôi sẽ tự hỏi liệu đây có phải là hàng nhái hay không. Tôi không liên quan những gì tôi thấy với bất cứ thứ gì từ Invense. Bất chấp điều đó, tôi đã chọn xem thông tin đăng ký cho các kiểu máy mà tôi tìm thấy: MPU-6050 và MPU-9250.

Trong cả hai trường hợp, điều sau đây là giống nhau cho cả hai. Và đối với những người mới bắt đầu, chúng tôi cho rằng nó cũng sẽ giống như vậy đối với chiếc MPU-92/65 này.

59 đến 64 - phép đo gia tốc kế

65, 66 - phép đo nhiệt độ 67 đến 72 - phép đo con quay hồi chuyển 73 đến 96 - dữ liệu cảm biến bên ngoài

Một điểm lưu ý: MPU-6050 dường như KHÔNG có từ kế, trong khi MPU-9250 (và chúng tôi giả định cái này cũng vậy) có một từ kế.

Một số thông tin thú vị, hy vọng hữu ích thu thập được từ tài liệu đăng ký:

Thông tin từ kế:

id từ kế: 0x48 đăng ký 00 đến 09: 00H WIA 0 1 0 0 1 0 0 0 01H THÔNG TIN THÔNG TIN 7 THÔNG TIN 6 THÔNG TIN 5 INFO4 INFO3 INFO1 INFO1 INFO0 02H ST1 0 0 0 0 0 0 DOR DRDY 03H HXL HX7 HX6 HX5 HX4 HX3 HX2 HX1 HX0 04H HXH HX15 HX14 HX13 HX12 HX11 HX10 HX9 HX8 05H HYL HY7 HY6 HY5 HY4 HY3 HY2 HY1 HY0 06H HY15 HY14 HY13 HY12 HY11 HY10 HY9 HY8 07H HZL HZ7 HZ6 HZ5 HZ4 HZ3 HZ2 HZ1 HZ 11 ST2 0 0 0 BITM HOFL 0 0 0 phân tích ý nghĩa của mỗi thanh ghi: HXL [7: 0]: Dữ liệu đo trục X thấp hơn 8 bit HXH [15: 8]: Dữ liệu đo trục X cao hơn 8 bit HYL [7: 0]: Dữ liệu đo trục Y thấp hơn 8bit HYH [15: 8]: Dữ liệu đo trục Y cao hơn 8bit HZL [7: 0]: Dữ liệu đo trục Z thấp hơn 8bit HZH [15: 8]: Dữ liệu đo trục Z cao hơn 8 bit

Lập trình

Một chút thông tin khác từ tài liệu đăng ký là dường như chỉ có khoảng 100 đăng ký hoặc hơn. Vì vậy, một chiến thuật có thể là viết một chương trình đơn giản truy cập thiết bị (0x68) và cố gắng đọc một loạt các thanh ghi một cách tuần tự, không quan tâm đến ý nghĩa của chúng, chỉ để xem dữ liệu nào có thể được nhìn thấy.

Và sau đó, thực hiện các lần vượt qua liên tiếp, sử dụng cùng một mã và so sánh dữ liệu từ lần vượt qua với lần tiếp theo.

Ý tưởng là chúng ta có thể loại bỏ bất kỳ thanh ghi nào dường như không có dữ liệu (số không hoặc FF?) Hoặc hoàn toàn không bao giờ thay đổi và chúng ta cũng có thể tập trung vào những thanh ghi có thay đổi.

Sau đó, chúng tôi chỉ xem xét những thứ thay đổi, thêm vào một hàm tính trung bình tính trung bình N lần đọc gần nhất của thanh ghi đó, để xem liệu trên thực tế có một giá trị ổn định nào đó cho thanh ghi đó hay không. Điều này giả sử rằng chúng tôi đang giữ cảm biến rất yên tĩnh và ở cùng một vị trí.

Cuối cùng, sau đó chúng tôi có thể nhẹ nhàng thử mọi thứ với cảm biến, chẳng hạn như tác động vào nó (gia tốc kế, con quay hồi chuyển) hoặc thổi vào nó (nhiệt độ) hoặc xoay nó (hai từ kế trước đó) và xem điều này có ảnh hưởng gì đến các giá trị.

Tôi muốn sử dụng thư viện wiringPi nhiều nhất có thể. Nó có hỗ trợ cho I2C.

Lần chạy đầu tiên:

/********************************************************************************

* để xây dựng: gcc first.test.mpu9265.c -o first.test.mpu9265 -lwiringPi * * để chạy: sudo./first.test.mpu9265 * * chương trình này chỉ xuất ra một loạt các thanh ghi (có thể) từ MCP23017, * và sau đó từ MPU9265 (hoặc bất kỳ MPU nào khác ở địa chỉ 0x68 đó) * * Tôi đã sử dụng nó để xác thực xem tôi thậm chí có thể đọc từ cảm biến hay không, vì tôi đã * tin tưởng vào MCP23017. * ************************************************* **************************** / #include #include #include #include #include int main (int argc, char ** argv) {put ("Hãy xem MCP23017 @ 0x20 nói gì:"); errno = 0; int deviceId1 = 0x20; int fd1 = wiringPiI2CSetup (deviceId1); if (-1 == fd1) {fprintf (stderr, "Không thể mở thiết bị I2C wiringPi:% s / n", strerror (errno)); trả về 1; } for (int reg = 0; reg <300; reg ++) {fprintf (stderr, "% d", wiringPiI2CReadReg8 (fd1, reg)); fflush (stderr); chậm trễ (10); } đặt (""); put ("Hãy xem MPU9265 @ 0x20 có gì để nói:"); errno = 0; int deviceId2 = 0x68; int fd2 = wiringPiI2CSetup (deviceId2); if (-1 == fd2) {fprintf (stderr, "Không thể mở thiết bị I2C wiringPi:% s / n", strerror (errno)); trả về 1; } for (int reg = 0; reg <300; reg ++) {fprintf (stderr, "% d", wiringPiI2CReadReg8 (fd2, reg)); fflush (stderr); chậm trễ (10); } đặt (""); trả về 0; }

Lần chạy thứ hai:

/********************************************************************************

* để xây dựng: gcc second.test.mpu9265.c -o second.test.mpu9265 -lwiringPi * * để chạy: sudo./second.test.mpu9265 * * Chương trình này xuất ra số đăng ký cùng với giá trị được đọc. * * Điều này rất hữu ích khi chuyển hướng (chuyển hướng) đầu ra đến một tệp, và sau đó * có thể thực hiện một số lần chạy để so sánh. Nó có thể cung cấp một số thông tin chi tiết về * thanh ghi nào là quan trọng và dữ liệu có thể hoạt động như thế nào. * ************************************************* **************************** / #include #include #include #include #include #include int main (int argc, char ** argv) {int deviceId = -1; if (0) {} else if (! strncmp (argv [1], "0x20", strlen ("0x20"))) {deviceId = 0x20; } else if (! strncmp (argv [1], "0x68", strlen ("0x68"))) {deviceId = 0x68; } else if (! strncmp (argv [1], "0x69", strlen ("0x69"))) {deviceId = 0x69; } put ("Hãy xem MPU9265 @ 0x20 có ý nghĩa gì:"); errno = 0; int fd = wiringPiI2CSetup (deviceId); if (-1 == fd) {fprintf (stderr, "Không thể mở thiết bị I2C wiringPi:% s / n", strerror (errno)); trả về 1; } for (int reg = 0; reg <300; reg ++) {fprintf (stderr, "% d:% d / n", reg, wiringPiI2CReadReg8 (fd, reg)); fflush (stderr); chậm trễ (10); } trả về 0; }

Lần chạy thứ ba:

/********************************************************************************

* để xây dựng: gcc third.test.mpu9265.c -o third.test.mpu9265 -lwiringPi * * để chạy: sudo./third.test.mpu9265 * * Chương trình này là kết quả của chương trình thứ hai. Nó chỉ đọc từ các thanh ghi * chỉ ra sự khác biệt giữa lần chạy này và lần chạy tiếp theo.* ************************************************* **************************** / #include #include #include #include #include #include int main (int argc, char ** argv) {int deviceId = -1; if (0) {} else if (! strncmp (argv [1], "0x68", strlen ("0x68"))) {deviceId = 0x68; } else if (! strncmp (argv [1], "0x69", strlen ("0x69"))) {deviceId = 0x69; } put ("Hãy xem MPU9265 @ 0x20 có ý nghĩa gì:"); errno = 0; int fd = wiringPiI2CSetup (deviceId); if (-1 == fd) {fprintf (stderr, "Không thể mở thiết bị I2C wiringPi:% s / n", strerror (errno)); trả về 1; } for (int reg = 61; reg <= 73; reg ++) {fprintf (stderr, "% d:% d / n", reg, wiringPiI2CReadReg8 (fd, reg)); fflush (stderr); chậm trễ (10); } for (int reg = 111; reg <= 112; reg ++) {fprintf (stderr, "% d:% d / n", reg, wiringPiI2CReadReg8 (fd, reg)); fflush (stderr); chậm trễ (10); } for (int reg = 189; reg <= 201; reg ++) {fprintf (stderr, "% d:% d / n", reg, wiringPiI2CReadReg8 (fd, reg)); fflush (stderr); chậm trễ (10); } for (int reg = 239; reg <= 240; reg ++) {fprintf (stderr, "% d:% d / n", reg, wiringPiI2CReadReg8 (fd, reg)); fflush (stderr); chậm trễ (10); } trả về 0; }

Vì vậy, những gì chúng ta đã học được cho đến nay? Hình ảnh của bảng với các vùng được đánh dấu màu cho biết rằng đầu ra dường như khớp với các bộ thanh ghi đầu tiên.

Kết quả cho đến nay có thể tạo ra những câu hỏi mới.

Câu hỏi: tại sao chỉ có một kết quả đăng ký cho nhóm "bên ngoài"?

Câu hỏi: tất cả những thanh ghi không xác định đó là gì "??????"

Câu hỏi: vì chương trình không được điều khiển bằng ngắt, nó yêu cầu dữ liệu quá chậm? quá nhanh?

Câu hỏi: chúng ta có thể ảnh hưởng đến kết quả bằng cách thử mọi thứ với chính cảm biến khi nó chạy không?

Bước 6: Hãy tìm hiểu thêm về các bài đọc / dữ liệu

Tôi nghĩ rằng bước tiếp theo trước bất kỳ điều gì khác là cải tiến chương trình để:

  • linh hoạt trong bao nhiêu độ trễ vòng lặp (mili giây)
  • linh hoạt trong số lần đọc để đưa ra mức trung bình chạy trên mỗi thanh ghi

(Tôi đã phải đính kèm chương trình dưới dạng tệp. Có vẻ như có sự cố khi chèn nó vào đây. "4th.test.mpu9265.c")

Đây là một lần chạy bằng cách sử dụng trung bình 10 lần đọc gần đây nhất, ở vòng lặp 10ms:

sudo./fourth.test.mpu9265 0x68 10 10

61:255 0 255 0 255 0 255 0 0 0: 102 62:204 112 140 164 148 156 188 248 88 228: 167 63:189 188 189 187 189 188 188 188 188 189: 188 64: 60 40 16 96 208 132 116 252 172 36: 112 65: 7 7 7 7 7 7 7 7 7 7: 7 66:224 224 224 240 160 208 224 208 144 96: 195 67: 0 0 0 0 0 0 0 0 0 0: 0 68:215 228 226 228 203 221 239 208 214 187: 216 69: 0 255 0 255 255 0 255 0 0 0: 102 70:242 43 253 239 239 45 206 28 247 207: 174 71: 0 255 255 0 255 255 255 255 255 255: 204 72: 51 199 19 214 11 223 21 236 193 8: 117 73: 0 0 0 0 0 0 0 0 0 0: 0 111: 46 149 91 199 215 46 142 2 233 199: 132 112: 0 0 0 0 0 0 0 0 0 0: 0 189:255 0 255 0 255 0 0 255 0 255: 127 190: 76 36 240 36 100 0 164 164 152 244: 121 191:188 188 188 188 187 188 187 189 187 189: 187 192: 8 48 48 196 96 220 144 0 76 40: 87 193: 7 7 7 7 7 8 7 7 7 7: 7 194:208 224 144 240 176 240 224 208 240 224: 212 195: 0 0 0 0 0 0 0 0 0 0: 0 196:243 184 233 200 225 192 189 242 188 203: 209 197:255 0 0 0 255 0 255 0 0 255: 102 198:223 39 247 43 245 22 255 221 0 6: 130 199: 0 255 255 255 0 255 255 255 255 0: 178 200:231 225 251 1 252 20 211 216 218 16: 164 201: 0 0 0 0 0 0 0 0 0 0: 0 239: 21 138 196 87 26 89 16 245 187 144: 114 240: 0 0 0 0 0 0 0 0 0 0: 0

Cột đầu tiên, ngoài cùng bên trái là số đăng ký. Sau đó đến 10 bài đọc cuối cùng cho thanh ghi đó. Cuối cùng, cột cuối cùng là giá trị trung bình cho mỗi hàng.

Có vẻ như các thanh ghi 61, 69, 71, 189, 197 và 199 hoặc chỉ là nhị phân, hoặc sẵn sàng / chưa sẵn sàng hoặc chúng là byte cao của giá trị 16 bit (âm?).

Các quan sát thú vị khác:

  • thanh ghi 65, 193 - rất ổn định và cùng giá trị
  • đăng ký 63, 191 - rất ổn định và cùng giá trị
  • đăng ký 73, 112, 195, 201, 240 - tất cả đều bằng 0

Hãy liên hệ những quan sát này trở lại hình ảnh bảng được tô sáng nhiều màu trước đó.

Đăng ký 65 - nhiệt độ

Đăng ký 193 - ??????

Đăng ký 63 - gia tốc kế

Đăng ký 191 - ??????

Đăng ký 73 - bên ngoài

Đăng ký 112 trở đi - ??????

Chà, chúng ta vẫn còn những ẩn số, tuy nhiên, chúng ta đã học được một điều hữu ích.

Đăng ký 65 (nhiệt độ) và đăng ký 63 (gia tốc kế) đều rất ổn định. Đây là điều mà chúng tôi mong đợi. Tôi chưa chạm vào cảm biến; nó không di chuyển, ngoài bất kỳ rung động ngẫu nhiên nào, vì robot đang nằm trên cùng bàn với máy tính của tôi.

Có một bài kiểm tra thú vị mà chúng tôi có thể thực hiện đối với từng thanh ghi nhiệt độ / gia tốc kế này. Đối với thử nghiệm đó, chúng tôi cần một phiên bản khác của chương trình.

Bước 7: Chúng ta có thể ảnh hưởng đến nhiệt độ và gia tốc

Trong các bước trước, chúng tôi đã thu hẹp ít nhất một thanh ghi nhiệt độ và một thanh ghi cho gia tốc.

Với phiên bản tiếp theo này của chương trình ("5th.test.mpu9265.c"), chúng ta thực sự có thể thấy sự thay đổi diễn ra cho cả hai thanh ghi. Mời các bạn xem video.

Đào nhiều hơn

Nếu chúng ta quay lại và xem lại thông tin đăng ký, chúng ta thấy rằng có:

  • ba đầu ra 16 bit cho con quay hồi chuyển
  • ba đầu ra 16 bit cho gia tốc kế
  • ba đầu ra 16 bit cho từ kế
  • một đầu ra 16 bit cho nhiệt độ

Tuy nhiên, kết quả thu được từ các chương trình thử nghiệm đơn giản của chúng tôi đều là đầu ra 8 bit duy nhất. (các thanh ghi đơn).

Vì vậy, chúng ta hãy thử nhiều cách tiếp cận tương tự, nhưng lần này đọc 16 bit thay vì 8.

Chúng tôi có thể sẽ phải làm một cái gì đó như dưới đây. Hãy sử dụng nhiệt độ làm ví dụ, vì nó chỉ có một đầu ra 16 bit.

// lấy bộ mô tả tệp fd…

int tempRegHi = 65; int tempRegLo = 66; int hiByte = wiringPiI2CReadReg8 (fd, tempRegHi); int loByte = wiringPiI2CReadReg8 (fd, tempRegLo); int result = hiByte << 8; // đặt lệnh hi 8 bit vào phần trên của kết quả giá trị 16 bit | = loByte; // bây giờ thêm vào thứ tự lo 8 bit, tạo ra một số 16 bit hoàn chỉnh // in số đó hoặc sử dụng chức năng vẽ đồ thị ngang hiển thị từ trước

Từ các bước trước của chúng tôi, chúng tôi đã thấy rằng đăng ký 65 khá ổn định, trong khi đăng ký 66 rất ồn ào. Vì 65 là byte thứ tự cao và 66 là byte thứ tự thấp, điều đó có ý nghĩa.

Để đọc, chúng ta có thể lấy dữ liệu của thanh ghi 65 như hiện tại, nhưng chúng ta có thể lấy trung bình các giá trị của thanh ghi 66.

Hoặc chúng ta có thể chỉ lấy trung bình toàn bộ kết quả.

Hãy xem video cuối cùng cho phần này; nó thể hiện việc đọc toàn bộ giá trị nhiệt độ 16 bit. Mã là "six.test.mpu9265.c"

Bước 8: Gia tốc kế và con quay hồi chuyển

Image
Image

Các video cho phần này hiển thị đầu ra từ gia tốc kế và con quay hồi chuyển, sử dụng chương trình thử nghiệm "7th.test.mpu9265.c". Mã đó có thể đọc 1, 2 hoặc 3 cặp byte liên tiếp (byte hi và byte) và chuyển đổi các giá trị thành một giá trị 16 bit duy nhất. Do đó, chúng ta có thể đọc bất kỳ trục đơn nào hoặc chúng ta có thể đọc hai trong số chúng cùng nhau (và nó tổng hợp các thay đổi), hoặc chúng ta có thể đọc cả ba (và nó tổng hợp các thay đổi).

Để nhắc lại, trong giai đoạn này, đối với Có thể hướng dẫn này, tôi chỉ muốn trả lời một câu hỏi đơn giản: "rô bốt đã quay / trục chưa?". Tôi không tìm kiếm bất kỳ giá trị chính xác nào, chẳng hạn như nó có xoay 90 độ không. Điều đó sẽ xảy ra sau khi chúng ta bắt đầu làm SLAM, nhưng nó không bắt buộc đối với việc tránh chướng ngại vật đơn giản và di chuyển ngẫu nhiên.

Bước 9: (Đang tiến hành) Máy đo từ tính

khi sử dụng công cụ i2cdetect, MPU9265 hiển thị dưới dạng 0x68 trong bảng:

0 1 2 3 4 5 6 7 8 9 a b c d e f

00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --

Cần có thêm các bước để đọc từ phần từ kế của IMU.

Từ tài liệu PDF đăng ký điều tra:

ĐĂNG KÝ 37 ĐẾN 39 - ĐIỀU KHIỂN I2C SLAVE 0

  • ĐĂNG KÝ 37 - I2C_SLV0_ADDR
  • ĐĂNG KÝ 38 - I2C_SLV0_REG
  • ĐĂNG KÝ 39 - I2C_SLV0_CTRL

Đề xuất: