code that runs on the arduino payload

code that runs on the arduino payload

#include <Wire.h>
#include "RTClib.h"
#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>
#include "Adafruit_TMP007.h"
#include "Adafruit_HTU21DF.h"

RTC_DS1307 rtc;
Adafruit_TMP007 tmp007;
Adafruit_HTU21DF htu = Adafruit_HTU21DF();

SoftwareSerial mySerial(3, 2);
Adafruit_GPS GPS(&mySerial);

// Set GPSECHO to 'false' to turn off echoing the GPS data to the Serial console
// Set to 'true' if you want to debug and listen to the raw GPS sentences.
#define GPSECHO  false

// this keeps track of whether we're using the interrupt
// off by default!
boolean usingInterrupt = false;
void useInterrupt(boolean); // Func prototype keeps Arduino 0023 happy

void setup() {
  Serial.begin(115200);
  Wire.begin();
  rtc.begin();

  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    //rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }

  if (! tmp007.begin(TMP007_CFG_4SAMPLE)) {
    Serial.println("No sensor found");
    while (1);
  }

  if (!htu.begin()) {
    Serial.println("Couldn't find sensor!");
    while (1);
  }

  // 9600 NMEA is the default baud rate for Adafruit MTK GPS's- some use 4800
  GPS.begin(9600);

  // uncomment this line to turn on RMC (recommended minimum) and GGA (fix data) including altitude
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
  // uncomment this line to turn on only the "minimum recommended" data
  //GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCONLY);
  // For parsing data, we don't suggest using anything but either RMC only or RMC+GGA since
  // the parser doesn't care about other sentences at this time

  // Set the update rate
  GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);   // 1 Hz update rate
  // For the parsing code to work nicely and have time to sort thru the data, and
  // print it out we don't suggest using anything higher than 1 Hz

  // Request updates on antenna status, comment out to keep quiet
  GPS.sendCommand(PGCMD_ANTENNA);

  // the nice thing about this code is you can have a timer0 interrupt go off
  // every 1 millisecond, and read data from the GPS for you. that makes the
  // loop code a heck of a lot easier!
  useInterrupt(true);

  delay(1000);
  // Ask for firmware version
  mySerial.println(PMTK_Q_RELEASE);
}

// Interrupt is called once a millisecond, looks for any new GPS data, and stores it
SIGNAL(TIMER0_COMPA_vect) {
  char c = GPS.read();
  // if you want to debug, this is a good time to do it!
#ifdef UDR0
  if (GPSECHO)
    if (c) UDR0 = c;
    // writing direct to UDR0 is much much faster than Serial.print
    // but only one character can be written at a time.
#endif
}

void useInterrupt(boolean v) {
  if (v) {
    // Timer0 is already used for millis() - we'll just interrupt somewhere
    // in the middle and call the "Compare A" function above
    OCR0A = 0xAF;
    TIMSK0 |= _BV(OCIE0A);
    usingInterrupt = true;
  } else {
    // do not call the interrupt function COMPA anymore
    TIMSK0 &= ~_BV(OCIE0A);
    usingInterrupt = false;
  }
}

uint32_t timer = millis();

void loop() {

    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  // in case you are not using the interrupt above, you'll
  // need to 'hand query' the GPS, not suggested :(
  if (! usingInterrupt) {
    // read data from the GPS in the 'main loop'
    char c = GPS.read();
    // if you want to debug, this is a good time to do it!
    if (GPSECHO)
      if (c) Serial.print(c);
  }

  // if a sentence is received, we can check the checksum, parse it...
  if (GPS.newNMEAreceived()) {
    // a tricky thing here is if we print the NMEA sentence, or data
    // we end up not listening and catching other sentences!
    // so be very wary if using OUTPUT_ALLDATA and trytng to print out data
    //Serial.println(GPS.lastNMEA());   // this also sets the newNMEAreceived() flag to false

    if (!GPS.parse(GPS.lastNMEA()))   // this also sets the newNMEAreceived() flag to false
      return;  // we can fail to parse a sentence in which case we should just wait for another
  }

  // if millis() or timer wraps around, we'll just reset it
  if (timer > millis())  timer = millis();

  // approximately every 1 seconds or so, print out the current stats
  if (millis() - timer > 1000) {
    timer = millis(); // reset the timer
    DateTime now = rtc.now();
    float objt = tmp007.readObjTempC();
    float diet = tmp007.readDieTempC();

    Serial.print("Fix: "); Serial.print((int)GPS.fix);
    Serial.print(" quality: "); Serial.println((int)GPS.fixquality);
    Serial.println(" ");
    if (GPS.fix) {
      if(GPS.seconds != now.second()){
        rtc.adjust(DateTime(2000+GPS.year, GPS.month, GPS.day, GPS.hour, GPS.minute, GPS.seconds));
      }
      Serial.print("Location: ");
      Serial.print(GPS.latitude, 4); Serial.print(GPS.lat);
      Serial.print(", ");
      Serial.print(GPS.longitude, 4); Serial.println(GPS.lon);
      Serial.print("Location (in degrees, works with Google Maps): ");
      Serial.print(GPS.latitudeDegrees, 4);
      Serial.print(", ");
      Serial.println(GPS.longitudeDegrees, 4);

      Serial.print("Speed (knots): "); Serial.println(GPS.speed);
      Serial.print("Angle: "); Serial.println(GPS.angle);
      Serial.print("Altitude: "); Serial.println(GPS.altitude);
      Serial.print("Object Temperature: "); Serial.print(objt); Serial.println("*C");
      Serial.print("Die Temperature: "); Serial.print(diet); Serial.println("*C");
      Serial.print("Hum: "); Serial.println(htu.readHumidity());

      Serial.println(" ");
    }
  }
}

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


removed the while loop

removed the while loop

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/TEAMarg/SiNe-DeMo.git/'


Create TheThingsNetworkSodaqExpLorer.ino

Simple example to connect a Sodaq ExpLoRer board to The Things Network

#include <Sodaq_RN2483.h>
#include <CayenneLPP.h>
#define debugSerial SerialUSB
#define loraSerial Serial2

bool OTAA = true;

const uint8_t devAddr[4] =
{
  0x00,0x00,0x00,0x00
};

const uint8_t appSKey[16] =
{
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};

const uint8_t nwkSKey[16] =
{
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};

const uint8_t DevEUI[8] =
{
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};

const uint8_t AppEUI[16] =
{
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};

const uint8_t AppKey[16] =
{
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};

void setup()
{
  while ((!debugSerial) && (millis() < 10000)) {
  }

  debugSerial.begin(57600);
  loraSerial.begin(LoRaBee.getDefaultBaudRate());
  setupLoRa();
}

void setupLoRa() {
  setupLoRaOTAA();
}

void setupLoRaOTAA() {
  debugSerial.println(LoRaBee.initOTA(loraSerial, DevEUI, AppEUI, AppKey, false));
  if (LoRaBee.initOTA(loraSerial, DevEUI, AppEUI, AppKey, false)){
    debugSerial.println("Network connection successful.");
  }else{
    debugSerial.println("Network connection failed!");
  }
}

CayenneLPP lpp(51);
float mVolts,temp;
void loop()
{
  mVolts = (float)analogRead(TEMP_SENSOR) * 3300.0 / 1023.0;
  temp = (mVolts - 500.0) / 10.0;
  lpp.reset();
  lpp.addTemperature(1, temp);

  switch (LoRaBee.send(1, lpp.getBuffer(), lpp.getSize()))
  {
    case NoError:
    debugSerial.println("Successful transmission.");
    break;
    case NoResponse:
    debugSerial.println("There was no response from the device.");
    break;
    case Timeout:
    debugSerial.println("Connection timed-out. Check your serial connection to the device! Sleeping for 20sec.");
    delay(20000);
    break;
    case PayloadSizeError:
    debugSerial.println("The size of the payload is greater than allowed. Transmission failed!");
    break;
    case InternalError:
    debugSerial.println("Oh No! This shouldn't happen. Something is really wrong! The program will reset the RN module.");
    setupLoRa();
    break;
    case Busy:
    debugSerial.println("The device is busy. Sleeping for 10 extra seconds.");
    delay(10000);
    break;
    case NetworkFatalError:
    debugSerial.println("There is a non-recoverable error with the network connection. The program will reset the RN module.");
    setupLoRa();
    break;
    case NotConnected:
    debugSerial.println("The device is not connected to the network. The program will reset the RN module.");
    setupLoRa();
    break;
    case NoAcknowledgment:
    debugSerial.println("There was no acknowledgment sent back!");
    break;
    default:
    break;
  }
  delay(10000);
}

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


modified servo sweep from Mark DeLoura

modified servo sweep from Mark DeLoura

// Sweep
// by BARRAGAN <>http://barraganstudio.com<>
// This example code is in the public domain.

#include <Servo.h>

Servo myservo;  // create servo object to control a servo
                // a maximum of eight servo objects can be created

int pos = 90;    // variable to store the servo position
int dir = -2;

void setup()
{
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
  Serial.begin(9600);
}

void loop()
{
  myservo.write(pos);
  pos += dir;
  delay(75);
  if (pos > 125) {
    dir *= -1;
    delay(3000);
  }
  if (pos < 35) {
    dir *= -1;
    delay(3000);
  }

}

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


add finger-web base

add finger-web base

#include <Adafruit_Fingerprint.h>
#include <SoftwareSerial.h>

int getFingerprintIDez();

// pin #2 is IN from sensor (GREEN wire)
// pin #3 is OUT from arduino  (WHITE wire)
SoftwareSerial mySerial(2, 3);

Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);

void setup()
{
  Serial.begin(9600);
  Serial.println("fingertest");

  // set the data rate for the sensor serial port
  finger.begin(57600);

  if (finger.verifyPassword()) {
    Serial.println("Sensor encontrado!");
  } else {
    Serial.println("Did not find fingerprint sensor :(");
    while (1);
  }
  Serial.println("COLOQUE SEU DEDO :)");
}

void loop()                     // run over and over again
{
  getFingerprintIDez();
  delay(50);            //don't ned to run this at full speed.
}

