Yearly Archives: 2016


3GPP Specification #: 25.331 version 14.1.0 – ASN.1 code

Reference: 25.331
Version: 14.1.0
Title: Radio Resource Control (RRC); Protocol specification
Status: Under change control
Type: ASN.1 code for Technical specification (TS)
Initial Planned Release: Release 1999
Radio Technology: 3G
Website: https://portal.3gpp.org/desktopmodules/Specifications/SpecificationDetails.aspx?specificationId=1180
Download ASN.1 File: 3GPP Specification #: 25.331 version 14.1.0 - ASN.1 code (compressed) (256 downloads)

Advertisements

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)

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


neural-style: An open source alternative to Prisma (for advanced users)

Recently we stumbled upon a very interesting project, it is called neural-style which is a torch implementation of an artificial system based on a Deep Neural Network that attempts to create artistic images of high perceptual quality.

According to the authors, this tool is based on the paper of Leon A. Gatys, Alexander S. Ecker and Matthias Bethge which is called “A Neural Algorithm of Artistic Style” (which is available to read for free here).

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 both on a Fedora GNU/Linux and on an Ubuntu with success.
Following are the exact commands we used to install it on Ubuntu and convert our first image (the one above).

cd ~;
git clone https://github.com/torch/distro.git ~/torch --recursive;
cd ~/torch;
bash install-deps;
./install.sh;
source ~/.bashrc;
sudo apt-get install libprotobuf-dev protobuf-compiler;
CC=gcc-5 CXX=g++-5 luarocks install loadcaffe;
luarocks install cutorch
cd ~/
git clone https://github.com/jcjohnson/neural-style.git;
cd neural-style/;
sh models/download_models.sh;
#After everything is complete, it is time to create our first 'artistic' image.
th neural_style.lua -num_iterations 1500 -image_size 1250 -gpu -1 -style_image "/home/bytefreaks/Pictures/Van_Gogh_-_Starry_Night_-_Google_Art_Project.jpg" -content_image "/home/bytefreaks/Pictures/Aphrodite Hills Golf Course - Paphos, Cyprus.jpg"

Our input images were the following:

Content Image

Style Image

Below are the intermediate steps the tool created until it reached the final rendered image.

This slideshow requires JavaScript.

Useful links


C/C++: Full example of reading a whole binary file to buffer

The following example will read a binary in full and store it to a buffer in memory.

Read binary file to memory full example source code (compressed) (244 downloads)

We used the custom structure binary_data_t to store the data information.
This structure stores the pointer to the data and their size.

struct binary_data_t {
  long size;
  void *data;
};

In main.cpp we performed three tests

  1. Reading a file that exists and is not empty
  2. Reading a non-existing file
  3. Reading an empty file

Read binary file to memory full example source code (compressed) (244 downloads)

file_helpers.h

#ifndef GM_S_LITTLE_HELPERS_FILE_HELPERS_H
#define GM_S_LITTLE_HELPERS_FILE_HELPERS_H

#ifdef __cplusplus
extern "C" {
#endif

typedef struct binary_data_t binary_data_t;
struct binary_data_t {
  long size;
  void *data;
};

binary_data_t * read_file(const char *filename);

#ifdef __cplusplus
}
#endif

#endif //GM_S_LITTLE_HELPERS_FILE_HELPERS_H

file_helpers.c

#include <stdio.h>
#include <malloc.h>
#include "file_helpers.h"


//Returns a binary_data_t structure if reading the file was OK.
//In case of an error it always returns NULL.
binary_data_t *read_file(const char *filename) {

  //Allocated our binary data structure
  binary_data_t *binary_data = malloc(sizeof(binary_data_t));
  if (binary_data != NULL) {

    binary_data->size = 0;
    void *buffer = NULL;
    long position;
    //Open the file for reading in binary mode
    FILE *fIn = fopen(filename, "rb");

    if (fIn != NULL) {
      //Go to the end of the file
      const int fseek_end_value = fseek(fIn, 0, SEEK_END);
      if (fseek_end_value != -1) {

        //Get the current position in the file (in bytes)
        position = ftell(fIn);
        if (position != -1) {

          //Go back to the beginning of the file
          const int fseek_set_value = fseek(fIn, 0, SEEK_SET);
          if (fseek_set_value != -1) {

            //Allocate enough space to read the whole file
            buffer = malloc(position);
            if (buffer != NULL) {

              //Read the whole file to buffer
              const long size = fread(buffer, 1, position, fIn);

              if (size == position) {
                binary_data->size = position;
                binary_data->data = buffer;

                fclose(fIn);
                return binary_data;
              }
              free(buffer);
            }
          }
        }
      }
      fclose(fIn);
    }
    free(binary_data);
  }
  return NULL;
}

main.cpp

#include <iostream>
#include "file_helpers.h"

int main(int argc, char *argv[]) {

  //Testing a non-zero sized file
  //read_file() will return a binary_data_t where size will be non zero
  binary_data_t *binary_data_non_zero = read_file(argv[0]);
  //Testing for a non-existing file
  //read_file() will return a NULL pointer
  binary_data_t *binary_data_not_existing = read_file("some file that does not exist...");
  const char * filename = "/tmp/some_empty_file";
  //Creating an empty file
  FILE * fout = fopen(filename, "w");
  fclose(fout);
  //Testing for an empty file
  //read_file() will return a binary_data_t where size will be zero
  binary_data_t *binary_data_empty = read_file(filename);

  return EXIT_SUCCESS;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.6)
project(GM_s_Little_Helpers)

set(CMAKE_CXX_STANDARD 11)

include_directories(${CMAKE_CURRENT_SOURCE_DIR})

set(SOURCE_FILES main.cpp file_helpers.c file_helpers.h)
add_executable(GM_s_Little_Helpers ${SOURCE_FILES})

target_link_libraries(GM_s_Little_Helpers)

Read binary file to memory full example source code (compressed) (244 downloads)