Initial version of the Arduino program to control the robot.

Handles command parsing, serial input, and fail-safe.
Doesn't actual control any hardware yet.

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

--- Arduino/Thingamabot/Thingamabot.ino
+++ Arduino/Thingamabot/Thingamabot.ino
@@ -0,0 +1,411 @@
+// Arduino code for Thingamashop wheelchair robot.
+//
+// Accepts commands over serial or Bluetooth LE.
+// Commands are two lower case letters, space, an integer value,
+// then CR, LF.
+//
+// A fail-safe mode will shut down the robot if no commands
+// are processed within a fail-safe interval. Once fail-safe mode
+// is entered, the "ef" command must be used to exit fail-safe mode.
+//
+// Command summary:
+//
+// ml <value>:     Motor Left. Value from -100 to 100. 0 is off.
+// mr <value>:     Motor Right. Value from -100 to 100. 0 is off.
+// bl <value>:     Brake Left. 0 is off, other value is on.
+// br <value>:     Break Right. 0 is off, other value is on.
+// sp <value>:     Servo Pan. Value from -180 to 180.
+// st <value>:     Servo Tilt. Value from -180 to 180.
+// ka:             Keep alive. Prevent from entering fail-safe mode.
+// fs <value>:     Set fail-safe interval in milliseconds. Use 0 to disable fail-safe mode.
+// ef:             Exit fail safe. Once fail-safe mode is entered, you must
+//                 use this command to exit.
+
+//////////////////////////////////////////////
+// UTILITY routines.
+
+boolean logging = true;      // Set to true to enable logging to serial port.
+
+// Log a message.
+void log(const __FlashStringHelper * message)
+{
+    if (logging) {
+        Serial.print(F("* "));
+        Serial.println(message);
+    }
+}
+
+// Log a message and an integer value.
+void log(const __FlashStringHelper * message, long value)
+{
+    if (logging) {
+        Serial.print(F("* "));
+        Serial.print(message);
+        Serial.print(F(" "));
+        Serial.println(value);
+    }
+}
+
+// Log two strings on same line.
+void log(const __FlashStringHelper * message, const char * value)
+{
+    if (logging) {
+        Serial.print(F("* "));
+        Serial.print(message);
+        Serial.print(F(" "));
+        Serial.println(value);
+    }
+}
+
+///////////////////////////////////////////////
+// MOTORS
+
+// Values designating the motors.
+const int LEFT_MOTOR = 0;
+const int RIGHT_MOTOR = 1;
+
+// Configure motor hardware.
+void setup_motors()
+{
+    // TODO: Configure motor hardware.
+}
+
+// Set a motor to a particular speed, or off.
+// "motor" is which motor to set.
+// "speed" is a value from -100 to 100. 0 is off,
+//         100 is full forward, -100 is full reverse
+void set_motor(int motor, int speed)
+{
+    // TODO: Set motor hardware.
+    // CONSIDER: Should setting a motor to non-zero automatically turn the brakes
+    // off?
+
+    if (motor == LEFT_MOTOR)
+        log(F("Set left motor to:"), speed);
+    else if (motor == RIGHT_MOTOR)
+        log(F("Set right motor to:"), speed);
+}
+
+///////////////////////////////////////////////
+// BRAKES
+
+// Values designating the brakes.
+const int LEFT_BRAKE = 0;
+const int RIGHT_BRAKE = 1;
+
+// Configure break hardware.
+void setup_brakes()
+{
+    // TODO: Configure brake hardware.
+}
+
+// Set a brake to on or off
+void set_brake(int brake, boolean on)
+{
+    // TODO: Set brake hardware.
+
+    const char * valueString = on ? "ON" : "OFF";
+    if (brake == LEFT_BRAKE)
+        log(F("Set left brake to:"), valueString);
+    else if (brake == RIGHT_BRAKE)
+        log(F("Set right brake to:"), valueString);
+}
+
+///////////////////////////////////////////////
+// SERVOS
+
+// Values designating the servos.
+const int PAN_SERVO = 0;
+const int TILT_SERVO = 1;
+
+// Configure servo hardware.
+void setup_servos()
+{
+    // TODO: Configure servo hardware.
+}
+
+// Set a servo to a particular setting.
+// "servo" is which servo to set.
+// "angle" is a value from -180 to 180, in degrees
+void set_servo(int servo, int angle)
+{
+    // TODO: Set servo hardware.
+
+    if (servo == PAN_SERVO) {
+        log(F("Set pan servo to:"), angle);
+    }
+    else if (servo == TILT_SERVO) {
+        log(F("Set tilt servo to:"), angle);
+    }
+}
+
+//////////////////////////////////////////////
+// FAILSAFE routines.
+//
+// The fail-safe timer puts the robot into fail-safe
+// mode if a command isn't received within a short amount
+// of time.
+
+boolean failsafe_enabled = true;  // is fail-safe enabled?
+boolean failsafe_on = false;      // is fail-safe currently on?
+long failsafe_interval = 2000;    // ms before entering fail-safe mode.
+long failsafe_last_input;         // last time a command was received.
+
+// Enter the fail-safe mode. All hardward (motors, brakes, etc.) should return
+// to the fail-safe position.
+void enter_failsafe()
+{
+    // Set motors to off and engage brakes.
+    failsafe_on = true;
+    set_motor(LEFT_MOTOR, 0);
+    set_motor(RIGHT_MOTOR, 0);
+    set_brake(LEFT_BRAKE, true);
+    set_brake(RIGHT_BRAKE, true);
+
+    log(F("Entered fail-safe mode."));
+}
+
+void exit_failsafe()
+{
+    if (failsafe_on) {
+        // If necessary, do anything to the hardware needed to exit failsafe mode.
+
+        reset_failsafe();
+        failsafe_on = false;
+        log(F("Exiting fail-safe mode."));
+    }
+}
+
+// Set the fail-safe interval to the given number of milliseconds. If
+// <= 0, turn fail-safe monitoring off.
+void set_failsafe(int intervalMillis)
+{
+    if (intervalMillis > 0) {
+        failsafe_enabled = true;
+        failsafe_interval = intervalMillis;
+        log(F("Failsafe interval set to:"), intervalMillis);
+    }
+    else {
+        failsafe_enabled = false;
+        log(F("Failsafe disabled."));
+    }
+}
+
+// Reset the fail-safe timer
+void reset_failsafe()
+{
+    failsafe_last_input = millis();
+}
+
+// Check to see if we should enter fail-safe mode.
+void check_failsafe()
+{
+    if (failsafe_enabled && !failsafe_on && (long) millis() - failsafe_last_input >= failsafe_interval) {
+        enter_failsafe();
+    }
+}
+
+
+///////////////////////////////////////////////
+// COMMAND PARSING AND DISPATCH
+
+// Dispatch a command.
+// Commands are a two-letter lowercase designator, followed by a
+// space, then an integer value (-32767 to 32768).
+void dispatch_command(char * commandString)
+{
+    log(F("Command received: "), commandString);
+
+    int len = strlen(commandString);
+    if (len < 2) {
+        log(F("Command string is too short -- ignoring"));
+        return;
+    }
+
+    // Parse the command string.
+
+    char c1 = commandString[0];
+    char c2 = commandString[1];
+
+    if (len > 2 && commandString[2] != ' ') {
+        log(F("Command string wrong format -- ignoring"));
+        return;
+    }
+
+    int value = 0;
+
+    if (len >= 4) {
+        value = atoi(commandString + 3);
+    }
+
+    // First -- commands that are allowed in fail-safe mode.
+    if (c1 == 'e' && c2 == 'f') {
+        // "ef" - exit failsafe.
+        exit_failsafe();
+        return;
+    }
+    else if (c1 == 'f' && c2 == 's') {
+        // "fs" - set failsafe interval
+        set_failsafe((long) value);
+        return;
+    }
+
+    // Don't allow other commands until exiting failsafe mode.
+
+    if (failsafe_on) {
+        // The fail-safe is ON. No commands until we explicitly exit fail-safe mode.
+        log(F("Failsafe is ON. Command ignored. Use \"ef\" command to exit fail-safe mode."));
+        return;
+    }
+
+    // Regular commands.
+    if (c1 == 'm') {
+        // "ml" - Motor Left; "mr" - Motor right
+
+        // Clamp value to -100 to 100.
+        if (value > 100)
+            value = 100;
+        else if (value < -100)
+            value = -100;
+
+        if (c2 == 'l')
+            set_motor(LEFT_MOTOR, value);
+        else if (c2 == 'r')
+            set_motor(RIGHT_MOTOR, value);
+        else
+            log(F("Invalid motor designator"));
+    }
+    else if (c1 == 's') {
+        // "sp" - pan servo, "st" - tilt servo
+
+        // Clamp value to -180 to 180.
+        if (value > 180)
+            value = 180;
+        else if (value < -180)
+            value = -180;
+
+        if (c2 == 'p')
+            set_servo(PAN_SERVO, value);
+        else if (c2 == 't')
+            set_servo(TILT_SERVO, value);
+        else
+            log(F("Invalid servo designator"));
+    }
+    else if (c1 == 'b') {
+        // "bl" - Brake Left; "br" - Brake Right
+
+        if (c2 == 'l')
+            set_brake(LEFT_BRAKE, value != 0);
+        else if (c2 == 'r')
+            set_brake(RIGHT_BRAKE, value != 0);
+        else
+            log(F("Invalid brake designator"));
+    }
+    else if (c1 == 'k' && c2 == 'a') {
+        // "ka" - keep alive for failsafe. Does nothing.
+    }
+    else {
+        log(F("Ignoring unknown command"));
+        return;
+    }
+
+    // Reset the fail-safe timer.
+    reset_failsafe();
+}
+
+///////////////////////////////////////////////
+// BLUETOOTH
+
+// Set up Bluetooth LE hardward.
+void setup_bluetooth()
+{
+    // TODO: Setup Bluetooth hardware.
+}
+
+// Check bluetooth for a command. If a command is
+// found, call dispatch_command.
+void read_bluetooth()
+{
+    // TODO: read characters from Bluetooth.
+}
+
+
+///////////////////////////////////////////////
+// SERIAL
+
+const long baudRate = 57600;
+
+const int SERIAL_BUFFER_SIZE = 80;
+char serial_buffer[SERIAL_BUFFER_SIZE];
+char * serial_next;  // Next free character in the buffer.
+
+void clear_serial_buffer()
+{
+    serial_next = serial_buffer;
+}
+
+// Set up Serial hardware.
+void setup_serial()
+{
+    Serial.begin(baudRate);
+    clear_serial_buffer();
+}
+
+// Check serial for a command. If a command is
+// found, call dispatch_command.
+void read_serial()
+{
+    while (Serial.available() > 0) {
+        int b = Serial.read();
+
+        if (b == -1 || b == 0 || b == '\r') {
+            // Ignore nulls, CR.
+        }
+        else if (b == '\n') {
+            // LF means end of command. Dispatch the command.
+            *serial_next++ ='\0';  // NUL terminate command.
+            dispatch_command(serial_buffer);
+            clear_serial_buffer();
+        }
+        else if (serial_next < serial_buffer + SERIAL_BUFFER_SIZE - 1) {
+            // Store character into buffer.
+            *serial_next++ = (char) b;
+        }
+    }
+}
+
+
+///////////////////////////////////////////////
+// SETUP and MAIN LOOP
+
+// Set up all the devices and the fail-safe timer.
+void setup()
+{
+    setup_motors();
+    setup_brakes();
+    setup_servos();
+    setup_serial();
+    setup_bluetooth();
+    reset_failsafe();
+
+    log(F("Hardware initialized."));
+
+    // Enter fail-safe mode to begin with.
+    enter_failsafe();
+}
+
+// This is the main loop. It should always complete
+// rapidly so it can continue to monitor inputs (e.g., serial port,
+// bluetooth, etc.)
+void loop()
+{
+    // Check for inputs. These functions will call dispatch_command
+    // if an input command is read.
+    read_serial();
+    read_bluetooth();
+
+    // Check if we need to enter fail-safe mode.
+    check_failsafe();
+}
+
+


PubNubJsonWifi: PubNub sample JSON-parsing client with WiFi support

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

--- examples/PubNubJsonWifi/PubNubJsonWifi.ino
+++ examples/PubNubJsonWifi/PubNubJsonWifi.ino
@@ -0,0 +1,206 @@
+/*
+  PubNub sample JSON-parsing client with WiFi support
+
+  This combines two sketches: the PubNubJson example of PubNub library
+  and the WifiWebClientRepeating example of the WiFi library.
+
+  This sample client will properly parse JSON-encoded PubNub subscription
+  replies using the aJson library. It will send a simple message, then
+  properly parsing and inspecting a subscription message received back.
+
+  This is achieved by integration with the aJson library. You will need
+  a version featuring Wiring Stream integration, that can be found
+  at http://github.com/pasky/aJson as of 2013-05-30.
+
+  Circuit:
+  * Wifi shield attached to pins 10, 11, 12, 13
+  * (Optional) Analog sensors attached to analog pin.
+  * (Optional) LEDs to be dimmed attached to PWM pins 8 and 9.
+
+
+  Please refer to the PubNubJson example description for some important
+  notes, especially regarding memory saving on Arduino Uno/Duemilanove.
+  You can also save some RAM by not using WiFi password protection.
+
+
+  created 30 May 2013
+  by Petr Baudis
+
+  https://github.com/pubnub/pubnub-api/tree/master/arduino
+  This code is in the public domain.
+  */
+
+#include <SPI.h>
+#include <WiFi.h>
+#include <PubNub.h>
+#include <aJSON.h>
+
+static char ssid[] = "yourNetwork";    // your network SSID (name)
+static char pass[] = "secretPassword"; // your network password
+static int keyIndex = 0;               // your network key Index number (needed only for WEP)
+
+const static char pubkey[] = "demo";
+const static char subkey[] = "demo";
+const static char channel[] = "hello_world";
+
+void setup()
+{
+	Serial.begin(9600);
+	Serial.println("Serial set up");
+
+	if (WiFi.status() == WL_NO_SHIELD) {
+	  Serial.println("WiFi shield not present");
+	  while(true); // stop
+	}
+
+	int status;
+	// attempt to connect to Wifi network:
+	do {
+		Serial.print("WiFi connecting to SSID: ");
+		Serial.println(ssid);
+
+		// Connect to the network. Uncomment whichever line is right for you:
+		//status = WiFi.begin(ssid); // open network
+		//status = WiFi.begin(ssid, keyIndex, key); // WEP network
+		status = WiFi.begin(ssid, pass); // WPA / WPA2 Personal network
+	} while (status != WL_CONNECTED);
+	Serial.println("WiFi set up");
+
+	PubNub.begin(pubkey, subkey);
+	Serial.println("PubNub set up");
+}
+
+aJsonObject *createMessage()
+{
+	aJsonObject *msg = aJson.createObject();
+
+	aJsonObject *sender = aJson.createObject();
+	aJson.addStringToObject(sender, "name", "Arduino");
+	aJson.addItemToObject(msg, "sender", sender);
+
+	int analogValues[6];
+	for (int i = 0; i < 6; i++) {
+		analogValues[i] = analogRead(i);
+	}
+	aJsonObject *analog = aJson.createIntArray(analogValues, 6);
+	aJson.addItemToObject(msg, "analog", analog);
+	return msg;
+}
+
+/* Process message like: { "pwm": { "8": 0, "9": 128 } } */
+void processPwmInfo(aJsonObject *item)
+{
+	aJsonObject *pwm = aJson.getObjectItem(item, "pwm");
+	if (!pwm) {
+		Serial.println("no pwm data");
+		return;
+	}
+
+	const static int pins[] = { 8, 9 };
+	const static int pins_n = 2;
+	for (int i = 0; i < pins_n; i++) {
+		char pinstr[3];
+		snprintf(pinstr, sizeof(pinstr), "%d", pins[i]);
+
+		aJsonObject *pwmval = aJson.getObjectItem(pwm, pinstr);
+		if (!pwmval) continue; /* Value not provided, ok. */
+		if (pwmval->type != aJson_Int) {
+			Serial.print("invalid data type ");
+			Serial.print(pwmval->type, DEC);
+			Serial.print(" for pin ");
+			Serial.println(pins[i], DEC);
+			continue;
+		}
+
+		Serial.print("setting pin ");
+		Serial.print(pins[i], DEC);
+		Serial.print(" to value ");
+		Serial.println(pwmval->valueint, DEC);
+		analogWrite(pins[i], pwmval->valueint);
+	}
+}
+
+void dumpMessage(Stream &s, aJsonObject *msg)
+{
+	int msg_count = aJson.getArraySize(msg);
+	for (int i = 0; i < msg_count; i++) {
+		aJsonObject *item, *sender, *analog, *value;
+		s.print("Msg #");
+		s.print(i, DEC);
+
+		item = aJson.getArrayItem(msg, i);
+		if (!item) { s.println("item not acquired"); delay(1000); return; }
+
+		processPwmInfo(item);
+
+		/* Below, we parse and dump messages from fellow Arduinos. */
+
+		sender = aJson.getObjectItem(item, "sender");
+		if (!sender) { s.println("sender not acquired"); delay(1000); return; }
+
+		s.print(" mac_last_byte: ");
+		value = aJson.getObjectItem(sender, "mac_last_byte");
+		if (!value) { s.println("mac_last_byte not acquired"); delay(1000); return; }
+		s.print(value->valueint, DEC);
+
+		s.print(" A2: ");
+		analog = aJson.getObjectItem(item, "analog");
+		if (!analog) { s.println("analog not acquired"); delay(1000); return; }
+		value = aJson.getArrayItem(analog, 2);
+		if (!value) { s.println("analog[2] not acquired"); delay(1000); return; }
+		s.print(value->valueint, DEC);
+
+		s.println();
+	}
+}
+
+void loop()
+{
+	// Intriguingly, the WiFi library doesn't seem to have a call
+	// equivalent to Ethernet.maintain();
+	//WiFi.maintain();
+
+	WiFiClient *client;
+
+	/* Publish */
+
+	Serial.print("publishing a message: ");
+	aJsonObject *msg = createMessage();
+	char *msgStr = aJson.print(msg);
+	aJson.deleteItem(msg);
+
+	// msgStr is returned in a buffer that can be potentially
+	// needlessly large; this call will "tighten" it
+	msgStr = (char *) realloc(msgStr, strlen(msgStr) + 1);
+
+	Serial.println(msgStr);
+	client = PubNub.publish(channel, msgStr);
+	free(msgStr);
+	if (!client) {
+		Serial.println("publishing error");
+		delay(1000);
+		return;
+	}
+	client->stop();
+
+	/* Subscribe and load reply */
+
+	Serial.println("waiting for a message (subscribe)");
+	client = PubNub.subscribe(channel);
+	if (!client) {
+		Serial.println("subscription error");
+		delay(1000);
+		return;
+	}
+
+	/* Parse */
+
+	aJsonClientStream stream(client);
+	msg = aJson.parse(&stream);
+	client->stop();
+	if (!msg) { Serial.println("parse error"); delay(1000); return; }
+	dumpMessage(Serial, msg);
+	aJson.deleteItem(msg);
+
+	delay(10000);
+}


Added Arduino sources

Added Arduino sources

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/phazebroek/voetbaltafel.git/'


Create  web-stepper-load-cell.ino

Create  web-stepper-load-cell.ino

error: pathspec 'web-stepper-load-cell.ino' did not match any file(s) known to git


removed a bug where the first column was not check properly

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


Adds the Arduino sketch to its skin

Adds the Arduino sketch to its skin

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

--- smart_bathroom.ino
+++ smart_bathroom.ino
@@ -0,0 +1,170 @@
+#include "neopixel/neopixel.h"
+
+#define PIXEL_PIN D2
+#define PIXEL_COUNT 64
+#define PIXEL_TYPE WS2812B
+#define sensorPin D1;
+int sensorData = 0;
+int doorStatus = 0;
+
+Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);
+
+void setup() {
+  strip.begin();
+  strip.show(); // Initialize all pixels to 'off'
+  Spark.variable(“doorStatus", &doorStatus, INT);
+}
+
+void loop() {
+
+  sensorData = digitalRead(sensorPin);
+  if (sensorData = 1)
+  {
+    doorStatus = 1;
+    doorClosed();
+  }
+  else
+  {
+    doorStatus = 0;
+    doorOpen();
+  }
+}
+
+void doorOpen() {
+    strip.setPixelColor(0, 0, 0, 0);
+    strip.setPixelColor(1, 0, 0, 0);
+    strip.setPixelColor(2, 0, 0, 0);
+    strip.setPixelColor(3, 0, 0, 0);
+    strip.setPixelColor(4, 0, 0, 0);
+    strip.setPixelColor(5, 0, 0, 0);
+    strip.setPixelColor(6, 0, 0, 0);
+    strip.setPixelColor(7, 0, 0, 0);
+    strip.setPixelColor(8, 0, 0, 0);
+    strip.setPixelColor(9, 0, 0, 0);
+    strip.setPixelColor(10, 0, 0, 0);
+    strip.setPixelColor(11, 0, 0, 0);
+    strip.setPixelColor(12, 0, 0, 0);
+    strip.setPixelColor(13, 0, 0, 0);
+    strip.setPixelColor(14, 0, 0, 0);
+    strip.setPixelColor(15, 0, 0, 0);
+    strip.setPixelColor(16, 0, 0, 0);
+    strip.setPixelColor(17, 0, 0, 0);
+    strip.setPixelColor(18, 0, 0, 0);
+    strip.setPixelColor(19, 0, 0, 0);
+    strip.setPixelColor(20, 0, 0, 0);
+    strip.setPixelColor(21, 0, 0, 0);
+    strip.setPixelColor(22, 27, 167, 46);
+    strip.setPixelColor(23, 0, 0, 0);
+    strip.setPixelColor(24, 0, 0, 0);
+    strip.setPixelColor(25, 0, 0, 0);
+    strip.setPixelColor(26, 0, 0, 0);
+    strip.setPixelColor(27, 0, 0, 0);
+    strip.setPixelColor(28, 0, 0, 0);
+    strip.setPixelColor(29, 27, 167, 46);
+    strip.setPixelColor(30, 0, 0, 0);
+    strip.setPixelColor(31, 0, 0, 0);
+    strip.setPixelColor(32, 0, 0, 0);
+    strip.setPixelColor(33, 0, 0, 0);
+    strip.setPixelColor(34, 0, 0, 0);
+    strip.setPixelColor(35, 0, 0, 0);
+    strip.setPixelColor(36, 27, 167, 46);
+    strip.setPixelColor(37, 0, 0, 0);
+    strip.setPixelColor(38, 0, 0, 0);
+    strip.setPixelColor(39, 0, 0, 0);
+    strip.setPixelColor(40, 0, 0, 0);
+    strip.setPixelColor(41, 27, 167, 46);
+    strip.setPixelColor(42, 0, 0, 0);
+    strip.setPixelColor(43, 27, 167, 46);
+    strip.setPixelColor(44, 0, 0, 0);
+    strip.setPixelColor(45, 0, 0, 0);
+    strip.setPixelColor(46, 0, 0, 0);
+    strip.setPixelColor(47, 0, 0, 0);
+    strip.setPixelColor(48, 0, 0, 0);
+    strip.setPixelColor(49, 0, 0, 0);
+    strip.setPixelColor(50, 27, 167, 46);
+    strip.setPixelColor(51, 0, 0, 0);
+    strip.setPixelColor(52, 0, 0, 0);
+    strip.setPixelColor(53, 0, 0, 0);
+    strip.setPixelColor(54, 0, 0, 0);
+    strip.setPixelColor(55, 0, 0, 0);
+    strip.setPixelColor(56, 0, 0, 0);
+    strip.setPixelColor(57, 0, 0, 0);
+    strip.setPixelColor(58, 0, 0, 0);
+    strip.setPixelColor(59, 0, 0, 0);
+    strip.setPixelColor(60, 0, 0, 0);
+    strip.setPixelColor(61, 0, 0, 0);
+    strip.setPixelColor(62, 0, 0, 0);
+    strip.setPixelColor(63, 0, 0, 0);
+    strip.setBrightness(30);
+    strip.show();
+}
+
+void doorClosed() {
+    strip.setPixelColor(0, 0, 0, 0);
+    strip.setPixelColor(1, 0, 0, 0);
+    strip.setPixelColor(2, 0, 0, 0);
+    strip.setPixelColor(3, 0, 0, 0);
+    strip.setPixelColor(4, 0, 0, 0);
+    strip.setPixelColor(5, 0, 0, 0);
+    strip.setPixelColor(6, 0, 0, 0);
+    strip.setPixelColor(7, 0, 0, 0);
+    strip.setPixelColor(8, 0, 0, 0);
+    strip.setPixelColor(9, 185, 30, 0);
+    strip.setPixelColor(10, 0, 0, 0);
+    strip.setPixelColor(11, 0, 0, 0);
+    strip.setPixelColor(12, 0, 0, 0);
+    strip.setPixelColor(13, 0, 0, 0);
+    strip.setPixelColor(14, 185, 30, 0);
+    strip.setPixelColor(15, 0, 0, 0);
+    strip.setPixelColor(16, 0, 0, 0);
+    strip.setPixelColor(17, 0, 0, 0);
+    strip.setPixelColor(18, 185, 30, 0);
+    strip.setPixelColor(19, 0, 0, 0);
+    strip.setPixelColor(20, 0, 0, 0);
+    strip.setPixelColor(21, 185, 30, 0);
+    strip.setPixelColor(22, 0, 0, 0);
+    strip.setPixelColor(23, 0, 0, 0);
+    strip.setPixelColor(24, 0, 0, 0);
+    strip.setPixelColor(25, 0, 0, 0);
+    strip.setPixelColor(26, 0, 0, 0);
+    strip.setPixelColor(27, 185, 30, 0);
+    strip.setPixelColor(28, 185, 30, 0);
+    strip.setPixelColor(29, 0, 0, 0);
+    strip.setPixelColor(30, 0, 0, 0);
+    strip.setPixelColor(31, 0, 0, 0);
+    strip.setPixelColor(32, 0, 0, 0);
+    strip.setPixelColor(33, 0, 0, 0);
+    strip.setPixelColor(34, 0, 0, 0);
+    strip.setPixelColor(35, 185, 30, 0);
+    strip.setPixelColor(36, 185, 30, 0);
+    strip.setPixelColor(37, 0, 0, 0);
+    strip.setPixelColor(38, 0, 0, 0);
+    strip.setPixelColor(39, 0, 0, 0);
+    strip.setPixelColor(40, 0, 0, 0);
+    strip.setPixelColor(41, 0, 0, 0);
+    strip.setPixelColor(42, 185, 30, 0);
+    strip.setPixelColor(43, 0, 0, 0);
+    strip.setPixelColor(44, 0, 0, 0);
+    strip.setPixelColor(45, 185, 30, 0);
+    strip.setPixelColor(46, 0, 0, 0);
+    strip.setPixelColor(47, 0, 0, 0);
+    strip.setPixelColor(48, 0, 0, 0);
+    strip.setPixelColor(49, 185, 30, 0);
+    strip.setPixelColor(50, 0, 0, 0);
+    strip.setPixelColor(51, 0, 0, 0);
+    strip.setPixelColor(52, 0, 0, 0);
+    strip.setPixelColor(53, 0, 0, 0);
+    strip.setPixelColor(54, 185, 30, 0);
+    strip.setPixelColor(55, 0, 0, 0);
+    strip.setPixelColor(56, 0, 0, 0);
+    strip.setPixelColor(57, 0, 0, 0);
+    strip.setPixelColor(58, 0, 0, 0);
+    strip.setPixelColor(59, 0, 0, 0);
+    strip.setPixelColor(60, 0, 0, 0);
+    strip.setPixelColor(61, 0, 0, 0);
+    strip.setPixelColor(62, 0, 0, 0);
+    strip.setPixelColor(63, 0, 0, 0);
+    strip.setBrightness(30);
+    strip.show();
+}
+


SD Card part for M0

SD Card part for M0

Code is now able to run on Arduino M0. Major changes:
+Size of the buffers are now 4096 bytes
+SS pin can be selected
+Improved dataSend function

Right now it saves only "dummy" values from buf01

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

--- SDModule/BatDetector/BatDetector.ino
+++ SDModule/BatDetector/BatDetector.ino
@@ -0,0 +1,97 @@
+#include <SD.h>
+#include <SPI.h>
+#define bufSize 4096
+//FILE
+File myFile;
+//----------------------SPI SPEED------------------------------------
+byte divider=3; // 48MHz / divider = SPI Speed. Max speed = 20 -> Min divider = 3 -> ~16 MHz
+byte chipSelect=4; //selects the SS pin on board
+//----------------------SD Info--------------------------------------
+
+//----------------------BUFFERs FOR ANALOG DATA----------------------
+byte buf00[bufSize]; // buffer array 1
+byte buf01[bufSize]; // buffer array 2
+word recByteCount = 0; // control byte to send certain buffer data
+
+//---------------------TEST COMMAND----------------------------------
+byte Test = 0b00000001;
+//----------------------PROTOTYPES----------------------
+void dataSend(void); //to send the data
+void SerialPrepare(void);
+void BDTest(byte);
+void testLoadBuffer(void);
+void SDPrepare(void);
+
+void setup()
+{
+  //----------------------USE LED AS AN ERROR INFORMER----------------------
+  pinMode(13, OUTPUT);
+  SerialPrepare();
+  SDPrepare();
+  BDTest(Test);
+
+
+
+}
+
+void loop()
+{
+  dataSend();
+  myFile.close();
+  SerialUSB.println("Finished");
+  while(1); //stop here
+}
+
+void SerialPrepare(void){
+  SerialUSB.begin(9600);
+  while (!SerialUSB) {
+    ; // wait for serial port to connect. Needed for native USB port only
+  }
+}
+
+void SDPrepare(void){
+  SerialUSB.print("Initializing SD card..."); //Initialization message
+  if (!SD.begin(chipSelect))
+  { //IF ERROR IS ENCOUNTERED
+    digitalWrite(13, HIGH); //LED GO ON
+    SerialUSB.println("Card failed, or not present"); //UNSUCCESSFUL MESSAGE
+    return;
+  }
+  SerialUSB.println("Card initialized.");//SUCCESSFUL MESSAGE
+  if (SD.exists("example.txt")) {
+    SerialUSB.println("example.txt exists."); //CHECK IF FILE EXISTS
+    }
+  else {
+    SerialUSB.println("example.txt doesn't exist.");
+  }
+  //----------------------CREATE AND OPEN A FILE ON SD CARD----------------------
+  myFile = SD.open("example.txt", FILE_WRITE);
+  //myFile.close(); //USE THIS TO CHECK IF EMPTY FILE CREATED
+}
+
+void dataSend(void){
+  SerialUSB.println("Saving to SD...");
+  if (recByteCount % 2*bufSize == bufSize) {
+      myFile.write(buf00,bufSize-1); // save buf01 to card
+      //recByteSaved+= 4095; //Count how many bytes were saved
+      }
+  if (recByteCount % 2*bufSize == 0) {
+      myFile.write(buf01,bufSize-1); // save buf02 to card
+      //recByteSaved+= 4095; //Count how many bytes were saved
+      }
+}
+
+void BDTest(byte Test){
+  if((Test && 0b00000001)==1){
+    SerialUSB.println("Starting to generate data");
+    testLoadBuffer();
+    SerialUSB.println("Finished generating");
+  }
+}
+
+void testLoadBuffer(void){
+  word i;
+  for(i=0; i<bufSize-1; i++){
+    buf01[i]=i;
+    }
+}


Update newLineSensor.ino

Update newLineSensor.ino

error: pathspec 'code' did not match any file(s) known to git
error: pathspec 'dump/lab2/newLineSensor.ino' did not match any file(s) known to git


Added initial totp

Added initial totp

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

--- totp/totp.ino
+++ totp/totp.ino
@@ -0,0 +1,134 @@
+#include <sha1.h>
+
+#define INTERVAL 30
+#define TOKEN_LENGTH 6
+
+
+#include <DS3231.h>
+
+
+DS3231 rtc(SDA, SCL);
+
+void printHash(uint8_t* hash, size_t len) {
+  int i;
+  for (i=0; i<len; i++) {
+    Serial.print("0123456789abcdef"[hash[i]>>4]);
+    Serial.print("0123456789abcdef"[hash[i]&0xf]);
+  }
+  Serial.println();
+}
+
+// Gets a UNIX timestamp from the RTC
+long getTimestamp() {
+  return rtc.getUnixTime(rtc.getTime());
+}
+
+// From https://code.google.com/p/google-authenticator/source/browse/libpam/base32.c
+int base32_decode(const uint8_t *encoded, uint8_t *result, int bufSize) {
+  int buffer = 0;
+  int bitsLeft = 0;
+  int count = 0;
+  for (const uint8_t *ptr = encoded; count < bufSize && *ptr; ++ptr) {
+    uint8_t ch = *ptr;
+    if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n' || ch == '-') {
+      continue;
+    }
+    buffer <<= 5;
+
+    // Deal with commonly mistyped characters
+    if (ch == '0') {
+      ch = 'O';
+    } else if (ch == '1') {
+      ch = 'L';
+    } else if (ch == '8') {
+      ch = 'B';
+    }
+
+    // Look up one base32 digit
+    if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')) {
+      ch = (ch & 0x1F) - 1;
+    } else if (ch >= '2' && ch <= '7') {
+      ch -= '2' - 26;
+    } else {
+      return -1;
+    }
+
+    buffer |= ch;
+    bitsLeft += 5;
+    if (bitsLeft >= 8) {
+      result[count++] = buffer >> (bitsLeft - 8);
+      bitsLeft -= 8;
+    }
+  }
+  if (count < bufSize) {
+    result[count] = '\000';
+  }
+  return count;
+}
+
+void totp(const uint8_t* key, const size_t len, const long time, char token[TOKEN_LENGTH]) {
+  Serial.println("Starting totp");
+  long tc = time / INTERVAL;
+  Sha1.initHmac(key, len);
+  Serial.println("inited Hmac");
+  Sha1.write((uint8_t) (tc >> 24));
+  Sha1.write((uint8_t) (tc >> 16));
+  Sha1.write((uint8_t) (tc >> 8));
+  Sha1.write((uint8_t) tc);
+
+
+
+
+  Serial.println("wrote");
+  uint8_t *hash = Sha1.resultHmac();
+
+  Serial.println("hashed");
+
+  uint8_t offset = hash[19] & 0xf;
+
+  unsigned long thing = ((hash[offset] & 0x7f) << 24)
+                      | ((hash[offset + 1] & 0xff) << 16)
+                      | ((hash[offset + 2] & 0xff) << 8)
+                      | ((hash[offset + 3] & 0xff));
+  Serial.println("thinged");
+  Serial.println(thing);
+
+  for (int i = TOKEN_LENGTH - 1; i >= 0; i--) {
+    token[i] = (thing % 10) + '0';
+    thing /= 10;
+  }
+
+  Serial.println("\ndone");
+}
+
+void setup() {
+  // put your setup code here, to run once
+  Serial.begin(115200);
+  rtc.begin();
+
+  uint8_t keyBase32[32];
+  String("salvdaxi3ipetshmxf54muq7q4k3cnrj").toCharArray((char *)keyBase32, 32);
+
+  uint8_t key[20];
+  base32_decode(keyBase32, key, 20);
+
+  uint8_t correctKey[20] = { 0x90, 0x17, 0x51, 0x82, 0xe8, 0xda, 0x1e, 0x49, 0xc8, 0xec, 0xb9, 0x7b, 0xc6, 0x52, 0x1f, 0x87, 0x15, 0xb1, 0x36, 0x29 };
+
+  printHash(correctKey, 20);
+
+
+  char token[TOKEN_LENGTH];
+
+  Serial.println("Trying to do work");
+
+  totp(key, 20, getTimestamp(), token);
+
+  Serial.println(token);
+  Serial.println("All done with work.");
+
+}
+
+void loop() {
+  // put your main code here, to run repeatedly:
+
+}