uint8_t getFingerprintID() {
  uint8_t p = finger.getImage();
  switch (p) {
    case FINGERPRINT_OK:
      Serial.println("Image taken");
      break;
    case FINGERPRINT_NOFINGER:
      Serial.println("No finger detected");
      return p;
    case FINGERPRINT_PACKETRECIEVEERR:
      Serial.println("Communication error");
      return p;
    case FINGERPRINT_IMAGEFAIL:
      Serial.println("Imaging error");
      return p;
    default:
      Serial.println("Unknown error");
      return p;
  }

  // OK success!

  p = finger.image2Tz();
  switch (p) {
    case FINGERPRINT_OK:
      Serial.println("Image converted");
      break;
    case FINGERPRINT_IMAGEMESS:
      Serial.println("Image too messy");
      return p;
    case FINGERPRINT_PACKETRECIEVEERR:
      Serial.println("Communication error");
      return p;
    case FINGERPRINT_FEATUREFAIL:
      Serial.println("Could not find fingerprint features");
      return p;
    case FINGERPRINT_INVALIDIMAGE:
      Serial.println("Could not find fingerprint features");
      return p;
    default:
      Serial.println("Unknown error");
      return p;
  }

  // OK converted!
  p = finger.fingerFastSearch();
  if (p == FINGERPRINT_OK) {
    Serial.println("Found a print match!");
  } else if (p == FINGERPRINT_PACKETRECIEVEERR) {
    Serial.println("Communication error");
    return p;
  } else if (p == FINGERPRINT_NOTFOUND) {
    Serial.println("Did not find a match");
    return p;
  } else {
    Serial.println("Unknown error");
    return p;
  }

  // found a match!
  Serial.print("SUA ID FOI ENCONTRADA. ESSA --> "); Serial.print(finger.fingerID);
  Serial.print(" Dado de confidencia "); Serial.println(finger.confidence);
}

// returns -1 if failed, otherwise returns ID #
int getFingerprintIDez() {
  uint8_t p = finger.getImage();
  if (p != FINGERPRINT_OK)  return -1;

  p = finger.image2Tz();
  if (p != FINGERPRINT_OK)  return -1;

  p = finger.fingerFastSearch();
  if (p != FINGERPRINT_OK)  return -1;

  // found a match!
  Serial.print("SUA ID FOI ENCONTRADA. ESSA --> "); Serial.print(finger.fingerID);
  Serial.print(" Dado de confidencia "); Serial.println(finger.confidence);
  return finger.fingerID;
}

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


Updated the repo with a folder for the sketch as needed by Arduino

/*
 * HID RFID Reader Wiegand Interface for Arduino Uno
 * Originally by  Daniel Smith, 2012.01.30 -- http://www.pagemac.com/projects/rfid/arduino_wiegand
 *
 * Updated 2016-11-23 by Jon "ShakataGaNai" Davis.
 * See https://obviate.io/?p=7470 for more details & instructions
*/
// needed for SD card
#include <SPI.h>
#include <SD.h>

File myFile;

// needed for RTC on the Datalogger shield
// https://learn.adafruit.com/adafruit-data-logger-shield
// Date and time functions using a DS1307 RTC connected via I2C and Wire lib
#include <Wire.h>
#include "RTClib.h"

#if defined(ARDUINO_ARCH_SAMD)
// for Zero, output on USB Serial console, remove line below if using programming port to program the Zero!
   #define Serial SerialUSB
#endif

RTC_DS1307 rtc;

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

// end of RTC setup

#define MAX_BITS 100                 // max number of bits
#define WEIGAND_WAIT_TIME  3000      // time to wait for another weigand pulse.

unsigned char databits[MAX_BITS];    // stores all of the data bits
unsigned char bitCount;              // number of bits currently captured
unsigned char flagDone;              // goes low when data is currently being captured
unsigned int weigand_counter;        // countdown until we assume there are no more bits

unsigned long facilityCode=0;        // decoded facility code
unsigned long cardCode=0;            // decoded card code

int LED_GREEN = 11;
int LED_RED = 12;
int BEEP_BEEP = 10;

// interrupt that happens when INTO goes low (0 bit)
void ISR_INT0() {
  //Serial.print("0");   // uncomment this line to display raw binary
  bitCount++;
  flagDone = 0;
  weigand_counter = WEIGAND_WAIT_TIME;

}

// interrupt that happens when INT1 goes low (1 bit)
void ISR_INT1() {
  //Serial.print("1");   // uncomment this line to display raw binary
  databits[bitCount] = 1;
  bitCount++;
  flagDone = 0;
  weigand_counter = WEIGAND_WAIT_TIME;
}

void setup() {
  pinMode(LED_RED, OUTPUT);
  pinMode(LED_GREEN, OUTPUT);
  pinMode(BEEP_BEEP, OUTPUT);
  digitalWrite(LED_RED, HIGH); // High = Off
  digitalWrite(BEEP_BEEP, HIGH); // High = off
  digitalWrite(LED_GREEN, LOW);  // Low = On
  pinMode(2, INPUT);     // DATA0 (INT0)
  pinMode(3, INPUT);     // DATA1 (INT1)

  Serial.begin(9600);
  Serial.println("RFID Readers");
  // SD card setup
  Serial.print("Initializing SD card...");

  if (!SD.begin(10)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");

// end of SD Card setup

// RTC chip setup
#ifndef ESP8266
  while (!Serial); // for Leonardo/Micro/Zero
#endif

  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }

 // end of RTC setup
  // binds the ISR functions to the falling edge of INTO and INT1
  attachInterrupt(0, ISR_INT0, FALLING);
  attachInterrupt(1, ISR_INT1, FALLING);

  weigand_counter = WEIGAND_WAIT_TIME;
}

void loop()
{
  // This waits to make sure that there have been no more data pulses before processing data
  if (!flagDone) {
    if (--weigand_counter == 0)
      flagDone = 1;
  }

  // if we have bits and we the weigand counter went out
  if (bitCount > 0 && flagDone) {
    unsigned char i;

    Serial.print("Read ");
    Serial.print(bitCount);
    Serial.print(" bits. ");

    if (bitCount == 35) {
      // 35 bit HID Corporate 1000 format
      // facility code = bits 2 to 14
      for (i=2; i<14; i++) {
         facilityCode <<=1;
         facilityCode |= databits[i];
      }

      // card code = bits 15 to 34
      for (i=14; i<34; i++) {
         cardCode <<=1;
         cardCode |= databits[i];
      }

      printBits();
    }
    else if (bitCount == 26) {
      // standard 26 bit format
      // facility code = bits 2 to 9
      for (i=1; i<9; i++) {
         facilityCode <<=1;
         facilityCode |= databits[i];
      }

      // card code = bits 10 to 23
      for (i=9; i<25; i++) {
         cardCode <<=1;
         cardCode |= databits[i];
      }

      printBits();
    }
    else {
     // you can add other formats if you want!
     // Serial.println("Unable to decode.");
    }

     // cleanup and get ready for the next card
     bitCount = 0;
     facilityCode = 0;
     cardCode = 0;
     for (i=0; i<MAX_BITS; i++)
     {
       databits[i] = 0;
     }
  }
}

void printBits() {
      Serial.print("FC = ");
      Serial.print(facilityCode);
      Serial.print(", CC = ");
      Serial.println(cardCode);
      if (cardCode == 941719) {
      writeBits(cardCode);
      }
      // Now lets play with some LED's for fun:
      digitalWrite(LED_RED, LOW); // Red
      if(cardCode == 862){
        // If this one "bad" card, turn off green
        // so it's just red. Otherwise you get orange-ish
        digitalWrite(LED_GREEN, HIGH);
      }
      delay(500);
      digitalWrite(LED_RED, HIGH);  // Red Off
      digitalWrite(LED_GREEN, LOW);  // Green back on

      // Lets be annoying and beep more
    /*
      digitalWrite(BEEP_BEEP, LOW);
      delay(500);
      digitalWrite(BEEP_BEEP, HIGH);
      delay(500);
      digitalWrite(BEEP_BEEP, LOW);
      delay(500);
      digitalWrite(BEEP_BEEP, HIGH);
    */
}

void writeBits(long cc) {

    DateTime now = getDateTime();
    String year =  String(now.year(),DEC);
    String day =  String(now.day(),DEC);
    String month = String(now.month(),DEC);
    String hour = String(now.hour(),DEC);
    String minute = String(now.minute(),DEC);
    String second = String(now.second(), DEC);

    String fn = year + month + day + ".csv";
   // function to write data to data logger
   // open the file. note that only one file can be open at a time,
   // so you have to close this one before opening another.
  myFile = SD.open(fn, FILE_WRITE);

  // if the file opened okay, write to it:
  if (myFile) {
    myFile.print(year + '/' + month + '/' + day + "(" + hour + ":" +minute+ ":" + second + "), " );
    myFile.println(cc);
    // close the file:
    myFile.close();
    Serial.println("done.");
    testBits(fn);
  } else {
    // if the file didn't open, print an error:
    Serial.println("error in initial opening and writing of your file.");
  }

} // end of write bits

void testBits(String fn) {
  // function to open the file and re-read what was just written

    // re-open the file for reading:
  myFile = SD.open(fn);
  if (myFile) {
    Serial.println(fn);

    // read from the file until there's nothing else in it:
    while (myFile.available()) {
      Serial.write(myFile.read());
    }
    // close the file:
    myFile.close();
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening " + fn + " for re-reading and tesitng");
  }

} // end of testBits()

DateTime getDateTime() {
    DateTime now = rtc.now();
    return now;

} // end of getDataTime

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


#10 Added a quick example 'sketch' for Arduino

#include <dispatchSerial.h>
#include <dispatch.h>

void setup() {
  // put your setup code here, to run once:
  Serial.begin(57600);

  DIS_assignChannelReadable(&readable);
  DIS_assignChannelWriteable(&writeable);
  DIS_assignChannelRead(&read);
  DIS_assignChannelWrite(&write);

  DIS_init();

  DIS_subscribe("foo", &mySubscriberFunction);
}

void loop() {
  static int32_t lastMillis = 0;
  const int32_t TIME_INTERVAL = 10000;
  uint32_t now = millis();

  DIS_process();
}

void mySubscriberFunction(void){
  static uint16_t i = 0;

  i++;

  /* publish i back to the sender to 'close the loop' */
  DIS_publish("i,u16", &i);
}

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


Update FISH_DEV.ino

Update FISH_DEV.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/TEAMarg/ID-36-Trolly-Fish.git/'


script arduino led

script arduino led

// constants won't change. They're used here to
// set pin numbers:
const int buttonPin = 3;     // the number of the pushbutton pin
const int ledPin =  2;      // the number of the LED pin

// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status
int ledState = 0;
int currenteState = 0;

void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);
}

void loop(){
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);
  ledState = digitalRead(ledPin);

  if(ledState == HIGH){
    if (buttonState == LOW) {
      // turn LED on:
      digitalWrite(ledPin, LOW);
    }
  }
  else{
    if (buttonState == LOW) {
      // turn LED on:
      digitalWrite(ledPin, HIGH);
    }
  }
}

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


add IRRemote support

add IRRemote support

/*
  Firmata is a generic protocol for communicating with microcontrollers
  from software on a host computer. It is intended to work with
  any host computer software package.

  To download a host software package, please clink on the following link
  to open the list of Firmata client libraries your default browser.

  https://github.com/firmata/arduino#firmata-client-libraries

  Copyright (C) 2006-2008 Hans-Christoph Steiner.  All rights reserved.
  Copyright (C) 2010-2011 Paul Stoffregen.  All rights reserved.
  Copyright (C) 2009 Shigeru Kobayashi.  All rights reserved.
  Copyright (C) 2009-2015 Jeff Hoefs.  All rights reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  See file LICENSE.txt for further informations on licensing terms.

  Last updated by Jeff Hoefs: August 9th, 2015
*/

#include <IRremote.h>
#include <Wire.h>
#include <Firmata.h>
#include <dht.h>
#include <MaxMatrix.h>
#include <SPI.h>
#include <MFRC522.h>
#include <Joypad.h>

#define I2C_WRITE                   B00000000
#define I2C_READ                    B00001000
#define I2C_READ_CONTINUOUSLY       B00010000
#define I2C_STOP_READING            B00011000
#define I2C_READ_WRITE_MODE_MASK    B00011000
#define I2C_10BIT_ADDRESS_MODE_MASK B00100000
#define I2C_MAX_QUERIES             8
#define I2C_REGISTER_NOT_SPECIFIED  -1

#define RST_PIN         9
#define SS_PIN          10

// the minimum interval for sampling analog input
#define MINIMUM_SAMPLING_INTERVAL 10

/*==============================================================================
   GLOBAL VARIABLES
  ============================================================================*/
dht DHT;
MaxMatrix *mm;
MFRC522 *mfrc522;
Joypad *joypad;
IRrecv *irrecv = NULL;
decode_results results;

unsigned char strhex[17] = "0123456789ABCDEF";
byte rfidTouchScan = 0;
boolean rfidTouch = false;
boolean rfidEnable = false;

/* analog inputs */
int analogInputsToReport = 0; // bitwise array to store pin reporting

/* digital input ports */
byte reportPINs[TOTAL_PORTS];       // 1 = report this port, 0 = silence
byte previousPINs[TOTAL_PORTS];     // previous 8 bits sent

/* pins configuration */
byte pinConfig[TOTAL_PINS];         // configuration of every pin
byte portConfigInputs[TOTAL_PORTS]; // each bit: 1 = pin in INPUT, 0 = anything else
int pinState[TOTAL_PINS];           // any value that has been written

/* timer variables */
unsigned long currentMillis;        // store the current value from millis()
unsigned long previousMillis;       // for comparison with currentMillis
unsigned int samplingInterval = 19; // how often to run the main loop (in ms)

/* i2c data */
struct i2c_device_info {
  byte addr;
  int reg;
  byte bytes;
};

/* for i2c read continuous more */
i2c_device_info query[I2C_MAX_QUERIES];

byte i2cRxData[32];
boolean isI2CEnabled = false;
signed char queryIndex = -1;
// default delay time between i2c read request and Wire.requestFrom()
unsigned int i2cReadDelayTime = 0;

boolean isResetting = false;

/* utility functions */
void wireWrite(byte data)
{
#if ARDUINO >= 100
  Wire.write((byte)data);
#else
  Wire.send(data);
#endif
}

byte wireRead(void)
{
#if ARDUINO >= 100
  return Wire.read();
#else
  return Wire.receive();
#endif
}

/*==============================================================================
   FUNCTIONS
  ============================================================================*/

void readAndReportData(byte address, int theRegister, byte numBytes) {
  // allow I2C requests that don't require a register read
  // for example, some devices using an interrupt pin to signify new data available
  // do not always require the register read so upon interrupt you call Wire.requestFrom()
  if (theRegister != I2C_REGISTER_NOT_SPECIFIED) {
    Wire.beginTransmission(address);
    wireWrite((byte)theRegister);
    Wire.endTransmission();
    // do not set a value of 0
    if (i2cReadDelayTime > 0) {
      // delay is necessary for some devices such as WiiNunchuck
      delayMicroseconds(i2cReadDelayTime);
    }
  } else {
    theRegister = 0;  // fill the register with a dummy value
  }

  Wire.requestFrom(address, numBytes);  // all bytes are returned in requestFrom

  // check to be sure correct number of bytes were returned by slave
  if (numBytes < Wire.available()) {
    Firmata.sendString("I2C: Too many bytes received");
  } else if (numBytes > Wire.available()) {
    Firmata.sendString("I2C: Too few bytes received");
  }

  i2cRxData[0] = address;
  i2cRxData[1] = theRegister;

  for (int i = 0; i < numBytes && Wire.available(); i++) {
    i2cRxData[2 + i] = wireRead();
  }

  // send slave address, register and received bytes
  Firmata.sendSysex(SYSEX_I2C_REPLY, numBytes + 2, i2cRxData);
}

void outputPort(byte portNumber, byte portValue, byte forceSend)
{
  // pins not configured as INPUT are cleared to zeros
  portValue = portValue & portConfigInputs[portNumber];
  // only send if the value is different than previously sent
  if (forceSend || previousPINs[portNumber] != portValue) {
    Firmata.sendDigitalPort(portNumber, portValue);
    previousPINs[portNumber] = portValue;
  }
}

/* -----------------------------------------------------------------------------
   check all the active digital inputs for change of state, then add any events
   to the Serial output queue using Serial.print() */
void checkDigitalInputs(void)
{
  /* Using non-looping code allows constants to be given to readPort().
     The compiler will apply substantial optimizations if the inputs
     to readPort() are compile-time constants. */
  if (TOTAL_PORTS > 0 && reportPINs[0]) outputPort(0, readPort(0, portConfigInputs[0]), false);
  if (TOTAL_PORTS > 1 && reportPINs[1]) outputPort(1, readPort(1, portConfigInputs[1]), false);
  if (TOTAL_PORTS > 2 && reportPINs[2]) outputPort(2, readPort(2, portConfigInputs[2]), false);
  if (TOTAL_PORTS > 3 && reportPINs[3]) outputPort(3, readPort(3, portConfigInputs[3]), false);
  if (TOTAL_PORTS > 4 && reportPINs[4]) outputPort(4, readPort(4, portConfigInputs[4]), false);
  if (TOTAL_PORTS > 5 && reportPINs[5]) outputPort(5, readPort(5, portConfigInputs[5]), false);
  if (TOTAL_PORTS > 6 && reportPINs[6]) outputPort(6, readPort(6, portConfigInputs[6]), false);
  if (TOTAL_PORTS > 7 && reportPINs[7]) outputPort(7, readPort(7, portConfigInputs[7]), false);
  if (TOTAL_PORTS > 8 && reportPINs[8]) outputPort(8, readPort(8, portConfigInputs[8]), false);
  if (TOTAL_PORTS > 9 && reportPINs[9]) outputPort(9, readPort(9, portConfigInputs[9]), false);
  if (TOTAL_PORTS > 10 && reportPINs[10]) outputPort(10, readPort(10, portConfigInputs[10]), false);
  if (TOTAL_PORTS > 11 && reportPINs[11]) outputPort(11, readPort(11, portConfigInputs[11]), false);
  if (TOTAL_PORTS > 12 && reportPINs[12]) outputPort(12, readPort(12, portConfigInputs[12]), false);
  if (TOTAL_PORTS > 13 && reportPINs[13]) outputPort(13, readPort(13, portConfigInputs[13]), false);
  if (TOTAL_PORTS > 14 && reportPINs[14]) outputPort(14, readPort(14, portConfigInputs[14]), false);
  if (TOTAL_PORTS > 15 && reportPINs[15]) outputPort(15, readPort(15, portConfigInputs[15]), false);
}

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

  if (pinConfig[pin] == I2C && isI2CEnabled && mode != I2C) {
    // disable i2c so pins can be used for other functions
    // the following if statements should reconfigure the pins properly
    disableI2CPins();
  }
  if (IS_PIN_ANALOG(pin)) {
    reportAnalogCallback(PIN_TO_ANALOG(pin), mode == ANALOG ? 1 : 0); // turn on/off reporting
  }
  if (IS_PIN_DIGITAL(pin)) {
    if (mode == INPUT) {
      portConfigInputs[pin / 8] |= (1 << (pin & 7));
    } else {
      portConfigInputs[pin / 8] &= ~(1 << (pin & 7));
    }
  }
  pinState[pin] = 0;
  switch (mode) {
    case ANALOG:
      if (IS_PIN_ANALOG(pin)) {
        if (IS_PIN_DIGITAL(pin)) {
          pinMode(PIN_TO_DIGITAL(pin), INPUT);    // disable output driver
          digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups
        }
        pinConfig[pin] = ANALOG;
      }
      break;
    case INPUT:
      if (IS_PIN_DIGITAL(pin)) {
        pinMode(PIN_TO_DIGITAL(pin), INPUT);    // disable output driver
        digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups
        pinConfig[pin] = INPUT;
      }
      break;
    case OUTPUT:
      if (IS_PIN_DIGITAL(pin)) {
        digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable PWM
        pinMode(PIN_TO_DIGITAL(pin), OUTPUT);
        pinConfig[pin] = OUTPUT;
      }
      break;
    case PWM:
      if (IS_PIN_PWM(pin)) {
        pinMode(PIN_TO_PWM(pin), OUTPUT);
        analogWrite(PIN_TO_PWM(pin), 0);
        pinConfig[pin] = PWM;
      }
      break;
    case I2C:
      if (IS_PIN_I2C(pin)) {
        // mark the pin as i2c
        // the user must call I2C_CONFIG to enable I2C for a device
        pinConfig[pin] = I2C;
      }
      break;
    default:
      Firmata.sendString("Unknown pin mode"); // TODO: put error msgs in EEPROM
  }
  // TODO: save status to EEPROM here, if changed
}

void analogWriteCallback(byte pin, int value)
{
  if (pin < TOTAL_PINS) {
    switch (pinConfig[pin]) {
      case PWM:
        if (IS_PIN_PWM(pin))
          analogWrite(PIN_TO_PWM(pin), value);
        pinState[pin] = value;
        break;
    }
  }
}

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

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

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

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

/*==============================================================================
   SYSEX-BASED commands
  ============================================================================*/
void setIRrecv(byte pin) {
  irrecv = new IRrecv(pin);
}

void irReceiver() { //68AE1A03
  byte sendByte = 0;
  unsigned long result = 0;
  if (irrecv != NULL) {
    if (irrecv->decode(&results)) {
      result = results.value;
      Firmata.write(START_SYSEX);
      Firmata.write(0x04);
      Firmata.write(0x10);
      for (int i = 3; i >= 0; i--) {
        sendByte = (result >> (8 * i)) & 0xff;
        char msb =  (sendByte >> 4) + 0x30;
        if (msb > 0x39) msb += 7;
        Firmata.write(msb);
        char lsb =  (sendByte & 0x0f) + 0x30;
        if (lsb > 0x39) lsb += 7;
        Firmata.write(lsb);
      }
      Firmata.write(END_SYSEX);
      irrecv->resume(); // Receive the next value
    }
  }
}

void sysexCallback(byte command, byte argc, byte *argv)
{
  byte mode;
  byte slaveAddress;
  byte data;
  int slaveRegister;
  unsigned int delayTime;
  byte strLen;
  String strData;
  //ir send
  byte codeType, bits;
  unsigned long sendCode;
  switch (command) {
    case 1:
      pinMode(argv[0] & 0x0f, OUTPUT);
      pinMode(argv[1] & 0x0f, INPUT);
      digitalWrite(argv[0] & 0x0f, LOW);
      delayMicroseconds(2);
      digitalWrite(argv[0] & 0x0f, HIGH);
      delayMicroseconds(10);
      digitalWrite(argv[0] & 0x0f, LOW);
      Firmata.write(START_SYSEX);
      Firmata.write(1);
      Firmata.write(argv[0] & 0x0f);
      Firmata.write(argv[1] & 0x0f);
      {
        String strData = String(pulseIn(argv[1] & 0x0f, HIGH) / 58);
        data = strData.length();
        for (int i = 0; i < data; i++) {
          Firmata.write(strData.charAt(i));
        }
      }
      Firmata.write(END_SYSEX);
      break;
    case 4:
      switch (argv[0]) {
        case 4:
          DHT.read11(argv[1]);
          Firmata.write(START_SYSEX);
          Firmata.write(4);
          Firmata.write(4);
          Firmata.write(argv[1]);
          strData = String(int(DHT.humidity * 100)) + String(int(DHT.temperature * 100));
          //Serial.println(strData);
          strLen = strData.length();
          for (int i = 0; i < strLen; i++) {
            Firmata.write(strData.charAt(i));
          }
          Firmata.write(END_SYSEX);
          break;
        case 7: //Buzzer f004070b131805f7
          pinMode(argv[1], OUTPUT);
          tone(argv[1], (String(argv[2], HEX)).toInt() * 100 +
               (String(argv[3], HEX)).toInt(), argv[4] * 100);
          break;
        case 8:
          // 00: init , 01:display , 02: clear
          switch (argv[1]) { //argv[1] = cmd;
            case 0: //init f0040800060708f7
              if (mm == NULL) {
                mm = new MaxMatrix();
                mm->init(argv[2], argv[3], argv[4], 1);
              }
              break;
            case 1: //display f0040801FF02040810204080f7
              for (byte i = 0; i < 16; i = i + 2) {
                mm->setColumn(i / 2, asc2hex(argv + i + 2));
              }
              break;
            case 2: //clear f0040802f7
              mm->clear();
              break;
            case 3: //Intensity f00408030ff7
              mm->setIntensity(argv[2]);
              break;
          }
          break;
        case 9: //IRremote
          codeType = argv[1];
          bits = argv[2];
          sendCode = argv[3];
          for (int i = 4; i <= 6; i++) {
            sendCode = (sendCode << 8) | argv[i];
          }
          switch (argv[1]) { //argv[1] = codeType
            case 4: //NEC
              //irsend.sendNEC(0x20DF10EF, bits);
              //irsend.sendNEC(sendCode, bits);
              if (irrecv != NULL) {
                irrecv->enableIRIn();
              }
              break;
          }
          Firmata.write(START_SYSEX);
          Firmata.write(9);
          Firmata.write('O');
          Firmata.write('K');
          Firmata.write(END_SYSEX);
          break;
        case 10:
          // 00: init , 01:disable
          switch (argv[1]) { //argv[1] = cmd;
            case 0: //init receiver pin
              setIRrecv(argv[2]);
              irrecv->enableIRIn();
              break;
            case 1: //disable receiver pin
              //irrecv = NULL;
              break;
          }
          break;
        case 15:
          switch (argv[1]) { //argv[1] = cmd;
            case 0: // init RFID
              if (mfrc522 == NULL) {
                mfrc522 = new MFRC522(SS_PIN, RST_PIN);
                SPI.begin();
                mfrc522->PCD_Init();
              }
              break;
            case 1: // start RFID
              if (mfrc522 != NULL) {
                rfidEnable = true;
              }
              break;
            case 2: // stop RFID
              if (mfrc522 != NULL) {
                rfidEnable = false;
              }
              break;
            case 3: // change RFID
              if (mfrc522 != NULL) {
              }
              break;
          }
          break;
        case 20: //Joypad
          switch (argv[1]) { //argv[1] = cmd;
            case 0: //board.board.send([0xf0,0x04,0x14,1,0,1,0xf7]);
              if (joypad == NULL) {
                joypad = new Joypad();
              }
              joypad->init(argv[2], argv[3]);
              break;
            case 1: //board.board.send([0xf0,0x04,0x14,1,0,1,2,3,0xf7]);
              if (joypad == NULL) {
                joypad = new Joypad();
              }
              joypad->init(argv[2], argv[3], argv[4], argv[5]);
              break;
            case 2: //start
              joypad->start();
              break;
            case 3: //stop
              joypad->stop();
              break;
          }
          break;
      }
      break;
    case I2C_REQUEST:
      mode = argv[1] & I2C_READ_WRITE_MODE_MASK;
      if (argv[1] & I2C_10BIT_ADDRESS_MODE_MASK) {
        Firmata.sendString("10-bit addressing not supported");
        return;
      }
      else {
        slaveAddress = argv[0];
      }

      switch (mode) {
        case I2C_WRITE:
          Wire.beginTransmission(slaveAddress);
          for (byte i = 2; i < argc; i += 2) {
            data = argv[i] + (argv[i + 1] << 7);
            wireWrite(data);
          }
          Wire.endTransmission();
          delayMicroseconds(70);
          break;
        case I2C_READ:
          if (argc == 6) {
            // a slave register is specified
            slaveRegister = argv[2] + (argv[3] << 7);
            data = argv[4] + (argv[5] << 7);  // bytes to read
          }
          else {
            // a slave register is NOT specified
            slaveRegister = I2C_REGISTER_NOT_SPECIFIED;
            data = argv[2] + (argv[3] << 7);  // bytes to read
          }
          readAndReportData(slaveAddress, (int)slaveRegister, data);
          break;
        case I2C_READ_CONTINUOUSLY:
          if ((queryIndex + 1) >= I2C_MAX_QUERIES) {
            // too many queries, just ignore
            Firmata.sendString("too many queries");
            break;
          }
          if (argc == 6) {
            // a slave register is specified
            slaveRegister = argv[2] + (argv[3] << 7);
            data = argv[4] + (argv[5] << 7);  // bytes to read
          }
          else {
            // a slave register is NOT specified
            slaveRegister = (int)I2C_REGISTER_NOT_SPECIFIED;
            data = argv[2] + (argv[3] << 7);  // bytes to read
          }
          queryIndex++;
          query[queryIndex].addr = slaveAddress;
          query[queryIndex].reg = slaveRegister;
          query[queryIndex].bytes = data;
          break;
        case I2C_STOP_READING:
          byte queryIndexToSkip;
          // if read continuous mode is enabled for only 1 i2c device, disable
          // read continuous reporting for that device
          if (queryIndex <= 0) {
            queryIndex = -1;
          } else {
            // if read continuous mode is enabled for multiple devices,
            // determine which device to stop reading and remove it's data from
            // the array, shifiting other array data to fill the space
            for (byte i = 0; i < queryIndex + 1; i++) {
              if (query[i].addr == slaveAddress) {
                queryIndexToSkip = i;
                break;
              }
            }

            for (byte i = queryIndexToSkip; i < queryIndex + 1; i++) {
              if (i < I2C_MAX_QUERIES) {
                query[i].addr = query[i + 1].addr;
                query[i].reg = query[i + 1].reg;
                query[i].bytes = query[i + 1].bytes;
              }
            }
            queryIndex--;
          }
          break;
        default:
          break;
      }
      break;
    case I2C_CONFIG:
      delayTime = (argv[0] + (argv[1] << 7));

      if (delayTime > 0) {
        i2cReadDelayTime = delayTime;
      }

      if (!isI2CEnabled) {
        enableI2CPins();
      }

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

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

  isI2CEnabled = true;

  Wire.begin();
}

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

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

void systemResetCallback()
{
  isResetting = true;

  // initialize a defalt state
  // TODO: option to load config from EEPROM instead of default

  if (isI2CEnabled) {
    disableI2CPins();
  }

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

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

  /* send digital inputs to set the initial state on the host computer,
     since once in the loop(), this firmware will only send on change */
  /*
    TODO: this can never execute, since no pins default to digital input
        but it will be needed when/if we support EEPROM stored config
    for (byte i=0; i < TOTAL_PORTS; i++) {
    outputPort(i, readPort(i, portConfigInputs[i]), true);
    }
  */
  isResetting = false;
}

void setup()
{
  Firmata.setFirmwareVersion(FIRMATA_MAJOR_VERSION, FIRMATA_MINOR_VERSION);

  Firmata.attach(ANALOG_MESSAGE, analogWriteCallback);
  Firmata.attach(DIGITAL_MESSAGE, digitalWriteCallback);
  Firmata.attach(REPORT_ANALOG, reportAnalogCallback);
  Firmata.attach(REPORT_DIGITAL, reportDigitalCallback);
  Firmata.attach(SET_PIN_MODE, setPinModeCallback);
  Firmata.attach(START_SYSEX, sysexCallback);
  Firmata.attach(SYSTEM_RESET, systemResetCallback);

  // to use a port other than Serial, such as Serial1 on an Arduino Leonardo or Mega,
  // Call begin(baud) on the alternate serial port and pass it to Firmata to begin like this:
  // Serial1.begin(57600);
  // Firmata.begin(Serial1);
  // then comment out or remove lines 701 - 704 below

  Firmata.begin(57600);
  while (!Serial) {
    ; // wait for serial port to connect. Only needed for ATmega32u4-based boards (Leonardo, etc).
  }
  systemResetCallback();  // reset to default config
}

/*==============================================================================
   LOOP()
  ============================================================================*/
void loop()
{
  byte pin, analogPin;

  /* DIGITALREAD - as fast as possible, check for changes and output them to the
     FTDI buffer using Serial.print()  */
  checkDigitalInputs();

  if (joypad != NULL && joypad->state()) {
    joypad->loop();
  }

  irReceiver();

  if (rfidEnable) {
    if (mfrc522->PICC_IsNewCardPresent() && mfrc522->PICC_ReadCardSerial()) {
      if (!rfidTouch) {
        Firmata.write(START_SYSEX);
        byte len = mfrc522->uid.size;
        for (byte i = 0; i < len; i++) {
          Firmata.write(strhex[mfrc522->uid.uidByte[i] >> 4]);
          Firmata.write(strhex[mfrc522->uid.uidByte[i] & 0x0f]);
        }
        Firmata.write(END_SYSEX);
        rfidTouch = true;
      }
      rfidTouchScan = 0;
    } else {
      if (rfidTouchScan++ == 2 && rfidTouch) {
        rfidTouch = false;
        Firmata.write(START_SYSEX);
        Firmata.write(0);
        Firmata.write(END_SYSEX);
      }
    }
  }
  /* STREAMREAD - processing incoming messagse as soon as possible, while still
     checking digital inputs.  */
  while (Firmata.available())
    Firmata.processInput();

  // TODO - ensure that Stream buffer doesn't go over 60 bytes

  currentMillis = millis();
  if (currentMillis - previousMillis > samplingInterval) {
    previousMillis += samplingInterval;
    /* ANALOGREAD - do all analogReads() at the configured sampling interval */
    for (pin = 0; pin < TOTAL_PINS; pin++) {
      if (IS_PIN_ANALOG(pin) && pinConfig[pin] == ANALOG) {
        analogPin = PIN_TO_ANALOG(pin);
        if (analogInputsToReport & (1 << analogPin)) {
          Firmata.sendAnalog(analogPin, analogRead(analogPin));
        }
      }
    }
    // report i2c data for all device with read continuous mode enabled
    if (queryIndex > -1) {
      for (byte i = 0; i < queryIndex + 1; i++) {
        readAndReportData(query[i].addr, query[i].reg, query[i].bytes);
      }
    }
  }
}

byte asc2hex(byte * array) {
  byte b = 0;
  if (*array >= 0x41 && *array <= 0x66) {
    b = (*array & 0x0F) + 9 << 4;
  } else if (*array >= 0x30 && *array <= 0x39) {
    b = (*array - 0x30) << 4;
  }
  array++;
  if (*array >= 0x41 && *array <= 0x66) {
    b |= (*array & 0x0F) + 9;
  } else if (*array >= 0x30 && *array <= 0x39) {
    b |= (*array - 0x30);
  }
  return b;
}

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


MakesLEDlightsBlink

MakesLEDlightsBlink

// First, we're going to make some variables.
// This is our "shorthand" that we'll use throughout the program:

int led1 = D0; // Instead of writing D0 over and over again, we'll write led1
// You'll need to wire an LED to this one to see it blink.

int led2 = D7; // Instead of writing D7 over and over again, we'll write led2
// This one is the little blue LED on your board. On the Photon it is next to D7, and on the Core it is next to the USB jack.

// Having declared these variables, let's move on to the setup function.
// The setup function is a standard part of any microcontroller program.
// It runs only once when the device boots up or is reset.

void setup() {

  // We are going to tell our device that D0 and D7 (which we named led1 and led2 respectively) are going to be output
  // (That means that we will be sending voltage to them, rather than monitoring voltage that comes from them)

  // It's important you do this here, inside the setup() function rather than outside it or in the loop function.

  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);

}

// Next we have the loop function, the other essential part of a microcontroller program.
// This routine gets repeated over and over, as quickly as possible and as many times as possible, after the setup function is called.
// Note: Code that blocks for too long (like more than 5 seconds), can make weird things happen (like dropping the network connection).  The built-in delay function shown below safely interleaves required background activity, so arbitrarily long delays can safely be done if you need them.

void loop() {
  // To blink the LED, first we'll turn it on...
  digitalWrite(led1, HIGH);
  digitalWrite(led2, HIGH);

  // We'll leave it on for 1 second...
  delay(1000);

  // Then we'll turn it off...
  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);

  // Wait 1 second...
  delay(1000);

  // And repeat!
}

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


cleaned code

cleaned code

/* Pins in Use:
     IR Sensor:       2
     PRessure sensor on A0
*/

  #define BOUNCE_DURATION 200   // define an appropriate bounce time in ms for your switches
  int val;                        // variable for reading the serial input
  volatile unsigned long bounceTime=0;
  volatile long dropcount;
  unsigned long drop_num;
  float flowrate;
  unsigned long time_int;
  unsigned long time_set;
  unsigned long timeold;
  unsigned long totaldrops;
  unsigned long totaldropsold;
  float totalvol;
  float dropsize;
  unsigned long steppermax;
  unsigned long steppermin;
  const int feedppin=A0;
  int sfeedp = 0;
  int feedp = 0;

void setup(){
   Serial.begin(9600);
   attachInterrupt(0, dropcount_fun, RISING);  //pin 2 tr reciever
   pinMode(feedppin,INPUT);//pin A0
   drop_num = 2;
   dropcount = 3;
   timeold = 0;
   totaldrops = 0;
   totaldropsold = 0;
   totalvol = 0;

   //make sure this is correct!
   dropsize = 0.047;//how to find this
   //make sure this is correct!

   flowrate = 0;
   pressures();
   pressures();
   pressures();
   pressures();
   pressures();
   pressures();
  Serial.print("Time");Serial.print("\t");
  Serial.print("PSI");Serial.print("\t");
  Serial.print("Drops");Serial.print("\t");
  Serial.print("Vol mL");Serial.print("\t");
  Serial.println("flowrate mL/min");
}

 void loop() {
   if (dropcount >= drop_num) {
     //Update every 30 counts, increase this for better DPM resolution,
     //decrease for faster update
     time_int = ((millis() - timeold));
     timeold = millis();
     totaldrops = totaldropsold + dropcount;
     totaldropsold = totaldrops;
     totalvol = totaldrops * dropsize; //reports in mL
     flowrate = dropcount * dropsize / time_int * 1000 * 60; //report in mL per min
     dropcount = 0;
     pressures();
     pressures();
     pressures();
     pressures();
     pressures();
     //Serial.print("Time: ");
     Serial.print(timeold);Serial.print("\t");
     //Serial.print(" Pressure: ");
     Serial.print(sfeedp);Serial.print("\t");
     //Serial.print(" Drops: ");
     Serial.print(totaldrops);Serial.print("\t");
     //Serial.print(" Volume (mL): ");
     Serial.print(totalvol);Serial.print("\t");
     //Serial.print(" FlowRate (mL/min): ");
     Serial.println(flowrate);}
      delay(1);
      if (Serial.available()){//type 0 for reset
        val = Serial.read();
      }
        if (val != 1) {// if zero is sent by serial command it resets
            totalvol = 0;
            totaldropsold = 0;
            Serial.println("RESET");
        }
     val=1; // save the new state in our variable
   }
 void dropcount_fun(){  // this is the interrupt handler for water drops
  if(millis() > bounceTime){
      dropcount++;
      bounceTime = millis() + BOUNCE_DURATION;  // set whatever bounce time in ms is appropriate
 }
}
void pressures(){//read and average pressure values
  int junk = analogRead(feedppin);
  feedp = (analogRead(feedppin)*.7018-54.74)*.868;
  sfeedp = (sfeedp+feedp)/2;
}

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


Added simple sketch to test duration of battery pack.

/**
 * BatteryDrain.ino
 *
 * Copyright (C) 2016 by CommonsLab <info@commonslab.gr>
 *
 * Repeatedly request a web page and blink an LED in order to see how long a battery will last.
 * (Based on LGPLv2 licensed example code of github.com/esp8266/arduino.)
 */

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266HTTPClient.h>

ESP8266WiFiMulti MyWiFi;

void setup() {
    pinMode(D1, OUTPUT);     // Initialize the LED_BUILTIN pin as an output

    Serial.begin(115200);

    for(uint8_t t = 4; t > 0; t--) {
        Serial.printf("[SETUP] WAIT %d...\n", t);
        Serial.flush();
        delay(1000);
    }

    MyWiFi.addAP("commons|lab", "PASSWORD");

}

void loop() {
    // wait for WiFi connection
    if((MyWiFi.run() == WL_CONNECTED)) {

        digitalWrite(D1, HIGH);   // Turn the LED on

        HTTPClient http;

        Serial.print("[HTTP] begin...\n");
        // configure traged server and url
        //http.begin("https://192.168.1.12/test.html", "7a 9c f4 db 40 d3 62 5a 6e 21 bc 5c cc 66 c8 3e a1 45 59 38"); //HTTPS
        //http.begin("http://192.168.1.12/test.html"); //HTTP
        http.begin("http://etherpad.commonslab.gr/"); //HTTP

        Serial.print("[HTTP] GET...\n");
        // start connection and send HTTP header
        int httpCode = http.GET();

        // httpCode will be negative on error
        if(httpCode > 0) {
            // HTTP header has been send and Server response header has been handled
            Serial.printf("[HTTP] GET... code: %d\n", httpCode);

            // file found at server
            if(httpCode == 503) {
                String payload = http.getString();
                Serial.println(payload);
            }
        } else {
            Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
        }

        http.end();
    }
    digitalWrite(D1, LOW);  // Turn the LED off

    delay(1000);
}

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


Create MIDI_test_v1.ino

Create MIDI_test_v1.ino

//***************************************************************
// Basic setup for testing out receiving MIDI on a Teensy 3.2
//
// Wiring is like this:
//   https://i.imgur.com/d4QRXhe.jpg
//
// Marc Miller, June 2018
//***************************************************************

#include <MIDI.h> // Add Midi Library
MIDI_CREATE_DEFAULT_INSTANCE();

#include "FastLED.h"  // Add FastLED library
#define LED_TYPE WS2812B
#define COLOR_ORDER GRB  // GRB for Neopixel
#define DATA_PIN 11
#define NUM_LEDS 12
CRGB leds[NUM_LEDS];
#define BRIGHTNESS 32

int led = 13;  // pin for MCU's onboard LED

uint8_t count;
uint8_t hue;

//---------------------------------------------------------------
void blinkyblink() {
  digitalWrite(led, HIGH);  delay(50);
  digitalWrite(led, LOW);   delay(30);
  digitalWrite(led, HIGH);  delay(20);
  digitalWrite(led, LOW);
}

//---------------------------------------------------------------
void solidFill(uint16_t color) {
  if (color > 255) {
    fill_solid( leds, NUM_LEDS, CHSV(random8(),255,255) );  //pick random color
  } else {
    color = (uint8_t)color;  //convert 16bit to 8bit
    fill_solid( leds, NUM_LEDS, CHSV(color,255,255) );  //fill with sent hue
  }
  FastLED.show();
}

void spinColor(uint8_t color) {
  EVERY_N_MILLISECONDS(120) {
    fadeToBlackBy(leds, NUM_LEDS, 100);
    leds[count] = CHSV(color, random8(150,255), 255);
    FastLED.show();
    count++;
    if (count == NUM_LEDS) { count = 0; }
  }
}

void clearAll() {  // turn off all pixels
  FastLED.clear();
  FastLED.show();
  blinkyblink();
}

//---------------------------------------------------------------
void HandleNoteOn(byte channel, byte pitch, byte velocity){
  if (velocity > 0){
    // check for specific notes
    if(pitch <= 50) { clearAll(); }
    else if(pitch == 51) { solidFill(888); }
    else if(pitch == 52) { solidFill(888); }
    else if(pitch == 53) { solidFill(hue); }
    else if(pitch == 54) { spinColor(0); }
    else if(pitch == 55) { solidFill(hue); }
    else if(pitch == 56) { spinColor(96); }
    else if(pitch == 57) { solidFill(hue); }
    else if(pitch == 58) { spinColor(160); }
    else if(pitch == 59) { solidFill(0); }
    else if(pitch == 60) { solidFill(96); }
    else if(pitch == 61) { clearAll(); }
    else if(pitch == 62) { solidFill(160); }
    else if(pitch == 63) { solidFill(888); }
    else if(pitch == 64) { solidFill(888); }
    else if(pitch == 65) {
      //if (velocity > 128) {
      //  try something extra here based on velocity;
      //}
      solidFill(888);
    }
    else if(pitch >= 66) { clearAll(); }
  }
}

//---------------------------------------------------------------
void setup(){
  Serial1.begin(31250);  //using MIDI baud rate but could be something faster
  delay(1000);
  pinMode(led, OUTPUT);
  blinkyblink();  //check onboard LED

  FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
  FastLED.setBrightness(BRIGHTNESS);
  fill_solid(leds, NUM_LEDS, CRGB(32,0,0)); FastLED.show(); delay(333);
  fill_solid(leds, NUM_LEDS, CRGB(0,32,0)); FastLED.show(); delay(333);
  fill_solid(leds, NUM_LEDS, CRGB(0,0,32)); FastLED.show(); delay(333);
  FastLED.clear();
  FastLED.show();

  MIDI.begin(MIDI_CHANNEL_OMNI);
  MIDI.setHandleNoteOn(HandleNoteOn); // Initiates HandleNoteOn function

  blinkyblink(); delay(100); blinkyblink(); delay(100); blinkyblink();
  Serial.println("Setup done. \n");
}//end_setup

//---------------------------------------------------------------
void loop(){
  MIDI.read();  // Tells Arduino to start listening for midi info on the serial RX pin.

  EVERY_N_MILLISECONDS(30) {
    hue++;
  }

}//end_main_loop

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

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


Sensorscript

Sensorscript

Sensorscript

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


Uploaded robot controller code

Uploaded robot controller code

Stephen's current state controller.

/* Servo automation

 created 2014
 by Jeff Moore
 */

//#include  <LiquidCrystal.h>

  // constants won't change. Used here to set pin numbers:
  // Pin 13: Arduino has an LED connected on pin 13
  // Pin 13: Teensy 3.0 has the LED on pin 13
const int ledPin =  13;      // the number of the LED pin
const int lookEnablePin = 19;
const int pwmPin = 20;
const int jawPin = 21;
const int motionPin = 11;
const int motionModulus = 100;
int motionTimer=0;
//const int motionDetectedPin = 10;

const int ledRedPin = 3;
const int ledGreenPin = 4;
const int ledBluePin = 5;

const byte soundBankPin[4] = {7,8,9,10};
#define SOUNDBANK0 3
#define SOUNDBANK1 3
#define SOUNDBANK2 3
#define SOUNDBANK3 3
const int numSoundPins = 4;

bool lookEnabled = true;
bool jawOpen = true;
bool chatterOn = false;

enum LookMode {
  Pause =      0,
  SlowLook =   1,
  Neutral =    2,
  Shake =      3,
  RandomLook = 4,
  FastShake =  5,
  LeftRight =  6
} lookMode, previousMode;

typedef enum LcdPinEnum {
  Pin8_RS =     9,
  Pin9_Enable = 10,
  Pin4_DB4 =    16,
  Pin5_DB5 =    15,
  Pin6_DB6 =    19,
  Pin7_DB7 =    22
} LcdPinEnum;
//LiquidCrystal lcd(Pin8_RS, Pin9_Enable, Pin4_DB4, Pin5_DB5, Pin6_DB6, Pin7_DB7);

const byte colors[9][3] = {
  { 0,   0,   0   },         // black
  { 180, 255, 255 },         // white
  { 255, 0,   0   },         // red
  { 0,   255, 0   },         // green
  { 0,   0,   255 },         // blue
  { 140, 255, 0   },         // yellow
  { 140, 0,   255 },         // purple
  { 0,   255, 255 },         // cyan
  { 200, 240, 0   }          // orange
};

enum ColorMap {
  Black = 0,
  White = 1,
  Red = 2,
  Green = 3,
  Blue = 4,
  Yellow = 5,
  Purple = 6,
  Cyan = 7,
  Orange = 8
} colorMap;

const int nColors = 9;

byte color[3] = {32, 64, 0};
byte targetColor[3] = {32, 64, 0};

// Frequency of PWM signal
const int f0 = 196;
const double T0Us = 1000000 / (255*f0);

// Min/max guardrails for PWM
// Converted to pulse width (normalized) 0-255
const int tMinUs = 900;  // min pulse width uS
const int tMaxUs = 2100; // max pulse width uS
const int tNeutral = 1500;

const int posMax = tMaxUs / T0Us;
const int posMin = tMinUs / T0Us;
//const int posNeutral = (255*f0)/666;
//const int posNeutral = (posMax+posMin)/2;
const int posNeutral = tNeutral / T0Us;

const int jawNeutralPos = tNeutral / T0Us;
const int jawOpenPos = 1100 / T0Us;
const int jawClosedPos = 1600 / T0Us;

int chatterWaitMs = 50;

const int delta = 300;

int timerModulus = 50;
int ledModulus = 5;
int motionCooldown = 0;
int motionDetectCounter = 0;
const int cooldownTimeMs = 750;

int agitation = 0;
int cyclesOnState = 0;
int cyclesOnPreviousState = 0;
int minPauseCycles = 5;

typedef enum KeypadButtonEnum {
  BtnNone =  0,
  BtnUp   =  1,
  BtnDown =  2,
  BtnLeft =  3,
  BtnRight = 4,
  BtnSelect= 5
} KeypadButton;

KeypadButton keypadButton;

// Counter
int pwmCounter = 0;
int duration = 2;
int dutyCycle = 0;

int pauseCounter = 0;

int position = (posMin+posMax)/2;
int newPos = position;

int slowCounter = 0;

boolean goLeft = 0;

boolean modeUp = 0;
int ledState = LOW;             // ledState used to set the LED
long previousMillis = 0;        // will store last time LED was updated

// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval = 75;           // interval at which to blink (milliseconds)

void setColorTo(byte *toRgb, const byte *fromRgb, const byte divider = 1);
void setColorRgb(const byte *rgb, const byte divider = 1);

void setup() {

  //delay(2000);
  pinMode(ledPin, OUTPUT);
  pinMode(pwmPin, OUTPUT);
  pinMode(jawPin, OUTPUT);
  //pinMode(extLedPin, OUTPUT);
  pinMode(motionPin, INPUT);
  pinMode(lookEnablePin, INPUT);
  //pinMode(motionDetectedPin, OUTPUT);
  pinMode(ledRedPin, OUTPUT);
  pinMode(ledGreenPin, OUTPUT);
  pinMode(ledBluePin, OUTPUT);

  analogWriteFrequency(pwmPin, f0);
  analogWriteFrequency(jawPin, f0);
  //digitalWrite(extLedPin, HIGH);

  initSoundPins();

  Serial.print("Min: ");
  Serial.println(posMin);
  Serial.print("Max: ");
  Serial.println(posMax);
  Serial.println("XXXX");

  lookMode = SlowLook;
  previousMode = SlowLook;
  changeModeTo( SlowLook );
}

void initSoundPins()
{
  for (int i = 0; i < numSoundPins; i++)
  {
    pinMode(soundBankPin[i], OUTPUT);
    digitalWrite(soundBankPin[i],HIGH);
  }
}

void triggerSound(int soundBank)
{
  Serial.print("Triggering bank #");
  Serial.print(soundBank);
  Serial.print(" on pin ");
  Serial.println(soundBankPin[soundBank]);
  digitalWrite(soundBankPin[soundBank],LOW);
  delay(200);
  digitalWrite(soundBankPin[soundBank],HIGH);
}

void ledBlink()
{
  if (ledState == LOW)
  {
    ledState = HIGH;
  }
  else
  {
    ledState = LOW;
  }
}

void pauseLook(int nCycles)
{
   minPauseCycles = nCycles;
   changeModeTo(Pause);
}

void randomizeLookTarget()
{
    newPos = posMin + random(1+posMax-posMin);
    Serial.print("[TGT:");
    Serial.print(newPos);
    Serial.print("]");
}

void steer()
{
  if ( position == newPos )
  {
    pauseLook(5+random(5));
    //if (previousMode == RandomLook && random(4) < 1) chatterOn = true;
  }
}

void steerLeftRight(int slowCounterDelay)
{
  if (slowCounter++ >= slowCounterDelay)
  {
    //if ( random(10) < 1) pauseLook(random(20));
    if (goLeft)
    {
      //newPos = posMin;
      newPos = posNeutral + delta;
      goLeft = false;
    } else {
      //newPos = posMax;
      newPos = posNeutral - delta;
      goLeft = true;
    }
    slowCounter = 0;
  }
}

void shake()
{
   if (slowCounter++ >= 1)
   {
      if (goLeft)
      {
        newPos = posNeutral-delta;
        slowCounter = 0;
        goLeft = false;
      } else {
        newPos = posNeutral+delta;
        goLeft = true;
      }
      slowCounter = 0;
   }
}

void steerNeutral()
{
  newPos = posNeutral;
}

void changeModeTo(int newModeInt)
{
  cyclesOnPreviousState = cyclesOnState;
  cyclesOnState = 0;
  jawStill();

  LookMode newMode = (LookMode) newModeInt;
  previousMode = lookMode;
  lookMode = newMode;

  Serial.flush();
  Serial.println("");
  Serial.print("[PrMode:");
  Serial.print(previousMode);
  Serial.print("]");
  Serial.print("[LkMode:");
  Serial.print(lookMode);
  Serial.println("]");
  Serial.flush();

  //switch (lookMode)
  switch (newModeInt)
  {
    case Pause:
       timerModulus = 40;
       setColorTo( targetColor, targetColor, 3);
       break;
    case SlowLook:
       timerModulus = 40;
       agitation=0;
       setColorTo( targetColor, colors[ random(nColors-2)+1 ], 16 );
       randomizeLookTarget();
       break;
    case RandomLook:
       timerModulus = 15;
       if (random(3) < 1) triggerSound(SOUNDBANK2);
       setColorTo( targetColor, colors[ random(nColors-2)+1 ], 3 );
       randomizeLookTarget();
       break;
    case LeftRight:
       timerModulus = 20;
       triggerSound(SOUNDBANK1);
       setColorTo( targetColor, colors[ Orange ], 2 );
       break;
    case FastShake:
       timerModulus = 10;
       triggerSound(SOUNDBANK3);
       setColorTo( targetColor, colors[ Cyan ], 1 );
       chatterOn = true;
       break;
    case Shake:
       timerModulus = 25;
       triggerSound(SOUNDBANK1);
       setColorTo( targetColor, colors[ random(nColors-2)+1 ], 3 );
       break;
    case Neutral:
       timerModulus = 15;
       setColorTo( targetColor, colors[ Purple ] , 4);
       triggerSound(SOUNDBANK0);
       //steerNeutral();
       break;
    default:
       setColorTo( targetColor, colors[ Orange ], 16);

  }
}

void updateState()
{
    switch (lookMode)
    {
      case SlowLook:
          steer();
          break;
      case RandomLook:
          if ( (cyclesOnState > 15) && random(2)<1 ) changeModeTo(SlowLook);
          steer();
          break;
      case LeftRight:
          steerLeftRight(1);
          if ( cyclesOnState > 10 && random(10)< 1) changeModeTo(RandomLook);
          break;
      case FastShake:
          steerLeftRight(0);
          if ( cyclesOnState > 8 && random(10) < 1) changeModeTo(RandomLook);
          break;
      case Shake:
          steerLeftRight(0);
          if ( cyclesOnState > 15 && random(10)< 1) changeModeTo(SlowLook);
          break;
      case Pause:
          //Serial.print(".");
          if ( previousMode == Pause ) previousMode = SlowLook;
          if ( cyclesOnState > minPauseCycles)
          {
            int tmpPrevCyclesOnState = cyclesOnPreviousState;
            changeModeTo(previousMode);
            cyclesOnState = tmpPrevCyclesOnState;
          }
          break;
      case Neutral:
          steerNeutral();
          if ( cyclesOnState > 10 && random(10) < 1 ) changeModeTo(SlowLook);
          break;
      default:
          changeModeTo(SlowLook);
          break;
    }

    cyclesOnState++;
}

void checkForMotion()
{
  if ((++motionTimer)%motionModulus !=0) return;
  motionTimer = 0;
  if (motionCooldown > 0)
  {
    motionCooldown -= motionModulus;
    //motionCooldown--;
    if (motionCooldown<=0)
    {
        if (digitalRead(motionPin)==LOW)
        {
          Serial.println("Cooldown reached - looking for motion...");
        } else {
          motionCooldown = 2*motionModulus; // wait another X ms
        }
    }
    return;
  }
  if (digitalRead(motionPin)==HIGH)
  {
    Serial.println("Motion detected!");
    motionDetectCounter++;
    Serial.print("MotionCounter=");
    Serial.println(motionDetectCounter);
    motionCooldown = cooldownTimeMs;
    //Serial.println("Neutral / min / max");
    //Serial.println(posNeutral);
    //Serial.println(posMin);
    //Serial.println(posMax);

    if (lookMode < FastShake)
    {
      if (lookMode == Pause) changeModeTo(previousMode+1);
      else changeModeTo(lookMode+1);

      if (lookMode == FastShake)
      {
        agitation++;
        Serial.print("Agitation : ");
        Serial.println(agitation);
        if (agitation > 3)
        {
          Serial.println("Calm down, monkey.");
          changeModeTo(SlowLook);
          agitation=0;
        }
      }
    }
  }
}

void pwmControl()
{
   dutyCycle++;
   if ( dutyCycle % 256 == 0 ) updateState();

   //Serial.print("blook");

   if ( dutyCycle % timerModulus == 0)
   {
     //dutyCycle = 0;
     if (position < (newPos))
     {
       position++;
       analogWrite(pwmPin, position);
       //Serial.print("+");
     }
     else if (position > (newPos))
     {
       position--;
       analogWrite(pwmPin, position);
       //Serial.print("-");
     } else
     {
       analogWrite(pwmPin, 0);
     }
   }
}

void setColor(byte red, byte green, byte blue, byte divider)
{
   analogWrite(ledRedPin, (char) (red/divider));
   analogWrite(ledGreenPin, (char) (green/divider));
   analogWrite(ledBluePin, (char) (blue/divider));
}

void setColorRgb(const byte *rgb, byte divider)
{
  setColor(rgb[0], rgb[1], rgb[2], divider);
}

void setColorTo(byte *toRgb, const byte *fromRgb, const byte divider)
{
    toRgb[0] = fromRgb[0]/divider;
    toRgb[1] = fromRgb[1]/divider;
    toRgb[2] = fromRgb[2]/divider;

    // St. Patty's
    toRgb[1] = 255/divider;
}

boolean rgbEqual(const byte *rgb1, const byte *rgb2)
{
    return ( rgb1[0] == rgb2[0] &&
             rgb1[1] == rgb2[1] &&
             rgb1[2] == rgb2[2] );
}

void adjustColor()
{
    if ( color[0] < targetColor[0] ) color[0]++;
    if ( color[0] > targetColor[0] ) color[0]--;
    if ( color[1] < targetColor[1] ) color[1]++;
    if ( color[1] > targetColor[1] ) color[1]--;
    if ( color[2] < targetColor[2] ) color[2]++;
    if ( color[2] > targetColor[2] ) color[2]--;
}

void chaseColors()
{
    if ( (dutyCycle % (50) == 0) &&
        !rgbEqual(color, targetColor) )
    {
        adjustColor();
        setColorRgb(color);
    } else { }
}

void checkLookEnablePinState()
{
  if ( dutyCycle % 10 != 0) return;
  int pinState = digitalRead(lookEnablePin);
  if ( lookEnabled == true && pinState == LOW)
  {
    lookEnabled = false;
    Serial.println("Look mode deactivated.");
  }
  if ( lookEnabled == false && pinState == HIGH)
  {
    lookEnabled = true;
    Serial.println("Look mode enabled.");
  }
}

void jawStill()
{
  analogWrite(jawPin, 0);
  chatterOn = false;
}

void chatter()
{
  if (!chatterOn) return;
  //if (chatterWaitMs < 500) analogWrite(jawPin,0);

  if (chatterWaitMs-- < 1)
  {
      //chatterWaitMs = 70+random(10);
      chatterWaitMs = 200+random(50);
      //Serial.println(chatterWaitMs);
      if (jawOpen)
      {
        //Serial.println("Open");
        analogWrite(jawPin, jawClosedPos);
        //analogWrite(jawPin,jawNeutralPos);
        jawOpen = false;
      } else {
        //Serial.println("Close");
        analogWrite(jawPin, jawOpenPos);
        jawOpen = true;
      }
      //Serial.flush();
  }
}

// Main control loop
void loop()
{
  delay(1);
  pwmControl();
  chatter();
  checkForMotion();
  chaseColors();
  //checkLookEnablePinState();
}

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


Add 4 camera time elapse demo low power mode

// ArduCAM demo (C)2015 Lee
// web: http://www.ArduCAM.com
// This program is a demo of how to use most of the functions
// of the library with a supported camera modules, and can run on any Arduino platform.
//
// This demo was made for ArduCAM Mini 2MP camera module.
// It will run 4 ArduCAM Mini 2MP moduels in low power mode and take time elapse images every 5 seconds.
// The demo sketch will do the following tasks:
// 1. Set the sensor to JPEG mode and power down all the cameras.
// 2. Power up all cameras and capture 4 image from 4 cameras simultaneously and buffer the image to FIFO, then power down all the cameras after capture completion.
// 3. Store the image to Micro SD/TF card with JPEG format in sequential.
// 4. Resolution can be changed by myCAM.set_JPEG_size() function.
// This program requires the ArduCAM V3.4.0 (or later) library and ArduCAM Mini 2MP shield
// and use Arduino IDE 1.5.2 compiler or above
#include <Wire.h>
#include <ArduCAM.h>
#include <SPI.h>
#include <SD.h>///////////
#include "memorysaver.h"
/////////////////////////////////
#define SD_CS 9
#if defined(__arm__)
#include <itoa.h>
#endif
/////////////////////////////////
const int CS1 = 4;
const int CS2 = 5;
const int CS3 = 6;
const int CS4 = 7;
bool cam1 = true, cam2 = true, cam3 = true, cam4 = true;

/////////////////////////////////
ArduCAM myCAM1(OV2640, CS1);
ArduCAM myCAM2(OV2640, CS2);
ArduCAM myCAM3(OV2640, CS3);
ArduCAM myCAM4(OV2640, CS4);

void setup() {
  // put your setup code here, to run once:
  uint8_t vid, pid;
  uint8_t temp;
#if defined (__AVR__)
  Wire.begin();
#endif
#if defined(__arm__)
  Wire1.begin();
#endif
  Serial.begin(115200);
  Serial.println("ArduCAM Start!");

  // set the SPI_CS as an output:
  pinMode(CS1, OUTPUT);
  pinMode(CS2, OUTPUT);
  pinMode(CS3, OUTPUT);
  pinMode(CS4, OUTPUT);

  // initialize SPI:
  SPI.begin();
  //Check if the ArduCAM SPI bus is OK
  myCAM1.write_reg(ARDUCHIP_TEST1, 0x55);
  temp = myCAM1.read_reg(ARDUCHIP_TEST1);
  if (temp != 0x55)
  {
    Serial.println("SPI1 interface Error!");
    cam1 = false;
    //while(1);
  }

  myCAM2.write_reg(ARDUCHIP_TEST1, 0x55);
  temp = myCAM2.read_reg(ARDUCHIP_TEST1);
  //Serial.println(temp);
  if (temp != 0x55)
  {
    Serial.println("SPI2 interface Error!");
    cam2 = false;
    //while(1);
  }

  myCAM3.write_reg(ARDUCHIP_TEST1, 0x55);
  temp = myCAM3.read_reg(ARDUCHIP_TEST1);
  //Serial.println(temp);
  if (temp != 0x55)
  {
    Serial.println("SPI3 interface Error!");
    cam3 = false;
    //while(1);
  }

  myCAM4.write_reg(ARDUCHIP_TEST1, 0x55);
  temp = myCAM4.read_reg(ARDUCHIP_TEST1);
  //Serial.println(temp);
  if (temp != 0x55)
  {
    Serial.println("SPI4 interface Error!");
    cam4 = false;
    //while(1);
  }

  //Check if the camera module type is OV2640
  myCAM1.wrSensorReg8_8(0xFF, 0x01);
  myCAM1.rdSensorReg8_8(OV2640_CHIPID_HIGH, &vid);
  myCAM1.rdSensorReg8_8(OV2640_CHIPID_LOW, &pid);

  if ((vid != 0x26) || (pid != 0x42))
    Serial.println("Can't find OV2640 module!");
  else
    Serial.println("OV2640 detected");

  //Change to JPEG capture mode and initialize the OV2640 module
  myCAM1.set_format(JPEG);
  myCAM1.InitCAM();
  myCAM1.OV2640_set_JPEG_size(OV2640_1600x1200);
  myCAM1.clear_fifo_flag();
  myCAM1.write_reg(ARDUCHIP_FRAMES, 0x00);

  myCAM1.set_bit(ARDUCHIP_GPIO,GPIO_PWDN_MASK);//enable low power
  myCAM2.set_bit(ARDUCHIP_GPIO,GPIO_PWDN_MASK);//enable low power
  myCAM3.set_bit(ARDUCHIP_GPIO,GPIO_PWDN_MASK);//enable low power
  myCAM4.set_bit(ARDUCHIP_GPIO,GPIO_PWDN_MASK);//enable low power

  ////////////////////////////////////////////////////
  if (!SD.begin(SD_CS))
  {
    //while (1);		//If failed, stop here
    Serial.println("SD Card Error");
  }
  else
    Serial.println("SD Card detected!");
  ////////////////////////////////////////////////////
}

