added thermistor prototype code

added thermistor prototype code

#include <LiquidCrystal.h>
#define TP 2      //Trig_pin
LiquidCrystal lcd(8, 13, 9, 4, 5, 6, 7);

int thermister_temp(int aval) {
	double R, T;

	// These were calculated from the thermister data sheet
	//	A = 2.3067434E-4;
	//	B = 2.3696596E-4;
	//	C = 1.2636414E-7;
	//
	// This is the value of the other half of the voltage divider
	//	Rknown = 22200;

	// Do the log once so as not to do it 4 times in the equation
	//	R = log(((1024/(double)aval)-1)*(double)22200);
	R = log((1 / ((1024 / (double) aval) - 1)) * (double) 1014000);
	//lcd.print("A="); lcd.print(aval); lcd.print(" R="); lcd.print(R);
	// Compute degrees C
	T = (1 / ((4.717016E-4) + (1.90988E-4) * R + (9.955908E-8) * R * R * R)) - 273.25;
	// return degrees F
	return ((int) ((T * 9.0) / 5.0 + 32.0));
}

void CelsiusToFarenheit(float const tCel, float &tFar) {
	tFar = tCel * 1.8 + 32;
}
void setup() {
  lcd.clear();
  lcd.begin(16, 2);
  lcd.setCursor(0,0);
  Serial.begin(9600);      // open the serial port at 9600 bps:
  pinMode(TP,OUTPUT);       // set TP output for trigger
}

void loop() {
    unsigned int signal = 0;
    unsigned int pit_temp = 0;
    signal = analogRead(1);
    pit_temp = thermister_temp(signal);
    Serial.print("Temp: ");
    Serial.print(pit_temp);
    Serial.print(", Signal: ");
    Serial.print(signal);
    Serial.println("");
    lcd.setCursor(0,0);
    lcd.print("Pit: ");
    lcd.print(pit_temp);
    lcd.print("deg");
    lcd.setCursor(0,1);
    lcd.print("Fan: ");

    if(pit_temp > 82){
      digitalWrite(TP,HIGH);
      lcd.print("ON ");
    }
    else {
      digitalWrite(TP,LOW);
      lcd.print("OFF");
    }
    Serial.println(digitalRead(2));
    delay(1000);
}

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


Added SimplePID example for the A-Star controller.

// AStarPIDTest - Test the PID control for an AStar-based robot.
//
// To gather PID tuning data for graphing, put the robot on blocks, then
// start this program and open a Serial Monitor. Press S4 to start both
// motors, let them come to a steady speed, then press S4 to stop the
// motors. Copy the Serial output to a spreadsheet and plot target speed and
// current speed versus time. You should see a classic PID controller graph
// with some overshoot.

#include <AStar32U4.h>
#include <EnableInterrupt.h>
#include <SimplePID.h>

// Motor parameters. These are based on a Pololu #2285 motor with 48cpr
// encoder.
const float GEAR_RATIO = 210.59;
const float ENCODER_CPR = 12;

// Number of encoder ticks per revolution of the wheel.
const float TICKS_PER_REV = GEAR_RATIO * ENCODER_CPR;

// Maximum desired motor speed. Pololu #2285 are rated for 130rpm, but we
// don't drive them with enough voltage to achieve that.
const float MAX_REVS_PER_SEC = 100.0 / 60.0;

// Use 60% of maximum speed for PID tuning.
const int PID_TUNING_TICKS_PER_SEC = 0.6 * MAX_REVS_PER_SEC * TICKS_PER_REV;

// DFRobot Romeo v2 and BLE PIN assignments.

const int ONBOARD_SWITCH_PIN = A7;

// Pins for the Pololu motor encoder outputs.
const int M1_A = 7;
const int M1_B = 11;
const int M2_A = 15;
const int M2_B = 16;

// Minimum motor control value. Motor output below this will stall.
const int MIN_MOTOR_CMD = 10;

// Maximum motor control value.
const int MAX_MOTOR_CMD = 400;

AStar32U4Motors motors;

// These objects provide access to the A-Star's on-board
// buttons.  We will only use buttonA.
AStar32U4ButtonA buttonA;
AStar32U4ButtonB buttonB;
AStar32U4ButtonC buttonC;

enum { NO_BUTTON, BUTTON_A, BUTTON_B, BUTTON_C };

int leftSpeedTarget = 0;
int rightSpeedTarget = 0;

volatile long leftTicks;
volatile long rightTicks;

long lastLeftTicks = 0;
long lastRightTicks = 0;

int leftMotorCmd = 0;
int rightMotorCmd = 0;

unsigned long lastLoopTime;

unsigned long lastSwitchTime;

float loopTime = 0.0;

// Ziegler-Nichols tuning. See this Wikipedia article for details:
//     https://en.wikipedia.org/wiki/PID_controller#Loop_tuning
// To tune the controller, set USE_KU_ONLY to 1 and increase Ku
// until oscillation occurs, and set Tu to the oscillation period
// in seconds. Then set USE_KU_ONLY to zero to use the
// Ziegler-Nichols tune. To get a less agressive tune, set LESS_AGGRESSIVE
// to 1.

// Set to 1 to use Ku only, to determine oscillation point.
#define USE_KU_ONLY 0

const float Ku = .15;
const float Tu = .1142857143;

#define LESS_AGGRESSIVE 0

#if !LESS_AGGRESSIVE
const float Kp = 0.6*Ku;
const float Ki = 2*Kp/Tu;
const float Kd = Kp*Tu/8;
#else
const float Kp = 0.2*Ku;
const float Ki = 2*Kp/Tu;
const float Kd = Kp*Tu/3;
#endif

#if USE_KU_ONLY
SimplePID leftController = SimplePID(Ku, 0, 0);
SimplePID rightController = SimplePID(Ku, 0, 0);
#else
SimplePID leftController = SimplePID(Kp, Ki, Kd);
SimplePID rightController = SimplePID(Kp, Ki, Kd);
#endif

// Sets up the serial output and the motor control pins, and attaches
// interrupt handlers to the pins on which we will read the encoder
// phototransistor values.
void setup() {
  Serial.begin(115200);
  delay(3000);

  enableInterrupt(M1_A, leftAChange, CHANGE);
  enableInterrupt(M1_B, leftBChange, CHANGE);
  enableInterrupt(M2_A, rightAChange, CHANGE);
  enableInterrupt(M2_B, rightBChange, CHANGE);

  Serial.print("Time (s)\tLeft Target\tLeft Speed\tLeft Cum Error\tLeft Motor");
  Serial.print("\tRight Target\tRight Speed\tRight Cum Error\tRight Motor");
  Serial.println();

  lastLoopTime = micros();
  lastSwitchTime = millis();

  leftTicks = rightTicks = 0;
}

// Loops forever showing the motor speeds and errors since the last loop,
// and adjusts the target speeds depending on whether the user is pressing
// switches S2 through S5, as indicated in the code below.
void loop() {
  delay(15);

  unsigned long curLoopTime = micros();
  noInterrupts();
  long curLeftTicks = leftTicks;
  long curRightTicks = rightTicks;
  interrupts();

  float dt = (curLoopTime - lastLoopTime) / 1E6;

  float leftSpeed = (curLeftTicks - lastLeftTicks) / dt;
  float rightSpeed = (curRightTicks - lastRightTicks) / dt;

  int leftControl = leftController.getControlValue(leftSpeed, dt);
  leftMotorCmd += min(MAX_MOTOR_CMD, leftControl);
  leftMotorCmd = constrain(leftMotorCmd, -MAX_MOTOR_CMD, MAX_MOTOR_CMD);
  if (leftMotorCmd > 0) {
    leftMotorCmd = max(leftMotorCmd, MIN_MOTOR_CMD);
  }

  int rightControl = rightController.getControlValue(rightSpeed, dt);
  rightMotorCmd += min(MAX_MOTOR_CMD, rightControl);
  rightMotorCmd = constrain(rightMotorCmd, -MAX_MOTOR_CMD, MAX_MOTOR_CMD);
  if (rightMotorCmd > 0) {
    rightMotorCmd = max(rightMotorCmd, MIN_MOTOR_CMD);
  }

  // Coast to a stop if target is zero.
  if (leftSpeedTarget == 0) {
    leftMotorCmd = 0;
  }
  if (rightSpeedTarget == 0) {
    rightMotorCmd = 0;
  }

  setSpeed(leftMotorCmd, rightMotorCmd);

  if (leftSpeedTarget > 0 || leftSpeed > 0 || rightSpeedTarget > 0 || rightSpeed > 0) {
    Serial.print(loopTime, 3);
    Serial.print("\t");
    Serial.print(leftSpeedTarget);
    Serial.print("\t");
    Serial.print(leftSpeed);
    Serial.print("\t");
    Serial.print(leftController.getCumulativeError());
    Serial.print("\t");
    Serial.print(leftMotorCmd);
    Serial.print("\t");

    Serial.print(rightSpeedTarget);
    Serial.print("\t");
    Serial.print(rightSpeed);
    Serial.print("\t");
    Serial.print(rightController.getCumulativeError());
    Serial.print("\t");
    Serial.print(rightMotorCmd);
    Serial.print("\t");

    Serial.println();

    loopTime += dt;
}

  // Ignore switches for a short time after pressing, to avoid bounce.
  if (curLoopTime - lastSwitchTime > 0.5*1E6) {
    int switchValue = readSwitch();
    if (switchValue > 0) {
      lastSwitchTime = curLoopTime;

      switch (switchValue) {
        case BUTTON_A:
          // Left motor on/off.
          leftSpeedTarget = (leftSpeedTarget==0 ? PID_TUNING_TICKS_PER_SEC : 0);
          break;
        case BUTTON_B:
          // Right motor on/off.
          rightSpeedTarget = (rightSpeedTarget==0 ? PID_TUNING_TICKS_PER_SEC : 0);
          break;
        case BUTTON_C:
          // Both motors on/off.
          leftSpeedTarget = (leftSpeedTarget==0 ? PID_TUNING_TICKS_PER_SEC : 0);
          rightSpeedTarget = (rightSpeedTarget==0 ? PID_TUNING_TICKS_PER_SEC : 0);
          break;
        default:
          // no change in speed
          break;
      }

      leftController.setSetPoint(leftSpeedTarget);
      rightController.setSetPoint(rightSpeedTarget);
    }
  }

  lastLeftTicks = curLeftTicks;
  lastRightTicks = curRightTicks;
  lastLoopTime = curLoopTime;
}

