Added modified version of StandardFirmata that uses the DotStar strip.

/*
  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.
  Copyright (C) 2015 Brian Schmalz. 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 Brian Schmalz: August 9th, 2015
*/
#include <SPI.h>
#include <SoftPWMServo.h>  // Gives us PWM and Servo on every pin
#include <Wire.h>
#include <Firmata.h>
#include <Adafruit_DotStar.h>

#define NUMPIXELS 30 // Number of LEDs in strip
#define DATAPIN    4
#define CLOCKPIN   5

#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

/*==============================================================================
 * GLOBAL VARIABLES
 *============================================================================*/
/* apa102c rgb led strip */
Adafruit_DotStar strip = Adafruit_DotStar(NUMPIXELS, DATAPIN, CLOCKPIN, DOTSTAR_BRG);

/* 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;

SoftServo 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 a pin that is in Servo mode to a particular output value
 * (i.e. pulse width). Different boards may have different ways of
 * setting servo values, so putting it in a function keeps things cleaner.
 */
void servoWrite(byte pin, int value)
{
  SoftPWMServoPWMWrite(PIN_TO_PWM(pin), value);
}

// -----------------------------------------------------------------------------
/* sets the pin mode to the correct state and sets the relevant bits in the
 * two bit-arrays that track Digital I/O and PWM status
 */
void setPinModeCallback(byte pin, int mode)
{
  if (pinConfig[pin] == IGNORE)
    return;

  if (pinConfig[pin] == I2C && isI2CEnabled && mode != I2C) {
    // disable i2c so pins can be used for other functions
    // the following if statements should reconfigure the pins properly
    disableI2CPins();
  }
  if (IS_PIN_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);
        servoWrite(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 I2C:
      if (IS_PIN_I2C(pin)) {
        // mark the pin as i2c
        // the user must call I2C_CONFIG to enable I2C for a device
        pinConfig[pin] = I2C;
      }
      break;
    default:
      Firmata.sendString("Unknown pin mode"); // TODO: put error msgs in EEPROM
  }
  // TODO: save status to EEPROM here, if changed
}

void analogWriteCallback(byte pin, int value)
{
  if (pin < TOTAL_PINS) {
    switch (pinConfig[pin]) {
      case SERVO:
        if (IS_PIN_DIGITAL(pin))
          servos[servoPinMap[pin]].write(value);
        pinState[pin] = value;
        break;
      case PWM:
        if (IS_PIN_PWM(pin))
          servoWrite(PIN_TO_PWM(pin), value);
        pinState[pin] = value;
        break;
    }
  }
}

void digitalWriteCallback(byte port, int value)
{
  byte pin, lastPin, mask = 1, pinWriteMask = 0;

  if (port < TOTAL_PORTS) {
    // create a mask of the pins on this port that are writable.
    lastPin = port * 8 + 8;
    if (lastPin > TOTAL_PINS) lastPin = TOTAL_PINS;
    for (pin = port * 8; pin < lastPin; pin++) {
      // do not disturb non-digital pins (eg, Rx & Tx)
      if (IS_PIN_DIGITAL(pin)) {
        // only write to OUTPUT and INPUT (enables pullup)
        // do not touch pins in PWM, ANALOG, SERVO or other modes
        if (pinConfig[pin] == OUTPUT || pinConfig[pin] == INPUT) {
          pinWriteMask |= mask;
          pinState[pin] = ((byte)value & mask) ? 1 : 0;
        }
      }
      mask = mask << 1;
    }
    writePort(port, (byte)value, pinWriteMask);
  }
}

// -----------------------------------------------------------------------------
/* sets bits in a bit array (int) to toggle the reporting of the analogIns
 */
//void FirmataClass::setAnalogPinReporting(byte pin, byte state) {
//}
void reportAnalogCallback(byte analogPin, int value)
{
  if (analogPin < TOTAL_ANALOG_PINS) {
    if (value == 0) {
      analogInputsToReport = analogInputsToReport & ~ (1 << analogPin);
    } else {
      analogInputsToReport = analogInputsToReport | (1 << analogPin);
      // prevent during system reset or all analog pin values will be reported
      // which may report noise for unconnected analog pins
      if (!isResetting) {
        // Send pin value immediately. This is helpful when connected via
        // ethernet, wi-fi or bluetooth so pin states can be known upon
        // reconnecting.
        Firmata.sendAnalog(analogPin, analogRead(analogPin));
      }
    }
  }
  // TODO: save status to EEPROM here, if changed
}

void reportDigitalCallback(byte port, int value)
{
  if (port < TOTAL_PORTS) {
    reportPINs[port] = (byte)value;
    // Send port value immediately. This is helpful when connected via
    // ethernet, wi-fi or bluetooth so pin states can be known upon
    // reconnecting.
    if (value) outputPort(port, readPort(port, portConfigInputs[port]), true);
  }
  // do not disable analog reporting on these 8 pins, to allow some
  // pins used for digital, others analog.  Instead, allow both types
  // of reporting to be enabled, but check if the pin is configured
  // as analog when sampling the analog inputs.  Likewise, while
  // scanning digital pins, portConfigInputs will mask off values from any
  // pins configured as analog
}

/*==============================================================================
 * SYSEX-BASED commands
 *============================================================================*/

void sysexCallback(byte command, byte argc, byte *argv)
{
  byte mode;
  byte slaveAddress;
  byte data;
  int slaveRegister;
  unsigned int delayTime;

  switch (command) {
    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 SAMPLING_INTERVAL:
      if (argc > 1) {
        samplingInterval = argv[0] + (argv[1] << 7);
        if (samplingInterval < MINIMUM_SAMPLING_INTERVAL) {
          samplingInterval = MINIMUM_SAMPLING_INTERVAL;
        }
      } else {
        //Firmata.sendString("Not enough data");
      }
      break;
    case EXTENDED_ANALOG:
      if (argc > 1) {
        int val = argv[1];
        if (argc > 2) val |= (argv[2] << 7);
        if (argc > 3) val |= (argv[3] << 14);
        analogWriteCallback(argv[0], val);
      }
      break;
    case CAPABILITY_QUERY:
      Firmata.write(START_SYSEX);
      Firmata.write(CAPABILITY_RESPONSE);
      for (byte pin = 0; pin < TOTAL_PINS; pin++) {
        if (IS_PIN_DIGITAL(pin)) {
          Firmata.write((byte)INPUT);
          Firmata.write(1);
          Firmata.write((byte)OUTPUT);
          Firmata.write(1);
        }
        if (IS_PIN_ANALOG(pin)) {
          Firmata.write(ANALOG);
          Firmata.write(10); // 10 = 10-bit resolution
        }
        if (IS_PIN_PWM(pin)) {
          Firmata.write(PWM);
          Firmata.write(8); // 8 = 8-bit resolution
        }
        if (IS_PIN_DIGITAL(pin)) {
          Firmata.write(SERVO);
          Firmata.write(14);
        }
        if (IS_PIN_I2C(pin)) {
          Firmata.write(I2C);
          Firmata.write(1);  // TODO: could assign a number to map to SCL or SDA
        }
        Firmata.write(127);
      }
      Firmata.write(END_SYSEX);
      break;
    case PIN_STATE_QUERY:
      if (argc > 0) {
        byte pin = argv[0];
        Firmata.write(START_SYSEX);
        Firmata.write(PIN_STATE_RESPONSE);
        Firmata.write(pin);
        if (pin < TOTAL_PINS) {
          Firmata.write((byte)pinConfig[pin]);
          Firmata.write((byte)pinState[pin] & 0x7F);
          if (pinState[pin] & 0xFF80) Firmata.write((byte)(pinState[pin] >> 7) & 0x7F);
          if (pinState[pin] & 0xC000) Firmata.write((byte)(pinState[pin] >> 14) & 0x7F);
        }
        Firmata.write(END_SYSEX);
      }
      break;
    case ANALOG_MAPPING_QUERY:
      Firmata.write(START_SYSEX);
      Firmata.write(ANALOG_MAPPING_RESPONSE);
      for (byte pin = 0; pin < TOTAL_PINS; pin++) {
        Firmata.write(IS_PIN_ANALOG(pin) ? PIN_TO_ANALOG(pin) : 127);
      }
      Firmata.write(END_SYSEX);
      break;
  }
}

void enableI2CPins()
{
  byte i;
  // is there a faster way to do this? would probaby require importing
  // Arduino.h to get SCL and SDA pins
  for (i = 0; i < TOTAL_PINS; i++) {
    if (IS_PIN_I2C(i)) {
      // mark pins as i2c so they are ignore in non i2c data requests
      setPinModeCallback(i, I2C);
    }
  }

  isI2CEnabled = true;

  Wire.begin();
}

/* disable the i2c pins so they can be used for other functions */
void disableI2CPins() {
  isI2CEnabled = false;
  // disable read continuous mode for all devices
  queryIndex = -1;
}

/*==============================================================================
 * SETUP()
 *============================================================================*/

void systemResetCallback()
{
  isResetting = true;
  // initialize a defalt state
  // TODO: option to load config from EEPROM instead of default
  if (isI2CEnabled) {
    disableI2CPins();
  }

  for (byte i = 0; i < TOTAL_PORTS; i++) {
    reportPINs[i] = false;    // by default, reporting off
    portConfigInputs[i] = 0;  // until activated
    previousPINs[i] = 0;
  }

  for (byte i = 0; i < TOTAL_PINS; i++) {
    // pins with analog capability default to analog input
    // otherwise, pins default to digital output
    if (IS_PIN_ANALOG(i)) {
      // turns off pullup, configures everything
      setPinModeCallback(i, ANALOG);
    } else {
      // sets the output to 0, configures portConfigInputs
      setPinModeCallback(i, OUTPUT);
    }

    servoPinMap[i] = 255;
  }
  // by default, do not report any analog inputs
  analogInputsToReport = 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);

  /* For chipKIT Pi board, we need to use Serial1. All others just use Serial. */
