|
本帖最后由 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类打印,为了防止屏幕闪烁和闪存溢出。
程序如下:
[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
|
|