开发者

Determine true north

I am working on an Arduino device I am building. I have bought a GPS module and a tilt sensing compas with an accelerometer.

I wish to determine true north so that I can always point an object towards the sun. Basically I want the device to always find true north wherever it is. The GPS will give a position, the compass will find magnetic north. I guess the true north can be obtained during movement of开发者_JAVA技巧 the device and written to RAM then retrieved for use when the device is stationary.

But how?


Are you trying to get the most sun for your rotational solar panel? If so then you can get away with just rough position setting between East and West according to your clock (you can improve this with taking long/lat position into the account to calculate sun rise and sun set times). You will need a lot of astronomy calculations if you want to control both azimuth and elevation precisely. Arduino does not support double, and with single you will not have very accurate results (they will be enough for solar panel tracker, but not enough if you want telescope to track some sky object). My advice would be to either investigate a lot on the topic, or take a look at some open source astronomy software and extract the needed calculations from the source (if licence terms permit). Just to give you a hint, this is a small extract from PilotLogic TMoon component that you can get in CodeTyphon/Lazarus/FPC installation package found here:

procedure Sun_Position_Horizontal(date:TdateTime; longitude,latitude: extended; var elevation,azimuth: extended);
var
  pos1: T_Coord;
begin
  pos1 := sun_coordinate(date);
  calc_horizontal(pos1,date,longitude,latitude);
end;

function sun_coordinate(date:TDateTime):t_coord;
var
  l,b,r: extended;
  lambda,t: extended;
begin
  earth_coord(date,l,b,r);
  (* convert earth coordinate to sun coordinate *)
  l := l+180;
  b := -b;
  (* conversion to FK5 *)
  t := (julian_date(date)-2451545.0)/365250.0*10;
  lambda:=l+(-1.397-0.00031*t)*t;
  l := l-0.09033/3600;
  b := b+0.03916/3600*(cos_d(lambda)-sin_d(lambda));
  (* aberration *)
  l := l-20.4898/3600/r;
  (* correction of nutation - is done inside calc_geocentric *)
{   calc_epsilon_phi(date,delta_phi,epsilon); }
{   l := l+delta_phi; }
  (* fill result and convert to geocentric *)
  result.longitude := put_in_360(l);
  result.latitude := b;
  result.radius := r*AU;
  calc_geocentric(result,date);
end;

procedure calc_horizontal(var coord:t_coord; date:TDateTime; longitude,latitude: extended);
var
  h: extended;
begin
  h := put_in_360(star_time(date)-coord.rektaszension-longitude);
  coord.azimuth := arctan2_d(sin_d(h), cos_d(h)*sin_d(latitude)-
                             tan_d(coord.declination)*cos_d(latitude));
  coord.elevation := arcsin_d(sin_d(latitude)*sin_d(coord.declination)+
                              cos_d(latitude)*cos_d(coord.declination)*cos_d(h));
end;

If you had a case that your device is not moving after installation (which is not the case after I reread your question so you can ignore the rest of the message), then your longitude and latitude are fixed and you know them at compile time, or you can enter them manually when device is first installed. That way GPS is not needed. You can also find North once at installation time, so you don't need compass either.


Compass will get haywire when it gets near some magnetic material and will not be practical at all. You can calculate the azimuth and elevation of the sun with respect to your location. It is more practical to use some digital encoders with your system and make calculated incremental movements. A calibrate button on the arduino could be used to normalize the parameters using a standard tools. For fine tune, manual buttons could be provided for up and down movements.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