Friday, 7 June 2019

Raspberry Pi Dashboard with Dakboard

A while ago I bought a cheap Raspberry Pi touchscreen. This like so many impulse buys spent many months gathering dust in a cupboard but given the progress of my webserver, I thought I'd try setting it up as a display.

I was inspired by the excellent Scott Handelman blog to setup a dashboard  using Dakboard and my Raspberry Pi display.

Back when I first got the display, I'd set the screen to portrait mode, but with the stand I have I needed to reset it back to landscape.  It took a while to remember how to do this.

First in  /boot/config.txt I'd added a line display_rotate=1 which rotates by 90 degrees. I removed this and rebooted.

Unfortunately, the response to the touch screen was still in portrait mode.

To change this I had to edit /etc/X11/xorg.conf.d/99-calibration.conf

And change the SwapAxes option back from "1" to "0".

Section "InputClass"
        Identifier      "calibration"
        MatchProduct    "ADS7846 Touchscreen"
        Option  "Calibration"   "145 3995 290 3945"
        Option "SwapAxes"    "0"
EndSection

(I also needed to recalibrate, this is available from Preferences -> Calibrate TouchScreen on my device)

I then created a Dakboard account and setup a simple view; Date, RSS feed and local weather. You are then given a private URL which can be used to display this on any device.

In order to startup the Raspberry Pi displaying this page full screen with no mouse pointre,  I followed the instructions on Scott Hanselman's blog.

Edit (take a copy first):  ~/.config/lxsession/LXDE-pi/autostart

Replace contents with:

@xset s off
@xset -dpms
@xset s noblank
@chromium-browser --noerrdialogs --incognito --kiosk https://dakboard.com/app?p=
private-url

(There are also good instructions here)

Unfortunately, while it does look great, Dakboard doesn't quite work for me.
The ability to use a my own webservice as data input is only supported on the paid-for Premium plan. At $5.95 per month this is too much for me so I'm going to look into creating my own webpage. After all, isn't creating something all the fun!

As an aside. With a 750mA power supply the Pi shows the lightening bolt in the top right hand corner, which indicates it's underpowered. Not surprising given we're also powering the screen.
 

I have an 850mA supply, which is slightly better but I would need more if I wanted to avoid the computer crashing.

Monday, 3 June 2019

Loading old Physics Data Files - Part 2

Previously, my attempt at running a FORTRAN program to load my old ZEUS data ntuples failed because CERNLIB isn't compatible with a 64-bit Linux OS:

 Test loading ntuple files
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
LOCB/LOCF: address 0x562cca6e2c80 exceeds the 32 bit address space
or is not in the data segments
This may result in program crash or incorrect results
Therefore we will stop here
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
 
Unfortunately, the recommendation in  /usr/share/doc/libpacklib1-dev/README.64-bit to statically link didn't work for me:

Static linking is the default behavior if you use the "cernlib" script when
linking, like this:

 # Should work everywhere:
 gfortran -o myprogram myprogram.F `cernlib -G Motif pawlib` 
 
Fortunately, Linux Mint still provides a 32-bit version of the latest OS. So, at this point rather than trying to fix it in 64-bit I thought the best approach would be to setup a Virtual Machine.

For the VM host, I decided to use VirtualBox. This is easy to install on Ubuntu from the Software Center.

After downloading the 32-bit Linux Mint ISO I setup a new VM with 4MB of Memory and Dynamically Allocated Storage with 70GB Virtual Size.

After installing Mint, I reinstalled the CERNLIB packages from the Mint Software Manager and loaded up the ntuple in PAW as per my last post

Now, given this was working I could try and load the file using my FORTRAN program:

      program main

      implicit none
      integer istat, NEvents, idnt
      real hmem
      common/pawc/hmem(2000000)

      print *, "Test loading ntuple files"
      call hlimit(2000000)  
     
      call hropen(80,'ntuple','mc97_1.rz','',4096,istat)
 
      if (istat.ne.0) then
          print *, "Failed to open input file"
         stop
      endif

      print *, "Loaded mc96_1.rz"
      call hrin(10, 9999999, 0) 
      call hnoent(10,NEvents)
      print *, NEvents
c      print *, idnt    

      call hrend('ntuple')
      close(80)  

      end program main

And this time, success!

 Test loading ntuple files
 Loaded mc96_1.rz
       51781

There's a few points to bear in mind:
  • common/pawc/hmem(2000000) is required to reserve locations to a common /PAWC/, for the HBOOK working space (an array)
  • call hlimit(2000000) informs HBOOK of the storage limit
  • call hropen opens the direct access rz file
  • call hrin(10, 9999999, 0) reads a histogram from the current directory of the direct access file into the current directory in memory. The 9999999 to to read the highest cycle
  • call hnoent Gets the number of events in the in-memory identifier

