is there a difference in sending a serial command at setup and during loop?

I think the subject says it all. I hava my arduino connected to a raspberry PI. I've got a sketch that sends serial commands to the Pi in the loop which works fine. When I try and send a serial command in the setup portion not all of the command is received by the PI. I would immagine that there shouldn't be any difference between the two right?

Thanks,

Loren

I would immagine that there shouldn't be any difference between the two right?

Right. So, the problem must be somewhere else in the code you didn't post.

Main sketch:

#include <UTFT.h>
#include <UTouch.h>
#include "Comms.h"
#include "Menus.h"


Comms comms;
Menus menus;

int x,y;

char inData[50]; // Allocate some space for the string
char inChar; // Where to store the character read
byte index = 0; // Index into array; where to store the character
boolean incoming = false;
String piStatus = "Waiting";
String piIp;

int statPin =A7;
int inPin = 53;
int val = 0;
int statli = 0;
int pstatli = 0;
int count = 0;

void setup()
{

  Serial.begin(9600);
  Serial1.begin(115200);
  Serial3.begin(9600);

  statli = analogRead(statPin);
  val = digitalRead(inPin);
  if (val==1){
    piStatus ="Booting"; 
  }
  else{
    piStatus = "Off"; 
  }

  menus.initScrn();
  menus.homeScrn();
  pinMode(inPin, INPUT); 




  Serial1.println("ST");
  Serial.println("setup Complete");
  myGLCD.print("Arduino Status:  Ready", LEFT, 14);

}

void loop(){

  count ++;

  menus.countMe(count);
  static char input_line [MAX_INPUT];
  static unsigned int input_pos = 0;

  int pVal = val;
  val = digitalRead(inPin);
  pstatli = statli;

  if((pVal==0) && (val == 1)){
    piStatus ="Booting"; 
    menus.homeScrn();
    Serial.println("Val is now 1");
  } 


  if((pVal==1) && (val == 0)){
    piStatus ="Off"; 
    menus.homeScrn();
    Serial.println("Val is now 0");

  }
  statli = analogRead(statPin);
  menus.updateStatpin(statli);

  /*if(piStatus != "Shutting down"){
   if((val ==1) && (statli ==0)){
   piStatus = "Shutting down"; 
   menus.homeScrn();
   }
   }*/



  if (Serial1.available () > 0) {
    comms.piInit();
  }  // end of incoming data


  if (Serial.available()){
    int inByte = Serial.read();
    Serial1.write(inByte);


  }
  if (Serial3.available()){
    //Serial.print("from remote:  ");
    int inByteT = Serial3.read();
    Serial.write(inByteT);
  }


  menus.touched();
  if(count == 1000){
    Serial.println("1,000");
    count = 0; 
    Serial3.println("$Check@");
  }



}

Menus:

#include "Arduino.h"
#include "Menus.h"


extern UTFT        myGLCD(ITDB32S, 38,39,40,41);   // Remember to change the model parameter to suit your display module!
UTouch      myTouch(6,5,4,3,2);

void Menus::initScrn(){
  // Uncomment the next two lines for the Arduino Mega

  // Setup the LCD
  myGLCD.InitLCD();
  myGLCD.setFont(SmallFont);

  myTouch.InitTouch();
  myTouch.setPrecision(PREC_MEDIUM);


}

void Menus::homeScrn(){
  myGLCD.clrScr();
  mnu = 0;

  myGLCD.setColor(255, 0, 0);
  myGLCD.fillRect(0, 0, 319, 13);
  myGLCD.setColor(64, 64, 64);
  myGLCD.fillRect(0, 226, 319, 240);
  myGLCD.setColor(255, 255, 255);
  myGLCD.setBackColor(255, 0, 0);
  myGLCD.print("* Loren's Operating System *", CENTER, 1);
  myGLCD.setBackColor(64, 64, 64);
  myGLCD.print("Arduino Status:  Setup", LEFT, 14);
  String temp(piStatus);

  myGLCD.print("PI Status:  " + temp, LEFT, 28);
  if (piIp != NULL){
    Serial.println("IP is not null");
    myGLCD.print("Pi IP:  " + piIp, LEFT,42);

  }

  myGLCD.setColor(0,0,255);
  myGLCD.fillRoundRect(10,200,70,230);
  myGLCD.setColor(255,255,255);
  myGLCD.drawRoundRect(10,200,70,230);
  myGLCD.setBackColor(0,0,255);
  myGLCD.print("Menu", 25,210);
}



