From ff98169b6ae3fdf68c5bfc9e53f5707d4d72539e Mon Sep 17 00:00:00 2001 From: Thomas Pietrzak Date: Wed, 14 Mar 2012 08:56:58 +0000 Subject: [PATCH] Dynamic Keyboard library initial import git-svn-id: svn+ssh://thomaspietrzak.com/var/svn/rep@59 47cf9a05-e0a8-4ed5-9e9b-101a649bc004 --- Arduino/dynamickeyboard/dynamickeyboard.ino | 155 ++++++++++++++++++ .../DynamicKeyboardLibrary.sln | 20 +++ .../DynamicKeyboardLibrary.suo | Bin 0 -> 12800 bytes .../DynamicKeyboardController.cpp | 113 +++++++++++++ .../DynamicKeyboardController.h | 68 ++++++++ .../DynamicKeyboardLibrary.vcxproj | 73 +++++++++ .../DynamicKeyboardLibrary.vcxproj.filters | 27 +++ 7 files changed, 456 insertions(+) create mode 100644 Arduino/dynamickeyboard/dynamickeyboard.ino create mode 100644 DynamicKeyboardLibrary/DynamicKeyboardLibrary.sln create mode 100644 DynamicKeyboardLibrary/DynamicKeyboardLibrary.suo create mode 100644 DynamicKeyboardLibrary/DynamicKeyboardLibrary/DynamicKeyboardController.cpp create mode 100644 DynamicKeyboardLibrary/DynamicKeyboardLibrary/DynamicKeyboardController.h create mode 100644 DynamicKeyboardLibrary/DynamicKeyboardLibrary/DynamicKeyboardLibrary.vcxproj create mode 100644 DynamicKeyboardLibrary/DynamicKeyboardLibrary/DynamicKeyboardLibrary.vcxproj.filters diff --git a/Arduino/dynamickeyboard/dynamickeyboard.ino b/Arduino/dynamickeyboard/dynamickeyboard.ino new file mode 100644 index 0000000..276149d --- /dev/null +++ b/Arduino/dynamickeyboard/dynamickeyboard.ino @@ -0,0 +1,155 @@ +#include + +int dataPin = 11; +int strobePin = 10; +int clockPin = 13; +int pwmPin = 3; + +byte keysState[2]; +byte maxDutyCycle = 255; +byte minDutyCycle = 200; +word boostDuration = 150; + +byte command = 0; + +void sendInformation() +{ + Serial.write(keysState[1]); + Serial.write(keysState[0]); + Serial.write(maxDutyCycle); + Serial.write(minDutyCycle); + Serial.write(boostDuration >> 8); + Serial.write(byte(boostDuration)); +} + +// 4Mbits/s +void setKeyConfiguration() +{ + //disable the output duding the setup + digitalWrite(strobePin, LOW); + //sends the keystates + SPI.transfer(keysState[0]); + SPI.transfer(keysState[1]); + //enable the output + digitalWrite(strobePin, HIGH); + //sets the boostmode + analogWrite(pwmPin, maxDutyCycle); + //wait for the end of the boost + delay(boostDuration); + //sets the economy mode + analogWrite(pwmPin, minDutyCycle); +} + +void setup() +{ + pinMode(strobePin, OUTPUT); + pinMode(pwmPin, OUTPUT); + SPI.begin(); +/* + pinMode(clockPin, OUTPUT); + pinMode(dataPin, OUTPUT); + pinMode(strobePin, OUTPUT); + */ + + Serial.begin(115200); + keysState[0] = 0; + keysState[1] = 0; + analogWrite(pwmPin, minDutyCycle); +} + +/* + Protocol: + cXYZ... where c is a character (byte) representing the command + and XYZ... are the paremeters. Eack digit parameter is a byte + In this version we assume we control 16 keys thus we need + 16bits (2 bytes) for commands related to keys. + Commands: + SXY sets a configuration on keys + XY is the configuration. Here 1 represent a raised key, + 0 a lowered key. + RXY raise the specified keys + 1 raises a key, 0 does not change its state + LXY lowers the specified keys + 1 lowers a key, 0 does not change its state + MX sets the Maximum duty cycle + this parameter controls the voltage used in the boost mode + required to raise the key + mX sets the minimum duty cycle + this parameter controls the voltage used in economic mode + this voltage should be suficient to keep the key up + DX sets the duration of the boost mode in ms + boost mode uses voltage out of the range of the solenoids + specification. Thus this modeshould not last too long and + be used too often + I send information (parameters) +*/ +void loop() +{ + if (Serial.available() == 0) + return; + + if (command == 0) + command = Serial.read(); + switch(command) + { + case 'S': + if (Serial.available() >= 2) + { + keysState[1] = Serial.read(); + keysState[0] = Serial.read(); + setKeyConfiguration(); + command = 0; + } + break; + case 'R': + if (Serial.available() >= 2) + { + keysState[1] = keysState[1] | Serial.read(); + keysState[0] = keysState[0] | Serial.read(); + setKeyConfiguration(); + command = 0; + } + break; + case 'L': + if (Serial.available() >= 2) + { + keysState[1] = keysState[1] & ~(Serial.read()); + keysState[0] = keysState[0] & ~(Serial.read()); + setKeyConfiguration(); + command = 0; + } + break; + case 'M': + if (Serial.available() >= 1) + { + maxDutyCycle = Serial.read(); + command = 0; + } + break; + case 'm': + if (Serial.available() >= 1) + { + minDutyCycle = Serial.read(); + analogWrite(pwmPin, minDutyCycle); + command = 0; + } + break; + case 'D': + if (Serial.available() >= 2) + { + boostDuration = 0; + boostDuration = Serial.read() << 8; + boostDuration |= Serial.read(); + command = 0; + } + break; + case 'I': + sendInformation(); + command = 0; + break; + default: + command = 0; + break; + } +} + diff --git a/DynamicKeyboardLibrary/DynamicKeyboardLibrary.sln b/DynamicKeyboardLibrary/DynamicKeyboardLibrary.sln new file mode 100644 index 0000000..26c28c0 --- /dev/null +++ b/DynamicKeyboardLibrary/DynamicKeyboardLibrary.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DynamicKeyboardLibrary", "DynamicKeyboardLibrary\DynamicKeyboardLibrary.vcxproj", "{291779F7-46DD-489D-BEB2-73D81107CFB3}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {291779F7-46DD-489D-BEB2-73D81107CFB3}.Debug|Win32.ActiveCfg = Debug|Win32 + {291779F7-46DD-489D-BEB2-73D81107CFB3}.Debug|Win32.Build.0 = Debug|Win32 + {291779F7-46DD-489D-BEB2-73D81107CFB3}.Release|Win32.ActiveCfg = Release|Win32 + {291779F7-46DD-489D-BEB2-73D81107CFB3}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/DynamicKeyboardLibrary/DynamicKeyboardLibrary.suo b/DynamicKeyboardLibrary/DynamicKeyboardLibrary.suo new file mode 100644 index 0000000000000000000000000000000000000000..4b5efe34db654ac8d45a81766c4cfc7469be65be GIT binary patch literal 12800 zcmeHNUu;`f89z=}`gd#v){auZZ0+c_*t6p#P8u>A+cE8uuHNFN1I(EJTqn12eWQD? z(^yRrFMu?m3W*n9c;L?iePiPR35_8kCJ+L3ydls8NWjZ9KuH=Rl$P~4`wNCW?ctoJnLa3`+20M7XyU^lQ2*bD3j?gict+y`L##RI?r-~+%1 zfe!%(0j`Hbjq6>ciua_b&k6&7wg`%8QN`61b8;QA$HMP689Nz4izS6iIJuLhY^ zz2$W4_XZJ={^E{6!;kMaUckM0(b~e zJdUCK2=GbZIPfU&7(fjS0%w4yfhPbybGC71c^Ksp*ZmmE{gGbld;JPXVLS>PNn51a>{19aeXz~_M+@CAU+ ze-YOgfILtD)H^kl%fJG#*r>mN>k?3D+~e`S(cn{m2>p7;4^Ce@_R#O@aVfu`4F=~m)585^G!mA7 zgTZ92V%JP9 zi>6^2Wjj2tTeW;;&aRboBP>N&(9HEh)-WpP^=iquWQ9|CJD=5;t#C%KR`Z35CU2%! zZLMnQ1-+u%^>BugTBs>%kI%}2X7af?+b}hbbKgch#j*E59K`p5BvyHD-FjIlXQf>? zP)eax6g6=X_JlT`trl!tQMPGVe>JSP1!;rMV@29%S;Sp8+edMOuz%d|^#7bj)^#Js z7qpio+Bi4=1mw~n!xF5bf!*WC>-25+dmQ{}U$_eW@@I_m!^X>6`P2W<_AWyUIwYue z(ZVC(&za;q{qko#McYbh<)4;gF2SA{m=(?uEkb7^fAZz~{PN$2zE4wVkOdD@6(w*f zfpY;|SLLdxqc)EfqeFrjwAN)?9uk$LuPpfNW#TQ2DQNrJ5q(ZSi0}C_;Oqk@s#pML zjv)w(uETnAMF-(kR>hbYg=fjZn{a%LKrEn)IS;~mGZLub$qMe~P*;<>F>ps;90qde zmBcTfwQ*IuNraLal8O+ECqaS zxcRGGECpL^1MMgb{(KeZ)GvSc`lFwvB~W8@^jyZM7f?(8p<3E;XHK&D_5WeKs@gCR zXR*gFzz@+^wa)Q8{8Tr32;-;k;~9+K@jr~d%0BHCKZE)P#5V>~CnET}JTxAS$H&w0 z(C}y~6&fBJPlXcGiJ?$DmKuvjBk^Q95xcUMs#o(D8DTU3I|EHsq@L(4>F?7Ljkn+Wvbdu}-*_EE)G|*h{Te$Xnw)|KiyWeVSkUzQ zAJPvlLl$~|dP8To(%*R#`SU!9Hq|fxqv*TbFo5TvRdUVCSg^EivmCq7DeBme3HDd= zC2!J3OXre%{HNe)N|JXKW3E7&wDd?Nsf9bwzYe>xg55~%D{IY|^1Zw#+UbO|c^D^x zw7kyTI9VlhwfEokLyx|Z{`RR?U$%aKVAu5@b(;Bh{ith#XMFv%&XXQ?)GZ%9MiHki zj6Zndz<7JMu^+tRF7=LH;{OmH=2MG&j;tR&h=bXou0bwJB`_KpBixIFb2!ww}f7cV*JKyfB)XE9-gSZ zvM=)1#Ft(^hGB6|+|>I>+do+^7*z= zDpFTRd8gDZt~~M`aK0)zwTGe0jjwj@uTHL~`dr+quXp}W6!@*Lxwkq|V1`k_AM^V# zyxTJVoRi3}l7Ql-BzpokGyXGxzV4q$8PbjclIXZ-}TtD(->P#-e*xU z$fOz6jXz^`FJk9_v$=HISGE9#rJ*L-Z9rMlBA)t^UP#G>ls*7dVQ?`WU@0p5kH6951J literal 0 HcmV?d00001 diff --git a/DynamicKeyboardLibrary/DynamicKeyboardLibrary/DynamicKeyboardController.cpp b/DynamicKeyboardLibrary/DynamicKeyboardLibrary/DynamicKeyboardController.cpp new file mode 100644 index 0000000..384b007 --- /dev/null +++ b/DynamicKeyboardLibrary/DynamicKeyboardLibrary/DynamicKeyboardController.cpp @@ -0,0 +1,113 @@ +#include "DynamicKeyboardController.h" + +#include + +#include + +DynamicKeyboardController::DynamicKeyboardController(char *port, int baudrate) +{ + try + { + _comPort = new SerialWindows(port, baudrate); + } + catch (...) + { + _comPort = NULL; + } +} + +void DynamicKeyboardController::setConfiguration(UINT16 config) +{ + if (!_comPort) + return; + unsigned char buffer[3]; + buffer[0] = 'S'; + buffer[1] = UINT8(config >> 8); + buffer[2] = UINT8(config & 0xff); + _comPort->WriteData(buffer, 3); +} + +void DynamicKeyboardController::raiseKeys(UINT16 config) +{ + if (!_comPort) + return; + unsigned char buffer[3]; + buffer[0] = 'R'; + buffer[1] = UINT8(config >> 8); + buffer[2] = UINT8(config & 0xff); + _comPort->WriteData(buffer, 3); +} + +void DynamicKeyboardController::lowerKeys(UINT16 config) +{ + if (!_comPort) + return; + unsigned char buffer[3]; + buffer[0] = 'L'; + buffer[1] = UINT8(config >> 8); + buffer[2] = UINT8(config & 0xff); + _comPort->WriteData(buffer, 3); +} + +void DynamicKeyboardController::setMaximumDutyCycle(UINT8 val) const +{ + if (!_comPort) + return; + unsigned char buffer[2]; + buffer[0] = 'M'; + buffer[1] = val; + _comPort->WriteData(buffer, 2); +} + +void DynamicKeyboardController::setMinimumDutyCycle(UINT8 val) const +{ + if (!_comPort) + return; + unsigned char buffer[2]; + buffer[0] = 'm'; + buffer[1] = val; + _comPort->WriteData(buffer, 2); +} + +void DynamicKeyboardController::setBoostDuration(UINT16 val) const +{ + if (!_comPort) + return; + unsigned char buffer[3]; + buffer[0] = 'D'; + buffer[1] = val >> 8; + buffer[2] = val & 0x00ff; + _comPort->WriteData(buffer, 3); +} + +bool DynamicKeyboardController::getState(UINT16 &solenoids, UINT8 &minDutyCycle, UINT8 &maxDutyCycle, UINT16 &boostDuration) const +{ + if (!_comPort) + return false; + _comPort->WriteData("I",1); + Sleep(1000); + + /* + we currently receive 2 bytes for 16 keys states, max DC, min DC and boost duration + We may receive more bytes in the future if we handle more keys + */ + unsigned char buffer[6]; + _comPort->ReadData(buffer, 6); + solenoids = (UINT16(buffer[0]) << 8) | buffer[1]; + maxDutyCycle = buffer[2]; + minDutyCycle = buffer[3]; + boostDuration = UINT16(buffer[4]) << 8 |buffer[5]; + return true; +} + +std::ostream& operator <<(std::ostream& stream, const DynamicKeyboardController& controller) +{ + UINT16 solenoids, duration; + UINT8 min, max; + if (!controller.getState(solenoids, min, max, duration)) + return stream; + + stream << std::hex << solenoids << std::dec << ";" << min << ";" << max << ";" << duration; + + return stream; +} diff --git a/DynamicKeyboardLibrary/DynamicKeyboardLibrary/DynamicKeyboardController.h b/DynamicKeyboardLibrary/DynamicKeyboardLibrary/DynamicKeyboardController.h new file mode 100644 index 0000000..483abb2 --- /dev/null +++ b/DynamicKeyboardLibrary/DynamicKeyboardLibrary/DynamicKeyboardController.h @@ -0,0 +1,68 @@ +#ifndef __DYNAMICKEYBOARDCONTROLLER__ +#define __DYNAMICKEYBOARDCONTROLLER__ + +#include + +#include + +typedef unsigned char UINT8; +typedef unsigned short int UINT16; + +class DynamicKeyboardController +{ + public: + /* + Creates the controller for a dynamic keyboard + port is the COM port for the communication with the Arduino Board + baudrate is the baudrate for the communication, the default value may be sufficient + */ + __declspec(dllexport) DynamicKeyboardController(char *port, int baudrate = 115200); + + /* sets a configuration on keys + XY is the configuration. Here 1 represent a raised key, + 0 a lowered key. + */ + __declspec(dllexport) void setConfiguration(UINT16 config); + /* + raise the specified keys + 1 raises a key, 0 does not change its state + */ + __declspec(dllexport) void raiseKeys(UINT16 config); + /* + lowers the specified keys + 1 lowers a key, 0 does not change its state + */ + __declspec(dllexport) void lowerKeys(UINT16 config); + + /* + higher duty cycle values results to higher voltage + maximum is used to give a boost to raise the key + minimum is used to keep the key raised + the values are choosen with empirical tests, + depending on the solenoids and the power supply + */ + __declspec(dllexport) void setMaximumDutyCycle(UINT8 val) const; + __declspec(dllexport) void setMinimumDutyCycle(UINT8 val) const; + + /* + The shorter the boost mode the better since it goes beyond the standards + The longer the boost mode is, the longer we should wait before changing + the keys state again. + */ + __declspec(dllexport) void setBoostDuration(UINT16) const; + + /* + returns the state of the solenoids, the max and min duty cycle and the boost duration + */ + __declspec(dllexport) bool getState(UINT16 &solenoids, UINT8 &minDutyCycle, UINT8 &maxDutyCycle, UINT16 &boostDuration) const; + + /* + returns on the stream the state of the solenoids, the max and min duty cycle and the boost duration + */ + __declspec(dllexport) friend std::ostream& operator<< (std::ostream& stream, const DynamicKeyboardController& controller); + + protected: + Serial *_comPort; +}; + +#endif diff --git a/DynamicKeyboardLibrary/DynamicKeyboardLibrary/DynamicKeyboardLibrary.vcxproj b/DynamicKeyboardLibrary/DynamicKeyboardLibrary/DynamicKeyboardLibrary.vcxproj new file mode 100644 index 0000000..dcbb1b3 --- /dev/null +++ b/DynamicKeyboardLibrary/DynamicKeyboardLibrary/DynamicKeyboardLibrary.vcxproj @@ -0,0 +1,73 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {291779F7-46DD-489D-BEB2-73D81107CFB3} + DynamicKeyboardLibrary + + + + DynamicLibrary + true + MultiByte + + + DynamicLibrary + false + true + MultiByte + + + + + + + + + + + + + + + Level3 + Disabled + + + true + arduinoseriald.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + arduinoserial.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + + + + + + \ No newline at end of file diff --git a/DynamicKeyboardLibrary/DynamicKeyboardLibrary/DynamicKeyboardLibrary.vcxproj.filters b/DynamicKeyboardLibrary/DynamicKeyboardLibrary/DynamicKeyboardLibrary.vcxproj.filters new file mode 100644 index 0000000..76cd099 --- /dev/null +++ b/DynamicKeyboardLibrary/DynamicKeyboardLibrary/DynamicKeyboardLibrary.vcxproj.filters @@ -0,0 +1,27 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + + + Source Files + + + \ No newline at end of file -- 2.30.2