Communications between Python and Arduino (USB-Serial)

In this post we’ll implement the basic communications between the PC and Arduino for our purpose. Also we’ll use the coordinate transformation with Arduino to implement a program that receive the equatorial coordinates as input, and then returns the azimuthal equivalent as output.

For the moment we can obtain these coordinates with Stellarium. With this data, we’ll implement a Python script to communicate with Arduino to establish the reference objects and then calculate the azimuthal coordinates (Az/Alt in Stellarium) from the equatorial ones for any object. It will be a kind of Arduino based “USB coprocessor” to coordinate transformation. Although as coprocessor it will be as unuseful as curious, I think 🙂

We’ll use the serial port provided by the Arduino Serial library for the communications, and they are going to consist mainly in a set of commands with parameters that returns the results to the Python script. These commands have a predefined structure: four characters of length, and a variable number of parameters and results. For the moment we just need the followings:

  • time‘ (float t) -> () Sets the initial observation time
  • set1‘ (float ar, float dec, float t, float az, float alt) -> () Sets the reference object 1
  • set2‘ (float ar, float dec, float t, float az, float alt) -> () Sets the reference object 2
  • goto‘ (float ar, float dec, float t) -> (float az, float alt) Calculates and returns the local coordinates (azimuthals) from the equatorial ones.

We start with the Arduino implementation. First, the following code snippet is enough to receive in Arduino one command from the PC:

For the parameter reception we’ll use a function which receives the characters by the serial port and returns the value as a float, ready for the math operations:

We have to take into account that the horizontal angle in the azimuthal coordinates (az) are counter-clockwise, unlike that in the equatorial ones. We’ll correct this value in the parameter reception.

With these pieces and the code for coordinate transformation I have in github (CoordsLib.h y CoordsLib.cpp) we can complete the software to receive and execute commands. To load Arduino with the software we must to place both files and the following sketch in the same folder:


Now we go with the Python script in the PC side. We’ll use a “Testing” class which contains the necessary methods to send commands with their parameters from a Python console (to which I recommend iPython: in Ubuntu, apt-get install ipython):

Now we can use Stellarium to get the equatorial coordinates of some objects, two as references and a few more to test the conversions. The following table shows the name, equatorial coordinates, measure time and the azimuthal coordinates of a bunch of celestial objects. I’ve chosen the Polar and Vega stars as references, both easy to find in the sky. For the rest, we’ll use the equatorial coordinates to obtain the azimuthal ones and check whether they are the same that Stellarium shows.

Initial time and date: 22:02 - Thursday, August 9th, 2012
Latitude:	N 37° 24' 0.01"
Longitude:	W 5° 58' 48.00"

__Obj__		__AR/DEC (J2000)__	__T__		__Az/Alt__

Polaris		2h31m49s/81º15'51''	22h04m20s 	0º27'09''/36º49'17''
Vega		18h36m56s/38º47'03''	22h05m07s	78º10'04''/70º05'19''

Altair		19h50m47s/8º52'07''	22h06m11s	114º36'45''/41º30'22''
Lagoon Nebula	18h03m48s/-24º23'00''	22h06m52s	163º02'47''/26º15'16''
Mars		13h17m55s/-8º29'04''	22h07m51s	240º18'46''/21º04'41''

With this values, and taking into account the Testing class methods, we can build the following instructions sequence:


If we execute this sequence in an ipython console, we’ll obtain the following results:

In [1]: from testing import *

In [2]: t = Testing()

In [3]: t.init()

In [4]: t.setTime("22h02m0s")

In [5]: t.setRef(1 , "2h31m49s", "89º15'51''", "22h04m20s", "0º27'09''", "36º49'17''")
SEND:	+0.662425/+1.557954 - +5.778494 - +0.007898/+0.642654

In [6]: t.setRef(2 , "18h36m56s", "38º47'03''", "22h05m07s", "78º10'04''", "70º05'19''")
SEND:	+4.873541/+0.676911 - +5.781912 - +1.364285/+1.223277

In [7]: t.goto("19h50m47s", "8º52'07''", "22h06m11s")
SEND:	+5.195772/+0.154786 - +5.786566
RECV:	2.000384/0.724421	(114º36'49'' / 41º30'23'')

In [8]: t.goto("18h03m48s", "-24º23'00''", "22h06m52s")
SEND:	+4.728970/-0.425569 - +5.789548
RECV:	2.845698/0.458214	(163º2'47'' / 26º15'13'')

In [9]: t.goto("13h17m55s", "-8º29'04''", "22h07m51s")
SEND:	+3.481568/-0.148081 - +5.793839
RECV:	-2.088903/0.367851	(240º18'53'' / 21º4'35'')


As can be seen, the obtained values for Altair, the Lagoon Nebulae and Mars, are very close to the Stellarium values (by the way, at the moment of write this post -the original in Spanish-, three days before the Curiosity rover landed on Mars!! 🙂).

Well, we already have that “Arduino based USB coprocessor” ( 😉 ) to transform equatorial coordinates into local ones, and viceversa.
Así que bueno, ya tenemos ese “co-procesador USB” ( 😉 ) basado en Arduino para transformar coordenadas ecuatoriales en locales, y vice versa.


Tagged . Bookmark the permalink.

2 Responses to Communications between Python and Arduino (USB-Serial)

  1. Alex Petrov says:

    Hello. I try to reproduce your project and I’ve some issues with converting coordinates from Horizontal to Equatorial. I am embarrassed by this particular line (in getECoords func.):

    (*ar) = atan2(EVC[1], EVC[0]) + (_k*(t-_t0));

    atan2 returns value in the range [-pi:pi] and you add the time. What the point? Now the value neither in radians nor in degrees. Can you explain more detailed this.

    Thanks a lot.

  2. Alex Petrov says:

    I’ve realized that I was totally wrong. It is not adding the time, but hour angle. And hour angle measured in radians!!! All works perfectly, thanks for your code!

Leave a Reply

Your email address will not be published. Required fields are marked *