#include "modules/robot/Robot.h"
#include "modules/robot/Stepper.h"
#include "modules/robot/Conveyor.h"
+#include "StepperMotor.h"
#include <malloc.h>
#include <array>
+#include <string>
#define baud_rate_setting_checksum CHECKSUM("baud_rate")
#define uart0_checksum CHECKSUM("uart0")
}
+// return a GRBL-like query string for serial ?
+std::string Kernel::get_query_string()
+{
+ std::string str;
+ str.append("<");
+ if(halted) {
+ str.append("Alarm,");
+ }else if(this->conveyor->is_queue_empty()) {
+ str.append("Idle,");
+ }else{
+ str.append("Run,");
+ }
+
+ char buf[64];
+ size_t n= snprintf(buf, sizeof(buf), "%f,%f,%f,", this->robot->actuators[X_AXIS]->get_current_position(), this->robot->actuators[Y_AXIS]->get_current_position(), this->robot->actuators[Z_AXIS]->get_current_position());
+ str.append("MPos:").append(buf, n);
+
+ float pos[3];
+ this->robot->get_axis_position(pos);
+ n= snprintf(buf, sizeof(buf), "%f,%f,%f", pos[0], pos[1], pos[2]);
+ str.append("WPos:").append(buf, n);
+ str.append(">\r\n");
+ return str;
+}
+
// Add a module to Kernel. We don't actually hold a list of modules we just call its on_module_loaded
void Kernel::add_module(Module* module){
module->on_module_loaded();
bool is_using_leds() const { return use_leds; }
bool is_halted() const { return halted; }
+ std::string get_query_string();
// These modules are available to all other modules
SerialConsole* serial;
void SerialConsole::on_module_loaded() {
// We want to be called every time a new char is received
this->serial->attach(this, &SerialConsole::on_serial_char_received, mbed::Serial::RxIrq);
+ query_flag= false;
// We only call the command dispatcher in the main loop, nowhere else
this->register_for_event(ON_MAIN_LOOP);
+ this->register_for_event(ON_IDLE);
// Add to the pack of streams kernel can call to, for example for broadcasting
THEKERNEL->streams->append_stream(this);
void SerialConsole::on_serial_char_received(){
while(this->serial->readable()){
char received = this->serial->getc();
+ if(received == '?') {
+ query_flag= true;
+ continue;
+ }
+ if(received == 26) { // ^X
+ halt_flag= true;
+ continue;
+ }
// convert CR to NL (for host OSs that don't send NL)
if( received == '\r' ){ received = '\n'; }
this->buffer.push_back(received);
}
}
+void SerialConsole::on_idle(void * argument)
+{
+ if(query_flag) {
+ query_flag= false;
+ puts(THEKERNEL->get_query_string().c_str());
+ }
+ if(halt_flag) {
+ halt_flag= false;
+ THEKERNEL->call_event(ON_HALT, nullptr);
+ }
+}
+
// Actual event calling must happen in the main loop because if it happens in the interrupt we will loose data
void SerialConsole::on_main_loop(void * argument){
if( this->has_char('\n') ){
void on_module_loaded();
void on_serial_char_received();
void on_main_loop(void * argument);
+ void on_idle(void * argument);
bool has_char(char letter);
int _putc(int c);
//vector<std::string> received_lines; // Received lines are stored here until they are requested
RingBuffer<char,256> buffer; // Receive buffer
mbed::Serial* serial;
+ struct {
+ bool query_flag:1;
+ bool halt_flag:1;
+ };
};
#endif