Robofun 機器人論壇

 找回密碼
 申請會員
搜索
熱搜: 活動 交友 discuz
查看: 5067|回復: 16

超音波感測 讀取序列埠數值 問題~

[複製鏈接]
發表於 2018-12-18 20:32:23 | 顯示全部樓層 |閱讀模式
目前想把Arduino的數值回傳到python上,先前在arduino序列埠上可以正常顯示數值,
但在python上發現讀取的值會空一行(在無障礙物遮擋時),有遮蔽物時,則可以正常顯示,
我們覺得是因為那些空行導致decode後在轉換成浮點數時,會出現不能把字串轉換成浮點數的error
不知道在python上的code有沒有錯誤~ 程式碼在下面

import serial

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

while True:
              response=ser.readline()
              decode=float(response[0:len(response)-2].decode("utf-8"))
              print(decode)
發表於 2018-12-18 21:01:06 來自手機 | 顯示全部樓層
本帖最後由 超新手 於 2018-12-19 08:58 編輯

用 try except 把不能 轉換的字串印出來就知道了

不過我猜可能的原因是
如果字串少於 2 個 byte
那就會變成空字串
float 沒辦法把空字串轉成浮點數


或是....直接不管它
try:
  decode=float(response[0:len(response)-2].decode("utf-8"))
  print(decode)
except:
  pass
 樓主| 發表於 2018-12-27 17:09:11 | 顯示全部樓層
超新手 發表於 2018-12-18 21:01
用 try except 把不能 轉換的字串印出來就知道了

不過我猜可能的原因是

我們已經可以成功讀取數值,現在加上第二個感測器,但讀取到的數值是交錯的,請問該如何將兩組數據分離出來?

arduino AB兩個感測器

arduino AB兩個感測器

python AB數據交錯

python AB數據交錯
發表於 2018-12-27 17:52:01 | 顯示全部樓層
本帖最後由 超新手 於 2018-12-28 08:53 編輯

在送第一筆時, 前面多送個辨識字元即可, 如 a
Arduino
Serial.print("a");
Serial.println(d);
Serial.println(d2);

Python
當然就要記得要把'a' 拿掉
try:
  response = ser.readline()
  response = response.strip()
  if response[0] == ord('a'):
    print("1")  
    decoder=int(response[1:])                        
  else:
    print("2")               
    decoder=int(response)   
  print(decoder)  
except:
  pass
 樓主| 發表於 2018-12-27 19:56:27 | 顯示全部樓層
超新手 發表於 2018-12-27 17:52
在送第一筆時, 前面多送個辨識字元即可, 如 a
Arduino
Serial.print("a");

已解決~~~~大感謝xdd
 樓主| 發表於 2019-2-18 17:42:21 | 顯示全部樓層
超新手 發表於 2018-12-27 17:52
在送第一筆時, 前面多送個辨識字元即可, 如 a
Arduino
Serial.print("a");

請問arduino與python上的程式碼與上面一模一樣都沒有改變而且之前可以正常使用.
為什麼今天使用時
一次使用兩個超音波感測,會有一個數值是錯誤(數值都是0)的並且在序列埠讀取數值的速度會變慢?
有個別測試兩個感測器功能皆正常
發表於 2019-2-18 17:59:16 | 顯示全部樓層
我猜是UART線斷了
檢查看看(或是把兩組 UART 線對調)
看看結果會不會變
 樓主| 發表於 2019-2-20 21:15:55 | 顯示全部樓層
超新手 發表於 2019-2-18 17:59
我猜是UART線斷了
檢查看看(或是把兩組 UART 線對調)
看看結果會不會變

請問若是需要讀取多個感測器數值並把他們寫成條件句(if ...and...)類似這種,
該如何撰寫?

圖片中我們嘗試使用def函式 但是error顯示讀取的數值沒有被定義,不知如何是好
123.png
發表於 2019-2-20 21:32:18 | 顯示全部樓層
本帖最後由 超新手 於 2019-2-21 08:31 編輯

要把副程式的變數decode1/decode2定義成global變數,
主程式才認的出來

def a():
  global decode2
  try:
.........

def b():
  global decode1
  try:
發表於 2019-2-21 12:48:59 | 顯示全部樓層
另外. 你的程式改成這樣,
不是很容易讀取失敗嗎?
如果 在執行 a() 的時候, 對方送sonar b 有效資料過來
或是 在執行 b() 的時候, 對方送sonar a 有效資料過來
這兩種情形都不會讀到有效資料吧?
而且 except: 中又去執行自己一次?
這種高等的程式技巧.
如果使用不當, 很容易出問題
 樓主| 發表於 2019-2-21 14:59:29 | 顯示全部樓層
超新手 發表於 2019-2-21 12:48
另外. 你的程式改成這樣,
不是很容易讀取失敗嗎?
如果 在執行 a() 的時候, 對方送sonar b 有效資料過來

我們把def函式 改為新的寫法,這樣是好的嗎?

後來因為一些原因,必須在主程式中寫入迴圈,以致於在python讀取延遲的問題
不知有沒有辦法可以解決這問題
既能有迴圈 讀取速度也不會減慢
2019-02-21-145254_1824x984_scrot.png
2019-02-21-145231_1824x984_scrot.png
 樓主| 發表於 2019-2-25 19:25:55 來自手機 | 顯示全部樓層
本帖最後由 albert000789 於 2019-2-25 19:30 編輯

另外想請問在python上可以使用serial read 二個序列埠數值嗎?

因為我們連接2 arduino板 不知道這樣讀取是否會有問題
發表於 2019-2-25 19:48:53 | 顯示全部樓層
這和軟體(PYTHON)沒關係
和你跑PYTHON的硬體, 昰不是有兩個 SERIAL PORT 有關
如果有, 就把 '/dev/ttyACM0' 改成另一個名字
例如 '/dev/ttyACM1'(注意 !!!!!!! ttyACM1 只是舉例, 要看你的硬體名稱)
ser1=serial.Serial('/dev/ttyACM1',9600,timeout=0.25)

 樓主| 發表於 2019-2-25 21:18:41 | 顯示全部樓層
本帖最後由 albert000789 於 2019-2-25 21:20 編輯
超新手 發表於 2019-2-25 19:48
這和軟體(PYTHON)沒關係
和你跑PYTHON的硬體, 昰不是有兩個 SERIAL PORT 有關
如果有, 就把 '/dev/ttyACM0' ...


我們正在學習多線程的使用,但是遇到其中一迴圈無運行
以下為程式碼:

import time
import threading

def b():
    while True:
        time.sleep(1)
        print("a")
        
        
def c():
    while True:
        time.sleep(1)
        print("b")
        
        
def main():
    t1=threading.Thread(target=c())
    t1.start()
    t2=threading.Thread(target=b())
    t2.start()

if __name__ == '__main__':
    main()

結果只印出bbbbb
不知識神馬問題
發表於 2019-2-26 08:51:05 | 顯示全部樓層
多了括號
def main():
    t1=threading.Thread(target=c)
    t1.start()
    t2=threading.Thread(target=b)
    t2.start()   
 樓主| 發表於 2019-3-7 22:36:14 | 顯示全部樓層
我們用多線程寫了這些code ,a() b() c() 函式可以執行,但是d()(tcp)卻沒有運作
可是我們單獨執行d() 卻可以成功傳送資料
不知是何處出了問題

import socket
import sys
import RPi.GPIO as GPIO
import serial,time
import threading

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

turn=17
motor=19
speedchange=21
no=24

GPIO.setmode(GPIO.BCM)
GPIO.setup(turn,GPIO.OUT)
GPIO.setup(motor,GPIO.OUT)
GPIO.setup(speedchange,GPIO.OUT)
GPIO.setup(no,GPIO.OUT)

pwm=GPIO.PWM(motor,55)
pwm1=GPIO.PWM(turn,55)


def a():
    global decode2
    global decode3
    while True:
        try:
            response=ser.readline()
            if response[0]==ord('b'):
                    print('b')
                    decode2=int(response[1:].decode("utf-8"))
                    print(decode2)
            if response[0]==ord('c'):
                    print('c')
                    decode3=int(response[1:].decode("utf-8"))
                    print(decode3)
        except:
            a()

