Saturday, 21 May 2016

Voyager 1 - The Build

Voyager 1 was planned as a quick build and launch of a relatively uncontrolled boat to test the out various technologies and design ideas in the lead up to the development of more sophisticated boats.

Voyager 1 is a 1.5 metre sailing vessel that used Vane Steering to control its direction. The Vane Steering was set to steer the boat almost downwind, with the wind about 20 degrees on the starboard quarter.

The aim was to launch the boat from the south-east corner of Australia at a time when the westerly winds would take it out into the Tasman Sea in a south westerly direction. Hopefully it would travel south of New Zealand in the Southern Ocean.

The actual path of Voyager 1 can followed here ww2.acaciacs.com.au/voyager1

The hull for Voyager 1 was not specially built for this task, It is actually a third-hand hull from a catamaran. It was built by Doug Hemm, then given to Jeff Gray, and then given to me (All members of Royal Yacht Club of Victoria).

Third-hand Catamaran Hull
The first task was to strip off the deck and remove centreboard in preparation for fitting out the hull as a monohull.
Balsa bulkheads were fitted, and an aluminium frame was added which incorporated a centerplate casing.
Mounting points were added for mounting the Vane Steering gear and also for securing payload. The payload is the modified SPOT GPS satellite tracking system described in an earlier posting here.
Hull fitted with New Aluminium Centreplate Frame, Bulkheads and Equipment Mounts  
A small hull will always leak.
If it is to remain afloat for months, then it must be intrinsically buoyant, regardless of leaks. This was handled by using expanding foam filler.
Expanding foam is not the best foam to use for buoyancy. It is not a closed cell foam, and if structure surrounding the foam flexes, then the foam will crush and become water-logged.
In this case, there weren't a lot of choices and so expanding foam was used.
Expanding Foam added before trimming back
Most of the detailed components in Voyager 1 were fabricated in ABS plastic using 3D Printer. The images below show the Vane Steering Gear and the equipment mounts mostly fabricated in ABS plastic.
Version 1 of the Vane Steering Gear and Rudder
Version 2 of the Vane Steering Gear


Voyager 1 with the Extra Long Keel, prior to first Sea Trial

 

Part 3 - Arduino Software for Controlling the SPOT GPS Gen 2

Arduino Software for Controlling the SPOT GPS Gen 2

This post provides the actual software used in the Arduino Nano for controlling the SPOT GPS Gen 2.
The whole system has had extensive testing for about 6 months on land before commencing trials at sea.

/*
 SPOT GPS Gen 2 Controller
 This controller is designed to activate the SPT GPS Gen 2 at predetermined intervals.
 It is intended to operate for many months on battery power.

 It uses a state machine to control transitions into different states.

 Alternate between pressing the ok button and the custom message button.
 This is intended to improve overall reliability. on the basis that if one message function fails, may be the other one will work.

 Power is minimized by using a sleep state, and using an 8 second watch dog timer.

Wiring Details
 --------------             ------------------------------
 | Arduino     |           |      SPOT GPS Gen 2          |
 | Nano        |           |                              |
 |  D9  Pin xx |----47kR-->|  Power Switch                |
 |             |           |                              |
 |  D12 Pin xx |<---47kR---| 3Vdc Switched (power sense)  |
 |             |           |  TP(unmarked)                |
 |             |           |                              |
 |  D10 Pin xx |----47kR-->| Ok Message Switch            |
 |             |           |                              |
 |  D11 Pin xx |----47kR-->| Custom Message Switch        |
 |             |           |                              |
 |             |           |                              |
 |             |           |                              |
 |         Gnd |-----------| Gnd                          |
 --------------             ------------------------------

 V1.0 16/8/2015 John Semmens Initial Version
 V1.1 30/8/2015 Near final release.  Adjusting timing constants.
 V1.2 3/9/2015 timing adjustment for 4 hours.

 */

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

const byte LED = 13;
int counter8s; // global variable as counter.

const byte SpotOnOffButton = 9;
const byte SpotOn3VSense = 12;
const byte SpotOkMsgButton = 10;
const byte SpotCustomMsgButton = 11;

const int kSpotOffTime = 1720; // x 8 seconds // 830 = 2 hours
// 1740 = 4 hours + 3 min
// 1720 = 4 hours-3minutes  --- this must be wrong... it must be about 4 hours. 8am 4/9/2015

