Loboplaya -> Programming

Arduino direct port writing
Moving from a powerful PC to a much smaller, less capable one, like an Arduino, is a bit of a shock. All of a sudden you have to think about saving CPU cycles and memory, which doesn't always come easy to programmers just starting out.

Fast code is not only important for doing calculations, but even more so for input/output (IO) operations. If you try robotics development this will become even more obvious since much of the work done by the microcontroller results in IO. Usually a faster feedback loop meant better performance.

The standard Arduino uses a clock with a speed of 16MHz, this doesn't equal to 16 million instructions per second, many instructions means more than one clock cycle per instruction, and many operations needs a vast row of instructions to complete its task. Take for example digitalWrite() and digitalRead() that controls ports IO.

This is the code for digitalWrite():


void digitalWrite(uint8_t pin, uint8_t val)  
    {
        uint8_t timer = digitalPinToTimer(pin);
        uint8_t bit = digitalPinToBitMask(pin);
        uint8_t port = digitalPinToPort(pin);
        volatile uint8_t *out;

        if (port == NOT_A_PIN) return;

        // If the pin that support PWM output, we need to turn it off
        // before doing a digital write.
        if (timer != NOT_ON_TIMER) turnOffPWM(timer);

        out = portOutputRegister(port);

        uint8_t oldSREG = SREG;
        cli();

        if (val == LOW) {
            *out &= ~bit;
        } else {
            *out |= bit;
        }

        SREG = oldSREG;
    }
            
This function is constructed for maximum flexibility concerning which model of Arduino that you want to use. In case of a private project you can afford to create a specialized function for a specific Arduino.

Here is for example an Arduino Uno rev 3 microcontroller, a ATmega328P:
Arduino Uno
The minimal "macro code" (C language) that can be used to correspond to digitalWrite() is:


#define CLR(x,y) (x&=(~(1<<y)))
#define SET(x,y) (x|=(1<<y))
...
SET(PORTB, 0); // To set pin 8 to HIGH (se above diagram for ATmega328P).
            
Why not buy a (much) faster Arduino? Well, money, and libraries that are compatible with for example the Arduino Uno are possibly not so much with the faster new board. Also, the macro is more than 30 times faster, that is almost impossible to beat with pure hardware... Though you have to take other possible slowing down reasons into consideration.
Arduino Uno
GiT version control
Git is today the most widely used modern version control system in the world. It's a mature, actively maintained open source project originally developed in 2005 by Linus Torvalds, the creator of the Linux operating system kernel. Developers who have worked with Git are well represented in the pool of available software development talent and it works well on a wide range of operating systems and IDEs (Integrated Development Environments).

Git is an example of a DVCS (Distributed Version Control System). Rather than have only one single place for the full version history of the software as is common in once-popular version control systems like CVS or Subversion (also known as SVN), in Git, every developer's working copy of the code is also a repository that can contain the full history of all changes. In addition to being distributed, Git has been designed with performance, security and flexibility in mind.

To initially setup the GiT environment:

  • git init
  • git config --global user.name "John Doe"
  • git config --global user.email johndoe@example.com

What settings are set for the GiT environment:

  • git config --list

Commit staged files and store a comment statement:

  • git commit -m 'initial project version'

The basic Git workflow goes something like this:

  • You modify files in your working tree.
  • You selectively stage just those changes you want to be part of your next commit, which adds only those changes to the staging area.
  • You do a commit, which takes the files as they are in the staging area and stores that snapshot permanently to your Git directory.
Example:
git add *.html
stage all HTML files to be part of the next commit.

A nice trick in GiT is that when you run
git status
, and want to avoid to see a file that you never intend to put into version control: At the same directory level as .git you add .gitignore; into that file you enter the file name (you can also use wildcard regex).

  • bootstra*
  • IDEER.txt
  • *ssThai*
  • *TEMPLATE*

To see the files that might be staged for commit in GiT you can use

git status
. There is of course also to review earlier commit history, and what changes that were made within these commits.

git log
produce a list something like the following:

    commit c36392fb76aebf27d062aa1abfbd77f3662995a5
    Author: John Doe <vargstrand@gmail.com>
    Date:   Thu Jun 6 16:02:17 2019 +0200

        Life style, new GiT section, footer (not used yet)

    commit e2208f2f0da425f0fa200ac6a65b202b6dd9829d
    Author: John Doe <vargstrand@gmail.com>
    Date:   Fri May 24 19:26:11 2019 +0200

        new style

    commit 00fe2f499f882212f0710e438a36503ab2a6d373
    Author: John Doe <vargstrand@gmail.com>
    Date:   Mon May 20 20:50:41 2019 +0200

    Initial version - why leaving Wordpress

                
As an example you could copy the second last "hexadecimal string" (commit ID) e22...29d and paste it at the next usage:

                    git diff e2208f2f0da425f0fa200ac6a65b202b6dd9829d
                

which gives something along these lines:

GiT diff look

 

SSH key for Git

Why did I previously spell Git as "GiT"? Perhaps a false memory of fact, I don't know x-) ... From now on, I will call it Git.

A few weeks ago I made a disastrous mistake to type something along the lines of
rm -Rf /*
, deleting a large portion of my Linux installation... Luckily (contrary to my lazy habit of NOT doing so!) I had an "ok" recent backup done. Among many other things, the SSH key directory was deleted in my Linux home directory. Therefore, Git version management of this site was not possible anymore.

The hard drive used for my Linux installation was bought very cheaply as I really only wanted to try out whether Linux Mint could be suitable as a working platform (not much gaming). Linux Mint turned out to be an excellent working environment, and I remained working in Linux, only sporadically looking back at the Windows 8.1 drive content.

Now, before the deletion accident I had been running for about 2 years on this Linux Mint (18) version and the remaining space of hard drive was getting somewhat limited. The support for Linux Mint 18 was also going to expire in early next year 2020, only leaving a few months left of the support. So I picked up the vastly bigger drive that I had bought a few months before (for superseded reasons; I had since decided to keep Windows 10 on the second hand portable computer).

I downloaded and installed Linux Mint 19.2 Tina (that will be supported until April 2023). There are plenty of instructions about how to install Git in a Linux environment, and I can't remember what extra packages I installed apart from the basic Linux packages. I will try here to recapitulate all the steps I made.

It's a must though to have ssh-agent installed, and it's very handy to have the xclip tool to manage the clipboard.

eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_rsa
to get the ssh-agent started,
sudo apt-get install xclip
installed the xclip package.
 xclip -sel clip < ~/.ssh/id_rsa.pub
copies the contents of the id_rsa.pub file to your clipboard.

git config --global user.email "<Your email address>"
git config --global user.name "<Your name>".

To be able to upload changes to a "master", you must then generate a new SSH key and add it to the ssh-agent:
ssh-keygen -t rsa -b 4096 -C "<Your email address>"
. You get a few question, a) key file and place for it (choose default), and b) invent a personal passphrase (don't forget this!). The terminal will outburst a text block along the lines of SHA256: (bla bla...) +----[SHA256]-----+.

This SHA256 block is to be taken to your Git account:
  • Click on profile photo
  • click Settings
  • SSH and GPG keys
  • write a suitable name for this key, and
  • paste the SHA256 key above into the following "Key" area
Now you can stand in the Git initialized directory (that have your user.email, user.name set) and type
git push origin master
to push changes to your Git repository. If my description of the matter feels somewhat vague, please visit the official Github site for help about "Generating a new SSH key and adding it to the ssh-agent".

Column alignment using basic CSS
During the work on Friday I stumbled upon the need to replace a table layout design structure with an unordered list,
<ul>...<li>.
The problem I needed to solve was to get a leftside aligned column look using only a single ul combined with multiple li tags. The reason for this that an excellent AngularJS package for drag- and drop functionality required this. I tried more basic HTML drag- and drop code, but AngularJS just seem to fully accept my solution. The fastest solution was to convert my table code to an unordered list.

The CSS code looks like the following:


<style>
    ul {
        width: 100%;
        margin-bottom: 20px;
        overflow: hidden;
    }

    li {
        display: inline;
        line-height: 1.5em;
        float: left;
    }

    #double li {
        width: 50%;
    }
    #triple li {
        width: 33.333%;
    }
    #quad li {
        width: 25%;
    }
</style>
            
If you want to create two columns, you simply use the class "double", for three use "triple", four columns the "quad". As the li content floats to the left, there must be room for chosen number of columns. Thus the with of the li element is set (in percent) to 100 / (number of requested columns). The HTML code for the column content looks like the following:


<ul id="triple">
    <li><a href="#">Mission</a></li>
    <li><a href="#">History</a></li>
    <li><a href="#">Organization</a></li>
    <li><a href="#">Board</a></li>
    <li><a href="#">Things to See & Do</a></li>
    <li><a href="#">Hours, Directions, Prices</a></li>
    <li><a href="#">Daily Schedule</a></li>
    <li><a href="#">Services</a></li>
    <li><a href="#">Calendar</a></li>
    <li><a href="#">Rent the Zoo</a></li>
    <li><a href="#">Birthday Parties</a></li>
</ul>
                
This creates a three column view of the list by using the "triple" class. I hope that this description can prove useful in future web projects.
Pomodoro
A person named Francesco Cirillo created a technology called Pomodoro in the 80s, the purpose of which was to have better control over the time of his studies. The home directory for the technology is https://francescocirillo.com/pages/pomodoro-technique.

I wrote an HTML/Javascript/CSS program that can be used for the same purpose, at the same time I got some insight when it comes to Javascript timing function. I usually maximize the browser window containing the running code with the F11 key (works in Chrome as well as Firefox). Then I work with study/task until the web window switches to a red background. The program (here) is a link to the program code below):


<!DOCTYPE html>
<html lang="en">
 <head>
    <script type="text/javascript">
        var countDown = 0;      var everySecIntervalId;
        var s_tmpTimer = "";    var c_msec = 60000;
        var kilo = 1000;

        function initz() {
            document.getElementById('bdy').style.background = '#99ccff';
            document.getElementById('mytime').focus();
        }

        function alarm() {
            myBdy = document.getElementById('bdy');
            myBdy.style.backgroundColor = '#882222';
            myBdy.style.color = 'white';
            myBdy.innerHTML = 'STOPPED timer';
            clearInterval(everySecIntervalId);
        }

        function doCountDown() {

            var currentTime = new Date();           var month = currentTime.getMonth() + 1;
            var day = currentTime.getDate();        var year = currentTime.getFullYear();
            var hours = currentTime.getHours();     var minutes = currentTime.getMinutes();
            countDown = countDown - kilo;

            s_CountDown = ' <span style="font-size: 70%; font-weight: bold">' +
                "\n\n\n\n\n" + (parseInt("" + countDown) / kilo) + '</span> secs remaining (' +
                parseInt((parseInt("" + countDown) / (kilo * 60))) + ') mins' +
                "          <strong>" + (year + "-" + (month < 10 ? "0" : "") + 
                month + "-" + (day < 10 ? "0" : "") + day) + " </strong>|<strong> " + 
                (hours < 10 ? "0" : "") + hours + ":" + (minutes < 10 ? "0" : "") + minutes + "</strong>";

            document.getElementById('bdy').innerHTML = s_tmpTimer + " " + s_CountDown;
        }

        function timer(x) {
            document.getElementById('bdy').style.backgroundColor = '#8db6cd';
            document.getElementById('bdy').style.color = 'black';

            var s_timeEntered = document.getElementById('mytime').value;

            s_tmpTimer = 'Timer (' + s_timeEntered + ' min';
            if (parseInt(s_timeEntered) != 1) {
                s_tmpTimer += 's'; // 1 => "min", otherwise "mins"
            }
            s_tmpTimer += ') started, ';
            setTimeout('alarm()', (x * c_msec));
            everySecIntervalId = setInterval("doCountDown()", kilo);
            countDown = parseInt(s_timeEntered * c_msec);
        }
    </script>
    <style type="text/css">
        body { margin: 0.2em }

        #bdy {
            font-family: Verdana, Arial, Helvetica, "sans-serif";
            font-size: 80%;
            margin: 0.4em;
            margin-top: 2.5em;
            padding: 0.2em
        }

        #bdy_header {
            letter-spacing: 0.2em;
            font-weight: bold;
            padding: 0.4em;
            margin: 0.8em;
            margin-left: 0;
            border: 1px inset;
            background-color: #e6e6e6
        }
    </style>
</head>

<body id="bdy" onload="initz()">
    <div id="bdy_header">HTML/JS Timer</div>
    Timer in minutes: <input type="text" size="4" maxsize="4" id="mytime">
    <input type="button" value=" Start " id="mybutton" onclick="timer(document.getElementById('mytime').value);">
</body>
</html>
                
            
Python 3 tagged file includer
2019-07-14

So I needed a tool that "inject" code into tagged places, at the same time i wanted to learn about Python 3 programming. So I came finally up with basic Python code for this. It was suprisingly difficult to convert a one object list into a simple string for capturing a program call argment... Usage is PROGRAM <filname> :

    import re
    import sys
    import getopt

    def replaceFromFile(foundFile, txt):

        # print incoming string txt to "[["
        posTag= txt.find('[[')    
        print (txt[0:posTag])

        try:
            # Open filename based on string [[<filename>]]
            fileInTag = open(foundFile);
            inline = fileInTag.readline()

            while inline:
                print (inline.rstrip())
                inline = fileInTag.readline()

            fileInTag.close()    

            # Print rest of incoming string "txt"
            posEndTag= txt.find(']]')
            print (txt[posEndTag+2:])

        except IOError:
            print("Could not read insertion file:", foundFile)
            sys.exit(-1)

    ########################################

    total = len(sys.argv)
    cmdargs = str(sys.argv)
    fileToInsertInto = ' '.join(sys.argv[1:2]) # "major" file (t.ex. "index.html")

    try:
        f= open(fileToInsertInto)
        print (f)
        txt= f.readline()

        while txt:
            pStr = re.search('\[\[(.*)?\]\]', txt)    

            if (pStr):
                replaceFromFile(pStr.group(1), txt)
            else:
                print (txt.rstrip())

            txt= f.readline()

        f.close()

    except IOError:
        print("Could not read file:", fileToInsertInto)
        sys.exit(-1)

                
 Python programming symbol
Useful scripts
1. I needed a script to quickly see what file that handled by GiT have become changed the last 24 hours:


 find . -mtime -1 \! -type d -exec ls -1 {} \; |grep -v git\/ | xargs ls -lrt
            
2. I thought that a script that could compress images for a small gallery window would be nice. Built into Linux are the command convert and you may repeatedly call it using a loop. Maximum height is set by the parameter <height>x</height>

 #!/bin/bash

 i=1
 for image in DSC*.jpg; do
   convert "$image" -resize 700x400 "out$i.jpg"
   i=$(expr $i + 1)
 done
            
3. This script checks if the URLs contained in a file are still valid; the result is saved locally in another file named "urlstatus.txt". To run the script, simply enter ./<script> <URL list file>.

 #!/bin/bash
 while read url
 do
    urlstatus=$(curl -o /dev/null --silent --head --write-out '%{http_code}' "$url" )
    echo "$url  $urlstatus" >> urlstatus.txt
 done < $1