Robofun 機器人論壇

標題: 超音波感測 讀取序列埠數值 問題~ [打印本頁]

作者: albert000789    時間: 2018-12-18 20:32
標題: 超音波感測 讀取序列埠數值 問題~
目前想把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
本帖最後由 超新手 於 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
作者: albert000789    時間: 2018-12-27 17:09
超新手 發表於 2018-12-18 21:01
用 try except 把不能 轉換的字串印出來就知道了

不過我猜可能的原因是

我們已經可以成功讀取數值,現在加上第二個感測器,但讀取到的數值是交錯的,請問該如何將兩組數據分離出來?
作者: 超新手    時間: 2018-12-27 17:52
本帖最後由 超新手 於 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
作者: albert000789    時間: 2018-12-27 19:56
超新手 發表於 2018-12-27 17:52
在送第一筆時, 前面多送個辨識字元即可, 如 a
Arduino
Serial.print("a");

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

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

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

圖片中我們嘗試使用def函式 但是error顯示讀取的數值沒有被定義,不知如何是好

123.png (129.6 KB, 下載次數: 342)

123.png

作者: 超新手    時間: 2019-2-20 21:32
本帖最後由 超新手 於 2019-2-21 08:31 編輯

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

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

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

作者: albert000789    時間: 2019-2-21 14:59
超新手 發表於 2019-2-21 12:48
另外. 你的程式改成這樣,
不是很容易讀取失敗嗎?
如果 在執行 a() 的時候, 對方送sonar b 有效資料過來

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

後來因為一些原因,必須在主程式中寫入迴圈,以致於在python讀取延遲的問題
不知有沒有辦法可以解決這問題
既能有迴圈 讀取速度也不會減慢

2019-02-21-145254_1824x984_scrot.png (121.57 KB, 下載次數: 304)

2019-02-21-145254_1824x984_scrot.png

2019-02-21-145231_1824x984_scrot.png (121.61 KB, 下載次數: 335)

2019-02-21-145231_1824x984_scrot.png

作者: albert000789    時間: 2019-2-25 19:25
本帖最後由 albert000789 於 2019-2-25 19:30 編輯

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

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


作者: albert000789    時間: 2019-2-25 21:18
本帖最後由 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
多了括號
def main():
    t1=threading.Thread(target=c)
    t1.start()
    t2=threading.Thread(target=b)
    t2.start()   
作者: albert000789    時間: 2019-3-7 22:36
我們用多線程寫了這些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
本帖最後由 超新手 於 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()




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