Added FW for Drone for debugging

Added FW for Drone for debugging

Added debug FW for Drone that leaves out autopilot to allow testing of
services.

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

--- xAPI/XAPI_CLASSES/XAPI_DRONE_DEBUG_COMMS/XAPI_DRONE_DEBUG_COMMS.ino
+++ xAPI/XAPI_CLASSES/XAPI_DRONE_DEBUG_COMMS/XAPI_DRONE_DEBUG_COMMS.ino
@@ -0,0 +1,94 @@
+#include <Serial_service.h>
+#include <LiquidCrystal.h>
+#include <LCD_service.h>
+#include <Xapi.h>
+#include <Subscriptions.h>
+#include <Universal.h>
+#include <Util.h>
+#include <Single_buff.h>
+#include <Land_service.h>
+#include <Takeoff_service.h>
+#include <DoMove_service.h>
+#include <Arm_service.h>
+#include <Heartbeat_service.h>
+
+//0013a200
+//40a1446d
+
+//***********************************************
+//***********************************************
+Xapi xapi = Xapi(Serial);
+//Serial_service serial_service = Serial_service(Serial1, xapi);
+LCD_service lcd_service (xapi);
+//************************************************
+// The next services pertain to drone instructions
+//************************************************
+Takeoff_service takeoff_service(xapi, lcd_service);
+Land_service land_service(xapi, lcd_service);
+DoMove_service doMove_service(xapi, lcd_service);
+Arm_service arm_service(xapi, lcd_service);
+//Heartbeat_service heartbeat_service(xapi, lcd_service);
+//Serial_service serial_service = Serial_service(Serial1, xapi, lcd_service);
+uint8_t msg1[] =   "I FEEL GREAT";
+uint8_t msg2[] =   "COMMODORE 64";
+uint8_t _clear[] = "                ";
+
+
+//***********************************************
+//***********************************************
+void setup()
+{
+ Serial.begin(MISC_PC_SPEED);
+ //Serial1.begin(MISC_PC_SPEED);
+
+
+
+}
+
+//***********************************************
+//***********************************************
+void loop()
+{
+  //system_active();
+  //process_buttons();
+  xapi.xapi_latch();
+  lcd_service.lcd_service_latch();
+  takeoff_service.takeoff_service_latch();
+  land_service.land_service_latch();
+  doMove_service.DoMove_service_latch();
+  arm_service.arm_service_latch();
+  //heartbeat_service.heartbeat_service_latch();
+  //serial_service.serial_service_latch();
+
+  //delay(4000);
+}
+
+
+//***********************************************
+// Old function. Not needed
+//***********************************************
+void system_active()
+{
+    static uint16_t cnt = 0;
+    static uint8_t row = 0;
+
+    cnt++;
+
+    if ( (cnt%2500) == 0)
+   {
+     // turn off both stars
+     lcd_service.lcd_print(15, 0, (const char*)" ");
+     lcd_service.lcd_print(15, 1, (const char*)" ");
+
+     row++;
+     // turn on new row
+     lcd_service.lcd_print(15, row%2, (const char*)"*");
+
+   }
+
+}
+
+
+
+
+


damn damn damn buggydibugg

damn damn damn buggydibugg

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/'


Move Arduino sketch to correct place

Move Arduino sketch to correct place

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/rwood-moz/iot-hacking.git/'


Updated test DS18B20 test sketch for new API and added some timings.

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/Denzo77/OTRadioLink.git/'


Added DmxDueTest.cpp

Added DmxDueTest.cpp

Added a quick smoke.test to see if we have dmx working on due.

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

--- TestPrograms/DmxDueTest/DmxDueTest.ino
+++ TestPrograms/DmxDueTest/DmxDueTest.ino
@@ -0,0 +1,73 @@
+/* TODO: add header */
+
+#include <DmxSimple.h>
+
+//======Compiler Definitions
+#define NUMMEGABARS 1 //the number of Mega Bars connected to the DMX bus. 4-ch mode assumed. Mega bars must be addressed as 001, 005, 009, etc
+
+//======Program Variables
+int MegaBarRed[NUMMEGABARS];
+int MegaBarGreen[NUMMEGABARS];
+int MegaBarBlue[NUMMEGABARS];
+int MegaBarBrightness[NUMMEGABARS];
+
+//======Function Definitions
+void update_megabars (int offset)
+{
+  int j;
+  offset = offset % NUMMEGABARS;
+  for (int i=0; (i<NUMMEGABARS); i++)
+  {
+    j = ((i + offset) % NUMMEGABARS);
+    DmxSimple.write( ((4*j)+1), MegaBarRed[i]);
+    DmxSimple.write( ((4*j)+2), MegaBarGreen[i]);
+    DmxSimple.write( ((4*j)+3), MegaBarBlue[i]);
+    DmxSimple.write( ((4*j)+4), MegaBarBrightness[i]);
+  }
+}
+
+void clear_megabars ()
+{
+  // initialize all the outputs to 0:
+  for (int thisMegaBar = 0; thisMegaBar < NUMMEGABARS; thisMegaBar++)
+  {
+    MegaBarRed[thisMegaBar] = 0;
+    MegaBarGreen[thisMegaBar] = 0;
+    MegaBarBlue[thisMegaBar] = 0;
+  }
+
+  update_megabars ( 0 );
+}
+
+volatile uint32_t *REG;
+uint32_t MASK;
+
+void setup() {
+  Serial.begin(9600);
+  pinMode(LED_BUILTIN, OUTPUT);
+  digitalWrite(LED_BUILTIN, LOW);
+  Serial.print( "setup\n" );
+  DmxSimple.usePin(3);
+}
+
+void loop() {
+  Serial.print( "loop\n" );
+  static bool red = true;
+  clear_megabars();
+  for (int i=0; (i<NUMMEGABARS); i++) {
+    if ( red ) {
+       MegaBarRed[i] = 255;
+    } else {
+       MegaBarGreen[i] = 255;
+    }
+    MegaBarBrightness[i] = 255;
+  }
+  update_megabars(0);
+  if ( red ) {
+     digitalWrite(LED_BUILTIN, HIGH);
+  } else {
+     digitalWrite(LED_BUILTIN, LOW);
+  }
+  red = !red;
+  delay( 500 );
+}


fix some comments

fix some comments

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


First example to build

First example to build

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

--- examples/power_test1/power_test1.ino
+++ examples/power_test1/power_test1.ino
@@ -0,0 +1,46 @@
+#include <PowerFunctions.h>
+
+/***
+ * This demo uses an arduino to drive a
+ * LEGO RC Tracked Racer 42065
+ * To drive it you must give some inverted command in sync.
+ * We go forward a bit then backward
+ */
+
+PowerFunctions pf(12, 0);
+
+void setup() {
+  // put your setup code here, to run once:
+}
+
+void loop() {
+  // put your main code here, to run repeatedly:
+  goForward(1500);
+  goBackward(500);
+  while(true) { delay(1000); }
+}
+
+//TODO: Add blinking led (13) in the pf library as optional setup
+void goForward(uint16_t time){
+  pf.combo_pwm(PWM_FWD2, PWM_REV2);
+  delay(time);
+  pf.combo_pwm(PWM_BRK,PWM_BRK);
+  pf.combo_pwm(PWM_FLT,PWM_FLT);
+}
+
+
+void goBackward(uint16_t time){
+  pf.combo_pwm(PWM_REV2, PWM_FWD2);
+  delay(time);
+  pf.combo_pwm(PWM_BRK,PWM_BRK);
+  pf.combo_pwm(PWM_FLT,PWM_FLT);
+}
+
+
+void step(uint8_t output, uint8_t pwm,  uint16_t time) {
+  pf.single_pwm(output, pwm);
+  delay(time);
+  pf.single_pwm(output, PWM_BRK);
+  delay(30);
+  pf.single_pwm(output, PWM_FLT);
+}


we cannot react to errors anyway …

we cannot react to errors anyway …


zmiany w komentarzu

zmiany w komentarzu

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/werar/iothome.git/'


Taken code from http://www.instructables.com/id/Arduino-Bike-Speedometer/?ALLSTEPS as a base of the hamsterometer

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

--- speedo/speedo.ino
+++ speedo/speedo.ino
@@ -0,0 +1,100 @@
+//arduino bike speedometer w serial.print()
+//by Amanda Ghassaei 2012
+//http://www.instructables.com/id/Arduino-Bike-Speedometer/
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+*/
+
+//calculations
+//tire radius ~ 13.5 inches
+//circumference = pi*2*r =~85 inches
+//max speed of 35mph =~ 616inches/second
+//max rps =~7.25
+
+#define reed A0//pin connected to read switch
+
+//storage variables
+int reedVal;
+long timer;// time between one full rotation (in ms)
+float mph;
+float radius = 13.5;// tire radius (in inches)
+float circumference;
+
+int maxReedCounter = 100;//min time (in ms) of one rotation (for debouncing)
+int reedCounter;
+
+
+void setup(){
+
+  reedCounter = maxReedCounter;
+  circumference = 2*3.14*radius;
+  pinMode(reed, INPUT);
+
+  // TIMER SETUP- the timer interrupt allows precise timed measurements of the reed switch
+  //for more info about configuration of arduino timers see http://arduino.cc/playground/Code/Timer1
+  cli();//stop interrupts
+
+  //set timer1 interrupt at 1kHz
+  TCCR1A = 0;// set entire TCCR1A register to 0
+  TCCR1B = 0;// same for TCCR1B
+  TCNT1  = 0;
+  // set timer count for 1khz increments
+  OCR1A = 1999;// = (1/1000) / ((1/(16*10^6))*8) - 1
+  // turn on CTC mode
+  TCCR1B |= (1 << WGM12);
+  // Set CS11 bit for 8 prescaler
+  TCCR1B |= (1 << CS11);
+  // enable timer compare interrupt
+  TIMSK1 |= (1 << OCIE1A);
+
+  sei();//allow interrupts
+  //END TIMER SETUP
+
+  Serial.begin(9600);
+}
+
+
+ISR(TIMER1_COMPA_vect) {//Interrupt at freq of 1kHz to measure reed switch
+  reedVal = digitalRead(reed);//get val of A0
+  if (reedVal){//if reed switch is closed
+    if (reedCounter == 0){//min time between pulses has passed
+      mph = (56.8*float(circumference))/float(timer);//calculate miles per hour
+      timer = 0;//reset timer
+      reedCounter = maxReedCounter;//reset reedCounter
+    }
+    else{
+      if (reedCounter > 0){//don't let reedCounter go negative
+        reedCounter -= 1;//decrement reedCounter
+      }
+    }
+  }
+  else{//if reed switch is open
+    if (reedCounter > 0){//don't let reedCounter go negative
+      reedCounter -= 1;//decrement reedCounter
+    }
+  }
+  if (timer > 2000){
+    mph = 0;//if no new pulses from reed switch- tire is still, set mph to 0
+  }
+  else{
+    timer += 1;//increment timer
+  }
+}
+
+void displayMPH(){
+  Serial.println(mph);
+}
+
+void loop(){
+  //print mph once a second
+  displayMPH();
+  delay(1000);
+}
+
+
+


Added porch lighting code. Going to use this as base for all other devices after vetting.

Signed-off-by: Braden Licastro <79d6010d7e15bbb3aa5be04af4e1cdfb0e9c5bfd@live.com>

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

--- sketches/PorchLights/PorchLights.ino
+++ sketches/PorchLights/PorchLights.ino
@@ -0,0 +1,401 @@
+/*
+ * Configuration for Home Assistant:
+ *   light:
+ *   # Exterior:
+ *   - platform: mqtt
+ *     name: 'Porch Ambiance Lights'
+ *     state_topic: 'exterior/porchlights/status'
+ *     command_topic: 'exterior/porchlights/switch'
+ *     optimistic: false
+ */
+
+#include <ESP8266WiFi.h>    // https://github.com/esp8266/Arduino (GNUv2.1 licence)
+#include <PubSubClient.h>   // https://github.com/knolleary/pubsubclient (no licence)
+#include <ArduinoOTA.h>
+
+
+#define DEBUG
+#define MQTT_VERSION MQTT_VERSION_3_1_1
+
+// ESP8266: SSID and password of desired network
+const char*       AP_SSID           = "<REDACTED>";
+const char*       AP_PASSWORD       = "<REDACTED>";
+
+// Device network details: IP address, IP gateway, subnet, dns.
+// NOTE: WiFi does not support configurable MAC
+const IPAddress   IP                (<REDACTED>);
+const IPAddress   IP_GATEWAY        (<REDACTED>);
+const IPAddress   IP_SUBNET         (<REDACTED>);
+const IPAddress   IP_DNS            (<REDACTED>);
+
+// MQTT: client ID, broker IP, port, username & password
+const char*       MQTT_CLIENT_ID    = "<REDACTED>";
+const char*       MQTT_SERVER_IP    = "<REDACTED>";
+const uint16_t    MQTT_SERVER_PORT  = 1883;
+const char*       MQTT_USERNAME     = "<REDACTED>";
+const char*       MQTT_PASSWORD     = "<REDACTED>";
+
+// OTA: hostname & password
+const char*       OTA_HOSTNAME      = MQTT_CLIENT_ID;
+const char*       OTA_PASSWORD      = "<REDACTED>";
+const uint16_t    OTA_PORT          = 8266;
+
+// MQTT: topics
+// Exterior: Porch Ambiance Lights
+const char*       TOPIC_RELAY_STATUS             = "exterior/porchlights/status";
+const char*       TOPIC_RELAY_COMMAND            = "exterior/porchlights/switch";
+
+// MQTT: Expected Payloads
+// Lamps : "ON"/"OFF"
+const char*       PAYLOAD_ON        = "ON";
+const char*       PAYLOAD_OFF       = "OFF";
+
+// Track current status of the devices
+boolean           g_relay_status                 = false;
+boolean           g_bypass_activated             = false;
+boolean           g_bypass_type                  = false; // True = switch; False = button
+
+// Buffer configuration used to send/receive data with MQTT
+const uint8_t     MSG_BUFFER_SIZE   = 20;
+char              g_msg_buffer[MSG_BUFFER_SIZE];
+
+// Pin configuration
+const uint8_t     RELAY_PIN         = D1;
+const uint8_t     BYPASS_PIN        = D2;
+
+// WiFi and MQTT client object initialization
+WiFiClient        g_wifiClient;
+PubSubClient      g_mqttClient(g_wifiClient);
+
+
+//############################################################################
+//
+//                          CONTROL AND STATUS
+//
+//############################################################################
+
+/*
+ * Publishes the status of the relay
+ *   INPUT:  NA
+ *   RETURN: NA
+ */
+void publishRelayStatus() {
+  if (g_relay_status) {
+    if (g_mqttClient.publish(TOPIC_RELAY_STATUS, PAYLOAD_ON, true)) {
+      #ifdef DEBUG
+        Serial.print(F("INFO:  MQTT message publish succeeded.\n       Topic: "));
+        Serial.println(TOPIC_RELAY_STATUS);
+        Serial.print(F("       Payload: "));
+        Serial.println(PAYLOAD_ON);
+      #endif
+    } else {
+      #ifdef DEBUG
+            Serial.println(F("ERROR: MQTT message publish failed, either connection lost, or message too large"));
+      #endif
+    }
+  } else {
+    if (g_mqttClient.publish(TOPIC_RELAY_STATUS, PAYLOAD_OFF, true)) {
+      #ifdef DEBUG
+        Serial.print(F("INFO:  MQTT message publish succeeded.\n       Topic: "));
+        Serial.println(TOPIC_RELAY_STATUS);
+        Serial.print(F("       Payload: "));
+        Serial.println(PAYLOAD_OFF);
+      #endif
+    } else {
+      #ifdef DEBUG
+        Serial.println(F("ERROR: MQTT message publish failed, either connection lost, or message too large"));
+      #endif
+    }
+  }
+}
+
+/*
+ * Switches the state of the relay
+ *   INPUT:  NA
+ *   RETURN: NA
+ */
+void setRelayStatus() {
+  if (g_relay_status) {
+    digitalWrite(RELAY_PIN, HIGH);
+  } else {
+    digitalWrite(RELAY_PIN, LOW);
+  }
+}
+
+
+//############################################################################
+//
+//                          WIFI CONFIGURATION
+//
+//############################################################################
+
+/*
+ * Set up the connection to the Access Point
+ *   INPUT:  NA
+ *   RETURN: NA
+*/
+void setupWifi() {
+  delay(10);
+  WiFi.mode(WIFI_STA); // Station mode. This is a client.
+  WiFi.begin(AP_SSID, AP_PASSWORD);
+  WiFi.config(IP, IP_GATEWAY, IP_SUBNET, IP_DNS); // MAC address configuration only supported for ethernet devices.
+
+  // Hold until wireless connection is up and running.
+  while (WiFi.status() != WL_CONNECTED) {
+    delay(500);
+  }
+
+  #ifdef DEBUG
+    Serial.println(F("INFO:  Client is now connected to the wireless network!"));
+    Serial.print(F("       IP address:  "));
+    Serial.println(WiFi.localIP());
+    Serial.print(F("       MAC Address: "));
+    Serial.println(WiFi.macAddress());
+  #endif
+}
+
+
+//############################################################################
+//
+//                                MQTT
+//
+//############################################################################
+
+/*
+ * Function called when a MQTT message arrives
+ *   INPUT:  Charanter array 'p_topic' is the topic of the MQTT message
+ *           Byte array 'p_payload' is the payload of the MQTT message
+ *           Integer 'p_length' is the expectedlength of the payload
+ *   RETURN: NA
+ */
+void callback(char* p_topic, byte* p_payload, unsigned int p_length) {
+  #ifdef DEBUG
+    Serial.println(F("INFO:  A new MQTT message has arrived"));
+    Serial.print(F("       Topic:   "));
+    Serial.println(p_topic);
+    Serial.print(F("       Payload: "));
+    for (int i = 0; i < p_length; i++) {
+      Serial.print((char)p_payload[i]);
+    }
+    Serial.println();
+    Serial.print(F("       Length:  "));
+    Serial.println(p_length);
+  #endif
+
+  // Act on the contents of the payload.
+  if (String(TOPIC_RELAY_COMMAND).equals(p_topic)) {
+    // Type juggle the payload from char array to string.
+    String payload;
+    for (uint8_t i = 0; i < p_length; i++) {
+      payload.concat((char)p_payload[i]);
+    }
+
+    // Perform payload action IF manual bypass isn't triggered for the given event.
+    if (payload.equals(String(PAYLOAD_ON)) && !g_bypass_hold) {
+      g_relay_status = true;
+      setRelayStatus();
+      publishRelayStatus();
+    } else if (payload.equals(String(PAYLOAD_OFF)) && !g_bypass_hold) {
+      g_relay_status = false;
+      setRelayStatus();
+      publishRelayStatus();
+    } else if (g_bypass_hold) {
+      #ifdef DEBUG
+        Serial.println(F("ALERT: Manual bypass for this action is held. Skipping this action."));
+      #endif
+    } else {
+      #ifdef DEBUG
+        Serial.println(F("ERROR: The payload of the MQTT message is not valid"));
+      #endif
+    }
+  } else {
+    #ifdef DEBUG
+      Serial.println(F("INFO:  The received MQTT message was for a topic we did not subscribe to and was not used."));
+    #endif
+  }
+}
+
+/*
+ * Function called to reconnect the client to the MQTT broker and publish/subscribe to/from some MQTT topics
+ *   INPUT:  NA
+ *   Return: NA
+ */
+void reconnect() {
+  while (!g_mqttClient.connected()) {
+    if (g_mqttClient.connect(MQTT_CLIENT_ID, MQTT_USERNAME, MQTT_PASSWORD)) {
+      #ifdef DEBUG
+        Serial.println(F("INFO:  The client is successfully connected to the MQTT broker"));
+      #endif
+
+      // Subscribe to the command topic.
+      if (g_mqttClient.subscribe(TOPIC_RELAY_COMMAND)) {
+        #ifdef DEBUG
+          Serial.print(F("INFO:  Sending the MQTT subscribe succeeded.\n       Topic: "));
+          Serial.println(TOPIC_RELAY_COMMAND);
+        #endif
+      } else {
+        #ifdef DEBUG
+          Serial.print(F("ERROR: Sending the MQTT subscribe failed.\n       Topic: "));
+          Serial.println(TOPIC_RELAY_COMMAND);
+        #endif
+      }
+
+      // Set the relay to match the value that we have stored.
+      setRelayStatus();
+
+      // Publish the status of the relay so bring everything back into sync.
+      publishRelayStatus();
+    } else {
+      #ifdef DEBUG
+        Serial.print(F("ERROR: The connection failed with the MQTT broker.\n       Status: "));
+        Serial.println(g_mqttClient.state());
+      #endif
+
+      // Wait before retrying instead of clobbering the server.
+      delay(2500);
+    }
+  }
+}
+
+
+//############################################################################
+//
+//                      Bypass monitoring and actions
+//
+//############################################################################
+
+/*
+ * Interrupt received, bypass flag for loop action item
+ *   INPUT:  NA
+ *   RETURN: NA
+ */
+void g_bypass_activated_interrupt() {
+  #ifdef DEBUG
+    Serial.println("INFO:  Bypass interrupt activated.");
+  #endif
+
+  // Set the interrupt
+  g_bypass_activated = true;
+}
+
+/*
+ * Detected bypass input request, trigger bypass action
+ *  INPUT:  NA
+ *  RETURN: NA
+ */
+void g_bypass_activated_actionable(){
+    if (g_relay_status == false && digitalRead(BYPASS_PIN) == 1) {
+      #ifdef DEBUG
+        Serial.println("INFO:  Bypass state switched from OFF to ON.");
+      #endif
+      g_relay_status = true;
+      setRelayStatus();
+      publishRelayStatus();
+    } else if (g_relay_status == true && digitalRead(BYPASS_PIN) == 0) {
+      #ifdef DEBUG
+        Serial.println("INFO:  Bypass state switched from ON to OFF");
+      #endif
+      g_relay_status = false;
+      setRelayStatus();
+      publishRelayStatus();
+    } else {
+      #ifdef DEBUG
+        Serial.println("INFO:  Requested bypass state matches current state.");
+      #endif
+    }
+}
+
+
+//############################################################################
+//
+//                            SETUP and LOOP
+//
+//############################################################################
+
+/*
+ * System initialization
+ */
+void setup() {
+  #ifdef DEBUG
+    Serial.begin(115200);
+    Serial.println(F("\nINFO:  Wireless network initializing..."));
+  #endif
+
+  // Connect to network.
+  setupWifi();
+
+  // Set IO pins for use.
+  pinMode(RELAY_PIN, OUTPUT);
+  pinMode(BYPASS_PIN, INPUT);
+
+  // Attach interrupt to avoid missing input.
+  if(g_bypass_type) {
+    // Switch
+    //attachInterrupt(BYPASS_PIN, g_bypass_activated_interrupt, <FILL_IN>) FILL IN THE STATE CHANGE DIRECTION BEFORE ENABLING
+  } else {
+    // Button
+    attachInterrupt(BYPASS_PIN, g_bypass_activated_interrupt, RISING);
+  }
+
+  // Configure and connect to MQTT broker.
+  g_mqttClient.setServer(MQTT_SERVER_IP, MQTT_SERVER_PORT);
+  g_mqttClient.setCallback(callback);
+
+  // Configure and initialize OTA listener.
+  ArduinoOTA.setHostname(OTA_HOSTNAME);
+  ArduinoOTA.setPassword(OTA_PASSWORD);
+  ArduinoOTA.setPort(OTA_PORT);
+
+  #ifdef DEBUG
+    ArduinoOTA.onStart([]() {
+      Serial.println(F("INFO:  OTA session started."));
+    });
+    ArduinoOTA.onEnd([]() {
+      Serial.println(F("INFO:  OTA session ended."));
+    });
+    ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
+      Serial.printf("INFO:  OTA rogress is %u%%\r", (progress / (total / 100)));
+    });
+    ArduinoOTA.onError([](ota_error_t error) {
+      Serial.printf("ERROR: [%u] ", error);
+      if (error == OTA_AUTH_ERROR) {
+        Serial.println("Auth Failed");
+      } else if (error == OTA_BEGIN_ERROR) {
+        Serial.println("Begin Failed");
+      } else if (error == OTA_CONNECT_ERROR) {
+        Serial.println("Connect Failed");
+      } else if (error == OTA_RECEIVE_ERROR) {
+        Serial.println("Receive Failed");
+      } else if (error == OTA_END_ERROR) {
+        Serial.println("End Failed");
+      }
+    });
+  #endif
+
+  ArduinoOTA.begin();
+}
+
+/*
+ * System run
+ */
+void loop() {
+  // Ensure connection to MQTT broker is active, if not fix it.
+  if (!g_mqttClient.connected()) {
+    reconnect();
+  }
+
+  // Listen for messages from the broker.
+  g_mqttClient.loop();
+
+  // Listen for OTA messages
+  ArduinoOTA.handle();
+
+  // Check interrupt to see if physical state request set.
+  if (g_bypass_activated) {
+    g_bypass_activated_actionable();
+    g_bypass_activated = false;
+  }
+
+  // Delay required if debug mode is disabled due to delay of mechanical relays.
+  yield();
+}