void Menus::touched(){
  if (myTouch.dataAvailable()){
    myTouch.read();
    x=myTouch.getX();
    y=myTouch.getY();
    //Bottom row
    if ((y>=200) && (y<=240)){
      //first column

      if((x>=10) && (x<=70)){
        if(mnu == 0){
          menuScrn(); 
        }
        else if(mnu ==1){
          homeScrn(); 

        }
      }//first column end

      //second column

        if ((x>=80) && (x<=140)){
        if (mnu == 1){
          Serial1.println("SD");
          Serial.println("shut down");
          piStatus = "Shutting Down";
          mnu = 0;
          homeScrn();
          //delay(50);
        }//end mnu ==1
      }//end second column

        if ((x>=150) && (x<=210)){
        if (mnu == 1){
          Serial1.println("RB");
          Serial.println("Restart");
          piStatus = "Restarting";
          piIp = NULL;
          mnu = 0;
          homeScrn(); 


        }//end mnu ==1
      }//end third column

        if ((x>=220) && (x<=270)){
        if (mnu == 1){
          Serial1.println("VN");
          Serial.println("vnc");
          mnu = 0;
          homeScrn();
          //delay(50);
        }//end mnu ==1
      }//end second column

        delay(75);
    }
  }

}

void Menus::menuScrn(){
  mnu = 1;
  myGLCD.clrScr();

  myGLCD.setColor(255, 0, 0);
  myGLCD.fillRect(0, 0, 319, 13);
  myGLCD.setColor(64, 64, 64);
  myGLCD.fillRect(0, 226, 319, 240);
  myGLCD.setColor(255, 255, 255);
  myGLCD.setBackColor(255, 0, 0);
  myGLCD.print("* Loren's Operating System *", CENTER, 1);


  //Buttons
  myGLCD.setColor(0,0,255);
  myGLCD.fillRoundRect(10,200,70,230);
  myGLCD.setColor(255,255,255);
  myGLCD.drawRoundRect(10,200,70,230);
  myGLCD.setBackColor(0,0,255);
  myGLCD.print("Home", 25,210);

  myGLCD.setColor(0,0,255);
  myGLCD.fillRoundRect(80,200,140,230);
  myGLCD.setColor(255,255,255);
  myGLCD.drawRoundRect(80,200,140,230);
  myGLCD.setBackColor(0,0,255);
  myGLCD.print("Quit", 95,210);

  myGLCD.setColor(0,0,255);
  myGLCD.fillRoundRect(150,200,210,230);
  myGLCD.setColor(255,255,255);
  myGLCD.drawRoundRect(150,200,210,230);
  myGLCD.setBackColor(0,0,255);
  myGLCD.print("Restart", 154,210);

  myGLCD.setColor(0,0,255);
  myGLCD.fillRoundRect(220,200,270,230);
  myGLCD.setColor(255,255,255);
  myGLCD.drawRoundRect(220,200,270,230);
  myGLCD.setBackColor(0,0,255);
  myGLCD.print("VNC", 228,210);
}

void Menus::updateStatpin(int stat){
  String statTemp(stat);
  myGLCD.print("Status pin:  " + statTemp, LEFT, 56);

}

void Menus::countMe(int count){
  String temp(count); 
  myGLCD.print("Count:  " + temp, LEFT, 70);
}

Serial 1 = Raspberry pi
Serial 3 = Arduino Uno via Xbee

Serial1.println("ST"); would call a function on the PI to see if the PI had powered up before the arduino. If nothing is returned then the mega just continues waiting for the Pi to boot. If the PI did start before the mega the command recieved by the pi will then will go through a routine to relay some information to the Arduino.

  Serial1.println("ST");

Even though the PI may be off or booting, you send data, anyway. Then some portion of this two byte stream of data is lost. You didn't think it important to show the PI code, or explain which portion gets lost, but you want us to help you fix it. I doubt that that will happen.

