Added files via upload

Added files via upload

//#define __DEBUG__

#define threshold 500
#define baud 9600
#define short_del 500
#define long_del 2000

const unsigned int red[] = {10, 7, 2, 13}; //r1, r2, r3, r4
const unsigned int yellow[] = {9, 6, 3, 12};
const unsigned int green[] = {8, 5, 4, 11};
const unsigned int ir[] = {A2, A3, A1, A0};

bool reading[] = {false, false, false, false};

enum LIGHT {FIRST = 0, SECOND = 1, THIRD = 2, FOURTH = 3, NONE = 4};

LIGHT light;

int index = 4;

void debug(void){
  Serial.println (" == DEBUG BEGIN == ");
  for (int i = 0; i < 4; i++){
    Serial.println("IR [ " + String(i) + "] = " + String(analogRead(ir[i])));
    delay(short_del);
  }
  Serial.println (" == DEBUG END == ");
  Serial.println();
  delay(long_del);
}

void setup() {
  Serial.begin(baud);
  for (int i = 0; i < 4; i++){
    pinMode(red[i], OUTPUT);
    pinMode(yellow[i], OUTPUT);
    pinMode(green[i], OUTPUT);
    pinMode(ir[i], INPUT);
  }
}

int whichLight(void){
  if (analogRead(ir[0]) < threshold) return FIRST;
  else if (analogRead(ir[1]) < threshold) return SECOND;
  else if (analogRead(ir[2]) < threshold) return THIRD;
  else if (analogRead(ir[3]) < threshold) return FOURTH;
  else return NONE;
}

void offAll (void){
  for (int i = 0; i < 4; i++){
    digitalWrite (red[i], LOW);
    digitalWrite (yellow[i], LOW);
    digitalWrite (green[i], LOW);
  }
}

void firstLight(void){
  offAll();
  digitalWrite (green[FIRST], HIGH);
  digitalWrite(red[SECOND], HIGH);
  digitalWrite(red[THIRD], HIGH);
  digitalWrite(red[FOURTH], HIGH);
}

void secondLight(void){
  offAll();
  digitalWrite(green[SECOND], HIGH);
  digitalWrite(red[FIRST], HIGH);
  digitalWrite(red[THIRD], HIGH);
  digitalWrite(red[FOURTH], HIGH);
}

void thirdLight(void){
  offAll();
  digitalWrite(green[THIRD], HIGH);
  digitalWrite(red[FIRST], HIGH);
  digitalWrite(red[SECOND], HIGH);
  digitalWrite(red[FOURTH], HIGH);
}

void fourthLight(void){
  offAll();
  digitalWrite(green[FOURTH], HIGH);
  digitalWrite(red[FIRST], HIGH);
  digitalWrite(red[THIRD], HIGH);
  digitalWrite(red[SECOND], HIGH);
}

void onAll(void){
  for (int i = 0; i < 4; i++) {
    digitalWrite(red[i], HIGH);
    digitalWrite(yellow[i], HIGH);
    digitalWrite(green[i], HIGH);
  }
}

void onIdle(void){

  index = whichLight();

  // For first light
  digitalWrite(green[FIRST], HIGH);
  digitalWrite(red[SECOND], HIGH);
  digitalWrite(red[THIRD], HIGH);
  digitalWrite(red[FOURTH], HIGH);
  delay(long_del);
  digitalWrite(green[FIRST], LOW);
  digitalWrite(red[SECOND], LOW);
  digitalWrite(red[THIRD], LOW);
  digitalWrite(red[FOURTH], LOW);

  for (int i = 0; i < 4; i++) digitalWrite(yellow[i], HIGH);
  delay(short_del);
  for (int i = 0; i < 4; i++) digitalWrite(yellow[i], LOW);

  index = whichLight();

  //For second
  digitalWrite(green[SECOND], HIGH);
  digitalWrite(red[FIRST], HIGH);
  digitalWrite(red[THIRD], HIGH);
  digitalWrite(red[FOURTH], HIGH);
  delay(long_del);
  digitalWrite(green[SECOND], LOW);
  digitalWrite(red[FIRST], LOW);
  digitalWrite(red[THIRD], LOW);
  digitalWrite(red[FOURTH], LOW);

  for (int i = 0; i < 4; i++) digitalWrite(yellow[i], HIGH);
  delay(short_del);
  for (int i = 0; i < 4; i++) digitalWrite(yellow[i], LOW);

  index = whichLight();

  //For third
  digitalWrite(green[THIRD], HIGH);
  digitalWrite(red[FIRST], HIGH);
  digitalWrite(red[SECOND], HIGH);
  digitalWrite(red[FOURTH], HIGH);
  delay(long_del);
  digitalWrite(green[THIRD], LOW);
  digitalWrite(red[FIRST], LOW);
  digitalWrite(red[SECOND], LOW);
  digitalWrite(red[FOURTH], LOW);

  for (int i = 0; i < 4; i++) digitalWrite(yellow[i], HIGH);
  delay(short_del);
  for (int i = 0; i < 4; i++) digitalWrite(yellow[i], LOW);

  index = whichLight();

  //For fourth
  digitalWrite(green[FOURTH], HIGH);
  digitalWrite(red[FIRST], HIGH);
  digitalWrite(red[SECOND], HIGH);
  digitalWrite(red[THIRD], HIGH);
  delay(long_del);
  digitalWrite(green[FOURTH], LOW);
  digitalWrite(red[FIRST], LOW);
  digitalWrite(red[SECOND], LOW);
  digitalWrite(red[THIRD], LOW);

  index = whichLight();

  for (int i = 0; i < 4; i++) digitalWrite(yellow[i], HIGH);
  delay(short_del);
  for (int i = 0; i < 4; i++) digitalWrite(yellow[i], LOW);

}

#ifdef __DEBUG__
void loop() { onAll(); }

#else

void loop(){

  int index = 4;

  index = whichLight();

  while(index != NONE){
    index = whichLight();
    switch(index){
      case FIRST:
        firstLight();
        break;
      case SECOND:
        secondLight();
        break;

      case THIRD:
        thirdLight();
        break;

      case FOURTH:
        fourthLight();
        break;

      default:
        offAll();
        break;
    }
  }

  while(whichLight() == NONE){

  if (whichLight() != NONE){
    offAll();
    break;
  }

      // For first light
  digitalWrite(green[FIRST], HIGH);
  digitalWrite(red[SECOND], HIGH);
  digitalWrite(red[THIRD], HIGH);
  digitalWrite(red[FOURTH], HIGH);
    if (whichLight() != NONE){
    offAll();
    break;
  }
  delay(long_del);
    if (whichLight() != NONE){
    offAll();
    break;
  }
  digitalWrite(green[FIRST], LOW);
  digitalWrite(red[SECOND], LOW);
  digitalWrite(red[THIRD], LOW);
  digitalWrite(red[FOURTH], LOW);
  index = whichLight();

  for (int i = 0; i < 4; i++) digitalWrite(yellow[i], HIGH);
  index = whichLight();
  delay(short_del);
  index = whichLight();
  for (int i = 0; i < 4; i++) digitalWrite(yellow[i], LOW);

  index = whichLight();

  //For second
  digitalWrite(green[SECOND], HIGH);
  digitalWrite(red[FIRST], HIGH);
  digitalWrite(red[THIRD], HIGH);
  digitalWrite(red[FOURTH], HIGH);
    if (whichLight() != NONE){
    offAll();
    break;
  }
  delay(long_del);
    if (whichLight() != NONE){
    offAll();
    break;
  }
  digitalWrite(green[SECOND], LOW);
  digitalWrite(red[FIRST], LOW);
  digitalWrite(red[THIRD], LOW);
  digitalWrite(red[FOURTH], LOW);
    if (whichLight() != NONE){
    offAll();
    break;
  }
  for (int i = 0; i < 4; i++) digitalWrite(yellow[i], HIGH);
    if (whichLight() != NONE){
    offAll();
    break;
  }
  delay(short_del);
    if (whichLight() != NONE){
    offAll();
    break;
  }
  for (int i = 0; i < 4; i++) digitalWrite(yellow[i], LOW);

    if (whichLight() != NONE){
    offAll();
    break;
  }

  //For third
  digitalWrite(green[THIRD], HIGH);
  digitalWrite(red[FIRST], HIGH);
  digitalWrite(red[SECOND], HIGH);
  digitalWrite(red[FOURTH], HIGH);
    if (whichLight() != NONE){
    offAll();
    break;
  }
  delay(long_del);
  digitalWrite(green[THIRD], LOW);
  digitalWrite(red[FIRST], LOW);
  digitalWrite(red[SECOND], LOW);
  digitalWrite(red[FOURTH], LOW);

    if (whichLight() != NONE){
    offAll();
    break;
  }
  for (int i = 0; i < 4; i++) digitalWrite(yellow[i], HIGH);
    if (whichLight() != NONE){
    offAll();
    break;
  }
  delay(short_del);
  for (int i = 0; i < 4; i++) digitalWrite(yellow[i], LOW);
    if (whichLight() != NONE){
    offAll();
    break;
  }

  //For fourth
  digitalWrite(green[FOURTH], HIGH);
  digitalWrite(red[FIRST], HIGH);
  digitalWrite(red[SECOND], HIGH);
  digitalWrite(red[THIRD], HIGH);

    if (whichLight() != NONE){
    offAll();
    break;
  }

  delay(long_del);
  digitalWrite(green[FOURTH], LOW);
  digitalWrite(red[FIRST], LOW);
  digitalWrite(red[SECOND], LOW);
  digitalWrite(red[THIRD], LOW);

    if (whichLight() != NONE){
    offAll();
    break;
  }

  for (int i = 0; i < 4; i++) digitalWrite(yellow[i], HIGH);
    if (whichLight() != NONE){
    offAll();
    break;
  }
  delay(short_del);
  for (int i = 0; i < 4; i++) digitalWrite(yellow[i], LOW);

    if (whichLight() != NONE){
    offAll();
    break;
  }

  }
}

#endif

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


Create mirrored_Fire2012.ino

Create mirrored_Fire2012.ino

//***************************************************************
// Example of running FastLED's Fire2012 example mirrored on
// both halves of a strip.
//
// gReverseDirection sets if the fire goes from center out or
// from the ends inward.
//
// The fire is first drawn into a temporary array (leds_temp) that
// is half the length of the strip.  Then the data is copied from
// leds_temp and mirrored to leds before running FastLED.show()
//
// Marc Miller, Jan 2018
//***************************************************************

#include "FastLED.h"
#define DATA_PIN    11
#define CLK_PIN     13
#define LED_TYPE    LPD8806
#define COLOR_ORDER GRB
#define NUM_LEDS    32  // Total number of pixels in strip
#define BRIGHTNESS  128
CRGB leds[NUM_LEDS];
CRGB leds_temp[NUM_LEDS/2];  // half the total number of pixels

#define FRAMES_PER_SECOND 60

bool gReverseDirection = false;  //false = center outward, true = from ends inward

//---------------------------------------------------------------
void setup() {
  Serial.begin(115200);  // Allows serial monitor output (check baud rate)
  delay(2000); // startup delay
  //FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
  FastLED.addLeds<LED_TYPE,DATA_PIN,CLK_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
  FastLED.setBrightness(BRIGHTNESS);
  FastLED.clear();
  FastLED.show();
  Serial.println("Setup done. \n");
}

