I'm using a Raspberry Pi with a GY-80 orientation sensor to turn my basic SkyWatcher EQ2 mount into a computer assisted "Push To" telescope - which can pass this information to planetarium software like SkySafari on my iPad/iPhone. To do this I've written a little Python script (telescope_server.py) which runs on the Raspberry Pi, and translates the orientation sensor information into RA/Dec angles. The Raspberry Pi listens to Meade LX200 (or Nexstar) serial protocol commands received over TCP/IP, and responds with the orientation information.
|SkySafari Plus v4, showing telescope direction from a Raspberry Pi|
Indoor testing has gone well so far... I can rotate the Raspberry Pi and watch the blue cross-hairs on SkySafari change position. The locations look sensible (and drift naturally due to sidereal rotation). There is a bit of jitter which may need some smoothing.
Part of the idea came from reading how easy it is to have SkySafari talking to telescope via a Raspberry Pi running a WiFi to serial port bridge (similar blog post), mimicking SkySafari's expensive but neat SkyFi box. I was also impressed with Simon Box's instrumented Dobsonian telescope (measuring altitude-azimuth angles directly) connected to Stellarium (Update: and this similar instrumented telescope project called scopebox), and Leon Rozengarten's project building an Arduino telescope controller using the HMC6352 and ADXL345 sensors (video, code).
This project meant integrating lots of different stuff - serial communication protocols, I2C sensor chips, Inertial measurement unit (IMU) / Attitude and heading reference system (AHRS) calculations, quaternion mathematics for rotations, sidereal time, angle conversions, etc. Here are a few notes... my Python script telescope_server.py is on GitHub.
Mounting the Raspberry Pi
Because I wanted a case with some form of external mounting, I went for the Cyntech "BerryBlack" Raspberry Pi case - plus the optional SD card cover. The red and green logo RPi stands out nicely, and the light pipe for the LEDs is very well done. I was able to mount this quite stably to the telescope tube via a piece of wood attached to the camera screw thread on the O-rings.
|Two screws ready to hang the Raspberry Pi on||Raspbery Pi attached to SkyWatcher telescope tube|
However, for outdoor use, note the Cyntech case is not air or water tight - for a start the slot for the GPIO cable is wide open. Also the two screw slots on the back are not fully enclosed - there is an air/water gap to the back of the board. I may have to do something about this to avoid dew getting inside...
Meade LX200 Protocol
This is a well established and widely used protocol for communicating with a computerised telescope using serial commands. It is also well documented, see Meade Telescope Serial Command Protocol (2010), see also Meade Telescope Serial Command Protocol (2002) and this alternative page (sometimes clearer).
The commercial SkySafari SkyFi box seems to use a standard approach (RFC 2217) for transmitting serial connection data via TCP/IP (i.e. a normal network connection), which can be done in software using ser2net on Linux. This means writing code to listen on a network port for Meade LX200 commands was actually quite straightforward. In my code I focussed on implementing enough of the commands for Sky Safari Plus v4 to connect, set the time and location, get the orientation - and behave nicely if any of the goto or slew commands are sent. SkySafari also handles alignment by sending a sync command to the (Raspberry Pi pretending to be a) telescope.
Celestron Nexstar Protocol
Celestron have released the Nexstar Protocol documentation. It is a similar serial protocol, and works over TCP/IP in the same way. In some ways it seems better designed than the Meade LX200 protocol - for example the RA/Dec angles are always sent as pairs.
Since Sky Safari Plus v4 can also connect using this protocol, I tried this too. Surprisingly SkySafari only uses a small handful of the commands and interestingly does not send sync commands to the telescope - it seems to do a local calibration itself instead. I'm sticking with the Meade LX200 protocol instead (see below for more details).
Measuring the Celestial Angles
The telescope communication protocols use two important celestial angles: the right ascension (equatorial axis) paired with the declination, which must be calculated from the local altitude and azimuth angles taking into account the latitude, longitude and time. See for example sidereal.py for how this works.
I'm using a combined gyroscope/accelerometer/magnetometer orientation sensor. Without caring about the telescope mount type etc, this can give me the altitude and azimuth angles - although most relevant documentation instead talks about yaw, pitch and roll angles.
IMU and AHRS code
Using the axis terminology for planes there are three rotational axes: roll (rotation about X-axis, direction of flight), pitch (lateral rotation about Y-axis), and yaw (rotation about Z-axis). In general planes fly horizontally, so the yaw is typically a compass bearing and maps to the telescope's azimuth. Similar the roll can be interpreted as the rotation of the eyepiece/camera, while pitch would be the telescope's elevation (i.e. the altitude angle).
For the yaw, the accelerometer is useless (the values don't change, gravity is just down) so we must combine the gyroscope and compass data. For the most part the Earth's magnetic field is nearly horizontal, but I suppose in principle the compass data is also of some limited use for the pitch when pointing roughly North or South. However, for the pitch and roll, it is normal to just combine the accelerometer and gyroscope data.
See for example this page on how a quadcopter can get its orientation, Raspberry Pi AHRS by David Grayson (core code in minimu9-ahrs.cpp), and FireTail AHRS software (for Arduino) based on this (core core in ahrs.cpp, FireTail is an autopilot for RC aircraft). There are lots of cool hobby projects out there using these kinds of sensors!
For the angle calculations I decided to play with quaternions, this page on IMU maths with quarternions was very helpful - as was Christoph Gohlke's Python quarternions code. I'm currently using a simple complementary filter putting 98% of the weighting on the gyroscope, and 2% on the accelerometer and compass. There are more advanced IMU approaches including Sebastian Madgwick's IMU/AHRS sensor fusion algorithm.
Using SkySafari Plus
Here's my SkySafari v4.0.1 telescope setup on the iPad or iPhone:
- Scope Type: Meade LX-200 GPS (see note below)
- Mount Type: Equatorial Push-To (see note below)
- Auto-Detect SkyFi: Off (I'm currently testing via ethernet)
- IP Address: The Raspberry Pi's IP address, or helpfully just the host name
- Port Number: 4030 (default, but must match the Raspberry Pi setting)
- Set Time & Location: On (see note below)
- Readout Rate: 4 per second (default)
- Save Log File: Off
|SkySafari Plus v4 on iPad, telescope connection settings||SkySafari Plus v4 on iPad, connected as "Push To" telescope|
|SkySafari Plus v4 on iPhone,|
telescope connection settings
|SkySafari Plus v4 on iPhone,|
connected as a "Push To" telescope
|SkySafari Plus v4 on iPhone,|
connected as a "GoTo" telescope
The exact mount type does not seem important, only if it is "Push-To" or "GoTo". If you select "Push-To" then the "GoTo" button and rate control are inactive. If you select "GoTo" these controls are live, and additional Left/Right and Up/Down buttons appear on the side of the screen. Since the iPad/iPhone is multi-touch, you can use these together at the same time. If you did have motors on the telescope connected to the Raspberry Pi, it should be possible to extend telescope_server.py to control the telescope this way.
In order to do the angle conversion, the Raspberry Pi needs to know the location (latitude and longitude) and time zone. If running a Raspberry Pi offline (e.g. from batteries away from the house) it won't know the date and time. Connecting a GPS to the Raspberry Pi is one solution, but from a usability point of view it seems simplest to just set this via SkySafari (especially if using an iPad or iPhone with a GPS).
However, if you configure the Scope Type as "Meade LX-200 Classic" then SkySafari v4 takes an extra 15 seconds or so for the connection. Using one of the other Meade settings like "Meade LX-200 GPS" avoids this and connects really quickly while setting the location and time information. Here's a sample of the output seen during connection (location redacted) when running my Python script telescope_server.py on a Raspberry Pi:
Connecting to sensors...
Connected to GY-80 sensor
Opening network port...
Starting up on 192.168.1.102 port 4030
Local site now latitude XX.XXXd, longitude X.XXXd
Local site timezone now -0.0
Local site timezone now -0.0
Requested site time 14:42:20 (TZ -0.0), new offset 1s, total offset 1s
Effective site date/time is 2014-01-25 14:42:20.964108 (local/GMT/UTC)
Requested site date 01/25/14 (MM/DD/YY) gives offset of 0 days
Effective site date/time is 2014-01-25 14:42:21.090983 (local/GMT/UTC)
Oddly, if the Scope Type is set to one of the Celestron NexStar models, then SkySafari v4 doesn't actually seem to try to set the location or time. This is one reason why I'm sticking with the Meade LX200 protocol instead.
With a target selected in SkySafari, pressing the align button should update the telescope mount tracking to be centred there. With the NexStar protocol SkySafari seems to do this itself (and only allow relatively small offsets to be used). With the Meade LX-200 protocol, SkySafari sends the revised orientation to the telescope with a sync command, and the telescope mount itself recalculates the calibration. This seems like a really neat user interface, which Simon Box uses on his project.
The Meade LX200 protocol includes commands for controlling a motorised focuser - but as far as I can see, SkySafari doesn't support this. If it did, I might be tempted to connect my Tasco 1603EF focuser to the Raspberry Pi as well.
To Do List
Improve the Raspberry Pi mounting. It currently has some give, so may need bracing to prevent any knocks while in use throwing off the calibration by a few degrees. Also this is too far away from the eyepiece to connect the Raspberry Pi add-on camera via its ribbon cable, but a USB cable to a web camera or DSLR should be fine...
Sensor calibration, see for example AndrewBirkett's post on calibrating the HMC5883L compass, another interesting post on compass calibration (from a group working on DIY robot lawn mowers), and these maths heavy posts on Gauss-Newton for sphere fitting (part 2, part 3, mcUSense on GitHub).
A refinement (or alternative) would be to capture photos from a webcam or DLSR on the telescope and run a plate solver (e.g. using astrometry.net's software), to report exactly where the telescope is pointed. Plate solvers can be sped up by providing an approximate orientation, so this orientation sensor could help there.
Multi-star calibration, probably with SkySafari as the front end using the Meade LX200 protocol's sync commands. This will be important if the sensor chip's X-axis isn't perfectly aligned with the telescope's line of sight. Initially I'm just use one-star alignment to correct the azimuth angle which depends on the offset between true North and the compass bearing.
Reduce cable clutter by switching from ethernet to wifi, ideally freeing me from the house wifi network (Update: done, using a mini USB WiFi dongle which supports use as an Access Point).
Further reduce cable clutter by tapping a 5V supply for the Raspberry Pi from the 6V supply for the SkyWatcher EQ2 sidereal motor?
And of course, test this outdoors for real... ;)
Update - Code Feedback
Can people check for or report any problems with the code on the issue tracker on the GitHub page please?