Make AES CCM debug command more verbose

Make AES CCM debug command more verbose

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


Added an example to navigate the menu over serial

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

--- examples/SerialNav/SerialNav.ino
+++ examples/SerialNav/SerialNav.ino
@@ -0,0 +1,136 @@
+/*
+  SerialNav.ino - Example code using the menu system library
+ that use serial to display the menu.
+
+ Created by Niesteszeck, Dec 1th 2013.
+ Released into the public domain.
+
+ License: GPL 3
+ */
+
+#include <MenuSystem.h>
+
+// Menu variables
+MenuSystem ms;
+Menu mm("ROOT Menu Title");
+MenuItem mm_mi1("Level 1 - Item 1 (Item)");
+MenuItem mm_mi2("Level 1 - Item 2 (Item)");
+Menu mu1("Level 1 - Item 3 (Menu)");
+MenuItem mu1_mi1("Level 2 - Item 1 (Item)");
+
+
+// Menu callback function
+// In this example all menu items use the same callback.
+
+void on_item1_selected(MenuItem* p_menu_item)
+{
+  Serial.println("Item1 Selected");
+}
+
+void on_item2_selected(MenuItem* p_menu_item)
+{
+  Serial.println("Item2 Selected");
+}
+
+void on_item3_selected(MenuItem* p_menu_item)
+{
+  Serial.println("Item3 Selected");
+}
+
+// Standard arduino functions
+
+void setup()
+{
+  Serial.begin(9600);
+  serialPrintHelp();
+  Serial.println("Setting up the menu.");
+  // Menu setup
+  /*
+  Menu Structure:
+   -Item1
+   -Item2
+   -Item3
+   -Item1
+
+   */
+  mm.add_item(&mm_mi1, &on_item1_selected);
+  mm.add_item(&mm_mi2, &on_item2_selected);
+  mm.add_menu(&mu1);
+  mu1.add_item(&mu1_mi1, &on_item3_selected);
+  ms.set_root_menu(&mm);
+  Serial.println("Menu setted.");
+  displayMenu();
+}
+
+void loop()
+{
+  // Handle serial commands
+  serialHandler();
+
+  // Wait for two seconds so the output is viewable
+  //delay(2000);
+}
+
+void displayMenu() {
+  Serial.println("");
+  // Display the menu
+  Menu const* cp_menu = ms.get_current_menu();
+
+  Serial.print("Current menu name: ");
+  Serial.println(cp_menu->get_name());
+
+  MenuComponent const* cp_menu_sel = cp_menu->get_selected();
+  for (int i = 0; i < cp_menu->get_num_menu_components(); ++i)
+  {
+    MenuComponent const* cp_m_comp = cp_menu->get_menu_component(i);
+    Serial.print(cp_m_comp->get_name());
+
+    if (cp_menu_sel == cp_m_comp)
+      Serial.print("<<< ");
+
+    Serial.println("");
+  }
+}
+
+void serialHandler() {
+  char inChar;
+  if((inChar = Serial.read())>0) {
+    switch (inChar) {
+    case 'w': // Previus item
+      ms.prev();
+      displayMenu();
+      break;
+    case 's': // Next item
+      ms.next();
+      displayMenu();
+      break;
+    case 'a': // Back presed
+      ms.back();
+      displayMenu();
+      break;
+    case 'd': // Select presed
+      ms.select();
+      displayMenu();
+      break;
+    case '?':
+    case 'h': // Display help
+      serialPrintHelp();
+      break;
+    default:
+      break;
+    }
+  }
+}
+
+void serialPrintHelp() {
+  Serial.println("***************");
+  Serial.println("w: go to previus itme (up)");
+  Serial.println("s: got to next item (down)");
+  Serial.println("a: go back (right)");
+  Serial.println("d: select \"selected\" item");
+  Serial.println("?: print this help");
+  Serial.println("h: print this help");
+  Serial.println("***************");
+
+}
+


add Cascade Color demo

add Cascade Color demo

error: pathspec 'examples-ltc/4.RainbowTape/6_CascadeColor/CascadingColors.ino' did not match any file(s) known to git

