From: Thomas Pietrzak Date: Wed, 14 Mar 2012 08:56:58 +0000 (+0000) Subject: Dynamic Keyboard library initial import X-Git-Url: https://git.thomaspietrzak.com/?a=commitdiff_plain;h=ff98169b6ae3fdf68c5bfc9e53f5707d4d72539e;p=DynamicKeyboardLib.git Dynamic Keyboard library initial import git-svn-id: svn+ssh://thomaspietrzak.com/var/svn/rep@59 47cf9a05-e0a8-4ed5-9e9b-101a649bc004 --- ff98169b6ae3fdf68c5bfc9e53f5707d4d72539e 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 0000000..4b5efe3 Binary files /dev/null and b/DynamicKeyboardLibrary/DynamicKeyboardLibrary.suo differ 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