add IRRemote support

add IRRemote support

error: pathspec 'waFirmata_buzzer_ultrasonic_dht_MaxMatrix_MFRC522_IR.ino' did not match any file(s) known to git

--- waFirmata_buzzer_ultrasonic_dht_MaxMatrix_MFRC522_IR.ino
+++ waFirmata_buzzer_ultrasonic_dht_MaxMatrix_MFRC522_IR.ino
@@ -0,0 +1,887 @@
+/*
+  Firmata is a generic protocol for communicating with microcontrollers
+  from software on a host computer. It is intended to work with
+  any host computer software package.
+
+  To download a host software package, please clink on the following link
+  to open the list of Firmata client libraries your default browser.
+
+  https://github.com/firmata/arduino#firmata-client-libraries
+
+  Copyright (C) 2006-2008 Hans-Christoph Steiner.  All rights reserved.
+  Copyright (C) 2010-2011 Paul Stoffregen.  All rights reserved.
+  Copyright (C) 2009 Shigeru Kobayashi.  All rights reserved.
+  Copyright (C) 2009-2015 Jeff Hoefs.  All rights reserved.
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  See file LICENSE.txt for further informations on licensing terms.
+
+  Last updated by Jeff Hoefs: August 9th, 2015
+*/
+
+#include <IRremote.h>
+#include <Wire.h>
+#include <Firmata.h>
+#include <dht.h>
+#include <MaxMatrix.h>
+#include <SPI.h>
+#include <MFRC522.h>
+#include <Joypad.h>
+
+#define I2C_WRITE                   B00000000
+#define I2C_READ                    B00001000
+#define I2C_READ_CONTINUOUSLY       B00010000
+#define I2C_STOP_READING            B00011000
+#define I2C_READ_WRITE_MODE_MASK    B00011000
+#define I2C_10BIT_ADDRESS_MODE_MASK B00100000
+#define I2C_MAX_QUERIES             8
+#define I2C_REGISTER_NOT_SPECIFIED  -1
+
+#define RST_PIN         9
+#define SS_PIN          10
+
+// the minimum interval for sampling analog input
+#define MINIMUM_SAMPLING_INTERVAL 10
+
+
+/*==============================================================================
+   GLOBAL VARIABLES
+  ============================================================================*/
+dht DHT;
+MaxMatrix *mm;
+MFRC522 *mfrc522;
+Joypad *joypad;
+IRrecv *irrecv = NULL;
+decode_results results;
+
+unsigned char strhex[17] = "0123456789ABCDEF";
+byte rfidTouchScan = 0;
+boolean rfidTouch = false;
+boolean rfidEnable = false;
+
+/* analog inputs */
+int analogInputsToReport = 0; // bitwise array to store pin reporting
+
+/* digital input ports */
+byte reportPINs[TOTAL_PORTS];       // 1 = report this port, 0 = silence
+byte previousPINs[TOTAL_PORTS];     // previous 8 bits sent
+
+/* pins configuration */
+byte pinConfig[TOTAL_PINS];         // configuration of every pin
+byte portConfigInputs[TOTAL_PORTS]; // each bit: 1 = pin in INPUT, 0 = anything else
+int pinState[TOTAL_PINS];           // any value that has been written
+
+/* timer variables */
+unsigned long currentMillis;        // store the current value from millis()
+unsigned long previousMillis;       // for comparison with currentMillis
+unsigned int samplingInterval = 19; // how often to run the main loop (in ms)
+
+/* i2c data */
+struct i2c_device_info {
+  byte addr;
+  int reg;
+  byte bytes;
+};
+
+/* for i2c read continuous more */
+i2c_device_info query[I2C_MAX_QUERIES];
+
+byte i2cRxData[32];
+boolean isI2CEnabled = false;
+signed char queryIndex = -1;
+// default delay time between i2c read request and Wire.requestFrom()
+unsigned int i2cReadDelayTime = 0;
+
+boolean isResetting = false;
+
+/* utility functions */
+void wireWrite(byte data)
+{
+#if ARDUINO >= 100
+  Wire.write((byte)data);
+#else
+  Wire.send(data);
+#endif
+}
+
+byte wireRead(void)
+{
+#if ARDUINO >= 100
+  return Wire.read();
+#else
+  return Wire.receive();
+#endif
+}
+
+/*==============================================================================
+   FUNCTIONS
+  ============================================================================*/
+
+void readAndReportData(byte address, int theRegister, byte numBytes) {
+  // allow I2C requests that don't require a register read
+  // for example, some devices using an interrupt pin to signify new data available
+  // do not always require the register read so upon interrupt you call Wire.requestFrom()
+  if (theRegister != I2C_REGISTER_NOT_SPECIFIED) {
+    Wire.beginTransmission(address);
+    wireWrite((byte)theRegister);
+    Wire.endTransmission();
+    // do not set a value of 0
+    if (i2cReadDelayTime > 0) {
+      // delay is necessary for some devices such as WiiNunchuck
+      delayMicroseconds(i2cReadDelayTime);
+    }
+  } else {
+    theRegister = 0;  // fill the register with a dummy value
+  }
+
+  Wire.requestFrom(address, numBytes);  // all bytes are returned in requestFrom
+
+  // check to be sure correct number of bytes were returned by slave
+  if (numBytes < Wire.available()) {
+    Firmata.sendString("I2C: Too many bytes received");
+  } else if (numBytes > Wire.available()) {
+    Firmata.sendString("I2C: Too few bytes received");
+  }
+
+  i2cRxData[0] = address;
+  i2cRxData[1] = theRegister;
+
+  for (int i = 0; i < numBytes && Wire.available(); i++) {
+    i2cRxData[2 + i] = wireRead();
+  }
+
+  // send slave address, register and received bytes
+  Firmata.sendSysex(SYSEX_I2C_REPLY, numBytes + 2, i2cRxData);
+}
+
+void outputPort(byte portNumber, byte portValue, byte forceSend)
+{
+  // pins not configured as INPUT are cleared to zeros
+  portValue = portValue & portConfigInputs[portNumber];
+  // only send if the value is different than previously sent
+  if (forceSend || previousPINs[portNumber] != portValue) {
+    Firmata.sendDigitalPort(portNumber, portValue);
+    previousPINs[portNumber] = portValue;
+  }
+}
+
+/* -----------------------------------------------------------------------------
+   check all the active digital inputs for change of state, then add any events
+   to the Serial output queue using Serial.print() */
+void checkDigitalInputs(void)
+{
+  /* Using non-looping code allows constants to be given to readPort().
+     The compiler will apply substantial optimizations if the inputs
+     to readPort() are compile-time constants. */
+  if (TOTAL_PORTS > 0 && reportPINs[0]) outputPort(0, readPort(0, portConfigInputs[0]), false);
+  if (TOTAL_PORTS > 1 && reportPINs[1]) outputPort(1, readPort(1, portConfigInputs[1]), false);
+  if (TOTAL_PORTS > 2 && reportPINs[2]) outputPort(2, readPort(2, portConfigInputs[2]), false);
+  if (TOTAL_PORTS > 3 && reportPINs[3]) outputPort(3, readPort(3, portConfigInputs[3]), false);
+  if (TOTAL_PORTS > 4 && reportPINs[4]) outputPort(4, readPort(4, portConfigInputs[4]), false);
+  if (TOTAL_PORTS > 5 && reportPINs[5]) outputPort(5, readPort(5, portConfigInputs[5]), false);
+  if (TOTAL_PORTS > 6 && reportPINs[6]) outputPort(6, readPort(6, portConfigInputs[6]), false);
+  if (TOTAL_PORTS > 7 && reportPINs[7]) outputPort(7, readPort(7, portConfigInputs[7]), false);
+  if (TOTAL_PORTS > 8 && reportPINs[8]) outputPort(8, readPort(8, portConfigInputs[8]), false);
+  if (TOTAL_PORTS > 9 && reportPINs[9]) outputPort(9, readPort(9, portConfigInputs[9]), false);
+  if (TOTAL_PORTS > 10 && reportPINs[10]) outputPort(10, readPort(10, portConfigInputs[10]), false);
+  if (TOTAL_PORTS > 11 && reportPINs[11]) outputPort(11, readPort(11, portConfigInputs[11]), false);
+  if (TOTAL_PORTS > 12 && reportPINs[12]) outputPort(12, readPort(12, portConfigInputs[12]), false);
+  if (TOTAL_PORTS > 13 && reportPINs[13]) outputPort(13, readPort(13, portConfigInputs[13]), false);
+  if (TOTAL_PORTS > 14 && reportPINs[14]) outputPort(14, readPort(14, portConfigInputs[14]), false);
+  if (TOTAL_PORTS > 15 && reportPINs[15]) outputPort(15, readPort(15, portConfigInputs[15]), false);
+}
+
+// -----------------------------------------------------------------------------
+/* sets the pin mode to the correct state and sets the relevant bits in the
+   two bit-arrays that track Digital I/O and PWM status
+*/
+void setPinModeCallback(byte pin, int mode)
+{
+  if (pinConfig[pin] == IGNORE)
+    return;
+
+  if (pinConfig[pin] == I2C && isI2CEnabled && mode != I2C) {
+    // disable i2c so pins can be used for other functions
+    // the following if statements should reconfigure the pins properly
+    disableI2CPins();
+  }
+  if (IS_PIN_ANALOG(pin)) {
+    reportAnalogCallback(PIN_TO_ANALOG(pin), mode == ANALOG ? 1 : 0); // turn on/off reporting
+  }
+  if (IS_PIN_DIGITAL(pin)) {
+    if (mode == INPUT) {
+      portConfigInputs[pin / 8] |= (1 << (pin & 7));
+    } else {
+      portConfigInputs[pin / 8] &= ~(1 << (pin & 7));
+    }
+  }
+  pinState[pin] = 0;
+  switch (mode) {
+    case ANALOG:
+      if (IS_PIN_ANALOG(pin)) {
+        if (IS_PIN_DIGITAL(pin)) {
+          pinMode(PIN_TO_DIGITAL(pin), INPUT);    // disable output driver
+          digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups
+        }
+        pinConfig[pin] = ANALOG;
+      }
+      break;
+    case INPUT:
+      if (IS_PIN_DIGITAL(pin)) {
+        pinMode(PIN_TO_DIGITAL(pin), INPUT);    // disable output driver
+        digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups
+        pinConfig[pin] = INPUT;
+      }
+      break;
+    case OUTPUT:
+      if (IS_PIN_DIGITAL(pin)) {
+        digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable PWM
+        pinMode(PIN_TO_DIGITAL(pin), OUTPUT);
+        pinConfig[pin] = OUTPUT;
+      }
+      break;
+    case PWM:
+      if (IS_PIN_PWM(pin)) {
+        pinMode(PIN_TO_PWM(pin), OUTPUT);
+        analogWrite(PIN_TO_PWM(pin), 0);
+        pinConfig[pin] = PWM;
+      }
+      break;
+    case I2C:
+      if (IS_PIN_I2C(pin)) {
+        // mark the pin as i2c
+        // the user must call I2C_CONFIG to enable I2C for a device
+        pinConfig[pin] = I2C;
+      }
+      break;
+    default:
+      Firmata.sendString("Unknown pin mode"); // TODO: put error msgs in EEPROM
+  }
+  // TODO: save status to EEPROM here, if changed
+}
+
+void analogWriteCallback(byte pin, int value)
+{
+  if (pin < TOTAL_PINS) {
+    switch (pinConfig[pin]) {
+      case PWM:
+        if (IS_PIN_PWM(pin))
+          analogWrite(PIN_TO_PWM(pin), value);
+        pinState[pin] = value;
+        break;
+    }
+  }
+}
+
+void digitalWriteCallback(byte port, int value)
+{
+  byte pin, lastPin, mask = 1, pinWriteMask = 0;
+
+  if (port < TOTAL_PORTS) {
+    // create a mask of the pins on this port that are writable.
+    lastPin = port * 8 + 8;
+    if (lastPin > TOTAL_PINS) lastPin = TOTAL_PINS;
+    for (pin = port * 8; pin < lastPin; pin++) {
+      // do not disturb non-digital pins (eg, Rx & Tx)
+      if (IS_PIN_DIGITAL(pin)) {
+        // only write to OUTPUT and INPUT (enables pullup)
+        // do not touch pins in PWM, ANALOG, SERVO or other modes
+        if (pinConfig[pin] == OUTPUT || pinConfig[pin] == INPUT) {
+          pinWriteMask |= mask;
+          pinState[pin] = ((byte)value & mask) ? 1 : 0;
+        }
+      }
+      mask = mask << 1;
+    }
+    writePort(port, (byte)value, pinWriteMask);
+  }
+}
+
+
+// -----------------------------------------------------------------------------
+/* sets bits in a bit array (int) to toggle the reporting of the analogIns
+*/
+//void FirmataClass::setAnalogPinReporting(byte pin, byte state) {
+//}
+void reportAnalogCallback(byte analogPin, int value)
+{
+  if (analogPin < TOTAL_ANALOG_PINS) {
+    if (value == 0) {
+      analogInputsToReport = analogInputsToReport & ~ (1 << analogPin);
+    } else {
+      analogInputsToReport = analogInputsToReport | (1 << analogPin);
+      // prevent during system reset or all analog pin values will be reported
+      // which may report noise for unconnected analog pins
+      if (!isResetting) {
+        // Send pin value immediately. This is helpful when connected via
+        // ethernet, wi-fi or bluetooth so pin states can be known upon
+        // reconnecting.
+        Firmata.sendAnalog(analogPin, analogRead(analogPin));
+      }
+    }
+  }
+  // TODO: save status to EEPROM here, if changed
+}
+
+void reportDigitalCallback(byte port, int value)
+{
+  if (port < TOTAL_PORTS) {
+    reportPINs[port] = (byte)value;
+    // Send port value immediately. This is helpful when connected via
+    // ethernet, wi-fi or bluetooth so pin states can be known upon
+    // reconnecting.
+    if (value) outputPort(port, readPort(port, portConfigInputs[port]), true);
+  }
+  // do not disable analog reporting on these 8 pins, to allow some
+  // pins used for digital, others analog.  Instead, allow both types
+  // of reporting to be enabled, but check if the pin is configured
+  // as analog when sampling the analog inputs.  Likewise, while
+  // scanning digital pins, portConfigInputs will mask off values from any
+  // pins configured as analog
+}
+
+/*==============================================================================
+   SYSEX-BASED commands
+  ============================================================================*/
+void setIRrecv(byte pin) {
+  irrecv = new IRrecv(pin);
+}
+
+void irReceiver() { //68AE1A03
+  byte sendByte = 0;
+  unsigned long result = 0;
+  if (irrecv != NULL) {
+    if (irrecv->decode(&results)) {
+      result = results.value;
+      Firmata.write(START_SYSEX);
+      Firmata.write(0x04);
+      Firmata.write(0x10);
+      for (int i = 3; i >= 0; i--) {
+        sendByte = (result >> (8 * i)) & 0xff;
+        char msb =  (sendByte >> 4) + 0x30;
+        if (msb > 0x39) msb += 7;
+        Firmata.write(msb);
+        char lsb =  (sendByte & 0x0f) + 0x30;
+        if (lsb > 0x39) lsb += 7;
+        Firmata.write(lsb);
+      }
+      Firmata.write(END_SYSEX);
+      irrecv->resume(); // Receive the next value
+    }
+  }
+}
+
+void sysexCallback(byte command, byte argc, byte *argv)
+{
+  byte mode;
+  byte slaveAddress;
+  byte data;
+  int slaveRegister;
+  unsigned int delayTime;
+  byte strLen;
+  String strData;
+  //ir send
+  byte codeType, bits;
+  unsigned long sendCode;
+  switch (command) {
+    case 1:
+      pinMode(argv[0] & 0x0f, OUTPUT);
+      pinMode(argv[1] & 0x0f, INPUT);
+      digitalWrite(argv[0] & 0x0f, LOW);
+      delayMicroseconds(2);
+      digitalWrite(argv[0] & 0x0f, HIGH);
+      delayMicroseconds(10);
+      digitalWrite(argv[0] & 0x0f, LOW);
+      Firmata.write(START_SYSEX);
+      Firmata.write(1);
+      Firmata.write(argv[0] & 0x0f);
+      Firmata.write(argv[1] & 0x0f);
+      {
+        String strData = String(pulseIn(argv[1] & 0x0f, HIGH) / 58);
+        data = strData.length();
+        for (int i = 0; i < data; i++) {
+          Firmata.write(strData.charAt(i));
+        }
+      }
+      Firmata.write(END_SYSEX);
+      break;
+    case 4:
+      switch (argv[0]) {
+        case 4:
+          DHT.read11(argv[1]);
+          Firmata.write(START_SYSEX);
+          Firmata.write(4);
+          Firmata.write(4);
+          Firmata.write(argv[1]);
+          strData = String(int(DHT.humidity * 100)) + String(int(DHT.temperature * 100));
+          //Serial.println(strData);
+          strLen = strData.length();
+          for (int i = 0; i < strLen; i++) {
+            Firmata.write(strData.charAt(i));
+          }
+          Firmata.write(END_SYSEX);
+          break;
+        case 7: //Buzzer f004070b131805f7
+          pinMode(argv[1], OUTPUT);
+          tone(argv[1], (String(argv[2], HEX)).toInt() * 100 +
+               (String(argv[3], HEX)).toInt(), argv[4] * 100);
+          break;
+        case 8:
+          // 00: init , 01:display , 02: clear
+          switch (argv[1]) { //argv[1] = cmd;
+            case 0: //init f0040800060708f7
+              if (mm == NULL) {
+                mm = new MaxMatrix();
+                mm->init(argv[2], argv[3], argv[4], 1);
+              }
+              break;
+            case 1: //display f0040801FF02040810204080f7
+              for (byte i = 0; i < 16; i = i + 2) {
+                mm->setColumn(i / 2, asc2hex(argv + i + 2));
+              }
+              break;
+            case 2: //clear f0040802f7
+              mm->clear();
+              break;
+            case 3: //Intensity f00408030ff7
+              mm->setIntensity(argv[2]);
+              break;
+          }
+          break;
+        case 9: //IRremote
+          codeType = argv[1];
+          bits = argv[2];
+          sendCode = argv[3];
+          for (int i = 4; i <= 6; i++) {
+            sendCode = (sendCode << 8) | argv[i];
+          }
+          switch (argv[1]) { //argv[1] = codeType
+            case 4: //NEC
+              //irsend.sendNEC(0x20DF10EF, bits);
+              //irsend.sendNEC(sendCode, bits);
+              if (irrecv != NULL) {
+                irrecv->enableIRIn();
+              }
+              break;
+          }
+          Firmata.write(START_SYSEX);
+          Firmata.write(9);
+          Firmata.write('O');
+          Firmata.write('K');
+          Firmata.write(END_SYSEX);
+          break;
+        case 10:
+          // 00: init , 01:disable
+          switch (argv[1]) { //argv[1] = cmd;
+            case 0: //init receiver pin
+              setIRrecv(argv[2]);
+              irrecv->enableIRIn();
+              break;
+            case 1: //disable receiver pin
+              //irrecv = NULL;
+              break;
+          }
+          break;
+        case 15:
+          switch (argv[1]) { //argv[1] = cmd;
+            case 0: // init RFID
+              if (mfrc522 == NULL) {
+                mfrc522 = new MFRC522(SS_PIN, RST_PIN);
+                SPI.begin();
+                mfrc522->PCD_Init();
+              }
+              break;
+            case 1: // start RFID
+              if (mfrc522 != NULL) {
+                rfidEnable = true;
+              }
+              break;
+            case 2: // stop RFID
+              if (mfrc522 != NULL) {
+                rfidEnable = false;
+              }
+              break;
+            case 3: // change RFID
+              if (mfrc522 != NULL) {
+              }
+              break;
+          }
+          break;
+        case 20: //Joypad
+          switch (argv[1]) { //argv[1] = cmd;
+            case 0: //board.board.send([0xf0,0x04,0x14,1,0,1,0xf7]);
+              if (joypad == NULL) {
+                joypad = new Joypad();
+              }
+              joypad->init(argv[2], argv[3]);
+              break;
+            case 1: //board.board.send([0xf0,0x04,0x14,1,0,1,2,3,0xf7]);
+              if (joypad == NULL) {
+                joypad = new Joypad();
+              }
+              joypad->init(argv[2], argv[3], argv[4], argv[5]);
+              break;
+            case 2: //start
+              joypad->start();
+              break;
+            case 3: //stop
+              joypad->stop();
+              break;
+          }
+          break;
+      }
+      break;
+    case I2C_REQUEST:
+      mode = argv[1] & I2C_READ_WRITE_MODE_MASK;
+      if (argv[1] & I2C_10BIT_ADDRESS_MODE_MASK) {
+        Firmata.sendString("10-bit addressing not supported");
+        return;
+      }
+      else {
+        slaveAddress = argv[0];
+      }
+
+      switch (mode) {
+        case I2C_WRITE:
+          Wire.beginTransmission(slaveAddress);
+          for (byte i = 2; i < argc; i += 2) {
+            data = argv[i] + (argv[i + 1] << 7);
+            wireWrite(data);
+          }
+          Wire.endTransmission();
+          delayMicroseconds(70);
+          break;
+        case I2C_READ:
+          if (argc == 6) {
+            // a slave register is specified
+            slaveRegister = argv[2] + (argv[3] << 7);
+            data = argv[4] + (argv[5] << 7);  // bytes to read
+          }
+          else {
+            // a slave register is NOT specified
+            slaveRegister = I2C_REGISTER_NOT_SPECIFIED;
+            data = argv[2] + (argv[3] << 7);  // bytes to read
+          }
+          readAndReportData(slaveAddress, (int)slaveRegister, data);
+          break;
+        case I2C_READ_CONTINUOUSLY:
+          if ((queryIndex + 1) >= I2C_MAX_QUERIES) {
+            // too many queries, just ignore
+            Firmata.sendString("too many queries");
+            break;
+          }
+          if (argc == 6) {
+            // a slave register is specified
+            slaveRegister = argv[2] + (argv[3] << 7);
+            data = argv[4] + (argv[5] << 7);  // bytes to read
+          }
+          else {
+            // a slave register is NOT specified
+            slaveRegister = (int)I2C_REGISTER_NOT_SPECIFIED;
+            data = argv[2] + (argv[3] << 7);  // bytes to read
+          }
+          queryIndex++;
+          query[queryIndex].addr = slaveAddress;
+          query[queryIndex].reg = slaveRegister;
+          query[queryIndex].bytes = data;
+          break;
+        case I2C_STOP_READING:
+          byte queryIndexToSkip;
+          // if read continuous mode is enabled for only 1 i2c device, disable
+          // read continuous reporting for that device
+          if (queryIndex <= 0) {
+            queryIndex = -1;
+          } else {
+            // if read continuous mode is enabled for multiple devices,
+            // determine which device to stop reading and remove it's data from
+            // the array, shifiting other array data to fill the space
+            for (byte i = 0; i < queryIndex + 1; i++) {
+              if (query[i].addr == slaveAddress) {
+                queryIndexToSkip = i;
+                break;
+              }
+            }
+
+            for (byte i = queryIndexToSkip; i < queryIndex + 1; i++) {
+              if (i < I2C_MAX_QUERIES) {
+                query[i].addr = query[i + 1].addr;
+                query[i].reg = query[i + 1].reg;
+                query[i].bytes = query[i + 1].bytes;
+              }
+            }
+            queryIndex--;
+          }
+          break;
+        default:
+          break;
+      }
+      break;
+    case I2C_CONFIG:
+      delayTime = (argv[0] + (argv[1] << 7));
+
+      if (delayTime > 0) {
+        i2cReadDelayTime = delayTime;
+      }
+
+      if (!isI2CEnabled) {
+        enableI2CPins();
+      }
+
+      break;
+    case SAMPLING_INTERVAL:
+      if (argc > 1) {
+        samplingInterval = argv[0] + (argv[1] << 7);
+        if (samplingInterval < MINIMUM_SAMPLING_INTERVAL) {
+          samplingInterval = MINIMUM_SAMPLING_INTERVAL;
+        }
+      } else {
+        //Firmata.sendString("Not enough data");
+      }
+      break;
+    case EXTENDED_ANALOG:
+      if (argc > 1) {
+        int val = argv[1];
+        if (argc > 2) val |= (argv[2] << 7);
+        if (argc > 3) val |= (argv[3] << 14);
+        analogWriteCallback(argv[0], val);
+      }
+      break;
+    case CAPABILITY_QUERY:
+      Firmata.write(START_SYSEX);
+      Firmata.write(CAPABILITY_RESPONSE);
+      for (byte pin = 0; pin < TOTAL_PINS; pin++) {
+        if (IS_PIN_DIGITAL(pin)) {
+          Firmata.write((byte)INPUT);
+          Firmata.write(1);
+          Firmata.write((byte)OUTPUT);
+          Firmata.write(1);
+        }
+        if (IS_PIN_ANALOG(pin)) {
+          Firmata.write(ANALOG);
+          Firmata.write(10); // 10 = 10-bit resolution
+        }
+        if (IS_PIN_PWM(pin)) {
+          Firmata.write(PWM);
+          Firmata.write(8); // 8 = 8-bit resolution
+        }
+        if (IS_PIN_DIGITAL(pin)) {
+          Firmata.write(SERVO);
+          Firmata.write(14);
+        }
+        if (IS_PIN_I2C(pin)) {
+          Firmata.write(I2C);
+          Firmata.write(1);  // TODO: could assign a number to map to SCL or SDA
+        }
+        Firmata.write(127);
+      }
+      Firmata.write(END_SYSEX);
+      break;
+    case PIN_STATE_QUERY:
+      if (argc > 0) {
+        byte pin = argv[0];
+        Firmata.write(START_SYSEX);
+        Firmata.write(PIN_STATE_RESPONSE);
+        Firmata.write(pin);
+        if (pin < TOTAL_PINS) {
+          Firmata.write((byte)pinConfig[pin]);
+          Firmata.write((byte)pinState[pin] & 0x7F);
+          if (pinState[pin] & 0xFF80) Firmata.write((byte)(pinState[pin] >> 7) & 0x7F);
+          if (pinState[pin] & 0xC000) Firmata.write((byte)(pinState[pin] >> 14) & 0x7F);
+        }
+        Firmata.write(END_SYSEX);
+      }
+      break;
+    case ANALOG_MAPPING_QUERY:
+      Firmata.write(START_SYSEX);
+      Firmata.write(ANALOG_MAPPING_RESPONSE);
+      for (byte pin = 0; pin < TOTAL_PINS; pin++) {
+        Firmata.write(IS_PIN_ANALOG(pin) ? PIN_TO_ANALOG(pin) : 127);
+      }
+      Firmata.write(END_SYSEX);
+      break;
+  }
+}
+
+void enableI2CPins()
+{
+  byte i;
+  // is there a faster way to do this? would probaby require importing
+  // Arduino.h to get SCL and SDA pins
+  for (i = 0; i < TOTAL_PINS; i++) {
+    if (IS_PIN_I2C(i)) {
+      // mark pins as i2c so they are ignore in non i2c data requests
+      setPinModeCallback(i, I2C);
+    }
+  }
+
+  isI2CEnabled = true;
+
+  Wire.begin();
+}
+
+/* disable the i2c pins so they can be used for other functions */
+void disableI2CPins() {
+  isI2CEnabled = false;
+  // disable read continuous mode for all devices
+  queryIndex = -1;
+}
+
+/*==============================================================================
+   SETUP()
+  ============================================================================*/
+
+void systemResetCallback()
+{
+  isResetting = true;
+
+  // initialize a defalt state
+  // TODO: option to load config from EEPROM instead of default
+
+  if (isI2CEnabled) {
+    disableI2CPins();
+  }
+
+  for (byte i = 0; i < TOTAL_PORTS; i++) {
+    reportPINs[i] = false;    // by default, reporting off
+    portConfigInputs[i] = 0;  // until activated
+    previousPINs[i] = 0;
+  }
+
+  for (byte i = 0; i < TOTAL_PINS; i++) {
+    // pins with analog capability default to analog input
+    // otherwise, pins default to digital output
+    if (IS_PIN_ANALOG(i)) {
+      // turns off pullup, configures everything
+      setPinModeCallback(i, ANALOG);
+    } else {
+      // sets the output to 0, configures portConfigInputs
+      setPinModeCallback(i, OUTPUT);
+    }
+  }
+  // by default, do not report any analog inputs
+  analogInputsToReport = 0;
+
+
+  /* send digital inputs to set the initial state on the host computer,
+     since once in the loop(), this firmware will only send on change */
+  /*
+    TODO: this can never execute, since no pins default to digital input
+        but it will be needed when/if we support EEPROM stored config
+    for (byte i=0; i < TOTAL_PORTS; i++) {
+    outputPort(i, readPort(i, portConfigInputs[i]), true);
+    }
+  */
+  isResetting = false;
+}
+
+void setup()
+{
+  Firmata.setFirmwareVersion(FIRMATA_MAJOR_VERSION, FIRMATA_MINOR_VERSION);
+
+  Firmata.attach(ANALOG_MESSAGE, analogWriteCallback);
+  Firmata.attach(DIGITAL_MESSAGE, digitalWriteCallback);
+  Firmata.attach(REPORT_ANALOG, reportAnalogCallback);
+  Firmata.attach(REPORT_DIGITAL, reportDigitalCallback);
+  Firmata.attach(SET_PIN_MODE, setPinModeCallback);
+  Firmata.attach(START_SYSEX, sysexCallback);
+  Firmata.attach(SYSTEM_RESET, systemResetCallback);
+
+  // to use a port other than Serial, such as Serial1 on an Arduino Leonardo or Mega,
+  // Call begin(baud) on the alternate serial port and pass it to Firmata to begin like this:
+  // Serial1.begin(57600);
+  // Firmata.begin(Serial1);
+  // then comment out or remove lines 701 - 704 below
+
+  Firmata.begin(57600);
+  while (!Serial) {
+    ; // wait for serial port to connect. Only needed for ATmega32u4-based boards (Leonardo, etc).
+  }
+  systemResetCallback();  // reset to default config
+}
+
+/*==============================================================================
+   LOOP()
+  ============================================================================*/
+void loop()
+{
+  byte pin, analogPin;
+
+  /* DIGITALREAD - as fast as possible, check for changes and output them to the
+     FTDI buffer using Serial.print()  */
+  checkDigitalInputs();
+
+  if (joypad != NULL && joypad->state()) {
+    joypad->loop();
+  }
+
+  irReceiver();
+
+  if (rfidEnable) {
+    if (mfrc522->PICC_IsNewCardPresent() && mfrc522->PICC_ReadCardSerial()) {
+      if (!rfidTouch) {
+        Firmata.write(START_SYSEX);
+        byte len = mfrc522->uid.size;
+        for (byte i = 0; i < len; i++) {
+          Firmata.write(strhex[mfrc522->uid.uidByte[i] >> 4]);
+          Firmata.write(strhex[mfrc522->uid.uidByte[i] & 0x0f]);
+        }
+        Firmata.write(END_SYSEX);
+        rfidTouch = true;
+      }
+      rfidTouchScan = 0;
+    } else {
+      if (rfidTouchScan++ == 2 && rfidTouch) {
+        rfidTouch = false;
+        Firmata.write(START_SYSEX);
+        Firmata.write(0);
+        Firmata.write(END_SYSEX);
+      }
+    }
+  }
+  /* STREAMREAD - processing incoming messagse as soon as possible, while still
+     checking digital inputs.  */
+  while (Firmata.available())
+    Firmata.processInput();
+
+  // TODO - ensure that Stream buffer doesn't go over 60 bytes
+
+  currentMillis = millis();
+  if (currentMillis - previousMillis > samplingInterval) {
+    previousMillis += samplingInterval;
+    /* ANALOGREAD - do all analogReads() at the configured sampling interval */
+    for (pin = 0; pin < TOTAL_PINS; pin++) {
+      if (IS_PIN_ANALOG(pin) && pinConfig[pin] == ANALOG) {
+        analogPin = PIN_TO_ANALOG(pin);
+        if (analogInputsToReport & (1 << analogPin)) {
+          Firmata.sendAnalog(analogPin, analogRead(analogPin));
+        }
+      }
+    }
+    // report i2c data for all device with read continuous mode enabled
+    if (queryIndex > -1) {
+      for (byte i = 0; i < queryIndex + 1; i++) {
+        readAndReportData(query[i].addr, query[i].reg, query[i].bytes);
+      }
+    }
+  }
+}
+
+byte asc2hex(byte * array) {
+  byte b = 0;
+  if (*array >= 0x41 && *array <= 0x66) {
+    b = (*array & 0x0F) + 9 << 4;
+  } else if (*array >= 0x30 && *array <= 0x39) {
+    b = (*array - 0x30) << 4;
+  }
+  array++;
+  if (*array >= 0x41 && *array <= 0x66) {
+    b |= (*array & 0x0F) + 9;
+  } else if (*array >= 0x30 && *array <= 0x39) {
+    b |= (*array - 0x30);
+  }
+  return b;
+}