--- examples-ltc/4.RainbowTape/6_CascadeColor/CascadingColors.ino
+++ examples-ltc/4.RainbowTape/6_CascadeColor/CascadingColors.ino
@@ -0,0 +1,246 @@
+// Love to Code
+
+// Cascading colors
+
+// This example is particularly useful when mapping a few colors
+// onto a long strip of rainbow tape or other Neopixel-style (WS2812B) LEDs.
+//
+// Color values, specified in pixel_color, are interpolated onto
+// a number of pixels that should be larger than the number of
+// color values.
+//
+// The system then animates a cascade effect which lights up the
+// colors one at a time down the strip, using a cross-fade effect.
+
+#include "html_colors.h"
+// see https://github.com/chibitronics/ltc-compiler-layer/blob/master/support/html_colors.h
+
+#define PIXELCOUNT 5  // number of pixels total (including the one on the Chibi Chip)
+#define RATE  100  // a number from 1-10,000. 100 is a reasonably calm setting.
+
+#define COLORCOUNT 3
+unsigned int pixel_color[COLORCOUNT] = {
+  COLOR_RED,
+  COLOR_GREEN,
+  COLOR_BLUE,
+//  COLOR_YELLOW,  // increase COLORCOUNT and add colors here!
+};
+
+#include "Adafruit_NeoPixel.h"
+Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXELCOUNT, LED_BUILTIN_RGB, NEO_GRB + NEO_KHZ800);
+
+typedef struct RgbColor {
+  uint8_t r;
+  uint8_t g;
+  uint8_t b;
+} RgbColor;
+
+typedef struct HsvColor {
+  int h;
+  int s;
+  int v;
+} HsvColor;
+
+HsvColor hsv_master[COLORCOUNT];
+
+// from https://gist.github.com/mity/6034000
+#define HUE_DEGREE    512 // hue is 0 ... (360*HUE_DEGREE - 1)
+#define MIN(a,b)      ((a) < (b) ? (a) : (b))
+#define MAX(a,b)      ((a) > (b) ? (a) : (b))
+
+#define MIN3(a,b,c)   MIN((a), MIN((b), (c)))
+#define MAX3(a,b,c)   MAX((a), MAX((b), (c)))
+
+void rgb2hsv(uint8_t r, uint8_t g, uint8_t b, HsvColor* hsv) {
+  int m = MIN3(r, g, b);
+  int M = MAX3(r, g, b);
+  int delta = M - m;
+
+  if(delta == 0) {
+    /* Achromatic case (i.e. grayscale) */
+    hsv->h = -1;          /* undefined */
+    hsv->s = 0;
+  } else {
+    int h;
+
+    if(r == M)
+      h = ((g-b)*60*HUE_DEGREE) / delta;
+    else if(g == M)
+      h = ((b-r)*60*HUE_DEGREE) / delta + 120*HUE_DEGREE;
+    else /*if(b == M)*/
+      h = ((r-g)*60*HUE_DEGREE) / delta + 240*HUE_DEGREE;
+
+    if(h < 0)
+      h += 360*HUE_DEGREE;
+
+    hsv->h = h;
+
+    /* The constatnt 8 is tuned to statistically cause as little
+     * tolerated mismatches as possible in RGB -> HSV -> RGB conversion.
+     * (See the unit test at the bottom of this file.)
+     */
+    hsv->s = (256*delta-8) / M;
+  }
+  hsv->v = M;
+}
+
+void hsv2rgb(int h, int s, int v, RgbColor *c) {
+  uint8_t r, g, b;
+
+  if(s == 0) {
+    r = g = b = v;
+  } else {
+    int i = h / (60*HUE_DEGREE);
+    int p = (256*v - s*v) / 256;
+
+    if(i & 1) {
+      int q = (256*60*HUE_DEGREE*v - h*s*v + 60*HUE_DEGREE*s*v*i) / (256*60*HUE_DEGREE);
+      switch(i) {
+      case 1:   r = q; g = v; b = p; break;
+      case 3:   r = p; g = q; b = v; break;
+      case 5:   r = v; g = p; b = q; break;
+      }
+    } else {
+      int t = (256*60*HUE_DEGREE*v + h*s*v - 60*HUE_DEGREE*s*v*(i+1)) / (256*60*HUE_DEGREE);
+      switch(i) {
+      case 0:   r = v; g = t; b = p; break;
+      case 2:   r = p; g = v; b = t; break;
+      case 4:   r = t; g = p; b = v; break;
+      }
+    }
+  }
+
+  c->r = r;
+  c->g = g;
+  c->b = b;
+}
+
+uint32_t rgb_to_hexcolor(RgbColor rgbcolor) {
+  return rgbcolor.r << 16 | rgbcolor.g << 8 | rgbcolor.b;
+}
+
+// alpha is 0-100
+void interpolate( HsvColor a, HsvColor b, int alpha, HsvColor *c ) {
+  c->h = (a.h * alpha + b.h * (100 - alpha)) / 100;
+  c->s = (a.s * alpha + b.s * (100 - alpha)) / 100;
+  c->v = (a.v * alpha + b.v * (100 - alpha)) / 100;
+}
+
+uint8_t alpha8(uint8_t a, uint8_t alpha) {
+  uint32_t q;
+
+  if( alpha > 100 )
+    alpha = 100;
+
+  q = (uint32_t) a * (uint32_t) alpha;
+
+  return (uint8_t) ((q / 100) & 0xFF);
+}
+
+RgbColor alpha_rgb(RgbColor a, uint8_t alpha) {
+  RgbColor result;
+
+  result.r = alpha8(a.r, alpha);
+  result.g = alpha8(a.g, alpha);
+  result.b = alpha8(a.b, alpha);
+
+  return result;
+}
+
+// map values onto a uniform 16-bit axis, and then re-interpolate
+// to the sub-axes of pixel and color count...
+#define MAX_AXIS 65535
+#define PIXEL_SPACING (MAX_AXIS / PIXELCOUNT)
+#define COLOR_SPACING (MAX_AXIS / (COLORCOUNT - 1))
+
+// This computes the brightness cascade.
+// x is a number from 0-MAX_AXIS (65535) which indicates where we
+// are in the global cascade.
+// p is the pixel number we want to compute the local cascade value for
+// returns a number from 0-100 which is the brightness mask versus pixel number
+unsigned int compute_interpolation( int x, int p ) {
+  int retval = 0;
+
+  if( x < p * PIXEL_SPACING ) {
+    retval = x - (p - 1) * PIXEL_SPACING;
+    retval = (retval * 100) / PIXEL_SPACING;
+    if( retval < 0 )
+      retval = 0;
+  } else {
+    retval = (p + 1) * PIXEL_SPACING - x;
+    retval = (retval * 100) / PIXEL_SPACING;
+    if( retval < 0 )
+      retval = 0;
+  }
+
+  return (unsigned int) retval;
+}
+
+// This computes the color of a given pixel
+// The color is static: it won't change for a given pixel, but
+// the actual color of a pixel must be interpolated from the set
+// of colors specified by the user, as there may be many more pixels
+// than there are colors
+HsvColor compute_color( int p ) {
+  HsvColor c;
+  HsvColor b;
+
+  // figure out which two colors we are in between for a given pixel
+  int lower_color = (p * (MAX_AXIS / (PIXELCOUNT - 1))) / COLOR_SPACING;
+  HsvColor a = hsv_master[lower_color];
+  if( lower_color < (COLORCOUNT-1) )
+    b = hsv_master[lower_color + 1];
+  else
+    b = hsv_master[lower_color];
+
+  //int alpha = ((x - (lower_color * COLOR_SPACING)) * 100) / COLOR_SPACING;
+  int x_a = lower_color * COLOR_SPACING;
+  int x_b = (lower_color + 1) * COLOR_SPACING;
+  int x_p = p * (MAX_AXIS / (PIXELCOUNT - 1));
+
+  int alpha = 100 - (x_p - x_a) * 100 / (x_b - x_a);
+
+  interpolate(a, b, alpha, &c);
+
+  return c;
+}
+
+void setup() {
+  int i;
+
+  // copy RGB colors into HSV space
+  for( i = 0; i < COLORCOUNT; i++ ) {
+    rgb2hsv( (pixel_color[i] >> 16) & 0xff, (pixel_color[i] >> 8) & 0xff,
+	     pixel_color[i] & 0xff, &hsv_master[i] );
+  }
+
+  strip.begin();
+  strip.show();
+}
+
+int x = -PIXEL_SPACING; // state variable that goes from 0 - MAX_AXIS
+
+void loop() {
+  int j;
+  int alpha;
+  HsvColor color_point_hsv;
+  RgbColor color_point_rgb;
+  RgbColor render_color;
+
+  for( j = 0; j < PIXELCOUNT; j++ ) {
+    // figure out the base color of the pixel
+    color_point_hsv = compute_color( j );
+    hsv2rgb( color_point_hsv.h, color_point_hsv.s, color_point_hsv.v, &color_point_rgb );
+    // now figure out the brightness mask given our state variable
+    alpha = compute_interpolation( x, j );
+    render_color = alpha_rgb( color_point_rgb, alpha );
+    // set the color
+    strip.setPixelColor(j, rgb_to_hexcolor(render_color));
+  }
+  x = (x + RATE);
+  if( x > MAX_AXIS )
+    x = -PIXEL_SPACING;
+
+  strip.show();
+  delay(10);
+}


Added files via upload

Added files via upload

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