void loop() {
  // put your main code here, to run repeatedly:
  uint8_t temp, temp_last;
  uint8_t start_capture = 0;

  delay(4000);
  myCAM1.clear_bit(ARDUCHIP_GPIO,GPIO_PWDN_MASK); //Power up Camera
  myCAM2.clear_bit(ARDUCHIP_GPIO,GPIO_PWDN_MASK); //Power up Camera
  myCAM3.clear_bit(ARDUCHIP_GPIO,GPIO_PWDN_MASK); //Power up Camera
  myCAM4.clear_bit(ARDUCHIP_GPIO,GPIO_PWDN_MASK); //Power up Camera
  delay(1000);
  myCAM1.flush_fifo();
  myCAM2.flush_fifo();
  myCAM3.flush_fifo();
  myCAM4.flush_fifo();
  //Clear the capture done flag
  myCAM1.clear_fifo_flag();
  //Start capture
  myCAM1.start_capture();
  //Clear the capture done flag
  myCAM2.clear_fifo_flag();
  //Start capture
  myCAM2.start_capture();
  //Clear the capture done flag
  myCAM3.clear_fifo_flag();
  //Start capture
  myCAM3.start_capture();
  //Clear the capture done flag
  myCAM4.clear_fifo_flag();
  //Start capture
  myCAM4.start_capture();

  while (!myCAM1.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK) && cam1);
  while (!myCAM2.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK) && cam2);
  while (!myCAM3.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK) && cam3);
  while (!myCAM4.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK) && cam4);

  myCAM1.set_bit(ARDUCHIP_GPIO,GPIO_PWDN_MASK);//enable low power
  myCAM2.set_bit(ARDUCHIP_GPIO,GPIO_PWDN_MASK);//enable low power
  myCAM3.set_bit(ARDUCHIP_GPIO,GPIO_PWDN_MASK);//enable low power
  myCAM4.set_bit(ARDUCHIP_GPIO,GPIO_PWDN_MASK);//enable low power

  if (cam1 == true)
  {
    Serial.println("CAM1 Capture Done!");
    read_fifo_burst(myCAM1);
    //Clear the capture done flag
    myCAM1.clear_fifo_flag();
  }

  if (cam2 == true)
  {
    Serial.println("CAM2 Capture Done!");
    read_fifo_burst(myCAM2);
    //Clear the capture done flag
    myCAM2.clear_fifo_flag();
  }

  if (cam3 == true)
  {
    Serial.println("CAM3 Capture Done!");
    read_fifo_burst(myCAM3);
    //Clear the capture done flag
    myCAM3.clear_fifo_flag();
  }

  if (cam4 == true)
  {
    Serial.println("CAM4 Capture Done!");
    read_fifo_burst(myCAM4);
    //Clear the capture done flag
    myCAM4.clear_fifo_flag();
  }
}

uint8_t read_fifo_burst(ArduCAM myCAM)
{
  uint8_t temp, temp_last;
  uint32_t length = 0;
  //////////////////////////////////////////
  char str[8];
  File outFile;
  byte buf[256];
  static int k = 0;
  static int i = 0;
  //////////////////////////////////////////
  ////////////////////////////////////////////////////
  //Construct a file name
  k = k + 1;
  itoa(k, str, 10);
  strcat(str, ".jpg");
  //Open the new file
  outFile = SD.open(str, O_WRITE | O_CREAT | O_TRUNC);
  if (! outFile)
  {
    Serial.println("open file failed");
    //return;
  }

  //////////////////////////////////////////////////
  length = myCAM.read_fifo_length();
  if (length >= 393216) //384 kb
  {
    Serial.println("Not found the end.");
    return 0;
  }
  //Serial.println(length);
  i = 0;
  myCAM.CS_LOW();
  myCAM.set_fifo_burst();
  SPI.transfer(0x00);//First byte is 0xC0 ,not 0xff

  ////////////////////////////////////////////////////////
  while ( (temp != 0xD9) | (temp_last != 0xFF))
  {
    temp_last = temp;
    temp = SPI.transfer(0x00);

    //Write image data to buffer if not full
    if (i < 256)
      buf[i++] = temp;
    else
    {
      //Write 256 bytes image data to file
      myCAM.CS_HIGH();
      outFile.write(buf, 256);
      i = 0;
      buf[i++] = temp;
      myCAM.CS_LOW();
      myCAM.set_fifo_burst();
    }
  }
  //Write the remain bytes in the buffer
  if (i > 0)
  {
    myCAM.CS_HIGH();
    outFile.write(buf, i);
  }
  //Close the file
  outFile.close();
  ///////////////////////////////////////////////////////
}

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


Add OV5642 2592x1944 RAW example

Add OV5642 2592x1944 RAW example

// ArduCAM demo (C)2017 Lee
// Web: http://www.ArduCAM.com
// This program is a demo of how to capture image in RAW format
// 1. Capture and buffer the image to FIFO every 5 seconds
// 2. Store the image to Micro SD/TF card with RAW format.
//3. You can change the resolution by change the "resolution = OV5642_640x480"
// This program requires the ArduCAM V4.0.0 (or above) library and ArduCAM shield V2
// and use Arduino IDE 1.6.8 compiler or above
#include <Wire.h>
#include <ArduCAM.h>
#include <SPI.h>
#include <SD.h>
#include "memorysaver.h"
//This demo can only work on OV5640_MINI_5MP_PLUS or OV5642_MINI_5MP_PLUS platform.
#if !(defined (OV5642_MINI_5MP_PLUS))
#error Please select the hardware platform and camera module in the ../libraries/ArduCAM/memorysaver.h file
#endif
#define   FRAMES_NUM    0x00
// set pin 7 as the slave select for the digital pot:
const int CS = 7;
#define SD_CS 9
bool is_header = false;
int total_time = 0;
uint8_t resolution = OV5642_2592x1944;
uint32_t line,column;
  ArduCAM myCAM(OV5642, CS);
uint8_t saveRAW(void);
void setup() {
// put your setup code here, to run once:
uint8_t vid, pid;
uint8_t temp ;

#if defined(__SAM3X8E__)
  Wire1.begin();
#else
  Wire.begin();
#endif
Serial.begin(115200);
Serial.println(F("ArduCAM Start!"));
// set the CS as an output:
pinMode(CS, OUTPUT);
// initialize SPI:
SPI.begin();
while(1){
  //Check if the ArduCAM SPI bus is OK
  myCAM.write_reg(ARDUCHIP_TEST1, 0x55);
  temp = myCAM.read_reg(ARDUCHIP_TEST1);
  if(temp != 0x55)
  {
    Serial.println(F("SPI interface Error!"));
    delay(1000);continue;
  }else{
    Serial.println(F("SPI interface OK."));break;
  }
}

while(1){
  //Check if the camera module type is OV5642
  myCAM.rdSensorReg16_8(OV5642_CHIPID_HIGH, &vid);
  myCAM.rdSensorReg16_8(OV5642_CHIPID_LOW, &pid);
  if ((vid != 0x56) || (pid != 0x42)){
    Serial.println(F("Can't find OV5642 module!"));
    delay(1000);continue;
  }else{
    Serial.println(F("OV5642 detected."));break;
  }
}
//Initialize SD Card
while(!SD.begin(SD_CS))
{
  Serial.println(F("SD Card Error!"));delay(1000);
}
Serial.println(F("SD Card detected."));
//Change to JPEG capture mode and initialize the OV5640 module
myCAM.set_format(RAW);
myCAM.InitCAM();
myCAM.set_bit(ARDUCHIP_TIM, VSYNC_LEVEL_MASK);
}

void loop() {
   File outFile;
    char VL;
    char str[8];
    byte buf[256];
    static int k = 0,m = 0;
    int i,j = 0;
// put your main code here, to run repeatedly:
  myCAM.flush_fifo();
  myCAM.clear_fifo_flag();
  myCAM.OV5642_set_RAW_size(resolution);delay(1000);
//Start capture
myCAM.start_capture();
Serial.println(F("start capture."));
total_time = millis();
while ( !myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK));
Serial.println(F("CAM Capture Done."));
total_time = millis() - total_time;
Serial.print(F("capture total_time used (in miliseconds):"));
Serial.println(total_time, DEC);
Serial.println("Saving the image,please waitting...");
total_time = millis();
     k = k + 1;
    itoa(k, str, 10);
    strcat(str,".raw");        //Generate file name
    outFile = SD.open(str,O_WRITE | O_CREAT | O_TRUNC);
    if (! outFile)
    {
      Serial.println(F("File open error"));
      return;
    }
    if(resolution == OV5642_640x480 ){
      line = 640;column = 480;
      }else if( resolution == OV5642_1280x960 ){
        line = 1280;column = 960;
        }else if( resolution == OV5642_1920x1080 ){
           line = 1920;column = 1080;
          }else if( resolution == OV5642_2592x1944 ){
            line = 2592;column = 1944;
            }
    //Save as RAW format
    for(i = 0; i < line; i++)
    for(j = 0; j < column; j++)
    {
      VL = myCAM.read_fifo();
      buf[m++] = VL;
      if(m >= 256)
      {
        //Write 256 bytes image data to file from buffer
        outFile.write(buf,256);
        m = 0;
      }
    }
    if(m > 0 )//Write the left image data to file from buffer
      outFile.write( buf, m );m = 0;
    //Close the file
    outFile.close();
    Serial.println("Image save OK.");
//Clear the capture done flag
myCAM.clear_fifo_flag();
delay(5000);
}

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


Restructured runMotorTest. Likely a problem with the electrical side.

unsigned char wheelID[15] =  {133, 132, 131, 130, 129, 128,         //Drive motors
                              133, 132, 131, 130, 129, 128,         //articulation motors
                              134,   0, 134};                       //Misc motors

const int FORWARD_DRIVE = 0;   //Command sent for Clockwise rotation for drive wheels (Motor 1)
const int BACKWARD_DRIVE =1;   //Command sent for Counter-Clockwise rotation for drive wheels (Motor 1)
const int FORWARD_ART = 4;     //Command sent for Clockwise rotation for articulation wheels (Motor 2)
const int BACKWARD_ART =5;     //Command sent Counter-Clockwise rotation for articulation wheels (Motor 2)

void setup() {
  Serial.begin(9600);//CHECK BAUD RATE
}

void loop(){
  runMotor();
}

void runMotor(){
  unsigned char address = 128;//motor controller address (between 128 and 135)
  unsigned char command = FORWARD_ART;//command: 0 Motor 1 forward, 1 Motor 1 backward, 4 Motor 2 forward, 5 Motor 2 backward. (Motor 1 is drive motor, Motor 2 is articulation motor)
  unsigned char data = 100;//speed from 0-127
  unsigned char checksum = (address + command + data) & 127;//error check. Sum address, command, and speed. Then, apply the bitwise AND operator on that and 127.
  Serial.write(address);//send all the values over the first Serial port. BYTE is used to make it send in binary representation.
  Serial.write(command);
  Serial.write(data);
  Serial.write(checksum);

}

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