this is the official SPI …

this is the official SPI …


starting with the DMXSimple example

starting with the DMXSimple example

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

--- nightlight_ard/nightlight_ard.ino
+++ nightlight_ard/nightlight_ard.ino
@@ -0,0 +1,39 @@
+/* Welcome to DmxSimple. This library allows you to control DMX stage and
+** architectural lighting and visual effects easily from Arduino. DmxSimple
+** is compatible with the Tinker.it! DMX shield and all known DIY Arduino
+** DMX control circuits.
+**
+** DmxSimple is available from: http://code.google.com/p/tinkerit/
+** Help and support: http://groups.google.com/group/dmxsimple       */
+
+/* To use DmxSimple, you will need the following line. Arduino will
+** auto-insert it if you select Sketch > Import Library > DmxSimple. */
+a
+#include <DmxSimple.h>
+
+void setup() {
+  /* The most common pin for DMX output is pin 3, which DmxSimple
+  ** uses by default. If you need to change that, do it here. */
+  DmxSimple.usePin(3);
+
+  /* DMX devices typically need to receive a complete set of channels
+  ** even if you only need to adjust the first channel. You can
+  ** easily change the number of channels sent here. If you don't
+  ** do this, DmxSimple will set the maximum channel number to the
+  ** highest channel you DmxSimple.write() to. */
+  DmxSimple.maxChannel(4);
+}
+
+void loop() {
+  int brightness;
+  /* Simple loop to ramp up brightness */
+  for (brightness = 0; brightness <= 255; brightness++) {
+
+    /* Update DMX channel 1 to new brightness */
+    DmxSimple.write(1, brightness);
+
+    /* Small delay to slow down the ramping */
+    delay(10);
+  }
+
+}


ok setting the clock speed does some magic


add StandardFirmata.ino

add StandardFirmata.ino

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