#if defined(_BOARD_CHIPKIT_PI_)
  Serial1.begin(57600);
  Firmata.begin(Serial1);
#else
  Firmata.begin(57600);
#endif
  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();

  // 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);
      }
    }
  }
}

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


Adds E-stop arduino code

Adds E-stop arduino code

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/jondolan/igvc-software.git/'


Final Working Arduino Code

Final Working Arduino Code

/* ArduStat, a web-controlled wifi thermostat project
Author - Rahul Sangole
Date - Jan 2014

Thanks for Adafruit and all the active members on the Arduino forums for their inputs!
 */
#include <Adafruit_CC3000.h>
#include <ccspi.h>
#include <SPI.h>
#include <string.h>
#include "utility/debug.h"
#include <Servo.h>
#include "dht11.h"

// ----------------------------
// ----------------------------
// Global Variables & Initiation
// ----------------------------
// Wireless Setup
// These are the interrupt and control pins
#define ADAFRUIT_CC3000_IRQ   3  // MUST be an interrupt pin!
// These can be any two pins
#define ADAFRUIT_CC3000_VBAT  5
#define ADAFRUIT_CC3000_CS    10
// On an UNO, SCK = 13, MISO = 12, and MOSI = 11
Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT,SPI_CLOCK_DIV2); // you can change this clock speed but DI
#define WLAN_SSID "YOURSSID"        // cannot be longer than 32 characters!
#define WLAN_PASS "YOURPASS"
// Security can be WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2
#define WLAN_SECURITY WLAN_SEC_WPA2
#define IDLE_TIMEOUT_MS 3000      // Amount of time to wait (in milliseconds) with no data

// ----------------------------
// Website Setup
#define WEBSITE      "YOUR SITE FOR TEMP COMMAND DATA"
#define WEBPAGE      "/tdata.html"

// ----------------------------
// Xively Setup
#define XWEBSITE  "api.xively.com"
#define API_key  "YOUR API KEY"
#define feedID  "YOUR FEED ID"

// ----------------------------
// Misc
#define DELAY 900000
int TEXIST=68;

// ----------------------------
// DHT Setup
#define DHTPIN A0     // what pin we're connected to
#define DHTTYPE DHT11
dht11 DHT11;

// ----------------------------
Servo myservo;
int SPOS=60;
#define SPIN 4

// ----------------------------
// ----------------------------

void setup(void){
  Serial.begin(9600);
  myservo.attach(SPIN);
  myservo.write(SPOS);
  delay(1000);
  myservo.detach();
}

// ----------------------------
// ----------------------------

void loop(void){
  Serial.print(F("Existing Temperature: "));
  Serial.print(TEXIST);
  Serial.println(F(" deg F"));
  initWifi();
  deleteOldConn();
  connectWifi();
  requestDCHP();
  // Get Commanded Temperature
  int treq=getTemp();
  // Check Against Existing Temperature, Command Servo
  if(treq!=TEXIST){
    myservo.attach(SPIN);
    changeTemp(treq);
    delay(1000);
    myservo.detach();
  }
  // Update Xively
  updateXively();
  // Close Wifi Connection
  closeWifi();
  // Delay
  delay(DELAY);
}

void initWifi(void){
  Serial.println(F("\nInitialising the CC3000 ..."));
  if (!cc3000.begin())
  {
    Serial.println(F("Unable to initialise the CC3000! Check your wiring?"));
    while(1);
  }
}

void deleteOldConn(void){
  /* Delete any old connection data on the module */
  Serial.println(F("\nDeleting old connection profiles"));
  if (!cc3000.deleteProfiles()) {
    Serial.println(F("Failed!"));
    while(1);
  }
}

void connectWifi(void){
  /* Attempt to connect to an access point */
  char *ssid = WLAN_SSID;             /* Max 32 chars */
  Serial.print(F("\nAttempting to connect to "));
  Serial.println(ssid);
  if (!cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY)) {
    Serial.println(F("Failed!"));
    while(1);
  }

  Serial.println(F("Connected!"));
  Serial.println(F("\n"));
}

void requestDCHP(){
  /* Wait for DHCP to complete */
  Serial.println(F("Requesting DHCP..."));
  while (!cc3000.checkDHCP())
  {
    delay(100); // ToDo: Insert a DHCP timeout!
  }
  Serial.println(F("DCHP Done."));
  Serial.println(F("\n\n"));

}

int getTemp(){
  uint32_t ip = 0;
  String readString = "";
  Serial.println(F("Connecting to website..."));
  while  (ip  ==  0)  {
    if  (!  cc3000.getHostByName(WEBSITE, &ip))  {
      Serial.println(F("Couldn't resolve!"));
    }
    delay(500);
  }
  cc3000.printIPdotsRev(ip);

  Adafruit_CC3000_Client www = cc3000.connectTCP(ip, 80);

  Serial.println(F("Text Return:"));
  if (www.connected()) {
    www.fastrprint(F("GET "));
    www.fastrprint(WEBPAGE);
    www.fastrprint(F(" HTTP/1.1\r\n"));
    www.fastrprint(F("Host: "));
    www.fastrprint(WEBSITE);
    www.fastrprint(F("\r\n"));
    www.fastrprint(F("\r\n"));
    www.println();
  }
  Serial.println(F("-------------------------------------"));

  /* Read data until either the connection is closed, or the idle timeout is reached. */
  unsigned long lastRead = millis();
  while (www.connected() && (millis() - lastRead < IDLE_TIMEOUT_MS)) {
    while (www.available()) {
      char c = www.read();
      Serial.print(c);      //read char by char HTTP request
      readString+=c;
      lastRead = millis();
    }
  }
  www.close();
  Serial.println(F("-------------------------------------"));
  Serial.println(F("\n"));
  //Find temperautre in the data based on <<
  int index = readString.indexOf('<<');
  String tempstr = readString.substring(index+2, index+4);
  int tempcomm = tempstr.toInt();
  Serial.print("Commanded temp in int: ");
  Serial.println(tempcomm);
  Serial.println(F("-------------------------------------"));
  return tempcomm;
}

void changeTemp(int treq){
  if (treq!=TEXIST){
    //Command Servo
    delay(1000);
    Serial.print(F("Command Servo to "));
    Serial.println(treq);
    myservo.write(110);
    delay(1000);
    switch(treq){
    case 58:
      myservo.write(110);
      break;
    case 60:
      myservo.write(100);
      break;
    case 62:
      myservo.write(90);
      break;
    case 64:
      myservo.write(80);
      break;
    case 66:
      myservo.write(70);
      break;
    case 68:
      myservo.write(60);
      break;
    case 70:
      myservo.write(50);
      break;
    case 0:
      myservo.write(100);
      break;
    }
    TEXIST=treq;
  }
  else
    Serial.println(F("No change in temp, no servo command"));
  Serial.println(F("\n"));

}

void updateXively(){

  uint32_t ip = 0;

  Serial.print(F("Humidity is: ")); Serial.println((float)h,2);
  Serial.print(F("Temp is: ")); Serial.println((float)t,2);

  int length = 0;
  String data = "";
  data = data + "\n" + "{\"version\":\"1.0.0\",\"datastreams\" : [ {\"id\" : \"TCommand\",\"current_value\" : \"" + String((int)((TEXIST-32)*5/9)) + "\"},"
    + "{\"id\" : \"Temperature\",\"current_value\" : \"" + String(t) + "\"},"
    + "{\"id\" : \"Humidity\",\"current_value\" : \"" + String(h) + "\"}]}";

  Serial.println(F("-------------------------------------"));
  Serial.println(F("Connecting to Xively website..."));
  while  (ip  ==  0)  {
    if  (!  cc3000.getHostByName(XWEBSITE, &ip))  {
      Serial.println(F("Couldn't resolve!"));
    }
    delay(500);
  }
  cc3000.printIPdotsRev(ip);
  length = data.length();
  Adafruit_CC3000_Client client = cc3000.connectTCP(ip, 80);
  if (client.connected()) {
    Serial.println("Connected!");
    client.println("PUT /v2/feeds/" + String(feedID) + ".json HTTP/1.0");
    client.println("Host: api.xively.com");
    client.println("X-ApiKey: " + String(API_key));
    client.println("Content-Length: " + String(length));
    client.print("Connection: close");
    client.println();
    client.print(data);
    client.println();
  }

  while (client.connected()) {
    while (client.available()) {
      char c = client.read();
      Serial.print(c);
    }
  }
  Serial.println(F("Xively update complete"));
  client.close();
}

void closeWifi(void){
  Serial.println(F("\nCC3000 disconnected"));
  cc3000.disconnect();
}

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


Cleaning up code, adding or clarifiying comments.

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/tomwagner1999/SmartHome.git/'


initial commit

initial commit

#define GRN_PIN 5
#define RED_PIN 6
#define BLU_PIN 9

byte RED, GREEN, BLUE;
byte RED_A = 0;
byte GREEN_A = 0;
byte BLUE_A = 0;
int led_delay = 0;
byte color_count = 1;                //Count the colors out
#define color_count_max 5              //Set this to the max number of colors defined
#define color_delay 20000             //Define the delay between changing colors in ms
#define time_at_color 1           //Time to stay on a color in ms

//Some Time values
unsigned long TIME_LED = 0;
unsigned long TIME_color = 0;

//Evening colors defined here
#define C1_R 200
#define C1_G 0
#define C1_B 0

#define C2_R 225
#define C2_G 20
#define C2_B 0

#define C3_R 255
#define C3_G 40
#define C3_B 0

#define C4_R 245
#define C4_G 30
#define C4_B 0

#define C5_R 200
#define C5_G 00
#define C5_B 0

