albert000789 發表於 2018-12-13 18:58:14

python轉arduino 超音波感測 問題求解~~~

本帖最後由 albert000789 於 2018-12-13 19:01 編輯

這幾天在研究python透過firmata協定在arduino上操作感測器,編譯成功後python數值不正確,這下面為我打的code,麻煩大大指點找錯了!

import pyfirmata
import time

board = pyfirmata.Arduino("/dev/ttyACM0")

trigger = board.get_pin("d:10:o")
echo = board.get_pin("d:9:i")
it = pyfirmata.util.Iterator(board)
it.start()
echo.enable_reporting()
def send_trigger_pulse():
    trigger.write(1)
    time.sleep(0.001)
    trigger.write(0)
   
def wait_for_echo(value,count):
    while echo.read() !=value and count>0:
      count=count-1
      

def get_distance():
    send_trigger_pulse()
    wait_for_echo(True,5000)
    start = time.time()
    wait_for_echo(False,5000)
    finish = time.time()
    pulse_len = finish-start
    distance_cm = pulse_len*340*100/2
    distance_in = distance_cm/2.5
    return(distance_cm,distance_in)

while True:
    print("cm=%f\tinches=%f" % get_distance())
    time.sleep(1)

超新手 發表於 2018-12-14 19:55:30

firmata 是用 UART 互連的
速度是 57600bps,
也就是就算來回只送一個byte, 也要花約 250us
更何況firmata的協定還不止傳一個byte
用這麼慢的速度去量測音波的來回(1cm 約 60us)
一定會不準的

albert000789 發表於 2018-12-15 15:13:16

超新手 發表於 2018-12-14 19:55
firmata 是用 UART 互連的
速度是 57600bps,
也就是就算來回只送一個byte, 也要花約 250us


另外請問有什麼方法可以解決感測器在arduino但是遙控車程式在python上,因為未來需要用到避障功能,不知道二者該如何互通?
目前我可以把arduino上的數據顯示在python上,但是怎麼把那些文字的數據(字串)弄成可以來寫if的讀取值(數值)嗎?因為一些原因我們的感測器必須裝在arduino上,但是遙控車移動的程式碼必須寫在python上

超新手 發表於 2018-12-15 16:05:50

本帖最後由 超新手 於 2018-12-15 16:06 編輯

1)一定要在Arduino 偵測完超音波, 再把值讀回, 值才會準
所以最簡單的方法就是去改寫 Firmata 的程式
例如用你的超音波程式去取代原來讀A/D 的程式
這樣你就可以用Firmata的架構, 不用大改
原本 arduino Firmata讀a/d的程式
Firmata.sendAnalog(analogPin, analogRead(analogPin));
改成
if(analogPin == A0){
// 以下是隨便寫
digitalWrite(Trig, HIGH);
delayMicroseconds(10);
digitalWrite(Trig, LOW);
pulse_len = pulsein(ECH, HIGH, 1000);
Firmata.sendAnalog(analogPin, pulse_len);
} else {
Firmata.sendAnalog(analogPin, analogRead(analogPin));
}
2)上傳的數值不是本來就可以用 if 了嗎
   v = get_distance()
if v >= 10:
   
if v == 100:

3) 那個 %....確定不是寫錯嗎?
print("cm=%f\tinches=%f" % get_distance())


albert000789 發表於 2018-12-17 19:19:40

超新手 發表於 2018-12-15 16:05
1)一定要在Arduino 偵測完超音波, 再把值讀回, 值才會準
所以最簡單的方法就是去改寫 Firmata 的程式
例如 ...

我們在arduino上執行超音波程式,然後用python去讀他的序列埠,我們要的是能夠去判斷由這個序列埠讀出來的值
我們的code無法做出判斷(使用if)怎麼把這些字串轉換成數值,拜託大大了><

import serial
ser=serial.Serial('/dev/ttyACM0',9600,timeout=0.25)


try:
    while 1:
            response = ser.readline()
            print(response)

except KeyboardInterrupt:
          ser.close()
         
if response<100:
    print("Quit")

超新手 發表於 2018-12-17 19:48:54

response = ser.readline()
a=int(response)
if a <100:
print("Quit")
試試看

albert000789 發表於 2018-12-17 21:52:52

本帖最後由 albert000789 於 2018-12-17 21:57 編輯

超新手 發表於 2018-12-17 19:48
response = ser.readline()
a=int(response)
if a

b'6cm\r\n'我們之前跑出來的結果是長這樣,不是純數字

加上a=int(response)之後就出現 ValueError: invalid literal for int() with base 10: b'6cm\r\n'

該怎麼解決 TT,下面是我們arduino上的code,不知道是不是要改這裡的程式

const byte trigPin = 10;
const int echoPin = 9;
unsigned long d;

unsigned long ping(){
digitalWrite(trigPin,HIGH);
delayMicroseconds(10);
digitalWrite(trigPin,LOW);

return pulseIn(echoPin,HIGH);
}
void setup(){
pinMode(trigPin,OUTPUT);
pinMode(echoPin,INPUT);

Serial.begin(9600);
}

void loop(){
d=ping()/58;

Serial.print(d);
Serial.print("cm");
Serial.println();

delay(250);
}

超新手 發表於 2018-12-18 07:28:54








Serial.print(d);
Serial.print("cm");
Serial.println();
改成
Serial.println(d);


頁: [1]
查看完整版本: python轉arduino 超音波感測 問題求解~~~