void waitForSwitch1() {
  while (readSwitch() != 1) {
    // do nothing
  }
}

void setSpeed(int leftSpeed, int rightSpeed) {
  motors.setSpeeds(leftSpeed, rightSpeed);
}

void leftAChange() {
  if (digitalRead(M1_A) == digitalRead(M1_B)) {
    ++leftTicks;
  } else {
    --leftTicks;
  }
}

void leftBChange() {
  if (digitalRead(M1_A) != digitalRead(M1_B)) {
    ++leftTicks;
  } else {
    --leftTicks;
  }
}

void rightAChange() {
  if (digitalRead(M2_A) != digitalRead(M2_B)) {
    ++rightTicks;
  } else {
    --rightTicks;
  }
}

void rightBChange() {
  if (digitalRead(M2_A) == digitalRead(M2_B)) {
    ++rightTicks;
  } else {
    --rightTicks;
  }
}

int readSwitch() {
  if (buttonA.getSingleDebouncedRelease()) {
    return BUTTON_A;
  } else if (buttonB.getSingleDebouncedRelease()) {
    return BUTTON_B;
  } else if (buttonC.getSingleDebouncedRelease()) {
    return BUTTON_C;
  } else {
    return 0;
  }
}

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


code of photon particle.io

code of photon particle.io

// This #include statement was automatically added by the Particle IDE.
#include "SparkTime/SparkTime.h"
#include <climits>
#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))
#define bit(b) (1UL << (b))

#define PI 3.1415926535897932384626433832795
#define HALF_PI 1.5707963267948966192313216916398
#define TWO_PI 6.283185307179586476925286766559
#define DEG_TO_RAD 0.017453292519943295769236907684886
#define RAD_TO_DEG 57.295779513082320876798154814105
typedef uint16_t word;
#define abs(x) ((x)>0?(x):-(x))
#define radians(deg) ((deg)*DEG_TO_RAD)
#define degrees(rad) ((rad)*RAD_TO_DEG)
#define sq(x) ((x)*(x))

#define lowByte(w) ((uint8_t) ((w) & 0xff))
#define highByte(w) ((uint8_t) ((w) >> 8))
UDP UDPClient;
SparkTime rtc;

unsigned long currentTime;
unsigned long lastTime = 0UL;
String timeStr;
const byte numPins = 8;
byte pins[] = {0,1,2,3,4,5,6,7};

bool alarmOnceSet = false;
short alarmHour = 0;
short alarmMinute = 0;
bool timeOnceSet = false;
short lastFPGAState = 0xf;
bool internetOnceConnected = false;

void setup() {
    Particle.publish("devStatus", "Device ON - Cuckoo MODE");

    //internet time sync
    rtc.begin(&UDPClient, "north-america.pool.ntp.org");
    rtc.setTimeZone(6); // gmt offset

    //set pin D0-D7 to be output
    for(int i=0;i<numPins;i++){
        pinMode(i, OUTPUT);
    }

    //set pin A0-A3 to be input
    for(int i=10;i<14;i++){
        pinMode(i, INPUT);
    }
    setIdleStateOnFPGA();

    //set debug LED
    pinMode(A4, OUTPUT); //FGPA Programmed?
    pinMode(A5, OUTPUT); //internet?

    delay(1000);
    reportState();
}

void loop() {
    if(lastFPGAState != 0xf){
        if(timeOnceSet == true){
            //check if an hour already
        }else{
            setTimeOnFPGA();
        }
    }
    delay(1000*5);
    reportState();
}

void checkInternet(){
    if(internetOnceConnected = WiFi.ready())digitalWrite(A5, HIGH);
    else digitalWrite(A5, LOW);
}

void reportState(){
    checkInternet();
    short state = 0;
    for(int i=0;i<4;i++){
        bitWrite(state, i, digitalRead(10+i));
    }
    digitalWrite(A4,LOW);
    switch (state) {
        case 0: Particle.publish("fpgaStatus", "normal"); break;
        case 1: Particle.publish("fpgaStatus", "never Set Clock"); break;
        case 2: Particle.publish("fpgaStatus", "never Set Alarm"); break;
        case 3: Particle.publish("fpgaStatus", "ringing"); break;
        case 0xf: Particle.publish("fpgaStatus", "fpga is on but unprogramed"); digitalWrite(A4,HIGH); break;
        default: break;
    }
    lastFPGAState = state ;
}

void setIdleStateOnFPGA(){
    setOpPins(0x0);
    setDataPins(0);
}

void setTimeOnFPGA(){
    Particle.publish("debug", "run setTimeOnFPGA");
    currentTime = rtc.now();

    short hour =  rtc.hour(currentTime);
    short hour_ = hour/10;
    short hour__ = hour-hour_*10;
    setOpPins(0xe);
    setDataPins(hour__);
    delay(50);
    setOpPins(0xf);
    setDataPins(hour_);
    delay(50);

    short min =  rtc.minute(currentTime);
    short min_ = min/10;
    short min__ = min-min_*10;
    setOpPins(0xc);
    setDataPins(min_);
    delay(50);
    setOpPins(0xd);
    setDataPins(min__);
    delay(50);

    short second =  rtc.second(currentTime);
    short second_ = second/10;
    short second__ = second-second_*10;
    setOpPins(0xa);
    setDataPins(second_);
    delay(50);
    setOpPins(0xb);
    setDataPins(second__);
    delay(50);
    Particle.publish("Debug", "Clock is seted at"+rtc.ISODateString(currentTime));
}

void setAlarmOnFPGA(short hour,short min){
    short hour_ = hour/10;
    short hour__ = hour-hour_*10;
    setOpPins(0x6);
    setDataPins(hour__);
    delay(5);
    setOpPins(0x7);
    setDataPins(hour_);
    delay(5);

    short min_ = min/10;
    short min__ = min-min_*10;
    setOpPins(0x4);
    setDataPins(min_);
    delay(5);
    setOpPins(0x5);
    setDataPins(min__);
    delay(5);

    timeStr = "";
    timeStr += rtc.hour12String(currentTime);
    timeStr += ":";
    timeStr += rtc.minuteString(currentTime);
    timeStr += ":";
    timeStr += rtc.secondString(currentTime);
    timeStr += " ";
    timeStr += rtc.AMPMString(currentTime);
    Particle.publish("info", timeStr);
    Particle.publish("Debug", "Clock is seted at"+rtc.ISODateString(currentTime)+"  "+timeStr);
}

/*function to set pin D0-D3 to desire byte*/
void setOpPins(byte data){
    for(int i=0;i<4;i++){
        byte state = bitRead(data, i);
        digitalWrite(pins[i], state);
    }
}
/*function to set pin D4-D7 to desire number*/
void setDataPins(byte data){
    for(int i=4;i<8;i++){
        byte state = bitRead(data, i);
        digitalWrite(pins[i], state);
    }
}

void publishTime(){
    currentTime = rtc.now();
    if (currentTime != lastTime) {
        byte sec = rtc.second(currentTime);
        if (sec == 10) {
        	// Build Date String
        	timeStr = "";
        	timeStr += rtc.dayOfWeekString(currentTime);
        	timeStr += ", ";
        	timeStr += rtc.monthNameString(currentTime);
        	timeStr += " ";
        	timeStr += rtc.dayString(currentTime);
        	timeStr += ", ";
        	timeStr += rtc.yearString(currentTime);
        	Particle.publish("info", timeStr);
        } else if (sec == 40) {
    	    // Including current timezone
    	    Particle.publish("info", rtc.ISODateString(currentTime));
    	    //Serial.println(rtc.ISODateString(currentTime));
        } else {
        	// Just the time in 12 hour format
        	timeStr = "";
        	timeStr += rtc.hour12String(currentTime);
        	timeStr += ":";
        	timeStr += rtc.minuteString(currentTime);
        	timeStr += ":";
        	timeStr += rtc.secondString(currentTime);
        	timeStr += " ";
        	timeStr += rtc.AMPMString(currentTime);
        	Particle.publish("info", timeStr);
        }
        lastTime = currentTime;
    }
}

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


Update Titan16_3DOF.ino

Update Titan16_3DOF.ino

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


Expand colour bar test from Ucg Graphicstest

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


Temperature

Temperature

/**
  Temperature

  The circuit:
  - GND to one end of a 10K resistor(Brown - Black - Orange - Gold)
  - One leg of the thermistor (temperature sensor) to the other end of the resistor
  - 3V3 to the other leg of the thermistor
  - A0 to the point where the thermistor & resitor are connected

   (GND) ---- (10k-Resistor) -------|------- (Thermistor) ---- (3V3)
                                    |
                               Analog Pin A0

  An image & more info on the setup is at
  https://github.com/theapi/denbit/blob/master/docs/examples/Sensors/Temperature.md

  To see the serial monitor, click the magnifiying class icon in the top right.
  The serial monitor needs to be listening at "115200 baud",
  so set the value in the bottom left to 115200 baud.
  If the wrong value is set, only gibberish will appear on the monitor.

  Graphical representation is available using serial plotter (Tools > Serial Plotter menu)

*/

// Include the Denbit library.
#include <Denbit.h>
// Initialize the denbit.
Denbit denbit;

/**
 * The setup function runs once when you press reset.
 */
void setup() {
  // initialize serial communication at 115200 bits per second:
  Serial.begin(115200);
}

/**
 * Do a bunch of mathmatics on the voltage reading from the sensor.
 *
 * @see http://playground.arduino.cc/ComponentLib/Thermistor2
 */
double thermistor(int raw_adc) {
 double temp;
 temp = log(10000.0 * ((1024.0/raw_adc-1)));
 temp = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * temp * temp ))* temp );
 temp = temp - 273.15;            // Convert Kelvin to Celcius

 return temp;
}

/**
 * The loop function runs over and over again forever.
 */
void loop() {
  // Read the input on analog A0 pin
  // and store it in a variable that is large enough to hold it
  double temperature = thermistor(analogRead(A0));

  // print out the value you read:
  Serial.println(temperature);
  delay(100);        // delay in between reads for stability
}

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


New tutorial for UDP Send and Receive added

/*
  UDPSendReceive.pde:
 This sketch receives UDP message strings, prints them to the serial port
 and sends an "acknowledge" string back to the sender

 A Processing sketch is included at the end of file that can be used to send
 and received messages for testing with a computer.

 created 21 Aug 2010
 by Michael Margolis

 Modified 10 Jan 2014
 by Luis David Lopez-Roberts

 This code is in the public domain.
 */

#include <SPI.h>         // needed for Arduino versions later than 0018
#include <Ethernet.h>
#include <EthernetUdp.h>         // UDP library from: bjoern@cs.stanford.edu 12/30/2008

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:

byte mac[] = {0x90, 0xA2, 0xDA, 0x0D, 0x6F, 0xA8 }; //Put MAC address of your Ethernet Board
IPAddress ip(192, 168, 1, 56); //This IP Address will be assigned if DHCP fails (IMPORTANT, you must put an IP within your network's range)
unsigned int localPort = 8888;      // local port to listen on

// buffers for receiving and sending data
char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet,
char  ReplyBuffer[] = "acknowledged";       // a string to send back

// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;

/*This function cleans the receiver buffer*/
void cleanRxBuffer() {
 for (int i = 0; i < UDP_TX_PACKET_MAX_SIZE; i++) {
  packetBuffer[i]=0x00;
 }
}

/*This function shows, via Serial Monitor, the local IP Address*/
void printLocalIp() {
  Serial.print("My IP address: ");
  for (byte thisByte = 0; thisByte < 4; thisByte++) {
    // print the value of each byte of the IP address:
    Serial.print(Ethernet.localIP()[thisByte], DEC);
    Serial.print(".");
  }
  Serial.println();
}

void setLocalIp() {
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP; assigning fixed IP");
    Ethernet.begin(mac,ip);
    // no point in carrying on, so do nothing forevermore:
    for(;;)
      ;
  }
}

void setup() {
  // start the Ethernet and UDP:
  //Ethernet.begin(mac,ip);
  // start the Ethernet connection:
  setLocalIp();

  Udp.begin(localPort);

  Serial.begin(115200);
}

void loop() {
  // if there's data available, read a packet
  int packetSize = Udp.parsePacket();

  if(packetSize)
  {
    // We show, via Serial Monitor, the remote IP and UDP port
    Serial.print("Received packet of size ");
    Serial.println(packetSize);
    Serial.print("From ");
    IPAddress remote = Udp.remoteIP();
    for (int i =0; i < 4; i++)
    {
      Serial.print(remote[i], DEC);
      if (i < 3)
      {
        Serial.print(".");
      }
    }
    Serial.print(", port ");
    Serial.println(Udp.remotePort());

    // read the packet into packetBufffer
    Udp.read(packetBuffer,UDP_TX_PACKET_MAX_SIZE);
    Serial.print("Contents: \"");
    Serial.print(packetBuffer);
    Serial.println("\"");
    cleanRxBuffer();

    // send a reply, to the IP address and port that sent us the packet we received
    //delay(500); //If needed, put a small delay before sending reply

    Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
    Udp.write(ReplyBuffer);
    Udp.endPacket();
  }

  // We show periodically, via Serial Monitor, the local IP Address (each 2 seconds).
  printLocalIp();
  delay(2000);

}

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


Added a comment

Added a 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/PhantomGrazzler/02-Single-DOF-Platform.git/'


코드 업로드 (개발 버전)

코드 업로드 (개발 버전)

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <Servo.h>

Servo myservo;
Servo myservo2;
ESP8266WebServer server(80);
String url = "https://raw.githubusercontent.com/SkyLightQP/RemotePetFood/master/index.html";

void setup() {
 // put your setup code here, to run once:
  Serial.begin(115200);
  myservo.attach(4); // D2
  myservo2.attach(5); // D1
  // 연결 완료 까지 대기
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(WiFi.SSID());
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  if (MDNS.begin("esp8266")) {
    Serial.println("MDNS responder started");
  }

  //접속별 동작 설정
  server.on("/", [](){
    sendHtml(url);
  });
  server.on("/open1", [](){
    myservo.write(160);
    sendHtml(url);
  });
  server.on("/close1", [](){
    myservo.write(130);
    sendHtml(url);
  });
  server.on("/auto1", [](){
    myservo.write(160);
    delay(600);
    myservo.write(130);
    sendHtml(url);
  });
   server.on("/open2", [](){
    myservo2.write(160);
    sendHtml(url);
  });
  server.on("/close2", [](){
    myservo2.write(130);
    sendHtml(url);
  });
  server.on("/auto2", [](){
    myservo2.write(160);
    delay(600);
    myservo2.write(130);
    sendHtml(url);
  });
  //서버 사용을 시작합니다.
  server.begin();
  Serial.println("HTTP server started");
}

void loop(void){
  server.handleClient();//클라이언트 접속을 관리합니다.
}

void sendHtml(String url){
  String html = "";
  html += "";
  html += "

";
  html += "";
   server.send(200, "text/html", html);
}

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


Create blend_into_rainbow.ino

Create blend_into_rainbow.ino

//***************************************************************
// Messing with blending a moving cycling color into a moving
// background rainbow.
//
// Marc Miller, Sept 2019
//***************************************************************

#include "FastLED.h"
#define DATA_PIN    11
#define CLK_PIN     13
#define LED_TYPE    LPD8806
#define COLOR_ORDER GRB
#define NUM_LEDS    32
#define BRIGHTNESS  255
CRGB leds[NUM_LEDS];

uint8_t pos;  //stores a position for color being blended in
uint8_t hue, hue2;  //stores a color

//---------------------------------------------------------------
void setup() {
  Serial.begin(115200);  // Allows serial monitor output (check baud rate)
  delay(2500); // 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);
  Serial.println("Setup done. \n");
}

//---------------------------------------------------------------
void loop() {
  EVERY_N_MILLISECONDS(60){
    hue++;  //used to cycle through the rainbow
  }

  fill_rainbow(leds, NUM_LEDS, hue, 255/NUM_LEDS/4);  //draw part of the rainbow into the strip
  fadeToBlackBy(leds, NUM_LEDS, 70);  //fade the whole strip down some

  EVERY_N_MILLISECONDS(150) {
    pos++;
    if (pos == NUM_LEDS) { pos = 0; }  //reset to begining
  }

  EVERY_N_MILLISECONDS(5){
    hue2 = hue2 - 1;  //used to change the moving color
  }
  CRGB blendThisIn  = CHSV(hue2, 140, 255);  //color to blend into the background
  CRGB blendThisIn2 = CHSV(hue2, 170, 255);  //color to blend into the background
  CRGB blendThisIn3 = CHSV(hue2, 210, 255);  //color to blend into the background
  CRGB blendThisIn4 = CHSV(hue2, 255, 255);  //color to blend into the background

  static uint8_t blendAmount = 240;  //amount of blend  [range: 0-255]

  leds[pos]                  = nblend(leds[pos],                  blendThisIn4, blendAmount/3);
  leds[mod8(pos+1,NUM_LEDS)] = nblend(leds[mod8(pos+1,NUM_LEDS)], blendThisIn3, blendAmount/2);
  leds[mod8(pos+2,NUM_LEDS)] = nblend(leds[mod8(pos+2,NUM_LEDS)], blendThisIn2, blendAmount);
  leds[mod8(pos+3,NUM_LEDS)] = nblend(leds[mod8(pos+3,NUM_LEDS)], blendThisIn,  blendAmount);
  leds[mod8(pos+4,NUM_LEDS)] = nblend(leds[mod8(pos+4,NUM_LEDS)], blendThisIn2, blendAmount);
  leds[mod8(pos+5,NUM_LEDS)] = nblend(leds[mod8(pos+5,NUM_LEDS)], blendThisIn3, blendAmount/2);
  leds[mod8(pos+6,NUM_LEDS)] = nblend(leds[mod8(pos+6,NUM_LEDS)], blendThisIn4, blendAmount/3);

  FastLED.show();  //update the display

  EVERY_N_SECONDS(random8(5,21)) {
    delay(3000);  //randomly stop the animation to observe the blending
  }

}//end_main_loop

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


minor changes to BarGraph Arduino

minor changes to BarGraph Arduino

error: pathspec 'Action' did not match any file(s) known to git
error: pathspec 'Modules/Bar' did not match any file(s) known to git
error: pathspec 'Graph/BarGraphArduino/BarGraphArduino.ino' did not match any file(s) known to git


mfrc522

// pro pins
// SPI: 10 (SS), 11 (MOSI), 12 (MISO), 13 (SCK).

/*
 * ----------------------------------------------------------------------------
 * This is a MFRC522 library example; see https://github.com/miguelbalboa/rfid
 * for further details and other examples.
 *
 * NOTE: The library file MFRC522.h has a lot of useful info. Please read it.
 *
 * Released into the public domain.
 * ----------------------------------------------------------------------------
 * Example sketch/program showing how to read data from a PICC (that is: a RFID
 * Tag or Card) using a MFRC522 based RFID Reader on the Arduino SPI interface.
 *
 * When the Arduino and the MFRC522 module are connected (see the pin layout
 * below), load this sketch into Arduino IDE then verify/compile and upload it.
 * To see the output: use Tools, Serial Monitor of the IDE (hit Ctrl+Shft+M).
 * When you present a PICC (that is: a RFID Tag or Card) at reading distance
 * of the MFRC522 Reader/PCD, the serial output will show the ID/UID, type and
 * any data blocks it can read. Note: you may see "Timeout in communication"
 * messages when removing the PICC from reading distance too early.
 *
 * If your reader supports it, this sketch/program will read all the PICCs
 * presented (that is: multiple tag reading). So if you stack two or more
 * PICCs on top of each other and present them to the reader, it will first
 * output all details of the first and then the next PICC. Note that this
 * may take some time as all data blocks are dumped, so keep the PICCs at
 * reading distance until complete.
 *
 * Typical pin layout used:
 * -----------------------------------------------------------------------------------------
 *             MFRC522      Arduino       Arduino   Arduino    Arduino          Arduino
 *             Reader/PCD   Uno           Mega      Nano v3    Leonardo/Micro   Pro Micro
 * Signal      Pin          Pin           Pin       Pin        Pin              Pin
 * -----------------------------------------------------------------------------------------
 * RST/Reset   RST          9             5         D9         RESET/ICSP-5     RST
 * SPI SS      SDA(SS)      10            53        D10        10               10
 * SPI MOSI    MOSI         11 / ICSP-4   51        D11        ICSP-4           16
 * SPI MISO    MISO         12 / ICSP-1   50        D12        ICSP-1           14
 * SPI SCK     SCK          13 / ICSP-3   52        D13        ICSP-3           15
 */