MakesLEDlightsBlink

MakesLEDlightsBlink

error: pathspec 'FlashingLEDlights.ino' did not match any file(s) known to git

--- FlashingLEDlights.ino
+++ FlashingLEDlights.ino
@@ -0,0 +1,47 @@
+
+// First, we're going to make some variables.
+// This is our "shorthand" that we'll use throughout the program:
+
+int led1 = D0; // Instead of writing D0 over and over again, we'll write led1
+// You'll need to wire an LED to this one to see it blink.
+
+int led2 = D7; // Instead of writing D7 over and over again, we'll write led2
+// This one is the little blue LED on your board. On the Photon it is next to D7, and on the Core it is next to the USB jack.
+
+// Having declared these variables, let's move on to the setup function.
+// The setup function is a standard part of any microcontroller program.
+// It runs only once when the device boots up or is reset.
+
+void setup() {
+
+  // We are going to tell our device that D0 and D7 (which we named led1 and led2 respectively) are going to be output
+  // (That means that we will be sending voltage to them, rather than monitoring voltage that comes from them)
+
+  // It's important you do this here, inside the setup() function rather than outside it or in the loop function.
+
+  pinMode(led1, OUTPUT);
+  pinMode(led2, OUTPUT);
+
+}
+
+// Next we have the loop function, the other essential part of a microcontroller program.
+// This routine gets repeated over and over, as quickly as possible and as many times as possible, after the setup function is called.
+// Note: Code that blocks for too long (like more than 5 seconds), can make weird things happen (like dropping the network connection).  The built-in delay function shown below safely interleaves required background activity, so arbitrarily long delays can safely be done if you need them.
+
+void loop() {
+  // To blink the LED, first we'll turn it on...
+  digitalWrite(led1, HIGH);
+  digitalWrite(led2, HIGH);
+
+  // We'll leave it on for 1 second...
+  delay(1000);
+
+  // Then we'll turn it off...
+  digitalWrite(led1, LOW);
+  digitalWrite(led2, LOW);
+
+  // Wait 1 second...
+  delay(1000);
+
+  // And repeat!
+}