//---------------------------------------------------------------
void loop()
{
  // Add entropy to random number generator; we use a lot of it.
  // random16_add_entropy( random());

  Fire2012_halfStrip(); // draw fire data to leds_temp

  mirror2ndHalf();  // copy and mirror data from leds_temp to leds

  FastLED.show(); // display leds
  FastLED.delay(1000 / FRAMES_PER_SECOND);
}

//---------------------------------------------------------------
// Fire2012 by Mark Kriegsman, July 2012
// as part of "Five Elements" shown here: http://youtu.be/knWiGsmgycY
//
// This basic one-dimensional 'fire' simulation works roughly as follows:
// There's a underlying array of 'heat' cells, that model the temperature
// at each point along the line.  Every cycle through the simulation,
// four steps are performed:
//  1) All cells cool down a little bit, losing heat to the air
//  2) The heat from each cell drifts 'up' and diffuses a little
//  3) Sometimes randomly new 'sparks' of heat are added at the bottom
//  4) The heat from each cell is rendered as a color into the leds array
//     The heat-to-color mapping uses a black-body radiation approximation.
//
// Temperature is in arbitrary units from 0 (cold black) to 255 (white hot).
//
// This simulation scales it self a bit depending on NUM_LEDS; it should look
// "OK" on anywhere from 20 to 100 LEDs without too much tweaking.
//
// I recommend running this simulation at anywhere from 30-100 frames per second,
// meaning an interframe delay of about 10-35 milliseconds.
//
// Looks best on a high-density LED setup (60+ pixels/meter).
//
//
// There are two main parameters you can play with to control the look and
// feel of your fire: COOLING (used in step 1 above), and SPARKING (used
// in step 3 above).
//
// COOLING: How much does the air cool as it rises?
// Less cooling = taller flames.  More cooling = shorter flames.
// Default 50, suggested range 20-100
#define COOLING  90

// SPARKING: What chance (out of 255) is there that a new spark will be lit?
// Higher chance = more roaring fire.  Lower chance = more flickery fire.
// Default 120, suggested range 50-200.
#define SPARKING 50

//---------------------------------------------------------------
// **** NOTE these changes to the Fire2012 function:
// - function renamed to Fire2012_halfStrip
// - leds was replaced with leds_temp so the fire is drawn into
//     the temporary (leds_temp) array.
// - NUM_LEDS was replaced with NUM_LEDS/2 (half the strip length).
// - The gReverseDirection logic was removed from Fire2012 code
//     since the reversing happens in the mirror2ndHalf function.
//---------------------------------------------------------------
void Fire2012_halfStrip() {
  // Fuction only operates on half the number of pixels (NUM_LEDS/2)

  // Array of temperature readings at each simulation cell
  static byte heat[NUM_LEDS/2];

  // Step 1.  Cool down every cell a little
  for( int i = 0; i < NUM_LEDS/2; i++) {
    heat[i] = qsub8( heat[i],  random8(0, ((COOLING * 10) / (NUM_LEDS/2)) + 2));
  }

  // Step 2.  Heat from each cell drifts 'up' and diffuses a little
  for( int k= (NUM_LEDS/2) - 1; k >= 2; k--) {
    heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2] ) / 3;
  }

  // Step 3.  Randomly ignite new 'sparks' of heat near the bottom
  if( random8() < SPARKING ) {
    int y = random8(7);
    heat[y] = qadd8( heat[y], random8(160,255) );
  }

  // Step 4.  Map from heat cells to LED colors
  for( int j = 0; j < NUM_LEDS/2; j++) {
    CRGB color = HeatColor( heat[j]);
    leds_temp[j] = color;
  }

}//end_Fire2012_halfStrip

//---------------------------------------------------------------
void mirror2ndHalf() {
  //copy and mirror pixel data from leds_temp to leds array.

  if (gReverseDirection == false) {  //false is center outward
    for (uint8_t i=0; i<NUM_LEDS/2; i++) {
      leds[(NUM_LEDS/2)-1-i] = leds_temp[i];
      leds[(NUM_LEDS/2)+i] = leds_temp[i];
    }

  } else {  //true is from ends inward
    for (uint8_t i=0; i<NUM_LEDS/2; i++) {
      leds[i] = leds_temp[i];
      leds[(NUM_LEDS-1)-i] = leds_temp[i];
    }
  }

}//end_mirror2ndHalf

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


Added first version of msp-430 code

Added first version of msp-430 code

preliminary version of the msp-430 code used to parse the serial command
and actuate the servo accordingly

#include <Servo.h>

/*
  Servo Event :
  When new serial data arrives, the data is parsed and the servo is moved accordingly.

*/
// set pin numbers:
const int buttonPin = PUSH2;     // the number of the pushbutton pin
const int ledPin =  GREEN_LED;      // the number of the LED pin

Servo myservo;  // create servo object to control a servo
int pos = 0;    // variable to store the servo position

String inputString = ""; // a string to hold incoming data
String outputString = "";
String stringKey = "joke";
String stringKey2 = ".";
int counter = 0;
int position = 1500;
boolean l_execute = false; // whether the string is complete

void setup() {
  // initialize serial:
  Serial.begin(9600);
  inputString.reserve(200);
  // servo in pos 11 (2.3)
  myservo.attach(11);  // attaches the servo on pin 9 to the servo object
  // configure led
  pinMode(ledPin, OUTPUT);
  // Button interruption
  attachInterrupt(PUSH2, buttonPressed, RISING );
}

void loop() {
  // check if something happened
  if (l_execute) {
    //increase counter;
    counter += 1;
    moveServo();
    Serial.println(counter);
    l_execute = false;
  }
}

// Button interrupt results
void buttonPressed(){
   l_execute = true;
}
// Do something action
void moveServo() {
  noInterrupts();
  myservo.write(position);
  digitalWrite(ledPin, HIGH);
  delay(500);
  digitalWrite(ledPin, LOW);
  myservo.write(1000);
  interrupts();
}

/*
  SerialEvent occurs whenever a new data comes in the
  hardware serial RX. This routine is run between each
  time loop() runs, so using delay inside loop can delay
  response. Multiple bytes of data may be available.
*/
void serialEvent() {
  while (Serial.available()) {
    // get the new byte:
    char inChar = (char)Serial.read();
    // add it to the inputString:
    // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    if (inChar == '\n') {
      if ((inputString.substring(0,4).equals(stringKey)&&(inputString.substring(8).equals(stringKey2)))){
        l_execute = true;

        position = StringtoInt(inputString.substring(4,8));
      }
     inputString = "";
    } else {
    inputString += inChar;
    }
  }
}

// translates the string into an integer
int StringtoInt (String inputString) {
  int pos = SingleStringtoInt(inputString.substring(0,1));
  pos = pos*10 + SingleStringtoInt(inputString.substring(1,2));
  pos = pos*10 + SingleStringtoInt(inputString.substring(2,3));
  pos = pos*10 + SingleStringtoInt(inputString.substring(3));
  return pos;
}

// parses each character
int SingleStringtoInt (String input) {

   if ( input.equals( "1") ) {
   return 1;
   }else if ( input.equals( "2") ) {
   return 2;
   }else if ( input.equals( "3") ) {
   return 3;
   } else if ( input.equals( "4") ) {
   return 4;
   } else if ( input.equals( "5") ) {
   return 5;
   } else if ( input.equals( "6") ) {
   return 6;
   } else if ( input.equals( "7") ) {
   return 7;
   } else if ( input.equals( "8") ) {
   return 8;
   }  else if ( input.equals( "9") ) {
   return 9;
   } else {
   return 0;
   };

  }

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


Working for ESP-01

Working for ESP-01

esp8266/projects/Blynk Light Switch v1/blynk_light_switch_01/blynk_light_switch_01.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/csgregg/maker.git/'


Added spark core code for temp monitor

Added spark core code for temp monitor

/*
This is the C code running on the Spark Core
reading temperature data from a TMP36 and
humidity from a DHT11

Needs Adafruit_DHT library
 */

// This #include statement was automatically added by the Spark IDE.
#include "Adafruit_DHT/Adafruit_DHT.h"

#define DHTPIN 2     // what pin we're connected to
#define DHTTYPE DHT11		// DHT 11

DHT dht(DHTPIN, DHTTYPE);

double tempC = 0;
int reading = 0;
double voltage = 0.0;

void setup() {
    pinMode(A0, INPUT);
    Serial.begin(9600);
    dht.begin();
}

void loop() {

    float h = dht.getHumidity();
   	float t = dht.getTempCelcius();

    reading = analogRead(A0);
    voltage = (reading * 3.3) / 4095;
    tempC = -(voltage - 0.5) * 100;

   	String publishString = "{ \"humidity\":"+String(h)+", \"temperature\":"+String(tempC)+" }";
   	Spark.publish("Temp",publishString);

   	delay(1000);
}

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


Spiral progress

Spiral progress

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/c-dante/glowbrella.git/'


Added an include for EEPROMWriter and remove useless comment.

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/RichoM/Uzi.git/'


Add RGBCalibrate sketch

Add RGBCalibrate sketch

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/JulianNicholls/Arduino.git/'


Add:IEEE754Converter

float float_value = 13;

void float2Bytes(byte* bytes_temp, float float_variable) {
  memcpy(bytes_temp, (unsigned char*) (&float_variable), 4);
}

byte result_lsb_value[4] = {0x00, 0x00, 0x00, 0x00};
unsigned char result_msb_value[4] = {0x00, 0x00, 0x00, 0x00};

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

void loop() {
  if (  Serial.available() > 0) {
    float_value = Serial.parseFloat();
  }
  float2Bytes(result_lsb_value, float_value);
  // put your main code here, to run repeatedly:
  Serial.println(float_value);
  Serial.println("Little Endian");
  for (int i = 0; i < 4; i++) {
    Serial.print(result_lsb_value[i], HEX);
    Serial.print('\t');
  }
  Serial.println('\n');
}

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


Minimal RGB Strip test

Minimal RGB Strip test

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


Fixed some code

Fixed some code

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


Create Receive_test.ino

Create Receive_test.ino

// This #include statement was automatically added by the Particle IDE.
#include <FastLED.h>
FASTLED_USING_NAMESPACE;

int receivedHue = 0;
int receivedSaturation = 0;
int receivedValue = 0;

CHSV baseColor;

void setup() {
    Particle.subscribe("Beacon Update", ColorUpdate, MY_DEVICES);
}

void loop() {

}

void ColorUpdate(const char *name, const char *data) {
    if (data) {
        char input[64];
        strcpy(input,data);
        char *p;
        receivedID = strtok(input,"~");
        p = strtok(NULL,"~");
        receivedHue = atoi(p);
        p = strtok(NULL,"~");
        receivedSaturation = atoi(p);
        p = strtok(NULL,"~");
        receivedValue = atoi(p);

    }
    // DEBUG
    String sColorRecieved = String(colorRecieved);
    Particle.publish("Color_Recieved", System.deviceID() + "~" + receivedHue + "~" + receivedSaturation + "~" receivedValue);
    // END DEBUG
    baseColor = CHSV(receivedHue, receivedSaturation, receivedValue)
}

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


Update: Add quickstart demo code

Update: Add quickstart demo code

#include <CustomSoftwareSerial.h>

CustomSoftwareSerial* customSerial;               // Declare serial

