Daily Archives: 28 December 2016


papouch: TMU – USB thermometer

Today, we found in stock some USB thermometers by papouch, which we decided to put to use.
We wanted to create a small bash script that would take the measurements from the thermometers and log them along with the system date/time.
After doing some minor research we got to the product website, where it had a lot of useful information about the device, device drivers and source code which can utilize the device on a Windows machine.

Unfortunately for us, there was no source code for a simple bash script on Linux.

Before we continue, lets fill our heads with some information on the device:

TMU is a simple thermometer with a USB interface. The thermometer uses the USB interface for communication and also as a power source. It measures temperatures from –55 °C to +125 °C (with 0.1 °C resolution). The communication utilizes a simple ASCII protocol. Temperature values are transmitted in degrees Celsius; no numerical conversion is necessary.

–From https://www.papouch.com/en/shop/product/tmu-usb-thermometer/

The operating system on our machine was GNU/Linux CentOS 7, after plugging in the devices, we issued the command lsusb from which we saw that the OS had recognized the devices.
From the manual we read that the interface for communication of the device with the computer is implemented via a serial port.
The configuration parameters of the serial port that the device creates were the following:

COMMUNICATION PROTOCOL
TMU cannot receive instructions, it can only send out the temperature values in regular time intervals (approx. 10 seconds).
The temperature is send in a format that is compatible with the Spinel protocol.
The thermometer’s serial line parameters are:

Speed : 9,600 Baud
Number of data bits : 8
Parity : none
Number of stop-bits : 1

— From https://www.papouch.com/en/shop/product/tmu-usb-thermometer/tmu_en.pdf/_downloadFile.php

Since the newly attached devices were USB-to-Serial devices, we knew that they would create ttyUSBx devices in the /dev folder.
Indeed, after checking into the /dev folder, there were two newly created devices ttyUSB0 and ttyUSB1, one for each device.

We tried to connect to the devices using various methods and attempted to redirect the output so that we could parse it.
To our surprise, the data would ‘disappear’ from the pipe…
We could see the data on the screen when we had no pipes following and we could even replace the \r character with \n so that each new information block would appear in a new line. But, whenever we tried to do additional formatting, e.g. remove all characters that are not part of the temperature description, the whole data would vanish..

Our solution

For us process substitution did the trick!
Process substitution feeds the output of a process into the stdin of another process.
We redirected the stdout that was being generated while reading the data from the serial port to another process from where we were able to normally process them.

The following example, reads the data from the serial port, from each line it discards all characters except for characters at the positions 6 until 11 where the temperature information is presented according to the documentation.

sudo sh -c "cat < /dev/ttyUSB0" 1> >(while read line; do echo $line | cut -c6-11; done);

The above command would turn data of this format:

*B1E1+026.0
*B1E1+026.1

To this format:

+026.0
+026.1

And so we could start the development of our script.

Our script

The following script will prepend the current date and time on each line (right before the temperature reading).

 sudo sh -c "cat < /dev/ttyUSB0" 1> >(while read line; do echo $line | cut -c6-11 | xargs -L 1 echo `date`; done); 

Another solution, using miniterm.py

It has come to our attention that some times the thermometers do no work as expected using the cat command.
So, we propose an alternative using miniterm.py.
miniterm.py is a very simple serial terminal and is part of pySerial.

 miniterm.py --echo --eol CR --quiet /dev/ttyUSB0 1> >(while read line; do echo $line | cut -c6-11 | xargs -L 1 echo `date`; done); 

Some details on the format from the manual:

The protocol format is shown in this example.
Example (the data are sent without the space characters from the TMU)

*B1E1+026.1
  • 1 Byte; Prefix: the character *
  • 1 Byte; Format code: the character B
  • 1 Byte; The address of the thermometer: the character 1
  • 2 Bytes; Device instruction code: the characters E1
  • 6 Bytes; Actual temperature value. It can be number from –055.0 to +125.0 or string Err.
    An ASCII string representing the temperature value including the sign. If there is a thermal sensor’s error, the Err string is transmitted.
  • 1 Byte; Terminating character: Carriage Return (Decimal: 13, Hex: 0Dh, Binary: 00001101, Character \r)

 


neural-style-tf: Another open source alternative to Prisma (for advanced users) 1

Recently we stumbled upon another very interesting project, it is called neural-style-tf which is a TensorFlow implementation of an artificial system based on Convolutional neural networks and attempts to separate and combine the content of one image with the style of another.

According to the authors, this tool is based on the following papers

What this tool does is ‘simple’, it takes as input two images, the style image and the content image and using the style image, it tries to recreate the content image in such way that the content image looks like it was created using the same technique as the style image.
Following, is an example of a photograph that was recreated using the style of The Starry Night.

This tool offers a ton of possibilities and options, which we still did not play through yet.
Overall, we are very happy with the initial results we got. The final renderings look really nice and the fact that you get to choose your own style images it gives this tool a very nice advantage.

What we did not like though, is that it takes a lot of time and memory to complete the rendering of a single image (especially if you do not use a GPU to speed up the process).
This issue with the resources is normal and expected, unfortunately though it limits the fun out of the system. Each experiment you make is blocking you for some time and you cannot fiddle with the results in real time.

We installed this tool on an Ubuntu GNU/Linux with success.
Following are the exact commands we used to install it on Ubuntu and convert our first image (the one above).

cd ~;
sudo apt-get install python-pip python-dev;
pip install tensorflow;
pip install tensorflow-gpu;
pip install scipy;
git clone https://github.com/opencv/opencv.git;
cd ~/opencv;
mkdir release;
cd release;
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local ..;
make;
sudo make install;
cd ~;
git clone https://github.com/cysmith/neural-style-tf.git;
cd neural-style-tf/;
wget http://www.vlfeat.org/matconvnet/models/imagenet-vgg-verydeep-19.mat;
#After everything is complete, it is time to create our first 'artistic' image.
python neural_style.py --content_img "/home/bytefreaks/Pictures/Aphrodite Hills Golf Course - Paphos, Cyprus.jpg" --style_imgs "/home/bytefreaks/Pictures/Van_Gogh_-_Starry_Night_-_Google_Art_Project.jpg" --max_size 1250 --max_iterations 1500 --device /cpu:0 --verbose;

Following are the exact commands we used to install it on CentOS 7 (64bit) and convert our first image (the one above).


cd ~;
sudo yum install python-pip cmake;
sudo pip install --upgrade pip;
sudo pip install tensorflow scipy numpy;
git clone https://github.com/opencv/opencv.git;
cd ~/opencv;
mkdir release;
cd release;
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local ..;
make;
sudo make install;
cd ~;
git clone https://github.com/cysmith/neural-style-tf.git;
cd neural-style-tf/;
wget http://www.vlfeat.org/matconvnet/models/imagenet-vgg-verydeep-19.mat;
export PYTHONPATH=$PYTHONPATH:/usr/local/lib/python2.7/site-packages
python neural_style.py --content_img "/home/bytefreaks/Pictures/Aphrodite Hills Golf Course - Paphos, Cyprus.jpg" --style_imgs "/home/bytefreaks/Pictures/Van_Gogh_-_Starry_Night_-_Google_Art_Project.jpg" --max_size 1250 --max_iterations 1500 --device /cpu:0 --verbose;

Our input images were the following:

Content Image

Style Image

Useful links