cleaned code

cleaned code

error: pathspec 'SterlitechDroprateTests/SterlitechDroprateTestsClean.ino' did not match any file(s) known to git

--- SterlitechDroprateTests/SterlitechDroprateTestsClean.ino
+++ SterlitechDroprateTests/SterlitechDroprateTestsClean.ino
@@ -0,0 +1,102 @@
+/* Pins in Use:
+     IR Sensor:       2
+     PRessure sensor on A0
+*/
+
+  #define BOUNCE_DURATION 200   // define an appropriate bounce time in ms for your switches
+  int val;                        // variable for reading the serial input
+  volatile unsigned long bounceTime=0;
+  volatile long dropcount;
+  unsigned long drop_num;
+  float flowrate;
+  unsigned long time_int;
+  unsigned long time_set;
+  unsigned long timeold;
+  unsigned long totaldrops;
+  unsigned long totaldropsold;
+  float totalvol;
+  float dropsize;
+  unsigned long steppermax;
+  unsigned long steppermin;
+  const int feedppin=A0;
+  int sfeedp = 0;
+  int feedp = 0;
+
+
+void setup(){
+   Serial.begin(9600);
+   attachInterrupt(0, dropcount_fun, RISING);  //pin 2 tr reciever
+   pinMode(feedppin,INPUT);//pin A0
+   drop_num = 2;
+   dropcount = 3;
+   timeold = 0;
+   totaldrops = 0;
+   totaldropsold = 0;
+   totalvol = 0;
+
+   //make sure this is correct!
+   dropsize = 0.047;//how to find this
+   //make sure this is correct!
+
+   flowrate = 0;
+   pressures();
+   pressures();
+   pressures();
+   pressures();
+   pressures();
+   pressures();
+  Serial.print("Time");Serial.print("\t");
+  Serial.print("PSI");Serial.print("\t");
+  Serial.print("Drops");Serial.print("\t");
+  Serial.print("Vol mL");Serial.print("\t");
+  Serial.println("flowrate mL/min");
+}
+
+ void loop() {
+   if (dropcount >= drop_num) {
+     //Update every 30 counts, increase this for better DPM resolution,
+     //decrease for faster update
+     time_int = ((millis() - timeold));
+     timeold = millis();
+     totaldrops = totaldropsold + dropcount;
+     totaldropsold = totaldrops;
+     totalvol = totaldrops * dropsize; //reports in mL
+     flowrate = dropcount * dropsize / time_int * 1000 * 60; //report in mL per min
+     dropcount = 0;
+     pressures();
+     pressures();
+     pressures();
+     pressures();
+     pressures();
+     //Serial.print("Time: ");
+     Serial.print(timeold);Serial.print("\t");
+     //Serial.print(" Pressure: ");
+     Serial.print(sfeedp);Serial.print("\t");
+     //Serial.print(" Drops: ");
+     Serial.print(totaldrops);Serial.print("\t");
+     //Serial.print(" Volume (mL): ");
+     Serial.print(totalvol);Serial.print("\t");
+     //Serial.print(" FlowRate (mL/min): ");
+     Serial.println(flowrate);}
+      delay(1);
+      if (Serial.available()){//type 0 for reset
+        val = Serial.read();
+      }
+        if (val != 1) {// if zero is sent by serial command it resets
+            totalvol = 0;
+            totaldropsold = 0;
+            Serial.println("RESET");
+        }
+     val=1; // save the new state in our variable
+   }
+ void dropcount_fun(){  // this is the interrupt handler for water drops
+  if(millis() > bounceTime){
+      dropcount++;
+      bounceTime = millis() + BOUNCE_DURATION;  // set whatever bounce time in ms is appropriate
+ }
+}
+void pressures(){//read and average pressure values
+  int junk = analogRead(feedppin);
+  feedp = (analogRead(feedppin)*.7018-54.74)*.868;
+  sfeedp = (sfeedp+feedp)/2;
+}


Added simple sketch to test duration of battery pack.

error: pathspec 'DrainBattery.ino' did not match any file(s) known to git

--- DrainBattery.ino
+++ DrainBattery.ino
@@ -0,0 +1,70 @@
+/**
+ * BatteryDrain.ino
+ *
+ * Copyright (C) 2016 by CommonsLab <info@commonslab.gr>
+ *
+ * Repeatedly request a web page and blink an LED in order to see how long a battery will last.
+ * (Based on LGPLv2 licensed example code of github.com/esp8266/arduino.)
+ */
+
+#include <Arduino.h>
+#include <ESP8266WiFi.h>
+#include <ESP8266WiFiMulti.h>
+#include <ESP8266HTTPClient.h>
+
+ESP8266WiFiMulti MyWiFi;
+
+void setup() {
+    pinMode(D1, OUTPUT);     // Initialize the LED_BUILTIN pin as an output
+
+    Serial.begin(115200);
+
+    for(uint8_t t = 4; t > 0; t--) {
+        Serial.printf("[SETUP] WAIT %d...\n", t);
+        Serial.flush();
+        delay(1000);
+    }
+
+    MyWiFi.addAP("commons|lab", "PASSWORD");
+
+}
+
+void loop() {
+    // wait for WiFi connection
+    if((MyWiFi.run() == WL_CONNECTED)) {
+
+        digitalWrite(D1, HIGH);   // Turn the LED on
+
+        HTTPClient http;
+
+        Serial.print("[HTTP] begin...\n");
+        // configure traged server and url
+        //http.begin("https://192.168.1.12/test.html", "7a 9c f4 db 40 d3 62 5a 6e 21 bc 5c cc 66 c8 3e a1 45 59 38"); //HTTPS
+        //http.begin("http://192.168.1.12/test.html"); //HTTP
+        http.begin("http://etherpad.commonslab.gr/"); //HTTP
+
+        Serial.print("[HTTP] GET...\n");
+        // start connection and send HTTP header
+        int httpCode = http.GET();
+
+        // httpCode will be negative on error
+        if(httpCode > 0) {
+            // HTTP header has been send and Server response header has been handled
+            Serial.printf("[HTTP] GET... code: %d\n", httpCode);
+
+            // file found at server
+            if(httpCode == 503) {
+                String payload = http.getString();
+                Serial.println(payload);
+            }
+        } else {
+            Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
+        }
+
+        http.end();
+    }
+    digitalWrite(D1, LOW);  // Turn the LED off
+
+    delay(1000);
+}
+


Create MIDI_test_v1.ino

Create MIDI_test_v1.ino

error: pathspec 'MIDI_test_v1.ino' did not match any file(s) known to git

