Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: ngscopeclient/scopehal-apps
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: ba8b90f99f68
Choose a base ref
...
head repository: ngscopeclient/scopehal-apps
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: b11749f365f1
Choose a head ref
  • 1 commit
  • 5 files changed
  • 1 contributor

Commits on Oct 27, 2019

  1. Unverified

    No user is associated with the committer email.
    Copy the full SHA
    b11749f View commit details
Showing with 518 additions and 0 deletions.
  1. +19 −0 reflowmon/CMakeLists.txt
  2. +168 −0 reflowmon/MainWindow.cpp
  3. +81 −0 reflowmon/MainWindow.h
  4. +202 −0 reflowmon/main.cpp
  5. +48 −0 reflowmon/reflowmon.h
19 changes: 19 additions & 0 deletions reflowmon/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#Set up include paths
include_directories(${GTKMM_INCLUDE_DIRS} ${SIGCXX_INCLUDE_DIRS})
link_directories(${GTKMM_LIBRARY_DIRS} ${SIGCXX_LIBRARY_DIRS})

###############################################################################
#C++ compilation
add_executable(reflowmon
MainWindow.cpp
main.cpp
)

###############################################################################
#Linker settings
target_link_libraries(reflowmon
scopehal
${GTKMM_LIBRARIES}
${SIGCXX_LIBRARIES}
)

168 changes: 168 additions & 0 deletions reflowmon/MainWindow.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
/***********************************************************************************************************************
* *
* ANTIKERNEL v0.1 *
* *
* Copyright (c) 2012-2019 Andrew D. Zonenberg *
* All rights reserved. *
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the *
* following conditions are met: *
* *
* * Redistributions of source code must retain the above copyright notice, this list of conditions, and the *
* following disclaimer. *
* *
* * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the *
* following disclaimer in the documentation and/or other materials provided with the distribution. *
* *
* * Neither the name of the author nor the names of any contributors may be used to endorse or promote products *
* derived from this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL *
* THE AUTHORS BE HELD LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES *
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR *
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
* POSSIBILITY OF SUCH DAMAGE. *
* *
***********************************************************************************************************************/

/**
@file
@author Andrew D. Zonenberg
@brief Implementation of main application window class
*/

#include "reflowmon.h"
#include "../scopehal/Instrument.h"
#include "../scopehal/Graph.h"
#include "MainWindow.h"

using namespace std;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Construction / destruction

/**
@brief Initializes the main window
*/
MainWindow::MainWindow(Multimeter* dmm)
: m_dmm(dmm)
{
//Set title
string title = "Reflow Monitor: ";
char tt[256];
snprintf(tt, sizeof(tt), "%s (%s %s, serial %s)",
dmm->m_nickname.c_str(),
dmm->GetVendor().c_str(),
dmm->GetName().c_str(),
dmm->GetSerial().c_str()
);
title += tt;
set_title(title);

//Initial setup
set_reallocate_redraws(true);

//Add widgets
CreateWidgets();

//Set the update timer
sigc::slot<bool> slot = sigc::bind(sigc::mem_fun(*this, &MainWindow::OnTimer), 1);
sigc::connection conn = Glib::signal_timeout().connect(slot, 1000);
}

/**
@brief Application cleanup
*/
MainWindow::~MainWindow()
{
}

