Converting _svn directories to .svn

I’ve been using TortoiseSVN on and to avoid grief with various Microsoft programs had been using the _svn hack (instead of .svn).

I’ve now moved all main development to LinuxMint/Ubuntu and want to using standard svn commands which means I need to find all the _svn directories and rename them to .svn.

Now I can almost certainly use find and xarg to do this but I whipped up this following little python script that does the job.

# I'll add the script later
# this is to test org2blog's publishing

def convert_svn(rootDir):
   files, dirs = os.walk(rootDir, topdown=False)
   for dir in dirs:
     if dir == "_svn":
       do_stuff()

Now let’s try publishing this to my wordpress blog using org2blog.

Posted in Linux, Software | Leave a comment

Fixing software update error: NOPUBKEY 8771ADB0816950D8

Trying to do and software update on LinuxMint 11-Kaya (and the same will probably happen with Ubuntu 11.10) gives this error/warning:

“W: GPG error: http://ppa.launchpad.net natty Release: The following signatures couldn’t be verified because the public key is not available: NO_PUBKEY 8771ADB0816950D8″

As having updates not completing correctly is unnerving, I went searching and found that is caused by the key for HandBrake video transcoder (http://handbrake.fr/) not being available. To fix this, download the key from a keyserver. I found the subkeys.pgp.net has this key.

gpg --keyserver subkeys.pgp.net --recv-keys 8771ADB0816950D8 
gpg --export --armor  8771ADB0816950D8 | sudo apt-key add -
Posted in General, Linux | Leave a comment

Factoring Humanity

I’ve just finished reading “Factoring Humanity” by Robert Sawyer. I enjoyed it. A good SciFi – to quote “A near-future philosophical SF story of first contact, quantum computing, and artificial intelligence” – i.e. lots of real science. I was following up the “Drake pictogram” when I found this:

Posted in Books & Movies, General | Leave a comment

MMANA and offcentre/offset antenna feedpoints – an easy way

One way of having off-centre fed antennas is to use 3 wires, e.g. 10m, 0.1m, 20m and feed the antenna at the centre of the very short segment, but there is an easier way that uses just a single wire.

You can specify the number of segments and the specify the feedpoint as a number, rather the just ‘w1b’, ‘w1c’ or ‘w1e’ (where b/c/e are beginning, centre or end).

It’s easiest to explaining using an example of a wire with a small number of segments:

#e.g. a 6m wire long, 1m up, 0.8mm radius, 4 segments

w1: 0,-3,1,    0,3, 1,   0.8,   4
feedpoint (sources/Pulse) = w1b2

A wire above with 4 segments has 5 nodes (possible feedpoints). They’re numbered from ‘-1′ to ‘n-1′ where ‘n’ is the number of segments.
e.g.
w1b-1   # beginning – the first coordinate (-1 really does work)
w1b0    # (that’s b zero), 25%
w1b1     # the centre
w1b2    # 75%
w1b3    # far end

Therefore if the number after the “b” is called the “feedpointNo”, we can get two useful equations:

fraction-along-wire = (feedpointNo+1)/no-of-segments

OR

feedPointNo = (fraction-along-wire * no-of-segments) – 1

A wire with 100 segments should be precise enough for most uses and is easy to work with.
If want to feed it 20% of the way along:

feedPointNo = (0.20 * 100) – 1      # as 20% is 0.20

so w1b19  is the feedpoint.

I found the reference to digits after the wire/pulse in the documentation somewhere. The above writeup sounds like I had it all clear in my mind, but your question prompted me to go and play with MMANA and define a wire with 4 segments and play to sort out the details. Apparently the number of segments must be even, you can have 4 or 6 segments, but not 5.

IMPORTANT: make sure that the feedpoint number is between -1 and n-2

  • if it’s n-1, the START button doesn’t seem to do anything, but there’s no warning
  • if it’s the same as the number of segments (or greater) the feedpoint vanishes, but the “Start” button does give an error message.

Do try the example above with 4 segments. As there are so few it’s very clear in the geometry view where the feedpoint is.

Giovanni – ZL2GX

Posted in Electronics, General, Ham Radio | Leave a comment

MUSE (Massey University Smart Home) Waterflow detector

MUSE (Massey University Smart Home) Waterflow detector

This software is designed to control the Arduino microcontroller on the water turbulence waterflow detector.

The idea is very simple – when water is flowing through a constriction (i.e. a tap), there’s turbulence and this makes a noise. Unlike most other noises in a home, this one is (for most uses of a tap) constant for more than a second.

An electret microphone is attached near a tap and the sound amplifed and applied to a threshold detector which is fed to one of the external interrupt inputs of the Arduino. The software detects when the noise begins and starts timing. If the noise doesn’t fall below the threshold for a definable period (say 1.5 seconds), then it sets the “waterflow detected” output.

This is susceptible to other constant noises in the room (e.g. a blender) but this can be ameliorated by some accoustic insulation on the microphone (bluetack maybe?).

For the intended environment, the presence of loud and constant noises is unlikely to be a problem.

This software is release under the terms of the GNU Public General Licence http://www.gnu.org/licenses/gpl.html.

I’ll upload the PC board and schematic shortly.

Giovanni Moretti
g.moretti@massey.ac.nz

/*
    Waterflow Detector for Massey University Smart Homes Research Project

    Accoustic Waterflow Detector Control Software
    Copyright (C) 2011 Giovanni S. Moretti

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <avr/sleep.h>
#include <avr/wdt.h>
#include <avr/power.h>

// Inputs
int noiseDetectPin  = 2;    //  D2 - Int0 - Pin 4
int noiseLossPin    = 3;    //  D3 - Int1 - Pin 5

// Outputs
int waterflowOutput = 4;    //  D4 - Pin  6 - Hi to turn on 2N7000
int waterflowLED    = 5;    //  D5 - Pin 11 - Low to turn LED on
int batteryCheck    = 0;    // ADC0 - pin 23 - To ADC to check battery
int arduinoLED      = 13;

//==============================================================================
#define  NOISE_DETECTED     1
#define  NOISE_LOSS         2
#define  TIMEOUT            3
#define  OUTPUT_ACTIVE      4
#define  PIN_GONEBACKHIGH   5
#define  UNKNOWNINTERRUPT   6
#define  ATTEMPTTOPULLFROMEMPTYQUEUE 7

//==============================================================================
// Which Interrupt is currently active - Waiting for HIGH or LOW?

volatile int activeInterrupt;
#define  WAITINGFORHIGH 1
#define  WAITINGFORLOW  2
#define  NONE           0

#define OFF LOW
#define ON  HIGH

volatile int watchdogTickCount;
#define WATCHDOGPERIOD WDTO_30MS
#define WATCHDOGTICKTHRESHOLD 60

//==============================================================================
// Debug LEDs on Arduino development board
void arduinoLEDOn()
{
  digitalWrite(arduinoLED, ON);
}

void arduinoLEDOff()
{
  digitalWrite(arduinoLED, OFF);
}

//==============================================================================
// Functions to enable/disable both the waterflowOutput which
//==============================================================================

void waterflowOutputActive()          // Signal Waterflow detected
{
  digitalWrite(waterflowOutput, HIGH);  // Hi to turn 2N7000 on for Monnit Sensor
  digitalWrite(waterflowLED,    LOW);   // Low to turn onboard diagnostic LED on
}

void waterflowOutputReset()             // Waterflow stopped
{
  digitalWrite(waterflowOutput, LOW);   // Hi to turn 2N7000 on for Monnit Sensor
  digitalWrite(waterflowLED,    HIGH);  // Low to turn onboard diagnostic LED on
}

//==============================================================================
// Noise Detection Interrupt - Int0
// Signal that we've heard something and start a two second timer

void noiseDetectionInterruptHandler()
{
   detachInterrupt(0);                                  // To stop repeated Interrupts
   watchdogTimerEnableWithInterrupts(WATCHDOGPERIOD);        // Start Timer
   watchdogTickCount = 0;
   queueEvent(NOISE_DETECTED);                          // Flag to be checked after wakeup
}

//==============================================================================
// Watchdog Interrupt Handler - Goes off every ~30mS if the NoiseInput
// is still active, increment a counter if the noise is still present
// and the counter gets to 1.5 to 2 seconds, signal WaterflowDetected,
// otherwise just disable timer
// ==============================================================================

ISR(WDT_vect) {
  queueEvent(TIMEOUT);
  if (digitalRead(noiseDetectPin) == LOW) // Still Noise
    {  
      if (watchdogTickCount < WATCHDOGTICKTHRESHOLD)
        watchdogTickCount++;
      else                            // Must be >= to Threshold
        {
          waterflowOutputActive();
          queueEvent(OUTPUT_ACTIVE);
        }

      // Start Watchdog timer for next sample of Noise Deteched Pin
      watchdogTimerEnableWithInterrupts(WATCHDOGPERIOD);  
    }
  else  // Noise Stopped - Pin is HIGH, disable output & reconnect interrupt handler
    {
      wdt_disable();
      queueEvent(NOISE_LOSS);
      waterflowOutputReset();
      watchdogTickCount = -1;
      attachInterrupt(0, noiseDetectionInterruptHandler, LOW);
    }
}
//==============================================================================
// Circular Queue: queue events under interrupt, and remove from the mainline

#define QUEUESIZE 25
volatile unsigned int hd, tl, count, tick = 0;
volatile unsigned int queue [QUEUESIZE];

void initEventQueue()
{
  hd = tl = count = tick = 0;
}

void queueEvent(int event)
{
  return;
  if (count >= QUEUESIZE) return;      // Queue is full, ignore event
  queue[hd++] = (event << 11) | watchdogTickCount;  // put item in queue
  if (hd == QUEUESIZE) hd == 0;        // point hd at next free slot
  count++;
  tick++;
}

int dequeueEvent()
{ int event;

  noInterrupts();
    if (queueSize() == 0)
      {
        interrupts();
        return(ATTEMPTTOPULLFROMEMPTYQUEUE);  // shouldn't ever happen
      }
    event = queue[tl++];
    if (tl == QUEUESIZE) tl == 0;
    count--;
  interrupts();
  return(event);
}

int queueSize()
{
  noInterrupts();
    int size = count;
  interrupts();
  return(size);
}

//=============================================================================
// Blink(n) - show a definable number of blinks for debugging.
//=============================================================================
void blink(int n)
{
  for (int i = 1; i<= n; i++)
    {
      arduinoLEDOn(); delay(400); arduinoLEDOff(); delay(250);
    }
  delay(1000);
}

//=============================================================================
// snooze - put the CPU to sleep, return when awoken
//=============================================================================
void snooze(int sleepState)
{
    delay(3);                      // Let any serial output finish
    set_sleep_mode(sleepState);    // sleep mode is set here
    sleep_enable();                // enables the sleep bit in the MCUCR register
                                   // so sleep is possible. just a safety pin
    sleep_mode();                  // GO TO SLEEP!
    sleep_disable();               // WOKEN UP
}

//****************************************************************
// Watchdog Timer Code from the Nightingale
// 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms
// 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
void setup_watchdog(int ii) {

  byte bb;
  int ww;
  if (ii > 9 ) ii=9;
  bb=ii & 7;
  if (ii > 7) bb|= (1<<5);
  bb|= (1<<WDCE);
  ww=bb;

  MCUSR &= ~(1<<WDRF);
  // start timed sequence
  WDTCSR |= (1<<WDCE)  ;// | (1<<WDE);
  // set new watchdog timeout value
  WDTCSR = bb | (1 << WDIE);
}

void watchdogInterruptEnable()         // Enable Watchdog Interrupts
{
  WDTCSR |=  (1 << WDIE);    
}

void watchdogInterruptDisable()          // Disable Watchdog Interrupts
{
  WDTCSR &= ~(1 << WDIE);
}

void watchdogTimerEnableWithInterrupts(int period)
{
  //  wdt_enable(period);
  setup_watchdog(period);
  //  watchdogInterruptEnable();
}
//==============================================================================
// Setup() - executed ONCE
//==============================================================================
void setup() {
 /*
    // Thanks to IONITO - http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1291420085

    // Prevent interrupts during this phase
    //     noInterrupts();

     // Temporarily turn off watchdog and kill watchdog if running
     wdt_reset();
     MCUSR = 0;
     WDTCSR |= _BV(WDCE) | _BV(WDE);
     WDTCSR = 0;

     // Turn OFF Analog parts
     ACSR = ACSR & 0b11110111 ;     // clearing ACIE prevent analog interupts happening during next command
     ACSR = ACSR | 0b10000000 ;     // set ACD bit powers off analog comparator
     ADCSRA = ADCSRA & 0b01111111;  // clearing ADEN turns off analog digital converter
     ADMUX &= B00111111;            // Comparator uses AREF/GND and not internally generated references

     power_adc_disable();           // redundant code if you check the above lines
     power_spi_disable();
     power_twi_disable();
     power_usart0_disable();        

     // Disabling timers:
     TCCR1B = 0b00000000;           // I need timer0 and timer; only timer1 is disabled

     // Put all I/O pins into input mode and internal pull-up

     for (int i=0; i<=13;i++)
       {
         pinMode(i, INPUT);
         digitalWrite(i, HIGH);
       }
*/
 //========================= End of snipped code ==================================

  // power_usart0_disable();  

  // Define the Input Pins
  pinMode(noiseDetectPin, INPUT);       // Single Pin Active Low ==> Noise Detected
  digitalWrite(noiseDetectPin, HIGH);   // turn on pullup resistor

  // Define the Output Pins
  pinMode(waterflowOutput, OUTPUT);
  pinMode(waterflowLED,    OUTPUT);
  pinMode(arduinoLED,      OUTPUT);        // Onboard LED on Arduino Uno

  // Blink All the LEDs as a startup/debug signal
  for (int i=1; i<= 5; i++) {
      arduinoLEDOn();    waterflowOutputActive();   delay(300);
      arduinoLEDOff();   waterflowOutputReset();    delay(300);
  }
  Serial.begin(115200);
  Serial.println("Giovanni's Waterflow Monitor");

  // All set up, now start mainline
  waterflowOutputReset();   // All outputs OFF

  initEventQueue();  

  //wait for a noise to occur:  Int0 - Pin 4 will go low
  attachInterrupt(0, noiseDetectionInterruptHandler, LOW);
}

//=============================================================================
//                    The eternally looping mainline
//=============================================================================
  void loop() {

    while (int currentCount = queueSize() > 0)
      {
        Serial.print ("QueueSize = "); Serial.print(currentCount);  

        unsigned int wakeupReason = dequeueEvent();
        unsigned int thisTick  = wakeupReason & 2047;
        unsigned int event     = wakeupReason >> 11;

        if (event == NOISE_LOSS)          Serial.println(" - Noise Loss: Timer stopped & Output Reset.");
        else
        if (event == NOISE_DETECTED)      Serial.println(" - Noise Detected: timer started ...");
        else
        if (event == TIMEOUT)            
          {
             Serial.print(" - Timeout");
             Serial.print (" - WD Tick: "); Serial.println(thisTick);
          }
        else
        if (event == OUTPUT_ACTIVE)         Serial.println(" - Waterflow Output Active");
        else
        if (event == ATTEMPTTOPULLFROMEMPTYQUEUE)
                                          Serial.println(" - attempt to pull from empty queue");   
        else
          {
            Serial.print(" - UnknownEvent Event "); Serial.println(event);
          }
      }
    //Serial.println("Sleeping ...\n");
    //    delay(400);
    snooze(SLEEP_MODE_PWR_DOWN);
    //Serial.println("WAKE UP");
}
Posted in Electronics | Leave a comment

RDiff-Backup

finding progress – use “lsof | grep rdiff-backup”

The lsof command lists open files …

Converting an existing directory to an rdiff-backup directory

This seems to work happily as long as the “–force” option is used

rdiff-backup --force --print-statistics  srcDir  existingCopyOfsrcDir

and simply creates the metadata as long as the file details are identical This means that their timestamps must match, not just their contents.

I was puzzled about this as I initially used “cp -R dir /tmp/dir” and it insisted on copying over the contents again, whereas using “rsync -av dir /tmp/dir” followed by the rdiff-backup only created the metadata. Naturally meld (a file/director content comparator) didn’t show any differences (it ignores timestamps). There was only the additional “rdiff-backup-data” directory, but puzzlingly even if it was deleted rdiff-backup seemed to know not to copy the files again. It finally clicked that the timestamps might be the cause.

What made me persist was the page that indicated this should work on backupcentral.com.

Posted in General | Leave a comment

Emacs IDO mode – a brilliant video

I’ve just been watching a tutorial video on the importance of uniform commands – ones you can use anywhere – centred around Emacs.

This is worth checking out http://www.vimeo.com/1013263

Interestingly enough (and it’s emphasised in the video), this sort of uniformity makes for great gains in productivity.

Posted in General | Leave a comment

An Inside Job. [Weekly Head Voices #33]

The interesting post below about scientific visualisation, music and the spread of ideas, and included this video with some really nice visualisations:

Darkstar: Gold from Evan Boehm on Vimeo.

The complete article is at
An Inside Job. [Weekly Head Voices #33].

Posted in General | Leave a comment

How to know/find out/see my ssh host key

Finding the host key fingerprint is useful for sorting out the SSH message about the host fingerprint message not matching the stored values and warning about man-in-the-middle attacks.

Here’s how to find the fingerprint from the public keys:

ssh-keygen -l -f /etc/ssh/ssh_host_rsa_key.pub
ssh-keygen -l -f /etc/ssh/ssh_host_dsa_key.pub
ssh-keygen -l -f /etc/ssh/ssh_host_key.pub

via How to know/find out/see my ssh host key.

Posted in Linux | Leave a comment

How to know/find out/see my ssh host key

How to know/find out/see my ssh host key.

This is useful when sorting out the SSH warning about a host-key being different from the stored value and warning about man-in-the-middle attacks.

To get the fingerprint from the public key, use one of:

ssh-keygen -l -f /etc/ssh/ssh_host_rsa_key.pub
ssh-keygen -l -f /etc/ssh/ssh_host_dsa_key.pub
ssh-keygen -l -f /etc/ssh/ssh_host_key.pub
Posted in General, Linux | Leave a comment