// Init value
void setup() {
  Serial.begin(57600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  Serial.write("Hello World");

  customSerial = new CustomSoftwareSerial(9, 10); // rx, tx
  customSerial->begin(9600, CSERIAL_8N1);         // Baud rate: 9600, configuration: CSERIAL_8N1
  customSerial->write("Test message");            // Write testing data
}

void loop() {
  if (customSerial->available())
    Serial.write(customSerial->read());
  if (Serial.available())
    customSerial->write(Serial.read());

  delay(1000);
}

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


[lmr] Fix rollover during wait for receive and switch to 5 second interval

#include <avr/wdt.h>
#include <avr/sleep.h>
#include <rf12_itplus.h>

// Enabling LMREMOTE_SERIAL also disables several power saving features
#define LMREMOTE_SERIAL 38400

// Base Idenfier for the RFM12B (0-63)
// The transmitted ID is this ID plus the pin number
const char _rfNodeBaseId = 0;
// RFM12B band RF12_433MHZ, RF12_868MHZ, RF12_915MHZ
const unsigned char _rfBand = RF12_915MHZ;
// How many seconds to delay between measurements
const unsigned char _sleepInterval = 2;
// Analog pins to read. This is a bitfield, LSB is analog 0
const unsigned char _enabledProbePins = 0x01;
// Analog pin connected to source power.  Set to 0xff to disable sampling
const unsigned char _pinBattery = 1;
// Digital pins for LEDs, 0xff to disable
const unsigned char _pinLedRx = 0xff;
const unsigned char _pinLedTx = 0xff; //9
// Digital pins used for sourcing power to the probe dividers
const unsigned char _pinProbeSupplyBase = 4;
// Percentage (integer) of VCC where the battery is considered low (33% = 1.1V)
#define BATTERY_LOW_PCT 33
// Number of seconds to keep the "recent/new" bit set
#define RECENT_EXPIRE_SECS 1800
// Number of oversampling bits when measuring temperature [0-2]
#define TEMP_OVERSAMPLE_BITS 1

#define RF_PINS_PER_SOURCE 6
#define PIN_DISABLED(pin) ((_enabledProbePins & (1 << pin)) == 0)

// Bits used in output packet
// byte0/1 reserved Node IDs
#define NODEID_MASTER      0x3F
// byte1
#define BYTE1_DUAL_PROBE   0x10
#define BYTE1_RECENT_BOOT  0x20
// hygro byte
#define HYGRO_BATTERY_OK   0x00
#define HYGRO_BATTERY_LOW  0x80
#define HYGRO_NO_HYGRO     0x6A
#define HYGRO_SECOND_PROBE 0x7D
#define HYGRO_LMREMOTE_KEY 0x7F

#ifdef LMREMOTE_SERIAL
  #define SLEEPMODE_TX    1
  #define SLEEPMODE_ADC   SLEEP_MODE_IDLE
#else
  #define SLEEPMODE_TX    2
  #define SLEEPMODE_ADC   SLEEP_MODE_ADC
#endif

#define RECV_CYCLE_TIME  5000    // expected receive cycle, millisecond
#define MIN_RECV_WIN     8       // minimum window size, power of 2
#define MAX_RECV_WIN     512     // maximum window size, power of 2

static unsigned int _previousReads[RF_PINS_PER_SOURCE];
static unsigned long _tempReadLast;
static unsigned int _loopCnt;
static unsigned char _sameCount;
static unsigned char _isRecent = BYTE1_RECENT_BOOT;
static unsigned char _isBattLow;

static unsigned int _recvCycleAct;
static unsigned int _recvWindow;
static unsigned long _recvLast;
static bool _recvSynced;

static volatile bool _adcBusy;
static volatile bool _watchdogWaiting;

// The WDT is used solely to wake us from sleep
ISR(WDT_vect) { _watchdogWaiting = false; }
ISR(ADC_vect) { _adcBusy = false; }

static bool packetReceived(unsigned char nodeId, unsigned int val)
{
#if LMREMOTE_SERIAL
  Serial.print(F("IN("));
  Serial.print(nodeId);
  Serial.print(',');
  Serial.print(rf12_rssi(), DEC);
  Serial.print(F(")="));
  Serial.print(val);
  Serial.print('\n');
#endif

  if (nodeId != NODEID_MASTER)
    return false;
  // val contains requested fan speed percent
  return true;
}

static bool rf12_doWork(void)
{
  if (rf12_recvDone() && rf12_crc == 0)
  {
    if (_pinLedRx != 0xff) digitalWrite(_pinLedRx, HIGH);

    unsigned char nodeId = ((rf12_buf[0] & 0x0f) << 2) | (rf12_buf[1] >> 6);
    unsigned int val = (rf12_buf[1] & 0x0f) << 8 | rf12_buf[2];
    return packetReceived(nodeId, val);
  }
  if (_pinLedRx != 0xff) digitalWrite(_pinLedRx, LOW);
  return false;
}

static unsigned int analogReadSleep(unsigned char pin)
{
  _adcBusy = true;
  ADMUX = (DEFAULT << 6) | pin;
  bitSet(ADCSRA, ADIE);
  set_sleep_mode(SLEEPMODE_ADC);
  while (_adcBusy)
    sleep_mode();
  return ADC;
}

static void sleepPeriod(uint8_t wdt_period)
{
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);

  // Set the watchdog to wake us up and turn on its interrupt
  wdt_enable(wdt_period);
  WDTCSR |= bit(WDIE);

  // Turn off Brown Out Detector
  // sleep must be entered within 3 cycles of BODS being set
  sleep_enable();
  MCUCR = MCUCR | bit(BODSE) | bit(BODS);
  MCUCR = (MCUCR & ~bit(BODSE)) | bit(BODS);

  // Sleep
  sleep_cpu();

  // Back from sleep
  wdt_disable();
  sleep_disable();
}

static void sleep(unsigned int msec)
// Code copied from Sleepy::loseSomeSleep(), jeelib
{
  unsigned int msleft = msec;
  while (msleft >= 16)
  {
    char wdp = 0; // wdp 0..9 corresponds to roughly 16..8192 ms
    // calc wdp as log2(msleft/16), i.e. loop & inc while next value is ok
    for (unsigned int m = msleft; m >= 32; m >>= 1)
      if (++wdp >= 9)
        break;
    _watchdogWaiting = true;
    sleepPeriod(wdp);
    unsigned int halfms = 8 << wdp;
    msleft -= halfms;
    if (_watchdogWaiting)
      continue;
    msleft -= halfms;
  }

  // adjust the milli ticks, since we will have missed several
#if defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny85__) || defined (__AVR_ATtiny44__)
    extern volatile unsigned long millis_timer_millis;
    millis_timer_millis += msecs - msleft;
#else
    extern volatile unsigned long timer0_millis;
    timer0_millis += msec - msleft;
#endif
}

static void resetEstimate(void)
{
#if _DEBUG
  Serial.print(F("Resetting Estimate\n"));
#endif
  _recvCycleAct = RECV_CYCLE_TIME;
  _recvWindow = MAX_RECV_WIN;
  _recvSynced = false;

  unsigned long start = millis();
  while (!rf12_doWork())
    if (millis() - start > RECV_CYCLE_TIME)
      return;
  _recvLast = millis();
}

static bool optimalSleep(void)
// Code adapted from jeelib/examples/syncRecv optimalSleep()
{
  unsigned char lost = (millis() - _recvLast + _recvCycleAct / 2) / _recvCycleAct;
  if (lost > 10)
  {
    resetEstimate();
    return false;
  }

  // double the window every N packets lost
  if (lost > 0 && lost % 2 == 0 && _recvWindow < MAX_RECV_WIN)
    _recvWindow *= 2;

  unsigned long predict = _recvLast + (lost + 1) * _recvCycleAct;
  unsigned int sleepDur =  predict - _recvWindow - millis();
  sleep(sleepDur);
  rf12_sleep(RF12_WAKEUP);

  unsigned long recvTime;
  unsigned long timeout = predict + _recvWindow;
  do {
    recvTime = millis();
    if ((long)(recvTime - timeout) >= 0)
    {
#if _DEBUG
      Serial.print(" f "); Serial.print(lost);
      Serial.print(" s "); Serial.print(sleepDur);
      Serial.print(" e "); Serial.print(_recvCycleAct);
      Serial.print(" w "); Serial.print(_recvWindow);
      Serial.print(" p "); Serial.print(predict);
      Serial.print(" r "); Serial.println(recvTime);
      Serial.flush();
#endif
      return false;
    }
  } while (!rf12_doWork());

  unsigned int newEst = (recvTime - _recvLast) / (lost + 1);
  if (_recvSynced)
    _recvCycleAct = (4 * _recvCycleAct + newEst + 3) / 5; // 5-fold smoothing
  else
    _recvCycleAct = newEst;
  _recvLast = recvTime;

#if _DEBUG
  Serial.print(" n "); Serial.print(lost);
  Serial.print(" e "); Serial.print(_recvCycleAct);
  Serial.print(" E "); Serial.print(newEst);
  Serial.print(" w "); Serial.print(_recvWindow);
  Serial.print(" p "); Serial.print(predict);
  Serial.print(" r "); Serial.println(recvTime);
#endif

  if (_recvWindow > MIN_RECV_WIN)
    _recvWindow /= 2;
  else
    _recvSynced = true;

  return true;
}

static void updateBatteryLow(void)
{
  const unsigned char BATREAD_COUNT = 4;

  _isBattLow = HYGRO_BATTERY_OK;
  if (_pinBattery != 0xff)
  {
    unsigned int adcSum = 0;
    unsigned char battPct;
    for (unsigned char i=0; i<BATREAD_COUNT; ++i)
      adcSum += analogReadSleep(_pinBattery);
    // Percent of VCC
    battPct = (adcSum * 100UL) / (1024 * BATREAD_COUNT);

#ifdef LMREMOTE_SERIAL
    Serial.print("Battery %: "); Serial.print(battPct, DEC); Serial.print('\n');
#endif

    if (battPct < BATTERY_LOW_PCT)
      _isBattLow = HYGRO_BATTERY_LOW;
  }
}

static void transmitTemp(unsigned char pin)
{
  unsigned char outbuf[4];
  unsigned char nodeId = _rfNodeBaseId + pin;
  unsigned int val = _previousReads[pin];
  val <<= (12 - (10 + TEMP_OVERSAMPLE_BITS));
  outbuf[0] = 0x90 | ((nodeId & 0x3f) >> 2);
  outbuf[1] = ((nodeId & 0x3f) << 6) | _isRecent | (val >> 8);
  outbuf[2] = (val & 0xff);
  outbuf[3] = HYGRO_LMREMOTE_KEY | _isBattLow;
  //Serial.println(outbuf[3], HEX);

  // Don't check for air to be clear, we just woke from sleep and it will be milliseconds before
  // the RFM chip is actually up and running
  rf12_sendStart(outbuf, sizeof(outbuf));
  rf12_sendWait(SLEEPMODE_TX);
}

static void newTempsAvailable(void)
{
  // Enable the transmitter because it takes 1-5ms to turn on (3ms in my testing)
  rf12_sleep(RF12_WAKEUP);

  updateBatteryLow();
  // We're done with the ADC shut it down until the next wake cycle
  ADCSRA &= ~bit(ADEN);
  if (_isRecent && (millis() > RECENT_EXPIRE_SECS))
  {
    //Serial.print("No longer recent\n");
    _isRecent = 0;
  }

  boolean hasTransmitted = false;
  for (unsigned char pin=0; pin < RF_PINS_PER_SOURCE; ++pin)
  {
    if (PIN_DISABLED(pin))
      continue;
    if (hasTransmitted) sleep(16);
    transmitTemp(pin);
    hasTransmitted = true;
  }

  rf12_sleep(RF12_SLEEP);
  if (_pinLedTx != 0xff)
  {
    digitalWrite(_pinLedTx, HIGH);
    sleep(16);
    digitalWrite(_pinLedTx, LOW);
  }
}

