In [3]:
# 19 July 2014

# in case any of this upsets Python purists it has been converted from an equivalent JRuby program

# this is designed to work with ... ArduinoPC2.ino ...

# the purpose of this program and the associated Arduino program is to demonstrate a system for sending 
#   and receiving data between a PC and an Arduino.

# The key functions are:
#    sendToArduino(str) which sends the given string to the Arduino. The string may 
#                       contain characters with any of the values 0 to 255
#
#    recvFromArduino()  which returns an array. 
#                         The first element contains the number of bytes that the Arduino said it included in
#                             message. This can be used to check that the full message was received.
#                         The second element contains the message as a string


# the overall process followed by the demo program is as follows
#   open the serial connection to the Arduino - which causes the Arduino to reset
#   wait for a message from the Arduino to give it time to reset
#   loop through a series of test messages
#      send a message and display it on the PC screen
#      wait for a reply and display it on the PC

# to facilitate debugging the Arduino code this program interprets any message from the Arduino
#    with the message length set to 0 as a debug message which is displayed on the PC screen

# the message to be sent to the Arduino starts with < and ends with >
#    the message content comprises a string, an integer and a float
#    the numbers are sent as their ascii equivalents
#    for example <LED1,200,0.2>
#    this means set the flash interval for LED1 to 200 millisecs
#      and move the servo to 20% of its range

# receiving a message from the Arduino involves
#    waiting until the startMarker is detected
#    saving all subsequent bytes until the end marker is detected

# NOTES
#       this program does not include any timeouts to deal with delays in communication
#
#       for simplicity the program does NOT search for the comm port - the user must modify the
#         code to include the correct reference.
#         search for the lines 
#               serPort = "/dev/ttyS80"
#               baudRate = 9600
#               ser = serial.Serial(serPort, baudRate)
#


#=====================================

#  Function Definitions

#=====================================

def sendToArduino(sendStr):
  ser.write(sendStr)


#======================================

def recvFromArduino():
  global startMarker, endMarker
  
  ck = ""
  x = "z" # any value that is not an end- or startMarker
  byteCount = -1 # to allow for the fact that the last increment will be one too many
  
  # wait for the start character
  while  ord(x) != startMarker: 
    x = ser.read()
  
  # save data until the end marker is found
  while ord(x) != endMarker:
    if ord(x) != startMarker:
      ck = ck + x.decode('ascii')
      byteCount += 1
    x = ser.read()
  
  return(ck)


# ============================

def waitForArduino():

   # wait until the Arduino sends 'Arduino Ready' - allows time for Arduino reset
   # it also ensures that any bytes left over from a previous message are discarded
   
    global startMarker, endMarker
    
    msg = ""
    while msg.find("Arduino is ready") == -1:

        while ser.inWaiting() == 0:
            pass
        
        msg = str(recvFromArduino())

    sendToArduino(1)# confirm that <Arduino is ready> was heard
    print(msg)


# ======================================


def runTest(td):
  numLoops = len(td)
  waitingForReply = False

  n = 0
  while n < numLoops:

    teststr = td[n]

    if waitingForReply == False:
      sendToArduino(teststr)
      print ("Sent from PC -- LOOP NUM " + str(n) + " TEST STR " + teststr)
      waitingForReply = True

    if waitingForReply == True:

      while ser.inWaiting() == 0:
        pass
        
      dataRecvd = recvFromArduino()
      print ("Reply Received  " + dataRecvd)
      n += 1
      waitingForReply = False

      print ("===========")

    time.sleep(5)

#=====================================


def sliceAndWrite(data, targetCsv, writerobject, psiYIntercept, psiCalibration):
    # Slices the data into integers and writes to a row
    csvRow = []
    buffer = ''
    for i in range(len(data)):
        if data[i] != ',':
            buffer += data[i]
        else:
            # csvRow.append((int(buffer)-psiYIntercept)/psiCalibration)
            # else:
            if len(csvRow) == 0:
                csvRow.append((int(buffer)))
                buffer = ''
            else:
                csvRow.append( (int(buffer) - psiYIntercept)/psiCalibration)
                buffer = ''

    with open(outputFileName, 'a') as csvfile:
         writerobject = csv.writer(csvfile, delimiter=',',
                                   quotechar='|', quoting=csv.QUOTE_MINIMAL)
         writerobject.writerow(csvRow)
         print(csvRow)

#======================================

def run():
  # numLoops = len(td)
  waitingForReply = True

  # n = 0
  while True: # n < numLoops:

    # teststr = td[n]

    # if waitingForReply == False:
      # sendToArduino(teststr)
      # print
      # "Sent from PC -- LOOP NUM " + str(n) + " TEST STR " + teststr
      # waitingForReply = True

    if waitingForReply == True:

      while ser.inWaiting() == 0:
        pass

      dataRecvd = recvFromArduino()
      #print("Reply Received  " + dataRecvd)
      sliceAndWrite(dataRecvd, outputFileName,  outputWriter, psiYIntercept, psiCalibration)
      # n += 1
      # waitingForReply = False

      print("===========")

    #time.sleep(5)


# THE DEMO PROGRAM STARTS HERE

#======================================

import serial
import time
import csv

# Create an output file
outputFileName = 'Pintletest'
outputFileName = outputFileName + '.csv'
columnTitleRow = "Time(ms), Omega600, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15"
with open(outputFileName, 'w') as csvfile:
    outputWriter = csv.writer(csvfile, delimiter=' ',
                              quotechar=' ', quoting=csv.QUOTE_MINIMAL)
    outputWriter.writerow(columnTitleRow)


# NOTE the user must ensure that the serial port and baudrate are correct
serPort = "/dev/ttyACM3"
baudRate = 9600
ser = serial.Serial(serPort, baudRate)
print("Serial port " + str(serPort) + " opened  Baudrate " + str(baudRate))

startMarker = 60
endMarker = 62

# Configuration the calibration factors

psiYIntercept, psiCalibration = 166, 0.85555555556

waitForArduino()


# testData = []
# testData.append("<LED1,200,0.2>")
# testData.append("<LED1,800,0.7>")
# testData.append("<LED2,800,0.5>")
# testData.append("<LED2,200,0.2>")
# testData.append("<LED1,200,0.7>")

# runTest(testData)
run()

# ser.close()


---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
<ipython-input-3-9cbdc46d84b9> in <module>()
    199 #======================================
    200 
--> 201 import serial
    202 import time
    203 import csv

ImportError: No module named 'serial'

In [ ]:


In [ ]: