Showing posts with label Arduino. Show all posts
Showing posts with label Arduino. Show all posts

Monday, 1 April 2024

The Importance of True Wind Direction for a Sailing Drone

 The Importance of True Wind Direction for a Sailing Drone - 4th Bass Strait Voyage

An opportunity arose on the evening of 22/3/2024 to commence a passage in Bass Strait from Torquay to Western Port. An 80km (50 mile) passage that would be expected to take around 48 hours.
The mission failed within a couple of hours, with the vessel running ashore before midnight of the same evening.


Torquay Fishing Beach 7pm launch


Conditions were calm as the vessel ran downwind to the lee shore.
The vessel was found with minor damage on the beach.
The first question was whether the damage occurred at sea and caused the failure of the mission, or whether the damage occurred when the vessel was beached.

The equipment housing was completely intact and the equipment was fully operational.
Later analysis of the log files contained on the SD Card showed that the failure was due to the sailing algorithms making bad decisions.


Midnight on the beach



Spot GPS Satellite position reports



The sailing algorithm aims to get the vessel to the next waypoint, while remaining within a maximum permissible cross track error (CTE) from the rhumb line. 
It does this by trying to sail the course, using the favoured tack.
If it can't make the waypoint directly, it will sailing until the CTE reaches the Maximum CTE (boundary) permitted for the current waypoint and then change tack.
If it is unable to directly sail for the next waypoint, it is assessing at all times whether it is able to reach the next waypoint directly on the other tack.

The determination of whether it is possible to sail directly to the waypoint on the other tack is a key issue.

Analysis of the logs showed the following:
  • The vessel could not quite sail directly to waypoint.
  • It gradually reached CTE Max on the leeward side of the course (port side of course) on starboard tack.
  • Having reached the boundary, it gybed on to port tack.
  • Then it reassessed the course to the waypoint  (if it were to change starboard tack) and decided it was directly sailable.
  • So, it gybed back on to starboard tack again, but it wasn't directly sailable, and it was still beyond Max CTE.
  • The process repeated.
  • The effect was to gybe and gybe again. effectively running downwind, until it beached on the lee shore.


Position Log from SD Card



The key issue was the wrong assessment of whether the waypoint could be directly reached on the other tack.
When racing sailing a full size yacht it can be tricky to assess when to tack to make the next mark without overlaying or underlaying.

The algorithm for assessing whether the waypoint can be reached directly on the other tack is as follows:
  • Compare the Bearing to Waypoint (BTW) with the True Wind Direction (TWD) less the minimum sailing angle from the wind, less an additional sailing margin.
  • The sailing margin is currently set to 25 degrees. This is effectively a measure of how much to overlay the mark before considering it is sailable.

Correctly estimating the TWD is critical for making correct decisions, and this was the source of the problem.

The determination of TWD is performed approximately as follows:
  • True heading of vessel (HDG_T),
  • less Apparent Wind Angle (AWA) 
  • less correction adjustments to include an approximation for boat speed..
So the main requirements for determining TWD is to measure an accurate vessel heading, and apparent wind angle.

The main problem with Voyager 2.7 was the accuracy of the magnetic heading.



The following plot illustrates the relationship between the vessel heading and the calculated AWD, as it was during the failed mission.
The plot was prepared from data recorded on the SD Card, while the vessel was rotated on a turntable to assist gathering measurements.

It shows that the AWD varied by up to 47 degrees with different headings.

AWD versus Heading as it was for the mission


The compass was upgraded by removing the UFSF Max IMU , and replacing it with the LSM303.
The improvements brought by the new compass, and careful calibration, and minor adjustments to the calculations greatly improved the results.

The resulting plot of AWD versus Heading after the upgrades performed, yielded significant improvements, as seen by the near flat orange line.

The variation of AWD was less the 6 degrees with heading completing three full turns.



AWD versus Heading after upgrades


Then end result should yield a much more accurate AWD and hence estimated TWD.
The next ocean voyage should be telling.





Thursday, 19 October 2023

Using Astrocast Astronode S+ with Teensy Microcontroller

Using Astrocast Astronode S+ with Teensy Microcontroller

The Astrocast Arduino library can be found here:

