国际空间站在哪里?-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 409|回复: 0

国际空间站在哪里?

[复制链接]
发表于 2022-10-3 22:03 | 显示全部楼层 |阅读模式
本帖最后由 topdog 于 2022-10-4 19:40 编辑

国际空间站在哪里?原来是一个树莓派的项目,专门设置了一个网站公布API,网址:http://open-notify.org/ 主要提供国际空间站实时的GPS定位信息和在太空的宇航员姓名(包括中国问天太空舱乘组)。

硬件使用深圳晶彩智能3.5寸彩色屏采用分辨率480x320彩色液晶屏,驱动芯片是ST7796,板载乐鑫公司出品ESP-WROOM-32,Flash 4M。采用静态地图,在上面实时标定国际空间站的定位,屏幕下方显示太空中所有太空人的人数和姓名。
首先,去 https://visibleearth.nasa.gov/images/73963/bathymetry 下载一幅 720x360 像素的世界地图,然后用Photoshop将其修改成适合深圳晶彩智能3.5寸彩色屏用的,分辨率480x240的jpg格式图片,然后到 http://rinkydinkelectronics.com/library.php?id=51 下载UTFT库文件,解压到libraries,再用UTFT\Tools\ImageConverter565.exe把图片转化成.c数组格式。
圆的地球
地球.PNG


平面的地图
验证.png

上面两张图国际空间站的定位是一致的。那么平面地图中间垂直的是0度经线,左面是西经为0至-180度,右面是东经为0至+180度。平面地图中间水平的是赤道0度纬线,上面是北纬0至+90度,下面是南纬0至-90度。已知我们准备的地图是480x240像素,利用map函数就能方便的求出坐标对应的屏幕上的位置。算法见程序。


数据的解析使用ArduinoJson库,ArduinoJson助手配置如下。特别需要说明的解析出来的数据采用Sprite类打印,为了防止屏幕闪烁和闪存溢出。
image.png

程序如下:

[pre]#include <ArduinoJson.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <TFT_eSPI.h>       // Hardware-specific library
#include "map.h"

TFT_eSPI tft = TFT_eSPI();  // Invoke custom library
TFT_eSprite people = TFT_eSprite(&tft);

const char* ssid     = "你的WiFi名称";     // your network SSID (name of wifi network)
const char* password = "你的WiFi密码"; // your network password

float iss_latitude, iss_longitude, x, y;
String payload = " ";

const String iss = "http://api.open-notify.org/iss-now.json";
const String ppl = "http://api.open-notify.org/astros.json";

void setup()
{
  Serial.begin(115200);

  pinMode(4, OUTPUT);
  digitalWrite(4, HIGH);

  pinMode(16, OUTPUT);
  digitalWrite(16, HIGH);

  pinMode(17, OUTPUT);
  digitalWrite(17, HIGH);

  pinMode(TFT_BL, OUTPUT);
  digitalWrite(TFT_BL, TFT_BACKLIGHT_ON);
  yield();

  Serial.print("Attempting to connect to SSID: ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);

  // attempt to connect to Wifi network:
  while (WiFi.status() != WL_CONNECTED) {
    //Serial.print(".");
    // wait 1 second for re-trying
    yield();
  }

  //Serial.print("Connected to ");
  //Serial.println(ssid);
  yield();


  tft.begin();
  tft.setRotation(3);  // landscape
  tft.fillScreen(TFT_BLACK);

  // Swap the colour byte order when rendering
  tft.setSwapBytes(true);

  tft.pushImage(0, 0, MAPWidth, MAPHeight, MAP);
  yield();
  decodePeopleJson();
  yield();
}

void loop() {
  decodeLocJson();
  yield();
}

void getJson(String url) {
  if (WiFi.status() == WL_CONNECTED) { //Check WiFi connection status
    HTTPClient http;  //Declare an object of class HTTPClient
    http.begin(url);  //Specify request destination
    int httpCode = http.GET();                                                                  //Send the request
    if (httpCode > 0) { //Check the returning code
      payload = http.getString();   //Get the request response payload
    }

    http.end();   //Close connection
  }
}

void decodeLocJson() {
  getJson(iss);
  yield();
  StaticJsonDocument<192> doc;

  DeserializationError error = deserializeJson(doc, payload);

  if (error) {
    //Serial.print("deserializeJson() failed: ");
    //Serial.println(error.c_str());
    return;
  }

  const char* message = doc["message"]; // "success"
  long timestamp = doc["timestamp"]; // 1664637856

  const char* iss_position_longitude = doc["iss_position"]["longitude"]; // "29.0242" 经度
  const char* iss_position_latitude = doc["iss_position"]["latitude"]; // "51.0796"   维度

  iss_latitude = String (iss_position_latitude).toFloat();
  iss_longitude = String (iss_position_longitude).toFloat();

if (iss_latitude <= 0 && iss_longitude >= 0 ) {
    x = round(map(iss_longitude, -180, 0, 0, 240));
    y = round(map(iss_latitude, 90, 0, 0, 120));
  } else if (iss_latitude <= 0 && iss_longitude <= 0 ) {
    x = round(map(iss_longitude, -180, 0, 0, 240));
    y = round(map(iss_latitude, 0, -90, 120, 240));
  } else if (iss_latitude >= 0 && iss_longitude >= 0 ) {
    x = round(map(iss_longitude, 0, 180, 240, 480));
    y = round(map(iss_latitude, 90, 0, 0, 120));
  } else if (iss_latitude >= 0 && iss_longitude <= 0 ) {
    x = round(map(iss_longitude, 0, 180, 240, 480));
    y = round(map(iss_latitude, 0, -90, 120, 240));
  }

  tft.fillCircle(x, y, 1, TFT_YELLOW);  
}

void decodePeopleJson() {

  getJson(ppl);
  StaticJsonDocument<1024> craft_people;

  DeserializationError error = deserializeJson(craft_people, payload);

  if (error) {
    //Serial.print("deserializeJson() failed: ");
    //Serial.println(error.c_str());
    return;
  }

  const char* message = craft_people["message"]; // "success"
  int  number = craft_people["number"]; // 13

  people.setSwapBytes(true);
  people.setColorDepth(16);
  people.createSprite(480, 78);

  people.setTextWrap(true, true);
  people.setTextColor(TFT_GREEN, TFT_BLACK);
  people.setTextFont(2);
  people.setCursor(0, 241);
  people.print("There are " + (String)number);
  people.println(" People in Space!");

  for (JsonObject people_item : craft_people["people"].as<JsonArray>()) {
    //const char* people_item_craft = people_item["craft"]; // "ISS", "ISS", "ISS", "ISS", "ISS", "ISS", ...
    const char* people_item_name = people_item["name"]; // "Oleg Artemyev", "Denis Matveev", "Sergey ...
    String temporary = people_item_name;
    people.print(temporary);
  }

  people.pushSprite(0, 241);
  people.deleteSprite();
}[/pre]

显示效果见抖音:https://www.douyin.com/video/7150293108473826563
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-12-1 01:46 , Processed in 0.120651 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表