I am trying to write a python script to compile and upload in parallel the same hex file to multiple microcontrollers via Arduino's command line interface.
My script does the following:
- Compile the ino file to a hex file in a particular directory. For example,
- Upload the hex to all /dev/tty.usbXXXXXX.
These are the requirements:
- I would have to be able to upload to multiple /dev/tty.usb* in parallel.
- I want to print all the stdout and stderr from all my subprocess.Popen into my main screen with DEVICE - STDOUT/STDERR - MSG as the format
- I want to save both stdout and stderr from each Popen into its own tty.usb* log file.
Right now i have:
import errno
import os
import re
import subprocess
ARDUINO_EXECUTABLE = '/Applications/Arduino.app/Contents/MacOS/JavaApplicationStub'
HEX_FOLDER_DIR = '/tmp/oyoroi'
LOG_FOLDER_DIR = './logs'
def get_devices():
  """Returns a list of tty.usbXXXXXX
  Make sure you use the USB hub. This will force an extra character in the /dev/tty.usbXXXXXX
  """
  ret = []
  for device in os.listdir('/dev'):
    if re.match('tty.usbmodem[0-9]{6}', device):
      ret.append(device)
  return ret
class Wrapper(object):
  """Wrapper for file objects
  """
  def __init__(self, name, fobject):
    self.name = name
    self.fobject = fobject
  def fileno(self):
    return self.fobject.fileno()
  def flush(self):
    self.fobject.flush()
  def write(self, a_str):
    print self.name, a_str
    self.fobject.write(a_str)
def main(fname):
  """Build once, but upload in parallel
  """
  try:
    os.makedirs(HEX_FOLDER_DIR)
  except OSError as exc:
    if exc.errno == errno.EEXIST and os.path.isdir(HEX_FOLDER_DIR):
      pass
  fname = os.path.abspath(fname)
  # Builds the hex
  command = "%s --verify --pref build.path=%s %s" % (ARDUINO_EXECUTABLE, HEX_FOLDER_DIR, fname)
  print "(Build Command)", command
  proc = subprocess.call(command, shell=True)
  # Make the log directory
  try:
    os.makedirs(LOG_FOLDER_DIR)
  except OSError as exc:
    if exc.errno == errno.EEXIST and os.path.isdir(LOG_FOLDER_DIR):
      # delete folder
      import shutil
      shutil.rmtree(LOG_FOLDER_DIR)
      # and recreate again
      os.makedirs(LOG_FOLDER_DIR)
  # Upload in parallel
  devices = get_devices()
  processes = []
  for device in devices:
    device_path = '/dev/' + device
    log_file_path = os.path.join(LOG_FOLDER_DIR, device + '.log')
    with open(log_file_path, 'a') as logfile:
      command = "%s --upload --pref build.path=%s --port %s %s" % \
                (ARDUINO_EXECUTABLE, HEX_FOLDER_DIR, device_path, fname)
      print "(Upload Command)", command
      wstdout = Wrapper('%_STDOUT', logfile)
      wstderr = Wrapper('%_STDERR', logfile)
      proc = subprocess.Popen(command, shell=True, stdout=wstdout, stderr=wstderr)
      processes.append(proc)
if __name__ == "__main__":
  import sys
  if len(sys.argv) != 2:
    print "python upload.py <.ino>"
    exit(1)
  main(sys.argv[1])
I am able to get what I want in each of the log files, but my terminal is not printing anything on the screen. It's also ending before the other processes are complete.
What am I missing?
 
    