Low latency logger sample for Teensy 3.5/3.6 SDIO SD slot.

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

--- SdFatSDIO_low_latency_logger.ino
+++ SdFatSDIO_low_latency_logger.ino
@@ -0,0 +1,362 @@
+/*
+ * Distributed under the 2-clause BSD licence (See LICENCE.TXT file at the
+ * repository root).
+ *
+ * Copyright (c) 2017 Tilo Nitzsche.  All rights reserved.
+ *
+ * https://github.com/tni/teensy-samples
+ */
+
+// Sample code for data logging. It uses a pre-allocated, pre-erased
+// file to minimize latency from SD card writes. This can reduce
+// the worst case write latency from 850ms down to 40ms, drastically
+// reducing the required buffer size.
+//
+// It is intented for usage with SdFat beta:
+// https://github.com/greiman/SdFat-beta
+//
+// with the Teensy 3.5 or 3.6 SDIO slot.
+//
+// The log data is captured in an ISR, triggered by an 'IntervalTimer'.
+// An interrupt-safe FIFO is used for interrupt-safe communication
+// with the main loop which is responsible for writing the captured data
+// to the SD card.
+
+#include <array>
+#include <atomic>
+#include <SdFat.h>
+
+// Content for debugging purposes.
+// Replace with something useful.
+struct LogEntry {
+    uint32_t counter;
+    uint32_t record_offset;
+    uint32_t time;
+    uint32_t dummy;
+};
+
+// Buffer that holds our log entries. When a buffer is full,
+// it is written to SD.
+template<class entry_t, size_t entry_count>
+class LogBuffer {
+public:
+    void addEntry(const entry_t& entry) {
+        if(size < capacity) log_entries[size++] = entry;
+    }
+    bool full() { return size >= capacity; }
+
+    static_assert(std::is_same<uint8_t, unsigned char>::value, "Aliasing rule violation.");
+    uint8_t* rawData() { return (uint8_t*) log_entries.data(); }
+
+    size_t rawSize() { return size * sizeof(entry_t); }
+    void reset() { *this = {}; }
+private:
+    static constexpr size_t capacity = entry_count;
+    std::array<entry_t, capacity> log_entries = {};
+    size_t size = 0;
+};
+
+// Simple lock free single-producer, single-consumer FIFO. Interrupt-safe.
+// It is intended for small entries.
+// Note: atomic_signal_fence is a compiler barrier only. It requires a CPU
+//       with memory order guarantees (like ARM Cortex M) to be sufficient.
+template<class entry_t, size_t capacity_>
+class FifoSpSc {
+public:
+    // Add entry to end of FIFO. FIFO must not be full.
+    void push(const entry_t& elem) {
+        atomic_signal_fence(std::memory_order_acq_rel);
+        const size_t write_pos_ = write_pos;
+        buffer[write_pos_] = elem;
+        atomic_signal_fence(std::memory_order_acq_rel);
+        write_pos = nextPos(write_pos_);
+        atomic_signal_fence(std::memory_order_acq_rel);
+    }
+    // Remove and return first FIFO entry. FIFO must not be empty.
+    entry_t pop() {
+        atomic_signal_fence(std::memory_order_acq_rel);
+        const size_t read_pos_ = read_pos;
+        entry_t ret = buffer[read_pos_];
+        atomic_signal_fence(std::memory_order_acq_rel);
+        read_pos = nextPos(read_pos_);
+        atomic_signal_fence(std::memory_order_acq_rel);
+        return ret;
+    }
+    bool empty() const { atomic_signal_fence(std::memory_order_acq_rel); return read_pos == write_pos; }
+    bool full() const { atomic_signal_fence(std::memory_order_acq_rel); return read_pos == nextPos(write_pos); }
+    size_t size() const {
+        atomic_signal_fence(std::memory_order_acq_rel);
+        const size_t read_pos_ = read_pos;
+        const size_t write_pos_ = write_pos;
+        return write_pos_ - read_pos_ + (write_pos_ >= read_pos_ ? 0 : buffer_size);
+    }
+    static size_t capacity() { return capacity_; }
+private:
+    static size_t nextPos(size_t pos) { return pos + 1 < buffer_size ? pos + 1 : 0; }
+
+    static constexpr size_t buffer_size = capacity_ + 1;
+    std::array<entry_t, buffer_size> buffer;
+    volatile size_t write_pos;
+    volatile size_t read_pos;
+};
+
+// Class for pre-allocated, pre-erased file.
+// It has an internal buffer that holds partial sector writes. This allows efficient writes
+// of any size.
+template<class sd_fat_t, class debuglog_t = void>
+class PreallocatedFile {
+public:
+    enum Error {
+        E_ok = 0,              // no error
+        E_eof,                 // end of file reached
+        E_create_contiguous,   // error allocating contiguous file
+        E_erase,               // error erasing allocated block
+        E_write_block,         // error writing data block
+    };
+
+    // Use SdFatSdio or SdFatSdioEX for sd_fat_t.
+    // 'debuglog' is optionally used for printing debug messages. Use one of the Arduino Stream classes,
+    // e.g. 'Serial'.
+    PreallocatedFile(sd_fat_t& sd_fat, debuglog_t* debuglog = nullptr) : sd_fat(sd_fat), debuglog(debuglog) {}
+    ~PreallocatedFile() { if(next_sector) close(); }
+
+    // Create a pre-allocated, pre-erased contiguous file. Any existing file
+    // with the same name, is erased.
+    // Return true on success.
+    bool create(const char* name, uint32_t size) {
+        log("Creating file: %s\n", name);
+        if(next_sector) close();
+        last_error = E_ok;
+        sd_fat.remove(name);
+        if(!file.createContiguous(sd_fat.vwd(), name, size)) {
+            log("ContigFile: createContiguous() failed");
+            last_error = E_create_contiguous;
+            return false;
+        }
+        uint32_t first_sector, last_sector;
+        if(!file.contiguousRange(&first_sector, &last_sector)) {
+            log("PreallocatedFile: contiguousRange() failed");
+            last_error = E_create_contiguous;
+            return false;
+        }
+        if(!sd_fat.card()->erase(first_sector, last_sector)) {
+            log("PreallocatedFile: erase() failed");
+            last_error = E_erase;
+            return false;
+        }
+        log("First sector: %u     last sector: %u\n", first_sector, last_sector);
+        this->first_sector = first_sector;
+        this->last_sector = last_sector;
+        next_sector = first_sector;
+
+        file.flush();
+        return true;
+    }
+
+    // Only full sectors can be written to disk. Partial sectors are automatically
+    // buffered. Writes of any size are allowed.
+    // sync_blocks == true closes the current multi-block write and allows the SD card to go
+    // to sleep. Performance is much lower.
+    bool write(const uint8_t* buffer, size_t size, bool sync_blocks = false) {
+        last_error = E_ok;
+        if(!next_sector || next_sector > last_sector) {
+            last_error = E_eof;
+            return false;
+        }
+        if(partial_sector_len) {
+            size_t copy_len = std::min(512 - partial_sector_len, size);
+            memcpy(partial_sector_buffer + partial_sector_len, buffer, copy_len);
+            partial_sector_len += copy_len;
+            if(partial_sector_len < 512) return true;
+            if(!sd_fat.card()->writeBlocks(next_sector, partial_sector_buffer, 1)) {
+                last_error = E_write_block;
+                log("Error writing log file. Current sector: %u\n", next_sector);
+            }
+            next_sector++;
+            buffer += copy_len;
+            size -= copy_len;
+            partial_sector_len = 0;
+        }
+        const size_t sector_count = size / 512;
+        if(sector_count) {
+            if(!sd_fat.card()->writeBlocks(next_sector, buffer, sector_count)) {
+                last_error = E_write_block;
+                log("Error writing log file. Current sector: %u\n", next_sector);
+            }
+            next_sector += sector_count;
+            size -= sector_count * 512;
+            buffer += sector_count * 512;
+        }
+        if(size) {
+            memcpy(partial_sector_buffer, buffer, size);
+            partial_sector_len = size;
+        }
+        if(sync_blocks) sd_fat.card()->syncBlocks();
+        return last_error == E_ok;
+    }
+
+    // Buffered data is written to disk, the file is truncated to the amount of data
+    // that was written and then closed.
+    void close() {
+        last_error = E_ok;
+        if(next_sector && partial_sector_len) {
+            if(!sd_fat.card()->writeBlocks(next_sector, partial_sector_buffer, 1)) {
+                last_error = E_write_block;
+                log("Error writing log file. Current sector: %u\n", next_sector);
+            }
+        }
+        if(next_sector) file.truncate((next_sector - first_sector - 1) * 512 + partial_sector_len);
+        file.close();
+        partial_sector_len = 0;
+        first_sector = 0;
+        last_sector = 0;
+        next_sector = 0;
+    }
+
+    size_t getWriteSector() { return next_sector; }
+    Error getLastError() { return last_error; }
+
+private:
+    void log(const char* msg) { if(debuglog) debuglog->println(msg); }
+
+    template<class... args_t>
+    void log(args_t... args) { if(debuglog) debuglog->printf(args...); }
+
+    File file;
+    sd_fat_t& sd_fat;
+    debuglog_t* debuglog = nullptr;
+    uint32_t first_sector = 0;
+    uint32_t last_sector = 0;
+    uint32_t next_sector = 0;
+    uint8_t partial_sector_buffer[512] __attribute__ ((aligned (4))) = {};
+    size_t partial_sector_len = 0;
+    Error last_error = E_ok;
+};
+
+// Store 'LogEntry's in 'LogBuffer'. Each buffer holds around 4200 bytes.
+using MyLogBuffer = LogBuffer<LogEntry, 4200 / sizeof(LogEntry)>;
+
+constexpr size_t log_buffer_count = 40;
+const char* log_file_name = "log.bin";
+uint8_t sensor_pin = A0;
+uint32_t log_file_size = 2ull * 1024 * 1024 * 1024;  // 2GB
+// PIT timer interval for invoking our data capture ISR.
+uint32_t capture_interval = 10;  // in microseconds
+
+// Allocate storage for log buffers.
+std::array<MyLogBuffer, log_buffer_count> log_buffers;
+// FIFO that holds pointers our empty log_buffers.
+FifoSpSc<MyLogBuffer*, log_buffer_count> empty_log_buffers;
+// Put all allocated log buffers into 'empty_log_buffers' FIFO.
+char empty_log_buffers_init = [](){
+    for(size_t i = 0; i < log_buffer_count; i++) empty_log_buffers.push(&log_buffers[i]);
+    return 0;
+}();
+// Filled log buffer FIFO.
+FifoSpSc<MyLogBuffer*, log_buffer_count> filled_log_buffers;
+
+auto& serial = Serial;
+// Count the number of times our log buffers overflow.
+std::atomic<size_t> buffer_overflow_counter;
+
+
+SdFatSdioEX sd_fat;
+bool logging_finished = false;
+size_t written_bytes = 0;
+size_t max_buffers_used = 0;
+
+
+// Add log entry to log buffers.
+void logEntry(const LogEntry& log_entry) {
+    static MyLogBuffer* log_buffer = nullptr;
+    if(!log_buffer) {
+        if(empty_log_buffers.empty()) {
+            buffer_overflow_counter++;
+            return;
+        } else {
+            log_buffer = empty_log_buffers.pop();
+        }
+    }
+    log_buffer->addEntry(log_entry);
+    if(log_buffer->full()) {
+        filled_log_buffers.push(log_buffer);
+        log_buffer = nullptr;
+    }
+}
+
+// ISR, periodically triggered by PIT timer. It creates some dummy
+// log entries. Put your data capturing here.
+void captureData() {
+    uint32_t time = micros();
+    static uint32_t counter = 0;
+    static uint32_t record_offset = 0;
+
+    logEntry( { counter, record_offset, time, 0x42424242 } );
+    counter++;
+    record_offset += sizeof(LogEntry);
+}
+
+void setup() {
+    pinMode(LED_BUILTIN, OUTPUT);
+    serial.begin(115200);
+    delay(2000);
+    serial.println("Initializing SD.");
+
+    if (!sd_fat.begin()) {
+        serial.println("SD init failed.");
+        return;
+    }
+    serial.println("SD init done.");
+
+    using file_t = PreallocatedFile<decltype(sd_fat), std::remove_reference<decltype(serial)>::type>;
+    file_t file(sd_fat, &serial);
+    file.create(log_file_name, log_file_size);
+    serial.println("Log file allocated and pre-erased.");
+    serial.println("\nPress 'c' to terminate logging.\n");
+
+    elapsedMillis report_timer;
+    IntervalTimer data_capture_timer;
+    data_capture_timer.begin(captureData, capture_interval);
+
+    while(true) {
+        // If we have a filled log buffer, write it to SD.
+        if(!filled_log_buffers.empty()) {
+            max_buffers_used = std::max(max_buffers_used, empty_log_buffers.capacity() - empty_log_buffers.size());
+            MyLogBuffer* log_buffer = filled_log_buffers.pop();
+            if(!file.write(log_buffer->rawData(), log_buffer->rawSize())) {
+                if(file.getLastError() == file.E_eof) {
+                    file.close();
+                    serial.println("Log file full. Logging finished.");
+                    return;
+                }
+                // ignore other write errors, hopefully subsequent writes will succeed
+            }
+            written_bytes += log_buffer->rawSize();
+            *log_buffer = {};
+            empty_log_buffers.push(log_buffer);
+        }
+        if(report_timer > 5000) {
+            serial.printf("elapsed: %us     bytes written: %u     buffer overflow count: %u\n",
+                           millis() / 1000, written_bytes, buffer_overflow_counter.load());
+            serial.printf("next write sector: %u    max buffers used during last 5s: %u\n",
+                          file.getWriteSector(), max_buffers_used);
+            report_timer = 0;
+            max_buffers_used = 0;
+        }
+        if(serial.available()) {
+            if(serial.read() == 'c') {
+                file.close();
+                serial.println("Logging finished.");
+                return;
+            }
+        }
+    }
+}
+
+// Running when an error is encountered or when logging is finished.
+void loop() {
+    digitalWrite(LED_BUILTIN, HIGH);
+    delay(200);
+    digitalWrite(LED_BUILTIN, LOW);
+    delay(200);
+}


