Câu trả lời:
Câu trả lời ngắn gọn: Bạn KHÔNG THỂ đọc tin cậy trên Raspberry Pi.
Đọc PWM yêu cầu độ chính xác đến từng giây (trừ khi bạn đọc một PWM rất rất chậm) và điều đó không có trên Raspberry Pi cho phần mềm người dùng mà không cần mày mò với các mô-đun hạt nhân.
Cách dễ nhất để nắm bắt PWM là lấy bất kỳ vi điều khiển giá rẻ (<$ 0,5) nào có đầu ra nối tiếp hoặc I 2 C và nối nó với Raspberry Pi của bạn và đọc các giá trị thực từ vi điều khiển. Điều này sẽ làm việc rất đáng tin cậy và khá chính xác.
Đây là một câu hỏi thú vị và một câu hỏi mà bạn đã đúng khi nói Google Search không cung cấp một giải pháp rõ ràng! (Tôi nhớ những ngày mà Google có thể trả lời bất cứ điều gì tôi muốn biết về giáo dục / bài tập của mình trong vài giây.)
Tôi giả sử bạn hiểu các nguyên tắc của PWM . Vì vậy, tôi sẽ không đi vào đó. Tuy nhiên, về mặt lý thuyết, bạn có thể đọc giá trị PWM trên chân đầu vào kỹ thuật số thông thường với một số mã hóa thông minh.
Tôi sẽ thừa nhận rằng tôi đã không tự mình thử điều này, nhưng bạn sẽ có thể đo thời gian pin cao và thời gian thấp (cung cấp cho bạn đọc PWM) và sau đó sử dụng bất kỳ công thức toán học nào mà nhà cung cấp cảm biến cung cấp để chuyển đổi nó để đọc thực tế.
Phương pháp này hiệu quả với tôi về một vấn đề tương tự khi tôi cần đọc độ dài xung từ một mô-đun siêu âm và sau đó chuyển đổi nó thành khoảng cách. Các vấn đề tôi có thể dự tính liên quan đến việc đảm bảo bài đọc đáng tin cậy!
Nếu bạn nghĩ rằng nó sẽ giúp và muốn xem mã tôi đã sử dụng cho mô-đun siêu âm, chỉ cần nói như vậy và tôi sẽ sao chép nó khi tôi về nhà.
Tôi đã bắt đầu sao chép mã nhưng vì một số lý do, trang web chỉ cho phép tôi sao chép một phần nhỏ tại một thời điểm (và tôi quá lười để đưa pi của mình ra khỏi nhà để xe) vì vậy đây là liên kết đến nó. bỏ qua hầu hết các chức năng ở phía dưới vì chúng có liên quan đến việc sử dụng mô-đun làm cảm biến tiệm cận. http://pibot.webnode.com/products/ult siêu-lạ-sensor /
Tôi có thể thực hiện phép đo độ rộng xung khá chính xác bằng thư viện piGpio C: http://abyz.me.uk/rpi/pigpio/index.html
Thư viện này cho phép bạn cài đặt chức năng gọi lại sẽ kích hoạt bất kỳ chuyển đổi cạnh nào trên pin gpio và cung cấp cho bạn dấu thời gian ở mức micro giây cho mỗi lần chuyển đổi. Đừng nghĩ rằng bạn có thể tin tưởng vào điều này cho độ chính xác của micro giây - nhưng thử nghiệm của tôi cho thấy độ chính xác ít nhất là +/- 10us, có thể tốt hơn.
Tốt hơn nhiều so với việc chạy một vòng lặp bận rộn bỏ phiếu cho một gpio để thay đổi cấp độ bản thân.
Câu trả lời dài: Bạn thực sự có thể! (cũng với một chút trợ giúp từ điện trở và tụ điện của bạn bè)
Bạn có thể chuyển đổi đầu ra PWM thành mức điện áp tương tự, (DAC) và đọc nó bằng chân ADC trên pi mâm xôi của bạn.
Những gì bạn cần là một điện trở 4k7 và tụ 0,1uF:
mô phỏng mạch này - Sơ đồ được tạo bằng CircuitLab
Bộ lọc thông thấp RC đơn giản ở trên chuyển đổi tín hiệu PWM thành điện áp tỷ lệ với chu kỳ nhiệm vụ có thể được đọc bởi raspberry pi của bạn dưới dạng giá trị tương tự.
Nếu bạn hài lòng với phản hồi chậm, bạn có thể đọc một PWM nhanh bằng cách lấy mẫu. Chỉ cần đọc GPIO trong một vòng lặp và áp dụng bộ lọc thông thấp. Xác suất đọc 1 mỗi chu kỳ tỷ lệ thuận với độ rộng xung. Một bộ lọc thông thấp IIR dễ thực hiện là:
double acc=0.5;
const double k=0.01;
for(;;) {
bool x=GPIO.read();
acc+=k*(x?1:0-acc);
}
Khi k giảm, độ phân giải được cải thiện nhưng băng thông giảm.
Mặc dù câu trả lời của tôi không phải là từ các chân, bạn có thể sử dụng một cái gì đó dựa trên Máy đo dao động âm thanh để đọc đầu vào xung.
Mọi người đã sử dụng Thẻ âm thanh trong máy tính để bàn trong nhiều năm để tạo ra máy hiện sóng. Dường như với một card âm thanh nội bộ hiện đại, bạn có thể nhận được kết quả có thể sử dụng lên đến 10kHz. Với Thẻ âm thanh được kết nối với Raspberry Pi USB, tần số tối đa của bạn có thể thấp hơn.
Dưới đây là ví dụ về một dự án dao động âm thanh cho Linux: http://www.yann.com/en/diy-turn-your-gnulinux-computer-into-a-free-oscillcop-29/09/2010.html
Kịch bản python này tôi đã viết hoạt động tốt cho tôi để đọc tín hiệu PWM của Bộ thu RC. Các tín hiệu PWM tần số cao rõ ràng sẽ không hoạt động như đã được chỉ ra.
Tôi kết nối trực tiếp mười chân ra tín hiệu của bộ thu RC với các chân GPIO Raspberry. Máy thu được cấp nguồn bởi các chân + 5V và GND từ RPI.
Tôi đã đơn giản hóa tập lệnh vì nó làm rất nhiều thứ khác, nếu bạn tìm thấy bất kỳ sai lầm hoặc thức ăn thừa, hãy cho tôi biết
import RPi.GPIO as GPIO
import time
import numpy as np
inPINS = [2,3,4,14,15,18,17,27,22,23]
smoothingWindowLength=4
def getTimex():
return time.time()
GPIO.setup(inPINS, GPIO.IN)
upTimes = [[0] for i in range(len(inPINS))]
downTimes = [[0] for i in range(len(inPINS))]
deltaTimes = [[0] for i in range(len(inPINS))]
def my_callback1(channel):
i = inPINS.index(channel)
v = GPIO.input(inPINS[i])
#GPIO.output(outPINS[0], v) # mirror input state to output state directly (forward servo value only) - don't set PWM then for this pin
if (v==0):
downTimes[i].append(getTimex())
if len(downTimes[i])>smoothingWindowLength: del downTimes[i][0]
else:
upTimes[i].append(getTimex())
if len(upTimes[i])>smoothingWindowLength: del upTimes[i][0]
deltaTimes[i].append( (downTimes[i][-1]-upTimes[i][-2])/(upTimes[i][-1]-downTimes[i][-1]) )
if len(deltaTimes[i])>smoothingWindowLength: del deltaTimes[i][0]
GPIO.add_event_detect(inPINS[0], GPIO.BOTH, callback=my_callback1)
GPIO.add_event_detect(inPINS[1], GPIO.BOTH, callback=my_callback1)
try:
while True:
ovl = deltaTimes[0][-smoothingWindowLength:] # output first pin PWM
ov = sorted(ovl)[len(ovl) // 2] #ov = np.mean(ovl)
print ov
time.sleep(0.1)
except KeyboardInterrupt:
GPIO.cleanup()
Giải pháp dễ dàng với độ chính xác cao:
Sử dụng Arduino làm nô lệ iic hoặc thiết bị UART dường như hoạt động hoàn toàn tốt. Vi điều khiển có khả năng đọc thông tin thông qua phương thức PulseIn.
Thông tin chi tiết trước: https://www.youtube.com/watch?v=ncBDvcbY1l4