def b():
    global decode4
    global decode5
    global decode6
    global decode7
    while True:
        try:
            response2=ser2.readline()
            if response2[0]==ord('d'):
                    print('d')
                    decode4=int(response2[1:].decode("utf-8"))
                    print(decode4)
            if response2[0]==ord('e'):
                    print('e')
                    decode5=int(response2[1:].decode("utf-8"))
                    print(decode5)
            if response2[0]==ord('f'):
                    print('f')
                    decode6=int(response2[1:].decode("utf-8"))
                    print(decode6)
            if response2[0]==ord('g'):
                    print('g')
                    decode7=int(response2[1:].decode("utf-8"))
                    print(decode7)
        except:
            b()

def c():
    while True:
        if decode2 > 50 and decode3 > 7 : #前進後退
            pwm.start(8.5)
            
            if 10 > (decode4 - decode5) > 5 : #左右微調
                pwm1.start(7.7)
                count=7.7
                while count>5:
                    count=count-0.01
                    time.sleep(0.001)
                    duty=float(count)
                    pwm1.ChangeDutyCycle(duty)

            if -10 < (decode4 - decode5) < -5 :
                pwm1.start(7.7)
                count=7.7
                while count<10:
                    count=count+0.01
                    time.sleep(0.001)
                    duty=float(count)
                    pwm1.ChangeDutyCycle(duty)
   
            if  (decode4 - decode5) > 10 : #左轉
                pwm1.start(7.7)
                count=7.7
                while count>5:
                    count=count-0.2
                    time.sleep(0.001)
                    duty=float(count)
                    pwm1.ChangeDutyCycle(duty)
                    
            if  (decode6 - decode7) > 10 : #右轉
                pwm1.start(7.7)
                count=7.7
                while count>12:
                    count=count+1
                    time.sleep(0.001)
                    duty=float(count)
                    pwm1.ChangeDutyCycle(duty)

        
          if decode2 < 50 :
            pwm.start(7.2)

               
        if decode3 < 5 and decode2 > 50 :
            pwm1.start(12)
            pwm.start(7)


def d():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    well_known_port = 8881
    sock.bind(('192.168.0.106', well_known_port))

    sock.listen(10)

    newSocket, address = sock.accept(  )
    print("connection success")

    while True:
        response=ser.readline()
        response2=ser2.readline()
        if not response.strip():
            continue
        if not response2.strip():
            continue
        sensor1=str(response.decode("utf-8"))
        aaa=str(len(sensor1))+sensor1
        newSocket.send(aaa.encode("utf-8"))
   
        sensor2=str(response2.decode("utf-8"))
        bbb=str(len(sensor2))+sensor2
        newSocket.send(bbb.encode("utf-8"))
        time.sleep(0.25)
      

def main():
    threading.Thread(target=d).start()
    threading.Thread(target=a).start()
    threading.Thread(target=b).start()
    time.sleep(1)
    threading.Thread(target=c).start()
               
main()
            
發表於 2019-3-8 12:43:04 | 顯示全部樓層
本帖最後由 超新手 於 2019-3-8 12:44 編輯

不知道為什麼要寫的這麼複雜?
出事是遲早的事
試看看這樣行不行, 如果不行, 那就.....自求多福了
ser=serial.Serial('/dev/ttyACM1',9600,timeout=0.25)
ser2=serial.Serial('/dev/ttyACM0',9600,timeout=0.25)
lock=threading.Lock()

def a():
lock.acquire()
response=ser.readline()
lock.release()

def a():
lock.acquire()
response=ser2.readline()
lock.release()


def d():
lock.acquire()
response=ser.readline()
response2=ser2.readline()
lock.release()
您需要登錄後才可以回帖 登錄 | 申請會員

本版積分規則

小黑屋|手機版|Archiver|機器人論壇 from 2005.07

GMT+8, 2024-3-28 16:51 , Processed in 0.234174 second(s), 8 queries , Apc On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回復 返回頂部 返回列表