--- MIDI_test_v1.ino
+++ MIDI_test_v1.ino
@@ -0,0 +1,131 @@
+
+//***************************************************************
+// Basic setup for testing out receiving MIDI on a Teensy 3.2
+//
+// Wiring is like this:
+//   https://i.imgur.com/d4QRXhe.jpg
+//
+// Marc Miller, June 2018
+//***************************************************************
+
+#include <MIDI.h> // Add Midi Library
+MIDI_CREATE_DEFAULT_INSTANCE();
+
+#include "FastLED.h"  // Add FastLED library
+#define LED_TYPE WS2812B
+#define COLOR_ORDER GRB  // GRB for Neopixel
+#define DATA_PIN 11
+#define NUM_LEDS 12
+CRGB leds[NUM_LEDS];
+#define BRIGHTNESS 32
+
+int led = 13;  // pin for MCU's onboard LED
+
+uint8_t count;
+uint8_t hue;
+
+
+//---------------------------------------------------------------
+void blinkyblink() {
+  digitalWrite(led, HIGH);  delay(50);
+  digitalWrite(led, LOW);   delay(30);
+  digitalWrite(led, HIGH);  delay(20);
+  digitalWrite(led, LOW);
+}
+
+
+//---------------------------------------------------------------
+void solidFill(uint16_t color) {
+  if (color > 255) {
+    fill_solid( leds, NUM_LEDS, CHSV(random8(),255,255) );  //pick random color
+  } else {
+    color = (uint8_t)color;  //convert 16bit to 8bit
+    fill_solid( leds, NUM_LEDS, CHSV(color,255,255) );  //fill with sent hue
+  }
+  FastLED.show();
+}
+
+void spinColor(uint8_t color) {
+  EVERY_N_MILLISECONDS(120) {
+    fadeToBlackBy(leds, NUM_LEDS, 100);
+    leds[count] = CHSV(color, random8(150,255), 255);
+    FastLED.show();
+    count++;
+    if (count == NUM_LEDS) { count = 0; }
+  }
+}
+
+void clearAll() {  // turn off all pixels
+  FastLED.clear();
+  FastLED.show();
+  blinkyblink();
+}
+
+
+//---------------------------------------------------------------
+void HandleNoteOn(byte channel, byte pitch, byte velocity){
+  if (velocity > 0){
+    // check for specific notes
+    if(pitch <= 50) { clearAll(); }
+    else if(pitch == 51) { solidFill(888); }
+    else if(pitch == 52) { solidFill(888); }
+    else if(pitch == 53) { solidFill(hue); }
+    else if(pitch == 54) { spinColor(0); }
+    else if(pitch == 55) { solidFill(hue); }
+    else if(pitch == 56) { spinColor(96); }
+    else if(pitch == 57) { solidFill(hue); }
+    else if(pitch == 58) { spinColor(160); }
+    else if(pitch == 59) { solidFill(0); }
+    else if(pitch == 60) { solidFill(96); }
+    else if(pitch == 61) { clearAll(); }
+    else if(pitch == 62) { solidFill(160); }
+    else if(pitch == 63) { solidFill(888); }
+    else if(pitch == 64) { solidFill(888); }
+    else if(pitch == 65) {
+      //if (velocity > 128) {
+      //  try something extra here based on velocity;
+      //}
+      solidFill(888);
+    }
+    else if(pitch >= 66) { clearAll(); }
+  }
+}
+
+
+//---------------------------------------------------------------
+void setup(){
+  Serial1.begin(31250);  //using MIDI baud rate but could be something faster
+  delay(1000);
+  pinMode(led, OUTPUT);
+  blinkyblink();  //check onboard LED
+
+  FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
+  FastLED.setBrightness(BRIGHTNESS);
+  fill_solid(leds, NUM_LEDS, CRGB(32,0,0)); FastLED.show(); delay(333);
+  fill_solid(leds, NUM_LEDS, CRGB(0,32,0)); FastLED.show(); delay(333);
+  fill_solid(leds, NUM_LEDS, CRGB(0,0,32)); FastLED.show(); delay(333);
+  FastLED.clear();
+  FastLED.show();
+
+  MIDI.begin(MIDI_CHANNEL_OMNI);
+  MIDI.setHandleNoteOn(HandleNoteOn); // Initiates HandleNoteOn function
+
+  blinkyblink(); delay(100); blinkyblink(); delay(100); blinkyblink();
+  Serial.println("Setup done. \n");
+}//end_setup
+
+
+//---------------------------------------------------------------
+void loop(){
+  MIDI.read();  // Tells Arduino to start listening for midi info on the serial RX pin.
+
+  EVERY_N_MILLISECONDS(30) {
+    hue++;
+  }
+
+}//end_main_loop
+
+
+//---------------------------------------------------------------
+
+


Sensorscript

Sensorscript

Sensorscript

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/onordbo/mood-cloud.git/'


Uploaded robot controller code

Uploaded robot controller code

Stephen's current state controller.

error: pathspec 'ServoController.ino' did not match any file(s) known to git

--- ServoController.ino
+++ ServoController.ino
@@ -0,0 +1,584 @@
+/* Servo automation
+
+ created 2014
+ by Jeff Moore
+ */
+
+//#include  <LiquidCrystal.h>
+
+  // constants won't change. Used here to set pin numbers:
+  // Pin 13: Arduino has an LED connected on pin 13
+  // Pin 13: Teensy 3.0 has the LED on pin 13
+const int ledPin =  13;      // the number of the LED pin
+const int lookEnablePin = 19;
+const int pwmPin = 20;
+const int jawPin = 21;
+const int motionPin = 11;
+const int motionModulus = 100;
+int motionTimer=0;
+//const int motionDetectedPin = 10;
+
+const int ledRedPin = 3;
+const int ledGreenPin = 4;
+const int ledBluePin = 5;
+
+const byte soundBankPin[4] = {7,8,9,10};
+#define SOUNDBANK0 3
+#define SOUNDBANK1 3
+#define SOUNDBANK2 3
+#define SOUNDBANK3 3
+const int numSoundPins = 4;
+
+bool lookEnabled = true;
+bool jawOpen = true;
+bool chatterOn = false;
+
+enum LookMode {
+  Pause =      0,
+  SlowLook =   1,
+  Neutral =    2,
+  Shake =      3,
+  RandomLook = 4,
+  FastShake =  5,
+  LeftRight =  6
+} lookMode, previousMode;
+
+typedef enum LcdPinEnum {
+  Pin8_RS =     9,
+  Pin9_Enable = 10,
+  Pin4_DB4 =    16,
+  Pin5_DB5 =    15,
+  Pin6_DB6 =    19,
+  Pin7_DB7 =    22
+} LcdPinEnum;
+//LiquidCrystal lcd(Pin8_RS, Pin9_Enable, Pin4_DB4, Pin5_DB5, Pin6_DB6, Pin7_DB7);
+
+const byte colors[9][3] = {
+  { 0,   0,   0   },         // black
+  { 180, 255, 255 },         // white
+  { 255, 0,   0   },         // red
+  { 0,   255, 0   },         // green
+  { 0,   0,   255 },         // blue
+  { 140, 255, 0   },         // yellow
+  { 140, 0,   255 },         // purple
+  { 0,   255, 255 },         // cyan
+  { 200, 240, 0   }          // orange
+};
+
+enum ColorMap {
+  Black = 0,
+  White = 1,
+  Red = 2,
+  Green = 3,
+  Blue = 4,
+  Yellow = 5,
+  Purple = 6,
+  Cyan = 7,
+  Orange = 8
+} colorMap;
+
+const int nColors = 9;
+
+byte color[3] = {32, 64, 0};
+byte targetColor[3] = {32, 64, 0};
+
+// Frequency of PWM signal
+const int f0 = 196;
+const double T0Us = 1000000 / (255*f0);
+
+// Min/max guardrails for PWM
+// Converted to pulse width (normalized) 0-255
+const int tMinUs = 900;  // min pulse width uS
+const int tMaxUs = 2100; // max pulse width uS
+const int tNeutral = 1500;
+
+const int posMax = tMaxUs / T0Us;
+const int posMin = tMinUs / T0Us;
+//const int posNeutral = (255*f0)/666;
+//const int posNeutral = (posMax+posMin)/2;
+const int posNeutral = tNeutral / T0Us;
+
+const int jawNeutralPos = tNeutral / T0Us;
+const int jawOpenPos = 1100 / T0Us;
+const int jawClosedPos = 1600 / T0Us;
+
+int chatterWaitMs = 50;
+
+const int delta = 300;
+
+int timerModulus = 50;
+int ledModulus = 5;
+int motionCooldown = 0;
+int motionDetectCounter = 0;
+const int cooldownTimeMs = 750;
+
+int agitation = 0;
+int cyclesOnState = 0;
+int cyclesOnPreviousState = 0;
+int minPauseCycles = 5;
+
+typedef enum KeypadButtonEnum {
+  BtnNone =  0,
+  BtnUp   =  1,
+  BtnDown =  2,
+  BtnLeft =  3,
+  BtnRight = 4,
+  BtnSelect= 5
+} KeypadButton;
+
+KeypadButton keypadButton;
+
+// Counter
+int pwmCounter = 0;
+int duration = 2;
+int dutyCycle = 0;
+
+int pauseCounter = 0;
+
+int position = (posMin+posMax)/2;
+int newPos = position;
+
+int slowCounter = 0;
+
+boolean goLeft = 0;
+
+boolean modeUp = 0;
+int ledState = LOW;             // ledState used to set the LED
+long previousMillis = 0;        // will store last time LED was updated
+
+// the follow variables is a long because the time, measured in miliseconds,
+// will quickly become a bigger number than can be stored in an int.
+long interval = 75;           // interval at which to blink (milliseconds)
+
+void setColorTo(byte *toRgb, const byte *fromRgb, const byte divider = 1);
+void setColorRgb(const byte *rgb, const byte divider = 1);
+
+void setup() {
+
+  //delay(2000);
+  pinMode(ledPin, OUTPUT);
+  pinMode(pwmPin, OUTPUT);
+  pinMode(jawPin, OUTPUT);
+  //pinMode(extLedPin, OUTPUT);
+  pinMode(motionPin, INPUT);
+  pinMode(lookEnablePin, INPUT);
+  //pinMode(motionDetectedPin, OUTPUT);
+  pinMode(ledRedPin, OUTPUT);
+  pinMode(ledGreenPin, OUTPUT);
+  pinMode(ledBluePin, OUTPUT);
+
+  analogWriteFrequency(pwmPin, f0);
+  analogWriteFrequency(jawPin, f0);
+  //digitalWrite(extLedPin, HIGH);
+
+  initSoundPins();
+
+  Serial.print("Min: ");
+  Serial.println(posMin);
+  Serial.print("Max: ");
+  Serial.println(posMax);
+  Serial.println("XXXX");
+
+  lookMode = SlowLook;
+  previousMode = SlowLook;
+  changeModeTo( SlowLook );
+}
+
+void initSoundPins()
+{
+  for (int i = 0; i < numSoundPins; i++)
+  {
+    pinMode(soundBankPin[i], OUTPUT);
+    digitalWrite(soundBankPin[i],HIGH);
+  }
+}
+
+void triggerSound(int soundBank)
+{
+  Serial.print("Triggering bank #");
+  Serial.print(soundBank);
+  Serial.print(" on pin ");
+  Serial.println(soundBankPin[soundBank]);
+  digitalWrite(soundBankPin[soundBank],LOW);
+  delay(200);
+  digitalWrite(soundBankPin[soundBank],HIGH);
+}
+
+void ledBlink()
+{
+  if (ledState == LOW)
+  {
+    ledState = HIGH;
+  }
+  else
+  {
+    ledState = LOW;
+  }
+}
+
+void pauseLook(int nCycles)
+{
+   minPauseCycles = nCycles;
+   changeModeTo(Pause);
+}
+
+void randomizeLookTarget()
+{
+    newPos = posMin + random(1+posMax-posMin);
+    Serial.print("[TGT:");
+    Serial.print(newPos);
+    Serial.print("]");
+}
+
+void steer()
+{
+  if ( position == newPos )
+  {
+    pauseLook(5+random(5));
+    //if (previousMode == RandomLook && random(4) < 1) chatterOn = true;
+  }
+}
+
+void steerLeftRight(int slowCounterDelay)
+{
+  if (slowCounter++ >= slowCounterDelay)
+  {
+    //if ( random(10) < 1) pauseLook(random(20));
+    if (goLeft)
+    {
+      //newPos = posMin;
+      newPos = posNeutral + delta;
+      goLeft = false;
+    } else {
+      //newPos = posMax;
+      newPos = posNeutral - delta;
+      goLeft = true;
+    }
+    slowCounter = 0;
+  }
+}
+
+void shake()
+{
+   if (slowCounter++ >= 1)
+   {
+      if (goLeft)
+      {
+        newPos = posNeutral-delta;
+        slowCounter = 0;
+        goLeft = false;
+      } else {
+        newPos = posNeutral+delta;
+        goLeft = true;
+      }
+      slowCounter = 0;
+   }
+}
+
+void steerNeutral()
+{
+  newPos = posNeutral;
+}
+
+void changeModeTo(int newModeInt)
+{
+  cyclesOnPreviousState = cyclesOnState;
+  cyclesOnState = 0;
+  jawStill();
+
+  LookMode newMode = (LookMode) newModeInt;
+  previousMode = lookMode;
+  lookMode = newMode;
+
+  Serial.flush();
+  Serial.println("");
+  Serial.print("[PrMode:");
+  Serial.print(previousMode);
+  Serial.print("]");
+  Serial.print("[LkMode:");
+  Serial.print(lookMode);
+  Serial.println("]");
+  Serial.flush();
+
+  //switch (lookMode)
+  switch (newModeInt)
+  {
+    case Pause:
+       timerModulus = 40;
+       setColorTo( targetColor, targetColor, 3);
+       break;
+    case SlowLook:
+       timerModulus = 40;
+       agitation=0;
+       setColorTo( targetColor, colors[ random(nColors-2)+1 ], 16 );
+       randomizeLookTarget();
+       break;
+    case RandomLook:
+       timerModulus = 15;
+       if (random(3) < 1) triggerSound(SOUNDBANK2);
+       setColorTo( targetColor, colors[ random(nColors-2)+1 ], 3 );
+       randomizeLookTarget();
+       break;
+    case LeftRight:
+       timerModulus = 20;
+       triggerSound(SOUNDBANK1);
+       setColorTo( targetColor, colors[ Orange ], 2 );
+       break;
+    case FastShake:
+       timerModulus = 10;
+       triggerSound(SOUNDBANK3);
+       setColorTo( targetColor, colors[ Cyan ], 1 );
+       chatterOn = true;
+       break;
+    case Shake:
+       timerModulus = 25;
+       triggerSound(SOUNDBANK1);
+       setColorTo( targetColor, colors[ random(nColors-2)+1 ], 3 );
+       break;
+    case Neutral:
+       timerModulus = 15;
+       setColorTo( targetColor, colors[ Purple ] , 4);
+       triggerSound(SOUNDBANK0);
+       //steerNeutral();
+       break;
+    default:
+       setColorTo( targetColor, colors[ Orange ], 16);
+
+  }
+}
+
+void updateState()
+{
+    switch (lookMode)
+    {
+      case SlowLook:
+          steer();
+          break;
+      case RandomLook:
+          if ( (cyclesOnState > 15) && random(2)<1 ) changeModeTo(SlowLook);
+          steer();
+          break;
+      case LeftRight:
+          steerLeftRight(1);
+          if ( cyclesOnState > 10 && random(10)< 1) changeModeTo(RandomLook);
+          break;
+      case FastShake:
+          steerLeftRight(0);
+          if ( cyclesOnState > 8 && random(10) < 1) changeModeTo(RandomLook);
+          break;
+      case Shake:
+          steerLeftRight(0);
+          if ( cyclesOnState > 15 && random(10)< 1) changeModeTo(SlowLook);
+          break;
+      case Pause:
+          //Serial.print(".");
+          if ( previousMode == Pause ) previousMode = SlowLook;
+          if ( cyclesOnState > minPauseCycles)
+          {
+            int tmpPrevCyclesOnState = cyclesOnPreviousState;
+            changeModeTo(previousMode);
+            cyclesOnState = tmpPrevCyclesOnState;
+          }
+          break;
+      case Neutral:
+          steerNeutral();
+          if ( cyclesOnState > 10 && random(10) < 1 ) changeModeTo(SlowLook);
+          break;
+      default:
+          changeModeTo(SlowLook);
+          break;
+    }
+
+    cyclesOnState++;
+}
+
+void checkForMotion()
+{
+  if ((++motionTimer)%motionModulus !=0) return;
+  motionTimer = 0;
+  if (motionCooldown > 0)
+  {
+    motionCooldown -= motionModulus;
+    //motionCooldown--;
+    if (motionCooldown<=0)
+    {
+        if (digitalRead(motionPin)==LOW)
+        {
+          Serial.println("Cooldown reached - looking for motion...");
+        } else {
+          motionCooldown = 2*motionModulus; // wait another X ms
+        }
+    }
+    return;
+  }
+  if (digitalRead(motionPin)==HIGH)
+  {
+    Serial.println("Motion detected!");
+    motionDetectCounter++;
+    Serial.print("MotionCounter=");
+    Serial.println(motionDetectCounter);
+    motionCooldown = cooldownTimeMs;
+    //Serial.println("Neutral / min / max");
+    //Serial.println(posNeutral);
+    //Serial.println(posMin);
+    //Serial.println(posMax);
+
+    if (lookMode < FastShake)
+    {
+      if (lookMode == Pause) changeModeTo(previousMode+1);
+      else changeModeTo(lookMode+1);
+
+      if (lookMode == FastShake)
+      {
+        agitation++;
+        Serial.print("Agitation : ");
+        Serial.println(agitation);
+        if (agitation > 3)
+        {
+          Serial.println("Calm down, monkey.");
+          changeModeTo(SlowLook);
+          agitation=0;
+        }
+      }
+    }
+  }
+}
+
+void pwmControl()
+{
+   dutyCycle++;
+   if ( dutyCycle % 256 == 0 ) updateState();
+
+   //Serial.print("blook");
+
+   if ( dutyCycle % timerModulus == 0)
+   {
+     //dutyCycle = 0;
+     if (position < (newPos))
+     {
+       position++;
+       analogWrite(pwmPin, position);
+       //Serial.print("+");
+     }
+     else if (position > (newPos))
+     {
+       position--;
+       analogWrite(pwmPin, position);
+       //Serial.print("-");
+     } else
+     {
+       analogWrite(pwmPin, 0);
+     }
+   }
+}
+
+void setColor(byte red, byte green, byte blue, byte divider)
+{
+   analogWrite(ledRedPin, (char) (red/divider));
+   analogWrite(ledGreenPin, (char) (green/divider));
+   analogWrite(ledBluePin, (char) (blue/divider));
+}
+
+void setColorRgb(const byte *rgb, byte divider)
+{
+  setColor(rgb[0], rgb[1], rgb[2], divider);
+}
+
+void setColorTo(byte *toRgb, const byte *fromRgb, const byte divider)
+{
+    toRgb[0] = fromRgb[0]/divider;
+    toRgb[1] = fromRgb[1]/divider;
+    toRgb[2] = fromRgb[2]/divider;
+
+    // St. Patty's
+    toRgb[1] = 255/divider;
+}
+
+boolean rgbEqual(const byte *rgb1, const byte *rgb2)
+{
+    return ( rgb1[0] == rgb2[0] &&
+             rgb1[1] == rgb2[1] &&
+             rgb1[2] == rgb2[2] );
+}
+
+void adjustColor()
+{
+    if ( color[0] < targetColor[0] ) color[0]++;
+    if ( color[0] > targetColor[0] ) color[0]--;
+    if ( color[1] < targetColor[1] ) color[1]++;
+    if ( color[1] > targetColor[1] ) color[1]--;
+    if ( color[2] < targetColor[2] ) color[2]++;
+    if ( color[2] > targetColor[2] ) color[2]--;
+}
+
+void chaseColors()
+{
+    if ( (dutyCycle % (50) == 0) &&
+        !rgbEqual(color, targetColor) )
+    {
+        adjustColor();
+        setColorRgb(color);
+    } else { }
+}
+
+void checkLookEnablePinState()
+{
+  if ( dutyCycle % 10 != 0) return;
+  int pinState = digitalRead(lookEnablePin);
+  if ( lookEnabled == true && pinState == LOW)
+  {
+    lookEnabled = false;
+    Serial.println("Look mode deactivated.");
+  }
+  if ( lookEnabled == false && pinState == HIGH)
+  {
+    lookEnabled = true;
+    Serial.println("Look mode enabled.");
+  }
+}
+
+
+void jawStill()
+{
+  analogWrite(jawPin, 0);
+  chatterOn = false;
+}
+
+void chatter()
+{
+  if (!chatterOn) return;
+  //if (chatterWaitMs < 500) analogWrite(jawPin,0);
+
+  if (chatterWaitMs-- < 1)
+  {
+      //chatterWaitMs = 70+random(10);
+      chatterWaitMs = 200+random(50);
+      //Serial.println(chatterWaitMs);
+      if (jawOpen)
+      {
+        //Serial.println("Open");
+        analogWrite(jawPin, jawClosedPos);
+        //analogWrite(jawPin,jawNeutralPos);
+        jawOpen = false;
+      } else {
+        //Serial.println("Close");
+        analogWrite(jawPin, jawOpenPos);
+        jawOpen = true;
+      }
+      //Serial.flush();
+  }
+}
+
+
+// Main control loop
+void loop()
+{
+  delay(1);
+  pwmControl();
+  chatter();
+  checkForMotion();
+  chaseColors();
+  //checkLookEnablePinState();
+}
+
+