// pro pins
// SPI: 10 (SS), 11 (MOSI), 12 (MISO), 13 (SCK).

/* wiring the MFRC522 to ESP8266 (ESP-12)
RST     = GPIO15
SDA(SS) = GPIO2
MOSI    = GPIO13
MISO    = GPIO12
SCK     = GPIO14
GND     = GND
3.3V    = 3.3V
*/

#include <ESP8266WiFi.h>
#include <SPI.h>
#include <MFRC522.h>

#define RST_PIN   15   //
#define SS_PIN    2    //

MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance

void setup() {
  Serial.begin(115200);   // Initialize serial communications with the PC
  while (!Serial);    // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
  SPI.begin();      // Init SPI bus
  mfrc522.PCD_Init();   // Init MFRC522
  ShowReaderDetails();  // Show details of PCD - MFRC522 Card Reader details
  Serial.println(F("Scan PICC to see UID, type, and data blocks..."));
}

void loop() {
  // Look for new cards
  if ( ! mfrc522.PICC_IsNewCardPresent()) {
    return;
  }

  // Select one of the cards
  if ( ! mfrc522.PICC_ReadCardSerial()) {
    return;
  }

  // Dump debug info about the card; PICC_HaltA() is automatically called
  mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
}

void ShowReaderDetails() {
  // Get the MFRC522 software version
  byte v = mfrc522.PCD_ReadRegister(mfrc522.VersionReg);
  Serial.print(F("MFRC522 Software Version: 0x"));
  Serial.print(v, HEX);
  if (v == 0x91)
    Serial.print(F(" = v1.0"));
  else if (v == 0x92)
    Serial.print(F(" = v2.0"));
  else
    Serial.print(F(" (unknown)"));
  Serial.println("");
  // When 0x00 or 0xFF is returned, communication probably failed
  if ((v == 0x00) || (v == 0xFF)) {
    Serial.println(F("WARNING: Communication failure, is the MFRC522 properly connected?"));
  }
}

error: pathspec '_13-mfrc522-esp8266/_13-mfrc522-esp8266.ino' did not match any file(s) known to git


poc claper

poc claper

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/dave-ausbone/TJU-SST.git/'


New Device ID method with init

New Device ID method with init

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/Countly/countly-sdk-iot-cpp.git/'


Added NanoEngine example with AdafruitGFX usage

/*
    MIT License

    Copyright (c) 2018, Alexey Dynda

    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"), to deal
    in the Software without restriction, including without limitation the rights
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included in all
    copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    SOFTWARE.
*/
/**
 *   Attiny85 PINS
 *             ____
 *   RESET   -|_|  |- 3V
 *   SCL (3) -|    |- (2)
 *   SDA (4) -|    |- (1)
 *   GND     -|____|- (0)
 *
 *   Atmega328 PINS: connect LCD to A4/A5
 */

// Define this before including library header, this will give Adafruit GFX support
// !!! Don't forget to install AdafruitGFX library to your Arduino IDE !!!
#define CONFIG_ADAFRUIT_GFX_ENABLE

#include "ssd1306.h"
#include "nano_engine.h"

// No need to include this for Arduino sketch
#ifndef ARDUINO
extern "C" void __cxa_pure_virtual() { while (1); }
#endif

/*
 * Heart image below is defined directly in flash memory.
 * This reduces SRAM consumption.
 * The image is define from left to rigth (bits), from top to
 * bottom (bytes). Unlike NanoCanvas1 of ssd1306 library, Adafruit
 * GFX implementation uses different aproach for images, stored in Flash.
 */
const PROGMEM uint8_t heartImage[8] =
{
    0B01100110,
    0B11111001,
    0B11111101,
    0B11111111,
    0B01111110,
    0B00111100,
    0B00011000,
    0B00000000
};

/*
 * Define sprite width. The width can be of any size.
 * But sprite height is always assumed to be 8 pixels
 * (number of bits in single byte).
 */
const int spriteWidth = sizeof(heartImage);

/* We use 8-pixels height sprites */
const int spriteHeight = 8;

/* Lets show 4 hearts on the display */
const int spritesCount = 4;

/* Declare variable that represents our 4 objects */
struct
{
    NanoPoint pos;
    NanoPoint speed;
} objects[ spritesCount ];

/* Create engine object */
NanoEngine<ADATILE_8x8_RGB8> engine;

/* Array of colors, used for the heart sprites */
static uint8_t s_colors[spritesCount] =
{
     RGB_COLOR8(255,0,0),
     RGB_COLOR8(0,255,0),
     RGB_COLOR8(0,0,255),
     RGB_COLOR8(255,255,0),
};

/*
 * This function is called by the engine every time, it needs to refresh
 * some part of the display. Just draw the content as usual. NanoCanvas
 * will do correct clipping for you.
 */
bool drawHearts()
{
    /* Clear canvas surface */
    engine.canvas.fillScreen(0);
    /* Draw line */
    engine.canvas.drawLine( 0, 0, ssd1306_displayWidth()*2 - 1, ssd1306_displayHeight()-1, RGB_COLOR8(128,128,128));
    /* Draw rectangle around our canvas. It will show the range of the canvas on the display */
    engine.canvas.drawRect(0, 0, ssd1306_displayWidth(), ssd1306_displayHeight(), RGB_COLOR8(0,255,255));
    /* Draw all 4 sprites on the canvas */
    for (uint8_t i = 0; i < spritesCount; i++)
    {
        engine.canvas.drawBitmap( objects[i].pos.x, objects[i].pos.y, heartImage, 8, 8, s_colors[i] );
    }
    /* Now, return true to draw canvas on the display. *
     * If you return false, the part of display will not be refreshed */
    return true;
}

void setup()
{
    /* Initialize and clear display: 3 RST, 4 CES, 5 DS */
    il9163_128x128_spi_init(3, 4, 5);
//    ssd1331_96x64_spi_init(3, 4, 5);
//    ssd1351_128x128_spi_init(3, 4, 5);
//    st7735_128x160_spi_init(3, 4, 5);
//    -- ssd1306_128x64_i2c_init();  // RGB canvas does not support monochrome displays
//    -- pcd8544_84x48_spi_init(3, 4, 5);

    /* Start the engine. It will switch display to required mode */
    engine.begin();

    /* Set frame refresh rate: 45 is ok for the eye */
    engine.setFrameRate(45);

    /* Make the engine to redraw whole display content when the board is powered on. *
     * refresh() function do not change display content, but says notifies engine that *
     * it needs to refresh() whole screen on next frame. */
    engine.refresh();

    /* Create 4 "hearts", and place them at different positions and give different movement direction */
    for(uint8_t i = 0; i < spritesCount; i++)
    {
        objects[i].speed = { .x = (i & 2) ? -1:  1, .y = (i & 1) ? -1:  1 };
        objects[i].pos = { .x = i*16, .y = i*8 + 2 };
    }

    /* Here we set draw callback, so the engine will call it every time it needs *
     * physically update display content */
    engine.drawCallback( drawHearts );
}

void loop()
{
    /* If it is not time to draw next frame just exit and do nothing */
    if (!engine.nextFrame()) return;

    /* Recalculate position and movement direction of all 4 "hearts" */
    for (uint8_t i = 0; i < spritesCount; i++)
    {
        /* We need to point the old position of the heart sprite */
        engine.refresh( objects[i].pos.x, objects[i].pos.y,
                        objects[i].pos.x + spriteWidth - 1,
                        objects[i].pos.y + spriteHeight - 1 );
        objects[i].pos += objects[i].speed;
        /* If left or right boundary is reached, reverse X direction */
        if ((objects[i].pos.x == (ssd1306_displayWidth() - 8)) || (objects[i].pos.x == 0))
            objects[i].speed.x = -objects[i].speed.x;
        /* Sprite height is always 8 pixels. Reverse Y direction if bottom or top boundary is reached. */
        if ((objects[i].pos.y == (ssd1306_displayHeight() - 8)) || (objects[i].pos.y == 0))
            objects[i].speed.y = -objects[i].speed.y;
        /* Now provide the new position of the heart sprite to engine */
        engine.refresh( objects[i].pos.x, objects[i].pos.y,
                        objects[i].pos.x + spriteWidth - 1,
                        objects[i].pos.y + spriteHeight - 1 );
    }
    /* Now do updates on the display */
    engine.display();
}

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


Push the button if you're a skittle

Push the button if you're a skittle

/*Button
 * LED attached from pin 13 to ground
 * pushbutton attached to pin 2 from +5V
 * 10K resistor attached to pin 2 from ground
 */

const int buttonPin = 2;
const int ledPin =  13;
int buttonState = 0;         // variable for reading pushbutton status

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT);
}

void loop() {
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);

  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  if (buttonState == HIGH) {
    // LED on:
    digitalWrite(ledPin, HIGH);
  } else {
    // LED off:
    digitalWrite(ledPin, LOW);
  }
}

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


Testing api call from arduino uno

Testing api call from arduino uno

error: pathspec 'Documentation/unit' did not match any file(s) known to git
error: pathspec 'tests/ciao_test/ciao_test.ino' did not match any file(s) known to git


Create meross-to-remote.ino

Create meross-to-remote.ino

// INPUT
#define REED_SENSOR_PIN 14
#define HKIT_CMD_PIN 10
#define HKIT_GND_PIN 16

// OUTPUT
#define AWNING_OPEN_CMD_PIN 8
#define AWNING_CLOSE_CMD_PIN 9

bool AWNING_REEDS_STATUS;

unsigned long DURATION;

void setup() {
  pinMode(REED_SENSOR_PIN, INPUT);
  pinMode(HKIT_CMD_PIN, INPUT_PULLUP);
  pinMode(HKIT_GND_PIN, OUTPUT);

  pinMode(AWNING_OPEN_CMD_PIN, OUTPUT);
  pinMode(AWNING_CLOSE_CMD_PIN, OUTPUT);

  digitalWrite(HKIT_GND_PIN, LOW);
  digitalWrite(AWNING_OPEN_CMD_PIN, LOW);
  digitalWrite(AWNING_CLOSE_CMD_PIN, LOW);
}

void loop() {
  DURATION = pulseIn(HKIT_CMD_PIN, LOW, 1000000000);
  if ( DURATION > 10 ) {
    AWNING_REEDS_STATUS = digitalRead(REED_SENSOR_PIN);
    if(AWNING_REEDS_STATUS) { // CLOSED STATUS --> OPEN
      digitalWrite(AWNING_OPEN_CMD_PIN, HIGH);
      delay(500);
      digitalWrite(AWNING_OPEN_CMD_PIN, LOW);
      Serial.println("CMD IN, OPENNING AWNING");
    } else {
      digitalWrite(AWNING_CLOSE_CMD_PIN, HIGH);
      delay(500);
      digitalWrite(AWNING_CLOSE_CMD_PIN, LOW);
      Serial.println("CMD IN, CLOSING AWNING");
    }
  }
}

error: pathspec '_86-meross-garage-to-remote/meross-to-remote.ino' did not match any file(s) known to git


RF12_printSerial_Vcc_T - first working version

//
// Receive packets from JNu Temperature node
// Print Vcc, Temperature

#include <JeeLib.h>

float Vcc, T;

void setup () {
    Serial.begin(57600);
    Serial.println(57600);
    Serial.println("Receive");
    rf12_initialize(1, RF12_868MHZ, 33);
}

void loop () {
    if (rf12_recvDone() && rf12_crc == 0) {
        for (byte i = 0; i < rf12_len; ++i) {
            Serial.print(rf12_data[i]);
            Serial.print(' ');
            }
        Serial.println();

        Vcc = (rf12_data[0] + 256 * rf12_data[1])/100.0;
        T = (rf12_data[2] + 256 * rf12_data[3])/100.0;
        Serial.println(Vcc);
        Serial.println(T);
        Serial.println();
    }

        delay(4000); // otherwise led blinking isn't visible
}

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


fix inconsistency issue for time to stay in setup mode before automatically moving to ACTIVE mode. Also did some code cleanup

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/JulioOrdonezV/pvcloud.git/'


Versioning Whack-a-Mole demo

Versioning Whack-a-Mole demo

/*************************************************
 *  WhackAMole.ino                               *
 *  Example from the ArTICL library              *
 *           Created by Timothy Keller,          *
 *           With Christopher Mitchell,          *
 *           2011-2015, all rights reserved.     *
 *                                               *
 *  This demo allows interfacing with a MSP432   *
 *  device designed as a Whack A Mole Board, by  *
 *  emulating a CBL2 Style API.                  *
 *  Pins 2 and 23-30 are connected to CDS cells  *
 *  that act as our "buttons" for this demo.     *
 *                                               *
 *************************************************/

#include <CBL2.h>
#include <TIVar.h>

//#define VERBOSE

CBL2* cbl;
const int lineRed = 4;
const int lineWhite = 3;

#define ANALOG_PIN_COUNT 9
const int analogPins[ANALOG_PIN_COUNT] = {30, 29, 28, 27, 26, 25, 24, 23, 2};

#define RGB_Red 40
#define RGB_Green 39
#define RGB_Blue 38
#define Multiplexer_PIN_COUNT 9
const int multiplexer_pins[Multiplexer_PIN_COUNT] = {37, 36, 35, 34, 33, 32, 31, 11, 12};

#define MAXDATALEN 255
uint8_t header[16];
uint8_t data[MAXDATALEN];

// Set up serial for debugging, and CBL2 for communication
void setup() {
  Serial.begin(9600);
  cbl = new CBL2(lineRed, lineWhite);
  cbl->resetLines();
#ifdef VERBOSE
  cbl->setVerbosity(true, &Serial);  // Comment this in for message information
#endif
  cbl->setupCallbacks(header, data, MAXDATALEN,
                      onGetAsCBL2, onSendAsCBL2);
}

// Main loop: Let CBL2 event handler do the work
void loop() {
  int rval;
  rval = cbl->eventLoopTick();
  if (rval && rval != ERR_READ_TIMEOUT) {
    Serial.print("Failed to run eventLoopTick: code ");
    Serial.println(rval);
  }

}

// Takes Led = LED 1-9
void SetRgbActive(int led){
    turnOffAllRGBLEDs();
    digitalWrite(multiplexer_pins[led - 1], HIGH);

}

void turnOffAllRGBLEDs(){
    for(int i = 0; i < Multiplexer_PIN_COUNT; i++) {
        digitalWrite(multiplexer_pins[i], LOW);
    }
}

int onGetAsCBL2(uint8_t type, enum Endpoint model, int datalen) {
#ifdef VERBOSE
  Serial.print("Got variable of type ");
  Serial.print(type);
  Serial.print(" from endpoint of type ");
  Serial.println((int)model);
#endif

  if (type != 0x5D) { //VarTypes82::VarRList) ???
    return -1;  //If you are not a list we do not want you ABORT
  }
  int list_len = data[0] | (data[1] << 8);
  switch(list_len) {
    case 1:{  //If we are a control structure
        int value = (int)TIVar::realToFloat8x(&data[2], model);  // Get element
        switch(value){
            case 0:{  // Turns off all LEDS
#ifdef VERBOSE
                Serial.println("Turning off all LEDs");
#endif
                turnOffAllRGBLEDs();
                return 0;
            }
            case 10:  // Unimplemented yet. But room to grow for single commands is here.
            case 11:  //
            default:
                return -1;
        }
    }
    case 4:{  // RGB Control structure
             // {N,R,G,B} Where N is LED and RGB=Analog Values for each color

        turnOffAllRGBLEDs();  //First we turn off the multiplexer

        int Offset = 2;  //Start us after the size bytes
        int NewLed = (int)TIVar::realToFloat8x(&data[Offset], model);  // Get element

        Offset += TIVar::sizeOfReal(model);
        int val_red = (int)TIVar::realToFloat8x(&data[Offset], model);
        Offset += TIVar::sizeOfReal(model);
        int val_green = (int)TIVar::realToFloat8x(&data[Offset], model);
        Offset += TIVar::sizeOfReal(model);
        int val_blue = (int)TIVar::realToFloat8x(&data[Offset], model);

#ifdef VERBOSE
        Serial.print("Setting LED ");
        Serial.print(NewLed);
        Serial.print(" to color (");
        Serial.print(val_red);
        Serial.print(',');
        Serial.print(val_green);
        Serial.print(',');
        Serial.print(val_blue);
        Serial.println(")");
#endif
        // I don't know why this is inverted. It works.
        analogWrite(RGB_Red, 255 - val_red);
        analogWrite(RGB_Green, 255 - val_green);
        analogWrite(RGB_Blue, 255 - val_blue);

        SetRgbActive(NewLed);  //Turn on the new LED
        return 0;
    }
    default:{  // Gotta Catch Em All!
        return -1;
    }
  }

  return -1;
}

int onSendAsCBL2(uint8_t type, enum Endpoint model, int* headerlen,
                 int* datalen, data_callback* data_callback)
{
  Serial.print("Got request for variable of type ");
  Serial.print(type);
  Serial.print(" from endpoint of type ");
  Serial.println((int)model);

  if (type != VarTypes82::VarRList)
    return -1; //If we are not a list we do not want you ABORT

     // Compose the VAR header
  *datalen = 2 + TIVar::sizeOfReal(model) * ANALOG_PIN_COUNT;
  TIVar::intToSizeWord(*datalen, &header[0]);	// Two bytes for the element count, ANALOG_PIN_COUNT Reals
                                                // This sets header[0] and header[1]
  header[2] = 0x04;				// RealList (if you're a TI-85. Bleh.)
  header[3] = 0x01;				// Name length
  header[4] = 0x41;				// "A", as per "standard" See http://www.cemetech.net/forum/viewtopic.php?p=224739#224739
  header[5] = 0x00;				// Zero terminator (remainder of header is ignored)
  *headerlen = 11;

  // Compose the body of the variable
  data[0] = ANALOG_PIN_COUNT;
  data[1] = 0;
  int offset = 2;
  for(int i = 0; i < ANALOG_PIN_COUNT; i++) {
	long value = analogRead(analogPins[i]);
	// Convert the value, get the length of the inserted data or -1 for failure
	int rval = TIVar::longToReal8x(value, &data[offset], model);
	if (rval < 0) {
		return -1;
	}
	offset += rval;
  }
  for(int i = 0; i < *datalen; i++) {
    Serial.print(data[i], HEX);
	Serial.print(" ");
  }
  Serial.println("]]");

  return 0;
}

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


Create dragino_sensor-act_mqtt.ino

Create dragino_sensor-act_mqtt.ino

#include <Process.h>
#include "MQTTclient.h"
#include "DHT.h"
#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS_PIN 3
float  tempC2 = 0;
float  tempC3 = 0;

OneWire oneWire(ONE_WIRE_BUS_PIN);
DallasTemperature sensors(&oneWire);
DeviceAddress probe01 =  {0x28, 0xC7, 0xEB, 0xF0, 0x05, 0x00, 0x00, 0xEA};
DeviceAddress probe02 =  {0x28, 0x82, 0x2F, 0xF1, 0x05, 0x00, 0x00, 0xC6};

#define MQTT_HOST "190.97.168.236"
#define DHTPIN A0

#define DHTTYPE DHT22   // DHT 22  (AM2302)
DHT dht(DHTPIN, DHTTYPE);
//DHT dht2(DHTPIN2, DHTTYPE);

char message_buff[100];
char message_buff2[100];
String id_sensor = "sensor1";
String id_sensor2 = "sensor2";
int led = 4;
//int led2 = 3 ;
int led3 = 2;
unsigned long time;
float t2;

void setup() {

  Serial.begin(9600);
  Bridge.begin();
  mqtt.begin(MQTT_HOST, 1883);
  dht.begin();
  //dht2.begin();
  sensors.begin();
  sensors.setResolution(probe01, 10);
    sensors.setResolution(probe02, 10);
  pinMode(led, OUTPUT);
 // pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);

  mqtt.subscribe("test/uno", someEvent);

}

/*void printTemperature(DeviceAddress deviceAddress)
{

float tempC = sensors.getTempC(deviceAddress);

   if (tempC == -127.00)
   {
   Serial.print("Error getting temperature  ");
   }
   else
   {
   Serial.print("C: ");
   Serial.print(tempC);
   Serial.print(" F: ");
   Serial.print(DallasTemperature::toFahrenheit(tempC));
   }
}

*/

