Difference between revisions of "PySerial Simulator"

From dftwiki3
Jump to: navigation, search
(Implementing the Simulator Module)
(Conclusion)
 
(13 intermediate revisions by the same user not shown)
Line 2: Line 2:
 
----
 
----
 
<bluebox>
 
<bluebox>
The purpose of this tutorial is to illustrate the basic steps required to build a Python module that can be used as a PySerial replacement while developing a Python application that interfaces with an Arduino.  The module presented here supports the basic PySerial functions one needs to call from a Python app to talk to an Arduino, but these functions either do not do anything, or returned canned, predefined data.
+
The purpose of this tutorial is to illustrate the basic steps required to build a Python module that can be used as a PySerial replacement while developing a Python application that interfaces with an Arduino.  The module presented here supports the basic PySerial functions one needs to call from a Python app to talk to an Arduino.  These functions, however, either do not do anything, or return canned and predefined data.
 
</bluebox>
 
</bluebox>
 
+
<br />
 +
<br />
 +
{|
 +
| style="width: 70%; background-color: white;"|
 +
__TOC__
 +
| style="width: 30%; background-color: white;"|
 +
[[File:PySerial.png|right]]
 +
|}
 
<br />
 
<br />
 
<br />
 
<br />
 
=PySerial=
 
=PySerial=
 
<br />
 