static void enableAdcPullups(void)
{
  for (unsigned char pin=0; pin < RF_PINS_PER_SOURCE; ++pin)
  {
    if (PIN_DISABLED(pin))
      continue;

    // The probe themistor voltage dividers are normally powered down
    // to save power, using digital lines to supply Vcc to them.
    // Lines are used sequentially starting from _pinProbeSupplyBase
    // Note you can use the analog internal pullups as the fixed half of
    // the divider by setting this value to A0 (or higher).
    // The analog pullups are 20k-40kOhms, about 36k on my handful of chips.
    // If using digital lines you will supply your own resistor for the fixed half.
    digitalWrite(_pinProbeSupplyBase + pin, HIGH);
  }
}

static void stabilizeAdc(void)
{
  const unsigned char INTERNAL_REF = 0b1110;
  unsigned int last;
  unsigned int totalCnt = 0;
  unsigned int sameCnt = 0;
  unsigned int curr = analogReadSleep(INTERNAL_REF);
  // Reads the adc a bunch of times until the value settles
  // Usually you hear "discard the first few ADC readings after sleep"
  // but this seems a bit more scientific as we wait for the AREF cap to charge
  do {
    ++totalCnt;
#ifdef LMREMOTE_SERIAL
    Serial.print(curr, DEC);
    Serial.print(' ');
#endif
    last = curr;
    curr = analogReadSleep(INTERNAL_REF);
    if (last == curr)
      ++sameCnt;
    else
      sameCnt = 0;
  } while ((totalCnt < 64) && (sameCnt < 4));
}

static void checkTemps(void)
{
  const unsigned char OVERSAMPLE_COUNT[] = {1, 4, 16, 64};  // 4^n
  boolean modified = false;
  unsigned int oversampled_adc = 0;

#ifdef LMREMOTE_SERIAL
  Serial.print(millis(), DEC);
  Serial.print(" Checking temps: ");
#endif

  // Enable the ADC
  ADCSRA |= bit(ADEN);
  enableAdcPullups();
  stabilizeAdc();
  for (unsigned char pin=0; pin < RF_PINS_PER_SOURCE; ++pin)
  {
    if (PIN_DISABLED(pin))
      continue;

    for (unsigned char o=0; o<OVERSAMPLE_COUNT[TEMP_OVERSAMPLE_BITS]; ++o)
    {
      unsigned int adc = analogReadSleep(pin);
      if (adc == 0 || adc >= 1023)
      {
        oversampled_adc = 0;
        break;
      }
      oversampled_adc += adc;
    }
    oversampled_adc = oversampled_adc >> TEMP_OVERSAMPLE_BITS;

#ifdef LMREMOTE_SERIAL
    Serial.print(oversampled_adc, DEC); Serial.print(' ');
#endif
    if (oversampled_adc != _previousReads[pin])
      modified = true;
    _previousReads[pin] = oversampled_adc;

    digitalWrite(_pinProbeSupplyBase + pin, LOW);
  }

#ifdef LMREMOTE_SERIAL
  Serial.print('\n');
#endif

  if (modified || (_sameCount > (30 / _sleepInterval)))
  {
    _sameCount = 0;
    newTempsAvailable();
  }
  else
    ++_sameCount;
  // Disable the ADC
  ADCSRA &= ~bit(ADEN);

  _tempReadLast = millis();
}

static void setupSupplyPins(void)
{
  // Analog pullup supply pins don't need DIR set
  if (_pinProbeSupplyBase >= A0)
    return;
  for (unsigned char pin=0; pin < RF_PINS_PER_SOURCE; ++pin)
  {
    if (PIN_DISABLED(pin))
      continue;
    pinMode(_pinProbeSupplyBase + pin, OUTPUT);
  }
}

void setup(void)
{
  // Turn off the units we never use (this only affects non-sleep power)
  PRR = bit(PRUSART0) | bit(PRTWI) | bit(PRTIM1) | bit(PRTIM2);
  // Disable digital input buffers on the analog in ports
  DIDR0 = bit(ADC5D) | bit(ADC4D) | bit(ADC3D) | bit(ADC2D) | bit(ADC1D) | bit(ADC0D);
  DIDR1 = bit(AIN1D) | bit(AIN0D);

#ifdef LMREMOTE_SERIAL
  PRR &= ~bit(PRUSART0);
  Serial.begin(LMREMOTE_SERIAL); Serial.println("$UCID,lmremote"); delay(10);
#endif

  rf12_initialize(1, _rfBand);
  // Crystal 1.66MHz Low Battery Detect 2.2V
  rf12_control(0xC040);

  if (_pinLedRx != 0xff) pinMode(_pinLedRx, OUTPUT);
  if (_pinLedTx != 0xff) pinMode(_pinLedTx, OUTPUT);

  setupSupplyPins();

  // Force a transmit on next read
  memset(_previousReads, 0xff, sizeof(_previousReads));
}

void loop(void)
{
  if (_loopCnt % 2 == 0)
    checkTemps();

#ifdef LMREMOTE_SERIAL
  Serial.flush(); delay(2);
#endif

  if (_recvLast == 0)
    resetEstimate();
  else
    optimalSleep();
  rf12_sleep(RF12_SLEEP);

  ++_loopCnt;
}

#include <avr/wdt.h>
#include <avr/sleep.h>
#include <rf12_itplus.h>

// Enabling LMREMOTE_SERIAL also disables several power saving features
#define LMREMOTE_SERIAL 38400

// Base Idenfier for the RFM12B (0-63)
// The transmitted ID is this ID plus the pin number
const char _rfNodeBaseId = 0;
// RFM12B band RF12_433MHZ, RF12_868MHZ, RF12_915MHZ
const unsigned char _rfBand = RF12_915MHZ;
// How many seconds to delay between measurements
const unsigned char _sleepInterval = 2;
// Analog pins to read. This is a bitfield, LSB is analog 0
const unsigned char _enabledProbePins = 0x01;
// Analog pin connected to source power.  Set to 0xff to disable sampling
const unsigned char _pinBattery = 1;
// Digital pins for LEDs, 0xff to disable
const unsigned char _pinLedRx = 0xff;
const unsigned char _pinLedTx = 0xff; //9
// Digital pins used for sourcing power to the probe dividers
const unsigned char _pinProbeSupplyBase = 4;
// Percentage (integer) of VCC where the battery is considered low (33% = 1.1V)
#define BATTERY_LOW_PCT 33
// Number of seconds to keep the "recent/new" bit set
#define RECENT_EXPIRE_SECS 1800
// Number of oversampling bits when measuring temperature [0-2]
#define TEMP_OVERSAMPLE_BITS 1

#define RF_PINS_PER_SOURCE 6
#define PIN_DISABLED(pin) ((_enabledProbePins & (1 << pin)) == 0)

// Bits used in output packet
// byte0/1 reserved Node IDs
#define NODEID_MASTER      0x3F
// byte1
#define BYTE1_DUAL_PROBE   0x10
#define BYTE1_RECENT_BOOT  0x20
// hygro byte
#define HYGRO_BATTERY_OK   0x00
#define HYGRO_BATTERY_LOW  0x80
#define HYGRO_NO_HYGRO     0x6A
#define HYGRO_SECOND_PROBE 0x7D
#define HYGRO_LMREMOTE_KEY 0x7F

#ifdef LMREMOTE_SERIAL
  #define SLEEPMODE_TX    1
  #define SLEEPMODE_ADC   SLEEP_MODE_IDLE
#else
  #define SLEEPMODE_TX    2
  #define SLEEPMODE_ADC   SLEEP_MODE_ADC
#endif

#define RECV_CYCLE_TIME  1000    // expected receive cycle, millisecond
#define MIN_RECV_WIN     8       // minimum window size, power of 2
#define MAX_RECV_WIN     512     // maximum window size, power of 2

static unsigned int _previousReads[RF_PINS_PER_SOURCE];
static unsigned long _tempReadLast;
static unsigned int _loopCnt;
static unsigned char _sameCount;
static unsigned char _isRecent = BYTE1_RECENT_BOOT;
static unsigned char _isBattLow;

static unsigned int _recvCycleAct;
static unsigned int _recvWindow;
static unsigned long _recvLast;
static bool _recvSynced;

static volatile bool _adcBusy;
static volatile bool _watchdogWaiting;

// The WDT is used solely to wake us from sleep
ISR(WDT_vect) { _watchdogWaiting = false; }
ISR(ADC_vect) { _adcBusy = false; }

static bool packetReceived(unsigned char nodeId, unsigned int val)
{
#if LMREMOTE_SERIAL
  Serial.print(F("IN("));
  Serial.print(nodeId);
  Serial.print(F(")="));
  Serial.print(val);
  Serial.print('\n');
#endif

  if (nodeId != NODEID_MASTER)
    return false;
  // val contains requested fan speed percent
  return true;
}

static bool rf12_doWork(void)
{
  if (rf12_recvDone() && rf12_crc == 0)
  {
    if (_pinLedRx != 0xff) digitalWrite(_pinLedRx, HIGH);

    unsigned char nodeId = ((rf12_buf[0] & 0x0f) << 2) | (rf12_buf[1] >> 6);
    unsigned int val = (rf12_buf[1] & 0x0f) << 8 | rf12_buf[2];
    return packetReceived(nodeId, val);
  }
  if (_pinLedRx != 0xff) digitalWrite(_pinLedRx, LOW);
  return false;
}

static unsigned int analogReadSleep(unsigned char pin)
{
  _adcBusy = true;
  ADMUX = (DEFAULT << 6) | pin;
  bitSet(ADCSRA, ADIE);
  set_sleep_mode(SLEEPMODE_ADC);
  while (_adcBusy)
    sleep_mode();
  return ADC;
}

static void sleepPeriod(uint8_t wdt_period)
{
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);

  // Set the watchdog to wake us up and turn on its interrupt
  wdt_enable(wdt_period);
  WDTCSR |= bit(WDIE);

  // Turn off Brown Out Detector
  // sleep must be entered within 3 cycles of BODS being set
  sleep_enable();
  MCUCR = MCUCR | bit(BODSE) | bit(BODS);
  MCUCR = (MCUCR & ~bit(BODSE)) | bit(BODS);

  // Sleep
  sleep_cpu();

  // Back from sleep
  wdt_disable();
  sleep_disable();
}

static void sleep(unsigned int msec)
// Code copied from Sleepy::loseSomeSleep(), jeelib
{
  unsigned int msleft = msec;
  while (msleft >= 16)
  {
    char wdp = 0; // wdp 0..9 corresponds to roughly 16..8192 ms
    // calc wdp as log2(msleft/16), i.e. loop & inc while next value is ok
    for (unsigned int m = msleft; m >= 32; m >>= 1)
      if (++wdp >= 9)
        break;
    _watchdogWaiting = true;
    sleepPeriod(wdp);
    unsigned int halfms = 8 << wdp;
    msleft -= halfms;
    if (_watchdogWaiting)
      continue;
    msleft -= halfms;
  }

  // adjust the milli ticks, since we will have missed several
#if defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny85__) || defined (__AVR_ATtiny44__)
    extern volatile unsigned long millis_timer_millis;
    millis_timer_millis += msecs - msleft;
#else
    extern volatile unsigned long timer0_millis;
    timer0_millis += msec - msleft;
#endif
}

static void radioSleep(unsigned int ms)
{
  rf12_sleep(RF12_SLEEP);
  sleep(ms);
  rf12_sleep(RF12_WAKEUP);
}

