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

topdog 发表于 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数组格式。
圆的地球



平面的地图


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


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


程序如下:

#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"
intnumber = 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();
}

显示效果见抖音:https://www.douyin.com/video/7150293108473826563
页: [1]
查看完整版本: 国际空间站在哪里?