support Stepper

support Stepper

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

--- waFirmata_Stepper.ino
+++ waFirmata_Stepper.ino
@@ -0,0 +1,895 @@
+/*
+  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 <Servo.h>
+#include <Wire.h>
+#include <Firmata.h>
+#include <FirmataStepper.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
+
+// the minimum interval for sampling analog input
+#define MINIMUM_SAMPLING_INTERVAL 10
+// pin configured to be ignored by digitalWrite and capabilityResponse
+#define PIN_MODE_IGNORE         0x7F
+
+#define MAX_STEPPERS    6     // arbitrary value... may need to adjust
+#define STEPPER_DATA    0x72  // move this to Firmata.h
+#define STEPPER_CONFIG  0
+#define STEPPER_STEP    1
+#define STEPPER         0x08  // pin configured for stepper motor
+
+
+/*==============================================================================
+   GLOBAL VARIABLES
+  ============================================================================*/
+
+/* 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;
+
+FirmataStepper *stepper[MAX_STEPPERS];
+byte numSteppers = 0;
+
+
+Servo servos[MAX_SERVOS];
+byte servoPinMap[TOTAL_PINS];
+byte detachedServos[MAX_SERVOS];
+byte detachedServoCount = 0;
+byte servoCount = 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 attachServo(byte pin, int minPulse, int maxPulse)
+{
+  if (servoCount < MAX_SERVOS) {
+    // reuse indexes of detached servos until all have been reallocated
+    if (detachedServoCount > 0) {
+      servoPinMap[pin] = detachedServos[detachedServoCount - 1];
+      if (detachedServoCount > 0) detachedServoCount--;
+    } else {
+      servoPinMap[pin] = servoCount;
+      servoCount++;
+    }
+    if (minPulse > 0 && maxPulse > 0) {
+      servos[servoPinMap[pin]].attach(PIN_TO_DIGITAL(pin), minPulse, maxPulse);
+    } else {
+      servos[servoPinMap[pin]].attach(PIN_TO_DIGITAL(pin));
+    }
+  } else {
+    Firmata.sendString("Max servos attached");
+  }
+}
+
+void detachServo(byte pin)
+{
+  servos[servoPinMap[pin]].detach();
+  // if we're detaching the last servo, decrement the count
+  // otherwise store the index of the detached servo
+  if (servoPinMap[pin] == servoCount && servoCount > 0) {
+    servoCount--;
+  } else if (servoCount > 0) {
+    // keep track of detached servos because we want to reuse their indexes
+    // before incrementing the count of attached servos
+    detachedServoCount++;
+    detachedServos[detachedServoCount - 1] = servoPinMap[pin];
+  }
+
+  servoPinMap[pin] = 255;
+}
+
+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] == PIN_MODE_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_DIGITAL(pin) && mode != SERVO) {
+    if (servoPinMap[pin] < MAX_SERVOS && servos[servoPinMap[pin]].attached()) {
+      detachServo(pin);
+    }
+  }
+  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 SERVO:
+      if (IS_PIN_DIGITAL(pin)) {
+        pinConfig[pin] = SERVO;
+        if (servoPinMap[pin] == 255 || !servos[servoPinMap[pin]].attached()) {
+          // pass -1 for min and max pulse values to use default values set
+          // by Servo library
+          attachServo(pin, -1, -1);
+        }
+      }
+      break;
+    case STEPPER:
+      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:(" + String(mode) + ")").c_str()); // 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 SERVO:
+        if (IS_PIN_DIGITAL(pin))
+          servos[servoPinMap[pin]].write(value);
+        pinState[pin] = value;
+        break;
+      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, nowState;
+
+  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;
+          nowState =  ((byte)value & mask) ? 1 : 0;
+          if (pinState[pin] != nowState) {
+            pinState[pin] = nowState;
+            Firmata.sendDigitalPort(port, nowState);
+            Firmata.sendString("test ok");
+          }
+        }
+      }
+      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 sysexCallback(byte command, byte argc, byte *argv)
+{
+  byte mode;
+  byte slaveAddress;
+  byte data;
+  int slaveRegister;
+  unsigned int delayTime;
+
+  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 3:
+      switch (argv[0]) {
+        //Webduino board's switch
+        case 1:
+          pinMode(12, OUTPUT);
+          if (argv[1] == 0) {
+            digitalWrite(12, LOW);
+          } else {
+            digitalWrite(12, HIGH);
+          }
+          break;
+      }
+      break;
+    case 4:
+      switch (argv[0]) {
+        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;
+      }
+      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 SERVO_CONFIG:
+      if (argc > 4) {
+        // these vars are here for clarity, they'll optimized away by the compiler
+        byte pin = argv[0];
+        int minPulse = argv[1] + (argv[2] << 7);
+        int maxPulse = argv[3] + (argv[4] << 7);
+
+        if (IS_PIN_DIGITAL(pin)) {
+          if (servoPinMap[pin] < MAX_SERVOS && servos[servoPinMap[pin]].attached()) {
+            detachServo(pin);
+          }
+          attachServo(pin, minPulse, maxPulse);
+          setPinModeCallback(pin, SERVO);
+        }
+      }
+      break;
+    case STEPPER_DATA:
+      byte stepCommand, deviceNum, directionPin, stepPin, stepDirection;
+      byte interface, interfaceType;
+      byte motorPin3, motorPin4;
+      unsigned int stepsPerRev;
+      long numSteps;
+      int stepSpeed;
+      int accel;
+      int decel;
+
+      stepCommand = argv[0];
+      deviceNum = argv[1];
+
+      if (deviceNum < MAX_STEPPERS)
+      {
+        if (stepCommand == STEPPER_CONFIG)
+        {
+          interface = argv[2]; // upper 4 bits are the stepDelay, lower 4 bits are the interface type
+          interfaceType = interface & 0x0F; // the interface type is specified by the lower 4 bits
+          stepsPerRev = (argv[3] + (argv[4] << 7));
+
+          directionPin = argv[5]; // or motorPin1 for TWO_WIRE or FOUR_WIRE interface
+          stepPin = argv[6]; // // or motorPin2 for TWO_WIRE or FOUR_WIRE interface
+          setPinModeCallback(directionPin, STEPPER);
+          setPinModeCallback(stepPin, STEPPER);
+
+          if (!stepper[deviceNum])
+          {
+            numSteppers++; // assumes steppers are added in order 0 -> 5
+          }
+
+          if (interfaceType == FirmataStepper::DRIVER || interfaceType == FirmataStepper::TWO_WIRE)
+          {
+            stepper[deviceNum] = new FirmataStepper(interface, stepsPerRev, directionPin, stepPin);
+          }
+          else if (interfaceType == FirmataStepper::FOUR_WIRE)
+          {
+            motorPin3 = argv[7];
+            motorPin4 = argv[8];
+            setPinModeCallback(motorPin3, STEPPER);
+            setPinModeCallback(motorPin4, STEPPER);
+            stepper[deviceNum] = new FirmataStepper(interface, stepsPerRev, directionPin, stepPin, motorPin3, motorPin4);
+          }
+        }
+        else if (stepCommand == STEPPER_STEP)
+        {
+          stepDirection = argv[2];
+          numSteps = (long)argv[3] | ((long)argv[4] << 7) | ((long)argv[5] << 14);
+          stepSpeed = (argv[6] + (argv[7] << 7));
+
+          if (stepDirection == 0)
+          {
+            numSteps *= -1;
+          }
+          if (stepper[deviceNum])
+          {
+            if (argc >= 8 && argc < 12)
+            {
+              // num steps, speed (0.01*rad/sec)
+              stepper[deviceNum]->setStepsToMove(numSteps, stepSpeed);
+            }
+            else if (argc == 12)
+            {
+              accel = (argv[8] + (argv[9] << 7));
+              decel = (argv[10] + (argv[11] << 7));
+              // num steps, speed (0.01*rad/sec), accel (0.01*rad/sec^2), decel (0.01*rad/sec^2)
+              stepper[deviceNum]->setStepsToMove(numSteps, stepSpeed, accel, decel);
+            }
+          }
+        }
+      }
+      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
+        }
+        if (IS_PIN_DIGITAL(pin))
+        {
+          Serial.write(STEPPER);
+          Serial.write(21); //21 bits used for number of steps
+        }
+        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);
+    }
+
+    servoPinMap[i] = 255;
+  }
+  // by default, do not report any analog inputs
+  analogInputsToReport = 0;
+
+  for (byte i = 0; i < MAX_STEPPERS; i++)
+  {
+    if (stepper[i])
+    {
+      free(stepper[i]);
+      stepper[i] = 0;
+    }
+  }
+  numSteppers = 0;
+  detachedServoCount = 0;
+  servoCount = 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();
+
+  /* STREAMREAD - processing incoming messagse as soon as possible, while still
+     checking digital inputs.  */
+  while (Firmata.available())
+    Firmata.processInput();
+
+  // if one or more stepper motors are used, update their position
+  if (numSteppers > 0) {
+    for (int i = 0; i < MAX_STEPPERS; i++) {
+      if (stepper[i]) {
+        bool done = stepper[i]->update();
+        // send command to client application when stepping is complete
+        if (done) {
+          Serial.write(START_SYSEX);
+          Serial.write(STEPPER_DATA);
+          Serial.write(i);
+          Serial.write(END_SYSEX);
+        }
+      }
+    }
+  }
+
+  // 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);
+      }
+    }
+  }
+}


Update flightTiny.ino

Update flightTiny.ino

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/JDat/RocketGPStracker.git/'


did not work with bitshift

did not work with bitshift

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/trinamic/T-Bone.git/'


Mood Setter

Mood Setter

Bluetooth Light Changing Display

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

--- JustForFun/BluetoothMoodSetter/BluetoothMoodSetter.ino
+++ JustForFun/BluetoothMoodSetter/BluetoothMoodSetter.ino
@@ -0,0 +1,78 @@
+
+const int red = 3;
+const int green = 5;
+const int blue = 6;
+
+void setup() {
+  Serial.begin(9600);
+  pinMode(red, OUTPUT);
+  pinMode(green, OUTPUT);
+  pinMode(blue, OUTPUT);
+  Serial.println("Welcome to mood setter!");
+  Serial.println("Enter R,O,Y,G,B,P,X,W or F to set the mood.");
+}
+
+void loop() {
+  //if an input has been entered
+ if (Serial.available()){
+   char value = Serial.read(); //get the int
+   Serial.println(value);
+
+   switch (value) {
+     case 'R' || 'r':
+       setRGB(200,0,0);
+       break;
+     case 'O' || 'o':
+       setRGB(240,20,0);
+       break;
+     case 'Y' || 'y':
+       setRGB(220,80,0);
+       break;
+     case 'G' || 'g':
+       setRGB(0,200,0);
+       break;
+     case 'B' || 'b':
+       setRGB(0,0,200);
+       break;
+     case 'P' || 'p':
+       setRGB(240,0,70);
+       break;
+     case 'X' || 'x':
+       setRGB(0,0,0);
+       break;
+     case 'W' || 'w':
+       setRGB(200,200,200);
+       break;
+     case 'F' || 'f':
+       for (int r = 0; r < 256; r+=51){
+          analogWrite(red, r);
+          //Loop green
+          for (int g = 0; g < 256; g+=51){
+            analogWrite(green, g);
+            //Loop blue
+            for (int b = 0; b < 256; b+=51){
+                char value = Serial.read(); //get the int
+                if (value == 'X') {
+                  Serial.println(value);
+                  setRGB(0,0,0);
+                  return;
+                }
+                analogWrite(blue, b);
+                delay(1000);
+              }//end for
+          }//end for
+      }//end for
+       break;
+     default:
+       Serial.println("Only R,O,Y,G,B,P,X,W,F allowed");
+
+   }
+ }
+}
+
+void setRGB (int r, int g, int b) {
+  analogWrite(red, r);
+  analogWrite(green, g);
+  analogWrite(blue, b);
+}
+


