Robofun 機器人論壇

標題: python轉arduino 超音波感測 問題求解~~~ [打印本頁]

作者: albert000789    時間: 2018-12-13 18:58
標題: 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
firmata 是用 UART 互連的
速度是 57600bps,
也就是就算來回只送一個byte, 也要花約 250us
更何況firmata的協定還不止傳一個byte
用這麼慢的速度去量測音波的來回(1cm 約 60us)
一定會不準的

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

另外請問有什麼方法可以解決感測器在arduino但是遙控車程式在python上,因為未來需要用到避障功能,不知道二者該如何互通?
目前我可以把arduino上的數據顯示在python上,但是怎麼把那些文字的數據(字串)弄成可以來寫if的讀取值(數值)嗎?因為一些原因我們的感測器必須裝在arduino上,但是遙控車移動的程式碼必須寫在python上
作者: 超新手    時間: 2018-12-15 16:05
本帖最後由 超新手 於 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[0] >= 10:
   
  if v[1] == 100:
  
3) 那個 %....確定不是寫錯嗎?
print("cm=%f\tinches=%f" % get_distance())



作者: albert000789    時間: 2018-12-17 19:19
超新手 發表於 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
response = ser.readline()
a=int(response)
if a <100:
  print("Quit")
試試看
作者: albert000789    時間: 2018-12-17 21: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







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







歡迎光臨 Robofun 機器人論壇 (https://robofun.net/forum/) Powered by Discuz! X3.2