The library provides functions to interact with the Astronode device. Most of the functions return an integer which is interpreted as an enumerated type.
A good response is 24834, meaning ANS_STATUS_SUCCESS.

When using the Astrocast Arduino library with the Teensyduino library, many of the responses are  24835 ANS_STATUS_TIMEOUT, or 1 ANS_STATUS_CRC_NOT_VALID.

Extensive testing was performed using software debugging, an oscilloscope, a logic analyzer and continual comparison with other Arduino compatible devices that did not yield communications errors.
It took a long time to find the actual problem.

The Astrocast Arduino library makes use of the function:

size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length)

This function terminates if:
  • "length" characters have been read,
  • timeout, or
  • terminator character  detected.
The Astrocast library calls this function with a precisely calculated length, but expects to return on finding the terminator character.

Unfortunately, the implementation of this function differs between the Teensyduino library and other Arduino libraries, with the primary functional difference being the handling of the length parameter.



Teensyduino: readBytesUntil

The Teensyduino implementation decrements the length parameter before using it in the "while" loop test.


Arduino: readBytesUntil

The Arduino implementation uses the length parameter without modification.

The Astrocast Arduino library passes in a precisely calculated length parameter, even though it expects it to terminate based on finding the terminator ETX (03).

When used with the Teensyduino library the function terminates due to length and does not find the terminator character, so the result is considered invalid.
Then the next call to the function immediately finds the terminator character and returns; so the next result is considered invalid also.

The solution is simple once understood.
The Astrocast library does not need to pass in the precisely calculated length parameter, so the simplest solution is to increment the length parameter before passing it in, and then it works with both the standard Arduino libraries and the Teensyduino library.

 
Code snippet from Astronode.cpp - unmodified.




Code snippet of modified Astronode.cpp 





Satellite Communications with Voyager - Part 1

 Satellite Communications - Part 1

Its always been the plan to add Satellite Communications to Voyager to allow for telemetry and re-routing whilst at sea.
The decision has been made to use the Astronode S+ from Astrocast.

https://www.astrocast.com/products/astronode-s-plus/

Astronode S+


The Astronode device allows for small telemetry messages to be uploaded from the vessel every few hours and simple commands to be received.
It will operate from 3V3, with an average current draw of less than 1mA while waiting to transmit its messages.
The peak current while transmitting is around 80mA. These power requirements can easily be supported onboard Voyager.

A new controller for Voyager has been designed with the key changes being a change from the Teeny3.6 to Teensy4.1, as well as support for the additional serial connection to the Astronode S+ Sat Comms device.

Prototype Voyager Controller V4.0

Astrocast provide a software library for interacting with the Astronode S+ within the Arduino C++ environment.



I used the Astrocast Arduino Library to exercise the Astronode S+ device using various Arduino compatible devices. These mostly worked ok, but I was having problems with the Teensy devices.

This was a problem because the Teensy device was only one that had to work.

The Teensy devices should have been the most capable of the microcontrollers in use, but they continually returned errors when communicating with the Astronode S+ device using simple 9600Baud serial data.

It took several months of part-time testing and debugging in hardware and software to eventually track down the reason for the communication errors between the Teensy devices and the Astronode devices.

In short, it is due to the Teensy Arduino Stream library, within Teensyduino, having a slight difference in implementation to other Arduino Stream libraries. 
The difference is only highlighted in edge cases, and would rarely become apparent. The Teensyduino Stream library is around 5 years old, and has always had this specific characteristic.
The Astrocast Arduino Library makes use of the Stream library, but it exercises the edge case that highlights the difference between the Teensyduino and other Arduino libraries.

The precise details of the problem with the interaction between the  Astrocast Arduino library and the Teensyduino library are covered in the next post, along with the solution.



Friday, 17 June 2022

Wingsail Controller Evolution

 Wingsail Controller Evolution

The wingsail is mounted on ball bearing races, and must be able to freely rotate. It also has a trim tab that must be controlled.
My solution to this has been to develop a controller to operate a trim tab servo under the command of a radio signal of some type.

The Voyager Sail Controller is visible in the image of Voyager 2.0 sailing, as the green PCB in wingsail.


Voyager 2.0 with Sail Controller V1 fitted in the Wingsail 


The first designs used Bluetooth 4 as the communications link. The Voyager Sail Controller was set up as a Slave Bluetooth 4 device, connecting to the main Voyager Controller which was the Bluetooth  Master.
This worked well but the Bluetooth 4 modules had a continuous current drain of about 9mA while connected.


Prototype Wingsail Controller using Bluetooth 4



Voyager Sail Controller V0 using Bluetooth 4 - August 2018


Voyager Sail Controller V1 using Bluetooth 4 - March 2019


During 2019 we changed the main telemetry link to the vessel to be LoRa radio using the Ebyte devices. 
The Ebyte LoRa devices can be operated in a low power mode, where they wake up at predetermined intervals and check for a signal and then return to sleep. In practice, this yields an average current drain of around 6mA.
It also yielded the benefit that there are less components required on the Main Voyager controller, because the radio link to the wingsail is the same as the telemetry link to shore.
The only problem is the slow data rata rate and high latency. This yielded delays of around 1 to 2 seconds from when the wingsail should be responding.


Voyager Sail Controller V2 using LoRa Radio - May 2019

In 2022 the Bluetooth 5 module JDY-25M became available, and new Wingsail controller V4 was developed.
The JDY-25M Bluetooth 5 module has an idle current of around 1mA.
The low current consumption, combined with high data rate and low latency make a good option.

As of mid-2022, this is best version of the Wingsail controller yet.
When the wingsail is fitted with 2 x 2200mAHour 18650 cells, the wingsail has a projected battery life of at least 2 months.
This compares very well with the original Bluetooth 4 Wingsail controller having a battery life of around 8 days.


Voyager Sail Controller V4 using Bluetooth 5 - February 2022


Thursday, 25 July 2019

Wingsail Angle Sensor

Wingsail Angle Sensor 

The vessel does not have any explicit wind sensors for measuring wind speed or wind direction.
All sailing navigation decisions rely on knowing the angle of the self-trimming wingsail against the hull.
The wingsail angle is measured using the MPU9250 IMU as a magnetic sensor, and magnetic disk attached to the wingsail.
The MPU9250 may be an overkill for a magnetic sensor, however they do have benefits:
  • I2C bus, so it easily interfaces to the Arduino microprocessor.
  • Sensitive as a magnetic sensor, allowing good separation distance to the magnetic disk
  • The MPU9250 was difficult to use as an actual magnetic compass because it was difficult calibrate and use. They are easy to use as a magnetic angle sensor however. They are not expensive and I have a few to spare.

Wingsail Angle Sensor with Wingsail Magnetic Disk

 The housing for the Wingsail angle sensor is a 3D printed shape that is integrated with the Mast Tube deck plate. 
Magnetic Sensor Housing fixed in place. 
The magnetic disk is attached to the wingsail, so that the magnetic field created by the disk rotates with the sail The disk consists of a 3D printed holder for an array of about 60 cylindrical magnets 2mm diameter, 10mm long. Its obviously important that all of the magnets have the same orientation.

3D model of the Wingsail Magnetic Disk 

Future design changes:
  •  Integrate the Magnetic Disk more tightly with the Wingsail, possibly by incorporating it with the bottom foil section.
  • Add a duplicate MPU9250 Wingsail angle sensor for redundancy. 

Note: This is part of the ongoing development of a low cost autonomous oceangoing sailing drones, utilising a self-trimming wingsail. This is the Voyager series of sailing drones.

Thursday, 18 July 2019

Compass Heading Error Correction using GPS

Compass Heading Error Correction using GPS

(or GPS/Magnetic Compass Fusion)


Magnetic compass calibration is constant problem, but if we assume the GPS Course of Ground (COG) represents the actual heading of the vessel, then we can establish a difference between the two sensors, and apply a correction to the compass.
Of course, we can only assume the GPS COG is correct if we assume there is no movement of the water. That is, no tidal flow or currents.

The GPS COG is only valid when the GPS is moving. The COG provided by a stationary GPS device tends to point in all directions is has little meaning.
Hence, the COG can only be used to establish a Compass heading error if the GPS Speed of the Ground (SOG) is above a reasonable level.

