1

I am trying to build a home automation system with Raspberry Pi connected to Arduino Uno via USB. Everything works but the Python script that I am using for reading variables from Arduino is always throwing exception the first time I run it after rebooting Raspberry Pi, so I can't make it start automatically after boot and I always have to have SSH open on my computer in order for it to work.

I am using Python to run C program with the wiringPi library http://wiringpi.com/reference/serial-library/, the C program writes to the serial, Arduino uses switch statement to return the requested data or to do something else (like flashing a LED). The returned data is written in a text file by the C program, which is then sorted in other text files by the Python script.

The interface is PHP displaying the data from the text files and sending commands to Arduino using another C program with the wiringPi library (it is almost the same as the first one).

This is the python script:

#!/usr/bin/python

import datetime
from datetime import datetime
import time
import sys
import os


while 1:
  print "\n" + datetime.now().strftime('%d-%m-%y %H:%M:%S')

  os.system("sudo ./fastUSB.o") #run C program
  fastFile = open("/var/www/fastReader.txt", "r+") #opens the file written from C
  fastValues = fastFile.read(14)
  fastArray = fastValues.split()
  fastFile.close()
  os.remove("/var/www/fastReader.txt") #deletes the file so the old data is removed
  createFastFile = open("/var/www/fastReader.txt", "w") #makes new one
  createFastFile.close()

  try: #puts the array in differen files
    lightCurrent = open("/var/www/current/light.txt", "w")
    lightCurrent.write(fastArray[0])
    lightCurrent.close()
    lightLog = open("/var/www/logs/lightLog.txt", "a")
    lightLog.write(datetime.now().strftime('%d-%m-%y %H:%M:%S') + " - ")
    lightLog.write(fastArray[0] + "\n")
    lightLog.close()
    print "Light level is " + fastArray[0]
  except:
    print "No"

  try:
    motionCurrent = open("/var/www/current/motion.txt", "w")
    motionCurrent.write(fastArray[1])
    motionCurrent.close()
    motionLog = open("/var/www/logs/motionLog.txt", "a")
    motionLog.write(datetime.now().strftime('%d-%m-%y %H:%M:%S') + " - ")
    motionLog.write(fastArray[1] + "\n")
    motionLog.close()
    if fastArray[1] == '1':
      motionState = "detected"
    else:
      motionState = "not detected"
    print "Motion is " + motionState
  except:
    print "No"

This is the C program:

/*
 Pi_Serial_test.cpp - SerialProtocol library - demo
 Copyright (c) 2014 NicoHood.  All right reserved.
 Program to test serial communication

 Compile with:
 sudo gcc -o Pi_Serial_Test.o Pi_Serial_Test.cpp -lwiringPi -DRaspberryPi -pedantic -Wall
 sudo ./Pi_Serial_Test.o
 */

// just that the Arduino IDE doesnt compile these files.
#ifdef RaspberryPi

//include system librarys
#include <stdio.h> //for printf
#include <stdint.h> //uint8_t definitions
#include <stdlib.h> //for exit(int);
#include <string.h> //for errno
#include <errno.h> //error output

//wiring Pi
#include <wiringPi.h>
#include <wiringSerial.h>

// Find Serial device on Raspberry with ~ls /dev/tty*
// ARDUINO_UNO "/dev/ttyACM0"
// FTDI_PROGRAMMER "/dev/ttyUSB0"
// HARDWARE_UART "/dev/ttyAMA0"
char device[]= "/dev/ttyUSB0";
// filedescriptor
int fd;
unsigned long baud = 9600;
int te = 1;

//prototypes
int main(void);
void loop(void);
void setup(void);

void setup(){
  printf("%s \n", "Slow reader");
  fflush(stdout);

  //get filedescriptor
  if ((fd = serialOpen (device, baud)) < 0){
    fprintf (stderr, "Unable to open serial device: %s\n", strerror (errno)) ;
    exit(1); //error
  }

  //setup GPIO in wiringPi mode
  if (wiringPiSetup () == -1){
    fprintf (stdout, "Unable to start wiringPi: %s\n", strerror (errno)) ;
    exit(1); //error
  }

}

void loop() {

  if(te == 1) {
    te = 0;
    serialPuts (fd, "00010\n");
    // you can also write data from 0-255
    // 65 is in ASCII 'A'
    //serialPutchar (fd, 5);
  }

  // read signal
  if(serialDataAvail (fd)){
    char tempChar = serialGetchar (fd);
    FILE * writeTemp = fopen("slowReader.txt", "a");
    printf("%c", tempChar);
    fputc(tempChar, writeTemp);
    fflush(stdout);
    fclose(writeTemp);
    }

  }

// main function for normal c++ programs on Raspberry
int main(){
  setup();
  while(millis()<=1000) loop();
  serialClose(fd);
  return 0;
}

#endif //#ifdef RaspberryPi

When I run the Python script for the first time after reboot it is continuesly throwing the exceptions, then I stop it by pressing Ctrl+Z and when I run it again it is working. I tried stopping it with sudo pkill -f reader.py and it's not fixing it like stopping it with Ctrl+Z. Copying the code after while 1: before the while also doesn't fix it. It has to be stopped manually with Ctrl+Z in order to work.

Sending commands from the site to Arduino is also not working before I run the script for the first time. My guess is that when the script is ran for the first time after boot it is configuring the serial port, baud, etc. but it doesn't make sense to not be able to start, stop, start it automatically.

  • What is the actual error(s) thrown. – Steve Robillard Jan 31 '15 at 22:05
  • It print the line I write after 'except:'. – Vasil Kalchev Jan 31 '15 at 22:21
  • except: print "No" – Vasil Kalchev Jan 31 '15 at 22:22
  • How about printing the actual exception? Maybe just comment out 'try' and 'except'?, and let the Python interpreter print an actual error message. – Frepa Feb 1 '15 at 0:19
  • it says: 'Traceback (most recent call last): File "newUSB.py", line 25, in <module> lightCurrent.write(fastArray[0]) IndexError: list index out of range' – Vasil Kalchev Feb 1 '15 at 2:15
1

It's possible that the Arduino was not detected by the system yet when the script ran. Try to run it after booting has completed.

You can place your script on crontab with the @reboot flag so it runs only after the system has finished booting.

Run crontab -e then add your bootup script as a new line:

@reboot /home/my_username/my.script.py
0

Try to do a flush() of the serial port after setup, this was causing a problem in my (almost) identical problem.

-ben

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.