static void resetEstimate(void)
{
#if _DEBUG
  Serial.print(F("Resetting Estimate\n"));
#endif
  _recvCycleAct = RECV_CYCLE_TIME;
  _recvWindow = MAX_RECV_WIN;
  _recvSynced = false;

  unsigned long start = millis();
  while (!rf12_doWork())
    if (millis() - start > RECV_CYCLE_TIME)
      return;
  _recvLast = millis();
}

static bool optimalSleep(void)
// Code adapted from jeelib/examples/syncRecv optimalSleep()
{
  unsigned char lost = (millis() - _recvLast + _recvCycleAct / 2) / _recvCycleAct;
  if (lost > 10)
  {
    resetEstimate();
    return false;
  }

  // double the window every N packets lost
  if (lost > 0 && lost % 2 == 0 && _recvWindow < MAX_RECV_WIN)
    _recvWindow *= 2;

  unsigned long predict = _recvLast + (lost + 1) * _recvCycleAct;
  unsigned int sleep =  predict - millis() - _recvWindow;
  radioSleep(sleep);

  unsigned long recvTime;
  unsigned long startTime = millis();
  do {
    recvTime = millis();
    if (recvTime > predict + _recvWindow)
    {
#if _DEBUG
      Serial.print(" f "); Serial.print(lost);
      Serial.print(" s "); Serial.print(sleep);
      Serial.print(" e "); Serial.print(_recvCycleAct);
      Serial.print(" w "); Serial.print(_recvWindow);
      Serial.print(" s "); Serial.print(startTime);
      Serial.print(" p "); Serial.print(predict);
      Serial.print(" r "); Serial.println(recvTime);
      Serial.flush();
#endif
      return false;
    }
  } while (!rf12_doWork());

  unsigned int newEst = (recvTime - _recvLast) / (lost + 1);
  if (_recvSynced)
    _recvCycleAct = (4 * _recvCycleAct + newEst + 3) / 5; // 5-fold smoothing
  else
    _recvCycleAct = newEst;
  _recvLast = recvTime;

#if _DEBUG
  Serial.print(" n "); Serial.print(lost);
  Serial.print(" e "); Serial.print(_recvCycleAct);
  Serial.print(" E "); Serial.print(newEst);
  Serial.print(" w "); Serial.print(_recvWindow);
  Serial.print(" s "); Serial.print(startTime);
  Serial.print(" p "); Serial.print(predict);
  Serial.print(" r "); Serial.println(recvTime);
#endif

  if (_recvWindow > MIN_RECV_WIN)
    _recvWindow /= 2;
  else
    _recvSynced = true;

  return true;
}

static void updateBatteryLow(void)
{
  const unsigned char BATREAD_COUNT = 4;

  _isBattLow = HYGRO_BATTERY_OK;
  if (_pinBattery != 0xff)
  {
    unsigned int adcSum = 0;
    unsigned char battPct;
    for (unsigned char i=0; i<BATREAD_COUNT; ++i)
      adcSum += analogReadSleep(_pinBattery);
    // Percent of VCC
    battPct = (adcSum * 100UL) / (1024 * BATREAD_COUNT);

#ifdef LMREMOTE_SERIAL
    Serial.print("Battery %: "); Serial.print(battPct, DEC); Serial.print('\n');
#endif

    if (battPct < BATTERY_LOW_PCT)
      _isBattLow = HYGRO_BATTERY_LOW;
  }
}

static void transmitTemp(unsigned char pin)
{
  unsigned char outbuf[4];
  unsigned char nodeId = _rfNodeBaseId + pin;
  unsigned int val = _previousReads[pin];
  val <<= (12 - (10 + TEMP_OVERSAMPLE_BITS));
  outbuf[0] = 0x90 | ((nodeId & 0x3f) >> 2);
  outbuf[1] = ((nodeId & 0x3f) << 6) | _isRecent | (val >> 8);
  outbuf[2] = (val & 0xff);
  outbuf[3] = HYGRO_LMREMOTE_KEY | _isBattLow;
  //Serial.println(outbuf[3], HEX);

  // Don't check for air to be clear, we just woke from sleep and it will be milliseconds before
  // the RFM chip is actually up and running
  rf12_sendStart(outbuf, sizeof(outbuf));
  rf12_sendWait(SLEEPMODE_TX);
}

static void newTempsAvailable(void)
{
  // Enable the transmitter because it takes 1-5ms to turn on (3ms in my testing)
  rf12_sleep(RF12_WAKEUP);

  updateBatteryLow();
  // We're done with the ADC shut it down until the next wake cycle
  ADCSRA &= ~bit(ADEN);
  if (_isRecent && (millis() > RECENT_EXPIRE_SECS))
  {
    //Serial.print("No longer recent\n");
    _isRecent = 0;
  }

  boolean hasTransmitted = false;
  for (unsigned char pin=0; pin < RF_PINS_PER_SOURCE; ++pin)
  {
    if (PIN_DISABLED(pin))
      continue;
    if (hasTransmitted) sleep(16);
    transmitTemp(pin);
    hasTransmitted = true;
  }

  rf12_sleep(RF12_SLEEP);
  if (_pinLedTx != 0xff)
  {
    digitalWrite(_pinLedTx, HIGH);
    sleep(16);
    digitalWrite(_pinLedTx, LOW);
  }
}

static void enableAdcPullups(void)
{
  for (unsigned char pin=0; pin < RF_PINS_PER_SOURCE; ++pin)
  {
    if (PIN_DISABLED(pin))
      continue;

    // The probe themistor voltage dividers are normally powered down
    // to save power, using digital lines to supply Vcc to them.
    // Lines are used sequentially starting from _pinProbeSupplyBase
    // Note you can use the analog internal pullups as the fixed half of
    // the divider by setting this value to A0 (or higher).
    // The analog pullups are 20k-40kOhms, about 36k on my handful of chips.
    // If using digital lines you will supply your own resistor for the fixed half.
    digitalWrite(_pinProbeSupplyBase + pin, HIGH);
  }
}

static void stabilizeAdc(void)
{
  const unsigned char INTERNAL_REF = 0b1110;
  unsigned int last;
  unsigned int totalCnt = 0;
  unsigned int sameCnt = 0;
  unsigned int curr = analogReadSleep(INTERNAL_REF);
  // Reads the adc a bunch of times until the value settles
  // Usually you hear "discard the first few ADC readings after sleep"
  // but this seems a bit more scientific as we wait for the AREF cap to charge
  do {
    ++totalCnt;
#ifdef LMREMOTE_SERIAL
    Serial.print(curr, DEC);
    Serial.print(' ');
#endif
    last = curr;
    curr = analogReadSleep(INTERNAL_REF);
    if (last == curr)
      ++sameCnt;
    else
      sameCnt = 0;
  } while ((totalCnt < 64) && (sameCnt < 4));
}

static void checkTemps(void)
{
  const unsigned char OVERSAMPLE_COUNT[] = {1, 4, 16, 64};  // 4^n
  boolean modified = false;
  unsigned int oversampled_adc = 0;

#ifdef LMREMOTE_SERIAL
  Serial.print(millis(), DEC);
  Serial.print(" Checking temps: ");
#endif

  // Enable the ADC
  ADCSRA |= bit(ADEN);
  enableAdcPullups();
  stabilizeAdc();
  for (unsigned char pin=0; pin < RF_PINS_PER_SOURCE; ++pin)
  {
    if (PIN_DISABLED(pin))
      continue;

    for (unsigned char o=0; o<OVERSAMPLE_COUNT[TEMP_OVERSAMPLE_BITS]; ++o)
    {
      unsigned int adc = analogReadSleep(pin);
      if (adc == 0 || adc >= 1023)
      {
        oversampled_adc = 0;
        break;
      }
      oversampled_adc += adc;
    }
    oversampled_adc = oversampled_adc >> TEMP_OVERSAMPLE_BITS;

#ifdef LMREMOTE_SERIAL
    Serial.print(oversampled_adc, DEC); Serial.print(' ');
#endif
    if (oversampled_adc != _previousReads[pin])
      modified = true;
    _previousReads[pin] = oversampled_adc;

    digitalWrite(_pinProbeSupplyBase + pin, LOW);
  }

#ifdef LMREMOTE_SERIAL
  Serial.print('\n');
#endif

  if (modified || (_sameCount > (30 / _sleepInterval)))
  {
    _sameCount = 0;
    newTempsAvailable();
  }
  else
    ++_sameCount;
  // Disable the ADC
  ADCSRA &= ~bit(ADEN);

  _tempReadLast = millis();
}

static void setupSupplyPins(void)
{
  // Analog pullup supply pins don't need DIR set
  if (_pinProbeSupplyBase >= A0)
    return;
  for (unsigned char pin=0; pin < RF_PINS_PER_SOURCE; ++pin)
  {
    if (PIN_DISABLED(pin))
      continue;
    pinMode(_pinProbeSupplyBase + pin, OUTPUT);
  }
}

void setup(void)
{
  // Turn off the units we never use (this only affects non-sleep power)
  PRR = bit(PRUSART0) | bit(PRTWI) | bit(PRTIM1) | bit(PRTIM2);
  // Disable digital input buffers on the analog in ports
  DIDR0 = bit(ADC5D) | bit(ADC4D) | bit(ADC3D) | bit(ADC2D) | bit(ADC1D) | bit(ADC0D);
  DIDR1 = bit(AIN1D) | bit(AIN0D);

#ifdef LMREMOTE_SERIAL
  PRR &= ~bit(PRUSART0);
  Serial.begin(LMREMOTE_SERIAL); Serial.println("$UCID,lmremote"); delay(10);
#endif

  rf12_initialize(1, _rfBand);
  // Crystal 1.66MHz Low Battery Detect 2.2V
  rf12_control(0xC040);

  if (_pinLedRx != 0xff) pinMode(_pinLedRx, OUTPUT);
  if (_pinLedTx != 0xff) pinMode(_pinLedTx, OUTPUT);

  setupSupplyPins();

  // Force a transmit on next read
  memset(_previousReads, 0xff, sizeof(_previousReads));
}

void loop(void)
{
  if (_loopCnt % 2 == 0)
    checkTemps();

#ifdef LMREMOTE_SERIAL
  Serial.flush(); delay(2);
#endif

  if (_recvLast == 0)
    resetEstimate();
  else
    optimalSleep();
  ++_loopCnt;
}


Added arduino Wiegand reader

Added arduino Wiegand reader

#include <Wiegand.h>
#define PIN_LENGTH 10
#define MAX_USER_ACTION_DELAY_MS 10000

WIEGAND wg;
bool isPinCodeSet = false;
int pincode[PIN_LENGTH + 1];
int pincodeptr = 0;

bool isKeyCodeSet = false;
long lastKeyCode = 0;

unsigned long lastUserAction = 0;

void setup() {
  Serial.begin(9600);
  resetPinCode();
  wg.begin();
}

void resetPinCode() {
  for (int i=0; i<PIN_LENGTH + 1; i++) {
    pincode[i] = -1;
  }

  pincodeptr = 0;
  isPinCodeSet = false;
}

void printAndResetAccessCodes() {
    Serial.print("{ \"pincode\": \"");

    int ptr = 0;

    do {
      Serial.print(pincode[ptr]);
    } while (ptr++ < PIN_LENGTH && pincode[ptr] != -1);

    Serial.print("\", ");
    Serial.print("\"keycode\": \"");
    Serial.print(lastKeyCode);
    Serial.println("\" }");

    resetPinCode();
    isKeyCodeSet = false;
}

void loop() {
  if (wg.available()) {
    lastUserAction = millis();

    if (wg.getWiegandType() == 4) {
      int code = wg.getCode();
      if (code == 27) {
        resetPinCode();
      } else if (code == 13) {
        isPinCodeSet = true;
      } else {
        pincode[pincodeptr % PIN_LENGTH] = wg.getCode();
        pincodeptr++;
      }
    } else {
      lastKeyCode = wg.getCode();
      isKeyCodeSet = true;
    }

    if (isPinCodeSet && isKeyCodeSet) {
      printAndResetAccessCodes();
    }
  }

  if (Serial.available()) {
    char c = Serial.read();
    Serial.print(c);
  }

  if (lastUserAction + MAX_USER_ACTION_DELAY_MS < millis()) {
    lastUserAction = millis();
    resetPinCode();
    isKeyCodeSet = false;
  }
}

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


Added Solenoid code

Added Solenoid code

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif

#define SOLENOID_PIN       2
#define LED_PIN            6

// How many NeoPixels are attached to the Arduino?
#define NUMPIXELS      18

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, LED_PIN, NEO_GRB + NEO_KHZ800);

int delayval = 65; // delay for half a second

void setup() {
  // This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket
#if defined (__AVR_ATtiny85__)
  if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
#endif
  // End of trinket special code
  Serial.begin(9600);
  pinMode(SOLENOID_PIN, OUTPUT);
  digitalWrite(SOLENOID_PIN, HIGH);
  pixels.begin(); // This initializes the NeoPixel library.
}

void loop() {

  // For a set of NeoPixels the first NeoPixel is 0, second is 1, all the way up to the count of pixels minus one.
  int on_pixel;
  int off_pixel;
  int num_pixels_on = 2;
  //This leaves 2 pixels on at all times:
  for(int i=0;i < NUMPIXELS;i++){
    on_pixel = i;
    off_pixel = i - num_pixels_on;
    if (on_pixel <  0){
      on_pixel += NUMPIXELS;
    }
    if (off_pixel < 0){
      off_pixel += NUMPIXELS;
    }
    if (on_pixel > NUMPIXELS){
      on_pixel -= NUMPIXELS;
    }
    if (off_pixel > NUMPIXELS){
      off_pixel -= NUMPIXELS;
    }
    pixels.setPixelColor(on_pixel, pixels.Color(255,255,255));
    pixels.show();
    pixels.setPixelColor(off_pixel, pixels.Color(0,0,0));
    pixels.show();

    if (Serial.available() > 0) {
      int input = Serial.parseInt();
      digitalWrite(SOLENOID_PIN, LOW);
    }
    if (Serial.read() == '\n') {};
    delay(delayval);
    digitalWrite(SOLENOID_PIN, HIGH);
  }
}

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


Initial commit

Initial commit

#include <ESP8266WiFi.h>         //https://github.com/esp8266/Arduino
#include <DNSServer.h>
#include <ESP8266WebServer.h>

#define FOCUS_PIN     0
#define SHUTTER_PIN   2
#define FOCUS_DELAY   800
#define SHUTTER_DELAY 1200
#define WEB_PORT      80
#define DNS_PORT      53
#define AP_NAME       "Canon WiFi Remote Module"
#define AP_PASSWORD   "LetMeJoin"

#define DEBUG

#ifdef DEBUG
#define DEBUG_PRINT(message) Serial.println(message)
#else
#define DEBUG_PRINT(message)
#endif

// prototypes
void setup();
void loop();
void indexHTML();
void redirectTo(String);
void triggerFocus();
void triggerShutter();

// global vars
IPAddress apIP(192, 168, 10, 1);
ESP8266WebServer webServer(WEB_PORT);
DNSServer dnsServer;

String responseHTML = "<!DOCTYPE html><title>"
                      AP_NAME
                      "</title>
"
                      AP_NAME
                      "

<button id=shutter-btn>take picture</button>
Every <input id=every-input type=number value=5> seconds <button id=every-btn>start</button>
<button id=focus-btn>focus</button>
"
                      ;

void setup() {
  pinMode(FOCUS_PIN, OUTPUT);
  pinMode(SHUTTER_PIN, OUTPUT);
  digitalWrite(FOCUS_PIN, LOW);
  digitalWrite(SHUTTER_PIN, LOW);

#ifdef DEBUG
  Serial.begin(115200); // open serial
#endif

  WiFi.mode(WIFI_AP);
  WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
  WiFi.softAP(AP_NAME, AP_PASSWORD);

  // if DNSServer is started with "*" for domain name, it will reply with
  // provided IP to all DNS request
  dnsServer.start(DNS_PORT, "*", apIP);

  webServer.on("/", HTTP_GET, indexHTML);
  webServer.on("/trigger/shutter", HTTP_POST, triggerShutter);
  webServer.on("/trigger/focus", HTTP_POST, triggerFocus);
  webServer.onNotFound([]() {
    redirectTo("/");
  });
  webServer.begin();
}

void loop() {
  dnsServer.processNextRequest();
  webServer.handleClient();
}

void indexHTML() {
  webServer.send(200, "text/html", responseHTML);
}

void redirectTo(String path) {
  webServer.sendHeader("Location", "http://" + apIP.toString() + path);
  webServer.send(302);
}

void triggerFocus() {
  redirectTo("/");

  DEBUG_PRINT("Focus: start");
  digitalWrite(FOCUS_PIN, HIGH);
  delay(FOCUS_DELAY);
  DEBUG_PRINT("Focus: stop");
  digitalWrite(FOCUS_PIN, LOW);
}

void triggerShutter() {
  redirectTo("/");

  DEBUG_PRINT("Shutter: start");
  digitalWrite(SHUTTER_PIN, HIGH);
  delay(SHUTTER_DELAY);
  DEBUG_PRINT("Shutter: stop");
  digitalWrite(SHUTTER_PIN, LOW);
}


Create readByte16x16.ino

Create readByte16x16.ino

This sketch read 256 byte size memory 24C02, and send to serial monitor like 16x16 table.

/******************************************************************************
 * Header file inclusions.
 ******************************************************************************/

#include <Wire.h>

#include <Eeprom24C0102.h>

/**************************************************************************//**
 * \def EEPROM_ADDRESS
 * \brief Address of EEPROM memory on TWI bus.
 ******************************************************************************/
#define EEPROM_ADDRESS  0x50

/******************************************************************************
 * Private variable definitions.
 ******************************************************************************/

static Eeprom24C0102 eeprom(EEPROM_ADDRESS);

void setup()
{
    // Initialize serial communication.
    Serial.begin(9600);

    // Initialize EEPROM library.
    eeprom.initialize();

    // Declare byte arrays.
    byte outputBytes[256] = { 0 };

    /*

    // Write a byte at address 0 in EEPROM memory.
    Serial.println("Write byte to EEPROM memory...");
    eeprom.writeByte(0, 0xAA);

    // Write cycle time (tWR). See EEPROM memory datasheet for more details.
    delay(10);

    */

    // Read a byte at address 0 in EEPROM memory.
    Serial.println("");
    Serial.println("Read as 16x16 matrix from EEPROM memory...");
    Serial.println("");
    eeprom.readBytes(0, 255, outputBytes);

    // Print read bytes.
    Serial.println("Like as is:");

    for (byte i = 0; i < 255; i++)
    {
      outputBytes[i] = i + 33;
      Serial.write(outputBytes[i]);
      Serial.print(" ");
      if (i == 15)Serial.println("");
      if (i == 31)Serial.println("");
      if (i == 48)Serial.println("");
      if (i == 64)Serial.println("");

      if (i == 79)Serial.println("");
      if (i == 95)Serial.println("");
      if (i == 111)Serial.println("");
      if (i == 127)Serial.println("");

      if (i == 143)Serial.println("");
      if (i == 159)Serial.println("");
      if (i == 175)Serial.println("");
      if (i == 191)Serial.println("");

      if (i == 207)Serial.println("");
      if (i == 223)Serial.println("");
      if (i == 239)Serial.println("");
      if (i == 255)Serial.println("");
    }

    Serial.println("");
    Serial.println("Like as DEC:");

    for (int i = 0; i<=255;i++){
    byte data = eeprom.readByte(i);
    Serial.print(data, DEC);
    Serial.print(" ");
    if (i == 15)Serial.println("");
    if (i == 31)Serial.println("");
    if (i == 48)Serial.println("");
    if (i == 64)Serial.println("");

    if (i == 79)Serial.println("");
    if (i == 95)Serial.println("");
    if (i == 111)Serial.println("");
    if (i == 127)Serial.println("");

    if (i == 143)Serial.println("");
    if (i == 159)Serial.println("");
    if (i == 175)Serial.println("");
    if (i == 191)Serial.println("");

    if (i == 207)Serial.println("");
    if (i == 223)Serial.println("");
    if (i == 239)Serial.println("");
    if (i == 255)Serial.println("");
    }

    Serial.println("");
    Serial.println("Like as HEX:");

    for (int i = 0; i<=255;i++){
    byte data = eeprom.readByte(i);
    Serial.print(data, HEX);
    Serial.print(" ");
    if (i == 15)Serial.println("");
    if (i == 31)Serial.println("");
    if (i == 48)Serial.println("");
    if (i == 64)Serial.println("");

    if (i == 79)Serial.println("");
    if (i == 95)Serial.println("");
    if (i == 111)Serial.println("");
    if (i == 127)Serial.println("");

    if (i == 143)Serial.println("");
    if (i == 159)Serial.println("");
    if (i == 175)Serial.println("");
    if (i == 191)Serial.println("");

    if (i == 207)Serial.println("");
    if (i == 223)Serial.println("");
    if (i == 239)Serial.println("");
    if (i == 255)Serial.println("");
    }

    Serial.println("Done!");
}

void loop()
{

}

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


EchoBLE: test BC127 BLE functionality

EchoBLE: test BC127 BLE functionality

An initial test to verify BC127 BLE functionality and interoperability with iOS devices. Once BLE connections are established, ASCII input from an iOS device should be echo'd back by the Tympan.

Begins: #26

/*
*	EchoBLE
*
*	Created: Ira Ray Jenkins, Creare, July 2020
*	Purpose: Demonstrates BLE functionality of the Tympan BC127 Bluetooth module. Data
		received via BLE will be echo'd back.
*
*/
#include <Tympan_Library.h>

Tympan myTympan(TympanRev::D);

usb_serial_class *USB_Serial;
HardwareSerial *BT_Serial;
String response;

void echoIncomingUSBSerial(void) {
  while (USB_Serial->available()) {
    BT_Serial->write(USB_Serial->read());
  }
}

void echoIncomingBTSerial(void) {
  while(BT_Serial->available()) {
    USB_Serial->write(BT_Serial->read());
  }
}

void readBTResponse(void) {
  response = BT_Serial->readString();
}

void setup() {
  myTympan.beginBothSerial(); delay(2000);
  USB_Serial = myTympan.getUSBSerial();
  BT_Serial = myTympan.getBTSerial();
  USB_Serial->println("*** Setup Starting...");

  BLE_Setup();

  USB_Serial->println("*** Setup Complete.");

}

void loop() {
 while(BT_Serial->available()) {
    response = BT_Serial->readString();

    USB_Serial->println("Response: " + response.trim());

    if(response.substring(0,8) == "RECV BLE") {
      USB_Serial->println("*** Received: " + response.substring(9));

      BT_Serial->print("SEND Received: " + response.substring(9) + "\r");

      delay(200);

      BT_Serial->readString();

    }
  }
}

