*/
#include "libs/Kernel.h"
+#include "LcdBase.h"
#include "Panel.h"
#include "PanelScreen.h"
#include "MainMenuScreen.h"
#include "SwitchPublicAccess.h"
#include "checksumm.h"
#include "Pauser.h"
+#include "TemperatureControlPool.h"
+
#include <math.h>
#include <string.h>
#include <string>
+#include <stdio.h>
+#include <algorithm>
using namespace std;
static const uint8_t icons[] = { // 115x19 - 3 bytes each: he1, he2, he3, bed, fan
{
speed_changed = false;
issue_change_speed = false;
- ipstr = NULL;
+ ipstr = nullptr;
+ update_counts= 0;
+}
+
+WatchScreen::~WatchScreen()
+{
+ delete[] ipstr;
}
void WatchScreen::on_enter()
{
THEPANEL->lcd->clear();
THEPANEL->setup_menu(4);
- get_temp_data();
+ get_current_status();
get_current_pos(this->pos);
get_sd_play_info();
this->current_speed = lround(get_current_speed());
}
// Update Only every 20 refreshes, 1 a second
- static int update_counts = 0;
update_counts++;
if ( update_counts % 20 == 0 ) {
get_sd_play_info();
get_current_pos(this->pos);
- get_temp_data();
+ get_current_status();
if (this->speed_changed) {
this->issue_change_speed = true; // trigger actual command to change speed
this->speed_changed = false;
this->refresh_screen(THEPANEL->lcd->hasGraphics() ? true : false); // graphics screens should be cleared
// for LCDs with leds set them according to heater status
- // TODO should be enabled and disabled and settable from config
- THEPANEL->lcd->setLed(LED_BED_ON, this->bedtarget > 0);
- THEPANEL->lcd->setLed(LED_HOTEND_ON, this->hotendtarget > 0);
+ bool bed_on= false, hotend_on= false, is_hot= false;
+ uint8_t heon=0, hemsk= 0x01; // bit set for which hotend is on bit0: hotend1, bit1: hotend2 etc
+ for(auto m : THEKERNEL->temperature_control_pool->get_controllers()) {
+ // query each heater
+ void *p= getTemperatures(m);
+ struct pad_temperature *temp= static_cast<struct pad_temperature *>(p);
+ if(temp != nullptr) {
+ if(temp->current_temperature > 50) is_hot= true; // anything is hot
+ if(temp->designator.front() == 'B' && temp->target_temperature > 0) bed_on= true; // bed on/off
+ if(temp->designator.front() == 'T') { // a hotend by convention
+ if(temp->target_temperature > 0){
+ hotend_on= true;// hotend on/off (anyone)
+ heon |= hemsk;
+ }
+ hemsk <<= 1;
+ }
+ }
+ }
+ THEPANEL->lcd->setLed(LED_BED_ON, bed_on);
+ THEPANEL->lcd->setLed(LED_HOTEND_ON, hotend_on);
+ THEPANEL->lcd->setLed(LED_HOT, is_hot);
+
THEPANEL->lcd->setLed(LED_FAN_ON, this->fan_state);
if (THEPANEL->lcd->hasGraphics()) {
// for (int i = 0; i < 5; ++i) {
// THEPANEL->lcd->bltGlyph(i*24, 38, 23, 19, icons, 15, i*24, 0);
// }
- if (this->hotendtarget > 0)
- THEPANEL->lcd->bltGlyph(8, 38, 20, 19, icons, 15, 0, 0);
+ if(heon&0x01) THEPANEL->lcd->bltGlyph(0, 38, 20, 19, icons, 15, 0, 0);
+ if(heon&0x02) THEPANEL->lcd->bltGlyph(20, 38, 20, 19, icons, 15, 24, 0);
+ if(heon&0x04) THEPANEL->lcd->bltGlyph(40, 38, 20, 19, icons, 15, 48, 0);
- if (this->bedtarget > 0)
- THEPANEL->lcd->bltGlyph(32, 38, 23, 19, icons, 15, 64, 0);
+ if (bed_on)
+ THEPANEL->lcd->bltGlyph(60, 38, 23, 19, icons, 15, 64, 0);
if(this->fan_state)
THEPANEL->lcd->bltGlyph(96, 38, 23, 19, icons, 15, 96, 0);
this->issue_change_speed = false;
set_speed();
}
+ PanelScreen::on_main_loop(); // in case any queued commands left
}
-// fetch the data we are displaying
-void WatchScreen::get_temp_data()
+void *WatchScreen::getTemperatures(uint16_t heater_cs)
{
void *returned_data;
- bool ok;
+ bool ok = PublicData::get_value( temperature_control_checksum, heater_cs, current_temperature_checksum, &returned_data );
- ok = THEKERNEL->public_data->get_value( temperature_control_checksum, bed_checksum, current_temperature_checksum, &returned_data );
if (ok) {
- struct pad_temperature temp = *static_cast<struct pad_temperature *>(returned_data);
- this->bedtemp = round(temp.current_temperature);
- if (this->bedtemp > 100000) this->bedtemp = -2;
- this->bedtarget = round(temp.target_temperature);
- //this->bedpwm= temp.pwm;
- } else {
- // temp probably disabled
- this->bedtemp = -1;
- this->bedtarget = -1;
+ return returned_data;
}
+ return nullptr;
+}
- ok = THEKERNEL->public_data->get_value( temperature_control_checksum, hotend_checksum, current_temperature_checksum, &returned_data );
- if (ok) {
- struct pad_temperature temp = *static_cast<struct pad_temperature *>(returned_data);
- this->hotendtemp = round(temp.current_temperature);
- if (this->hotendtemp > 100000) this->hotendtemp = -2;
- this->hotendtarget = round(temp.target_temperature);
- //this->hotendpwm= temp.pwm;
- } else {
- // temp probably disabled
- this->hotendtemp = -1;
- this->hotendtarget = -1;
- }
+// fetch the data we are displaying
+void WatchScreen::get_current_status()
+{
+ void *returned_data;
+ bool ok;
// get fan status
- ok = THEKERNEL->public_data->get_value( switch_checksum, fan_checksum, 0, &returned_data );
+ ok = PublicData::get_value( switch_checksum, fan_checksum, 0, &returned_data );
if (ok) {
struct pad_switch s = *static_cast<struct pad_switch *>(returned_data);
this->fan_state = s.state;
{
void *returned_data;
- bool ok = THEKERNEL->public_data->get_value( robot_checksum, speed_override_percent_checksum, &returned_data );
+ bool ok = PublicData::get_value( robot_checksum, speed_override_percent_checksum, &returned_data );
if (ok) {
float cs = *static_cast<float *>(returned_data);
return cs;
{
void *returned_data;
- bool ok = THEKERNEL->public_data->get_value( robot_checksum, current_position_checksum, &returned_data );
+ bool ok = PublicData::get_value( robot_checksum, current_position_checksum, &returned_data );
if (ok) {
float *p = static_cast<float *>(returned_data);
cp[0] = p[0];
void WatchScreen::get_sd_play_info()
{
void *returned_data;
- bool ok = THEKERNEL->public_data->get_value( player_checksum, get_progress_checksum, &returned_data );
+ bool ok = PublicData::get_value( player_checksum, get_progress_checksum, &returned_data );
if (ok) {
struct pad_progress p = *static_cast<struct pad_progress *>(returned_data);
this->elapsed_time = p.elapsed_secs;
{
// in menu mode
switch ( line ) {
- case 0: THEPANEL->lcd->printf("H%03d/%03dc B%03d/%03dc", this->hotendtemp, this->hotendtarget, this->bedtemp, this->bedtarget); break;
+ case 0:
+ {
+ auto& tm= THEKERNEL->temperature_control_pool->get_controllers();
+ if(tm.size() > 0) {
+ // only if we detected heaters in config
+ int n= 0;
+ if(tm.size() > 2) {
+ // more than two temps we need to cycle between them
+ n= update_counts/100; // increments every 5 seconds
+ int ntemps= (tm.size()+1)/2;
+ n= n%ntemps; // which of the pairs of temps to display
+ }
+
+ int off= 0;
+ for (size_t i = 0; i < 2; ++i) {
+ size_t o= i+(n*2);
+ if(o>tm.size()-1) break;
+ struct pad_temperature *temp= static_cast<struct pad_temperature *>(getTemperatures(tm[o]));
+ if(temp == nullptr) continue;
+ int t= std::min(999, (int)roundf(temp->current_temperature));
+ int tt= roundf(temp->target_temperature);
+ THEPANEL->lcd->setCursor(off, 0); // col, row
+ off += THEPANEL->lcd->printf("%s:%03d/%03d ", temp->designator.substr(0, 2).c_str(), t, tt);
+ }
+
+ }else{
+ //THEPANEL->lcd->printf("No Heaters");
+ }
+ break;
+ }
case 1: THEPANEL->lcd->printf("X%4d Y%4d Z%7.2f", (int)round(this->pos[0]), (int)round(this->pos[1]), this->pos[2]); break;
case 2: THEPANEL->lcd->printf("%3d%% %2lu:%02lu %3u%% sd", this->current_speed, this->elapsed_time / 60, this->elapsed_time % 60, this->sd_pcnt_played); break;
case 3: THEPANEL->lcd->printf("%19s", this->get_status()); break;
const char *WatchScreen::get_status()
{
- if (THEPANEL->hasMessage()) {
+ if (THEPANEL->hasMessage())
return THEPANEL->getMessage().c_str();
- }
+
+ if (THEPANEL->is_halted())
+ return "HALTED Reset or M999";
if (THEKERNEL->pauser->paused())
return "Paused";
+ if (THEPANEL->is_suspended())
+ return "Suspended";
+
if (THEPANEL->is_playing())
return THEPANEL->get_playing_file();
- if (!THEKERNEL->conveyor->is_queue_empty()) {
+ if (!THEKERNEL->conveyor->is_queue_empty())
return "Printing";
- }
const char *ip = get_network();
if (ip == NULL) {
{
void *returned_data;
- bool ok = THEKERNEL->public_data->get_value( network_checksum, get_ip_checksum, &returned_data );
+ bool ok = PublicData::get_value( network_checksum, get_ip_checksum, &returned_data );
if (ok) {
uint8_t *ipaddr = (uint8_t *)returned_data;
char buf[20];
int n = snprintf(buf, sizeof(buf), "IP %d.%d.%d.%d", ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]);
buf[n] = 0;
- if (this->ipstr == NULL) {
- this->ipstr = (char *)malloc(n + 1);
+ if (this->ipstr == nullptr) {
+ this->ipstr = new char[n + 1];
}
strcpy(this->ipstr, buf);