void loop() {
  float h = dht.readHumidity();
  float t = dht.readTemperature();

 // float h2 = dht2.readHumidity();
  //float t2 = dht2.readTemperature();

 sensors.requestTemperatures();
 tempC2 = sensors.getTempC(probe01);
  tempC3 = sensors.getTempC(probe02);

   if (millis() > (time + 30000)) {
       time = millis();

  String pubString = "" + String(t) + " ," + String(h) + " ," + id_sensor + "" ;
   pubString.toCharArray(message_buff, pubString.length()+1);

   String pubString2= "" + String(tempC2) + " ," + String(tempC3) + " ," + id_sensor2 + "" ;
    pubString2.toCharArray(message_buff2, pubString2.length()+1);

       mqtt.publish("test/temp",message_buff );
       mqtt.publish("test/temp",message_buff2 );

   }
   else{

  mqtt.monitor();
   }
}

void someEvent(const String& topic, const String& subtopic, const String& message) {

  Serial.print("topic: ");
  Serial.println(topic);
  Serial.print("message: ");
  Serial.println(message);

  //int integer = 25;
 // String integer = hola;

  mqtt.publish("test/dos", "Recibido_Control_D1");
   if (message == "s3up") {
    digitalWrite(led, HIGH);

  } //else if (message == "s2up"){
    //digitalWrite(led2, HIGH);

  //}
  else if (message == "s3down"){
    digitalWrite(led, LOW);

  } //else if (message == "s2down"){
    //digitalWrite(led2, LOW);

 // }
 else if (message == "s21up"){
    digitalWrite(led3, HIGH);

  }  else if (message == "s21down"){
    digitalWrite(led3, LOW);

  }

}

error: pathspec 'dragino/dragino_sensor-act_mqtt.ino' did not match any file(s) known to git


created students dir, added example morse code reader to students/lesson-2

int buttonPin = 4;

int ledPin_R = 13;
int ledPin_G = 12;
int ledPin_B = 11;
int t1 = 0;
int t2 = 0;
String message = "";

int currentPinMode = 2;
int pressLag = 0;

/* debounce variables */
int buttonState;             // the current reading from the input pin
int lastButtonState = LOW;   // the previous reading from the input pin
// the following variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long lastDebounceTime = 0;  // the last time the output pin was toggled
long debounceDelay = 50;    // the debounce time; increase if the output flickers

void setup() {
  // set pin 4 for input, pin 11-13 for output
  Serial.begin(9600);
  pinMode(buttonPin, INPUT);
  pinMode(ledPin_R, OUTPUT);
  pinMode(ledPin_G, OUTPUT);
  pinMode(ledPin_B, OUTPUT);

  // turn off all those LEDs by setting them HIGH
  digitalWrite(ledPin_R, HIGH);
  digitalWrite(ledPin_G, HIGH);
  digitalWrite(ledPin_B, HIGH);
}

void loop() {
  // read input
  int reading = digitalRead(buttonPin);

// If the switch changed, due to noise or pressing:
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

  // only execute this code if the button has held steady for `debounceDelay` milliseconds
  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer
    // than the debounce delay, so take it as the actual current state:

    // if the button state has changed:
    if (reading != buttonState) {
      buttonState = reading;
      if (buttonState == LOW) {
        //OK, now that everything is debounced, we know that the button has really been pressed
        //when button is pressed, record current time in t1
        t1 = millis();
      }

      if (buttonState == HIGH){
        //when button is released, record current time in t2. t2-t1 = the time the button was depressed for
        t2 = millis();
        if( (t2 - t1) <= 300 ){
          //this is the morse code part, define a press under 300 ms as "short" (could fiddle w/ this, or find actual
          //military best practices, this decision was pretty arbitrary, based on trial and error)
          message += '.';
        }

        else if( (t2 - t1) > 300){
          //otherwise, if button is depressed more than 300 ms, record it as "long"
          message += '-';
        }
        //print the current morse code message to Serial (Tools > Serial Monitor to view this output)
        Serial.println(message)

          if( (contains(message,"...---...")) == 1){
            //every loop, check the message to see if it contains 'SOS' in morse code, any
            //where within the message (see below for the contains() method
            //If it does, turn the led to red
            currentPinMode = 0;
            Serial.println(currentPinMode);
          }

      }
    }
  }

  switch (currentPinMode) {
    case 0: // red
      digitalWrite(ledPin_R, LOW);
      digitalWrite(ledPin_G, HIGH);
      digitalWrite(ledPin_B, HIGH);
      break;

    case 1: // green
      digitalWrite(ledPin_R, HIGH);
      digitalWrite(ledPin_G, LOW);
      digitalWrite(ledPin_B, HIGH);
      break;

    case 2: // blue
      digitalWrite(ledPin_R, HIGH);
      digitalWrite(ledPin_G, HIGH);
      digitalWrite(ledPin_B, LOW);
      break;
  }

  // save the reading.  Next time through the loop,
  // it'll be the lastButtonState:
  lastButtonState = reading;
}

bool contains(String s, String search) {
  //a bit of a wonky method, the `substring()` method needs to know exactly where to look for
  //the substring. So, this loop iterates through the whole message, looking at chunks of characters as long as
  //the substring (in this case, "...---..."), and seeing if there's a match
    int max = s.length() - search.length();

    for (int i = 0; i <= max; i++) {
        if (s.substring(i) == search) return true; // or i
    }

    return false; //or -1
}

error: pathspec 'students/lesson-2/chartoff_morse_code.ino' did not match any file(s) known to git


Addind first test without usb shield

Addind first test without usb shield

#include <IRremote.h>

int RECV_PIN = 2;
IRrecv irrecv(RECV_PIN);
decode_results results;
int keys[21] = {0x5D, 0x9D, 0x1D, 0xDD, 0xFD, 0x3D, 0x1F, 0x57, 0x6F, 0x97, 0x67, 0x4F, 0xCF, 0xE7, 0x85, 0xEF, 0xC7, 0xA5, 0xBD, 0xB5, 0xAD};
int to[21] = {0x1A, 0x14, 0x04, 0x1B, 0x16, 0x1D, 0x06, 0x07, 0x08, 0x19, 0x09, 0x15, 0x05, 0x0A, 0x17, 0x11, 0x0B, 0x1C, 0x36, 0x0D, 0x18};

void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
}

void loop() {
  if (irrecv.decode(&results)) {
    if (results.value != 0xFFFFFFFF) {
      Serial.println(results.value, HEX);
      Serial.println(getConvertedKey(results.value), HEX);
    }
    irrecv.resume(); // Receive the next value
  }
}

int getConvertedKey(int val){
  int value = val & 0x0000FF;
  for(int i = 0; i < 21; i++) {
    if(value == keys[i]) {
      return to[i];
    }
  }
  return 0;
}

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


The Example demonstrates how the Arduino Uno board can read a single line from the serialport (ASCII chars) where the line is ended width '\n' (newLine)

#define MAX_RECV_LINE_LENGTH 200

String strIncompleteLine = "";   // a string to hold incoming data
String strInputLine = "";            // a string to the recieved line
boolean bStrComplete = false;    // whether the string is complete

void setup() {
  // initialize serial:
  Serial.begin(9600);
  // reserve MAX_RECV_LENGTH bytes for the inputString:
  strIncompleteLine.reserve(MAX_RECV_LINE_LENGTH);
  strInputLine.reserve(MAX_RECV_LINE_LENGTH);
}

void loop() {
  // print the string when a newline arrives:
  if (bStrComplete) {
    Serial.print(strInputLine);
    // clear the string:
    strInputLine = "";
    bStrComplete = false;
  }
}

/*
  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:
    strIncompleteLine += inChar;
    // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    if (inChar == '\n') {
      strInputLine=strIncompleteLine;
      bStrComplete = true;
      strIncompleteLine="";
    }
  }
}

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


New Method For Increased Timing

New Method For Increased Timing

//#include <TimerOne.h>
#define RESOLUTION 65536

int period = 20000; // 20 ms
unsigned int pwmPeriod;
unsigned char clockSelectBits;
char oldSREG;
void resume();

void timerSetup(int duty) {
  TCCR1A = 0;                 // clear control register A
  TCCR1B = 0; //_BV(WGM13);        // set mode 8: phase and frequency correct pwm, stop the timer
  TCNT1 = 0x00;
  long cycles = (F_CPU / 1000000) * period;                                      // the counter runs backwards after TOP, interrupt is at BOTTOM so divide microseconds by 2
  if(cycles < RESOLUTION)              clockSelectBits = _BV(CS10);              // no prescale, full xtal
  else if((cycles >>= 3) < RESOLUTION) clockSelectBits = _BV(CS11);              // prescale by /8
  else if((cycles >>= 3) < RESOLUTION) clockSelectBits = _BV(CS11) | _BV(CS10);  // prescale by /64
  else if((cycles >>= 2) < RESOLUTION) clockSelectBits = _BV(CS12);              // prescale by /256
  else if((cycles >>= 2) < RESOLUTION) clockSelectBits = _BV(CS12) | _BV(CS10);  // prescale by /1024
  else        cycles = RESOLUTION - 1, clockSelectBits = _BV(CS12) | _BV(CS10);  // request was out of bounds, set as maximum

  oldSREG = SREG;
  cli();							// Disable interrupts for 16 bit register access
  ICR1 = 0;//pwmPeriod = cycles;                                          // ICR1 is TOP in p & f correct pwm mode
  //OCR1A = 0;  // Set TOP to 0. This effectively keeps us from counting becuase the counter just keeps reseting back to 0.
          // We break out of this by manually setting the TCNT higher than 0, in which case it will count all the way up to MAX and then overflow back to 0 and get locked up again.
  //OCR1B = 512;
  SREG = oldSREG;

  TCCR1A |= _BV(COM1A0) | _BV(COM1A1);// | _BV(WGM10) | _BV(WGM11);                    // activates the output pin
  // OC2B=Set on Match, clear on BOTTOM. Mode 7 Fast PWM.

  TCCR1B &= ~(_BV(CS10) | _BV(CS11) | _BV(CS12));         // Ensure clock mode bits are cleared
  TCCR1B |= _BV(WGM13) | clockSelectBits;                              // Set clock mode / prescaler

  DDRB |= _BV(PORTB1);                                   // sets data direction register for pwm output pin

  //DDRD |= _BV(3);     // Set pin to output (Note that OC2B = GPIO port PD3 = Arduino Digital Pin 3)

  //unsigned long dutyCycle = pwmPeriod;

  //dutyCycle *= duty;
  //dutyCycle >>= 10;

  //Serial.println(dutyCycle);

  oldSREG = SREG;
  cli();
  OCR1B = duty;//dutyCycle;
  SREG = oldSREG;

  TCCR1B |= clockSelectBits;		// Lex - make sure the clock is running.  We don't want to restart the count, in case we are starting the second WGM
					// and the first one is in the middle of a cycle
}

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

void loop() {
  // put your main code here, to run repeatedly:
  //long t1 = micros();
  //while(TCNT1>0){}
  //long t2 = micros();
  long t1 = micros();
  TCNT1=6000;
  while(TCNT1>0);
  //delay(20);
  long t2 = micros();
  Serial.println(t2-t1);
  delay(100);
}

void isr() {
  Serial.println(millis());
}

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


Create forwardbackward.ino

Create forwardbackward.ino

int motorPin = 9;
void setup() {
  pinMode(motorPin, OUTPUT);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
}

void loop() {
  openCage();
  closeCage();
}

//opens cage to deliver drink
void openCage() {
  digitalWrite(motorPin, LOW);
  digitalWrite(2, LOW);   // set leg 1 of the H-bridge low
  digitalWrite(3, HIGH);
  delay(1500);
}

//closes cage after delivery
void closeCage() {
  digitalWrite(motorPin, LOW);
  digitalWrite(3, LOW);   // set leg 1 of the H-bridge low
  digitalWrite(2, HIGH);
  delay(1500);
}

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


Added a Demo program for the Romi, mostly copied from the Zumo 32U4 demo program.

/* This demo program shows many features of the Romi 32U4.

It uses the buttons, LCD, and buzzer to provide a user interface.
It presents a menu to the user that lets the user select from
several different demos.

To use this demo program, you will need to have the LCD connected
to the Romi 32U4.  If you cannot see any text on the LCD,
try rotating the contrast potentiometer. */

#include <Wire.h>
#include <Romi32U4.h>

Romi32U4LCD lcd;
Romi32U4Buzzer buzzer;
Romi32U4ButtonA buttonA;
Romi32U4ButtonB buttonB;
Romi32U4ButtonC buttonC;
LSM6 imu;
LIS3MDL mag;
Romi32U4Motors motors;
Romi32U4Encoders encoders;

char buttonMonitor();

class Menu
{
public:
  struct Item
  {
    const char * name;
    void (* action)();
  };

  Menu(Item * items, uint8_t itemCount)
  {
    this->items = items;
    this->itemCount = itemCount;
    lcdItemIndex = 0;
  }

  void lcdUpdate(uint8_t index)
  {
    lcd.clear();
    lcd.print(items[index].name);
    lcd.gotoXY(0, 1);
    lcd.print(F("\x7f" "A \xa5" "B C\x7e"));
  }

  void action(uint8_t index)
  {
    items[index].action();
  }

  // Prompts the user to choose one of the menu items,
  // then runs it, then returns.
  void select()
  {
    lcdUpdate(lcdItemIndex);

    while (1)
    {
      switch (buttonMonitor())
      {
      case 'A':
        // The A button was pressed so decrement the index.
        if (lcdItemIndex == 0)
        {
          lcdItemIndex = itemCount - 1;
        }
        else
        {
          lcdItemIndex--;
        }
        lcdUpdate(lcdItemIndex);
        break;

      case 'C':
        // The C button was pressed so increase the index.
        if (lcdItemIndex >= itemCount - 1)
        {
          lcdItemIndex = 0;
        }
        else
        {
          lcdItemIndex++;
        }
        lcdUpdate(lcdItemIndex);
        break;

      case 'B':
        // The B button was pressed so run the item and return.
        action(lcdItemIndex);
        return;
      }
    }
  }

private:
  Item * items;
  uint8_t itemCount;
  uint8_t lcdItemIndex;
};

// A couple of simple tunes, stored in program space.
const char beepBrownout[] PROGMEM = "<c32<e32#<g32";
const char beepWelcome[] PROGMEM = ">g32>>c32";
const char beepThankYou[] PROGMEM = ">>c32>g32";
const char beepButtonA[] PROGMEM = "!c32";
const char beepButtonB[] PROGMEM = "!e32";
const char beepButtonC[] PROGMEM = "!g32";

// Custom characters for the LCD:

// This character is a back arrow.
const char backArrow[] PROGMEM = {
  0b00000,
  0b00010,
  0b00001,
  0b00101,
  0b01001,
  0b11110,
  0b01000,
  0b00100,
};

// This character is two chevrons pointing up.
const char forwardArrows[] PROGMEM = {
  0b00000,
  0b00100,
  0b01010,
  0b10001,
  0b00100,
  0b01010,
  0b10001,
  0b00000,
};

// This character is two chevrons pointing down.
const char reverseArrows[] PROGMEM = {
  0b00000,
  0b10001,
  0b01010,
  0b00100,
  0b10001,
  0b01010,
  0b00100,
  0b00000,
};

// This character is two solid arrows pointing up.
const char forwardArrowsSolid[] PROGMEM = {
  0b00000,
  0b00100,
  0b01110,
  0b11111,
  0b00100,
  0b01110,
  0b11111,
  0b00000,
};

// This character is two solid arrows pointing down.
const char reverseArrowsSolid[] PROGMEM = {
  0b00000,
  0b11111,
  0b01110,
  0b00100,
  0b11111,
  0b01110,
  0b00100,
  0b00000,
};

void loadCustomCharacters()
{
  // The LCD supports up to 8 custom characters.  Each character
  // has a number between 0 and 7.  We assign #7 to be the back
  // arrow; other characters are loaded by individual demos as
  // needed.

  lcd.loadCustomCharacter(backArrow, 7);
}

// Assigns #0-6 to be bar graph characters.
void loadCustomCharactersBarGraph()
{
  static const char levels[] PROGMEM = {
    0, 0, 0, 0, 0, 0, 0, 63, 63, 63, 63, 63, 63, 63
  };
  lcd.loadCustomCharacter(levels + 0, 0);  // 1 bar
  lcd.loadCustomCharacter(levels + 1, 1);  // 2 bars
  lcd.loadCustomCharacter(levels + 2, 2);  // 3 bars
  lcd.loadCustomCharacter(levels + 3, 3);  // 4 bars
  lcd.loadCustomCharacter(levels + 4, 4);  // 5 bars
  lcd.loadCustomCharacter(levels + 5, 5);  // 6 bars
  lcd.loadCustomCharacter(levels + 6, 6);  // 7 bars
}

// Assigns #0-4 to be arrow symbols.
void loadCustomCharactersMotorDirs()
{
  lcd.loadCustomCharacter(forwardArrows, 0);
  lcd.loadCustomCharacter(reverseArrows, 1);
  lcd.loadCustomCharacter(forwardArrowsSolid, 2);
  lcd.loadCustomCharacter(reverseArrowsSolid, 3);
}

// Clears the LCD and puts [back_arrow]B on the second line
// to indicate to the user that the B button goes back.
void displayBackArrow()
{
  lcd.clear();
  lcd.gotoXY(0,1);
  lcd.print(F("\7B"));
  lcd.gotoXY(0,0);
}

// Blinks all three LEDs in sequence.
void ledDemo()
{
  displayBackArrow();

  uint8_t state = 3;
  static uint16_t lastUpdateTime = millis() - 2000;
  while (buttonMonitor() != 'B')
  {
    if ((uint16_t)(millis() - lastUpdateTime) >= 500)
    {
      lastUpdateTime = millis();
      state = state + 1;
      if (state >= 4) { state = 0; }

      switch (state)
      {
      case 0:
        buzzer.play("c32");
        lcd.gotoXY(0, 0);
        lcd.print(F("Red   "));
        ledRed(1);
        ledGreen(0);
        ledYellow(0);
        break;

      case 1:
        buzzer.play("e32");
        lcd.gotoXY(0, 0);
        lcd.print(F("Green"));
        ledRed(0);
        ledGreen(1);
        ledYellow(0);
        break;

      case 2:
        buzzer.play("g32");
        lcd.gotoXY(0, 0);
        lcd.print(F("Yellow"));
        ledRed(0);
        ledGreen(0);
        ledYellow(1);
        break;
      }
    }
  }

  ledRed(0);
  ledYellow(0);
  ledGreen(0);
}

void printBar(uint8_t height)
{
  if (height > 8) { height = 8; }
  static const char barChars[] = {' ', 0, 1, 2, 3, 4, 5, 6, 255};
  lcd.print(barChars[height]);
}

// Starts I2C and initializes the inertial sensors.
void initInertialSensors()
{
  Wire.begin();
  imu.init();
  imu.enableDefault();
  mag.init();
  mag.enableDefault();
}

// Given 3 readings for axes x, y, and z, prints the sign
// and axis of the largest reading unless it is below the
// given threshold.
void printLargestAxis(int16_t x, int16_t y, int16_t z, uint16_t threshold)
{
  int16_t largest = x;
  char axis = 'X';

  if (abs(y) > abs(largest))
  {
    largest = y;
    axis = 'Y';
  }
  if (abs(z) > abs(largest))
  {
    largest = z;
    axis = 'Z';
  }

  if (abs(largest) < threshold)
  {
    lcd.print("  ");
  }
  else
  {
    bool positive = (largest > 0);
    lcd.print(positive ? '+' : '-');
    lcd.print(axis);
  }
}

// Print the direction of the largest rotation rate measured
// by the gyro and the up direction based on the
// accelerometer's measurement of gravitational acceleration
// (assuming gravity is the dominant force acting on the
// Romi).
void inertialDemo()
{
  displayBackArrow();

  lcd.gotoXY(3, 0);
  lcd.print(F("Rot"));
  lcd.gotoXY(4, 1);
  lcd.print(F("Up"));

  while (buttonMonitor() != 'B')
  {
    imu.read();

    lcd.gotoXY(6, 0);
    printLargestAxis(imu.g.x, imu.g.y, imu.g.z, 2000);
    lcd.gotoXY(6, 1);
    printLargestAxis(imu.a.x, imu.a.y, imu.a.z, 200);
  }
}

