Showing posts with label programming. Show all posts
Showing posts with label programming. Show all posts

Hat for Raspberry Pi to monitor environmental conditions (my sandbox for learning modern DevOps tools).

It’s 2024, and technologies from web development have made their way into the embedded world too-things like containerization, automated deployment, and more. This project is a small hat for the Raspberry Pi that gathers measurements for temperature, humidity, and air pressure. I created it as a learning tool to explore these concepts while using Docker, Ansible, and Grafana.

The picture below shows the hat. I thought it was so simple that I wouldn't make any mistakes during assembly, but, as usual, I did. The PCB turned out to be too long and collides with the USB port of the Raspberry Pi. That’s why I had to connect it using jumper wires. It works, but it doesn’t look very cool.

I didn’t choose these sensors for any particular reason—they were just parts I had on hand from the good pre-COVID times when software components and sensors were still cheap :)

The circuit is shown below. It consists of two sensors that communicate via I2C with the Raspberry Pi, along with a small LCD that also uses I2C. The LCD displays the measurement data as well.

Some people say that if your Raspberry Pi starts slowing down, it’s a sign that the SD card is about to fail, so it’s time to back up. I noticed mine was slowing down, checked the kernel logs, and everything looked fine, so I figured I was safe. The next day, the SD card was dead. So yeah, it’s definitely a good idea to back up in such cases.

This happened before I got into Docker and all the containerization stuff, so I was just developing scripts directly on the Raspberry Pi—and I think I lost them. It’s funny how I started this project to learn about containerization as a reliable way to deploy code, and I kicked things off with such a fail!

From the software point of view, the project will consist of three components:

  • Python software for gathering data from the sensors
  • InfluxDB for storing the measurements
  • Grafana for data analysis and presentation

I think each of these components will have its own Docker container. In addition, I’ve already created a Docker container for cross-compilation (since my PC has x86 architecture and the Raspberry Pi uses ARM architecture). It was quite a struggle to get that working. I plan to automate the installation using Ansible.

If you’re interested in the details, the full project is available on GitHub and Hackaday. Feel free to explore, make your own modifications, and maybe even improve on what I’ve done. And if you find it useful, don’t forget to share it!

Hardware Data Logger based on STM32 Nucleo and ESP Module

It's been a while since I last posted here, but here I am with something new. This project started when I was cleaning up the repo for a semiconductor radioactivity detector. For that project, I made a small shield for the STM32 Nucleo that included a button and a display.

It was used to present measurements in real time on the display and send them to a Raspberry Pi for further processing. I thought this could be turned into a separate project and reused, and I'll be presenting the results of that in this post. Here is the link to the GitHub of this new project that I describe in this post.

I started working on a new version and came up with these specs:

  • Keep the STM32 Nucleo as the main microcontroller
  • Add an ESP module for remotely uploading data to a Raspberry Pi or any other device
  • Use a much larger color display
  • Include four buttons for interacting with the device
  • Add 4 BNC connectors for gathering data from other devices
  • Include an SD card slot for local data storage
  • It also has a light sensor to dim the display at night.

The picture below shows the version that includes these specifications. Fun fact is that I traveled with this device in my carry-on luggage and was worried there might be issues at security, since it kind of looks like a movie bomb, but everything went fine.

Based on the that version, I created a dedicated PCB. I thought assembling the PCB would be pretty simple, but unfortunately, I forgot to buy all the components, which made it much harder than I expected. In this version, I used SMD female pins to connect to the Nucleo board. However, since I didn't have them on hand, I used THT pins instead. The footprint was different, and I didn’t solder them well, which put a lot of stress on the Nucleo board when connecting the shield.

It kept breaking repeatedly, and I didn’t expect such a small issue to cause so many problems. The LCD no longer works—probably something broke again—but the rest of the setup is functioning. In this version, the STM and ESP communicate with each other, but only in a limited way.

The device was designed in KiCad, and the circuit is shown below.

The firmware was developed using STM32CubeMX (for peripheral configuration), CMake, and C++17. I didn’t use anything from the standard library or dynamic memory allocation.

I’ve also included several tools for checking code quality: unit tests (Google Test, Google Mock), code coverage, static code analysis (cppcheck), and even dynamic code quality checks (which don’t make much sense in my case since I explicitly avoid using dynamic memory allocation, but I wasn’t thinking about that at the time). There are also Doxygen comments and coverage reports to flag any missing documentation.

