Keyboard + mouse with serial port discovery
authorMjolnir <thomas.pietrzak@inria.fr>
Fri, 21 Aug 2015 13:56:30 +0000 (15:56 +0200)
committerMjolnir <thomas.pietrzak@inria.fr>
Fri, 21 Aug 2015 13:56:30 +0000 (15:56 +0200)
ArduinoKeyboard/ArduinoKeyboard.ino
ArduinoKeyboard/motorcontrol.ino
GCodeParser/GCodeParser.ino
GCodeParser/process_string.ino
GCodeParser/stepper_control.ino
Library/LivingKeyboard.cpp
Library/LivingKeyboard.h
Library/XYPlotter.cpp
Library/XYPlotter.h
Test/mainwindow.cpp

index b720004c11d793eef5664cb7c0acf0654485944f..7bdf52115f7ce380d9a60c1054b95191a3dca452 100644 (file)
@@ -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 ");
index 9ea6a8b8ff7aa5a5c150e619da3ea4a80e814956..505a798d14a53aea0dc073a400b8a1f55dfa6b0b 100644 (file)
@@ -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;
   }
index c658da74db056b9a541360de37baec87d94134ec..77c801c08dc78d87a2610208c9aa04ea46789cd5 100644 (file)
@@ -1,6 +1,6 @@
 /*
   Pin numbers adapted
-*/
+ */
 
 #include <Servo.h>
 // 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(currentPosServo<targetPosServo){
-//                   currentPosServo += dPos>8?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(currentPosServo<targetPosServo){
+  //                   currentPosServo += dPos>8?6:1;
+  //                }else if(currentPosServo>targetPosServo){
+  //                   currentPosServo -= dPos>8?6:1;
+  //                }
+
+
 }
+
index 665ea614f7eb1a8d0edd1e0200a3af6ea72f3a37..0240f02b5acedc66ae6cc11605905bfccb3a86a8 100644 (file)
@@ -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);
 }
 
index dc1f2dac1da966b47c952a11625198ff4c5ce841..e25d91dfa88ba313aa2e8b2350a159842d87a8d7 100644 (file)
@@ -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)
index a401f8190fb91f6d0edb080d4c5d33537512e5bd..45cbcdb908a0cdd764c5dd54f4171ecc35373000 100644 (file)
@@ -1,33 +1,85 @@
 #include "LivingKeyboard.h"
 
-LivingKeyboard::LivingKeyboard(QString port)
-: serialPort(new QSerialPort(port)), connected(false)
+#include <QDebug>
+#include <QThread>
+
+#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)
index 43db051c9043ad49bcd1bfedba5ceb07b82ef436..0fbe8d1b56c742f5e1b0dded421ba6680a98b000 100644 (file)
@@ -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
index eecbd77cee56011a107ceebe81833e81c787dc5b..c243b35be9fbb5768da3031a3f29d50a12c7534a 100644 (file)
@@ -1,39 +1,88 @@
 #include "XYPlotter.h"
 
 #include <QString>
+#include <QDebug>
+#include <QThread>
 
+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";
index a3064c03ad44513c7450ee4f9d3b56c923f83c28..69319e3a4486730c996223073bb33abb2ae999db 100644 (file)
@@ -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
index e11121047441a0f0e1f20eae20500e331b7b614d..49682b11232d98df61e8627643d35a9c634277f7 100644 (file)
@@ -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);