Added SHT heating code.

Added SHT heating code.

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


xBee_2.0

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

--- XBee_rob_function_2.0/xBee_2.0/xBee_2.0.ino
+++ XBee_rob_function_2.0/xBee_2.0/xBee_2.0.ino
@@ -0,0 +1,43 @@
+#include <Dynamixel_Serial.h>
+//#include <readxBee.h>
+
+int x, y, z, emg1, emg2;
+int infoPk[24];
+
+int actualName(){
+  if(Serial1.available() >= 24){
+    if (Serial1.read() == 0x7E){
+          for (int i = 0; i < 22 ; i++){
+            byte jelly = Serial1.read();
+            infoPk[i] = jelly;
+          }
+          for(int a = 13; a < 22; a++) {
+            x = infoPk[15] + (infoPk[14] << 8);
+            y = infoPk[13] + (infoPk[12] << 8);
+            z = infoPk[17] + (infoPk[16] << 8);
+            emg1 = infoPk[11] + (infoPk[10] << 8);
+            emg2 = infoPk[19] + (infoPk[18] << 8);
+          }
+          Serial.print(" X = ");
+          Serial.print(x);
+          Serial.print(" Y = ");
+          Serial.print(y);
+          Serial.print(" Z = ");
+          Serial.print(z);
+          Serial.print(" EMG Ch.1 = ");
+          Serial.print(emg1);
+          Serial.print(" EMG Ch.2 = ");
+          Serial.print(emg2);
+          Serial.println();
+
+    }
+  }
+}
+void setup() {
+  Serial.begin(115200);
+  Serial1.begin(115200);
+}
+
+void loop() {
+  actualName();
+}


_08_kidSerie_sketch_01.No_Bluetooth.ino.ino

_08_kidSerie_sketch_01.No_Bluetooth.ino.ino

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

--- _08_kidSerie_sketch_01.No_Bluetooth.ino.ino
+++ _08_kidSerie_sketch_01.No_Bluetooth.ino.ino
@@ -0,0 +1,67 @@
+/*
+  Project name:
+     Park Assist I w/ MIT App Inventor 2 - Bluetooth + Arduino + MIT App + HC-SR04 Sonar #kidSerie —08
+     Flavour I - With Bluetooth
+     Hex File: _08_kidSerie_sketch_01.No_Bluetooth.ino
+   Revision History:
+     14/05/2017:
+Description:
+        How about that, sound and vibrate your cell? There you are!
+        Here is a Golpe de Vista circuit for building garages that are getting tighter and tighter.
+
+    MCU:                     Arduino 1.8.2 - @16MHz       http://www.arduino.cc/
+IC Chip:                     Bluetooth Datasheet - HC-06   https://goo.gl/s9ZcNC
+Connections:
+      See Official youtube channel vids: https://goo.gl/pj20lS
+
+Based on:  see bellow
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License v3 as published by the Free Software Foundation
+
+*/
+/*
+  HC-SR04 Ping distance sensor]
+  VCC to arduino 5v GND to arduino GND
+  Echo to Arduino pin 13 Trig to Arduino pin 12
+  Red POS to Arduino pin 11
+  Green POS to Arduino pin 10
+  560 ohm resistor to both LED NEG and GRD power rail
+  More info at: http://goo.gl/kJ8Gl
+  Original code improvements to the Ping sketch sourced from Trollmaker.com
+  Some code and wiring inspired by http://en.wikiversity.org/wiki/User:Dstaub/robotcar
+*/
+
+#define trigPin 13
+#define echoPin 12
+#define stop_LED 11
+#define go_LED 10
+
+void setup() {
+
+  pinMode(trigPin, OUTPUT);
+  pinMode(echoPin, INPUT);
+  pinMode(stop_LED, OUTPUT);
+  pinMode(go_LED, OUTPUT);
+}
+
+void loop() {
+  long duration, distance;
+  digitalWrite(trigPin, LOW);     // Added this line
+  delayMicroseconds(2);           // Added this line
+  digitalWrite(trigPin, HIGH);
+                                  //  delayMicroseconds(1000); - Removed this line
+  delayMicroseconds(10);          // Added this line
+  digitalWrite(trigPin, LOW);
+  duration = pulseIn(echoPin, HIGH);
+  distance = (duration ) / 58.2;
+  if (distance < 5) {             // This is where the LED On/Off happens
+    digitalWrite(stop_LED, HIGH); // When the Red condition is met, the Green LED should turn off
+    digitalWrite(go_LED, LOW);
+  }
+  else {
+    digitalWrite(stop_LED, LOW);
+    digitalWrite(go_LED, HIGH);
+  }
+  delay(500);
+}


Add ArduCAM mini 5MP Low Power example

Add ArduCAM mini 5MP Low Power example

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

--- ArduCAM/examples/mini/ArduCAM_Mini_OV5642_LowPowerMode/ArduCAM_Mini_OV5642_LowPowerMode.ino
+++ ArduCAM/examples/mini/ArduCAM_Mini_OV5642_LowPowerMode/ArduCAM_Mini_OV5642_LowPowerMode.ino
@@ -0,0 +1,126 @@
+#include <Wire.h>
+#include <ArduCAM.h>
+#include <SPI.h>
+#include "memorysaver.h"
+
+// set pin 4 as the slave select for the digital pot:
+const int CS = 4;
+
+ArduCAM myCAM(OV5642,CS);
+
+void setup() {
+  uint8_t vid,pid;
+  uint8_t temp;
+#if defined (__AVR__)
+  Wire.begin();
+#endif
+#if defined(__arm__)
+  Wire1.begin();
+#endif
+  Serial.begin(921600);
+  Serial.println("ArduCAM Start!");
+
+  // set the SPI_CS as an output:
+  pinMode(CS, OUTPUT);
+
+  // initialize SPI:
+  SPI.begin();
+  //Check if the ArduCAM SPI bus is OK
+  myCAM.write_reg(ARDUCHIP_TEST1, 0x55);
+  temp = myCAM.read_reg(ARDUCHIP_TEST1);
+  //Serial.println(temp);
+  if(temp != 0x55)
+  {
+    Serial.println("SPI1 interface Error!");
+    //while(1);
+  }
+
+  //Check if the camera module type is OV5642
+  myCAM.rdSensorReg16_8(OV5642_CHIPID_HIGH, &vid);
+  myCAM.rdSensorReg16_8(OV5642_CHIPID_LOW, &pid);
+  if((vid != 0x56) || (pid != 0x42))
+    Serial.println("Can't find OV5642 module!");
+  else
+    Serial.println("OV5642 detected.");
+
+  //Change to JPEG capture mode and initialize the OV5642 module
+  myCAM.set_format(JPEG);
+  myCAM.InitCAM();
+  myCAM.write_reg(ARDUCHIP_TIM, VSYNC_LEVEL_MASK);
+
+  myCAM.clear_fifo_flag();
+  myCAM.write_reg(ARDUCHIP_FRAMES,0x00);
+  myCAM.set_bit(ARDUCHIP_GPIO,GPIO_PWDN_MASK);//enable low power
+}
+
+void loop() {
+  uint8_t temp,temp_last;
+  uint8_t start_capture = 0;
+
+  temp = Serial.read();
+  switch(temp)
+  {
+    case 0:
+      myCAM.clear_bit(ARDUCHIP_GPIO,GPIO_PWDN_MASK);
+      myCAM.OV5642_set_JPEG_size(OV5642_320x240);
+      myCAM.set_bit(ARDUCHIP_GPIO,GPIO_PWDN_MASK);
+      break;
+    case 1:
+      myCAM.clear_bit(ARDUCHIP_GPIO,GPIO_PWDN_MASK);
+      myCAM.OV5642_set_JPEG_size(OV5642_640x480);
+      myCAM.set_bit(ARDUCHIP_GPIO,GPIO_PWDN_MASK);
+      break;
+    case 2:
+      myCAM.clear_bit(ARDUCHIP_GPIO,GPIO_PWDN_MASK);
+      myCAM.OV5642_set_JPEG_size(OV5642_1280x720);
+      myCAM.set_bit(ARDUCHIP_GPIO,GPIO_PWDN_MASK);
+      break;
+    case 3:
+      myCAM.clear_bit(ARDUCHIP_GPIO,GPIO_PWDN_MASK);
+      myCAM.OV5642_set_JPEG_size(OV5642_1920x1080);
+      myCAM.set_bit(ARDUCHIP_GPIO,GPIO_PWDN_MASK);
+      break;
+    case 4:
+      myCAM.clear_bit(ARDUCHIP_GPIO,GPIO_PWDN_MASK);
+      myCAM.OV5642_set_JPEG_size(OV5642_2048x1563);
+      myCAM.set_bit(ARDUCHIP_GPIO,GPIO_PWDN_MASK);
+      break;
+    case 5:
+      myCAM.clear_bit(ARDUCHIP_GPIO,GPIO_PWDN_MASK);
+      myCAM.OV5642_set_JPEG_size(OV5642_2592x1944);
+      myCAM.set_bit(ARDUCHIP_GPIO,GPIO_PWDN_MASK);
+      break;
+    case 0x10:
+      start_capture = 1;
+      Serial.println("CAM1 start single shot.");
+      myCAM.clear_bit(ARDUCHIP_GPIO,GPIO_PWDN_MASK);//disable low power
+
+      delay(800);
+      break;
+    default:
+      break;
+  }
+  if(start_capture == 1)
+  {
+    myCAM.flush_fifo();
+    myCAM.clear_fifo_flag();
+    //Start capture
+    myCAM.start_capture();
+    start_capture = 0;
+  }
+  if(myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK))
+  {
+    myCAM.set_bit(ARDUCHIP_GPIO,GPIO_PWDN_MASK);
+    Serial.println("CAM1 Capture Done!");
+    temp = 0;
+    while( (temp != 0xD9) | (temp_last != 0xFF) )
+    {
+      temp_last = temp;
+      temp = myCAM.read_fifo();
+      Serial.write(temp);
+      delayMicroseconds(10);
+    }
+    //Clear the capture done flag
+    myCAM.clear_fifo_flag();
+  }
+}


Tidy up

Tidy up

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/freephases/lenr-logger.git/'


FIX night and PWM flickering on pins that use timer3

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/wiiproSK/arduino.git/'


Add new piano revision from Tim with adjustable volume knob

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


Remise en place des commande moteur

Remise en place des commande moteur

error: pathspec 'Module' did not match any file(s) known to git
error: pathspec 'Moteur/Software/Asservissement/Asservissement_vitesse_2.5/Asservissement_vitesse_2.5/Asservissement_vitesse_2.5.ino' did not match any file(s) known to git


not working...

not working...

error: pathspec 'Arduino/hardware/V0p2_Main_PCB_REV7_DORM1_and_REV8/testsuite/201706/REV7CallForHeat/REV7CallForHeat.ino' did not match any file(s) known to git

--- Arduino/hardware/V0p2_Main_PCB_REV7_DORM1_and_REV8/testsuite/201706/REV7CallForHeat/REV7CallForHeat.ino
+++ Arduino/hardware/V0p2_Main_PCB_REV7_DORM1_and_REV8/testsuite/201706/REV7CallForHeat/REV7CallForHeat.ino
@@ -0,0 +1,436 @@
+/*
+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
+*/
+/**
+ * Minimal REV7 config for testing power consumption.
+ * Aim is to:
+ *     - todo init GPIO pins to safe mode.
+ *     - todo init peripherals to safe low power mode.
+ *     - loop endlessly.
+ */
+
+// INCLUDES & DEFINES
+// Debug output flag
+#define DEBUG
+// REV7 / DORM1 all-in-one valve unit, secure TX.
+#define CONFIG_DORM1
+// Get defaults for valve applications.
+#include <OTV0p2_valve_ENABLE_defaults.h>
+// All-in-one valve unit (DORM1).
+#include <OTV0p2_CONFIG_REV7.h>
+// I/O pin allocation and setup: include ahead of I/O module headers.
+#include <OTV0p2_Board_IO_Config.h>
+// OTV0p2Base Libraries
+#include <OTV0p2Base.h>
+// Radio Libraries
+//#include <OTRadioLink.h>
+#include <OTRFM23BLink.h>
+// RadValve libraries
+#include <OTRadValve.h>
+#include <OTAESGCM.h>
+
+
+// Debugging output
+#ifndef DEBUG
+#define DEBUG_SERIAL_PRINT(s) // Do nothing.
+#define DEBUG_SERIAL_PRINTFMT(s, format) // Do nothing.
+#define DEBUG_SERIAL_PRINT_FLASHSTRING(fs) // Do nothing.
+#define DEBUG_SERIAL_PRINTLN_FLASHSTRING(fs) // Do nothing.
+#define DEBUG_SERIAL_PRINTLN() // Do nothing.
+#define DEBUG_SERIAL_TIMESTAMP() // Do nothing.
+#else
+// Send simple string or numeric to serial port and wait for it to have been sent.
+// Make sure that Serial.begin() has been invoked, etc.
+#define DEBUG_SERIAL_PRINT(s) { OTV0P2BASE::serialPrintAndFlush(s); }
+#define DEBUG_SERIAL_PRINTFMT(s, fmt) { OTV0P2BASE::serialPrintAndFlush((s), (fmt)); }
+#define DEBUG_SERIAL_PRINT_FLASHSTRING(fs) { OTV0P2BASE::serialPrintAndFlush(F(fs)); }
+#define DEBUG_SERIAL_PRINTLN_FLASHSTRING(fs) { OTV0P2BASE::serialPrintlnAndFlush(F(fs)); }
+#define DEBUG_SERIAL_PRINTLN() { OTV0P2BASE::serialPrintlnAndFlush(); }
+// Print timestamp with no newline in format: MinutesSinceMidnight:Seconds:SubCycleTime
+extern void _debug_serial_timestamp();
+#define DEBUG_SERIAL_TIMESTAMP() _debug_serial_timestamp()
+#endif // DEBUG
+
+// OBJECTS & VARIABLES
+/**
+ * Peripherals present on REV7
+ * - Pot        Set input to Hi-Z?  +
+ * - PHT        IO_POWER_UP LOW
+ * - Encoder    IO_POWER_UP LOW
+ * - LED        Set pin HIGH?
+ * - Button     Set to INPUT
+ * - H-Bridge   Control pins HIGH, Current sense set to input.  +
+ * - SHT21      read() once.        +
+ * - RFM23B     ??                  +
+ * - XTAL       Setup and leave running?
+ * - UART       Disable
+ */
+
+/**
+ * Dummy Types
+ */
+// Placeholder class with dummy static status methods to reduce code complexity.
+typedef OTV0P2BASE::DummySensorOccupancyTracker OccupancyTracker;
+
+/**
+ * Supply Voltage instance
+ */
+// Sensor for supply (eg battery) voltage in millivolts.
+// Singleton implementation/instance.
+OTV0P2BASE::SupplyVoltageCentiVolts Supply_cV;
+
+/*
+ * Radio instance
+ */
+static constexpr uint8_t RFM22_PREAMBLE_BYTES = 5; // Recommended number of preamble bytes for reliable reception.
+static constexpr uint8_t RFM22_SYNC_MIN_BYTES = 3; // Minimum number of sync bytes.
+// Send the underlying stats binary/text 'whitened' message.
+// This must be terminated with an 0xff (which is not sent),
+// and no longer than STATS_MSG_MAX_LEN bytes long in total (excluding the terminating 0xff).
+// This must not contain any 0xff and should not contain long runs of 0x00 bytes.
+// The message to be sent must be written at an offset of STATS_MSG_START_OFFSET from the start of the buffer.
+// This routine will alter the content of the buffer for transmission,
+// and the buffer should not be re-used as is.
+//   * doubleTX  double TX to increase chance of successful reception
+//   * RFM23BfriendlyPremable  if true then add an extra preamble
+//     to allow RFM23B-based receiver to RX this
+// This will use whichever transmission medium/carrier/etc is available.
+static constexpr uint8_t STATS_MSG_START_OFFSET = (RFM22_PREAMBLE_BYTES + RFM22_SYNC_MIN_BYTES);
+static constexpr uint8_t STATS_MSG_MAX_LEN = (64 - STATS_MSG_START_OFFSET);
+
+static constexpr bool RFM23B_allowRX = false;
+
+static constexpr uint8_t RFM23B_RX_QUEUE_SIZE = OTRFM23BLink::DEFAULT_RFM23B_RX_QUEUE_CAPACITY;
+static constexpr int8_t RFM23B_IRQ_PIN = -1;// PIN_RFM_NIRQ;
+OTRFM23BLink::OTRFM23BLink<OTV0P2BASE::V0p2_PIN_SPI_nSS, RFM23B_IRQ_PIN, RFM23B_RX_QUEUE_SIZE, RFM23B_allowRX> PrimaryRadio;//RFM23B;
+// Pick an appropriate radio config for RFM23 (if it is the primary radio).
+// Nodes talking on fast GFSK channel 0.
+static const uint8_t nPrimaryRadioChannels = 1;
+static const OTRadioLink::OTRadioChannelConfig RFM23BConfigs[nPrimaryRadioChannels] = {
+    // GFSK channel 0 full config, RX/TX, not in itself secure.
+    OTRadioLink::OTRadioChannelConfig(OTRFM23BLink::StandardRegSettingsGFSK57600, true), };
+
+/*
+ * SHT21 instance
+ */
+OTV0P2BASE::RoomTemperatureC16_SHT21 TemperatureC16; // SHT21 impl.
+
+// HUMIDITY_SENSOR_SUPPORT is defined if at least one humidity sensor has support compiled in.
+// Simple implementations can assume that the sensor will be present if defined;
+// more sophisticated implementations may wish to make run-time checks.
+// If SHT21 support is enabled at compile-time then its humidity sensor may be used at run-time.
+// Singleton implementation/instance.
+typedef OTV0P2BASE::HumiditySensorSHT21 RelHumidity_t;
+RelHumidity_t RelHumidity;
+
+/**
+ * Temp pot
+ */
+// Sensor for temperature potentiometer/dial UI control.
+// Correct for DORM1/TRV1 with embedded REV7.
+// REV7 does not drive pot from IO_POWER_UP.
+typedef OTV0P2BASE::SensorTemperaturePot<OccupancyTracker, nullptr, 48, 296, false> TempPot_t;
+TempPot_t TempPot;
+
+/**
+ * Ambient Light Sensor
+ */
+typedef OTV0P2BASE::SensorAmbientLight AmbientLight;
+// Singleton implementation/instance.
+AmbientLight AmbLight;
+
+/**
+ * Valve Actuator
+ */
+// DORM1/REV7 direct drive motor actuator.
+static constexpr bool binaryOnlyValveControl = false;
+static constexpr uint8_t m1 = MOTOR_DRIVE_ML;
+static constexpr uint8_t m2 = MOTOR_DRIVE_MR;
+static constexpr uint8_t mSleep = OTRadValve::MOTOR_DRIVE_NSLEEP_UNUSED;
+typedef OTRadValve::ValveMotorDirectV1<OTRadValve::ValveMotorDirectV1HardwareDriver, m1, m2, MOTOR_DRIVE_MI_AIN, MOTOR_DRIVE_MC_AIN, mSleep, decltype(Supply_cV), &Supply_cV> ValveDirect_t;// Singleton implementation/instance.
+// Suppress unnecessary activity when room dark, eg to avoid disturbance if device crashes/restarts,
+// unless recent UI use because value is being fitted/adjusted.
+ValveDirect_t ValveDirect([](){return(AmbLight.isRoomDark());});
+
+// FUNCTIONS
+
+/**
+ * Panic Functions
+ */
+// Indicate that the system is broken in an obvious way (distress flashing the main LED).
+// DOES NOT RETURN.
+// Tries to turn off most stuff safely that will benefit from doing so, but nothing too complex.
+// Tries not to use lots of energy so as to keep distress beacon running for a while.
+void panic()
+{
+    // Reset radio and go into low-power mode.
+    PrimaryRadio.panicShutdown();
+    // Power down almost everything else...
+    OTV0P2BASE::minimisePowerWithoutSleep();
+    pinMode(OTV0P2BASE::LED_HEATCALL_L, OUTPUT);
+    for( ; ; )
+    {
+        OTV0P2BASE::LED_HEATCALL_ON();
+        OTV0P2BASE::nap(WDTO_15MS);
+        OTV0P2BASE::LED_HEATCALL_OFF();
+        OTV0P2BASE::nap(WDTO_120MS);
+    }
+}
+// Panic with fixed message.
+void panic(const __FlashStringHelper *s)
+{
+    OTV0P2BASE::serialPrintlnAndFlush(); // Start new line to highlight error.  // May fail.
+    OTV0P2BASE::serialPrintAndFlush('!'); // Indicate error with leading '!' // May fail.
+    OTV0P2BASE::serialPrintlnAndFlush(s); // Print supplied detail text. // May fail.
+    panic();
+}
+
+
+/**
+ * @brief   Set pins and on-board peripherals to safe low power state.
+ */
+
+
+// Managed JSON stats.
+static OTV0P2BASE::SimpleStatsRotation<12> ss1; // Configured for maximum different stats.  // FIXME increased for voice & for setback lockout
+// Do bare stats transmission.
+// Output should be filtered for items appropriate
+// to current channel security and sensitivity level.
+// This is JSON format.
+// Sends stats on primary radio channel 0 with possible duplicate to secondary channel.
+// If sending encrypted then ID/counter fields (eg @ and + for JSON) are omitted
+// as assumed supplied by security layer to remote recipent.
+void callForHeatTX()
+{
+    // Note if radio/comms channel is itself framed.
+    const bool framed = !PrimaryRadio.getChannelConfig()->isUnframed;
+    const bool neededWaking = OTV0P2BASE::powerUpSerialIfDisabled<>();
+
+static_assert(OTV0P2BASE::FullStatsMessageCore_MAX_BYTES_ON_WIRE <= STATS_MSG_MAX_LEN, "FullStatsMessageCore_MAX_BYTES_ON_WIRE too big");
+static_assert(OTV0P2BASE::MSG_JSON_MAX_LENGTH+1 <= STATS_MSG_MAX_LEN, "MSG_JSON_MAX_LENGTH too big"); // Allow 1 for trailing CRC.
+
+    // Allow space in buffer for:
+    //   * buffer offset/preamble
+    //   * max binary length, or max JSON length + 1 for CRC + 1 to allow detection of oversize message
+    //   * terminating 0xff
+    //  uint8_t buf[STATS_MSG_START_OFFSET + max(FullStatsMessageCore_MAX_BYTES_ON_WIRE,  MSG_JSON_MAX_LENGTH+1) + 1];
+    // Buffer need be no larger than leading length byte + typical 64-byte radio module TX buffer limit + optional terminator.
+    const uint8_t MSG_BUF_SIZE = 1 + 64 + 1;
+    uint8_t buf[MSG_BUF_SIZE];
+    // Send JSON message.
+    bool sendingJSONFailed = false; // Set true and stop attempting JSON send in case of error.
+
+    // Set pointer location based on whether start of message will have preamble
+    uint8_t *bptr = buf;
+    bptr += STATS_MSG_START_OFFSET;
+    // Where to write the real frame content.
+    uint8_t *const realTXFrameStart = bptr;
+
+    // If forcing encryption or if unconditionally suppressed
+    // then suppress the "@" ID field entirely,
+    // assuming that the encrypted commands will carry the ID, ie in the 'envelope'.
+    ss1.setID(V0p2_SENSOR_TAG_F(""));
+
+    // Managed JSON stats.
+    // Make best use of available bandwidth...
+    constexpr bool maximise = true;
+    // Enable "+" count field for diagnostic purposes, eg while TX is lossy,
+    // if the primary radio channel does not include a sequence number itself.
+    // Assume that an encrypted channel will provide its own (visible) sequence counter.
+    ss1.enableCount(false); // as encrypted
+    ss1.put(TemperatureC16);
+    // OPTIONAL items
+    // Only TX supply voltage for units apparently not mains powered, and TX with low priority as slow changing.
+    constexpr uint8_t privacyLevel = OTV0P2BASE::stTXalwaysAll;
+
+    // Buffer to write JSON to before encryption.
+    // Size for JSON in 'O' frame is:
+    constexpr uint8_t maxSecureJSONSize = OTRadioLink::ENC_BODY_SMALL_FIXED_PTEXT_MAX_SIZE - 2 + 1;
+    // writeJSON() requires two further bytes including one for the trailing '\0'.
+    uint8_t ptextBuf[maxSecureJSONSize + 2];
+
+    // Redirect JSON output appropriately.
+    uint8_t *const bufJSON = ptextBuf;
+    const uint8_t bufJSONlen = sizeof(ptextBuf);
+
+    // Number of bytes written for body.
+    // For non-secure, this is the size of the JSON text.
+    // For secure this is overridden with the secure frame size.
+    int8_t wrote = 0;
+
+    // Generate JSON text.
+    if(!sendingJSONFailed)
+    {
+        // Generate JSON and write to appropriate buffer:
+        // direct to TX buffer if not encrypting, else to separate buffer.
+        wrote = ss1.writeJSON(bufJSON, bufJSONlen, privacyLevel, maximise);
+        if(0 == wrote) { sendingJSONFailed = true; }
+    }
+
+    // Push the JSON output to Serial.
+    if(!sendingJSONFailed)
+    {
+        // Insert synthetic full ID/@ field for local stats, but no sequence number for now.
+        Serial.print(F("{\"@\":\""));
+        for(int i = 0; i < OTV0P2BASE::OpenTRV_Node_ID_Bytes; ++i) { Serial.print(eeprom_read_byte((uint8_t *)V0P2BASE_EE_START_ID+i), HEX); }
+        Serial.print(F("\","));
+        Serial.write(bufJSON+1, wrote-1);
+        Serial.println();
+        OTV0P2BASE::flushSerialSCTSensitive(); // Ensure all flushed since system clock may be messed with...
+    }
+
+    // Get the 'building' key for stats sending.
+    uint8_t key[16];
+    if(!sendingJSONFailed)
+    {
+        if(!OTV0P2BASE::getPrimaryBuilding16ByteSecretKey(key))
+        {
+            sendingJSONFailed = true;
+            OTV0P2BASE::serialPrintlnAndFlush(F("!TX key")); // Know why TX failed.
+        }
+    }
+
+    // If doing encryption
+    // then build encrypted frame from raw JSON.
+    if(!sendingJSONFailed)
+    {
+        // Explicit-workspace version of encryption.
+        const OTRadioLink::SimpleSecureFrame32or0BodyTXBase::fixed32BTextSize12BNonce16BTagSimpleEncWithWorkspace_ptr_t eW = OTAESGCM::fixed32BTextSize12BNonce16BTagSimpleEnc_DEFAULT_WITH_WORKSPACE;
+        constexpr uint8_t workspaceSize = OTRadioLink::SimpleSecureFrame32or0BodyTXBase::generateSecureOFrameRawForTX_total_scratch_usage_OTAESGCM_2p0;
+        uint8_t workspace[workspaceSize];
+        OTV0P2BASE::ScratchSpace sW(workspace, workspaceSize);
+        constexpr uint8_t txIDLen = OTRadioLink::ENC_BODY_DEFAULT_ID_BYTES;
+        // When sending on a channel with framing, do not explicitly send the frame length byte.
+        const uint8_t offset = framed ? 1 : 0;
+        // Assumed to be at least one free writeable byte ahead of bptr.
+        // Force the valve to call for heat.
+        constexpr uint8_t valvePC = 99;
+        const uint8_t bodylen = OTRadioLink::SimpleSecureFrame32or0BodyTXV0p2::getInstance().generateSecureOFrameRawForTX(
+            realTXFrameStart - offset, sizeof(buf) - (realTXFrameStart-buf) + offset,
+            txIDLen, valvePC, (const char *)bufJSON, eW, sW, key);
+        sendingJSONFailed = (0 == bodylen);
+        wrote = bodylen - offset;
+    }
+
+    if(!sendingJSONFailed)
+    {
+        // Send directly to the primary radio...
+        PrimaryRadio.queueToSend(realTXFrameStart, wrote);
+    }
+    if(neededWaking) { OTV0P2BASE::flushSerialProductive(); OTV0P2BASE::powerDownSerial(); }
+}
+
+//========================================
+// SETUP
+//========================================
+
+// Setup routine: runs once after reset.
+// Does some limited board self-test and will panic() if anything is obviously broken.
+void setup()
+{
+    // Set appropriate low-power states, interrupts, etc, ASAP.
+    OTV0P2BASE::powerSetup();
+    // IO setup for safety, and to avoid pins floating.
+    OTV0P2BASE::IOSetup();
+
+    OTV0P2BASE::serialPrintAndFlush(F("\r\nOpenTRV: ")); // Leading CRLF to clear leading junk, eg from bootloader.
+    V0p2Base_serialPrintlnBuildVersion();
+
+    OTV0P2BASE::LED_HEATCALL_ON();
+
+    // Give plenty of time for the XTal to settle.
+    delay(1000);
+
+    // Have 32678Hz clock at least running before going any further.
+    // Check that the slow clock is running reasonably OK, and tune the fast one to it.
+    if(!::OTV0P2BASE::HWTEST::calibrateInternalOscWithExtOsc()) { panic(F("Xtal")); } // Async clock not running or can't tune.
+
+    // Initialise the radio, if configured, ASAP because it can suck a lot of power until properly initialised.
+    PrimaryRadio.preinit(NULL);
+    // Check that the radio is correctly connected; panic if not...
+    if(!PrimaryRadio.configure(nPrimaryRadioChannels, RFM23BConfigs) || !PrimaryRadio.begin()) { panic(F("r1")); }
+
+    // Buttons should not be activated DURING boot for user-facing boards; an activated button implies a fault.
+    // Check buttons not stuck in the activated position.
+    if(fastDigitalRead(BUTTON_MODE_L) == LOW) { panic(F("b")); }
+
+    // Collect full set of environmental values before entering loop() in normal mode.
+    // This should also help ensure that sensors are properly initialised.
+
+    // No external sensors are *assumed* present if running alt main loop
+    // This may mean that the alt loop/POST will have to initialise them explicitly,
+    // and the initial seed entropy may be marginally reduced also.
+    const int cV = Supply_cV.read();
+    DEBUG_SERIAL_PRINT_FLASHSTRING("V: ");
+    DEBUG_SERIAL_PRINT(cV);
+    DEBUG_SERIAL_PRINTLN();
+    const int heat = TemperatureC16.read();
+    DEBUG_SERIAL_PRINT_FLASHSTRING("T: ");
+    DEBUG_SERIAL_PRINT(heat);
+    DEBUG_SERIAL_PRINTLN();
+    const uint8_t rh = RelHumidity.read();
+    DEBUG_SERIAL_PRINT_FLASHSTRING("RH%: ");
+    DEBUG_SERIAL_PRINT(rh);
+    DEBUG_SERIAL_PRINTLN();
+    const int light = AmbLight.read();
+    DEBUG_SERIAL_PRINT_FLASHSTRING("L: ");
+    DEBUG_SERIAL_PRINT(light);
+    DEBUG_SERIAL_PRINTLN();
+    const int tempPot = TempPot.read();
+    DEBUG_SERIAL_PRINT_FLASHSTRING("temp pot: ");
+    DEBUG_SERIAL_PRINT(tempPot);
+    DEBUG_SERIAL_PRINTLN();
+
+    ValveDirect.read();
+
+    // Initialised: turn main/heatcall UI LED off.
+    OTV0P2BASE::LED_HEATCALL_OFF();
+
+    // Do OpenTRV-specific (late) setup.
+    PrimaryRadio.listen(false);
+
+    // Long delay after everything set up to allow a non-sleep power measurement.
+    delay(10000);
+}
+
+//========================================
+// MAIN LOOP
+//========================================
+/**
+ * @brief   Sleep in low power mode if not sleeping.
+ */
+void loop()
+{
+    static uint8_t tickCounter = 0;
+    // TX every 30 cycles (1 min, assuming 2 second cycles)
+    // Too high for normal use, but convenient for testing purposes.
+    if(0 == tickCounter) {
+        callForHeatTX();
+        tickCounter = 30;
+    }
+    --tickCounter;
+
+    // Ensure that serial I/O is off while sleeping.
+    OTV0P2BASE::powerDownSerial();
+    // Power down most stuff (except radio for hub RX).
+    OTV0P2BASE::minimisePowerWithoutSleep();
+    // Normal long minimal-power sleep until wake-up interrupt.
+    // Rely on interrupt to force quick loop round to I/O poll.
+    OTV0P2BASE::sleepUntilInt();
+
+}
+


Re-added with Energia linked folder

Re-added with Energia linked folder

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


Added demo arduino sensor project

Added demo arduino sensor project

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

--- Sensors/iot-demo-sensors/iot-demo-sensors.ino
+++ Sensors/iot-demo-sensors/iot-demo-sensors.ino
@@ -0,0 +1,112 @@
+#define DEBOUNCE 10  // button debouncer, how many ms to debounce, 5+ ms is usually plenty
+
+// here is where we define the buttons that we'll use. button "1" is the first, button "6" is the 6th, etc
+byte buttons[] = {3, 5}; // 12
+String buttonNames[] = {"pb1", "pb2"};
+
+// This handy macro lets us determine how big the array up above is, by checking the size
+#define NUMBUTTONS sizeof(buttons)
+
+byte potmeters[] = {14}; // A0-14, A5-19 6
+
+String potmeterNames[] = {"pot1"};
+// This handy macro lets us determine how big the array up above is, by checking the size
+#define NUMPOTMETERS sizeof(potmeters)
+
+
+
+// we will track if a button is just pressed, just released, or 'currently pressed'
+byte pressed[NUMBUTTONS];
+
+void setup() {
+  byte i;
+
+  // set up serial port
+  Serial.begin(9600);
+  Serial.print("Button checker with ");
+  Serial.print(NUMBUTTONS, DEC);
+  Serial.println(" buttons");
+  // pin13 LED
+  pinMode(13, OUTPUT);
+
+  // Make input & enable pull-up resistors on switch pins
+  for (i=0; i< NUMBUTTONS; i++) {
+    pinMode(buttons[i], INPUT);
+    digitalWrite(buttons[i], HIGH);
+  }
+}
+
+void check_switches()
+{
+  static byte previousstate[NUMBUTTONS];
+  static byte currentstate[NUMBUTTONS];
+  static long lasttime;
+  byte index;
+  if (millis() < lasttime) {
+     lasttime = millis(); // we wrapped around, lets just try again
+  }
+
+  if ((lasttime + DEBOUNCE) > millis()) {
+    return; // not enough time has passed to debounce
+  }
+  // ok we have waited DEBOUNCE milliseconds, lets reset the timer
+  lasttime = millis();
+
+  for (index = 0; index < NUMBUTTONS; index++) {
+    /*justpressed[index] = 0;       // when we start, we clear out the "just" indicators
+    justreleased[index] = 0;*/
+
+    currentstate[index] = digitalRead(buttons[index]);   // read the button
+    if (currentstate[index] == previousstate[index]) {
+      pressed[index] = !currentstate[index];  // remember, digital HIGH means NOT pressed
+    }
+    //Serial.println(pressed[index], DEC);
+    previousstate[index] = currentstate[index];   // keep a running tally of the buttons
+  }
+}
+
+String getSensorValueJSON(int value){
+  return String("{\"value\" : " + String(value, DEC) + "}");
+}
+
+void reportButtons(){
+  for (byte i = 0; i < NUMBUTTONS; i++) {
+    String buttonName = buttonNames[i];
+    Serial.print("\"" + buttonName + "\" : ");
+    if (pressed[i]) {
+      Serial.print(getSensorValueJSON(1));
+    }else{
+      Serial.print(getSensorValueJSON(0));
+    }
+    if((NUMPOTMETERS != 0) || (NUMPOTMETERS == 0 && i != NUMBUTTONS-1)){
+      Serial.print(", ");
+    }
+  }
+}
+
+void reportPotentiometers(){
+  for (byte i = 0; i < NUMPOTMETERS; i++) {
+    String btnName = potmeterNames[i];
+    Serial.print("\"" + btnName + "\" : ");
+    int val = analogRead(potmeters[i]);
+    Serial.print(getSensorValueJSON(val));
+    if(i != NUMPOTMETERS-1){
+      Serial.print(", ");
+    }
+  }
+}
+
+void reportInputStates(){
+  Serial.print("{");
+  reportButtons();
+  reportPotentiometers();
+  Serial.println("}");
+}
+
+void loop() {
+  check_switches();      // when we check the switches we'll get the current state
+
+  reportInputStates();
+
+}
+


Updated main board code

Updated main board code

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


draw rectangles demo

draw rectangles demo

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

--- examples/draw_rectangles/draw_rectangles.ino
+++ examples/draw_rectangles/draw_rectangles.ino
@@ -0,0 +1,44 @@
+
+#include <SoftwareSerial.h>
+#include <Warefab_TFT.h>
+
+int x, y, r, g, b;
+
+SoftwareSerial ss_tft(2, 3); // RX, TX
+Warefab_TFT tft(&ss_tft);
+
+void setup() {
+  //initialize uart speed, 115200
+  tft.begin(115200);
+}
+
+void loop() {
+  //draw rectangles
+  drawRects();
+}
+
+void drawRects()
+{
+  //initialize colors
+  tft.fillScreen(255, 255, 255);
+  //rotate 90 degrees
+  tft.rotateDisplay(tft.rotate.rotate_90);
+  //delay for 5ms
+  delay(5);
+  //loop drawing random rectangles
+  for (uint8_t i = 0; i < 50 ; i++) {
+    //random pen color
+    r = random(0, 255);
+    g = random(0, 255);
+    b = random(0, 255);
+    tft.brushColor(r, g, b);
+    //draw fill round rectangle of random sizer
+    tft.fillRectangle(x, y, (x + random(5, 41)), (y + random(5, 41)), 0);
+    //set a random position
+    x = random(20, 301);
+    y = random(20, 221);
+    //animate drawing with a 100 ms delay
+    delay(50);
+  }
+}
+


Variabler i arduino

Variabler i 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/DivineChili/Arduino-For-Noobs.git/'


beginnings of Tinyduino sketch

beginnings of Tinyduino sketch

error: pathspec 'sketch/wifi-prox.ino' did not match any file(s) known to git

--- sketch/wifi-prox.ino
+++ sketch/wifi-prox.ino
@@ -0,0 +1,112 @@
+/*
+*  Tiny WiFi temperature sensor with Arduino, the TMP36 sensor & the CC3000 chip
+*  Written by Marco Schwartz for Open Home Automation
+*  Further hacked by @noopkat for use with a proximity sensor
+*/
+
+// Include required libraries
+#include <Adafruit_CC3000.h>
+#include <ccspi.h>
+#include <SPI.h>
+#include <string.h>
+//#include "utility/debug.h"
+#include<stdlib.h>
+
+// Define CC3000 chip pins
+#define ADAFRUIT_CC3000_IRQ   2
+#define ADAFRUIT_CC3000_VBAT  A3
+#define ADAFRUIT_CC3000_CS    8
+
+// WiFi network (change with your settings !)
+#define WLAN_SSID       ""        // cannot be longer than 32 characters!
+#define WLAN_PASS       ""
+#define WLAN_SECURITY   WLAN_SEC_WPA // This can be WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2
+
+// Create CC3000 instance
+Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT, SPI_CLOCK_DIV2);
+
+// Local server IP, port, and repository (change with your settings !)
+uint32_t ip = cc3000.IP2U32(172,0,0,1);
+int port = 80;
+String repository = "/";
+byte mac[6];
+
+//  VARIABLES
+int sensorPin = 0;                 // Proximity sensor pin A0
+pinMode(sensorPin, INPUT);
+//int blinkPin = 13;                // pin to blink led
+
+
+
+void setup(void)
+{
+
+  Serial.begin(115200);
+
+  // Initialise the CC3000 module
+  if (!cc3000.begin())
+  {
+    while(1);
+  }
+
+  // Connect to  WiFi network
+  cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY);
+  Serial.println("Connected to WiFi network!");
+
+  // Check DHCP
+  Serial.println(F("Request DHCP"));
+  while (!cc3000.checkDHCP())
+  {
+    delay(100);
+  }
+
+  // this is the api call to your software running anywhere
+  String request = "POST "+ repository + " HTTP/1.0";
+
+}
+
+void loop(void)
+{
+  // bool sent = false;
+  // Serial.begin(9600);
+  // int sensorValue = analogRead(sensorPin);
+  // Serial.println(sensorValue);
+
+  // if () {
+    // watch sensor data
+    // if sensor data changes in a way expected of someone crossing the sensor's 'sight', send a request to the api
+
+    // send_request(request);
+    // sent = true;
+  }
+}
+
+// Function to send a TCP request and get the result as a string
+void send_request (String request) {
+
+    // Connect
+    Serial.println("Starting connection to server...");
+    Adafruit_CC3000_Client client = cc3000.connectTCP(ip, port);
+
+    // Send request
+    if (client.connected()) {
+      client.println(request);
+      client.println(F(""));
+      Serial.println("Connected & Data sent");
+    }
+    else {
+      Serial.println(F("Connection failed"));
+    }
+
+    while (client.connected()) {
+      while (client.available()) {
+
+      // Read answer
+      char c = client.read();
+      }
+    }
+    Serial.println("Closing connection");
+    Serial.println("");
+    client.close();
+    Serial.println("Connection closed.");
+}


initial commit

initial commit

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

--- examples/EnergyMonitor/EnergyMonitor.ino
+++ examples/EnergyMonitor/EnergyMonitor.ino
@@ -0,0 +1,76 @@
+#include <PZEM004T.h>
+
+#include "MqttConnection.h"
+MqttConnection * myMqtt;
+
+
+
+/************************* WiFi Access Point *********************************/
+
+#define WLAN_SSID       "SFR_34A8"
+#define WLAN_PASS       "ab4ingrograstanstorc"
+
+/************************* MQTT *********************************/
+
+#define MQTT_SERVER  "192.168.1.27"
+#define MQTT_PORT 1883
+
+#define SENSOR_ID "EDF"
+
+
+PZEM004T pzem(D2,D1);
+IPAddress ip(192,168,1,1);
+
+void setup() {
+  Serial.begin(115200);
+  pzem.setAddress(ip);
+  myMqtt = new MqttConnection(SENSOR_ID, WLAN_SSID, WLAN_PASS, MQTT_SERVER, MQTT_PORT);
+
+}
+
+void loop() {
+
+  if (!myMqtt->connected()) {
+    myMqtt->reconnect();
+  }
+  myMqtt->loop();
+
+
+  float v = pzem.voltage(ip);
+  wdt_reset();
+  if (v < 0.0) v = 0.0;
+  Serial.print(v);Serial.print("V; ");
+  myMqtt->publishValue("voltage", (int)v, 1);
+
+
+
+
+
+
+  float i = pzem.current(ip);
+  wdt_reset();
+  if(i >= 0.0){
+    Serial.print(i);Serial.print("A; ");
+    myMqtt->publishValue("current", i, 1);
+  }
+
+  float p = pzem.power(ip);
+  wdt_reset();
+  if(p >= 0.0){
+    Serial.print(p);Serial.print("W; ");
+    myMqtt->publishValue("power", p, 1);
+  }
+
+  float e = pzem.energy(ip);
+  wdt_reset();
+  if(e >= 0.0){
+    Serial.print(e);Serial.print("Wh; ");
+    myMqtt->publishValue("energy", v, 1);
+  }
+
+  Serial.println();
+
+  delay(1000);
+}
+
+


add laser sketch

add laser sketch

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

--- Arduino/laser-radar/laser-radar.ino
+++ Arduino/laser-radar/laser-radar.ino
@@ -0,0 +1,211 @@
+#include "Arduino.h"
+#include "Servo.h"
+#include "Wire.h"
+#include "VL53L0X.h"
+
+// Laser
+#define XSHUT_pin4 8
+#define XSHUT_pin3 7
+#define XSHUT_pin2 6
+#define XSHUT_pin1 5
+
+//ADDRESS_DEFAULT 0b0101001 or 41
+//#define Sensor1_newAddress 41 not required address change
+#define Sensor2_newAddress 42
+#define Sensor3_newAddress 43
+#define Sensor4_newAddress 44
+
+VL53L0X Sensor1;
+VL53L0X Sensor2;
+VL53L0X Sensor3;
+VL53L0X Sensor4;
+
+
+// Servo
+Servo ServoMotor;
+const uint8_t servoPin = 6;
+uint8_t servoRotationAngel = 5;
+const uint8_t servoRotationAngelFast = 10;
+const uint8_t servoRotationAngelMedium = 5;
+const uint8_t servoRotationAngelDetailed = 1;
+
+const uint8_t seroRotationDurationPerAngle = 2;
+
+enum direction {
+    left,
+    center,
+    right
+};
+
+uint8_t servoPos = 90;
+direction servoMovement = right;
+
+// ------------------------------
+//            SETUP
+// ------------------------------
+
+void setup()
+{
+    pinMode(XSHUT_pin1, OUTPUT);
+    pinMode(XSHUT_pin2, OUTPUT);
+    pinMode(XSHUT_pin3, OUTPUT);
+    pinMode(XSHUT_pin4, OUTPUT);
+
+    Serial.begin(115200);
+
+    Wire.begin();
+
+    Sensor4.setAddress(Sensor4_newAddress);
+    pinMode(XSHUT_pin3, INPUT);
+    delay(10);
+
+    Sensor3.setAddress(Sensor3_newAddress);
+    pinMode(XSHUT_pin2, INPUT);
+    delay(10);
+
+    Sensor2.setAddress(Sensor2_newAddress);
+    pinMode(XSHUT_pin1, INPUT);
+    delay(10);
+
+    Sensor1.init();
+    Sensor2.init();
+    Sensor3.init();
+    Sensor4.init();
+
+    Sensor1.setTimeout(500);
+    Sensor2.setTimeout(500);
+    Sensor3.setTimeout(500);
+    Sensor4.setTimeout(500);
+
+    Sensor1.startContinuous();
+    Sensor2.startContinuous();
+    Sensor3.startContinuous();
+    Sensor4.startContinuous();
+
+    // attach servo pin and set to initial direction
+    ServoMotor.attach(servoPin, 450, 2400); // 400, 2600 to fix rotation issues
+    ServoMotor.write(servoPos);
+    servoRotationAngel = servoRotationAngelMedium;
+}
+
+
+long GetRange(int id)
+{
+    if(id == 1)
+    {
+        return Sensor1.readRangeContinuousMillimeters();
+    }
+
+    if(id == 2)
+    {
+        return Sensor2.readRangeContinuousMillimeters();
+    }
+
+    if(id == 2)
+    {
+        return Sensor3.readRangeContinuousMillimeters();
+    }
+
+    if(id == 2)
+    {
+        return Sensor4.readRangeContinuousMillimeters();
+    }
+
+    return 0;
+}
+
+
+uint8_t GetNextServoAngle()
+{
+    if(servoPos <= 0)
+    {
+        servoMovement = right;
+        servoPos = 0;
+    }
+
+    if(servoPos >= 180)
+    {
+        servoMovement = left;
+        servoPos = 180;
+    }
+
+    if(servoMovement == right)
+    {
+        servoPos += servoRotationAngel;
+    }
+    else
+    {
+        servoPos -= servoRotationAngel;
+    }
+
+    if(servoPos <= 0) { servoPos = 0; }
+    if(servoPos >= 180) { servoPos = 180; }
+
+    return servoPos;
+}
+
+
+void ReadDataAndSetSpeed()
+{
+    String data;
+    if (Serial.available() > 0) {
+        data = Serial.readStringUntil(';');
+
+        if(data == "fast")
+        {
+            servoRotationAngel = servoRotationAngelFast;
+            averageScanAmount = averageScanAmountFast;
+            return;
+        }
+
+        if(data == "medium")
+        {
+            servoRotationAngel = servoRotationAngelMedium;
+            averageScanAmount = averageScanAmountMedium;
+            return;
+        }
+
+        if(data == "detail")
+        {
+            servoRotationAngel = servoRotationAngelDetailed;
+            averageScanAmount = averageScanAmountDetailed;
+            return;
+        }
+    }
+}
+
+void SendData(name, position, distance)
+{
+    Serial.print("Laser");
+    Serial.print("|");
+    Serial.print(name);
+    Serial.print("|");
+    Serial.print(position);
+    Serial.print("|");
+    Serial.println(distance);
+}
+
+
+void loop()
+{
+    ReadDataAndSetSpeed();
+
+    uint8_t actualServoPos = ServoMotor.read();
+    if(servoPos == actualServoPos)
+    {
+        uint8_t nextAngle = GetNextServoAngle();
+        ServoMotor.write(nextAngle);
+        delay(seroRotationDurationPerAngle * (abs(nextAngle - actualServoPos)));
+    }
+
+    long laserOne = GetRange(1);
+    long laserTwo = GetRange(2);
+    long laserThree = GetRange(3);
+    long laserFrour = GetRange(4);
+
+    SendData("One", servoPos, laserOne);
+    SendData("Two", (servoPos+90%360), laserTwo);
+    SendData("Three", (servoPos+180%360), laserThree);
+    SendData("Four", (servoPos+270%360), laserFour);
+}
+


Tidy up of h-bridge master for sudoac device: https://github.com/freephases/sudoac


Initial commit

Initial commit

--- bike-sensor.ino
+++ bike-sensor.ino
@@ -0,0 +1,35 @@
+const int PIN_LED = 11;
+const int PIN_PULSE = 5;
+const int DEBOUNCE_TIME = 100;
+const int LED_TIME = 100;
+
+unsigned long last_rev = 0;
+unsigned long led_off = 0;
+
+void revolution() {
+  unsigned long time = millis();
+  long elapsed = time - last_rev;
+  if (elapsed > DEBOUNCE_TIME) {
+    digitalWrite(PIN_LED, HIGH);
+    led_off = time + LED_TIME;
+    last_rev = time;
+
+    int rpm = 60000 / elapsed;
+    Serial.println(rpm);
+  }
+}
+
+void setup() {
+  pinMode(PIN_LED, OUTPUT);
+  pinMode(PIN_PULSE, INPUT_PULLUP);
+
+  Serial.begin(9600);
+
+  attachInterrupt(0, revolution, FALLING);
+}
+
+void loop() {
+  if (millis() > led_off) {
+    digitalWrite(PIN_LED, LOW);
+  }
+}


Boost: Initial working code

Boost: Initial working code

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

--- ppt-boost/ppt-boost.ino
+++ ppt-boost/ppt-boost.ino
@@ -0,0 +1,268 @@
+//------------------------------------------------------------------------------------------------------
+//
+// Arduino Peak Power Tracking Solar Charger     by Tim Nolan (www.timnolan.com)   5/1/09
+//
+//    This software implements my Peak Power Tracking Solar Charger using the Arduino Demilove developement
+//    board. I'm releasing this software and hardware project as open source. It is free of any restiction for
+//    anyone to use. All I ask is that if you use any of my hardware or software or ideas from this project
+//    is that you give me credit and add a link to my website www.timnolan.com to your documentation.
+//    Thank you.
+//
+//    5/1/09  v1.00    First development version. Just getting something to work.
+//
+//
+//------------------------------------------------------------------------------------------------------
+
+#include <TimerOne.h>          // using Timer1 library from http://www.arduino.cc/playground/Code/Timer1
+
+//------------------------------------------------------------------------------------------------------
+// definitions
+#define TRUE                1
+#define FALSE               0
+#define ON                  TRUE
+#define OFF                 FALSE
+
+#define PWM_PIN             9             // the output pin for the pwm, connected to OC1A
+#define PWM_ENABLE_PIN      8             // pin used to control shutoff function of the IR2104 MOSFET driver
+#define TURN_ON_MOSFETS     digitalWrite(PWM_ENABLE_PIN, HIGH)     // enable MOSFET driver
+#define TURN_OFF_MOSFETS    digitalWrite(PWM_ENABLE_PIN, LOW)      // disable MOSFET driver
+
+#define ADC_SOL_AMPS_CHAN   1             // the adc channel to read solar amps
+#define ADC_SOL_VOLTS_CHAN  0             // the adc channel to read solar volts
+#define ADC_BAT_VOLTS_CHAN  2             // the adc channel to read battery volts
+
+#define PWM_FULL            1023          // the actual value used by the Timer1 routines for 100% pwm duty cycle
+#define PWM_MAX             0.5*PWM_FULL  // the value for pwm duty cyle 0-100.0% (Resolution in
+#define PWM_MIN             0.01*PWM_FULL // the value for pwm duty cyle 0-100.0%
+#define PWM_START           PWM_MIN       // the value for pwm duty cyle 0-100.0%
+#define PWM_INC             4             // the value the increment to the pwm value for the ppt algorithm
+
+#define AVG_NUM             2             // number of iterations of the adc routine to average the adc readings
+#define SOL_AMPS_SCALE      0.5           // the scaling value for raw adc reading to get solar amps scaled by 100 [(1/(0.005*(3.3k/25))*(5/1023)*100]
+#define SOL_VOLTS_SCALE     2.7           // the scaling value for raw adc reading to get solar volts scaled by 100 [((10+2.2)/2.2)*(5/1023)*100]
+#define BAT_VOLTS_SCALE     2.7           // the scaling value for raw adc reading to get battery volts scaled by 100 [((10+2.2)/2.2)*(5/1023)*100]
+
+#define ONE_SECOND          50000         // count for number of interrupt in 1 second on interrupt period of 20us
+
+#define PIN_LED             13            // LED connected to digital pin 13
+
+//------------------------------------------------------------------------------------------------------
+// global variables
+struct system_states_t {
+   int sol_amps;                         // solar amps in 10 mV (scaled by 100)
+   int sol_volts;                        // solar volts in 10 mV (scaled by 100)
+   int bat_volts;                        // battery volts in 10 mV (scaled by 100)
+   int sol_watts;                        // solar watts in 10 mV (scaled by 100)
+   uint16_t pwm_duty;
+} power_status;
+
+unsigned int seconds = 0;             // seconds from timer routine
+
+void set_pwm_duty(int pwm);
+
+//------------------------------------------------------------------------------------------------------
+// This routine is automatically called at powerup/reset
+//------------------------------------------------------------------------------------------------------
+void setup()                            // run once, when the sketch starts
+{
+  Serial.begin(115200);                  // open the serial port at 9600 bps:
+  pinMode(PWM_ENABLE_PIN, OUTPUT);     // sets the digital pin as output
+  Timer1.initialize(20);               // initialize timer1, and set a 20uS period
+  Timer1.pwm(PWM_PIN, 0);              // setup pwm on pin 9, 0% duty cycle
+  TURN_ON_MOSFETS;                     //turn on MOSFET driver chip
+  Timer1.attachInterrupt(callback);    // attaches callback() as a timer overflow interrupt
+
+  set_pwm_duty(PWM_START);
+}
+//------------------------------------------------------------------------------------------------------
+// This is interrupt service routine for Timer1 that occurs every 20uS.
+// It is only used to incremtent the seconds counter.
+// Timer1 is also used to generate the pwm output.
+//------------------------------------------------------------------------------------------------------
+void callback()
+{
+  static unsigned int interrupt_counter = 0;     // counter for 20us interrrupt
+
+  if (interrupt_counter++ > ONE_SECOND) {        //increment interrupt_counter until one second has passed
+    interrupt_counter = 0;
+    seconds++;                                   //then increment seconds counter
+  }
+}
+//------------------------------------------------------------------------------------------------------
+// This routine reads and averages the analog inputs for this system, solar volts, solar amps and
+// battery volts. It is called with the adc channel number (pin number) and returns the average adc
+// value as an integer.
+//------------------------------------------------------------------------------------------------------
+int read_adc(int channel){
+
+  int sum = 0;
+
+  for (int i=0; i<AVG_NUM; i++) {            // loop through reading raw adc values AVG_NUM number of times
+    int temp = analogRead(channel);          // read the input pin
+    sum += temp;                        // store sum for averaging
+   // delayMicroseconds(2);              // pauses for 50 microseconds
+  }
+  return(sum / AVG_NUM);                // divide sum by AVG_NUM to get average and return it
+}
+//-----------------------------------------------------------------------------------
+// This function prints int that was scaled by 100 with 2 decimal places
+//-----------------------------------------------------------------------------------
+void print_int100_dec2(int temp) {
+
+  Serial.print(temp/100,DEC);        // divide by 100 and print interger value
+  Serial.print(".");
+  if ((temp%100) < 10) {              // if fractional value has only one digit
+    Serial.print("0");               // print a "0" to give it two digits
+    Serial.print(temp%100,DEC);      // get remainder and print fractional value
+  }
+  else {
+    Serial.print(temp%100,DEC);      // get remainder and print fractional value
+  }
+}
+//------------------------------------------------------------------------------------------------------
+// This routine uses the Timer1.pwm function to set the pwm duty cycle. The routine takes the value in
+// the variable pwm as 0-100 duty cycle and scales it to get 0-1034 for the Timer1 routine.
+// There is a special case for 100% duty cycle. Normally this would be have the top MOSFET on all the time
+// but the MOSFET driver IR2104 uses a charge pump to generate the gate voltage so it has to keep running
+// all the time. So for 100% duty cycle I set the pwm value to 1023 - 1 so it is on 99.9% almost full on
+// but is switches enough to keep the charge pump on IR2104 working.
+//------------------------------------------------------------------------------------------------------
+
+void set_pwm_duty(int pwm) {
+
+  if (pwm > PWM_MAX) {					   // check limits of PWM duty cyle and set to PWM_MAX
+    pwm = PWM_MAX;
+  }
+  else if (pwm < PWM_MIN) {				   // if pwm is less than PWM_MIN then set it to PWM_MIN
+    pwm = PWM_MIN;
+  }
+
+  power_status.pwm_duty = pwm;                             // store this value in the status
+
+  if (pwm < PWM_MAX) {
+    Timer1.pwm(PWM_PIN, PWM_FULL - pwm, 20); // use Timer1 routine to set pwm duty cycle at 20uS period
+    //Timer1.pwm(PWM_PIN,(PWM_FULL * (long)pwm / 100));
+  }
+  else if (pwm == PWM_MAX) {				  // if pwm set to 100% it will be on full but we have
+    Timer1.pwm(PWM_PIN, 4, 1000);             // keep switching so set duty cycle at 99.9% and slow down to 1000uS period
+    //Timer1.pwm(PWM_PIN,(PWM_FULL - 1));
+  }
+}
+
+//------------------------------------------------------------------------------------------------------
+// This routine prints all the data out to the serial port.
+//------------------------------------------------------------------------------------------------------
+void print_data(void) {
+
+  Serial.print(seconds,DEC);
+  Serial.print("  ");
+
+  Serial.print("pwm = ");
+  print_int100_dec2((long)power_status.pwm_duty * 10000 / (PWM_FULL - 1));
+  Serial.print("  ");
+
+  Serial.print("s_amps = ");
+  print_int100_dec2(power_status.sol_amps);
+  Serial.print("  ");
+
+  Serial.print("s_volts = ");
+  //Serial.print(sol_volts,DEC);
+  //Serial.print("  ");
+  print_int100_dec2(power_status.sol_volts);
+  Serial.print("  ");
+
+  Serial.print("s_watts = ");
+  print_int100_dec2(power_status.sol_watts);
+  Serial.print("  ");
+
+  Serial.print("b_volts = ");
+  //Serial.print(bat_volts,DEC);
+  print_int100_dec2(power_status.bat_volts);
+  Serial.print("  ");
+
+  Serial.print("\n\r");
+}
+//------------------------------------------------------------------------------------------------------
+// This routine reads all the analog input values for the system. Then it multiplies them by the scale
+// factor to get actual value in volts or amps. Then it adds on a rounding value before dividing to get
+// the result scaled by 100 to give a fractional value of two decimal places. It also calculates the input
+// watts from the solar amps times the solar voltage and rounds and scales that by 100 (2 decimal places) also.
+//------------------------------------------------------------------------------------------------------
+void read_data(void) {
+
+  power_status.sol_amps =  SOL_AMPS_SCALE * read_adc(ADC_SOL_AMPS_CHAN) ;// * read_adc(ADC_SOL_AMPS_CHAN); //((read_adc(ADC_SOL_AMPS_CHAN)  * SOL_AMPS_SCALE) + 5) / 10;    //input of solar amps result scaled by 100
+  power_status.sol_volts = SOL_VOLTS_SCALE * read_adc(ADC_SOL_VOLTS_CHAN); //((read_adc(ADC_SOL_VOLTS_CHAN) * SOL_VOLTS_SCALE) + 5) / 10;   //input of solar volts result scaled by 100
+  power_status.bat_volts = BAT_VOLTS_SCALE * read_adc(ADC_BAT_VOLTS_CHAN); // ((read_adc(ADC_BAT_VOLTS_CHAN) * BAT_VOLTS_SCALE) + 5) / 10;   //input of battery volts result scaled by 100
+  power_status.sol_watts = (int)((((long)power_status.sol_amps * (long)power_status.sol_volts) + 50) / 100);    //calculations of solar watts scaled by 10000 divide by 100 to get scaled by 100
+}
+//------------------------------------------------------------------------------------------------------
+// Main loop.
+// Right now the number of times per second that this main loop runs is set by how long the printing to
+// the serial port takes. You can speed that up by speeding up the baud rate.
+// You can also run the commented out code and the charger routines will run once a second.
+//------------------------------------------------------------------------------------------------------
+
+void constant_power_control(int target_watts) {
+  static int old_sol_watts = 0;
+
+  int current_watts = power_status.sol_watts;
+  int current_pwm = power_status.pwm_duty;
+
+  if (target_watts < current_watts) {
+    current_pwm -= PWM_INC;
+  } else if (target_watts > current_watts) {
+    current_pwm += PWM_INC;
+  }
+
+  set_pwm_duty(current_pwm);
+}
+
+void constant_voltage_control(int target_voltage) {
+  static int old_bat_volt = 0;
+
+  int current_voltage = power_status.bat_volts;
+  int current_pwm = power_status.pwm_duty;
+
+  if (target_voltage < current_voltage) {
+    current_pwm -= PWM_INC;
+  } else if (target_voltage > current_voltage) {
+    current_pwm += PWM_INC;
+  }
+
+  set_pwm_duty(current_pwm);
+}
+
+void loop()                          // run over and over again
+{
+  read_data();                         //read data from inputs
+//  MPPT_state_machine();                      //run the charger state machine
+
+  static int current_power = 0;
+  static unsigned int prev_seconds = 0;        // seconds value from previous pass
+  if ((seconds - prev_seconds) > 4) {
+    prev_seconds = seconds;		// do this stuff once a second
+
+    if (current_power >= 1600) {
+      current_power = 1200;
+    }
+    else {
+      current_power += 100;
+    }
+  }
+
+  //constant_voltage_control(current_power);
+  constant_voltage_control(current_power);
+
+  static unsigned int print_counter = 0;
+  print_counter++;
+  if (print_counter > 100) {
+    print_data();                       //print data
+    print_counter = 0;
+  }
+
+//    read_data();                         //read data from inputs
+//    MPPT_state_machine();
+//    print_data();                       //print data
+//  }
+}
+//------------------------------------------------------------------------------------------------------


Create weatherstation.ino

Create weatherstation.ino

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

--- weatherstation.ino
+++ weatherstation.ino
@@ -0,0 +1,539 @@
+// This #include statement was automatically added by the Spark IDE.
+#include "idDHT22.h"
+
+/****************************************************************************
+*   Project: Weather Station NG                                           *
+*                                                                           *
+****************************************************************************/
+extern char* itoa(int a, char* buffer, unsigned char radix);
+
+// Time (seconds) for each sleep
+#define PERIOD 300
+// Set UPDATE2CLOUD to true if you want the measurement sent to the cloud
+#define UPDATE2CLOUD true
+// Thingspeak API WRITE key
+#define THINGSPEAK_API_WRITEKEY "89DQON6G9XOGVTR3"
+#define version 101
+
+#define BACKLDUR 10000 // 10s
+#define TIMEOUT 10000
+#define CHTUPDPERIOD 300 // update every 300s
+
+int lastT;
+// int BackLight = A1;
+int BackLightTrigger = D3;
+int trigger = 0;
+bool refresh = true;
+
+// Pin out defs
+int led = D7;
+
+// declaration for AM2321 handler
+int idDHT22pin = D4; //Digital pin for comunications
+void dht22_wrapper(); // must be declared before the lib initialization
+String status;
+float temp, humi = 0;
+// AM2321 instantiate
+idDHT22 DHT22(idDHT22pin, dht22_wrapper);
+
+
+// Thingspeak.com API
+TCPClient client;
+const char * WRITEKEY = THINGSPEAK_API_WRITEKEY;
+const char * serverName = "api.thingspeak.com";
+IPAddress server = {184,106,153,149};
+
+// 1.3" 12864 OLED with SH1106 and Simplified Chinese IC for Spark Core
+int Rom_CS = A2;
+unsigned long  fontaddr=0;
+char dispCS[32];
+
+/****************************************************************************
+*****************************************************************************
+****************************   OLED Driver  *********************************
+*****************************************************************************
+****************************************************************************/
+
+
+/*****************************************************************************
+ Funtion    :   OLED_WrtData
+ Description:   Write Data to OLED
+ Input      :   byte8 ucCmd
+ Output     :   NONE
+ Return     :   NONE
+*****************************************************************************/
+void transfer_data_lcd(byte ucData)
+{
+   Wire.beginTransmission(0x78 >> 1);
+   Wire.write(0x40);      //write data
+   Wire.write(ucData);
+   Wire.endTransmission();
+}
+
+/*****************************************************************************
+ Funtion    :   OLED_WrCmd
+ Description:   Write Command to OLED
+ Input      :   byte8 ucCmd
+ Output     :   NONE
+ Return     :   NONE
+*****************************************************************************/
+void transfer_command_lcd(byte ucCmd)
+{
+   Wire.beginTransmission(0x78 >> 1);            //Slave address,SA0=0
+   Wire.write(0x00);      //write command
+   Wire.write(ucCmd);
+   Wire.endTransmission();
+}
+
+
+/* OLED Initialization */
+void initial_lcd()
+{
+  digitalWrite(Rom_CS, HIGH);
+  // Wire.enableDMAMode(true);
+  Wire.begin();
+  delay(20);
+  transfer_command_lcd(0xAE);   //display off
+  transfer_command_lcd(0x20); //Set Memory Addressing Mode
+  transfer_command_lcd(0x10); //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid
+  transfer_command_lcd(0xb0); //Set Page Start Address for Page Addressing Mode,0-7
+  transfer_command_lcd(0xc8); //Set COM Output Scan Direction
+  transfer_command_lcd(0x00);//---set low column address
+  transfer_command_lcd(0x10);//---set high column address
+  transfer_command_lcd(0x40);//--set start line address
+  transfer_command_lcd(0x81);//--set contrast control register
+  transfer_command_lcd(0x7f);
+  transfer_command_lcd(0xa1);//--set segment re-map 0 to 127
+  transfer_command_lcd(0xa6);//--set normal display
+  transfer_command_lcd(0xa8);//--set multiplex ratio(1 to 64)
+  transfer_command_lcd(0x3F);//
+  transfer_command_lcd(0xa4);//0xa4,Output follows RAM content;0xa5,Output ignores RAM content
+  transfer_command_lcd(0xd3);//-set display offset
+  transfer_command_lcd(0x00);//-not offset
+  transfer_command_lcd(0xd5);//--set display clock divide ratio/oscillator frequency
+  transfer_command_lcd(0xf0);//--set divide ratio
+  transfer_command_lcd(0xd9);//--set pre-charge period
+  transfer_command_lcd(0x22); //
+  transfer_command_lcd(0xda);//--set com pins hardware configuration
+  transfer_command_lcd(0x12);
+  transfer_command_lcd(0xdb);//--set vcomh
+  transfer_command_lcd(0x20);//0x20,0.77xVcc
+  transfer_command_lcd(0x8d);//--set DC-DC enable
+  transfer_command_lcd(0x14);//
+  transfer_command_lcd(0xaf);//--turn on oled panel
+
+}
+
+void lcd_address(byte page,byte column)
+{
+
+  transfer_command_lcd(0xb0 + column);   /* Page address */
+  transfer_command_lcd((((page + 1) & 0xf0) >> 4) | 0x10);  /* 4 bit MSB */
+  transfer_command_lcd(((page + 1) & 0x0f) | 0x00); /* 4 bit LSB */
+}
+
+void clear_screen()
+{
+  unsigned char i,j;
+  digitalWrite(Rom_CS, HIGH);
+  for(i=0;i<8;i++)
+  {
+    transfer_command_lcd(0xb0 + i);
+    transfer_command_lcd(0x00);
+    transfer_command_lcd(0x10);
+    for(j=0;j<132;j++)
+    {
+        transfer_data_lcd(0x00);
+    }
+  }
+
+}
+
+void display_128x64(byte *dp)
+{
+  unsigned int i,j;
+  for(j=0;j<8;j++)
+  {
+    lcd_address(0,j);
+    for (i=0;i<132;i++)
+    {
+      if(i>=2&&i<130)
+      {
+          // Write data to OLED, increase address by 1 after each byte written
+        transfer_data_lcd(*dp);
+        dp++;
+      }
+    }
+
+  }
+
+}
+
+
+
+void display_graphic_16x16(unsigned int page,unsigned int column,byte *dp)
+{
+  unsigned int i,j;
+
+  digitalWrite(Rom_CS, HIGH);
+  for(j=2;j>0;j--)
+  {
+    lcd_address(column,page);
+    for (i=0;i<16;i++)
+    {
+      transfer_data_lcd(*dp);
+      dp++;
+    }
+    page++;
+  }
+}
+
+
+void display_graphic_8x16(unsigned int page,byte column,byte *dp)
+{
+  unsigned int i,j;
+
+  for(j=2;j>0;j--)
+  {
+    lcd_address(column,page);
+    for (i=0;i<8;i++)
+    {
+      // Write data to OLED, increase address by 1 after each byte written
+      transfer_data_lcd(*dp);
+      dp++;
+    }
+    page++;
+  }
+
+}
+
+
+/*
+    Display a 5x7 dot matrix, ASCII or a 5x7 custom font, glyph, etc.
+*/
+
+void display_graphic_5x7(unsigned int page,byte column,byte *dp)
+{
+  unsigned int col_cnt;
+  byte page_address;
+  byte column_address_L,column_address_H;
+  page_address = 0xb0 + page - 1;//
+
+
+
+  column_address_L =(column&0x0f);  // -1
+  column_address_H =((column>>4)&0x0f)+0x10;
+
+  transfer_command_lcd(page_address);     /*Set Page Address*/
+  transfer_command_lcd(column_address_H); /*Set MSB of column Address*/
+  transfer_command_lcd(column_address_L); /*Set LSB of column Address*/
+
+  for (col_cnt=0;col_cnt<6;col_cnt++)
+  {
+    transfer_data_lcd(*dp);
+    dp++;
+  }
+}
+
+/**** Send command to Character ROM ***/
+void send_command_to_ROM( byte datu )
+{
+  SPI.transfer(datu);
+}
+
+/**** Read a byte from the Character ROM ***/
+byte get_data_from_ROM( )
+{
+  byte ret_data=0;
+  ret_data = SPI.transfer(255);
+  return(ret_data);
+}
+
+
+/*
+*     Read continuously from ROM DataLen's bytes and
+*     put them into pointer pointed to by pBuff
+*/
+
+void get_n_bytes_data_from_ROM(byte addrHigh,byte addrMid,byte addrLow,byte *pBuff,byte DataLen )
+{
+  byte i;
+  digitalWrite(Rom_CS, LOW);
+  delayMicroseconds(100);
+  send_command_to_ROM(0x03);
+  send_command_to_ROM(addrHigh);
+  send_command_to_ROM(addrMid);
+  send_command_to_ROM(addrLow);
+
+  for(i = 0; i < DataLen; i++ ) {
+       *(pBuff+i) =get_data_from_ROM();
+  }
+  digitalWrite(Rom_CS, HIGH);
+}
+
+
+/******************************************************************/
+
+void display_string_5x7(byte y,byte x,const char *text)
+{
+  unsigned char i= 0;
+  unsigned char addrHigh,addrMid,addrLow ;
+  while((text[i]>0x00))
+  {
+
+    if((text[i]>=0x20) &&(text[i]<=0x7e))
+    {
+      unsigned char fontbuf[8];
+      fontaddr = (text[i]- 0x20);
+      fontaddr = (unsigned long)(fontaddr*8);
+      fontaddr = (unsigned long)(fontaddr+0x3bfc0);
+      addrHigh = (fontaddr&0xff0000)>>16;
+      addrMid = (fontaddr&0xff00)>>8;
+      addrLow = fontaddr&0xff;
+
+      get_n_bytes_data_from_ROM(addrHigh,addrMid,addrLow,fontbuf,8);/*取8个字节的数据，存到"fontbuf[32]"*/
+
+      display_graphic_5x7(y,x+1,fontbuf);/*显示5x7的ASCII字到LCD上，y为页地址，x为列地址，fontbuf[]为数据*/
+      i+=1;
+      x+=6;
+    }
+    else
+    i++;
+  }
+
+}
+
+
+/****************************************************************************
+*****************************************************************************
+****************************  Data Upload   *********************************
+*****************************************************************************
+****************************************************************************/
+
+void sendToThingSpeak(const char * key, String mesg)
+{
+    noInterrupts();
+    client.stop();
+    RGB.control(true);
+    RGB.color(0,255,0);
+    int lt = millis();
+    display_string_5x7(6,1,"Wifi");
+
+    while (!WiFi.ready() && (millis() - lt < TIMEOUT)) {
+        display_string_5x7(6,1,"Wifi...X");
+        delay(1000);
+    }
+    while (!client.connect(server,80) && (millis() - lt < TIMEOUT)) {
+        display_string_5x7(6,1,"Connecting Server...");
+        delay(15000);
+    }
+    if (millis() - lt < TIMEOUT) {
+        display_string_5x7(6,1,"Sending...         ");
+        client.print("POST /update");
+        client.println(" HTTP/1.1");
+        client.print("Host: ");
+        client.println(serverName);
+        client.println("User-Agent: Spark");
+        client.println("Connection: close");
+        client.print("X-THINGSPEAKAPIKEY: ");
+        client.println(key);
+        client.println("Content-Type: application/x-www-form-urlencoded");
+        client.print("Content-length: ");
+        client.println(mesg.length());
+        client.println();
+        client.println(mesg);
+        client.flush();
+        display_string_5x7(6,1,"Waiting resp  ");
+        lt = millis();
+        while (client.available() == false && millis() - lt < 1000) {
+            // Just wait up to 1000 millis
+            delay(200);
+        }
+        display_string_5x7(6,1,"Reading resp  ");
+        lt = millis();
+        while (client.available() > 0 && millis() - lt < 10000) {
+            client.read();
+        }
+        client.flush();
+        client.stop();
+        RGB.control(false);
+        display_string_5x7(6,1,"Done          ");
+    }
+    else{
+        display_string_5x7(6,1,"Connection Failed");
+        RGB.color(255,0,0);
+    }
+    interrupts();
+}
+
+
+
+int myVersion(String command)
+{
+    return version;
+}
+
+void publishReadings()
+{
+    if ((millis() - lastT) > (CHTUPDPERIOD * 1000)) {
+        lastT = millis();
+        readAM2321();
+        char szEventInfo[64];
+        sprintf(szEventInfo, "field1=%.1f&field2=%.2f", temp, humi);
+        sendToThingSpeak(WRITEKEY,String(szEventInfo));
+        Spark.sleep(CHTUPDPERIOD - 30);
+    }
+}
+
+void backLightOn()
+{
+    trigger = millis() + BACKLDUR;
+    transfer_command_lcd(0xaf);//--turn on oled panel
+    //display_string_5x7(6,1,"DISP ON ");
+    refresh = true;
+}
+
+void backLightOff()
+{
+    //display_string_5x7(6,1,"DISP OFF");
+    transfer_command_lcd(0xae);//--turn off oled panel
+    refresh=false;
+}
+
+
+// This wrapper is in charge of calling
+// mus be defined like this for the lib work
+void dht22_wrapper() {
+  DHT22.isrCallback();
+}
+
+void readAM2321() {
+  int lt = millis();
+  int result;
+
+  detachInterrupt(BackLightTrigger);
+    DHT22.acquire();
+  while (DHT22.acquiring() && (millis() - lt < TIMEOUT))
+    ;
+  //delay(500);
+  //DHT22.acquire();
+  //while (DHT22.acquiring())
+  //  ;
+  if (millis() - lt >= TIMEOUT) {
+      result = IDDHTLIB_ERROR_ACQUIRING;
+  } else {
+      result = DHT22.getStatus();
+  }
+  switch (result)
+  {
+    case IDDHTLIB_OK:
+      status = "OK";
+      break;
+    case IDDHTLIB_ERROR_CHECKSUM:
+      status = "Checksum";
+      break;
+    case IDDHTLIB_ERROR_ISR_TIMEOUT:
+      status = "ISR Time out";
+      break;
+    case IDDHTLIB_ERROR_RESPONSE_TIMEOUT:
+      status = "Response time out";
+      break;
+    case IDDHTLIB_ERROR_DATA_TIMEOUT:
+      status = "Data time out";
+      break;
+    case IDDHTLIB_ERROR_ACQUIRING:
+      status = "Acquiring";
+      break;
+    case IDDHTLIB_ERROR_DELTA:
+      status = "Delta time to small";
+      break;
+    case IDDHTLIB_ERROR_NOTSTARTED:
+      status = "Not started";
+      break;
+    default:
+      status = "Unknown";
+      break;
+  }
+
+    temp = DHT22.getCelsius();
+    humi = DHT22.getHumidity();
+    attachInterrupt(BackLightTrigger, backLightOn, RISING);
+
+}
+
+
+/****************************************************************************
+*****************************************************************************
+**************************  Initialization  *********************************
+*****************************************************************************
+****************************************************************************/
+
+void setup()
+{
+    Time.zone(8);
+
+    pinMode(led, OUTPUT);
+//    pinMode(BackLight, OUTPUT);
+    pinMode(BackLightTrigger, INPUT);
+
+  // Register a Spark variable here
+    Spark.variable("Temperature", &temp, DOUBLE);
+    Spark.variable("Pressure", &humi, DOUBLE);
+    attachInterrupt(BackLightTrigger, backLightOn, RISING);
+
+    SPI.begin();
+    SPI.setBitOrder(MSBFIRST);
+    SPI.setDataMode(SPI_MODE3);
+    SPI.setClockDivider(SPI_CLOCK_DIV8);
+    digitalWrite(Rom_CS, HIGH);
+
+    initial_lcd();
+    clear_screen();    //clear all dots
+    digitalWrite(led, LOW);
+    display_string_5x7(4,1,"(c)2014 ioStation");
+    sprintf(dispCS, "Version: %d", version);
+    display_string_5x7(6,1,dispCS);
+    delay(1000);
+    clear_screen();    //clear all dots
+    sprintf(dispCS, "v%d", version);
+    display_string_5x7(7,1,dispCS);
+    lastT = millis();
+    backLightOn();
+}
+
+/****************************************************************************
+*****************************************************************************
+**************************  Main Proc Loop  *********************************
+*****************************************************************************
+****************************************************************************/
+
+void loop()
+{
+    if (refresh) {
+      Time.timeStr().substring(4,19).toCharArray(dispCS, 16);
+      display_string_5x7(1,1,"     ");
+      display_string_5x7(1,20,dispCS);
+
+      readAM2321();
+      status.toCharArray(dispCS, 18);
+      display_string_5x7(6,1,dispCS);
+
+      sprintf(dispCS, "T: %0.1f, H: %0.1f    ", temp, humi);
+      display_string_5x7(3,1,dispCS);
+    }
+
+    publishReadings();
+    //backLightOn();
+    if (trigger > 0 && millis() > trigger) {
+        trigger = 0;
+        backLightOff();
+    }
+
+
+    delay(500);
+}
+
+
+
+
+