I used ChatGPT (paid version) for most of this configuration. It’s amazing but can also help you quickly generate garbage. It speeds things up when you're headed in the right direction, but if you're doing something silly, it will just help you do it faster. You can check out how the CMake files are written in this project to get an idea of what I mean.

The current version is not finished, and I think I’ll abandon it in favor of a new version. I plan to drop the Nucleo board and place the STM chip directly on the PCB. This will solve the connector issues and make the device smaller and cheaper.

Another idea I have is to use some slots (similar to the ones used for connecting RAM to a PC motherboard, though I haven’t researched the names or footprints yet). This way, I could have one main PCB with the STM, ESP, display, etc., and use detachable boards for acquisition modules.

This is just the beginning, and there’s plenty of room for improvement. If you're curious to see where it goes, don't forget to watch or star the project on GitHub!

Collecting data from measurements devices using USBTMC, SCPI, Python and R

High end test gear allows two-way communication with PC to set measurement parameters and to send the measured data to PC for further analyze. On PC side there are applications for this (LabView, BenchVue), but they are expensive. One option is to make own program/script that will communicate with the device and parse/present measured data - this approach I will present it in this post. The tool I'm using it with is 34460A(digital multimeter).

Below is an example of the measurement graph made using this home-made software.

The module of communication with the device I made in Python, it stores data to .csv file, that is later parsed by a script in R and the output graph is stored as .png image. The R part could ass well do some numeric stuff and print it on STDOUT, but for me that was not the case.

Initially all was in Python, but I didn't like Python's graphs, they weren't visually nice.

Python part when started will save measurements to the .csv file constantly, at any time, user can run R script to create new graph.

Installation steps

Assuming device driver correctly enumerate in the Device Manager (if not one needs to install its drivers first).

  • Install Python and R, add them to Path (environment variable).
  • In R, install following packages: latticeExtra, gridExtra, grid.
  • In Python install following packages: usbtmc, pyusb.
  • On Windows, download libusb-win32 and follow README steps to bind it to the device. In addition it didn't work for me if I didn't run the tool as an Administrator. If everything went ok, device will be visible in Device Manager in branch named libusb-win32 devices.
  • Download Python/R scripts, they are available via my IonizationChamber repository.
  • In main.py, replace idDMM with id of the device.

For usbtmc, I got the same problem as described here, fortunately the fix presented in that thread fixed it, so please check it if you have some weird stacktrace errors in Python.

Usage

I made those scripts for my personal use, so they may be a bit awkward to work with, but once the setup is done, everything should work fine.

  • Set meassurement type and range on your device (this could be also done via python script)
  • Start python script
  • Run R script, it will create results.png file with graphs.

That's all.

How to check how many elements an array has?

In C it's possible to omit typing array size if it's fields are provided immediately, so the compiler can easily calculate the size by itself. This is presented below, note empty [] parenthesis.

    char* sampleArray[] = {
        "Hello world!",
        "How are you?",
        "You like coffe?"
    };

We can also specify the size directly:

    char* sampleArray[2] = {
        "Hello world!",
        "How are you?",
        "You like coffe?"
    };

Or use the best way:

    const int SampleArraySize = 2;

    char* sampleArray[SampleArraySize] = {
        "Hello world!",
        "How are you?",
        "You like coffe?"
    };

In the first two examples we don't have a variable that would tell us how many elements the array has. Sure, we may hardcode it, but it's not a good idea from a maintainability point of view.

We may calculate the size of above array by using a simple trick:

int sampleArrayLength = sizeof(sampleArray) / sizeof(sampleArray[0]);

Note that it will work with all built in types and if the size or even the type of an array will be changed in the future, this line will still be correct.

Below you may see a simple use case.

#include <stdio.h>


int main()
{
    char* sampleArray[] = {
        "Hello world!",
        "How are you?",
        "You like coffe?"
    };

    int sampleArrayLength = sizeof(sampleArray) / sizeof(sampleArray[0]);

    printf("someStrings array has %d  elments counting from one.\n", sampleArrayLength);

    for(int i = 0U; i < sampleArrayLength; i++)
    {
        printf("#%d element: %s\n", i, sampleArray[i]);
        
    }
    
    return 0;
}
sh-4.3$ main                                                                                                                                                                                                                                            
someStrings array has 3  elments counting from one.                                                                                                                                                                                                     
#0 element: Hello world!                                                                                                                                                                                                                                
#1 element: How are you?                                                                                                                                                                                                                                
#2 element: You like coffe?

Unfortunately, it will not work for arrays passed as pointers - for them, we need to pass size of an array as an additional argument.

How to check how many elements an enum has?

While C language doesn't offer build in method to check how many elements an enum has, it's still possible to obtain this information by using a simple trick.

The idea is to add a dummy element at the very end, since numeric enums values are 0, 1, 2, 3, 4, 5, ..., the numeric value of last element will be also the amount of elements that this enum has.

#include <stdio.h>

typedef enum Fruit {
    FRUIT_APPLE,
    FRUIT_ORANGE,
    FRUIT_BLACKBERRY,
    /* place new elements below */
    
    /* guard */
    FRUIT_LAST_ELEMENT
} Fruit;

int main()
{
    int fruitEnumLength = (FRUIT_LAST_ELEMENT - 1);
    printf("Fruit enum has %d elments counting from zero.\n", fruitEnumLength);

    return 0;
}
sh-4.3$ gcc -o main *.c                                                                                                                                                                                                                                 
sh-4.3$ main                                                                                                                                                                                                                                            
Fruit enum has 2 elments counting from zero.  

This technique may be useful for sanitizing input data or for writing tests.

Conway's Game of Life - online JavaScript version

Game of life is an example of a system with very simple rules but unpredictable state in the long term.

Each square represents a living space available for a single cell. If there aren't enough cells in the neighborhood, the space is empty, if the cell was present there it dies from loneliness. If in the neighborhood is enough of other cells, the cell can survive in its square, or a new cell is born if it was empty before.

It's interesting to notice that we can't compute the n-th iteration directly, we have to go through all previous iterations.

Controls: generate new map / start / pause-unpause.

I wrote this implementation almost ten years ago, so it may not be how it should be done today, especially the table should be replaced by canvas, but it's still usable and shows the concept.

If you are interested, how it works, please take a look on the source code of this page.

Fractal way of map generation by using diamond-square algorithm

Diamond-square algorithm is a simple way to generate maps by using fractal approach. The idea is to generate recursively a point based on the values of its neighbors and an additional fluctuation.

The main disadvantage is that landscapes aren't realistic and there exist visible edges created during recursive slicing of the terrain during recursive computing

Below you may see how the diamond-square algorithm works. Availability to change perspective is not part of the algorithm, but I've added it to make the visualisation more user-friendly.

up
left create new right
down

To check exactly, how the scripts are working please take a look on the source code of this page.

Above scripts were created a couple of years ago, they may not be aligned with the modern way of doing things in JavaScript. The code can be hard to read, I've written it when I was a student, back in those days I've been in love in short variable names and lack of comments.

Julia set, Cantor set and Fern fractal implemented in JavScript

In the previous post, I presented a simple fractal - bifurcation diagram of the logistic map. Today I will show more fractals and their implementation in JavaScript, they are embedded below so it's possible to run them on this page.

Julia set

The equitation for Julia set is given for complex numbers:

fc(x) = x2 + c

This implementation uses random numbers to create the fractal.

Click to draw Julia set. This can take a while.

function drawJuliaFractal(canvasID)
{
    // get canvas to be able to draw into it
    var canvas = document.getElementById(canvasID)
    var ctx = canvas.getContext("2d")

    var width = canvas.width
    var height = canvas.height

    var c_r = -0.73
    var c_i = 0.19
    var step = 0.002

    // z= a+bi
    for(var a = -2; a < 2; a+=step)
    {
        for(var b = -2; b < 2; b+=step)
        {
            var za = a
            var zb = b
            for(var n = 0; n < 160; n++){
               var za_temp = (za * za) - (zb * zb)
               zb = 2 * za *zb
               za = za_temp

               // add c constant
               za+=c_r
               zb+=c_i
            }

            if(Math.sqrt((za * za) + (zb * zb)) < 2)
            {
                var zoom = width / 3
                var x_print = (zoom * a) + (width / 2)
                var y_print = (zoom * b) + (height / 2)
                putPixel(ctx, x_print, y_print)
            }

        }
    }
}