/**
@brief Helper function for creating widgets and setting up signal handlers
*/
void MainWindow::CreateWidgets()
{
//Set up window hierarchy
add(m_vbox);
m_tempFrame.set_label("Temperature");
m_vbox.pack_start(m_tempFrame, Gtk::PACK_SHRINK);
m_tempFrame.add(m_tempBox);
m_tempBox.pack_start(m_tempGraph, Gtk::PACK_SHRINK);
m_tempGraph.set_size_request(1000, 300);
m_tempGraph.m_units = "C";
m_tempGraph.m_minScale = 0;
m_tempGraph.m_maxScale = 270;
m_tempGraph.m_scaleBump = 20;
m_tempGraph.m_maxRedline = 219;
m_tempGraph.m_series.push_back(&m_tempData);
m_tempGraph.m_seriesName = "temp";
m_tempGraph.m_timeScale = 1.5;
m_tempGraph.m_timeTick = 30;
m_tempGraph.m_drawLegend = false;
m_tempData.m_color = Gdk::Color("#0000ff");
m_tempBox.pack_start(m_tempLabelBox, Gtk::PACK_SHRINK);
m_tempLabelBox.pack_start(m_tempLabel, Gtk::PACK_EXPAND_WIDGET);
m_tempLabel.override_font(Pango::FontDescription("monospace bold 20"));
m_tempLabelBox.pack_start(m_talLabel, Gtk::PACK_EXPAND_WIDGET);
m_talLabel.override_font(Pango::FontDescription("monospace bold 20"));
m_talLabel.set_label("TAL: 0 s");

m_rateFrame.set_label("Ramp Rate");
m_vbox.pack_start(m_rateFrame, Gtk::PACK_SHRINK);
m_rateFrame.add(m_rateBox);
m_rateBox.pack_start(m_rateGraph, Gtk::PACK_SHRINK);
m_rateGraph.set_size_request(1000, 300);
m_rateGraph.m_units = "C/s";
m_rateGraph.m_minScale = -4;
m_rateGraph.m_maxScale = 4;
m_rateGraph.m_scaleBump = 1;
m_rateGraph.m_series.push_back(&m_rateData);
m_rateGraph.m_seriesName = "rate";
m_rateGraph.m_timeScale = 1.5;
m_rateGraph.m_timeTick = 30;
m_rateGraph.m_drawLegend = false;
m_rateGraph.m_minRedline = -999;
m_rateData.m_color = Gdk::Color("#0000ff");
m_rateBox.pack_start(m_rateLabel, Gtk::PACK_SHRINK);
m_rateLabel.override_font(Pango::FontDescription("monospace bold 20"));

//Done adding widgets
show_all();
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Message handlers

bool MainWindow::OnTimer(int /*timer*/)
{
double t = GetTime();
double temp = m_dmm->GetTemperature();

m_tempData.GetSeries("temp")->push_back(GraphPoint(t, temp));

char str[32];
snprintf(str, sizeof(str), "%.1f C ", temp);
m_tempLabel.set_label(str);

//TODO: make melting point configurable
if(temp > 219)
m_tal ++;
snprintf(str, sizeof(str), "TAL: %d s ", m_tal);
m_talLabel.set_label(str);

//Save historical temp data to calculate ramp rate
m_tempBuffer.push_back(temp);
while(m_tempBuffer.size() > 5)
m_tempBuffer.erase(m_tempBuffer.begin());

float rate = (temp - m_tempBuffer[0]) / 5;

m_rateData.GetSeries("rate")->push_back(GraphPoint(t, rate));

snprintf(str, sizeof(str), "%.2f C/s ", rate);
m_rateLabel.set_label(str);

return true;
}
81 changes: 81 additions & 0 deletions reflowmon/MainWindow.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/***********************************************************************************************************************
* *
* ANTIKERNEL v0.1 *
* *
* Copyright (c) 2012-2019 Andrew D. Zonenberg *
* All rights reserved. *
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the *
* following conditions are met: *
* *
* * Redistributions of source code must retain the above copyright notice, this list of conditions, and the *
* following disclaimer. *
* *
* * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the *
* following disclaimer in the documentation and/or other materials provided with the distribution. *
* *
* * Neither the name of the author nor the names of any contributors may be used to endorse or promote products *
* derived from this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL *
* THE AUTHORS BE HELD LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES *
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR *
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
* POSSIBILITY OF SUCH DAMAGE. *
* *
***********************************************************************************************************************/

/**
@file
@author Andrew D. Zonenberg
@brief Top-level window for the application
*/

#ifndef MainWindow_h
#define MainWindow_h

#include "../scopehal/Multimeter.h"

/**
@brief Main application window class for a power supply
*/
class MainWindow : public Gtk::Window
{
public:
MainWindow(Multimeter* dmm);
~MainWindow();

protected:

//Initialization
void CreateWidgets();

//Widgets
Gtk::VBox m_vbox;
Gtk::Frame m_tempFrame;
Gtk::HBox m_tempBox;
Graph m_tempGraph;
Graphable m_tempData;
Gtk::VBox m_tempLabelBox;
Gtk::Label m_tempLabel;
Gtk::Label m_talLabel;

Gtk::Frame m_rateFrame;
Gtk::HBox m_rateBox;
Graph m_rateGraph;
Graphable m_rateData;
Gtk::Label m_rateLabel;

bool OnTimer(int timer);

protected:

std::vector<float> m_tempBuffer;
int m_tal;

Multimeter* m_dmm;
};

#endif
202 changes: 202 additions & 0 deletions reflowmon/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
/***********************************************************************************************************************
* *
* ANTIKERNEL v0.1 *
* *
* Copyright (c) 2012-2019 Andrew D. Zonenberg *
* All rights reserved. *
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the *
* following conditions are met: *
* *
* * Redistributions of source code must retain the above copyright notice, this list of conditions, and the *
* following disclaimer. *
* *
* * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the *
* following disclaimer in the documentation and/or other materials provided with the distribution. *
* *
* * Neither the name of the author nor the names of any contributors may be used to endorse or promote products *
* derived from this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL *
* THE AUTHORS BE HELD LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES *
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR *
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
* POSSIBILITY OF SUCH DAMAGE. *
* *
***********************************************************************************************************************/

/**
@file
@author Andrew D. Zonenberg
@brief Program entry point
*/

#include "reflowmon.h"
#include "MainWindow.h"
#include "../scopehal/RohdeSchwarzHMC8012Multimeter.h"

using namespace std;

/**
@brief The main application class
*/
class ReflowApp : public Gtk::Application
{
public:
ReflowApp()
: Gtk::Application()
, m_meter(NULL)
, m_window(NULL)
{}

virtual ~ReflowApp();

static Glib::RefPtr<ReflowApp> create()
{
return Glib::RefPtr<ReflowApp>(new ReflowApp);
}

Multimeter* m_meter;

virtual void run();

protected:
MainWindow* m_window;

virtual void on_activate();
};

ReflowApp::~ReflowApp()
{
delete m_meter;
m_meter = NULL;
}

void ReflowApp::run()
{
register_application();
on_activate();

while(true)
{
//Dispatch events if we have any
while(Gtk::Main::events_pending())
Gtk::Main::iteration();

//Stop if the main window got closed
if(!m_window->is_visible())
break;
}
delete m_window;
m_window = NULL;
}

/**
@brief Create the main window
*/
void ReflowApp::on_activate()
{
//Test application
m_window = new MainWindow(m_meter);
add_window(*m_window);
m_window->present();
}

int main(int argc, char* argv[])
{
auto app = ReflowApp::create();

//Global settings
Severity console_verbosity = Severity::NOTICE;

//Parse command-line arguments
string mname;
for(int i=1; i<argc; i++)
{
string s(argv[i]);

//Let the logger eat its args first
if(ParseLoggerArguments(i, argc, argv, console_verbosity))
continue;

if(s == "--help")
{
//not implemented
return 0;
}
else if(s == "--version")
{
//not implemented
//ShowVersion();
return 0;
}
else if(s[0] == '-')
{
fprintf(stderr, "Unrecognized command-line argument \"%s\", use --help\n", s.c_str());
return 1;
}
else
mname = s;
}

//Set up logging
g_log_sinks.emplace(g_log_sinks.begin(), new ColoredSTDLogSink(console_verbosity));

//Scope format: name:api:host[:port]
char nick[128];
char api[128];
char host[128];
int port = 0;
if(4 != sscanf(mname.c_str(), "%127[^:]:%127[^:]:%127[^:]:%d", nick, api, host, &port))
{
if(3 != sscanf(mname.c_str(), "%127[^:]:%127[^:]:%127[^:]", nick, api, host))
{
LogError("Invalid multimeter string %s\n", mname.c_str());
return 1;
}
}

string sapi(api);

//Connect to the scope
if(sapi == "rs_hmc8")
{
//default port if not specified
if(port == 0)
port = 5025;

auto dmm = new RohdeSchwarzHMC8012Multimeter(new SCPISocketTransport(host, port));
dmm->m_nickname = nick;
app->m_meter = dmm;
}
else
{
LogError("Unrecognized API \"%s\", use --help\n", api);
return 1;
}

app->run();
return 0;
}

double GetTime()
{
#ifdef _WIN32
uint64_t tm;
static uint64_t freq = 0;
QueryPerformanceCounter(reinterpret_cast<LARGE_INTEGER*>(&tm));
double ret = tm;
if(freq == 0)
QueryPerformanceFrequency(reinterpret_cast<LARGE_INTEGER*>(&freq));
return ret / freq;
#else
timespec t;
clock_gettime(CLOCK_REALTIME,&t);
double d = static_cast<double>(t.tv_nsec) / 1E9f;
d += t.tv_sec;
return d;
#endif
}

48 changes: 48 additions & 0 deletions reflowmon/reflowmon.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/***********************************************************************************************************************
* *
* ANTIKERNEL v0.1 *
* *
* Copyright (c) 2012-2019 Andrew D. Zonenberg *
* All rights reserved. *
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the *
* following conditions are met: *
* *
* * Redistributions of source code must retain the above copyright notice, this list of conditions, and the *
* following disclaimer. *
* *
* * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the *
* following disclaimer in the documentation and/or other materials provided with the distribution. *
* *
* * Neither the name of the author nor the names of any contributors may be used to endorse or promote products *
* derived from this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL *
* THE AUTHORS BE HELD LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES *
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR *
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
* POSSIBILITY OF SUCH DAMAGE. *
* *
***********************************************************************************************************************/

/**
@file
@author Andrew D. Zonenberg
@brief Main project include file
*/
#ifndef reflowmon_h
#define reflowmon_h

#include "../scopehal/scopehal.h"
#include "../scopehal/Instrument.h"
#include "../scopehal/PowerSupply.h"
#include "../scopehal/Multimeter.h"

#include <giomm.h>
#include <gtkmm.h>

double GetTime();

#endif