【C语言】计算实时太阳角度(高度角、方位角),以及使用stm32单片机实时获取时间戳

news2024/11/17 19:38:47

整体计算方法

在编写该代码的过程中寻找了多篇博文和论文,综合所有文章且按网上的以0时的方位角的0°,且随时间累加累加至360度。我修改了博文和论文的一些角度的计算方法。得到一下代码与网站计算的方位角相互验证过,误差不超过1°
验证网站

太阳赤纬角

在这里插入图片描述
n为该天在当年的序号
另一种方法没尝试成功:
在这里插入图片描述
代码如下读者可以自行尝试,我没尝试成功

	int n, n0;
	double t, theta, delta;

	// 计算n和n0
	n = month * 30 + day;
	n0 = 79.6764 + 0.2422 * (year - 1985) - ((year - 1985) / 4);

	// 计算t
	t = n ;

	// 计算θ(日角)
	theta = 2 * M_PI * t / 365.2422;

	// 计算δ(太阳赤纬)
	delta = 0.3723 + 23.2567 * sin(theta) + 0.1149 * sin(2 * theta) - 0.1712 * sin(3 * theta)
	        - 0.758 * cos(theta) + 0.3656 * cos(2 * theta) + 0.0201 * cos(3 * theta);

太阳时角

在这里插入图片描述
时角这里的话中午时时角为0下午时角为负,可以简化为时角=15*(t-12)
不过这里计算的是时区的时间,不是当地时间所以存在误差,我怀疑代码计算的误差大部分都是出自这里
当地时角位于东7区的换算方法: (120度 – 当地经度) * 4,1个小时15度,平均下来,1度4分钟。
时角=15*(t-12)+(120-经度)

太阳高度角

在这里插入图片描述
通过上述两个方程,即可求出高度角的各个参数。

太阳方位角

在这里插入图片描述
h为太阳高度角
Φ为纬度数据
σ为太阳的赤纬角

代码部分

C语言三角函数运算

因为角度计算涉及大量三角函数,所以C语言的三角函数计算不可避免需要使用。

C语言的三角函数计算函数

需要包含头文件#include <math.h>

  double __cdecl sin(double _X);
  double __cdecl cos(double _X);
  double __cdecl tan(double _X);
  double __cdecl asin(double _X);
  double __cdecl acos(double _X);
  double __cdecl atan(double _X);
  double __cdecl atan2(double _Y,double _X);

其中sin、cos、tan 函数的参数是一个用弧度表示的角度,分别返回这个角度的正弦、余弦、正切值。度和弧度都是衡量角的大小的单位。度用 ° 来表示,弧度用rad表示。

1度=π/180 弧度 ( ≈0.017453弧度 )

asin()、acos、atan 函数分别返回它们的参数的反正弦、反余弦、反正切值。功能刚好和sin、cos、tan 函数相反。

赤纬角计算

通过公式:
在这里插入图片描述

/********************************************************************************************************************************************
*@*名称 : Declination_Angle_Calculation
*@*功能 : 计算太阳赤纬角
*@*形参 : YearData年数据	DayData日数据
*@*返回值 : DeclinationAngle太阳赤纬角 
*********************************************************************************************************************************************/
static double Declination_Angle_Calculation(double Daydata,short YearData)
{
	double DeclinationAngle;
	DeclinationAngle = 23.45 * sin((Daydata-80)/370.0 * 360*PI/180);		//赤纬角公式 
	
	return DeclinationAngle;												//返回赤纬角 
}

时角计算

通过公式:
时角=15*(t-12)

/********************************************************************************************************************************************
*@*名称 : Hour_Angle_Calculation
*@*功能 : 计算太阳时角
*@*形参 : HourData小时数据 
*@*返回值 : HourAngle太阳时角 
*********************************************************************************************************************************************/
static double Hour_Angle_Calculation(double HourData)
{
	double HourAngle;
	
	HourAngle = 15*(HourData-12);
	
	return HourAngle;
	
}

太阳高度角计算

通过公式
在这里插入图片描述