void magnetometerDemo()
{
  displayBackArrow();

  while (buttonMonitor() != 'B')
  {
    mag.read();

    char buffer[7];

    sprintf(buffer, "%6d", mag.m.x);
    lcd.gotoXY(2, 0);
    lcd.print(buffer);

    sprintf(buffer, "%6d", mag.m.y);
    lcd.gotoXY(2, 1);
    lcd.print(buffer);
  }
}

// Provides an interface to test the motors. Holding button A or C
// causes the left or right motor to accelerate; releasing the
// button causes the motor to decelerate. Tapping the button while
// the motor is not running reverses the direction it runs.
//
// If the showEncoders argument is true, encoder counts are
// displayed on the first line of the LCD; otherwise, an
// instructional message is shown.
void motorDemoHelper(bool showEncoders)
{
  loadCustomCharactersMotorDirs();
  lcd.clear();
  lcd.gotoXY(1, 1);
  lcd.print(F("A \7B C"));

  int16_t leftSpeed = 0, rightSpeed = 0;
  int8_t leftDir = 1, rightDir = 1;
  uint16_t lastUpdateTime = millis() - 100;
  uint8_t btnCountA = 0, btnCountC = 0, instructCount = 0;

  int16_t encCountsLeft = 0, encCountsRight = 0;
  char buf[4];

  while (buttonMonitor() != 'B')
  {
    encCountsLeft += encoders.getCountsAndResetLeft();
    if (encCountsLeft < 0) { encCountsLeft += 1000; }
    if (encCountsLeft > 999) { encCountsLeft -= 1000; }

    encCountsRight += encoders.getCountsAndResetRight();
    if (encCountsRight < 0) { encCountsRight += 1000; }
    if (encCountsRight > 999) { encCountsRight -= 1000; }

    // Update the LCD and motors every 50 ms.
    if ((uint16_t)(millis() - lastUpdateTime) > 50)
    {
      lastUpdateTime = millis();

      lcd.gotoXY(0, 0);
      if (showEncoders)
      {
        sprintf(buf, "%03d", encCountsLeft);
        lcd.print(buf);
        lcd.gotoXY(5, 0);
        sprintf(buf, "%03d", encCountsRight);
        lcd.print(buf);
      }
      else
      {
        // Cycle the instructions every 2 seconds.
        if (instructCount == 0)
        {
          lcd.print("Hold=run");
        }
        else if (instructCount == 40)
        {
          lcd.print("Tap=flip");
        }
        if (++instructCount == 80) { instructCount = 0; }
      }

      if (buttonA.isPressed())
      {
        if (btnCountA < 4)
        {
          btnCountA++;
        }
        else
        {
          // Button has been held for more than 200 ms, so
          // start running the motor.
          leftSpeed += 15;
        }
      }
      else
      {
        if (leftSpeed == 0 && btnCountA > 0 && btnCountA < 4)
        {
          // Motor isn't running and button was pressed for
          // 200 ms or less, so flip the motor direction.
          leftDir = -leftDir;
        }
        btnCountA = 0;
        leftSpeed -= 30;
      }

      if (buttonC.isPressed())
      {
        if (btnCountC < 4)
        {
          btnCountC++;
        }
        else
        {
          // Button has been held for more than 200 ms, so
          // start running the motor.
          rightSpeed += 15;
        }
      }
      else
      {
        if (rightSpeed == 0 && btnCountC > 0 && btnCountC < 4)
        {
          // Motor isn't running and button was pressed for
          // 200 ms or less, so flip the motor direction.
          rightDir = -rightDir;
        }
        btnCountC = 0;
        rightSpeed -= 30;
      }

      leftSpeed = constrain(leftSpeed, 0, 400);
      rightSpeed = constrain(rightSpeed, 0, 400);

      motors.setSpeeds(leftSpeed * leftDir, rightSpeed * rightDir);

      // Display arrows pointing the appropriate direction
      // (solid if the motor is running, chevrons if not).
      lcd.gotoXY(0, 1);
      if (leftSpeed == 0)
      {
        lcd.print((leftDir > 0) ? '\0' : '\1');
      }
      else
      {
        lcd.print((leftDir > 0) ? '\2' : '\3');
      }
      lcd.gotoXY(7, 1);
      if (rightSpeed == 0)
      {
        lcd.print((rightDir > 0) ? '\0' : '\1');
      }
      else
      {
        lcd.print((rightDir > 0) ? '\2' : '\3');
      }
    }
  }
  motors.setSpeeds(0, 0);
}

// Motor demo with instructions.
void motorDemo()
{
  motorDemoHelper(false);
}

// Motor demo with encoder counts.
void encoderDemo()
{
  motorDemoHelper(true);
}

const char fugue[] PROGMEM =
  "! T120O5L16agafaea dac+adaea fa<aa<bac#a dac#adaea f"
  "O6dcd<b-d<ad<g d<f+d<gd<ad<b- d<dd<ed<f+d<g d<f+d<gd<ad"
  "L8MS<b-d<b-d MLe-<ge-<g MSc<ac<a MLd<fd<f O5MSb-gb-g"
  "ML>c#e>c#e MS afaf ML gc#gc# MS fdfd ML e<b-e<b-"
  "O6L16ragafaea dac#adaea fa<aa<bac#a dac#adaea faeadaca"
  "<b-acadg<b-g egdgcg<b-g <ag<b-gcf<af dfcf<b-f<af"
  "<gf<af<b-e<ge c#e<b-e<ae<ge <fe<ge<ad<fd"
  "O5e>ee>ef>df>d b->c#b->c#a>df>d e>ee>ef>df>d"
  "e>d>c#>db>d>c#b >c#agaegfe fO6dc#dfdc#<b c#4";

const char fugueTitle[] PROGMEM =
  "       Fugue in D Minor - by J.S. Bach       ";

// Play a song on the buzzer and display its title.
void musicDemo()
{
  displayBackArrow();

  uint8_t fugueTitlePos = 0;
  uint16_t lastShiftTime = millis() - 2000;

  while (buttonMonitor() != 'B')
  {
    // Shift the song title to the left every 250 ms.
    if ((uint16_t)(millis() - lastShiftTime) > 250)
    {
      lastShiftTime = millis();

      lcd.gotoXY(0, 0);
      for (uint8_t i = 0; i < 8; i++)
      {
        char c = pgm_read_byte(fugueTitle + fugueTitlePos + i);
        lcd.print(c);
      }
      fugueTitlePos++;

      if (fugueTitlePos + 8 >= strlen(fugueTitle))
      {
        fugueTitlePos = 0;
      }
    }

    if (!buzzer.isPlaying())
    {
      buzzer.playFromProgramSpace(fugue);
    }
  }
}

// Display the the battery (VIN) voltage and indicate whether USB
// power is detected.
void powerDemo()
{
  displayBackArrow();

  uint16_t lastDisplayTime = millis() - 2000;
  char buf[6];

  while (buttonMonitor() != 'B')
  {
    if ((uint16_t)(millis() - lastDisplayTime) > 250)
    {
      bool usbPower = usbPowerPresent();

      uint16_t batteryLevel = readBatteryMillivolts();

      lastDisplayTime = millis();
      lcd.gotoXY(0, 0);
      sprintf(buf, "%5d", batteryLevel);
      lcd.print(buf);
      lcd.print(F(" mV"));
      lcd.gotoXY(3, 1);
      lcd.print(F("USB="));
      lcd.print(usbPower ? 'Y' : 'N');
    }
  }
}

Menu::Item mainMenuItems[] = {
  { "LEDs", ledDemo },
  { "Inertial", inertialDemo },
  { "Magnet", magnetometerDemo },
  { "Motors", motorDemo },
  { "Encoders", encoderDemo },
  { "Music", musicDemo },
  { "Power", powerDemo },
};
Menu mainMenu(mainMenuItems, 7);

// This function watches for button presses.  If a button is
// pressed, it beeps a corresponding beep and it returns 'A',
// 'B', or 'C' depending on what button was pressed.  If no
// button was pressed, it returns 0.  This function is meant to
// be called repeatedly in a loop.
char buttonMonitor()
{
  if (buttonA.getSingleDebouncedPress())
  {
    buzzer.playFromProgramSpace(beepButtonA);
    return 'A';
  }

  if (buttonB.getSingleDebouncedPress())
  {
    buzzer.playFromProgramSpace(beepButtonB);
    return 'B';
  }

  if (buttonC.getSingleDebouncedPress())
  {
    buzzer.playFromProgramSpace(beepButtonC);
    return 'C';
  }

  return 0;
}

void setup()
{
  initInertialSensors();

  loadCustomCharacters();

  bool brownout = MCUSR >> BORF & 1;
  MCUSR = 0;
  if (brownout)
  {
    // The AVR was reset by a brownout reset
    // (VCC dropped below 4.3 V).
    // Play a special sound and display a note to the user.

    buzzer.playFromProgramSpace(beepBrownout);
    lcd.clear();
    lcd.print(F("Brownout"));
    lcd.gotoXY(0, 1);
    lcd.print(F(" reset! "));
    delay(1000);
  }
  else
  {
    buzzer.playFromProgramSpace(beepWelcome);
  }

  lcd.clear();
  lcd.print(F("  Romi"));
  lcd.gotoXY(2, 1);
  lcd.print(F("32U4"));

  delay(1000);

  lcd.clear();
  lcd.print(F("Demo"));
  lcd.gotoXY(0, 1);
  lcd.print(F("Program"));
  delay(1000);

  lcd.clear();
  lcd.print(F("Use B to"));
  lcd.gotoXY(0, 1);
  lcd.print(F("select."));
  delay(1000);

  lcd.clear();
  lcd.print(F("Press B"));
  lcd.gotoXY(0, 1);
  lcd.print(F("-try it!"));

  while (buttonMonitor() != 'B'){}

  buzzer.playFromProgramSpace(beepThankYou);
  lcd.clear();
  lcd.print(F(" Thank"));
  lcd.gotoXY(0, 1);
  lcd.print(F("  you!"));
  delay(1000);
}

// This function prompts the user to choose something from the
// main menu, runs their selection, and then returns.
void mainMenuSelect()
{
  lcd.clear();
  lcd.print(F("  Main"));
  lcd.gotoXY(0, 1);
  lcd.print(F("  Menu"));
  delay(1000);
  mainMenu.select();
}

void loop()
{
  mainMenuSelect();
}

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