Advertisement
manni

eli_dataplotting_linux

Jan 21st, 2012
342
1
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.09 KB | None | 1 0
  1.  
  2. To You Eli:
  3.  
  4.  
  5. 1. serialutils.py became like this on Linux:
  6. (haven't figured out conditional coding methods in Python yet)
  7.  
  8. """
  9. Some serial port utilities for Linux and PySerial
  10. Port to Linux by Manni
  11.  
  12. """
  13. import subprocess
  14.  
  15. def full_port_name(portname):
  16. # No name lookup needed on *nix, keep function only for portability
  17. return portname
  18.  
  19. def enumerate_serial_ports():
  20. p = subprocess.Popen('ls /dev/ttyS*', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
  21. l=[]
  22. for line in p.stdout.readlines():
  23. l.append(line.rstrip('\n'))
  24. retval = p.wait()
  25. return l
  26.  
  27.  
  28. if __name__ == "__main__":
  29. import serial
  30. for p in enumerate_serial_ports():
  31. print p, full_port_name(p)
  32.  
  33. -------
  34.  
  35.  
  36. 2. sender_sim.py needs a different port name:
  37.  
  38. port = "/dev/ttySx"
  39.  
  40.  
  41. --------
  42.  
  43. 3. com_monitor.py needs 2 minor modifications to get the timestamps right.
  44. These modifcations might be runnable on Windows as well, I guess, please let us know.
  45.  
  46. add a line somewhere (perhaps last) in def __init__(....):
  47. self.start_time=time.time() # Manni, for Linux
  48.  
  49. and in def run(self):
  50. change timestamp = time.clock()
  51. into
  52. timestamp =time.time()-self.start_time # Manni, for Linux
  53.  
  54.  
  55. To clarify, here is my suggestion for a com_monitor.py in full again.
  56. (Look for the lines with Manni comments)
  57.  
  58. import Queue
  59. import threading
  60. import time
  61.  
  62. import serial
  63.  
  64.  
  65. class ComMonitorThread(threading.Thread):
  66. """ A thread for monitoring a COM port. The COM port is
  67. opened when the thread is started.
  68.  
  69. data_q:
  70. Queue for received data. Items in the queue are
  71. (data, timestamp) pairs, where data is a binary
  72. string representing the received data, and timestamp
  73. is the time elapsed from the thread's start (in
  74. seconds).
  75.  
  76. error_q:
  77. Queue for error messages. In particular, if the
  78. serial port fails to open for some reason, an error
  79. is placed into this queue.
  80.  
  81. port:
  82. The COM port to open. Must be recognized by the
  83. system.
  84.  
  85. port_baud/stopbits/parity:
  86. Serial communication parameters
  87.  
  88. port_timeout:
  89. The timeout used for reading the COM port. If this
  90. value is low, the thread will return data in finer
  91. grained chunks, with more accurate timestamps, but
  92. it will also consume more CPU.
  93. """
  94. def __init__( self,
  95. data_q, error_q,
  96. port_num,
  97. port_baud,
  98. port_stopbits=serial.STOPBITS_ONE,
  99. port_parity=serial.PARITY_NONE,
  100. port_timeout=0.01):
  101. threading.Thread.__init__(self)
  102.  
  103. self.serial_port = None
  104. self.serial_arg = dict( port=port_num,
  105. baudrate=port_baud,
  106. stopbits=port_stopbits,
  107. parity=port_parity,
  108. timeout=port_timeout)
  109.  
  110. self.data_q = data_q
  111. self.error_q = error_q
  112.  
  113. self.alive = threading.Event()
  114. self.alive.set()
  115. self.start_time=time.time() # Manni, for Linux
  116.  
  117. def run(self):
  118. try:
  119. if self.serial_port:
  120. self.serial_port.close()
  121. self.serial_port = serial.Serial(**self.serial_arg)
  122. except serial.SerialException, e:
  123. self.error_q.put(e.message)
  124. return
  125.  
  126. # Restart the clock
  127. time.clock()
  128.  
  129. while self.alive.isSet():
  130. # Reading 1 byte, followed by whatever is left in the
  131. # read buffer, as suggested by the developer of
  132. # PySerial.
  133. #
  134. data = self.serial_port.read(1)
  135. data += self.serial_port.read(self.serial_port.inWaiting())
  136.  
  137. if len(data) > 0:
  138. # timestamp = time.clock() # Windows
  139. timestamp =time.time()-self.start_time # Manni, for Linux
  140. self.data_q.put((data, timestamp))
  141.  
  142. # clean up
  143. if self.serial_port:
  144. self.serial_port.close()
  145.  
  146. def join(self, timeout=None):
  147. self.alive.clear()
  148. threading.Thread.join(self, timeout)
  149.  
  150.  
  151. ------------------------------------------------------------------------------------
  152.  
  153. Instruction to any Linux user:
  154.  
  155. # get socat, software package for serial port emulation/redirection
  156. # use your preferred available package manager, on ubuntu/debian:
  157. sudo apt-get install socat
  158.  
  159. To run:
  160. 1. setup the virtual serial ports
  161. (change myuser to your actual user name to get access to the ports)
  162. sudo socat -d -d PTY,link=/dev/ttySx,user=myuser PTY,link=/dev/ttySy,user=myuser
  163.  
  164. This creates two bidirectional virtual ports and creates symbolic links while the socat-process runs
  165. (Symbolic links makes them easier to refer than /dev/pts/x where x is unknown in advance.)
  166. Keep this process running as long as you run sendersim and dataplotting.
  167.  
  168. 2. edit the data-sending script, sender_sim.py, set the sender portname to:
  169. port = "/dev/ttySx"
  170.  
  171. and start the data-sending script:
  172. python sendersim.py
  173.  
  174.  
  175. 3. start the plotting:
  176. python plotting_data_monitor.pyw
  177. select COM port /dev/ttySy
  178. and start monitoring
  179.  
  180.  
  181. Setup becomes: sendersim.py --> /dev/ttySx --> socat ---> /dev/ttySy dataplotting.py
  182.  
  183.  
  184. ------------------------------------------------------------------------------------
  185.  
  186.  
  187.  
  188. # References:
  189.  
  190. # Emulating serial port communication on Linux
  191. # http://balau82.wordpress.com/2010/06/13/emulating-8051-serial-port-communication-on-linux/
  192.  
  193.  
  194. About the timestamping issue:
  195.  
  196. Python time.clock() on Unices is only for benchmarking of code,
  197. you get used processor time which is not wall time.
  198. On windows wall time seems to be used for benchmarking purposes
  199.  
  200.  
  201. http://docs.python.org/library/time.html :
  202.  
  203. time.clock()
  204.  
  205. On Unix, return the current processor time as a floating point number
  206. expressed in seconds. The precision, and in fact the very definition of the
  207. meaning of processor time , depends on that of the C function of the same
  208. name, but in any case, this is the function to use for benchmarking Python or
  209. timing algorithms.
  210.  
  211. On Windows, this function returns wall-clock seconds elapsed since the
  212. first call to this function, as a floating point number, based on the Win32
  213. function QueryPerformanceCounter(). The resolution is typically better than one
  214. microsecond.
  215.  
  216.  
  217.  
  218. time.time()
  219. Return the time as a floating point number expressed in seconds since the
  220. epoch, in UTC. Note that even though the time is always returned as a floating
  221. point number, not all systems provide time with a better precision than 1
  222. second. While this function normally returns non-decreasing values, it can
  223. return a lower value than a previous call if the system clock has been set back
  224. between the two calls.
  225.  
  226.  
  227.  
  228.  
  229. Best regards,
  230. Manni
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement