Created
September 13, 2020 20:05
-
-
Save takeru/6c0eaf513f41c3bfdcf9b98e566516c2 to your computer and use it in GitHub Desktop.
3Dプリントの残り時間カウントダウンタイマー
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 3Dプリンタタイマー | |
* 1. OctoPrintAPIから残り時間を取得して表示 | |
* 2. deepsleepで電池節約 | |
* 3. プリントが終わったら音と光でお知らせ | |
*/ | |
#include "time.h" | |
#include <M5StickC.h> | |
#include <WiFi.h> | |
#include <WiFiMulti.h> | |
#include <ESPmDNS.h> | |
#include <HTTPClient.h> | |
#include <ArduinoJson.h> // 6.16.1 https://arduinojson.org/v6/doc/installation/ | |
#include <TimeLib.h> // "Time by Michael Margolis" https://github.com/PaulStoffregen/Time | |
#define LED_BUILTIN 10 | |
#define LED_IR 9 | |
#define PIN_SPK 26 | |
#define OCTOPRINT_API_KEY "xxxxxx" | |
#define OCTOPRINT_MDNS_NAME "octopi" // http://octopi.local/... without ".local" | |
WiFiMulti wifiMulti; | |
#include "secret.h"; | |
//#define WIFI_MULTI_ADD_APS() \ | |
// wifiMulti.addAP("aaa", "xxx"); \ | |
// wifiMulti.addAP("bbb", "yyy"); | |
IPAddress ipaddr = INADDR_NONE; | |
unsigned long origin_ms = 0; | |
String state = ""; | |
float completion = 0.0; | |
int printTime0 = 0; | |
int printTimeLeft0 = 0; | |
TFT_eSprite tftSprite = TFT_eSprite(&M5.Lcd); | |
void set_led_red(bool on) | |
{ | |
digitalWrite(LED_BUILTIN, on ? LOW : HIGH); | |
} | |
void init_timelib(void) | |
{ | |
RTC_TimeTypeDef time; | |
RTC_DateTypeDef date; | |
M5.Rtc.GetTime(&time); | |
M5.Rtc.GetData(&date); | |
setTime(time.Hours, time.Minutes, time.Seconds, date.Date, date.Month, date.Year); | |
} | |
String datetime_string(){ | |
time_t t = now(); | |
char s[20]; | |
sprintf(s, "%04d-%02d-%02d_%02d:%02d:%02d", year(t), month(t), day(t), hour(t), minute(t), second(t)); | |
return String(s); | |
} | |
bool sync_rtc() | |
{ | |
configTime(9 * 3600, 0, "ntp.nict.jp"); // JST | |
// Get local time | |
struct tm timeInfo; | |
if (getLocalTime(&timeInfo)) | |
{ | |
// Set RTC time | |
RTC_TimeTypeDef TimeStruct; | |
TimeStruct.Hours = timeInfo.tm_hour; | |
TimeStruct.Minutes = timeInfo.tm_min; | |
TimeStruct.Seconds = timeInfo.tm_sec; | |
M5.Rtc.SetTime(&TimeStruct); | |
RTC_DateTypeDef DateStruct; | |
DateStruct.WeekDay = timeInfo.tm_wday; | |
DateStruct.Month = timeInfo.tm_mon + 1; | |
DateStruct.Date = timeInfo.tm_mday; | |
DateStruct.Year = timeInfo.tm_year + 1900; | |
M5.Rtc.SetData(&DateStruct); | |
return true; | |
} | |
else | |
{ | |
return false; | |
} | |
} | |
String mac_string(const uint8_t *mac) | |
{ | |
char macStr[18] = {0}; | |
sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); | |
return String(macStr); | |
} | |
String get_printer_job_json() { | |
HTTPClient http; | |
String url = "http://"; | |
url += ipaddr.toString(); | |
// url += ":8080" | |
url += "/api/job?apikey="; | |
url += OCTOPRINT_API_KEY; | |
printf("url=%s\n", url.c_str()); | |
http.begin(url); | |
int code = http.GET(); | |
String jsonString = ""; | |
if (code == HTTP_CODE_OK) { | |
jsonString = http.getString(); | |
} | |
http.end(); | |
return jsonString; | |
} | |
void deepsleep(long ms) { | |
WiFi.disconnect(); | |
printf("deepsleep ms=%ld\n", ms); | |
Serial.flush(); | |
M5.Axp.DeepSleep(ms * 1000); | |
} | |
unsigned long millis_from_origin(){ | |
return millis() - origin_ms; | |
} | |
bool get_printer_status(bool ntp_sync){ | |
if (wifiMulti.run() == WL_CONNECTED) { | |
printf("localIP=%s\n", WiFi.localIP().toString().c_str()); | |
if(ntp_sync){ | |
printf("sync_rtc=%d\n", sync_rtc()); | |
} | |
} | |
init_timelib(); | |
printf("now=%s\n", datetime_string().c_str()); | |
MDNS.begin("mdns-client"); | |
ipaddr = MDNS.queryHost(OCTOPRINT_MDNS_NAME); | |
printf("ipaddr=%s\n", ipaddr.toString().c_str()); | |
String jsonString = get_printer_job_json(); | |
WiFi.disconnect(); | |
printf("WiFi.disconnect\n"); | |
if (jsonString == "") { | |
printf("ERROR: http failed.\n"); | |
return false; | |
} | |
printf("jsonString========\n"); | |
jsonString.trim(); | |
printf("%s\n", jsonString.c_str()); | |
printf("========\n"); | |
const size_t capacity = 1000; | |
DynamicJsonDocument doc(capacity); | |
DeserializationError error = deserializeJson(doc, jsonString); | |
if (error) { | |
printf("ERROR: deserialize failed.\n"); | |
return false; | |
} | |
String _state = doc["state"]; | |
state = _state; | |
completion = doc["progress"]["completion"]; | |
printTime0 = doc["progress"]["printTime"]; | |
printTimeLeft0 = doc["progress"]["printTimeLeft"]; | |
printf("state=%s\n", state.c_str()); | |
printf("completion=%5.2f\n", completion); | |
printf("printTime=%d\n", printTime0); | |
printf("printTimeLeft=%d\n", printTimeLeft0); | |
origin_ms = millis(); | |
//printTimeLeft0 = 100*60+20; | |
//completion = 98.34; | |
return true; | |
} | |
void setup() { | |
pinMode(PIN_SPK, OUTPUT); | |
digitalWrite(PIN_SPK, LOW); | |
M5.Axp.begin(); | |
M5.Axp.ScreenBreath(0); | |
M5.Lcd.begin(); | |
M5.Rtc.begin(); | |
M5.Lcd.fillScreen(BLACK); | |
printf("rotation=%d width=%d height=%d\n", M5.Lcd.getRotation(), M5.Lcd.width(), M5.Lcd.height()); | |
M5.Lcd.setRotation(1); | |
printf("rotation=%d width=%d height=%d\n", M5.Lcd.getRotation(), M5.Lcd.width(), M5.Lcd.height()); | |
tftSprite.createSprite(M5.Lcd.width(), M5.Lcd.height()); | |
pinMode(LED_BUILTIN, OUTPUT); | |
pinMode(LED_IR, OUTPUT); | |
set_led_red(false); | |
WIFI_MULTI_ADD_APS(); | |
uint8_t mac[6]; | |
WiFi.macAddress(mac); | |
printf("macAddress=%s\n", mac_string(mac).c_str()); | |
if(!get_printer_status(true)){ | |
for (int i = 0; i < 10; i++) { | |
set_led_red(true); | |
delay(100); | |
set_led_red(false); | |
delay(400); | |
} | |
delay(1000); | |
deepsleep(60 * 1000); | |
} | |
M5.Axp.ScreenBreath(9); | |
} | |
void loop() { | |
bool demo_mode = false; | |
update_display(); | |
if(printTimeLeft0==0){ | |
set_led_red(true); | |
delay(100); | |
set_led_red(false); | |
delay(100); | |
if(millis_from_origin()/1000 % 60 == 59){ | |
get_printer_status(false); | |
} | |
for(int j=0; j<2; j++){ | |
for(int i=0; i<50; i++){ | |
digitalWrite(PIN_SPK, HIGH); | |
delayMicroseconds(400); | |
digitalWrite(PIN_SPK, LOW); | |
delayMicroseconds(400); | |
} | |
delay(100); | |
} | |
delay(1000); | |
}else if(printTimeLeft0 < 3*60 || demo_mode){ | |
if(millis_from_origin()/1000 % 15 == 14){ | |
if(!get_printer_status(false)){ | |
deepsleep(5 * 1000); | |
} | |
} | |
}else if(printTimeLeft0 < 15*60){ | |
if(60*1000 < millis_from_origin()){ | |
deepsleep(1 * 60 * 1000); | |
} | |
}else{ | |
if(30*1000 < millis_from_origin()){ | |
deepsleep(5 * 60 * 1000); | |
} | |
} | |
delay(100); | |
} | |
void update_display() | |
{ | |
int printTime = printTime0 + millis_from_origin() / 1000; | |
int printTimeLeftMs = printTimeLeft0*1000 - millis_from_origin(); | |
if(printTimeLeftMs < 0){ | |
printTimeLeftMs = 0; | |
} | |
tftSprite.fillSprite(M5.Lcd.color565(200, 60, 0)); | |
tftSprite.setTextColor(BLACK); | |
tftSprite.setCursor(5, 10); | |
tftSprite.setTextFont(7); | |
tftSprite.setTextSize(1); | |
int mode = 0; | |
if(printTimeLeftMs==0){ | |
mode = millis()/1000 / 1 % 2 + 1; | |
}else if(printTimeLeftMs < 100*60*1000){ | |
mode = millis()/1000 / 5 % 3; | |
}else{ | |
mode = millis()/1000 / 5 % 2; | |
} | |
if(mode==0){ | |
time_t t = now() + printTimeLeftMs / 1000; | |
tftSprite.printf("%02d:%02d", hour(t), minute(t)); | |
} | |
if(mode==1){ | |
tftSprite.printf("%2d.%1d", int(completion), int(completion*10)%10); | |
} | |
if(mode==2){ | |
if(printTimeLeftMs < 10*60*1000){ // 9:59.9 | |
tftSprite.printf("%1d:%02d.%1d", printTimeLeftMs/1000/60, printTimeLeftMs/1000%60, printTimeLeftMs%1000/100); | |
}else if(printTimeLeftMs < 100*60*1000){ // 99:59 | |
tftSprite.printf("%02d:%02d%s", printTimeLeftMs/1000/60, printTimeLeftMs/1000%60, (printTimeLeftMs%1000/100)%2==0 ? ".":""); | |
} | |
} | |
tftSprite.pushSprite(0, 0); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define WIFI_MULTI_ADD_APS() \ | |
wifiMulti.addAP("aaa", "xxx"); \ | |
wifiMulti.addAP("bbb", "yyy"); | |
#define OCTOPRINT_API_KEY "zzzzzzzzzz" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment