implementation for Serial communication.
A sample content with Arduino sketch is added.
--- /dev/null
+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);
+}
--- /dev/null
+<?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
--- /dev/null
+
+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;
+}
--- /dev/null
+<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
--- /dev/null
+<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>
{
return mUIPath;
}
+
+//static
+void DNEngine::callbackSerialPortClosed(DNEngine *engine)
+{
+ //TODO
+}
+
std::string getUIPath();
bool isValid() { return mValid; }
-
+
+ static void callbackSerialPortClosed(DNEngine *engine);
private:
bool parseSettingFile(const char *settingXML);
virtual void doQueryRequest(std::string requestBody) = 0;
virtual void doSetRequest(std::string requestBody) = 0;
+ DNEngine* getEngine() { return mEngine; }
+
protected:
DNEngine *mEngine;
};
#include "TKContainer.h"
#include "TKCell.h"
#include "DNStorage.h"
+#include "DNUtils.h"
TKContainer::~TKContainer()
{
TKCell* TKContainer::getInterfaceCell(std::string theFQNName)
{
+ DNLocker locker(&mLock);
+
+ if (mInterfaceCells.empty())
+ {
+ return NULL;
+ }
TKCellMap::iterator it = mInterfaceCells.find(theFQNName);
if (it == mInterfaceCells.end())
{
#include <QThread>
#include <QtCore/QVariant>
+//
+#include "DNEngine.h"
+
class SleeperThread : public QThread
{
public:
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),
QtDNSerialPortImpl::~QtDNSerialPortImpl()
{
stop();
- if (mListnerThread)
+ if (mSerialCommunicationThread)
{
- delete mListnerThread;
- mListnerThread = NULL;
+ delete mSerialCommunicationThread;
+ mSerialCommunicationThread = NULL;
}
if (mHandlerThread)
{
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();
if (!mStopping)
{
mStopping = true;
- if (mListnerThread)
+ if (mSerialCommunicationThread)
{
- mListnerThread->waitForExit(1000);
- delete mListnerThread;
- mListnerThread = NULL;
+ mSerialCommunicationThread->waitForExit(1000);
+ delete mSerialCommunicationThread;
+ mSerialCommunicationThread = NULL;
}
if (mHandlerThread)
{
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;
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)
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;
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;
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();
}
}
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;