void setup()
{

  //Assign initial values
  RED = C1_R;
  GREEN = C1_G;
  BLUE = C1_B;
  //Get the led_delay speed
  led_delay = (color_delay - time_at_color) / 255;

  analogWrite(GRN_PIN, 0);
  analogWrite(RED_PIN, 0);
  analogWrite(BLU_PIN, 0);

}

void loop()
{

  //Rest of your program - Avoid using delay(); function!

  if(millis() - TIME_LED >= led_delay){
    TIME_LED = millis();

    //Run the LED Function to check and adjust the values
    LED();
  }

  if(millis() - TIME_color >= color_delay){
    TIME_color = millis();

    //Run the color Change function
    color();
  }

}

void LED()
{

  //Check Values and adjust "Active" Value
  if(RED != RED_A){
    if(RED_A > RED) RED_A = RED_A - 1;
    if(RED_A < RED) RED_A++;
  }
  if(GREEN != GREEN_A){
    if(GREEN_A > GREEN) GREEN_A = GREEN_A - 1;
    if(GREEN_A < GREEN) GREEN_A++;
  }
  if(BLUE != BLUE_A){
    if(BLUE_A > BLUE) BLUE_A = BLUE_A - 1;
    if(BLUE_A < BLUE) BLUE_A++;
  }

  //Assign modified values to the pwm outputs for each color led
  analogWrite(RED_PIN, RED_A);
  analogWrite(GRN_PIN, GREEN_A);
  analogWrite(BLU_PIN, BLUE_A);

}

void color()
{

  //Increment the color by one or go back to 1 if maxed out
  if(color_count < color_count_max) color_count++;
  else color_count = 1;

  if(color_count == 1){
    RED = C1_R;
    GREEN = C1_G;
    BLUE = C1_B;
  } else if(color_count == 2){
    RED = C2_R;
    GREEN = C2_G;
    BLUE = C2_B;
  } else if(color_count == 3){
    RED = C3_R;
    GREEN = C3_G;
    BLUE = C3_B;
  } else if(color_count == 4){
    RED = C4_R;
    GREEN = C4_G;
    BLUE = C4_B;
  } else if(color_count == 5){
    RED = C5_R;
    GREEN = C5_G;
    BLUE = C5_B;
  }
}

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


Test of verkstedskilt.ino with delayed connection, but where program starts at power on.

// This #include statement was automatically added by the Spark IDE.
#include "SparkCorePolledTimer/SparkCorePolledTimer.h"

/*-------------------------------------------------------------------------
  Spark Core library to control WS2811/WS2812 based RGB
  LED devices such as Adafruit NeoPixel strips.
  Currently handles 800 KHz and 400kHz bitstream on Spark Core,
  WS2812, WS2812B and WS2811.

  Also supports:
  - Radio Shack Tri-Color Strip with TM1803 controller 400kHz bitstream.
  - TM1829 pixels

  PLEASE NOTE that the NeoPixels require 5V level inputs
  and the Spark Core only has 3.3V level outputs. Level shifting is
  necessary, but will require a fast device such as one of the following:

  [SN74HCT125N]
  http://www.digikey.com/product-detail/en/SN74HCT125N/296-8386-5-ND/376860

  [SN74HCT245N]
  http://www.digikey.com/product-detail/en/SN74HCT245N/296-1612-5-ND/277258

  Written by Phil Burgess / Paint Your Dragon for Adafruit Industries.
  Modified to work with Spark Core by Technobly.
  Contributions by PJRC and other members of the open source community.

  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing products
  from Adafruit!
  --------------------------------------------------------------------*/

/* ======================= includes ================================= */

#include "application.h"
//#include "spark_disable_wlan.h" (for faster local debugging only)
#include "neopixel/neopixel.h"

/* ======================= prototypes =============================== */

void colorAll(uint32_t c, uint8_t wait);
void colorWipe(uint32_t c, uint8_t wait);
void rainbow(uint8_t wait);
void rainbowCycle(uint8_t wait);
uint32_t Wheel(byte WheelPos);
boolean LEDflag = FALSE;
#define LED D7 // Tiny blue LED onboard

/* ======================= extra-examples.cpp ======================== */

// IMPORTANT: Set pixel COUNT, PIN and TYPE
#define PIXEL_COUNT 10
#define PIXEL_PIN A7
#define PIXEL_TYPE WS2812B

// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
//               note: if not specified, D2 is selected for you.
// Parameter 3 = pixel type [ WS2812, WS2812B, WS2811, TM1803 ]
//               note: if not specified, WS2812B is selected for you.
//               note: RGB order is automatically applied to WS2811,
//                     WS2812/WS2812B/TM1803 is GRB order.
//
// 800 KHz bitstream 800 KHz bitstream (most NeoPixel products ...
//                         ... WS2812 (6-pin part)/WS2812B (4-pin part) )
//
// 400 KHz bitstream (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//                   (Radio Shack Tri-Color LED Strip - TM1803 driver
//                    NOTE: RS Tri-Color LED's are grouped in sets of 3)

Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);

// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
// and minimize distance between Arduino and first pixel.  Avoid connecting
// on a live circuit...if you must, connect GND first.

SYSTEM_MODE(SEMI_AUTOMATIC);

SparkCorePolledTimer updateTimer(10000);  //Create a timer object and set it's timeout in milliseconds
void OnTimer(void);   //Prototype for timer callback method

void setup() {
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  pinMode(LED, OUTPUT); // Tiny blue LED onboard
  digitalWrite(LED, LOW);   // Turn Off the LED
  updateTimer.SetCallback(OnTimer);
}

void loop() {
  updateTimer.Update();

  // Some example procedures showing how to display to the pixels:
  // Do not run more than one of these at a time, or the b/g tasks
  // will be blocked.
  //--------------------------------------------------------------

  pixelSwipeRandom(strip.Color(0, 0, 10),strip.Color(15, 50, 0), 20);

  //pixelWipe(strip.Color(0, 0, 0),strip.Color(0, 0, 15), 50); // Red
  //pixelWipeReverse(strip.Color(0, 0, 0),strip.Color(0, 0, 15), 50);
  //colorWipe(strip.Color(255, 0, 0), 50); // Red

  //colorWipe(strip.Color(20, 25, 0), 50); // Green

  //colorWipe(strip.Color(0, 0, 25), 50); // Blue

  //rainbow(20);

  //rainbowCycle(20);

  //colorAll(strip.Color(0, 255, 255), 50); // Magenta
}

void pixelSwipeRandom(uint32_t c, uint32_t b, uint8_t wait) {
  pixelWipe(c, b, wait); // Red
  clearAll(b);
  strip.show();
  delay(random(100,10000));
  pixelWipeReverse(c,b, wait);
  clearAll(b);
  strip.show();
  delay(random(100,10000));
}
// Set all pixels in the strip to a solid color, then wait (ms)
void colorAll(uint32_t c, uint8_t wait) {
  uint16_t i;

  for(i=0; i<strip.numPixels(); i++) {
    strip.setPixelColor(i, c);
  }
  strip.show();
  delay(wait);
}

// Fill the dots one after the other with a color, wait (ms) after each one
void colorWipe(uint32_t c, uint8_t wait) {
  for(uint16_t i=0; i<strip.numPixels(); i++) {
    strip.setPixelColor(i, c);
    strip.show();
    delay(wait);
  }
}

void pixelWipe(uint32_t c, uint32_t b, uint8_t wait) {
  for(uint16_t i=0; i<strip.numPixels(); i++) {
    clearAll(b);
    strip.setPixelColor(i, c);
    strip.show();
    delay(wait);

  }
}

void pixelWipeReverse(uint32_t c, uint32_t b, uint8_t wait) {
  for(int16_t i=strip.numPixels() -1; i>=0; i--) {
    clearAll(b);
    strip.setPixelColor(i, c);
    strip.show();
    delay(wait);
  }
}

void clearAll(uint32_t b) {
  for(uint16_t t=0; t<strip.numPixels(); t++) {
    strip.setPixelColor(t, b);
  }
}

void rainbow(uint8_t wait) {
  uint16_t i, j;

  for(j=0; j<256; j++) {
    for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel((i+j) & 255));
    }
    strip.show();
    delay(wait);
  }
}