Added keymappings etc.

Added keymappings etc.

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/ocean-x/erikson-1.git/'


update calc_minute()

update calc_minute()

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/janiversen/SolarPower.git/'


Isolated working RFIDreader

Isolated working RFIDreader

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

--- MF_ACM/MF_ACM.ino
+++ MF_ACM/MF_ACM.ino
@@ -0,0 +1,133 @@
+#include <SoftwareSerial.h>
+
+#define RDM880_RX 2
+#define RDM880_TX 3
+#define bufferSize 255
+
+#define STX 0xAA
+#define ETX 0xBB
+
+#define CMD_READ 0x20
+#define CMD_WRITE 0x21
+#define CMD_INITVAL 0x22
+#define CMD_DECREMENT 0x23
+#define CMD_INCREMENT 0x24
+#define CMD_GET_SNR 0x25
+
+/* RFID Reader
+   Uses RDM880 breakout board with RX connected to pin 2 and TX connected to pin 3.
+   Another serial interface is added by including the Software Serial library.
+   Dummy signal from 3.3 V is connected to pin 4.
+
+   Input:
+      RFID tags
+      Signal from Pin 4
+
+   Output:
+      Serial number of tag scanned
+      Elapsed time
+
+   Operation:
+      Reader waits until a tag is scanned, then prints the serial number of the tag.
+      Reader now waits for "control" signal, and when that signal goes high, counts time.
+
+*/
+
+// instantiate new serial ports, Uno ports are reserved for serial monitor
+SoftwareSerial RDM880(RDM880_RX, RDM880_TX);
+char txrxbuffer[bufferSize];
+
+const int ledPin = 13;
+const int signalPin = 4;
+const int debounce = 25;
+
+void setup() {
+  Serial.begin(57600);
+  RDM880.begin(9600);
+  pinMode(ledPin, OUTPUT);
+  pinMode(signalPin, INPUT);
+}
+
+void loop() {
+  bool standby = true;
+  unsigned char responseFlag = NULL;
+  unsigned long elapsedTime = 0;
+
+  // send command packet to RDM880 to read serial number every second
+  MF_GET_SNR(0x00);
+  delay(100);
+  digitalWrite(ledPin, LOW);
+
+  responseFlag = getResponse(responseFlag);
+
+  // LED on if an RFID is detected (idle packet only contains 7 bytes)
+  if(responseFlag != NULL) {
+    digitalWrite(ledPin, HIGH);
+    // Machine is ready to fire, get ready to track time
+    standby = false;
+    elapsedTime = accumulator(standby);
+  }
+  Serial.println();
+}
+
+unsigned long accumulator(bool standby) {
+  unsigned long startTime, endTime = 0;
+  int signalState;
+  int previousState = NULL;
+
+  while(standby == false) {
+    // read signal state
+    signalState = digitalRead(signalPin);
+    delay(debounce);
+
+    // debounce check
+    if (signalState == digitalRead(signalPin)) {
+
+      // check for new ON signal
+      if (previousState == LOW && signalState == HIGH) {
+        startTime = millis();
+        previousState = signalState;
+      }
+      // check for OFF signal
+      else if (previousState == HIGH && signalState == LOW) {
+        endTime = (millis() - startTime)/1000;
+        if (endTime != 0) {
+          Serial.print("Elapsed time: ");
+          Serial.print(endTime);
+        }
+        previousState = signalState;
+        standby = true;
+      }
+      // no event
+      else {
+        previousState = signalState;
+      }
+
+    }
+
+  }
+}
+
+unsigned char getResponse(unsigned char responseFlag) {
+  int i = 0;
+  unsigned char response[bufferSize];
+  response[7] = NULL;
+
+  while(RDM880.available()) {
+    response[i] = RDM880.read();
+    Serial.print(response[i], HEX);
+    Serial.print(" ");
+    i++;
+  }
+
+  if (response[7] != NULL)
+    return response[7];
+  else
+    return NULL;
+}
+
+void MF_GET_SNR(unsigned char DADD) {
+  unsigned char CMD[] = { STX, DADD, 0x03, CMD_GET_SNR, 0x26, 0x00, 0x00, ETX};
+  RDM880.write(CMD, 8);
+}
+


Delete USB_PS3_Example.ino

Delete USB_PS3_Example.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/nitricx/Tank_Automation.git/'


Combined LCD & motor control with mosfet

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

--- Watering/Watering.ino
+++ Watering/Watering.ino
@@ -0,0 +1,39 @@
+#include <LiquidCrystal.h>
+
+LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
+const int contrastPin = 6;
+const int contrast = 40;
+
+const int gate = 7;
+int mode = 0;
+
+void setup() {
+  Serial.begin(9600);
+  pinMode(gate, OUTPUT);
+  Serial.println("Enter 0 or 1");
+
+  lcd.begin(16, 2);
+  pinMode(contrastPin, OUTPUT);
+  analogWrite(contrastPin, contrast);
+  lcd.print("Type 0 or 1");
+  lcd.setCursor(0, 1);
+  lcd.print("in serial");
+}
+
+void loop() {
+  if (Serial.available()) {
+    mode = Serial.parseInt();
+    if (mode == 0) {
+      digitalWrite(gate, LOW);
+    }
+    else {
+      digitalWrite(gate, HIGH);
+    }
+    lcd.clear();
+    lcd.setCursor(0, 0);
+    lcd.print("New value ");
+    lcd.print(mode);
+    lcd.setCursor(0, 1);
+    lcd.write("Enter 0 or 1");
+  }
+}


add obstacle avoiding program

add obstacle avoiding program

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/nisald/robot_program.git/'


FIx spelling mistake and added comments

FIx spelling mistake and added comments

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