--- ReactionTimer01.ino
+++ ReactionTimer01.ino
@@ -0,0 +1,301 @@
+// Clay pigeon release reaction timer game
+// simulates a manual clay pigeon trap release button,
+// displays reaction time and statistics on the previous 10 button presses
+////
+/// Uses Adafruit OLED 1.3" 128x64 SPI display and simple momentary push button
+// and a generic Arduino Nano v3 ATMega328@16Mhz
+//////////////
+// To create your own audio sample for 'pull', record your sample in e.g. Audacity at 8Khz mono
+// in Audacity, to go Analyse->Sample Data Export-->
+// limit output to [insert length of your recording - aroun 3-5000 samples]
+// measurement scale - linear
+//data (csv)
+//no header
+//L channel first
+//chose filename as required
+// then open the CSV in e.g. Excel
+// you need to transpose the values to integers between 0 and 255
+// save from excel as CSV, then open in a text editor e.g. notepad++, and do a search and replace \r\n for ','
+// this will give you a comma separated list of samples, integer values between 0 and 255 to copy into PROGMEM below
+//////////////////////
+//// PINS ///
+// n.b. some pins unavailable for other uses as they are used for interrupt-driven async audio output by ATMega328
+// SPI Data   D8
+// SPI Clock  D9
+// SPI DC     D10
+// SPI CS     D12
+// SPI  REST  D13
+//
+// BUTTON     D2 and ground
+/////////////////
+// uses Asynchronous PWM audio playback
+// http://highlowtech.org/?p=1963
+// and Adafruit SSD1306 / GFX libraries
+// https://github.com/adafruit/Adafruit_SSD1306
+// respective licenses respected
+////////////////////
+// libs for OLED
+#include <SPI.h>
+#include <Wire.h>
+#include <Adafruit_GFX.h>
+#include <Adafruit_SSD1306.h>
+
+// libs for async audio
+#include <PCM.h>
+
+// audio clip
+const unsigned char sample[] PROGMEM = {
+  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 95, 95, 95, 95, 95, 95, 96, 96, 96, 95, 95, 95, 95, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 97, 96, 95, 96, 97, 96, 96, 97, 96, 95, 95, 96, 96, 96, 96, 96, 96, 95, 95, 95, 96, 96, 95, 95, 94, 95, 95, 95, 95, 94, 95, 95, 95, 95, 94, 95, 95, 95, 95, 96, 95, 95, 95, 94, 94, 94, 94, 95, 94, 94, 94, 93, 93, 93, 93, 94, 94, 93, 93, 93, 93, 93, 93, 93, 93, 92, 92, 93, 93, 92, 92, 93, 93, 93, 92, 93, 93, 93, 93, 93, 93, 92, 95, 88, 77, 83, 82, 82, 72, 60, 72, 73, 72, 74, 72, 80, 82, 82, 91, 91, 91, 94, 92, 93, 91, 88, 84, 84, 79, 74, 75, 74, 75, 74, 74, 75, 74, 76, 78, 80, 80, 81, 84, 84, 85, 89, 91, 89, 89, 92, 93, 91, 91, 93, 95, 95, 91, 91, 93, 94, 95, 91, 87, 87, 89, 89, 90, 91, 89, 88, 91, 96, 98, 97, 93, 97, 100, 100, 101, 96, 94, 97, 95, 94, 95, 94, 92, 93, 92, 92, 97, 96, 93, 95, 98, 99, 99, 98, 98, 99, 98, 97, 100, 101, 99, 98, 98, 98, 95, 96, 96, 95, 96, 95, 98, 101, 100, 99, 99, 102, 103, 105, 105, 105, 107, 109, 108, 108, 104, 102, 103, 101, 100, 103, 103, 101, 100, 98, 97, 98, 97, 97, 96, 95, 94, 95, 94, 91, 88, 85, 85, 85, 84, 81, 80, 79, 77, 78, 79, 79, 80, 81, 83, 86, 88, 87, 88, 90, 92, 92, 94, 97, 99, 102, 104, 104, 104, 106, 109, 113, 113, 115, 118, 121, 123, 124, 121, 119, 117, 113, 107, 105, 94, 85, 78, 73, 72, 68, 65, 66, 66, 63, 63, 65, 66, 71, 77, 80, 83, 86, 85, 86, 88, 88, 90, 96, 100, 107, 116, 118, 118, 118, 120, 127, 132, 136, 135, 138, 132, 127, 123, 113, 109, 103, 96, 92, 87, 83, 80, 80, 81, 83, 81, 77, 72, 69, 72, 79, 81, 82, 80, 79, 79, 77, 76, 77, 84, 93, 103, 111, 115, 119, 124, 127, 130, 130, 135, 142, 147, 154, 155, 150, 142, 129, 113, 105, 99, 93, 87, 79, 73, 71, 72, 72, 76, 78, 81, 83, 75, 71, 65, 66, 76, 79, 77, 73, 64, 63, 66, 71, 80, 93, 104, 117, 128, 133, 135, 138, 142, 144, 145, 153, 151, 156, 158, 134, 116, 98, 88, 90, 88, 81, 79, 75, 68, 75, 81, 85, 93, 99, 91, 83, 71, 61, 57, 58, 57, 57, 62, 62, 64, 72, 76, 81, 95, 107, 121, 138, 145, 143, 146, 141, 138, 143, 143, 144, 132, 107, 91, 78, 78, 79, 77, 79, 73, 70, 71, 80, 88, 101, 107, 108, 102, 86, 64, 51, 50, 50, 54, 62, 63, 62, 74, 80, 87, 105, 120, 136, 158, 161, 155, 155, 146, 151, 151, 152, 141, 101, 89, 70, 66, 81, 72, 75, 75, 68, 66, 81, 87, 95, 116, 110, 110, 106, 80, 60, 53, 47, 48, 55, 64, 62, 75, 82, 87, 99, 114, 133, 158, 176, 171, 162, 153, 146, 145, 158, 149, 113, 97, 72, 60, 79, 65, 71, 78, 66, 67, 83, 87, 91, 117, 108, 103, 105, 77, 50, 56, 50, 50, 60, 60, 54, 70, 82, 87, 108, 121, 137, 162, 178, 171, 174, 164, 149, 147, 157, 110, 88, 85, 49, 79, 76, 62, 69, 60, 53, 67, 90, 89, 112, 117, 97, 102, 97, 60, 55, 46, 35, 48, 59, 57, 64, 82, 78, 97, 109, 117, 143, 165, 169, 170, 169, 152, 147, 162, 144, 97, 103, 64, 61, 84, 64, 70, 70, 54, 52, 77, 80, 95, 121, 105, 95, 107, 70, 45, 52, 34, 45, 63, 56, 53, 75, 74, 88, 117, 117, 140, 167, 165, 164, 174, 150, 142, 162, 136, 88, 104, 61, 61, 94, 65, 78, 73, 56, 53, 79, 80, 95, 124, 109, 98, 108, 77, 48, 55, 39, 48, 67, 62, 54, 78, 77, 87, 119, 118, 135, 170, 164, 159, 173, 152, 141, 163, 145, 91, 105, 70, 59, 103, 73, 80, 81, 56, 52, 80, 82, 89, 124, 105, 97, 108, 74, 40, 44, 30, 40, 70, 64, 56, 77, 73, 82, 122, 121, 140, 179, 174, 160, 171, 154, 134, 170, 128, 81, 95, 50, 69, 98, 91, 94, 85, 63, 52, 79, 86, 107, 130, 114, 100, 86, 50, 34, 45, 52, 64, 71, 57, 44, 63, 68, 96, 134, 146, 168, 187, 168, 153, 156, 138, 152, 138, 84, 81, 49, 58, 81, 81, 106, 88, 72, 62, 64, 74, 102, 123, 119, 114, 88, 44, 35, 42, 48, 87, 77, 61, 52, 51, 59, 92, 124, 146, 186, 187, 173, 165, 143, 134, 158, 119, 85, 77, 29, 50, 69, 71, 106, 100, 81, 76, 77, 68, 100, 119, 111, 113, 72, 42, 42, 62, 71, 96, 85, 60, 52, 58, 69, 100, 135, 160, 185, 188, 169, 156, 149, 141, 148, 106, 81, 55, 28, 52, 51, 74, 93, 81, 83, 84, 80, 90, 115, 110, 114, 88, 58, 41, 51, 70, 86, 107, 86, 66, 61, 65, 83, 124, 147, 174, 187, 179, 166, 159, 158, 150, 128, 85, 65, 33, 37, 44, 53, 75, 68, 73, 76, 78, 93, 117, 118, 99, 85, 52, 32, 57, 63, 77, 114, 92, 74, 76, 64, 76, 127, 145, 169, 198, 176, 161, 162, 150, 145, 129, 93, 62, 37, 41, 31, 57, 64, 52, 68, 62, 63, 89, 117, 107, 112, 88, 42, 37, 44, 50, 86, 101, 85, 88, 79, 78, 110, 141, 157, 184, 189, 169, 163, 155, 143, 127, 109, 87, 58, 60, 50, 43, 68, 49, 41, 53, 43, 58, 88, 99, 94, 109, 76, 51, 58, 49, 55, 84, 75, 75, 86, 82, 107, 152, 170, 195, 210, 184, 162, 155, 135, 109, 98, 85, 55, 78, 66, 60, 88, 67, 58, 60, 46, 38, 75, 73, 79, 102, 67, 66, 74, 65, 66, 85, 61, 66, 76, 80, 113, 158, 178, 203, 219, 187, 175, 157, 122, 82, 80, 52, 45, 76, 59, 80, 87, 71, 67, 71, 48, 58, 73, 57, 76, 68, 58, 63, 77, 74, 88, 83, 64, 66, 70, 94, 134, 179, 204, 226, 218, 190, 162, 123, 72, 63, 46, 51, 64, 62, 81, 71, 77, 68, 61, 64, 66, 73, 72, 70, 54, 56, 54, 70, 82, 88, 86, 80, 72, 79, 102, 139, 185, 224, 241, 229, 213, 141, 79, 55, 18, 44, 69, 66, 93, 79, 63, 64, 62, 59, 74, 83, 65, 81, 64, 56, 75, 76, 66, 88, 70, 62, 80, 84, 107, 147, 168, 188, 225, 212, 208, 180, 102, 68, 27, 25, 47, 60, 93, 89, 84, 70, 58, 52, 60, 76, 76, 88, 74, 63, 71, 79, 78, 99, 84, 72, 72, 71, 97, 141, 178, 206, 239, 219, 203, 153, 82, 63, 27, 46, 58, 61, 86, 73, 73, 69, 62, 59, 70, 69, 65, 80, 57, 61, 74, 73, 82, 97, 77, 80, 81, 82, 114, 150, 184, 224, 250, 231, 201, 120, 68, 23, 18, 43, 49, 91, 82, 75, 71, 53, 50, 73, 86, 85, 96, 69, 51, 60, 58, 73, 96, 87, 85, 82, 70, 95, 130, 169, 222, 253, 255, 217, 134, 84, 18, 21, 39, 46, 90, 76, 73, 67, 50, 42, 67, 76, 85, 103, 74, 66, 69, 58, 71, 94, 79, 91, 90, 74, 98, 122, 143, 200, 238, 242, 216, 141, 85, 23, 28, 31, 62, 102, 85, 91, 61, 32, 28, 53, 62, 97, 107, 79, 79, 64, 54, 81, 97, 93, 114, 92, 81, 101, 114, 152, 215, 238, 237, 180, 109, 44, 6, 33, 37, 97, 112, 100, 96, 54, 32, 33, 54, 65, 99, 88, 72, 71, 64, 68, 96, 99, 104, 111, 93, 97, 112, 133, 170, 229, 235, 219, 151, 84, 17, 5, 18, 42, 104, 98, 115, 96, 55, 39, 37, 47, 74, 100, 82, 86, 69, 59, 73, 88, 89, 117, 109, 105, 119, 121, 152, 204, 240, 239, 188, 120, 39, 0, 4, 16, 84, 99, 107, 111, 63, 43, 36, 40, 58, 95, 78, 79, 74, 58, 73, 96, 90, 109, 106, 93, 113, 119, 146, 196, 239, 239, 195, 147, 48, 17, 6, 0, 76, 76, 96, 109, 74, 54, 53, 46, 50, 92, 68, 76, 76, 57, 65, 95, 79, 109, 112, 96, 123, 120, 142, 184, 230, 226, 203, 159, 60, 41, 4, 1, 74, 67, 98, 110, 69, 54, 52, 41, 59, 97, 75, 86, 80, 52, 65, 89, 70, 113, 106, 98, 121, 115, 134, 180, 221, 214, 207, 154, 70, 55, 7, 16, 76, 63, 104, 104, 65, 52, 47, 36, 65, 94, 73, 98, 79, 62, 83, 89, 80, 120, 99, 105, 124, 113, 145, 181, 204, 192, 194, 121, 74, 67, 4, 55, 74, 68, 113, 91, 57, 59, 41, 29, 81, 73, 81, 99, 75, 69, 97, 87, 97, 128, 94, 126, 127, 129, 159, 188, 172, 169, 157, 74, 90, 40, 28, 81, 59, 88, 103, 76, 60, 64, 32, 49, 77, 59, 89, 84, 70, 88, 100, 87, 123, 110, 110, 133, 133, 148, 181, 179, 147, 166, 85, 80, 68, 23, 76, 64, 75, 101, 85, 71, 74, 53, 45, 73, 50, 74, 84, 69, 81, 97, 84, 115, 122, 115, 142, 137, 150, 167, 176, 137, 154, 99, 75, 85, 30, 73, 68, 64, 96, 83, 70, 78, 64, 49, 77, 50, 58, 76, 63, 77, 99, 86, 106, 123, 107, 145, 141, 157, 176, 187, 146, 150, 103, 62, 91, 35, 73, 83, 61, 92, 86, 66, 81, 74, 53, 80, 57, 47, 70, 56, 66, 99, 87, 100, 119, 96, 128, 138, 148, 175, 192, 158, 149, 125, 57, 90, 48, 59, 96, 64, 86, 91, 65, 74, 82, 57, 81, 78, 51, 73, 59, 55, 85, 88, 89, 123, 95, 116, 130, 132, 161, 179, 176, 148, 149, 77, 84, 70, 45, 96, 71, 81, 97, 72, 70, 77, 60, 64, 83, 58, 75, 77, 63, 76, 91, 75, 109, 101, 95, 126, 119, 147, 167, 182, 152, 158, 109, 75, 93, 41, 78, 87, 62, 96, 76, 67, 77, 69, 58, 81, 66, 66, 85, 69, 78, 92, 85, 90, 109, 80, 111, 110, 123, 152, 170, 170, 153, 149, 86, 98, 72, 51, 96, 62, 80, 86, 63, 72, 74, 61, 71, 82, 58, 87, 75, 80, 92, 95, 83, 104, 84, 86, 108, 97, 135, 144, 171, 169, 156, 141, 95, 102, 66, 69, 88, 61, 88, 72, 67, 68, 70, 58, 72, 73, 66, 92, 83, 93, 102, 95, 83, 100, 70, 89, 95, 95, 126, 134, 156, 168, 155, 150, 120, 106, 88, 70, 79, 66, 72, 76, 69, 69, 65, 62, 54, 68, 67, 88, 101, 104, 112, 103, 87, 85, 75, 76, 90, 92, 112, 123, 134, 159, 160, 153, 158, 118, 115, 91, 66, 76, 59, 69, 76, 71, 69, 70, 50, 58, 69, 73, 105, 115, 118, 118, 98, 79, 75, 62, 73, 84, 92, 103, 114, 122, 142, 160, 153, 168, 134, 116, 99, 54, 66, 55, 62, 78, 77, 67, 66, 50, 46, 70, 81, 113, 135, 129, 116, 100, 66, 63, 61, 62, 86, 86, 93, 96, 97, 108, 130, 155, 177, 173, 162, 126, 93, 66, 44, 59, 60, 81, 84, 76, 65, 50, 47, 58, 88, 110, 140, 144, 131, 106, 80, 57, 53, 58, 70, 87, 91, 93, 91, 93, 98, 117, 142, 164, 175, 162, 143, 100, 76, 54, 47, 63, 68, 83, 82, 72, 61, 55, 58, 81, 103, 123, 147, 135, 129, 98, 74, 62, 60, 65, 80, 87, 85, 94, 86, 94, 106, 119, 146, 160, 163, 153, 135, 101, 84, 63, 54, 66, 65, 79, 80, 75, 68, 69, 68, 86, 106, 119, 140, 135, 127, 105, 83, 63, 57, 55, 66, 81, 87, 102, 98, 101, 103, 110, 126, 141, 156, 153, 145, 118, 92, 71, 56, 58, 68, 80, 91, 93, 84, 80, 73, 79, 92, 108, 121, 128, 121, 106, 88, 68, 65, 64, 72, 83, 88, 94, 92, 92, 94, 100, 108, 118, 123, 129, 129, 119, 113, 98, 94, 90, 86, 89, 89, 84, 85, 77, 75, 77, 79, 89, 99, 105, 111, 111, 102, 102, 91, 88, 86, 83, 84, 86, 85, 85, 87, 85, 92, 97, 103, 110, 114, 117, 121, 124, 120, 122, 112, 103, 94, 80, 76, 74, 74, 81, 89, 90, 96, 94, 91, 91, 91, 96, 103, 108, 111, 110, 97, 90, 78, 73, 78, 81, 92, 99, 104, 105, 105, 100, 99, 98, 100, 107, 112, 116, 114, 110, 102, 96, 89, 91, 93, 94, 97, 92, 89, 84, 81, 83, 87, 92, 100, 104, 108, 108, 104, 102, 98, 96, 97, 95, 93, 88, 86, 81, 83, 84, 90, 98, 104, 110, 112, 114, 113, 111, 110, 109, 109, 107, 104, 99, 91, 86, 81, 82, 85, 92, 99, 104, 104, 103, 98, 92, 93, 92, 97, 102, 105, 104, 101, 90, 84, 78, 79, 87, 95, 105, 109, 108, 101, 95, 87, 86, 88, 92, 98, 99, 98, 96, 95, 95, 99, 103, 107, 107, 105, 101, 95, 90, 88, 91, 94, 98, 100, 99, 97, 91, 90, 88, 91, 96, 99, 104, 102, 99, 93, 87, 84, 85, 89, 96, 105, 109, 113, 113, 110, 107, 105, 103, 105, 105, 102, 98, 90, 83, 77, 76, 77, 82, 87, 93, 98, 99, 101, 102, 103, 105, 107, 105, 106, 102, 99, 96, 95, 95, 95, 96, 93, 94, 92, 93, 92, 92, 93, 93, 95, 94, 96, 95, 96, 97, 96, 97, 96, 96, 95, 97, 97, 101, 103, 104, 104, 102, 102, 99, 98, 97, 96, 94, 95, 94, 93, 93, 92, 93, 93, 93, 93, 95, 95, 96, 96, 95, 94, 95, 96, 96, 97, 97, 96, 95, 96, 94, 94, 94, 96, 98, 99, 101, 102, 102, 100, 99, 96, 94, 92, 93, 93, 93, 93, 92, 91, 90, 90, 92, 95, 96, 97, 97, 95, 95, 94, 94, 95, 95, 96, 98, 98, 99, 99, 100, 101, 102, 102, 104, 103, 101, 100, 97, 96, 93, 91, 91, 89, 89, 89, 91, 91, 93, 94, 96, 98, 100, 100, 100, 98, 97, 96, 94, 94, 92, 92, 93, 94, 95, 96, 99, 100, 101, 103, 104, 104, 103, 103, 100, 98, 96, 95, 94, 92, 93, 92, 93, 92, 92, 92, 92, 93, 94, 97, 99, 101, 102, 102, 102, 100, 99, 98, 98, 98, 99, 98, 98, 97, 96, 95, 95, 95, 95, 96, 96, 95, 96, 95, 94, 94, 95, 95, 95, 94, 94, 95, 94, 95, 95, 95, 95, 96, 96, 97, 96, 96, 96, 95, 95, 94, 94, 93, 93, 92, 93, 93, 94, 94, 95, 95, 97, 97, 98, 99, 98, 98, 97, 97, 96, 96, 96, 97, 97, 96, 96, 94, 93, 92, 93, 93, 94, 96, 96, 97, 96, 96, 94, 94, 94, 94, 94, 94, 94, 95, 95, 94, 94, 94, 95, 94, 94, 94, 96, 96, 96, 96, 96, 95, 95, 96, 95, 95, 95, 95, 95, 94, 95, 96, 95, 95, 95, 95, 94, 95, 95, 95, 94, 94, 95, 95, 95, 94, 94, 95, 96, 97, 97, 97, 96, 95, 94, 94, 94, 95, 96, 96, 95, 94, 94, 94, 95, 96, 97, 99, 99, 97, 97, 97, 97, 97, 98, 98, 97, 97, 98, 98, 97, 97, 97, 96, 96, 95, 95, 95, 95, 95, 94, 94, 94, 94, 94, 94, 94, 94, 95, 94, 94, 94, 94, 94, 94, 94, 95, 95, 95, 94, 95, 95, 95, 96, 97, 97, 96, 96, 96, 96, 96, 96, 96, 96, 95, 94, 94, 93, 94, 95, 95, 96, 95, 94, 94, 93, 93, 93, 94, 95, 95, 95, 95, 95, 95, 96, 96, 96, 97, 97, 97, 97, 96, 96, 95, 94, 94, 93, 93, 93, 93, 93, 93, 92, 92, 93, 92, 92, 92,
+};
+
+// If using software SPI (the default case):
+#define OLED_MOSI   8
+#define OLED_CLK   9
+#define OLED_DC    10
+#define OLED_CS    12
+#define OLED_RESET 13
+Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
+
+#if (SSD1306_LCDHEIGHT != 64)
+#error("Height incorrect, please fix Adafruit_SSD1306.h!");
+#endif
+
+//// CONSTANTS
+int button = 2;           // button pin
+
+long starttime = 0;       //start time of 'pull'
+long endtime = 0;         //end time of 'pull'
+long mypause = 5000;      // delay between 'pull cause' -
+long myrandomtime = 0;    //variable for randomising 'pull' calls by a certain degree
+
+long mydelay = 0;         // single press reaction time
+long results[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // array to hold past 10 results
+long myaverage = 0;       //average of past 10 calls
+long mymin = 0;           // minimum reaction time of past 10 calls
+long mymax = 0;           // maximum "" ""
+long mystdev = 0;         // Standard Deviation of reaction times
+int pointer = 0;          // 'pointer' to non-zero values in an array of previous button pressses
+long mytotal = 0;         // helper for calculating averagage
+int count = 0;            //helper for calculatin g average - number of legitimate button presses
+long mysquares = 0;       // helper for calculating standard deviation
+int line1start = 30;      // pixel of dividing line for display grid
+int line2start = 84;      // "" "" ""
+
+void setup()   {
+  //start serial for debug
+  Serial.begin(9600);
+  //set button to input pullup, so we can just wire it to ground to trigger
+  pinMode(button, INPUT_PULLUP);
+  //init SSD as per sample Adafruit code
+  display.begin(SSD1306_SWITCHCAPVCC);
+  // init done
+
+  // clear display buffer
+  display.clearDisplay();
+  // portrait rotation
+  display.setRotation(1);
+  // set text and home
+  display.setTextSize(1);
+  display.setTextColor(WHITE);
+  display.setCursor(0, 0);
+
+  // intro notice
+  display.println("Pull!");
+  display.println();
+  display.println("Reaction");
+  display.println("Timer");
+  display.println("(C) Steve Wilson");
+  display.println("Feb 2016");
+  display.println("Ver 0.1");
+  display.display();
+  delay(2000);
+
+  // now clear display and set up a grid pattern for displaying results neatly
+  // this is done in a function we can re-use, as each time we draw text we need to clear the background
+  // probably a more efficient way of doing this, but hey, it works.
+  redraw();
+}
+
+
+void loop() {
+
+  //debug to serial
+  Serial.println ("Pull!");
+
+  //start playback of audio sample
+  startPlayback(sample, sizeof(sample));
+
+  //start our timer
+  starttime = millis();
+
+  //now wait for a button press - super tight loop here (could be done with interrupts, but this works fine
+  while (digitalRead(button) == HIGH) {
+  }
+
+  // button has been pressed - record time
+  endtime = millis();
+
+  //calculate reaction time
+  mydelay = endtime - starttime;
+  Serial.print("Delay: ");
+  Serial.println(mydelay);
+
+
+  //if the reaction time is a reasonable figure (less than 2 seconds), then record it as a valid result
+  // if the device is left unused, then delay is large and result is discarded
+  // this effectively puts the box into an inefficient standby until the button is pressed to restart the sequence
+  if (mydelay < 2000)
+  {
+    //we have a valid button press, store the result in our array of 10 previous valid responses
+    // rolling buffer array of previous 10 arrays. Oldest result gets overwritten
+    results[pointer] = mydelay;
+    pointer++;
+    if (pointer == 10) {
+      pointer = 0;
+    }
+
+    //reset stats
+    myaverage = 0;
+    mytotal = 0;
+    mymin = 0;
+    mymax = 0;
+    count = 0;
+    mystdev = 0;
+    mysquares = 0;
+
+
+    // calculate stats based on previous valid button presses
+    for (int i = 0; i < 10; i++)
+    {
+
+      // result in array is a valid button press, calculate stats
+      if (results[i] > 0)
+      {
+        //count how many valid presses we have
+        count++;
+
+        //sum values for working average
+        mytotal = mytotal + results[i];
+
+        //get the minimum value in the array
+        if (mymin == 0) {
+          mymin = results[i];
+        }
+        if (results[i] < mymin) {
+          mymin = results[i];
+        }
+
+        //max value in array
+        if (results[i] > mymax) {
+          mymax = results[i];
+        }
+
+      }//end if array unit greater than zero
+    }//end loop over results array
+
+    //having looped over all valid results, now calculate the average reaction time and print
+    myaverage = mytotal / count;
+    Serial.print("Average: ");
+    Serial.println (myaverage);
+
+
+    //calculate standard deviation
+    for (int i = 0; i < 10; i++)
+    {
+      if (results[i] > 0) {
+        long var = results[i] - myaverage;
+        mysquares = mysquares + (var * var);
+      }
+    }
+    long sqmean = mysquares / count;
+    mystdev = sqrt(sqmean);
+
+
+
+  } //end if delay less than 2000
+
+  //debug - output the array
+  for (int i = 0; i < 10; i++) {
+    Serial.println(results[i]);
+  }
+  //debug output raw values used in calcs
+  Serial.println(myaverage);
+  Serial.println(count);
+  Serial.println(mymin);
+  Serial.println(mymax);
+  Serial.println(mystdev);
+
+  //display results on OLED
+
+  //clear display
+  display.clearDisplay();
+
+  //redraw grid
+  redraw();
+
+  // put last reaction time at top in big fint
+  display.setCursor(0, 0);
+  display.setTextSize(2);
+  display.print(mydelay);
+  display.setTextSize(1);
+  display.setCursor(50, 0);
+  display.print (" m");
+  display.setCursor(50, 10);
+  display.print (" s");
+
+  //minimum - top right of grid
+  display.setCursor(5, line1start + 30);
+  display.print(mymin);
+  //max - top  left
+  display.setCursor(37, line1start + 30);
+  display.print(mymax);
+  // average
+  display.setCursor(5, line2start + 30);
+  display.print(myaverage);
+  //std deviation
+  display.setCursor(37, line2start + 30);
+  display.print(mystdev);
+  //draw
+  display.display();
+
+  //now wait for our given pause (e.g. 6 seconds +-1 second) between 'pull' calls to mimic a real DTL/ABT layout
+  delay(mypause + random(0, 2000));
+
+}//end loop
+
+
+
+//function to clear display and draw simple grid
+void redraw() {
+
+  display.clearDisplay();
+  display.setCursor(0, 0);
+  //fast horiz line at 32
+
+  display.drawFastHLine(0, line1start, 64, 1);
+  display.drawFastHLine(0, line2start, 64, 1);
+  display.drawFastVLine(32, line1start, 128, 1);
+  display.display();
+  display.setCursor(0, 0);
+  display.setTextSize(2);
+  // display.println("123 ms");
+  // display.display();
+  //vast vert line at 64
+  display.setTextSize(1);
+  display.setCursor(0, (line1start + 2));
+  display.print("Best");
+
+  display.setCursor(32, (line1start + 2));
+  display.print("Worst");
+  display.setCursor(5, (line2start + 2));
+
+  display.print("Avg:");
+  display.setCursor(35, (line2start + 2));
+
+  display.print("Dev:");
+  display.display();
+
+}
+
+
+


some more visisble result

some more visisble result

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


Motor Demo

Motor Demo

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

--- rsc/L298N_Motor_Controller_Demo.ino
+++ rsc/L298N_Motor_Controller_Demo.ino
@@ -0,0 +1,83 @@
+// connect motor controller pins to Arduino digital pins
+// motor one
+int enA = 10;
+int in1 = 9;
+int in2 = 8;
+// motor two
+int enB = 5;
+int in3 = 7;
+int in4 = 6;
+void setup()
+{
+  // set all the motor control pins to outputs
+  pinMode(enA, OUTPUT);
+  pinMode(enB, OUTPUT);
+  pinMode(in1, OUTPUT);
+  pinMode(in2, OUTPUT);
+  pinMode(in3, OUTPUT);
+  pinMode(in4, OUTPUT);
+}
+void demoOne()
+{
+  // this function will run the motors in both directions at a fixed speed
+  // turn on motor A
+  digitalWrite(in1, HIGH);
+  digitalWrite(in2, LOW);
+  // set speed to 200 out of possible range 0~255
+  analogWrite(enA, 200);
+  // turn on motor B
+  digitalWrite(in3, HIGH);
+  digitalWrite(in4, LOW);
+  // set speed to 200 out of possible range 0~255
+  analogWrite(enB, 200);
+  delay(2000);
+  // now change motor directions
+  digitalWrite(in1, LOW);
+  digitalWrite(in2, HIGH);
+  digitalWrite(in3, LOW);
+  digitalWrite(in4, HIGH);
+  delay(2000);
+  // now turn off motors
+  digitalWrite(in1, LOW);
+  digitalWrite(in2, LOW);
+  digitalWrite(in3, LOW);
+  digitalWrite(in4, LOW);
+}
+void demoTwo()
+{
+  // this function will run the motors across the range of possible speeds
+  // note that maximum speed is determined by the motor itself and the operating voltage
+  // the PWM values sent by analogWrite() are fractions of the maximum speed possible
+  // by your hardware
+  // turn on motors
+  digitalWrite(in1, LOW);
+  digitalWrite(in2, HIGH);
+  digitalWrite(in3, LOW);
+  digitalWrite(in4, HIGH);
+  // accelerate from zero to maximum speed
+  for (int i = 0; i < 256; i++)
+  {
+    analogWrite(enA, i);
+    analogWrite(enB, i);
+    delay(20);
+  }
+  // decelerate from maximum speed to zero
+  for (int i = 255; i >= 0; --i)
+  {
+    analogWrite(enA, i);
+    analogWrite(enB, i);
+    delay(20);
+  }
+  // now turn off motors
+  digitalWrite(in1, LOW);
+  digitalWrite(in2, LOW);
+  digitalWrite(in3, LOW);
+  digitalWrite(in4, LOW);
+}
+void loop()
+{
+  demoOne();
+  delay(1000);
+  demoTwo();
+  delay(1000);
+}


Create game.ino

Create game.ino

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

--- game.ino
+++ game.ino
@@ -0,0 +1,208 @@
+// led matrix (8 * 8) pin to arduino pin mappings
+const int pin1 = 17;
+const int pin2 = 15;
+const int pin3 = 7;
+const int pin4 = 8;
+const int pin5 = 14;
+const int pin6 = 10;
+const int pin7 = 16;
+const int pin8 = 4;
+const int pin9 = 2;
+const int pin10 = 9;
+const int pin11 = 11;
+const int pin12 = 5;
+const int pin13 = 6;
+const int pin14 = 3;
+const int pin15 = 12;
+const int pin16 = 13;
+
+// led matrix pin to row/col mappings
+const int row1 = pin9;
+const int row2 = pin14;
+const int row3 = pin8;
+const int row4 = pin12;
+const int row5 = pin1;
+const int row6 = pin7;
+const int row7 = pin2;
+const int row8 = pin5;
+const int col1 = pin13;
+const int col2 = pin3;
+const int col3 = pin4;
+const int col4 = pin10;
+const int col5 = pin6;
+const int col6 = pin11;
+const int col7 = pin15;
+const int col8 = pin16;
+
+// easy access by index later
+const int rows[8] = {row1, row2, row3, row4, row5, row6, row7, row8};
+const int cols[8] = {col1, col2, col3, col4, col5, col6, col7, col8};
+
+// matrix alive or empty states
+int matrix[8][8] = {};
+
+// hold next gen matrix alive or empty states
+int next_matrix[8][8] = {};
+
+// light up leds based on matrix states
+void render()
+{
+  for (int row=0; row<8; row++)
+  {
+    digitalWrite(rows[row], HIGH);
+    for (int col=0; col<8; col++)
+    {
+      int led = matrix[row][col];
+      // when the row is HIGH and the col is LOW, the LED where they meet turns on
+      digitalWrite(cols[col], led == 1 ? LOW : HIGH);
+      if (led == 1)
+      {
+        digitalWrite(cols[col], HIGH);
+      }
+    }
+    digitalWrite(rows[row], LOW);
+  }
+}
+
+// dim the entire matrix
+void dim()
+{
+  for (int row=0; row<8; row++)
+  {
+    digitalWrite(rows[row], LOW);
+    for (int col=0; col<8; col++)
+    {
+      digitalWrite(cols[col], HIGH);
+    }
+  }
+}
+
+// randomize the matrix inital states for conway game of live
+void chance()
+{
+  for (int row=0; row<8; row++)
+  {
+    for (int col=0; col<8; col++)
+    {
+      matrix[row][col] = random(2);
+    }
+  }
+}
+
+// seed the matrix inital states to result in glider for conway game of live
+void glider()
+{
+  for (int row=0; row<8; row++)
+  {
+    for (int col=0; col<8; col++)
+    {
+      matrix[row][col] = 0;
+    }
+  }
+  matrix[2][2] = 1;
+  matrix[1][2] = 1;
+  matrix[0][2] = 1;
+  matrix[2][1] = 1;
+  matrix[1][0] = 1;
+}
+
+// calculate new matrix states
+void next_gen()
+{
+  for (int row=0; row<8; row++)
+  {
+    for (int col=0; col<8; col++)
+    {
+      // check neighbor count
+      int count = 0;
+      int lrow = row - 1 >= 0 ? row - 1 : row, hrow = row + 1 < 8 ? row + 1 : row;
+      int lcol = col - 1 >= 0 ? col - 1 : col, hcol = col + 1 < 8 ? col + 1 : col;
+      for (int r=lrow; r<=hrow; r++)
+      {
+        for (int c=lcol; c<=hcol; c++)
+        {
+          if (r != row || c != col)
+          {
+            if (matrix[r][c] == 1)
+            {
+              count += 1;
+            }
+          }
+        }
+      }
+
+      // based on neighbor count, decide to live or die
+      int cell = matrix[row][col];
+      if (cell == 1) // live cell
+      {
+        if (count < 2 || count > 3)
+        {
+          cell = 0; // to die
+        }
+      }
+      else // empty cell
+      {
+        if (count > 2)
+        {
+          cell = 1; // to live
+        }
+      }
+
+      // update new matrix state
+      next_matrix[row][col] = cell;
+    }
+  }
+
+  // ** update matrix in one go
+  for (int row=0; row<8; row++)
+  {
+    for (int col=0; col<8; col++)
+    {
+      matrix[row][col] = next_matrix[row][col];
+    }
+  }
+}
+
+// arduino life cycle method: setup is called once
+void setup()
+{
+  // set arduino pin mode
+  for (int i=2; i<18; i++)
+  {
+    pinMode(i, OUTPUT);
+  }
+
+  // setup initial pattern for matrix
+  glider();
+
+  // dim entire matrix
+  dim();
+
+  // debug to console if needed
+  Serial.begin(9600);
+  Serial.println("Game on!");
+}
+
+int loops = 0; // think of one loop is one day
+int lifespan = 365 * 3; // 365 * 3 days per generation
+
+// arduino life cycle method: it's called very rapidly, treat one call as one day
+void loop()
+{
+  // just another day
+  loops += 1;
+
+  // next generation is to come
+  if (loops % lifespan == 0)
+  {
+    loops = 0;
+    next_gen();
+  }
+
+  // called every loop to keep showing the matrix states
+  render();
+}
+
+
+
+


add avr programmer code for iuppiter

add avr programmer code for iuppiter

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

--- c/wifi_avrisp_programmer/wifi_avrisp_programmer.ino
+++ c/wifi_avrisp_programmer/wifi_avrisp_programmer.ino
@@ -0,0 +1,61 @@
+#include <Arduino.h>
+
+#include <SPI.h>
+#include <ESP8266WiFi.h>
+#include <ESP8266mDNS.h>
+#include <ESP8266AVRISP.h>
+
+const char* host = "esp8266-avrisp";
+const char* ssid = "IoT_Dobbi";
+const char* pass = "was7thod";
+const uint16_t port = 328;
+const uint8_t reset_pin = 5;
+
+ESP8266AVRISP avrprog(port, reset_pin);
+
+void setup() {
+  Serial.begin(115200);
+  avrprog.setReset(false);
+
+  WiFi.begin(ssid, pass);
+  while (WiFi.waitForConnectResult() != WL_CONNECTED);
+
+  MDNS.begin(host);
+  MDNS.addService("avrisp", "tcp", port);
+
+  IPAddress local_ip = WiFi.localIP();
+  Serial.print("\n\nIP address: ");
+  Serial.println(local_ip);
+
+  // listen for avrdudes
+  avrprog.begin();
+}
+
+void loop() {
+    static AVRISPState_t last_state = AVRISP_STATE_IDLE;
+    AVRISPState_t new_state = avrprog.update();
+    if (last_state != new_state) {
+        switch (new_state) {
+            case AVRISP_STATE_IDLE: {
+                //Serial.printf("[AVRISP] now idle\r\n");
+                // Use the SPI bus for other purposes
+                break;
+            }
+            case AVRISP_STATE_PENDING: {
+                //Serial.printf("[AVRISP] connection pending\r\n");
+                // Clean up your other purposes and prepare for programming mode
+                break;
+            }
+            case AVRISP_STATE_ACTIVE: {
+                //Serial.printf("[AVRISP] programming mode\r\n");
+                // Stand by for completion
+                break;
+            }
+        }
+        last_state = new_state;
+    }
+    // Serve the client
+    if (last_state != AVRISP_STATE_IDLE) {
+        avrprog.serve();
+    }
+}


Create Test_analogue.ino

Create Test_analogue.ino

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

--- ESP8266-code/Test_analogue.ino
+++ ESP8266-code/Test_analogue.ino
@@ -0,0 +1,74 @@
+#define ADC_REF 3.3  // Reference voltage
+#define ADC A0   // Analog input
+
+#define STATSON D7 // take this pin high to turn on stats
+
+// Sensor
+String sensorName = "Angle";
+
+// sampling
+int samples = 25;
+int delayms = 1000;
+
+void setup()
+{
+  Serial.begin(9600);
+
+  delay(100);  // sensor startup delay
+
+  Serial.println();
+  Serial.println(sensorName);
+}
+
+
+void loop() {
+  if (digitalRead(STATSON))
+       gatherStats();
+  else getSample();
+  delay(delayms);
+}
+
+void gatherStats() {
+  float sum=0;
+  float sum1=0;
+  float sum2=0;
+  float value, k;
+  k = asValue(getVoltage());
+  Serial.println(String("k = ") + k);
+  delay(delayms);
+  for(int i =0; i<samples; i++) {
+      float voltage = getVoltage();
+      value =asValue(voltage);
+      Serial.println(String("value = ") + value);
+      sum += value;
+      sum1 += (value - k);
+      sum2 += (value - k)* (value - k);
+      delay(delayms);
+  }
+  float mean = sum / samples ;
+  float stddev = sqrt((sum2 - (sum1 * sum1) / samples) / (samples - 1));
+  Serial.println(String("Statistics for ") + samples + " samples");
+  Serial.println(String("mean =")+ mean + " StdDev= " + stddev + " 95% interval = " + (mean - 2 * stddev) + "," + (mean+ 2 * stddev));
+  if (digitalRead(LOGON) ==1 )
+      log_data(String("average=")+mean+"&stddev="+stddev);
+
+}
+
+void getSample() {
+      float voltage = getVoltage();
+      float value =asValue(voltage);
+      Serial.println(String("voltage = ") + voltage + " value=" +value);
+}
+
+float getVoltage()
+{
+  int sensor_value;
+  sensor_value = analogRead(ADC);
+  float voltage = (float)sensor_value*ADC_REF/1024;
+  return voltage;
+}
+
+float asValue(float voltage) {
+    return voltage*270/ADC_REF;  // 270 degrees full turn
+}
+


Test code for the line follow

Test code for the line follow

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

--- DOCS/line_follow_head_test/line_follow_head_test.ino
+++ DOCS/line_follow_head_test/line_follow_head_test.ino
@@ -0,0 +1,81 @@
+#define FAR_LEFT A0
+#define LEFT A1
+#define CENTER_LEFT A2
+#define CENTER_RIGHT A3
+#define RIGHT A4
+#define FAR_RIGHT A5
+
+#define WB_THRESHOLD 400
+#define IR_DELAY 140
+
+void setup()
+{
+  Serial.begin(9600);
+  pinMode(FAR_LEFT, INPUT);
+  pinMode(LEFT, INPUT);
+  pinMode(CENTER_LEFT, INPUT);
+  pinMode(CENTER_RIGHT, INPUT);
+  pinMode(RIGHT, INPUT);
+  pinMode(FAR_RIGHT, INPUT);
+  pinMode(LED_BUILTIN, OUTPUT);
+}
+
+boolean toDigital(uint8_t pin){
+  int reading = analogRead(pin);
+  delayMicroseconds(IR_DELAY);
+  // Serial.println(reading);
+  return reading > WB_THRESHOLD;
+}
+
+void print_digital_readings(){
+
+   boolean far_left =     toDigital(FAR_LEFT);
+   boolean left =         toDigital(LEFT);
+   boolean center_left  = toDigital(CENTER_LEFT);
+   boolean center_right = toDigital(CENTER_RIGHT);
+   boolean right =        toDigital(RIGHT);
+   boolean far_right =    toDigital(FAR_RIGHT);
+
+
+   Serial.print(far_left);
+   Serial.print("\t");
+   Serial.print(left);
+   Serial.print("\t");
+   Serial.print(center_left);
+   Serial.print("\t");
+   Serial.print(center_right);
+   Serial.print("\t");
+   Serial.print(right);
+   Serial.print("\t");
+   Serial.println(far_right);
+
+}
+
+void print_analog_readings(){
+
+   int far_left =     analogRead(FAR_LEFT);
+   int left =         analogRead(LEFT);
+   int center_left  = analogRead(CENTER_LEFT);
+   int center_right = analogRead(CENTER_RIGHT);
+   int right =        analogRead(RIGHT);
+   int far_right =    analogRead(FAR_RIGHT);
+
+   Serial.print(far_left);
+   Serial.print("\t");
+   Serial.print(left);
+   Serial.print("\t");
+   Serial.print(center_left);
+   Serial.print("\t");
+   Serial.print(center_right);
+   Serial.print("\t");
+   Serial.print(right);
+   Serial.print("\t");
+   Serial.println(far_right);
+
+}
+
+void loop(){
+  print_analog_readings();
+  //print_digital_readings();
+  delay(20);
+}


Working version of SPI - requires updated libraries (to be documented).

error: pathspec 'test/PoE-test/ETH-LAN8720-OTA-SPI/ETH-LAN8720-OTA-SPI.ino' did not match any file(s) known to git

--- test/PoE-test/ETH-LAN8720-OTA-SPI/ETH-LAN8720-OTA-SPI.ino
+++ test/PoE-test/ETH-LAN8720-OTA-SPI/ETH-LAN8720-OTA-SPI.ino
@@ -0,0 +1,221 @@
+/* SPI - sends an ever increasing count from MO->SI.
+ *
+ */
+
+#define ETH_PHY_ADDR      1
+#define ETH_PHY_MDC       23
+#define ETH_PHY_MDIO      18
+#define ETH_PHY_POWER     17
+#define ETH_PHY_TYPE      ETH_PHY_LAN8720
+
+#define SPI__SCK     (14)
+#define SPI__MISO    (12)
+#define SPI__MOSI    (13)
+#define SPI__SS      (15)
+
+#include <ETH.h>
+#include <ArduinoOTA.h>
+#include <SPI.h>
+
+SPIClass spirfid = SPIClass(VSPI);
+
+static bool eth_connected = false;
+
+static bool ota = false;
+void enableOTA() {
+  if (ota)
+    return;
+
+  // Port defaults to 3232
+  // ArduinoOTA.setPort(3232);
+
+  // Hostname defaults to esp3232-[MAC]
+  // ArduinoOTA.setHostname("myesp32");
+
+  // No authentication by default
+  // ArduinoOTA.setPassword("admin");
+
+  // Password can be set with it's md5 value as well
+  // MD5(admin) = 21232f297a57a5a743894a0e4a801fc3
+  // ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3");
+
+
+  ArduinoOTA.onStart([]() {
+    String type;
+    if (ArduinoOTA.getCommand() == U_FLASH)
+      type = "sketch";
+    else // U_SPIFFS
+      type = "filesystem";
+
+    // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
+    Serial.println("Start updating " + type);
+  });
+
+  ArduinoOTA.onEnd([]() {
+    Serial.println("\nEnd");
+  });
+
+  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
+    Serial.printf("Progress: %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");
+  });
+
+  // Unfortunately - deep in OTA it auto defaults to Wifi. So we
+  // force it to ETH -- requires pull RQ https://github.com/espressif/arduino-esp32/issues/944
+  // and https://github.com/espressif/esp-idf/issues/1431.
+  //
+  ArduinoOTA.begin(TCPIP_ADAPTER_IF_ETH);
+  ota = true;
+
+  Serial.println("\nOTA enabled too\n");
+}
+
+void WiFiEvent(WiFiEvent_t event)
+{
+  switch (event) {
+    case SYSTEM_EVENT_ETH_START:
+      Serial.println("ETH Started");
+      //set eth hostname here
+      ETH.setHostname("esp32-ethernet");
+      break;
+    case SYSTEM_EVENT_ETH_CONNECTED:
+      Serial.println("ETH Connected");
+      break;
+    case SYSTEM_EVENT_ETH_GOT_IP:
+    case SYSTEM_EVENT_STA_GOT_IP:
+      Serial.print("ETH MAC: ");
+      Serial.print(ETH.macAddress());
+      Serial.print(", IPv4: ");
+      Serial.print(ETH.localIP());
+      if (ETH.fullDuplex()) {
+        Serial.print(", FULL_DUPLEX");
+      }
+      Serial.print(", ");
+      Serial.print(ETH.linkSpeed());
+      Serial.printf("Mbps (event %d)\n", event);
+      eth_connected = true;
+      break;
+    case SYSTEM_EVENT_ETH_DISCONNECTED:
+      Serial.printf("ETH Disconnected (event %d)\n", event);
+      eth_connected = false;
+      break;
+    case SYSTEM_EVENT_ETH_STOP:
+      Serial.println("ETH Stopped");
+      eth_connected = false;
+      break;
+    default:
+      Serial.printf("Unknown event %d\n", event);
+      break;
+  }
+}
+
+void testClient(const char * host, uint16_t port)
+{
+  Serial.print("\nconnecting to ");
+  Serial.println(host);
+
+  WiFiClient client;
+  if (!client.connect(host, port)) {
+    Serial.println("connection failed");
+    return;
+  }
+  client.printf("GET / HTTP/1.1\r\nHost: %s\r\n\r\n", host);
+  while (client.connected() && !client.available());
+  while (client.available()) {
+    Serial.write(client.read());
+  }
+
+  Serial.println("closing connection\n");
+  client.stop();
+}
+
+void setup()
+{
+  const char  * pname = rindex(__FILE__, '/');
+
+  Serial.begin(115200);
+  Serial.print("\n\n\nStart ");
+  Serial.print(pname);
+  Serial.println(" " __DATE__ " " __TIME__);
+
+  WiFi.onEvent(WiFiEvent);
+
+  ETH.begin();
+
+  Serial.println("SPI init");
+  pinMode(SPI__SS, OUTPUT);
+  digitalWrite(SPI__SS,HIGH);
+
+  spirfid.begin(SPI__SCK, SPI__MISO, SPI__MOSI, SPI__SS);
+
+  Serial.println("setup() done");
+}
+
+
+void loop()
+{
+  if (eth_connected) {
+    if (!ota)
+      enableOTA();
+    ArduinoOTA.handle();
+  }
+
+  // The crux of this test -- send an every increasing count to the Slave In.
+  //
+  static byte i;
+  pinMode(SPI__SS, OUTPUT);
+  digitalWrite(SPI__SS,LOW);
+  spirfid.transfer(i++);
+  digitalWrite(SPI__SS,HIGH);
+
+#if 0
+for(int i=0; i < 20;i++){
+  {
+    const int pin = SPI__MOSI;
+    pinMode(pin, OUTPUT);
+    static byte i;
+    digitalWrite(pin, i % 2); i++;
+  }
+  {
+    const int pin = SPI__MISO;
+    pinMode(pin, OUTPUT);
+    static byte i;
+    digitalWrite(pin, i % 4); i++;
+  }
+  {
+    const int pin = SPI__SS;
+    pinMode(pin, OUTPUT);
+    static byte i;
+    digitalWrite(pin, i % 8); i++;
+  }
+  {
+    const int pin = SPI__SCK;
+    pinMode(pin, OUTPUT);
+    static byte i;
+    digitalWrite(pin, i % 16); i++;
+  }
+}
+#endif
+
+  static unsigned long tock = 0;
+  if (millis() - tock  > 30 * 1000) {
+    Serial.println("Tock - 30 seconds");
+    tock = millis();
+  }
+
+#if 0
+  static unsigned long google = 0;
+  if (eth_connected && millis() - google > 60 * 1000) {
+    testClient("google.com", 80);
+    google = millis();
+  }
+#endif
+}


Kód z lekce

Kód z lekce

error: pathspec 'lekce/lekce05/work/disp/disp.ino' did not match any file(s) known to git

--- lekce/lekce05/work/disp/disp.ino
+++ lekce/lekce05/work/disp/disp.ino
@@ -0,0 +1,22 @@
+#include <Wire.h>
+#define ADDR 0x27
+
+void setup() {
+  Wire.begin();
+}
+
+void loop() {
+  digit(0, 0b00101101);
+  digit(1, 0b00101101);
+  digit(2, 0b00101101);
+  digit(3, 0b00101101);
+  delay(1000);
+}
+
+void digit(byte n, byte s) {
+  Wire.beginTransmission(ADDR);
+  Wire.write(n); // <- pozice
+  Wire.write(s); // <- segmenty
+  Wire.endTransmission();
+}
+


parsing serial data

parsing serial data

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

--- Playground/SerialPingPong2/SerialPingPong2.ino
+++ Playground/SerialPingPong2/SerialPingPong2.ino
@@ -0,0 +1,52 @@
+void setup()
+{
+  Serial.begin(115200);
+}
+
+void loop()
+{
+  checkSerial();
+}
+
+#define MAX 32
+char buf[MAX] = { '\0' };
+byte index = 0;
+
+void checkSerial()
+{
+  while (Serial.available() > 0)
+  {
+    char received = Serial.read();
+    buf[index] = received;
+    buf[index+1] = '\0';
+    ++index;
+    if(index == MAX) { index = 0; }
+  }
+
+  if(index != 0 && buf[index-1] == '\n')
+  {
+    Serial.print("1: "); Serial.print(buf);
+    String sbuf(buf);
+    Serial.print("2: "); Serial.print(sbuf);
+
+    if(index == 14)
+    {
+      String s("");
+      s = sbuf.substring(0, 2);  int x = s.toInt();
+      s = sbuf.substring(2, 4);  int y = s.toInt();
+      s = sbuf.substring(4, 7);  int RED = s.toInt();
+      s = sbuf.substring(7, 10);  int GREEN = s.toInt();
+      s = sbuf.substring(10, 13); int BLUE = s.toInt();
+
+      Serial.print("x: "); Serial.println(x);
+      Serial.print("y: "); Serial.println(y);
+      Serial.print("R: "); Serial.println(RED);
+      Serial.print("G: "); Serial.println(GREEN);
+      Serial.print("B: "); Serial.println(BLUE);
+      Serial.println("----------");
+    }
+
+    index = 0;
+  }
+}
+


Added correct file

Added correct file

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

--- hardware/REV14/REV14test/REV14test.ino
+++ hardware/REV14/REV14test/REV14test.ino
@@ -0,0 +1,288 @@
+/*
+The OpenTRV project licenses this file to you
+under the Apache Licence, Version 2.0 (the "Licence");
+you may not use this file except in compliance
+with the Licence. You may obtain a copy of the Licence at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the Licence is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the Licence for the
+specific language governing permissions and limitations
+under the Licence.
+
+Author(s) / Copyright (s): Deniz Erbilgin 2016
+*/
+
+/**
+ * Set of tests for REV14 hardware.
+ * Tests:
+ *     - Supply voltage : Print measured voltage to serial
+ *     - Xtal           : Check resonator frequency against internal RC
+ *     - Phototransistor: Perform a reading
+ *     - TMP112         : Test for ACK
+ *     - SHT21          : Test for ACK
+ *     - QM-1 module    : Test for ACK
+ *     - RN2483         : Test for ACK
+ *     - Mobdet         : TBD
+ *     - DS18B20        : TBD
+ *
+ * @todo   Work out how to setup serial connection to RN2483
+ *         Move stuff out into libraries
+ */
+
+#include <Wire.h>
+#include <OTV0p2Base.h>
+
+/************************* Pin Defs **********************************/
+// Power control pins
+static const uint8_t IO_Powerup_pin  =  7; // IO power up pin.
+static const uint8_t BoostRegEn_pin  = A3; // Boost regulator enable pin.
+// Peripheral connect pins
+static const uint8_t lightSensor_pin = A0; // analogue pin phototransistor is connected to.
+static const uint8_t QM1_IRQ_pin     =  6; // interrupt pin connected to QM-1 module.
+static const uint8_t RN2483_Rx_pin   =  8; // Software serial Rx pin connected to RN2483.
+static const uint8_t RN2483_Tx_pin   =  5; // Software serial Tx pin connected to RN2483.
+static const uint8_t RN2483_Rst_pin  = A2; // Pin connected to RN2483 reset line.
+
+/************************ Other Constants ****************************/
+// Xtal
+static const uint8_t xtalExpectedValue = 122;  // Expected value from xtal
+static const uint8_t xtalMaxDeviation  =   2;  // Max acceptable deviation from xtal
+// TMP112
+static const uint8_t tmp112_i2cAddr = 0x48; // TMP112 I2C bus address
+// SHT21
+static const uint8_t sht21_i2cAddr  = 0x40; // SHT21 I2C bus address
+// QM-1
+static const uint8_t qm1_i2cAddr    = 0x09; // QM1 I2C bus address
+// RN2483
+static const uint16_t RN2483_baud    = 23040;     // Baud rate to talk to RN2483 at. Need to autobaud with break+'U' after reset.
+//static const char    RN2483_END[3]  = "\r\n";   // RN2483 message end
+
+/************************ Objects and variables **********************/
+OTV0P2BASE::SupplyVoltageCentiVolts Supply_cV;
+OTV0P2BASE::OTSoftSerial rn2483(RN2483_Rx_pin, RN2483_Tx_pin);
+
+void setup() {
+    /**
+     * 1) Put all pins in safe state (low power not as important) - AVR should automatically init correctly
+     * 2) Setup Xtal first to give time to settle
+     * 3) Setup ADC0
+     * 4) Setup software serial
+     * 5) Setup I2C
+     * 6) Wait a couple of secs
+     */
+     Serial.begin(4800); // start serial connection for debug output
+     Serial.println(F("REV14 Hardware Tests"));
+
+     Serial.print(F("Setting up Xtal..."));
+     delay(500);
+     setupXtal();
+     Serial.println(F("done"));
+     Serial.print(F("Setting up SoftSerial..."));
+     setupSoftSerial();
+     Serial.println(F("done"));
+     Serial.print(F("Setting up I2C..."));
+     setupI2C();
+     Serial.println(F("done"));
+     Serial.print(F("Setup pins..."));
+//     setupPins();
+     Serial.println(F("done"));
+     Serial.println(F("Waiting for Xtal to settle"));
+     delay(2000);
+}
+
+void loop() {
+    /**
+     * 1) Test Vcc
+     * 2) Test Xtal
+     * 3) Test light sensor
+     * 4) Test RN2483
+     * 5) Scan I2C bus
+     * 6) Test available I2C devices sequentially
+     */
+     Serial.println(F("\n\nStarting Tests..."));
+
+     testVcc();
+     testXtal();
+     delay(500);
+     testLightSensor();
+     testRN2483();
+     scanI2C();
+     delay(5000);
+}
+
+/**
+ * @brief   Sets up TOSC registers for asyncronous capture to Timer X
+ * @note    powerSetup() disables everything and then enables@
+ *          - Timer 0 (arduino functions)
+ *          - Timer 2 (xtal capture timer)
+ */
+void setupXtal()
+{
+    OTV0P2BASE::powerSetup(); // Standard V0p2 startup method.
+    OTV0P2BASE::powerUpSerialIfDisabled<4800>();
+    OTV0P2BASE::powerUpADCIfDisabled();
+}
+
+/**
+ * @brief   Sets up ADC0 for one shot capture
+ */
+// void setupADC0()
+// {
+//
+// }
+
+/**
+ * @brief   Sets up software serial on relevant pins
+ */
+ void setupSoftSerial()
+ {
+    rn2483.begin(RN2483_baud);
+ }
+
+/**
+ * @brief   Sets up I2C bus
+ */
+ void setupI2C()
+ {
+    OTV0P2BASE::powerUpTWIIfDisabled();
+ }
+
+/**
+ * @brief   Sets up pins that are not defined by other peripheral setup
+ *          - Set RN2483 ~reset to high (non reset state)
+ *          - Power up photodiode/any "intermittent peripherals"
+ *          - Enable boost reg to power up QM-1
+ */
+void setupPins()
+{
+    pinMode(RN2483_Rst_pin, OUTPUT);
+    pinMode(IO_Powerup_pin, OUTPUT);
+    pinMode(BoostRegEn_pin, OUTPUT);
+    digitalWrite(RN2483_Rst_pin, HIGH);
+    digitalWrite(IO_Powerup_pin, HIGH);
+    digitalWrite(BoostRegEn_pin, HIGH);
+}
+
+/**
+ * @brief   Tests supply voltage against internal reference
+ * @todo    Implement test
+ */
+ void testVcc()
+ {
+    uint16_t value = 0;
+    Serial.print(F("Testing Supply..."));
+    value = Supply_cV.read();
+    Serial.print(value); // print supply voltage
+    Serial.println(F("V"));
+ }
+
+/**
+ * @brief   Tests xtal against internal high speed RC oscillator
+ */
+ void testXtal()
+ {
+    Serial.print(F("Testing Xtal..."));
+    delay(500);
+    if(::OTV0P2BASE::HWTEST::check32768HzOscExtended()) Serial.println(F("passed"));
+    else Serial.println(F("failed"));
+ }
+
+/**
+ * @brief   Tests light sensor. Prints failed if value is 0 or 255, else prints value.
+ */
+void testLightSensor()
+{
+    uint8_t value = 0;
+    Serial.print(F("Testing Light Sensor..."));
+//    OTV0P2BASE::power_intermittent_peripherals_enable();
+//    delay(100);
+    value = analogRead(lightSensor_pin);
+    if( (value == 0) || (value == 255) ) Serial.println(F("failed"));
+    else Serial.println(value); // print light value;
+}
+/**
+ * @brief   Tests RN2483 is present
+ * @todo    get this working
+ */
+void testRN2483()
+{
+    char buf[9];
+    memset(buf, 0, sizeof(buf));
+    buf[8] = ' ';
+    Serial.println(F("Testing RN2483..."));
+    // reset RN2483
+    digitalWrite(RN2483_Rst_pin, LOW);
+    delay(100);
+    digitalWrite(RN2483_Rst_pin, HIGH);
+    delay(1000);
+    // autobaud (break+'U')
+    digitalWrite(RN2483_Tx_pin, LOW);
+    delay(10);
+    digitalWrite(RN2483_Tx_pin, HIGH);
+    rn2483.print('U');
+    delay(100);
+    // send test message and check reply
+    rn2483.print("sys get ver\r\n");
+    rn2483.read( (uint8_t *)buf, (sizeof(buf)-1) );
+    Serial.println(buf);
+}
+/**
+ * @brief   Scans I2C bus for possible devices on the REV10 and prints to serial.
+ */
+void scanI2C()
+{
+    uint8_t value = 0;
+    Serial.println(F("Scanning I2C bus:"));
+    testTMP112();
+    testSHT21();
+    testQM1();
+
+//    Serial.println(value); // print supply voltage;
+}
+/**
+ * @brief   Tests TMP112
+ */
+void testTMP112()
+{
+    Serial.print(F("Checking for TMP112..."));
+    if(!testI2CDev(tmp112_i2cAddr)) Serial.println(F("present."));
+    else Serial.println(F("not present."));
+}
+/**
+ * @brief   Tests SHT21
+ */
+void testSHT21()
+{
+    Serial.print(F("Checking for SHT21..."));
+    if(!testI2CDev(sht21_i2cAddr)) Serial.println(F("present."));
+    else Serial.println(F("not present."));
+}
+/**
+ * @brief   Tests QM-1
+ * @note    This requires boostRegEn_pin to be set high (+delay for QM-1 to start properly?)
+ */
+void testQM1()
+{
+    Serial.print(F("Checking for QM-1..."));
+    if(!testI2CDev(qm1_i2cAddr)) Serial.println(F("present."));
+    else Serial.println(F("not present."));
+}
+
+/**
+ * @brief   Tests I2C device at address for ACK
+ * @retval  0 success
+ *          1 buffer error (should never happen)
+ *          2 NACK received
+ *          3 NACK received
+ *          4 other error
+ */
+uint8_t testI2CDev(uint8_t addr)
+{
+    Wire.beginTransmission(addr);
+    return Wire.endTransmission();
+}
+


added asteriods game

added asteriods game

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

--- arduino/libraries/VeloKey/examples/Asteroids/Asteroids.ino
+++ arduino/libraries/VeloKey/examples/Asteroids/Asteroids.ino
@@ -0,0 +1,40 @@
+#include "events.h"
+#include "VeloKey.h"
+
+class MyListener : public VeloKeyListener{
+  void onScrollLeftCW(){
+  }
+  void onScrollLeftCCW(){
+  }
+  void onScrollRightCW(){
+  }
+  void onScrollRightCCW(){
+  }
+  void onScrollLeftPress(){
+  }
+  void onScrollRightPress(){
+  }
+};
+
+MyListener my_listener = MyListener();
+
+int16_t ship_xs[3] = {80 + 0, 80 + 5, 80 - 5};
+int16_t ship_ys[3] = {64 - 5, 64 + 5, 64 + 5};
+ConvexPolygonSprite ship = ConvexPolygonSprite();
+
+void setup(){
+  Serial.begin(115200);
+  velokey.begin();
+  ship.setup(3, ship_xs, ship_ys, VELOKEY_WHITE);
+  // velokey.splash(2000);
+  velokey.backlightOn();
+  velokey.subscribe(&my_listener);
+  for(int ii=0; ii=90; ii++){
+    ship.rotate(1);
+    ship.draw();
+    delay(100);
+  }
+}
+
+void loop(){
+}


playing with Uno timing

playing with Uno timing

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/wsnook/sandbox.git/'


#159 one more example

#159 one more example

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

--- examples/More/ServerAsDataStorage/ServerAsDataStorage.ino
+++ examples/More/ServerAsDataStorage/ServerAsDataStorage.ino
@@ -0,0 +1,70 @@
+/**************************************************************
+ * Blynk is a platform with iOS and Android apps to control
+ * Arduino, Raspberry Pi and the likes over the Internet.
+ * You can easily build graphic interfaces for all your
+ * projects by simply dragging and dropping widgets.
+ *
+ *   Downloads, docs, tutorials: http://www.blynk.cc
+ *   Blynk community:            http://community.blynk.cc
+ *   Social networks:            http://www.fb.com/blynkapp
+ *                               http://twitter.com/blynk_app
+ *
+ * Blynk library is licensed under MIT license
+ * This example code is in public domain.
+ *
+ **************************************************************
+ * This example shows you how you can use server as storage for
+ * your data like EEPROM
+ *
+ * Project setup in the Blynk app (not necessary):
+ *   Value display on V0 in PUSH mode.
+ *
+ **************************************************************/
+
+#define BLYNK_PRINT Serial
+#include <SPI.h>
+#include <Ethernet.h>
+#include <BlynkSimpleEthernet.h>
+#include <SimpleTimer.h>
+
+// You should get Auth Token in the Blynk App.
+// Go to the Project Settings (nut icon).
+char auth[] = "YourAuthToken";
+
+SimpleTimer timer;
+int uptimeCounter;
+
+void increment() {
+  uptimeCounter++;
+  Blynk.virtualWrite(V0, uptimeCounter);
+}
+
+void setup()
+{
+  Serial.begin(9600); // See the connection status in Serial Monitor
+  Blynk.begin(auth);
+
+  while (Blynk.connect() == false) {
+    // Wait until connected
+  }
+
+  timer.setInterval(1000L, increment);
+}
+
+void loop()
+{
+  Blynk.run();
+  timer.run();
+}
+
+// This function will run every time Blynk connection is established
+BLYNK_CONNECTED() {
+  //get data stored in virtual pin V0 from server
+  Blynk.syncVirtual(V0);
+}
+
+// restoring counter from server
+BLYNK_WRITE(V0)
+{
+  uptimeCounter = param.asInt();
+}


Initial upload of test test code for MS5803-14BA

This code displays pressure and temperature values from the MS5803-14BA
detected through its I2C bus on the "serial monitor" screen in the
Arduino IDE.  Because the MS5803-14BA uses a 3v3 logic, the user should
take care to only power the devise with 3v3 (not 5v).  CLK and SDA seem
to work when attached directly to the Arduino, however.

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


Update MC3672_demo.ino

Update MC3672_demo.ino

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


First implementation for RFduino. Reading and sending sensor values work.

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/Ossit/SenseBack.git/'


Arduino：文言修正

Arduino：文言修正

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/ics-creative/160125_arduino_ESP-WROOM-02_v2.git/'