/********************************************************************************************************************************************
*@*名称 : Height_Angle_Calculation
*@*功能 : 计算太阳高度角
*@*形参 : LatitudeData纬度数据		HourData小时数据 	DeclinationAngle赤纬角数据 
*@*返回值 : ElevatingAngle太阳高度角 
*********************************************************************************************************************************************/
static double Height_Angle_Calculation(double LatitudeData,double HourAngle,double DeclinationAngle)
{
	double ElevatingAngle;													//高度角
	double ElevatingAngle_sin;												//高度角正弦值
	
	double DeclinationAngle_sin = sin(DeclinationAngle * PI / 180);			//赤纬角的正弦值 
	double DeclinationAngle_cos = cos(DeclinationAngle * PI / 180);			//赤纬角余弦值 
	double LatitudeData_sin = sin(LatitudeData * PI / 180);					//纬度正弦值 
	double LatitudeData_cos = cos(LatitudeData * PI / 180);					//纬度余弦值 
	double HourAngle_cos = cos(HourAngle * PI/180);
		
	ElevatingAngle_sin = (DeclinationAngle_sin*LatitudeData_sin) + (DeclinationAngle_cos*LatitudeData_cos*HourAngle_cos);
	ElevatingAngle = asin(ElevatingAngle_sin)*180/PI;
	return ElevatingAngle;
}

太阳方位角计算

通过公式
在这里插入图片描述

/********************************************************************************************************************************************
*@*名称 : Azimuth_Angle_Calculation
*@*功能 : 计算太阳方位角
*@*形参 : ElevatingAngle太阳高度角		HourAngle太阳时角	DeclinationAngle赤纬角数据	HourData小时数据	LatitudeData纬度数据
*@*返回值 : 太阳方位角(0点开始360度) 
*********************************************************************************************************************************************/
static double  Azimuth_Angle_Calculation(double ElevatingAngle,double HourAngle,double DeclinationAngle,double HourData,double LatitudeData)
{
	double AzimuthAngle,AzimuthAngle_cos;
	
 	double ElevatingAngle_cos = cos(ElevatingAngle * PI / 180);				//高度角余弦值 
 	double ElevatingAngle_sin = sin(ElevatingAngle * PI / 180);				//高度角正弦值 
	double LatitudeData_sin = sin(LatitudeData * PI / 180);					//纬度正弦值 
	double LatitudeData_cos = cos(LatitudeData * PI / 180);					//纬度余弦值  	
 	double HourAngle_sin = sin(HourAngle * PI / 180); 						//时角正弦值 
 	double DeclinationAngle_cos = cos(DeclinationAngle * PI / 180);			//赤纬角余弦值 
 	double DeclinationAngle_sin = sin(DeclinationAngle * PI / 180);			//赤纬角正弦值
 	
 	AzimuthAngle_cos = (ElevatingAngle_sin*LatitudeData_sin-DeclinationAngle_sin)/(ElevatingAngle_cos*LatitudeData_cos);		//初步计算太阳方位角弧度值的cos值 
 	AzimuthAngle = acos(AzimuthAngle_cos)*180/PI;																				//计算方位角的角度 
 	
	if (HourData > 12) 														//不判断的话12点为180度最高,然后两边的角度都是180度递减,所以需要一个360度的角度反馈需要将方位角判断一下。 
	{
		return AzimuthAngle + 180;
	}
	else 
	{
		return -AzimuthAngle + 180;
	}
	
} 

其中函数尾部的返回时180度加减计算得出的方位角,是为了对齐网页计算得出的方位角,以0时的方位角的0°,且随时间累加累加至360度。

角度计算到此就结束了

时间戳转换

下文内容多数引用自:博客

因为我打算用stm32f103mcu进行太阳方位角以及高度角的计算,所以需要用stm32单片机获取时间戳信息

我采用的方法是使用esp8266-01s模块来通过联网获取时间戳的方式得到时间。

配置 ESP8266 入网

AT+CWMODE=1                     // station模式,设置成3也行
AT+RST                          // 重启模块
AT+CWJAP="ssid","password"      // 连接AP

连接授时服务器