Add 4 camera time elapse demo low power mode

error: pathspec 'ArduCAM/examples/mini/ArduCAM_Mini_2MP_4Cams_TimeElapse2SD_LowPower/ArduCAM_Mini_2MP_4Cams_TimeElapse2SD_LowPower.ino' did not match any file(s) known to git

--- ArduCAM/examples/mini/ArduCAM_Mini_2MP_4Cams_TimeElapse2SD_LowPower/ArduCAM_Mini_2MP_4Cams_TimeElapse2SD_LowPower.ino
+++ ArduCAM/examples/mini/ArduCAM_Mini_2MP_4Cams_TimeElapse2SD_LowPower/ArduCAM_Mini_2MP_4Cams_TimeElapse2SD_LowPower.ino
@@ -0,0 +1,274 @@
+// ArduCAM demo (C)2015 Lee
+// web: http://www.ArduCAM.com
+// This program is a demo of how to use most of the functions
+// of the library with a supported camera modules, and can run on any Arduino platform.
+//
+// This demo was made for ArduCAM Mini 2MP camera module.
+// It will run 4 ArduCAM Mini 2MP moduels in low power mode and take time elapse images every 5 seconds.
+// The demo sketch will do the following tasks:
+// 1. Set the sensor to JPEG mode and power down all the cameras.
+// 2. Power up all cameras and capture 4 image from 4 cameras simultaneously and buffer the image to FIFO, then power down all the cameras after capture completion.
+// 3. Store the image to Micro SD/TF card with JPEG format in sequential.
+// 4. Resolution can be changed by myCAM.set_JPEG_size() function.
+// This program requires the ArduCAM V3.4.0 (or later) library and ArduCAM Mini 2MP shield
+// and use Arduino IDE 1.5.2 compiler or above
+#include <Wire.h>
+#include <ArduCAM.h>
+#include <SPI.h>
+#include <SD.h>///////////
+#include "memorysaver.h"
+/////////////////////////////////
+#define SD_CS 9
+#if defined(__arm__)
+#include <itoa.h>
+#endif
+/////////////////////////////////
+const int CS1 = 4;
+const int CS2 = 5;
+const int CS3 = 6;
+const int CS4 = 7;
+bool cam1 = true, cam2 = true, cam3 = true, cam4 = true;
+
+/////////////////////////////////
+ArduCAM myCAM1(OV2640, CS1);
+ArduCAM myCAM2(OV2640, CS2);
+ArduCAM myCAM3(OV2640, CS3);
+ArduCAM myCAM4(OV2640, CS4);
+
+void setup() {
+  // put your setup code here, to run once:
+  uint8_t vid, pid;
+  uint8_t temp;
+#if defined (__AVR__)
+  Wire.begin();
+#endif
+#if defined(__arm__)
+  Wire1.begin();
+#endif
+  Serial.begin(115200);
+  Serial.println("ArduCAM Start!");
+
+  // set the SPI_CS as an output:
+  pinMode(CS1, OUTPUT);
+  pinMode(CS2, OUTPUT);
+  pinMode(CS3, OUTPUT);
+  pinMode(CS4, OUTPUT);
+
+  // initialize SPI:
+  SPI.begin();
+  //Check if the ArduCAM SPI bus is OK
+  myCAM1.write_reg(ARDUCHIP_TEST1, 0x55);
+  temp = myCAM1.read_reg(ARDUCHIP_TEST1);
+  if (temp != 0x55)
+  {
+    Serial.println("SPI1 interface Error!");
+    cam1 = false;
+    //while(1);
+  }
+
+  myCAM2.write_reg(ARDUCHIP_TEST1, 0x55);
+  temp = myCAM2.read_reg(ARDUCHIP_TEST1);
+  //Serial.println(temp);
+  if (temp != 0x55)
+  {
+    Serial.println("SPI2 interface Error!");
+    cam2 = false;
+    //while(1);
+  }
+
+  myCAM3.write_reg(ARDUCHIP_TEST1, 0x55);
+  temp = myCAM3.read_reg(ARDUCHIP_TEST1);
+  //Serial.println(temp);
+  if (temp != 0x55)
+  {
+    Serial.println("SPI3 interface Error!");
+    cam3 = false;
+    //while(1);
+  }
+
+  myCAM4.write_reg(ARDUCHIP_TEST1, 0x55);
+  temp = myCAM4.read_reg(ARDUCHIP_TEST1);
+  //Serial.println(temp);
+  if (temp != 0x55)
+  {
+    Serial.println("SPI4 interface Error!");
+    cam4 = false;
+    //while(1);
+  }
+
+  //Check if the camera module type is OV2640
+  myCAM1.wrSensorReg8_8(0xFF, 0x01);
+  myCAM1.rdSensorReg8_8(OV2640_CHIPID_HIGH, &vid);
+  myCAM1.rdSensorReg8_8(OV2640_CHIPID_LOW, &pid);
+
+  if ((vid != 0x26) || (pid != 0x42))
+    Serial.println("Can't find OV2640 module!");
+  else
+    Serial.println("OV2640 detected");
+
+  //Change to JPEG capture mode and initialize the OV2640 module
+  myCAM1.set_format(JPEG);
+  myCAM1.InitCAM();
+  myCAM1.OV2640_set_JPEG_size(OV2640_1600x1200);
+  myCAM1.clear_fifo_flag();
+  myCAM1.write_reg(ARDUCHIP_FRAMES, 0x00);
+
+  myCAM1.set_bit(ARDUCHIP_GPIO,GPIO_PWDN_MASK);//enable low power
+  myCAM2.set_bit(ARDUCHIP_GPIO,GPIO_PWDN_MASK);//enable low power
+  myCAM3.set_bit(ARDUCHIP_GPIO,GPIO_PWDN_MASK);//enable low power
+  myCAM4.set_bit(ARDUCHIP_GPIO,GPIO_PWDN_MASK);//enable low power
+
+  ////////////////////////////////////////////////////
+  if (!SD.begin(SD_CS))
+  {
+    //while (1);		//If failed, stop here
+    Serial.println("SD Card Error");
+  }
+  else
+    Serial.println("SD Card detected!");
+  ////////////////////////////////////////////////////
+}
+
+void loop() {
+  // put your main code here, to run repeatedly:
+  uint8_t temp, temp_last;
+  uint8_t start_capture = 0;
+
+  delay(4000);
+  myCAM1.clear_bit(ARDUCHIP_GPIO,GPIO_PWDN_MASK); //Power up Camera
+  myCAM2.clear_bit(ARDUCHIP_GPIO,GPIO_PWDN_MASK); //Power up Camera
+  myCAM3.clear_bit(ARDUCHIP_GPIO,GPIO_PWDN_MASK); //Power up Camera
+  myCAM4.clear_bit(ARDUCHIP_GPIO,GPIO_PWDN_MASK); //Power up Camera
+  delay(1000);
+  myCAM1.flush_fifo();
+  myCAM2.flush_fifo();
+  myCAM3.flush_fifo();
+  myCAM4.flush_fifo();
+  //Clear the capture done flag
+  myCAM1.clear_fifo_flag();
+  //Start capture
+  myCAM1.start_capture();
+  //Clear the capture done flag
+  myCAM2.clear_fifo_flag();
+  //Start capture
+  myCAM2.start_capture();
+  //Clear the capture done flag
+  myCAM3.clear_fifo_flag();
+  //Start capture
+  myCAM3.start_capture();
+  //Clear the capture done flag
+  myCAM4.clear_fifo_flag();
+  //Start capture
+  myCAM4.start_capture();
+
+
+  while (!myCAM1.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK) && cam1);
+  while (!myCAM2.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK) && cam2);
+  while (!myCAM3.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK) && cam3);
+  while (!myCAM4.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK) && cam4);
+
+  myCAM1.set_bit(ARDUCHIP_GPIO,GPIO_PWDN_MASK);//enable low power
+  myCAM2.set_bit(ARDUCHIP_GPIO,GPIO_PWDN_MASK);//enable low power
+  myCAM3.set_bit(ARDUCHIP_GPIO,GPIO_PWDN_MASK);//enable low power
+  myCAM4.set_bit(ARDUCHIP_GPIO,GPIO_PWDN_MASK);//enable low power
+
+  if (cam1 == true)
+  {
+    Serial.println("CAM1 Capture Done!");
+    read_fifo_burst(myCAM1);
+    //Clear the capture done flag
+    myCAM1.clear_fifo_flag();
+  }
+
+  if (cam2 == true)
+  {
+    Serial.println("CAM2 Capture Done!");
+    read_fifo_burst(myCAM2);
+    //Clear the capture done flag
+    myCAM2.clear_fifo_flag();
+  }
+
+  if (cam3 == true)
+  {
+    Serial.println("CAM3 Capture Done!");
+    read_fifo_burst(myCAM3);
+    //Clear the capture done flag
+    myCAM3.clear_fifo_flag();
+  }
+
+  if (cam4 == true)
+  {
+    Serial.println("CAM4 Capture Done!");
+    read_fifo_burst(myCAM4);
+    //Clear the capture done flag
+    myCAM4.clear_fifo_flag();
+  }
+}
+
+uint8_t read_fifo_burst(ArduCAM myCAM)
+{
+  uint8_t temp, temp_last;
+  uint32_t length = 0;
+  //////////////////////////////////////////
+  char str[8];
+  File outFile;
+  byte buf[256];
+  static int k = 0;
+  static int i = 0;
+  //////////////////////////////////////////
+  ////////////////////////////////////////////////////
+  //Construct a file name
+  k = k + 1;
+  itoa(k, str, 10);
+  strcat(str, ".jpg");
+  //Open the new file
+  outFile = SD.open(str, O_WRITE | O_CREAT | O_TRUNC);
+  if (! outFile)
+  {
+    Serial.println("open file failed");
+    //return;
+  }
+
+  //////////////////////////////////////////////////
+  length = myCAM.read_fifo_length();
+  if (length >= 393216) //384 kb
+  {
+    Serial.println("Not found the end.");
+    return 0;
+  }
+  //Serial.println(length);
+  i = 0;
+  myCAM.CS_LOW();
+  myCAM.set_fifo_burst();
+  SPI.transfer(0x00);//First byte is 0xC0 ,not 0xff
+
+  ////////////////////////////////////////////////////////
+  while ( (temp != 0xD9) | (temp_last != 0xFF))
+  {
+    temp_last = temp;
+    temp = SPI.transfer(0x00);
+
+    //Write image data to buffer if not full
+    if (i < 256)
+      buf[i++] = temp;
+    else
+    {
+      //Write 256 bytes image data to file
+      myCAM.CS_HIGH();
+      outFile.write(buf, 256);
+      i = 0;
+      buf[i++] = temp;
+      myCAM.CS_LOW();
+      myCAM.set_fifo_burst();
+    }
+  }
+  //Write the remain bytes in the buffer
+  if (i > 0)
+  {
+    myCAM.CS_HIGH();
+    outFile.write(buf, i);
+  }
+  //Close the file
+  outFile.close();
+  ///////////////////////////////////////////////////////
+}


Add OV5642 2592x1944 RAW example

Add OV5642 2592x1944 RAW example

error: pathspec 'ArduCAM/examples/mini/ArduCAM_Mini_5MP_Plus_OV5642_RAW/ArduCAM_Mini_5MP_Plus_OV5642_RAW.ino' did not match any file(s) known to git

--- ArduCAM/examples/mini/ArduCAM_Mini_5MP_Plus_OV5642_RAW/ArduCAM_Mini_5MP_Plus_OV5642_RAW.ino
+++ ArduCAM/examples/mini/ArduCAM_Mini_5MP_Plus_OV5642_RAW/ArduCAM_Mini_5MP_Plus_OV5642_RAW.ino
@@ -0,0 +1,141 @@
+// ArduCAM demo (C)2017 Lee
+// Web: http://www.ArduCAM.com
+// This program is a demo of how to capture image in RAW format
+// 1. Capture and buffer the image to FIFO every 5 seconds
+// 2. Store the image to Micro SD/TF card with RAW format.
+//3. You can change the resolution by change the "resolution = OV5642_640x480"
+// This program requires the ArduCAM V4.0.0 (or above) library and ArduCAM shield V2
+// and use Arduino IDE 1.6.8 compiler or above
+#include <Wire.h>
+#include <ArduCAM.h>
+#include <SPI.h>
+#include <SD.h>
+#include "memorysaver.h"
+//This demo can only work on OV5640_MINI_5MP_PLUS or OV5642_MINI_5MP_PLUS platform.
+#if !(defined (OV5642_MINI_5MP_PLUS))
+#error Please select the hardware platform and camera module in the ../libraries/ArduCAM/memorysaver.h file
+#endif
+#define   FRAMES_NUM    0x00
+// set pin 7 as the slave select for the digital pot:
+const int CS = 7;
+#define SD_CS 9
+bool is_header = false;
+int total_time = 0;
+uint8_t resolution = OV5642_2592x1944;
+uint32_t line,column;
+  ArduCAM myCAM(OV5642, CS);
+uint8_t saveRAW(void);
+void setup() {
+// put your setup code here, to run once:
+uint8_t vid, pid;
+uint8_t temp ;
+
+#if defined(__SAM3X8E__)
+  Wire1.begin();
+#else
+  Wire.begin();
+#endif
+Serial.begin(115200);
+Serial.println(F("ArduCAM Start!"));
+// set the CS as an output:
+pinMode(CS, OUTPUT);
+// initialize SPI:
+SPI.begin();
+while(1){
+  //Check if the ArduCAM SPI bus is OK
+  myCAM.write_reg(ARDUCHIP_TEST1, 0x55);
+  temp = myCAM.read_reg(ARDUCHIP_TEST1);
+  if(temp != 0x55)
+  {
+    Serial.println(F("SPI interface Error!"));
+    delay(1000);continue;
+  }else{
+    Serial.println(F("SPI interface OK."));break;
+  }
+}
+
+while(1){
+  //Check if the camera module type is OV5642
+  myCAM.rdSensorReg16_8(OV5642_CHIPID_HIGH, &vid);
+  myCAM.rdSensorReg16_8(OV5642_CHIPID_LOW, &pid);
+  if ((vid != 0x56) || (pid != 0x42)){
+    Serial.println(F("Can't find OV5642 module!"));
+    delay(1000);continue;
+  }else{
+    Serial.println(F("OV5642 detected."));break;
+  }
+}
+//Initialize SD Card
+while(!SD.begin(SD_CS))
+{
+  Serial.println(F("SD Card Error!"));delay(1000);
+}
+Serial.println(F("SD Card detected."));
+//Change to JPEG capture mode and initialize the OV5640 module
+myCAM.set_format(RAW);
+myCAM.InitCAM();
+myCAM.set_bit(ARDUCHIP_TIM, VSYNC_LEVEL_MASK);
+}
+
+void loop() {
+   File outFile;
+    char VL;
+    char str[8];
+    byte buf[256];
+    static int k = 0,m = 0;
+    int i,j = 0;
+// put your main code here, to run repeatedly:
+  myCAM.flush_fifo();
+  myCAM.clear_fifo_flag();
+  myCAM.OV5642_set_RAW_size(resolution);delay(1000);
+//Start capture
+myCAM.start_capture();
+Serial.println(F("start capture."));
+total_time = millis();
+while ( !myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK));
+Serial.println(F("CAM Capture Done."));
+total_time = millis() - total_time;
+Serial.print(F("capture total_time used (in miliseconds):"));
+Serial.println(total_time, DEC);
+Serial.println("Saving the image,please waitting...");
+total_time = millis();
+     k = k + 1;
+    itoa(k, str, 10);
+    strcat(str,".raw");        //Generate file name
+    outFile = SD.open(str,O_WRITE | O_CREAT | O_TRUNC);
+    if (! outFile)
+    {
+      Serial.println(F("File open error"));
+      return;
+    }
+    if(resolution == OV5642_640x480 ){
+      line = 640;column = 480;
+      }else if( resolution == OV5642_1280x960 ){
+        line = 1280;column = 960;
+        }else if( resolution == OV5642_1920x1080 ){
+           line = 1920;column = 1080;
+          }else if( resolution == OV5642_2592x1944 ){
+            line = 2592;column = 1944;
+            }
+    //Save as RAW format
+    for(i = 0; i < line; i++)
+    for(j = 0; j < column; j++)
+    {
+      VL = myCAM.read_fifo();
+      buf[m++] = VL;
+      if(m >= 256)
+      {
+        //Write 256 bytes image data to file from buffer
+        outFile.write(buf,256);
+        m = 0;
+      }
+    }
+    if(m > 0 )//Write the left image data to file from buffer
+      outFile.write( buf, m );m = 0;
+    //Close the file
+    outFile.close();
+    Serial.println("Image save OK.");
+//Clear the capture done flag
+myCAM.clear_fifo_flag();
+delay(5000);
+}


Restructured runMotorTest. Likely a problem with the electrical side.

error: pathspec 'runMotorTest/runMotorTest.ino' did not match any file(s) known to git

--- runMotorTest/runMotorTest.ino
+++ runMotorTest/runMotorTest.ino
@@ -0,0 +1,28 @@
+unsigned char wheelID[15] =  {133, 132, 131, 130, 129, 128,         //Drive motors
+                              133, 132, 131, 130, 129, 128,         //articulation motors
+                              134,   0, 134};                       //Misc motors
+
+const int FORWARD_DRIVE = 0;   //Command sent for Clockwise rotation for drive wheels (Motor 1)
+const int BACKWARD_DRIVE =1;   //Command sent for Counter-Clockwise rotation for drive wheels (Motor 1)
+const int FORWARD_ART = 4;     //Command sent for Clockwise rotation for articulation wheels (Motor 2)
+const int BACKWARD_ART =5;     //Command sent Counter-Clockwise rotation for articulation wheels (Motor 2)
+
+void setup() {
+  Serial.begin(9600);//CHECK BAUD RATE
+}
+
+void loop(){
+  runMotor();
+}
+
+void runMotor(){
+  unsigned char address = 128;//motor controller address (between 128 and 135)
+  unsigned char command = FORWARD_ART;//command: 0 Motor 1 forward, 1 Motor 1 backward, 4 Motor 2 forward, 5 Motor 2 backward. (Motor 1 is drive motor, Motor 2 is articulation motor)
+  unsigned char data = 100;//speed from 0-127
+  unsigned char checksum = (address + command + data) & 127;//error check. Sum address, command, and speed. Then, apply the bitwise AND operator on that and 127.
+  Serial.write(address);//send all the values over the first Serial port. BYTE is used to make it send in binary representation.
+  Serial.write(command);
+  Serial.write(data);
+  Serial.write(checksum);
+
+}


move serial_led.ino into it's own folder

error: pathspec 'Arduino/SerialLed/serial-led.ino' did not match any file(s) known to git