Correction to output example

Correction to output example

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/DanNixon/Alice.git/'


start main sketch

start main sketch

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

--- main/main.ino
+++ main/main.ino
@@ -0,0 +1,144 @@
+#include <Canbus.h>
+#include <defaults.h>
+#include <global.h>
+#include <mcp2515.h>
+#include <mcp2515_defs.h>
+
+#include <LiquidCrystal.h>
+#include <math.h>
+
+//RS,EN,DB4,DB5,DB6,DB7
+LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
+
+#define REDLITE 3
+#define GREENLITE 5
+#define BLUELITE 6
+
+int brightness = 255;
+
+byte fill1[8] = {
+  B10000,
+  B10000,
+  B10000,
+  B10000,
+  B10000,
+  B10000,
+  B10000,
+  B10000
+};
+byte fill2[8] = {
+  B11000,
+  B11000,
+  B11000,
+  B11000,
+  B11000,
+  B11000,
+  B11000,
+  B11000
+};
+byte fill3[8] = {
+  B11100,
+  B11100,
+  B11100,
+  B11100,
+  B11100,
+  B11100,
+  B11100,
+  B11100
+};
+byte fill4[8] = {
+  B11110,
+  B11110,
+  B11110,
+  B11110,
+  B11110,
+  B11110,
+  B11110,
+  B11110
+};
+byte fill5[8] = {
+  B11111,
+  B11111,
+  B11111,
+  B11111,
+  B11111,
+  B11111,
+  B11111,
+  B11111
+};
+
+//possible parameters to display
+double  engine_afr;         //AFR
+double  engine_afr_tgt;     //AFR target
+double  engine_map;         //MAP sensor
+double  engine_boost;       //boost (psi) calculated from map value
+double  engine_adv;         //ignition advance
+int     engine_rpm;         //RPM
+int     engine_tps;         //throttle position
+double  engine_vbat;        //battery voltage
+int     engine_clt;         //coolant temp
+int     engine_iat;         //intake air temp
+
+void setup() {
+
+  lcd.createChar(0, fill1);
+  lcd.createChar(1, fill2);
+  lcd.createChar(2, fill3);
+  lcd.createChar(3, fill4);
+  lcd.createChar(4, fill5);
+
+  lcd.begin(20, 4);
+  lcd.print("AFR");
+  lcd.setCursor(0, 2);
+  lcd.print("TGT");
+
+  pinMode(REDLITE, OUTPUT);
+  pinMode(GREENLITE, OUTPUT);
+  pinMode(BLUELITE, OUTPUT);
+
+  setBacklight(255, 0, 0);
+}
+
+void loop() {
+  double afr = 12.5;
+  double tgt = 14.7;
+
+  lcd.setCursor(4, 0);
+  lcd.print(afr);
+  lcd.setCursor(4, 2);
+  lcd.print(tgt);
+
+  draw_bar(afr, 1, 10, 20);
+  draw_bar(tgt, 3, 10, 20);
+}
+
+void draw_bar(double value, int row, double minimum, double maximum) {
+  lcd.setCursor(0, row);
+  int bars = ((value - minimum) * 100) / (maximum - minimum);
+  int fullBars = bars/5;
+  int partialBars = bars % 5;
+  lcd.setCursor(0, row);
+  for(int i = 0; i < fullBars; i++) {
+    lcd.write(byte(4));
+  }
+  if(partialBars > 0) {
+    lcd.write(byte(partialBars - 1));
+  }
+}
+
+void setBacklight(uint8_t r, uint8_t g, uint8_t b) {
+  // normalize the red LED - its brighter than the rest!
+  r = map(r, 0, 255, 0, 100);
+  g = map(g, 0, 255, 0, 150);
+  r = map(r, 0, 255, 0, brightness);
+  g = map(g, 0, 255, 0, brightness);
+  b = map(b, 0, 255, 0, brightness);
+  // common anode so invert!
+  r = map(r, 0, 255, 255, 0);
+  g = map(g, 0, 255, 255, 0);
+  b = map(b, 0, 255, 255, 0);
+  analogWrite(REDLITE, r);
+  analogWrite(GREENLITE, g);
+  analogWrite(BLUELITE, b);
+}
+


Create constants.ino

Create constants.ino

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

--- constants.ino
+++ constants.ino
@@ -0,0 +1,21 @@
+// Geometric constants (in mm):
+float L = 50; // This assumes all upper links are the same length
+float l = 50; // This assumes all parallelograms are the same length
+float h = 15; // Parallelogram width
+float sB = 70; // Length of side of base triangle
+float sP = 30; // Length of side of actuator triangle
+
+// Personal preference constants:
+float distThresh = 2.0; // If a move travels more mm than this, break it up into segments
+float rotvel = 0.3; // servo rotational velocity (in deg/ms)
+float zMax = 20;   // farthest up (in mm) that the end effector will go
+float zMin; float xMax; float xMin; float yMax; float yMin; // eventually i should figure these out too
+
+// Do-not-touch constants:
+float wB = sB/(2*sqrt(3)); // Assumes equilateral triangle
+float uB = 2*wB;
+float wP = sP/(2*sqrt(3)); // Assumes equilateral triangle
+float uP = 2*wP;
+float a = wB - uP;
+float b = sP/2 - (wB*sqrt(3)/2);
+float c = wP - wB/2;


Adding SparkCore ino file

Adding SparkCore ino file

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

--- sparkcore/beakn.sparkcore.ino
+++ sparkcore/beakn.sparkcore.ino
@@ -0,0 +1,33 @@
+int red = 5;
+int yellow = 6;
+int green = 7;
+
+void setup()
+{
+  Spark.function("setStatus", setStatus);
+
+  pinMode(red, OUTPUT);
+  pinMode(yellow, OUTPUT);
+  pinMode(green, OUTPUT);
+}
+
+void loop()
+{
+}
+
+int setStatus(String status)
+{
+  digitalWrite(red, LOW);
+  digitalWrite(yellow, LOW);
+  digitalWrite(green, LOW);
+
+  if(status == "Busy" || status == "DoNotDisturb"){
+    digitalWrite(red, HIGH);
+  }else if(status == "Away" || status == "TemporarilyAway"){
+    digitalWrite(yellow, HIGH);
+  }else if (status == "Free"){
+    digitalWrite(green, HIGH);
+  }
+
+  return 1;
+}


anavi-led-dimmer: Add anavi-led-dimmer.ino

Add Arduino sketch to control a single channel LED strip with a
potentiometer and a button.

Signed-off-by: Leon Anavi <be92910ae7bb6f58bb9b7c6f845bc30640119592@anavi.org>

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

--- anavi-led-dimmer/anavi-led-dimmer/anavi-led-dimmer.ino
+++ anavi-led-dimmer/anavi-led-dimmer/anavi-led-dimmer.ino
@@ -0,0 +1,47 @@
+// Pin for the button
+#define BUT 1
+// Pin to drive the LED strip
+#define PWM 0
+// Analog 1 corresponds to pin PB2
+#define POT 1
+
+int potValue = 0;
+
+// the current state of LED
+int ledState = HIGH;
+// the previous state of button
+int lastButtonState = HIGH;
+// the current state of button
+int currentButtonState = HIGH;
+
+void setup()
+{
+	pinMode(BUT, INPUT_PULLUP);
+	currentButtonState = digitalRead(BUT);
+	pinMode(PWM, OUTPUT);
+}
+
+void loop()
+{
+	lastButtonState = currentButtonState;
+	// Check the status of the button
+	currentButtonState = digitalRead(BUT);
+	if ( (HIGH == lastButtonState) && (LOW == currentButtonState) )
+	{
+		// toggle state of LED
+		ledState = !ledState;
+	}
+
+	if (LOW == ledState)
+	{
+		// Turn off the LED strip
+		analogWrite(PWM, 0);
+	}
+	else
+	{
+		// Read potentiometer value in range 0 - 1024
+		// and map it to the LED
+		potValue = map(analogRead(1), 0, 1023, 0, 255);
+		analogWrite(PWM, potValue);
+	}
+}


Added Arduino code

Added Arduino code

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

--- arduino/hawk/hawk.ino
+++ arduino/hawk/hawk.ino
@@ -0,0 +1,121 @@
+/*
+  Arduino code part of the Ra project.
+  Copyright OKso http://okso.me, All rights reserved.
+
+  This program provides a Serial interface to various Arduino functions such as:
+   - controlling remote switches via RCSwitch
+   - controlling LEDs
+   (future) - sensing temperature
+   (future) - sensing light
+
+  Protocol:
+  - w + action: turn ON (1) of OFF (0) the current plug (eg: w0, w1)
+  - n + network ID: change current network ID (eg: n00001)
+  - p + plug ID: change current plug ID (eg: p00010)
+  - l: switch ON a LED
+  - f: switch OFF a LED
+*/
+
+#include <RCSwitch.h>
+
+RCSwitch mySwitch = RCSwitch();
+
+char inByte;
+
+/* Modes :
+- 'w': waiting for message
+- 'n': switch, waiting for network ID
+- 'p': switch, waiting for plug ID
+- 'l': switch on a LED
+- 'f': switch off a LED
+*/
+char MODE = 'w';
+
+char network_id[5+1] = "00001";
+char plug_id[5+1] = "00010";
+
+void setup() {
+  MODE = 'w';
+
+  pinMode(9, OUTPUT);
+  pinMode(10, OUTPUT);
+  digitalWrite(9, LOW);
+  digitalWrite(10, HIGH);
+  // Transmitter is connected to Arduino Pin #10
+  mySwitch.enableTransmit(11);
+
+  Serial.begin(9600);
+  Serial.println("Welcome.");
+  Serial.print("net = ");
+  Serial.println(network_id);
+  Serial.print("plug = ");
+  Serial.println(plug_id);
+}
+
+void loop() {
+
+  if (Serial.available() > 0) {
+
+    if (MODE == 'n') {
+      Serial.readBytesUntil('\n', network_id, 5);
+      MODE = 'w';
+      Serial.print("net = ");
+      Serial.println(network_id);
+    }
+    else if (MODE == 'p') {
+      Serial.readBytesUntil('\n', plug_id, 5);
+      MODE = 'w';
+      Serial.print("plug = ");
+      Serial.println(plug_id);
+    }
+    else if (MODE == 'l') {
+      inByte = Serial.read();
+      if (inByte == '0') {
+        digitalWrite(13, HIGH);
+        MODE = 'w';
+        Serial.print("LED ON = ");
+        Serial.println(inByte);
+      }
+      else {
+        Serial.println("LED ON error");
+      }
+    }
+    else if (MODE == 'f') {
+      inByte = Serial.read();
+      if (inByte == '0') {
+        digitalWrite(13, LOW);
+        MODE = 'w';
+        Serial.print("LED OFF = ");
+        Serial.println(inByte);
+      }
+      else {
+        Serial.println("LED ON error");
+      }
+    }
+    else if (MODE == 'w') {
+
+      inByte = Serial.read();
+
+      if (inByte == '1') {
+        mySwitch.switchOn(network_id, plug_id);
+        Serial.println("on");
+      }
+      else if (inByte == '0') {
+        mySwitch.switchOff(network_id, plug_id);
+        Serial.println("off");
+      }
+      else if (inByte == 'w' || inByte == 'n' || inByte == 'p' || inByte == 'l' || inByte == 'f') {
+        MODE = inByte;
+        Serial.println("mode");
+      }
+      else {
+        MODE = 'w';
+        Serial.println("Debug info:");
+        Serial.print("net = ");
+        Serial.println(network_id);
+        Serial.print("plug = ");
+        Serial.println(plug_id);
+      }
+    }
+  }
+}


