linux - How to read data from serial port SICK LMS200? -


i read data sick lms200 lidar scanner through serial port. can see serial port /dev/ttyusb0. not know how data out of it.

i've tried install the sick lidar matlab/c++ toolbox under ubuntu 14.04.3 lts using manual installation shown in toolbox manual.

i untar file:

$tar -xzvf sicktoolbox-1.0.1.tar.gz 

that's after running ./configure (not sure if it's helpfull)

me@mypc:~/smetiste/sick/sicktoolbox-1.0.1$ ./configure  checking bsd-compatible install... /usr/bin/install -c checking whether build environment sane... yes checking thread-safe mkdir -p... /bin/mkdir -p checking gawk... gawk checking whether make sets $(make)... yes checking g++... g++ checking c++ compiler default output file name... a.out checking whether c++ compiler works... yes checking whether cross compiling... no checking suffix of executables...  checking suffix of object files... o checking whether using gnu c++ compiler... yes checking whether g++ accepts -g... yes checking style of include used make... gnu checking dependency style of g++... gcc3 checking gcc... gcc checking whether using gnu c compiler... yes checking whether gcc accepts -g... yes checking gcc option accept iso c89... none needed checking dependency style of gcc... gcc3 checking how run c preprocessor... gcc -e checking bsd-compatible install... /usr/bin/install -c checking whether ln -s works... yes checking whether make sets $(make)... (cached) yes checking build system type... i686-pc-linux-gnu checking host system type... i686-pc-linux-gnu checking sed not truncate output... /bin/sed checking grep handles long lines , -e... /bin/grep checking egrep... /bin/grep -e checking ld used gcc... /usr/bin/ld checking if linker (/usr/bin/ld) gnu ld... yes checking /usr/bin/ld option reload object files... -r checking bsd-compatible nm... /usr/bin/nm -b checking how recognise dependent libraries... pass_all checking ansi c header files... yes checking sys/types.h... yes checking sys/stat.h... yes checking stdlib.h... yes checking string.h... yes checking memory.h... yes checking strings.h... yes checking inttypes.h... yes checking stdint.h... yes checking unistd.h... yes checking dlfcn.h usability... yes checking dlfcn.h presence... yes checking dlfcn.h... yes checking how run c++ preprocessor... g++ -e checking g77... no checking xlf... no checking f77... no checking frt... no checking pgf77... no checking cf77... no checking fort77... no checking fl32... no checking af77... no checking xlf90... no checking f90... no checking pgf90... no checking pghpf... no checking epcf90... no checking gfortran... no checking g95... no checking xlf95... no checking f95... no checking fort... no checking ifort... no checking ifc... no checking efc... no checking pgf95... no checking lf95... no checking ftn... no checking whether using gnu fortran 77 compiler... no checking whether  accepts -g... no checking maximum length of command line arguments... 32768 checking command parse /usr/bin/nm -b output gcc object... ok checking objdir... .libs checking ar... ar checking ranlib... ranlib checking strip... strip checking if gcc supports -fno-rtti -fno-exceptions... no checking gcc option produce pic... -fpic checking if gcc pic flag -fpic works... yes checking if gcc static flag -static works... yes checking if gcc supports -c -o file.o... yes checking whether gcc linker (/usr/bin/ld) supports shared libraries... yes checking whether -lc should explicitly linked in... no checking dynamic linker characteristics... gnu/linux ld.so checking how hardcode library paths programs... immediate checking whether stripping libraries possible... yes checking if libtool supports shared libraries... yes checking whether build shared libraries... yes checking whether build static libraries... yes configure: creating libtool appending configuration tag "cxx" libtool checking ld used g++... /usr/bin/ld checking if linker (/usr/bin/ld) gnu ld... yes checking whether g++ linker (/usr/bin/ld) supports shared libraries... yes checking g++ option produce pic... -fpic checking if g++ pic flag -fpic works... yes checking if g++ static flag -static works... yes checking if g++ supports -c -o file.o... yes checking whether g++ linker (/usr/bin/ld) supports shared libraries... yes checking dynamic linker characteristics... gnu/linux ld.so checking how hardcode library paths programs... immediate appending configuration tag "f77" libtool checking gnuplot... no configure: warning: *** gnuplot not found, examples not built. checking doxygen... no configure: warning: doxygen not found - not generate doxygen documentation checking perl... /usr/bin/perl checking pthreads library -lpthreads... no checking whether pthreads work without flags... no checking whether pthreads work -kthread... no checking whether pthreads work -kthread... no checking pthreads library -llthread... no checking whether pthreads work -pthread... yes checking joinable pthread attribute... pthread_create_joinable checking if more special flags required pthreads... no checking ansi c header files... (cached) yes checking arpa/inet.h usability... yes checking arpa/inet.h presence... yes checking arpa/inet.h... yes checking fcntl.h usability... yes checking fcntl.h presence... yes checking fcntl.h... yes checking netinet/in.h usability... yes checking netinet/in.h presence... yes checking netinet/in.h... yes checking string.h... (cached) yes checking sys/ioctl.h usability... yes checking sys/ioctl.h presence... yes checking sys/ioctl.h... yes checking sys/socket.h usability... yes checking sys/socket.h presence... yes checking sys/socket.h... yes checking sys/time.h usability... yes checking sys/time.h presence... yes checking sys/time.h... yes checking termios.h usability... yes checking termios.h presence... yes checking termios.h... yes checking unistd.h... (cached) yes checking linux/serial.h usability... yes checking linux/serial.h presence... yes checking linux/serial.h... yes checking stdbool.h conforms c99... yes checking _bool... yes checking ansi c-conforming const... yes checking inline... inline checking whether byte ordering bigendian... no checking whether time.h , sys/time.h may both included... yes checking int16_t... yes checking uint16_t... yes checking uint32_t... yes checking uint8_t... yes checking whether gcc needs -traditional... no checking sys/select.h usability... yes checking sys/select.h presence... yes checking sys/select.h... yes checking sys/socket.h... (cached) yes checking types of arguments select... int,fd_set *,struct timeval * checking return type of signal handlers... void checking gettimeofday... yes checking memset... yes checking select... yes checking socket... yes checking strcasecmp... yes configure: creating ./config.status config.status: creating makefile config.status: creating c++/makefile config.status: creating c++/examples/makefile config.status: creating c++/examples/ld/makefile config.status: creating c++/examples/ld/ld_config/makefile config.status: creating c++/examples/ld/ld_config/src/makefile config.status: creating c++/examples/ld/ld_more_config/makefile config.status: creating c++/examples/ld/ld_more_config/src/makefile config.status: creating c++/examples/ld/ld_multi_sector/makefile config.status: creating c++/examples/ld/ld_multi_sector/src/makefile config.status: creating c++/examples/ld/ld_single_sector/makefile config.status: creating c++/examples/ld/ld_single_sector/src/makefile config.status: creating c++/examples/lms/makefile config.status: creating c++/examples/lms/lms_config/makefile config.status: creating c++/examples/lms/lms_config/src/makefile config.status: creating c++/examples/lms/lms_mean_values/makefile config.status: creating c++/examples/lms/lms_mean_values/src/makefile config.status: creating c++/examples/lms/lms_partial_scan/makefile config.status: creating c++/examples/lms/lms_partial_scan/src/makefile config.status: creating c++/examples/lms/lms_plot_values/makefile config.status: creating c++/examples/lms/lms_plot_values/src/makefile config.status: creating c++/examples/lms/lms_real_time_indices/makefile config.status: creating c++/examples/lms/lms_real_time_indices/src/makefile config.status: creating c++/examples/lms/lms_set_variant/makefile config.status: creating c++/examples/lms/lms_set_variant/src/makefile config.status: creating c++/examples/lms/lms_simple_app/makefile config.status: creating c++/examples/lms/lms_simple_app/src/makefile config.status: creating c++/examples/lms/lms_stream_range_and_reflect/makefile config.status: creating c++/examples/lms/lms_stream_range_and_reflect/src/makefile config.status: creating c++/examples/lms/lms_subrange/makefile config.status: creating c++/examples/lms/lms_subrange/src/makefile config.status: creating c++/drivers/makefile config.status: creating c++/drivers/ld/makefile config.status: creating c++/drivers/ld/sickld-1.0/makefile config.status: creating c++/drivers/lms/makefile config.status: creating c++/drivers/lms/sicklms-1.0/makefile config.status: creating c++/drivers/base/src/sickconfig.hh config.status: executing depfiles commands 

