From d79da4c00b1ae907c1f0e6334cc9f44efb1f9202 Mon Sep 17 00:00:00 2001 From: Mjolnir Date: Fri, 21 Aug 2015 15:56:30 +0200 Subject: [PATCH] Keyboard + mouse with serial port discovery --- ArduinoKeyboard/ArduinoKeyboard.ino | 3 +- ArduinoKeyboard/motorcontrol.ino | 8 +- GCodeParser/GCodeParser.ino | 182 ++++++++++++++-------------- GCodeParser/process_string.ino | 10 +- GCodeParser/stepper_control.ino | 14 +-- Library/LivingKeyboard.cpp | 88 +++++++++++--- Library/LivingKeyboard.h | 5 +- Library/XYPlotter.cpp | 85 ++++++++++--- Library/XYPlotter.h | 6 +- Test/mainwindow.cpp | 25 ++-- 10 files changed, 265 insertions(+), 161 deletions(-) diff --git a/ArduinoKeyboard/ArduinoKeyboard.ino b/ArduinoKeyboard/ArduinoKeyboard.ino index b720004..7bdf521 100644 --- a/ArduinoKeyboard/ArduinoKeyboard.ino +++ b/ArduinoKeyboard/ArduinoKeyboard.ino @@ -26,7 +26,8 @@ void eval(int command, int value) switch(command) { case 'I': - Serial.println("Living Keyboard"); + Serial.print(F("LivingKeyboard\0\n")); + Serial.flush(); break; case 'T': Serial.print("Translate "); diff --git a/ArduinoKeyboard/motorcontrol.ino b/ArduinoKeyboard/motorcontrol.ino index 9ea6a8b..505a798 100644 --- a/ArduinoKeyboard/motorcontrol.ino +++ b/ArduinoKeyboard/motorcontrol.ino @@ -92,11 +92,11 @@ void translate(int distance) else { //left motor backward - digitalWrite(leftmotor1, HIGH); - digitalWrite(leftmotor2, LOW); + digitalWrite(leftmotor1, LOW); + digitalWrite(leftmotor2, HIGH); //right motor backward - digitalWrite(rightmotor1, HIGH); - digitalWrite(rightmotor2, LOW); + digitalWrite(rightmotor1, LOW); + digitalWrite(rightmotor2, HIGH); distance = -distance; } diff --git a/GCodeParser/GCodeParser.ino b/GCodeParser/GCodeParser.ino index c658da7..77c801c 100644 --- a/GCodeParser/GCodeParser.ino +++ b/GCodeParser/GCodeParser.ino @@ -1,6 +1,6 @@ /* Pin numbers adapted -*/ + */ #include // define the parameters of our machine. @@ -17,8 +17,8 @@ float Z_STEPS_PER_MM = 40; int Z_MOTOR_STEPS = 100; //our maximum feedrates -long FAST_XY_FEEDRATE = 2000; -long FAST_Z_FEEDRATE = 2000; +long FAST_XY_FEEDRATE = 50000; +long FAST_Z_FEEDRATE = 50000; // Units in curve section #define CURVE_SECTION_INCHES 0.019685 @@ -32,29 +32,29 @@ int SENSORS_INVERTING = 1; /**************************************************************************************** -* digital i/o pin assignment -* -* this uses the undocumented feature of Arduino - pins 14-19 correspond to analog 0-5 -****************************************************************************************/ + * digital i/o pin assignment + * + * this uses the undocumented feature of Arduino - pins 14-19 correspond to analog 0-5 + ****************************************************************************************/ /* int X_STEP_PIN = 8; -int X_DIR_PIN = 11; -int X_ENABLE_PIN = 4; -int X_MIN_PIN = A4; -int X_MAX_PIN = A5; - -int Y_STEP_PIN = 12; -int Y_DIR_PIN = 13; -int Y_ENABLE_PIN = 4; -int Y_MIN_PIN = A1; -int Y_MAX_PIN = A0; - -int Z_STEP_PIN = A3; -int Z_DIR_PIN = 9; -int Z_ENABLE_PIN = 4; -int Z_MIN_PIN = A1; -int Z_MAX_PIN = A0; -int Z_ENABLE_SERVO = 1;*/ + int X_DIR_PIN = 11; + int X_ENABLE_PIN = 4; + int X_MIN_PIN = A4; + int X_MAX_PIN = A5; + + int Y_STEP_PIN = 12; + int Y_DIR_PIN = 13; + int Y_ENABLE_PIN = 4; + int Y_MIN_PIN = A1; + int Y_MAX_PIN = A0; + + int Z_STEP_PIN = A3; + int Z_DIR_PIN = 9; + int Z_ENABLE_PIN = 4; + int Z_MIN_PIN = A1; + int Z_MAX_PIN = A0; + int Z_ENABLE_SERVO = 1;*/ int X_STEP_PIN = 10; int X_DIR_PIN = 11; @@ -88,75 +88,77 @@ int targetPosServo = 90; bool comment = false; void setup() { - //Do startup stuff here - Serial.begin(115200); - if(Z_ENABLE_SERVO==1){ - servo.attach(Z_STEP_PIN); - } - //other initialization. - init_process_string(); - init_steppers(); - process_string("G90",3);//Absolute Position - Serial.println("start"); + //Do startup stuff here + Serial.begin(9600); + if(Z_ENABLE_SERVO==1){ + servo.attach(Z_STEP_PIN); + } + //other initialization. + init_process_string(); + init_steppers(); + process_string("G90",3);//Absolute Position + //Serial.println("start"); } void loop() { - - char c; - //read in characters if we got them. - if (Serial.available() > 0) - { - c = Serial.read(); - no_data = 0; - //newlines are ends of commands. - if (c != '\n') - { - if(c==0x18){ - Serial.println("Grbl 1.0"); - }else{ - if (c == '('){ - comment = true; - } - // If we're not in comment mode, add it to our array. - if (!comment) - { - commands[serial_count] = c; - serial_count++; - } - if (c == ')'){ - comment = false; // End of comment - start listening again - } - } - - } - }else - { - no_data++; - delayMicroseconds(100); - - //if theres a pause or we got a real command, do it - if (serial_count && (c == '\n' || no_data > 100)) - { - //process our command! - process_string(commands, serial_count); - //clear command. - init_process_string(); - } - - //no data? turn off steppers - if (no_data > 1000){ - disable_steppers(); - } + + char c; + //read in characters if we got them. + if (Serial.available() > 0) + { + c = Serial.read(); + no_data = 0; + //newlines are ends of commands. + if (c != '\n') + { + if(c=='I') + Serial.print(F("XYPlotter\0\n")); + else + { + if (c == '(') + comment = true; + + // If we're not in comment mode, add it to our array. + if (!comment) + { + commands[serial_count] = c; + serial_count++; } -// return; -// delay(5); -// int dPos = abs(currentPosServo-targetPosServo); -// if(currentPosServo8?6:1; -// }else if(currentPosServo>targetPosServo){ -// currentPosServo -= dPos>8?6:1; -// } - - + if (c == ')') + comment = false; // End of comment - start listening again + } + + } + } + else + { + no_data++; + delayMicroseconds(100); + + //if theres a pause or we got a real command, do it + if (serial_count && (c == '\n' || no_data > 100)) + { + //process our command! + process_string(commands, serial_count); + //clear command. + init_process_string(); + } + + //no data? turn off steppers + if (no_data > 1000){ + disable_steppers(); + } + } + // return; + // delay(5); + // int dPos = abs(currentPosServo-targetPosServo); + // if(currentPosServo8?6:1; + // }else if(currentPosServo>targetPosServo){ + // currentPosServo -= dPos>8?6:1; + // } + + } + diff --git a/GCodeParser/process_string.ino b/GCodeParser/process_string.ino index 665ea61..0240f02 100644 --- a/GCodeParser/process_string.ino +++ b/GCodeParser/process_string.ino @@ -51,7 +51,7 @@ void process_string(char instruction[], int size) //the character / means delete block... used for comments and stuff. if (instruction[0] == '/') { - Serial.println("ok"); + //Serial.println("ok"); return; } @@ -299,7 +299,7 @@ void process_string(char instruction[], int size) */ default: - Serial.print("huh? G"); + Serial.print("Unknown G"); Serial.println(code,DEC); } } @@ -314,7 +314,7 @@ void process_string(char instruction[], int size) break; default: - Serial.print("Huh? M"); + Serial.print("Unknown M"); Serial.println(code); } } @@ -440,11 +440,11 @@ void process_string(char instruction[], int size) } //tell our host we're done. - if(code==0&&size==1){ + /*if(code==0&&size==1){ Serial.println("start"); }else{ Serial.println("ok"); - } + }*/ // Serial.println(line, DEC); } diff --git a/GCodeParser/stepper_control.ino b/GCodeParser/stepper_control.ino index dc1f2da..e25d91d 100644 --- a/GCodeParser/stepper_control.ino +++ b/GCodeParser/stepper_control.ino @@ -47,30 +47,30 @@ void init_steppers() void goto_machine_zero() { - Serial.println("init"); - Serial.println("calibrate axis x"); + //Serial.println("init"); + //Serial.println("calibrate axis x"); move_to_max(X_MIN_PIN, X_STEP_PIN, X_DIR_PIN, 0); - Serial.println("calibrate axis y"); + //Serial.println("calibrate axis y"); move_to_max(Y_MIN_PIN, Y_STEP_PIN, Y_DIR_PIN, 0); - Serial.println("ok"); + //Serial.println("ok"); } void move_to_max(int limiter_pin, int stepper_pin, int stepper_dir_pin,int dir) { /* Moves to the maximum possible position */ - Serial.println("go to max"); + //Serial.println("go to max"); while(can_step(limiter_pin, limiter_pin, 0, 1, dir)){ do_step(stepper_pin, stepper_dir_pin, 0); delay(1); } - Serial.println("step back"); + //Serial.println("step back"); // slowly back unitl pin is released while(!can_step(limiter_pin, limiter_pin, 0, 1, dir)){ do_step(stepper_pin, stepper_dir_pin, 1); delay(100); } - Serial.println("done"); + //Serial.println("done"); } void dda_move(long micro_delay) diff --git a/Library/LivingKeyboard.cpp b/Library/LivingKeyboard.cpp index a401f81..45cbcdb 100644 --- a/Library/LivingKeyboard.cpp +++ b/Library/LivingKeyboard.cpp @@ -1,33 +1,85 @@ #include "LivingKeyboard.h" -LivingKeyboard::LivingKeyboard(QString port) -: serialPort(new QSerialPort(port)), connected(false) +#include +#include + +#define QIODEVICE_DEBUG + +char const *LivingKeyboard::serialports[] = {"ttyUSB0", "ttyUSB1", "ttyUSB2", "ttyUSB3", "ttyUSB4"}; + +LivingKeyboard::LivingKeyboard() +: serialPort(NULL) { - if(serialPort->open(QIODevice::ReadWrite)) + //Port discovery + for (int i = 0 ; i < 5 && !serialPort ; i++) { - serialPort->setBaudRate(QSerialPort::Baud9600,QSerialPort::AllDirections); - serialPort->setDataBits(QSerialPort::Data8); - serialPort->setParity(QSerialPort::NoParity); - serialPort->setStopBits(QSerialPort::TwoStop); - serialPort->setFlowControl(QSerialPort::NoFlowControl); - connected = true; - } - else - { - serialPort->close(); - throw(ErrorMessage("Keyboard: serial port error " + QString::number(serialPort->error()))); + serialPort = new QSerialPort(serialports[i]); + if(serialPort->open(QIODevice::ReadWrite)) + { + serialPort->setBaudRate(QSerialPort::Baud9600, QSerialPort::AllDirections); + serialPort->setDataBits(QSerialPort::Data8); + serialPort->setParity(QSerialPort::NoParity); + serialPort->setStopBits(QSerialPort::OneStop); + serialPort->setFlowControl(QSerialPort::NoFlowControl); + serialPort->setReadBufferSize(32); + + qDebug() << "Trying port " << serialports[i]; + + //ask fo his name + serialPort->write("I\n", 2); + serialPort->flush(); + QThread::msleep(500); + char buffer[32]; + //memset(buffer,0, 32*sizeof(char)); + if (serialPort->waitForReadyRead(10000)) + { + int nb = serialPort->read(buffer, sizeof(buffer) - 1); + buffer[nb] = 0; + qDebug() << "Received " << nb << " bytes : '" << buffer << "'"; + if (nb <= 0) + { + qDebug() << "Communcation problem with port " << serialports[i]; + serialPort->close(); + serialPort = NULL; + } + else if (strcmp(buffer, "LivingKeyboard") == 0) + qDebug() << "Found LivingKeyboard on port " << serialports[i]; + else + { + qDebug() << "Not LivingKeyboard"; + serialPort->close(); + serialPort = NULL; + } + } + else + { + qDebug() << "Port " << serialports[i] << "not responding"; + serialPort->close(); + serialPort = NULL; + } + } + else + { + serialPort->close(); + serialPort = NULL; + } } + if (! serialPort) + throw(ErrorMessage("Cannot find Keyboard")); } LivingKeyboard::~LivingKeyboard() { - serialPort->close(); - delete serialPort; + if (serialPort) + { + serialPort->close(); + delete serialPort; + } } void LivingKeyboard::rotation(LivingKeyboard::tilt t, unsigned int angle) { - if (connected) + if (serialPort) { int a = angle; if (t == LEFT) @@ -39,7 +91,7 @@ void LivingKeyboard::rotation(LivingKeyboard::tilt t, unsigned int angle) void LivingKeyboard::translation(LivingKeyboard::direction d, unsigned int distance) { - if (connected) + if (serialPort) { int dis = distance; if (d == BACKWARD) diff --git a/Library/LivingKeyboard.h b/Library/LivingKeyboard.h index 43db051..0fbe8d1 100644 --- a/Library/LivingKeyboard.h +++ b/Library/LivingKeyboard.h @@ -8,7 +8,7 @@ class LivingKeyboard { public: - LivingKeyboard(QString port); + LivingKeyboard(); ~LivingKeyboard(); @@ -20,7 +20,8 @@ class LivingKeyboard private: QSerialPort* serialPort; - bool connected; + + static char const *serialports[]; }; #endif // LIVINGKEYBOARD_H diff --git a/Library/XYPlotter.cpp b/Library/XYPlotter.cpp index eecbd77..c243b35 100644 --- a/Library/XYPlotter.cpp +++ b/Library/XYPlotter.cpp @@ -1,39 +1,88 @@ #include "XYPlotter.h" #include +#include +#include +char const *XYPlotter::serialports[] = {"ttyUSB0", "ttyUSB1", "ttyUSB2", "ttyUSB3", "ttyUSB4"}; const int XYPlotter::toolDistance = 70; -XYPlotter::XYPlotter(QString port) -: serialPort(new QSerialPort(port)), connected(false), posX(0), posY(0), toolUp(false) +XYPlotter::XYPlotter() +: serialPort(NULL) { - if(serialPort->open(QIODevice::ReadWrite)) + //Port discovery + for (int i = 0 ; i < 5 && !serialPort ; i++) { - serialPort->setBaudRate(QSerialPort::Baud115200,QSerialPort::AllDirections); - serialPort->setDataBits(QSerialPort::Data8); - serialPort->setParity(QSerialPort::NoParity); - serialPort->setStopBits(QSerialPort::TwoStop); - serialPort->setFlowControl(QSerialPort::NoFlowControl); - connected = true; - } - else - { - serialPort->close(); - throw(ErrorMessage("XYPlotter: serial port error " + QString::number(serialPort->error()))); + serialPort = new QSerialPort(serialports[i]); + if(serialPort->open(QIODevice::ReadWrite)) + { + serialPort->setBaudRate(QSerialPort::Baud9600, QSerialPort::AllDirections); + serialPort->setDataBits(QSerialPort::Data8); + serialPort->setParity(QSerialPort::NoParity); + serialPort->setStopBits(QSerialPort::OneStop); + serialPort->setFlowControl(QSerialPort::NoFlowControl); + serialPort->setReadBufferSize(32); + + qDebug() << "Trying port " << serialports[i]; + + //ask fo his name + QThread::sleep(13); + serialPort->write("I\n", 2); + serialPort->flush(); + char buffer[32]; + //memset(buffer,0, 32*sizeof(char)); + qDebug() << "Waiting for data"; + if (serialPort->waitForReadyRead(1500)) + { + int nb = serialPort->read(buffer, sizeof(buffer) - 1); + buffer[nb] = 0; + qDebug() << "Received " << nb << " bytes : '" << buffer << "'"; + if (nb <= 0) + { + qDebug() << "Port " << serialports[i] << "not responding"; + serialPort->close(); + serialPort = NULL; + } + else if (strcmp(buffer, "XYPlotter") == 0) + qDebug() << "Found XYPlotter on port " << serialports[i]; + else + { + qDebug() << "Not XYPlotter"; + serialPort->close(); + serialPort = NULL; + } + } + else + { + qDebug() << "Port " << serialports[i] << "not responding"; + serialPort->close(); + serialPort = NULL; + } + } + else + { + serialPort->close(); + serialPort = NULL; + } } + if (! serialPort) + throw(ErrorMessage("Cannot find XYPlotter")); } XYPlotter::~XYPlotter() { - serialPort->close(); - delete serialPort; + if (serialPort) + { + serialPort->close(); + delete serialPort; + } } void XYPlotter::moveTo(unsigned int x, unsigned int y, bool toolup=true) { - if (connected) + if (serialPort) { - QString buffer = "G01X" + QString::number(x) + + QString buffer = "G00X" + QString::number(x) + "Y" + QString::number(y) + "Z" + QString::number(toolup * toolDistance) + "\n"; //"F50000\n"; diff --git a/Library/XYPlotter.h b/Library/XYPlotter.h index a3064c0..69319e3 100644 --- a/Library/XYPlotter.h +++ b/Library/XYPlotter.h @@ -8,21 +8,19 @@ class LIVINGDESKTOPLIBRARYSHARED_EXPORT XYPlotter { public: - XYPlotter(QString port); + XYPlotter(); ~XYPlotter(); void moveTo(unsigned int x, unsigned int y, bool toolup); private: - XYPlotter(){} - QSerialPort* serialPort; - bool connected; unsigned int posX, posY; bool toolUp; static const int toolDistance; + static char const *serialports[]; }; #endif // XYPLOTTER_H diff --git a/Test/mainwindow.cpp b/Test/mainwindow.cpp index e111210..49682b1 100644 --- a/Test/mainwindow.cpp +++ b/Test/mainwindow.cpp @@ -7,29 +7,30 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); - qDebug("Connect mouse"); + qDebug() << "Connect keyboard"; try { - mouse = new XYPlotter("ttyUSB3"); - connect(ui->mousebutton, SIGNAL(clicked()), this, SLOT(moveMouse())); - ui->mousebutton->setEnabled(true); + keyboard = new LivingKeyboard(); + connect(ui->keyboardbutton, SIGNAL(clicked()), this, SLOT(translateKeyboard())); + connect(ui->rotation, SIGNAL(valueChanged(int)), this, SLOT(rotateKeyboard(int))); + ui->keyboardbutton->setEnabled(true); } catch (ErrorMessage e) { - mouse = NULL; + keyboard = NULL; qDebug() << QString(e.what()); } - qDebug() << "Connect keyboard"; + qDebug("Connect mouse"); try { - keyboard = new LivingKeyboard("ttyUSB2"); - connect(ui->keyboardbutton, SIGNAL(clicked()), this, SLOT(translateKeyboard())); - connect(ui->rotation, SIGNAL(valueChanged(int)), this, SLOT(rotateKeyboard(int))); - ui->keyboardbutton->setEnabled(true); + //The mouse may require a little time because of calibration (blocking process) + mouse = new XYPlotter(); + connect(ui->mousebutton, SIGNAL(clicked()), this, SLOT(moveMouse())); + ui->mousebutton->setEnabled(true); } catch (ErrorMessage e) { - keyboard = NULL; + mouse = NULL; qDebug() << QString(e.what()); } } @@ -49,7 +50,7 @@ MainWindow::~MainWindow() void MainWindow::moveMouse() { unsigned int x = ui->xvalue->value(); - unsigned int y = ui->xvalue->value(); + unsigned int y = ui->yvalue->value(); bool toolup = ui->toolupvalue->checkState() == Qt::Checked; if (mouse) mouse->moveTo(x, y, toolup); -- 2.30.2