--- Arduino/SerialLed/serial-led.ino
+++ Arduino/SerialLed/serial-led.ino
@@ -0,0 +1,929 @@
+ /***********************************************************************
+ *  Copyright (c) 2014 - Matthew Fatheree <greymattr@gmail.com>
+ *  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES.  THE USER(S) ARE HEREBY NOTIFIED THAT USE OF THIS SOFTWARE MAY
+ * MAY CAUSE LOSS OF DATA, DATA DESTRUCTION, HEALTH AND MENTAL PROBLEMS. IT
+ * MAY CAUSE YOU TO START DRINKING, INCREASE YOUR STUPIDITY LEVEL, CLUB
+ * BABY SEALS, AND OVERALL BECOME A BAD PERSON.
+ *
+ * PLEASE USE AT YOUR OWN RISK
+ * ____    ________
+ * \   \  /    ___/
+ * |    \/     __|
+ * |  |\__/|  |
+ * /  \atthew \atheree
+ ************************************************************************/
+
+#include <stdarg.h>
+
+#define	min(a,b)	  ((a) < (b) ? (a) : (b))
+#define	max(a,b)	  ((a) > (b) ? (a) : (b))
+
+#define SET_BIT(p,n)      ((p) |= (1 << (n)))
+#define CLR_BIT(p,n)      ((p) &= (~(1) << (n)))
+#define IS_BIT_SET(val, bit_no) (((val) >> (bit_no)) & 1)
+
+#define INTENSE_MIN        0
+#define INTENSE_MAX        255
+
+
+//#define FADE_STEPS         8
+#define FADE_STEPS         16
+//#define FADE_STEPS         32
+
+#define SL_VERSION         "v0.1.1"
+
+
+
+#define BORDER             "\n--------------------\n"
+#define LED_CHOICE         "Which LED would you like to"
+#define FREQ_CHOICE        "How quickly would you like it to"
+#define REPEAT_CHOICE      "How many times should it"
+#define INTENSE_CHOICE     "How bright"
+#define MODE_SEL_ERR       "mode select error\n"
+#define PARAM_ERR          "parameter error\n"
+
+#define HIGH_VAL_STR       "High Value"
+#define MID_VAL_STR        "Mid Value"
+#define LOW_VAL_STR        "Low Value"
+
+#define CONTROL_SETTINGS   "Control Settings"
+#define START_INTS         "Start Intensity"
+#define END_INTS           "End Intensity"
+#define TXT_MACRO          "\n\n macro = "
+
+
+#define MAX_MACRO_LEN      128
+#define SMALL_BUFF         8
+
+#define LED1_FLAG          1
+#define LED2_FLAG          2
+#define LED3_FLAG          4
+#define LED4_FLAG          8
+#define LED5_FLAG          16
+#define LED6_FLAG          32
+#define LED7_FLAG          64
+#define LED8_FLAG          128
+#define LED9_FLAG          256
+#define LED10_FLAG         512
+#define LED11_FLAG         1024
+#define LED12_FLAG         2048
+#define LED13_FLAG         4096
+
+//macro modes
+#define MODE_BLINK         1
+#define MODE_PULSE         2
+#define MODE_FADE          3
+#define MODE_WAIT          4
+#define MODE_SET           5
+
+#define MAX_LEDS           13
+#define ALL_LEDS           8191
+#define NONE_LEDS          0
+
+#define POWER_SAVE
+
+int HighVal = INTENSE_MAX;
+int MidVal = INTENSE_MAX / 2;
+int LowVal = INTENSE_MIN;
+int UserLed = 10;
+int UserVal = INTENSE_MAX;
+int UserFreq = 1000;
+int UserRepeat = 1;
+int UserState1 = LowVal;
+int UserState2 = HighVal;
+char Uinput[ MAX_MACRO_LEN ];
+
+void setup()
+{
+  int x = 0;
+
+  for( x=0; x<=MAX_LEDS; x++ ) {
+    pinMode( UserLed,OUTPUT );    // Configure the onboard LED for output
+    analogWrite( UserLed,0 );  // default to LED off
+  }
+  Serial.begin( 57600 );
+  while( !Serial ) {
+    delay( 500 );
+  }
+  delay( 1000 ); // because Arduino,... am I right?...
+
+}
+
+void p( char *fmt, ... )
+{
+  char buf[MAX_MACRO_LEN]; // resulting string limited to 128 chars
+  va_list args;
+  va_start ( args, fmt );
+  memset( buf, 0, sizeof( buf ) );
+  vsnprintf( buf, MAX_MACRO_LEN, fmt, args );
+  va_end ( args );
+  Serial.print( buf );
+}
+
+void display_menu()
+{
+  delay( 500 );
+  p( "\n\n    LED %s %s\n", CONTROL_SETTINGS, SL_VERSION );
+  p( " I. Intensity %s\n", CONTROL_SETTINGS );
+  p( " F. Fade  %s\n", CONTROL_SETTINGS );
+  p( " P. Pulse %s\n", CONTROL_SETTINGS );
+  p( " B. Blink %s\n", CONTROL_SETTINGS );
+  p( " C. Clear all LEDS off\n" );
+#if 0
+  p( " M. Macro %s\n", CONTROL_SETTINGS );
+#endif
+  p( "%s", BORDER);
+  p( " > " );
+}
+
+void loop()
+{
+  char *selection;
+  int a = 0;
+  int ok;
+
+  display_menu();
+  selection = get_user_input();
+  memset( Uinput, 0, sizeof( Uinput ) );
+  for( a=0; a<( MAX_MACRO_LEN-1 ); a++ ) {
+    Uinput[a] = ( char ) *( selection + a );
+    if( Uinput[a] == '\0' ) {
+      break;
+    }
+  }
+  switch ( Uinput[0] ) {
+  case 'I':
+  case 'i':
+    IntensityControls();
+    break;
+  case 'F':
+  case 'f':
+    FadeControls();
+    break;
+  case 'P':
+  case 'p':
+    PulseControls();
+    break;
+  case 'B':
+  case 'b':
+    BlinkControls();
+    break;
+  case 'C':
+  case 'c':
+    p( "\n All LEDS OFF\n\n" );
+    a = 8191;
+    p("%s c\n", TXT_MACRO);
+    set_leds( a, 0 );
+    break;
+  case '*':
+    SayHello();
+    break;
+#if 1
+  case 't':
+    // put test functions here
+    unrecognized();
+    break;
+  case 'M':
+  case 'm':
+    //unrecognized();
+    parse_macro( ( char * )( Uinput + 1 ) );
+    break;
+#endif
+  default:
+    unrecognized();
+    break;
+  }
+
+}
+
+
+void set_leds( int leds, int brightness )
+{
+  int x;
+  //p("\nset led(s) %d at %d\n", leds, brightness);
+  for( x=1; x<=MAX_LEDS; x++ ) {
+    if( IS_BIT_SET( leds, x ) ) {
+      analogWrite( x,brightness );
+    }
+  }
+}
+
+void leds_off( int leds )
+{
+  set_leds( leds,0 );
+}
+
+void leds_on( int leds )
+{
+  set_leds( leds,255 );
+}
+
+void blink_leds( int leds, int brightness, int freq, int repeat )
+{
+  int i = 0, x = 0;
+  int led;
+
+  set_leds( leds, 0 );
+  //p( "\n blink led(s) %d at %d/%dms %d times\n", leds, brightness, freq, repeat );
+  for( i=0; i<repeat; i++ ) {
+    set_leds( leds, brightness );
+    delay( freq / 2 );
+    set_leds( leds, 0 );
+    delay( freq/2 );
+  }
+}
+
+void blink_led( int led, int b, int f, int r )
+{
+  int ls = 0;
+  SET_BIT( ls, led );
+  blink_leds( ls, b, f, r );
+}
+
+void fade_leds( int leds, int from, int to, int freq, int repeat )
+{
+  int total_time = freq;
+  int steps = FADE_STEPS;
+  int total_range = ( ( max( from,to ) ) - min( from,to ) );
+  int step_value =  ( total_range / steps );
+  int sleep_value = ( total_time / steps );
+  int i, y;
+  int curval;
+  int led = 0;
+
+  //p( "\n fade led(s) %d from %d to %d/%dms %d times\n", leds, from, to, freq, repeat );
+  for( i=0; i<repeat; i++ ) {
+    curval = from;
+    for ( y=0; y<=steps; y++ ) {
+      if( curval < 0 ) {
+        curval = 0;
+      }
+      set_leds( leds, curval );
+      if( curval > to ) {
+        curval = curval - step_value;
+      } else {
+        curval = curval + step_value;
+      }
+      delay( sleep_value );
+    }
+  }
+  set_leds( leds, to );
+}
+
+void fade_led( int leds, int from, int to, int freq, int repeat )
+{
+  int ls = 0;
+  SET_BIT( ls, leds );
+  fade_leds( ls, from, to, freq, repeat );
+}
+
+
+void pulse_leds( int leds, int from, int to, int freq, int repeat )
+{
+  int i;
+  int new_freq = freq / 2;
+  for( i=0; i<repeat; i++ ) {
+    fade_leds( leds, from, to, new_freq, 1 );
+    fade_leds( leds, to, from, new_freq, 1 );
+  }
+
+}
+
+void pulse_led( int led, int from, int to, int freq, int repeat )
+{
+  int ls = 0;
+  SET_BIT( ls, led );
+  pulse_leds( ls, from, to, freq, repeat );
+}
+
+void SayHello()
+{
+  p( "%s", BORDER );
+  p( "\n Hey Matt... greymattr want a beer?... You're awesome!...\n" );
+  p( "%s", BORDER );
+}
+
+char *get_user_input()
+{
+  int i=0;
+  char b = 0;
+  char commandbuffer[MAX_MACRO_LEN];
+
+  memset( commandbuffer, 0, sizeof( commandbuffer ) );
+  while( i < ( sizeof( commandbuffer )-1 ) ) {
+    if( Serial.available() ) {
+      b = Serial.read();
+      if( b != 0x08 ){
+        commandbuffer[i++] = b;
+      } else {
+        commandbuffer[i] = '\0';
+        i--;
+      }
+      if( ( b == 0x0a ) || ( b== 0x0d ) ) {
+        break;
+      } else {
+        Serial.write( b );
+      }
+    }
+  }
+  if( i<2 ) {
+    return "\0";
+  }
+  commandbuffer[i]='\0';
+  //p("\ncmd buffer = %s\n", commandbuffer);
+  return commandbuffer;
+}
+
+int get_user_int( int orig )
+{
+  char *arg = '\0';
+  int val = 0;
+  arg = get_user_input();
+  if( *arg != '\0' ) {
+    val=atoi( arg );
+    if( ( val >= INTENSE_MIN ) && ( val <= INTENSE_MAX ) ) {
+      return val;
+    } else {
+      return orig;
+    }
+  }
+  return orig;
+}
+
+int get_user_intlarge( int orig )
+{
+  char *arg = '\0';
+  int val = 0;
+  arg = get_user_input();
+  if( *arg != '\0' ) {
+    val=atoi( arg );
+    if( ( val >= 0 ) && ( val <= 0xFFFF ) ) {
+      return val;
+    } else {
+      return orig;
+    }
+  }
+  return orig;
+}
+
+void BlinkControls()
+{
+  int aNumber;
+  char resp;
+  char *arg = '\0';
+  int ok;
+  int val;
+
+  Serial.flush();
+  p( "\n\nBlink %s\n", CONTROL_SETTINGS );
+  p( "%s blink [ %d ]?: ", LED_CHOICE, UserLed );
+  while( !Serial.available() ) {
+    ;
+  }
+  UserLed = get_user_int( UserLed );
+  p( "\n%s blink [ %dms ]?: ", FREQ_CHOICE, UserFreq );
+  while( !Serial.available() ) {
+    ;
+  }
+  UserFreq = get_user_intlarge( UserFreq );
+  p( "\n%s (1-255) [ %d ]?: ", INTENSE_CHOICE, UserVal );
+  while( !Serial.available() ) {
+    ;
+  }
+  UserVal = get_user_int( UserVal );
+  p( "\n%s should it blink [ %d ]?: ", REPEAT_CHOICE, UserRepeat );
+  while( !Serial.available() ) {
+    ;
+  }
+  UserRepeat = get_user_int( UserRepeat );
+  p("%s ml(%d)b(%d,%d,%d)\n", TXT_MACRO,UserLed, UserVal, UserFreq, UserRepeat);
+  blink_led( UserLed, UserVal, UserFreq, UserRepeat );
+}
+
+void IntensityControls()
+{
+  char *arg = NULL;
+  int val = 0;
+  int ok;
+
+  Serial.flush();
+  p( "\n\nIntensity %s ( 1 - 255 )\n", CONTROL_SETTINGS );
+  p( "%s [ %d ]?: ",HIGH_VAL_STR, HighVal );
+  while( !Serial.available() ) {
+    ;
+  }
+  HighVal = get_user_int( HighVal );
+  p( "\n %s [ %d ]?: ",MID_VAL_STR, MidVal );
+  while( !Serial.available() ) {
+    ;
+  }
+  MidVal = get_user_int( MidVal );
+  p( "\n %s [ %d ]?: ",LOW_VAL_STR, LowVal );
+  while( !Serial.available() ) {
+    ;
+  }
+  LowVal = get_user_int( LowVal );
+  p( "%s", BORDER );
+  p( "%s=%d, %s=%d, %s=%d\n",HIGH_VAL_STR,HighVal,MID_VAL_STR, MidVal,LOW_VAL_STR, LowVal );
+  p( "%s", BORDER );
+  p( "\n%s set [ %d ]?: ", LED_CHOICE, UserLed );
+  while( !Serial.available() ) {
+    ;
+  }
+  UserLed = get_user_int( UserLed );
+  p( "\n%s [ %d ]?: ", INTENSE_CHOICE, UserVal );
+  while( !Serial.available() ) {
+    ;
+  }
+  UserVal = get_user_intlarge( UserVal );
+  p( "%s", BORDER );
+  p( "\nLED %d set to %d\n", UserLed, UserVal );
+  p("%s ml(%d)i(%d)\n", TXT_MACRO,UserLed, UserVal);
+  analogWrite( UserLed, UserVal );
+  p( "%s", BORDER );
+}
+
+void intensity_menu()
+{
+  p( "\n a. %s ( %d )\n", HIGH_VAL_STR, HighVal );
+  p( " b.  %s ( %d )\n", MID_VAL_STR, MidVal );
+  p( " c.  %s ( %d )\n", LOW_VAL_STR, LowVal );
+}
+
+void FadeControls()
+{
+  char *arg = '\0';
+  int state1 = UserState1;
+  int state2 = UserState2;
+
+  Serial.flush();
+  p( "\n\nFade %s\n", CONTROL_SETTINGS );
+  p( "%s fade [ %d ]?: ", LED_CHOICE, UserLed );
+  while( !Serial.available() ) {
+    ;
+  }
+  UserLed = get_user_int( UserLed );
+  intensity_menu();
+  p( "%s [ %d ]?: ", START_INTS, UserState1 );
+  while( !Serial.available() ) {
+    ;
+  }
+  arg = get_user_input();
+  switch( *arg ) {
+  case 'A':
+  case 'a':
+    UserState1 = HighVal;
+    break;
+  case 'B':
+  case 'b':
+    UserState1 = MidVal;
+    break;
+  case 'C':
+  case 'c':
+    UserState1 = LowVal;
+    break;
+  default:
+    state1 = atoi( arg );
+    if( ( state1 > 255 ) || ( state1 < 0 ) ) {
+      state1=UserState1;
+    } else {
+      state1 = UserState1;
+    }
+    break;
+  }
+  intensity_menu();
+  p( "%s [ %d ]?: ",END_INTS, UserState2 );
+  while( !Serial.available() ) {
+    ;
+  }
+  arg = get_user_input();
+  switch( *arg ) {
+  case 'A':
+  case 'a':
+    state2 = HighVal;
+    break;
+  case 'B':
+  case 'b':
+    state2 = MidVal;
+    break;
+  case 'c':
+  case 'C':
+    state2 = LowVal;
+    break;
+  default:
+    state2 = atoi( arg );
+    if( ( state2 > 255 ) || ( state2 < 0 ) ) {
+      state2=UserState2;
+    } else {
+      state2 = UserState2;
+    }
+    break;
+  }
+  UserState2 = state2;
+  p( "\n%s fade [ %d ]?: ", FREQ_CHOICE, UserFreq );
+  while( !Serial.available() ) {
+    ;
+  }
+  UserFreq = get_user_intlarge( UserFreq );
+  p( "\n%s fade [ %d ]?: ", REPEAT_CHOICE, UserRepeat );
+  while( !Serial.available() ) {
+    ;
+  }
+  UserRepeat = get_user_int( UserRepeat );
+  p("%s ml(%d)f(%d,%d,%d,%d)\n", TXT_MACRO,UserLed, UserState1, UserState2, UserFreq, UserRepeat);
+  fade_led( UserLed, UserState1, UserState2, UserFreq, UserRepeat );
+}
+
+void PulseControls()
+{
+  char *arg = '\0';
+  int sel = 0;
+  int state1, state2;
+  int ok;
+
+  Serial.flush();
+  p( "\n\nPulse %s\n", CONTROL_SETTINGS );
+  p( "%s Pulse [ %d ]?: ",LED_CHOICE, UserLed );
+  while( !Serial.available() ) {
+    ;
+  }
+  UserLed = get_user_int( UserLed );
+  intensity_menu();
+  p( "%s [ %d ]?: ", START_INTS, UserState1 );
+  while( !Serial.available() ) {
+    ;
+  }
+  arg = get_user_input();
+  switch( arg[0] ) {
+  case 'a':
+  case 'A':
+    state1 = HighVal;
+    break;
+  case 'b':
+  case 'B':
+    state1 = MidVal;
+    break;
+  case 'c':
+  case 'C':
+    state1 = LowVal;
+    break;
+  default:
+    state1 = atoi( arg );
+    if( ( state1 > 255 ) || ( state1 < 0 ) ) {
+      state1=UserState1;
+    } else {
+      state1 = UserState1;
+    }
+    break;
+  }
+  UserState1 = state1;
+  p( "\n%s %d\n", START_INTS, UserState1 );
+  intensity_menu();
+  p( "%s [ %d ]?: ",END_INTS, UserState2 );
+  while( !Serial.available() ) {
+    ;
+  }
+  arg = get_user_input();
+  switch( arg[0] ) {
+  case 'a':
+  case 'A':
+    state2 = HighVal;
+    break;
+  case 'b':
+  case 'B':
+    state2 = MidVal;
+    break;
+  case 'c':
+  case 'C':
+    state2 = LowVal;
+    break;
+  default:
+    state2 = atoi( arg );
+    if( ( state2 > 255 ) || ( state2 < 0 ) ) {
+      state2=UserState2;
+    } else {
+      state2 = UserState2;
+    }
+    break;
+  }
+  UserState2 = state2;
+  p( "\n%s pulse [ %d ]?: ", FREQ_CHOICE, UserFreq );
+  while( !Serial.available() ) {
+    ;
+  }
+  UserFreq=get_user_intlarge( UserFreq );
+  p( "\n%s pulse [ %d ]?: ", REPEAT_CHOICE, UserRepeat );
+  while( !Serial.available() ) {
+    ;
+  }
+  UserRepeat=get_user_int( UserRepeat );
+  p("%s ml(%d)p(%d,%d,%d,%d)\n", TXT_MACRO,UserLed, UserState1, UserState2, UserFreq, UserRepeat);
+  pulse_led( UserLed, UserState1, UserState2, UserFreq, UserRepeat );
+}
+
+int parse_macro( char *macro )
+{
+  int ok = 0;
+  long int leds = 0;
+  char *ch;
+  char buf[ SMALL_BUFF ];
+  int val1 = -1;
+  int val2 = -1;
+  int freq = -1;
+  int repeat = -1;
+  int wait = -1;
+  int state = 0;
+  int i, x;
+  int scratch = 0;
+  int mode = 0;
+
+  set_leds( ALL_LEDS, 0 );
+  p( "\nRun Macro [ %s ]\n", macro-1 );
+  for( i=0; i<( MAX_MACRO_LEN - 1 ); i++ ) {
+    ch = ( char * )( macro + i );
+    switch( *ch ) {
+    case 'l':
+    case 'L':
+      leds = 0;
+      if( *( ch + 1 ) == '(' ) {
+        i++;  // skip char
+        memset( buf, 0, sizeof( buf ) );
+        for( x=0; x<sizeof( buf ); x++ ) {
+          i++;
+          ch = ( char * )( macro + i );
+          switch( *ch ) {
+          case ',':
+          case ')':
+            scratch = atoi( buf );
+            //p("got led #%d\n", scratch);
+            SET_BIT( leds, scratch );
+            if( *ch == ')' ) {
+              for( x=0; x<MAX_LEDS; x++ ) {
+                if( IS_BIT_SET( leds, x ) ) {
+                  p( "+ LED #%d\n", x );
+                }
+              }
+              x = sizeof( buf ); // stop here
+            } else {
+              memset( buf, 0, sizeof( buf ) );
+              x = -1;
+            }
+            break;
+          default:
+            buf[x] = *ch;
+            //p("buf[%d] = %c\n", x, *ch);
+            break;
+          }
+        }
+      } else {
+        p( "LED err: %s", PARAM_ERR );
+        ok = -1;
+      }
+      //leds = 0;
+      val1 = -1;
+      val2 = -1;
+      freq = -1;
+      wait = - 1;
+      repeat = -1;
+      mode = 0;
+      break;
+    case 'b':
+    case 'B':
+      i++;
+      if( mode == 0 ) {
+        p("\nBlink\n");
+        mode = MODE_BLINK;
+      } else {
+        p( "%s",MODE_SEL_ERR );
+      }
+      for( x=0; x<sizeof( buf ); x++ ) {
+        i++;
+        ch = ( char * )( macro + i );
+        switch( *ch ) {
+        case ',':
+        case ')':
+          scratch = atoi( buf );
+          //p("got led #%d\n", scratch);
+          if( val1 == -1 ) {
+            p( "got %s %d\n", END_INTS, scratch );
+            val1 = scratch;
+            x = -1;
+          } else {
+            if( freq == -1 ) {
+              p( "got frequency %d\n", scratch );
+              freq = scratch;
+              x = -1;
+            } else {
+              if( repeat == -1 ) {
+                p( "got repeat %d\n", scratch );
+                repeat = scratch;
+                blink_leds( leds, val1, freq, repeat );
+                x = sizeof( buf );
+              } else {
+                p( "Blink set %s", PARAM_ERR );
+              }
+            }
+          }
+          memset( buf, 0, sizeof( buf ) );
+          break;
+        default:
+          buf[x] = *ch;
+          //p("buf[%d] = %c\n", x, *ch);
+          break;
+        }
+      }
+      //leds = 0;
+      val1 = -1;
+      val2 = -1;
+      freq = -1;
+      wait = - 1;
+      repeat = -1;
+      mode = 0;
+      break;
+    case 'f':
+    case 'F':
+    case 'p':
+    case 'P':
+      i++;
+      if( mode == 0 ) {
+        if( ( *ch == 'f' ) || ( *ch == 'F' ) ) {
+          mode = MODE_FADE;
+          p( "\nFade\n" );
+        } else {
+          mode = MODE_PULSE;
+          p( "\nPulse\n" );
+        }
+      } else {
+        p( "%s",MODE_SEL_ERR );
+      }
+      for( x=0; x<sizeof( buf ); x++ ) {
+        i++;
+        ch = ( char * )( macro + i );
+        switch( *ch ) {
+        case ',':
+        case ')':
+          scratch = atoi( buf );
+          //p("got led #%d\n", scratch);
+          if( val1 == -1 ) {
+            p( "got %s %d\n",START_INTS, scratch );
+            val1 = scratch;
+            x = -1;
+          } else {
+            if ( val2 == -1 ) {
+              p( "got %s %d\n",END_INTS, scratch );
+              val2 = scratch;
+              x = -1;
+            } else {
+              if( freq == -1 ) {
+                p( "got frequency %d\n", scratch );
+                freq = scratch;
+                x = -1;
+              } else {
+                if( repeat == -1 ) {
+                  p( "got repeat %d\n", scratch );
+                  repeat = scratch;
+                  if( mode == MODE_FADE ) {
+                    fade_leds( leds, val1, val2, freq, repeat );
+                  } else {
+                    pulse_leds( leds, val1, val2, freq, repeat );
+                  }
+                  x = sizeof( buf );
+                } else {
+                  p( "set %s", PARAM_ERR );
+                }
+              }
+            }
+          }
+          memset( buf, 0, sizeof( buf ) );
+          break;
+        default:
+          buf[x] = *ch;
+          //p("buf[%d] = %c\n", x, *ch);
+          break;
+        }
+      }
+      //leds = 0;
+      val1 = -1;
+      val2 = -1;
+      freq = -1;
+      wait = - 1;
+      repeat = -1;
+      mode = 0;
+      break;
+    case 'i':
+    case 'I':
+      if( mode == 0 ) {
+        mode = MODE_SET;
+        p( "\nIntensity\n" );
+      } else {
+        p( "%s",MODE_SEL_ERR );
+      }
+      i++;
+      mode = MODE_SET;
+      memset( buf,0, sizeof( buf ) );
+      for( x=0; x<sizeof( buf ); x++ ) {
+        i++;
+        ch = ( char * )( macro + i );
+        switch( *ch ) {
+        case ')':
+          if( freq == -1 ) {
+            scratch = atoi( buf );
+            p( "got %s %d\n", END_INTS, scratch );
+            val1 = scratch;
+            set_leds( leds, val1 );
+            x = sizeof( buf );
+          } else {
+            p( "intensity %s", PARAM_ERR );
+          }
+          break;
+        default:
+          buf[x] = *ch;
+          break;
+        }
+      }
+      //leds = 0;
+      val1 = -1;
+      val2 = -1;
+      freq = -1;
+      wait = - 1;
+      repeat = -1;
+      mode = 0;
+      break;
+    case 'w':
+    case 'W':
+      if( ( mode == 0 ) &&  ( *( ch+1 ) == '(' ) ) {
+        i++;
+        p( "\nWait\n" );
+        mode = MODE_WAIT;
+        memset( buf,0, sizeof( buf ) );
+        for( x=0; x<sizeof( buf ); x++ ) {
+          i++;
+          ch = ( char * )( macro + i );
+          switch( *ch ) {
+          case ')':
+            if( freq == -1 ) {
+              scratch = atoi( buf );
+              p( "got freq %d\n", scratch );
+              freq = scratch;
+              delay( freq );
+              x = sizeof( buf );
+            } else {
+              p( "Wait set %s", PARAM_ERR );
+            }
+            break;
+          default:
+            buf[x] = *ch;
+            break;
+          }
+        }
+      } else {
+        p( "%s",MODE_SEL_ERR );
+      }
+      //leds = 0;
+      val1 = -1;
+      val2 = -1;
+      freq = -1;
+      wait = - 1;
+      repeat = -1;
+      mode = 0;
+      break;
+    case 'c':
+    case 'C':
+      i++;
+      p( "Clear\n" );
+      set_leds( ALL_LEDS, 0 );
+      //leds = 0;
+      val1 = -1;
+      val2 = -1;
+      freq = -1;
+      wait = - 1;
+      repeat = -1;
+      mode = 0;
+      break;
+    }
+  }// end of loop through macro
+  //p("led = %d\n", leds );
+  return ok;
+}
+
+void unrecognized()
+{
+  p( "\nError!\n" );
+}
+