Fern fractal

Unfortunately, I don't remember the direct mathematics formula.

This implementation uses random numbers to create the fractal.

Click to draw Fern fractal.

function drawFernFractal(canvasID)
{
    // get canvas to be able to draw into it
    var canvas = document.getElementById(canvasID)
    var ctx = canvas.getContext("2d")

    var width = canvas.width
    var height = canvas.height

    var max_step = 20000
    var x = 0
    var y = 0

    for(var i=0; i<max_step; i++)
    {
        var r = Math.random()

        if(r <= 0.01)
        {
            x = 0
            y = 0.16 * y
        }
        else if(r <= 0.08)
        {
            x = (0.2 * x) - (0.26 * y)
            y = 0.23*x+0.22*y+1.6
        }
        else if(r <= 0.15)
        {
            x = (-0.15 * x) + (0.28 * y)
            y = (0.26 * x) + (0.24 * y) + 0.44
        }
        else 
        {
            x = (0.85 * x) + (0.04 * y)
            y = (-0.04 * x) + (0.85 * y) + 1.6
        }


        // scale fractal to best fit to the canvas object
        var zoom = width / 10
        x_print = width - ((x * zoom) + (width / 2))
        y_print = height - (y * zoom)

        putPixel(ctx, x_print, y_print)
    }
}

Cantor set

The equitation for Cantor set is given by formula:

Cn = Cn-1/3 ∪ (2/3 + Cn-1/3), C0 = [0,1]

This implementation uses recursion to create the fractal.

Click to draw Cantor set.

// Note, initial invocation should be with xb = canvas width
function drawCantor(canvasID, level, xa, xb)
{
    // get canvas to be able to draw into it
    var canvas = document.getElementById(canvasID)
    var ctx = canvas.getContext("2d")

    var width = canvas.width
    var height = canvas.height

    var level_max = 10;
    if(level < level_max)
    {
        // put bar
        var bar_height = 3
        for(var i = xa; i < xb; i++)
        {
            var h = level * 6

            for(var j = h; j != (h + bar_height); j++)
            {
                var y_print = j +( height / 2)
                putPixel(ctx, i, y_print)
            }
        }

        //  call itself to print two child bars
        drawCantor(canvasID, level+1, xa, xa+ (xb-xa)/3)
        drawCantor(canvasID, level+1, xb - (xb-xa)/3, xb)
    }
}

To check exactly, how the scripts are working please take a look on the source code of this page.

Above scripts were created a couple of years ago, they may not be aligned with the modern way of doing things in JavaScript.

Bifurcation diagram of the logistic map [online version]

One of the reasons why mathematics is so amazing is that even a simple at first glance concepts have interesting behaviors and features. I think that the bifurcation diagram of the logistic map is a great example.

The logistic map is given by the equitation:

xn+1 = rxn(1 - xn), x0 < 1, r ∈ (0,4]

Below you may generate its bifurcation diagrams for different ranges and for different values of the x0. It's amazing that those diagrams have fractal nature - self-similarity is even visible at first glance.

X-axis represents values for different r values, Y-axis represents x0...n element value, n < 90 because in real world we can't show elements ad infinimum.

rstart>0: rstop≤4: x0<1:

The script was originally created a couple of years ago, so it may not be aligned with the modern JavaScript way of doing things. If you are interested how it works, please take a look on the source code of this page.

Yet another way protect pictures against copying

It's not possible to protect an image against any person, but it can be protected enough for most of the users. There are a couple of ways to do this, most popular are CSS tricks, but today I will present another way.

Can you save below image? I bet you can't! ;-)

Dangling else problem

What is a dangling else problem? It's presented below - what will print this program?

#include <iostream>

int main()
{
    bool a = true;
    bool b = false;
    
    if(a)
        if (b)
            std::cout << "foo" << std::endl;
    else
        std::cout << "bar" << std::endl;

   return 0;
}

It may seem that it won't print anything, but isn't true - on the screen we will see "bar". That's because the "else" is bound to the last "if" statement that wasn't already bound to other "else".

This may lead to bugs and confusion. One easy way is to always embrace body of the "if" statement in brackets. If we want to bind the "else" to the first "if" then correct parenthesis should be added as below:

    if(a)
    {
        if (b)
        {
            std::cout << "foo" << std::endl;
        }
    }
    else
    {
        std::cout << "bar" << std::endl;
    }

If we want to bound it to the second "if", it should be:

    if(a)
    {
        if (b)
        {
            std::cout << "foo" << std::endl;
        }
        else
        {
            std::cout << "bar" << std::endl;
        }
    }

What is good is that compilers will usually produce a warning in places where this error may exist:

 In function 'int main()':
8:7: warning: suggest explicit braces to avoid ambiguous 'else' [-Wparentheses]

More readable way of casting primitive types in C++

How to cast a variable of one primitive type to another? Usually people use static_cast operator, but it can be done in other, more readable way.

Below example demonstrate the problem, and two solutions:

char var1 = 3;
char var2 = 5;

// first way
int result1 = static_cast<int>(var1 + var2);

// second way
int result2 = int(var1 + var2);

The same trick may be used e.g. when passing to a function an argument of different type that expected.

There is also C-style casting available in C++, but I didn't mention it above because it's discouraged.

Yes, I know, casting from one type to another is a common source of bugs, and can signify that overall design could be improved. That's true, but sometimes it's inevitable.

A trip with Geiger Counter on the Śnieżka mountain

During the Second World War Nazis established a uranium mine in Krkonoše mountains. Extracted ore was used in a research facility in Oranienburg. After the war, the mine was in polish borders, but Poland was then a puppy country of the USSR, so the ore was still extracted, but now was transported to the USSR. Later the mine was used in civil research.

I've visited those mountains with my Geiger counter, not the mine, but still close - Śnieżka mountain.

My construction uses three GM tubes instead of one - that's why the amount of pulses per period of time is also three times bigger. Don't panic! :) In addition, even if radioactivity is a bit bigger that in (for example) my home in Wroclaw, it's still not hazardous for health.

As a reference, at home my Geiger Counter shows around 60 pulses per minute.

As you will see below results were bigger than those that I observe at home, is it due to the uranium ore that is near? Maybe, I'm not sure, I wasn't on any other mountains with my counter, so I can't verify it.

Preparations

32F429IDISCOVERY board is used to count pulses and show results, it requires 5V power supply, the same as my Geiger Counter. Both were supplied from DC/DC converter (the cheapest I could buy), and 3xAA NiCd batteries. In total 250-300mA was drained from the batteries.

Final adjustments of the latest HW version - as usual, I made mistakes during the design of the PCB.

Geiger Counter - last modification before a trip

ATtiny44 evaluation board for DYI robots

Intro

I will start from saying that the board could be replaced by any Arduino plus some(s) its motor driver shield(s). So why I made it you may ask? Well, while I made this tiny tank-robot model presented on below pictures, I wanted to make at least some things by myself, and decide what I need and how I need it instead of only buying prefabricated stuff.

This is the result, hope you will enjoy it and that maybe you will find inspirations for your own stuff.

Her's what it has and what it can..

  • Handle two separate motors, each can run either "forward", "backward", or stop.
  • Motors can be powered from a separate power source (there's a jumper for that, if removed, power is taken from a source connected to a separate goldpin)
  • ATtiny24 manages the board, it's relatively small microprocessor, but I think that it will be fine for such project. All its pins are available via goldpins, I also added a couple goldpins connected to Vcc and GND to make easier connection to other boards, shields and stuff like that.
  • To make programming easier, 6 PINs ISP socket for the ATtiny24 is also included.
  • ATtiny24 can be removed and the motor driver can be managed from external source, e.g. an Arduino. This could be useful in future if the ATtiny24 would not be sufficient.
  • There isn't any voltage regulator, or step/up/down/ converter because it would make the board less flexible.

Circuit

The circuit is simple, consists only of a small microprocessor, motor driver, some filtering capacitors and a lot off connectors.

The hardware was designed in Eagle, the board is available on GitHub.

Software

PB0, PB1, PB2 and PB3 ports of the ATtiny24 are used to drive the motor, others are available for other purposes, e.g to communicate with the sensors. There's not a lot of them left, because the microprocessor is quite small, but I think that for such project, it will be enough.

Modular DIY Geiger–Müller counter

The Geiger–Müller counter is a relatively simple tool to measure ionizing radiation. To increase sensitivity, construction presented here contains three (instead of one as usually) soviet STS-5 lamps. This is important for measurements of natural sources of (low) radiation like soil, rocks (an article about my trip with Geiger–Müller counter on Śnieżka mountain).

Principle of operation of a Geiger–Müller counter

When high voltage (typically 380-420V) is applied to the Geiger–Müller tube, the tube doesn't conducts electricity, but it does conducts for a short period, when radiation particle is observed. Those pulses are observed by the detector. The level of ionizing radiation is proportional to the amount of pulses detected in a constant interval of time (typically from 20s to 2,5min).

Geiger–Müller tube behavior can be described as a "button", that is "pushed" by an ionizing particle.

Homemade Geiger–Müller simplified circuit

Let's go further into the details. Geiger–Müller tube is made of two electrodes, ionizing particle creates a spark gap between them, to reduce amount of current that flows in this situation, a resistor is put in series with the tube. Marked as R1 on above circuit, R6 on below. Typically it's in a range 1-10M, acceptable values are listed in documentation of the GM tube.

There are a different ways to obtain a signal from the tube, in presented here, a resistor is connected in series between the tube and ground, changes of the voltage on the resistor are measured by the detector. This resistor is marked as R2 on above diagram, R7 on below. Typically it's in a range 10-220k.

Similarly to diode, a Geiger–Müller tube has its polarity, when connected in the opposite direction it will work incorrectly.

Below is shown a signal from GM tube when a particle is detected.

The electronic circuit of a Geiger–Müller counter

MC34063 is a DC/DC converter used to produce required high voltage, one of it's advantage over a simple NE555 or similar generators in this circuit is that it can monitor the output voltage and adjusts parameters to make it stable (R3, R4, R5, C3).

IC1A, R8, R9 are used as a comparator to filter out noises and produce binary signal (low=no pulse at this moment, high=pulse is currently being observed). R10, R11, R12 and a bunch of transistors drives LED, a speaker and (as an option) external digital devices, e.g. Arduino, or other evaluation board.

Waring! The device uses high voltage and can lead to unpleasant shock, injury or death. Don't touch the PCB or tubes when power is on.

Deobfuscation JavaScript code - how to start?

The easiest way to obfuscate code is to remove white-spaces that are not necessary and to shorten the names of variables and functions. A couple of years ago a made this simple tool to parse such obfuscated JavaScript code.

An example how the code can look after obfuscation and before passing it to a more readable form is presented below.

(function(){var s=true,t=false,aa=window,u=undefined,v=Math,ba="push",fa="slice",ga="cookie",y="charAt",z="indexOf",A="gaGlobal",ha="getTime",ja="toString",B="window",D="length",E="document",F="split",G="location",ka="href",H="substring",I="join",L="toLowerCase";var la="_gat",ma="_gaq",na="4.8.6",oa="_gaUserPrefs",pa="ioo",M="&",N="=",O="__utma=",qa="__utmb=",ra="__utmc=",sa="__utmk=",ta="__utmv=",ua="__utmz=",va="__utmx=",wa="GASO=";var xa=function(){var j=this,h=[],k="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";j.uc=function(m){h[m]=s};j.Nb=function()

[...]

After parsing it to more friendly form, we can spot functions, variables, loops and other things. Although the code still is far from being beautiful, it looks much better.

(function()
{
 var s = true,t = false,aa = window,u = undefined,v = Math,ba = "push",fa = "slice",ga = "cookie",y = "charAt",z = "indexOf",A = "gaGlobal",ha = "getTime",ja = "toString",B = "window",D = "length",E = "document",F = "split",G = "location",ka = "href",H = "substring",I = "join",L = "toLowerCase";
 var la = "_gat",ma = "_gaq",na = "4.8.6",oa = "_gaUserPrefs",pa = "ioo",M = "&",N = " = ",O = "__utma = ",qa = "__utmb = ",ra = "__utmc = ",sa = "__utmk = ",ta = "__utmv = ",ua = "__utmz = ",va = "__utmx = ",wa = "GASO = ";
 var xa = function()
 {
  var j = this,h = [],k = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
  j.uc = function(m)
  {
   h[m] = s
   }
  ;
  j.Nb = function()
  {
   for(var m = [],i = 0;
   i<h[D];
   i++)if(h[i])m[v.floor(i/6)]^ = 1<<i%6;
   for(i = 0;
   i<m[D];
   i++)m[i] = k[y](m[i]||0);
   return m[I]("")
   }
  
  }
 ,ya = new xa;
 function Q(j)
 {
  ya.uc(j)
  }
 ;
       [...] 

USB powered thermometer with an interesting data display

Almost each person interested in building electronic devices has built at least one thermometer and power supply in his life. I'm not different, to add to this, today I will present one of my thermometers.

Original concept was different, I wanted to use it as a weather station, wake up, go to my balcony, smoke a cigarette and check what on this device what is the temperature, humidity and air pressure. At the end I decided to build a small thermometer (in future with all mentioned features), that I could plug to my computer and check conditions in my home.

What is nice here is that the data is displayed original way, there are two rows of nine LEDs, if on the upper row second diode is on, and on the bottom row fifth diode is on, then the value presented by the device is 2*10 + 5 = 25. It can sounds complicated at first, but in practice it's fast and intuitive. Below is an example, value presented on the display is 25:

Popularne pytania z rozmów wstępnych dla programisty C/C++

W tym wpisie podzielę się zbiorem pytań, które często powtarzają się na różnych rozmowach wstępnych na stanowisko programisty C/C++. Są to pytania techniczne - nie opisałem tu żadnych pytań miękkich (HR'owych). Spotkałem się z nimi sam (już prawie 10 lat pracy, jak ten czas leci..), a niektóre zadawałem osobiście, gdy byłem po drugiej stronie stołu. Mam nadzieję, że taka lista okaże się pomocna podczas przygotowań do rozmowy.

Na początek pytania związane stricte z C/C++. Kolejność losowa.

  • Czym jest język obiektowy? Czy C++ jest językiem obiektowym (odpowiedź na to, czy jest może się różnić w zależności od tego, jak definiujemy język obiektowy)?
  • Napisz program, który jest poprawny składniowo w C, a nie jest w C++.
  • Czym są słowa kluczowe (w kontekście zmiennej, w kontekście metody) static i const? Co oznacza słowo kluczowe volatile?
  • Czym różni się alokacja pamięci na stosie od alokacji pamięci na stercie? Jak zmienną na oba sposoby? Kiedy stosować jedno, a kiedy drugie?
  • Czym jest smart pointer? Kiedy go stosować? Jakie są rodzaje?

Is it possible to write a program in C without using semicolons?

Yes, it's possible! In this text I will show a set of tricks to do it. I will present this on a simple program that that reads two numbers from STDIN and prints theirs sum to the STDOUT.

Normally I would start this program from declaring two variables:

int a, b;

Unfortunately, there's a semicolon at the end of the line. It can be omitted by using variables already declared for the main function:

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

I will use argc as a and argv[0] as b. Normally, next thing would be reading two values from STDIN and placing them in a and b variables. It could be like this:

scanf("%d%d", &a, &b);

Once again, there's a semicolon! This one can be skipped by using 'if' statement:

if (scanf("%d%d", &a, &b)) {}

The same trick can be used for printing to STDOUT:

if( printf("%d", a + b ) ){}

Above code compiles and works correctly, but normally the main function should return zero if everything went OK:

return 0;

This semicolon can't be avoided by using the trick with 'if' statement, but we other construction can help here:

if(brk(0)){}

That's all, below is full source code:

#include <stdio.h>
#include <unistd.h>

int main(int argc, char* argv[]) {
    if (scanf("%d%d", &argc, &argv[0])) {}
    if (printf("%d", argc+argv[0])) {}
    if (brk(0)) {}
}

Leave a comment, if you know other interesting riddles or tricks that can be used here!

Breaking CAPTCHA in Python

Usually CAPTCHAs are analyzed by using neural network, it's a good approach, but it may be overcomplicated in simple cases. Presented below, much shorter algorithm can produce sufficient results for uncomplicated CAPTCHAs.

In this algorithm an image with unknown letter is compared with samples of known letters, the letter in the most similar sample is probably also the letter in analyzed image. It was implemented as a Python script, usage presented below:

captcha breaker in python, sample of usage
bash-3.2$ python cracker.py test1.png 
e
other sample of usage of the script for breaking CAPTCHAs in Python
bash-3.2$ python cracker.py test2.png 
p

It can't be directly used on a raw CAPTCHA, firstly small artifacts have to be removed from the CAPTCHA, secondly each letter should be stored in a separate image.