TypeError:必须是str,而不是字节

时间:2018-01-19 21:53:02

标签: python arduino tweepy pyserial

所以我正在编写一个函数,从发布当天颜色的Twitter帐户中提取十六进制颜色值。我希望将这个发送给arduino以点亮和使用那种颜色的LED,但是在尝试写入Arduino时我遇到了问题。我已将十六进制颜色值转换为RGB值并将其存储在元组中。我尝试引用RGB元组中的每个值来写出与我的Arduino的串行连接,但是我无法正确编码整数以便它们被发送。以下是我所指代码的具体部分:

 #Convert from hex to rgb
        rgb = tuple(int(this_color[i:i+2], 16) for i in (0, 2 ,4))

        #Add individual rgb values to list
        rgb_values = [rgb[0], rgb[1], rgb[2]]

        if (ser.isOpen()):
        # Start a main loop
            while (loopVar):

                # Prompt for Red value
                redVal = rgb[0]
                print(struct.pack('>B', redVal))
                ser.write("r" + struct.pack('>B',redVal))

                # Prompt for Green value
                greenVal = rgb[1]
                print(struct.pack('>B', greenVal))
                ser.write("g" + struct.pack('>B',greenVal))

                # Prompt for Blue value
                blueVal = rgb[2]
                print(struct.pack('>B', blueVal))
                ser.write("b" + struct.pack('>B',blueVal))

                # Check if user wants to end
                loopCheck = raw_input('Loop (y/N):')
                if (loopCheck == 'N'):
                    loopVar = False

    # After loop exits, close serial connection
    ser.close()

我认为我需要将整数值转换为原始二进制文件以便在write.serial中使用,但这似乎不起作用。

以下是运行文件时的输出:

142
<class 'int'>
33
<class 'int'>
38
<class 'int'>
b'\x8e'
Traceback (most recent call last):
  File "C:\Users\Louis\Desktop\MSTI Application\Arduino Lamp\Twitter_Scraping_Script_2.py", line 117, in <module>
    get_user_tweets('color_OTD', 5)
  File "C:\Users\Louis\Desktop\MSTI Application\Arduino Lamp\Twitter_Scraping_Script_2.py", line 92, in get_user_tweets
    ser.write("r" + struct.pack('>B',redVal))
TypeError: must be str, not bytes

有什么想法吗?

这是我的完整代码:

import tweepy 
import csv
import sys
import serial
import struct

#Create Serial port object called arduinoSerialData
ser = serial.Serial("COM1", 57600)
connected = False


#Twitter API credentials
consumer_key = 'xx'
consumer_secret = 'xx'
access_key = 'xx'
access_secret = 'xx'

def get_user_tweets(user_name, num_tweets):
 # Open the Serial Connection
    ser.close()
    ser.open()
    loopVar = True

    #authorize twitter, initialize tweepy
    auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
    auth.set_access_token(access_key, access_secret)
    api = tweepy.API(auth)

    #initialize list to hold tweet colors
    tweets_colors = []

    #Initialize string to hold current tweet
    this_tweet = ""

    #Initialize string to hold current color
    this_color = ""

    #Initialize tuple to hold rgb values
    rgb = ()

    #Initialize list to hold rgb values
    rgb_values =[]


    #Call to get access tweets from specified user
    tweets = api.user_timeline(screen_name='color_OTD',count=num_tweets)

    #Create a csv file with the username of the given user
    #with open('%s_tweets.csv' % user_name, 'w', newline='') as f:

        #Create writer object and give csv column names
        #writer = csv.writer(f)
        #writer.writerow(['red','green','blue'])

    #Loop through all tweets accessed
    for tweet in tweets:

        #If the tweet isn't a retweet
        if not tweet.retweeted:

            #Get # with hex color value
            this_tweet = str(tweet.entities.get('hashtags'))

            #Access hex value within hashtag string
            this_color = this_tweet[11:17]

            #Append all colors to list
            tweets_colors.append(this_color)

            #Convert from hex to rgb
            rgb = tuple(int(this_color[i:i+2], 16) for i in (0, 2 ,4))

            #Add individual rgb values to list
            rgb_values = [rgb[0], rgb[1], rgb[2]]
            #Write rgb values to csv
            #writer.writerow(rgb_values)

            print(rgb[0])
            print(type(rgb[0]))
            print(rgb[1])
            print(type(rgb[1]))
            print(rgb[2])
            print(type(rgb[2]))

            if (ser.isOpen()):
            # Start a main loop
                while (loopVar):

                    # Prompt for Red value
                    redVal = rgb[0]
                    print(struct.pack('>B', redVal))
                    ser.write("r" + struct.pack('>B',redVal))

                    # Prompt for Green value
                    greenVal = rgb[1]
                    print(struct.pack('>B', greenVal))
                    ser.write("g" + struct.pack('>B',greenVal))

                    # Prompt for Blue value
                    blueVal = rgb[2]
                    print(struct.pack('>B', blueVal))
                    ser.write("b" + struct.pack('>B',blueVal))

                    # Check if user wants to end
                    loopCheck = raw_input('Loop (y/N):')
                    if (loopCheck == 'N'):
                        loopVar = False

        # After loop exits, close serial connection
        ser.close()





if __name__ == '__main__':
    get_user_tweets('color_OTD', 5)

1 个答案:

答案 0 :(得分:0)

当您尝试将结构returns a bytes string添加到str类型时,出现错误的原因是结构https://docs.python.org/3/library/stdtypes.html#bytes。见第ser.write("r" + struct.pack('>B',redVal)) 行。

在python 3 shell中键入"r" + b"r",您将得到相同的错误TypeError: must be str, not bytes。您需要将“r”更改为b“r”,将字符串转换为字节字符串。 {{3}}

因此,您需要更改一些陈述。

ser.write(b"r" + struct.pack('>B',redVal))
ser.write(b"g" + struct.pack('>B',greenVal))
ser.write(b"b" + struct.pack('>B',blueVal))