--- StandardFirmata.ino
+++ StandardFirmata.ino
@@ -0,0 +1,721 @@
+/*
+  Firmata is a generic protocol for communicating with microcontrollers
+  from software on a host computer. It is intended to work with
+  any host computer software package.
+
+  To download a host software package, please clink on the following link
+  to open the download page in your default browser.
+
+  https://github.com/firmata/arduino#firmata-client-libraries
+
+  Copyright (C) 2006-2008 Hans-Christoph Steiner.  All rights reserved.
+  Copyright (C) 2010-2011 Paul Stoffregen.  All rights reserved.
+  Copyright (C) 2009 Shigeru Kobayashi.  All rights reserved.
+  Copyright (C) 2009-2015 Jeff Hoefs.  All rights reserved.
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  See file LICENSE.txt for further informations on licensing terms.
+
+  Last updated by Jeff Hoefs: April 11, 2015
+*/
+
+#include <Servo.h>
+#include <Wire.h>
+#include <Firmata.h>
+
+#define I2C_WRITE                   B00000000
+#define I2C_READ                    B00001000
+#define I2C_READ_CONTINUOUSLY       B00010000
+#define I2C_STOP_READING            B00011000
+#define I2C_READ_WRITE_MODE_MASK    B00011000
+#define I2C_10BIT_ADDRESS_MODE_MASK B00100000
+#define MAX_QUERIES                 8
+#define REGISTER_NOT_SPECIFIED      -1
+
+// the minimum interval for sampling analog input
+#define MINIMUM_SAMPLING_INTERVAL 10
+
+
+/*==============================================================================
+ * GLOBAL VARIABLES
+ *============================================================================*/
+
+/* analog inputs */
+int analogInputsToReport = 0; // bitwise array to store pin reporting
+
+/* digital input ports */
+byte reportPINs[TOTAL_PORTS];       // 1 = report this port, 0 = silence
+byte previousPINs[TOTAL_PORTS];     // previous 8 bits sent
+
+/* pins configuration */
+byte pinConfig[TOTAL_PINS];         // configuration of every pin
+byte portConfigInputs[TOTAL_PORTS]; // each bit: 1 = pin in INPUT, 0 = anything else
+int pinState[TOTAL_PINS];           // any value that has been written
+
+/* timer variables */
+unsigned long currentMillis;        // store the current value from millis()
+unsigned long previousMillis;       // for comparison with currentMillis
+unsigned int samplingInterval = 19; // how often to run the main loop (in ms)
+
+/* i2c data */
+struct i2c_device_info {
+  byte addr;
+  int reg;
+  byte bytes;
+};
+
+/* for i2c read continuous more */
+i2c_device_info query[MAX_QUERIES];
+
+byte i2cRxData[32];
+boolean isI2CEnabled = false;
+signed char queryIndex = -1;
+// default delay time between i2c read request and Wire.requestFrom()
+unsigned int i2cReadDelayTime = 0;
+
+Servo servos[MAX_SERVOS];
+byte servoPinMap[TOTAL_PINS];
+byte detachedServos[MAX_SERVOS];
+byte detachedServoCount = 0;
+byte servoCount = 0;
+
+boolean isResetting = false;
+
+/* utility functions */
+void wireWrite(byte data)
+{
+#if ARDUINO >= 100
+  Wire.write((byte)data);
+#else
+  Wire.send(data);
+#endif
+}
+
+byte wireRead(void)
+{
+#if ARDUINO >= 100
+  return Wire.read();
+#else
+  return Wire.receive();
+#endif
+}
+
+/*==============================================================================
+ * FUNCTIONS
+ *============================================================================*/
+
+void attachServo(byte pin, int minPulse, int maxPulse)
+{
+  if (servoCount < MAX_SERVOS) {
+    // reuse indexes of detached servos until all have been reallocated
+    if (detachedServoCount > 0) {
+      servoPinMap[pin] = detachedServos[detachedServoCount - 1];
+      if (detachedServoCount > 0) detachedServoCount--;
+    } else {
+      servoPinMap[pin] = servoCount;
+      servoCount++;
+    }
+    if (minPulse > 0 && maxPulse > 0) {
+      servos[servoPinMap[pin]].attach(PIN_TO_DIGITAL(pin), minPulse, maxPulse);
+    } else {
+      servos[servoPinMap[pin]].attach(PIN_TO_DIGITAL(pin));
+    }
+  } else {
+    Firmata.sendString("Max servos attached");
+  }
+}
+
+void detachServo(byte pin)
+{
+  servos[servoPinMap[pin]].detach();
+  // if we're detaching the last servo, decrement the count
+  // otherwise store the index of the detached servo
+  if (servoPinMap[pin] == servoCount && servoCount > 0) {
+    servoCount--;
+  } else if (servoCount > 0) {
+    // keep track of detached servos because we want to reuse their indexes
+    // before incrementing the count of attached servos
+    detachedServoCount++;
+    detachedServos[detachedServoCount - 1] = servoPinMap[pin];
+  }
+
+  servoPinMap[pin] = 255;
+}
+
+void readAndReportData(byte address, int theRegister, byte numBytes) {
+  // allow I2C requests that don't require a register read
+  // for example, some devices using an interrupt pin to signify new data available
+  // do not always require the register read so upon interrupt you call Wire.requestFrom()
+  if (theRegister != REGISTER_NOT_SPECIFIED) {
+    Wire.beginTransmission(address);
+    wireWrite((byte)theRegister);
+    Wire.endTransmission();
+    // do not set a value of 0
+    if (i2cReadDelayTime > 0) {
+      // delay is necessary for some devices such as WiiNunchuck
+      delayMicroseconds(i2cReadDelayTime);
+    }
+  } else {
+    theRegister = 0;  // fill the register with a dummy value
+  }
+
+  Wire.requestFrom(address, numBytes);  // all bytes are returned in requestFrom
+
+  // check to be sure correct number of bytes were returned by slave
+  if (numBytes < Wire.available()) {
+    Firmata.sendString("I2C: Too many bytes received");
+  } else if (numBytes > Wire.available()) {
+    Firmata.sendString("I2C: Too few bytes received");
+  }
+
+  i2cRxData[0] = address;
+  i2cRxData[1] = theRegister;
+
+  for (int i = 0; i < numBytes && Wire.available(); i++) {
+    i2cRxData[2 + i] = wireRead();
+  }
+
+  // send slave address, register and received bytes
+  Firmata.sendSysex(SYSEX_I2C_REPLY, numBytes + 2, i2cRxData);
+}
+
+void outputPort(byte portNumber, byte portValue, byte forceSend)
+{
+  // pins not configured as INPUT are cleared to zeros
+  portValue = portValue & portConfigInputs[portNumber];
+  // only send if the value is different than previously sent
+  if (forceSend || previousPINs[portNumber] != portValue) {
+    Firmata.sendDigitalPort(portNumber, portValue);
+    previousPINs[portNumber] = portValue;
+  }
+}
+
+/* -----------------------------------------------------------------------------
+ * check all the active digital inputs for change of state, then add any events
+ * to the Serial output queue using Serial.print() */
+void checkDigitalInputs(void)
+{
+  /* Using non-looping code allows constants to be given to readPort().
+   * The compiler will apply substantial optimizations if the inputs
+   * to readPort() are compile-time constants. */
+  if (TOTAL_PORTS > 0 && reportPINs[0]) outputPort(0, readPort(0, portConfigInputs[0]), false);
+  if (TOTAL_PORTS > 1 && reportPINs[1]) outputPort(1, readPort(1, portConfigInputs[1]), false);
+  if (TOTAL_PORTS > 2 && reportPINs[2]) outputPort(2, readPort(2, portConfigInputs[2]), false);
+  if (TOTAL_PORTS > 3 && reportPINs[3]) outputPort(3, readPort(3, portConfigInputs[3]), false);
+  if (TOTAL_PORTS > 4 && reportPINs[4]) outputPort(4, readPort(4, portConfigInputs[4]), false);
+  if (TOTAL_PORTS > 5 && reportPINs[5]) outputPort(5, readPort(5, portConfigInputs[5]), false);
+  if (TOTAL_PORTS > 6 && reportPINs[6]) outputPort(6, readPort(6, portConfigInputs[6]), false);
+  if (TOTAL_PORTS > 7 && reportPINs[7]) outputPort(7, readPort(7, portConfigInputs[7]), false);
+  if (TOTAL_PORTS > 8 && reportPINs[8]) outputPort(8, readPort(8, portConfigInputs[8]), false);
+  if (TOTAL_PORTS > 9 && reportPINs[9]) outputPort(9, readPort(9, portConfigInputs[9]), false);
+  if (TOTAL_PORTS > 10 && reportPINs[10]) outputPort(10, readPort(10, portConfigInputs[10]), false);
+  if (TOTAL_PORTS > 11 && reportPINs[11]) outputPort(11, readPort(11, portConfigInputs[11]), false);
+  if (TOTAL_PORTS > 12 && reportPINs[12]) outputPort(12, readPort(12, portConfigInputs[12]), false);
+  if (TOTAL_PORTS > 13 && reportPINs[13]) outputPort(13, readPort(13, portConfigInputs[13]), false);
+  if (TOTAL_PORTS > 14 && reportPINs[14]) outputPort(14, readPort(14, portConfigInputs[14]), false);
+  if (TOTAL_PORTS > 15 && reportPINs[15]) outputPort(15, readPort(15, portConfigInputs[15]), false);
+}
+
+// -----------------------------------------------------------------------------
+/* sets the pin mode to the correct state and sets the relevant bits in the
+ * two bit-arrays that track Digital I/O and PWM status
+ */
+void setPinModeCallback(byte pin, int mode)
+{
+  if (pinConfig[pin] == IGNORE)
+    return;
+
+  if (pinConfig[pin] == I2C && isI2CEnabled && mode != I2C) {
+    // disable i2c so pins can be used for other functions
+    // the following if statements should reconfigure the pins properly
+    disableI2CPins();
+  }
+  if (IS_PIN_DIGITAL(pin) && mode != SERVO) {
+    if (servoPinMap[pin] < MAX_SERVOS && servos[servoPinMap[pin]].attached()) {
+      detachServo(pin);
+    }
+  }
+  if (IS_PIN_ANALOG(pin)) {
+    reportAnalogCallback(PIN_TO_ANALOG(pin), mode == ANALOG ? 1 : 0); // turn on/off reporting
+  }
+  if (IS_PIN_DIGITAL(pin)) {
+    if (mode == INPUT) {
+      portConfigInputs[pin / 8] |= (1 << (pin & 7));
+    } else {
+      portConfigInputs[pin / 8] &= ~(1 << (pin & 7));
+    }
+  }
+  pinState[pin] = 0;
+  switch (mode) {
+    case ANALOG:
+      if (IS_PIN_ANALOG(pin)) {
+        if (IS_PIN_DIGITAL(pin)) {
+          pinMode(PIN_TO_DIGITAL(pin), INPUT);    // disable output driver
+          digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups
+        }
+        pinConfig[pin] = ANALOG;
+      }
+      break;
+    case INPUT:
+      if (IS_PIN_DIGITAL(pin)) {
+        pinMode(PIN_TO_DIGITAL(pin), INPUT);    // disable output driver
+        digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups
+        pinConfig[pin] = INPUT;
+      }
+      break;
+    case OUTPUT:
+      if (IS_PIN_DIGITAL(pin)) {
+        digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable PWM
+        pinMode(PIN_TO_DIGITAL(pin), OUTPUT);
+        pinConfig[pin] = OUTPUT;
+      }
+      break;
+    case PWM:
+      if (IS_PIN_PWM(pin)) {
+        pinMode(PIN_TO_PWM(pin), OUTPUT);
+        analogWrite(PIN_TO_PWM(pin), 0);
+        pinConfig[pin] = PWM;
+      }
+      break;
+    case SERVO:
+      if (IS_PIN_DIGITAL(pin)) {
+        pinConfig[pin] = SERVO;
+        if (servoPinMap[pin] == 255 || !servos[servoPinMap[pin]].attached()) {
+          // pass -1 for min and max pulse values to use default values set
+          // by Servo library
+          attachServo(pin, -1, -1);
+        }
+      }
+      break;
+    case I2C:
+      if (IS_PIN_I2C(pin)) {
+        // mark the pin as i2c
+        // the user must call I2C_CONFIG to enable I2C for a device
+        pinConfig[pin] = I2C;
+      }
+      break;
+    default:
+      Firmata.sendString("Unknown pin mode"); // TODO: put error msgs in EEPROM
+  }
+  // TODO: save status to EEPROM here, if changed
+}
+
+void analogWriteCallback(byte pin, int value)
+{
+  if (pin < TOTAL_PINS) {
+    switch (pinConfig[pin]) {
+      case SERVO:
+        if (IS_PIN_DIGITAL(pin))
+          servos[servoPinMap[pin]].write(value);
+        pinState[pin] = value;
+        break;
+      case PWM:
+        if (IS_PIN_PWM(pin))
+          analogWrite(PIN_TO_PWM(pin), value);
+        pinState[pin] = value;
+        break;
+    }
+  }
+}
+
+void digitalWriteCallback(byte port, int value)
+{
+  byte pin, lastPin, mask = 1, pinWriteMask = 0;
+
+  if (port < TOTAL_PORTS) {
+    // create a mask of the pins on this port that are writable.
+    lastPin = port * 8 + 8;
+    if (lastPin > TOTAL_PINS) lastPin = TOTAL_PINS;
+    for (pin = port * 8; pin < lastPin; pin++) {
+      // do not disturb non-digital pins (eg, Rx & Tx)
+      if (IS_PIN_DIGITAL(pin)) {
+        // only write to OUTPUT and INPUT (enables pullup)
+        // do not touch pins in PWM, ANALOG, SERVO or other modes
+        if (pinConfig[pin] == OUTPUT || pinConfig[pin] == INPUT) {
+          pinWriteMask |= mask;
+          pinState[pin] = ((byte)value & mask) ? 1 : 0;
+        }
+      }
+      mask = mask << 1;
+    }
+    writePort(port, (byte)value, pinWriteMask);
+  }
+}
+
+
+// -----------------------------------------------------------------------------
+/* sets bits in a bit array (int) to toggle the reporting of the analogIns
+ */
+//void FirmataClass::setAnalogPinReporting(byte pin, byte state) {
+//}
+void reportAnalogCallback(byte analogPin, int value)
+{
+  if (analogPin < TOTAL_ANALOG_PINS) {
+    if (value == 0) {
+      analogInputsToReport = analogInputsToReport & ~ (1 << analogPin);
+    } else {
+      analogInputsToReport = analogInputsToReport | (1 << analogPin);
+      // prevent during system reset or all analog pin values will be reported
+      // which may report noise for unconnected analog pins
+      if (!isResetting) {
+        // Send pin value immediately. This is helpful when connected via
+        // ethernet, wi-fi or bluetooth so pin states can be known upon
+        // reconnecting.
+        Firmata.sendAnalog(analogPin, analogRead(analogPin));
+      }
+    }
+  }
+  // TODO: save status to EEPROM here, if changed
+}
+
+void reportDigitalCallback(byte port, int value)
+{
+  if (port < TOTAL_PORTS) {
+    reportPINs[port] = (byte)value;
+    // Send port value immediately. This is helpful when connected via
+    // ethernet, wi-fi or bluetooth so pin states can be known upon
+    // reconnecting.
+    if (value) outputPort(port, readPort(port, portConfigInputs[port]), true);
+  }
+  // do not disable analog reporting on these 8 pins, to allow some
+  // pins used for digital, others analog.  Instead, allow both types
+  // of reporting to be enabled, but check if the pin is configured
+  // as analog when sampling the analog inputs.  Likewise, while
+  // scanning digital pins, portConfigInputs will mask off values from any
+  // pins configured as analog
+}
+
+/*==============================================================================
+ * SYSEX-BASED commands
+ *============================================================================*/
+
+void sysexCallback(byte command, byte argc, byte *argv)
+{
+  byte mode;
+  byte slaveAddress;
+  byte data;
+  int slaveRegister;
+  unsigned int delayTime;
+
+  switch (command) {
+    case I2C_REQUEST:
+      mode = argv[1] & I2C_READ_WRITE_MODE_MASK;
+      if (argv[1] & I2C_10BIT_ADDRESS_MODE_MASK) {
+        Firmata.sendString("10-bit addressing not supported");
+        return;
+      }
+      else {
+        slaveAddress = argv[0];
+      }
+
+      switch (mode) {
+        case I2C_WRITE:
+          Wire.beginTransmission(slaveAddress);
+          for (byte i = 2; i < argc; i += 2) {
+            data = argv[i] + (argv[i + 1] << 7);
+            wireWrite(data);
+          }
+          Wire.endTransmission();
+          delayMicroseconds(70);
+          break;
+        case I2C_READ:
+          if (argc == 6) {
+            // a slave register is specified
+            slaveRegister = argv[2] + (argv[3] << 7);
+            data = argv[4] + (argv[5] << 7);  // bytes to read
+          }
+          else {
+            // a slave register is NOT specified
+            slaveRegister = REGISTER_NOT_SPECIFIED;
+            data = argv[2] + (argv[3] << 7);  // bytes to read
+          }
+          readAndReportData(slaveAddress, (int)slaveRegister, data);
+          break;
+        case I2C_READ_CONTINUOUSLY:
+          if ((queryIndex + 1) >= MAX_QUERIES) {
+            // too many queries, just ignore
+            Firmata.sendString("too many queries");
+            break;
+          }
+          if (argc == 6) {
+            // a slave register is specified
+            slaveRegister = argv[2] + (argv[3] << 7);
+            data = argv[4] + (argv[5] << 7);  // bytes to read
+          }
+          else {
+            // a slave register is NOT specified
+            slaveRegister = (int)REGISTER_NOT_SPECIFIED;
+            data = argv[2] + (argv[3] << 7);  // bytes to read
+          }
+          queryIndex++;
+          query[queryIndex].addr = slaveAddress;
+          query[queryIndex].reg = slaveRegister;
+          query[queryIndex].bytes = data;
+          break;
+        case I2C_STOP_READING:
+          byte queryIndexToSkip;
+          // if read continuous mode is enabled for only 1 i2c device, disable
+          // read continuous reporting for that device
+          if (queryIndex <= 0) {
+            queryIndex = -1;
+          } else {
+            // if read continuous mode is enabled for multiple devices,
+            // determine which device to stop reading and remove it's data from
+            // the array, shifiting other array data to fill the space
+            for (byte i = 0; i < queryIndex + 1; i++) {
+              if (query[i].addr == slaveAddress) {
+                queryIndexToSkip = i;
+                break;
+              }
+            }
+
+            for (byte i = queryIndexToSkip; i < queryIndex + 1; i++) {
+              if (i < MAX_QUERIES) {
+                query[i].addr = query[i + 1].addr;
+                query[i].reg = query[i + 1].reg;
+                query[i].bytes = query[i + 1].bytes;
+              }
+            }
+            queryIndex--;
+          }
+          break;
+        default:
+          break;
+      }
+      break;
+    case I2C_CONFIG:
+      delayTime = (argv[0] + (argv[1] << 7));
+
+      if (delayTime > 0) {
+        i2cReadDelayTime = delayTime;
+      }
+
+      if (!isI2CEnabled) {
+        enableI2CPins();
+      }
+
+      break;
+    case SERVO_CONFIG:
+      if (argc > 4) {
+        // these vars are here for clarity, they'll optimized away by the compiler
+        byte pin = argv[0];
+        int minPulse = argv[1] + (argv[2] << 7);
+        int maxPulse = argv[3] + (argv[4] << 7);
+
+        if (IS_PIN_DIGITAL(pin)) {
+          if (servoPinMap[pin] < MAX_SERVOS && servos[servoPinMap[pin]].attached()) {
+            detachServo(pin);
+          }
+          attachServo(pin, minPulse, maxPulse);
+          setPinModeCallback(pin, SERVO);
+        }
+      }
+      break;
+    case SAMPLING_INTERVAL:
+      if (argc > 1) {
+        samplingInterval = argv[0] + (argv[1] << 7);
+        if (samplingInterval < MINIMUM_SAMPLING_INTERVAL) {
+          samplingInterval = MINIMUM_SAMPLING_INTERVAL;
+        }
+      } else {
+        //Firmata.sendString("Not enough data");
+      }
+      break;
+    case EXTENDED_ANALOG:
+      if (argc > 1) {
+        int val = argv[1];
+        if (argc > 2) val |= (argv[2] << 7);
+        if (argc > 3) val |= (argv[3] << 14);
+        analogWriteCallback(argv[0], val);
+      }
+      break;
+    case CAPABILITY_QUERY:
+      Firmata.write(START_SYSEX);
+      Firmata.write(CAPABILITY_RESPONSE);
+      for (byte pin = 0; pin < TOTAL_PINS; pin++) {
+        if (IS_PIN_DIGITAL(pin)) {
+          Firmata.write((byte)INPUT);
+          Firmata.write(1);
+          Firmata.write((byte)OUTPUT);
+          Firmata.write(1);
+        }
+        if (IS_PIN_ANALOG(pin)) {
+          Firmata.write(ANALOG);
+          Firmata.write(10); // 10 = 10-bit resolution
+        }
+        if (IS_PIN_PWM(pin)) {
+          Firmata.write(PWM);
+          Firmata.write(8); // 8 = 8-bit resolution
+        }
+        if (IS_PIN_DIGITAL(pin)) {
+          Firmata.write(SERVO);
+          Firmata.write(14);
+        }
+        if (IS_PIN_I2C(pin)) {
+          Firmata.write(I2C);
+          Firmata.write(1);  // TODO: could assign a number to map to SCL or SDA
+        }
+        Firmata.write(127);
+      }
+      Firmata.write(END_SYSEX);
+      break;
+    case PIN_STATE_QUERY:
+      if (argc > 0) {
+        byte pin = argv[0];
+        Firmata.write(START_SYSEX);
+        Firmata.write(PIN_STATE_RESPONSE);
+        Firmata.write(pin);
+        if (pin < TOTAL_PINS) {
+          Firmata.write((byte)pinConfig[pin]);
+          Firmata.write((byte)pinState[pin] & 0x7F);
+          if (pinState[pin] & 0xFF80) Firmata.write((byte)(pinState[pin] >> 7) & 0x7F);
+          if (pinState[pin] & 0xC000) Firmata.write((byte)(pinState[pin] >> 14) & 0x7F);
+        }
+        Firmata.write(END_SYSEX);
+      }
+      break;
+    case ANALOG_MAPPING_QUERY:
+      Firmata.write(START_SYSEX);
+      Firmata.write(ANALOG_MAPPING_RESPONSE);
+      for (byte pin = 0; pin < TOTAL_PINS; pin++) {
+        Firmata.write(IS_PIN_ANALOG(pin) ? PIN_TO_ANALOG(pin) : 127);
+      }
+      Firmata.write(END_SYSEX);
+      break;
+  }
+}
+
+void enableI2CPins()
+{
+  byte i;
+  // is there a faster way to do this? would probaby require importing
+  // Arduino.h to get SCL and SDA pins
+  for (i = 0; i < TOTAL_PINS; i++) {
+    if (IS_PIN_I2C(i)) {
+      // mark pins as i2c so they are ignore in non i2c data requests
+      setPinModeCallback(i, I2C);
+    }
+  }
+
+  isI2CEnabled = true;
+
+  Wire.begin();
+}
+
+/* disable the i2c pins so they can be used for other functions */
+void disableI2CPins() {
+  isI2CEnabled = false;
+  // disable read continuous mode for all devices
+  queryIndex = -1;
+}
+
+/*==============================================================================
+ * SETUP()
+ *============================================================================*/
+
+void systemResetCallback()
+{
+  isResetting = true;
+
+  // initialize a defalt state
+  // TODO: option to load config from EEPROM instead of default
+
+  if (isI2CEnabled) {
+    disableI2CPins();
+  }
+
+  for (byte i = 0; i < TOTAL_PORTS; i++) {
+    reportPINs[i] = false;    // by default, reporting off
+    portConfigInputs[i] = 0;  // until activated
+    previousPINs[i] = 0;
+  }
+
+  for (byte i = 0; i < TOTAL_PINS; i++) {
+    // pins with analog capability default to analog input
+    // otherwise, pins default to digital output
+    if (IS_PIN_ANALOG(i)) {
+      // turns off pullup, configures everything
+      setPinModeCallback(i, ANALOG);
+    } else {
+      // sets the output to 0, configures portConfigInputs
+      setPinModeCallback(i, OUTPUT);
+    }
+
+    servoPinMap[i] = 255;
+  }
+  // by default, do not report any analog inputs
+  analogInputsToReport = 0;
+
+  detachedServoCount = 0;
+  servoCount = 0;
+
+  /* send digital inputs to set the initial state on the host computer,
+   * since once in the loop(), this firmware will only send on change */
+  /*
+  TODO: this can never execute, since no pins default to digital input
+        but it will be needed when/if we support EEPROM stored config
+  for (byte i=0; i < TOTAL_PORTS; i++) {
+    outputPort(i, readPort(i, portConfigInputs[i]), true);
+  }
+  */
+  isResetting = false;
+}
+
+void setup()
+{
+  Firmata.setFirmwareVersion(FIRMATA_MAJOR_VERSION, FIRMATA_MINOR_VERSION);
+
+  Firmata.attach(ANALOG_MESSAGE, analogWriteCallback);
+  Firmata.attach(DIGITAL_MESSAGE, digitalWriteCallback);
+  Firmata.attach(REPORT_ANALOG, reportAnalogCallback);
+  Firmata.attach(REPORT_DIGITAL, reportDigitalCallback);
+  Firmata.attach(SET_PIN_MODE, setPinModeCallback);
+  Firmata.attach(START_SYSEX, sysexCallback);
+  Firmata.attach(SYSTEM_RESET, systemResetCallback);
+
+  Firmata.begin(57600);
+  systemResetCallback();  // reset to default config
+}
+
+/*==============================================================================
+ * LOOP()
+ *============================================================================*/
+void loop()
+{
+  byte pin, analogPin;
+
+  /* DIGITALREAD - as fast as possible, check for changes and output them to the
+   * FTDI buffer using Serial.print()  */
+  checkDigitalInputs();
+
+  /* STREAMREAD - processing incoming messagse as soon as possible, while still
+   * checking digital inputs.  */
+  while (Firmata.available())
+    Firmata.processInput();
+
+  // TODO - ensure that Stream buffer doesn't go over 60 bytes
+
+  currentMillis = millis();
+  if (currentMillis - previousMillis > samplingInterval) {
+    previousMillis += samplingInterval;
+    /* ANALOGREAD - do all analogReads() at the configured sampling interval */
+    for (pin = 0; pin < TOTAL_PINS; pin++) {
+      if (IS_PIN_ANALOG(pin) && pinConfig[pin] == ANALOG) {
+        analogPin = PIN_TO_ANALOG(pin);
+        if (analogInputsToReport & (1 << analogPin)) {
+          Firmata.sendAnalog(analogPin, analogRead(analogPin));
+        }
+      }
+    }
+    // report i2c data for all device with read continuous mode enabled
+    if (queryIndex > -1) {
+      for (byte i = 0; i < queryIndex + 1; i++) {
+        readAndReportData(query[i].addr, query[i].reg, query[i].bytes);
+      }
+    }
+  }
+}