AT+CIPMUX=0                                // 设置WiFi模块为单路链接
AT+CIPSTART="UDP","1.cn.pool.ntp.org",123  
// 链接到 NTP 服务器,时间服务器默认的端口号是 123,协议为UDP.AT+CIPSEND=48                              
// 发送48byte的数据若ESP8266返回'>'则继续注意,严格遵照以下数据且使用16进制发送
//切勿发送新行E3 0 6 EC 0 0 0 0 0 0 0 0 31 4E 31 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
//用16进制接收数据
E3 0 6 EC 0 0 0 0 0 0 0 0 31 4E 31 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

不知道为什么我好像需要发送两遍下边的16进制数据,然后接收两帧数据

接收数据

  • 执行完上面两步,此时如果顺利的话会受到一大堆16进制数据
  • 诸如:41 54 2B 43 49 50 53 45 4E 44 3D 34 38 0D 0D 0A 0D 0A 4F 4B 0D 0A 3E 20 0D 0A 52 65 63 76 20 34 38 20 62 79 74 65 73 0D 0A 0D 0A 53 45 4E 44 20 4F 4B 0D 0A 0D 0A 2B 49 50 44 2C 34 38 3A 24 02 06 E9 00 00 00 52 00 00 08 F2 0A 45 02 22 E0 4F 57 31 79 AF 20 82 00 00 00 00 00 00 00 00 E0 4F 59 9C 2F 4A 40 07 E0 4F 59 9C 2F 4C 22 B9
  • 此时需要找到数据中的关键帧,也就是服务器返回的48位时间数据,它们通常具有以下格式:(如果找不到的话请重试2中的3、4步)
    • ① 它前面的数据为"2B 49 50 44 2C 34 38 3A"(+IPD,48:),他后面没有东西;
    • ② 它通常以 24 开头.3.对数据提取后编号,其中[40][41][42][43]为我们需要的时间数据,在本例中为"E0 4F 5C 00".

处理数据

①将”E04F5C00“转为十进制为3763297280,此即为1900距今的秒数。
②把这个时间减去2208988800(70年),得到标准的Unix时间戳。[3763297280-2208988800=1554308480]
③[1554308480/31556736+1970=2019],得到当下年份。
④计算月份和日期需要考虑平年闰年和每月天数,太麻烦我也没搞懂。
⑤[(1554308480/3600)%24+8=24],得到北京时间-时(别忘了满24归零)
⑥[(1554308480/60)%60=21],得到北京时间-分
⑦[1554308480%60=20],得到北京时间-秒,既当下时间是 24:21:20
⑧将时间戳(1554308480)输入 时间戳生成网页 与计算结果进行比较

时间戳解码并加入代码

因为我们计算太阳角度的代码,只需要获取年份,当天在一年中的序号,以及小时分钟信息。
所以有以下计算

/********************************************************************************************************************************************
*@*名称 : Timestamp_Calculation
*@*功能 : 计算时间戳
*@*形参 : Timestamp时间戳数据 	Year_data年数据存放的地址	DayData日数据存放的地址		 Hour_data小时数据存放的地址 
*@*返回值 : 无
*********************************************************************************************************************************************/
static void  Timestamp_Calculation(unsigned int Timestamp,short *Year_data,short *DayData,double *Hour_data)
{
	Timestamp  = Timestamp-0x83AA7E80;						//将网络获取的时间戳减去70年得到标准时间戳 
	*Year_data = Timestamp/31556736+1970;					//用时间戳获取年份 
	*DayData = (short)((Timestamp%31556736)/86400)+1;		//获取日期 
	*Hour_data = (Timestamp/3600)%24+8;						//获取小时数 
	if(*Hour_data==24)
	{
		*Hour_data = 0;										//当时间为24点时归零 
	} 
	*Hour_data += ((Timestamp/60)%60)/60.0;					//获取分钟信息并且转为小数形式加入小时数中 
}

步骤:

  1. 将网络获取的时间戳减70年得到标准时间戳
  2. 然后用标准时间戳除一年的秒数,就得到距离时间戳开始运行的1970年过去了多少年
  3. 标准时间戳除于一天的秒数,为今年过去了多少天,还要加上没过完的今天,即加1。
  4. 小时数为将时间戳除一小时的秒数,得到至今运行了多少小时,再进行24小时取余,余今天过了多少小时
  5. 小时数在加上分钟数,得到带小数点的精确时间。(方法类似步骤5)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1242255.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

docker安装mysql挂着目录和mysql备份和恢复

第一&#xff0c;镜像拉取&#xff0c;运行镜像并挂载目录&#xff0c;尝试挂bin下&#xff0c;启动不了&#xff0c;不知为啥 docker run --privilegedtrue -itd --namevmysql -p 3306:3306 -v /home/vmysql:/home/vmysql -e MYSQL_ROOT_PASSWORD123456 mysql&#xff08;图…

计算机视觉的应用19-基于pytorch框架搭建卷积神经网络CNN的卫星地图分类问题实战应用

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下计算机视觉的应用19-基于pytorch框架搭建卷积神经网络CNN的卫星地图分类问题实战应用。随着遥感技术和卫星图像获取能力的快速发展&#xff0c;卫星图像分类任务成为了计算机视觉研究中一个重要的挑战。为了促进这一…

Leetcode—6.N字形变换【中等】

2023每日刷题&#xff08;三十七&#xff09; Leetcode—6.N字形变换 算法思想 参考k神的题解 实现代码 class Solution { public:string convert(string s, int numRows) {if(numRows < 2) {return s;}vector<string> rows(numRows);int flag -1;int i 0;for(…

FreeSQL 基本使用

FreeSQL连接MySQL 安装 FeeSql相关库 FreeSql 基本库 FreeSql.DbContext FreeSql.Extensions.Linq linq语法扩展库 FreeSql.Provider.Mysql MySQL连接库 新建DbConent.cs public class Base{static string connstr "Data Source127.0.0.1;Port3306;User IDroot;Pa…

S32K144W深度睡眠的问题

电源芯片是一个9到60的宽压芯片。另带一个两轴加表&#xff0c;两个485。 10V正常工作时&#xff0c;电流为26mA 休眠后的电流&#xff0c;只有串口2进行了反初始化&#xff1a; u2_printf(“ENTER LOW-POWER SLEEPDEEP MODE. %d \r\n”,MCU_Freq); //LPUART_DRV_Deinit(INST…

赛桨在结构领域全新探索:机理驱动的无网格结构拓扑优化

自PaddleScience&#xff08;赛桨&#xff09; V1.0于2023年8月正式发布以来&#xff0c;其支持数据和机理驱动的AI for Science求解模式备受工程领域的欢迎。赛桨不仅提供了包括流体、结构、气象等多个领域的基础网络模型&#xff0c;还提供了丰富的生态共建案例。截至目前&am…

数组对象判重最佳实践

数组对象判重最佳实践 赶紧挣钱&#xff0c;回家过年… 1.问题回顾 deviceSelectedRow(row) {this.ElectricalPartList.push(row)}&#xff0c;在此方法中&#xff0c;ElectricalPartList需要多次push进去数据&#xff0c;但是row可能存在重复&#xff0c;如何判重呢&#xff…

easyrecovery免费版2024最新电脑数据恢复工具

easyrecovery免费版是一款操作简便且实用的数据恢复工具&#xff0c;easyrecovery绿色版可以用来恢复各种各样被删除的文件、视频、图片等&#xff1b;EasyRecovery功能非常全面&#xff0c;easyrecovery还可以支持SD卡数据恢复&#xff0c;TF卡等各种存储卡文件恢复(图片、视频…

GeoTrust通配符证书:保护您的网站安全

GeoTrust通配符 SSL证书是一种特殊的 SSL 证书类型&#xff0c;它可以同时为您的主域名及其所有子域提供安全保护。无论您有多少个不同的子域需要保障&#xff0c;都可以通过单一的 GeoTrust 通配符 SSL 证书轻松实现&#xff0c;极大地简化了管理流程并降低了成本。 此外&…

基于.net framework4.0框架下winform项目实现寄宿式web api

首先Nuget中下载包&#xff1a;Microsoft.AspNet.WebApi.SelfHost&#xff0c;如下&#xff1a; 注意版本哦&#xff0c;最高版本只能4.0.30506能用。 1.配置路由 public static class WebApiConfig{public static void Register(this HttpSelfHostConfiguration config){// …

【数据结构】树的基本概念 | 入门树以及二叉树必熟知

树的学习过程中&#xff0c;二叉树比较重要&#xff0c;但是在学习二叉树之前&#xff0c;得先需要了解到一些数的概念。 树的定义 树是一种非线性的数据结构&#xff0c;它是由 n&#xff08;n > 0&#xff09;个有限结点组成一个具有层次关系的集合。把它叫做树是因为它…

兼顾陪读|自由职业者赴美国加州大学尔湾分校访学

I老师出国访学除了提升自己的科研水平外&#xff0c;主要目标还是以陪伴孩子上学为主。最终我们为其落实了排名还不错的加州大学尔湾分校的职位&#xff0c;这对于已多年脱离科研工作岗位&#xff0c;学术背景非常薄弱的I老师来说相当不易。 I老师背景&#xff1a; 申请类型&a…

需求分析BSA法

&#x1f449;BSA法&#xff08;Basic–Satisfier–Attractor&#xff09;是对客户需求进行优先级划分的需求分析方法。该模型体现了需求满足度和客户满意度之间的非线性关系。BSA法将客户需求分为3种类型&#xff0c;分别是基本型需求、满意型需求和兴奋型需求。下面将对每种需…

php一句话木马免杀

php一句话木马免杀 针对于php一句话木马做免杀&#xff1a; 利用php动态函数的特性&#xff0c;将危险函数拆分成字符&#xff0c;最终使用字符串拼接的方式&#xff0c;然后重新拼接&#xff0c;后加括号执行代码&#xff0c;并且可以使用花指令进行包装&#xff0c;如无限i…

2023“亚太杯”大学生数学建模竞赛

2023亚太杯数学建模C题 中国新能源电动汽车的发展趋势 解题思路、数据 该题并没有提供数据集&#xff0c;对所需数据进行收集整理是对题目进行求解的基础。在本题中&#xff0c;主要需要以下数据&#xff1a;新能源汽车历史销售量、新能汽车相关专利的历史数量、充电桩历史数…

Docker 安装 Apache

目录 拉取官方 Apache 镜像 查看本地镜像 列出正在运行的容器 运行 Apache 容器 创建一个 HTML 文件&#xff1a;index.html 访问 Apache 拉取官方 Apache 镜像 查找 Docker Hub 上的 httpd 镜像。 可以通过 Tags 查看其他版本的 httpd&#xff0c;默认是最新版本 httpd…

VUE项目部署过程中遇到的错误:POST http://124.60.11.183:9090/test/login 405 (Not Allowed)

我当初报了这个405错误&#xff0c;再网上查了半天&#xff0c;他们都说什么是nginx部署不支持post访问静态资源。 但后面我发现我是因为另一个原因才导致的无法访问。 我再vue中有使用devServer:{ proxy:{} }进行路由转发。 但是&#xff01;&#xff01; 在这个配置只…

「邀请函」开启“全”方位软件授权创新之旅

尊敬的各位创新者&#xff1a; 随着数字化时代的到来&#xff0c;软件授权license已成为了企业开拓市场、提升竞争力的关键环节。为了满足不断变化的市场需求也为了引领行业的创新与变革&#xff0c;我们带着2023年软件授权“全”面、“全”新的方案来了&#xff01;

【云原生 Prometheus篇】Prometheus的动态服务发现机制与认证配置

目录 一、Prometheus服务发现的方式1.1 基于文件的服务发现1.2 基于consul的服务发现1.3 基于 Kubernetes API 的服务发现1.3.1 简介1.3.2 基于Kurbernetes发现机制的部分配置参数 二、实例一&#xff1a;部署基于文件的服务发现2.1 创建用于服务发现的文件2.2 修改Prometheus的…

揭开病毒式内容的秘密:爆炸性在线增长的策略

介绍 病毒式内容的想法已经完全接管了巨大的互联网上的数字世界。我们都看过&#xff1a;那些吸引数百万人注意力的电影、文章或图片似乎像野火一样蔓延开来。然而&#xff0c;是什么导致内容传播开来&#xff1f;公司和个人如何发现互联网快速扩张的关键&#xff1f;在这篇文…