import SumoCollisionDetect example

import SumoCollisionDetect example

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

--- ZumoExamples/examples/SumoCollisionDetect/SumoCollisionDetect.ino
+++ ZumoExamples/examples/SumoCollisionDetect/SumoCollisionDetect.ino
@@ -0,0 +1,485 @@
+#include <ZumoBuzzer.h>
+#include <ZumoMotors.h>
+#include <Pushbutton.h>
+#include <QTRSensors.h>
+#include <ZumoReflectanceSensorArray.h>
+#include <avr/pgmspace.h>
+#include <Wire.h>
+#include <LSM303.h>
+
+/* This example uses the accelerometer in the Zumo Shield's onbaord LSM303DLHC with the LSM303 Library to
+ * detect contact with an adversary robot in the sumo ring. The LSM303 Library is not included in the Zumo
+ * Shield libraries; it can be downloaded separately from GitHub at:
+ *
+ *    https://github.com/pololu/LSM303
+ *
+ * This example extends the BorderDetect example, which makes use of the onboard Zumo Reflectance Sensor Array
+ * and its associated library to detect the border of the sumo ring.  It also illustrates the use of the
+ * ZumoMotors, PushButton, and ZumoBuzzer libaries.
+ *
+ * In loop(), the program reads the x and y components of acceleration (ignoring z), and detects a
+ * contact when the magnitude of the 3-period average of the x-y vector exceeds an empirically determined
+ * XY_ACCELERATION_THRESHOLD.  On contact detection, the forward speed is increased to FULL_SPEED from
+ * the default SEARCH_SPEED, simulating a "fight or flight" response.
+ *
+ * The program attempts to detect contact only when the Zumo is going straight.  When it is executing a
+ * turn at the sumo ring border, the turn itself generates an acceleration in the x-y plane, so the
+ * acceleration reading at that time is difficult to interpret for contact detection.  Since the Zumo also
+ * accelerates forward out of a turn, the acceleration readings are also ignored for MIN_DELAY_AFTER_TURN
+ * milliseconds after completing a turn. To further avoid false positives, a MIN_DELAY_BETWEEN_CONTACTS is
+ * also specified.
+ *
+ * This example also contains the following enhancements:
+ *
+ *  - uses the Zumo Buzzer libary to play a sound effect ("charge" melody) at start of competition and
+ *    whenever contact is made with an opposing robot
+ *
+ *  - randomizes the turn angle on border detection, so that the Zumo executes a more effective search pattern
+ *
+ *  - supports a FULL_SPEED_DURATION_LIMIT, allowing the robot to switch to a SUSTAINED_SPEED after a short
+ *    period of forward movement at FULL_SPEED.  In the example, both speeds are set to 400 (max), but this
+ *    feature may be useful to prevent runoffs at the turns if the sumo ring surface is unusually smooth.
+ *
+ *  - logging of accelerometer output to the serial monitor when LOG_SERIAL is #defined.
+ *
+ *  This example also makes use of the public domain RunningAverage library from the Arduino website; the relevant
+ *  code has been copied into this .ino file and does not need to be downloaded separately.
+ */
+
+// #define LOG_SERIAL // write log output to serial port
+
+#define LED 13
+Pushbutton button(ZUMO_BUTTON); // pushbutton on pin 12
+
+// Accelerometer Settings
+#define RA_SIZE 3  // number of readings to include in running average of accelerometer readings
+#define XY_ACCELERATION_THRESHOLD 150  // for detection of contact (1000 = magnitude of acceleration due to gravity)
+
+// Reflectance Sensor Settings
+#define NUM_SENSORS 6
+unsigned int sensor_values[NUM_SENSORS];
+// this might need to be tuned for different lighting conditions, surfaces, etc.
+#define QTR_THRESHOLD  1500 // microseconds
+ZumoReflectanceSensorArray sensors(QTR_NO_EMITTER_PIN);
+
+// Motor Settings
+ZumoMotors motors;
+
+// these might need to be tuned for different motor types
+#define REVERSE_SPEED     200 // 0 is stopped, 400 is full speed
+#define TURN_SPEED        200
+#define SEARCH_SPEED      200
+#define SUSTAINED_SPEED   400 // switches to SUSTAINED_SPEEND from FULL_SPEED after FULL_SPEED_DURATION_LIMIT ms
+#define FULL_SPEED        400
+#define STOP_DURATION     100 // ms
+#define REVERSE_DURATION  200 // ms
+#define TURN_DURATION     300 // ms
+
+#define RIGHT 1
+#define LEFT -1
+
+enum ForwardSpeed { SearchSpeed, SustainedSpeed, FullSpeed };
+ForwardSpeed _forwardSpeed;  // current forward speed setting
+unsigned long full_speed_start_time;
+#define FULL_SPEED_DURATION_LIMIT     250  // ms
+
+// Sound Effects
+ZumoBuzzer buzzer;
+const char sound_effect[] PROGMEM = "O4 T100 V15 L4 MS g12>c12>e12>G6>E12 ML>G2"; // "charge" melody
+ // use V0 to suppress sound effect; v15 for max volume
+
+ // Timing
+unsigned long loop_start_time;
+unsigned long last_turn_time;
+unsigned long contact_made_time;
+#define MIN_DELAY_AFTER_TURN          400  // ms = min delay before detecting contact event
+#define MIN_DELAY_BETWEEN_CONTACTS   1000  // ms = min delay between detecting new contact event
+
+// RunningAverage class
+// based on RunningAverage library for Arduino
+// source:  http://playground.arduino.cc/Main/RunningAverage
+template <typename T>
+class RunningAverage
+{
+  public:
+    RunningAverage(void);
+    RunningAverage(int);
+    ~RunningAverage();
+    void clear();
+    void addValue(T);
+    T getAverage() const;
+    void fillValue(T, int);
+  protected:
+    int _size;
+    int _cnt;
+    int _idx;
+    T _sum;
+    T * _ar;
+    static T zero;
+};
+
+// Accelerometer Class -- extends the LSM303 Library to support reading and averaging the x-y acceleration
+//   vectors from the onboard LSM303DLHC accelerometer/magnetometer
+class Accelerometer : public LSM303
+{
+  typedef struct acc_data_xy
+  {
+    unsigned long timestamp;
+    int x;
+    int y;
+    float dir;
+  } acc_data_xy;
+
+  public:
+    Accelerometer() : ra_x(RA_SIZE), ra_y(RA_SIZE) {};
+    ~Accelerometer() {};
+    void enable(void);
+    void getLogHeader(void);
+    void readAcceleration(unsigned long timestamp);
+    float len_xy() const;
+    float dir_xy() const;
+    int x_avg(void) const;
+    int y_avg(void) const;
+    long ss_xy_avg(void) const;
+    float dir_xy_avg(void) const;
+  private:
+    acc_data_xy last;
+    RunningAverage<int> ra_x;
+    RunningAverage<int> ra_y;
+};
+
+Accelerometer lsm303;
+boolean in_contact;  // set when accelerometer detects contact with opposing robot
+
+// forward declaration
+void setForwardSpeed(ForwardSpeed speed);
+
+void setup()
+{
+  // Initiate the Wire library and join the I2C bus as a master
+  Wire.begin();
+
+  // Initiate LSM303
+  lsm303.init();
+  lsm303.enable();
+
+#ifdef LOG_SERIAL
+  Serial.begin(9600);
+  lsm303.getLogHeader();
+#endif
+
+  randomSeed((unsigned int) millis());
+
+  // uncomment if necessary to correct motor directions
+  //motors.flipLeftMotor(true);
+  //motors.flipRightMotor(true);
+
+  pinMode(LED, HIGH);
+  buzzer.playMode(PLAY_AUTOMATIC);
+  waitForButtonAndCountDown(false);
+}
+
+void waitForButtonAndCountDown(bool restarting)
+{
+#ifdef LOG_SERIAL
+  Serial.print(restarting ? "Restarting Countdown" : "Starting Countdown");
+  Serial.println();
+#endif
+
+  digitalWrite(LED, HIGH);
+  button.waitForButton();
+  digitalWrite(LED, LOW);
+
+  // play audible countdown
+  for (int i = 0; i < 3; i++)
+  {
+    delay(1000);
+    buzzer.playNote(NOTE_G(3), 50, 12);
+  }
+  delay(1000);
+  buzzer.playFromProgramSpace(sound_effect);
+  delay(1000);
+
+  // reset loop variables
+  in_contact = false;  // 1 if contact made; 0 if no contact or contact lost
+  contact_made_time = 0;
+  last_turn_time = millis();  // prevents false contact detection on initial acceleration
+  _forwardSpeed = SearchSpeed;
+  full_speed_start_time = 0;
+}
+
+void loop()
+{
+  if (button.isPressed())
+  {
+    // if button is pressed, stop and wait for another press to go again
+    motors.setSpeeds(0, 0);
+    button.waitForRelease();
+    waitForButtonAndCountDown(true);
+  }
+
+  loop_start_time = millis();
+  lsm303.readAcceleration(loop_start_time);
+  sensors.read(sensor_values);
+
+  if ((_forwardSpeed == FullSpeed) && (loop_start_time - full_speed_start_time > FULL_SPEED_DURATION_LIMIT))
+  {
+    setForwardSpeed(SustainedSpeed);
+  }
+
+  if (sensor_values[0] < QTR_THRESHOLD)
+  {
+    // if leftmost sensor detects line, reverse and turn to the right
+    turn(RIGHT, true);
+  }
+  else if (sensor_values[5] < QTR_THRESHOLD)
+  {
+    // if rightmost sensor detects line, reverse and turn to the left
+    turn(LEFT, true);
+  }
+  else  // otherwise, go straight
+  {
+    if (check_for_contact()) on_contact_made();
+    int speed = getForwardSpeed();
+    motors.setSpeeds(speed, speed);
+  }
+}
+
+// execute turn
+// direction:  RIGHT or LEFT
+// randomize: to improve searching
+void turn(char direction, bool randomize)
+{
+#ifdef LOG_SERIAL
+  Serial.print("turning ...");
+  Serial.println();
+#endif
+
+  // assume contact lost
+  on_contact_lost();
+
+  static unsigned int duration_increment = TURN_DURATION / 4;
+
+  // motors.setSpeeds(0,0);
+  // delay(STOP_DURATION);
+  motors.setSpeeds(-REVERSE_SPEED, -REVERSE_SPEED);
+  delay(REVERSE_DURATION);
+  motors.setSpeeds(TURN_SPEED * direction, -TURN_SPEED * direction);
+  delay(randomize ? TURN_DURATION + (random(8) - 2) * duration_increment : TURN_DURATION);
+  int speed = getForwardSpeed();
+  motors.setSpeeds(speed, speed);
+  last_turn_time = millis();
+}
+
+void setForwardSpeed(ForwardSpeed speed)
+{
+  _forwardSpeed = speed;
+  if (speed == FullSpeed) full_speed_start_time = loop_start_time;
+}
+
+int getForwardSpeed()
+{
+  int speed;
+  switch (_forwardSpeed)
+  {
+    case FullSpeed:
+      speed = FULL_SPEED;
+      break;
+    case SustainedSpeed:
+      speed = SUSTAINED_SPEED;
+      break;
+    default:
+      speed = SEARCH_SPEED;
+      break;
+  }
+  return speed;
+}
+
+// check for contact, but ignore readings immediately after turning or losing contact
+bool check_for_contact()
+{
+  static long threshold_squared = (long) XY_ACCELERATION_THRESHOLD * (long) XY_ACCELERATION_THRESHOLD;
+  return (lsm303.ss_xy_avg() >  threshold_squared) && \
+    (loop_start_time - last_turn_time > MIN_DELAY_AFTER_TURN) && \
+    (loop_start_time - contact_made_time > MIN_DELAY_BETWEEN_CONTACTS);
+}
+
+// sound horn and accelerate on contact -- fight or flight
+void on_contact_made()
+{
+#ifdef LOG_SERIAL
+  Serial.print("contact made");
+  Serial.println();
+#endif
+  in_contact = true;
+  contact_made_time = loop_start_time;
+  setForwardSpeed(FullSpeed);
+  buzzer.playFromProgramSpace(sound_effect);
+}
+
+// reset forward speed
+void on_contact_lost()
+{
+#ifdef LOG_SERIAL
+  Serial.print("contact lost");
+  Serial.println();
+#endif
+  in_contact = false;
+  setForwardSpeed(SearchSpeed);
+}
+
+// class Accelerometer -- member function definitions
+
+// enable accelerometer only
+// to enables both accelerometer and magnetometer, call enableDefault() instead
+void Accelerometer::enable(void)
+{
+  // Enable Accelerometer
+  // 0x27 = 0b00100111
+  // Normal power mode, all axes enabled
+  writeAccReg(LSM303_CTRL_REG1_A, 0x27);
+
+  if (getDeviceType() == LSM303DLHC_DEVICE)
+  writeAccReg(LSM303_CTRL_REG4_A, 0x08); // DLHC: enable high resolution mode
+}
+
+void Accelerometer::getLogHeader(void)
+{
+  Serial.print("millis    x      y     len     dir  | len_avg  dir_avg  |  avg_len");
+  Serial.println();
+}
+
+void Accelerometer::readAcceleration(unsigned long timestamp)
+{
+  readAcc();
+  int a_x = static_cast<int>(a.x);
+  int a_y = static_cast<int>(a.y);
+  if (a_x == last.x && a_y == last.y) return;
+
+  last.timestamp = timestamp;
+  last.x = a_x;
+  last.y = a_y;
+
+  ra_x.addValue(last.x);
+  ra_y.addValue(last.y);
+
+#ifdef LOG_SERIAL
+ Serial.print(last.timestamp);
+ Serial.print("  ");
+ Serial.print(last.x);
+ Serial.print("  ");
+ Serial.print(last.y);
+ Serial.print("  ");
+ Serial.print(len_xy());
+ Serial.print("  ");
+ Serial.print(dir_xy());
+ Serial.print("  |  ");
+ Serial.print(sqrt(static_cast<float>(ss_xy_avg())));
+ Serial.print("  ");
+ Serial.print(dir_xy_avg());
+ Serial.println();
+#endif
+}
+
+float Accelerometer::len_xy() const
+{
+  return sqrt(last.x*a.x + last.y*a.y);
+}
+
+float Accelerometer::dir_xy() const
+{
+  return atan2(last.x, last.y) * 180.0 / M_PI;
+}
+
+int Accelerometer::x_avg(void) const
+{
+  return ra_x.getAverage();
+}
+
+int Accelerometer::y_avg(void) const
+{
+  return ra_y.getAverage();
+}
+
+long Accelerometer::ss_xy_avg(void) const
+{
+  long x_avg_long = static_cast<long>(x_avg());
+  long y_avg_long = static_cast<long>(y_avg());
+  return x_avg_long*x_avg_long + y_avg_long*y_avg_long;
+}
+
+float Accelerometer::dir_xy_avg(void) const
+{
+  return atan2(static_cast<float>(x_avg()), static_cast<float>(y_avg())) * 180.0 / M_PI;
+}
+
+
+
+// RunningAverage class
+// based on RunningAverage library for Arduino
+// source:  http://playground.arduino.cc/Main/RunningAverage
+// author:  Rob.Tillart@gmail.com
+// Released to the public domain
+
+template <typename T>
+T RunningAverage<T>::zero = static_cast<T>(0);
+
+template <typename T>
+RunningAverage<T>::RunningAverage(int n)
+{
+  _size = n;
+  _ar = (T*) malloc(_size * sizeof(T));
+  clear();
+}
+
+template <typename T>
+RunningAverage<T>::~RunningAverage()
+{
+  free(_ar);
+}
+
+// resets all counters
+template <typename T>
+void RunningAverage<T>::clear()
+{
+  _cnt = 0;
+  _idx = 0;
+  _sum = zero;
+  for (int i = 0; i< _size; i++) _ar[i] = zero;  // needed to keep addValue simple
+}
+
+// adds a new value to the data-set
+template <typename T>
+void RunningAverage<T>::addValue(T f)
+{
+  _sum -= _ar[_idx];
+  _ar[_idx] = f;
+  _sum += _ar[_idx];
+  _idx++;
+  if (_idx == _size) _idx = 0;  // faster than %
+  if (_cnt < _size) _cnt++;
+}
+
+// returns the average of the data-set added sofar
+template <typename T>
+T RunningAverage<T>::getAverage() const
+{
+  if (_cnt == 0) return zero; // NaN ?  math.h
+  return _sum / _cnt;
+}
+
+// fill the average with a value
+// the param number determines how often value is added (weight)
+// number should preferably be between 1 and size
+template <typename T>
+void RunningAverage<T>::fillValue(T value, int number)
+{
+  clear();
+  for (int i = 0; i < number; i++)
+  {
+    addValue(value);
+  }
+}
+
+
+