Update if/else statement in _ard/_sensorTesting/sensor.ino


fixed receiver pin/value

fixed receiver pin/value

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/Duke-Medical-Instrumentation/Inception.git/'


Create Lee's Retirement countdown clock

Create Lee's Retirement countdown clock

error: pathspec 'Lee_Retirement/Lee_Retirement.ino' did not match any file(s) known to git

--- Lee_Retirement/Lee_Retirement.ino
+++ Lee_Retirement/Lee_Retirement.ino
@@ -0,0 +1,150 @@
+/*
+ Testing buttons as well
+*/
+#include <LiquidCrystal.h>
+
+// initialize the library with the numbers of the interface pins
+/* LCD Shield mappings:
+ D8, // RS
+ D9, // Enable
+ D4, // bit 4
+ D5, // bit 5
+ D6, // bit 6
+ D7  // bit 7
+ D10 // backlight brightness
+ A0  // buttons
+ So, LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
+*/
+LiquidCrystal lcd(
+ 8, // RS
+ 9, // Enable
+ 4, // bit 4
+ 5, // bit 5
+ 6, // bit 6
+ 7  // bit 7
+);
+
+#define PinBacklight 10
+#define PinButton    0
+
+// define some values used by the panel and buttons
+int lcd_key     = 0;
+int adc_key_in  = 0;
+#define btnRIGHT  0
+#define btnUP     1
+#define btnDOWN   2
+#define btnLEFT   3
+#define btnSELECT 4
+#define btnNONE   5
+
+String line1 = "";
+String line2 = "";
+String secs;
+String key;
+
+#define BrightMax 255
+#define BrightMin 0
+int brightness_increment = -2;
+int brightness = BrightMax;
+
+// read the buttons
+int read_LCD_buttons()
+{
+ adc_key_in = analogRead(PinButton);      // read the value from the sensor
+ //return adc_key_in;
+ // example buttons when read are centered at these valies: 0, 144, 329, 504, 741
+ // values measured in Lee's display: 0, 143, 328, 503, 741 (really close to the author's, apparently)
+ // we add half the distance to the next button to allow for as much variance as is reasonably likely
+ //
+ // I picked 1000 as the top value mostly arbitrarily; ~1024 is the select, due to being a "short"
+ // I suppose the "right" way would be to do 741+(1024-741/2) to be consistent
+ if (adc_key_in > 1000) return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result
+ // For V1.1 us this threshold
+ if (adc_key_in < (0   + (143 - 0)   / 2 ))  return btnRIGHT;
+ if (adc_key_in < (143 + (328 - 143) / 2 ))  return btnUP;
+ if (adc_key_in < (328 + (503 - 328) / 2 ))  return btnDOWN;
+ if (adc_key_in < (503 + (741 - 503) / 2 ))  return btnLEFT;
+ if (adc_key_in <= 1000)                     return btnSELECT;
+
+ // For V1.0 comment the other threshold and use the one below:
+/*
+ if (adc_key_in < 50)   return btnRIGHT;
+ if (adc_key_in < 195)  return btnUP;
+ if (adc_key_in < 380)  return btnDOWN;
+ if (adc_key_in < 555)  return btnLEFT;
+ if (adc_key_in < 790)  return btnSELECT;
+*/
+
+ return btnNONE;  // when all others fail, return this...
+}
+
+void setup() {
+  // define PWM brightness pin for output
+  pinMode(PinBacklight, OUTPUT);
+  // set up the LCD's number of columns and rows:
+  lcd.begin(16, 2);
+  lcd.clear();
+}
+
+void loop() {
+  lcd_key = read_LCD_buttons();
+  switch (lcd_key){
+    case btnNONE: {
+      key = "NONE";
+      break;
+    }
+    case btnRIGHT: {
+      key = "RIGHT";
+      brightness += 1;
+      if( brightness >= BrightMax ){
+        brightness = BrightMax;
+      }
+      break;
+    }
+    case btnLEFT: {
+      key = "LEFT";
+      brightness -= 1;
+      if( brightness <= BrightMin ){
+        brightness = BrightMin;
+      }
+      break;
+    }
+    case btnUP: {
+      key = "UP";
+      lcd.display();
+      brightness = BrightMax;
+      break;
+    }
+    case btnDOWN: {
+      key = "DOWN";
+      brightness = BrightMin;
+      lcd.noDisplay();
+      break;
+    }
+    case btnSELECT: {
+      key = "SELECT";
+      break;
+    }
+  }
+  analogWrite(PinBacklight, brightness);
+
+  // assemble LCD line
+  line1 = "";
+  line1 = "ADC:" + String(adc_key_in);
+  while( line1.length() < 16 - key.length() ){
+    line1 = line1 + " ";
+  }
+  line1 = line1 + key;
+  lcd.setCursor(0,0);
+  lcd.print(line1);
+
+  // assemble second LCD line
+  line2 = "inc:" + String(brightness_increment);
+  secs = String(millis()/1000);
+  while( line2.length() < 16 - secs.length() ){
+    line2 = line2 + " ";
+  }
+  line2 = line2 + secs;
+  lcd.setCursor(0,1);
+  lcd.print(line2);
+}


Add Arduino sketch to test encoders and leds

error: pathspec 'arduino/encoders_and_leds_test/encoders_and_leds_test.ino' did not match any file(s) known to git

--- arduino/encoders_and_leds_test/encoders_and_leds_test.ino
+++ arduino/encoders_and_leds_test/encoders_and_leds_test.ino
@@ -0,0 +1,48 @@
+// Total number of input channels supported by the hardware
+const uint8_t numChannels = 5;
+const uint8_t ledPins[] = {2, 4, 7, 8, 12};
+const uint8_t encoderPins[] = {5, 6, 9, 10, 11};
+unsigned long currentEncoderValues[] = {0, 0, 0, 0, 0};
+unsigned long previousEncoderValues[] = {0, 0, 0, 0, 0};
+const unsigned long encoderValueThreshold = 2048;
+
+// Number of active parameters in the sketch
+const uint8_t numParams = 4;
+
+/*
+ * Tests the LEDs and encoders.
+ * If the encoder value is over a given threshold, the corresponding LED is lit.
+ */
+void setup()
+{
+  Serial.begin(57600);
+  for (uint8_t i = 0; i < numChannels; i++)
+  {
+    pinMode(ledPins[i], OUTPUT);
+    pinMode(encoderPins[i], INPUT);
+  }
+}
+
+void loop()
+{
+  for (uint8_t i = 0; i < numParams; i++)
+  {
+    previousEncoderValues[i] = currentEncoderValues[i];
+    currentEncoderValues[i] = pulseIn(encoderPins[i], HIGH);
+
+    Serial.print(currentEncoderValues[i]);
+    if (i < numParams - 1)
+    {
+      Serial.print(" ");
+    }
+    if (currentEncoderValues[i] > encoderValueThreshold)
+    {
+      digitalWrite(ledPins[i], HIGH);
+    }
+    else
+    {
+      digitalWrite(ledPins[i], LOW);
+    }
+  }
+  Serial.println();
+}