after running $make error:

me@ mypc:~/smetiste/sick/sicktoolbox-1.0.1$ make making in c++ make[1]: entering directory `/home/me/smetiste/sick/sicktoolbox-1.0.1/c++' making in drivers make[2]: entering directory `/home/me/smetiste/sick/sicktoolbox-1.0.1/c++/drivers' making in ld make[3]: entering directory `/home/me/smetiste/sick/sicktoolbox-1.0.1/c++/drivers/ld' making in sickld-1.0 make[4]: entering directory `/home/me/smetiste/sick/sicktoolbox-1.0.1/c++/drivers/ld/sickld-1.0' /bin/sh ../../../../libtool --tag=cxx   --mode=compile g++ -dhave_config_h -i. -i../../../../c++/drivers/base/src  -i../../../../c++/drivers/base/src   -g -o2 -mt sickld.lo -md -mp -mf .deps/sickld.tpo -c -o sickld.lo sickld.cc mkdir .libs  g++ -dhave_config_h -i. -i../../../../c++/drivers/base/src -i../../../../c++/drivers/base/src -g -o2 -mt sickld.lo -md -mp -mf .deps/sickld.tpo -c sickld.cc  -fpic -dpic -o .libs/sickld.o sickld.cc: in member function 'void sicktoolbox::sickld::_flushtcprecvbuffer()': sickld.cc:4137:35: warning: ignoring return value of 'ssize_t read(int, void*, size_t)', declared attribute warn_unused_result [-wunused-result]         read(_sick_fd,&null_byte,1);                                    ^  g++ -dhave_config_h -i. -i../../../../c++/drivers/base/src -i../../../../c++/drivers/base/src -g -o2 -mt sickld.lo -md -mp -mf .deps/sickld.tpo -c sickld.cc -o sickld.o >/dev/null 2>&1 mv -f .deps/sickld.tpo .deps/sickld.plo /bin/sh ../../../../libtool --tag=cxx   --mode=compile g++ -dhave_config_h -i. -i../../../../c++/drivers/base/src  -i../../../../c++/drivers/base/src   -g -o2 -mt sickldmessage.lo -md -mp -mf .deps/sickldmessage.tpo -c -o sickldmessage.lo sickldmessage.cc  g++ -dhave_config_h -i. -i../../../../c++/drivers/base/src -i../../../../c++/drivers/base/src -g -o2 -mt sickldmessage.lo -md -mp -mf .deps/sickldmessage.tpo -c sickldmessage.cc  -fpic -dpic -o .libs/sickldmessage.o  g++ -dhave_config_h -i. -i../../../../c++/drivers/base/src -i../../../../c++/drivers/base/src -g -o2 -mt sickldmessage.lo -md -mp -mf .deps/sickldmessage.tpo -c sickldmessage.cc -o sickldmessage.o >/dev/null 2>&1 mv -f .deps/sickldmessage.tpo .deps/sickldmessage.plo /bin/sh ../../../../libtool --tag=cxx   --mode=compile g++ -dhave_config_h -i. -i../../../../c++/drivers/base/src  -i../../../../c++/drivers/base/src   -g -o2 -mt sickldbuffermonitor.lo -md -mp -mf .deps/sickldbuffermonitor.tpo -c -o sickldbuffermonitor.lo sickldbuffermonitor.cc  g++ -dhave_config_h -i. -i../../../../c++/drivers/base/src -i../../../../c++/drivers/base/src -g -o2 -mt sickldbuffermonitor.lo -md -mp -mf .deps/sickldbuffermonitor.tpo -c sickldbuffermonitor.cc  -fpic -dpic -o .libs/sickldbuffermonitor.o in file included sickldbuffermonitor.hh:24:0,                  sickldbuffermonitor.cc:24: ../../../../c++/drivers/base/src/sickbuffermonitor.hh: in member function 'void sicktoolbox::sickbuffermonitor<sick_monitor_class, sick_msg_class>::_readbytes(uint8_t*, int, unsigned int) const': ../../../../c++/drivers/base/src/sickbuffermonitor.hh:356:47: error: there no arguments 'getdtablesize' depend on template parameter, declaration of 'getdtablesize' must available [-fpermissive]        num_active_files = select(getdtablesize(),&file_desc_set,0,0,(timeout_value > 0) ? &timeout_val : 0);                                                ^ ../../../../c++/drivers/base/src/sickbuffermonitor.hh:356:47: note: (if use '-fpermissive', g++ accept code, allowing use of undeclared name deprecated) ../../../../c++/drivers/base/src/sickbuffermonitor.hh:370:73: error: there no arguments 'read' depend on template parameter, declaration of 'read' must available [-fpermissive]       num_bytes_read = read(_sick_fd,&dest_buffer[total_num_bytes_read],1);                                                                          ^ ../../../../c++/drivers/base/src/sickbuffermonitor.hh: in static member function 'static void* sicktoolbox::sickbuffermonitor<sick_monitor_class, sick_msg_class>::_buffermonitorthread(void*)': ../../../../c++/drivers/base/src/sickbuffermonitor.hh:456:18: error: there no arguments 'usleep' depend on template parameter, declaration of 'usleep' must available [-fpermissive]        usleep(1000);                   ^ ../../../../c++/drivers/base/src/sickbuffermonitor.hh: in instantiation of 'void sicktoolbox::sickbuffermonitor<sick_monitor_class, sick_msg_class>::_readbytes(uint8_t*, int, unsigned int) const [with sick_monitor_class = sicktoolbox::sickldbuffermonitor; sick_msg_class = sicktoolbox::sickldmessage; uint8_t = unsigned char]': sickldbuffermonitor.cc:59:2:   required here ../../../../c++/drivers/base/src/sickbuffermonitor.hh:356:47: error: 'getdtablesize' not declared in scope        num_active_files = select(getdtablesize(),&file_desc_set,0,0,(timeout_value > 0) ? &timeout_val : 0);                                                ^ ../../../../c++/drivers/base/src/sickbuffermonitor.hh:370:73: error: 'read' not declared in scope       num_bytes_read = read(_sick_fd,&dest_buffer[total_num_bytes_read],1);                                                                          ^ make[4]: *** [sickldbuffermonitor.lo] error 1 make[4]: leaving directory `/home/me/smetiste/sick/sicktoolbox-1.0.1/c++/drivers/ld/sickld-1.0' make[3]: *** [all-recursive] error 1 make[3]: leaving directory `/home/me/smetiste/sick/sicktoolbox-1.0.1/c++/drivers/ld' make[2]: *** [all-recursive] error 1 make[2]: leaving directory `/home/me/smetiste/sick/sicktoolbox-1.0.1/c++/drivers' make[1]: *** [all-recursive] error 1 make[1]: leaving directory `/home/me/smetiste/sick/sicktoolbox-1.0.1/c++' make: *** [all-recursive] error 1 me@ mypc:~/smetiste/sick/sicktoolbox-1.0.1$  

