Serial communication problem between Arduino and Raspberry PI

I have connected the Arduino MEGA2560 to a Raspberry PI using the USB ports. I am able to send serial commands from the Raspberry PI to Mega2560 without any problem. I am also able to send commands from MEGA2560 to Raspberry PI. Both
boards acknowledge the receipt of the commands.

The problem I have is when the communication is included in a LOOP. In other words Raspberry PI program keeps sending a command and Arduino receives it and then it should send data back to Raspberry PI. The Arduino receives the command but it does not send out the data. If I stop Raspberry PI from sending out serial command then the Arduino is able to send data to Raspberry PI. And Raspberry PI sees the data. It seems that they can not both send and receive data on the serial port. Is this caused because the USB port in half duplex. And I need to use the serial pins on both boards? If so then do I use the TX and RX pins on the GPIO connector of the Raspberry PI.
Thanks

When did you first discover the problem? Sure seems like it was caused by the last changes you made to the program.
Paul

@bahram, your topic has been moved to a more suitable location on the forum.

The problem was there from the beginning. I can send data back and forth if it is only one time. For example when I click on a button.
But if I put the serial communication in a LOOP then all that happens is that the Raspberry PI keeps sending data to Arduino. Arduino sees the command but does not respond back. I also tried to slow it down to once every 5 seconds. It seems that the Raspberry PI has taken control of the USB/Serial port and does not let Arduino to send anything.

Thanks

You have written several time that the Arduino does not write back to the Raspberry PI, but have never told us how you know this to be so.
Paul

Hello
Two reasons.

  1. The Raspberry PI does not display any data.
  2. The TX light on the Mega2560 does not turn on at all.
    Only RX light turns on and blinks because it sees the command coming from Raspberry PI.

But if I stop sending commands from Raspberry PI then Mega2560 will send out data and the TX light blinks and the Raspberry PI receives and displays the data.

I think the problem is that the Raspberry PI takes control of the serial port and does not allow the mega2560 to send out anything.

Another test I did was to stop the Raspberry PI program. Then I open the serial monitor on the Arduino. Then I send a command to Arduino. It successfully sends out data continuously out of the serial port which I can see on the serial monitor. The TX light also starts blinking.
Thanks

Maybe time to show the programs for both the Mega and the Pi. Please don't forget the code tags.

You mean, open serial monitor on the Pi?

as well as code as circuit diagram would be useful
on a recent project I had a Arduino Mega communicating over Serial1 to a raspberry pi using GPIO 15 UART TxD and GPIO 16 UART RxD - using a level shifter to convert the Arduino Mega 5V to 3.3V for the pi

Hello,

I do not open the serial monitor on Raspberry PI. I open serial Monitor on the Arduino to make sure that it does send out the correct data before disabling the serial monitor and running the Raspberry program. There is no drawings or schematics. The Mega2560 is connected to the Raspberry PI using the USB port.

Please note that if I remove this line in the Raspberry program
ser.write(b"temps\n")

Then the Mega2560 send out the data and Raspberry PI sees it.

Here are the programs.

Here is the Arduino code;

const int LED        = 8;

boolean ledON        = 1;

// Initialize All the buttons to on when pushed for the first time.


boolean cabin         = 1; // Cabin Light button

boolean galley        = 1; // Galley light button

  
int tempC;           
  
int tempF;           
int sensorPin = A0;  // Vout from the Analog input 0 on Ardunio
  
int sensorPin1 = A1;  // Vout from the Analog input 0 on Ardunio

String fwdheader = "fwdtmp,";     // The string sent out to Raspberry PI so it knows next is the data (FWD temp)
  
String fwdtmp;                    // final message sent out for AFT temp including its data
  
String aftheader = "afttmp,";     // The string sent out to Raspberry PI so it knows next is the data (AFT temp)
  
String afttmp;                    // final message sent out for AFT temp including its data

  
int FWD_Temp, AFT_Temp;



String command;       // Used to receive commands from Raspberry PI
  



void setup() 
{ 
  // Serial port is used to communicate with the Raspberry PI

 
 Serial.begin(9600);
  
     

	pinMode(22, OUTPUT);
	pinMode(23, OUTPUT);


           
}





void loop() 
{ 
 
        
        


// Read Temperature using Ardunio Analog Input 0 and 1 
        

	tempC = ((5.0 * analogRead(sensorPin) * 100.0) / 1024) + 2;  
	tempF = tempC * 9 / 5 + 32;                                  
	FWD_Temp = tempF;

        

// Send fwd temp to Raspberry PI. Lets first send the word fwdtmp word to Raspberry PI so it know what data is coming in

         fwdtmp = fwdheader + tempF; 
       
        
	 tempC = ((5.0 * analogRead(sensorPin1) * 100.0) / 1024) + 2;
 
        tempF = tempC * 9 / 5 + 32; 
 
        AFT_Temp = tempF ;

         afttmp = aftheader + tempF; 
  
 
          

// Receive Data Commands from Raspberry Pi and execute them

         if (Serial.available())
          
	 {
              

		command = Serial.readStringUntil('\n');
  
              command.trim();


                

		if (command.equals("temps"))

                {

       
             		 Serial.print(fwdtmp);
        
                 Serial.print("\n");    
     
                 
   delay(50);
 
               
          Serial.print(afttmp); 
       
                  Serial.print("\n"); 
        
        }
 


               
 if (command.equals("galley"))

                {
  
                	digitalWrite(22, galley);
  
                	galley = !galley; 
       
         }
                

		if (command.equals("cabin"))

                {
                  

			digitalWrite(23, cabin);
 
                 	cabin = !cabin;
   
                }
 

      delay(100);


          }

  
  
}

