OSDN Git Service

alpha 1 development in progress.
authortkawata <tkawata@users.sourceforge.jp>
Tue, 24 Apr 2012 14:24:30 +0000 (23:24 +0900)
committertkawata <tkawata@users.sourceforge.jp>
Tue, 24 Apr 2012 14:24:30 +0000 (23:24 +0900)
implementation for Serial communication.
A sample content with Arduino sketch is added.

Samples/Samples/Sample3_Arduino1/Arduino/sketch1/sketch1.ino [new file with mode: 0644]
Samples/Samples/Sample3_Arduino1/Container/cells.xhtml [new file with mode: 0644]
Samples/Samples/Sample3_Arduino1/Container/dstyle.css [new file with mode: 0644]
Samples/Samples/Sample3_Arduino1/property.xml [new file with mode: 0644]
Samples/Samples/Sample3_Arduino1/ui/index.html [new file with mode: 0644]
Source/DNEngine.cpp
Source/DNEngine.h
Source/DNServerBase.h
Source/TKContainer.cpp
Source/platform/qt/qtdnserialportimpl.cpp
Source/platform/qt/qtdnserialportimpl.h

diff --git a/Samples/Samples/Sample3_Arduino1/Arduino/sketch1/sketch1.ino b/Samples/Samples/Sample3_Arduino1/Arduino/sketch1/sketch1.ino
new file mode 100644 (file)
index 0000000..fbd5e96
--- /dev/null
@@ -0,0 +1,90 @@
+byte   gSeq = 0;
+String gInputString = "";         
+String gOutputString = "";
+String gInputBuffer = "";
+
+boolean stringComplete = false;  
+
+void setup(){
+  Serial.begin(9600);
+}
+void loop(){
+  
+  int val=analogRead(0);
+  String m = "analog input:";
+  m += val;
+  analogWrite(3,val/4);
+  sendMessage(m);
+  delay(50);
+}
+
+void sendMessage(String message)
+{
+  gOutputString = "M" + message;
+  serialSend();
+}
+
+void setData()
+{
+  serialSendAndLoad();  
+}
+
+void getData()
+{
+  serialSendAndLoad();    
+}
+
+void serialSendAndLoad()
+{
+  serialSend();
+  
+  unsigned long timeout = millis() + 1000;
+  gInputString = "";
+  int isDataRecieved = false;
+  while(!isDataRecieved && millis() < timeout)
+  {
+    while (Serial.available() > 0)
+    {
+      // get the new byte:
+      char inChar = (char)Serial.read(); 
+      // add it to the inputString:
+      if (inChar != '\n' && inChar != '\r')
+      {
+        gInputBuffer += inChar;
+      }
+      // if the incoming character is a newline, set a flag
+      // so the main loop can do something about it:
+      if (inChar == '\n') 
+      {
+        //check input data
+        if (gInputBuffer.length() >= 2)
+        {
+          char rsecChars[3];
+          gInputBuffer.toCharArray(rsecChars,2);
+          rsecChars[2] = 0;
+          if (int(rsecChars) == gSeq)
+          {
+            gInputString = gInputBuffer;
+            isDataRecieved = true;
+          }
+        }
+        gInputBuffer = "";
+      }
+    }
+  }
+}
+
+void serialSend()
+{
+  gSeq ++;
+  if (gSeq > 99)
+  {
+    gSeq = 1;
+  }
+  if (gSeq < 10)
+  {
+    Serial.print("0");
+  }
+  Serial.print(gSeq, DEC);
+  Serial.println(gOutputString);
+}
diff --git a/Samples/Samples/Sample3_Arduino1/Container/cells.xhtml b/Samples/Samples/Sample3_Arduino1/Container/cells.xhtml
new file mode 100644 (file)
index 0000000..c1c3e27
--- /dev/null
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head><title>Dennco - test1</title>
+<link rel="stylesheet" type="text/css" href="dstyle.css" />  
+</head>
+
+<body>
+<h1>Sample3 - communicate with Arduino</h1>
+
+<a define="cell"  name="fromArduino1"><a parameter="cellcode"  type="I"> </a>
+<a parameter="connection" href="#ui_out1" receptor="in"></a>
+</a>
+
+<a define="cell" name="ui_in1"><a parameter="cellcode"  type="I"> </a>
+<a parameter="connection" href="#toArduino1" receptor="in"></a>
+</a>
+
+<a define="cell"  name="toArduino1"><a parameter="cellcode"  type="O"></a></a>
+<a define="cell"  name="ui_out1"><a parameter="cellcode"  type="O"></a></a>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/Samples/Samples/Sample3_Arduino1/Container/dstyle.css b/Samples/Samples/Sample3_Arduino1/Container/dstyle.css
new file mode 100644 (file)
index 0000000..18df600
--- /dev/null
@@ -0,0 +1,51 @@
+
+a[define] {
+       border-top:    1px solid gray;
+       text-indent:   1em;
+       display:       block;
+       margin-top:    32px;
+       margin-bottom: 8px;
+} 
+
+a[define="cellcode"]:before {
+       content:       "Definition of CellCode : " attr(name)      "  (type:" attr(type) ")" ;
+       font-size:     large;
+       font-weight:   bold;
+       display:       inline;
+       white-space:   pre;
+}
+
+
+a[define="cell"]:before {
+       content:       "Definition of Cell : " attr(name)  ;
+       font-size:     large;
+       font-weight:   bold;
+       display:       inline;
+       white-space:   pre;
+}
+         
+a[parameter="cellcode"]:before {
+       content:       "CellCode : " attr(href)  attr(type); 
+       display:       inline;
+}
+
+a[parameter="cellcode"] {
+       text-indent:   1em;
+       display:       block;
+}
+
+a[parameter="connection"]:before {
+       content:       "-> " attr(href)  "(" attr(receptor)")"; 
+       display:       inline;
+}
+
+a[parameter="connection"] {
+       text-indent:   2em;
+       display:       block;
+}
+
+[parameter="script"] { 
+        border:             1px solid gray;
+        background-color:   #f0f0cc;
+        margin-left:        2em;
+}
diff --git a/Samples/Samples/Sample3_Arduino1/property.xml b/Samples/Samples/Sample3_Arduino1/property.xml
new file mode 100644 (file)
index 0000000..e742219
--- /dev/null
@@ -0,0 +1,8 @@
+<dennco>
+
+<TickIntervalSec>0.2</TickIntervalSec>
+<UIPath>/ui/index.html</UIPath>
+<EnableHTTPServer>no</EnableHTTPServer> <!-- not implemented yet -->
+<EnableSerialServer>yes</EnableSerialServer>
+
+</dennco>
\ No newline at end of file
diff --git a/Samples/Samples/Sample3_Arduino1/ui/index.html b/Samples/Samples/Sample3_Arduino1/ui/index.html
new file mode 100644 (file)
index 0000000..332697a
--- /dev/null
@@ -0,0 +1,43 @@
+<html>
+<head>
+<title>Dennco Sample3 - work with Arduino</title>
+<script type="text/javascript">
+var timerId = setInterval("updateOutput()", 100);
+
+function updateOutput()
+{
+       document.getElementById("analog1Value").value = engine.getValue('/cells.xhtml#ui_out1');
+}
+
+function updateInput1(newValue)
+{
+       engine.setValue('/cells.xhtml#ui_in1', newValue);
+       document.getElementById("input1Value").value = newValue;
+}
+
+function stopTimer()
+{
+       clearInterval(timerId);
+}
+</script>
+</head>
+<body onunload="stopTimer()">
+<h3>Sample3 - work with Arduino</h3>
+<table border=1 cellspacing=0 cellpadding=2>
+<tr>
+<td>Control PWD3</td>
+<td>
+<input type="range"  min="0" max="255" value="0" onChange="updateInput1(this.value)" />
+<input type="text" value="0" disabled size="4" style="text-align:right" id="input1Value"/>
+</td>
+</tr>
+<tr>
+<td>Input from Arduino Analog1</td>
+<td>
+<input type="text" value="0" disabled  size="4" style="text-align:right" id="analog1Value"/>
+</td>
+</tr>
+</table>
+
+</body>
+</html>
index b979008..09606cf 100644 (file)
@@ -389,3 +389,10 @@ std::string DNEngine::getUIPath()
 {
     return mUIPath;
 }
+
+//static
+void DNEngine::callbackSerialPortClosed(DNEngine *engine)
+{
+    //TODO
+}
+
index c6ac40d..e5ebcd9 100644 (file)
@@ -56,7 +56,8 @@ public:
     std::string getUIPath();
     
     bool        isValid() { return mValid; }
-    
+
+    static      void callbackSerialPortClosed(DNEngine *engine);
     
 private:
     bool            parseSettingFile(const char *settingXML);
index 744e846..98f59da 100644 (file)
@@ -40,6 +40,8 @@ public:
     virtual void    doQueryRequest(std::string requestBody) = 0;
     virtual void    doSetRequest(std::string requestBody) = 0;
 
+    DNEngine*       getEngine() { return mEngine; }
+
 protected:
     DNEngine *mEngine;
 };
index f614bb6..35f6c0f 100644 (file)
@@ -20,6 +20,7 @@
 #include "TKContainer.h"
 #include "TKCell.h"
 #include "DNStorage.h"
+#include "DNUtils.h"
 
 TKContainer::~TKContainer()
 {
@@ -87,6 +88,12 @@ TKCell* TKContainer::getCell(std::string theFQNName)
 
 TKCell* TKContainer::getInterfaceCell(std::string theFQNName)
 {
+    DNLocker locker(&mLock);
+
+    if (mInterfaceCells.empty())
+    {
+        return NULL;
+    }
     TKCellMap::iterator it = mInterfaceCells.find(theFQNName);
     if (it == mInterfaceCells.end())
     {
index 9f4a0a0..2a59a70 100644 (file)
@@ -28,6 +28,9 @@
 #include <QThread>
 #include <QtCore/QVariant>
 
+//
+#include "DNEngine.h"
+
 class SleeperThread : public QThread
 {
 public:
@@ -44,7 +47,8 @@ DNSerialPortImpl * DNSerialPortImpl::create(DNServerSerialPort *server)
 
 
 QtDNSerialPortImpl::QtDNSerialPortImpl(DNServerSerialPort *server) :
-    DNSerialPortImpl(server), mListnerThread(NULL), mHandlerThread(NULL), mStopping(false),
+    DNSerialPortImpl(server), mSerialCommunicationThread(NULL), mHandlerThread(NULL), mStopping(false),
+    mResponseString(""),
     mPortName(""),
     mBaudRate(SerialPort::Rate9600),
     mDataBits(SerialPort::Data8),
@@ -57,10 +61,10 @@ QtDNSerialPortImpl::QtDNSerialPortImpl(DNServerSerialPort *server) :
 QtDNSerialPortImpl::~QtDNSerialPortImpl()
 {
     stop();
-    if (mListnerThread)
+    if (mSerialCommunicationThread)
     {
-        delete mListnerThread;
-        mListnerThread = NULL;
+        delete mSerialCommunicationThread;
+        mSerialCommunicationThread = NULL;
     }
     if (mHandlerThread)
     {
@@ -98,10 +102,10 @@ void QtDNSerialPortImpl::start()
     if (mStopping)
     {
         mStopping = false;
-        mListnerThread = DNThread::createThread(QtDNSerialPortImpl::requestListenerThreadBody, this);
+        mSerialCommunicationThread = DNThread::createThread(QtDNSerialPortImpl::serialCommunicationThreadBody, this);
         mHandlerThread = DNThread::createThread(QtDNSerialPortImpl::requestHandelrThreadBody, this);
 
-        mListnerThread->start();
+        mSerialCommunicationThread->start();
         mHandlerThread->start();
     }
     mStartStopLock.unlock();
@@ -113,11 +117,11 @@ void QtDNSerialPortImpl::stop()
     if (!mStopping)
     {
         mStopping = true;
-        if (mListnerThread)
+        if (mSerialCommunicationThread)
         {
-            mListnerThread->waitForExit(1000);
-            delete mListnerThread;
-            mListnerThread = NULL;
+            mSerialCommunicationThread->waitForExit(1000);
+            delete mSerialCommunicationThread;
+            mSerialCommunicationThread = NULL;
         }
         if (mHandlerThread)
         {
@@ -130,8 +134,16 @@ void QtDNSerialPortImpl::stop()
     mStartStopLock.unlock();
 }
 
+void QtDNSerialPortImpl::sendMessage(const char* message)
+{
+    mResponseStringLock.lock();
+    mResponseString.append(message);
+    mResponseStringLock.unlock();
+    mSerialWriteSemaphore.release(1);
+}
+
 //static
-void QtDNSerialPortImpl::requestListenerThreadBody(void *_impl)
+void QtDNSerialPortImpl::serialCommunicationThreadBody(void *_impl)
 {
     if (!_impl)
         return;
@@ -203,12 +215,13 @@ void QtDNSerialPortImpl::requestListenerThreadBody(void *_impl)
         return;
     }
 
+    int waitTime = 1;
 
     char buffer[1024];
     int p = 0;
     while(!impl->mStopping)
     {
-        if (port->bytesAvailable() > 0 ||  port->waitForReadyRead(100))
+        if (port->bytesAvailable() > 0)
         {
             int len = port->read( (buffer + p), sizeof(buffer) - p);
             if (len != -1)
@@ -221,9 +234,9 @@ void QtDNSerialPortImpl::requestListenerThreadBody(void *_impl)
                         if (i>0)
                         {
                             buffer[i] = 0;
-                            impl->mLock.lock();
+                            impl->mRequestQueueLock.lock();
                             impl->mRequestQueue.push_back(QString::fromLocal8Bit(buffer));
-                            impl->mLock.unlock();
+                            impl->mRequestQueueLock.unlock();
                             impl->mQueueSemaphore.release(1);
                         }
                         int j = i + 1;
@@ -250,12 +263,38 @@ void QtDNSerialPortImpl::requestListenerThreadBody(void *_impl)
                     i++;
                 }
                 p = p + len;
+                waitTime = 1;
             }
         }
-        if (!port->isOpen())
+        else
+        {
+            if (!impl->mSerialWriteSemaphore.tryAcquire(1,waitTime))
+            {
+                waitTime++;
+                if (waitTime>100)
+                {
+                    waitTime = 100;
+                    if (!port->isOpen())
+                    {
+                        //TODO
+                    }
+                }
+            }
+        }
+
+        impl->mResponseStringLock.lock();
+        if (impl->mResponseString.length()>0 && port->isOpen())
+        {
+            QString response = impl->mResponseString;
+            impl->mResponseString.clear();
+            impl->mResponseStringLock.unlock();
+            port->write(response.toLocal8Bit());
+        }
+        else
         {
-            SleeperThread::msleep(300);
+            impl->mResponseStringLock.unlock();
         }
+
     }
     port->close();
     delete port;
@@ -271,19 +310,47 @@ void QtDNSerialPortImpl::requestHandelrThreadBody(void *_impl)
     while(!impl->mStopping)
     {
         impl->mQueueSemaphore.tryAcquire(1,100);
-        impl->mLock.lock();
+        impl->mRequestQueueLock.lock();
         if (!impl->mRequestQueue.isEmpty())
         {
             QString line = impl->mRequestQueue.dequeue();
-            impl->mLock.unlock();
-
-            //TODO
-            TKLog::printf("serial input:%s", line.toLocal8Bit().constData());
+            impl->mRequestQueueLock.unlock();
 
+            if (line.length()>3)
+            {
+                QString seq = line.left(2);
+                QString cmd = line.mid(2,1);
+                QString par = line.mid(3);
+                if (cmd == "M")
+                {
+                    //message
+                    TKLog::printf("(SERIALl):%s", par.toLocal8Bit().constData());
+                }
+                else if (cmd == "S")
+                {
+                    //set data
+                    int idx = par.indexOf(",");
+                    if (idx > 0 && par.length() > idx + 1)
+                    {
+                        QString path = par.left(idx);
+                        float val = par.mid(idx+1).toFloat();
+                        impl->mServer->getEngine()->doClientSetRequest(path.toLocal8Bit().constData(),val);
+                    }
+                }
+                else if (cmd == "G")
+                {
+                    //get data
+                    float val = impl->mServer->getEngine()->doClientGetRequest(par.toLocal8Bit().constData());
+                    QString rep = seq;
+                    rep.append(QString::number(val));
+                    rep.append("\n");
+                    impl->sendMessage(rep.toLocal8Bit().constData());
+                }
+            }
         }
         else
         {
-            impl->mLock.unlock();
+            impl->mRequestQueueLock.unlock();
         }
 
     }
index cff1f99..3271fe9 100644 (file)
@@ -72,18 +72,23 @@ public:
     virtual void    start();
     virtual void    stop();
 
-    static void requestListenerThreadBody(void *impl);
-    static void requestHandelrThreadBody(void *impl);
+    void            sendMessage(const char* message);
+
+    static void     serialCommunicationThreadBody(void *impl);
+    static void     requestHandelrThreadBody(void *impl);
 
 private:
-    DNThread *mListnerThread;
+    DNThread *mSerialCommunicationThread;
     DNThread *mHandlerThread;
     bool    mStopping;
 
     QQueue<QString> mRequestQueue;
-    TKLock          mLock;
+    QString         mResponseString;
+    TKLock          mRequestQueueLock;
+    TKLock          mResponseStringLock;
     TKLock          mStartStopLock;
     QSemaphore      mQueueSemaphore;
+    QSemaphore      mSerialWriteSemaphore;
 
     QString mPortName;
     SerialPort::Rate mBaudRate;