Monday, 20 May 2019

Loading old Physics Data Files - Part 1

It's been a while since I built the CERNLIB libraries on my laptop. Since then the old laptop has finally failed and I've installed CERNLIB from the Ubuntu repositories, so I thought it was time to try and load my old data files again.

The data are saved as binary ntuples packaged as .rz files. So, to begin I tested opening them in PAW (Physics Analysis Workstation).

To load, simply run paw, take the default workstation type and enter:
hi/file 1 mc96_2.rz

jonathan@jonathan-Inspiron-5759:~/Development/Physics$ paw
 ******************************************************
 *                                                    *
 *            W E L C O M E    to   P A W             *
 *                                                    *
 *       Version 2.14/04      12 January 2004         *
 *                                                    *
 ******************************************************
 Workstation type (?=HELP) <CR>=1 : 
 Version 1.29/04 of HIGZ started
PAW > hi/file 1 mc96_2.rz 4096
PAW > 

The arguments are:
  • '1' is the 'logical unit' of the file
  • The filename, 'mc96_2.rz'
  • Record length in words (I saved the data back in the day with 4096) It's important this is included or a segmentation error is returned:
PAW > hi/file 1 mc96_2.rz

 *** Break *** Segmentation violation
 Traceq lun = 0, level = 99 

 TRACEQ.  In-line trace-back still not available.
 Longjump 
PAW > 

The structure of the ntuple currently loaded in memory can be seen with nt/print 10
(10 is the ntuple identifier. Again, I originally saved it with this value)

PAW > nt/print 10


 ******************************************************************
 * Ntuple ID = 10     Entries = 5882      ntuple
 ******************************************************************
 * Var numb * Type * Packing *    Range     *  Block   *  Name    *
 ******************************************************************
 *      1   * R*4  *         *              * FLT      * TrigDat(15)
 *      1   * I*4  *         *              * TLT      * TLT(15)
 *      1   * R*4  *         *              * TRK      * VCT_XVC
 *      2   * R*4  *         *              * TRK      * VCT_YVC
 *      3   * R*4  *         *              * TRK      * VCT_ZVC
 *      4   * I*4  *         *              * TRK      * NVTRKC
 *      5   * I*4  *         *              * TRK      * NTRKC
 *      6   * R*4  *         *              * TRK      * CHVCC 
...
 ******************************************************************
 *  Block   *  Entries  * Unpacked * Packed *   Packing Factor    *
 ******************************************************************
 * FLT      *  5882     * 60       * 60     *       1.000         *
 * TLT      *  5882     * 60       * 60     *       1.000         *
 * TRK      *  5882     * 40       * 40     *       1.000         *
 * CAL      *  5882     * 60       * 60     *       1.000         *
 * ELEC     *  5882     * 144      * 144    *       1.000         *
 * ZUFOS1   *  5882     * 16       * 16     *       1.000         *
 * ZUFOS2   *  5882     * 4        * 4      *       1.000         *
 * ZUFOS3   *  5882     * 12       * 12     *       1.000         *
 * ZUFOS4   *  5882     * 96       * 96     *       1.000         *
 * ZUFOS5   *  5882     * 16       * 16     *       1.000         *
 * TEMP     *  5882     * 8        * 8      *       1.000         *
 * TAG1     *  5882     * 4        * 4      *       1.000         *
 * TAG2     *  5882     * 4        * 4      *       1.000         *
 * LUMI1    *  5882     * 12       * 12     *       1.000         *
 * LUMI2    *  5882     * 12       * 12     *       1.000         *
 * GEN      *  5882     * 32       * 29     *       1.103         *
 * MCTRUE   *  5882     * 88       * 88     *       1.000         *
 * BGDTUP   *  5882     * 28       * 28     *       1.000         *
 * Total    *    ---    * 696      * 693    *       1.004         *
 ******************************************************************
 * Blocks = 18           Variables = 126          Columns = 174   *
 ******************************************************************
  
And to page through the data use nt/scan 10

PAW > nt/scan 10
/NTUPLE/SCAN: Only showing first 30 of expressions
+-------+--------------+-------------+--------------+--------------+--------------+-------------+-------------+--------------+-----
| Event |   TrigDat    |   TLT       |   VCT_XVC    |   VCT_YVC    |   VCT_ZVC    |   NVTRKC    |   NTRKC     |   CHVCC      |   FC
+-------+--------------+-------------+--------------+--------------+--------------+-------------+-------------+--------------+-----
|     1 |              |             | -1.43087     |  1.24444     |  18.4673     |  2          |  3          |  3.27624     |  0. 
| *   1 |  0.          |  0          |              |              |              |             |             |              |     
| *   2 |  0.          |  0          |              |              |              |             |             |              |     
| *   3 |  0.          |  0          |              |              |              |             |             |              |     

I've got 174 columns in this particular ntuple. To restrict the selection use:
nt/scan 10 varlis=[Comma separated list of columns]

PAW > nt/scan 10 varlis=ENE44M:ZufoPz
+-------+-------------+--------------+--------------+--------------+
| Event |   ENE44M    |   TEMPLUME   |   TEMPLUMG   |   ZufoPz     |
+-------+-------------+--------------+--------------+--------------+
|     1 |  1000       | -500.        | -500.        |  2.55895     |
|     2 |  1000       | -500.        | -500.        |  11.4667     |
|     3 |  1000       | -500.        | -500.        | -1.63046     |
|     4 |  1000       | -500.        | -500.        |  1.37581     |
|     5 |  1000       | -500.        | -500.        | -2.54238     |
|     6 |  1000       | -500.        | -500.        | -1.91473     |
|     7 |  1000       | -500.        | -500.        |  1.51911     |
|     8 |  1000       | -500.        | -500.        |  0.          |
|     9 |  1000       | -500.        | -500.        |  12.3712     |
|    10 |  1000       | -500.        | -500.        | -4.4222      |
|    11 |  1000       | -500.        | -500.        |  0.0533053   |
|    12 |  1000       | -500.        | -500.        | -0.0746093   |
|    13 |  1000       | -500.        | -500.        |  33.6832     |
|    14 |  1000       | -500.        | -500.        |  0.223857    |
|    15 |  1000       | -500.        | -500.        |  8.72115     |
|    16 |  1000       | -500.        | -500.        |  10.5479     |
|    17 |  1000       | -500.        | -500.        |  2.4528      |
|    18 |  1000       | -500.        | -500.        | -1.17858     |
|    19 |  1000       | -500.        | -500.        |  1.03199     |
+-------+-------------+--------------+--------------+--------------+
 

After this, I knew I could load the data but I really wanted to run the files through my old analysis code in FORTRAN.

Rather than try to compile the old project, I created a simple FORTRAN program to try and load the ntuple:

jonathan@jonathan-Inspiron-5759:~/Development/Physics/New Stuff/Development$ more Zeus1.f
      program main

      print *, "Test loading ntuple files"
     
      call hlimit(2000000)      
      call hropen(80,'ntuple','nommc_1033.rz','',4096,istat)
 
      if (istat.ne.0) then
          print *, "Failed to open input file"
         stop
      endif

      print *, "Loaded nommc_1033.rz"
      end program main

(I'll talk about these commands in the next blog)

Compilation is easy with the official repository, we just need to link against packlib:

gfotrtran Zeus1.f  -lpacklib

And with no problems it created the default executable a.out (that takes me back!)

So with huge anticipation I ran it and, oh...

jonathan@jonathan-Inspiron-5759:~/Development/Physics/New Stuff/Development$ ./a.out
 Test loading ntuple files
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
LOCB/LOCF: address 0x7f57832df7a0 exceeds the 32 bit address space
or is not in the data segments
This may result in program crash or incorrect results
Therefore we will stop here
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
The reason was to be found in the readme file in the same location as the libraries:
/usr/share/doc/libpacklib1-dev/README.64-bit

CERNLIB was never designed to run on machines where the size of a pointer
is 64 bits.  The code implicitly assumes that
 sizeof(void *) == sizeof(int) == 4
in many different places.  The biggest culprits are the ZEBRA and COMIS sets
of routines in the packlib and pawlib libraries, respectively.  This would be
difficult to fix without rewriting megabytes of FORTRAN source code.

My old 2002 laptop was of course 32bit so this wasn't a problem before. My next blog will describe how I got this working.

Tuesday, 23 April 2019

Germinating Seeds

Here's a quick an simple way to view a seed germinating.

All it took was kitchen towel, a straight glass, two sunflower seeds and some water.

Take 4 or 5 sheets of kitchen towel, slightly damp and roll into a cylinder. We're going to put this into the glass.

On the side of the kitchen towel, where it would be about 3/4 of the way up the glass, put the seed. We put two in, on opposite sides.

Now, place the kitchen towel into the glass and fill the bottom with water up to a depth of about 2cm.

At this point the glass was put on a shelf and left alone apart from topping up the water once the kitchen towel fully absorbed it.

After 4 days a root appeared and headed down very quickly, over 2cm a day.
We had placed one seed point up and the other point down. This had no discernible effect as the root appeared more from the side.

Then after another 2 days, the leaf came out.

Here it is, just before I planted out into a pot


The seed itself required water, warmth and oxygen to germinate. By keeping it damp, but not submerged, the seed took in a large amount of water to allow it to soften and swell the coating as well as trigger the internal metabolism.

Thursday, 29 November 2018

Distance Sensor


Another online purchase saw me get a set of HC-SR04 Ultrasonic sensors. These sensors contain an ultrasonic transmitter and receivers. Sound waves sent from the transmitter reflect off a distant surface and are sensed by the receiver. The time taken for the round trip can be used to calculate the distance. Details how it works are on the datasheet.
The company that sold the sensor, www.elegoo.com provided an download for Arduino, this consisted of a library and sample sketch.
The .cpp and .h files needed to be setup as an Arduino Library. To do this i needed to copy the files to ~/Arduino/Libraries/SR04/  The SR04 folder must match the library name.
The simple sketch below could then be created:
#include "SR04.h"
#define ECHO_PIN 11
#define TRIG_PIN 12

SR04 sr04 = SR04(ECHO_PIN, TRIG_PIN);
long distance;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  delay(1000);
}

void loop() {
  // put your main code here, to run repeatedly:
  distance = sr04.Distance();
  Serial.print(distance);
  Serial.println("cm");
  delay(1000);
}

Unfortunately, when I tried to upload to the Arduino I got this error:

/home/jonathan/Development/Arduino/arduino-1.6.7/hardware/tools/avr/bin/avrdude: error while loading shared libraries: libreadline.so.6: cannot open shared object file: No such file or directory

Looking in the /lib/x86_64-linux-gnu folder I discovered I only had libreadline.so.7.
An upgrade to Ubuntu 18.04 meant the installed version of the Arduino IDE, 1.6.7 was no longer compatible. However, simply installing the latest version 1.8.7 resolved the problem and I was able to upload the sketch.
Finally I added a piezoelectric buzzer configured to beep more rapidly the closer something got to the sensor.


The speaker was plugged into pin 8 and ground, with the code changed as below:
#define SPEAKER 8
void loop() {
  // put your main code here, to run repeatedly:
  distance = sr04.Distance();
  Serial.print(distance);
  Serial.println("cm");


  tone(SPEAKER, 550, 100);
  int delayTime = distance * 10;
  delay(delayTime);
}


This is what the setup looked like:


In practice the maximum distance reported by the sensor was around 1.25m.

Tuesday, 27 November 2018

Why everyone should keep a Soldering iron (and wire stripper)


The children have a toy guitar which they played with for quite a lot, with plenty of dropping and banging before it disappeared in a cupboard for a few months. Here it is, plenty of buttons for playing tunes, LEDs and the like.

But horror, when it was found in the back of the cupboard and new batteries inserted absolutely nothing happened. Horror for the children I have to add, I didn't really miss the sound it made!

But given my geeky nature I had to see what was the problem.  Opening it proved to be tricky. Although not glued it was held together by 18 screws, some of which were very tight. Eventually the inside was revealed:


Fortunately, the reason nothing worked was immediately obvious.

The wire to the positive battery terminal had snapped off. So the fix was a quick strip of the insulation and soldering the wire back onto the terminal.

Finally, replacing 18 screws turned out to be a lot quicker and the guitar lit up and played as soon as it was turned back on!

I'm looking forward to years more play out of it !!

Tuesday, 13 November 2018

Bird Box Camera Failure

After 2 years of continuous filming. The BirdBox camera has finally failed.

The Raspberry Pi itself is fine, I could still log onto it but unfortunately, when I tried to start up the motion detector python it complained it couldn't find the camera and that I should try enabling the camera. Now, clearly I'd already done this so some more investigation was required.

I then tried to take a still picture with raspistill, but this returned the following:

mmal: Camera is not detected. Please check carefully the camera module is installed correctly

This didn't look good.

I decided to take the Birdbox down to investigate. Being November there are no issues around disturbing nesting birds and the box itself can be taken down and cleaned between September and January.

The Birdbox was showing signs of age but the Raspberry Pi and Power over Ethernet box both looked as good as new.


As for the camera, this was looking a bit worse for wear. It turns out a large spider had made a home under the camera and had made meals of a number of woodlice.



After getting the Camera IC indoors I could certainly now see some quite significant corrosion. This is clear in the image below taken with a microscope. In particular the C8 capacitor looks to have corroded completely. Notice also the droppings.


I have a spare camera so I'll be setting up a new installation. Next time I'll look at to seal it more thoroughly.

Some links I discovered while looking for what the corroded capacitor was for