The procedure below is currently in use, and forms Compass error value based on the GPS COG, when the SOG is greater than 0.2 m/s.
The resulting error is passed through a low pass filter to dampen its movement and then applied to the measured Compass Heading.


void NavigationUpdate_FastData(void)
{
 // Calculate True Heading From Magnetic Heading.
 // This is expected to be called from a fast loop .
 // about 50ms
 // V1.0 31/10/2016 John Semmens
 // V1.1 6/4/2019 added CompassOffsetAngle for handling mounting orientation
 // V1.2 11/7/2019 added Heading Error calculation and correction.


NavData.HDG_Mag = int(wrap_360(myIMU.heading + Configuration.MagnetVariation + Configuration.CompassOffsetAngle));

 // calculate and error value from the GPS and dampen it using low pass filter
 int RawHeadingError;
 if (NavData.SOG_mps > 0.2) // if the SOG is reasonable then assume the
 {
  RawHeadingError = wrap_180(NavData.HDG_Mag - NavData.COG);
 }
 else
 {
  RawHeadingError = 0;
 }

 // apply a low pass filter
 NavData.HDG_Err = HeadingErrorFilter.Filter(RawHeadingError);


 NavData.HDG = int(wrap_360(NavData.HDG_Mag - NavData.HDG_Err));

}



The GPS based compass correction has made a noticeable difference on the water.
The image below depicts the longest mission to date for the vessel. The wind is from the NNW.
The image clearly shows that the vessel has steered accurately to the waypoints on the downwind legs.
The longest course so far, incorporating GPS Based Compass Correction

The image below shows a similar, but shorter course, that was completed prior to the GPS based compass compensation.
The image shows that the vessel is steering significantly to the left as it approaches each waypoint that it can sail to without tacking.
A previous course successfully completed, without GPS compensation for the Compass 


And of course a photo from today's sailing...

Note: This is part of the ongoing development of a low cost autonomous oceangoing sailing drones, utilising a self-trimming wingsail. This is the Voyager series of sailing drones.

Sunday, 14 July 2019

New PCB for Bluetooth Sail Controller

New PCB for Bluetooth Sail Controller


The sailing trials continue in fresh water, but the aim is to put to sea.
The electronic systems need a lot of hardening to survive a saltwater environment.

One step in the process is the development of a dedicated PCB for the Wingsail controller.
The new PCB incorporates:
  •  On-board ATMega328p with the Arduino Pro Mini bootloader, rather than a separate Arduino module.
  •  Support for a Dual Servo Outputs, although only one is populated.
  • Support for switching an auxiliary 5Vdc load. I'm thinking of an LED Strobe or lights to aid night time operations.
  • Solar Charging circuitry using the LTC3105, also currently not populated.
The justification for adding solar charging to the Wingsail Controller is not great.
Testing suggests that the Wingsail Controller cells can operate for about 8 days on a single charge. The current Voyager Controller for can only operate for a couple of days in the current configuration. There will be more discussion on that in future posts as efforts are made to improve battery life, prior to engaging solar charging for the vessel.

The competed PCB operated faultlessly There were no errors in the PCB design, which is what is was worried about of course. For some reason, the Arduino takes an extra second or two to boot up when compared the prototype design using the Arduino Pro Mini module. It doesn't really matter, but I'd like to understand the reason, when I have time to investigate.

The competed PCB was sprayed with about a dozen coats of Conformal Coating to provide some protection from the environment.


 The new production Bluetooth Sail Controller PCB with conformal coating and mounted ready for installation in the wingsail.

































Note: This is part of the ongoing development of a low cost autonomous oceangoing sailing drones, utilising a self-trimming wingsail. This is the Voyager series of sailing drones.

Sunday, 23 June 2019

Electronic Compasses for Voyager

Electronic Compasses for Voyager

I'm losing count, but I think its about 5 different compass devices I've trialled during the development of the Voyager Controller - so far.

The image below shows a mild case of the problem of compass accuracy.
The leg with a bearing of about 350 degrees from first to second waypoints shows the boat heading off on a bearing of about 330 degrees with about 20 degrees error.
It still gets there, but its not good.

