-1

I am sending one integer variable from rpi to arduino. However, it is showing an error. Everything else is correct and here is the code which sends the data:-

from pubnub.pnconfiguration import PNConfiguration
from pubnub.pubnub import PubNub, SubscribeListener
import time
import numpy as np
import cv2
import serial
import RPi.GPIO as GPIO
import logging

#PubNub.set_stream_logger('recieve', logging.DEBUG)

#PubNub.SDK_VERSION

ser=serial.Serial("/dev/ttyACM0",9600)  #change ACM number as found from ls /dev/tty/ACM*
ser.baudrate=9600
ser.flushInput()

GPIO.setmode(GPIO.BOARD)
#GPIO.setup(11, GPIO.OUT)

pnconfig = PNConfiguration()
pnconfig.subscribe_key = "sub-c-fefb53da-045f-11ea-a185-1a72d7432d4b"
pnconfig.publish_key = "pub-c-811efe68-1f19-4cbc-9583-473ef14f04f5"
pnconfig.ssl = False

print("Code Run")

pubnub = PubNub(pnconfig)

print("lol1")

my_listener = SubscribeListener()
print("lol2")
pubnub.add_listener(my_listener)
print("lol3")
pubnub.subscribe().channels('recieve').execute()
print("lol4")
my_listener.wait_for_connect()

print("connected")

#pubnub.publish().channel("my_channel").message('hello there').sync()
result = my_listener.wait_for_message_on('recieve')
print(result.message)

if (result.message == 'point+B'):
        print("msg send")
        time.sleep(1)
        video_capture = cv2.VideoCapture(0)
        print("video activated")

        while(True):
                # Capture the frames

                ret, frame = video_capture.read()
                print("image processing on")

                crop_img = frame[0:1200, 0:700]
                gray = cv2.cvtColor(crop_img, cv2.COLOR_BGR2GRAY)

                # Gaussian blur
                blur = cv2.GaussianBlur(gray,(5,5),0)

                # Color thresholding
                ret,thresh = cv2.threshold(blur,60,255,cv2.THRESH_BINARY_INV)

                # Find the contours of the frame
                #contours,hierarchy = cv2.findContours(thresh.copy(), 1, cv2.CHAIN_APPROX_NONE)                    
                _, contours, _= cv2.findContours(thresh.copy(), 1, cv2.CHAIN_APPROX_NONE)

                # Find the biggest contour (if detected)
                if (len(contours) > 0):
                        c = max(contours, key=cv2.contourArea)
                        M = cv2.moments(c)
                        cx = int(M['m10']/M['m00'])
                        cy = int(M['m01']/M['m00'])
                        cv2.line(crop_img,(cx,0),(cx,720),(255,0,0),1)
                        cv2.line(crop_img,(0,cy),(1280,cy),(255,0,0),1)
                        cv2.drawContours(crop_img, contours, -1, (0,255,0), 1)
                        print(cx)
                        #cv2.imshow('frame',crop_img)
                        str(cx)
                        #cx = cx + str('\n')
                        write_ser=ser.write(cx.encode())
                        #write_ser=ser.write(cx)

                        int(cx)
                        if cx >= 450:
                                print ("Turn Right!")

                        if cx < 400 and cx > 300:
                                print ("On Track!")

                        if cx <= 50:
                                print ("Turn Left!")
                        else:
                                print ("I don't see the line")

                    #Display the resulting frame
                    cv2.imshow('frame',crop_img)
                    if cv2.waitKey(1) & 0xFF == ord('q'):
                            break

                    #cap.release()
                    #cv2.destroyAllWindows()

console:-

Code Run
lol1
lol2
lol3
lol4
connected
point+B
msg send
video activated
image processing on
222
Traceback (most recent call last):
  File "/home/pi/Desktop/Transporter codes/Final_transporter.py", line 97, in <module>
    write_ser=ser.write(cx.encode())
AttributeError: 'int' object has no attribute 'encode'

I tried converting to string variable but didn't work. What is the solution?

  • 1
    So, cx is a Python integer? What did you expect the encoded form to be? How did you try a string, and what happened that it didn't work? (Please edit this information into your question rather than replying as a comment.) – Bob Brown Feb 12 at 14:04
  • 1
    Nothing to do with the Raspberry Pi. – joan Feb 12 at 16:09
  • why did you use an arduino tag or even the serial tag? ... your question is about python – jsotola Feb 12 at 20:15
  • @susu, Welcome and nice to meet you. Ah, let me see. When I first read the statement "write_ser = ser.write(cx.encode()), I became nervous, because I could tell which language it uses, is it Arduino Mega C++, or Google Go, or Scala, or Node.Red. I was too afraid to ask, worrying other elites would LOL at my stupid question. I now think that this specific question might belong to the big or general question of "How can Rp talk to Arduino", then I have no worries, because I am a ninja in Rpi talking to Xduino, using python and serial UART, perhaps one of my old posts might help. – tlfong01 Feb 13 at 1:26
  • Reference 10 of The Lazy's answer to the following Rpi UART/serial question explains how Rpi can talk to Arudino (actually any device talking serial) using Python UART/serial: raspberrypi.stackexchange.com/questions/105223/…. – tlfong01 Feb 13 at 1:56
1

The error message you are getting says 'int' object has no attribute 'encode', the encode method is only available for objects of type str.

I believe you want the str() function instead to convert the integer into a string (or byte array) that the write function can then use. You also mention (in the comments) that the Arduino side is only receiving the data when you add a newline character to the newly created string: this is probably because the Arduino code is using something like readline and is looking for an EOL character.

As an aside, some might argue that converting cx into a string and putting it into the same variable and then adding the newline for sending is poor form, especially if you then convert it back into an integer later on. A more "readable" line of code that's easier to see what's going on and a bit more compact might be something like...

# Send CX as an ASCII string over the serial connection, terminate with newline.
write_ser = ser.write( str( cx ).encode( 'ascii' ) + b'\n' )
| improve this answer | |
  • 1
    right answer but 2 more lines after str(cx):- cx = cx + '/n', ser.write(cx.encoding('ascii')) .Then it sends data to arduino. Thats what I found just recently. – suu Feb 14 at 10:06
  • 1
    @suu I've added some more information to my answer that might help with adding the '\n' to the string. – Roger Jones Feb 14 at 10:54
  • cool, sounds good – suu Feb 15 at 12:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.