Create Triple_IR_and_Motors.ino

Create Triple_IR_and_Motors.ino

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

--- Triple_IR_and_Motors.ino
+++ Triple_IR_and_Motors.ino
@@ -0,0 +1,45 @@
+nt left, right, front;
+
+int E1 = 6;
+int M1 = 7;
+int E2 = 5;
+int M2 = 4;
+
+
+void setup()
+{
+ Serial.begin(9600);
+    pinMode(M1, OUTPUT);
+    pinMode(M2, OUTPUT);
+}
+
+void loop()
+{
+//IR Sensors
+ left = analogRead(1); //set x = data from analog port A#
+ right = analogRead(2);
+ front = analogRead(3);
+ Serial.print(left);
+ Serial.print(" ");
+ Serial.print(front);
+ Serial.print(" ");
+ Serial.print(right);
+ Serial.println();
+ delay(1000); //Delay the output by 1s (1000ms)
+
+
+ //Motors
+    digitalWrite(M1,HIGH);
+    digitalWrite(M2,HIGH);
+    analogWrite(E1, 250);   //PWM Speed Control
+    analogWrite(E2, 250);   //PWM Speed Control
+    delay(2000);
+
+
+    digitalWrite(M1,LOW);
+    digitalWrite(M2,LOW);
+    analogWrite(E1, 250);   //PWM Speed Control
+    analogWrite(E2, 250);   //PWM Speed Control
+    delay(2000);
+
+}


Make Arduino Servo Test

Make Arduino Servo Test

Hopefully the arduino will be able to run the servo better than the rpi. This will repeatedly sweep the servo, 0 to 180 then 180 to 0 and looped.

error: pathspec 'LIDAR' did not match any file(s) known to git
error: pathspec 'Data' did not match any file(s) known to git
error: pathspec 'Extraction/LidarCommands/Currently' did not match any file(s) known to git
error: pathspec 'Used/lidar_servo_test/lidar_servo_test.ino' did not match any file(s) known to git


First commit of Claw code for ITTiny13

First commit of Claw code for ITTiny13

error: pathspec 'Muscle/Arduino' did not match any file(s) known to git
error: pathspec 'Code/MinimalGripper/ClawForITTiny13.ino' did not match any file(s) known to git


seperate example for M2X

seperate example for M2X

error: pathspec 'SerialModem/examples/ArduinoWithM2X/ArduinoM2X.ino' did not match any file(s) known to git

--- SerialModem/examples/ArduinoWithM2X/ArduinoM2X.ino
+++ SerialModem/examples/ArduinoWithM2X/ArduinoM2X.ino
@@ -0,0 +1,38 @@
+#include "jsonlite.h"
+#include "M2XStreamClient.h"
+#include "SerialModem.h"
+
+SerialModemClient client;
+char m2xFeedId[] = "feed-id";    // Feed you want to post to
+char m2xKey[] = "access-key";    // Your M2X access key
+M2XStreamClient m2xClient(&client, m2xKey);
+
+void setup() {
+  Serial.begin(115200);
+  while (!Serial);
+
+  SerialModem.setHardwareInterface(INTERFACE_SIM5218);
+  SerialModem.begin(&Serial, 115200);
+  while (!SerialModem.ready()) {
+    Serial.println("waiting for modem ready..");
+    delay(100);
+  }
+
+  while (SerialModem.getNetworkStatus() < NETWORK_STATUS_ROAMING) {
+    Serial.println("waiting for network registration");
+    delay(2000);
+  }
+
+  while (!SerialModem.setAPN(PROGMEM_STR("m2m.com.attz"))) {
+    Serial.println("setting APN");
+    delay(2000);
+  }
+}
+
+void loop() {
+  int result = m2xClient.post(m2xFeedId, "temperature", 12.1f);
+  Serial.print("M2x client response code: ");
+  Serial.println(result);
+
+  delay(10000);
+}


added AHRS Test

added AHRS Test

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

--- ahrsCodeOutline/ahrsCodeOutline.ino
+++ ahrsCodeOutline/ahrsCodeOutline.ino
@@ -0,0 +1,76 @@
+#include <Wire.h>
+#include <Adafruit_Sensor.h>
+#include <Adafruit_LSM303_U.h>
+#include <Adafruit_9DOF.h>
+#include <Adafruit_L3GD20_U.h>
+
+/* Assign a unique ID to the sensors */
+Adafruit_9DOF                 dof   = Adafruit_9DOF();
+Adafruit_LSM303_Accel_Unified accel = Adafruit_LSM303_Accel_Unified(30301);
+Adafruit_LSM303_Mag_Unified   mag   = Adafruit_LSM303_Mag_Unified(30302);
+
+/**************************************************************************/
+/*!
+    @brief  Initialises all the sensors used by this example
+*/
+/**************************************************************************/
+void initSensors()
+{
+  if(!accel.begin())
+  {
+    /* There was a problem detecting the LSM303 ... check your connections */
+    Serial.println(F("Ooops, no LSM303 detected ... Check your wiring!"));
+    while(1);
+  }
+  if(!mag.begin())
+  {
+    /* There was a problem detecting the LSM303 ... check your connections */
+    Serial.println("Ooops, no LSM303 detected ... Check your wiring!");
+    while(1);
+  }
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+void setup(void)
+{
+  Serial.begin(9600);
+  Serial.println(F("Adafruit 9 DOF Pitch/Roll/Heading Example")); Serial.println("");
+
+  /* Initialise the sensors */
+  initSensors();
+}
+
+/**************************************************************************/
+/*!
+    @brief  Constantly check the roll/pitch/heading/altitude/temperature
+*/
+/**************************************************************************/
+void loop(void)
+{
+  sensors_event_t accel_event;
+  sensors_event_t mag_event;
+  sensors_vec_t   orientation;
+
+  /* Read the accelerometer and magnetometer */
+  accel.getEvent(&accel_event);
+  mag.getEvent(&mag_event);
+
+  /* Use the new fusionGetOrientation function to merge accel/mag data */
+  if (dof.fusionGetOrientation(&accel_event, &mag_event, &orientation))
+  {
+    /* 'orientation' should have valid .roll and .pitch fields */
+    Serial.print(F("Orientation: "));
+    Serial.print(orientation.roll);
+    Serial.print(F(" "));
+    Serial.print(orientation.pitch);
+    Serial.print(F(" "));
+    Serial.print(orientation.heading);
+    Serial.println(F(""));
+  }
+
+  delay(100);
+}


ADD - Added the first sketch to be executed when hardware is assembled.

error: pathspec 'Arduino/Lidar' did not match any file(s) known to git
error: pathspec 'Controller/Lidar_Implementation/Lidar_Module_Test_1/Lidar_Module_Test_1.ino' did not match any file(s) known to git


Nightly

Nightly

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/rniemand/ArduinoProjects.git/'


Updated example.

Updated example.

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

--- examples/Single/Single.ino
+++ examples/Single/Single.ino
@@ -0,0 +1,79 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2013 Mathias Munk Hansen
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include <OneWire.h>
+#include <DS18B20.h>
+
+// Low alarm in degrees Celcius.
+#define LOW_ALARM 20
+
+// High alarm in degrees Celcius.
+#define HIGH_ALARM 25
+
+// 1-Wire devices connected to digital pin 2 on the Arduino.
+DS18B20 ds(2);
+
+// Address of the device.
+uint8_t address[] = {40, 250, 31, 218, 4, 0, 0, 52};
+
+// Indicates if the device was successfully selected.
+uint8_t selected;
+
+void setup()
+{
+  Serial.begin(9600);
+
+  // Select device.
+  selected = ds.select(address);
+
+  if(selected)
+  {
+    // Set alarms.
+    ds.setAlarms(LOW_ALARM, HIGH_ALARM);
+  }
+  else
+  {
+    Serial.println("Error");
+  }
+}
+
+void loop()
+{
+  // Check if the device has an active alarm condition.
+  if(selected)
+  {
+    if(ds.hasAlarm())
+    {
+      Serial.print("Warning! Temperature is ");
+      Serial.print(ds.getTempC());
+      Serial.println(" C");
+    }
+  }
+  else
+  {
+    Serial.println("Error");
+  }
+
+  // Wait 10 seconds.
+  delay(10000);
+}


Adds first draft of Light Shield Arduino-side code.

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


Added v0.54 firmware

Added v0.54 firmware

- support for TSL2591 sensor
- support for NeoPixel

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

--- firmware/SensorBoard_node_054/SensorBoard_node_054.ino
+++ firmware/SensorBoard_node_054/SensorBoard_node_054.ino
@@ -0,0 +1,263 @@
+#include <RFM69.h>  //  https://github.com/LowPowerLab/RFM69
+#include <SPI.h>
+#include <Arduino.h>
+#include <Wire.h>
+#include <Adafruit_SHT31.h> //https://github.com/adafruit/Adafruit_SHT31
+#include <Adafruit_BMP280.h> // https://github.com/adafruit/Adafruit_BMP280_Library
+#include <Adafruit_Sensor.h>  // https://github.com/adafruit/Adafruit_Sensor
+#include <Adafruit_TSL2591.h> // https://github.com/adafruit/Adafruit_TSL2591_Library
+#include <Adafruit_NeoPixel.h> // https://github.com/adafruit/Adafruit_NeoPixel
+#include <avr/sleep.h>
+#include <avr/wdt.h>
+
+// define node parameters
+char node[] = "25";
+#define NODEID        25 // same sa above - must be unique for each node on same network (range up to 254, 255 is used for broadcast)
+#define GATEWAYID     1
+#define NETWORKID     101
+#define FREQUENCY     RF69_915MHZ //Match this with the version of your Moteino! (others: RF69_433MHZ, RF69_868MHZ)
+#define ENCRYPTKEY    "Tt-Mh=SQ#dn#JY3_" //has to be same 16 characters/bytes on all nodes, not more not less!
+#define IS_RFM69HW    //uncomment only for RFM69HW! Leave out if you have RFM69W!
+#define LED           9 // led pin
+#define PIN           6 // NeoPixel driver pin
+
+// define objects
+RFM69 radio;
+Adafruit_BMP280 bme; // I2C
+Adafruit_SHT31 sht31 = Adafruit_SHT31();
+Adafruit_TSL2591 tsl = Adafruit_TSL2591(2591); // pass in a number for the sensor identifier (for your use later)
+Adafruit_NeoPixel strip = Adafruit_NeoPixel(1, PIN, NEO_GRB + NEO_KHZ800);  // number of pixels, digital pin, pixel flags
+
+// define IAQ core global variables
+#define iaqaddress 0x5A
+uint16_t co2;
+uint8_t statu;
+int32_t resistance;
+uint16_t tvoc;
+
+// define global variables
+long lux;
+float bar;
+float sound;
+
+char dataPacket[150];
+
+ISR(WDT_vect)  // Interrupt service routine for WatchDog Timer
+{
+  wdt_disable();  // disable watchdog
+}
+
+void setup()
+{
+  pinMode(10, OUTPUT); // Radio SS pin set as output
+
+  Serial.begin(115200);
+  Serial.println("Setup");
+
+  radio.initialize(FREQUENCY,NODEID,NETWORKID);
+#ifdef IS_RFM69HW
+  radio.setHighPower(); //uncomment only for RFM69HW!
+#endif
+  radio.encrypt(ENCRYPTKEY);
+
+  pinMode(9, OUTPUT);  // pin 9 controls LED
+
+  strip.begin(); // initialize neo pixels
+  strip.show(); // Initialize all pixels to 'off'
+
+  Serial.println("Ready");
+}
+
+
+void sleep()
+{
+  Serial.flush(); // empty the send buffer, before continue with; going to sleep
+
+  radio.sleep();
+
+  cli();          // stop interrupts
+  MCUSR = 0;
+  WDTCSR  = (1<<WDCE | 1<<WDE);     // watchdog change enable
+  WDTCSR  = 1<<WDIE | (1<<WDP3) | (0<<WDP2) | (0<<WDP1) | (0<<WDP0); // set  prescaler to 4 second
+  sei();  // enable global interrupts
+
+  byte _ADCSRA = ADCSRA;  // save ADC state
+  ADCSRA &= ~(1 << ADEN);
+
+  asm("wdr");
+  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
+  cli();
+
+  sleep_enable();
+  sleep_bod_disable();
+  sei();
+  sleep_cpu();
+
+  sleep_disable();
+  sei();
+
+  ADCSRA = _ADCSRA; // restore ADC state (enable ADC)
+  delay(1);
+}
+
+
+void loop()
+{
+  sleep();
+
+  readSensors();
+
+  Serial.println(dataPacket);
+  delay(50);
+
+  // send datapacket
+  radio.sendWithRetry(GATEWAYID, dataPacket, strlen(dataPacket), 5, 100);  // send data, retry 5 times with delay of 100ms between each retry
+  dataPacket[0] = (char)0; // clearing first byte of char array clears the array
+
+  //fadeLED();
+  //colorWipe(strip.Color(0, 255, 0), 10); // Green
+  //strip.show();
+  for (int i = 0; i <= 255; i++)
+  {
+      colorWipe(strip.Color(0,i,0), 1);
+  }
+  for (int i = 255; i > 0; i--)
+  {
+      colorWipe(strip.Color(0,i,0), 2);
+  }
+  colorWipe(strip.Color(0, 0, 0), 1); // turn pixel off
+  strip.show();
+}
+
+
+void readSensors()
+{
+   //T/RH
+  sht31.begin(0x44);
+  float temp = sht31.readTemperature();
+  float rh = sht31.readHumidity();
+
+
+  //light
+  tsl.begin();
+  tsl.setGain(TSL2591_GAIN_MED);      // 25x gain
+  tsl.setTiming(TSL2591_INTEGRATIONTIME_100MS);  // shortest integration time (bright light)
+  sensors_event_t event;
+  tsl.getEvent(&event);
+  if ((event.light == 0) | (event.light > 4294966000.0) | (event.light <-4294966000.0))
+  {
+    lux = 0;  // invalid value; replace with 'NAN' if needed
+  }
+  else
+  {
+    lux = event.light;
+  }
+
+
+  // IAQ core
+  Wire.requestFrom(iaqaddress, 9);
+  co2 = (Wire.read()<< 8 | Wire.read());
+  statu = Wire.read();
+  resistance = (Wire.read()& 0x00)| (Wire.read()<<16)| (Wire.read()<<8| Wire.read());
+  tvoc = (Wire.read()<<8 | Wire.read());
+
+
+  // ADMP401 mic for sound level
+  float sumADC=0.0;
+  for(int i=0;i<5;i++)
+  {
+     sumADC = sumADC + analogRead(A0); // take avg of 5 readings
+  }
+  float averageADC = sumADC/5.0;
+  float volts = (averageADC/1023.0 * 3.3);
+  sound = (20 * log10(volts/0.007943)) - 42 + 94 - 60;  // VRMS = 0.007943; -42dB is sensitivity of ADMP401 mic; 1 Pa = 94 dB SPL RMS; 60dB is gain of amplifier
+  // the above is uncalibrated sound level - needs to be calibrated with reference to an accurate sound level meter in varying SPLs, frequencies and environments.
+
+
+  // BMP280 air pressure sensor
+  bme.begin();
+  float bar = bme.readPressure();
+  bar = bar / 3386.39;  // convert pressure in Pa to inches of Mercury
+
+
+
+  // define character arrays for all variables
+  //char _i[4];
+  char _t[7];
+  char _h[7];
+  char _c[7];
+  char _o[7];
+  char _g[7];
+  char _l[7];
+  char _n[7];
+  char _s[7];
+  char _v[7];
+
+  // convert all flaoting point and integer variables into character arrays
+  //dtostrf(nodeID, 2, 0, _i);
+  dtostrf(temp, 3, 1, _t);  // this function converts float into char array. 3 is minimum width, 2 is decimal precision
+  dtostrf(rh, 3, 1, _h);
+  dtostrf(co2, 3, 0, _c);
+  dtostrf(bar, 3, 2, _g);
+  dtostrf(lux, 1, 0, _l);
+  dtostrf(sound, 1, 1, _s);
+  dtostrf(tvoc, 1, 0, _v);
+  delay(50);
+
+  dataPacket[0] = 0;  // first value of dataPacket should be a 0
+
+  // create datapacket by combining all character arrays into a large character array
+  strcat(dataPacket, "i:");
+  strcat(dataPacket, node);
+  strcat(dataPacket, ",t:");
+  strcat(dataPacket, _t);
+  strcat(dataPacket, ",h:");
+  strcat(dataPacket, _h);
+  strcat(dataPacket, ",c:");
+  strcat(dataPacket, _c);
+  strcat(dataPacket, ",g:");
+  strcat(dataPacket, _g);
+  strcat(dataPacket, ",l:");
+  strcat(dataPacket, _l);
+  strcat(dataPacket, ",s:");
+  strcat(dataPacket, _s);
+  strcat(dataPacket, ",v:");
+  strcat(dataPacket, _v);
+  delay(50);
+}
+
+
+
+
+void fadeLED()
+{
+  int brightness = 0;
+  int fadeAmount = 5;
+  for(int i=0; i<510; i=i+5)  // 255 is max analog value, 255 * 2 = 510
+  {
+    analogWrite(9, brightness);  // pin 9 is LED
+
+    // change the brightness for next time through the loop:
+    brightness = brightness + fadeAmount;  // increment brightness level by 5 each time (0 is lowest, 255 is highest)
+
+    // reverse the direction of the fading at the ends of the fade:
+    if (brightness <= 0 || brightness >= 255)
+    {
+      fadeAmount = -fadeAmount;
+    }
+    // wait for 20-30 milliseconds to see the dimming effect
+    delay(10);
+  }
+  digitalWrite(9, LOW); // switch LED off at the end of fade
+}
+
+
+// Fill the dots one after the other with a color
+void colorWipe(uint32_t c, uint8_t wait) {
+  for(uint16_t i=0; i<strip.numPixels(); i++) {
+    strip.setPixelColor(i, c);
+    strip.show();
+    delay(wait);
+  }
+}
+


Added comments for LCD 5110

Added comments for LCD 5110

error: pathspec 'examples/7.Display/LCD_5110_430/LCD_5110_430.ino' did not match any file(s) known to git

--- examples/7.Display/LCD_5110_430/LCD_5110_430.ino
+++ examples/7.Display/LCD_5110_430/LCD_5110_430.ino
@@ -0,0 +1,114 @@
+//
+//  LCD_5110_main.pde
+//  Sketch
+//  ----------------------------------
+//  Developed with embedXcode
+//
+//  Project LCD 5110
+//  Created by Rei VILO on 28/05/12
+//  Copyright (c) 2012 http://embeddedcomputing.weebly.com
+//  Licence CC = BY SA NC
+//
+
+// Core library
+#if defined(__MSP430G2452__) || defined(__MSP430G2553__) || defined(__MSP430G2231__) // LaunchPad specific
+#include "Energia.h"
+#else
+#error Board not supported
+#endif
+
+// Include application, user and local libraries
+#include "LCD_5110.h"
+#include "Thermometer_430.h"
+
+// Variables
+// Option 1: parameters with suggested pins
+//LCD_5110 myScreen(P2_4, P2_3, P2_2, P2_1, P2_0, P2_5, PUSH2);
+
+//#define _pinChipSelect  P2_4
+//#define _pinSerialClock P2_3
+//#define _pinSerialData  P2_2
+//#define _pinDataCommand P2_1
+//#define _pinReset       P2_0
+//#define _pinBacklight   P2_5
+//#define _pinPushButton  PUSH2
+
+// Option 2: no parameters, pins compatible with LCD BoosterPack / Nokia 7110
+LCD_5110 myScreen;
+
+//LCD_5110(P2_2,    // Chip Select *
+//         P2_4,    // Serial Clock *
+//         P2_0,    // Serial Data *
+//         P2_3,    // Data/Command *
+//         P1_0,    // Reset *
+//         P2_1,    // Backlight
+//         PUSH2);  // Push Button 0
+
+
+Thermometer_430 myThermometer;
+boolean	backlight = false;
+
+
+// Add setup code
+void setup() {
+    myThermometer.begin();
+
+    myScreen.begin();
+
+    myScreen.setFont(1);
+    myScreen.text(1, 1, "MSP430");
+    myScreen.setFont(0);
+    myScreen.text(0, 5, "1234567890abcd");
+
+    delay(2000);
+    myScreen.clear();
+    myScreen.text(2, 0, "Thermometer");
+    myScreen.text(0, 5, "off");
+
+}
+
+// Display mask
+char display[8] = {' ', ' ', ' ', '.', ' ', 0x7f, 'C', 0x00};
+
+
+// Add loop code
+void loop() {
+    if (myScreen.getButton()) {
+        backlight = ~backlight;
+        myScreen.setFont(0);
+        myScreen.text(0, 5, backlight ? "on " : "off");
+        myScreen.setBacklight(backlight);
+    }
+
+    myThermometer.get();
+
+    // Temperature display
+    int32_t number = myThermometer.temperatureX10();
+
+	boolean flag = (number<0);
+    if (flag) number = -number;
+
+    display[4] = 0x30 + (number%10);
+    number /= 10;
+    display[2] = 0x30 + (number%10);
+    number /= 10;
+	if (number>0) {
+        display[1] = 0x30 + (number%10);
+    } else if (flag) {
+        display[1] = '-';
+        flag = false;
+    } else {
+        display[1] = ' ';
+    }
+    number /= 10;
+	if (number>0) display[0] = 0x30 + (number%10);
+    else if (flag) display[0] = '-';
+    else display[0] = ' ';
+
+    myScreen.setFont(1);
+    myScreen.text(0, 2, display);
+
+    delay(500);
+}
+
+


Add arduino project

Add arduino project

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

--- arduino/arduino.ino
+++ arduino/arduino.ino
@@ -0,0 +1,167 @@
+/*
+  Web Server
+
+ A simple web server that shows the value of the analog input pins.
+ using an Arduino Wiznet Ethernet shield.
+
+ Circuit:
+ * Ethernet shield attached to pins 10, 11, 12, 13
+ * Analog inputs attached to pins A0 through A5 (optional)
+
+ created 18 Dec 2009
+ by David A. Mellis
+ modified 9 Apr 2012
+ by Tom Igoe
+
+ */
+
+#include <SPI.h>
+#include <Ethernet.h>
+
+// Enter a MAC address and IP address for your controller below.
+// The IP address will be dependent on your local network:
+byte mac[] = {
+  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
+};
+IPAddress ip(192, 168, 2, 15);
+
+// Google DNS
+IPAddress myDns(8, 8, 8, 8);
+
+// Initialize the Ethernet server library
+// with the IP address and port you want to use
+// (port 80 is default for HTTP):
+// EthernetServer server(80);
+
+//
+char serverName[] = "smart-trash.app.hackinpoa.tsuru.io";    // name address for Google (using DNS)
+
+EthernetClient sendClient;
+
+unsigned long lastConnectionTime = 0;             // last time you connected to the server, in milliseconds
+const unsigned long postingInterval = 1L * 1000L; // Every second (10000)
+
+String postData;
+
+void setup() {
+  // Open serial communications and wait for port to open:
+  Serial.begin(9600);
+  while (!Serial) {
+    ; // wait for serial port to connect. Needed for Leonardo only
+  }
+
+
+  // start the Ethernet connection and the server:
+  Ethernet.begin(mac, ip, myDns);
+  //server.begin();
+  //Serial.print("server is at ");
+  Serial.println(Ethernet.localIP());
+}
+
+
+void loop() {
+
+  readResponse();
+
+  // listen for incoming clients
+  /*
+  EthernetClient client = server.available();
+  if (client) {
+    Serial.println("new client");
+    // an http request ends with a blank line
+    boolean currentLineIsBlank = true;
+    while (client.connected()) {
+      if (client.available()) {
+        char c = client.read();
+        Serial.write(c);
+        // if you've gotten to the end of the line (received a newline
+        // character) and the line is blank, the http request has ended,
+        // so you can send a reply
+        if (c == '\n' && currentLineIsBlank) {
+          // send a standard http response header
+          client.println("HTTP/1.1 200 OK");
+          client.println("Content-Type: text/html");
+          client.println("Connection: close");  // the connection will be closed after completion of the response
+          client.println("Refresh: 5");  // refresh the page automatically every 5 sec
+          client.println();
+          client.println("<!DOCTYPE HTML>");
+          client.println("");
+          // output the value of each analog input pin
+          for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
+            int sensorReading = analogRead(analogChannel);
+            client.print("analog input ");
+            client.print(analogChannel);
+            client.print(" is ");
+            client.print(sensorReading);
+            client.println("
");
+          }
+          client.println("");
+          break;
+        }
+        if (c == '\n') {
+          // you're starting a new line
+          currentLineIsBlank = true;
+        }
+        else if (c != '\r') {
+          // you've gotten a character on the current line
+          currentLineIsBlank = false;
+        }
+      }
+    }
+    // give the web browser time to receive the data
+    delay(1);
+    // close the connection:
+    client.stop();
+    Serial.println("client disconnected");
+  }
+  */
+
+  // if ten seconds have passed since your last connection,
+  // then connect again and send data:
+  if (millis() - lastConnectionTime > postingInterval) {
+    httpRequest(0, analogRead(0));
+  }
+}
+
+void readResponse() {
+  //Read http response
+  if (sendClient.available()) {
+    char c = sendClient.read();
+    Serial.write(c);
+  }
+}
+
+// this method makes a HTTP connection to the server:
+void httpRequest(int sensor, int value) {
+  // close any connection before send a new request.
+  // This will free the socket on the WiFi shield
+  sendClient.stop();
+
+  String path = "/coleta/" + String(sensor) + "/" + String(value);
+
+  // if there's a successful connection:
+  if (sendClient.connect(serverName, 80)) {
+    Serial.println("connecting...");
+    // send the HTTP PUT request:
+    sendClient.println("GET " + path + " HTTP/1.1");
+    sendClient.println("Host: smart-trash.app.hackinpoa.tsuru.io");
+    sendClient.println("User-Agent: arduino-ethernet");
+    sendClient.println("Connection: close");
+    sendClient.println();
+
+    //sendClient.print("Content-Length: ");
+    //sendClient.println(postData.length());
+    //sendClient.println();
+    //sendClient.println(postData);
+
+    sendClient.println();
+
+    // note the time that the connection was made:
+    lastConnectionTime = millis();
+  }
+  else {
+    // if you couldn't make a connection:
+    Serial.println("connection failed");
+  }
+}
+


Create motor_4.ino

Create motor_4.ino

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

--- arduino/motor_4.ino
+++ arduino/motor_4.ino
@@ -0,0 +1,107 @@
+#include <Wire.h>
+
+double potcurval;    // variable to read the value from the analog pin
+int angel; //Integer value of angle
+ double angle =0;
+
+ double curangle,kP=32.00,kI=45,kD=1.5,Last=0;
+ double P=0,I=0,D=0,Drive,Error=0,Integral=0;
+
+
+ void backward()
+ {
+   digitalWrite(12,HIGH);
+   digitalWrite(9,LOW);
+ }
+  void forward()
+ {
+   digitalWrite(12,LOW);
+   digitalWrite(9,HIGH);
+ }
+ void halt()
+ {
+    digitalWrite(12,LOW);
+    digitalWrite(9,LOW);
+ }
+void setup()
+{
+  // myservo.attach(6);  // attaches the servo on pin 9 to the servo object
+  pinMode(9,OUTPUT);
+  pinMode(12,OUTPUT);
+  Serial.begin(9600);
+  pinMode(11,OUTPUT);
+  Wire.begin(4);
+  Wire.onReceive(receiveEvent);
+  pinMode(13, OUTPUT);
+}
+ void Errorcalc()
+ {
+   potcurval=(double)analogRead(A0)+1;
+   potcurval=(potcurval/1024)*5;
+    curangle=(potcurval/5)*270;
+
+                Error = curangle-angle;
+ }
+void loop()
+{
+            Serial.print("got: ");
+	    Serial.println(angle);
+	    if(angle > 127) digitalWrite(13, HIGH);
+	   else digitalWrite(13, LOW);
+                 Errorcalc();
+                if (abs(Error) <1.0){ // prevent integral 'windup'
+                Integral = Integral + Error; // accumulate the error integral
+                }
+                else {
+                Integral=0; // zero it if out of bounds
+                }
+                P = Error*kP; // calc proportional term
+                I = Integral*kI; // integral term
+                D = (Last-curangle)*kD; // derivative term
+
+                Drive = P + I + D; // Total drive = P+I+D
+
+                //Drive = (Drive/550)*255; // scale Drive to be in the range 0-255
+
+                if(abs(Drive) < 60)
+                {
+                  Drive += (Drive/abs(Drive)) *60;
+                }
+                if (abs(Drive)>255) {
+                Drive=(Drive/abs(Drive)) *255;
+                }
+
+
+                Serial.println(Error);
+                if (Error < 0){ // Check which direction to go.
+                forward();
+
+                }
+                else if(Error >=0){ // depending on the sign of Error
+                 backward();
+
+                }
+
+                if(abs(Error)<2)
+                {
+                  halt();
+                  Serial.println("break !!!");
+                }
+
+                analogWrite (11,abs(Drive)); // send PWM command to motor board
+                Last=curangle;
+   /*
+    Serial.println("P :");
+    Serial.println(P);
+    Serial.println("I :");
+    Serial.println(I);
+    Serial.println("D :");
+    Serial.println(D);
+    */
+
+}
+void receiveEvent(int howMany)
+{
+  int x = Wire.read();
+  angle = (double) x;
+}


Added arduino source code.

Added arduino source code.

--- arduino/arduino.ino
+++ arduino/arduino.ino
@@ -0,0 +1,82 @@
+//
+// This file is part of DoorOpener.
+// Copyright (c) 2014 Jacob Dawid <jacob@omg-it.works>
+//
+// DoorOpener is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// DoorOpener 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 Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public
+// License along with DoorOpener.
+// If not, see <http://www.gnu.org/licenses/>.
+//
+
+#define RELAIS_DOOR_OUT_1 7
+#define RELAIS_DOOR_OUT_2 8
+#define BELL_IN 2
+#define BEEP_OUT 13
+
+#define BUFFER_SIZE 256
+
+char *readBuffer = (char*)malloc(sizeof(char) * BUFFER_SIZE);
+int readBufferPosition = 0;
+
+void setup() {
+  // Set up serial port connection
+  Serial.begin(9600);
+
+  // Set pin IO modes
+  pinMode(RELAIS_DOOR_OUT_1, OUTPUT);
+  pinMode(RELAIS_DOOR_OUT_2, OUTPUT);
+  pinMode(BELL_IN, INPUT);
+  pinMode(BEEP_OUT, OUTPUT);
+
+  // Turn off door opener
+  digitalWrite(RELAIS_DOOR_OUT_1, LOW);
+  digitalWrite(RELAIS_DOOR_OUT_2, LOW);
+}
+
+void loop() {
+  // Check if bell rings at bell input pin
+  if(digitalRead(BELL_IN) == HIGH) {
+    Serial.println("bell\n");
+  }
+
+  // Read data from serial port if available
+  while(Serial.available() > 0) {
+    char c = Serial.read();
+
+    // If line ends or maximum buffer size reached, handle line
+    if(c == '\n' || c == '\r' || (readBufferPosition == BUFFER_SIZE - 1)) {
+      readBuffer[readBufferPosition] = 0;
+      handleInputLine();
+      readBufferPosition = 0;
+
+    // Otherwise, append character
+    } else {
+      readBuffer[readBufferPosition] = c;
+      readBufferPosition++;
+    }
+  }
+}
+
+// Handles a server command
+void handleInputLine() {
+  if (readBuffer[0] == '1') {
+      digitalWrite(RELAIS_DOOR_OUT_1, HIGH);
+  } else if (readBuffer[0] == '0') {
+      digitalWrite(RELAIS_DOOR_OUT_1, LOW);
+  }
+
+  if (readBuffer[1] == '1') {
+      digitalWrite(RELAIS_DOOR_OUT_2, HIGH);
+  } else if (readBuffer[1] == '0') {
+      digitalWrite(RELAIS_DOOR_OUT_2, LOW);
+  }
+}


move sketch out of examples folder

move sketch out of examples folder

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

--- PIRMotionSensor/PIRMotionSensor.ino
+++ PIRMotionSensor/PIRMotionSensor.ino
@@ -0,0 +1,82 @@
+/*
+ * PIRMotionSensor.ino
+ * Example sketch for the PIR motion sensor
+ *
+ * Copyright (c) 2013 seeed technology inc.
+ * Website    : www.seeed.cc
+ * Author     : FrankieChu
+ * Create Time: Jan 21,2013
+ * Change Log :
+ *
+ * The MIT License (MIT)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+
+/*****************************************************************************/
+//  Function: If the sensor detects the moving people in it's detecting range,
+//			  the Grove - LED is turned on.Otherwise, the LED is turned off.
+//  Hardware: Grove - PIR Motion Sensor, Grove - LED
+//	Arduino IDE: Arduino-1.0
+/*******************************************************************************/
+/*macro definitions of PIR motion sensor pin and LED pin*/
+#define PIR_MOTION_SENSOR 2//Use pin 2 to receive the signal from the module
+#define LED	4//the Grove - LED is connected to D4 of Arduino
+
+void setup()
+{
+	pinsInit();
+}
+
+void loop()
+{
+	if(isPeopleDetected())//if it detects the moving people?
+		turnOnLED();
+	else
+		turnOffLED();
+}
+void pinsInit()
+{
+	pinMode(PIR_MOTION_SENSOR, INPUT);
+	pinMode(LED,OUTPUT);
+}
+void turnOnLED()
+{
+	digitalWrite(LED,HIGH);
+}
+void turnOffLED()
+{
+	digitalWrite(LED,LOW);
+}
+/***************************************************************/
+/*Function: Detect whether anyone moves in it's detecting range*/
+/*Return:-boolean, ture is someone detected.*/
+boolean isPeopleDetected()
+{
+	int sensorValue = digitalRead(PIR_MOTION_SENSOR);
+	if(sensorValue == HIGH)//if the sensor value is HIGH?
+	{
+		return true;//yes,return ture
+	}
+	else
+	{
+		return false;//no,return false
+	}
+}


and we can simply unify this …

and we can simply unify this …

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/'


Create lighthouse_beacon_v2_anti-aliased.ino

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

--- lighthouse_beacon_v2_anti-aliased.ino
+++ lighthouse_beacon_v2_anti-aliased.ino
@@ -0,0 +1,87 @@
+//***************************************************************
+// rotating beacon for lighthouse emulation, Anti-aliased version
+// Marc Miller, Nov 2015
+//
+//Based on Mark Kriegsman's Anti-aliased light bar example here:
+//http://pastebin.com/yAgKs0Ay#
+//***************************************************************
+
+#include "FastLED.h"
+#define LED_TYPE NEOPIXEL
+#define DATA_PIN 6
+//#define CLOCK_PIN 13
+#define NUM_LEDS 12
+//#define COLOR_ORDER GRB
+#define BRIGHTNESS 255
+CRGB leds[NUM_LEDS];
+
+int8_t hue = 42;  // Light color
+int8_t sat = 190;  // Saturation
+int8_t val = BRIGHTNESS;  // Max brightness of light
+uint8_t pixelPos = 0; // position of the "fraction-based bar"
+int delta = -1; // Number of 16ths of a pixel to move.  (Use negative value for reverse.)
+uint8_t width  = 3; // width of light in pixels
+uint16_t holdTime = 80;  // Milliseconds to hold between microsteps.
+int8_t fadeRate = 40;  // Fade ends a bit.
+
+
+//---------------------------------------------------------------
+void setup() {
+  //FastLED.addLeds<LED_TYPE, DATA_PIN, CLOCK_PIN, COLOR_ORDER>(leds, NUM_LEDS);
+  FastLED.addLeds<LED_TYPE, DATA_PIN>(leds, NUM_LEDS);
+  FastLED.setBrightness(BRIGHTNESS);
+  //Serial.begin(115200);
+}
+
+
+//---------------------------------------------------------------
+// Fractional bar funtion
+void drawFractionalBar( uint8_t pos16, uint8_t width, uint8_t hue)
+{
+  uint8_t i = pos16 / 16; // convert from pos to raw pixel number
+  uint8_t frac = pos16 & 0x0F; // extract the 'factional' part of the position
+  uint8_t firstpixelbrightness = 255 - (frac * 16);
+  uint8_t lastpixelbrightness  = 255 - firstpixelbrightness;
+  uint8_t bright;
+  for( uint8_t n = 0; n <= width; n++) {
+    if( n == 0) {
+      bright = firstpixelbrightness;
+      leds[i] += CHSV( hue, sat, bright);
+      //fadeToBlackBy( leds, NUM_LEDS, fadeRate );  // creates outward fade
+    }
+    else if (n == width) {
+      bright = lastpixelbrightness;
+      leds[i] += CHSV( hue, sat, bright);
+      fadeToBlackBy( leds, NUM_LEDS, fadeRate );  // creates outward fade
+    }
+    else {
+      bright = 255;  // center pixel full bright
+      leds[i] += CHSV( hue, sat, bright);
+    }
+    i++;
+    if( i == NUM_LEDS) i = 0; // wrap around
+  }
+}
+
+//---------------------------------------------------------------
+void loop() {  // START MAIN LOOP
+  if (delta > 0) {
+    pixelPos += delta;
+  } else {
+    pixelPos = (pixelPos + delta + (NUM_LEDS *16)) % (NUM_LEDS * 16);
+  }
+
+  if( pixelPos >= (NUM_LEDS * 16)) {
+    pixelPos -= (NUM_LEDS * 16);
+  }
+
+  static byte countdown = 0;
+  if( countdown == 0) { countdown = 16; } // reset countdown
+  countdown -= 1;  // decrement once each loop though
+
+  memset8( leds, 0, NUM_LEDS * sizeof(CRGB));  // Clear the pixel buffer
+  drawFractionalBar( pixelPos, width, hue);  // Draw the pixels
+  FastLED.show();  // Show the pixels
+  delay(holdTime);  // Delay a bit before micro advancing
+
+}  // END MAIN LOOP


minor bug

minor bug

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/ivegotasthma/washmashine.git/'


Add button interrupt example

Add button interrupt example

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

--- examples/button-interrupt/button-interrupt.ino
+++ examples/button-interrupt/button-interrupt.ino
@@ -0,0 +1,18 @@
+#define BUTTON_PIN 2;
+#define LED_PIN 13;
+
+volatile uint8_t pinState = LOW;
+
+void setup() {
+  pinMode(LED_PIN, OUTPUT);
+  pinMode(BUTTON_PIN, INPUT_PULLUP);
+  attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), toggle, CHANGE);
+}
+
+void loop() {
+  digitalWrite(LED_PIN, pinState);
+}
+
+void toggle() {
+  pinState = !pinState;
+}


Example using aramp

Example using aramp

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

--- examples/gentlelight.ino
+++ examples/gentlelight.ino
@@ -0,0 +1,103 @@
+// #define ADEL_DEBUG 1
+
+#include <adel.h>
+
+/** Use a button to turn a light on/off slowly
+ *
+ *  Uses the aramp command to turn light on/off over a specific period of time
+ */
+
+#define LED_PIN 5
+#define BUTTON_PIN 4
+
+void setup()
+{
+  delay(1000);
+  Serial.begin(9600);
+  pinMode(LED_PIN, OUTPUT);
+  pinMode(BUTTON_PIN, INPUT);
+  digitalWrite(LED_PIN, LOW);
+}
+
+/** Wait for a button
+ *
+ *  First wait for the pin to go high, then debounce, then wait for the
+ *  button to go low. The key feature of this routine is that it does not
+ *  return until the button is pressed.
+ */
+adel waitbutton(int pin)
+{
+   abegin:
+   while (1) {
+      await (digitalRead(pin) == HIGH);
+      adelay (50);
+      if (digitalRead(pin) == HIGH) {
+         await (digitalRead(pin) == LOW);
+         afinish;
+      }
+   }
+   aend;
+}
+
+/** blink
+ *
+ *  Blink an LED continuously at some interval
+ */
+adel blink(int pin, int interval)
+{
+  abegin:
+  while (1) {
+    digitalWrite(pin, HIGH);
+    adelay(interval);
+    digitalWrite(pin, LOW);
+    adelay(interval);
+  }
+  aend;
+}
+
+adel rampuplight(int pin, int howlong)
+{
+  int val;
+  abegin:
+  aramp(howlong, val, 0, 255) {
+    analogWrite(pin, val);
+    adelay(50);
+  }
+  analogWrite(pin, 255);
+  aend;
+}
+
+adel rampdownlight(int pin, int howlong)
+{
+  int val;
+  abegin:
+  aramp(howlong, val, 255, 0) {
+    analogWrite(pin, val);
+    adelay(50);
+  }
+  analogWrite(pin, 0);
+  aend;
+}
+
+adel buttonblink()
+{
+  int howlong;
+  abegin:
+  // -- Wait for button to get started
+  andthen( waitbutton(BUTTON_PIN) );
+  // -- Initially, make the light go fast
+  howlong = 1000;
+  while (1) {
+    auntil( waitbutton(BUTTON_PIN) , rampuplight(LED_PIN, howlong) );
+    auntil( waitbutton(BUTTON_PIN) , rampdownlight(LED_PIN, howlong) );
+    // -- On each cycle, make it go slower
+    howlong += 1000;
+  }
+  aend;
+}
+
+void loop()
+{
+  arepeat( buttonblink() );
+}
+