A successful voyage under motor, but poor compass accuracy

Measuring the boat's heading accurately has been quite difficult.
Overall, I suspect it all comes down to calibration, and the built-in mechanisms to manage calibration in a way that actually works in the environment in which it will be used.
The following is a list of the different compass devices that made it into the Voyager Controller and my thoughts about them.
These notes represent my understanding of what's going on. If I can be corrected, then good.

MPU-9250 - August 2016

This is quite a good low-cost IMU device for measuring 9 degrees of freedom including 3-axis magnetic sensing. It requires all sensor fusion and calibration management to be handled by the host processor.
The problem I had was that I could not get any sensor fusion and calibration software sample that I could find to work satisfactorily. (This may be attributed to my impatience or incompetence).
I'm sure it may be possible, but there are more complete (and expensive) devices available which perform the sensor fusion and calibration maintenance on board.

Note: I now use the MPU-9250 device as magnetic rotation angle sensors. This is where a rotating device (like the Wingsail) has a magnet held near the MPU-9250, and its angle is measured. The magnet can easily swamp the effect of the earth's magnetic field and the resulting accuracy of the rotational measurement seems to be within 1 or 2 degrees.

BNO 055 - October 2017

This was the first IMU I tried with built-in sensor fusion.
The sensor fusion worked quite well, but magnetic calibration was not being maintained and it kept drifting off.

BNO 080 - October 2018

This seems to have improved accuracy over the BNO 055. Its built-in calibration processes continuously seem to perform calibration of the compass as it moves.
The problem that I could not solve, was that it continues to perform those calibrations when its not moving then starts drifting off for no apparent reason.
The end result seems to be that with the boat sitting stationary on ground, and after preforming some calibration motions to achieve a high-level of calibration, it simply starts to drift off by 20 or 30 degrees.
My understanding is that this behaviour can't be controlled.

Ultimate Sensor Fusion Solution - LSM6DSM + LIS2MD - April 2019


This device has been the most successful yet.
It incorporates onboard sensor fusion processing and calibration management.
One key point is that the calibration is well controlled, and seems to be better behaved.
Small movements of the boat seem to be enough to maintain the compass calibration.
It is also possible to save a calibration state, and reload it for a warm start.
I found the documentation and sample code to operate this device couldn't be directly used in my environment without the need to gain a better understanding of the operation of the device. Once I had gained enough understanding of the device, I was able to alter the sample drivers software to suit my requirment. This wasn't really necessary with most of the other devices I've used.

Saturday, 25 May 2019

Minimal ATMega328P - common error

Minimal ATMega328P - common error  - won't run at 3V3.

I've started using ATMega328P as a minimal version  of the Arduino Pro Mini operating a 3Vdc.
I have been breadboarding circuits using the various articles published on the Internet as a guide for the minimal wiring required for running an ATMega328P as an Arduino.

The problem I suffered was that the circuits would happily run at 5Vdc, but stop running as the voltage was reduced to 3.3Vdc.

There seems to be a lot of discussion about the problem on forums; with almost none of it relevant to me.

Eventually I realised the silly mistake that I was making, by taking minimal circuits from Internet without checking the details for myself.

Many articles for minimal ATMega circuits leave AVCC open, rather than tying it to VCC.
If AVCC is left open, the ATMega will work at 5Vdc but will stop working at around 3.5Vdc.
Once connected to VCC, the ATMega will work below 3Vdc.

In my case, it worked down to about 2.7Vdc, which is one of the settings for the Brown Out Detector, so I suspect, that is what has come into play.





Friday, 24 May 2019

Slave I2C Interface for Serial GPS using Arduino Pro Mini 328P

Slave I2C Interface for Serial GPS using Arduino Pro Mini 328P


This post contains the code for creating a slave I2C device using an Arduino for a GPS receiver.
Hardware serial ports are precious on ATMega devices and I don't have enough available in my project to use on a GPS receiver, despite using an ATMega2560.
Software serial ports are often ok, but can suffer compatibility issues with other libraries in larger projects, and this has been prohibitive for me.
You can buy I2C GPS devices, and I do prefer to use them, but the one I was using failed, and I needed a quick solution to get my project back on the water without having to wait the 2 or 3 weeks for a replacement I2C GPS to arrive.
So, after an evening's research I was able to create a working I2C slave device using an Arduino Pro Mini 328P and integrate it with a regular serial GPS receiver.

The Arduino Pro Mini 328P running is at 16MHz and 3V3. Yes, I know its outside of specification with that combination of voltage and clock speed.

Overview

This simple sketch uses the very excellent TinyGPS++ to parse the GPS serial data and load the GPS object. Then we copy individual field values into our GPS structure which is mapped to linear Data buffer using UNION statement.
The Data buffer is then written out to the I2C interface in response to an I2C request.

Wiring

The Tx Pin from the GPS is connected to the RX pin of the Arduino Pro Mini 328P using a 1k resistor. This provides isolation to allow the Arduino to be programmed over the serial interface while the GPS is connected. If this were a direct connection, serial programming of the Arduino would not be possible without disconnecting the GPS.

Slave I2C GPS sketch


/*
    Name:       I2C_GPS.ino
    Created: 2 May 2019
    Author:     John Semmens
 Slave I2C Interface for Serial GPS using Arduino Pro Mini 328P
 ----------------------------------------------------------------
 Interface for converting a serial GPS to allow it to be used on an I2C bus.
 This uses the Arduino Pro Mini 328P running at 16MHz and 3V3. (Yes, i know its outside of specification!!!).
 This simple sketch uses the very excellent TinyGPS++ to parse the GPS serial data and load the GPS object.
 Then we copy individual field values into our GPS structure which is mapped to linear Data buffer using UNION statement.
 The Data buffer is then written out to the I2C interface in response to an I2C request.
 Wiring:
 The Tx Pin from the GPS is connected to the RX pin of the Arduino Pro Mini 328P using a 1k resistor.
 This provides isolation to allow the Arduino to be programmed over the serial interface while the GPS is connected.
 If this were a direct connection, serial programming of the Arduino would not be possible without disconnecting the GPS.
*/


#include <SPI.h>
#include <Wire.h>
#include "TinyGPS++.h"


// The TinyGPS++ object
TinyGPSPlus gps;


static const uint32_t GPSBaud = 9600;

#define  SLAVE_ADDRESS           0x29  //slave I2C address: 0x01 to 0x7F
#define  REG_MAP_SIZE            18 


// GPS variables
typedef union {
 struct {
  long Lat, Long;     // 2 x 4 bytes
  uint8_t Year, Month, Day;  // 3 x 1 bytes
  uint8_t Hour, Minute, Second; // 3 x 1 bytes
  int COG, SOG;     // 2 x 2 bytes SOG is in m/s
 };
 uint8_t Data[REG_MAP_SIZE];   //  = 18 bytes
} buffer_t;
buffer_t gps_data,buf;

boolean newDataAvailable = false;

void setup()
{
 Wire.begin(SLAVE_ADDRESS);
 Wire.onRequest(requestEvent);
 Serial.begin(GPSBaud);
}
void loop()
{
 while (Serial.available() > 0)
 {
  if (gps.encode(Serial.read()))
  {
   LoadRegisters();
   newDataAvailable = true;
  }
 }
}


void requestEvent()
{
 if (newDataAvailable)
 {
  for (int c = 0; c < (REG_MAP_SIZE); c++)
  {
   buf.Data[c] = gps_data.Data[c];
  }
 }
 newDataAvailable = false;
 Wire.write(buf.Data, REG_MAP_SIZE);
}


void LoadRegisters()
{
 gps_data.Lat = gps.location.lat() * 10000000UL;
 gps_data.Long = gps.location.lng() * 10000000UL;
 gps_data.COG = gps.course.deg() * 100;
 gps_data.SOG = gps.speed.mps() * 100; // m/s
 gps_data.Year = gps.date.year()-2000;
 gps_data.Month = gps.date.month();
 gps_data.Day = gps.date.day();
 gps_data.Hour = gps.time.hour();
 gps_data.Minute = gps.time.minute();
 gps_data.Second = gps.time.second();
 // Copy gps buffer to buf buffer
 for (int i = 0; i<REG_MAP_SIZE; i++)
  buf.Data[i] = gps_data.Data[i];
}


Master I2C Code Excerpt



void GPS_Read() {
 // V1.1 27/4/2019 Temp GPS reader for Temp I2C Arduino interface to a serial GPS



 Wire.requestFrom(0x29, 18);       // Ask for 18 bytes


 long Lat=0, Long=0;     // 8 bytes
 uint8_t Year =0, Month=0, Day=0;    // 3 bytes
 uint8_t Hour=0, Minute=0, Second=0; // 3 bytes
 int COG=0, SOG=0;     // 8 bytes


 for (int i = 0; i<4; i++)
  Lat = Lat | (long)Wire.read() << (i * 8);


 for (int i = 0; i<4; i++)
  Long = Long | (long)Wire.read() << (i * 8);


 Year = Wire.read();
 Month = Wire.read();
 Day = Wire.read();
 Hour = Wire.read();
 Minute = Wire.read();
 Second = Wire.read();


 for (int i = 0; i<2; i++)
  COG = COG | Wire.read() << (i * 8);


 for (int i = 0; i<2; i++)
  SOG = SOG | Wire.read() << (i * 8);


 NavData.Currentloc.lat = Lat;
 NavData.Currentloc.lng = Long; 


 // get the date and time from GPS into CurrentTime object.
 CurrentUTCTime.year = Year;
 CurrentUTCTime.month = Month;
 CurrentUTCTime.dayOfMonth = Day;
 CurrentUTCTime.hour = Hour;
 CurrentUTCTime.minute = Minute;
 CurrentUTCTime.second = Second;


 // get course and speed directly from GPS
 NavData.COG = ((float)COG/100);
 NavData.SOG_mps = ((float)SOG / 100);

};

Saturday, 1 December 2018

Voyager 2.0 Angle Sensor for Wingsail







Friday, 2 November 2018

Voyager 2.0 Bluetooth Controller for Wingsail Servo

Voyager 2.0 Bluetooth Controller for Wingsail Servo




Friday, 23 February 2018

Voyager 2.0 Controller Evolution

Voyager 2.0 Controller Evolution

This series of photo illustrates the evolution of the Voyager Controller design so far.

November 2016 - They're not called "Breadboards" for nothing

October 2018 - Veroboard Design




January 2019 - More compact and robust 3D Printed Chassis

January 2019
March 2019 - New PCBs  !!


April 2019 - The first dedicated PCB Design



Sunday, 29 May 2016

Arduino Servo Endurance Tester

How long do RC servos last ?

The RC servo manufacturers don't seem to publish any information about the operational life span of their servos. The life span of a servo will be influenced by the amount of loading, both static and dynamic. But there'is a fundamental limit which is the number of cycles with no load.
It seems that the quality of feedback potentiometer, rather than the drive train or motor is the limiting factor for the maximum number of cycles an RC servo can perform.

This is a design for a very simple RC Servo exerciser to cycle a servo 20 degrees either side of neutral about once per second. It includes an I2C LCD 2 line by 16 character display to display a count of cycles.
Servo Test Rig showing Arduino Nano, I2C LCD and Test Servo

The code for the Arduino is provided below:


#include "LiquidCrystal_I2C.h"
#include <Wire.h>
#include <Servo.h>

Servo myservo; // create servo object to control a servo
int pos = 0; // variable to store the servo position

// Set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x27, 16, 2);

long CycleCounter = 0;
int BasePosition = 90;

void setup()
{
 
// attach the servo on pin 9 to the servo object
  myservo.attach(9);

  // initialize the LCD
  lcd.begin();

  // Turn on the blacklight
  lcd.backlight();
  lcd.clear();
}

 void loop()
{
 
myservo.write(BasePosition); // tell servo to go to Base Position
  delay(400);
 

  myservo.write(BasePosition+20); // move + 20 degrees
  delay(300);

  myservo.write(BasePosition-20); // move - 20 degrees
  delay(300);

  CycleCounter++;
  lcd.setCursor(0, 0);
  lcd.print(CycleCounter);
}
 



The YouTube clip below shows the test rig in operation with an initial test using a low cost servo. It lasted for about 40,000 cycles before failure. I'll discuss the results of servo tests in another post.