Established YunHub_MASTER as master file - versioning via git

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

--- projects/YunHub/YunHub_MASTER/YunHub_MASTER.ino
+++ projects/YunHub/YunHub_MASTER/YunHub_MASTER.ino
@@ -0,0 +1,210 @@
+//
+// Receive RFM12B packets and publish to  MQTT server 192.168.178.27
+//
+// only for dedicated senders:
+//
+// 1) Temperature Node (group 33, node 22)
+//      --> time stamp, RF12 group ID, node ID, Vcc, T1, T2
+// 2) RadioBlip2 (group 33, id 17)
+//
+// Blink LED #13 for each package received
+//
+#define PROGRAMVERSION "150919 YunHub 1.07"
+
+#include <Bridge.h>
+#include <JeeLib.h>
+#include <YunClient.h>
+#include <PubSubClient.h>
+
+byte rf12_group, rf12_nodeid;
+String timeStamp, dataStr, rawdataStr;
+char message_buff[100];
+
+// Update these with values suitable for your network.
+byte server[] = { 192, 168, 178, 27 };
+
+
+// Temperature node data structure. Timestamp created locally, at time of receival.
+struct
+{
+  String timeStamp;   // "+%Y-%m-%d %T": format "YYYY-MM-DD hh:mm:ss"
+  byte rf12_group;    // RF12 group ID
+  byte rf12_nodeid;   // RF12 node ID
+  float Vcc;          // Supply voltage
+  float T1;            // Temperature reading
+  float T2;            // Temperature reading
+} TNodeData;
+
+
+// RadioBlip2 data structure. Timestamp created locally, at time of receival.
+struct
+{
+  String timeStamp;   // "+%Y-%m-%d %T": format "YYYY-MM-DD hh:mm:ss"
+  byte rf12_group;    // RF12 group ID
+  byte rf12_nodeid;   // RF12 node ID
+  float Vcc;          // Supply voltage
+} RadioBlip2Data;
+
+
+// ===========================================================
+// MQTT callback function, called for incoming messages
+// ===========================================================
+void callback(char *topic, byte *payload, unsigned int length)
+{
+  // counter
+  int i = 0;
+  // buffer for payload-to-string conversion
+  char message_buff[100];
+
+  // copy payload to buffer, append \0
+  for (i = 0; i < length; i++)
+  {
+    message_buff[i] = payload[i];
+  }
+  message_buff[i] = '\0';
+}
+
+YunClient yun;
+PubSubClient client(server, 1883, callback, yun);
+
+void setup ()
+{
+  // start-up the Yun bridge
+  Bridge.begin();
+  delay(2000);
+
+  Serial.begin(57600);
+  Serial.println("***");
+  Serial.print("*** ");
+  Serial.println(PROGRAMVERSION);
+  Serial.println("***");
+
+  // initialize digital pin 13 as an output.
+  pinMode(13, OUTPUT);
+
+  rf12_initialize(1, RF12_868MHZ, 0); // group id = 0 to receive from all groups
+
+  // Connect to MQTT server if not available
+  client.connect("arduinoYunClient");
+  client.publish("ConnectMessage", "YunChen setup: connected.");
+}
+
+
+void loop ()
+{
+  client.loop();
+
+  if (rf12_recvDone() && rf12_crc == 0)
+  {
+    digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
+
+    // Connect to MQTT server if connection was lost
+    if (!client.connected())
+    {
+      client.connect("arduinoYunClient");
+      client.publish("ConnectMessage", "YunChen loop: reconnected.");
+    }
+
+    // identify sender via group & nodeid
+    // node id is in the first 5 bits of rf12_hdr --> & RF12_HDR_MASK
+    rf12_group = rf12_grp;
+    rf12_nodeid = rf12_hdr & RF12_HDR_MASK;
+    timeStamp = getTimeStamp();
+
+
+    ////////////////////////////////////
+    //  Raw Data (group ALL, id ALL)  //
+    ////////////////////////////////////
+
+    /* remove raw data log since it freezes for long data strings
+    rawdataStr = timeStamp + ","
+                 + String(rf12_group) + ","
+                 + String(rf12_nodeid);
+    for (byte i = 0; i < rf12_len; ++i)
+    {
+      rawdataStr += ",";
+      rawdataStr += rf12_data[i];
+    }
+
+    // publish to MQTT server
+    char charBuf[rawdataStr.length()];
+    rawdataStr.toCharArray(charBuf, rawdataStr.length());
+    client.publish("RF12_RawData", charBuf);
+    */
+
+
+    ///////////////////////////////
+    //  TNode (group 33, id 22)  //
+    ///////////////////////////////
+    if (rf12_group == 33 and rf12_nodeid == 22)
+    {
+      TNodeData.rf12_group = rf12_group;
+      TNodeData.rf12_nodeid = rf12_nodeid;
+      TNodeData.timeStamp = timeStamp;
+      TNodeData.Vcc = int(word(rf12_data[1], rf12_data[0])) / 1000.0;
+      TNodeData.T1 = int(word(rf12_data[3], rf12_data[2])) / 100.0;
+      TNodeData.T2 = int(word(rf12_data[5], rf12_data[4])) / 100.0;
+
+      dataStr = TNodeData.timeStamp + ","
+                + String(TNodeData.rf12_group) + ","
+                + String(TNodeData.rf12_nodeid) + ","
+                + String(TNodeData.Vcc) + ","
+                + String(TNodeData.T1) + ","
+                + String(TNodeData.T2);
+
+      // publish interpreted TNode data to MQTT server
+      char charBuf[dataStr.length() + 1];
+      dataStr.toCharArray(charBuf, dataStr.length());
+      client.publish("TNode", charBuf);
+    }
+
+    ////////////////////////////////////
+    //  RadioBlip2 (group 33, id 17)  //
+    ////////////////////////////////////
+    if (rf12_group == 33 and rf12_nodeid == 17)
+    {
+      RadioBlip2Data.rf12_group = rf12_group;
+      RadioBlip2Data.rf12_nodeid = rf12_nodeid;
+      RadioBlip2Data.timeStamp = timeStamp;
+      RadioBlip2Data.Vcc = 1.0 + rf12_data[5] * 0.02;
+
+      dataStr = RadioBlip2Data.timeStamp + ","
+                + String(RadioBlip2Data.rf12_group) + ","
+                + String(RadioBlip2Data.rf12_nodeid) + ","
+                + String(RadioBlip2Data.Vcc);
+
+      // publish interpreted TNode data to MQTT server
+      char charBuf[dataStr.length() + 1];
+      dataStr.toCharArray(charBuf, dataStr.length());
+      client.publish("RadioBlip2", charBuf);
+    }
+    digitalWrite(13, LOW);   // turn the LED off (HIGH is the voltage level)
+  }
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+// This function returns a string with the time stamp
+String getTimeStamp()
+{
+  String result;
+  Process time;
+  // date is a command line utility to get the date and the time
+  // in different formats depending on the additional parameter
+  time.begin("date");
+  time.addParameter("+%Y-%m-%d %T");  // parameters: D for the complete date mm/dd/yy, T for the time hh:mm:ss
+  time.run();  // run the command
+
+  // read the output of the command
+  while (time.available() > 0)
+  {
+    char c = time.read();
+    if (c != '\n')
+      result += c;
+  }
+
+  return result;
+}
+


Create WaterQualityMonitor.ino

Create WaterQualityMonitor.ino

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

--- playground/playground/WaterQualityMonitor/WaterQualityMonitor.ino
+++ playground/playground/WaterQualityMonitor/WaterQualityMonitor.ino
@@ -0,0 +1 @@
+


this should not cut corners …

this should not cut corners …


Motorz

Motorz

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

--- Motors_Prototype/Motors_Prototype.ino
+++ Motors_Prototype/Motors_Prototype.ino
@@ -0,0 +1,150 @@
+/*
+  Receiving Motor Code
+  Attempt 1 of mutliaxis support in order to make JP happy
+
+  Written for the Sea Sweepers ROV Club
+  Michael Georgariou 2016
+*/
+
+#include <Servo.h>
+Servo H1;
+Servo H2;
+Servo H3;
+Servo H4;
+Servo V1;
+Servo V2;
+Servo V3;
+Servo V4;
+
+int Joystick1A; //vertical
+  int 1AMap;
+int Joystick1B;
+  int 1BMap;
+int Joystick1C;
+  int 1CMap;
+int Joystick2A; //horizontal
+  int 2AMap;
+int Joystick2B;
+  int 2BMap;
+int Joystick2C;
+  int 2CMap;
+
+int Crab;
+int Pitch;
+
+void setup() {
+
+  H1.attach(2); // left front
+  H2.attach(3); // right front
+  H3.attach(4); // right back
+  H4.attach(5); // left back
+  V1.attach(6);
+  V2.attach(7);
+  V3.attach(8);
+  V4.attach(9);
+}
+
+void loop() {
+  1AMap = map(Joystick1A, 0, 1023, 1100, 1900);
+  1BMap = map(Joystick1B, 0, 1023, 1100, 1900);
+  1CMap = map(Joystick1C, 0, 1023, 1100, 1900);
+  2AMap = map(Joystick2A, 0, 1023, 1100, 1900);
+  2BMap = map(Joystick2B, 0, 1023, 1100, 1900);
+  2CMap = map(Joystick2C, 0, 1023, 1100, 1900);
+
+
+  if ((2CMap < 1600) && (2CMap > 1400)) { //if 2CMap is neutral
+    H2.write(2AMap);
+    H3.write(2AMap);
+    H1.write(2BMap);
+    H4.write(2BMap);
+  }
+
+  if (2CMap > 1600) {
+    Crab = map(2CMap, 1600, 1900, 0, 400);
+    if ((2AMap - Crab) > 1100){
+      H2.write(2AMap + Crab);
+      H3.write(2AMap + Crab);
+    }
+    else {
+      H2.write(2AMap);
+      H3.write(2AMap);
+    }
+    if ((2BMap + Crab) < 1900) {
+      H1.write(2BMap - Crab);
+      H4.write(2BMap - Crab);
+    }
+    else {
+      H1.write(2BMap);
+      H4.write(2BMap);
+    }
+  }
+
+  if (2CMap < 1400) {
+    Crab = map(2CMap, 1400, 1100, 0, 400);
+    if ((2AMap - Crab) > 1100){
+      H2.write(2AMap - Crab);
+      H3.write(2AMap - Crab);
+    }
+    else {
+      H2.write(2AMap);
+      H3.write(2AMap);
+    }
+    if ((2BMap + Crab) < 1900) {
+      H1.write(2BMap + Crab);
+      H4.write(2BMap + Crab);
+    }
+    else {
+      H1.write(2BMap);
+      H4.write(2BMap);
+    }
+  }
+
+
+  if ((1CMap < 1600) && (1CMap > 1400)) { //if 2CMap is neutral
+    V2.write(1AMap);
+    V3.write(1AMap);
+    V1.write(1BMap);
+    V4.write(1BMap);
+  }
+  if (1CMap > 1600) {
+    Pitch = map(1CMap, 1600, 1900, 0, 400);
+    if ((2AMap + Pitch) < 1900){
+      H1.write(2AMap + Pitch);
+      H2.write(2AMap + Pitch);
+    }
+    else {
+      H1.write(2AMap);
+      H2.write(2AMap);
+    }
+    if ((2BMap - Pitch) > 1100) {
+      H3.write(2BMap - Pitch);
+      H4.write(2BMap - Pitch);
+    }
+    else {
+      H3.write(2BMap);
+      H4.write(2BMap);
+    }
+  }
+
+  if (2CMap < 1400) {
+    Pitch = map(2CMap, 1400, 1100, 0, 400);
+    if ((2AMap - Pitch) > 1100){
+      H1.write(2AMap - Pitch);
+      H2.write(2AMap - Pitch);
+    }
+    else {
+      H1.write(2AMap);
+      H2.write(2AMap);
+    }
+    if ((2BMap + Pitch) < 1900) {
+      H3.write(2BMap + Pitch);
+      H4.write(2BMap + Pitch);
+    }
+    else {
+      H3.write(2BMap);
+      H4.write(2BMap);
+    }
+  }
+}
+


Added example folder and test file

Added example folder and test file

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

--- RadiationBean/Examples/test.ino
+++ RadiationBean/Examples/test.ino
@@ -0,0 +1,7 @@
+void setup() {
+  /* code */
+}
+
+void loop() {
+  /* code */
+}


mario bross music

mario bross music

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

--- Mario_Ring/Mario_Ring.ino
+++ Mario_Ring/Mario_Ring.ino
@@ -0,0 +1,288 @@
+/*Arduino Mario Bros Tunes
+  With Piezo Buzzer and PWM
+
+  Connect the positive side of the Buzzer to pin 3,
+  then the negative side to a 1k ohm resistor. Connect
+  the other side of the 1 k ohm resistor to
+  ground(GND) pin on the Arduino.
+
+  by: Dipto Pratyaksa
+  last updated: 31/3/13
+*/
+
+/*************************************************
+ * Public Constants
+ *************************************************/
+
+#define NOTE_B0  31
+#define NOTE_C1  33
+#define NOTE_CS1 35
+#define NOTE_D1  37
+#define NOTE_DS1 39
+#define NOTE_E1  41
+#define NOTE_F1  44
+#define NOTE_FS1 46
+#define NOTE_G1  49
+#define NOTE_GS1 52
+#define NOTE_A1  55
+#define NOTE_AS1 58
+#define NOTE_B1  62
+#define NOTE_C2  65
+#define NOTE_CS2 69
+#define NOTE_D2  73
+#define NOTE_DS2 78
+#define NOTE_E2  82
+#define NOTE_F2  87
+#define NOTE_FS2 93
+#define NOTE_G2  98
+#define NOTE_GS2 104
+#define NOTE_A2  110
+#define NOTE_AS2 117
+#define NOTE_B2  123
+#define NOTE_C3  131
+#define NOTE_CS3 139
+#define NOTE_D3  147
+#define NOTE_DS3 156
+#define NOTE_E3  165
+#define NOTE_F3  175
+#define NOTE_FS3 185
+#define NOTE_G3  196
+#define NOTE_GS3 208
+#define NOTE_A3  220
+#define NOTE_AS3 233
+#define NOTE_B3  247
+#define NOTE_C4  262
+#define NOTE_CS4 277
+#define NOTE_D4  294
+#define NOTE_DS4 311
+#define NOTE_E4  330
+#define NOTE_F4  349
+#define NOTE_FS4 370
+#define NOTE_G4  392
+#define NOTE_GS4 415
+#define NOTE_A4  440
+#define NOTE_AS4 466
+#define NOTE_B4  494
+#define NOTE_C5  523
+#define NOTE_CS5 554
+#define NOTE_D5  587
+#define NOTE_DS5 622
+#define NOTE_E5  659
+#define NOTE_F5  698
+#define NOTE_FS5 740
+#define NOTE_G5  784
+#define NOTE_GS5 831
+#define NOTE_A5  880
+#define NOTE_AS5 932
+#define NOTE_B5  988
+#define NOTE_C6  1047
+#define NOTE_CS6 1109
+#define NOTE_D6  1175
+#define NOTE_DS6 1245
+#define NOTE_E6  1319
+#define NOTE_F6  1397
+#define NOTE_FS6 1480
+#define NOTE_G6  1568
+#define NOTE_GS6 1661
+#define NOTE_A6  1760
+#define NOTE_AS6 1865
+#define NOTE_B6  1976
+#define NOTE_C7  2093
+#define NOTE_CS7 2217
+#define NOTE_D7  2349
+#define NOTE_DS7 2489
+#define NOTE_E7  2637
+#define NOTE_F7  2794
+#define NOTE_FS7 2960
+#define NOTE_G7  3136
+#define NOTE_GS7 3322
+#define NOTE_A7  3520
+#define NOTE_AS7 3729
+#define NOTE_B7  3951
+#define NOTE_C8  4186
+#define NOTE_CS8 4435
+#define NOTE_D8  4699
+#define NOTE_DS8 4978
+
+#define melodyPin 10
+//Mario main theme melody
+int melody[] = {
+  NOTE_E7, NOTE_E7, 0, NOTE_E7,
+  0, NOTE_C7, NOTE_E7, 0,
+  NOTE_G7, 0, 0,  0,
+  NOTE_G6, 0, 0, 0,
+
+  NOTE_C7, 0, 0, NOTE_G6,
+  0, 0, NOTE_E6, 0,
+  0, NOTE_A6, 0, NOTE_B6,
+  0, NOTE_AS6, NOTE_A6, 0,
+
+  NOTE_G6, NOTE_E7, NOTE_G7,
+  NOTE_A7, 0, NOTE_F7, NOTE_G7,
+  0, NOTE_E7, 0, NOTE_C7,
+  NOTE_D7, NOTE_B6, 0, 0,
+
+  NOTE_C7, 0, 0, NOTE_G6,
+  0, 0, NOTE_E6, 0,
+  0, NOTE_A6, 0, NOTE_B6,
+  0, NOTE_AS6, NOTE_A6, 0,
+
+  NOTE_G6, NOTE_E7, NOTE_G7,
+  NOTE_A7, 0, NOTE_F7, NOTE_G7,
+  0, NOTE_E7, 0, NOTE_C7,
+  NOTE_D7, NOTE_B6, 0, 0
+};
+//Mario main them tempo
+int tempo[] = {
+  12, 12, 12, 12,
+  12, 12, 12, 12,
+  12, 12, 12, 12,
+  12, 12, 12, 12,
+
+  12, 12, 12, 12,
+  12, 12, 12, 12,
+  12, 12, 12, 12,
+  12, 12, 12, 12,
+
+  9, 9, 9,
+  12, 12, 12, 12,
+  12, 12, 12, 12,
+  12, 12, 12, 12,
+
+  12, 12, 12, 12,
+  12, 12, 12, 12,
+  12, 12, 12, 12,
+  12, 12, 12, 12,
+
+  9, 9, 9,
+  12, 12, 12, 12,
+  12, 12, 12, 12,
+  12, 12, 12, 12,
+};
+//Underworld melody
+int underworld_melody[] = {
+  NOTE_C4, NOTE_C5, NOTE_A3, NOTE_A4,
+  NOTE_AS3, NOTE_AS4, 0,
+  0,
+  NOTE_C4, NOTE_C5, NOTE_A3, NOTE_A4,
+  NOTE_AS3, NOTE_AS4, 0,
+  0,
+  NOTE_F3, NOTE_F4, NOTE_D3, NOTE_D4,
+  NOTE_DS3, NOTE_DS4, 0,
+  0,
+  NOTE_F3, NOTE_F4, NOTE_D3, NOTE_D4,
+  NOTE_DS3, NOTE_DS4, 0,
+  0, NOTE_DS4, NOTE_CS4, NOTE_D4,
+  NOTE_CS4, NOTE_DS4,
+  NOTE_DS4, NOTE_GS3,
+  NOTE_G3, NOTE_CS4,
+  NOTE_C4, NOTE_FS4, NOTE_F4, NOTE_E3, NOTE_AS4, NOTE_A4,
+  NOTE_GS4, NOTE_DS4, NOTE_B3,
+  NOTE_AS3, NOTE_A3, NOTE_GS3,
+  0, 0, 0
+};
+//Underwolrd tempo
+int underworld_tempo[] = {
+  12, 12, 12, 12,
+  12, 12, 6,
+  3,
+  12, 12, 12, 12,
+  12, 12, 6,
+  3,
+  12, 12, 12, 12,
+  12, 12, 6,
+  3,
+  12, 12, 12, 12,
+  12, 12, 6,
+  6, 18, 18, 18,
+  6, 6,
+  6, 6,
+  6, 6,
+  18, 18, 18, 18, 18, 18,
+  10, 10, 10,
+  10, 10, 10,
+  3, 3, 3
+};
+
+void setup(void)
+{
+  pinMode(10, OUTPUT);//buzzer
+  pinMode(13, OUTPUT);//led indicator when singing a note
+
+}
+void loop()
+{
+  //sing the tunes
+  sing(1);
+  sing(1);
+  sing(2);
+}
+int song = 0;
+
+void sing(int s) {
+  // iterate over the notes of the melody:
+  song = s;
+  if (song == 2) {
+    Serial.println(" 'Underworld Theme'");
+    int size = sizeof(underworld_melody) / sizeof(int);
+    for (int thisNote = 0; thisNote < size; thisNote++) {
+
+      // to calculate the note duration, take one second
+      // divided by the note type.
+      //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
+      int noteDuration = 1000 / underworld_tempo[thisNote];
+
+      buzz(melodyPin, underworld_melody[thisNote], noteDuration);
+
+      // to distinguish the notes, set a minimum time between them.
+      // the note's duration + 30% seems to work well:
+      int pauseBetweenNotes = noteDuration * 1.30;
+      delay(pauseBetweenNotes);
+
+      // stop the tone playing:
+      buzz(melodyPin, 0, noteDuration);
+
+    }
+
+  } else {
+
+    Serial.println(" 'Mario Theme'");
+    int size = sizeof(melody) / sizeof(int);
+    for (int thisNote = 0; thisNote < size; thisNote++) {
+
+      // to calculate the note duration, take one second
+      // divided by the note type.
+      //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
+      int noteDuration = 1000 / tempo[thisNote];
+
+      buzz(melodyPin, melody[thisNote], noteDuration);
+
+      // to distinguish the notes, set a minimum time between them.
+      // the note's duration + 30% seems to work well:
+      int pauseBetweenNotes = noteDuration * 1.30;
+      delay(pauseBetweenNotes);
+
+      // stop the tone playing:
+      buzz(melodyPin, 0, noteDuration);
+
+    }
+  }
+}
+
+void buzz(int targetPin, long frequency, long length) {
+  digitalWrite(13, HIGH);
+  long delayValue = 1000000 / frequency / 2; // calculate the delay value between transitions
+  //// 1 second's worth of microseconds, divided by the frequency, then split in half since
+  //// there are two phases to each cycle
+  long numCycles = frequency * length / 1000; // calculate the number of cycles for proper timing
+  //// multiply frequency, which is really cycles per second, by the number of seconds to
+  //// get the total number of cycles to produce
+  for (long i = 0; i < numCycles; i++) { // for the calculated length of time...
+    digitalWrite(targetPin, HIGH); // write the buzzer pin high to push out the diaphram
+    delayMicroseconds(delayValue); // wait for the calculated delay value
+    digitalWrite(targetPin, LOW); // write the buzzer pin low to pull back the diaphram
+    delayMicroseconds(delayValue); // wait again or the calculated delay value
+  }
+  digitalWrite(13, LOW);
+
+}


poscomp is applied directly …

poscomp is applied directly …


Added files via upload

Added files via upload

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

--- taqi/taqi.ino
+++ taqi/taqi.ino
@@ -0,0 +1,358 @@
+//#define __DEBUG__
+
+#define threshold 500
+#define baud 9600
+#define short_del 500
+#define long_del 2000
+
+const unsigned int red[] = {10, 7, 2, 13}; //r1, r2, r3, r4
+const unsigned int yellow[] = {9, 6, 3, 12};
+const unsigned int green[] = {8, 5, 4, 11};
+const unsigned int ir[] = {A2, A3, A1, A0};
+
+bool reading[] = {false, false, false, false};
+
+enum LIGHT {FIRST = 0, SECOND = 1, THIRD = 2, FOURTH = 3, NONE = 4};
+
+LIGHT light;
+
+int index = 4;
+
+void debug(void){
+  Serial.println (" == DEBUG BEGIN == ");
+  for (int i = 0; i < 4; i++){
+    Serial.println("IR [ " + String(i) + "] = " + String(analogRead(ir[i])));
+    delay(short_del);
+  }
+  Serial.println (" == DEBUG END == ");
+  Serial.println();
+  delay(long_del);
+}
+
+void setup() {
+  Serial.begin(baud);
+  for (int i = 0; i < 4; i++){
+    pinMode(red[i], OUTPUT);
+    pinMode(yellow[i], OUTPUT);
+    pinMode(green[i], OUTPUT);
+    pinMode(ir[i], INPUT);
+  }
+}
+
+int whichLight(void){
+  if (analogRead(ir[0]) < threshold) return FIRST;
+  else if (analogRead(ir[1]) < threshold) return SECOND;
+  else if (analogRead(ir[2]) < threshold) return THIRD;
+  else if (analogRead(ir[3]) < threshold) return FOURTH;
+  else return NONE;
+}
+
+void offAll (void){
+  for (int i = 0; i < 4; i++){
+    digitalWrite (red[i], LOW);
+    digitalWrite (yellow[i], LOW);
+    digitalWrite (green[i], LOW);
+  }
+}
+
+void firstLight(void){
+  offAll();
+  digitalWrite (green[FIRST], HIGH);
+  digitalWrite(red[SECOND], HIGH);
+  digitalWrite(red[THIRD], HIGH);
+  digitalWrite(red[FOURTH], HIGH);
+}
+
+void secondLight(void){
+  offAll();
+  digitalWrite(green[SECOND], HIGH);
+  digitalWrite(red[FIRST], HIGH);
+  digitalWrite(red[THIRD], HIGH);
+  digitalWrite(red[FOURTH], HIGH);
+}
+
+
+void thirdLight(void){
+  offAll();
+  digitalWrite(green[THIRD], HIGH);
+  digitalWrite(red[FIRST], HIGH);
+  digitalWrite(red[SECOND], HIGH);
+  digitalWrite(red[FOURTH], HIGH);
+}
+
+void fourthLight(void){
+  offAll();
+  digitalWrite(green[FOURTH], HIGH);
+  digitalWrite(red[FIRST], HIGH);
+  digitalWrite(red[THIRD], HIGH);
+  digitalWrite(red[SECOND], HIGH);
+}
+
+
+void onAll(void){
+  for (int i = 0; i < 4; i++) {
+    digitalWrite(red[i], HIGH);
+    digitalWrite(yellow[i], HIGH);
+    digitalWrite(green[i], HIGH);
+  }
+}
+
+
+void onIdle(void){
+
+  index = whichLight();
+
+  // For first light
+  digitalWrite(green[FIRST], HIGH);
+  digitalWrite(red[SECOND], HIGH);
+  digitalWrite(red[THIRD], HIGH);
+  digitalWrite(red[FOURTH], HIGH);
+  delay(long_del);
+  digitalWrite(green[FIRST], LOW);
+  digitalWrite(red[SECOND], LOW);
+  digitalWrite(red[THIRD], LOW);
+  digitalWrite(red[FOURTH], LOW);
+
+  for (int i = 0; i < 4; i++) digitalWrite(yellow[i], HIGH);
+  delay(short_del);
+  for (int i = 0; i < 4; i++) digitalWrite(yellow[i], LOW);
+
+  index = whichLight();
+
+  //For second
+  digitalWrite(green[SECOND], HIGH);
+  digitalWrite(red[FIRST], HIGH);
+  digitalWrite(red[THIRD], HIGH);
+  digitalWrite(red[FOURTH], HIGH);
+  delay(long_del);
+  digitalWrite(green[SECOND], LOW);
+  digitalWrite(red[FIRST], LOW);
+  digitalWrite(red[THIRD], LOW);
+  digitalWrite(red[FOURTH], LOW);
+
+  for (int i = 0; i < 4; i++) digitalWrite(yellow[i], HIGH);
+  delay(short_del);
+  for (int i = 0; i < 4; i++) digitalWrite(yellow[i], LOW);
+
+  index = whichLight();
+
+  //For third
+  digitalWrite(green[THIRD], HIGH);
+  digitalWrite(red[FIRST], HIGH);
+  digitalWrite(red[SECOND], HIGH);
+  digitalWrite(red[FOURTH], HIGH);
+  delay(long_del);
+  digitalWrite(green[THIRD], LOW);
+  digitalWrite(red[FIRST], LOW);
+  digitalWrite(red[SECOND], LOW);
+  digitalWrite(red[FOURTH], LOW);
+
+  for (int i = 0; i < 4; i++) digitalWrite(yellow[i], HIGH);
+  delay(short_del);
+  for (int i = 0; i < 4; i++) digitalWrite(yellow[i], LOW);
+
+  index = whichLight();
+
+  //For fourth
+  digitalWrite(green[FOURTH], HIGH);
+  digitalWrite(red[FIRST], HIGH);
+  digitalWrite(red[SECOND], HIGH);
+  digitalWrite(red[THIRD], HIGH);
+  delay(long_del);
+  digitalWrite(green[FOURTH], LOW);
+  digitalWrite(red[FIRST], LOW);
+  digitalWrite(red[SECOND], LOW);
+  digitalWrite(red[THIRD], LOW);
+
+  index = whichLight();
+
+  for (int i = 0; i < 4; i++) digitalWrite(yellow[i], HIGH);
+  delay(short_del);
+  for (int i = 0; i < 4; i++) digitalWrite(yellow[i], LOW);
+
+}
+
+#ifdef __DEBUG__
+void loop() { onAll(); }
+
+#else
+
+
+
+void loop(){
+
+  int index = 4;
+
+  index = whichLight();
+
+  while(index != NONE){
+    index = whichLight();
+    switch(index){
+      case FIRST:
+        firstLight();
+        break;
+      case SECOND:
+        secondLight();
+        break;
+
+      case THIRD:
+        thirdLight();
+        break;
+
+      case FOURTH:
+        fourthLight();
+        break;
+
+      default:
+        offAll();
+        break;
+    }
+  }
+
+  while(whichLight() == NONE){
+
+  if (whichLight() != NONE){
+    offAll();
+    break;
+  }
+
+      // For first light
+  digitalWrite(green[FIRST], HIGH);
+  digitalWrite(red[SECOND], HIGH);
+  digitalWrite(red[THIRD], HIGH);
+  digitalWrite(red[FOURTH], HIGH);
+    if (whichLight() != NONE){
+    offAll();
+    break;
+  }
+  delay(long_del);
+    if (whichLight() != NONE){
+    offAll();
+    break;
+  }
+  digitalWrite(green[FIRST], LOW);
+  digitalWrite(red[SECOND], LOW);
+  digitalWrite(red[THIRD], LOW);
+  digitalWrite(red[FOURTH], LOW);
+  index = whichLight();
+
+  for (int i = 0; i < 4; i++) digitalWrite(yellow[i], HIGH);
+  index = whichLight();
+  delay(short_del);
+  index = whichLight();
+  for (int i = 0; i < 4; i++) digitalWrite(yellow[i], LOW);
+
+  index = whichLight();
+
+  //For second
+  digitalWrite(green[SECOND], HIGH);
+  digitalWrite(red[FIRST], HIGH);
+  digitalWrite(red[THIRD], HIGH);
+  digitalWrite(red[FOURTH], HIGH);
+    if (whichLight() != NONE){
+    offAll();
+    break;
+  }
+  delay(long_del);
+    if (whichLight() != NONE){
+    offAll();
+    break;
+  }
+  digitalWrite(green[SECOND], LOW);
+  digitalWrite(red[FIRST], LOW);
+  digitalWrite(red[THIRD], LOW);
+  digitalWrite(red[FOURTH], LOW);
+    if (whichLight() != NONE){
+    offAll();
+    break;
+  }
+  for (int i = 0; i < 4; i++) digitalWrite(yellow[i], HIGH);
+    if (whichLight() != NONE){
+    offAll();
+    break;
+  }
+  delay(short_del);
+    if (whichLight() != NONE){
+    offAll();
+    break;
+  }
+  for (int i = 0; i < 4; i++) digitalWrite(yellow[i], LOW);
+
+    if (whichLight() != NONE){
+    offAll();
+    break;
+  }
+
+  //For third
+  digitalWrite(green[THIRD], HIGH);
+  digitalWrite(red[FIRST], HIGH);
+  digitalWrite(red[SECOND], HIGH);
+  digitalWrite(red[FOURTH], HIGH);
+    if (whichLight() != NONE){
+    offAll();
+    break;
+  }
+  delay(long_del);
+  digitalWrite(green[THIRD], LOW);
+  digitalWrite(red[FIRST], LOW);
+  digitalWrite(red[SECOND], LOW);
+  digitalWrite(red[FOURTH], LOW);
+
+    if (whichLight() != NONE){
+    offAll();
+    break;
+  }
+  for (int i = 0; i < 4; i++) digitalWrite(yellow[i], HIGH);
+    if (whichLight() != NONE){
+    offAll();
+    break;
+  }
+  delay(short_del);
+  for (int i = 0; i < 4; i++) digitalWrite(yellow[i], LOW);
+    if (whichLight() != NONE){
+    offAll();
+    break;
+  }
+
+
+  //For fourth
+  digitalWrite(green[FOURTH], HIGH);
+  digitalWrite(red[FIRST], HIGH);
+  digitalWrite(red[SECOND], HIGH);
+  digitalWrite(red[THIRD], HIGH);
+
+    if (whichLight() != NONE){
+    offAll();
+    break;
+  }
+
+  delay(long_del);
+  digitalWrite(green[FOURTH], LOW);
+  digitalWrite(red[FIRST], LOW);
+  digitalWrite(red[SECOND], LOW);
+  digitalWrite(red[THIRD], LOW);
+
+    if (whichLight() != NONE){
+    offAll();
+    break;
+  }
+
+  for (int i = 0; i < 4; i++) digitalWrite(yellow[i], HIGH);
+    if (whichLight() != NONE){
+    offAll();
+    break;
+  }
+  delay(short_del);
+  for (int i = 0; i < 4; i++) digitalWrite(yellow[i], LOW);
+
+    if (whichLight() != NONE){
+    offAll();
+    break;
+  }
+
+  }
+}
+
+
+#endif
+


Update test-128x64ZW. The draw loop got lost

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/JulianNicholls/Arduino.git/'


Update pt_remote controlled car2.ino

Update pt_remote controlled car2.ino

error: pathspec 'pt_remote' did not match any file(s) known to git
error: pathspec 'controlled' did not match any file(s) known to git
error: pathspec 'car/pt_remote' did not match any file(s) known to git
error: pathspec 'controlled' did not match any file(s) known to git
error: pathspec 'car2.ino' did not match any file(s) known to git


Add v0.2.0 conditioning Arduino source

Add v0.2.0 conditioning Arduino source

error: pathspec 'Arduino/v0.2.0_with_conditioning/v0.2.0_with_conditioning.ino' did not match any file(s) known to git

--- Arduino/v0.2.0_with_conditioning/v0.2.0_with_conditioning.ino
+++ Arduino/v0.2.0_with_conditioning/v0.2.0_with_conditioning.ino
@@ -0,0 +1,82 @@
+#include "AES.h"
+#include "CBC.h"
+
+#define CHAIN_SIZE 2
+#define BLOCK_SIZE 16
+#define SAMPLE_SIZE (BLOCK_SIZE * CHAIN_SIZE)
+
+byte key[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+                    0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
+
+CBC<AES128> cbc;
+
+
+byte sourcePool[SAMPLE_SIZE];
+
+void setup()
+{
+  Serial.begin(115200);
+  //Set B pins to input
+  DDRB = B00000000;
+  delay(1000);
+
+}
+
+
+void loop() {
+  static byte currentByte = 0x00;
+  byte pinVal = (PINB >> 3) & B00000001;
+  boolean byteReady = collectBit(pinVal, &currentByte);
+
+  if (byteReady){
+    //Serial.println("ByteCollected");
+    boolean poolFull = collectByte(currentByte);
+    if (poolFull){
+      conditionPool();
+      //Serial.write(sourcePool, SAMPLE_SIZE);
+    }
+    currentByte = 0;
+  }
+}
+
+//@return true if byte is full/complete
+boolean collectBit(byte inputBit, byte *currentByte){
+  static int bitCounter = 0;
+  *currentByte |= inputBit << bitCounter;
+   bitCounter = ++bitCounter % 8;
+
+  if (bitCounter == 0) {
+    return true;
+  }
+  return false;
+}
+
+//@return true if sourcePool is full
+boolean collectByte(byte currentByte){
+  static int byteCount = 0;
+  sourcePool[byteCount] = currentByte;
+  byteCount = ++byteCount % SAMPLE_SIZE;
+  //Serial.println(byteCount);
+
+  if (byteCount == 0){
+    return true;
+  }
+  return false;
+}
+
+ //TODO: this should return encrypted pool, and mac should
+ //be sent in the calling function
+void conditionPool(){
+  //Serial.println("Conditioning");
+  static byte iv[BLOCK_SIZE] = {0};
+  byte output[SAMPLE_SIZE];
+  cbc.clear();
+  cbc.setKey(key, 16);
+  cbc.setIV(iv, 16);
+  cbc.encrypt(output, sourcePool, SAMPLE_SIZE);
+
+   //advance pointer to last block (the MAC)
+  byte *outBuf = &output[SAMPLE_SIZE - BLOCK_SIZE];
+  Serial.write(outBuf, BLOCK_SIZE);
+}
+


it all works

it all works

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/markwatneyy/ttt_arduino.git/'


Added cardwriter program. This allows users to enter in item numbers and put them onto RFID cards

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

--- CardWriter/cardwriter.ino
+++ CardWriter/cardwriter.ino
@@ -0,0 +1,299 @@
+/**
+ * CARDWRITER
+ * Purpose of this program is write new item numbers to an RFID card
+ *
+ * -----------------------------------------------------------------------------------------
+ *             MFRC522
+ *             Reader/PCD   Uno
+ * Signal      Pin          Pin
+ * -----------------------------------------------------------------------------------------
+ * RST/Reset   RST          9
+ * SPI SS      SDA(SS)      7
+ * SPI MOSI    MOSI         11 / ICSP-4
+ * SPI MISO    MISO         12 / ICSP-1
+ * SPI SCK     SCK          13 / ICSP-3
+ *
+ */
+
+#include <SPI.h>
+#include <MFRC522.h>
+#include <stdio.h>
+
+#define RST_PIN           9           // Configurable, see typical pin layout above
+#define SS_PIN            7         // Configurable, see typical pin layout above
+#define ITEM_NUMBER_SIZE  6          //number of characters in item number
+#define DEFAULT_READ_SIZE 18        //in order to read, the minimum/default read size is 18
+
+//Arduino kept overwriting this variables so I had to put it here
+byte dataBlock[ITEM_NUMBER_SIZE+1];
+
+MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance.
+MFRC522::MIFARE_Key key;
+
+//read areas of the card. Doesn't change
+const byte sector         = 1;
+const byte blockAddr      = 4;
+const byte trailerBlock   = 7;
+
+
+/**
+ * Initialize.
+ */
+void setup() {
+    Serial.begin(9600); // Initialize serial communications with the PC
+    while (!Serial);    // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
+    SPI.begin();        // Init SPI bus
+    mfrc522.PCD_Init(); // Init MFRC522 card
+
+    // Prepare the key (used both as key A and as key B)
+    // using FFFFFFFFFFFFh which is the default at chip delivery from the factory
+    for (byte i = 0; i < 6; i++) {
+        key.keyByte[i] = 0xFF;
+    }
+
+
+    Serial.println(F("No item number set. Enter part number to write to card:"));
+
+}
+
+/**
+ * Main loop.
+ */
+void loop() {
+
+    //adding null character to end of datablock for reading purposes
+    dataBlock[ITEM_NUMBER_SIZE+1] = '\0';
+    int dataBlock_size = sizeof(dataBlock) / sizeof(dataBlock[0]);
+
+    //check if user has entered a number
+    if(Serial.available())
+    {
+      //receives new item number and writes it to the datablock array
+      get_response(dataBlock,ITEM_NUMBER_SIZE);
+
+      //ready to write new number to card
+      question_user(dataBlock,dataBlock_size);
+    }
+
+   // Look for new cards
+    if ( ! mfrc522.PICC_IsNewCardPresent())
+        return;
+
+    // Select one of the cards
+    if ( ! mfrc522.PICC_ReadCardSerial())
+        return;
+
+    //checks card compatibility
+    if (!card_ok())
+      Serial.println(F("This sample only works with MIFARE Classic cards."));
+
+    //authenticates cards for writing purposes
+    authenticate();
+
+    //writes datablock array to the card
+    write_to_block(dataBlock);
+
+
+    // Halt PICCt
+    mfrc522.PICC_HaltA();
+    // Stop encryption on PCD
+    mfrc522.PCD_StopCrypto1();
+
+}
+
+
+/* *************************************************************************
+ * *************************************************************************
+ * **************************** FUNCTIONS **********************************
+ * *************************************************************************
+ * ************************************************************************/
+
+/* Function: to_char
+ * Description: helper routine to dump a byte array as ascii values to Serial
+ * Inputs: pointer to buffer and the buffer's size
+ * Outputs: writes read characters to serial
+ */
+ void to_char(byte *buffer,byte bufferSize)
+ {
+  //Iterates through the buffer
+    for (byte i=0; i < bufferSize; i++){
+      //skips writing characters such as the enter key, backspace etc
+     if(buffer[i]> 0x7E || (buffer[i] < 0x20 && buffer[i] >0x9)){
+
+      }
+      //This will pick up and write all numbers to serial. I have to
+      //format as HEX otherwise it might try to write the character value
+      //which is like the null character, acknowledge, etc
+     else if(buffer[i]< 0x0A){
+       Serial.print(buffer[i],HEX);
+       }
+
+     //everything else is a regular character and I can print it as such.
+     //For some reason, serial.write prints out the character value but
+     //serial.print will print the decimal value. I'll need to research
+     //this more
+     else{
+       Serial.write(buffer[i]);
+       }
+
+    }
+    Serial.println();
+ }
+
+ /* Function: card_ok
+ * Description: Checks rfid card for compatibility
+ * Inputs: None
+ * Outputs: boolean, true if card compatible, false if not
+ */
+ boolean card_ok()
+ {
+
+    //get card type to check for compatibility
+    byte piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);
+    // Check for compatibility
+    if (    piccType != MFRC522::PICC_TYPE_MIFARE_MINI
+        &&  piccType != MFRC522::PICC_TYPE_MIFARE_1K
+        &&  piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
+
+        return false;
+    }
+    return true;
+ }
+
+ /* Function: authenticate
+ * Description: Authenticates card to allow writing and reading functions
+ * Inputs: none
+ * Outputs: none
+ */
+ void authenticate()
+ {
+   byte status;
+   // In order to read or write data to a PICC, the card must first be
+    //authenticated using a key. Below, the PICC is being authenticated using
+    //key A so we can read data from card
+
+    status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(mfrc522.uid));
+    if (status != MFRC522::STATUS_OK) {
+        Serial.print(F("PCD_Authenticate() failed: "));
+        Serial.println(mfrc522.GetStatusCodeName(status));
+        return;
+    }
+
+    // Authenticate using key B
+    status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_B, trailerBlock, &key, &(mfrc522.uid));
+    if (status != MFRC522::STATUS_OK) {
+        Serial.print(F("PCD_Authenticate() failed: "));
+        Serial.println(mfrc522.GetStatusCodeName(status));
+        return;
+    }
+ }
+
+
+/* Function: read_from_block
+ * Description: reads data from a specified block on the card
+ * Inputs: empty buffer, size of the data to read, size of the buffer
+ * Outputs: will print out the data written on the card
+ */
+ void read_from_block(byte *buffer, int data_size, byte *buff_size)
+ {
+    byte status;
+
+    //method reads from the block address(blockAddr) and writes it to the
+    //buffer.
+    status = mfrc522.MIFARE_Read(blockAddr, buffer, buff_size);
+    if (status != MFRC522::STATUS_OK) {
+        Serial.print(F("MIFARE_Read() failed: "));
+        Serial.println(mfrc522.GetStatusCodeName(status));
+        return;
+    }
+
+    // Read data from the block (should now be what we have written)
+    Serial.print(F("Card item number is now: "));
+
+    //calls to_char to print out the buffer data
+    to_char(buffer,data_size);
+    Serial.println();
+ }
+
+/* Function: write_to_block
+ * Description: Writes data onto the RFID card
+ * Inputs: pointer to the data to write
+ * Outputs: None
+ */
+void write_to_block(byte *data)
+ {
+  //sucks about the variables, I'll need to optimize this later
+  byte status, count = 0, buffer[DEFAULT_READ_SIZE], buff_size = DEFAULT_READ_SIZE;
+  int num_size = ITEM_NUMBER_SIZE + 1;
+
+    Serial.print(F("Writing data onto card..."));
+
+  //Writes data to the block address (blockAddr)
+  //Not sure why I'm using 16 here. Need to research
+    status = mfrc522.MIFARE_Write(blockAddr, data, 16);
+    if (status != MFRC522::STATUS_OK) {
+        Serial.print(F("MIFARE_Write() failed: "));
+        Serial.println(mfrc522.GetStatusCodeName(status));
+        return;
+    }
+
+     // Check that data in block is what we have written
+    for (byte i = 0; i < num_size; i++) {
+        // Compare buffer (= what we've read) with dataBlock (= what we've written)
+        if (data[i] == dataBlock[i])
+            count++;
+    }
+
+    //if data and the card data don't match
+    if (count != num_size) {
+        Serial.println(F("Failure, no match"));
+        Serial.println(F("Perhaps the write didn't work properly..."));
+    }
+    else {
+      Serial.println(" Success!");
+
+      //call read_from_block to print out data on card
+      read_from_block(buffer, ITEM_NUMBER_SIZE, &buff_size);
+
+    }
+
+    //asks user for new part number or new card
+    question_user(data, num_size);
+ }
+
+ /* Function: question_user
+ * Description: Prompt that tells user the current item number stored
+ *              and asks for a new card or part number.
+ * Inputs: pointer to the current part number and the length of it
+ * Outputs: None
+ */
+ void question_user(byte *datablock, int len)
+ {
+
+    Serial.print("Current number stored for writing is: ");
+      while (*datablock != '\0')
+        Serial.write(*datablock++);
+    Serial.println("\nPlease swipe new card or enter new part number when ready.\n");
+
+ }
+
+/* Function: get_response
+ * Description: Receives user input and writes it to the dataBlock variable
+ * Inputs: pointer to the dataBlock variable and the length to write
+ * Outputs: None
+ */
+ void get_response(byte *buffer, int len)
+ {
+    int i = 0;
+
+    //While there's still characters in the serial buffer and
+    //i is less than the length to read
+    while (Serial.available() != 0 && i++ <= len)
+    {
+      //assigns current buffer address to the next character read from Serial
+      *buffer++ = Serial.read();
+    }
+    Serial.println("New number received.");
+ }
+
+