mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-11-02 20:51:23 -07:00 
			
		
		
		
	Several fixes to GCodeSender, including compilation on older OS X and DTR reset
This commit is contained in:
		
							parent
							
								
									e50bbc0245
								
							
						
					
					
						commit
						21a5d6e137
					
				
					 4 changed files with 112 additions and 59 deletions
				
			
		| 
						 | 
				
			
			@ -60,7 +60,7 @@ sub new {
 | 
			
		|||
            my ($pos) = @_;
 | 
			
		||||
            
 | 
			
		||||
            # delete any pending commands to get a smoother movement
 | 
			
		||||
            $self->purge_queue(1);
 | 
			
		||||
            $self->sender->purge_queue(1);
 | 
			
		||||
            $self->abs_xy_move($pos);
 | 
			
		||||
        });
 | 
			
		||||
        $bed_sizer->Add($canvas, 0, wxEXPAND | wxRIGHT, 3);
 | 
			
		||||
| 
						 | 
				
			
			@ -97,6 +97,7 @@ sub new {
 | 
			
		|||
    my $main_sizer = Wx::BoxSizer->new(wxVERTICAL);
 | 
			
		||||
    $main_sizer->Add($bed_sizer, 1, wxEXPAND | wxALL, 10);
 | 
			
		||||
    $main_sizer->Add($self->CreateButtonSizer(wxCLOSE), 0, wxEXPAND);
 | 
			
		||||
    EVT_BUTTON($self, wxID_CLOSE, sub { $self->Close });
 | 
			
		||||
    
 | 
			
		||||
    $self->SetSizer($main_sizer);
 | 
			
		||||
    $self->SetMinSize($self->GetSize);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,7 +10,8 @@ use Module::Build::WithXSpp;
 | 
			
		|||
# _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
 | 
			
		||||
# 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 @LIBS = qw();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,6 +36,8 @@ GCodeSender::~GCodeSender()
 | 
			
		|||
bool
 | 
			
		||||
GCodeSender::connect(std::string devname, unsigned int baud_rate)
 | 
			
		||||
{
 | 
			
		||||
    this->disconnect();
 | 
			
		||||
    
 | 
			
		||||
    this->set_error_status(false);
 | 
			
		||||
    try {
 | 
			
		||||
        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
 | 
			
		||||
    this->set_baud_rate(baud_rate);
 | 
			
		||||
    this->open = true;
 | 
			
		||||
    this->reset();
 | 
			
		||||
    
 | 
			
		||||
    // this gives some work to the io_service before it is started
 | 
			
		||||
    // (post() runs the supplied function in its thread)
 | 
			
		||||
| 
						 | 
				
			
			@ -117,7 +120,6 @@ void
 | 
			
		|||
GCodeSender::disconnect()
 | 
			
		||||
{
 | 
			
		||||
    if (!this->open) return;
 | 
			
		||||
 | 
			
		||||
    this->open = false;
 | 
			
		||||
    this->connected = false;
 | 
			
		||||
    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);
 | 
			
		||||
    if (error) {
 | 
			
		||||
        // 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);
 | 
			
		||||
        if (error.value() == 45) {
 | 
			
		||||
            // OS X bug: http://osdir.com/ml/lib.boost.asio.user/2008-08/msg00004.html
 | 
			
		||||
            this->do_read();
 | 
			
		||||
        } else {
 | 
			
		||||
            // 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;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // copy the read buffer into string
 | 
			
		||||
    std::istream is(&this->read_buffer);
 | 
			
		||||
    std::string line;
 | 
			
		||||
    std::getline(is, line);
 | 
			
		||||
    // note that line might contain \r at its end
 | 
			
		||||
    
 | 
			
		||||
    // parse incoming line
 | 
			
		||||
    if (!this->connected
 | 
			
		||||
        && (boost::starts_with(line, "start")
 | 
			
		||||
         || boost::starts_with(line, "Grbl "))) {
 | 
			
		||||
        this->connected = true;
 | 
			
		||||
        {
 | 
			
		||||
            boost::lock_guard<boost::mutex> l(this->queue_mutex);
 | 
			
		||||
            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) {
 | 
			
		||||
    if (!line.empty()) {
 | 
			
		||||
        // note that line might contain \r at its end
 | 
			
		||||
        // parse incoming line
 | 
			
		||||
        if (!this->connected
 | 
			
		||||
            && (boost::starts_with(line, "start")
 | 
			
		||||
             || boost::starts_with(line, "Grbl ")
 | 
			
		||||
             || boost::starts_with(line, "ok")
 | 
			
		||||
             || boost::contains(line, "T:"))) {
 | 
			
		||||
            this->connected = true;
 | 
			
		||||
            {
 | 
			
		||||
                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 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 {
 | 
			
		||||
            printf("Cannot resend %lu (last was %lu)\n", toresend, this->sent);
 | 
			
		||||
        }
 | 
			
		||||
    } 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
 | 
			
		||||
            // push any other line into the log
 | 
			
		||||
            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:");
 | 
			
		||||
            this->log.push(line);
 | 
			
		||||
        }
 | 
			
		||||
    
 | 
			
		||||
        // parse temperature info
 | 
			
		||||
        {
 | 
			
		||||
            size_t pos = line.find("T:");
 | 
			
		||||
            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));
 | 
			
		||||
                // we got temperature info
 | 
			
		||||
                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
 | 
			
		||||
GCodeSender::send()
 | 
			
		||||
{
 | 
			
		||||
    this->io.post(boost::bind(&GCodeSender::do_send, this));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
GCodeSender::do_send()
 | 
			
		||||
{
 | 
			
		||||
    boost::lock_guard<boost::mutex> l(this->queue_mutex);
 | 
			
		||||
    
 | 
			
		||||
| 
						 | 
				
			
			@ -414,15 +430,47 @@ GCodeSender::do_send(const std::string &line)
 | 
			
		|||
       cs = cs ^ *it;
 | 
			
		||||
    
 | 
			
		||||
    // write line to device
 | 
			
		||||
    asio::streambuf b;
 | 
			
		||||
    std::ostream os(&b);
 | 
			
		||||
    os << full_line << "*" << cs << "\n";
 | 
			
		||||
    asio::write(this->serial, b);
 | 
			
		||||
    full_line += "*";
 | 
			
		||||
    full_line += boost::lexical_cast<std::string>(cs);
 | 
			
		||||
    full_line += "\n";
 | 
			
		||||
    asio::async_write(this->serial, asio::buffer(full_line), boost::bind(&GCodeSender::do_send, this));
 | 
			
		||||
    
 | 
			
		||||
    this->last_sent = line;
 | 
			
		||||
    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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,6 +32,8 @@ class GCodeSender : private boost::noncopyable {
 | 
			
		|||
    std::vector<std::string> purge_log();
 | 
			
		||||
    std::string getT() const;
 | 
			
		||||
    std::string getB() const;
 | 
			
		||||
    void set_DTR(bool on);
 | 
			
		||||
    void reset();
 | 
			
		||||
    
 | 
			
		||||
    private:
 | 
			
		||||
    asio::io_service io;
 | 
			
		||||
| 
						 | 
				
			
			@ -58,6 +60,7 @@ class GCodeSender : private boost::noncopyable {
 | 
			
		|||
    
 | 
			
		||||
    void set_baud_rate(unsigned int baud_rate);
 | 
			
		||||
    void set_error_status(bool e);
 | 
			
		||||
    void do_send();
 | 
			
		||||
    void do_send(const std::string &line);
 | 
			
		||||
    void do_close();
 | 
			
		||||
    void do_read();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue