Add script with IMU and ultrasonic sensor

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

--- Arduino/ultrasonic_IMU/ultrasonic_IMU.ino
+++ Arduino/ultrasonic_IMU/ultrasonic_IMU.ino
@@ -0,0 +1,779 @@
+#include "Ultrasonic.h"
+Ultrasonic ultrasonic1(8,9);
+Ultrasonic ultrasonic2(10,11);
+Ultrasonic ultrasonic3(12,13);
+const int alimPin1 =  6;      // the number of the LED pin
+const int alimPin2 =  7;      // the number of the LED pin
+
+double d1,d2,d3;
+double distance_cm = 25;
+/*****************************************************************
+MPU9150_AHRS_directdata.ino
+SFE_MPU9150 Library AHRS Data Fusion Example Code
+Kris Winer for Sparkfun Electronics
+Original Creation Date: April 8, 2014
+https://github.com/sparkfun/MPU9150_Breakout
+
+The MPU9150 is a versatile 9DOF sensor. It has a built-in
+accelerometer, gyroscope, and magnetometer that
+functions over I2C. It is very similar to the 6 DoF MPU6050 for which an extensive library has already been built.
+Most of the function of the MPU9150 can utilize the MPU6050 library.
+
+This Arduino sketch utilizes Jeff Rowberg's MPU6050 library to generate the basic sensor data
+for use in two sensor fusion algorithms becoming increasingly popular with DIY quadcopter and robotics engineers.
+I have added and slightly modified Jeff's library here.
+
+This simple sketch will demo the following:
+* How to create a MPU6050 object, using a constructor (global variables section).
+* How to use the initialize() function of the MPU6050 class.
+* How to read the gyroscope, accelerometer, and magnetometer
+  using the readAcceleration(), readRotation(), and readMag() functions and the
+  gx, gy, gz, ax, ay, az, mx, my, and mz variables.
+* How to calculate actual acceleration, rotation speed, magnetic
+  field strength using the  specified ranges as described in the data sheet:
+  http://dlnmh9ip6v2uc.cloudfront.net/datasheets/Sensors/IMU/PS-MPU-9150A.pdf
+  and
+  http://dlnmh9ip6v2uc.cloudfront.net/datasheets/Sensors/IMU/RM-MPU-9150A-00.pdf.
+
+In addition, the sketch will demo:
+* How to check for data updates using the data ready status register
+* How to display output at a rate different from the sensor data update and fusion filter update rates
+* How to specify the accelerometer and gyro sampling and bandwidth rates
+* How to use the data from the MPU9150 to fuse the sensor data into a quaternion representation of the sensor frame
+  orientation relative to a fixed Earth frame providing absolute orientation information for subsequent use.
+* An example of how to use the quaternion data to generate standard aircraft orientation data in the form of
+  Tait-Bryan angles representing the sensor yaw, pitch, and roll angles suitable for any vehicle stablization control application.
+
+Hardware setup: This library supports communicating with the
+MPU9150 over I2C. These are the only connections that need to be made:
+	MPU9150 --------- Arduino
+	 SCL ---------- SCL (A5 on older 'Duinos')
+	 SDA ---------- SDA (A4 on older 'Duinos')
+	 VDD ------------- 3.3V
+	 GND ------------- GND
+
+The LSM9DS0 has a maximum voltage of 3.5V. Make sure you power it
+off the 3.3V rail! And either use level shifters between SCL
+and SDA or just use a 3.3V Arduino Pro.
+
+Development environment specifics:
+	IDE: Arduino 1.0.5
+	Hardware Platform: Arduino Pro 3.3V/8MHz
+	MPU9150 Breakout Version: 1.0
+
+This code is beerware. If you see me (or any other SparkFun
+employee) at the local, and you've found our code helpful, please
+buy us a round!
+
+Distributed as-is; no warranty is given.
+*****************************************************************/
+/*
+MS561101BA_altitude.pde - Computes altitude from sea level using pressure readings from the sensor.
+The algorithm uses the Hypsometric formula as explained in http://keisan.casio.com/has10/SpecExec.cgi?path=06000000.Science%2F02100100.Earth%20science%2F12000300.Altitude%20from%20atmospheric%20pressure%2Fdefault.xml&charset=utf-8
+
+Copyright (C) 2011 Fabio Varesano <fvaresano@yahoo.it>
+
+Development of this code has been supported by the Department of Computer Science,
+Universita' degli Studi di Torino, Italy within the Piemonte Project
+http://www.piemonte.di.unito.it/
+
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the version 3 GNU General Public License as
+published by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#define USE_MAVLINK //Uncomment this line to use mavlink
+#ifdef USE_MAVLINK
+  #include "MavlinkForArduino.h"        // Mavlink interface
+#endif
+
+#include <Wire.h>
+#include "I2Cdev.h" //from https://github.com/sparkfun/MPU-9150_Breakout.git
+#include "MPU6050_9Axis_MotionApps41.h"
+#include <MS561101BA.h>
+
+#define OUTPUT_RATE_ms 50 // 20Hz
+
+#define MOVAVG_SIZE 32
+
+// Define corrections/offsets for magnetometer
+#define LOCAL_DECLINATION_DEG -3 //at Nantes, France is around 3 degrees in 2014
+#define MAG_1_OFFSET -7.0f
+#define MAG_2_OFFSET 75.0f
+#define MAG_3_OFFSET 117.0f
+#define ACC_1_OFFSET 0.0f
+#define ACC_2_OFFSET 0.0f
+#define ACC_3_OFFSET 0.0f
+#define GYRO_1_OFFSET -284.8f
+#define GYRO_2_OFFSET -161.0f
+#define GYRO_3_OFFSET 12.7f
+#define GYRO_RANGE_DEGPS 250.0f
+#define ACCEL_RANGE_G 2.0f
+#define MAG_RANGE_mG 12290.0f// milliGauss (1229 microTesla per 2^12 bits, 10 mG per microTesla)
+
+// class default I2C address is 0x68
+// specific I2C addresses may be passed as a parameter here
+// AD0 low = 0x68 (default for InvenSense evaluation board)
+// AD0 high = 0x69
+MPU6050 accelGyroMag(0x69);
+
+// global constants for 9 DoF fusion and AHRS (Attitude and Heading Reference System)
+#define GyroMeasError PI * (40.0f / 180.0f)       // gyroscope measurement error in rads/s (shown as 3 deg/s)
+#define GyroMeasDrift PI * (0.0f / 180.0f)      // gyroscope measurement drift in rad/s/s (shown as 0.0 deg/s/s)
+// There is a tradeoff in the beta parameter between accuracy and response speed.
+// In the original Madgwick study, beta of 0.041 (corresponding to GyroMeasError of 2.7 degrees/s) was found to give optimal accuracy.
+// However, with this value, the LSM9SD0 response time is about 10 seconds to a stable initial quaternion.
+// Subsequent changes also require a longish lag time to a stable output, not fast enough for a quadcopter or robot car!
+// By increasing beta (GyroMeasError) by about a factor of fifteen, the response time constant is reduced to ~2 sec
+// I haven't noticed any reduction in solution accuracy. This is essentially the I coefficient in a PID control sense;
+// the bigger the feedback coefficient, the faster the solution converges, usually at the expense of accuracy.
+// In any case, this is the free parameter in the Madgwick filtering and fusion scheme.
+#define beta sqrt(3.0f / 4.0f) * GyroMeasError   // compute beta
+#define zeta sqrt(3.0f / 4.0f) * GyroMeasDrift   // compute zeta, the other free parameter in the Madgwick scheme usually set to a small or zero value
+#define Kp 2.0f * 5.0f // these are the free parameters in the Mahony filter and fusion scheme, Kp for proportional feedback, Ki for integral
+#define Ki 0.0f
+
+#define RAW       0
+#define FUSION    1
+#define DEBUG     2
+short outputMode = FUSION;
+
+// String management
+String inputString = "";         // a string to hold incoming data
+boolean stringComplete = false;  // whether the string is complete
+
+
+int16_t a1, a2, a3, g1, g2, g3, m1, m2, m3;     // raw data arrays reading
+uint16_t last_output_ms = 0;  // used to control display output rate
+uint16_t delt_t_ms = 0; // used to control display output rate
+uint8_t BaroRate;     // read rate for magnetometer data
+
+float pitch, yaw, roll;
+float deltat_s = 0.0f;        // integration interval for both filter schemes
+uint64_t lastUpdate_us = 0; // used to calculate integration interval
+uint64_t time_boot_us = 0;        // used to calculate integration interval
+
+float ax_g, ay_g, az_g, gx_degps, gy_degps, gz_degps, mx, my, mz; // variables to hold latest sensor data values
+float q[4] = {1.0f, 0.0f, 0.0f, 0.0f};    // vector to hold quaternion
+float eInt[3] = {0.0f, 0.0f, 0.0f};       // vector to hold integral error for Mahony method
+
+uint8_t system_id = 100;
+uint8_t component_id = 200;
+uint32_t time_boot_ms;
+uint32_t last_baro_read_ms;
+
+//MS5611
+MS561101BA baro = MS561101BA();
+float movavg_buff[MOVAVG_SIZE];
+int movavg_i=0;
+
+const float sea_press = 1013.25;
+float ground_press;
+float press, temperature, altitude;
+
+short n_gyro_range = 0;
+short n_gyro_range_old = 0;
+short n_accel_range = 0;
+short n_accel_range_old = 0;
+
+#define   PIN_5V_1 4
+#define   PIN_0V_1 3
+
+void setup()
+{
+  //Alim for ultrasonic sensors
+  pinMode(alimPin1, OUTPUT);
+  pinMode(alimPin2, OUTPUT);
+  digitalWrite(alimPin1, HIGH);
+  digitalWrite(alimPin2, HIGH);
+
+  //pinMode(PIN_0V_1, OUTPUT);
+  //pinMode(PIN_5V_1, OUTPUT);
+  //digitalWrite(PIN_5V_1, HIGH);
+  //digitalWrite(PIN_0V_1, LOW);
+
+  // join I2C bus (I2Cdev library doesn't do this automatically)
+  Wire.begin();
+  Serial.begin(57600); // Start serial at 57600 bps
+  // Reserve bytes for the inputString:
+  inputString.reserve(200);
+
+  delay(2000);
+
+  // initialize MPU6050 device
+  Serial.println(F("Initializing I2C devices..."));
+  accelGyroMag.initialize();
+
+  // verify connection
+  Serial.println(F("Testing device connections..."));
+  Serial.println(accelGyroMag.testConnection() ? F("MPU9150 connection successful") : F("MPU9150 connection failed"));
+
+// Set up the accelerometer, gyro, and magnetometer for data output
+
+   accelGyroMag.setRate(7); // set gyro rate to 8 kHz/(1 + rate) shows 1 kHz, accelerometer ODR is fixed at 1 KHz
+
+   BaroRate = 100;
+
+// Digital low pass filter configuration.
+// It also determines the internal sampling rate used by the device as shown in the table below.
+// The accelerometer output rate is fixed at 1kHz. This means that for a Sample
+// Rate greater than 1kHz, the same accelerometer sample may be output to the
+// FIFO, DMP, and sensor registers more than once.
+/*
+ *          |   ACCELEROMETER    |           GYROSCOPE
+ * DLPF_CFG | Bandwidth | Delay  | Bandwidth | Delay  | Sample Rate
+ * ---------+-----------+--------+-----------+--------+-------------
+ * 0        | 260Hz     | 0ms    | 256Hz     | 0.98ms | 8kHz
+ * 1        | 184Hz     | 2.0ms  | 188Hz     | 1.9ms  | 1kHz
+ * 2        | 94Hz      | 3.0ms  | 98Hz      | 2.8ms  | 1kHz
+ * 3        | 44Hz      | 4.9ms  | 42Hz      | 4.8ms  | 1kHz
+ * 4        | 21Hz      | 8.5ms  | 20Hz      | 8.3ms  | 1kHz
+ * 5        | 10Hz      | 13.8ms | 10Hz      | 13.4ms | 1kHz
+ * 6        | 5Hz       | 19.0ms | 5Hz       | 18.6ms | 1kHz
+ */
+  accelGyroMag.setDLPFMode(4); // set bandwidth of both gyro and accelerometer to ~20 Hz
+
+// Full-scale range of the gyro sensors:
+// 0 = +/- 250 degrees/sec, 1 = +/- 500 degrees/sec, 2 = +/- 1000 degrees/sec, 3 = +/- 2000 degrees/sec
+  accelGyroMag.setFullScaleGyroRange(0); // set gyro range to 250 degrees/sec
+
+// Full-scale accelerometer range.
+// The full-scale range of the accelerometer: 0 = +/- 2g, 1 = +/- 4g, 2 = +/- 8g, 3 = +/- 16g
+  accelGyroMag.setFullScaleAccelRange(0); // set accelerometer to 2 g range
+
+  //accelGyroMag.setIntDataReadyEnabled(true); // enable data ready interrupt
+
+  // Suppose that the CSB pin is connected to GND.
+  // You'll have to check this on your breakout schematics
+  baro.init(MS561101BA_ADDR_CSB_LOW);
+  delay(100);
+
+  // populate movavg_buff before starting loop
+  for(int i=0; i<MOVAVG_SIZE; i++) {
+    movavg_buff[i] = baro.getPressure(MS561101BA_OSR_4096);
+  }
+}
+/*
+  SerialEvent occurs whenever a new data comes in the
+ hardware serial RX.  This routine is run between each
+ time loop() runs, so using delay inside loop can delay
+ response.  Multiple bytes of data may be available.
+ */
+void serialEvent()
+{
+  while (Serial.available()) {
+    // Get the new byte:
+    char inChar = (char)Serial.read();
+    // Add it to the inputString:
+    inputString += inChar;
+    // If the incoming character is a newline, set a flag
+    // so the main loop can do something about it:
+    if (inChar == '\n') {
+      stringComplete = true;
+    }
+  }
+}
+
+
+void loop()
+{
+  //digitalWrite(PIN_5V_1, HIGH);
+  //digitalWrite(PIN_0V_1, LOW);
+    d1 = ultrasonic1.Ranging(CM);
+    d2 = ultrasonic2.Ranging(CM);
+    d3 = ultrasonic3.Ranging(CM);
+
+  //ground_press = baro.getPressure(MS561101BA_OSR_4096);
+    processSerialInput();
+    if (fabs(millis()-last_baro_read_ms)>1./BaroRate)
+    {
+      last_baro_read_ms = millis();
+      getBaroData();
+    }
+    automaticGyroRangeSelection();
+    automaticAccelRangeSelection();
+
+    if(accelGyroMag.getIntDataReadyStatus() == 1)// wait for data ready status register to update all data registers
+    {
+      // read the raw sensor data
+        //getMotion9 is not working properly for unknown reason
+        //accelGyroMag.getMotion9(&a1, &a1, &a3, &g1, &g2, &g3, &m1, &m2, &m3);
+        accelGyroMag.getAcceleration  ( &a1, &a2, &a3  );
+        accelGyroMag.getRotation  ( &g1, &g2, &g3  );
+        accelGyroMag.getMag  ( &m1, &m2, &m3 );
+        a2 = -a2;// Invert y to get NED classical convention
+        a1 = a1 + ACC_1_OFFSET;
+        a2 = a2 + ACC_2_OFFSET;
+        a3 = a3 + ACC_3_OFFSET;
+        ax_g = a1*ACCEL_RANGE_G*pow(2.0, n_accel_range)/pow(2.0, 15);
+        ay_g = a2*ACCEL_RANGE_G*pow(2.0, n_accel_range)/pow(2.0, 15);
+        az_g = a3*ACCEL_RANGE_G*pow(2.0, n_accel_range)/pow(2.0, 15);
+
+        g1 = -g1;
+        g3 = -g3;
+        g1 = g1 + GYRO_1_OFFSET;
+        g2 = g2 + GYRO_2_OFFSET;
+        g3 = g3 + GYRO_3_OFFSET;
+        gx_degps = g1*GYRO_RANGE_DEGPS*pow(2.0, n_gyro_range)/pow(2.0, 15);
+        gy_degps = g2*GYRO_RANGE_DEGPS*pow(2.0, n_gyro_range)/pow(2.0, 15);
+        gz_degps = g3*GYRO_RANGE_DEGPS*pow(2.0, n_gyro_range)/pow(2.0, 15);
+        //  The gyros and accelerometers can in principle be calibrated in addition to any factory calibration but they are generally
+        //  pretty accurate. You can check the accelerometer by making sure the reading is +1 g in the positive direction for each axis.
+        //  The gyro should read zero for each axis when the sensor is at rest. Small or zero adjustment should be needed for these sensors.
+        //  The magnetometer is a different thing. Most magnetometers will be sensitive to circuit currents, computers, and
+        //  other both man-made and natural sources of magnetic field. The rough way to calibrate the magnetometer is to record
+        //  the maximum and minimum readings (generally achieved at the North magnetic direction). The average of the sum divided by two
+        //  should provide a pretty good calibration offset. Don't forget that for the MPU9150, the magnetometer x- and y-axes are switched
+        //  compared to the gyro and accelerometer!
+
+        m2 = -m2;
+        // Apply calibration offsets on raw measurements that correspond to your environment and magnetometer
+        m1 = m1 + MAG_1_OFFSET;
+        m2 = m2 + MAG_2_OFFSET;
+        m3 = m3 + MAG_3_OFFSET;
+        // Sensors x (y)-axis of the accelerometer is aligned with the y (x)-axis of the magnetometer;
+        // the magnetometer z-axis (+ down) is opposite to z-axis (+ up) of accelerometer and gyro!
+        // We have to make some allowance for this orientationmismatch in feeding the output to the quaternion filter.
+        mx = m2*MAG_RANGE_mG/pow(2, 12); //Warning x and y are inverted!!
+        my = m1*MAG_RANGE_mG/pow(2, 12);
+        mz = m3*MAG_RANGE_mG/pow(2, 12);
+
+    }
+
+    time_boot_us = micros();
+    time_boot_ms = millis();
+    deltat_s = ((time_boot_us - lastUpdate_us)/1000000.0f); // set integration time by time elapsed since last filter update
+    lastUpdate_us = time_boot_us;
+
+    // Pass gyro rate as rad/s
+    MadgwickQuaternionUpdate(ax_g, ay_g, az_g, gx_degps*PI/180.0f, gy_degps*PI/180.0f, gz_degps*PI/180.0f, mx, my, mz);
+    // MahonyQuaternionUpdate(ax_g, ay, az, gx_degps*PI/180.0f, gy_degps*PI/180.0f, gz_degps*PI/180.0f, my, mx, mz);
+
+    // Serial print and/or display at output rate independent of data rates
+    delt_t_ms = fabs(millis() - last_output_ms);
+    if (delt_t_ms > OUTPUT_RATE_ms) {
+       last_output_ms = millis();
+    // Define output variables from updated quaternion---these are Tait-Bryan angles, commonly used in aircraft orientation.
+    // In this coordinate system, the positive z-axis is down toward Earth.
+    // Yaw is the angle between Sensor x-axis and Earth magnetic North (or true North if corrected for local declination, looking down on the sensor positive yaw is counterclockwise.
+    // Pitch is angle between sensor x-axis and Earth ground plane, toward the Earth is positive, up toward the sky is negative.
+    // Roll is angle between sensor y-axis and Earth ground plane, y-axis up is positive roll.
+    // These arise from the definition of the homogeneous rotation matrix constructed from quaternions.
+    // Tait-Bryan angles as well as Euler angles are non-commutative; that is, the get the correct orientation the rotations must be
+    // applied in the correct order which for this configuration is yaw, pitch, and then roll.
+    // For more see http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles which has additional links.
+      yaw   = atan2(2.0f * (q[1] * q[2] + q[0] * q[3]), q[0] * q[0] + q[1] * q[1] - q[2] * q[2] - q[3] * q[3]);
+      pitch = -asin(2.0f * (q[1] * q[3] - q[0] * q[2]));
+      roll  = atan2(2.0f * (q[0] * q[1] + q[2] * q[3]), q[0] * q[0] - q[1] * q[1] - q[2] * q[2] + q[3] * q[3]);
+      yaw = yaw + LOCAL_DECLINATION_DEG*PI/180.0f; // Declination is difference between magnetic and true north
+
+#ifdef USE_MAVLINK
+      // Initialize the required buffers
+      mavlink_message_t msg;
+      uint8_t buf[MAVLINK_MAX_PACKET_LEN];
+      uint16_t len;
+
+      if ((outputMode == FUSION)||(outputMode == RAW))
+      {
+        mavlink_msg_heartbeat_pack(system_id, component_id, &msg, MAV_TYPE_KITE, MAV_AUTOPILOT_GENERIC, MAV_MODE_GUIDED_ARMED, 0, MAV_STATE_ACTIVE);
+        len = mavlink_msg_to_send_buffer(buf, &msg);
+        Serial.write(buf, len);
+      }
+
+      if (outputMode == FUSION)
+      {
+        //static inline uint16_t mavlink_msg_attitude_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t* msg,
+        //  uint32_t time_boot_ms, float roll, float pitch, float yaw, float rollspeed, float pitchspeed, float yawspeed)
+        mavlink_msg_attitude_pack(system_id, component_id, &msg, time_boot_ms, roll, pitch, yaw, gx_degps*PI/180.0f, gy_degps*PI/180.0f, gz_degps*PI/180.0f);
+        len = mavlink_msg_to_send_buffer(buf, &msg);
+        Serial.write(buf, len);
+        mavlink_msg_scaled_pressure_pack(system_id, component_id, &msg, time_boot_ms, press, press-ground_press, temperature);
+        len = mavlink_msg_to_send_buffer(buf, &msg);
+        Serial.write(buf, len);
+
+        mavlink_msg_distance_sensor_pack(system_id,component_id, &msg,time_boot_ms, 4, 400, (uint16_t)d1, MAV_DISTANCE_SENSOR_ULTRASOUND, 0, MAV_SENSOR_ROTATION_NONE, 1);
+	len = mavlink_msg_to_send_buffer(buf, &msg);
+        Serial.write(buf, len);
+        mavlink_msg_distance_sensor_pack(system_id,component_id+1, &msg,time_boot_ms, 4, 400, (uint16_t)d2, MAV_DISTANCE_SENSOR_ULTRASOUND, 1, MAV_SENSOR_ROTATION_NONE, 1);
+	len = mavlink_msg_to_send_buffer(buf, &msg);
+        Serial.write(buf, len);
+        mavlink_msg_distance_sensor_pack(system_id,component_id+2, &msg,time_boot_ms, 4, 400, (uint16_t)d3, MAV_DISTANCE_SENSOR_ULTRASOUND, 2, MAV_SENSOR_ROTATION_NONE, 1);
+	len = mavlink_msg_to_send_buffer(buf, &msg);
+        Serial.write(buf, len);
+      }
+
+      if (outputMode == RAW)
+      {
+        //static inline uint16_t mavlink_msg_highres_imu_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t* msg,
+        //						       uint64_t time_usec, float xacc, float yacc, float zacc, float xgyro, float ygyro, float zgyro, float xmag, float ymag, float zmag, float abs_pressure, float diff_pressure, float pressure_alt, float temperature, uint16_t fields_updated)
+        mavlink_msg_highres_imu_pack(system_id, component_id, &msg, (uint64_t)time_boot_us, ax_g*9.81, ay_g*9.81, az_g*9.81, gx_degps*PI/180.0f, gy_degps*PI/180.0f, gz_degps*PI/180.0f, mx, my, mz, press, press-ground_press, altitude, temperature, a1);
+        len = mavlink_msg_to_send_buffer(buf, &msg);
+        Serial.write(buf, len);
+      }
+      /*
+      //mavlink_msg_scaled_imu_pack(uint8_t system_id, uint8_t component_id, mavlink_message_t* msg,
+      // uint32_t time_boot_ms, int16_t xacc, int16_t yacc, int16_t zacc, int16_t xgyro, int16_t ygyro, int16_t zgyro, int16_t xmag, int16_t ymag, int16_t zmag)
+      mavlink_msg_raw_imu_pack(system_id, component_id, &msg, time_boot_ms, a1, a2, a3, g1, g2, g3, m1, m2, m3);
+      len = mavlink_msg_to_send_buffer(buf, &msg);
+      Serial.write(buf, len);
+
+      mavlink_msg_scaled_imu_pack(system_id, component_id, &msg, time_boot_ms, ax_g*1000, ay_g*1000, az_g*1000, gx_degps*PI/180.0f*1000, gy_degps*PI/180.0f*1000, gz_degps*PI/180.0f*1000, mx, my, mz);
+      len = mavlink_msg_to_send_buffer(buf, &msg);
+      Serial.write(buf, len);
+      */
+
+#endif
+      if (outputMode == DEBUG)
+      {
+        Serial.print("ax = "); Serial.print((int)1000*ax_g);
+        Serial.print(" ay = "); Serial.print((int)1000*ay_g);
+        Serial.print(" az = "); Serial.print((int)1000*az_g); Serial.println(" mg");
+        Serial.print("gx = "); Serial.print( gx_degps, 2);
+        Serial.print(" gy = "); Serial.print( gy_degps, 2);
+        Serial.print(" gz = "); Serial.print( gz_degps, 2); Serial.println(" deg/s");
+        Serial.print("mx = "); Serial.print( (int)mx );
+        Serial.print(" my = "); Serial.print( (int)my );
+        Serial.print(" mz = "); Serial.print( (int)mz ); Serial.println(" mG");
+
+        Serial.print("q0 = "); Serial.print(q[0]);
+        Serial.print(" qx = "); Serial.print(q[1]);
+        Serial.print(" qy = "); Serial.print(q[2]);
+        Serial.print(" qz = "); Serial.println(q[3]);
+        Serial.print("Yaw, Pitch, Roll: ");
+        Serial.print(yaw*180.0f / PI, 2);
+        Serial.print(", ");
+        Serial.print(pitch*180.0f / PI, 2);
+        Serial.print(", ");
+        Serial.println(roll*180.0f / PI, 2);
+
+        Serial.print("rate = "); Serial.print((float)1.0f/deltat_s, 2); Serial.println(" Hz");
+
+        Serial.print(" temp: ");
+        Serial.print(temperature);
+        Serial.print(" degC pres: ");
+        Serial.print(press);
+        Serial.print(" mbar altitude: ");
+        Serial.print(altitude);
+        Serial.println(" m");
+      }
+
+      // With these settings the filter is updating at a ~145 Hz rate using the Madgwick scheme and
+      // >200 Hz using the Mahony scheme even though the display refreshes at only 2 Hz.
+      // The filter update rate is determined mostly by the mathematical steps in the respective algorithms,
+      // the processor speed (8 MHz for the 3.3V Pro Mini), and the magnetometer ODR:
+      // an ODR of 10 Hz for the magnetometer produce the above rates, maximum magnetometer ODR of 100 Hz produces
+      // filter update rates of 36 - 145 and ~38 Hz for the Madgwick and Mahony schemes, respectively.
+      // This is presumably because the magnetometer read takes longer than the gyro or accelerometer reads.
+      // This filter update rate should be fast enough to maintain accurate platform orientation for
+      // stabilization control of a fast-moving robot or quadcopter. Compare to the update rate of 200 Hz
+      // produced by the on-board Digital Motion Processor of Invensense's MPU6050 6 DoF and MPU9150 9DoF sensors.
+      // The 3.3 V 8 MHz Pro Mini is doing pretty well!
+    }
+}
+void processSerialInput()
+{
+  // Print the string when a newline arrives:
+  if (stringComplete)
+  {
+    if (inputString.startsWith("r"))
+    {
+      outputMode = RAW;
+    }
+    else if (inputString.startsWith("f"))
+    {
+      outputMode = FUSION;
+    }
+    else if (inputString.startsWith("d"))
+    {
+      outputMode = DEBUG;
+    }
+
+    // Clear the string:
+    inputString = "";
+    stringComplete = false;
+  }
+}
+void getBaroData()
+{
+    temperature = baro.getTemperature(MS561101BA_OSR_4096);
+    press = baro.getPressure(MS561101BA_OSR_4096);
+    pushAvg(press);
+    press = getAvg(movavg_buff, MOVAVG_SIZE);
+    if (millis()<5000)
+      ground_press = press;
+    altitude = getAltitude(press, temperature);
+}
+void automaticGyroRangeSelection()
+{
+  for (int i =0; i<=2; i++)
+  {
+    if (max(max(fabs(gx_degps),fabs(gy_degps)),fabs(gz_degps)) <0.2*GYRO_RANGE_DEGPS*pow(2, i))
+    {
+      n_gyro_range = i;
+    }
+    else
+    {
+      n_gyro_range = i+1;
+    }
+  }
+
+  if (n_gyro_range!=n_gyro_range_old)
+  {
+    // Full-scale range of the gyro sensors:
+    // 0 = +/- 250 degrees/sec, 1 = +/- 500 degrees/sec, 2 = +/- 1000 degrees/sec, 3 = +/- 2000 degrees/sec
+    accelGyroMag.setFullScaleGyroRange(n_gyro_range); // set gyro range to 250 degrees/sec
+    n_gyro_range_old = n_gyro_range;
+  }
+}
+void automaticAccelRangeSelection()
+{
+  for (int i =0; i<=2; i++)
+  {
+    if (max(max(fabs(ax_g),fabs(ay_g)),fabs(az_g)) <0.2*ACCEL_RANGE_G*pow(2, i))
+    {
+      n_accel_range = i;
+    }
+    else
+    {
+      n_accel_range = i+1;
+    }
+  }
+
+  if (n_accel_range!=n_accel_range_old)
+  {
+  // Full-scale accelerometer range.
+// The full-scale range of the accelerometer: 0 = +/- 2g, 1 = +/- 4g, 2 = +/- 8g, 3 = +/- 16g
+    accelGyroMag.setFullScaleAccelRange(n_accel_range);
+    n_accel_range_old = n_accel_range;
+  }
+}
+
+
+float getAltitude(float press, float temp) {
+  //return (1.0f - pow(press/101325.0f, 0.190295f)) * 4433000.0f;
+  return ((pow((sea_press / press), 1/5.257) - 1.0) * (temp + 273.15)) / 0.0065;
+}
+
+void pushAvg(float val) {
+  movavg_buff[movavg_i] = val;
+  movavg_i = (movavg_i + 1) % MOVAVG_SIZE;
+}
+
+float getAvg(float * buff, int size) {
+  float sum = 0.0;
+  for(int i=0; i<size; i++) {
+    sum += buff[i];
+  }
+  return sum / size;
+}
+
+
+// Implementation of Sebastian Madgwick's "...efficient orientation filter for... inertial/magnetic sensor arrays"
+// (see http://www.x-io.co.uk/category/open-source/ for examples and more details)
+// which fuses acceleration, rotation rate, and magnetic moments to produce a quaternion-based estimate of absolute
+// device orientation -- which can be converted to yaw, pitch, and roll. Useful for stabilizing quadcopters, etc.
+// The performance of the orientation filter is at least as good as conventional Kalman-based filtering algorithms
+// but is much less computationally intensive---it can be performed on a 3.3 V Pro Mini operating at 8 MHz!
+        void MadgwickQuaternionUpdate(float ax, float ay, float az, float gx, float gy, float gz, float mx, float my, float mz)
+        {
+            float q1 = q[0], q2 = q[1], q3 = q[2], q4 = q[3];   // short name local variable for readability
+            float norm;
+            float hx, hy, _2bx, _2bz;
+            float s1, s2, s3, s4;
+            float qDot1, qDot2, qDot3, qDot4;
+
+            // Auxiliary variables to avoid repeated arithmetic
+            float _2q1mx;
+            float _2q1my;
+            float _2q1mz;
+            float _2q2mx;
+            float _4bx;
+            float _4bz;
+            float _2q1 = 2.0f * q1;
+            float _2q2 = 2.0f * q2;
+            float _2q3 = 2.0f * q3;
+            float _2q4 = 2.0f * q4;
+            float _2q1q3 = 2.0f * q1 * q3;
+            float _2q3q4 = 2.0f * q3 * q4;
+            float q1q1 = q1 * q1;
+            float q1q2 = q1 * q2;
+            float q1q3 = q1 * q3;
+            float q1q4 = q1 * q4;
+            float q2q2 = q2 * q2;
+            float q2q3 = q2 * q3;
+            float q2q4 = q2 * q4;
+            float q3q3 = q3 * q3;
+            float q3q4 = q3 * q4;
+            float q4q4 = q4 * q4;
+
+            // Normalise accelerometer measurement
+            norm = sqrt(ax * ax + ay * ay + az * az);
+            if (norm == 0.0f) return; // handle NaN
+            norm = 1.0f/norm;
+            ax *= norm;
+            ay *= norm;
+            az *= norm;
+
+            // Normalise magnetometer measurement
+            norm = sqrt(mx * mx + my * my + mz * mz);
+            if (norm == 0.0f) return; // handle NaN
+            norm = 1.0f/norm;
+            mx *= norm;
+            my *= norm;
+            mz *= norm;
+
+            // Reference direction of Earth's magnetic field
+            _2q1mx = 2.0f * q1 * mx;
+            _2q1my = 2.0f * q1 * my;
+            _2q1mz = 2.0f * q1 * mz;
+            _2q2mx = 2.0f * q2 * mx;
+            hx = mx * q1q1 - _2q1my * q4 + _2q1mz * q3 + mx * q2q2 + _2q2 * my * q3 + _2q2 * mz * q4 - mx * q3q3 - mx * q4q4;
+            hy = _2q1mx * q4 + my * q1q1 - _2q1mz * q2 + _2q2mx * q3 - my * q2q2 + my * q3q3 + _2q3 * mz * q4 - my * q4q4;
+            _2bx = sqrt(hx * hx + hy * hy);
+            _2bz = -_2q1mx * q3 + _2q1my * q2 + mz * q1q1 + _2q2mx * q4 - mz * q2q2 + _2q3 * my * q4 - mz * q3q3 + mz * q4q4;
+            _4bx = 2.0f * _2bx;
+            _4bz = 2.0f * _2bz;
+
+            // Gradient decent algorithm corrective step
+            s1 = -_2q3 * (2.0f * q2q4 - _2q1q3 - ax) + _2q2 * (2.0f * q1q2 + _2q3q4 - ay) - _2bz * q3 * (_2bx * (0.5f - q3q3 - q4q4) + _2bz * (q2q4 - q1q3) - mx) + (-_2bx * q4 + _2bz * q2) * (_2bx * (q2q3 - q1q4) + _2bz * (q1q2 + q3q4) - my) + _2bx * q3 * (_2bx * (q1q3 + q2q4) + _2bz * (0.5f - q2q2 - q3q3) - mz);
+            s2 = _2q4 * (2.0f * q2q4 - _2q1q3 - ax) + _2q1 * (2.0f * q1q2 + _2q3q4 - ay) - 4.0f * q2 * (1.0f - 2.0f * q2q2 - 2.0f * q3q3 - az) + _2bz * q4 * (_2bx * (0.5f - q3q3 - q4q4) + _2bz * (q2q4 - q1q3) - mx) + (_2bx * q3 + _2bz * q1) * (_2bx * (q2q3 - q1q4) + _2bz * (q1q2 + q3q4) - my) + (_2bx * q4 - _4bz * q2) * (_2bx * (q1q3 + q2q4) + _2bz * (0.5f - q2q2 - q3q3) - mz);
+            s3 = -_2q1 * (2.0f * q2q4 - _2q1q3 - ax) + _2q4 * (2.0f * q1q2 + _2q3q4 - ay) - 4.0f * q3 * (1.0f - 2.0f * q2q2 - 2.0f * q3q3 - az) + (-_4bx * q3 - _2bz * q1) * (_2bx * (0.5f - q3q3 - q4q4) + _2bz * (q2q4 - q1q3) - mx) + (_2bx * q2 + _2bz * q4) * (_2bx * (q2q3 - q1q4) + _2bz * (q1q2 + q3q4) - my) + (_2bx * q1 - _4bz * q3) * (_2bx * (q1q3 + q2q4) + _2bz * (0.5f - q2q2 - q3q3) - mz);
+            s4 = _2q2 * (2.0f * q2q4 - _2q1q3 - ax) + _2q3 * (2.0f * q1q2 + _2q3q4 - ay) + (-_4bx * q4 + _2bz * q2) * (_2bx * (0.5f - q3q3 - q4q4) + _2bz * (q2q4 - q1q3) - mx) + (-_2bx * q1 + _2bz * q3) * (_2bx * (q2q3 - q1q4) + _2bz * (q1q2 + q3q4) - my) + _2bx * q2 * (_2bx * (q1q3 + q2q4) + _2bz * (0.5f - q2q2 - q3q3) - mz);
+            norm = sqrt(s1 * s1 + s2 * s2 + s3 * s3 + s4 * s4);    // normalise step magnitude
+            norm = 1.0f/norm;
+            s1 *= norm;
+            s2 *= norm;
+            s3 *= norm;
+            s4 *= norm;
+
+            // Compute rate of change of quaternion
+            qDot1 = 0.5f * (-q2 * gx - q3 * gy - q4 * gz) - beta * s1;
+            qDot2 = 0.5f * (q1 * gx + q3 * gz - q4 * gy) - beta * s2;
+            qDot3 = 0.5f * (q1 * gy - q2 * gz + q4 * gx) - beta * s3;
+            qDot4 = 0.5f * (q1 * gz + q2 * gy - q3 * gx) - beta * s4;
+
+            // Integrate to yield quaternion
+            q1 += qDot1 * deltat_s;
+            q2 += qDot2 * deltat_s;
+            q3 += qDot3 * deltat_s;
+            q4 += qDot4 * deltat_s;
+            norm = sqrt(q1 * q1 + q2 * q2 + q3 * q3 + q4 * q4);    // normalise quaternion
+            norm = 1.0f/norm;
+            q[0] = q1 * norm;
+            q[1] = q2 * norm;
+            q[2] = q3 * norm;
+            q[3] = q4 * norm;
+
+        }
+
+
+
+ // Similar to Madgwick scheme but uses proportional and integral filtering on the error between estimated reference vectors and
+ // measured ones.
+            void MahonyQuaternionUpdate(float ax, float ay, float az, float gx, float gy, float gz, float mx, float my, float mz)
+        {
+            float q1 = q[0], q2 = q[1], q3 = q[2], q4 = q[3];   // short name local variable for readability
+            float norm;
+            float hx, hy, bx, bz;
+            float vx, vy, vz, wx, wy, wz;
+            float ex, ey, ez;
+            float pa, pb, pc;
+
+            // Auxiliary variables to avoid repeated arithmetic
+            float q1q1 = q1 * q1;
+            float q1q2 = q1 * q2;
+            float q1q3 = q1 * q3;
+            float q1q4 = q1 * q4;
+            float q2q2 = q2 * q2;
+            float q2q3 = q2 * q3;
+            float q2q4 = q2 * q4;
+            float q3q3 = q3 * q3;
+            float q3q4 = q3 * q4;
+            float q4q4 = q4 * q4;
+
+            // Normalise accelerometer measurement
+            norm = sqrt(ax * ax + ay * ay + az * az);
+            if (norm == 0.0f) return; // handle NaN
+            norm = 1.0f / norm;        // use reciprocal for division
+            ax *= norm;
+            ay *= norm;
+            az *= norm;
+
+            // Normalise magnetometer measurement
+            norm = sqrt(mx * mx + my * my + mz * mz);
+            if (norm == 0.0f) return; // handle NaN
+            norm = 1.0f / norm;        // use reciprocal for division
+            mx *= norm;
+            my *= norm;
+            mz *= norm;
+
+            // Reference direction of Earth's magnetic field
+            hx = 2.0f * mx * (0.5f - q3q3 - q4q4) + 2.0f * my * (q2q3 - q1q4) + 2.0f * mz * (q2q4 + q1q3);
+            hy = 2.0f * mx * (q2q3 + q1q4) + 2.0f * my * (0.5f - q2q2 - q4q4) + 2.0f * mz * (q3q4 - q1q2);
+            bx = sqrt((hx * hx) + (hy * hy));
+            bz = 2.0f * mx * (q2q4 - q1q3) + 2.0f * my * (q3q4 + q1q2) + 2.0f * mz * (0.5f - q2q2 - q3q3);
+
+            // Estimated direction of gravity and magnetic field
+            vx = 2.0f * (q2q4 - q1q3);
+            vy = 2.0f * (q1q2 + q3q4);
+            vz = q1q1 - q2q2 - q3q3 + q4q4;
+            wx = 2.0f * bx * (0.5f - q3q3 - q4q4) + 2.0f * bz * (q2q4 - q1q3);
+            wy = 2.0f * bx * (q2q3 - q1q4) + 2.0f * bz * (q1q2 + q3q4);
+            wz = 2.0f * bx * (q1q3 + q2q4) + 2.0f * bz * (0.5f - q2q2 - q3q3);
+
+            // Error is cross product between estimated direction and measured direction of gravity
+            ex = (ay * vz - az * vy) + (my * wz - mz * wy);
+            ey = (az * vx - ax * vz) + (mz * wx - mx * wz);
+            ez = (ax * vy - ay * vx) + (mx * wy - my * wx);
+            if (Ki > 0.0f)
+            {
+                eInt[0] += ex;      // accumulate integral error
+                eInt[1] += ey;
+                eInt[2] += ez;
+            }
+            else
+            {
+                eInt[0] = 0.0f;     // prevent integral wind up
+                eInt[1] = 0.0f;
+                eInt[2] = 0.0f;
+            }
+
+            // Apply feedback terms
+            gx = gx + Kp * ex + Ki * eInt[0];
+            gy = gy + Kp * ey + Ki * eInt[1];
+            gz = gz + Kp * ez + Ki * eInt[2];
+
+            // Integrate rate of change of quaternion
+            pa = q2;
+            pb = q3;
+            pc = q4;
+            q1 = q1 + (-q2 * gx - q3 * gy - q4 * gz) * (0.5f * deltat_s);
+            q2 = pa + (q1 * gx + pb * gz - pc * gy) * (0.5f * deltat_s);
+            q3 = pb + (q1 * gy - pa * gz + pc * gx) * (0.5f * deltat_s);
+            q4 = pc + (q1 * gz + pa * gy - pb * gx) * (0.5f * deltat_s);
+
+            // Normalise quaternion
+            norm = sqrt(q1 * q1 + q2 * q2 + q3 * q3 + q4 * q4);
+            norm = 1.0f / norm;
+            q[0] = q1 * norm;
+            q[1] = q2 * norm;
+            q[2] = q3 * norm;
+            q[3] = q4 * norm;
+
+        }
+
+
+
+
+
+


Added 8 LEDs example for FraunchPad

Added 8 LEDs example for FraunchPad

error: pathspec 'examples/1.Basics/FRAM_8_LEDs/FRAM_8_LEDs.ino' did not match any file(s) known to git

--- examples/1.Basics/FRAM_8_LEDs/FRAM_8_LEDs.ino
+++ examples/1.Basics/FRAM_8_LEDs/FRAM_8_LEDs.ino
@@ -0,0 +1,102 @@
+///
+/// @mainpage	FRAM_8_LEDs
+/// @details	FraunchPad playing K2000!
+/// @n
+/// @n
+/// @n @a	Developed with [embedXcode](http://embedXcode.weebly.com)
+///
+/// @author	Rei VILO
+/// @author	http://embedxcode.weebly.com
+/// @date	01/11/12 15:56
+/// @version	101
+///
+/// @copyright	© Rei VILO, 2012
+/// @copyright	CC = BY NC SA
+///
+/// @see	ReadMe.txt for references
+///
+
+
+///
+/// @file	FRAM_8_LEDs.ino
+/// @brief	Main sketch
+/// @details	FraunchPad playing K2000!
+/// @n @a	Developed with [embedXcode](http://embedXcode.weebly.com)
+///
+/// @author	Rei VILO
+/// @author	http://embedxcode.weebly.com
+/// @date	01/11/12 15:56
+/// @version	101
+///
+/// @copyright	© Rei VILO, 2012
+/// @copyright	CC = BY NC SA
+///
+/// @see	ReadMe.txt for references
+/// @n
+///
+
+
+// Core library - MCU-based
+#if defined(__MSP430FR5739__) // FraunchPad specific
+#include "Energia.h"
+#else
+#error Platform not supported
+#endif
+
+
+// Include application, user and local libraries
+
+// Define variables and constants
+///
+/// @brief	Table of the LEDs
+///
+uint8_t myLED[8];
+uint8_t i;
+const uint16_t PAUSE = 20; // ms
+const uint16_t STAY  = 80; // ms
+
+///
+/// @brief	Setup
+/// @details	Define the pins of the LEDs
+///
+void setup() {
+  myLED[0] = LED1;
+  myLED[1] = LED2;
+  myLED[2] = LED3;
+  myLED[3] = LED4;
+  myLED[4] = LED5;
+  myLED[5] = LED6;
+  myLED[6] = LED7;
+  myLED[7] = LED8;
+
+  for (i=0; i<8; i++) {
+    pinMode(myLED[i], OUTPUT);
+    digitalWrite(myLED[i], LOW);
+  }
+}
+
+///
+/// @brief	Loop
+///
+void loop() {
+  digitalWrite(myLED[0], HIGH);
+  delay(PAUSE);
+
+  for (i=1; i<8; i++) {
+    digitalWrite(myLED[i], HIGH);
+    delay(PAUSE);
+    digitalWrite(myLED[i-1], LOW);
+    delay(STAY);
+  }
+
+  digitalWrite(myLED[7], HIGH);
+  delay(PAUSE);
+
+  for (i=1; i<8; i++) {
+    digitalWrite(myLED[7-i], HIGH);
+    delay(PAUSE);
+    digitalWrite(myLED[7-i+1], LOW);
+    delay(STAY);
+  }
+
+}


_05_kidSerie_sketch_05.Adafruit_First_Try.ino  05#kidSerie

_05_kidSerie_sketch_05.Adafruit_First_Try.ino  05#kidSerie

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

--- _05_kidSerie_sketch_05.Adafruit_First_Try.ino
+++ _05_kidSerie_sketch_05.Adafruit_First_Try.ino
@@ -0,0 +1,250 @@
+/*
+  Project name:
+     05 #kidSerie - Adafruit-IO Meets ESP8266, Arduino & MIT App Inventor 2
+     (Awesome Smart Phone App!)
+     Flavour V -
+     Hex File: _05_kidSerie_sketch_05.Adafruit_First_Try.ino
+   Revision History:
+     20161029:
+       - from github adafruit/Adafruit_MQTT_Library
+  https://github.com/adafruit/Adafruit_MQTT_Library/blob/master/examples/mqtt_esp8266/mqtt_esp8266.ino
+  https://learn.adafruit.com/mqtt-adafruit-io-and-you/intro-to-adafruit-mqtt
+
+   Description:
+     Simple code to intro Adafruit-io technology using MQTT broker, ESP8266, DHTXX sensor & arduino.
+     We will publish two topics: temp and humidity and subscribe them also.
+     We will access the our dashboard by phone using MIT App Inventor 2.
+     Awesome project!!!
+
+   MCU:                  Arduino 1.6.12 - @16MHz       http://www.arduino.cc/
+   ESP8266:              ESP-01                        https://goo.gl/E0Eq4l
+   DHT11:                PRODUCT ID: 386               https://www.adafruit.com/product/386
+
+   Connections:
+      See Official youtube channel vids:
+   Based on:   Tony DiCola for Adafruit Industries - see below!
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License v3 as published by
+   the Free Software Foundation
+*/
+/***************************************************
+  Adafruit MQTT Library ESP8266 Example
+  Must use ESP8266 Arduino from:
+    https://github.com/esp8266/Arduino
+  Works great with Adafruit's Huzzah ESP board & Feather
+  ----> https://www.adafruit.com/product/2471
+  ----> https://www.adafruit.com/products/2821
+  Adafruit invests time and resources providing this open source code,
+  please support Adafruit and open-source hardware by purchasing
+  products from Adafruit!
+  Written by Tony DiCola for Adafruit Industries.
+  MIT license, all text above must be included in any redistribution
+ ****************************************************/
+/******************************* Adafruit MQTT *******************************/
+#include "Adafruit_MQTT.h"
+#include "Adafruit_MQTT_Client.h"
+
+/******************************* Esp8266**************************************/
+#include <ESP8266WiFi.h>
+#include <WiFiClient.h>
+#include <ESP8266WebServer.h>
+/******************************* DHT Config **********************************/
+#include <DHT.h>
+#define DHTTYPE DHT11
+#define DHTPIN  2
+
+/************************* WiFi Access Point *********************************/
+
+#define WLAN_SSID       "...your SSID..."
+#define WLAN_PASS       "...your password..."
+
+/************************* Adafruit.io Setup *********************************/
+
+#define AIO_SERVER      "io.adafruit.com"
+#define AIO_SERVERPORT  1883      // use 8883 for SSL
+#define AIO_USERNAME    "...your AIO username (see https://accounts.adafruit.com)..."
+#define AIO_KEY         "...your AIO key..."
+
+/************ Global State (you don't need to change this!) ******************/
+
+// Create an ESP8266 WiFiClient class to connect to the MQTT server.
+WiFiClient client;
+// or... use WiFiFlientSecure for SSL
+//WiFiClientSecure client;
+
+// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
+Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);
+
+/****************************** Feeds ****************************************/
+/****************************** Topics ***************************************/
+// Setup a feed called 'temp_topic' and 'humid_topic' for publishing.
+// Notice MQTT paths for AIO follow the form: <username>/feeds/<feedname>
+Adafruit_MQTT_Publish temp_topic = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/temp");
+Adafruit_MQTT_Publish humid_topic = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/humid");
+/****************************** Subscriptions*********************************/
+// Setup a feed for subscribing
+Adafruit_MQTT_Subscribe temp_subscription = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/temp");
+Adafruit_MQTT_Subscribe humid_subscription = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/humid");
+
+/*************************** MQTT Conn ***************************************/
+
+// Bug workaround for Arduino 1.6.6, it seems to need a function declaration
+// for some reason (only affects ESP8266, likely an arduino-builder bug).
+void MQTT_connect();
+
+/*************************** DHT Init   **************************************/
+// Initialize DHT sensor
+// NOTE: For working with a faster than ATmega328p 16 MHz Arduino chip, like an ESP8266,
+// you need to increase the threshold for cycle counts considered a 1 or 0.
+// You can do this by passing a 3rd parameter for this threshold.  It's a bit
+// of fiddling to find the right value, but in general the faster the CPU the
+// higher the value.  The default for a 16mhz AVR is a value of 6.  For an
+// Arduino Due that runs at 84mhz a value of 30 works.
+// This is for the ESP8266 processor on ESP-01
+DHT dht(DHTPIN, DHTTYPE, 11); // 11 works fine for ESP8266
+/*************************** DHT Data   **************************************/
+//float humidity, temp_f;   // Values read from sensor as Fahrenheit
+float humidity, temp_c;    // Values read from sensor as Celsius
+String tempString = "";    // String to display
+/*************************** DHT Timing   ************************************/
+// Generally, you should use "unsigned long" for variables that hold time
+unsigned long previousMillis = 0;        // will store last temp was read
+const long interval = 2000;              // interval at which to read sensor
+
+/****************************** Setup  ***************************************/
+void setup() {
+  Serial.begin(115200);
+  delay(10);
+
+  Serial.println(F("Adafruit MQTT demo"));
+
+  // Connect to WiFi access point.
+  Serial.println(); Serial.println();
+  Serial.print("Connecting to ");
+  Serial.println(WLAN_SSID);
+
+  WiFi.begin(WLAN_SSID, WLAN_PASS);
+  while (WiFi.status() != WL_CONNECTED) {
+    delay(500);
+    Serial.print(".");
+  }
+  Serial.println();
+
+  Serial.println("WiFi connected");
+  Serial.println("IP address: "); Serial.println(WiFi.localIP());
+
+  // Setup MQTT subscription for onoff feed.
+  mqtt.subscribe(&temp_subscription);
+  delay(1000);
+  mqtt.subscribe(&humid_subscription);
+}
+
+//uint32_t x = 0;   // Mock data
+
+/****************************** Loop  ***************************************/
+void loop() {
+  gettemperature() ;
+  // Ensure the connection to the MQTT server is alive (this will make the first
+  // connection and automatically reconnect when disconnected).  See the MQTT_connect
+  // function definition further below.
+  MQTT_connect();
+
+  // this is our 'wait for incoming subscription packets' busy subloop
+  // try to spend your time here
+
+  /****************************** Subscript  ***********************************/
+  Adafruit_MQTT_Subscribe *subscription;
+  while ((subscription = mqtt.readSubscription(10000))) {
+    if (subscription == &humid_subscription) {
+      Serial.print(F("Got humid: "));
+      Serial.println((char *)humid_subscription.lastread);
+    }
+    else {
+      Serial.print(F("Got temp: "));
+      Serial.println((char *)temp_subscription.lastread);
+    }
+  }
+
+  /****************************** Publish  **********************************/
+  // Now we can publish stuff!
+  Serial.print(F("\nSending temp val "));
+  Serial.print(temp_c);
+  Serial.print("...");
+  if (! temp_topic.publish(temp_c)) {
+    Serial.println(F("Failed"));
+  } else {
+    Serial.println(F("OK!"));
+  }
+
+
+  Serial.print(F("\nSending humid val "));
+  Serial.print(humidity);
+  Serial.print("...");
+  if (! humid_topic.publish(humidity)) {
+    Serial.println(F("Failed"));
+  } else {
+    Serial.println(F("OK!"));
+  }
+
+  /****************************** Ping  ***************************************/
+
+  // ping the server to keep the mqtt connection alive
+  // NOT required if you are publishing once every KEEPALIVE seconds
+  /*
+    if(! mqtt.ping()) {
+    mqtt.disconnect();
+    }
+  */
+}
+/********************************* MQTT Conn  ********************************/
+// Function to connect and reconnect as necessary to the MQTT server.
+// Should be called in the loop function and it will take care if connecting.
+void MQTT_connect() {
+  int8_t ret;
+
+  // Stop if already connected.
+  if (mqtt.connected()) {
+    return;
+  }
+
+  Serial.print("Connecting to MQTT... ");
+
+  uint8_t retries = 3;
+  while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
+    Serial.println(mqtt.connectErrorString(ret));
+    Serial.println("Retrying MQTT connection in 5 seconds...");
+    mqtt.disconnect();
+    delay(5000);  // wait 5 seconds
+    retries--;
+    if (retries == 0) {
+      // basically die and wait for WDT to reset me
+      while (1);
+    }
+  }
+  Serial.println("MQTT Connected!");
+}
+/****************************** Get Data From DHTxx  ************************/
+void gettemperature() {
+  // Wait at least 2 seconds seconds between measurements.
+  // if the difference between the current time and last time you read
+  // the sensor is bigger than the interval you set, read the sensor
+  // Works better than delay for things happening elsewhere also
+  unsigned long currentMillis = millis();
+
+  if (currentMillis - previousMillis >= interval) {
+    // save the last time you read the sensor
+    previousMillis = currentMillis;
+
+    // Reading temperature for humidity takes about 250 milliseconds!
+    // Sensor readings may also be up to 2 seconds 'old' (it's a very slow sensor)
+    humidity = dht.readHumidity();          // Read humidity (percent)
+    //temp_f = dht.readTemperature(true);     // Read temperature as Fahrenheit
+    temp_c = dht.readTemperature();    // Read temperature as Celsius
+    // Check if any reads failed and exit early (to try again).
+    if (isnan(temp_c) || isnan(humidity) || temp_c != 0 || humidity != 0 ) {
+      Serial.println("Failed to read from DHT sensor!");
+      return;
+    }
+  }
+}


Arduino code for voltmeter and relay controller

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

--- arduino/SolarVoltmeter/SolarVoltmeter.ino
+++ arduino/SolarVoltmeter/SolarVoltmeter.ino
@@ -0,0 +1,132 @@
+// http://startingelectronics.com/articles/arduino/measuring-voltage-with-arduino/
+
+/*--------------------------------------------------------------
+  Program:      volt_measure
+
+  Description:  Reads value on analog input A2 and calculates
+                the voltage assuming that a voltage divider
+                network on the pin divides by 11.
+
+  Hardware:     Arduino Uno with voltage divider on A2.
+
+  Software:     Developed using Arduino 1.0.5 software
+                Should be compatible with Arduino 1.0 +
+
+  Date:         22 May 2013
+
+  Author:       W.A. Smith, http://startingelectronics.com
+--------------------------------------------------------------*/
+
+// number of analog samples to take per reading
+#define NUM_SAMPLES 20
+
+int sum = 0;                    // sum of samples taken
+unsigned char sample_count = 0; // current sample number
+float voltage = 0.0;            // calculated voltage
+
+int inverter    = 0;            // is the inverter remote on?
+int mains_power = 0;            // is mains power on?
+
+#define REF_VOLTAGE  4.97       // Arduino 5V voltage
+
+#define INV_REMOTE  8           // Output pin for inverter remote control
+#define INV_LIVE    9           // Output pin for inverter live power
+#define INV_NEUTRAL 10          // Output
+
+// Voltage divider A0: 12.59 / 2.11
+
+void setup()
+{
+    Serial.begin(9600);
+    pinMode(A0, INPUT);  // Doesn't seem to work
+    pinMode(A1, INPUT);  // Input from voltage divider
+
+    pinMode(12, INPUT);  // mains_power voltage sensor (relay contact, 0V/5V)
+    // Relay http://www.farnell.com/datasheets/296895.pdf wiring 5V (digital 1)=no power
+
+    pinMode(INV_REMOTE, OUTPUT);   // Relay board channel 1: Inverter remote
+    pinMode(INV_LIVE, OUTPUT);   // Relay board channel 3: Inverter/mains_power live
+    pinMode(INV_NEUTRAL, OUTPUT);   // Relay board channel 4: Inverter/mains_power neutral
+
+    digitalWrite(INV_REMOTE, LOW);
+    digitalWrite(INV_LIVE, LOW);
+    digitalWrite(INV_NEUTRAL, LOW);
+
+}
+
+void loop()
+{
+    // take a number of analog samples and add them up
+    while (sample_count < NUM_SAMPLES) {
+        float sample = analogRead(A1);
+        sum += sample;
+        sample_count++;
+        // Serial.print("Actual: ");
+        // Serial.println(sample);
+        delay(20);
+    }
+    // calculate the voltage
+    // use 5.0 for a 5.0V ADC reference voltage
+    // 5.015V is the calibrated reference voltage
+    voltage = (((float)sum / (float)NUM_SAMPLES * REF_VOLTAGE) / 1024.0) * 5.99;
+
+    // send voltage for display on Serial Monitor
+    // voltage multiplied by 11 when using voltage divider that
+    // divides by 11. 11.132 is the calibrated voltage divide
+    // value
+
+    Serial.print("voltage=");
+    Serial.print(voltage);
+
+    // mains_power sensor
+    mains_power = !digitalRead(12);
+
+    Serial.print(" mains_power=");
+    Serial.print(mains_power);
+
+    if (!mains_power) {
+        // Always use inverter: low-voltage cutoff will cause it to power off eventually
+        if (!inverter) {
+            inverterOn();
+        }
+    } else {
+
+      // Battery getting low
+      if ((voltage < 12.1) && inverter) {
+          inverterOff();
+      }
+
+      // Battery charged and/or solar power available
+      if ((voltage > 12.5) && !inverter) {
+        inverterOn();
+      }
+
+    }
+
+    Serial.print(" inverter=");
+    Serial.print(inverter);
+
+    Serial.println();
+
+    sample_count = 0;
+    sum = 0;
+
+    delay(4600);
+}
+
+void inverterOn() {
+  digitalWrite(INV_REMOTE, HIGH);
+  delay(1000);
+  digitalWrite(INV_LIVE, HIGH);
+  digitalWrite(INV_NEUTRAL, HIGH);
+  inverter = 1;
+}
+
+void inverterOff() {
+  digitalWrite(INV_LIVE, LOW);
+  digitalWrite(INV_NEUTRAL, LOW);
+  delay(500);
+  digitalWrite(INV_REMOTE, LOW);
+  inverter = 0;
+}
+


special animation for the Vermillion exhibit that incorporates a range finder to shift between a blue-green stasis pattern and go more red-orange as someone gets closer.  with sparkle motion!

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

--- arduino/scripts/vermillion/vermillion.ino
+++ arduino/scripts/vermillion/vermillion.ino
@@ -0,0 +1,101 @@
+
+#include <Adafruit_WS2801.h>
+
+// Choose which 2 pins you will use for output.
+// Can be any valid output pins.
+const int DATA_PIN = 2;       // 'yellow' wire
+const int CLOCK_PIN = 3;      // 'green' wire
+
+const int SENSOR_PIN = A0;
+
+// highest component color value we want to push. could be as high as 31
+const int MAX_COLOR = 31;
+const int MIN_COLOR = 2;
+const int NUM_PIXELS = 50;
+
+const int INACTIVE_MAX_BLUE = MAX_COLOR / 2;
+const int INACTIVE_MIN_BLUE = MIN_COLOR;
+const int INACTIVE_MAX_GREEN = MAX_COLOR;
+const int INACTIVE_MIN_GREEN = MAX_COLOR + 10;
+const int INACTIVE_MAX_RED = 0;
+const int INACTIVE_MIN_RED = 0;
+
+const int ACTIVE_MAX_BLUE = 0;
+const int ACTIVE_MIN_BLUE = 0;
+const int ACTIVE_MAX_GREEN = 20;
+const int ACTIVE_MIN_GREEN = 8;
+const int ACTIVE_MAX_RED = MAX_COLOR;
+const int ACTIVE_MIN_RED = MAX_COLOR;
+
+const int LOOP_DELAY = 50;
+// odds of any one pixel being full white for 1 loop delay
+const int SPARKLE_DEMONINATOR = 100;
+
+
+
+Adafruit_WS2801 strip = Adafruit_WS2801(NUM_PIXELS, DATA_PIN, CLOCK_PIN);
+
+void setup() {
+  // put your setup code here, to run once:
+  strip.begin();
+  strip.show();
+
+  pinMode(SENSOR_PIN, INPUT);
+
+  Serial.begin(9600);
+  Serial.println("Starting Up Vermillion animation...");
+}
+
+
+void loop() {
+  // put your main code here, to run repeatedly:
+  int i;
+  int component;
+  int step;
+  int red;
+  int green;
+  int blue;
+  int sensorValue;
+
+  // sensor values between 20 - 200 cause an equal percentage of the first and last
+  // 20 pixels to go to red scale
+  sensorValue = analogRead(SENSOR_PIN);
+
+  for (int i = 0; i < NUM_PIXELS; i++){
+    if (random(SPARKLE_DEMONINATOR) == 1){
+      red = MAX_COLOR;
+      green = MAX_COLOR;
+      blue = MAX_COLOR;
+    } else if( shouldGoRed(i, sensorValue) ){
+      red = random(ACTIVE_MIN_RED, ACTIVE_MAX_RED);
+      green = random(ACTIVE_MIN_GREEN, ACTIVE_MAX_GREEN);
+      blue = random(ACTIVE_MIN_BLUE, ACTIVE_MAX_BLUE);
+    } else {
+      red = random(INACTIVE_MIN_RED, INACTIVE_MAX_RED);
+      green = random(INACTIVE_MIN_GREEN, INACTIVE_MAX_GREEN);
+      blue = random(INACTIVE_MIN_BLUE, INACTIVE_MAX_BLUE);
+    }
+    strip.setPixelColor(i, red, green, blue);
+  }
+  strip.show();
+  delay(LOOP_DELAY);
+}
+
+bool shouldGoRed(int pixelIndex, int sensorValue){
+  char outputBuffer[64];
+  int degree = (sensorValue / 9);
+
+  if( pixelIndex > 20 && pixelIndex < 30 || sensorValue > 200)
+    return false;
+
+  // Serial.print(itoa(pixelIndex, outputBuffer, 10));
+  // Serial.print("- SENSOR_PIN: ");
+  // Serial.print(", degree: ");
+  // Serial.print(itoa(degree, outputBuffer, 10));
+  // Serial.print("\n");
+
+  return pixelIndex < 20 - degree || pixelIndex > 30 && pixelIndex < 50 - degree;
+}
+
+
+


calibration code for IR sensor for reference

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

--- arduino_motor/Calibration/Calibration.ino
+++ arduino_motor/Calibration/Calibration.ino
@@ -0,0 +1,75 @@
+/*
+  Calibration
+
+ Demonstrates one technique for calibrating sensor input.  The
+ sensor readings during the first five seconds of the sketch
+ execution define the minimum and maximum of expected values
+ attached to the sensor pin.
+
+ The sensor minimum and maximum initial values may seem backwards.
+ Initially, you set the minimum high and listen for anything
+ lower, saving it as the new minimum. Likewise, you set the
+ maximum low and listen for anything higher as the new maximum.
+
+ The circuit:
+ * Analog sensor (potentiometer will do) attached to analog input 0
+ * LED attached from digital pin 9 to ground
+
+ created 29 Oct 2008
+ By David A Mellis
+ modified 30 Aug 2011
+ By Tom Igoe
+
+ http://arduino.cc/en/Tutorial/Calibration
+
+ This example code is in the public domain.
+
+ */
+
+// These constants won't change:
+const int sensorPin = A0;    // pin that the sensor is attached to
+const int ledPin = 9;        // pin that the LED is attached to
+
+// variables:
+int sensorValue = 0;         // the sensor value
+int sensorMin = 1023;        // minimum sensor value
+int sensorMax = 0;           // maximum sensor value
+
+
+void setup() {
+  // turn on LED to signal the start of the calibration period:
+  pinMode(13, OUTPUT);
+  digitalWrite(13, HIGH);//pin 13?
+
+  // calibrate during the first five seconds
+  while (millis() < 5000) {
+    sensorValue = analogRead(sensorPin);
+
+    // record the maximum sensor value
+    if (sensorValue > sensorMax) {
+      sensorMax = sensorValue;
+    }
+
+    // record the minimum sensor value
+    if (sensorValue < sensorMin) {
+      sensorMin = sensorValue;
+    }
+  }
+
+  // signal the end of the calibration period
+  digitalWrite(13, LOW);
+}
+
+void loop() {
+  // read the sensor:
+  sensorValue = analogRead(sensorPin);
+
+  // apply the calibration to the sensor reading
+  sensorValue = map(sensorValue, sensorMin, sensorMax, 0, 255);
+
+  // in case the sensor value is outside the range seen during calibration
+  sensorValue = constrain(sensorValue, 0, 255);
+
+  // fade the LED using the calibrated value:
+  analogWrite(ledPin, sensorValue);
+}


Create Heltec_LoRa32_ttn-abp.ino

Create Heltec_LoRa32_ttn-abp.ino

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

--- Heltec_LoRa32_ttn-abp/Heltec_LoRa32_ttn-abp.ino
+++ Heltec_LoRa32_ttn-abp/Heltec_LoRa32_ttn-abp.ino
@@ -0,0 +1 @@
+


dang, wasn't that the error anyway??

dang, wasn't that the error anyway??

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


copy galaxytopper.ino to "tick_demos.ino"

I'm going to be reducing the number and diversity of modes in my topper,
but want to preserve this functionality for demonstration purposes.

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

--- tick_demos.ino
+++ tick_demos.ino
@@ -0,0 +1,448 @@
+/*
+ * Fimware for the Galaxy Topper
+ * Galaxy Topper is a top hat inspired by Chris Knight's build at:
+ *   http://www.instructables.com/id/My-hat-its-full-of-stars/
+ *
+ * It uses 6 ShiftBrite pixels to drive a "galaxy" of points of light poking
+ * through the felt of a simple, felt top hat. The hat has several different
+ * modes and more can be added fairly easily. There is a momentary pushbutton
+ * hidden under the bow on the band to cycle through the modes. To keep things
+ * fresh and interesting the pushbutton seeds the pRNG with the current value
+ * of millis() when pushed.
+ *
+ * MODES:
+ *  - Stealth: All pixels are off, leaving the hat dark.
+ *  - Sparkle: each pixel picks a random color, waits a short time, and picks a
+ *      new one
+ *  - Rainbow: Each pixel fades around the color wheel. Pixels are offset from
+ *      one another to give a more active pattern
+ *  - Nebula: each pixel fades randomly through blue/white/purple colors
+ *      creating a rippling, twinkling pattern in the colors of the night sky
+ *  - Christmas Lights: Pixels cycle through the soft colors of old strings of
+ *      Christmas lights. Colors are nominally red, yellow, green, and blue,
+ *      TODO: but in practice are washed out and warmed over
+ *  - Christmas: Pixels alternate between red and green.
+ *
+ * TODO:
+ * I'd really like to add a couple more pixels tied directly into certain
+ * patterns (alchemical symbols?) that I can have illuminate at random or on
+ * command, but I'm not sure if that'll work out.
+ */
+
+
+#include "shiftbrite.h"
+#include "ticker.h"
+#include "math.h"     // only used to get pow(...) for our skew(...) function
+
+/* Constants */
+#define LATCH_PIN    9  // replace with pin you use for the ShiftBrite latch
+#define BUTTON_PIN   3  // pin used for the button to cycle modes
+#define NUM_LEDS     6  // Number of LEDs in your chain
+#define NUM_MODES    6  // Number of light modes the topper supports
+#define FPS        100  // number of times per second to update shiftbrites
+#define TPS        100  // ticks per second
+
+/* Predeclarations */
+// Necessary to avoid confusing particle's preprocessor
+// see https://docs.particle.io/reference/firmware/core/#preprocessor
+void colorwheel_tick(Ticker *t, unsigned long tick);
+void cycling_tick(Ticker *t, unsigned long tick);
+void fading_cycling_tick(Ticker *t, unsigned long tick);
+void targeted_tick(Ticker *t, unsigned long tick);
+void dark_tick(Ticker *t, unsigned long tick);
+TickerRgb hsv2rgb(double hue, double sat, double value);
+
+/* Define Objects */
+ShiftBrite sb(NUM_LEDS, LATCH_PIN);
+Ticker Tickers[NUM_LEDS] = {
+	Ticker(&dark_tick, 0, 0,  0),
+	Ticker(&dark_tick, 0, 0,  0),
+	Ticker(&dark_tick, 0, 0,  0),
+	Ticker(&dark_tick, 0, 0,  0),
+	Ticker(&dark_tick, 0, 0,  0),
+	Ticker(&dark_tick, 0, 0,  0),
+};
+
+/* Timing */
+unsigned long frame_delay = 1000 / FPS;
+unsigned long tick_delay  = 1000 / TPS;
+unsigned long tick, last_tick, last_frame = 0;
+
+/* Button to switch modes */
+int current_mode = 0;
+volatile int           mode_change_requested = 0;
+volatile unsigned long button_last_triggered = 0;
+
+void setup()
+{
+	// Initialize shiftbrite
+	sb.begin();
+	sb.show();
+
+	// Set up mode-change button
+	pinMode(BUTTON_PIN, INPUT_PULLUP);
+	attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), trigger_change, FALLING);
+
+	// Initialize tickers
+	mode_stealth();
+}
+
+void loop()
+{
+	if (mode_change_requested) {
+		change_mode();
+		mode_change_requested = 0;
+	}
+
+	unsigned long now = millis();
+
+	// Is it time to do another tick?
+	if (now - last_tick > tick_delay) {
+		last_tick = millis();
+		for(int i = 0; i < NUM_LEDS; ++i) {
+			Tickers[i].Tick(tick);
+			TickerRgb c = Tickers[i].current;
+			sb.setPixelRGB(i, c.red, c.green, c.blue);
+		}
+		++tick;
+	}
+
+	// Is it time to refresh our shiftbrites?
+	if (millis() - last_frame > frame_delay) {
+		last_frame = millis();
+		sb.show();
+	}
+}
+
+/*********************
+ * MODE SETUP FUNCTIONS *
+ ************************/
+void trigger_change() {
+	if (millis() - button_last_triggered > 600) {
+		button_last_triggered = millis();
+		mode_change_requested = 1;
+	}
+}
+
+void change_mode() {
+	randomSeed(millis());
+
+	++current_mode;
+	current_mode %= NUM_MODES;
+	switch(current_mode) {
+		case 0:
+			mode_stealth();
+			break;
+		case 1:
+			mode_sparkle();
+			break;
+		case 2:
+			mode_rainbow();
+			break;
+		case 3:
+			mode_nebula();
+			break;
+		case 4:
+			mode_christmas_lights();
+			break;
+		case 5:
+			mode_christmas();
+			break;
+		default:
+			mode_stealth();
+			break;
+	}
+
+}
+
+void mode_stealth()
+{
+	for (int i = 0; i < NUM_LEDS; ++i) {
+		Tickers[i] = Ticker(&dark_tick, 0, 0, 0);
+	}
+}
+
+void mode_nebula()
+{
+	// Use targeting tickers constrained to be colors with strong blue channels
+	// to make a flickering "nebula" effect.
+	for (int i = 0; i < NUM_LEDS; ++i) {
+		Tickers[i] = Ticker(&targeted_tick, 3, 0, i * 5 + 1);
+
+		Tickers[i].targets[0] = {red: random(0,1023), green: random(0,1023), blue: random(0,1023)};
+		Tickers[i].targets[1] = {red: 0, green: 0, blue: 511};
+		Tickers[i].targets[2] = {red: 1023, green: 1023, blue: 1023};
+	}
+}
+
+void mode_sparkle()
+{
+	for (int i = 0; i < NUM_LEDS; ++i) {
+		Tickers[i] = Ticker(&random_tick, 0, 2, i);
+	}
+}
+
+void mode_christmas_lights()
+{
+	for (int i = 0; i < NUM_LEDS; ++i) {
+		// Slow by 2^6
+		Tickers[i] = Ticker(&cycling_tick, 4, 6, i);
+
+		//TODO: Adjust these values to taste to simulate christmas lights
+		Tickers[i].targets[0] = {red: 1023, green:    0, blue:    0}; // Red
+		Tickers[i].targets[1] = {red: 1023, green: 1023, blue:    0}; // Yellow
+		Tickers[i].targets[2] = {red:    0, green: 1023, blue:    0}; // Green
+		Tickers[i].targets[3] = {red:    0, green:    0, blue: 1023}; // Blue
+	}
+}
+
+void mode_christmas()
+{
+	for (int i = 0; i < NUM_LEDS; ++i) {
+		// Slow by 2^6
+		Tickers[i] = Ticker(&cycling_tick, 2, 6, i);
+
+		Tickers[i].targets[0] = {red: 1023, green:    0, blue:    0}; // Red
+		Tickers[i].targets[1] = {red:    0, green: 1023, blue:    0}; // Green
+	}
+}
+
+void mode_rainbow()
+{
+	for (int i = 0; i < NUM_LEDS; ++i) {
+		Tickers[i] = Ticker(&colorwheel_tick, 0, 0, i * 15);
+	}
+}
+
+/*********************
+ *  TICKER FUNCTIONS *
+ *********************/
+
+/* Do nothing */
+void dark_tick(Ticker *t, unsigned long tick)
+{
+	t->current = {red: 0, green: 0, blue: 0};
+}
+
+/*
+ * Cycles around the color wheel by using tick to compute the hue (value and
+ * saturation are held constant at 1).
+ *
+ * Ticker's speed_adjust is used to slow the cycle by powers of 2
+ *
+ * Ticker's offset is used to set the color *ahead* of the tick's base hue.
+ * This can be used to sync multiple colorwheel_tick Tickers into a ribbon.
+ *
+ * This tick function does not use any target colors.
+ */
+void colorwheel_tick(Ticker *t, unsigned long tick)
+{
+	int16_t hue = ((tick >> t->speed_adjust) + t->offset) % 360;
+	t->current = hsv2rgb((double)hue, 1.0, 1.0);
+}
+
+/*
+ * Picks a random color and switches to it.
+ *
+ * By default it switches every tick. Slow this by 2^n by setting Ticker's
+ * speed_adjust to n.
+ *
+ * This tick function does not use any targets
+ */
+void random_tick(Ticker *t, unsigned long tick)
+{
+	if (tick % (1 << t->speed_adjust)) {return;}
+	t->current = {red: random(0,1023), green: random(0,1023), blue: random(0,1023)};
+}
+
+/*
+ * Cycles through a fixed list of target colors.
+ *
+ * By default moves to the next color in the cycle every tick. Slow this
+ * by 2^n by setting Ticker's speed_adjust to n.
+ *
+ * Advance the position in the cycle with Ticker's offset. This can be used to
+ * sync multiple cycling_tick tickers into a string.
+ *
+ * This tick function uses as many targets as you choose to give the Ticker.
+ */
+void cycling_tick(Ticker *t, unsigned long tick)
+{
+	int current_index = ((tick >> t->speed_adjust) + t->offset) % t->num_targets;
+	t->current = t->targets[current_index];
+}
+
+/*
+ * Cycles through a fixed list of target colors, fading between them.
+ *
+ * Fading from one color to the next takes about a second. TODO: make this
+ * dynamic via Ticker's speed_adjust.
+ *
+ * Advance the position in the cycle with Ticker's offset. This can be used to
+ * sync multiple cycling_tick tickers into a string.
+ *
+ * This tick function uses as many targets as you choose to give the Ticker.
+ */
+void fading_cycling_tick(Ticker *t, unsigned long tick)
+{
+	int previous_index = ((tick / TPS) + t->offset) % t->num_targets; // Update target once per second.
+	TickerRgb previous_color = t->targets[previous_index];
+	TickerRgb next_color     = t->targets[(previous_index + 1) % t->num_targets];
+
+	int16_t red_delta     = next_color.red       - previous_color.red;
+	int16_t current_red   = previous_color.red   + ((red_delta * (tick % TPS)) / TPS);
+	int16_t green_delta   = next_color.green     - previous_color.green;
+	int16_t current_green = previous_color.green + ((green_delta * (tick % TPS)) / TPS);
+	int16_t blue_delta    = next_color.blue      - previous_color.blue;
+	int16_t current_blue  = previous_color.blue  + ((blue_delta * (tick % TPS)) / TPS);
+
+	t->current = {red: current_red, green: current_green, blue: current_blue};
+}
+
+/*
+ * Fades to a target color. Once target color is reached, the target and fade
+ * speed are randomized. Target randomization is controllable within min and
+ * max values on each color channel.
+ *
+ * Ticker's offset is used as the step size to control how quickly the color
+ * moves towards the target.
+ *
+ * Ticker's speed_adjust is used to skip cycles by powers of 2:
+ * 0 executes every cycle
+ * 1 executes every other cycle
+ * 2 executes every fourth cycle...
+ *
+ * This tick function uses three "target" colors:
+ *   0: The color to fade towards
+ *   1: The minimum value for each color channel when randomizing
+ *   2: The maximum value for each color channel when randomizing
+ */
+void targeted_tick(Ticker *t, unsigned long tick)
+{
+	// speed_adjust keeps us from ticking on certain cycles
+	if (tick % (1 << t->speed_adjust)) {return;}
+
+	TickerRgb* current = &t->current;
+	TickerRgb* target  = &t->targets[0];
+	TickerRgb  minima  = t->targets[1];
+	TickerRgb  maxima  = t->targets[2];
+	int step_size = t->offset;
+
+	if (   current->red   == target->red
+		&& current->green == target->green
+		&& current->blue  == target->blue)
+	{
+		// We've reached the target! Pick a new one.
+		target->red   = random(minima.red,   maxima.red);
+		target->green = random(minima.green, maxima.green);
+		target->blue  = random(minima.blue,  maxima.blue);
+		// And just for fun let's also randomize the fade speed!
+		t->offset       = skew(random(1, 100), 5, 50, 100);
+		t->speed_adjust = random(0, 1);
+	}
+	// Still working towards the target. Take a step in the right direction
+	// TODO: Should we adjust the step sizes so that each channel reaches
+	//       its target at the same time?
+	current->red   += stepToward(target->red,   current->red,   step_size);
+	current->green += stepToward(target->green, current->green, step_size);
+	current->blue  += stepToward(target->blue,  current->blue,  step_size);
+}
+
+/*** HELPER FUNCTIONS ***/
+
+/*
+ * Given a target value, current value, and step size, calculate the value to
+ * add to the current value to move it towards its target by the step size
+ * without going past the target.
+ */
+int16_t stepToward(int16_t target, int16_t current, int step_size)
+{
+	int16_t delta = target - current;
+	delta = abs(delta);
+
+	int direction = 0;
+	if (target > current) {direction =  1;}
+	if (target < current) {direction = -1;}
+
+	return (delta > step_size ? step_size : delta) * direction;
+}
+
+/*
+ * This is the gamma correction function that I included a lookup table for in
+ * shiftbrite.h. It's used here to map a uniform distribution to something skewed
+ * heavily towards the low end.
+ *
+ * Basically I want my targeting Tickers to fade slowly most of the time but do a
+ * really quick flicker every once in a while.
+ */
+int16_t skew(int16_t x, int16_t exponent, int16_t max_out, int16_t range)
+{
+	return (int16_t)(pow((float)x / (float)range, exponent) * max_out + 1);
+}
+
+/*
+ * This function converts an HSV value into an RGB value.
+ * Code taken from StackOverflow user DavidH:
+ *   http://stackoverflow.com/questions/3018313/algorithm-to-convert-rgb-to-hsv-and-hsv-to-rgb-in-range-0-255-for-both
+ */
+TickerRgb hsv2rgb(double hue, double sat, double value)
+{
+	double sextant, chroma, q, t, ff;
+	double red, blue, green;
+	long  i;
+	TickerRgb   out;
+
+	if(sat <= 0.0) {
+		red   = value;
+		green = value;
+		blue  = value;
+		return out;
+	}
+
+	sextant = hue;
+	if(sextant >= 360.0) sextant = 0.0;
+	sextant /= 60.0;
+	i = (long)sextant;
+	ff = sextant - i;
+	chroma = value * (1.0 - sat);
+	q = value * (1.0 - (sat * ff));
+	t = value * (1.0 - (sat * (1.0 - ff)));
+
+	switch(i) {
+		case 0:
+			red   = value;
+			green = t;
+			blue  = chroma;
+			break;
+		case 1:
+			red   = q;
+			green = value;
+			blue = chroma;
+			break;
+		case 2:
+			red   = chroma;
+			green = value;
+			blue  = t;
+			break;
+		case 3:
+			red   = chroma;
+			green = q;
+			blue  = value;
+			break;
+		case 4:
+			red   = t;
+			green = chroma;
+			blue  = value;
+			break;
+		case 5:
+		default:
+			red   = value;
+			green = chroma;
+			blue  = q;
+			break;
+	}
+	out.red   = (int16_t)(red   * 1023);
+	out.green = (int16_t)(green * 1023);
+	out.blue  = (int16_t)(blue  * 1023);
+	return out;
+}


Nonce pool should be post-incremented instead of pre-incremented

Signed-off-by: Edi Permadi <163b49ac0c44ca5b49677bf42f3f8680b3bd9867@gmail.com>

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/edipermadi/teensy-hsm.git/'


improved error handling for nduino comm

improved error handling for nduino comm

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/ekwoodrich/nirha.git/'


fixed TX_REPEAT typo in nduino

fixed TX_REPEAT typo in nduino


Basic one-wire temperature sensor sketch

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

--- sous_vide_arduino/sous_vide_arduino.ino
+++ sous_vide_arduino/sous_vide_arduino.ino
@@ -0,0 +1,70 @@
+#include <OneWire.h>
+#include <DallasTemperature.h>
+
+// Data wire is plugged into port 2 on the Arduino
+#define ONE_WIRE_BUS 2
+
+// State variables
+bool enabled = false;
+byte targetTempF = 0;
+
+// Setup a oneWire instance to communicate with OneWire devices
+OneWire oneWire(ONE_WIRE_BUS);
+
+// Pass our oneWire reference to the Dallas Temperature library
+DallasTemperature sensors(&oneWire);
+DeviceAddress thermometer;
+
+void setup()
+{
+    Serial.begin(9600);
+
+    sensors.begin();
+    if (!sensors.getAddress(thermometer, 0)) {
+        Serial.println("Unable to find address for Device 0");
+    }
+
+    sensors.setResolution(thermometer, 9);
+}
+
+float temperature()
+{
+    return DallasTemperature::toFahrenheit(sensors.getTempC(thermometer));
+}
+
+void loop()
+{
+    // Wait for serial data
+    while (!Serial.available());
+    byte cmd = Serial.read();
+    if (cmd == '0') {
+        // 0: Get status
+        // Send the command to get temperatures
+        sensors.requestTemperatures();
+        // Print the received temperature
+        Serial.print("Enabled: ");
+        Serial.print(enabled);
+        Serial.print(", temp F: ");
+        Serial.print(temperature());
+        Serial.print(", target F: ");
+        Serial.println(targetTempF);
+    } else if (cmd == '1') {
+        // 1: Turn on heater
+        enabled = true;
+        Serial.println("Heater on");
+    } else if (cmd == '2') {
+        // 2: Turn off heater
+        enabled = false;
+        Serial.println("Heater off");
+    } else if (cmd == '3') {
+        // 3: Set target temperature
+        while (!Serial.available());
+        targetTempF = Serial.read();
+        Serial.print("Set temp to ");
+        Serial.println(targetTempF);
+    } else {
+        while (Serial.available()) {
+            Serial.read();
+        }
+    }
+}


Issue #2 Debugging for every action and state of the device

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/franciscoalario/GoldenAnt.git/'


added example files

added example files

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

--- arduino/RobotArmServo/examples/ExampleUse/ExampleUse.ino
+++ arduino/RobotArmServo/examples/ExampleUse/ExampleUse.ino
@@ -0,0 +1,11 @@
+#include <Servo.h>
+#include <RobotArm.h>
+
+RobotArm arm(1,2,3,4,5);
+
+void setup() {
+}
+
+void loop() {
+  arm.updateJoint(RobotArm::BASE,125);
+}


Kill interrupts during reading an math period.

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/spoollord/MyOurWeather.git/'


Add updated sketch with range detection average

error: pathspec 'testing/arduino/self-driving-v5.ino' did not match any file(s) known to git

--- testing/arduino/self-driving-v5.ino
+++ testing/arduino/self-driving-v5.ino
@@ -0,0 +1,310 @@
+#include "Arduino.h"
+#include "Adafruit_NeoPixel.h"
+#include "Servo.h"
+
+// Base Date
+const uint8_t initialDelay = 2500;
+
+// Ranges and Data
+const uint8_t rangeLimit_Warning1 = 50;
+const uint8_t rangeLimit_Warning2 = 40;
+const uint8_t rangeLimit_Warning3 = 25;
+const uint8_t rangeLimit_Stop = 15;
+
+const uint16_t rangeLimit_RotateFor = 500;
+unsigned long rangeLimit_Timestamp = 0;
+bool wheelSpinCompleted = true;
+
+
+// Ultrasonic Sensor
+const uint8_t trigPin = 9;
+const uint8_t echoPin = 10;
+
+long rangeData_Left[15];
+long average_Left;
+long rangeData_Center[10];
+long average_Center;
+long rangeData_Right[15];
+long average_Right;
+uint8_t rangeDataIndex = 0;
+
+// LED
+const uint8_t ledPin = 11;
+const bool ledBatterySaving = true;
+Adafruit_NeoPixel LEDStrip = Adafruit_NeoPixel(26, ledPin, NEO_GRB + NEO_KHZ800);
+
+// Motor / Wheels
+const uint8_t motorPin1_1 = 4;
+const uint8_t motorPin1_2 = 5;
+
+const uint8_t motorPin2_1 = 7;
+const uint8_t motorPin2_2 = 8;
+
+const uint8_t motorEnablePin = 3;
+
+// Ultrasonic Servo
+Servo ServoMotor;
+const uint8_t servoPin = 6;
+const uint8_t servoRotationAngel = 10;
+
+enum direction {
+  left,
+  center,
+  right
+};
+
+uint8_t servoPos = 90;
+direction servoMovement = right;
+direction servoLocation = center;
+
+
+void setup()
+{
+    // Scanner
+    pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
+    pinMode(echoPin, INPUT); // Sets the echoPin as an Input
+
+    rangeLimit_Timestamp = millis();
+
+    pinMode(motorEnablePin, OUTPUT);
+    analogWrite(motorEnablePin, 255);
+
+    // Motor
+    pinMode(motorPin1_1, OUTPUT);
+    pinMode(motorPin1_2, OUTPUT);
+
+    pinMode(motorPin2_1, OUTPUT);
+    pinMode(motorPin2_2, OUTPUT);
+
+    Serial.begin(9600); // Starts the serial communication
+
+    LEDStrip.begin();
+    LEDStrip.show(); // Initialize all pixels to 'off'
+
+    // attach servo pin and set to initial direction
+    ServoMotor.attach(servoPin);
+    ServoMotor.write(servoPos);
+}
+
+
+long MicrosecondsToCentimeters(long microseconds)
+{
+    return microseconds / 29 / 2;
+}
+
+
+// Use library to minimize delay
+long GetUltrasoundRange()
+{
+    digitalWrite(trigPin, LOW);
+    delayMicroseconds(2);
+
+    digitalWrite(trigPin, HIGH);
+    delayMicroseconds(10);
+    digitalWrite(trigPin, LOW);
+
+    long duration = pulseIn(echoPin, HIGH);
+
+    // convert the time into a distance
+    return MicrosecondsToCentimeters(duration);
+}
+
+void CalculateAverageRange()
+{
+    long range = GetUltrasoundRange();
+    long **rangeData_Current;
+
+    // get current meassurement and add to array
+    if(servoLocation == left)
+    {
+        rangeData_Left[rangeDataIndex++] = range;
+        rangeData_Current = rangeData_Left;
+    }
+
+    if(servoLocation == center)
+    {
+        rangeData_Center[rangeDataIndex++] = range;
+        rangeData_Current = rangeData_Center;
+    }
+
+    if(servoLocation == right)
+    {
+        rangeData_Right[rangeDataIndex++] = range;
+        rangeData_Current = rangeData_Right;
+    }
+
+    direction servoLocationLast = servoLocation;
+    direction servoMovementLast = servoMovement;
+
+    // Get the next Angle and Move the Servo
+    ServoMotor.write(GetNextServoAngle());
+
+    // if the new servo location is different from the one before calculate an anverage
+    if(servoLocation != servoLocationLast || servoMovement != servoMovementLast)
+    {
+        long summedUp = 0;
+        for (int i = 0; i < rangeDataIndex; i++)
+        {
+            summedUp += rangeData_Current[i];
+            rangeData_Current[i] = 0;
+        }
+
+        long average = summedUp/rangeDataIndex;
+        if(servoLocationLast == left) { average_Left = average; }
+        if(servoLocationLast == center) { average_Center = average; }
+        if(servoLocationLast == right) { average_Right = average; }
+
+        rangeDataIndex = 0;
+    }
+}
+
+
+void SetMotor(int pin1, int pin2, int speed)
+{
+    if (speed < 0)
+    {
+        analogWrite(pin1, 0);
+        analogWrite(pin2, 255);
+    }
+    else
+    {
+        analogWrite(pin1, 255);
+        analogWrite(pin2, 0);
+    }
+
+    if (speed == 0)
+    {
+        analogWrite(pin1, 0);
+        analogWrite(pin2, 0);
+    }
+}
+
+
+void ColorSet(uint32_t c)
+{
+    for(uint16_t i=0; i < LEDStrip.numPixels(); i++)
+    {
+        if(ledBatterySaving && i%4 == 0 || !ledBatterySaving)
+        {
+            LEDStrip.setPixelColor(i, c);
+        }
+    }
+    LEDStrip.show();
+}
+
+
+uint8_t GetNextServoAngle()
+{
+    // 0 - 80 / 80 - 100 / 100 - 180
+    if(servoPos <= 0)
+    {
+        servoMovement = right;
+        servoPos = 0;
+    }
+
+    if(servoPos >= 180)
+    {
+        servoMovement = left;
+        servoPos = 180;
+    }
+
+
+    if(servoMovement == right)
+    {
+        servoPos += servoRotationAngel;
+    }
+    else
+    {
+        servoPos -= servoRotationAngel;
+    }
+
+
+    if(servoPos < 80)
+    {
+        servoLocation = left;
+    }
+
+    if(servoPos >= 80 && servoPos <= 100)
+    {
+        servoLocation = center;
+    }
+
+    if(servoPos > 100)
+    {
+        servoLocation = right;
+    }
+
+    return servoPos;
+}
+
+
+void SetLightByRange(long range)
+{
+    uint32_t color = LEDStrip.Color(0, 255, 0);
+    if(range < rangeLimit_Warning1) { color = LEDStrip.Color(127, 255, 0);}
+    if(range < rangeLimit_Warning2) { color = LEDStrip.Color(255, 255, 0); }
+    if(range < rangeLimit_Warning3) { color = LEDStrip.Color(255, 127, 0); }
+    if(range < rangeLimit_Stop) { color = LEDStrip.Color(255, 0, 0); }
+
+    ColorSet(color);
+}
+
+void ErrorState()
+{
+    ColorSet(LEDStrip.Color(0, 0, 255));
+
+    SetMotor(motorPin1_1, motorPin1_2, 0);
+    SetMotor(motorPin2_1, motorPin2_2, 0);
+}
+
+void loop()
+{
+
+    CalculateAverageRange();
+
+    /*
+    average_Left
+    average_Center
+    average_Right
+    */
+
+    long range = average_Center;
+
+    SetLightByRange(range);
+
+    if(millis() < initialDelay)
+    {
+        return;
+    }
+
+    // maybe wait for x seconds before starting so a full
+    // left center right scan can be performed first
+
+
+    // obstacle is further away than X cm
+    if(wheelSpinCompleted && range > rangeLimit_Stop)
+    {
+        // drive
+        SetMotor(motorPin1_1, motorPin1_2, 255);
+        SetMotor(motorPin2_1, motorPin2_2, 255);
+
+        rangeLimit_Timestamp = millis();
+    }
+    else
+    {
+
+        // TODO
+
+        // rotate
+        SetMotor(motorPin1_1, motorPin1_2, -255);
+        SetMotor(motorPin2_1, motorPin2_2, 255);
+
+        wheelSpinCompleted = false;
+
+        if(range > rangeLimit_Warning3 && (rangeLimit_Timestamp + rangeLimit_RotateFor) <= millis())
+        {
+            wheelSpinCompleted = true;
+        }
+    }
+}
+


Pressure Mat code for MOAD

Pressure Mat code for MOAD

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

--- things/examples/arduino/PressureMat/PressureMat/PressureMat.ino
+++ things/examples/arduino/PressureMat/PressureMat/PressureMat.ino
@@ -0,0 +1,181 @@
+#include <Dhcp.h>
+#include <Dns.h>
+#include <Ethernet.h>
+#include <EthernetClient.h>
+#include <EthernetServer.h>
+#include <EthernetUdp.h>
+#include <util.h>
+
+#include <SPI.h>
+
+int requestID = 1;
+
+// The MAC address of your Ethernet board (or Ethernet Shield) is located on the back of the curcuit board.
+byte mac[] = { 0x0, 0xA2, 0xDA, 0x0D, 0x90, 0xE2 };  // Arduino Ethernet
+
+char packetBuffer[512];
+
+PROGMEM prog_char *loopPacket1 = "{\"path\":\"/api/v1/thing/reporting\",\"requestID\":\"";
+PROGMEM prog_char *loopPacket2 = "\",\"things\":{\"/device/sensor/arduino/mat\":{\"prototype\":{\"device\":{\"name\":\"60# pressure mat (902PR)\",\"maker\":\"United Security Products\"},\"name\":\"true\",\"status\":[\"present\",\"absent\",\"recent\"],\"properties\":{\"pressure\":[\"on\",\"off\"]}},\"instances\":[{\"name\":\"Pressure Mat\",\"status\":\"present\",\"unit\":{\"serial\":\"";
+PROGMEM prog_char *loopPacket3 = "\",\"udn\":\"195a42b0-ef6b-11e2-99d0-";
+PROGMEM prog_char *loopPacket4 = "-mat\"},\"info\":{\"pressure\":\"";
+PROGMEM prog_char *loopPacket5 = "\"},\"uptime\":\"";
+PROGMEM prog_char *loopPacket6 = "\"}]}}}";
+
+// All TSRP transmissions are via UDP to port 22601 on multicast address '224.192.32.19'.
+EthernetUDP udp;
+IPAddress ip(224,192,32,19);
+unsigned int port = 22601;
+
+const int buttonPin = 7;
+int buttonState;
+int lastButtonState = LOW;
+int sentPacket = 0;
+
+long lastDebounceTime = 0;
+long debounceDelay = 50;
+
+void setup() {
+  pinMode(buttonPin, INPUT);
+
+  Serial.begin(9600);
+  Serial.println("Starting...");
+  while(!Serial) { }
+
+  Serial.println("Waiting for DHCP address.");
+  if (Ethernet.begin(mac) == 0) {
+    Serial.println("Error: Failed to configure Ethernet using DHCP");
+    while(1) {  }
+  }
+
+  Serial.print("MAC address: ");
+  for (byte thisByte = 0; thisByte < 6; thisByte++) {
+    Serial.print(mac[thisByte], HEX);
+    Serial.print(":");
+  }
+  Serial.println();
+
+  Serial.print("IP address: ");
+  for (byte thisByte = 0; thisByte < 4; thisByte++) {
+    Serial.print(Ethernet.localIP()[thisByte], DEC);
+    Serial.print(".");
+  }
+  Serial.println();
+
+  udp.beginMulti(ip,port);
+
+}
+
+void loop() {
+  int reading = digitalRead(buttonPin);
+
+  if (reading != lastButtonState) {
+    lastDebounceTime = millis();
+  }
+  if ((millis() - lastDebounceTime) > debounceDelay) {
+    buttonState = reading;
+    //Serial.print( "Button state = " );
+    //Serial.println( buttonState );
+    if ( buttonState && !sentPacket ) {
+       Serial.println("Sending pressure = on");
+       sentPacket = 1;
+       requestID = requestID + 1;
+
+       char buffer[12];
+       strcpy(packetBuffer,(char*)pgm_read_word(&loopPacket1) );
+       strcat(packetBuffer, itoa( requestID, buffer, 10) );
+       strcat(packetBuffer,(char*)pgm_read_word(&loopPacket2) );
+       for (byte thisByte = 0; thisByte < 6; thisByte++) {
+         sprintf(buffer, "%x", mac[thisByte] );
+         strcat(packetBuffer, buffer);
+       }
+       strcat(packetBuffer,(char*)pgm_read_word(&loopPacket3) );
+       for (byte thisByte = 0; thisByte < 6; thisByte++) {
+         sprintf(buffer, "%x", mac[thisByte] );
+         strcat(packetBuffer, buffer);
+       }
+       strcat(packetBuffer,(char*)pgm_read_word(&loopPacket4) );
+       strcat(packetBuffer, "on");
+       strcat(packetBuffer,(char*)pgm_read_word(&loopPacket5) );
+       strcat(packetBuffer, itoa( millis()/1000, buffer, 10) );
+       strcat(packetBuffer,(char*)pgm_read_word(&loopPacket6) );
+
+       Serial.println(packetBuffer);
+       udp.beginPacket(udp.remoteIP(), udp.remotePort());
+       udp.write(packetBuffer);
+       udp.endPacket();
+
+    } else if ( !buttonState && !sentPacket ) {
+       Serial.println("Sending pressure = off");
+       sentPacket = 1;
+       requestID = requestID + 1;
+
+       char buffer[12];
+       strcpy(packetBuffer,(char*)pgm_read_word(&loopPacket1) );
+       strcat(packetBuffer, itoa( requestID, buffer, 10) );
+       strcat(packetBuffer,(char*)pgm_read_word(&loopPacket2) );
+       for (byte thisByte = 0; thisByte < 6; thisByte++) {
+         sprintf(buffer, "%x", mac[thisByte] );
+         strcat(packetBuffer, buffer);
+       }
+       strcat(packetBuffer,(char*)pgm_read_word(&loopPacket3) );
+       for (byte thisByte = 0; thisByte < 6; thisByte++) {
+         sprintf(buffer, "%x", mac[thisByte] );
+         strcat(packetBuffer, buffer);
+       }
+       strcat(packetBuffer,(char*)pgm_read_word(&loopPacket4) );
+       strcat(packetBuffer, "off");
+       strcat(packetBuffer,(char*)pgm_read_word(&loopPacket5) );
+       strcat(packetBuffer, itoa( millis()/1000, buffer, 10) );
+       strcat(packetBuffer,(char*)pgm_read_word(&loopPacket6) );
+
+       Serial.println(packetBuffer);
+       udp.beginPacket(udp.remoteIP(), udp.remotePort());
+       udp.write(packetBuffer);
+       udp.endPacket();
+
+   }
+
+
+  }
+
+  if ( lastButtonState != reading ) {
+     sentPacket = 0;
+  }
+  lastButtonState = reading;
+
+
+    /*
+
+    char buffer[12];
+
+    strcpy(packetBuffer,(char*)pgm_read_word(&loopPacket1) );
+    strcat(packetBuffer, itoa( requestID, buffer, 10) );
+    strcat(packetBuffer,(char*)pgm_read_word(&loopPacket2) );
+    for (byte thisByte = 0; thisByte < 6; thisByte++) {
+      sprintf(buffer, "%x", mac[thisByte] );
+      strcat(packetBuffer, buffer);
+    }
+    strcat(packetBuffer,(char*)pgm_read_word(&loopPacket3) );
+    for (byte thisByte = 0; thisByte < 6; thisByte++) {
+      sprintf(buffer, "%x", mac[thisByte] );
+      strcat(packetBuffer, buffer);
+    }
+    strcat(packetBuffer,(char*)pgm_read_word(&loopPacket4) );
+    strcat(packetBuffer, dtostrf(t,4,2,buffer));
+    strcat(packetBuffer,(char*)pgm_read_word(&loopPacket5) );
+    strcat(packetBuffer, dtostrf(h,4,2,buffer));
+    strcat(packetBuffer,(char*)pgm_read_word(&loopPacket6) );
+    strcat(packetBuffer, itoa( millis()/1000, buffer, 10) );
+    strcat(packetBuffer,(char*)pgm_read_word(&loopPacket7) );
+
+    Serial.println(packetBuffer);
+    udp.beginPacket(udp.remoteIP(), udp.remotePort());
+    udp.write(packetBuffer);
+    udp.endPacket();
+
+    */
+
+
+}
+


add new Arilux example

add new Arilux example

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

--- ha_mqtt_light_arilux/ha_mqtt_light_arilux.ino
+++ ha_mqtt_light_arilux/ha_mqtt_light_arilux.ino
@@ -0,0 +1,236 @@
+#include <ESP8266WiFi.h>
+#include <ArduinoOTA.h>
+#include <PubSubClient.h>   // https://github.com/knolleary/pubsubclient
+#include <ArduinoJson.h>    // https://github.com/bblanchon/ArduinoJson
+#include <WS2812FX.h>       // https://github.com/kitesurfer1404/WS2812FX
+
+#include "config.h"
+
+struct RGBW {
+  uint8_t red;
+  uint8_t green;
+  uint8_t blue;
+  uint8_t white;
+  bool    isWhiteSelected;
+  uint8_t brightness;
+};
+
+WiFiClient    wifiClient;
+PubSubClient  mqttClient(wifiClient);
+WS2812FX      ws2812fx = WS2812FX(1, NULL, NEO_RGBW);
+RGBW          rgbw = {PWM_MIN,PWM_MIN,PWM_MIN,PWM_MIN,false,PWM_MAX};
+
+long lastReconnectAttempt = 0;
+bool newStateToPublish = false;
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+// LIGHT
+///////////////////////////////////////////////////////////////////////////////////////////////
+uint8_t getRedValueFromRGB(uint32_t p_color) {return p_color >> 16;}
+uint8_t getGreenValueFromRGB(uint32_t p_color) {return p_color >> 8;}
+uint8_t getBlueValueFromRGB(uint32_t p_color) {return p_color;}
+
+void customShow(void) {
+  // get the current color
+  uint32 rgb = ws2812fx.getPixelColor(0);
+
+  // retrieve the value for each channel
+  rgbw.red =    getRedValueFromRGB(rgb);
+  rgbw.green =  getGreenValueFromRGB(rgb);
+  rgbw.blue =   getBlueValueFromRGB(rgb);
+
+  // set each channel with the new value
+  analogWrite(RED_PIN,    map(rgbw.red,   PWM_MIN, PWM_MAX, PWM_MIN, rgbw.brightness));
+  analogWrite(GREEN_PIN,  map(rgbw.green, PWM_MIN, PWM_MAX, PWM_MIN, rgbw.brightness));
+  analogWrite(BLUE_PIN,   map(rgbw.blue,  PWM_MIN, PWM_MAX, PWM_MIN, rgbw.brightness));
+  analogWrite(WHITE_PIN,  map(rgbw.white, PWM_MIN, PWM_MAX, PWM_MIN, rgbw.brightness));
+}
+
+void setupLight(void) {
+  // set the pins as output
+  pinMode(RED_PIN,    OUTPUT);
+  pinMode(GREEN_PIN,  OUTPUT);
+  pinMode(BLUE_PIN,   OUTPUT);
+  pinMode(WHITE_PIN,  OUTPUT);
+
+  analogWriteFreq(PWM_FREQUENCY);
+  analogWriteRange(PWM_MAX);
+
+  ws2812fx.init();
+  ws2812fx.setColor(GREEN);
+  ws2812fx.stop();
+  ws2812fx.setCustomShow(customShow);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+// MQTT
+///////////////////////////////////////////////////////////////////////////////////////////////
+
+void callback(char* p_topic, byte* p_payload, unsigned int p_length) {
+  String topic(p_topic);
+
+  if (topic.equals(MQTT_CMD_TOPIC)) {
+    DynamicJsonBuffer dynamicJsonBuffer;
+    JsonObject& root = dynamicJsonBuffer.parseObject(p_payload);
+
+    // check if the payload contains a new state
+    if (root.containsKey("state")) {
+      if (strcmp(root["state"], MQTT_STATE_ON_PAYLOAD) == 0) {
+        if (ws2812fx.isRunning() == false) {
+          if (rgbw.isWhiteSelected == true) {
+            rgbw.white = PWM_MAX;
+          }
+
+          ws2812fx.start();
+          newStateToPublish = true;
+        }
+      } else if (strcmp(root["state"], MQTT_STATE_OFF_PAYLOAD) == 0) {
+        if (ws2812fx.isRunning() == true) {
+          if (rgbw.isWhiteSelected == true) {
+            rgbw.white = PWM_MIN;
+          }
+
+          ws2812fx.stop();
+          newStateToPublish = true;
+        }
+      }
+    }
+
+    // check if the payload contains a new color value
+    if (root.containsKey("color")) {
+      uint8_t red = root["color"]["r"];
+      uint8_t green = root["color"]["g"];
+      uint8_t blue = root["color"]["b"];
+
+      if ((red >= PWM_MIN || red <= PWM_MAX) && (green >= PWM_MIN || green <= PWM_MAX) && (blue >= PWM_MIN || blue <= PWM_MAX)) {
+        rgbw.white = PWM_MIN;
+        rgbw.isWhiteSelected = false;
+        ws2812fx.setColor(red, green, blue);
+        newStateToPublish = true;
+      }
+    }
+
+    // check if the payload contains a new brightness value
+    if (root.containsKey("brightness")) {
+      uint8_t brightness = root["brightness"];
+
+      if (brightness >= PWM_MIN || brightness <= PWM_MAX) {
+        rgbw.brightness = brightness;
+        newStateToPublish = true;
+      }
+    }
+
+    // check if the payload contains a new white value
+    if (root.containsKey("white_value")) {
+      uint8_t white_value = root["white_value"];
+
+      if (white_value >= PWM_MIN || white_value <= PWM_MAX) {
+        rgbw.white = PWM_MAX;
+        rgbw.brightness = white_value;
+        rgbw.isWhiteSelected = true;
+        ws2812fx.setColor(0, 0, 0);
+        newStateToPublish = true;
+      }
+    }
+  }
+}
+
+void sendState(void) {
+  DynamicJsonBuffer dynamicJsonBuffer;
+  JsonObject& root = dynamicJsonBuffer.createObject();
+  root["state"] = ws2812fx.isRunning() ? MQTT_STATE_ON_PAYLOAD : MQTT_STATE_OFF_PAYLOAD;
+  root["brightness"] = rgbw.brightness;
+  JsonObject& color = root.createNestedObject("color");
+  color["r"] = rgbw.red;
+  color["g"] = rgbw.green;
+  color["b"] = rgbw.blue;
+  root["white_value"] = rgbw.white == 0 ? 0 : rgbw.brightness;
+
+  char tmp[128] = {0};
+  root.printTo(tmp);
+  mqttClient.publish(MQTT_STATE_TOPIC, tmp);
+}
+
+bool reconnect() {
+  if (mqttClient.connect(DEVICE_NAME, MQTT_USERNAME, MQTT_PASSWORD, MQTT_AVAILABILITY_TOPIC, 0, 1, "offline")) {
+    mqttClient.subscribe(MQTT_CMD_TOPIC);
+    mqttClient.publish(MQTT_AVAILABILITY_TOPIC, "online");
+
+    sendState();
+  }
+  return mqttClient.connected();
+}
+
+void setupMQTT(void) {
+  mqttClient.setServer(MQTT_SERVER, MQTT_SERVER_PORT);
+  mqttClient.setCallback(callback);
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+// WIFI
+///////////////////////////////////////////////////////////////////////////////////////////////
+
+void setupWiFi(void) {
+  Serial.print("Connecting to ");
+  Serial.println(WIFI_SSID);
+
+  WiFi.mode(WIFI_STA);
+  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
+
+  while (WiFi.status() != WL_CONNECTED) {
+    delay(500);
+    Serial.print(".");
+  }
+
+  randomSeed(micros());
+
+  Serial.println("");
+  Serial.println("WiFi connected");
+  Serial.println("IP address: ");
+  Serial.println(WiFi.localIP());
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+// SETUP and LOOP
+///////////////////////////////////////////////////////////////////////////////////////////////
+
+void setup() {
+  Serial.begin(115200);
+  delay(10);
+
+  setupWiFi();
+
+  setupMQTT();
+
+  setupLight();
+
+  ArduinoOTA.begin();
+}
+
+
+void loop() {
+  if (!mqttClient.connected()) {
+    long now = millis();
+    if (now - lastReconnectAttempt > 5000) {
+      lastReconnectAttempt = now;
+      if (reconnect())
+        lastReconnectAttempt = 0;
+    }
+  } else {
+    mqttClient.loop();
+  }
+
+  ws2812fx.service();
+
+  yield();
+
+  if (newStateToPublish) {
+    newStateToPublish = false;
+    sendState();
+  }
+
+  yield();
+
+  ArduinoOTA.handle();
+}


Add media keys

Add media keys

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/mvines/futboard.git/'


just another git test

just another git test

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/mule-ear/shiny-spice.git/'