Overview
Everyone has a GPS these days in your smartphone and they are amazing. Military grade technology in the hands of everyone.
We have received various inquiries about being able to trigger GoPro’s based on a GPS position. I myself had thought about rigging a GPS up to the camera when I went skiing - so it would automatically start filming at the top of the mountain, stop when I stopped, even turning the camera off when it worked out I was now going back up the mountain due to the change in altitude (ie going up hill quite quickly!) and therefore must be on the ski lift.
I was looking through my many boxes of parts the other day and came across a UBlox GPS module I had picked up a while ago. I also came across a 16x2 LCD screen shield for Arduino that I had recently bought from my favourite Chinese supplier websites (DX.com or BangGood) but hadn’t yet tried out.
A perfect excuse to put both into action.
The CamDo Blink enables remote control of your GoPro via the motion detector input. But instead of a motion detector, we instead use the Arduino microcontroller to trigger it in response to the GPS position and associated calculations.
I decided to implement a useful tool for bushwalkers or cross country skiers. It’s not really feasible (or indeed that interesting) to take video of an entire hiking trip, but taking a photo every 500m or 1km is a different matter. Alternatively you could also set a time lapse controller like Blink to take a photo every 10 minutes and not worry about distance but that’s too simple!
There are plenty of applications for this, basically any of the data that a GPS can generate (or that you can infer / calculate) can be used. eg :
- Take a photo when I am in proximity to a certain landmark
- Take a photo every x seconds when I am travelling above or below a certain speed
- Take a photo every x metres (the example we have implemented in this blog post)
Before we get into it, you might also be interested in our post here onHow to interface your GoPro to a Radio Control which uses our Bullet controller product to interface to an RC controller or our post here onHow to interface your GoPro to a microcontroller (Arduino, ESP8266, etc) using Blink. Both have good background information on the signal interface to trigger the camera, so we won’t go into the same detail in this post.
All of the code can be found on our Github page here.
Hardware Setup
The basic hardware setup is as follows:
Parts required:
- 1 x Arduino/Genuino UNO R3 (genuine) / (replica) or similar
- GoPro camera (HERO4 or HERO3+Black)
- 1 xCamDo Blink time lapse controller
- 1 x16x2 Arduino LCD Keypad Shield
- 1 xUBlox GPS Module or similar (DFRobot has one with a case)
- 3.5mm TRS audio stereo cable
- 5V power supply eg a V15 or V44 battery if you are going hiking.
For the UBlox GPS used in the parts list, the pinouts and connections are as follows:
Pin Name |
Color |
Description |
Arduino Connection |
PPS |
White |
time standard pulse output |
No connection |
VCC |
Red |
Power Supply Input 3.3V-5.V |
5V |
TX |
Blue |
UART/TTL Interface |
Arduino Pin 0 (serial Rx) |
RX |
Green |
UART/TTL Interface |
Arduino Pin 1 (serial Tx) |
GND |
Black |
GND |
GND |
EN |
Yellow |
Enable Pin.The device is in shutdown mode when voltage to this pin is LOW and enabled when HIGH or floating |
5V. Technically it can be left floating but for reliability tie it to VCC. |
In addition to this, we need to make the connections to the CamDo Blink controller which are as follows, using the 3.5mm TRS connector.Take your 3.5mm stereo cable and check which of your bare wires is connected to the Sleeve, Ring and Tip. You can use a multimeter continuity test to check.Note that the colours in the diagram above are indicative only and will depend on your cable.One of the cheapest ways to get a cable is to just buy an audio extension cable and cut it to the length you require and strip the ends. Pin-out /connections are as follows:
Pin Name |
Color |
Description |
Arduino Connection |
Tip |
N/A |
+5V power supply |
No connection |
Ring |
Purple |
Signal Input |
Digital Pin 2 |
Sleeve |
Black |
GND |
GND |
Whilst we are not connecting the Tip (+5V) to anything, you could actually use that as the power supply to the Arduino, which in turn provides it to the GPS. This port can provide up to 350mA at 5V but only if USB power is supplied to Blink via the mini USB port on the side (the Arduino/GPS combination only uses about 100mA). It is probably simpler though to just use an external battery and provide power to both Blink and the Arduino via the USB ports.
The connections are straightforward, but if you are just making this on your bench for fun you might find it easier to use a breadboard. Depending on the connections you get with your particular GPS (any GPS with serial output will work for this project), a small piece of proto board could also be used. There are also some Arduino models out there that include proto board on the PCB so you can solder directly to the Arduino which is handy for this sort of project.
Here is a pic of my initial test using a breadboard.
![GPS GoPro Arduino breadboard setup](http://cdn.shopify.com/s/files/1/0906/7602/files/breadboard_setup_reduced.jpg?v=1503906546)
Software Setup
This assumes using the Arduino IDE. If you are using something else, you probably don't need the instructions below!Steps are as follows:
- Install the Arduino IDE fromarduino.cc.
- Once installed, complete the following:
- Download the project files from our Github page here.
- Open the fileCamDo_LCD_GPS.ino
- Import the TinyGPS Arduino library into the Arduino IDE.
- In the Arduino IDE, just go to “Sketch → Include Library → Add .ZIP Library.
- Now exit and restart the IDE, as otherwise you won’t see TinyGPS in any of the IDE menus.
- Once you have restarted, you will see “TinyGPS” under the “Sketch → Include Library” menu, all the way down the bottom under “Contributed Libraries”. You will also see it under “File → Examples”. There is no need to do anything else, the IDE can now see the library when it compiles the project. Adafruit also has a good guidehere regarding libraries in general if you are interested in more info.
-
Plug the Arduino into your PC, select the COM port (under Tools) and hit Tools-> Upload. All going well it should compile straight away and upload.
Note: that you need to disconnect the GPS Tx/Rx pins to upload the sketch as it will interfere with the serial interface to your computer. Once upload, reconnect the GPS to pins 0 and 1 and away you go.The LCD screen will provide feedback as to the status of the GPS signal - if it says No Signal, then double check you have re-connected.
Hopefully it all uploaded and you are getting messages on the LCD screen rotating through at the refresh rate we set above (set by the displayInterval variable - default is 1 second). It should look something like this:
Once you have it working, let's look at a few features in the code to give you a basic understanding and let you edit to suit your requirements.
Arduino Sketch - Basic Structure
The code is fairly well commented so we’ll just touch on the highlights here.
All basic sketches follow the same structure:
- Variables
- Setup/Initialisation
- Main Loop
In addition to this there are all of the routines we call from the main loop to complete the various tasks.
Variables
All of the variables that you may want to adjust for your particular project sit at the top. You may want to adjust the following:
int triggerDistance = 50;
The distance in metres between triggering photos. Set to a low number for testing (50m). Can be changed here and also via the LCD buttons (just hold down left or right. The current setting will be displayed.)
const float pauseSpeed = 2.5;
In kmph - this is the speed below which the distance measured is paused to help remove some of the GPS noise when standing still. If we don't build something like this in, the GPS inaccuracy (couple of metres) makes it look like you are still moving if you just stopped for lunch etc.
const long timeInterval = 5000;
Similar to the pauseSpeed above, this 5 sec time interval is for smoothing GPS data (measured in milliseconds). This sets how often the new GPS position and distance travelled calculated in the checkDistance() routine.
const long displayInterval = 1000
Time to display each message on the LCD before rolling to the next message. Default is 1 second (1000 msec).
Setup / Initialisation
Setup is short and sweet. We create the GPS and LCD screen objects, initialise them, plus initialise some of the variables.
Main Loop
The main loop is the core of the program and runs continuously. It is structured as follows:
- Read in and intrepret GPS data. It uses the TinyGPS librarywhich is a great library for reading and interpreting NMEA data from any serial based GPS module. It is well explained at the authors sitehere. It is worth a read as you may want to change the functionality and trigger the camera in a different way. There are a number of pieces of code included in the sketch but commented out with some of the extra/alternate commands available. Eg currently speed is reported back in km/h - you might like to change this to miles/per hour which is easy to do by uncommenting the line in the checkDistance() routine.
- If valid data has been read in, check the distance travelled and display appropriate messages. If not, alert the user that there is no GPS fix yet.
- Check for button presses on the LCD keypad and take the appropriate action.
- Repeat!
checkDistance() routine
Once we have all the GPS information we need, the main logic is dealt with in the checkDistance() routine.
First it checks if it is time to check the distance again (set by the timeInterval variable). If not it exits straight away.
If however it is time to check the distance, it takes a new measurement and adds it to the previous distance travelled. At the same time, your current position is updated. If the threshold is reached (set by the triggerDistance variable), the camera is triggered, the distance reset and the number of photos variable is updated for display on the screen.
LCD Messages
The messages in the screenshots above will cycle across the LCD screen. The amount of time each message is displayed can be altered by changing thedisplayInterval variable at the top of the sketch in the variable declarations. The default is set to 1000 msec = 1 second.
LCD Keypad Functionality
The 16x2 LCD keypad Arduino shields are great value and can be picked up for under $10.
We use it on this project to report back the current latitude and longitude, what distance has been travelled since the last photo, the number of photos taken, the current speed and the the number of satellites the GPS can see. It also reports back if the GPS data appears stale or when there is no GPS reception at all.
One caveat: depending on where you buy it from, the pin-outs can be different. For the unit I picked up, the pin-out was different to the default pin-out in the standard Arduino LCD display library. Lines 17-25 in the Arduino sketch provide the instructions to change the pin-out if you are having issues. It looks like there are 2 x products generally available with different pin-outs - both are included in the code so you can just swap the pins over if you are having an issue.
/******** LCD driver pins ********
note these pins are different to the defaults in the Arduino LiquidCrystal library examples.
you may need to change back to the Arduino defaults depending on the model LCD 16x2 display you get.
**********************************/
// uncomment the following line if you are having trouble with your display (Arduino defaults)
// const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
// comment out the following line if you go back to the Arduino defaults above.
const int rs = 8, en = 9, d4 = 4, d5 = 5, d6 = 6, d7 = 7;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7); // initialise the display library
One of the nice things about these modules is the set of keypad buttons. The sketch assigns the following functionality to the buttons
- pressing UP or DOWN will fade the display backLight up / down.
- pressing SELECT will turn the screen ON / OFF.
- pressing LEFT or RIGHT will increase or decrease the camera trigger distance (distance is in metres)
Thanks to the DX.com forum for the outline sketch to pick up which button has been pressed.
Note you may have to hold the button for a small amount of time to get it to respond (as the processor gets tied up reading in the next batch of GPS data so is not taking any action to the button press during that time), but generally it worked pretty well.
CamDo Blink Settings
The final piece of the puzzle is to make sure that the Blink GoPro controller is going to respond to the input on Port 2 from the Arduino.
All we need to do is setup a PIR/External Input (Motion Detector) schedule, which will cause the camera to wake-up and take a photo (or a video if you set it that way) on each trigger from the Arduino/GPS combo.There are detailed instructions for setting up Blink here. If you don’t already have a Blink, you could also use the CamDo Bullet to trigger the camera which
So there you have it, now you can trigger your camera in response to a GPS signal. We have implemented a distance calculation in this post, but it can be easily modified in response to other location based calculations such as proximity to a landmark, when travelling over a certain velocity, etc.
Hope you enjoyed it, please share your projects with us by emailingmarketing@cam-do.com.