Arduino library
authorThomas Pietrzak <thomas.pietrzak@gmail.com>
Tue, 14 Jun 2011 19:15:23 +0000 (19:15 +0000)
committerThomas Pietrzak <thomas.pietrzak@gmail.com>
Tue, 14 Jun 2011 19:15:23 +0000 (19:15 +0000)
git-svn-id: svn+ssh://thomaspietrzak.com/var/svn/rep@29 47cf9a05-e0a8-4ed5-9e9b-101a649bc004

Arduino/Tacton/Tacton.cpp [new file with mode: 0644]
Arduino/Tacton/Tacton.h [new file with mode: 0644]
Arduino/Tacton/keywords.txt [new file with mode: 0644]
Arduino/TactonManager/TactonManager.cpp [new file with mode: 0644]
Arduino/TactonManager/TactonManager.h [new file with mode: 0644]
Arduino/TactonManager/keywords.txt [new file with mode: 0644]
Arduino/TactonPlayer/TactonPlayer.cpp [new file with mode: 0644]
Arduino/TactonPlayer/TactonPlayer.h [new file with mode: 0644]
Arduino/TactonPlayer/keywords.txt [new file with mode: 0644]
Arduino/wristbandTactons/wristbandTactons.pde [new file with mode: 0644]

diff --git a/Arduino/Tacton/Tacton.cpp b/Arduino/Tacton/Tacton.cpp
new file mode 100644 (file)
index 0000000..11bf828
--- /dev/null
@@ -0,0 +1,79 @@
+#include "WProgram.h"\r
+#include "Tacton.h"\r
+\r
+\r
+/*Tacton::Tacton()\r
+:_nbframes(0), _patterns(NULL), _durations(NULL), _frequencies(NULL), _amplitudes(NULL)\r
+{\r
+}*/\r
+\r
+Tacton::Tacton(unsigned int nbframes, byte *desc)\r
+:_nbframes(nbframes), _patterns((byte *)malloc(nbframes * sizeof(byte))), _durations((unsigned int *)malloc(nbframes * sizeof(unsigned int))), _frequencies((unsigned int *)malloc(nbframes * sizeof(unsigned int))), _amplitudes((byte *)malloc(nbframes * sizeof(byte)))\r
+{\r
+       if (isValid())\r
+       {\r
+               for(int i = 0 ; i < nbframes ; i++)\r
+               {\r
+                       _patterns[i] = desc[6*i];\r
+                       _durations[i] = (((unsigned int)(desc[6*i+1])) << 8) | ((unsigned int)(desc[6*i+2]));\r
+                       _frequencies[i] = (((unsigned int)(desc[6*i+3])) << 8) | ((unsigned int)(desc[6*i+4]));\r
+                       _amplitudes[i] = desc[6*i+5];\r
+               }\r
+       }\r
+}\r
+\r
+/*Tacton::Tacton(const Tacton &tacton)\r
+:_nbframes(tacton._nbframes), _patterns((byte *)malloc(tacton._nbframes * sizeof(byte))), _durations((unsigned int *)malloc(tacton._nbframes * sizeof(unsigned int))), _frequencies((unsigned int *)malloc(tacton._nbframes * sizeof(unsigned int))), _amplitudes((byte *)malloc(tacton._nbframes * sizeof(byte)))\r
+{\r
+       for(int i = 0 ; i < tacton._nbframes ; i++)\r
+       {\r
+               _patterns[i] = tacton._patterns[i];\r
+               _durations[i] = tacton._durations[i];\r
+               _frequencies[i] = tacton._frequencies[i];\r
+               _amplitudes[i] = tacton._amplitudes[i];\r
+       }\r
+}*/\r
+\r
+Tacton::~Tacton()\r
+{\r
+       free(_patterns);\r
+       free(_durations);\r
+       free(_frequencies);\r
+       free(_amplitudes);\r
+}\r
+               \r
+void Tacton::play(const TactonPlayer &player) const\r
+{            \r
+       if (isValid())\r
+               for (int i = 0 ; i < _nbframes ; i++)\r
+                       player.beep(_patterns[i], _durations[i], _frequencies[i], _amplitudes[i]);\r
+}\r
+\r
+/*Tacton& Tacton::operator=(const Tacton &t) \r
+{\r
+    if (this == &t)\r
+               return *this;\r
+       if (_patterns)\r
+               free(_patterns);\r
+       if (_durations)\r
+               free(_durations);\r
+       if (_frequencies)\r
+               free(_frequencies);\r
+       if (_amplitudes)\r
+               free(_amplitudes);\r
+       _nbframes = t._nbframes;\r
+       _patterns = (byte *)malloc(_nbframes * sizeof(byte));\r
+       _durations = (unsigned int *)malloc(_nbframes * sizeof(unsigned int));\r
+       _frequencies = (unsigned int *)malloc(_nbframes * sizeof(unsigned int));\r
+       _amplitudes = (byte *)malloc(_nbframes * sizeof(byte));\r
+       for(int i = 0 ; i < _nbframes ; i++)\r
+       {\r
+               _patterns[i] = t._patterns[i];\r
+               _durations[i] = t._durations[i];\r
+               _frequencies[i] = t._frequencies[i];\r
+               _amplitudes[i] = t._amplitudes[i];\r
+       }\r
+\r
+    return *this;\r
+}*/\r
+  
\ No newline at end of file
diff --git a/Arduino/Tacton/Tacton.h b/Arduino/Tacton/Tacton.h
new file mode 100644 (file)
index 0000000..8ef8ae1
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef _TACTON_\r
+#define _TACTON_\r
+\r
+#include "WProgram.h"\r
+\r
+#include <TactonPlayer.h>\r
+\r
+class Tacton \r
+{\r
+       public:\r
+//             Tacton();\r
+               Tacton(unsigned int nbframes, byte *desc);\r
+//             Tacton(const Tacton &tacton);\r
+               ~Tacton();\r
+               \r
+               void play(const TactonPlayer &player) const;\r
+               \r
+//             Tacton & operator=(const Tacton &t);\r
+               boolean isValid() const { return _patterns && _durations && _frequencies && _amplitudes; }\r
+\r
+       private:\r
+               unsigned int _nbframes;\r
+               byte *_patterns;\r
+               unsigned int *_durations;\r
+               unsigned int *_frequencies;\r
+               byte *_amplitudes;\r
+};\r
+\r
+#endif\r
diff --git a/Arduino/Tacton/keywords.txt b/Arduino/Tacton/keywords.txt
new file mode 100644 (file)
index 0000000..4cc4b36
--- /dev/null
@@ -0,0 +1,3 @@
+Tacton KEYWORD1\r
+play   KEYWORD2\r
+isValid        KEYWORD2
\ No newline at end of file
diff --git a/Arduino/TactonManager/TactonManager.cpp b/Arduino/TactonManager/TactonManager.cpp
new file mode 100644 (file)
index 0000000..91e7093
--- /dev/null
@@ -0,0 +1,109 @@
+#include "WProgram.h"\r
+#include "TactonManager.h"\r
+\r
+TactonManager::TactonManager(TactonPlayer *player)\r
+: _nbplays(0), _nbtactons(0), _player(player)\r
+{\r
+}\r
+\r
+void TactonManager::add(unsigned int nbframes, byte *desc)\r
+{\r
+       if (_nbtactons < MAXTACTONS)\r
+       {\r
+               _tactons[_nbtactons] = new Tacton(nbframes, desc);\r
+               if (_tactons[_nbtactons])\r
+               {\r
+                       Serial.println("Tacton added");\r
+                       _nbtactons++;\r
+               }\r
+       }\r
+}\r
+\r
+const Tacton *TactonManager::get(byte numtacton) const\r
+{\r
+       if (numtacton < _nbtactons)\r
+               return _tactons[numtacton];\r
+       else\r
+               return NULL;\r
+}\r
+\r
+void TactonManager::clear()\r
+{\r
+       for (int i = 0 ; i < _nbtactons ; i++)\r
+               delete _tactons[i];\r
+       _nbtactons = 0;\r
+       _nbplays = 0;\r
+}\r
+\r
+void TactonManager::addPlay(byte index, unsigned long timestamp)\r
+{\r
+       if (index >= _nbtactons || _nbplays >= MAXPLAYBUFFER)\r
+               return;\r
+       _playindex[_nbplays] = index;\r
+       _playtimestamps[_nbplays] = timestamp;\r
+       _nbplays++;     \r
+}\r
+\r
+void TactonManager::play(byte index)\r
+{\r
+       if (index < _nbtactons)\r
+               _tactons[index]->play(*_player);\r
+}\r
+\r
+void TactonManager::play(unsigned int nbframes, byte *desc)\r
+{\r
+       Tacton t(nbframes, desc);\r
+       t.play(*_player);\r
+}\r
+\r
+void TactonManager::setOffset(unsigned long timestamp)\r
+{\r
+       _offset = timestamp;\r
+}\r
+\r
+void TactonManager::checkPlay()\r
+{\r
+       unsigned long now = millis() - _offset;\r
+/*     if (_nbplays == 0 || _playtimestamps[0] > now)\r
+               return;\r
+       Serial.print("Play at ");\r
+       Serial.println(now, DEC);\r
+       play(_playindex[0]);\r
+       //shift other plays\r
+       for (int i = 0 ; i < _nbplays ; i++)\r
+       {\r
+               _playindex[i] = _playindex[i + i];\r
+               _playtimestamps[i] = _playtimestamps[i + i];            \r
+       }\r
+       _nbplays--;*/\r
+\r
+       int i = 0, j = 0;\r
+       while (_nbplays > 0 && i < MAXPLAYBUFFER && _playtimestamps[i] < now)\r
+       {\r
+               //TEST\r
+               Serial.print("Play ");\r
+               Serial.println(_playtimestamps[i], DEC);\r
+               Serial.print(" at ");\r
+               Serial.println(now, DEC);\r
+               //\r
+               play(_playindex[i]);\r
+               i++;\r
+               _nbplays--;\r
+       }\r
+       if (i == 0)\r
+               return;\r
+       //shift not played tactons\r
+       for (j = 0 ; i + j < MAXPLAYBUFFER ; j++)\r
+       {\r
+               _playindex[j] = _playindex[j + i];\r
+               _playtimestamps[j] = _playtimestamps[j + i];            \r
+       }\r
+       //erase shifted values\r
+/*     for (i = j ; i < MAXPLAYBUFFER ; i++)\r
+       {\r
+               _playindex[i] = 0xff;\r
+               _playtimestamps[i] = 0xffffffff;\r
+       }*/\r
+}\r
+\r
+               
\ No newline at end of file
diff --git a/Arduino/TactonManager/TactonManager.h b/Arduino/TactonManager/TactonManager.h
new file mode 100644 (file)
index 0000000..5d89970
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef _TACTONMANAGER_\r
+#define _TACTONMANAGER_\r
+\r
+#include "WProgram.h"\r
+\r
+#include <Tacton.h>\r
+#include <TactonPlayer.h>\r
+\r
+#define MAXTACTONS             16\r
+#define MAXPLAYBUFFER  10\r
+\r
+class TactonManager\r
+{\r
+       public:\r
+               TactonManager(TactonPlayer *player);\r
+               \r
+//             void add(const Tacton &t);\r
+               void add(unsigned int nbframes, byte *desc);\r
+               const Tacton *get(byte numtacton) const;\r
+               \r
+               void play(byte index);\r
+               void play(unsigned int nbframes, byte *desc);\r
+               void addPlay(byte index, unsigned long timestamp);\r
+               void checkPlay();\r
+               void setOffset(unsigned long timestamp);\r
+\r
+               void clear();\r
+               \r
+       private:\r
+               byte _nbplays;\r
+               byte _nbtactons;\r
+               Tacton *_tactons[MAXTACTONS];\r
+               byte _playindex[MAXPLAYBUFFER];\r
+               unsigned long _playtimestamps[MAXPLAYBUFFER];\r
+               TactonPlayer *_player;\r
+               unsigned long _offset;\r
+};\r
+\r
+#endif\r
diff --git a/Arduino/TactonManager/keywords.txt b/Arduino/TactonManager/keywords.txt
new file mode 100644 (file)
index 0000000..ca231bc
--- /dev/null
@@ -0,0 +1,7 @@
+TactonManager  KEYWORD1\r
+get    KEYWORD2\r
+add    KEYWORD2\r
+clear  KEYWORD2\r
+play   KEYWORD2\r
+addPlay        KEYWORD2\r
+checkPlay      KEYWORD2
\ No newline at end of file
diff --git a/Arduino/TactonPlayer/TactonPlayer.cpp b/Arduino/TactonPlayer/TactonPlayer.cpp
new file mode 100644 (file)
index 0000000..b8a7a3f
--- /dev/null
@@ -0,0 +1,27 @@
+#include "WProgram.h"\r
+#include "TactonPlayer.h"\r
+\r
+TactonPlayer::TactonPlayer(byte nbtactors, byte *pins)\r
+:_nbtactors(nbtactors), _pins(pins)\r
+{\r
+       for (int i = 0 ; i < nbtactors ; i++)\r
+               pinMode(pins[i], OUTPUT);     \r
+}\r
+\r
+void TactonPlayer::beep(byte pattern, unsigned int duration, unsigned int frequency, byte amplitude) const\r
+{\r
+    int i;\r
+    long del = (long)(1000000 / frequency);\r
+    long looptime = (long)((((long)duration) * 1000) / (del * 2));\r
+    for (i = 0 ; i < looptime ; i++)\r
+    {\r
+               for (int j = 0 ; j < 8 ; j++)\r
+                       if (j < _nbtactors && (pattern & (0x01 << j)))\r
+                               analogWrite(_pins[j], amplitude);\r
+               delayMicroseconds(del);\r
+               for (int j = 0 ; j < 8 ; j++)\r
+                       if (j < _nbtactors && (pattern & (0x01 << j)))\r
+                               analogWrite(_pins[j], 0);\r
+               delayMicroseconds(del);\r
+    }\r
+}\r
diff --git a/Arduino/TactonPlayer/TactonPlayer.h b/Arduino/TactonPlayer/TactonPlayer.h
new file mode 100644 (file)
index 0000000..775f9f6
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef _TACTONPLAYER_\r
+#define _TACTONPLAYER_\r
+\r
+#include "WProgram.h"\r
+\r
+class TactonPlayer \r
+{\r
+       public:\r
+               TactonPlayer(byte nbtactors, byte *pins);\r
+\r
+               //8bits pattern => max 8 tactors, change type if using more\r
+               void beep(byte pattern, unsigned int duration, unsigned int frequency, byte amplitude) const;\r
+               \r
+               void debug1() { analogWrite(_pins[0], 255); delay(200); analogWrite(_pins[0], 0); delay(100);}\r
+               void debug2() { analogWrite(_pins[1], 255); delay(200); analogWrite(_pins[1], 0); delay(100); }\r
+               void debug3() { analogWrite(_pins[2], 255); delay(200); analogWrite(_pins[2], 0); delay(100); }\r
+               void debug4() { analogWrite(_pins[3], 255); delay(200); analogWrite(_pins[3], 0); delay(100); }\r
+       \r
+       private:                \r
+               byte _nbtactors;\r
+               byte *_pins;\r
+};\r
+\r
+#endif\r
diff --git a/Arduino/TactonPlayer/keywords.txt b/Arduino/TactonPlayer/keywords.txt
new file mode 100644 (file)
index 0000000..2e2fd22
--- /dev/null
@@ -0,0 +1,6 @@
+TactonPlayer   KEYWORD1\r
+beep   KEYWORD2\r
+debug1 KEYWORD2\r
+debug2 KEYWORD2\r
+debug3 KEYWORD2\r
+debug4 KEYWORD2
\ No newline at end of file
diff --git a/Arduino/wristbandTactons/wristbandTactons.pde b/Arduino/wristbandTactons/wristbandTactons.pde
new file mode 100644 (file)
index 0000000..e512d44
--- /dev/null
@@ -0,0 +1,141 @@
+#include <TactonManager.h>
+#include <TactonPlayer.h>
+#include <Tacton.h>
+byte pins[] = {
+  3, 11, 9, 5};
+TactonPlayer player(4, pins);
+TactonManager manager(&player);
+
+void* operator new(size_t n, void * p) { 
+  return p; 
+}
+void* operator new(size_t n) { 
+  return malloc(n); 
+}
+void operator delete (void * p) { 
+  free(p); 
+};
+
+byte command = 0;
+byte posbuf = 0;
+unsigned int nbf = 0;
+byte buffer[60];
+//unsigned long start = 0;
+boolean active = false;
+
+void setup()
+{
+  Serial.begin(57600);
+  player.debug1();
+  player.debug2();
+  player.debug3();
+  player.debug4();
+}
+
+void loop()
+{
+  byte index;
+  unsigned long timestamp;
+
+  if (Serial.available() > 0)
+  {
+    if (command == 0)
+      command = Serial.read();
+    switch(command)
+    {
+    //set the timestamp to 0, and watch for scheduled tactons
+    case 'S':
+//      start = millis();
+      manager.setOffset(millis());
+      command = 0;
+      active = true;
+      break;
+    //stop watching scheduled tactons, and erase registered tactons
+    case 'Q':
+      command = 0;
+      manager.clear();
+      active = false;
+      break;
+    //register a tacton
+    case 'N':
+      if (nbf == 0 && Serial.available() >= 2)
+        nbf = (((unsigned int) Serial.read()) << 8) | ((unsigned int) Serial.read());
+      if (nbf > 0)
+      {
+        //DO NOT OVERFLOW max(nbf): 10
+        while (posbuf < nbf * 6 && Serial.available() > 0)
+        {
+          buffer[posbuf] = Serial.read();
+          posbuf++;
+        }
+        if (posbuf >= nbf*6)
+        {
+          manager.add(nbf, buffer);
+          posbuf = 0;
+          command = 0;
+          nbf = 0;
+        }
+      }
+      break;
+    //play a specified tacton
+    case 'V':
+      if (nbf == 0 && Serial.available() >= 2)
+        nbf = (((unsigned int) Serial.read()) << 8) | ((unsigned int) Serial.read());
+      if (nbf > 0)
+      {
+        //DO NOT OVERFLOW max(nbf): 10
+        while (posbuf < nbf * 6 && Serial.available() > 0)
+        {
+          buffer[posbuf] = Serial.read();
+          posbuf++;
+        }
+        if (posbuf >= nbf*6)
+        {
+          manager.play(nbf, buffer);
+          posbuf = 0;
+          command = 0;
+          nbf = 0;
+        }
+      }
+      break;
+    //play a registered tacton
+    case 'T':
+      if (Serial.available() >= 1)
+      {
+        index = Serial.read();
+        manager.play(index);
+        command = 0;
+        Serial.print("Play");
+        Serial.println(index, DEC);
+      }
+      break;
+    //schedule the play of a registered tacton
+    case 'P':
+      if (Serial.available() >= 5)
+      {
+        index = Serial.read();
+        timestamp = (((unsigned long)Serial.read()) << 24) | \
+            (((unsigned long)Serial.read()) << 16) | \
+            (((unsigned long)Serial.read()) << 8) | \
+            (((unsigned long)Serial.read()));
+        Serial.print("Plan ");
+        Serial.println(timestamp, DEC);
+/*        Serial.print(" played at ");
+        Serial.print(timestamp + start, DEC);
+        Serial.print(" shift=");
+        Serial.println(start, DEC);*/
+        manager.addPlay(index, timestamp);
+        command = 0;
+      }
+      break;
+    //unknown command: do nothing
+    default:
+      command = 0;
+      break;
+    }
+  }
+
+  if (active)
+    manager.checkPlay();
+}
+\r