const int kSpotOnTime = 38;    // x 8 seconds // 38 = about 5 min

enum SpotGPSState_Type
{
    Power_Off,
    Power_On,
    Sending_Ok,
    Power_Off_2,
    Power_On_2,
    Sending_Custom
};

SpotGPSState_Type SpotGPSState;
int q8SecondBlocks;

// watchdog interrupt
ISR(WDT_vect)
{
    wdt_disable();  // disable watchdog
} 

void setup() {
    counter8s = 0;
    SpotGPSState = Power_Off;
    q8SecondBlocks = 1;
}

void loop()
{
    EightSeconds();

    // disable ADC
    ADCSRA = 0;

    // clear various "reset" flags
    MCUSR = 0;
    // allow changes, disable reset
    WDTCSR = bit(WDCE) | bit(WDE);
    // set interrupt mode and an interval
    WDTCSR = bit(WDIE) | bit(WDP3) | bit(WDP0);    // set WDIE, and 8 seconds delay
    wdt_reset();  // pat the dog

    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
    noInterrupts();           // timed sequence follows
    sleep_enable();

    // turn off brown-out enable in software
    MCUCR = bit(BODS) | bit(BODSE);
    MCUCR = bit(BODS);
    interrupts();             // guarantees next instruction executed
    sleep_cpu();

    // cancel sleep as a precaution
    sleep_disable();
}

void EightSeconds()
{
    // We arrive here every 8 seconds approx
    // Perform the "action()" at intervals of aprroximately 8 seconds x k8SecondBlocks
    // Typical values:
    //          7 = 1 minute
    //        106 = 15 minutes
    //        424 = 1 hour
    //        833 = 2 hours
    //        1000 = 2 hours 22 minutes (measured)
    //       1700 = 4 hours

    counter8s++;
    if (counter8s >= q8SecondBlocks)
    {
        counter8s = 0;
        action();
    }
}

void action() {
    // Process the state machine

    switch (SpotGPSState)
    {
    case Power_Off:
        Spot_Turn_On();
        SpotGPSState = Power_On;
        q8SecondBlocks = 1; // "on" time before moving to next state, about 8 sec
        break;

    case Power_On:
        Spot_Message_OK();
        SpotGPSState = Sending_Ok;
        q8SecondBlocks = kSpotOnTime; // "send ok message" time before turning off. 38 = about 5 min
        break;

    case Sending_Ok:
        Spot_Turn_Off();
        SpotGPSState = Power_Off_2;
        q8SecondBlocks = kSpotOffTime; // "off time" before turning on again.
        break;

    case Power_Off_2:
        Spot_Turn_On();
        SpotGPSState = Power_On_2;
        q8SecondBlocks = 1; // "on" time before moving to next state, about 8 sec
        break;

    case Power_On_2:
        Spot_Message_Custom();
        SpotGPSState = Sending_Custom;
        q8SecondBlocks = kSpotOnTime; // "send Custom message" time before turning off. 38 = about 5 min
        break;

    case Sending_Custom:
        Spot_Turn_Off();
        SpotGPSState = Power_Off;
        q8SecondBlocks = kSpotOffTime; // "off time" before turning on again.
        break;

    default: // should not get here.
        Spot_Turn_Off();
        SpotGPSState = Power_Off;
        q8SecondBlocks = kSpotOffTime; // "off time" before turning on again.
    }
}

void Spot_Turn_On()
{
    // Procedure to simulate pressing the power on button on the spot - to turn it on.
    // it waits for the feedback from the Spot device in the form of a switched 3Volt signal.

    // check if its off by looking for 3V sense signal low
    pinMode(SpotOn3VSense, INPUT);
    if (digitalRead(SpotOn3VSense) == LOW)
    {
        // press the on/off button.
        pinMode(SpotOnOffButton, OUTPUT);
        digitalWrite(SpotOnOffButton, LOW);

        // turn the led on
        pinMode(LED, OUTPUT);
        digitalWrite(LED, HIGH);

        // wait for power sense 3V signal
        pinMode(SpotOn3VSense, INPUT);
        while (digitalRead(SpotOn3VSense) == LOW)
        {
            delay(100);
            wdt_reset();
        }

        // release on/off button.
        digitalWrite(SpotOnOffButton, HIGH);
        pinMode(SpotOnOffButton, INPUT);

        // turn led off
        digitalWrite(LED, LOW);
        pinMode(LED, INPUT);
    }
}

void Spot_Turn_Off()
{
    // Procedure to simulate pressing the power on button on the spot - to turn it off
    // it waits for the feedback from the Spot device in the form of a switched 3Volt signal.

    // check if its on by looking for 3V sense signal
    pinMode(SpotOn3VSense, INPUT);
    if (digitalRead(SpotOn3VSense) == HIGH)
    {
        // only turn it off if its on already

        // press the on/off button.
        pinMode(SpotOnOffButton, OUTPUT);
        digitalWrite(SpotOnOffButton, LOW);

        // LED on
        pinMode(LED, OUTPUT);
        digitalWrite(LED, HIGH);

        // wait for power sense 3V to drop to zero
        pinMode(SpotOn3VSense, INPUT);
        while (digitalRead(SpotOn3VSense) == HIGH)
        {
            delay(100);
            wdt_reset();
        }

        // release on/off button.
        digitalWrite(SpotOnOffButton, HIGH);
        pinMode(SpotOnOffButton, INPUT);

        // turn led off
        digitalWrite(LED, LOW);
        pinMode(LED, INPUT);
    }
}

void Spot_Message_OK()
{
    // Procedure to simulate pressing the "I'm OK" button on the Spot Device.
    // It uses a simple 4 second delay before releasing.

    // press the OK Message button.
    pinMode(SpotOkMsgButton, OUTPUT);
    digitalWrite(SpotOkMsgButton, LOW);

    // LED on
    pinMode(LED, OUTPUT);
    digitalWrite(LED, HIGH);

    // hold down OK button for 4 seconds
    delay(4000);

    // release OK Message button.
    digitalWrite(SpotOkMsgButton, HIGH);
    pinMode(SpotOkMsgButton, INPUT);

    // turn led off
    digitalWrite(LED, LOW);
    pinMode(LED, INPUT);
}


void Spot_Message_Custom()
{
    // Procedure to simulate pressing the "Custom Message" button on the Spot Device.
    // It uses a simple 4 second delay before releasing.

    // press the "Custom" Message button.
    pinMode(SpotCustomMsgButton, OUTPUT);
    digitalWrite(SpotCustomMsgButton, LOW);

    // LED on
    pinMode(LED, OUTPUT);
    digitalWrite(LED, HIGH);

    // hold down OK button for 4 seconds
    delay(4000);

    // release "Custom" Message button.
    digitalWrite(SpotCustomMsgButton, HIGH);
    pinMode(SpotCustomMsgButton, INPUT);

    // turn led off
    digitalWrite(LED, LOW);
    pinMode(LED, INPUT);
}


Part 2 - Configuring an Arduino Nano for Ultra Low Power Operation

Configuring an Arduino Nano for Ultra Low Power Operation

The Arduino Nano is good, low cost microprocessor for simple jobs.
With small modifications to the standard Arduino Nano, and with the appropriate software design, it possible to operate an Arduino Nano for periods approaching one year on a pair of AA alkaline Cells.

Without modification a standard Arduino Nano would probably only last a few weeks on AA batteries.

The physical modifications to reduce the power consumption of the Arduino Nano are as follows:
  • Remove the Power LED labelled PWR in the upper image below.
  • Remove the 5V Linear Regulator shown in the lower image below.
  • Connect 3Vdc power to the connections labelled 5V and GND in the upper image below.
Note: Operating current is considerably reduced by running at 3Vdc compared to 5Vdc.

Top View and Bottom View of the Arduino Nano



The key software design issues for running an Arduino in Ultra Low Power are as follows:
  • Disable the Analog to digital Converter
  • Disable the Brown-Out detection
  • Use Sleep mode
  • Use the Watch Dog Timer (WDT) to wake the microprocessor, to perform the operation and then return to sleep.
  • The maximum time the WDT can operate is about 8 seconds.


Some example code is provide below, that simply flashes the LED approximately every 8 seconds.
Between the 8 second flashes, the current consumption was measured at approximately 66uA with a 3Vdc supply.  


#include <avr/sleep.h>
#include <avr/wdt.h>
const byte LED = 13;
// watchdog interrupt
ISR(WDT_vect )
{
        wdt_disable();  // disable watchdog
}  // end of WDT_vect
void setup() { }
void loop()
{
       pinMode(LED, OUTPUT);
       digitalWrite(LED, HIGH);
       delay(50);
       digitalWrite(LED, LOW);
       pinMode(LED, INPUT);

        // disable ADC
        ADCSRA = 0;
        // clear various "reset" flags
        MCUSR = 0;
        // allow changes, disable reset
        WDTCSR = bit( WDCE) | bit( WDE);
        // set interrupt mode and an interval
        //WDTCSR = bit(WDIE) | bit(WDP2) | bit(WDP1);    // set WDIE, and 1 second delay
        WDTCSR = bit( WDIE) | bit( WDP3) | bit( WDP0);    // set WDIE, and 8 seconds delay
        wdt_reset();  // pat the dog
        set_sleep_mode(SLEEP_MODE_PWR_DOWN );
        noInterrupts();           // timed sequence follows
        sleep_enable();
        // turn off brown-out enable in software
        MCUCR = bit( BODS) | bit( BODSE);
        MCUCR = bit( BODS);
        interrupts();             // guarantees next instruction executed
        sleep_cpu();
        // cancel sleep as a precaution
        sleep_disable();
} // end of loop
 

References:
The following website provides good information on running an Arduino using low power techniques.

https://hwstartup.wordpress.com/2013/04/15/how-to-run-an-arduino-clone-on-aa-batteries-for-over-a-year-part-2/



Part 1 - Modifying a Spot Gen 2 GPS for Long Duration Automatic Operation

SPOT GPS devices are part of a low cost service for reporting a position almost anywhere on the Earth's surface.
Earlier model Gen 2, SPOT GPS devices, can be purchased second-hand for less than AUD $60. on eBay.

Second-hand Spot Gen 2 from eBay
This post covers how I modified a GEN 2 SPOT for long duration automatic operation, suitable for deployment on board a small model boat. The aim is to modify the SPOT GPS to send a signal at regular intervals (4 hours was chosen) and operate on batteries for many months.

At the time of writing, this modified SPOT GPS Gen 2, is located approximately 350km east of Sydney, in the Pacific Ocean, and still working well.






Tear down

Front of PCB Assembly
showing Patch Antenna, Switches and LEDS


Rear of PCB Assembly


The modifications to the SPOT device consist of:
  • Using an Arduino Nano microcontroller to activate the SPOT GPS every four hours.
  • Packaging the new assembly in water tight container for deployment on a model boat.
The details of the Arduino software development will be covered in Part 2 of this post.

The SPOT GPS is normally operated by pressing buttons to switch it on, and selecting a message type to send, and switch it off.
The microprocessor is used to simulate pressing the buttons and also observes whether the device is currently on or off. This is necessary, because the action to turn on the SPOT GPS is exactly the same action required to turn it off. A human operator can observe the LEDs flashing an know that it is turned on. The microprocessor needs the same insight.

The following is an outline of the minimal steps to be performed by the microprocessor to cause the SPOT GPS to transmit a signal.

Minimal Operating Steps
Step 1
SW5: POWER ON  - hold for about 5 seconds .
LED2: POWER LED - Flashes Green every 3 seconds while powered on
 
Step 2 
SW4: Send OK Message.  - hold for about 5 seconds
LED5: OK Message LED - Flashes Green every 3 seconds 
or 
SW6: Send Custom Message.  - hold for about 5 seconds
LED8: Custom Message LED - Flashes Green every 3 seconds 
 
Step 3 
Once a message has been sent "Message Sent " 
(Note: there is no means of acknowledgment of message being received)
LED4: Message Sent - Flashes Green every 3 seconds once a message has been sent.
Note all three green LEDS appear to flash in unison every 3 seconds.
 
Step 4 
SW5: POWER OFF  - hold for about 5 seconds .
LED2: POWER LED - ceases flashing every 3 seconds

PCB Notes
The following section covers observations about SPOT GPS Gen 2 PCB with details relating to how a microprocessor would interact with it.

Inner Rings of all switches are ground.

Outer rings can be pull low to ground to activate switch function.

 

The LEDs are bi-colour Red/Green LEDs with grounded cathodes. The ends marked with an arrow on the PCB are the grounded ends.
 

Front of PCB showing Push Button Switches and LEDs


Rear of PCB showing Test Points with colour coding to indicate their purpose

Test Points marked RED are linked to the RED LED Anodes
Test Points marked GREEN are linked to the Green LED Anodes.
Test Points marked BLUE are linked to the Button outer rings.
 
3uA is the measured current flow when the button rings are grounded.
(@3V implies 1MOhm)
 
 
The connections between the Arduino Nano and the SPOT GPS Gen 2 are as follows:
 
Wiring Details
 --------------             ------------------------------
 | Arduino     |           |      SPOT GPS Gen 2          |
 | Nano        |           |                              |
 |  D9  Pin xx |----47kR-->|  Power Switch                |
 |             |           |                              |
 |  D12 Pin xx |<---47kR---| 3Vdc Switched (power sense)  |
 |             |           |  TP(unmarked)                |
 |             |           |                              |
 |  D10 Pin xx |----47kR-->| Ok Message Switch            |
 |             |           |                              |
 |  D11 Pin xx |----47kR-->| Custom Message Switch        |
 |             |           |                              |
 |             |           |                              |
 |             |           |                              |
 |         Gnd |-----------| Gnd                          |
 --------------             ------------------------------

 

The image below shows the battery connections: BAT1- and BAT1+.
It also shows an unmarked Test Point which provides a switched 3Vdc signal, which provides a 3Vdc signal only while SPOT GPS is on.
This unmarked Test Point is very important because it is the simplest way for the Arduino microprocessor to determine whether the SPOT GPS is on or off.
Rear of PCB showing Battery Connections and the Unmarked 3Vdc Switched signal used to indicate that the device is On.
Power Supply 
The SPOT GPS is normally powered using three lithium AAA Cells. These cells have an open circuit voltage of about 1.8Vdc, or 5.4Vdc for three of them. 
 
It was decided to power the SPOT GPS using four AA Alkaline Cells with a combined open circuit voltage of 6Vdc.
I did have a slight concern about operating the SPOT GPS at a slightly higher voltage compared to its unmodified form, but it has been tested continuously in this configuration for over 10 months without any problems.  
 
The Arduino Nano is powered separately with pair of AA Alkaline Cells yielding 3Vdc.
 
The Assembled SPOT GPS with Arduino Nano and Battery Pack ready for packaging.

Enclosure - Sistema

The Complete Assembly prior to the final Silicone Sealing 

 

The modified SPOT GPS with the Arduino Nano and Battery power supply were packed into 300ml Sistema food container, along with about 100g of Silica Gel desiccant to absorb any moisture.

The Sistema Food containers are a good, low cost housings for electronic projects, with an effective lid closure mechanism. They are not fully water tight, however.
It is necessary to use a sealant to ensure they a fully water tight.

Ordinary silicone sealers purchased from the local hardware store must not be used in confined spaces with electronic equipment. The chemicals released during the curing process is typically acetic acid which is quite corrosive and harmful to small electronic components. The local hardware stores do supply a range of silicone sealer types, including some described as "Neutral Cure". But these are still not suitable for use with electronics.

I use the Silicone Sealant of type Alkoxy. It is safe for use with electronics in a confined space and does not cause corrosion of electronic components. It is only available from specialist suppliers.
Dow Corning Silicone Sealant 798 is an example of Alkoxy type Silicone Sealant. 


Dow Corning 798 Silicone Sealant

Monday, 16 May 2016

Long Duration Voyages for Small Unmanned Boats

As a teenager I watched the Voyager spacecraft send photos of the outer planets back to Earth.
I've always liked the idea of sending machines off to places where we can't go. 
I can't launch a spacecraft, but I can send model boats into our oceans on long duration voyages.
There are quite a few projects attempting to cross oceans with autonomous boats, but one of the most professional examples that provides me with inspiration is saildrone. The Saildrone company is based near San Francisco and produces well designed, well made sailing drones that are 19 feet in length.

saildrone - State of the art ocean going drone


This blog is intended to follow the path I'll take as a hobbyist in the development of sailing drones and perhaps other types of ocean going drones.

Voyager 1 is the first trial in what is expected to be a series of models designed to cross oceans. 

As of May 2016, its about 200 nautical miles east of Sydney, and has travelled 800km from the launch point in 2 weeks.
The voyage of Voyager 1 is plotted here http://ww2.acaciacs.com.au/voyager1.


Voyager 1 - Sea trials on Port Phillip
http://ww2.acaciacs.com.au/voyager1
The Voyage of Voyager 1 - click on live map 











 The details of Voyager 1 will be covered in other posts to follow.