Fair enough...

Here is the python script recieving the commands:

import RPi.GPIO as GPIO
import serial
import os
from subprocess import *

GPIO.setmode(GPIO.BOARD)
print "Setup pin 22"
GPIO.setup(22, GPIO.OUT)
GPIO.output(22, False)
serialport = serial.Serial("/dev/ttyAMA0",115200);
serialport.write("^Power&\n");

cmd = "ip addr show wlan0 | grep inet | awk '{print $2}' | cut -d/ -f1"
def run_cmd(cmd):
        p = Popen(cmd, shell=True, stdout=PIPE)
        output = p.communicate()[0]
        return output

def ret_ip():
        print "returning ip"
        ipaddr = run_cmd(cmd)
        serialport.write("^$wip");
        serialport.write(ipaddr);
        serialport.write("&\n");

while True:
        response = serialport.readline(None);
        response = response[0:2]
        print "response = " + response
        if response == "ip":
                print "if triggered"
                ipaddr = run_cmd(cmd)
                serialport.write("^$wip");
                serialport.write(ipaddr);
                serialport.write("&\n");

        if response == "SD":
                serialport.write("Shutdown recieved\n");
                os.system( "sudo shutdown -h now" )

        if response =="RB":
                serialport.write("reboot command rx")
                os.system("sudo reboot");

        if response == "VN":
                os.system("vncserver :1 -geometry 1300x700 -depth 24")

        if response == ("ST"):
                serialport.write("^Power&\n");

this code returns this:

response =

when the line Serial1.println("ST");
is executed

serialport = serial.Serial("/dev/ttyAMA0",115200);
serialport.write("^Power&\n");

No open? Opening the serial port resets the Arduino.

        response = serialport.readline(None);
        response = response[0:2]

But, the Arduino sent a carriage return and line feed. What does None cause readline() to do?

PaulS:

serialport = serial.Serial("/dev/ttyAMA0",115200);

serialport.write("^Power&\n");




No open? Opening the serial port resets the Arduino.

I forgot to mention that the arduino is powered externally. Serial3 is connected to the PI via GPIO

PaulS:

        response = serialport.readline(None);

response = response[0:2]



But, the Arduino sent a carriage return and line feed. What does None cause readline() to do?

None was part of an example I used. According to http://pyserial.sourceforge.net/shortintro.html the "None" parameter isn't listed as necessary. Its been removed and the python script still behaves the same.

I'll try and be more thorough in my posts in the future.

Because the Arduino is in reset and then the bootloader for a couple seconds after the serial.open, this won't work:

serialport = serial.Serial("/dev/ttyAMA0",115200);
serialport.write("^Power&\n");

This works better for me:

serialport = serial.Serial("/dev/ttyAMA0",115200)
time.sleep(2)
serialport.write("^Power&\n")

-br

billroy:
Because the Arduino is in reset and then the bootloader for a couple seconds after the serial.open, this won't work:

serialport = serial.Serial("/dev/ttyAMA0",115200);

serialport.write("^Power&\n");




This works better for me:


serialport = serial.Serial("/dev/ttyAMA0",115200)
time.sleep(2)
serialport.write("^Power&\n")




-br

Again the arduino mega is externally powered. The PI takes a minute or two to boot. There are two scenarios that could happen.

Scenario 1 (this works fine):

Arduino and PI boot at the same time. The arduino boots in two or three seconds and then sends the line "Serial1.println("ST");" but the PI isn't listening to input from the arduino yet. At the end of the boot sequence the PI runs the python script shown above and sends the information to the Mega.

Scenario 2 (this is what doesn't work):

The arduino gets powered up after the PI or resets for some reason. The mega boots and then sends the line "Serial1.println("ST");" after the PI has completed its boot sequence and the script is waiting for input. That is when I get no response.

Does that make sense????

Again the arduino mega is externally powered.

The power source usually has nothing to do with resetting an arduino. Activity on the serial port causes the arduino to reset. When a pc opens a serial port it sends signals on the rts/dtr setial lines which cause the arduino reset (unless defeated).

zoomkat:

Again the arduino mega is externally powered.

The power source usually has nothing to do with resetting an arduino. Activity on the serial port causes the arduino to reset. When a pc opens a serial port it sends signals on the rts/dtr setial lines which cause the arduino reset (unless defeated).

Even if the mega is connected to the pc via two pins tx & rx on Serial1 via the GPIO?

Even if the mega is connected to the pc via two pins tx & rx on Serial1 via the GPIO?

You would need to check your mega schematic for that answer. As far as I know the reset is associated with the USB serial input to facilitate the arduino programming from the pc.

I added this to the main sketch in the loop to see if see if that would work any differently:

  if ((!connection) && (!attempted)){
    comms.isAnyone();
    attempted = true; 
    Serial.println("attempted to connect");
  }

Here is comms:

#include "Arduino.h"
#include "Comms.h"



void Comms::piInit(){
  static char input_line [MAX_INPUT];
  static unsigned int input_pos = 0;
  if (Serial1.available () > 0) 
  {
    char inByte = Serial1.read ();

    switch (inByte)
    {

    case '\n':   // end of text
      input_line [input_pos] = 0;  // terminating null byte

      // terminator reached! process input_line here ...
      process_data (input_line);

      // reset buffer for next time
      input_pos = 0;  
      break;

    case '\r':   // discard carriage return
      break;

    default:
      // keep adding if not full ... allow for terminating null byte
      if (input_pos < (MAX_INPUT - 1))
        input_line [input_pos++] = inByte;
      break;

    }  // end of switch

  }  // end of incoming data

}

void Comms::process_data (char * data)
{
  byte index = 0;

  // for now just display it
  Serial.println("here comes what was read:  ");
  Serial.println(data);
  int i;

  for (i = 0; i < strlen(data); i++){
    //Looks for the ^ Char
    if(data[i] == 94){
      incoming = true; 
    }// end of if i = ^
    else{

      //Looks for the & Char
      if(data[i] == 38){

      }// end of if i = &

      if((data[i] != 38) && (incoming)){
        inChar = data[i]; // Read a character
        inData[index] = inChar; // Store it
        index++; // Increment where to write next
      }
    }// end of else



  }// end of for
  char tinData[20]; // Allocate some space for the string
  char tinChar; // Where to store the character read
  byte tindex = 0; // Index into array; where to store the character

  String lantemp = String (inData[0]);
  if(lantemp.equals("$")){
    //need to read through inData here to get the IP
    for (i = 0; i < strlen(inData); i++){
      if(i>3){
        tinChar = inData[i]; // Read a character

        tinData[tindex] = tinChar; // Store it
        //Serial.println(tinData[index
        tindex++; // Increment where to write next
      }// end i>3   
    }
    String IP(tinData);
    piIp = IP;
    Serial.print("IP:  ");
    Serial.println(IP);
    myGLCD.print("Pi IP:  " + IP, LEFT,42);
    menus.homeScrn();
  }// end if = $

  String temp = inData;
  Serial.print("String Temp:  ");
  Serial.println(temp);
  if(temp.equals("Power")){
    piStatus = "Ready";
    delay (50);
    Serial1.println("ip");
    menus.homeScrn();
    connection = true;

    //myGLCD.print("PI Status:  "+piStatus, LEFT, 28);
  }//end if inData.equals



  inData[0] = '\0';
  temp = "";
}  // end of process_data


void Comms::serialGack(int port){
  switch(port){
  case 1:

    if (Serial1.available () > 0) {
      char inByte = Serial1.read ();

    }  // end of incoming data

    break;
  case 3: 

    if (Serial3.available () > 0) {
      char inByte = Serial3.read ();
    }
    break;
  }
}

void Comms::isAnyone(){
 Serial1.println("VN");
delay(75); 
}

What baffles me now is that in the Menus library this works:

if ((x>=150) && (x<=210)){
        if (mnu == 1){
          Serial1.println("RB");
          Serial.println("Restart");
          piStatus = "Restarting";
          piIp = NULL;
          mnu = 0;
          homeScrn();

but Serial1.println("ST"); is still not working correctly.