From c01bc2b62f76a5d417e5ed13dcb0c047a4f67224 Mon Sep 17 00:00:00 2001
From: Cristian Maglie <c.maglie@bug.st>
Date: Sun, 6 Jan 2013 18:38:03 +0100
Subject: Merged upcoming 1.0.4 and updated revision log

---
 .../Esplora/Experts/EsploraTable/EsploraTable.ino  | 213 +++++++++++++++++++++
 1 file changed, 213 insertions(+)
 create mode 100644 libraries/Esplora/Experts/EsploraTable/EsploraTable.ino

(limited to 'libraries/Esplora/Experts/EsploraTable/EsploraTable.ino')

diff --git a/libraries/Esplora/Experts/EsploraTable/EsploraTable.ino b/libraries/Esplora/Experts/EsploraTable/EsploraTable.ino
new file mode 100644
index 0000000..712dffa
--- /dev/null
+++ b/libraries/Esplora/Experts/EsploraTable/EsploraTable.ino
@@ -0,0 +1,213 @@
+/*
+  Esplora Table
+
+  Acts like a keyboard that prints sensor
+  data in a table-like text, row by row.
+  
+  At startup, it does nothing. It waits for you to open a
+  spreadsheet (e.g. Google Drive spreadsheet) so it can write
+  data. By pressing Switch 1, it starts printing the table
+  headers and the first row of data. It waits a bit, then it
+  will print another row, and so on.
+  
+  The amount of time between each row is determined by the slider.
+  If put to full left, the sketch will wait 10 seconds; at
+  full right position, it will wait 5 minutes. An intermediate
+  position will make the sketch wait for some time in-between.
+  
+  Clicking the Switch 1 at any time will stop the logging.
+
+  The color LED shows what the sketch is doing:
+  blue  = idle, waiting for you to press Switch 1 to start logging
+  green = active; will print soon
+  red   = printing data to the PC
+
+  Created on 22 november 2012
+  By Enrico Gueli <enrico.gueli@gmail.com>
+  modified 24 Nov 2012
+  by Tom Igoe
+*/
+
+#include <Esplora.h>
+
+/*
+ * this variable tells if the data-logging is currently active.
+ */
+boolean active = false;
+
+/*
+ * this variable holds the time in the future when the sketch
+ * will "sample" the data (sampling is the act of reading some
+ * input at a known time). This variable is checked continuously
+ * against millis() to know when it's time to sample.
+ */
+unsigned long nextSampleAt = 0;
+
+/*
+ * This variable just holds the millis() value at the time the
+ * logging was activated. This is needed to enter the correct
+ * value in the "Time" column in the printed table.
+ */
+unsigned long startedAt = 0;
+
+
+/*
+ * when the "active" variable is set to true, the same is done
+ * with this variable. This is needed because the code that does
+ * the "just-after-activation" stuff is run some time later than
+ * the code that says "be active now".
+ */
+boolean justActivated = false;
+
+
+/*
+ * this variable holds the last sensed status of the switch press
+ * button. If the code sees a difference between the value of
+ * this variable and the current status of the switch, it means
+ * that the button was either pressed or released.
+ */
+boolean lastStartBtn = HIGH;
+
+/*
+ * Initialization code. The virtual USB keyboard must be
+ * initialized; the Serial class is needed just for debugging.
+ */
+void setup() {
+  Keyboard.begin();
+  Serial.begin(9600);
+}
+
+/*
+ * This code is run continuously.
+ */
+void loop() {
+  /*
+   * note: we don't use Arduino's delay() here, because we can't
+   * normally do anything while delaying. Our own version lets us
+   * check for button presses often enough to not miss any event.
+   */
+  activeDelay(50);
+ 
+  /*
+   * the justActivated variable may be set to true in the
+   * checkSwitchPress() function. Here we check its status to
+   * print the table headers and configure what's needed to.
+   */
+  if (justActivated == true) {
+    justActivated = false; // do this just once
+    printHeaders();
+    // do next sampling ASAP
+    nextSampleAt = startedAt = millis();
+  }
+  
+  if (active == true) {
+    if (nextSampleAt < millis()) {
+      // it's time to sample!
+      int slider = Esplora.readSlider();
+      // the row below maps the slider position to a range between
+      // 10 and 290 seconds.
+      int sampleInterval = map(slider, 0, 1023, 10, 290);
+      nextSampleAt = millis() + sampleInterval * 1000;
+      
+      logAndPrint();
+    }
+    
+    // let the RGB led blink green once per second, for 200ms.
+    unsigned int ms = millis() % 1000;
+    if (ms < 200)
+      Esplora.writeGreen(50);
+    else
+      Esplora.writeGreen(0);
+    
+    Esplora.writeBlue(0);
+  } 
+  else
+    // while not active, keep a reassuring blue color coming
+    // from the Esplora...
+    Esplora.writeBlue(20);
+    
+}
+
+/*
+ * Print the table headers.
+ */
+void printHeaders() {
+  Keyboard.print("Time");
+  Keyboard.write(KEY_TAB);
+  activeDelay(300); // Some spreadsheets are slow, e.g. Google
+                    // Drive that wants to save every edit.
+  Keyboard.print("Accel X");
+  Keyboard.write(KEY_TAB);
+  activeDelay(300);
+  Keyboard.print("Accel Y");
+  Keyboard.write(KEY_TAB);
+  activeDelay(300);
+  Keyboard.print("Accel Z");
+  Keyboard.println();
+  activeDelay(300);
+}
+
+void logAndPrint() {
+  // do all the samplings at once, because keystrokes have delays
+  unsigned long timeSecs = (millis() - startedAt) /1000;
+  int xAxis = Esplora.readAccelerometer(X_AXIS);
+  int yAxis = Esplora.readAccelerometer(Y_AXIS);
+  int zAxis = Esplora.readAccelerometer(Z_AXIS);
+  
+  Esplora.writeRed(100);
+  
+  Keyboard.print(timeSecs);
+  Keyboard.write(KEY_TAB);
+  activeDelay(300);
+  Keyboard.print(xAxis);
+  Keyboard.write(KEY_TAB);
+  activeDelay(300);
+  Keyboard.print(yAxis);
+  Keyboard.write(KEY_TAB);
+  activeDelay(300);
+  Keyboard.print(zAxis);
+  Keyboard.println();
+  activeDelay(300);
+  Keyboard.write(KEY_HOME);
+  
+  Esplora.writeRed(0);
+}
+
+/**
+ * Similar to delay(), but allows the program to do something else
+ * in the meanwhile. In particular, it calls checkSwitchPress().
+ * Note 1: it may wait longer than the specified amount, not less;
+ * Note 2: beware of data synchronization issues, e.g. if the
+ * activeDelay() function alters some variables used by the
+ * caller of this function.
+ */
+void activeDelay(unsigned long amount) {
+  unsigned long at = millis() + amount;
+  while (millis() < at) {
+    checkSwitchPress();
+  }
+}
+
+/*
+ * This function reads the status of the switch; if it sees that
+ * it was pressed, toggles the status of the "active" variable.
+ * If it's set to true, also the justActivated variable is set to
+ * true, so the loop() function above can do the right things.
+ * This function should be called as often as possible and do as
+ * little as possible, because it can be called while another
+ * function is running.
+ */
+void checkSwitchPress() {
+  boolean startBtn = Esplora.readButton(SWITCH_DOWN);
+
+  if (startBtn != lastStartBtn) {
+    if (startBtn == HIGH) { // button released
+      active = !active;
+      if (active)
+        justActivated = true;    
+    }
+    
+    lastStartBtn = startBtn;
+  }
+}
+
-- 
cgit v1.2.3-18-g5258