mirror of
https://github.com/eried/portapack-mayhem.git
synced 2025-01-11 15:29:28 -05:00
Quick and dirty temperature logger, debug view of temp vs. time.
This commit is contained in:
parent
750506b33e
commit
86edf01def
@ -180,6 +180,7 @@ CPPSRC = main.cpp \
|
||||
log_file.cpp \
|
||||
manchester.cpp \
|
||||
string_format.cpp \
|
||||
temperature_logger.cpp \
|
||||
../common/utility.cpp \
|
||||
../common/chibios_cpp.cpp \
|
||||
../common/debug.cpp \
|
||||
|
@ -129,6 +129,8 @@ private:
|
||||
|
||||
void handle_rtc_tick() {
|
||||
sd_card::poll_inserted();
|
||||
|
||||
portapack::temperature_logger.second_tick();
|
||||
}
|
||||
|
||||
static ui::Widget* touch_widget(ui::Widget* const w, ui::TouchEvent event) {
|
||||
|
@ -65,6 +65,8 @@ ReceiverModel receiver_model {
|
||||
clock_manager
|
||||
};
|
||||
|
||||
TemperatureLogger temperature_logger;
|
||||
|
||||
class Power {
|
||||
public:
|
||||
void init() {
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "lcd_ili9341.hpp"
|
||||
|
||||
#include "radio.hpp"
|
||||
#include "temperature_logger.hpp"
|
||||
|
||||
namespace portapack {
|
||||
|
||||
@ -45,6 +46,8 @@ extern si5351::Si5351 clock_generator;
|
||||
|
||||
extern ReceiverModel receiver_model;
|
||||
|
||||
extern TemperatureLogger temperature_logger;
|
||||
|
||||
void init();
|
||||
void shutdown();
|
||||
|
||||
|
65
firmware/application/temperature_logger.cpp
Normal file
65
firmware/application/temperature_logger.cpp
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
|
||||
*
|
||||
* This file is part of PortaPack.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "temperature_logger.hpp"
|
||||
|
||||
#include "radio.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
void TemperatureLogger::second_tick() {
|
||||
sample_phase++;
|
||||
if( sample_phase >= sample_interval ) {
|
||||
push_sample(read_sample());
|
||||
}
|
||||
}
|
||||
|
||||
size_t TemperatureLogger::size() const {
|
||||
return std::min(samples.size(), samples_count);
|
||||
}
|
||||
|
||||
std::vector<TemperatureLogger::sample_t> TemperatureLogger::history() const {
|
||||
std::vector<sample_t> result;
|
||||
|
||||
const auto n = size();
|
||||
result.resize(n);
|
||||
|
||||
// Copy the last N samples from the buffer, since new samples are added at the end.
|
||||
std::copy(samples.cend() - n, samples.cend(), result.data());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
TemperatureLogger::sample_t TemperatureLogger::read_sample() {
|
||||
// MAX2837 does not return a valid temperature if in "shutdown" mode.
|
||||
return radio::second_if.temp_sense() & 0x1f;
|
||||
}
|
||||
|
||||
void TemperatureLogger::push_sample(const TemperatureLogger::sample_t sample) {
|
||||
// Started out building a pseudo-FIFO, then got lazy.
|
||||
|
||||
// Shift samples: samples[1:] -> samples[0:-1]
|
||||
// New sample goes into samples[-1]
|
||||
std::copy(samples.cbegin() + 1, samples.cend(), samples.begin());
|
||||
samples.back() = sample;
|
||||
samples_count++;
|
||||
sample_phase = 0;
|
||||
}
|
51
firmware/application/temperature_logger.hpp
Normal file
51
firmware/application/temperature_logger.hpp
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
|
||||
*
|
||||
* This file is part of PortaPack.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __TEMPERATURE_LOGGER_H__
|
||||
#define __TEMPERATURE_LOGGER_H__
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
class TemperatureLogger {
|
||||
public:
|
||||
using sample_t = uint8_t;
|
||||
|
||||
void second_tick();
|
||||
|
||||
size_t size() const;
|
||||
|
||||
std::vector<sample_t> history() const;
|
||||
|
||||
private:
|
||||
std::array<sample_t, 128> samples;
|
||||
|
||||
static constexpr size_t sample_interval = 5;
|
||||
size_t sample_phase = 0;
|
||||
size_t samples_count = 0;
|
||||
|
||||
sample_t read_sample();
|
||||
void push_sample(const sample_t sample);
|
||||
};
|
||||
|
||||
#endif/*__TEMPERATURE_LOGGER_H__*/
|
@ -57,6 +57,50 @@ void DebugMemoryView::focus() {
|
||||
button_done.focus();
|
||||
}
|
||||
|
||||
/* TemperatureWidget *****************************************************/
|
||||
|
||||
void TemperatureWidget::paint(Painter& painter) {
|
||||
const auto history = portapack::temperature_logger.history();
|
||||
|
||||
const auto rect = screen_rect();
|
||||
|
||||
for(size_t i=0; i<history.size(); i++) {
|
||||
const auto sample = history[i];
|
||||
const Dim bar_height = sample * 4;
|
||||
const Rect bar_rect {
|
||||
static_cast<Coord>(rect.right() - (history.size() - i) * 1),
|
||||
static_cast<Coord>(rect.bottom() - bar_height),
|
||||
1, bar_height
|
||||
};
|
||||
painter.fill_rectangle(bar_rect, Color::green());
|
||||
}
|
||||
|
||||
if( !history.empty() ) {
|
||||
const int32_t temp = -45 + history.back() * 5;
|
||||
const size_t temp_len = 3;
|
||||
painter.draw_string(
|
||||
{ static_cast<Coord>(rect.right() - (temp_len * 8)), rect.top() },
|
||||
style(),
|
||||
to_string_dec_int(temp, temp_len)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/* TemperatureView *******************************************************/
|
||||
|
||||
TemperatureView::TemperatureView(NavigationView& nav) {
|
||||
add_children({ {
|
||||
&temperature_widget,
|
||||
&button_done,
|
||||
} });
|
||||
|
||||
button_done.on_select = [&nav](Button&){ nav.pop(); };
|
||||
}
|
||||
|
||||
void TemperatureView::focus() {
|
||||
button_done.focus();
|
||||
}
|
||||
|
||||
/* RegistersWidget *******************************************************/
|
||||
|
||||
RegistersWidget::RegistersWidget(
|
||||
@ -80,6 +124,8 @@ void RegistersWidget::paint(Painter& painter) {
|
||||
}
|
||||
|
||||
void RegistersWidget::draw_legend(const Coord left, Painter& painter) {
|
||||
const auto pos = screen_pos();
|
||||
|
||||
for(size_t i=0; i<config.registers_count; i+=config.registers_per_row) {
|
||||
const Point offset {
|
||||
left, static_cast<Coord>((i / config.registers_per_row) * row_height)
|
||||
@ -87,7 +133,7 @@ void RegistersWidget::draw_legend(const Coord left, Painter& painter) {
|
||||
|
||||
const auto text = to_string_hex(i, config.legend_length);
|
||||
painter.draw_string(
|
||||
screen_pos() + offset,
|
||||
pos + offset,
|
||||
style().invert(),
|
||||
text
|
||||
);
|
||||
@ -98,6 +144,8 @@ void RegistersWidget::draw_values(
|
||||
const Coord left,
|
||||
Painter& painter
|
||||
) {
|
||||
const auto pos = screen_pos();
|
||||
|
||||
for(size_t i=0; i<config.registers_count; i++) {
|
||||
const Point offset = {
|
||||
static_cast<Coord>(left + config.legend_width() + 8 + (i % config.registers_per_row) * (config.value_width() + 8)),
|
||||
@ -108,7 +156,7 @@ void RegistersWidget::draw_values(
|
||||
|
||||
const auto text = to_string_hex(value, config.value_length);
|
||||
painter.draw_string(
|
||||
screen_pos() + offset,
|
||||
pos + offset,
|
||||
style(),
|
||||
text
|
||||
);
|
||||
@ -152,7 +200,7 @@ void RegistersView::focus() {
|
||||
/* DebugMenuView *********************************************************/
|
||||
|
||||
DebugMenuView::DebugMenuView(NavigationView& nav) {
|
||||
add_items<7>({ {
|
||||
add_items<8>({ {
|
||||
{ "Memory", [&nav](){ nav.push<DebugMemoryView>(); } },
|
||||
{ "Radio State", [&nav](){ nav.push<NotImplementedView>(); } },
|
||||
{ "SD Card", [&nav](){ nav.push<NotImplementedView>(); } },
|
||||
@ -172,6 +220,7 @@ DebugMenuView::DebugMenuView(NavigationView& nav) {
|
||||
"WM8731", RegistersWidgetConfig { wolfson::wm8731::reg_count, 1, 3, 4 },
|
||||
[](const size_t register_number) { return portapack::audio_codec.read(register_number); }
|
||||
); } },
|
||||
{ "Temperature", [&nav](){ nav.push<TemperatureView>(); } },
|
||||
} });
|
||||
on_left = [&nav](){ nav.pop(); };
|
||||
}
|
||||
|
@ -82,6 +82,36 @@ private:
|
||||
};
|
||||
};
|
||||
|
||||
class TemperatureWidget : public Widget {
|
||||
public:
|
||||
explicit constexpr TemperatureWidget(
|
||||
Rect parent_rect
|
||||
) : Widget { parent_rect }
|
||||
{
|
||||
}
|
||||
|
||||
void paint(Painter& painter) override;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
class TemperatureView : public View {
|
||||
public:
|
||||
explicit TemperatureView(NavigationView& nav);
|
||||
|
||||
void focus() override;
|
||||
|
||||
private:
|
||||
TemperatureWidget temperature_widget {
|
||||
{ 0, 16, 240, 192 },
|
||||
};
|
||||
|
||||
Button button_done {
|
||||
{ 72, 256, 96, 24 },
|
||||
"Done"
|
||||
};
|
||||
};
|
||||
|
||||
struct RegistersWidgetConfig {
|
||||
size_t registers_count;
|
||||
size_t legend_length;
|
||||
|
Loading…
Reference in New Issue
Block a user