void BLE_Setup(void) {
  // get into command mode
  USB_Serial->println("*** Switching Tympan RevD BT module into command mode...");
  myTympan.forceBTtoDataMode(false); delay(500);
  BT_Serial->print("$"); delay(400);
  BT_Serial->print("$$$"); delay(400);
  delay(2000);
  echoIncomingBTSerial();
  echoIncomingUSBSerial();
  USB_Serial->println("*** Should be in command mode.");

  USB_Serial->println("*** Clearing buffers. Sending carriage return.");
  BT_Serial->print("\r"); delay(500);
  USB_Serial->println("*** Should have gotten 'Error', which is fine here.");

  // restore factory defaults
  USB_Serial->println("*** Restoring factory defaults...");
  BT_Serial->print("RESTORE"); BT_Serial->print('\r'); delay(500);echoIncomingBTSerial();
  BT_Serial->print("WRITE"); BT_Serial->print('\r'); delay(500);echoIncomingBTSerial();
  BT_Serial->print("RESET"); BT_Serial->print('\r'); delay(1500);echoIncomingBTSerial();
  USB_Serial->println("*** Reset should be complete.  Did it give two 'OK's, an ID blurb, and then 'READY'?");

  // Is this necessary?
  // set the GP IO pins so that the data mode / command mode can be set by hardware
  USB_Serial->println("*** Setting GPIOCONTROL mode to OFF, which is what we need...");
  BT_Serial->print("SET GPIOCONTROL=OFF");BT_Serial->print('\r'); delay(500);echoIncomingBTSerial();
  BT_Serial->print("WRITE"); BT_Serial->print('\r'); delay(500); echoIncomingBTSerial();

  // set advertising
  USB_Serial->println("*** Set advertising on...");
  BT_Serial->print("ADVERTISING ON\r"); delay(500); echoIncomingBTSerial();
  USB_Serial->println("*** Advertising on.");

  while(1) {
    if(BT_Serial->available()) {
      readBTResponse();
      USB_Serial->print("*** Response = "); USB_Serial->println(response);
      response.trim();

      if(response.equalsIgnoreCase("OPEN_OK BLE")) {
        USB_Serial->println("*** Connected.");
        break;
      }

      delay(2000);
    }
  }

  USB_Serial->println("*** BLE Connected.");
}

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


Kapitola: Začíname s robotom

Kapitola: Začíname s robotom

Programy/01_Chodenie rovno a doprava.ino

error: pathspec 'Programy/01_Chodenie' did not match any file(s) known to git
error: pathspec 'rovno' did not match any file(s) known to git
error: pathspec 'a' did not match any file(s) known to git
error: pathspec 'doprava.ino' did not match any file(s) known to git


Initial Commit - Arduino pan-tilt robot code using MPU6050 gryo/accelerometer to mimic head-tracking shoulder cannon, similar to the one in the Predator movie.  This is the single-gyro code seen in https://www.youtube.com/watch?v=FX67M_g3Bmk

#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"
#include "Wire.h"
#include "Servo.h"

//initialize gyro instance
//TODO:  Change this to initialize two gyros with +VDC/Ground arguments
MPU6050 mpu;

//initialize servo instances
Servo yawServo;
Servo pitchServo;

#define DEBUG  //Comment to turn off Serial printing

//Debug serial printing macros
#ifdef DEBUG
	//#define DPRINT(args...)  Serial.print(args)             //OR use the following syntax:
	#define DPRINTSTIMER(t)    for (static unsigned long SpamTimer; (unsigned long)(millis() - SpamTimer) >= (t); SpamTimer = millis())
	#define  DPRINTSFN(StrSize,Name,...) {char S[StrSize];Serial.print("\t");Serial.print(Name);Serial.print(" "); Serial.print(dtostrf((float)__VA_ARGS__ ,S));}//StringSize,Name,Variable,Spaces,Percision
	#define DPRINTLN(...)      Serial.println(__VA_ARGS__)
#else
	#define DPRINTSTIMER(t)    if(false)
	#define DPRINTSFN(...)     //blank line
	#define DPRINTLN(...)      //blank line
#endif

//TODO:  Find out if it's really necessary to turn on this LED...probably not.
const int LED_PIN = 13;

//Prevent the servos from turning beyond mechanical limits
const int maxPitch = 135;
const int minPitch = 45;
//Yaw direction is inverted via map() method in moveServos()
const int maxYaw = 135;
const int minYaw = 45;

// supply gyro offsets here, scaled for min sensitivity use MPU6050_calibration.ino
// Gyro 0 (head) calibrated at:   {-3074,  -2036,  1236,    63,    -16,     78}
//                     XA      YA      ZA      XG      YG      ZG
int MPUOffsets0[6] = {-3074,  -2036,  1236,    63,    -16,     78};

unsigned long currentMillis = 0;    // stores the value of millis() in each iteration of loop()
unsigned long prevMillis = 0;    // stores the value of millis() in each iteration of loop()

int pos = 0;    // variable to store the servo position when testing

// ================================================================
// ===                      i2c SETUP Items                     ===
// ================================================================
void i2cSetup() {
  // join I2C bus (I2Cdev library doesn't do this automatically)
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
  Wire.begin();
  TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz)
#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
  Fastwire::setup(400, true);
#endif
}

// ================================================================
// ===               INTERRUPT DETECTION ROUTINE                ===
// ================================================================
volatile bool mpuInterrupt = false;     // indicates whether MPU interrupt pin has gone high
void dmpDataReady() {
  mpuInterrupt = true;
}

// ================================================================
// ===                      MPU DMP SETUP                       ===
// ================================================================
int FifoAlive = 0; // tests if the interrupt is triggering
int IsAlive = -20;     // counts interrupt start at -20 to get 20+ good values before assuming connected
// MPU control/status vars
uint8_t mpuIntStatus;   // holds actual interrupt status byte from MPU
uint8_t devStatus;      // return status after each device operation (0 = success, !0 = error)
uint16_t packetSize;    // expected DMP packet size (default is 42 bytes)
uint16_t fifoCount;     // count of all bytes currently in FIFO
uint8_t fifoBuffer[64]; // FIFO storage buffer

// orientation/motion vars
Quaternion q;           // [w, x, y, z]         quaternion container
VectorInt16 aa;         // [x, y, z]            accel sensor measurements
VectorInt16 aaReal;     // [x, y, z]            gravity-free accel sensor measurements
VectorInt16 aaWorld;    // [x, y, z]            world-frame accel sensor measurements
VectorFloat gravity;    // [x, y, z]            gravity vector
float euler[3];         // [psi, theta, phi]    Euler angle container
float ypr[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity vector
byte StartUP = 100; // lets get 100 readings from the MPU before we start trusting them (Bot is not trying to balance at this point it is just starting up.)

void MPU6050Connect() {
  static int MPUInitCntr = 0;
  // initialize device
  mpu.initialize(); // same
  // load and configure the DMP
  devStatus = mpu.dmpInitialize();// same

  if (devStatus != 0) {
    // ERROR!
    // 1 = initial memory load failed
    // 2 = DMP configuration updates failed
    // (if it's going to break, usually the code will be 1)

    char * StatStr[5] { "No Error", "initial memory load failed", "DMP configuration updates failed", "3", "4"};

    MPUInitCntr++;

    Serial.print(F("MPU connection Try #"));
    Serial.println(MPUInitCntr);
    Serial.print(F("DMP Initialization failed (code "));
    Serial.print(StatStr[devStatus]);
    Serial.println(F(")"));

    if (MPUInitCntr >= 10) return; //only try 10 times
    delay(1000);
    MPU6050Connect(); // Lets try again
    return;
  }
  mpu.setXAccelOffset(MPUOffsets0[0]);
  mpu.setYAccelOffset(MPUOffsets0[1]);
  mpu.setZAccelOffset(MPUOffsets0[2]);
  mpu.setXGyroOffset(MPUOffsets0[3]);
  mpu.setYGyroOffset(MPUOffsets0[4]);
  mpu.setZGyroOffset(MPUOffsets0[5]);

  Serial.println(F("Enabling DMP..."));
  mpu.setDMPEnabled(true);
  // enable Arduino interrupt detection
  Serial.println(F("Enabling interrupt detection (Arduino external interrupt pin 2 on the Uno)..."));
  Serial.print("mpu.getInterruptDrive=  "); Serial.println(mpu.getInterruptDrive());
  attachInterrupt(0, dmpDataReady, RISING); //pin 2 on the Uno
  mpuIntStatus = mpu.getIntStatus(); // Same
  // get expected DMP packet size for later comparison
  packetSize = mpu.dmpGetFIFOPacketSize();
  delay(1000); // Let it Stabalize
  mpu.resetFIFO(); // Clear fifo buffer
  mpu.getIntStatus();
  mpuInterrupt = false; // wait for next interrupt
}

// ================================================================
// ===                    MPU DMP Get Data                      ===
// ================================================================
void GetDMP() { // Best version I have made so far
  // Serial.println(F("FIFO interrupt at:"));
  // Serial.println(micros());
  static unsigned long LastGoodPacketTime;
  mpuInterrupt = false;
  FifoAlive = 1;
  fifoCount = mpu.getFIFOCount();
  if ((!fifoCount) || (fifoCount % packetSize)) { // we have failed Reset and wait till next time!
    digitalWrite(LED_PIN, LOW); // lets turn off the blinking light so we can see we are failing.
    mpu.resetFIFO();// clear the buffer and start over
  } else {
    while (fifoCount  >= packetSize) { // Get the packets until we have the latest!
      mpu.getFIFOBytes(fifoBuffer, packetSize); // lets do the magic and get the data
      fifoCount -= packetSize;
    }
    LastGoodPacketTime = millis();
    MPUMath(); // <<<<<<<<<<<<<<<<<<<<<<<<<<<< On success MPUMath() <<<<<<<<<<<<<<<<<<<
    digitalWrite(LED_PIN, !digitalRead(LED_PIN)); // Blink the Light
  }
}

// ================================================================
// ===                        MPU Math                          ===
// ================================================================
float Yaw, Pitch, Roll;
void MPUMath() {
  mpu.dmpGetQuaternion(&q, fifoBuffer);
  mpu.dmpGetGravity(&gravity, &q);
  mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);

  //TODO: Move the +90 gyro/servo leveling math to another method,
  //it doesn't belong here and will cause readability problems later.
  Yaw = (ypr[0] * 180.0 / M_PI) + 90;
  Pitch = (ypr[1] *  180.0 / M_PI) + 90;
  Roll = (ypr[2] *  180.0 / M_PI) + 90;

  /*
  //Serial.log the current actual values of the gyro position.
  DPRINTSTIMER(100) {
    DPRINTSFN(15, "\tYaw:", Yaw, 6, 1);
    DPRINTSFN(15, "\tPitch:", Pitch, 6, 1);
    DPRINTSFN(15, "\tRoll:", Roll, 6, 1);
    DPRINTLN();
  }
  */

  if (currentMillis >= prevMillis + 15) {
    moveServos(round(Yaw), round(Pitch));
  }

}

/**
 * Move the servos to the gyro postion
 * =============================================================
 *
 * @author Mike Muscato
 * @date   2017-01-14
 *
 * @param  {integer}   int servoYaw      The rounded angle of the z-axis rotation of the gyro
 * @param  {integer}   int servoPitch    The rounded angle of the y-axis rotation of the gryo
 * @return {void}
 */