Here is the Raspberry Code;

from tkinter import *

import tkinter as tk

from tkinter import colorchooser            


from tkinter.colorchooser import askcolor            



import serial

import time



LARGE_FONT= ("Verdana", 22)



# Establish Serial Communication with Raspberry PI


if __name__ == '__main__':


	ser = serial.Serial('/dev/ttyACM0',9600, timeout=1)
    
	ser.flush()







class CMS(tk.Tk):



    def __init__(self, *args, **kwargs):



        tk.Tk.__init__(self, *args, **kwargs)



        self.overrideredirect(True)



        # Create Windows, Frames


        container = tk.Frame(self)



        container.pack(side="top", fill="both", expand = True)


        container.grid_rowconfigure(0, minsize = 830)


        container.grid_columnconfigure(0, minsize = 1150)





        self.frames = {}




        for F in (StartPage, PageOne, PageTwo, Page3, Page4, Page5, Page6):



            frame = F(container, self)



            self.frames[F] = frame



            frame.grid(row=0, column=0, sticky="nsew")



        self.show_frame(StartPage)



    def show_frame(self, cont):



        frame = self.frames[cont]


        frame.tkraise()



class StartPage(tk.Frame):




    def __init__(self, parent, controller):


        tk.Frame.__init__(self,parent)



        # need to defined the pointers to the images for the buttons to show their image as global variables


        global home_btn

        global cooling_btn



        #images of the buttons


        home_btn = PhotoImage(file='/home/pi/Documents/Bobby/Pictures/Home_On.png')

        cooling_btn = PhotoImage(file='/home/pi/Documents/Bobby/Pictures/Cooling_Off.png')



        home = tk.Button(self, image=home_btn,

                           command=lambda: controller.show_frame(StartPage))


        home.place(x=10, y=745)




        cooling = tk.Button(self, image=cooling_btn,

                           command=lambda: controller.show_frame(Page3))


        cooling.place(x=510, y=745)








class Page3(tk.Frame):



    def __init__(self, parent, controller):



        tk.Frame.__init__(self, parent)



        label = tk.Label(self, text="Cooling", font = "Times 60 bold", fg="AntiqueWhite1", bg="black")

        label.place(x=15, y=40)



        self.configure(bg='black') # background color




         # Display The Temperature value coming from Ardunio and display it

         # Function to communicate with Ardunio and get the FW and AFT temperature


        def Temps():



            # Send out a request to Ardunio to send out the Temperatures

            ser.write(b"temps\n")




            tmp_str = ser.readline().decode()


            # Remove the header 'fwdtmp' or 'afttmp' seperate it from the real data

            tmps = tmp_str.split(',')


            print("Read input back: " + tmp_str)


            #print("tmps =  " + tmps[0])    # This is the header

            #print("tmps1 =  " + tmps[1])   # This is the data
            
	    #Remove carriage reurn from the end of tmp[2] data
            
	    #tmps2 = tmps[1].strip()

            # Now display the correct data for the selected header


            if tmps[0] == "fwdtmp":


                FwdTemp = tk.Label(self, text=tmps2, font = "Times 25 bold", fg="black", bg="AntiqueWhite1")

                FwdTemp.place(x=265, y=340)



            if tmps[0] == "afttmp":



                AftTemp = tk.Label(self, text=tmps2, font = "Times 25 bold", fg="black", bg="AntiqueWhite1")

                AftTemp.place(x=790, y=340)


                # .after command queues tkinter to run the FWD_Temp function every second (1000 msec)


            self.after(1000, Temps)


        Temps()


        # need to defined the pointers to the images for the buttons to show their image as global variables

        # need to rename them because usingthe same names wont show the button images or functions



        global home_btn3

        global cooling_btn3



        #images of the buttons


        home_btn3 = PhotoImage(file='/home/pi/Documents/Bobby/Pictures/Home_Off.png')

        cooling_btn3 = PhotoImage(file='/home/pi/Documents/Bobby/Pictures/Cooling_On.png')


        home = tk.Button(self, image=home_btn3,
                           
				command=lambda: controller.show_frame(StartPage))


        home.place(x=10, y=745)



        cooling = tk.Button(self, image=cooling_btn3,

                           command=lambda: controller.show_frame(Page3))


        cooling.place(x=510, y=745)




app = CMS()



app.mainloop()

Please edit your post, select all Arduino code and click </>. Repeat for the Pi code. Next save your post.

Makes it a lot easier for others to read and copy, thanks.

I got a level Converter and connected the Raspberry PI TX and RX lines on the GPIO connector to Mega2560 RX0 and TX0 pins. I then changed the line of code in the Raspberry PI from

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

to

ser = serial.Serial('/dev/ttyS0',9600, timeout=1)

Now when I run the program the Mega2560 does send out data and the Raspberry pin reads the correct value. So it seems that the problem may be that the USB is being half duplex is the problem.