i've heard using "old" packages newer releases may tricky. there chance make work?

is there other way how data scanner on linux since doesn't have internal memory?

the protocol relatively straightforward , well documented. don't daunted size of documentation, practical use need small subset (commands 10h,20hand responses 90h,91h,92h,b0h start with).

here's little python script should started:

import binascii import serial import threading  # =============================================================================  serial_port = 'com6' # nb: different crystal, x8 multiplier serial_baudrate = int(500000 * 14745600 / 16000000 / 8) serial_timeout = 1  # =============================================================================  def lms200_crc(data):   crc16 = 0   byte = [0,0]   c in data:     byte[1] = byte[0]     byte[0] = ord(c)      if (crc16 & 0x8000):       crc16 = (crc16 & 0x7fff) << 1       crc16 ^= 0x8005     else:       crc16 = crc16<< 1      crc16 ^= (byte[1] << 8) | byte[0]    return crc16  # =============================================================================  class lms200telegram(object):   def __init__(self, data=none):     if data:       if len(data) < 7:         raise runtimeerror("invalid telegram size")       if data[0] != '\x02':         raise runtimeerror("invalid stx")       self.address = ord(data[1])       self.length = ord(data[2]) + (ord(data[3]) * 256)       self.payload = data[4:-2]       self.crc = ord(data[-2]) + (ord(data[-1]) * 256)     else:       self.address = 0       self.length = 0       self.payload = ''       self.crc = 0    def generate(self):     data = '\x02' + chr(self.address)     self.length = len(self.payload)     data += chr(self.length & 0xff)     data += chr((self.length >> 8) & 0xff)     data += self.payload     self.crc = lms200_crc(data)     data += chr(self.crc & 0xff)     data += chr((self.crc >> 8) & 0xff)     return data  class lms200command(object):   def __init__(self, payload):     if len(payload) < 1:       raise runtimeerror("invalid payload size")     self.opcode = ord(payload[0])     self.body = payload[1:]  class lms200response(object):   def __init__(self, payload):     if len(payload) < 2:       raise runtimeerror("invalid payload size")     self.opcode = ord(payload[0])     self.status = ord(payload[-1])     self.body = payload[1:-1]  # =============================================================================  def cmd_reset_sensor():   t = lms200telegram()   t.payload = '\x10'   return t  def cmd_start_measurement():   t = lms200telegram()   t.payload = '\x20\x20'   return t  # =============================================================================  class lms200interface(object):   def __init__(self, port, baudrate, timeout):     self.port = port     self.baudrate = baudrate     self.timeout = timeout     self.serial = none     self.serial_rlock = threading.lock()     self.serial_wlock = threading.lock()     self.buffer = []    def open_port(self):     self.serial = serial.serial(port=self.port       , baudrate=self.baudrate       , timeout=self.timeout)    def close_port(self):     self.serial.close()     self.serial = none    def process_data(self, data):     self.buffer += data    def write_telegram(self, t):     self.serial.flush()     self.serial_wlock:       self.serial.write(t.generate())     self.serial_rlock:       while true:         ack = self.serial.read(1)         if len(ack) > 0:           if ack == '\x06':             return true           elif ack == '\x15':             return false           else:             raise runtimeerror("invalid value received (neither ack, nor nack)")    def worker(self):     if not self.serial:       raise runtimeerror("serial port not initialized.")      print "reading serial port '%s'..." % self.port      while(not self.stop_flag):       data = self.serial.read(1024)       if len(data) > 0:         print "got %d bytes." % len(data)         self.process_data(data)    def run(self):     lms.open_port()     self.thread = threading.thread(target=self.worker)     self.stop_flag = false     self.thread.start()    def stop(self):     self.stop_flag = true     self.thread.join()     lms.close_port()  # =============================================================================  lms = lms200interface(serial_port, serial_baudrate, serial_timeout)  lms.run() 

you'd still need extend process_data method to:

  • detect , separate individual telegram frames.
    • simplest way find occurrences of stx byte. address byte constant, can search e.g. 0x02 0x80. can validation of length. try read payload, , see if crcs match.
  • when identify telegram, need parse payload.
    • identify payload type command/response byte.
    • interpret payload using python struct module.
  • handle measured data need. exact form depend on measurement mode. example in basic measurement mode, have array of 361 16bit distances in mm, taken in 0.5 degree steps. need mask out flags stored in significant bits, , handle special values represent error conditions.

i haven't implemented in script, since written basic communication tests when had compatibility issues our serial cards.


Comments

Popular posts from this blog

resizing Telegram inline keyboard -

command line - How can a Python program background itself? -

php - "cURL error 28: Resolving timed out" on Wordpress on Azure App Service on Linux -