<br />
The first examples of a real PySerial program are taken from [http://pyserial.sourceforge.net/shortintro.html http://pyserial.sourceforge.net/shortintro.html], and are reproduced  below:
+
First we look at how the real PySerial module behaves when supporting a Python program that interacts with an Arduino.  We pick several examples from the PySerial documentation.
 +
 
 +
These examples of a real PySerial program are taken from [http://pyserial.sourceforge.net/shortintro.html http://pyserial.sourceforge.net/shortintro.html], and are reproduced  below for completeness:
 
<br />
 
<br />
 
==Example 1==
 
==Example 1==
Line 56: Line 65:
 
</source>
 
</source>
 
<br />
 
<br />
 +
 
=Implementing the Simulator Module=
 
=Implementing the Simulator Module=
 
<br />
 
<br />
 
So, all we have to do is create a module called '''fakeSerial.py''' that will contain  
 
So, all we have to do is create a module called '''fakeSerial.py''' that will contain  
 
# a class called '''Serial()''' that can be initialized with various amount of arguments
 
# a class called '''Serial()''' that can be initialized with various amount of arguments
# a member variable of this class should be called '''name''' and return the name of a port (fictitius)
+
# a member variable of this class should be called '''name''' and return the name of a port.
 
# a method called '''write( )''' which receives a string and passes it to the fake Arduino
 
# a method called '''write( )''' which receives a string and passes it to the fake Arduino
 
# a method called '''read()''' which will read some number of bytes from the Arduino
 
# a method called '''read()''' which will read some number of bytes from the Arduino
 
# a method called '''close()''' that closes the port and  make all further operations with the Arduino impossible.
 
# a method called '''close()''' that closes the port and  make all further operations with the Arduino impossible.
 
# a method called '''isOpen()''' which will return True or False depending on whether the port to the fake Arduino is opened or closed.
 
# a method called '''isOpen()''' which will return True or False depending on whether the port to the fake Arduino is opened or closed.
 +
# a method called '''readline()''' that will return characters until a \n is found.
 
<br />
 
<br />
 
Below is our first attempt at building this module.
 
Below is our first attempt at building this module.
Line 150: Line 161:
 
</source>
 
</source>
 
<br />
 
<br />
 +
 
=Test Program=
 
=Test Program=
 
<br />
 
<br />
Below is our test program that uses the simulator and runs the same tests we illustrated at the top of the page.
+
Below is our test program that uses the simulator and runs the same tests we listed at the top of the page. Note that the output is the same as with a real Arduino!
 
<br />
 
<br />
 
<source lang="python">
 
<source lang="python">
 +
# testSerialSimulator.py
 +
# D. Thiebaut
 +
# This program energizes the fakeSerial simulator using example code taken
 +
# from http://pyserial.sourceforge.net/shortintro.html
 +
#
 +
 +
# import the simulator module (it should be in the same directory as this program)
 
import fakeSerial as serial
 
import fakeSerial as serial
  
 +
# Example 1  from http://pyserial.sourceforge.net/shortintro.html
 
def Example1():
 
def Example1():
 
     ser = serial.Serial(0)  # open first serial port
 
     ser = serial.Serial(0)  # open first serial port
Line 163: Line 183:
 
     ser.close()            # close port
 
     ser.close()            # close port
  
 +
# Example 2  from http://pyserial.sourceforge.net/shortintro.html
 
def Example2():
 
def Example2():
 
     ser = serial.Serial('/dev/ttyS1', 19200, timeout=1)
 
     ser = serial.Serial('/dev/ttyS1', 19200, timeout=1)
Line 173: Line 194:
 
     print( "line = ", line )
 
     print( "line = ", line )
  
 +
# Example 3  from http://pyserial.sourceforge.net/shortintro.html
 
def Example3():
 
def Example3():
 
     ser = serial.Serial()
 
     ser = serial.Serial()
Line 197: Line 219:
 
  0
 
  0
 
  Arduino got: "hello"
 
  Arduino got: "hello"
 +
 
  x =  I
 
  x =  I
 
  s =  t was the  
 
  s =  t was the  
Line 207: Line 230:
  
 
<br />
 
<br />
 +
 +
=Conclusion=
 
<br />
 
<br />
 +
We have developed a module that can be used as an Arduino simulator and that will mimic how an Arduino would respond to various commands.  This simulator is useful for developing Python programs that will eventually communicate with Arduino hardware.  The program won't have to worry about connecting hardware to the development computer until the very last step of the development process. 
 +
 +
With such a simulator the Python program can be quickly developed, debugged, and fine-tuned before connecting to the real thing.  If more sophisticated communication with the Arduino simulator is required, then the '''write()''', '''read()''' and '''readline()''' methods of the simulator can be modified to yield more complex behavior.
 
<br />
 
<br />
 
<br />
 
<br />

Latest revision as of 07:48, 22 May 2014

--D. Thiebaut (talk) 13:45, 21 April 2014 (EDT)


The purpose of this tutorial is to illustrate the basic steps required to build a Python module that can be used as a PySerial replacement while developing a Python application that interfaces with an Arduino. The module presented here supports the basic PySerial functions one needs to call from a Python app to talk to an Arduino. These functions, however, either do not do anything, or return canned and predefined data.



PySerial.png



PySerial


First we look at how the real PySerial module behaves when supporting a Python program that interacts with an Arduino. We pick several examples from the PySerial documentation.

These examples of a real PySerial program are taken from http://pyserial.sourceforge.net/shortintro.html, and are reproduced below for completeness:

Example 1


>>> import serial
>>> ser = serial.Serial(0)  # open first serial port
>>> print ser.name          # check which port was really used
>>> ser.write("hello")      # write a string
>>> ser.close()             # close port


Example 2


>>> ser = serial.Serial('/dev/ttyS1', 19200, timeout=1)
>>> x = ser.read()          # read one byte
>>> s = ser.read(10)        # read up to ten bytes (timeout)
>>> line = ser.readline()   # read a '\n' terminated line
>>> ser.close()


Example 3


>>> ser = serial.Serial(1, 38400, timeout=0,
...                     parity=serial.PARITY_EVEN, rtscts=1)
>>> s = ser.read(100)       # read up to one hundred bytes
...                         # or as much is in the buffer


Example 4


>>> ser = serial.Serial()
>>> ser.baudrate = 19200
>>> ser.port = 0
>>> ser
Serial<id=0xa81c10, open=False>(port='COM1', baudrate=19200, bytesize=8, parity='N', stopbits=1, timeout=None, xonxoff=0, rtscts=0)
>>> ser.open()
>>> ser.isOpen()
True
>>> ser.close()
>>> ser.isOpen()
False


Implementing the Simulator Module


So, all we have to do is create a module called fakeSerial.py that will contain

  1. a class called Serial() that can be initialized with various amount of arguments
  2. a member variable of this class should be called name and return the name of a port.
  3. a method called write( ) which receives a string and passes it to the fake Arduino
  4. a method called read() which will read some number of bytes from the Arduino
  5. a method called close() that closes the port and make all further operations with the Arduino impossible.
  6. a method called isOpen() which will return True or False depending on whether the port to the fake Arduino is opened or closed.
  7. a method called readline() that will return characters until a \n is found.


Below is our first attempt at building this module.

# fakeSerial.py
# D. Thiebaut
# A very crude simulator for PySerial assuming it
# is emulating an Arduino.


# a Serial class emulator 
class Serial:

    ## init(): the constructor.  Many of the arguments have default values
    # and can be skipped when calling the constructor.
    def __init__( self, port='COM1', baudrate = 19200, timeout=1,
                  bytesize = 8, parity = 'N', stopbits = 1, xonxoff=0,
                  rtscts = 0):
        self.name     = port
        self.port     = port
        self.timeout  = timeout
        self.parity   = parity
        self.baudrate = baudrate
        self.bytesize = bytesize
        self.stopbits = stopbits
        self.xonxoff  = xonxoff
        self.rtscts   = rtscts
        self._isOpen  = True
        self._receivedData = ""
        self._data = "It was the best of times.\nIt was the worst of times.\n"

    ## isOpen()
    # returns True if the port to the Arduino is open.  False otherwise
    def isOpen( self ):
        return self._isOpen

    ## open()
    # opens the port
    def open( self ):
        self._isOpen = True

    ## close()
    # closes the port
    def close( self ):
        self._isOpen = False

    ## write()
    # writes a string of characters to the Arduino
    def write( self, string ):
        print( 'Arduino got: "' + string + '"' )
        self._receivedData += string

    ## read()
    # reads n characters from the fake Arduino. Actually n characters
    # are read from the string _data and returned to the caller.
    def read( self, n=1 ):
        s = self._data[0:n]
        self._data = self._data[n:]
        #print( "read: now self._data = ", self._data )
        return s

    ## readline()
    # reads characters from the fake Arduino until a \n is found.
    def readline( self ):
        returnIndex = self._data.index( "\n" )
        if returnIndex != -1:
            s = self._data[0:returnIndex+1]
            self._data = self._data[returnIndex+1:]
            return s
        else:
            return ""

    ## __str__()
    # returns a string representation of the serial class
    def __str__( self ):
        return  "Serial<id=0xa81c10, open=%s>( port='%s', baudrate=%d," \
               % ( str(self.isOpen), self.port, self.baudrate ) \
               + " bytesize=%d, parity='%s', stopbits=%d, xonxoff=%d, rtscts=%d)"\
               % ( self.bytesize, self.parity, self.stopbits, self.xonxoff,
                   self.rtscts )


Test Program


Below is our test program that uses the simulator and runs the same tests we listed at the top of the page. Note that the output is the same as with a real Arduino!

# testSerialSimulator.py
# D. Thiebaut
# This program energizes the fakeSerial simulator using example code taken
# from http://pyserial.sourceforge.net/shortintro.html
#

# import the simulator module (it should be in the same directory as this program)
import fakeSerial as serial

# Example 1  from http://pyserial.sourceforge.net/shortintro.html
def Example1():
    ser = serial.Serial(0)  # open first serial port
    print( ser.name )       # check which port was really used
    ser.write("hello")      # write a string
    ser.close()             # close port

# Example 2  from http://pyserial.sourceforge.net/shortintro.html
def Example2():
    ser = serial.Serial('/dev/ttyS1', 19200, timeout=1)
    x = ser.read()          # read one byte
    print( "x = ", x )
    s = ser.read(10)        # read up to ten bytes (timeout)
    print( "s = ", s )
    line = ser.readline()   # read a '\n' terminated line
    ser.close()
    print( "line = ", line )

# Example 3  from http://pyserial.sourceforge.net/shortintro.html
def Example3():
    ser = serial.Serial()
    ser.baudrate = 19200
    ser.port = 0
    print( ser )
    
    ser.open()
    print( str( ser.isOpen() ) )

    ser.close()
    print( ser.isOpen() )
    

Example1()
Example2()
Example3()


The output of the program is shown below:

0
Arduino got: "hello"

x =  I
s =  t was the 
line =  best of times.

Serial<id=0xa81c10, open=<bound method Serial.isOpen of <fakeSerial.Serial object at 0x102b37ad0>>>( port='0',  baudrate=19200, bytesize=8, parity='N', stopbits=1, xonxoff=0, rtscts=0)
True
False



Conclusion


We have developed a module that can be used as an Arduino simulator and that will mimic how an Arduino would respond to various commands. This simulator is useful for developing Python programs that will eventually communicate with Arduino hardware. The program won't have to worry about connecting hardware to the development computer until the very last step of the development process.

With such a simulator the Python program can be quickly developed, debugged, and fine-tuned before connecting to the real thing. If more sophisticated communication with the Arduino simulator is required, then the write(), read() and readline() methods of the simulator can be modified to yield more complex behavior.