Bicky
Posts: 5
Joined: Wed Jul 10, 2019 5:24 am

Arduino does not recieve value from raspberry pi

Tue Jul 30, 2019 4:15 am

Hello friends, I have been trying to transfer co-ordinates from picamera of raspberry pi to arduino .It was running smoothly in python 2.7.But in python 3+ i had to encode the value using encode() function to before serial write .
But now the arduino does not receive any value at all.
Serial.read in arduino shows -1 value .
Can someone tell me what to do? :( :(

This is my raspi code:

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Code: Select all

import io
from picamera.array import PiRGBArray
from picamera import PiCamera
import time
import sys
sys.path.append("/usr/local/lib/python3.5/site-packages")
import cv2
import serial
import numpy as np

camera = PiCamera()
camera.resolution = (640, 480)
camera.framerate = 32
rawCapture = PiRGBArray(camera, size=(640, 480))
port = "/dev/ttyUSB0"
s1 = serial.Serial(port,9600)

time.sleep(0.1)

for frame in camera.capture_continuous(rawCapture, format="bgr", use_video_port=True):
	image = frame.array

	hsv = cv2.cvtColor(image,cv2.COLOR_BGR2HSV)
	 
	lower_range = np.array([110,50,50])
	upper_range = np.array([130,255,255])

	mask = cv2.inRange(hsv, lower_range, upper_range)
	#cv2.imshow("Frame",image)
	key = cv2.waitKey(1) & 0xFF

	
	ret,thresh = cv2.threshold(mask,127,225,0)
	im2,contours,hierarchy = cv2.findContours(thresh,1,2)
	
	#cnt = contours[0]
	M = cv2.moments(thresh)
	
	if M['m00']!=0:
		cx = int(M['m10']/M['m00'])
		cy = int(M['m01']/M['m00'])
		cv2.circle(image, (cx, cy), 10, (255, 0, 0), -1)
		print cx
		z= str(cx)+'a'		
		s1.write(z.enocde())
		
		
	else:
		cx, cy = 0, 0

	cv2.imshow("TERMINATOR",image)
	key = cv2.waitKey(1) & 0xFF


	rawCapture.truncate(0)
	if key == ord("q"):
		break

cv2.destroyAllWindows()
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
This is my code in arduino :
#include <Servo.h>
//#include <SoftwareSerial.h>
//SoftwareSerial data_serial(52 , 36); // RX, TX
//SoftwareSerial data_serial2(9, 11); // RX, TX
char m[10];
char n;
int count;
int i=0;
float value;
const int Oina1 = 12;
const int Oina2 = 13;
const int Oina3 = 9;
const int Oina4 = 8;

const int Oinb1 = 6;
const int Oinb2 = 7;
const int Oinb3 = 3;
const int Oinb4 = 2;
int Oena1=11;
int Oena2=10;
int Oenb1=5;
int Oenb2=4;
int spray=14;

Servo servo01;
Servo servo02;
Servo servo03;
Servo servo04;
Servo servo05;
Servo servo06;
int servo1Pos, servo2Pos, servo3Pos, servo4Pos, servo5Pos, servo6Pos; // current position
int servo1PPos, servo2PPos, servo3PPos, servo4PPos, servo5PPos, servo6PPos; // previous position


void setup() {
  
  pinMode(Oina1,OUTPUT);
  pinMode(Oina2,OUTPUT);
  pinMode(Oina3,OUTPUT);
  pinMode(Oina4,OUTPUT);
  pinMode(Oinb1,OUTPUT);
  pinMode(Oinb2,OUTPUT);
  pinMode(Oinb3,OUTPUT);
  pinMode(Oinb4,OUTPUT);
  pinMode(Oena1,OUTPUT);
  pinMode(Oena2,OUTPUT);
  pinMode(Oenb1,OUTPUT);
  pinMode(Oenb2,OUTPUT);
 pinMode(spray,OUTPUT);
  servo02.attach(22);
  servo03.attach(23);
  servo05.attach(24);
  servo06.attach(25);
  servo2PPos = 100;
  servo02.write(servo2PPos);
  servo3PPos = 10;
  servo03.write(servo3PPos);
  servo5PPos = 10;
  servo05.write(servo5PPos);
  servo6PPos = 100;
  servo06.write(servo6PPos);
  Serial.begin(9600);
 // Serial.begin(9600);

}

void loop() {
 
  if(Serial.available()){
  n=Serial.read();
 if(n =='b'){
  value=atof(m);
   Serial.println("y-axis:");
  Serial.println(value);
 
  i=0;
  m[0]=0;
  m[1]=0;
  m[2]=0;
  m[3]=0;
  
} 
else{
m[i]=n;
i++;
}
}

  if(value>=180 && value<=400){
    while(value>=180 && value<=400){
      Stop();
    pick();
    }


  }

  sideways();
  
 

}
void pick(){
 
 for(int i=100;i<=160;i++){ 
    servo02.write(i);
    delay(20);
 }
 for(int j=10;j<=50;j++){ 
    servo03.write(j);
   delay(20);
 }
 for(int k=10;k<=50;k++){ 
    servo05.write(k);
  delay(20);
 }
 for(int l=100;l>=0;l--){
     servo06.write(l);
   delay(20);
 }

 
}
void sideways()
{
  analogWrite(Oena1,50);
  analogWrite(Oena2,50);
   analogWrite(Oenb1,50);
  analogWrite(Oenb2,50);
  
  
  digitalWrite(Oina1,HIGH);
  digitalWrite(Oina2,LOW);
    digitalWrite(Oina3,LOW);
  digitalWrite(Oina4,HIGH);
   digitalWrite(Oinb1,LOW);
  digitalWrite(Oinb2,LOW);
    digitalWrite(Oinb3,LOW);
  digitalWrite(Oinb4,LOW);
  
  
}
void frontways()
{
  analogWrite(Oena1,50);
  analogWrite(Oena2,50);
   analogWrite(Oenb1,50);
  analogWrite(Oenb2,50);
  
  
  digitalWrite(Oina1,LOW);
  digitalWrite(Oina2,LOW);
    digitalWrite(Oina3,LOW);
  digitalWrite(Oina4,LOW);
   digitalWrite(Oinb1,HIGH);
  digitalWrite(Oinb2,LOW);
    digitalWrite(Oinb3,HIGH);
  digitalWrite(Oinb4,LOW);
  
  
}
void Stop()
{
  analogWrite(Oena1,50);
  analogWrite(Oena2,50);
   analogWrite(Oenb1,50);
  analogWrite(Oenb2,50);
  
  
  digitalWrite(Oina1,LOW);
  digitalWrite(Oina2,LOW);
    digitalWrite(Oina3,LOW);
  digitalWrite(Oina4,LOW);
   digitalWrite(Oinb1,LOW);
  digitalWrite(Oinb2,LOW);
    digitalWrite(Oinb3,LOW);
  digitalWrite(Oinb4,LOW);
  
  
}
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
This is my pi and Arduino setup:
Attachments
67622194_1816616935151454_266816369293524992_n.jpg
67622194_1816616935151454_266816369293524992_n.jpg (165.52 KiB) Viewed 409 times

dshaw619
Posts: 12
Joined: Thu Jan 04, 2018 7:06 am
Location: San Diego, California, USA

Re: Arduino does not recieve value from raspberry pi

Tue Jul 30, 2019 4:48 am

Should

Code: Select all

 s1.write(z.enocde())
actually be

Code: Select all

 s1.write(z.encode())
?

p.s. It greatly helps to put your code (especially Python which is sensitive to indentation) between code tags (click "Code" on formatting menu when creating your post, then paste in your code).

Bicky
Posts: 5
Joined: Wed Jul 10, 2019 5:24 am

Re: Arduino does not recieve value from raspberry pi

Tue Jul 30, 2019 6:32 am

Sorry , it is encode() in the main program . It still doesn't work .

User avatar
MrYsLab
Posts: 375
Joined: Mon Dec 15, 2014 7:14 pm
Location: Noo Joysey, USA

Re: Arduino does not recieve value from raspberry pi

Tue Jul 30, 2019 3:16 pm

Try:

Code: Select all

s1.write(bytes([ord(data)]))

ghp
Posts: 1409
Joined: Wed Jun 12, 2013 12:41 pm
Location: Stuttgart Germany
Contact: Website

Re: Arduino does not recieve value from raspberry pi

Tue Jul 30, 2019 5:46 pm

Hello, your code is

Code: Select all

	
	        z= str(cx)+'a'		
		s1.write(z.enocde())
What is the range of cx ? Please add

Code: Select all

   	        z= str(cx)+'a'		
		print ("z is", z)
		s1.write(z.enocde())
and give some of the results here. I assume that the byte arrays transferred are something like b"123.4a".

Your arduino code has some problems. (A1) You add an 'a' to the number sent. In arduino, you check for a 'b'. This does not match.
(A2) There is a while loop in the code:

Code: Select all

if (value >= 180 && value <= 400) {
    while (value >= 180 && value <= 400) {
      ...
    }
  }
So if the value goes between 180 and 400, the loop never terminates ?

(A3) Instead of using atof, the atoi function could be more appropriate (when values are integer).
(A4) When values can be float, consider huge values like 34.333333333 which easily extend your 10 byte m-array. This is where in python you should limit the length AND in C you extend the array to say 40 bytes and you limit the length:

Code: Select all

const int LENGTH = 40 ;
char m[LENGTH +1];  // for terminating '\0'

char n;
int i = 0;

void setup() {
  Serial.begin(9600);
}

void loop() {
  if (Serial.available()) {
    n = Serial.read();
    Serial.println("got");
    Serial.println(n);
    
    if (n == 'b') {
      value = atof(m);

      i = 0;
      for ( int k = 0; k < LENGTH +1; k++)
      {
        m[k] = 0;
      }

    }
    else {
      
      if (i < LENGTH){
        m[i] = n;
        i++;
      }
    }
  }
  ...


Last not least: Test your arduino code using the serial monitor.

Good luck !

Edit: you use USB serial (from a PC?) and the serial pins on the arduino in parallel. As there is only one serial on atmel328, this could be a problem. In my projects, I use mostly USB serial only.

Bicky
Posts: 5
Joined: Wed Jul 10, 2019 5:24 am

Re: Arduino does not recieve value from raspberry pi

Wed Jul 31, 2019 10:50 pm

But in Arduino serial.read shows that the Arduino is not receiving any value at all.
It prints -1

ghp
Posts: 1409
Joined: Wed Jun 12, 2013 12:41 pm
Location: Stuttgart Germany
Contact: Website

Re: Arduino does not recieve value from raspberry pi

Thu Aug 01, 2019 4:45 am

The photo shows that you use two serial adapters in parallel,
- a usb to digital from the raspberry
- the usb cable, most possibly to a pc or laptop.
Take a look to the schematics https://content.arduino.cc/assets/UNO-TH_Rev3e_sch.pdf. Both of these inputs go into (TXD)PD1, (RXD)PD0 pins of the processor, decoupled by RN4B, RN4A. Most possibly the digital inputs will win, but you never know unless measuring the levels.

My proposal is:
Step 1: disconnect the wires from the arduino to the usb-digital converter (unpower the assembly first). Then use the serial monitor of your arduino software , set to 9600bd, and type in some values like "123.4b", the 'b' is according to your sketch posted. This should work, you should see the arduino send data back.
Step 2: disconnect the usb cable from arduino, and reconnect to raspberry. Arduino will be powered from raspberry now. Do not start your python code. Use "minicom" with your USB serial device and you should see same behavior as in Step 1. minicom might not be available in your system, install with 'sudo apt-get install minicom'.
Step 3: stop minicom, start your python code. The serial input from arduino into raspberry is not visible, but your arduino should react to the codes sent.
Step 4: You can extend your python code with a thread which reads the data from serial and just prints to console to see the printouts of arduino.

ankith26
Posts: 103
Joined: Mon Mar 25, 2019 11:08 am
Location: Earth
Contact: Website

Re: Arduino does not recieve value from raspberry pi

Fri Aug 09, 2019 3:24 pm

I know i am replying a bit late but i shall try to solve the problem.
try
s.encode('ascii')

You have to tell python to encode data in ascii cos it does it in utf8 by default.
And arduino uses ascii

BTW,
I noticed you are using port /dev/ttyUSB0..
Check whether arduino is on same port.
Cos in my case it has always been /dev/ttyACM0 ...

Why not directly connect arduino to raspberry pi via usb cable.. That will help
Your code appears to have some bugs i can notice..
You would want to also solve those to make your project work
My website is at https://pratt.ml
Hope it runs (which it wont)

ankith26
Posts: 103
Joined: Mon Mar 25, 2019 11:08 am
Location: Earth
Contact: Website

Re: Arduino does not recieve value from raspberry pi

Fri Aug 09, 2019 3:44 pm

Here is some sample code i had used in a project few months ago
This helped me acheive 2 directional messaging.

Arduino side:-

Code: Select all

void setup() {
   Serial.begin(9600); // begin transmission
}
void loop() {
  String val;
  while (Serial.available() > 0) {
    val = val + (char)Serial.read(); // read data byte by byte and store it
  }
  Serial.print(val); // send the received data back to raspberry pi
}
Raspberry side:-

Code: Select all

import serial
port = "/dev/ttyACM0"#put your port here
baudrate = 9600
ser = serial.Serial(port, baudrate)
def tell(msg):
    msg = msg + '\n'
    x = msg.encode('ascii') # encode n send
    ser.write(x)

def hear():
    msg = ser.read_until() # read until a new line
    mystring = msg.decode('ascii')  # decode n return 
    return mystring

while True:
    val = input() # take user input
    tell(val) # send it to arduino
    var = hear() # listen to arduino
    print(var) #print what arduino sent
 
The raspberry pi sends a string, arduino reads it and sends it back to raspberry pi which prints it after reading it.
My website is at https://pratt.ml
Hope it runs (which it wont)

Return to “Python”