void moveServos(int servoYaw, int servoPitch) {

  //TODO: Determine if yaw/pitch is beyond normal servo angles
  //i.e. > 179 or < 0
  //If so, assume actual gyro position and provide max servo value.
  //Create trimAngles() method.

  //Invert Yaw
  int invertedYaw = map(servoYaw, 0, 179, 179, 0);

  //Prevent the servos from moving farther than my head can rotate.
  if (invertedYaw > maxYaw) {
    invertedYaw = maxYaw;
  }
  else if (invertedYaw < minYaw) {
    invertedYaw = minYaw;
  }

  //Prevent the servos from tilting farther than my head can nod.
  if (servoPitch > maxPitch) {
    servoPitch = maxPitch;
  }
  else if (servoPitch < minPitch) {
    servoPitch = minPitch;
  }

  DPRINTSTIMER(100) {
    DPRINTSFN(15, "\tServo - Yaw:", servoYaw, 6, 1);
    DPRINTSFN(15, "\tServo - invertYaw:", invertedYaw, 6, 1);
    DPRINTSFN(15, "\tPitch:", servoPitch, 6, 1);
    DPRINTLN();
  }

  yawServo.write(invertedYaw);
  pitchServo.write(servoPitch);

  prevMillis = currentMillis;

}

// ================================================================
// ===                         Setup                            ===
// ================================================================
void setup() {
  Serial.begin(115200); //115200
  while (!Serial);
  Serial.println("i2cSetup");
  i2cSetup();
  Serial.println("MPU6050Connect");
  MPU6050Connect();
  Serial.println("Setup complete");
  pinMode(LED_PIN, OUTPUT);

  yawServo.attach(9);
  pitchServo.attach(10);

  yawServo.write(90);
  pitchServo.write(90);
}

// ================================================================
// ===                          Loop                            ===
// ================================================================
void loop() {
  currentMillis = millis();   // capture the latest value of millis()
  if (mpuInterrupt ) { // wait for MPU interrupt or extra packet(s) available
    GetDMP();
  }

  //for calibrating the start position in the hardware.
  //TODO: Comment when completed or it will conflict with the
  //motion of the robot.
  // yawServo.write(90);
  // pitchServo.write(90);

  //for testing hardware
  // //TODO: Comment when completed
  // for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
  //   // in steps of 1 degree
  //   yawServo.write(pos);              // tell servo to go to position in variable 'pos'
  //   delay(20);                       // waits 15ms for the servo to reach the position
  // }
  // for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
  //   yawServo.write(pos);              // tell servo to go to position in variable 'pos'
  //   delay(20);                       // waits 15ms for the servo to reach the position
  // }
}

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


added the pin mappings

added the pin mappings

THIS IS A FUNCTIONAL TEST.

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


Added new commant RQ_SET_GLOBAL

Added new commant RQ_SET_GLOBAL


Refactored tftTask.

Refactored tftTask.

void tftTask( void * pvParameters )
{
  const uint16_t TFT_TEXT_COLOR   = ILI9341_YELLOW;
  const uint16_t TFT_DATE_COLOR   = ILI9341_BLUE;
  const uint16_t TFT_TEMP_COLOR   = ILI9341_WHITE;
  const uint16_t TFT_BACK_COLOR   = ILI9341_BLACK;

  tft.begin( 35000000, SPI );
  uint8_t x = tft.readcommand8( ILI9341_RDSELFDIAG );
  Serial.print( "ILI9341 TFT Self Diagnostic: 0x" ); Serial.println( x, HEX );

  tft.fillScreen( TFT_BACK_COLOR );

  digitalWrite( TFT_BACKLIGHT_PIN, HIGH );

  ( readStringNVS( "tftorientation", "normal" ) == "normal" ) ? tftOrientation = TFT_ORIENTATION_NORMAL : tftOrientation = TFT_ORIENTATION_UPSIDEDOWN;
  tft.setRotation( tftOrientation );

  int tftTaskdelayTime = 1000 / UPDATE_FREQ_LEDS;

  while (1)
  {
    const uint16_t BARS_BOTTOM      = 205;
    const uint16_t BARS_HEIGHT      = BARS_BOTTOM;
    const uint16_t BARS_BORDER      = 10;
    const uint16_t BARS_WIDTH       = ILI9341_TFTHEIGHT / 5;
    const float    HEIGHT_FACTOR    = BARS_HEIGHT / 100.0;

    for ( byte thisChannel = 0; thisChannel < NUMBER_OF_CHANNELS; thisChannel++ )
    {
      //convert from String to RGB color
      //https://stackoverflow.com/questions/2342114/extracting-rgb-color-components-from-integer-value/2342149#2342149
      int r, g, b;
      uint32_t color = strtol( &channel[thisChannel].color[1], NULL, 16 );
      r = ( color & 0xFF0000 ) >> 16; // Filter the 'red' bits from color. Then shift right by 16 bits.
      g = ( color & 0x00FF00 ) >> 8;  // Filter the 'green' bits from color. Then shift right by 8 bits.
      b = ( color & 0x0000FF );       // Filter the 'blue' bits from color. No shift needed.

      // redraw the top part of the bar
      tft.fillRect( thisChannel * BARS_WIDTH + BARS_BORDER,
                    BARS_BOTTOM - BARS_HEIGHT,
                    BARS_WIDTH - BARS_BORDER * 2,
                    BARS_HEIGHT - channel[thisChannel].currentPercentage * HEIGHT_FACTOR,
                    TFT_BACK_COLOR );
      /*
            //high water mark
            tft.drawFastHLine( thisChannel * BARS_WIDTH + BARS_BORDER,
                               BARS_BOTTOM - BARS_HEIGHT - 1,
                               BARS_WIDTH - BARS_BORDER * 2,
                               tft.color565( r, g, b ) );
      */
      tft.fillRect( thisChannel * BARS_WIDTH + BARS_BORDER,
                    BARS_BOTTOM - channel[thisChannel].currentPercentage * HEIGHT_FACTOR,
                    BARS_WIDTH - BARS_BORDER * 2,
                    channel[thisChannel].currentPercentage * HEIGHT_FACTOR,
                    tft.color565( r, g, b ) );

      tft.setCursor( thisChannel * BARS_WIDTH + 9, BARS_BOTTOM + 4 );
      tft.setTextSize( 1 );
      tft.setTextColor( TFT_TEXT_COLOR , TFT_BACK_COLOR );

      char buffer [9];
      snprintf( buffer, sizeof( buffer ), "%*" ".3f%%", 7, channel[thisChannel].currentPercentage );
      tft.print( buffer );
    }

    tft.setTextSize( 2 );
    if ( numberOfFoundSensors )
    {
      for ( byte thisSensor = 0; thisSensor < numberOfFoundSensors; thisSensor++ )
      {
        tft.setCursor( 0, BARS_BOTTOM + 15 );
        tft.setTextColor( TFT_TEMP_COLOR , TFT_BACK_COLOR );
        tft.print( " " + String( sensor[thisSensor].temp / 16.0 ) + (char)247 + "C " );
      }
    }
    else
    {
      struct tm timeinfo;
      getLocalTime( &timeinfo );
      tft.setCursor( 18, BARS_BOTTOM + 15 );
      tft.setTextColor( TFT_DATE_COLOR , TFT_BACK_COLOR );
      tft.print( asctime( &timeinfo ) );
    }
    vTaskDelay( tftTaskdelayTime / portTICK_PERIOD_MS );
  }
}

void tftTask( void * pvParameters )
{
  tft.begin( 35000000, SPI );
  uint8_t x = tft.readcommand8(ILI9341_RDSELFDIAG);
  Serial.print("ILI9341 TFT Self Diagnostic: 0x"); Serial.println(x, HEX);

  tft.fillScreen(ILI9341_BLACK);

  digitalWrite( TFT_BACKLIGHT_PIN, HIGH );

  ( readStringNVS( "tftorientation", "normal" ) == "normal" ) ? tftOrientation = TFT_ORIENTATION_NORMAL : tftOrientation = TFT_ORIENTATION_UPSIDEDOWN;
  tft.setRotation( tftOrientation );

  int tftTaskdelayTime = 1000 / UPDATE_FREQ_LEDS;

  while (1)
  {
    const uint16_t TFT_TEXT_COLOR   = ILI9341_YELLOW;
    const uint16_t TFT_DATE_COLOR   = ILI9341_BLUE;
    const uint16_t TFT_TEMP_COLOR   = ILI9341_WHITE;
    const uint16_t TFT_BACK_COLOR   = ILI9341_BLACK;

    const uint16_t BARS_BOTTOM      = 181;
    const uint16_t BARS_HEIGHT      = 180;
    const uint16_t BARS_BORDER      = 10;
    const uint16_t BARS_WIDTH       = ILI9341_TFTHEIGHT / 5;
    const float    HEIGHT_FACTOR    = BARS_HEIGHT / 100.0;

    for ( byte thisChannel = 0; thisChannel < NUMBER_OF_CHANNELS; thisChannel++ )
    {
      //convert from String to RGB color
      //https://stackoverflow.com/questions/2342114/extracting-rgb-color-components-from-integer-value/2342149#2342149
      int r, g, b;
      uint32_t color = strtol( &channel[thisChannel].color[1], NULL, 16 );
      r = ( color & 0xFF0000 ) >> 16; // Filter the 'red' bits from color. Then shift right by 16 bits.
      g = ( color & 0x00FF00 ) >> 8;  // Filter the 'green' bits from color. Then shift right by 8 bits.
      b = ( color & 0x0000FF );       // Filter the 'blue' bits from color. No shift needed.

      // redraw the top part of the bar
      tft.fillRect( thisChannel * BARS_WIDTH + BARS_BORDER,
                    BARS_BOTTOM - BARS_HEIGHT,
                    BARS_WIDTH - BARS_BORDER * 2,
                    BARS_HEIGHT - channel[thisChannel].currentPercentage * HEIGHT_FACTOR,
                    TFT_BACK_COLOR );
      /*
            //high water mark
            tft.drawFastHLine( thisChannel * BARS_WIDTH + BARS_BORDER,
                               BARS_BOTTOM - BARS_HEIGHT - 1,
                               BARS_WIDTH - BARS_BORDER * 2,
                               tft.color565( r, g, b ) );
      */
      tft.fillRect( thisChannel * BARS_WIDTH + BARS_BORDER,
                    BARS_BOTTOM - channel[thisChannel].currentPercentage * HEIGHT_FACTOR,
                    BARS_WIDTH - BARS_BORDER * 2,
                    channel[thisChannel].currentPercentage * HEIGHT_FACTOR,
                    tft.color565( r, g, b ) );

      tft.setCursor( thisChannel * BARS_WIDTH + 12, BARS_BOTTOM + 4 );
      tft.setTextSize( 1 );
      tft.setTextColor( TFT_TEXT_COLOR , TFT_BACK_COLOR );

      char buffer [9];
      snprintf( buffer, sizeof( buffer ), "%*" ".3f%%", 7, channel[thisChannel].currentPercentage );
      tft.print( buffer );
    }

    tft.setCursor( 0, BARS_BOTTOM + 20 );
    tft.setTextSize( 2 );
    tft.setTextColor( TFT_TEMP_COLOR , TFT_BACK_COLOR );

    if ( numberOfFoundSensors )
    {
      for ( byte thisSensor = 0; thisSensor < numberOfFoundSensors; thisSensor++ )
      {
        tft.print( " " + String( sensor[thisSensor].temp / 16.0 ) + (char)247 + "C " );
      }
    }

    tft.setCursor( 60, BARS_BOTTOM + 40 );
    tft.setTextColor( TFT_TEMP_COLOR , TFT_BACK_COLOR );

    tft.print( lightStatus );

    vTaskDelay( tftTaskdelayTime / portTICK_PERIOD_MS );
  }
}