// Slightly different, this makes the rainbow equally distributed throughout, then wait (ms)
void rainbowCycle(uint8_t wait) {
  uint16_t i, j;

  for(j=0; j<256; j++) { // 1 cycle of all colors on wheel
    for(i=0; i< strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
    }
    strip.show();
    delay(wait);
  }
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  if(WheelPos < 85) {
   return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  } else if(WheelPos < 170) {
   WheelPos -= 85;
   return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else {
   WheelPos -= 170;
   return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
}

void OnTimer(void) {  //Handler for the timer, will be called automatically
  if (LEDflag == FALSE) {
    digitalWrite(LED, HIGH);   // Turn ON the LED
    LEDflag = TRUE;
  } else {
    digitalWrite(LED, LOW);   // Turn OFF the LED
    LEDflag = FALSE;
  }
  if (Spark.connected() == false) {
    Spark.connect();
  }
}

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


Added test version of the ESP code

Added test version of the ESP code

//
// esppic - An ESP8266-bsed Microchip PIC programmer
// Copyright 2016 Mats Engstrom SmallRoomLabs
// Released under the MIT license
//

#define SWAP16(x) (((x & 0x00ff) << 8) | ((x & 0xff00) >> 8))

#define FLASHSIZE     	8192
#define PICMAXWORDS   	8192
#define PICBLANKWORD  	0x3FFF

// Locations of the special Config & Id memories on the PIC
#define USERID  	0
#define CONFIG1 	7
#define CONFIG2 	8
#define DEVID   	6
#define DEVREV  	5

#define DLY1  10      // 10 microseconds for toggling and stuff
#define DLY2  10000   // 10  millisecond for command delay

#define PIN_RESET D0
#define PIN_DAT   D1
#define PIN_CLK   D2

#define DAT_INPUT   pinMode(PIN_DAT, INPUT);
#define DAT_OUT     pinMode(PIN_DAT, OUTPUT);
#define DAT_LOW     digitalWrite(PIN_DAT,   LOW)
#define DAT_HIGH    digitalWrite(PIN_DAT,   HIGH)
#define DAT_GET     digitalRead(PIN_DAT)

#define CLK_LOW     digitalWrite(PIN_CLK,   LOW)
#define CLK_HIGH    digitalWrite(PIN_CLK,   HIGH)

#define RESET_LOW   digitalWrite(PIN_RESET, LOW)
#define RESET_HIGH  digitalWrite(PIN_RESET, HIGH)

uint16_t currentAddress;

// Some hardcoded firmware to upload to the PIC for testing
char code[]={\
":08000000803102288731672FCF\n"\
":100ECE002000692FF0302100990023008C018E0143\n"\
":100EDE0021008C018E0122008C018E010530F20062\n"\
":100EEE000F30F100F430F000F00B7B2FF10B7B2F65\n"\
":100EFE00F20B7B2FFF3022008C00FF308E0029304A\n"\
":100F0E00F2009630F100A630F000F00B8C2FF10BB2\n"\
":100F1E008C2FF20B8C2F2930F2009630F100A63078\n"\
":100F2E00F000F00B982FF10B982FF20B982F293021\n"\
":100F3E00F2009630F100A630F000F00BA42FF10B6A\n"\
":100F4E00A42FF20BA42F2930F2009630F100A63018\n"\
":100F5E00F000F00BB02FF10BB02FF20BB02F2930A9\n"\
":100F6E00F2009630F100A630F000F00BBC2FF10B22\n"\
":100F7E00BC2FF20BBC2F2930F2009630F100A630B8\n"\
":100F8E00F000F00BC82FF10BC82FF20BC82F293031\n"\
":100F9E00F2009630F100A630F000F00BD42FF10BDA\n"\
":100FAE00D42FF20BD42F2930F2009630F100A63058\n"\
":100FBE00F000F00BE02FF10BE02FF20BE02F2930B9\n"\
":100FCE00F2009630F100A630F000F00BEC2FF10B92\n"\
":100FDE00EC2FF20BEC2F2530F2008730F100AE3003\n"\
":100FEE00F000F00BF82FF10BF82FF20BF82F003268\n"\
":020FFE00722F50\n"\
":020000040001F9\n"\
":08000000650003001800000078\n"\
":04000E00C4C9FFFF63\n"\
":00000001FF\n"\
};
char *codep=code;

//
// Get a line of HEX code from the hardcoded FW
//
char *getline(void) {
    static char tmps[80];
    uint8_t i=0;
    while (*codep!='\n') {
      tmps[i++]=*codep;
      codep++;
    }
  tmps[i]=0;
  codep++;
  return tmps;
}

//
// Setup pins and start the serial comms for debugging
//
void setup() {
  pinMode(PIN_RESET, OUTPUT);
  pinMode(PIN_DAT,   OUTPUT);
  pinMode(PIN_CLK,   OUTPUT);
  RESET_HIGH;
  DAT_LOW;
  CLK_LOW;

  Serial.begin(115200);
  Serial.println("\n\n\npicflasher v0.1 starting\n");
}

//
// Convert a one character hex string to an uint8
//
uint8_t HexDec1(uint8_t c1) {
  if (c1>='A') c1-=7;
  c1-='0';
  return c1;
}

//
// Convert a two character hex string to an uint8
//
uint8_t HexDec2(uint8_t c1, uint8_t c2) {
  return HexDec1(c1)*16 + HexDec1(c2);
}

//
// Convert a four character hex string to an uint16
//
uint16_t HexDec4(uint8_t c1, uint8_t c2, uint8_t c3, uint8_t c4) {
  return HexDec2(c1,c2)*256 + HexDec2(c3,c4);
}

//
// prints 8-bit data in hex with leading zeroes
//
void PrintHex8(uint8_t *data, uint8_t length) {
   char tmp[5];
   byte first;
   byte second;
   for (uint8_t i=0; i<length; i++) {
       first = (data[i] >> 4) & 0x0f;
       second = data[i] & 0x0f;
       tmp[0] = '0'; // add leading 0
       tmp[1] = 'x'; // add leading x
       tmp[2] = first+48;
       if (first > 9) tmp[2] += 7;
       tmp[3] = second+48;
       if (second > 9) tmp[3] += 7;
       tmp[4] = ' '; // add trailing space
       tmp[5] = 0;
       Serial.print(&tmp[2]);
   }
}

//
// prints 16-bit data in hex with leading zeroes
//
void PrintHex16(uint16_t *data, uint8_t length) {
   char tmp[7];
   uint8_t first;
   uint8_t second;
   uint8_t third;
   uint8_t fourth;
   for (uint8_t i=0; i<length; i++) {
       first = (data[i] >> 12) & 0x0f;
       second = (data[i] >> 8) & 0x0f;
       third = (data[i] >> 4) & 0x0f;
       fourth = data[i] & 0x0f;
       tmp[0] = '0'; // add leading 0
       tmp[1] = 'x'; // add leading x
       tmp[2] = first+48;  if (first > 9) tmp[2] += 7;
       tmp[3] = second+48; if (second > 9) tmp[3] += 7;
       tmp[4] = third+48;  if (third > 9) tmp[4] += 7;
       tmp[5] = fourth+48; if (fourth > 9) tmp[5] += 7;
       tmp[6] = ' '; // add trailing space
       tmp[7] = 0;
       Serial.print(&tmp[2]);
   }
}

//
//
//
void PrintBinary16(uint16_t data) {
  char tmp[19];
  tmp[0]=(data&0x8000?'1':'0');
  tmp[1]=(data&0x4000?'1':'0');
  tmp[2]=(data&0x2000?'1':'0');
  tmp[3]=(data&0x1000?'1':'0');
  tmp[4]=' ';
  tmp[5]=(data&0x800?'1':'0');
  tmp[6]=(data&0x400?'1':'0');
  tmp[7]=(data&0x200?'1':'0');
  tmp[8]=(data&0x100?'1':'0');
  tmp[9]=' ';
  tmp[10]=(data&0x80?'1':'0');
  tmp[11]=(data&0x40?'1':'0');
  tmp[12]=(data&0x20?'1':'0');
  tmp[13]=(data&0x10?'1':'0');
  tmp[14]=' ';
  tmp[15]=(data&0x8?'1':'0');
  tmp[16]=(data&0x4?'1':'0');
  tmp[17]=(data&0x2?'1':'0');
  tmp[18]=(data&0x1?'1':'0');
  tmp[19]=0;
  Serial.print(tmp);
}

//
// Clock out data to the PIC. The "bits" argument
// specifies how many bits to be sent.
//
void Send(uint16_t data, uint8_t bits) {
  DAT_OUT;
  delayMicroseconds(DLY1);
  for (uint8_t i=0; i<bits; i++) {
    if (data&0x01) {
      DAT_HIGH;
    } else {
      DAT_LOW;
    }
    delayMicroseconds(DLY1);
    CLK_HIGH;
    delayMicroseconds(DLY1);
    CLK_LOW;
    delayMicroseconds(DLY1);
    data = data >> 1;
  }
  DAT_LOW;
}

//
// Clock in 16 bits of data from the PIC
//
uint16_t Read16(void){
  uint16_t data=0;

  DAT_INPUT;
  delayMicroseconds(DLY1);
  for (uint8_t i=0; i<16; i++) {
    CLK_HIGH;
    delayMicroseconds(DLY1);
    CLK_LOW;
    delayMicroseconds(DLY1);
    data=data >> 1;
    if (DAT_GET) data = data | 0x8000;
  }
  return data;
}

//
// Send the RESET ADDRESS command to the PIC
//
void CmdResetAddress(void) {
  currentAddress=0;
  Send(0x16,6);
  delayMicroseconds(DLY2);
}

//
// Send the INCREMENT ADDRESS command to the PIC
//
void CmdIncAddress(void) {
  currentAddress++;
  Send(0x06,6);
  delayMicroseconds(DLY1);
}

//
// Send the BEGIN PROGRAMMING INTERNAL TIMED command to the PIC
//
void CmdBeginProgramI(void) {
  Send(0x08,6);
  delayMicroseconds(DLY2);
}

//
// Send the LOAD CONFIG command to the PIC
//
void CmdLoadConfig(uint16_t data) {
  currentAddress=0;
  Send(0x00,6);
  Send(data,16);
  delayMicroseconds(DLY2);
}

//
// Send the READ DATA command to the PIC
// TODO: This command should not increment the address here
//
void CmdReadData(uint16_t *data, uint8_t cnt) {
for (uint8_t i=0; i<cnt; i++) {
  Send(0x04, 6);
  delayMicroseconds(DLY1);
  data[i] = (Read16() & 0x7FFE) >> 1;
  CmdIncAddress();
  }
}

//
// Send the BULK ERASE command to the PIC
//
void CmdBulkErase(void) {
  Serial.println("BulkErase");
  CmdLoadConfig(0);
  Send(0x09,6);
  delay(10);
}

//
// Send the magic 32 bits plus one extra clock
// to get into the LVP programming mode
//
void EnterLVPmode() {
  CLK_LOW;
  DAT_LOW;
  delayMicroseconds(500);
  RESET_LOW;
  delayMicroseconds(500);
  Send(0b01010000,8); //P
  Send(0b01001000,8); //H
  Send(0b01000011,8); //C
  Send(0b01001101,8); //M
  Send(0,1);
  delayMicroseconds(DLY1);
 }

//
// Dump the contents of the PIC flash memory onto the
// serial line for debugging
//
void DumpMemory(void) {
  bool isBlank;
  uint16_t data[16];

  CmdResetAddress();
  for (uint16_t rows=0; rows<FLASHSIZE/16; rows++) {
    CmdReadData(data,16);
    isBlank=true;
    for (uint8_t i=0; i<16; i++) {
      if (data[i]!=0x3FFF) isBlank=false;
    }
    if (!isBlank) {
      uint16_t address=rows*16;
      PrintHex16(&address,1);
      Serial.print(":");
      PrintHex16(&data[0],16);
      Serial.println();
    }
    yield();
  }
}

//
// Dump the CONFIG memory parts of the PIC onto the
// serial line for debugging
//
void DumpConfig() {
  uint16_t data[16];

  CmdLoadConfig(0x00);
  CmdReadData(data,16);
  Serial.print("DEV ID : "); PrintHex16(&data[DEVID],1); Serial.println();
  Serial.print("DEV REV: "); PrintHex16(&data[DEVREV],1); Serial.println();
  Serial.print("CONFIG1: "); PrintHex16(&data[CONFIG1],1); Serial.print(" ("); PrintBinary16(data[7]); Serial.println(")");
  Serial.print("CONFIG2: "); PrintHex16(&data[CONFIG2],1); Serial.print(" ("); PrintBinary16(data[8]); Serial.println(")");
  Serial.print("USER ID: "); PrintHex16(&data[USERID],4); Serial.println();
}

//
// Flash one word of data into the specified location on the PIC
//
void Store(uint16_t address, uint16_t data) {
  Serial.printf("0x%04X:0x%04X\n",address,data);
  if (address<currentAddress) CmdResetAddress();
  while (address>currentAddress) CmdIncAddress();
  Send(0x02,6);
  Send(data<<1,16);
  CmdBeginProgramI();
  delay(3);
}

//
// The main code that does the stuff ^__^
//
void loop() {
  uint16_t data[32];
  uint16_t a;
  uint8_t d_len;
  uint16_t d_addr;
  uint8_t d_typ;

  EnterLVPmode();

  // CONFIG words
  CmdResetAddress();
  CmdLoadConfig(0x00);
  CmdBulkErase();
  Store(CONFIG1, SWAP16(0xE4C9));  delay(5);
  Store(CONFIG2, SWAP16(0xFBFF));  delay(5);

  CmdResetAddress();

  // USER ID's in the CONFIG area
  Store(USERID+0,SWAP16(0x8031));	// Just put some hardcoded
  Store(USERID+1,SWAP16(0x0228));	// data here for fun while
  Store(USERID+2,SWAP16(0x8731));	// debugging
  Store(USERID+3,SWAP16(0xE12F));

  // CODE
  char *s;
  do {
    s=getline();
    Serial.println(s);
    d_len=HexDec2(s[1],s[2]);
    d_addr=HexDec4(s[3],s[4],s[5],s[6]);
    d_typ=HexDec2(s[7],s[8]);
    Serial.printf("len=%02x addres=%04x type=%02x\n",d_len,d_addr,d_typ);
    if (d_typ==0x00) {
      for (uint8_t i=0; i<d_len*2; i+=4) {
        Store(d_addr/2+i/4,HexDec4(s[11+i],s[12+i],s[9+i],s[10+i]));
      }
    }
  } while (d_typ!=1);

  // Dump the CONFIGs and the CODE areas onto serial
  // for debugging
  CmdResetAddress();
  DumpConfig();
  CmdResetAddress();
  DumpMemory();

  // De-assert the PIC reset line so the new code just uploaded
  // can start running on it. Then just hang the ESP in an forever loop
  RESET_HIGH;
  for (;;) delay(1);
}

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


Add TFmini plus (lidar) test code

Add TFmini plus (lidar) test code

// set this to the hardware serial port you wish to use
#define HWSERIAL Serial1
byte byteArray [9];
// Byte0 Byte 1 Byte2 Byte3  Byte4      Byte5      Byte6  Byte7  Byte8
// 0x89  0x89 Dist_L  Dist_H Strength_L Strength_H Temp_L Temp_H Checksum
// byte2 is distance, overflows into byte3

byte configOutput [5] = {0x5A, 0x05, 0x07, 0x01, 0x11}; // write this array to HWSERIAL to enable output
byte configUART [5] = {0x5A, 0x05, 0x0A, 0x00, 0x11}; // write this array to HWSERIAL to set sensor to UART mode
// more config commands on datasheet https://acroname.com/sites/default/files/assets/sj-gu-tfmini_plus-01-a04-datasheet_en.pdf

void setup() {
  Serial.begin(115200);
  HWSERIAL.begin(115200);// default baud rate
  HWSERIAL.write(configUART, 5); // set sensor to UART mode
  HWSERIAL.write(configOutput, 5); // enable output
}

void loop() {
  if (HWSERIAL.available() > 0) {
    HWSERIAL.readBytes(byteArray, 9); // write output of read to an array of length 9
    for (int i =0;i<9;i++){
      Serial.println(byteArray[i]);
    }
  }
}

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


Firmware for the control board MCU

Firmware for the control board MCU

/**
 * Power Control board for the Raspberry Pi using an ATTinyx5 microcontroller.
 * The Power Control board is using a relay to turn on and off the power to a Raspberry Pi.
 * Additionally, they are connected via (software) UART for communication when the RPi is on.
 * The microcontroller connected to a capacitive touch sensor which allows interaction with
 * the external user that wants to turn the Raspberry Pi on and off.
 *
 * ==== STATES ====
 * The microcontroller has the following states:
 * - Sleep state where the microcontroller is in deep sleep and the power to the RPi is OFF.
 * - Operation state where the microcontroller is triggering the relay to power on the RPi and
 * can communication to it via UART.
 *
 * ==== CURRENT FUNCTIONALITY ====
 * Upon starting up, the microcontroller goes in deep sleep which can be interrupted by a HIGH
 * signal coming from the capacitive sensor. This initiates a window of operation for the Raspberry Pi
 * during which it will remain on. Every consecutive touch moves the end of this window further in the
 * future, therefore, prolonging the period that the Raspberry Pi is functioning. In other words, on
 * every touch, the operation gets extended for the specified amount of time.
 */

#include <avr/sleep.h>    // Sleep Modes
#include <avr/power.h>    // Power management

const unsigned short touchSensorPin = PB2;
const unsigned short rpiPwrPin = PB3;
const boolean powerOnState = LOW; // The rpiPwrPin state that turns the power on to the RPi

volatile unsigned long timeToSleep = 0;
const unsigned long awakePeriod = 600000; // Time in milliseconds to remain awake on every new touch

/**
 * The change interrupt callback
 */
ISR (PCINT0_vect)
{
  // We register a touch event only when the signal from the touchSensor is rising
  if (digitalRead(touchSensorPin) == HIGH){
    timeToSleep = millis() + awakePeriod;
  }
}

/**
 * Makes the microcontroller go to deep sleep until a change interrupt occurs
 */
void goToSleep() {
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  ADCSRA = 0;            // turn off ADC
  power_all_disable ();  // power off ADC, Timer 0 and 1, serial interface
  sleep_enable();
  sleep_cpu();          // Sleep here and wait for the interrupt
  sleep_disable();
  power_all_enable();    // power everything back on
}

void turnRPiPowerOn(){
  digitalWrite(rpiPwrPin, powerOnState);
}

void turnRPiPowerOff(){
  digitalWrite(rpiPwrPin, !powerOnState);
}

void setup() {
  Serial.begin(9600); // The Universal ATtinyCore library by Spence Konde uses PB0 as TX and PB1 as RX
  pinMode(rpiPwrPin, OUTPUT);
  pinMode(touchSensorPin, INPUT);
  turnRPiPowerOff(); // When starting up, make sure the power to the RPi is off
  // Setup pin change interrupt for D2
  PCMSK  |= bit (PCINT2); // want pin D2 (PB2)
  GIFR   |= bit (PCIF); // clear any outstanding interrupts
  GIMSK  |= bit (PCIE); // enable pin change interrupts
}

void loop() {
  if (millis() >= timeToSleep) { // Check if it is currently time to be asleep
    turnRPiPowerOff(); // Turn off the power to the RPi
    goToSleep(); // Deep sleep until a change interrupt at the specified pin is triggered
  } else { // If we should not be sleeping, then we should be awake and doing stuff
    turnRPiPowerOn(); // Turn on the power to the RPi (if this is already on, it won't make any difference)
  }
}

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


Initial commit

Initial commit

/*
 * Sketch1.ino
 *
 * Timer 3 counts the 1Mhz reference from the THCAD (Port E bit 6)
 * Timer 4 counts the signal from the THCAD (Port H bit 7)
 * Timer 5 controls the output to the stepper driver (pins 45-46)
 * Int4 is the input from the parallel port (pin 2) counting pulses
 * Int5 is the input from the parallel port (pin 3) reading direction
 * Int7 is the input from the parallel port (Port E bit 7) THC ON
 *
 * Created: 5/30/2014 2:10:21 PM
 * Author: owner
 */

int timer4Val = 0;
int interruptCntr = 0;
boolean porte4s = false;
boolean porte5s = false;
float voltageACT = 0.0;
float voltageSP = 70.0;
float deadBand = 1.0;
long thcCorrectInc = 1;
int FreqZero = 1212;
int incomingByte = 0;
long currPosACT = 0;
long currPosIN = 0;
long currPosSP = 0;
boolean timer5ON = false;
int temp = 0;
boolean zDirIn = false;
boolean thcOn = false;
float thcKP = 0.10;
float voltageERR = 0.0;
boolean voltageUpdated = 0;
unsigned int junkCounter = 0;

//Only called upon startup
void setup()
{

        DDRB |= _BV(DDB7); // set direction for the LED

	DDRL |= _BV(DDL4) | _BV(DDL3); //set them as outputs

	//Serial.begin(57600);
	//Serial.println("Serial Started");

//////// TIMER 3 ///////// TIMER 3 ////////

	// External clock, Clear timer on Compare Match
	TCCR3A = 0x0;
	TCCR3B = _BV(WGM32)|_BV(CS32) | _BV(CS31) | _BV(CS30);

	//Set the top and enable the interrupt
	OCR3A = 0xA17;
	TIMSK3 = _BV(OCIE3A);

	//Set the pin as an input Port E bit 6
	DDRE &= ~_BV(DDE6);

//////// TIMER 4 ///////// TIMER 4 ////////

	//Normal counter, select external Clock rising edge
	TCCR4A = 0x0;
	TCCR4B = _BV(CS42) | _BV(CS41) | _BV(CS40);

	// Set Port H Bit 7 as an input
	DDRH &= ~_BV(DDH7);

//////// TIMER 5 ///////// TIMER 5 ////////

	//Set it to toggle the bit on COM5B on match (phase and freq correct
	TCCR5A = _BV(COM5B1) | _BV(WGM50);
	TCCR5B = _BV(WGM53); //leave the clock off for now

	//Set the top and compare value
	OCR5A = 0xE6; //E6=230//398=920//730=1840 is 115uS with no prescaling (top)
	OCR5B = 0x73; //73=115//1CC=460//398=920 is 57.5uS with no prescaling (toggle bit)

	TIMSK5 = _BV(TOIE5); //enable bottom interrupt

///////////// EXTERNAL INTERRUPTS /////////////////////////

	//Set the external interrupt edge triggers
	EICRB =  _BV(ISC70)| _BV(ISC50) | _BV(ISC41) | _BV(ISC40);

	//Enable the external interrupt
	EIMSK = _BV(INT7) | _BV(INT5) | _BV(INT4);

	//Set port E bit 4 as an input and enable pull up resistor
	DDRE &= ~_BV(DDE4);
	PORTE |= _BV(PORTE4);

	//Set port E bit 5 as an input and enable pull up resistor
	DDRE &= ~_BV(DDE5);
	PORTE |= _BV(PORTE5);

	//Set port E bit 7 as an input and enable pull up resistor
	DDRE &= ~_BV(DDE7);
	PORTE |= _BV(PORTE7);

	// Clear all timers
	TCNT3 = 0;
	TCNT4 = 0;
	TCNT5 = 0;

	currPosACT = 0;
	currPosIN = 0;
	currPosSP = 0;
	timer5ON = 0;

//NEED TO INITIALIZE THE PINS THAT ARE INTERRUPT DRIVEN
	temp = PINE & _BV(PINE7);

	if (temp != 0)
		thcOn = 1;
	else
		thcOn = 0;

	temp = PINE & _BV(PINE5);

	if (temp != 0)
		zDirIn = 1;
	else
		zDirIn = 0;

}

//STEP counter from the PC
ISR(INT4_vect)
{
	//porte4s = ~porte4s;

	if (zDirIn != 0)
		currPosIN--;
	else
		currPosIN++;

	if(!thcOn)
		currPosSP = currPosIN;
}

//Direction monitor from the PC
ISR(INT5_vect)
{
	//porte5s = ~porte5s;

	temp = PINE & _BV(PINE5);

	if (temp != 0)
		zDirIn = 1;
	else
		zDirIn = 0;
}

//Monitors the THC ON/OFF command from the PC
ISR(INT7_vect)
{
	//This is where the THC Enable is monitored
	temp = PINE & _BV(PINE7);

	if (temp != 0)
		thcOn = 1;
	else
	{
		thcOn = 0;
		currPosSP = currPosIN;
		currPosACT = currPosIN;
	}
}

//Collects the counts from the V/F converter
ISR(TIMER3_COMPA_vect)
{
	timer4Val = TCNT4;
	TCNT4 = 0;
	voltageUpdated = 1;
}

//Updates the output position, issues new step, or stops stepping
ISR(TIMER5_OVF_vect )
{
	//Sample the pin to see which direction it moved
	temp = PINL & _BV(PINL3);

	if (temp != 0)
		currPosACT--;
	else
		currPosACT++;

	//see if there are more pulses to be delivered
	if (currPosACT > currPosSP)
	{
		PORTL |= _BV(PORTL3);  //set direction for motor
	}
	else if ( currPosACT < currPosSP)
	{
		PORTL &= ~_BV(PORTL3);	//set direction for motor
	}
	else
	{
		//no pulses are needed, stop the timer
		TCCR5B &= 0xF8;
		timer5ON = 0;
	}
}

//Calculates the voltage feedback
void calcVolts()
{
	/*
	Voltage =  voltageFullScale * (timer4Val - FreqZero) / (freqFullScale - FreqZero)

	Where FreqOut is the output frequency of the THCAD, VFS is the unipolar full scale
	range 10V or 300V or custom value determined by external resistors. FFS is the full scale
	output frequency on the calibration sticker, and FZERO is the 0V input output frequency
	on the calibration sticker
	*/

	float temp = timer4Val*4-1212;

	if(temp <= 0)
	{
		voltageACT = 0;
	}else
	{
		voltageACT =  300 * temp / 8399;
	}
}

//Main loop
void loop()
{

      //calcVolts();//moved out of loop below just for debugging

	// if THC is on and there is a new data point available
	if (thcOn && voltageUpdated)
	{
		voltageUpdated = 0;
		calcVolts();

		voltageERR = voltageSP - voltageACT;

		if (voltageACT < (voltageSP-deadBand))
		{
			currPosSP += thcCorrectInc*voltageERR*thcKP;
		}
		else if (voltageACT > (voltageSP+deadBand))
		{
			currPosSP += thcCorrectInc*voltageERR*thcKP;
		}

	}

	//Start the output pulsing if it is not already
	if (timer5ON == 0 )
	{
		if (currPosACT != currPosSP)
		{
			if (currPosACT > currPosSP)
				PORTL |= _BV(PORTL3);//set the direction
			else
				PORTL &= ~_BV(PORTL3);//set the direction

			//start the timer
			TCCR5B |= _BV(CS50); // | _BV(CS50);
			timer5ON = 1;
		}
	}

        if( thcOn )
          PORTB |= _BV(7);
        else
          PORTB &= ~_BV(7);

	//debugJunk();
}

//Just for debugging
void debugJunk()
{
	junkCounter++;
/*
	if (Serial.available() )//> 0 && timer5ON == 0)
	{
		incomingByte = Serial.read();

		if(incomingByte == '0')
		{
			thcOn = 0;
		}
		else if (incomingByte == '1')
		{
			thcOn = 1;
		}
	}

*/

		//Serial.print(temp2,BIN);

	if (!(junkCounter % 2000))
	{
		Serial.print(thcOn,BIN);
		Serial.print(" ");
		Serial.print(voltageSP);
		Serial.print(" ");
		Serial.print(voltageACT);
		Serial.print(" ");
		Serial.print(currPosIN);
		Serial.print(" ");
		Serial.println(zDirIn);
	}

	//delay(50);

	/*

	temp2 = PINL & _BV(PINL4);

	if (temp2 > 0)
	{
		Serial.print("UP");
	}
	else
	{
		Serial.print("DN");
	}

	//Serial.print(temp2,BIN);

		Serial.print(" ");
	Serial.print(timer5ON);
	Serial.print(" ");
	Serial.println(currPos);

	delay(10);

	*/
	//digitalWrite(13, porte5s);

	/*
	Serial.print(voltage);
	Serial.print("\t ");
	Serial.println(timer4Val);
	Serial.println();
	delay(100);

	digitalWrite(13, HIGH);
	Serial.println("High");
	delay(250);
	digitalWrite(13,LOW);
	Serial.println("Low");
	delay(250);
	*/
}

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


Added Encoders example for sending Control Change events

// Encoders example. Assumes Arduino connected to the Mainboard, and the Encoders module connected to the first port (SV1).

#include <SPI.h>
#include <BuildingBlocks.h>

// Define an instance of MiniKeyboard module.
Encoders encoders;

// Define an instance of the Mainboard module.
Mainboard mainboard(encoders);

void setup() {
	// Setup serial communication for the MIDI port.
	Serial1.begin(31250);

	// Initialize the Mainboard module
	mainboard.init();

	// Set the function which will get called when keyboard events are detected.
	encoders.setCallback(&onEncEvent);
}

// Just update the Mainboard in order to receive the events that are happening in the attached modules.
void loop() {
	mainboard.update();
}

int16_t clamp(int16_t value, int16_t min, int16_t max) {
  if (value < min) value = min;
  else if (value > max) value = max;
  return value;
}

// This will get called while executing mainboard.update(), if events were detected.
void onEncEvent(uint8_t enc, int8_t change, bool isDown) {
	sendMidiCC(0, enc, clamp(encoders.getValue(enc), 0, 127)); // clamp the value between 0 and 127
}

// Send the 3 byte MIDI Control Change message through the Serial port.
void sendMidiCC(uint8_t channel, uint8_t control, uint8_t value) {
	Serial1.write(0xB0 | channel);
	Serial1.write(control);
	Serial1.write(value);
}

error: pathspec 'arduino/libraries/BuildingBlocks/examples/Encoders/Encoders.ino' did not match any file(s) known to git


Added BULB light controller sketch

Added BULB light controller sketch

#include <SPI.h>
#include <Ethernet.h>

#include <avr/wdt.h>

#include <PusherClient.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

PusherClient client;

#define FLOOR1  2
#define FLOOR2  3
#define FLOOR3  5
#define FLOOR4  6

void setup() {
  pinMode(FLOOR1, OUTPUT);
  pinMode(FLOOR2, OUTPUT);
  pinMode(FLOOR3, OUTPUT);
  pinMode(FLOOR4, OUTPUT);

  Serial.begin(9600);

  turnOnFloor1("");
  turnOnFloor2("");
  turnOnFloor3("");
  turnOnFloor4("");

  wdt_enable(WDTO_8S);

  Serial.println("Init...");

  if (Ethernet.begin(mac) == 0) {
    Serial.println("Init Ethernet failed");
    while(1) {}
  }

  wdt_reset();

  Serial.println("Connecting...");

  if (client.connect("138289ba194ec1862b00")) {
    wdt_reset();

    Serial.println("Connected");

    client.bind("floor1_on", turnOnFloor1);
    client.bind("floor1_off", turnOffFloor1);

    client.bind("floor2_on", turnOnFloor2);
    client.bind("floor2_off", turnOffFloor2);

    client.bind("floor3_on", turnOnFloor3);
    client.bind("floor3_off", turnOffFloor3);

    client.bind("floor4_on", turnOnFloor4);
    client.bind("floor4_off", turnOffFloor4);

    client.bind("all_off", turnOffAll);
    client.bind("all_on", turnOnAll);

    client.subscribe("homekit_channel");
  }

  wdt_disable();
}

void loop() {
  if (client.connected()) {
    client.monitor();
  } else {
    wdt_enable(WDTO_8S);

    Serial.println("Connection lost, reconnecting...");

    while(1) {};
  }
}

void turnOffFloor1(String data) {
  Serial.println("FLOOR 1 OFF");
  digitalWrite(FLOOR1, HIGH);
}

void turnOnFloor1(String data) {
  Serial.println("FLOOR 1 ON");
  digitalWrite(FLOOR1, LOW);
}

void turnOffFloor2(String data) {
  digitalWrite(FLOOR2, HIGH);
}

void turnOnFloor2(String data) {
  digitalWrite(FLOOR2, LOW);
}

void turnOffFloor3(String data) {
  digitalWrite(FLOOR3, HIGH);
}

void turnOnFloor3(String data) {
  digitalWrite(FLOOR3, LOW);
}

void turnOffFloor4(String data) {
  digitalWrite(FLOOR4, HIGH);
}

void turnOnFloor4(String data) {
  digitalWrite(FLOOR4, LOW);
}

void turnOffAll(String data) {
  turnOffFloor1("");
  turnOffFloor2("");
  turnOffFloor3("");
  turnOffFloor4("");
}

void turnOnAll(String data) {
  turnOnFloor1("");
  turnOnFloor2("");
  turnOnFloor3("");
  turnOnFloor4("");
}

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


Added new wifi driver as supported device

/*
 Wifi driver board using the ESP8266 on a H801 WIFI LED Controller

 Make sure you install the ESP8266 board:
  - Add the following 3rd party board manager under "File -> Preferences -> Additional Boards Manager URLs":
       http://arduino.esp8266.com/stable/package_esp8266com_index.json
  - Open the "Tools -> Board -> Board Manager" and click install for the ESP8266"
  - Select your ESP8266 in "Tools -> Board"
*/

#include <ESP8266WiFi.h>
#include <PubSubClient.h>

// RGB FET
// SWAPPED RED AND W1 in enschede
constexpr uint8_t led_pin_red   = 14;
constexpr uint8_t led_pin_green = 13;
constexpr uint8_t led_pin_blue  = 12;

// W FET
constexpr uint8_t led_pin_w1    = 15;
constexpr uint8_t led_pin_w2    = 4;

// onboard green LED D1
constexpr uint8_t led_pin_onboard_green = 5;
// onboard red LED D2
constexpr uint8_t leD_pin_onboard_red   = 1;

constexpr char ssid[] = "YOURSSID";
constexpr char password[] = "SECRET!";
constexpr char mqtt_server[] = "mqtthost.lan";
constexpr short mqtt_port = 1883;

constexpr char mqtt_prefix[]            = "/devices/dimmer/";
constexpr char mqtt_w1_status[]         = "/w1/status";
constexpr char mqtt_w2_status[]         = "/w2/status";
constexpr char mqtt_w1_status_set[]     = "/w1/status_set";
constexpr char mqtt_w2_status_set[]     = "/w2/status_set";
constexpr char mqtt_w1_brightness[]     = "/w1/brightness";
constexpr char mqtt_w2_brightness[]     = "/w2/brightness";
constexpr char mqtt_w1_brightness_set[] = "/w1/brightness_set";
constexpr char mqtt_w2_brightness_set[] = "/w2/brightness_set";
constexpr char mqtt_fade_time[]         = "/fadetime";
constexpr char mqtt_fade_time_set[]     = "/fadetime_set";

constexpr uint8_t led_index_r = 0;
constexpr uint8_t led_index_g = 1;
constexpr uint8_t led_index_b = 2;
constexpr uint8_t led_index_w1 = 3;
constexpr uint8_t led_index_w2 = 4;

WiFiClient espClient;
PubSubClient client(espClient);
uint8_t mac[6];
unsigned long lastLedCheck = 0;
char friendly_mac_address[18] = {0};

constexpr short led_loop_time = 20;

short led_brightness_current[5] = {0};
short led_brightness[5] = {0};
short led_step_size[5] = {0};
bool  led_status[5] = {0};
short led_fade_time = 200;
uint8_t led_pins[] = {led_pin_red, led_pin_blue, led_pin_green, led_pin_w1, led_pin_w2};

void setup_wifi() {

  delay(10);
  // Connect to the local WiFi network
  Serial1.println();
  Serial1.print("Connecting to ");
  Serial1.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial1.print(".");
  }

  randomSeed(micros());

  Serial1.println("");
  Serial1.println("WiFi connected");
  Serial1.println("IP address: ");
  Serial1.println(WiFi.localIP());
}

void set_led_status(uint8_t led, bool status) {
  led_status[led] = status;
  Serial1.print("Led status ");
  Serial1.print(String(led));
  Serial1.print(" to ");
  Serial1.print(String(status));
  Serial1.println();

  const char* topic;
  std::string device_prefix(mqtt_prefix);
  device_prefix += std::string(friendly_mac_address);
  if(led == led_index_w1) {
    topic = (device_prefix + mqtt_w1_status).c_str();
  } else {
    topic = (device_prefix + mqtt_w2_status).c_str();
  }
  client.publish(topic, String(led_status[led]).c_str());
}

void set_led_brightness(uint8_t led, uint16_t status) {
  led_brightness[led] = status;
  short difference = led_brightness[led] - led_brightness_current[led];
  short number_of_steps = (led_fade_time / led_loop_time);
  led_step_size[led] = difference / number_of_steps;

  // Print a bit to inform of changing brightness
  Serial1.print("Led brightness ");
  Serial1.print(String(led));
  Serial1.print(" to ");
  Serial1.print(String(status));
  Serial1.println();

  const char* topic;
  std::string device_prefix(mqtt_prefix);
  device_prefix += std::string(friendly_mac_address);
  if(led == led_index_w1) {
    topic = (device_prefix + mqtt_w1_brightness).c_str();
  } else {
    topic = (device_prefix + mqtt_w2_brightness).c_str();
  }
  client.publish(topic, String(led_brightness[led]).c_str());
}

void set_fade_time(uint16_t fadetime) {
  led_fade_time = fadetime;
  Serial1.print("Led fadetime ");
  Serial1.print(String(fadetime));
  Serial1.println();

  const char* topic;
  std::string device_prefix(mqtt_prefix);
  device_prefix += std::string(friendly_mac_address);
  topic = (device_prefix + mqtt_fade_time).c_str();
  client.publish(topic, String(led_fade_time).c_str());
}

void check_leds() {
  for (int i = 0; i < sizeof(led_status); ++i) {
    short step = led_step_size[i];
    short target = led_brightness[i];
    short current = led_brightness_current[i];

    if(!led_status[i]) {
      analogWrite(led_pins[i], 0);
    } else if(current != target) {

      if((step > 0 && (current + step) < target) || (step < 0 && (current + step) > target)) {
        led_brightness_current[i] = current + step;
      } else {
        led_brightness_current[i] = target;
      }
      analogWrite(led_pins[i], led_brightness_current[i]);
    }
  }
}

void callback(char* topic, byte* payload, unsigned int length) {
  Serial1.print("Message arrived [");
  Serial1.print(topic);
  Serial1.print("] ");
  Serial1.println();

  topic += sizeof(mqtt_prefix) + sizeof(friendly_mac_address) - 2;

  Serial1.print(topic);
  Serial1.println();

  if(strncmp(topic, mqtt_w1_status_set, sizeof(mqtt_w1_status_set)) == 0) {
    bool status = ((char)payload[0] == '1');
    set_led_status(led_index_w1, status);

  } else if(strncmp(topic, mqtt_w2_status_set, sizeof(mqtt_w2_status_set)) == 0) {
    bool status = ((char)payload[0] == '1');
    set_led_status(led_index_w2, status);

  } else if(strncmp(topic, mqtt_w1_brightness_set, sizeof(mqtt_w1_brightness_set)) == 0) {
    payload[length] = 0;
    int level = atoi((char*)payload);
    set_led_brightness(led_index_w1, level);
  } else if(strncmp(topic, mqtt_w2_brightness_set, sizeof(mqtt_w2_brightness_set)) == 0) {
    payload[length] = 0;
    int level = atoi((char*)payload);
    set_led_brightness(led_index_w2, level);
  } else if(strncmp(topic, mqtt_fade_time_set, sizeof(mqtt_fade_time_set)) == 0) {
    payload[length] = 0;
    int fadetime = atoi((char*)payload);
    set_fade_time(fadetime);
  }
}

void reconnect() {
  while (!client.connected()) {
    Serial1.print("Attempting MQTT connection...");

    // Create a random client ID
    String clientId = "ESP8266Client-";
    clientId += String(random(0xffff), HEX);

    // Attempt to connect
    if (client.connect(clientId.c_str())) {
      Serial1.println("connected to mqtt");

      // Once connected, publish an announcement...
      std::string device_prefix(mqtt_prefix);
      device_prefix += std::string(friendly_mac_address);
      client.publish((device_prefix + mqtt_w1_status).c_str(), String(led_status[led_index_w1]).c_str());
      client.publish((device_prefix + mqtt_w2_status).c_str(), String(led_status[led_index_w2]).c_str());
      client.publish((device_prefix + mqtt_w1_brightness).c_str(), String(led_brightness[led_index_w1]).c_str());
      client.publish((device_prefix + mqtt_w2_brightness).c_str(), String(led_brightness[led_index_w2]).c_str());
      client.publish((device_prefix + mqtt_fade_time).c_str(), String(led_fade_time).c_str());

      client.subscribe((device_prefix + mqtt_w1_status_set).c_str());
      client.subscribe((device_prefix + mqtt_w2_status_set).c_str());
      client.subscribe((device_prefix + mqtt_w1_brightness_set).c_str());
      client.subscribe((device_prefix + mqtt_w2_brightness_set).c_str());
      client.subscribe((device_prefix + mqtt_fade_time_set).c_str());
      client.subscribe((device_prefix + mqtt_fade_time_set).c_str());
    } else {
      Serial1.print("failed, rc=");
      Serial1.print(client.state());
      Serial1.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup() {
  for(int i = 0; i < sizeof(led_pins); ++i) {
    analogWrite(i, 0);
  }

  pinMode(BUILTIN_LED, OUTPUT);     // Initialize the BUILTIN_LED pin as an output
  Serial1.begin(115200);
  setup_wifi();
  WiFi.macAddress(mac);
  for (int i = 0; i < sizeof(mac); ++i){
    snprintf(friendly_mac_address + i*3, sizeof(friendly_mac_address) - i*3, "%02x:", mac[i]);
  }
  client.setServer(mqtt_server, mqtt_port);
  client.setCallback(callback);
}

void loop() {

  if (!client.connected()) {
    reconnect();
  }
  client.loop();

  unsigned long now = millis();
  if(now - lastLedCheck >= led_loop_time) {
    check_leds();
    lastLedCheck = now;
  }
}

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


Simple demo example program.

Simple demo example program.

#pragma GCC diagnostic warning "-Wall"
#include "RA8875.h"

const int intPin = 0;
const int csPin = 10;
const int resetPin = 9;

RA8875 tft = RA8875(csPin, intPin);

void setup()
{
  Serial.begin(9600);

//  while (!Serial)
//    ;

  delay(2000);

  Serial.println("Hello!");

  tft.init();
  tft.clearMemory();
  tft.setBacklight(true);
  tft.setScrollWindow(0, 479, 0, 271);

  Serial.println("TFT init complete.");

//  tft.setDrawLayer(2);
//  tft.clearMemory();
//  tft.setDrawLayer(1);

  textTest();

  delay(1000);

  pixelTest();

  delay(1000);

  gradientTest();

  //tft.setLayerMode(RA8875_LAYER_OR);

  //tft.setDrawLayer(2);

//  tft.drawRect(50, 50, 100, 100, RGB332(0, 255, 0));
//  tft.fillRect(150, 50, 200, 100, RGB332(0, 255, 255));
//  tft.drawLine(250, 50, 300, 100, RGB332(255, 0, 255));
//  tft.drawRect(0, 256, 479, 271, RGB332(255, 0, 255));
}

void textTest()
{
  Serial.println("Text test.");

  tft.setCursor(0, 0);
  Serial.println("Set cursor position complete.");

  tft.setCursorVisibility(false, true);
  Serial.println("Set cursor visibility complete.");

  tft.setTextSize(1);
  tft.println("Text size 1");

  tft.setTextSize(2);
  tft.println("Text size 2");

  tft.setTextSize(3);
  tft.println("Text size 3");

  tft.setTextSize(4);
  tft.println("Text size 4");

  Serial.println("Print text complete.");
}

void gradientTest()
{
  Serial.println("Gradient test.");

  tft.clearMemory();

  int width = tft.getWidth();
  int barHeight = tft.getHeight() / 3;

  for (int i = 0; i <= 255; i++)
  {
    tft.fillRect((width / 256.0) * i, 0, (width / 256.0) * i + 1, barHeight, RGB332(i, 0, 0));
    tft.fillRect((width / 256.0) * i, barHeight, (width / 256.0) * i + 1, barHeight * 2, RGB332(0, i, 0));
    tft.fillRect((width / 256.0) * i, barHeight * 2, (width / 256.0) * i + 1, barHeight * 3, RGB332(0, 0, i));
    //tft.fillRect(0, 0, 479, 271, RGB332(0, i, 0));
    //tft.fillRect(0, 0, 479, 271, RGB332(0, 0, i));
  }

}

void pixelTest()
{
  Serial.println("Pixel test.");

  int width = tft.getWidth();
  int height = tft.getHeight();

  for (int i = 0; i < 20000; i++)
  {
    int x = random(0, width);
    int y = random(0, height);

    tft.drawPixel(x, y, 0x55);
  }

}

void loop()
{

}

error: pathspec 'examples/ra8875-demo/ra8875-demo.ino' did not match any file(s) known to git


Create Garage_control.ino

Create Garage_control.ino

/*
 * from
 * http://esp8266-server.de/
 *
 * Webserver as Accesspoint for ESP8266
 *
 * Free for anyone!!!
 *
 */

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

String html1 = "<!DOCTYPE html>\r\n\r\n\
\r\n<meta content=\"text/html; charset=ISO-8859-1\" http-equiv=\"content-type\">\r\n\
<title>Garage control</title>\r\n\
<form action=\"";
// String((val)?"/1.html":"/0.html")
String html2 = "\">\r\n<input value=\"ON/OFF\" style=\"";
String html3 = " width:15em;height:13em; font-size: 24px;\" type=\"submit\">\
</form>\r\n\r\n\r\n\r\n";

ESP8266WebServer server(80);    // Setup server port
int val = 1;                    // switched off during init
String Temp = "";

void Ereignis_SchalteON()       // Executed if "http://<ip address>/1.html" is called
{
    val = 0;                      // Relay off
    digitalWrite(0, val);         // GPIO0
    Temp = html1 + String((val) ? "/1.html" : "/0.html");
    Temp += html2 + String((val) ? "BACKGROUND-COLOR: DarkGray;" : "BACKGROUND-COLOR: Chartreuse;") + html3;
    server.send(200, "text/html", Temp);
}

void Ereignis_SchalteOFF()      // Executed if "http://<ip address>//0.html" is called
{
    val = 1;                      // Relay on
    digitalWrite(0, val);         // GPIO0
    Temp = html1 + String((val) ? "/1.html" : "/0.html");
    Temp += html2 + String((val) ? "BACKGROUND-COLOR: DarkGray;" : "BACKGROUND-COLOR: Chartreuse;") + html3;
    server.send(200, "text/html", Temp);
}

void Ereignis_Index()           // Executed if "http://<ip address>/" is called
{
    Temp = html1 + String((val) ? "/1.html" : "/0.html");
    Temp += html2 + String((val) ? "BACKGROUND-COLOR: DarkGray;" : "BACKGROUND-COLOR: Chartreuse;") + html3;
    server.send(200, "text/html", Temp);
}

void setup()
{
    //digitalWrite(0, 1);                   // Anfangszustand 1 (Relais ausgeschaltet)
    pinMode(0, OUTPUT);                   // GPIO0 configured as output
    pinMode(2, INPUT_PULLUP);             // GPIO2 configured as input with Pullup
    digitalWrite(0, 1);                   // initial condition 1 (Relay off)

    Serial.begin(115200);                 // init seriel inteface
    Serial.println("");                   // print empty line
    Serial.println("Starte WLAN-Hotspot \"astral\"");
    WiFi.mode(WIFI_AP);                   // access point modus
    WiFi.softAP("astral", "12345678");    // name of the Wifi net
    delay(500);                           // wait 0,5s
    Serial.print("IP Adresse ");          // print of the current IP of the server
    Serial.println(WiFi.softAPIP());

    // treatment of the different events - before server.begin()!!!
    server.on("/",       Ereignis_Index);
    server.on("/1.html", Ereignis_SchalteON);
    server.on("/0.html", Ereignis_SchalteOFF);

    server.begin();                       // start the server
    Serial.println("HTTP Server gestartet");
}

void loop()
{
    server.handleClient();
    delay(500);

//  if (!digitalRead(2))          //Wenn Taster an GPIO2 betetigt wurde
//  {
//    val = !val;                 // Schaltzuschtand andern
//    digitalWrite(0, val);
//    while (!digitalRead(2))server.handleClient(); // Warten bis der Taster losgelassen wird.
//  }
}

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


Create spark-plotly.ino

Create spark-plotly.ino

#include "spark-plotly.h"

#define DATA_POINTS 4

char* data_point_tokens[NUM_TOKENS] = {"token1", "token2", "token3","token4"};
plotly graph = plotly("username", "secret", streaming_tokens, "streamname", DATA_POINTS);

void setup() {
   graph.init();
   graph.fileopt = "extend";
   graph.openStream();
}

void loop() {

    float val1;
    float val2;
    float val3;
    float val4;

    // up to you to decide what these values represent and how they get initialized/updated.

    unsigned long x = millis();

    graph.plot(x, val1, data_point_tokens[0]);
    graph.plot(x, val2, data_point_tokens[1]);
    graph.plot(x, val3, data_point_tokens[2]);
    graph.plot(x, val4, data_point_tokens[3]);

}

error: pathspec 'examples/spark-plotly.ino' did not match any file(s) known to git