Several fixes to GCodeSender, including compilation on older OS X and DTR reset
This commit is contained in:
parent
e50bbc0245
commit
21a5d6e137
@ -60,7 +60,7 @@ sub new {
|
|||||||
my ($pos) = @_;
|
my ($pos) = @_;
|
||||||
|
|
||||||
# delete any pending commands to get a smoother movement
|
# delete any pending commands to get a smoother movement
|
||||||
$self->purge_queue(1);
|
$self->sender->purge_queue(1);
|
||||||
$self->abs_xy_move($pos);
|
$self->abs_xy_move($pos);
|
||||||
});
|
});
|
||||||
$bed_sizer->Add($canvas, 0, wxEXPAND | wxRIGHT, 3);
|
$bed_sizer->Add($canvas, 0, wxEXPAND | wxRIGHT, 3);
|
||||||
@ -97,6 +97,7 @@ sub new {
|
|||||||
my $main_sizer = Wx::BoxSizer->new(wxVERTICAL);
|
my $main_sizer = Wx::BoxSizer->new(wxVERTICAL);
|
||||||
$main_sizer->Add($bed_sizer, 1, wxEXPAND | wxALL, 10);
|
$main_sizer->Add($bed_sizer, 1, wxEXPAND | wxALL, 10);
|
||||||
$main_sizer->Add($self->CreateButtonSizer(wxCLOSE), 0, wxEXPAND);
|
$main_sizer->Add($self->CreateButtonSizer(wxCLOSE), 0, wxEXPAND);
|
||||||
|
EVT_BUTTON($self, wxID_CLOSE, sub { $self->Close });
|
||||||
|
|
||||||
$self->SetSizer($main_sizer);
|
$self->SetSizer($main_sizer);
|
||||||
$self->SetMinSize($self->GetSize);
|
$self->SetMinSize($self->GetSize);
|
||||||
|
@ -10,7 +10,8 @@ use Module::Build::WithXSpp;
|
|||||||
# _GLIBCXX_USE_C99 : to get the long long type for g++
|
# _GLIBCXX_USE_C99 : to get the long long type for g++
|
||||||
# HAS_BOOL : stops Perl/lib/CORE/handy.h from doing "# define bool char" for MSVC
|
# HAS_BOOL : stops Perl/lib/CORE/handy.h from doing "# define bool char" for MSVC
|
||||||
# NOGDI : prevents inclusion of wingdi.h which defines functions Polygon() and Polyline() in global namespace
|
# NOGDI : prevents inclusion of wingdi.h which defines functions Polygon() and Polyline() in global namespace
|
||||||
my @cflags = qw(-D_GLIBCXX_USE_C99 -DHAS_BOOL -DNOGDI -DSLIC3RXS);
|
# BOOST_ASIO_DISABLE_KQUEUE : prevents a Boost ASIO bug on OS X: https://svn.boost.org/trac/boost/ticket/5339
|
||||||
|
my @cflags = qw(-D_GLIBCXX_USE_C99 -DHAS_BOOL -DNOGDI -DSLIC3RXS -DBOOST_ASIO_DISABLE_KQUEUE);
|
||||||
|
|
||||||
my @INC = qw();
|
my @INC = qw();
|
||||||
my @LIBS = qw();
|
my @LIBS = qw();
|
||||||
|
@ -36,6 +36,8 @@ GCodeSender::~GCodeSender()
|
|||||||
bool
|
bool
|
||||||
GCodeSender::connect(std::string devname, unsigned int baud_rate)
|
GCodeSender::connect(std::string devname, unsigned int baud_rate)
|
||||||
{
|
{
|
||||||
|
this->disconnect();
|
||||||
|
|
||||||
this->set_error_status(false);
|
this->set_error_status(false);
|
||||||
try {
|
try {
|
||||||
this->serial.open(devname);
|
this->serial.open(devname);
|
||||||
@ -57,6 +59,7 @@ GCodeSender::connect(std::string devname, unsigned int baud_rate)
|
|||||||
// set baud rate again because set_option overwrote it
|
// set baud rate again because set_option overwrote it
|
||||||
this->set_baud_rate(baud_rate);
|
this->set_baud_rate(baud_rate);
|
||||||
this->open = true;
|
this->open = true;
|
||||||
|
this->reset();
|
||||||
|
|
||||||
// this gives some work to the io_service before it is started
|
// this gives some work to the io_service before it is started
|
||||||
// (post() runs the supplied function in its thread)
|
// (post() runs the supplied function in its thread)
|
||||||
@ -117,7 +120,6 @@ void
|
|||||||
GCodeSender::disconnect()
|
GCodeSender::disconnect()
|
||||||
{
|
{
|
||||||
if (!this->open) return;
|
if (!this->open) return;
|
||||||
|
|
||||||
this->open = false;
|
this->open = false;
|
||||||
this->connected = false;
|
this->connected = false;
|
||||||
this->io.post(boost::bind(&GCodeSender::do_close, this));
|
this->io.post(boost::bind(&GCodeSender::do_close, this));
|
||||||
@ -262,73 +264,81 @@ GCodeSender::on_read(const boost::system::error_code& error,
|
|||||||
{
|
{
|
||||||
this->set_error_status(false);
|
this->set_error_status(false);
|
||||||
if (error) {
|
if (error) {
|
||||||
// error can be true even because the serial port was closed.
|
if (error.value() == 45) {
|
||||||
// In this case it is not a real error, so ignore.
|
// OS X bug: http://osdir.com/ml/lib.boost.asio.user/2008-08/msg00004.html
|
||||||
if (this->open) {
|
this->do_read();
|
||||||
this->do_close();
|
} else {
|
||||||
this->set_error_status(true);
|
// printf("ERROR: [%d] %s\n", error.value(), error.message().c_str());
|
||||||
|
// error can be true even because the serial port was closed.
|
||||||
|
// In this case it is not a real error, so ignore.
|
||||||
|
if (this->open) {
|
||||||
|
this->do_close();
|
||||||
|
this->set_error_status(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy the read buffer into string
|
|
||||||
std::istream is(&this->read_buffer);
|
std::istream is(&this->read_buffer);
|
||||||
std::string line;
|
std::string line;
|
||||||
std::getline(is, line);
|
std::getline(is, line);
|
||||||
// note that line might contain \r at its end
|
if (!line.empty()) {
|
||||||
|
// note that line might contain \r at its end
|
||||||
// parse incoming line
|
// parse incoming line
|
||||||
if (!this->connected
|
if (!this->connected
|
||||||
&& (boost::starts_with(line, "start")
|
&& (boost::starts_with(line, "start")
|
||||||
|| boost::starts_with(line, "Grbl "))) {
|
|| boost::starts_with(line, "Grbl ")
|
||||||
this->connected = true;
|
|| boost::starts_with(line, "ok")
|
||||||
{
|
|| boost::contains(line, "T:"))) {
|
||||||
boost::lock_guard<boost::mutex> l(this->queue_mutex);
|
this->connected = true;
|
||||||
this->can_send = true;
|
|
||||||
}
|
|
||||||
this->send();
|
|
||||||
} else if (boost::starts_with(line, "ok")) {
|
|
||||||
{
|
|
||||||
boost::lock_guard<boost::mutex> l(this->queue_mutex);
|
|
||||||
this->can_send = true;
|
|
||||||
}
|
|
||||||
this->send();
|
|
||||||
} else if (boost::istarts_with(line, "resend") // Marlin uses "Resend: "
|
|
||||||
|| boost::istarts_with(line, "rs")) {
|
|
||||||
// extract the first number from line
|
|
||||||
boost::algorithm::trim_left_if(line, !boost::algorithm::is_digit());
|
|
||||||
size_t toresend = boost::lexical_cast<size_t>(line.substr(0, line.find_first_not_of("0123456789")));
|
|
||||||
if (toresend == this->sent) {
|
|
||||||
{
|
{
|
||||||
boost::lock_guard<boost::mutex> l(this->queue_mutex);
|
boost::lock_guard<boost::mutex> l(this->queue_mutex);
|
||||||
this->priqueue.push(this->last_sent);
|
|
||||||
this->sent--; // resend it with the same line number
|
|
||||||
this->can_send = true;
|
this->can_send = true;
|
||||||
}
|
}
|
||||||
this->send();
|
this->send();
|
||||||
|
} else if (boost::starts_with(line, "ok")) {
|
||||||
|
{
|
||||||
|
boost::lock_guard<boost::mutex> l(this->queue_mutex);
|
||||||
|
this->can_send = true;
|
||||||
|
}
|
||||||
|
this->send();
|
||||||
|
} else if (boost::istarts_with(line, "resend") // Marlin uses "Resend: "
|
||||||
|
|| boost::istarts_with(line, "rs")) {
|
||||||
|
// extract the first number from line
|
||||||
|
boost::algorithm::trim_left_if(line, !boost::algorithm::is_digit());
|
||||||
|
size_t toresend = boost::lexical_cast<size_t>(line.substr(0, line.find_first_not_of("0123456789")));
|
||||||
|
if (toresend == this->sent) {
|
||||||
|
{
|
||||||
|
boost::lock_guard<boost::mutex> l(this->queue_mutex);
|
||||||
|
this->priqueue.push(this->last_sent);
|
||||||
|
this->sent--; // resend it with the same line number
|
||||||
|
this->can_send = true;
|
||||||
|
}
|
||||||
|
this->send();
|
||||||
|
} else {
|
||||||
|
printf("Cannot resend %lu (last was %lu)\n", toresend, this->sent);
|
||||||
|
}
|
||||||
|
} else if (boost::starts_with(line, "wait")) {
|
||||||
|
// ignore
|
||||||
} else {
|
} else {
|
||||||
printf("Cannot resend %lu (last was %lu)\n", toresend, this->sent);
|
// push any other line into the log
|
||||||
}
|
|
||||||
} else if (boost::starts_with(line, "wait")) {
|
|
||||||
// ignore
|
|
||||||
} else {
|
|
||||||
// push any other line into the log
|
|
||||||
boost::lock_guard<boost::mutex> l(this->log_mutex);
|
|
||||||
this->log.push(line);
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse temperature info
|
|
||||||
{
|
|
||||||
size_t pos = line.find("T:");
|
|
||||||
if (pos != std::string::npos && line.size() > pos + 2) {
|
|
||||||
// we got temperature info
|
|
||||||
boost::lock_guard<boost::mutex> l(this->log_mutex);
|
boost::lock_guard<boost::mutex> l(this->log_mutex);
|
||||||
this->T = line.substr(pos+2, line.find_first_not_of("0123456789.", pos+2) - (pos+2));
|
this->log.push(line);
|
||||||
|
}
|
||||||
|
|
||||||
pos = line.find("B:");
|
// parse temperature info
|
||||||
|
{
|
||||||
|
size_t pos = line.find("T:");
|
||||||
if (pos != std::string::npos && line.size() > pos + 2) {
|
if (pos != std::string::npos && line.size() > pos + 2) {
|
||||||
// we got bed temperature info
|
// we got temperature info
|
||||||
this->B = line.substr(pos+2, line.find_first_not_of("0123456789.", pos+2) - (pos+2));
|
boost::lock_guard<boost::mutex> l(this->log_mutex);
|
||||||
|
this->T = line.substr(pos+2, line.find_first_not_of("0123456789.", pos+2) - (pos+2));
|
||||||
|
|
||||||
|
pos = line.find("B:");
|
||||||
|
if (pos != std::string::npos && line.size() > pos + 2) {
|
||||||
|
// we got bed temperature info
|
||||||
|
this->B = line.substr(pos+2, line.find_first_not_of("0123456789.", pos+2) - (pos+2));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -370,6 +380,12 @@ GCodeSender::send(const std::string &line, bool priority)
|
|||||||
|
|
||||||
void
|
void
|
||||||
GCodeSender::send()
|
GCodeSender::send()
|
||||||
|
{
|
||||||
|
this->io.post(boost::bind(&GCodeSender::do_send, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GCodeSender::do_send()
|
||||||
{
|
{
|
||||||
boost::lock_guard<boost::mutex> l(this->queue_mutex);
|
boost::lock_guard<boost::mutex> l(this->queue_mutex);
|
||||||
|
|
||||||
@ -414,15 +430,47 @@ GCodeSender::do_send(const std::string &line)
|
|||||||
cs = cs ^ *it;
|
cs = cs ^ *it;
|
||||||
|
|
||||||
// write line to device
|
// write line to device
|
||||||
asio::streambuf b;
|
full_line += "*";
|
||||||
std::ostream os(&b);
|
full_line += boost::lexical_cast<std::string>(cs);
|
||||||
os << full_line << "*" << cs << "\n";
|
full_line += "\n";
|
||||||
asio::write(this->serial, b);
|
asio::async_write(this->serial, asio::buffer(full_line), boost::bind(&GCodeSender::do_send, this));
|
||||||
|
|
||||||
this->last_sent = line;
|
this->last_sent = line;
|
||||||
this->can_send = false;
|
this->can_send = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GCodeSender::set_DTR(bool on)
|
||||||
|
{
|
||||||
|
#if defined(_WIN32) && !defined(__SYMBIAN32__)
|
||||||
|
asio::serial_port_service::native_handle_type handle = this->serial.native_handle();
|
||||||
|
if (on)
|
||||||
|
EscapeCommFunction(handle, SETDTR);
|
||||||
|
else
|
||||||
|
EscapeCommFunction(handle, CLRDTR);
|
||||||
|
#else
|
||||||
|
int fd = this->serial.native_handle();
|
||||||
|
int status;
|
||||||
|
ioctl(fd, TIOCMGET, &status);
|
||||||
|
if (on)
|
||||||
|
status |= TIOCM_DTR;
|
||||||
|
else
|
||||||
|
status &= ~TIOCM_DTR;
|
||||||
|
ioctl(fd, TIOCMSET, &status);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GCodeSender::reset()
|
||||||
|
{
|
||||||
|
this->set_DTR(false);
|
||||||
|
boost::this_thread::sleep(boost::posix_time::milliseconds(200));
|
||||||
|
this->set_DTR(true);
|
||||||
|
boost::this_thread::sleep(boost::posix_time::milliseconds(200));
|
||||||
|
this->set_DTR(false);
|
||||||
|
boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SLIC3RXS
|
#ifdef SLIC3RXS
|
||||||
|
@ -32,6 +32,8 @@ class GCodeSender : private boost::noncopyable {
|
|||||||
std::vector<std::string> purge_log();
|
std::vector<std::string> purge_log();
|
||||||
std::string getT() const;
|
std::string getT() const;
|
||||||
std::string getB() const;
|
std::string getB() const;
|
||||||
|
void set_DTR(bool on);
|
||||||
|
void reset();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
asio::io_service io;
|
asio::io_service io;
|
||||||
@ -58,6 +60,7 @@ class GCodeSender : private boost::noncopyable {
|
|||||||
|
|
||||||
void set_baud_rate(unsigned int baud_rate);
|
void set_baud_rate(unsigned int baud_rate);
|
||||||
void set_error_status(bool e);
|
void set_error_status(bool e);
|
||||||
|
void do_send();
|
||||||
void do_send(const std::string &line);
|
void do_send(const std::string &line);
|
||||||
void do_close();
|
void do_close();
|
||||||
void do_read();
|
void do_read();
|
||||||
|
Loading…
Reference in New Issue
Block a user