This is the R0 version of this code

This is the R0 version of this code

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

--- CNCSpindleSpeedControl/CNCSpindleSpeedControl.ino
+++ CNCSpindleSpeedControl/CNCSpindleSpeedControl.ino
@@ -0,0 +1,775 @@
+/*
+This Program when loaded on an Arduino/Leonardo is a Tach based speed controller.
+It was originally written to operate a 400W/48VDC CNC spindle motor through
+a simple electronic controller, readily found on E-Bay
+This program assumes that the +PWM lead of this controller is connected to
+pin D13 of the Leonardo, and the collector output of the speed sensor
+[OPB704 is a direct pin-for-pin replacement for the once popular,
+but now discontinued, QRB1114; the Parallax Inc 550-27401 or FairChild qrd1114
+might also maybe adapted to work] is connected to pin D3.
+Note this collector is also tied +5Volts through a 20K pull-up resistor.
+It Furhter assumes that a Sansmart 16x2 LCD/KeyPad sheild has been installed.
+This display & keypad provides a simple user interface, where the Up/Down buttons
+will ramp the speed from 1400 to 10,000RPM in steps of 200RPM, and the Left/Right
+Button select the display mode.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+===============================================
+ */
+#include <LiquidCrystal.h>
+#include <LCDKeypad.h>
+
+LiquidCrystal lcd(8, 9, 4, 5, 6, 7); //initialize Sansmart LCD Display
+LCDKeypad Keypad;
+int trgtRPM = 5000;
+//unsigned long now = millis();
+//unsigned long now = micros(); //will overflow ~ every 70 minutes
+
+//int timeChange = (now - lastTime);
+//if(timeChange>=SampleTimeP)
+unsigned long timeval = 0;
+unsigned long Start = 0;
+unsigned long Stop;
+unsigned long startPrgm = millis()/1000;
+unsigned long now;
+//unsigned long CalcStrt;
+//unsigned long CalcFnsh;
+
+int PWMpin = 13; //Note - Pin 13 has an LED connected on most Arduino boards.
+//                 When the pin is HIGH value, the LED is on, when the pin is LOW, it's off.
+int calcrpm = 0;
+int GPIOpin = 1; // Use pin "0" [Pi IO header pin 11] to simulate a Clk pulse s$
+//int GPIOpinSlow = 4; //Under Speed LED
+//int GPIOpinOK = 5; //Speed Ok LED
+//int GPIOpinFast = 6; //Over Speed LED
+
+// -----------------PID/PWM Constants -----------------
+unsigned long lastTime;
+double Input, SetPoint;
+double ITerm, lastInput;
+double kp, ki, kd;
+double Kp = 0.02;//0.06;
+double Ki = 0.05;//0.05;
+double Kd = 0.0005;//0.0005;
+//double OS = 18;
+//double BrkPt = 22;
+//double X = 0.0;
+double PIDOut = 0.0;
+double Max = 254.0;
+double Min = 0.0;
+int SampleTime = 60;// measured in milliseconds [FWIW: 10,000 RPM measured over 10 revolutions = 60 ms]
+int MstrSampleTime = SampleTime;
+
+// -----------------End PID Constants -----------------
+long int TotalRunTime = 0;
+int MaxRunTime = 0;//60*60*10;// number of seconds the program is allowed to run be
+int SpndlPWM;
+int newdutycycle = 0;
+//int range = 800; //the number Substeps the Mark/Space ratio can be divided into
+//int Maxdutycycle =  630;
+//int Mindutycycle = 23;
+int dutycycle = 30; // percentage of time clock is high
+int StrtDC = 0; // the calculated Start dutycycle needed to hit the target rpm $
+//int TooHighCnt = 0;
+//int TooLowCnt = 0;
+//int MaxChngLmt = 0;
+int LastRPM = 0;
+int AltRPM = 0;
+int SpeedChange = 0;
+int SuspectRdCnt = 0;
+bool increaseSpeed = true;
+bool NewTrgtVal = true; //used to determine if display needs updating
+bool ExitNow = false;
+bool NuInput = true;
+char *intFlgStat;
+int ThrtlLpCnt= 0;
+int Startup = 0; // Locks out pid calcs on startup to give the default throttle setting a chance to take effect before correcting it
+int CalcIntrvl = 0;
+int BackLight = 6;  // set Display BackGround color to 1=Red; 2=Green; 4=Blue
+int Mode = 7;
+
+// the event counter
+volatile int eventCounter = 0;
+volatile int LoopCounter = 0;
+
+char buf [16]; // used to concatenate strings & numerical data for display on SanSmart LCD
+
+// Display Custom characters for Throttle Bar Graph Mode
+static unsigned char Char0 [8] =
+{
+  0b00000,
+  0b00000,
+  0b00000,
+  0b00000,
+  0b00000,
+  0b00000,
+  0b00000,
+  0b00000
+} ;
+
+static unsigned char Char1 [8] =
+{
+  0b10000,
+  0b10000,
+  0b10000,
+  0b10000,
+  0b10000,
+  0b10000,
+  0b10000,
+  0b10000
+} ;
+
+static unsigned char Char2 [8] =
+{
+  0b11000,
+  0b11000,
+  0b11000,
+  0b11000,
+  0b11000,
+  0b11000,
+  0b11000,
+  0b11000
+} ;
+
+static unsigned char Char3 [8] =
+{
+  0b11100,
+  0b11100,
+  0b11100,
+  0b11100,
+  0b11100,
+  0b11100,
+  0b11100,
+  0b11100
+} ;
+
+static unsigned char Char4 [8] =
+{
+  0b11110,
+  0b11110,
+  0b11110,
+  0b11110,
+  0b11110,
+  0b11110,
+  0b11110,
+  0b11110,
+} ;
+
+static unsigned char Char5 [8] =
+{
+  0b11111,
+  0b11111,
+  0b11111,
+  0b11111,
+  0b11111,
+  0b11111,
+  0b11111,
+  0b11111
+} ;
+
+// ================================================================
+// ===               INTERRUPT DETECTION ROUTINE                ===
+// ================================================================
+
+// SpindleTachInterrupt:  called every time an event occurs
+
+void SpindleTachInterrupt(void)
+{
+   int ThisRPM = 0;
+   double pulseperiod = 0;
+//   if (Startup>0) // PID Lock out counter
+//   {
+//     LoopCounter = 1;
+//     Startup -= 1;
+//     return;
+//   }
+   if (eventCounter == 0)
+     {
+      Start = micros();//gettimeofday(&Start, NULL);
+     }
+   if (eventCounter == 10)
+     {
+      Stop = micros();//gettimeofday(&Stop, NULL);
+     }
+   eventCounter +=1;//eventCounter++;
+///////////////////////////////////////////////////////////////////////////////
+    if (eventCounter < 11)// Let's see if there's enough samples to calc the current RPM
+     {
+      if (eventCounter < 3)
+       {
+        return; //No, there isn't enough samples
+       }
+      else
+       {
+        // yes there is, but does it seem like a reasonable value
+        Stop = micros(); //gettimeofday(&CalcStrt, NULL);
+        //pulseperiod = ((Stop.tv_sec-Start.tv_sec)*1000000ULL+(Stop.tv_usec-Start.tv_usec));
+        pulseperiod = (Stop-Start);
+        ThisRPM  = (60000000*(eventCounter-1))/pulseperiod;
+        if (ThisRPM <1200 || ThisRPM > 4200)
+         {
+          return; // its too slow, or its going fast enough that we need to go for a full ten
+                  // samples before deciding what to do with it
+         }
+       }
+     }
+   if (eventCounter >= 11 || ThisRPM >0 )// There's enough samples to calc the current RPM
+     {
+      if (eventCounter >= 11)
+       {
+        pulseperiod = (Stop-Start);
+        calcrpm = 600000000/pulseperiod;// calculate rpm based on having measured the period of 10 revolutions
+       }
+       else
+       {
+        calcrpm = ThisRPM;
+       }
+
+//       AltRPM = (60000000*(eventCounter-2))/pulseperiod;//AltRPM = ThisRPM  = (60000000*(eventCounter-2))/pulseperiod;
+//       //if(abs(AltRPM-LastRPM) < abs(calcrpm-LastRPM) && abs(trgtRPM-calcrpm)>100) //(abs(100*LastRPM/trgtRPM)<6)
+//       if(abs(AltRPM-trgtRPM) < abs(calcrpm-trgtRPM) && abs(trgtRPM-LastRPM)<100)
+//         {
+//           calcrpm = AltRPM;
+//           //curspeed = LastRPM;
+//           sprintf (buf, "RPM %d ECnt %d\n", calcrpm, eventCounter);
+//           Serial1.println(buf);
+//         }
+         //else curspeed = calcrpm;
+      SpeedChange =  calcrpm -  LastRPM;
+      //LastRPM = curspeed;
+      LastRPM = calcrpm;
+      eventCounter = 0;
+      LoopCounter = 1;
+      //return; // temp stop for testing just the Tachometer portion of the code
+
+      if (pulseperiod<0 )//|| pulseperiod > 600000
+       {
+         sprintf (buf, "Pulse Period Err");
+         //Serial1.println(buf);
+        return; // disregard this result; it appears to be bogus
+       }
+
+      SampleTime = MstrSampleTime;
+      SetTunings(Kp, Ki, Kd);
+      SpndlPWM = CalcMtrPID(calcrpm);//Max+CalcMtrPID(calcrpm);
+      analogWrite(PWMpin, SpndlPWM);
+      dutycycle = (int)((SpndlPWM*100)/(Max));//(int)((SpndlPWM*100)/(2*Max));// convert PWM signal to a precentage
+     }
+
+   }
+// ================================================================
+// ===               END INTERRUPT DETECTION ROUTINE            ===
+// ================================================================
+
+// -------------------------------------------------------------------------
+
+// ================================================================
+// ===                      INITIAL SETUP                       ===
+// ================================================================
+
+void setup()
+{
+  //Serial1.begin(9600); // enable when bluetooth diagnostic is needed
+   // set up the lcd's number of columns and rows:
+  lcd.begin(16, 2);
+  //setup PWM frequency to ~60Hz for OutPut pins 13 & 11
+  TCCR4B = TCCR4B & 0b11111000 | 0x06; //Set Digital pin 13 [Spindle] PWM period @ ~2ms
+  attachInterrupt(0, SpindleTachInterrupt, FALLING); //digital pin 3;
+  pinMode(PWMpin, OUTPUT);
+// install  user defined special characters
+  lcd.createChar(0, Char0);
+  // create a new character
+  lcd.createChar(1, Char1);
+  // create a new character
+  lcd.createChar(2, Char2);
+  // create a new character
+  lcd.createChar(3, Char3);
+  // create a new character
+  lcd.createChar(4,Char4);
+  // create a new character
+  lcd.createChar(5, Char5);
+  //lcd.setCursor(0,0);
+  //lcd.print("SetUp Complete");
+  //startPrgm = 1000*millis();
+  long MaxRunTime = 60*60*10;// number of seconds the program is allowed to run be
+}
+// ================================================================
+// ===                    MAIN PROGRAM LOOP                     ===
+// ================================================================
+void loop()
+{
+  int UsrInput = 0;
+  int stopCnt = 0;
+  //  lcdPosition (lcdHandle, 0, 0) ; lcdPuts (lcdHandle, "Speed Cntl Ready") ;
+  lcd.setCursor(0,1);
+  lcd.print("Speed Cntl Ready");
+  //  lcdPosition (lcdHandle, 0, 1) ; lcdPrintf (lcdHandle, " Set RPM: %d",trgtRPM) ;
+  lcd.setCursor(0,0);
+  sprintf (buf,"Set RPM: %d", trgtRPM);
+  lcd.print(buf);
+  //If you're here [and can see, "Speed Cntl Ready" on the Display]
+  //then LCD setup seemed to go OK, & you're ready to start the speed control stuff
+
+  // Calc initial dutycycle based on trgtRPM
+  //dutycycle = (int) 75*(trgtRPM/9800.0)*(trgtRPM/9800.0) ;
+  //int valA = (trgtRPM - 1500)/140;
+   //StrtDC =((valA*valA)/14)+22;
+   //StrtDC = 30;
+   SpndlPWM = (int) 95.0*(trgtRPM/9800.0)*(trgtRPM/9800.0) ; //190.5*(trgtRPM/9800.0)*(trgtRPM/9800.0)
+
+  //pinMode (GPIOpin, PWM_OUTPUT) ; //configure pin 1 as a PWM output
+  //pwmSetMode (PWM_MODE_MS); //configure PWM output to operate in Mark / Space mode
+  //pwmSetMode (PWM_MODE_BAL); //configure PWM output to operate in Mark / Balanced Mode
+  //pwmSetRange (range) ;// This sets the range register in the PWM generator. The default is 1024.
+ // pwmSetClock (5) ;// This sets the divisor for the PWM clock.
+
+// pinMode (GPIOpinSlow, OUTPUT) ; //configure pin 1 as a simple output pin
+// digitalWrite (GPIOpinSlow, LOW); //set/force pin 4 output High[Under Speed LED off]
+// pinMode (GPIOpinOK, OUTPUT) ; //configure pin 5 as a simple output pin
+// digitalWrite (GPIOpinOK, LOW); //set/force pin 5 output  High[Speed Ok LED off]
+// pinMode (GPIOpinFast, OUTPUT) ; //configure pin 6 as a simple output pin
+// digitalWrite (GPIOpinFast, LOW); //set/force pin 6 output  High[Over Speed LED off]
+
+
+
+  // display counter value every 1/4 second.
+  //sprintf (buf, "Time %d Max %d\n", TotalRunTime, MaxRunTime);
+  //Serial1.println(buf);
+  while ( TotalRunTime <= MaxRunTime && !ExitNow )
+  {
+
+    while (eventCounter == 0 && LoopCounter == 0 &&  TotalRunTime <= MaxRunTime && !ExitNow)
+     {
+      //Motor is not running, So initialize PID for next startup
+      //SpndlPWM = (int) 190.5*(trgtRPM/9800.0)*(trgtRPM/9800.0) ;
+      SpndlPWM = 15;
+      SetPoint = 2000;
+      ITerm = 0.0; //kill any residual Integral component that might be left over from a previous run
+      lastTime = millis();// reset/establish time mark for initial PID calculation
+      analogWrite(PWMpin, SpndlPWM); //start the PWM output
+      //Startup, in this version of the code is not used
+      //Startup = 60; // Locks out pid calcs on startup to give the default throttle setting a chance to take effect before correcting it
+      delay(100);
+      if (NewTrgtVal)
+       {
+//         lcdPosition (lcdHandle, 0, 0) ;  lcdPrintf (lcdHandle, "Trgt RPM: %d   ", trgtRPM) ;
+//         lcdPosition (lcdHandle, 0, 1) ; lcdPuts (lcdHandle, "Speed Cntl Ready") ;
+         lcd.setCursor(0,0); //lcd.setCursor(pos,line)
+         sprintf (buf, "%s %04i ", "Trgt RPM:", trgtRPM);
+         lcd.print(buf);
+         lcd.setCursor(0,1);
+         lcd.print("Speed Cntl Ready");
+         NewTrgtVal = false;
+       }
+      UsrInput =  ScanButtons();
+      UpDateSettings(UsrInput, Mode);
+      if (stopCnt == 0)
+       {
+//         Serial1.print( "Eventcount:%d ; Duty Cycle %d \n", eventCounter, dutycycle );
+//         digitalWrite (GPIOpinSlow, HIGH); //set/force pin 4 output High[Under Speed LED On]
+//         digitalWrite (GPIOpinOK, HIGH); //set/force pin 5 output  High[Speed Ok LED On]
+//         digitalWrite (GPIOpinFast, HIGH); //set/force pin 6 output  High[Over Speed LED On]
+       }
+      if (stopCnt == 5)
+       {
+//      delay( 500 ); // wait 1/2 second(s)
+//         digitalWrite (GPIOpinSlow, LOW); //set/force pin 4 output Low[Under Speed LED off]
+//         digitalWrite (GPIOpinOK, LOW); //set/force pin 5 output  Low[Speed Ok LED off]
+//         digitalWrite (GPIOpinFast, LOW); //set/force pin 6 output  Low[Over Speed LED off]
+       }
+      long TotalRunTime = calcruntime();
+      SuspectRdCnt = 3;
+      stopCnt = stopCnt+1;
+      if (stopCnt == 10)
+       {
+        stopCnt = 0;
+       }
+     } // end 2nd inner While looop
+//   Serial1.print( "rpm: %d; trgtRPM: %d; Duty Cycle: %d; SpdChng: %d %s; EvntCnt: %d \n", calcrpm, trgtRPM,$
+   //lcdClear (lcdHandle) ;
+   if (NewTrgtVal)
+    {
+      //lcdPosition (lcdHandle, 0, 0) ; lcdPrintf (lcdHandle, "Trgt RPM: %d   ", trgtRPM) ;
+      lcd.setCursor(0,0); //lcd.setCursor(pos,line)
+      sprintf (buf, "%s %04i ", "Trgt RPM:", trgtRPM);
+      lcd.print(buf);
+      NewTrgtVal = false;
+    }
+   lcd.setCursor(0,1);//lcdPosition (lcdHandle, 0, 1) ;
+   if (Mode == 7) // Original Display Mode; Show Measured RPM, on the 2nd line
+    {
+     //lcdPrintf (lcdHandle, "Actl RPM: %d  ", calcrpm) ;
+     sprintf (buf, "%s %04i  ", "Actl RPM:", calcrpm);
+     lcd.print(buf);
+    }
+   if (Mode == 5) // Display Duty Cycle Mode
+    {
+     char DsplyStr[16];
+     char BlnkChr [1];
+     sprintf(DsplyStr, "Duty Cycle: %d ", dutycycle );// convert SpdEr to a String
+     strncpy( BlnkChr, " ", 1);// now fill out the rest of the display message/line with Blanks
+                               //[to ensure previous message has been erased
+     while (strlen(DsplyStr)<16)
+      {
+       strcat(DsplyStr, BlnkChr);
+      }
+     //lcdPrintf (lcdHandle,"%s", DsplyStr);
+     //sprintf (buf, "%s %04i ", "Actl RPM:", calcrpm);
+     lcd.print(DsplyStr);
+    }
+   if (Mode == 6) // show Speed error Mode
+    {
+     char SpdErStr[6];
+     char SgndErStr[8];
+     char *pntr;
+     int SpdEr =  calcrpm-trgtRPM;
+     sprintf(SpdErStr, "%d",SpdEr );// convert SpdEr to a String
+     pntr = strchr (SpdErStr, '-');
+     if(pntr == NULL)
+      {
+       strncpy(SgndErStr, " +", 8);
+       strcat(SgndErStr, SpdErStr);
+      }
+     else
+      {
+//      strncpy(SgndErStr, SpdErStr, 6);
+       strncpy(SgndErStr, " ", 8);
+       strcat(SgndErStr, SpdErStr);
+      }
+     strncpy( SpdErStr, " ", 6);
+     while (strlen(SgndErStr)<8)
+      {
+       strcat(SgndErStr, SpdErStr);
+      }
+     //lcdPrintf (lcdHandle, "Spd Err:%s", SgndErStr ) ;
+     sprintf (buf, "%s%s ", "Spd Err:", SgndErStr);
+     lcd.print(buf);
+    }
+// ############ Begin BarGraph Mode #################
+   if (Mode == 4)// PWM Bar Graph Mode
+    {
+     int FullCell;
+     int runngCnt = 0;
+     int postn = 0;
+     int remainder = 0;
+     int rowWeight;
+     FullCell =  100/16;//(Maxdutycycle - Mindutycycle)/16;
+     rowWeight = FullCell/5;
+//   First, fill in the whole spaces
+     while (runngCnt +  FullCell<= dutycycle)
+      {
+       //lcdPutchar  (lcdHandle, 7) ;
+       lcd.write(byte(5));
+       runngCnt = runngCnt +  FullCell;
+       postn =  postn + 1;
+      }
+//   Next, Deterime which partial charater to use
+     remainder =  dutycycle- runngCnt;
+    //Serial1.print("remainder: %d Dutycycle: %d\n", remainder, dutycycle-Mindutycycle);
+     if(remainder>0)
+      {
+      postn =  postn + 1;
+       if (remainder>= 4*rowWeight)
+        {
+          lcd.write(byte(4));//lcdPutchar  (lcdHandle, 6) ;
+        }
+       else
+        {
+         if (remainder>= 3*rowWeight)
+          {
+           lcd.write(byte(3));//lcdPutchar  (lcdHandle, 5) ;
+          }
+         else
+          {
+           if (remainder>= 2*rowWeight)
+            {
+              lcd.write(byte(2));//lcdPutchar  (lcdHandle, 4) ;
+            }
+           else
+            {
+             lcd.write(byte(1));//lcdPutchar  (lcdHandle, 3) ;
+            }
+          }
+        }
+      }
+
+//   finally, Finish out the Bar Graph line with blanks
+     while (postn < 16)
+      {
+        lcd.write(byte(0));//lcdPutchar  (lcdHandle, 2) ;
+        postn =  postn + 1;
+      }
+    }
+// ############ End BarGraph Mode #################
+   if (Mode == 3)// Set Back Light Color Mode
+    {
+      //lcdPrintf (lcdHandle,"Set Display Clr ");
+      //sprintf (buf, "%s%s ", "Spd Err:", calcrpm);
+     lcd.print("Set Display Clr ");
+    }
+   UsrInput =  ScanButtons();
+   UpDateSettings(UsrInput, Mode);
+   delay( 250 ); // wait 1/4 second(s)
+    LoopCounter = LoopCounter + 1;
+
+    if (LoopCounter >= 8)
+     {
+      LoopCounter = 0;
+      eventCounter = 0;
+//      TooHighCnt = 0;
+//      TooLowCnt = 0;
+      NewTrgtVal = true;
+      //Serial1.print("Looks as if Motor has Stopped\n");
+     }
+   long TotalRunTime = calcruntime();
+  }
+ //kill the PWM signal
+ digitalWrite (PWMpin, LOW);
+// pinMode (GPIOpin, OUTPUT) ; //configure pin 1 as a simple output pin
+// digitalWrite (GPIOpin, LOW); //set/force pin 1 output to ground [low]
+// digitalWrite (GPIOpinSlow, LOW); //set/force pin 4 output High[Under Speed LED off]
+// digitalWrite (GPIOpinOK, LOW); //set/force pin 5 output  High[Speed Ok LED off]
+// digitalWrite (GPIOpinFast, LOW); //set/force pin 6 output  High[Over Speed LED off]
+
+
+ //Serial1.print("All Done!\n");
+ //setBacklightColour (0);
+ lcd.clear();
+ lcd.setCursor(0,0); //lcd.setCursor(pos,line)
+ sprintf (buf, "Program Stopped");
+ lcd.print(buf);
+ lcd.setCursor(0,1); //lcd.setCursor(pos,line)
+ sprintf (buf, "CYCLE PWR 2 STRT");
+ lcd.print(buf);
+ return;
+}
+// ================================================================
+// ===                   END MAIN PROGRAM LOOP                  ===
+// ================================================================
+
+//###########################################################################
+// Begin PID computations
+int CalcMtrPID(float Input)
+{
+   unsigned long now = millis();
+   int timeChange = (now - lastTime);
+   if(timeChange>=SampleTime)
+   {
+      //sprintf (buf, "DT %d", timeChange);
+      //Serial1.println(buf);
+      SetSampleTime(timeChange);
+      /*Compute all the working error variables*/
+      if (SetPoint < trgtRPM) SetPoint +=200;
+      else if(SetPoint > trgtRPM) SetPoint -=200;
+      double error = SetPoint - Input;
+      double dInput = (Input - lastInput);
+      double offset = 0.0;
+      double DtI = ki*error;
+      double Cap = 10.0;
+      if (DtI >Cap) DtI = Cap;
+      else if (DtI <-Cap) DtI = -Cap;
+      ITerm+= DtI;//ITerm+= (0.75*ki*error);
+
+      /*Compute PID PIDOut*/
+      PIDOut = kp*error + ITerm - kd * dInput;
+      //sprintf (buf, "P %d\n", PIDOut);
+      //Serial1.println(PIDOut);
+
+      SetPIDOutLimits(Min, Max);
+      /*Remember some variables for next time*/
+      lastInput = Input;
+      lastTime = now;
+   }
+   return (int) PIDOut;
+
+}
+
+void SetTunings(double Kp, double Ki, double Kd)
+{
+  double SampleTimeInSec = ((double)SampleTime)/1000;
+   kp = Kp;
+   ki = Ki * SampleTimeInSec;
+   kd = Kd / SampleTimeInSec;
+}
+
+void SetSampleTime(int NewSampleTime)
+{
+   if (NewSampleTime > 0)
+   {
+      double ratio  = (double)NewSampleTime
+                      / (double)SampleTime;
+      ki *= ratio;
+      kd /= ratio;
+      SampleTime = (unsigned long)NewSampleTime;
+   }
+}
+
+void SetPIDOutLimits(double Min, double Max)
+{
+   if(Min > Max) return;
+//   double outMin = Min;
+//   double outMax = Max;
+
+//   if(PIDOut > outMax) PIDOut = outMax;
+//   else if(PIDOut < outMin) PIDOut = outMin;
+//
+//   if(ITerm> outMax) ITerm= outMax;
+//   else if(ITerm< outMin) ITerm = outMin;
+
+   if (PIDOut > Max)
+    {
+      ITerm -= PIDOut - Max;
+      PIDOut = Max;
+    }
+   else if (PIDOut < Min)
+    {
+      ITerm  -=(PIDOut - Min);//+= Min - PIDOut;// -=(PIDOut - Min)
+      PIDOut = Min;
+    }
+}
+
+
+// End PID computations
+//#######################################################################
+
+// ================================================================
+// ===              BEGIN LOCAL FUNCTION DEFINITIONS            ===
+// ================================================================
+
+
+static int ScanButtons()
+{
+  int buttons = 0;
+  int buttonPressed = Keypad.button();
+  if (buttonPressed==KEYPAD_UP) buttons += 1;
+  if (buttonPressed==KEYPAD_DOWN) buttons += 2;
+  if (buttonPressed==KEYPAD_LEFT) buttons += 4;
+  if (buttonPressed==KEYPAD_RIGHT) buttons += 8;
+  if (buttonPressed==KEYPAD_SELECT) buttons += 16;
+  if (buttonPressed==KEYPAD_NONE) NuInput = true;
+  return buttons;
+}
+
+void UpDateSettings(int UsrInput, int mode)
+{
+   if (UsrInput !=0)
+    {
+      if(UsrInput == 1 || UsrInput == 2) //[Display Up or Down Button]  Speed, $
+       {
+         if (mode == 3)
+          {
+           if(UsrInput == 1 )
+            {
+             if (BackLight <7)
+              {
+               BackLight = BackLight+1;
+              }
+             else
+              {
+               BackLight = 1;
+              }
+            }
+           else
+            {
+             if (BackLight >1)
+              {
+               BackLight = BackLight-1;
+              }
+             else
+              {
+               BackLight = 7;
+              }
+            }
+           //setBacklightColour (BackLight) ;
+          }
+         else
+          {
+           NewTrgtVal = true;
+           if(UsrInput == 1 )
+            {
+             if (trgtRPM <10000)
+              {
+               trgtRPM = trgtRPM+200;
+              }
+            }
+           else
+            {
+             if (trgtRPM >1500)
+              {
+                trgtRPM = trgtRPM-200;
+              }
+            }
+          }
+       }
+      if((UsrInput == 4 || UsrInput == 8) && NuInput == true) //[Display Left o$
+       {
+//        Serial1.print("NuInput %s\n", NuInput ? "true" : "false");
+        NuInput = false;
+        if (UsrInput == 4)
+         {
+           Mode = Mode +1;
+           if (Mode == 8)
+            {
+              Mode = 3;
+            }
+         }
+        else
+         {
+           Mode = Mode- 1;
+           if (Mode == 2)
+            {
+              Mode = 7;
+            }
+
+         }
+        //setBacklightColour (BackLight);
+       }
+      if (UsrInput ==16)
+       {
+          ExitNow = true;
+       }
+    }
+}
+
+
+// -------------------------------------------------------------------------
+// Function that, given a start time, will calculate an interger number of seconds
+// that the progam has been running
+
+long int calcruntime()
+{
+  now = millis()/1000;//gettimeofday(&now, NULL);
+  long int RunTime = (now -startPrgm); //TotalRunTime = ((now.tv_sec - startPrgm.tv_sec));
+  return RunTime;
+}
+// -------------------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+
+
+
+
+


Initial upload of test test code for MS5803-14BA

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

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


debugging suboption; always send stopid

debugging suboption; always send stopid

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/upperman/Wireless-Led-Display.git/'


Se crea ejercicio de arduino input output

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

--- arduino_input_output/arduino_input_output.ino
+++ arduino_input_output/arduino_input_output.ino
@@ -0,0 +1,30 @@
+/**Arduino input output
+*
+* Copyright: codigoelectronica.com
+* Author: Oscar Fernandez @oscar_fedezal
+* License: MIT*/
+
+//Se declaran los pines en un array
+int pinInput[] = {2, 3, 4, 5};
+int pinOutput[] = {6, 7, 8, 9};
+
+void setup() {
+  //Se declaran los pines como entrada o salida
+  for(int i = 0; i < 4; i++){
+    pinMode(pinInput[i], INPUT);
+    pinMode(pinOutput[i], OUTPUT);
+  }
+}
+
+void loop() {
+  for(int i = 0; i < 4; i++){
+    //Leemos el valor del pin que esta en el array
+    int val = digitalRead(pinInput[i]);
+    //Si el valor es 1 lo activamos, de lo contrario desactivamos
+    if(val == 1){
+      digitalWrite(pinOutput[i], HIGH);
+    }else{
+      digitalWrite(pinOutput[i], LOW);
+    }
+  }
+}


Create followLine.ino

Create followLine.ino

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

--- followLine.ino
+++ followLine.ino
@@ -0,0 +1,22 @@
+int linePossitionPWMPin = 11;
+int leftMostPhotoDiode = 10;
+int rightMostPhotoDiode = 12;
+
+void setup(){
+  analogReference(INTERNAL);
+  pinMode(A0, INPUT);
+  pinMode(A1, INPUT);
+  pinMode(A2, INPUT);
+  pinMode(A3, INPUT);
+  pinMode(A4, INPUT);
+  pinMode(A5, INPUT);
+  pinMode(A6, INPUT);
+  pinMode(A7, INPUT);
+  pinMode(linePossitionPWMPin, OUTPUT);
+  pinMode(leftMostPhotoDiode, OUTPUT);
+  pinMode(rightMostPhotoDiode, OUTPUT);
+}
+
+void loop(){
+
+}


commit arduino

commit arduino

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

--- arduino/sketch_dec23a.ino
+++ arduino/sketch_dec23a.ino
@@ -0,0 +1,48 @@
+void setup()
+{
+for (int i = 2; i < 19; i++)
+ {
+  pinMode(i,INPUT_PULLUP);
+ }
+ for (int i = 22; i < 54; i++)
+ {
+  pinMode(i,OUTPUT);
+ }
+ Serial.begin(9600);
+
+}
+
+void loop() {
+  for (int i = 2; i < 18; i++)
+ {
+    printled(i,digitalRead(i));
+ }
+  if (digitalRead(18))
+  {
+    digitalWrite(52,HIGH);
+    digitalWrite(53,LOW);
+  }
+  else
+  {
+    digitalWrite(53,HIGH);
+    digitalWrite(52,LOW);
+  }
+}
+void printled(int port, boolean highlow)
+{
+  Serial.println(port);
+  Serial.println(highlow);
+  if (highlow == 1)
+  {
+  digitalWrite(22+(port-2)*2, HIGH);
+  digitalWrite(23+(port-2)*2,LOW);
+  }
+  else
+  {
+    digitalWrite(22+(port-2)*2, LOW);
+    digitalWrite(23+(port-2)*2, HIGH);
+  }
+
+}
+
+


added Wifi signal & System.sleep() sample

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

--- sleep-wifi-test/sleeptest.ino
+++ sleep-wifi-test/sleeptest.ino
@@ -0,0 +1,32 @@
+char timeStamp[22];
+char publishString[64];
+
+void setup() {
+    pinMode(D7, OUTPUT);
+    uint32_t startTime = millis();
+    while(millis() - startTime < 5000UL) {
+        digitalWrite(D7, HIGH);
+        Spark.process();
+        delay(100);
+        digitalWrite(D7, LOW);
+        Spark.process();
+        delay(100);
+    }
+}
+
+void loop() {
+
+    int wifiSignal = WiFi.RSSI();
+    sprintf(publishString,"{\"Wifi\": \"%s\", \"Signal\": %d}",WiFi.SSID(),wifiSignal);
+    Particle.publish("Wifi",publishString);
+
+    time_t time = Time.now();
+    Time.format(time, TIME_FORMAT_ISO8601_FULL).toCharArray(timeStamp, 64);
+    Particle.publish("TimeStamp", timeStamp);
+
+    digitalWrite(D7, HIGH);
+    delay(1000);
+    digitalWrite(D7, LOW);
+
+    System.sleep(SLEEP_MODE_DEEP, 60);
+}


Added High Speed Wave example

Added High Speed Wave example

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/TFTLibraries/TFT.git/'


Naomi's LCD script

Naomi's LCD script

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

--- lcd_display/lcd_display.ino
+++ lcd_display/lcd_display.ino
@@ -0,0 +1,39 @@
+#include <Adafruit_GFX.h>
+#include <Adafruit_SharpMem.h>
+
+// any pins can be used
+#define SCK 10
+#define MOSI 11
+#define SS 13
+
+Adafruit_SharpMem display(SCK, MOSI, SS);
+
+#define BLACK 0
+#define WHITE 1
+
+void setup(void)
+{
+  Serial.begin(9600);
+  Serial.println("Hello!");
+
+  // start & clear the display
+  display.begin();
+  display.clearDisplay();
+
+  display.setTextSize(1);
+  display.setTextColor(BLACK);
+  display.setCursor(0,0);
+  display.println("Hello, world!");
+  display.refresh();
+  delay(200);
+  display.clearDisplay();
+
+}
+
+void loop(void)
+{
+  // Screen must be refreshed at least once per second
+  display.refresh();
+  delay(500);
+}
+


v3 final

v3 final

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/Omemanti/MantiOT.git/'


Update Snake.ino

Update Snake.ino

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


Add looper example

Add looper example

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

--- examples/MidiLight_Looper/MidiLight_Looper.ino
+++ examples/MidiLight_Looper/MidiLight_Looper.ino
@@ -0,0 +1,244 @@
+/**
+ * MidiLight_Looper - Midi looper application
+ *
+ * @file    MidiLight_Looper.ino
+ * @author  S.Tudoret
+ * @date    20/04/16
+ * @license MIT
+ *
+ * Copyright (c) 2016 S. Tudoret
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "Arduino.h"
+#include <MidiLight.h>
+
+#define LED_PORT         (PORTB) // B (digital pin 8 to 13)
+#define LED_13           (13)    // LED pin on Arduino Uno
+#define SWITCH_LED_13()  (LED_PORT ^= 1 << 5) // Faster than using digitalWrite
+
+#define REC_EVT_TYPE_EOT      (0) // end of track
+#define REC_EVT_TYPE_NOTE_ON  (1)
+#define REC_EVT_TYPE_NOTE_OFF (2)
+
+#define REC_STATE_IDLE        (0x00)
+#define REC_STATE_RECORDING   (0x01)
+#define REC_STATE_PLAYING     (0x02)
+
+#define IS_RECORDING(idx) (tracks[idx].state & REC_STATE_RECORDING)
+#define RECORD(idx)       (tracks[idx].state = REC_STATE_RECORDING)
+#define IS_PLAYING(idx)   (tracks[idx].state & REC_STATE_PLAYING)
+#define PLAY(idx)         (tracks[idx].state = REC_STATE_PLAYING)
+
+#define REC_EVT_MAX           (100) // Max number of events by record
+#define REC_MAX               (3)   // Max number of records
+
+// C1 is the lower note on my keyboard
+#define KEY_C1       (36)  // reserved to switch RECORD/PLAYBACK on track 1
+#define KEY_C1_SHARP (37)  // reserved to switch RECORD/PLAYBACK on track 2
+#define KEY_D1       (38)  // reserved to switch RECORD/PLAYBACK on track 3
+#define LAST_RESERVED_KEY KEY_D1
+
+static unsigned long evtDelay = 0;
+static unsigned long currentTime = 0;
+
+typedef struct s_recEvt {
+    byte type;
+    byte pitch;
+    byte velocity;
+    byte delay; // unity of 64ms, so 255 means 16,3 seconds
+} t_recEvt;
+
+typedef struct s_track{
+    t_recEvt events[REC_EVT_MAX + 1];
+    unsigned long lastEvtTime; // used to manage delay of events
+    byte key; // the key used to switch RECORD/PLAYBACK
+    byte playbackChannel;
+    byte eIdx;
+    byte state;
+} t_track;
+
+static t_track tracks[REC_MAX];
+static t_recEvt * evtPtr;
+
+static void
+handleNoteOn(
+        byte channel,
+        byte pitch,
+        byte velocity)
+{
+    byte tIdx = 0;
+    for (tIdx = 0; tIdx < REC_MAX; tIdx++) {
+        if (IS_RECORDING(tIdx) && (tracks[tIdx].eIdx >= REC_EVT_MAX)) {
+                // abort the record by simulate
+                pitch = tracks[tIdx].key;
+            }
+        if (pitch == tracks[tIdx].key) {
+            // If is recording then stop recording and trigger a play
+            // If is playing playback then stop playing and trigger a record
+            if (IS_RECORDING(tIdx)) {
+                evtPtr = &tracks[tIdx].events[tracks[tIdx].eIdx];
+                PLAY(tIdx);
+                SWITCH_LED_13();
+                evtPtr->type = REC_EVT_TYPE_EOT;
+                if (tracks[tIdx].eIdx == 0) {
+                    evtPtr->delay = 0;
+                } else {
+                    evtPtr->delay =
+                            (byte)((currentTime - tracks[tIdx].lastEvtTime) >> 5);
+                }
+            } else {
+                RECORD(tIdx);
+                SWITCH_LED_13();
+            }
+            tracks[tIdx].eIdx = 0;
+        } else {
+            // if recording then add the event in the event table
+            if ((pitch > LAST_RESERVED_KEY) && (IS_RECORDING(tIdx))) {
+                evtPtr = &tracks[tIdx].events[tracks[tIdx].eIdx];
+                if (tracks[tIdx].eIdx == 0) {
+                    evtPtr->delay = 0;
+                } else {
+                    evtPtr->delay =
+                            (byte)((currentTime - tracks[tIdx].lastEvtTime) >> 5);
+                }
+
+                tracks[tIdx].lastEvtTime = currentTime;
+                evtPtr->type = REC_EVT_TYPE_NOTE_ON;
+                evtPtr->pitch = pitch;
+                evtPtr->velocity = velocity;
+
+                // Shift the end of track event
+                tracks[tIdx].eIdx++;
+                evtPtr++;
+                evtPtr->type = REC_EVT_TYPE_EOT;
+                evtPtr->delay = 0;
+            }
+        }
+    }
+}
+
+static void
+handleNoteOff(
+        byte channel,
+        byte pitch,
+        byte velocity)
+{
+    // Do nothing on reserved key.
+    // for the rest, if recording then add the event in the event table
+    byte tIdx = 0;
+    for (tIdx = 0; tIdx < REC_MAX; tIdx++) {
+        if ((pitch > LAST_RESERVED_KEY) && IS_RECORDING(tIdx)){
+            evtPtr = &tracks[tIdx].events[tracks[tIdx].eIdx];
+            if (tracks[tIdx].eIdx == 0) {
+                evtPtr->delay = 0;
+            } else {
+                evtPtr->delay =
+                        (byte)((currentTime - tracks[tIdx].lastEvtTime) >> 5);
+            }
+
+            tracks[tIdx].lastEvtTime = currentTime;
+
+            evtPtr->type = REC_EVT_TYPE_NOTE_OFF;
+            evtPtr->pitch = pitch;
+            evtPtr->velocity = velocity;
+
+            // Shift the end of track event
+            tracks[tIdx].eIdx++;
+            evtPtr++;
+            evtPtr->type = REC_EVT_TYPE_EOT;
+            evtPtr->delay = 0;
+        }
+    }
+}
+
+void
+setup()
+{
+    byte tIdx = 0;
+    pinMode(LED_13, OUTPUT);
+
+    midiLight_setup();
+
+    midiLight_setCallbacks(
+            handleNoteOn,
+            handleNoteOff);
+
+    // config tracks
+    tracks[0].key = KEY_C1;
+    tracks[0].playbackChannel = 1;
+    tracks[1].key = KEY_C1_SHARP;
+    tracks[1].playbackChannel = 2;
+    tracks[2].key = KEY_D1;
+    tracks[2].playbackChannel = 3;
+    for (tIdx = 0; tIdx < REC_MAX; tIdx++) {
+        tracks[tIdx].eIdx = 0;
+        tracks[tIdx].state = REC_STATE_IDLE;
+        tracks[tIdx].events[0].delay = 0;
+        tracks[tIdx].events[0].type = REC_EVT_TYPE_EOT;
+    }
+
+}
+
+
+void
+loop()
+{
+    byte tIdx = 0;
+    currentTime = millis();
+    midiLight_read();
+
+    for (tIdx = 0; tIdx < REC_MAX; tIdx++) {
+        if (IS_PLAYING(tIdx)) {
+            evtPtr = &tracks[tIdx].events[tracks[tIdx].eIdx];
+            // convert the event delay in ms
+            if (tracks[tIdx].eIdx > 0) {
+                evtDelay = (unsigned long)evtPtr->delay;
+                evtDelay <<= 5;
+            }
+
+            // check if the current event has to be played
+            if ((tracks[tIdx].eIdx == 0) || (currentTime > tracks[tIdx].lastEvtTime + evtDelay)){
+                tracks[tIdx].lastEvtTime = currentTime;
+
+                if (evtPtr->type == REC_EVT_TYPE_NOTE_ON) {
+                    midiLight_writeNoteOn(
+                            tracks[tIdx].playbackChannel,
+                            evtPtr->pitch,
+                            evtPtr->velocity);
+                } else if (evtPtr->type == REC_EVT_TYPE_NOTE_OFF) {
+                    midiLight_writeNoteOff(
+                            tracks[tIdx].playbackChannel,
+                            evtPtr->pitch,
+                            evtPtr->velocity);
+                }
+
+                // Update the track index
+                if (evtPtr->type == REC_EVT_TYPE_EOT) {
+                    tracks[tIdx].eIdx = 0;
+                } else {
+                    tracks[tIdx].eIdx++;
+                }
+            }
+
+        }
+    }
+
+}


Added method bool `LedMatrix::get(Row row, Col col)` & example 'TestGet.ino'

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

--- examples/TestGet/TestGet.ino
+++ examples/TestGet/TestGet.ino
@@ -0,0 +1,46 @@
+//We always have to include the library
+#include "LedMatrix.h"
+
+// pin 12 is connected to the DataIn
+// pin 11 is connected to the CLK
+// pin 10 is connected to LOAD
+LedMatrix matrix(12,11,10);
+
+/* we always wait a bit between updates of the display */
+const uint16_t delaytime = 1000;
+
+
+void setup()
+{
+    Serial.begin(9600);
+    // Set the brightness to a medium values
+    matrix.setIntensity(1);
+}
+
+void printSer(const char * str)
+{
+
+    Serial.println("--------------------------");
+    Serial.println(str);
+    Serial.println("--------------------------");
+    for(auto row: matrix.rows()) {
+        for(auto col: matrix.cols()) {
+            Serial.print(matrix.get(row, col) ? ("*  ") : ("-  "));
+        }
+        Serial.println();
+    }
+    Serial.println("==========================");
+}
+
+void loop()
+{
+    matrix.set({B00111111, B00011111, B00001111, B00011111, B00110011, B01100001, B11000111, B10000111});
+    printSer("orig:");
+    delay(delaytime);
+
+    matrix.invert();
+    printSer("inverted:");
+    delay(delaytime);
+
+    matrix.setRotation();
+}


Initial Commit Ex 45 Start

Initial Commit Ex 45 Start

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

--- exercises/45/Excercise45_StartingPoint/Excercise45_StartingPoint.ino
+++ exercises/45/Excercise45_StartingPoint/Excercise45_StartingPoint.ino
@@ -0,0 +1,24 @@
+void setup()
+{
+  //
+  // configure the LED pins as outputs
+  //
+  for (int ledNumber=2; ledNumber<=15; ledNumber++) // enable all the pins to be outputs
+  {
+    pinMode(ledNumber, OUTPUT);
+  }
+}
+void loop()
+{
+  int myFirstArray[5] = {
+    2, 4, 6, 8, 14  }; // creates an array of 5 integers / elements and initializes / assigns values to those integers
+  int index;
+  // Blinks LED's in the order defined by the array
+  for(index = 0; index <= 4; index++)
+  {
+    digitalWrite(myFirstArray[index], HIGH);
+    delay(150);
+    digitalWrite(myFirstArray[index], LOW);
+  }
+  delay(4000);
+}


its a party!

its a party!

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/audetto/Adafruit_Motor_Shield_V2_Library.git/'


Change voltage and current to float in diag


Sandboxing a Mega UARTs example sketch.

Sandboxing a Mega UARTs example sketch.

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

--- examples/Sandbox/CosaMegaUARTs/CosaMegaUARTs.ino
+++ examples/Sandbox/CosaMegaUARTs/CosaMegaUARTs.ino
@@ -0,0 +1,73 @@
+/**
+ * @file CosaMegaUARTs.ino
+ * @version 1.0
+ *
+ * @section License
+ * Copyright (C) 2013, Mikael Patel
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA  02111-1307  USA
+ *
+ * @section Description
+ * Cosa demonstration of the Arduino Mega addition UART support.
+ *
+ * This file is part of the Arduino Che Cosa project.
+ */
+
+#include "Cosa/Trace.hh"
+#include "Cosa/IOBuffer.hh"
+#include "Cosa/IOStream/Driver/UART.hh"
+#include "Cosa/Watchdog.hh"
+
+// Create buffer for UART1
+static IOBuffer<UART::BUFFER_MAX> ibuf;
+static IOBuffer<UART::BUFFER_MAX> obuf;
+
+// Create UART1 and bind to the cout IOStream
+UART uart1(1, &ibuf, &obuf);
+IOStream cout(&uart1);
+
+// Undefine as this is a macro in AVR
+#undef getchar
+
+void setup()
+{
+  // Bind UART1 to the Interrupt Service Routine
+  UART_SETUP(1, uart1);
+
+  // Start the normal trace output
+  uart.begin(9600);
+  trace.begin(&uart, PSTR("CosaMegaUARTs: started"));
+
+  // Start the additional UART
+  uart1.begin(9600);
+  cout << PSTR("Running....");
+
+  // Watchdog for sleeping
+  Watchdog::begin();
+}
+
+void loop()
+{
+  // Tick on cout
+  cout << '.';
+
+  // Transfer character from UART1 to trace
+  while (uart1.available()) trace << (char) uart1.getchar();
+
+  // And take a nap
+  SLEEP(1);
+}
+


adding code for streaming samples (instead of storing them)

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

--- firmware/RFDuino_badge/mic_stream/mic_stream.ino
+++ firmware/RFDuino_badge/mic_stream/mic_stream.ino
@@ -0,0 +1,144 @@
+/************************************************************
+Simple code for mic sampling
+************************************************************/
+
+#include <RFduinoBLE.h>
+
+// get Latest time library from https://github.com/PaulStoffregen/Time.git
+#include <Time.h>
+
+/************************************************************
+Input/output
+************************************************************/
+const int GREEN_LED_PIN = 6;
+const int RED_LED_PIN = 5;
+const int SENSOR_PIN = 2;
+
+
+int cnt = 0;  // number of bytes written
+int snd = 0;  // number of bytes sent
+
+
+// Setup expected "zero" for the mic value.
+// assuming mic has a regulated 2V, on-mic bias is 1/2 (giving us 1V),
+//   reference is set to VBG, and prescaling is 1/3.
+const int zeroValue = 1023/3.6;
+
+/************************************************************
+Sound
+************************************************************/
+const int SAMPLE_WINDOW = 32; // how long we should sample
+const int SAMPLE_WAIT = 64;   // time between samples - must exceed SAMPLE_WINDOW
+unsigned int readingsCount = 0;  //number of mic readings taken \
+unsigned long readingsSum = 0;  //sum of mic readings taken      } for computing average
+
+unsigned int THRESHOLD_VALUE = 15;
+
+/************************************************************
+BLE
+************************************************************/
+boolean isConnected = false;
+const int PACKET_SIZE = 20;
+
+/************************************************************
+Time
+************************************************************/
+
+void setup()
+{
+  // Sets the Reference to 1.2V band gap. Otherwise, if using the VCC as reference
+  // the input will change as the input voltage drops (since the mic is connected to a voltage regulator)
+  analogReference(VBG);
+
+  //Serial.begin(9600); // turn off serial to save battery
+
+  // BLE settings
+  RFduinoBLE.txPowerLevel = 0;
+  RFduinoBLE.deviceName = "MiniBadge";
+  RFduinoBLE.advertisementData = "mic";
+
+  RFduinoBLE.advertisementInterval = 100; //Sets the interval to 100ms
+
+  // LED
+  pinMode(GREEN_LED_PIN, OUTPUT);
+  pinMode(RED_LED_PIN, OUTPUT);
+
+  // start the BLE stack
+  RFduinoBLE.begin();
+
+  // setting MIC pin
+  pinMode(SENSOR_PIN, INPUT);
+
+  // blink to start
+  digitalWrite(GREEN_LED_PIN,HIGH);
+  delay(1000);
+  digitalWrite(GREEN_LED_PIN,LOW);
+}
+
+void loop()
+{
+  unsigned long startMillis = millis();  // Start of sample window
+
+  // get reading
+  unsigned int micValue = 0;
+  micValue = sampleMic();
+
+  // Trigger LED?
+  if (micValue > THRESHOLD_VALUE) {
+    digitalWrite(GREEN_LED_PIN,HIGH);
+  } else {
+    digitalWrite(GREEN_LED_PIN,LOW);
+  }
+
+  // clip the reading
+  byte reading = micValue <= 255 ? micValue : 255;
+
+  RFduinoBLE.sendByte(reading);
+  Serial.println(reading);
+
+  // wait between readings (or between empty iterations... save battery)
+  int timeSpent = millis() - startMillis;
+  timeSpent > 0 ? timeSpent : SAMPLE_WINDOW; // millis() will overflow
+  RFduino_ULPDelay(SAMPLE_WAIT - timeSpent); // Wait before sampling again, put RFDuino to sleep
+}
+
+/* Reading mic values */
+int sampleMic() {
+  unsigned long sampleStartMillis= millis();  // Start of sample window
+  unsigned int sample;
+  int adjustedSample;
+  unsigned int count = 0;
+  unsigned long sum = 0;
+
+  unsigned int micValue = 0;
+  unsigned int trimmerValue = 0;
+
+  // collect data for XX mS
+  while (millis() - sampleStartMillis < SAMPLE_WINDOW && millis() - sampleStartMillis >= 0)
+   {
+      sample = analogRead(SENSOR_PIN);
+      if (sample < 1024) { // toss out spurious readings
+            count += 1;
+            adjustedSample = sample - zeroValue;  // adjust reading based on "real" zero
+            adjustedSample = abs(adjustedSample); //must keep as seperate line.. soemthing todo with abs() implemetnation
+            sum = sum + adjustedSample;
+      }
+   }
+
+  // calc average amplitude
+  micValue = sum / count;
+
+  return micValue;
+}
+
+void RFduinoBLE_onConnect() {
+  Serial.println("Connected");
+  isConnected = true;
+}
+
+void RFduinoBLE_onDisconnect() {
+  Serial.println("Disconnected");
+  isConnected = false;
+}
+
+


Update Initialization.ino

Update Initialization.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/Electroscholars/Motor.git/'


Create MicroMRLComm.ino

Create MicroMRLComm.ino

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

--- home/Markus/MicroMRLComm.ino
+++ home/Markus/MicroMRLComm.ino
@@ -0,0 +1,1274 @@
+/**
+*
+* @author GroG (at) myrobotlab.org
+*
+* This file is part of MyRobotLab.
+*
+* Enjoy !
+*
+* MRLComm.ino
+* -----------------
+* Purpose: support servos, sensors, analog & digital polling
+* oscope, motors, range sensors, pingdar & steppers.
+*
+* Requirements: MyRobotLab running on a computer & a serial connection
+*
+*/
+
+#include <Servo.h>
+#define MRLCOMM_VERSION				24
+
+// serial protocol functions
+#define MAGIC_NUMBER  					170 // 10101010
+
+// ----- MRLCOMM FUNCTION GENERATED INTERFACE BEGIN -----------
+///// INO GENERATED DEFINITION BEGIN //////
+// {publishMRLCommError Integer}
+#define PUBLISH_MRLCOMM_ERROR		1
+
+// {getVersion}
+#define GET_VERSION		2
+
+// {publishVersion Integer}
+#define PUBLISH_VERSION		3
+
+// {analogReadPollingStart Integer}
+#define ANALOG_READ_POLLING_START		4
+
+// {analogReadPollingStop Integer}
+#define ANALOG_READ_POLLING_STOP		5
+
+// {analogWrite Integer Integer}
+#define ANALOG_WRITE		6
+
+// {digitalReadPollingStart Integer}
+#define DIGITAL_READ_POLLING_START		7
+
+// {digitalReadPollingStop Integer}
+#define DIGITAL_READ_POLLING_STOP		8
+
+// {digitalWrite Integer Integer}
+#define DIGITAL_WRITE		9
+
+// {motorAttach String String Integer Integer Integer}
+#define MOTOR_ATTACH		10
+
+// {motorDetach String}
+#define MOTOR_DETACH		11
+
+// {motorMove String}
+#define MOTOR_MOVE		12
+
+// {motorMoveTo String double}
+#define MOTOR_MOVE_TO		13
+
+// {pinMode Integer Integer}
+#define PIN_MODE		14
+
+// {publishCustomMsg Object[]}
+#define PUBLISH_CUSTOM_MSG		15
+
+// {publishLoadTimingEvent Long}
+#define PUBLISH_LOAD_TIMING_EVENT		16
+
+// {publishPin Pin}
+#define PUBLISH_PIN		17
+
+// {publishPulse Integer}
+#define PUBLISH_PULSE		18
+
+// {publishSensorData SensorData}
+#define PUBLISH_SENSOR_DATA		19
+
+// {publishServoEvent Integer}
+#define PUBLISH_SERVO_EVENT		20
+
+// {publishStepperEvent Integer}
+#define PUBLISH_STEPPER_EVENT		21
+
+// {publishTrigger Pin}
+#define PUBLISH_TRIGGER		22
+
+// {pulseIn int int int String}
+#define PULSE_IN		23
+
+// {sensorAttach String}
+#define SENSOR_ATTACH		24
+
+// {sensorPollingStart String int}
+#define SENSOR_POLLING_START		25
+
+// {sensorPollingStop String}
+#define SENSOR_POLLING_STOP		26
+
+// {servoAttach String Integer}
+#define SERVO_ATTACH		27
+
+// {servoDetach Servo}
+#define SERVO_DETACH		28
+
+// {servoSweepStart String int int int}
+#define SERVO_SWEEP_START		29
+
+// {servoSweepStop String}
+#define SERVO_SWEEP_STOP		30
+
+// {servoWrite String Integer}
+#define SERVO_WRITE		31
+
+// {servoWriteMicroseconds String Integer}
+#define SERVO_WRITE_MICROSECONDS		32
+
+// {setDebounce int}
+#define SET_DEBOUNCE		33
+
+// {setDigitalTriggerOnly Boolean}
+#define SET_DIGITAL_TRIGGER_ONLY		34
+
+// {setLoadTimingEnabled boolean}
+#define SET_LOAD_TIMING_ENABLED		35
+
+// {setPWMFrequency Integer Integer}
+#define SET_PWMFREQUENCY		36
+
+// {setSampleRate int}
+#define SET_SAMPLE_RATE		37
+
+// {setSerialRate int}
+#define SET_SERIAL_RATE		38
+
+// {setServoEventsEnabled String boolean}
+#define SET_SERVO_EVENTS_ENABLED		39
+
+// {setServoSpeed String Float}
+#define SET_SERVO_SPEED		40
+
+// {setStepperSpeed Integer}
+#define SET_STEPPER_SPEED		41
+
+// {setTrigger int int int}
+#define SET_TRIGGER		42
+
+// {softReset}
+#define SOFT_RESET		43
+
+// {stepperAttach Stepper}
+#define STEPPER_ATTACH		44
+
+// {stepperDetach String}
+#define STEPPER_DETACH		45
+
+// {stepperMoveTo String int int}
+#define STEPPER_MOVE_TO		46
+
+// {stepperReset String}
+#define STEPPER_RESET		47
+
+// {stepperStop String}
+#define STEPPER_STOP		48
+
+// {stopService}
+#define STOP_SERVICE		49
+
+///// INO GENERATED DEFINITION END //////
+
+// ----- MRLCOMM FUNCTION GENERATED INTERFACE END -----------
+
+#define STEPPER_TYPE_SIMPLE  			1
+
+// ------ event types ------
+#define STEPPER_EVENT_STOP				1
+#define STEPPER_EVENT_STEP				2
+
+// servo event types
+#define  SERVO_EVENT_STOPPED			1
+#define  SERVO_EVENT_POSITION_UPDATE 	2
+
+// error types
+#define ERROR_SERIAL					1
+#define ERROR_UNKOWN_CMD				2
+#define ERROR_ALREADY_EXISTS			3
+#define ERROR_DOES_NOT_EXIST			4
+
+// ------ error types ------
+#define SENSOR_ULTRASONIC				1
+
+#define CUSTOM_MSG						50
+
+// need a method to identify type of board
+// http://forum.arduino.cc/index.php?topic=100557.0
+
+#define COMMUNICATION_RESET	   252
+#define SOFT_RESET			   253
+#define NOP  				   255
+
+// ----------  MRLCOMM FUNCTION INTERFACE END -----------
+
+// MAX definitions
+// MAX_SERVOS defined by boardtype/library
+#define PINGDARS_MAX		6
+#define SENSORS_MAX			12
+#define STEPPERS_MAX		6
+
+#define MAX_MOTORS 10
+
+#define ECHO_STATE_START 1
+#define ECHO_STATE_TRIG_PULSE_BEGIN 2
+#define ECHO_STATE_TRIG_PULSE_END 3
+#define ECHO_STATE_MIN_PAUSE_PRE_LISTENING 4
+#define ECHO_STATE_LISTENING 5
+#define ECHO_STATE_GOOD_RANGE	6
+#define ECHO_STATE_TIMEOUT	7
+
+// --VENDOR DEFINE SECTION BEGIN--
+// --VENDOR DEFINE SECTION END--
+
+// FIXME FIXME FIXME
+// -- FIXME - modified by board type BEGIN --
+// Need Arduino to do a hardware abstraction layer
+// https://code.google.com/p/arduino/issues/detail?id=59
+// AHAAA !! - many defintions in - pins_arduino.h !!!
+// Need a "board" identifier at least !!!
+
+#define ANALOG_PIN_COUNT 16 // mega
+#define DIGITAL_PIN_COUNT 54 // mega
+// #define MAX_SERVOS 48 - is defined @ compile time !!
+// -- FIXME - modified by board type END --
+
+#define ARDUINO_TYPE_INT 16; // :) type identifier - not size - but what the hell ;)
+
+/*
+* TODO - CRC for last byte
+* getCommand - retrieves a command message
+* inbound and outbound messages are the same format, the following represents a basic message
+* format
+*
+* MAGIC_NUMBER|NUM_BYTES|FUNCTION|DATA0|DATA1|....|DATA(N)
+*              NUM_BYTES - is the number of bytes after NUM_BYTES to the end
+*
+*/
+
+int msgSize = 0; // the NUM_BYTES of current message
+
+unsigned int debounceDelay = 50; // in ms
+long lastDebounceTime[DIGITAL_PIN_COUNT];
+byte msgBuf[64];
+
+typedef struct
+  {
+      int type;
+      int trigPin;
+      int echoPin;
+      bool isRunning;
+      int timeoutUS;
+      unsigned long ts;
+      unsigned long lastValue;
+      int state;
+      //NewPing* ping;
+  }  sensor_type;
+
+sensor_type sensors[SENSORS_MAX];
+
+typedef struct
+  {
+  	  int ts;
+      int type;
+      int index; // is this redundant?
+      int currentPos;
+      int targetPos;
+      int speed;
+
+      int dirPin;
+      int stepPin;
+
+	  // support up to 5 wire steppers
+      int pin0;
+      int pin1;
+      int pin2;
+      int pin3;
+      int pin4;
+
+  }  stepper_type;
+
+stepper_type steppers[STEPPERS_MAX];
+
+// Servos
+typedef struct
+{
+    Servo* servo;
+    int index; // index of this servo
+    int speed;
+    int targetPos;
+    int currentPos;
+    bool isMoving;
+
+    int step; // affects speed usually 1
+
+    // sweep related
+    int min;
+    int max;
+    // int delay; - related to speed
+    int increment;
+    bool isSweeping;
+
+    // event related
+    bool eventsEnabled;
+} servo_type;
+
+
+servo_type servos[MAX_SERVOS];
+
+// Motors
+typedef struct
+{
+    int index; // index of this motor
+    int speed;
+    int targetPos;
+    int currentPos;
+    bool isMoving;
+
+    int step; // affects speed usually 1
+
+    // sweep related
+    int min;
+    int max;
+    // int delay; - related to speed
+    int increment;
+    bool isSweeping;
+
+    // event related
+    bool eventsEnabled;
+} motor_type;
+
+motor_type motors[MAX_MOTORS];
+
+unsigned long loopCount     = 0;
+unsigned long lastMicros 	= 0;
+int byteCount               = 0;
+unsigned char newByte 		= 0;
+unsigned char ioCmd[64];  // message buffer for all inbound messages
+int readValue;
+
+// FIXME - normalize with sampleRate ..
+int loadTimingModulus = 1000;
+
+boolean loadTimingEnabled = false;
+unsigned long loadTime = 0;
+// TODO - avg load time
+
+unsigned int sampleRate = 1; // 1 - 65,535 modulus of the loopcount - allowing you to sample less
+
+int digitalReadPin[DIGITAL_PIN_COUNT];        // array of pins to read from
+int digitalReadPollingPinCount = 0;           // number of pins currently reading
+int lastDigitalInputValue[DIGITAL_PIN_COUNT]; // array of last input values
+bool digitalTriggerOnly	= false;      // send data back only if its different
+
+int analogReadPin[ANALOG_PIN_COUNT];          // array of pins to read from
+int analogReadPollingPinCount = 0;            // number of pins currently reading
+int lastAnalogInputValue[ANALOG_PIN_COUNT];   // array of last input values
+bool analogTriggerOnly = false;         // send data back only if its different
+
+//---- data record definitions begin -----
+
+
+// TODO - all well and good .. but you dont control Servo's data (yet)
+// should have a struct for it too - contains all the data info you'd want to have
+// in a servo - same with stepper
+
+typedef struct
+  {
+      int servoIndex; // id of servo in servos array
+      //int servoPos; in servo
+      int sensorIndex;
+      int sweepMin;
+      int sweepMax;
+      int step;
+      bool isRunning; // needed ? - is combo of two
+  }  pingdar_type;
+
+pingdar_type pingdars[PINGDARS_MAX];
+//===custom msg interface begin===
+	byte customParams[256];
+	int paramBuffIndex;
+	int paramCnt;
+//===custom msg interface end===
+
+void sendServoEvent(servo_type& s, int eventType);
+void sendStepperEvent(stepper_type& s, int eventType);
+unsigned long getUltrasonicRange(sensor_type& sensor);
+// void sendMsg ( int num, ... );
+
+//---- data record definitions end -----
+
+void append(const int& data) {
+	++paramCnt;
+	customParams[paramBuffIndex] = ARDUINO_TYPE_INT;
+	customParams[++paramBuffIndex] = (byte)(data >> 8);
+	customParams[++paramBuffIndex] = ((byte) data & 0xff);
+	++paramBuffIndex;
+}
+
+void startMsg() {
+}
+
+void setup() {
+	Serial.begin(57600);        // connect to the serial port
+
+	softReset();
+
+	// --VENDOR SETUP BEGIN--
+	// --VENDOR SETUP END--
+}
+
+
+void sendMsg(){
+
+	// unbox
+	Serial.write(MAGIC_NUMBER);
+	Serial.write(paramBuffIndex + 2); // = param buff size + FN + paramCnt
+	//Serial.write(2); // = param buff size + FN + paramCnt
+	Serial.write(CUSTOM_MSG);
+	Serial.write(paramCnt);
+
+	for (int i = 0; i < paramBuffIndex; ++i){
+		Serial.write(customParams[i]);
+	}
+
+	paramCnt = 0;
+	paramBuffIndex = 0;
+}
+
+
+
+void softReset()
+{
+	for (int i = 0; i < MAX_SERVOS - 1; ++i)
+	{
+                servo_type& s = servos[i];
+		s.speed = 100;
+                if (s.servo != 0){
+		  s.servo->detach();
+                }
+	}
+
+	for (int j = 0; j < DIGITAL_PIN_COUNT - 1; ++j)
+	{
+		pinMode(j, OUTPUT);
+	}
+
+
+	digitalReadPollingPinCount = 0;
+	analogReadPollingPinCount = 0;
+	loopCount = 0;
+
+}
+
+void setPWMFrequency (int address, int prescalar)
+{
+	int clearBits = 0x07;
+	if (address == 0x25)
+	{
+		TCCR0B &= ~clearBits;
+		TCCR0B |= prescalar;
+	} else if (address == 0x2E)
+	{
+		TCCR1B &= ~clearBits;
+		TCCR1B |= prescalar;
+	} else if (address == 0xA1)
+	{
+		//TCCR2B &= ~clearBits;
+		//TCCR2B |= prescalar;
+	}
+
+}
+
+/**
+ * checks the existance of the searched value in the array
+ * - good for not adding to a dynamic list of values if it
+ * already exists
+ */
+bool exists(int array[], int len, int searchValue){
+	for (int i = 0; i < len; ++i)
+	{
+		if (searchValue == array[i])
+		{
+			return true;
+		}
+	}
+	return false;
+}
+
+/**
+ * adds new value to a pseudo dynamic array/list
+ * if successful - if value already exists on list
+ * sends back an error
+ */
+bool addNewValue(int array[], int& len, int addValue)
+{
+	if (!exists(array, len, addValue)){
+		array[len] = addValue;
+		++len;
+		return true;
+	} else {
+		sendError(ERROR_ALREADY_EXISTS);
+		return false;
+	}
+}
+
+
+bool removeAndShift (int array [], int& len, int removeValue)
+{
+	if (!exists(array, len, removeValue)){
+		sendError(ERROR_DOES_NOT_EXIST);
+		return false;
+	}
+
+	int pos = -1;
+
+	if (len == 0)
+	{
+		// "should" never happen
+		// would be calling remove on an empty list
+		// the error ERROR_DOES_NOT_EXIST - "should" be called
+		return true;
+	}
+
+	// find position of value
+	for (int i = 0; i < len; ++i)
+	{
+		if (removeValue == array[i])
+		{
+			pos = i;
+			break;
+		}
+	}
+	// if at the end just decrement size
+	if (pos == len - 1)
+	{
+		--len;
+		return true;
+	}
+
+	// if found somewhere else shift left
+	if (pos < len && pos > -1)
+	{
+		for (int j = pos; j < len - 1; ++j)
+		{
+			array[j] = array[j+1];
+		}
+		--len;
+	}
+
+	return true;
+}
+
+boolean getCommand ()
+{
+	// handle serial data begin
+	if (Serial.available() > 0)
+	{
+		// read the incoming byte:
+		newByte = Serial.read();
+		++byteCount;
+
+		// checking first byte - beginning of message?
+		if (byteCount == 1 && newByte != MAGIC_NUMBER)
+		{
+			sendError(ERROR_SERIAL);
+
+			// reset - try again
+			byteCount = 0;
+			return false;
+		}
+
+		if (byteCount == 2)
+		{
+		   // get the size of message
+		   // todo check msg < 64 (MAX_MSG_SIZE)
+		   msgSize = newByte;
+		}
+
+		if (byteCount > 2) {
+		  // fill in msg data - (2) headbytes -1 (offset)
+		  ioCmd[byteCount - 3] = newByte;
+		}
+
+		// if received header + msg
+		if (byteCount == 2 + msgSize)
+		{
+          return true;
+		}
+	} // if Serial.available
+
+	return false;
+}
+
+void loop () {
+
+	++loopCount;
+
+	if (getCommand())
+	{
+		switch (ioCmd[0])
+		{
+
+		case DIGITAL_WRITE:{
+			digitalWrite(ioCmd[1], ioCmd[2]);
+			break;
+		}
+
+		case ANALOG_WRITE:{
+			analogWrite(ioCmd[1], ioCmd[2]);
+			break;
+		}
+
+		case PIN_MODE:{
+			pinMode(ioCmd[1], ioCmd[2]);
+			break;
+		}
+
+		case SERVO_ATTACH:{
+			servo_type& s = servos[ioCmd[1]];
+			s.index = ioCmd[1];
+			if (s.servo == NULL){
+				s.servo = new Servo();
+			}
+			s.servo->attach(ioCmd[2]);
+			s.step = 1;
+			s.eventsEnabled = false;
+			break;
+		}
+
+		case SERVO_SWEEP_START:{
+			servo_type& s = servos[ioCmd[1]];
+			s.min = ioCmd[2];
+			s.max = ioCmd[3];
+			s.step = ioCmd[4];
+			s.isMoving = true;
+			s.isSweeping = true;
+			break;
+		}
+
+		case SERVO_SWEEP_STOP:{
+			servo_type& s = servos[ioCmd[1]];
+			s.isMoving = false;
+			s.isSweeping = false;
+			break;
+		}
+
+		case SERVO_WRITE:{
+			servo_type& s = servos[ioCmd[1]];
+			if (s.speed == 100 && s.servo != 0)// move at regular/full 100% speed
+			{
+				s.targetPos = ioCmd[2];
+				s.currentPos = ioCmd[2];
+				s.isMoving = false;
+				s.servo->write(ioCmd[2]);
+				if (s.eventsEnabled) sendServoEvent(s, SERVO_EVENT_STOPPED);
+			} else if (s.speed < 100 && s.speed > 0) {
+				s.targetPos = ioCmd[2];
+				s.isMoving = true;
+			}
+			break;
+		}
+
+		case PUBLISH_SERVO_EVENT:{
+			servo_type& s = servos[ioCmd[1]];
+			s.eventsEnabled = ioCmd[2];
+			break;
+		}
+
+		case SET_LOAD_TIMING_ENABLED:{
+			loadTimingEnabled = ioCmd[1];
+			//loadTimingModulus = ioCmd[2];
+			loadTimingModulus = 1000;
+			break;
+		}
+
+		case SERVO_WRITE_MICROSECONDS:{
+			// TODO - incorporate into speed control etc
+			// normalize - currently by itself doesn't effect events
+			// nor is it involved in speed control
+			servo_type& s = servos[ioCmd[1]];
+			if (s.servo != 0) {
+				// 1500 midpoint
+				s.servo->writeMicroseconds(ioCmd[2]);
+			}
+
+			break;
+		}
+
+		case SET_SERVO_SPEED:{
+			// setting the speed of a servo
+			servo_type& servo = servos[ioCmd[1]];
+			servo.speed = ioCmd[2];
+			break;
+		}
+
+		case SERVO_DETACH:{
+			servo_type& s = servos[ioCmd[1]];
+			if (s.servo != 0){
+			  s.servo->detach();
+			}
+			break;
+		}
+
+		case SET_PWMFREQUENCY:{
+			setPWMFrequency (ioCmd[1], ioCmd[2]);
+			break;
+		}
+
+		case ANALOG_READ_POLLING_START:{
+			int pin = ioCmd[1];
+			addNewValue(analogReadPin, analogReadPollingPinCount, pin);
+			break;
+		}
+
+		case ANALOG_READ_POLLING_STOP:{
+			int pin = ioCmd[1];
+			removeAndShift(analogReadPin, analogReadPollingPinCount, pin);
+			break;
+		}
+
+		case DIGITAL_READ_POLLING_START:{
+			int pin = ioCmd[1];
+			addNewValue(digitalReadPin, digitalReadPollingPinCount, pin);
+			break;
+		}
+
+		case DIGITAL_READ_POLLING_STOP:{
+			int pin = ioCmd[1];
+			removeAndShift(digitalReadPin, digitalReadPollingPinCount, pin);
+			break;
+		}
+
+		case SET_TRIGGER:{
+                        // FIXME !!! - you need 1. a complete pin list !!!   analog & digital should be defined by attribute not
+                        // data structure !!!  if (pin.type == ??? if needed
+			// TODO - if POLLING ALREADY DON'T RE-ADD - MAKE RE-ENTRANT
+			analogReadPin[analogReadPollingPinCount] = ioCmd[1]; // put on polling read list
+			++analogReadPollingPinCount;
+			break;
+		}
+
+		case SET_DEBOUNCE:{
+			// default debounceDelay = 50;
+			debounceDelay = ((ioCmd[1]<<8) + ioCmd[2]);
+			break;
+		}
+
+		case SET_DIGITAL_TRIGGER_ONLY:{
+			digitalTriggerOnly = ioCmd[1];
+			break;
+                }
+
+		case SET_SERIAL_RATE:
+		{
+			Serial.end();
+			delay(500);
+			Serial.begin(ioCmd[1]);
+			break;
+		}
+
+		case GET_VERSION:{
+			Serial.write(MAGIC_NUMBER);
+			Serial.write(2); // size
+			Serial.write(PUBLISH_VERSION);
+			Serial.write((byte)MRLCOMM_VERSION);
+			break;
+			}
+
+		case PULSE_IN: {
+		    // might need to hack the pulseIn lib - but would
+		    // like to do it without delay
+			// http://arduino.cc/en/Tutorial/BlinkWithoutDelay
+			int trigPin = ioCmd[1];
+			int echoPin = ioCmd[2];
+			// TODO - implement HI/LOW value & timeout & variable delay for trigger
+
+			pinMode(trigPin, OUTPUT);
+			pinMode(echoPin, INPUT);
+
+			digitalWrite(trigPin, LOW);
+			delayMicroseconds(2);
+
+			digitalWrite(trigPin, HIGH);
+			delayMicroseconds(10);
+
+			digitalWrite(trigPin, LOW);
+			unsigned long duration = pulseIn(echoPin, HIGH);
+
+			//Calculate the distance (in cm) based on the speed of sound.
+			// distance = duration/58.2;
+
+			//sendMsg(4, ANALOG_VALUE, analogReadPin[i], readValue >> 8, readValue & 0xff);
+ 			//sendMsg(5, PULSE_IN, duration >> 24, duration >> 16, duration >> 8, duration & 0xff);
+ 			//sendMsg(6, SENSOR_DATA, 47, duration >> 24, duration >> 16, duration >> 8, duration & 0xff);
+
+
+			Serial.write(MAGIC_NUMBER);
+			Serial.write(5); // size 1 FN + 4 bytes of unsigned long
+			Serial.write(PULSE_IN);
+            // write the long value out
+			Serial.write((byte)(duration >> 24));
+			Serial.write((byte)(duration >> 16));
+			Serial.write((byte)(duration >> 8));
+			Serial.write((byte)duration & 0xff);
+
+
+			break;
+		}
+
+		case SET_SAMPLE_RATE:{
+			// 2 byte int - valid range 1-65,535
+			sampleRate = (ioCmd[1]<<8) + ioCmd[2];
+			if (sampleRate == 0)
+				{ sampleRate = 1; } // avoid /0 error - FIXME - time estimate param
+			break;
+		}
+
+		case SOFT_RESET:{
+			softReset();
+			break;
+		}
+
+		case STEPPER_ATTACH:{
+			stepper_type& stepper = steppers[ioCmd[1]];
+			stepper.index = ioCmd[1];
+			stepper.type = ioCmd[2];
+			stepper.currentPos = 0;
+			stepper.targetPos = 0;
+			stepper.speed = 100;
+
+			if (stepper.type == STEPPER_TYPE_SIMPLE) {
+				stepper.dirPin = ioCmd[3]; // dir pin
+				stepper.stepPin = ioCmd[4]; // step pin
+				pinMode(stepper.dirPin, OUTPUT);
+				pinMode(stepper.stepPin, OUTPUT);
+			} else {
+				sendError(ERROR_UNKOWN_CMD);
+			}
+			break;
+		}
+
+		case STEPPER_RESET:{
+			stepper_type& stepper = steppers[ioCmd[1]];
+			stepper.currentPos = 0;
+			stepper.targetPos = 0;
+			stepper.speed = 100;
+			break;
+		}
+
+		/* absolute position - not relative */
+		case STEPPER_MOVE_TO:{
+			stepper_type& stepper = steppers[ioCmd[1]];
+			if (stepper.type == STEPPER_TYPE_SIMPLE) {
+				stepper.targetPos = stepper.currentPos + (ioCmd[2]<<8) + ioCmd[3];
+				// relative position & direction
+				if (stepper.targetPos < 0) {
+					// direction
+					digitalWrite(stepper.dirPin, 1);
+				} else {
+					digitalWrite(stepper.dirPin, 0);
+				}
+			} else {
+				sendError(ERROR_UNKOWN_CMD);
+			}
+			break;
+		}
+
+		case STEPPER_STOP:{
+			stepper_type& stepper = steppers[ioCmd[1]];
+			if (stepper.type == STEPPER_TYPE_SIMPLE) {
+				stepper.targetPos = stepper.currentPos;
+				sendStepperEvent(stepper, STEPPER_EVENT_STOP);
+			} else {
+				sendError(ERROR_UNKOWN_CMD);
+			}
+			break;
+		}
+
+			// --VENDOR CODE BEGIN--
+			// --VENDOR CODE END--
+// not sure if its worth implementing - same info can be retrieved from publish servo event & publish pin
+/*
+
+		case PINGDAR_ATTACH:{
+			int pingdarIndex = ioCmd[1];
+			pingdar_type& pingdar = pingdars[pingdarIndex];
+			pingdar.servoIndex = ioCmd[2];
+			pingdar.sensorIndex = ioCmd[3];
+			pingdar.step = 1;
+			break;
+		}
+*/
+		// used by ultrasonic sensor
+		case SENSOR_ATTACH:{
+			int sensorIndex = ioCmd[1];
+			sensor_type& sensor = sensors[sensorIndex];
+			sensor.type = ioCmd[2];
+
+
+
+			// initialize based on sensor type
+			if (sensor.type == SENSOR_ULTRASONIC){
+				sensor.trigPin = ioCmd[3];
+				sensor.echoPin = ioCmd[4];
+				pinMode(sensor.trigPin, OUTPUT);
+				pinMode(sensor.echoPin, INPUT);
+				//sensor.ping = new NewPing(sensor.trigPin, sensor.echoPin, 100);
+			}
+
+			break;
+		}
+
+		case SENSOR_POLLING_START:{
+			int sensorIndex = ioCmd[1];
+			sensor_type& sensor = sensors[sensorIndex];
+			sensor.isRunning = true;
+
+			// I'm used to ms - and would need to change some
+			// interfaces if i was to support inbound longs
+			//sensor.timeoutUS = ioCmd[2] * 1000;
+			sensor.timeoutUS = 20000; // 20 ms
+			sensor.state = ECHO_STATE_START;
+
+			break;
+		}
+
+		case SENSOR_POLLING_STOP:{
+			int sensorIndex = ioCmd[1];
+			sensor_type& sensor = sensors[sensorIndex];
+			sensor.isRunning = false;
+			break;
+		}
+
+		case NOP:{
+			// No Operation
+			break;
+		}
+
+		default:{
+		    sendError(ERROR_UNKOWN_CMD);
+			break;
+		}
+		} // end switch
+
+		// reset buffer
+		memset(ioCmd,0,sizeof(ioCmd));
+		byteCount = 0;
+
+	} // if getCommand()
+
+	// all reads are affected by sample rate
+	if (loopCount%sampleRate == 0) {
+		// digital polling read - send data for pins which are currently in INPUT mode only AND whose state has changed
+		for (int i  = 0; i < digitalReadPollingPinCount; ++i)
+		{
+			if (debounceDelay)
+			{
+			  if (millis() - lastDebounceTime[digitalReadPin[i]] < debounceDelay)
+			  {
+			    continue;
+			  }
+			}
+
+			// FIXME !! - normalize with analog
+			// read the pin
+			readValue = digitalRead(digitalReadPin[i]);
+
+			// if my value is different from last time  && config - send it
+			if (lastDigitalInputValue[digitalReadPin[i]] != readValue  || !digitalTriggerOnly)
+			{
+				Serial.write(MAGIC_NUMBER);
+				Serial.write(4); // size
+				Serial.write(PUBLISH_PIN);
+				Serial.write(digitalReadPin[i]);// Pin#
+				Serial.write((byte)0); 	// MSB
+				Serial.write(readValue); 	// LSB
+
+			    lastDebounceTime[digitalReadPin[i]] = millis();
+			}
+
+			// set the last input value of this pin
+			lastDigitalInputValue[digitalReadPin[i]] = readValue;
+		}
+
+
+		// analog polling read - send data for pins which are currently in INPUT mode only AND whose state has changed
+		for (int i  = 0; i < analogReadPollingPinCount; ++i)
+		{
+			// read the pin
+			readValue = analogRead(analogReadPin[i]);
+
+			// if my value is different from last time - send it
+			if (lastAnalogInputValue[analogReadPin[i]] != readValue   || !analogTriggerOnly) //TODO - SEND_DELTA_MIN_DIFF
+			{
+				//sendMsg(4, ANALOG_VALUE, analogReadPin[i], readValue >> 8, readValue & 0xff);
+
+				Serial.write(MAGIC_NUMBER);
+				Serial.write(4); //size
+				Serial.write(PUBLISH_PIN);
+				Serial.write(analogReadPin[i]);
+				Serial.write(readValue >> 8);   // MSB
+				Serial.write(readValue & 0xff);	// LSB
+
+	        }
+			// set the last input value of this pin
+			lastAnalogInputValue[analogReadPin[i]] = readValue;
+		}
+	}
+
+	// update moving servos - send events if required
+	for (int i = 0; i < MAX_SERVOS; ++i)
+	{
+		servo_type& s = servos[i];
+		if (s.isMoving && s.servo != 0){
+			if (s.currentPos != s.targetPos)
+			{
+				// caclulate the appropriate modulus to drive
+				// the servo to the next position
+				// TODO - check for speed > 0 && speed < 100 - send ERROR back?
+				int speedModulus = (100 - s.speed) * 10;
+				if (loopCount % speedModulus == 0)
+				{
+					int increment = s.step * ((s.currentPos < s.targetPos)?1:-1);
+					// move the servo an increment
+					s.currentPos = s.currentPos + increment;
+					s.servo->write(s.currentPos);
+					if (s.eventsEnabled) sendServoEvent(s, SERVO_EVENT_POSITION_UPDATE);
+				}
+			} else {
+				if (s.isSweeping) {
+					if (s.targetPos == s.min){
+						s.targetPos = s.max;
+					} else {
+						s.targetPos = s.min;
+					}
+				} else {
+					if (s.eventsEnabled) sendServoEvent(s, SERVO_EVENT_STOPPED);
+					s.isMoving = false;
+				}
+			}
+		}
+	}
+
+	unsigned long ts;
+
+	for (int i = 0; i < SENSORS_MAX; ++i) {
+		sensor_type& sensor = sensors[i];
+		if (sensor.isRunning == true){
+			if (sensor.type == SENSOR_ULTRASONIC){
+
+				// we are running & have an ultrasonic (ping) sensor
+				// check to see what state we  are in
+
+				if (sensor.state == ECHO_STATE_START){
+					// trigPin prepare - start low for an
+					// upcoming high pulse
+					pinMode(sensor.trigPin, OUTPUT);
+					digitalWrite(sensor.trigPin, LOW);
+
+					// put the echopin into a high state
+					// is this necessary ???
+					pinMode(sensor.echoPin, OUTPUT);
+					digitalWrite(sensor.echoPin, HIGH);
+
+					ts = micros();
+					if (ts - sensor.ts > 2){
+						sensor.ts = ts;
+						sensor.state = ECHO_STATE_TRIG_PULSE_BEGIN;
+					}
+				} else if (sensor.state == ECHO_STATE_TRIG_PULSE_BEGIN){
+
+					// begin high pulse for at least 10 us
+					pinMode(sensor.trigPin, OUTPUT);
+					digitalWrite(sensor.trigPin, HIGH);
+
+					ts = micros();
+					if (ts - sensor.ts > 10){
+						sensor.ts = ts;
+						sensor.state = ECHO_STATE_TRIG_PULSE_END;
+					}
+				} else if (sensor.state == ECHO_STATE_TRIG_PULSE_END){
+					// end of pulse
+					pinMode(sensor.trigPin, OUTPUT);
+					digitalWrite(sensor.trigPin, LOW);
+
+					sensor.state = ECHO_STATE_MIN_PAUSE_PRE_LISTENING;
+					sensor.ts = micros();
+				} else if (sensor.state == ECHO_STATE_MIN_PAUSE_PRE_LISTENING){
+
+					ts = micros();
+					if (ts - sensor.ts > 1500){
+						sensor.ts = ts;
+
+						// putting echo pin into listen mode
+						pinMode(sensor.echoPin, OUTPUT);
+						digitalWrite(sensor.echoPin, HIGH);
+						pinMode(sensor.echoPin, INPUT);
+
+						sensor.state = ECHO_STATE_LISTENING;
+					}
+
+				} else if (sensor.state == ECHO_STATE_LISTENING) {
+					// timeout or change states..
+					int value = digitalRead(sensor.echoPin);
+					ts = micros();
+
+					if (value == LOW) {
+						sensor.lastValue = ts - sensor.ts;
+						sensor.ts = ts;
+						sensor.state = ECHO_STATE_GOOD_RANGE;
+					} else if (ts - sensor.ts > sensor.timeoutUS) {
+						sensor.state = ECHO_STATE_TIMEOUT;
+						sensor.ts = ts;
+						sensor.lastValue = 0;
+					}
+
+				} else if (sensor.state == ECHO_STATE_GOOD_RANGE || sensor.state == ECHO_STATE_TIMEOUT) {
+					Serial.write(MAGIC_NUMBER);
+					Serial.write(6); // size 1 FN + 4 bytes of unsigned long
+					Serial.write(PUBLISH_SENSOR_DATA);
+					Serial.write(i);
+		            // write the long value out
+					Serial.write((byte)(sensor.lastValue >> 24));
+					Serial.write((byte)(sensor.lastValue >> 16));
+					Serial.write((byte)(sensor.lastValue >> 8));
+					Serial.write((byte) sensor.lastValue & 0xff);
+					sensor.state = ECHO_STATE_START;
+				} // end else if
+
+			} // if (sensor.type == SENSOR_ULTRASONIC)
+
+		} // end isRunning
+
+	} // end for each sensor
+
+	// TODO - brake - speed - fractional stepping - other stepper types
+	for (int i = 0; i < STEPPERS_MAX; ++i) {
+		stepper_type& stepper = steppers[i];
+		if (stepper.currentPos != stepper.targetPos){
+			if (stepper.type == STEPPER_TYPE_SIMPLE){
+
+				// direction is already set in initial STEPPER_MOVE
+
+				if (stepper.currentPos < stepper.targetPos) {
+					digitalWrite(stepper.stepPin, 1);
+					delayMicroseconds(1); // :P should require another state? loop is ~106us min ?
+					digitalWrite(stepper.stepPin, 0);
+					stepper.currentPos++;
+					sendStepperEvent(stepper, STEPPER_EVENT_STEP);
+
+				} else if (stepper.currentPos > stepper.targetPos) {
+					digitalWrite(stepper.stepPin, 1);
+					delayMicroseconds(1); // :P should require another state? loop is ~106us min ?
+					digitalWrite(stepper.stepPin, 0);
+					stepper.currentPos--;
+					sendStepperEvent(stepper, STEPPER_EVENT_STEP);
+				}
+
+				if (stepper.currentPos == stepper.targetPos){
+					sendStepperEvent(stepper, STEPPER_EVENT_STOP);
+				}
+
+			}
+		}
+	}
+
+	// FIXME - fix overflow with getDiff() method !!!
+	unsigned long now = micros();
+	loadTime = now - lastMicros; // avg outside
+ 	lastMicros = now;
+
+	// report load time
+	if (loadTimingEnabled && (loopCount%loadTimingModulus == 0)) {
+
+ 		// send it
+		Serial.write(MAGIC_NUMBER);
+		Serial.write(5); // size 1 FN + 4 bytes of unsigned long
+		Serial.write(PUBLISH_LOAD_TIMING_EVENT);
+        // write the long value out
+		Serial.write((byte)(loadTime >> 24));
+		Serial.write((byte)(loadTime >> 16));
+		Serial.write((byte)(loadTime >> 8));
+		Serial.write((byte) loadTime & 0xff);
+	}
+
+
+} // end of big loop
+
+unsigned long getUltrasonicRange(sensor_type& sensor){
+
+		// added for sensors which have single pin !
+		pinMode(sensor.trigPin, OUTPUT);
+		digitalWrite(sensor.trigPin, LOW);
+		delayMicroseconds(2);
+
+		digitalWrite(sensor.trigPin, HIGH);
+		delayMicroseconds(10);
+
+		digitalWrite(sensor.trigPin, LOW);
+
+		// added for sensors which have single pin !
+		pinMode(sensor.echoPin, INPUT);
+		// CHECKING return pulseIn(sensor.echoPin, HIGH, sensor.timeoutUS);
+		// TODO - adaptive timeout ? - start big - pull in until valid value - push out if range is coming close
+		return pulseIn(sensor.echoPin, HIGH);
+}
+
+void sendServoEvent(servo_type& s, int eventType){
+  	// check type of event - STOP vs CURRENT POS
+
+	Serial.write(MAGIC_NUMBER);
+	Serial.write(5); // size = 1 FN + 1 INDEX + 1 eventType + 1 curPos
+	Serial.write(PUBLISH_SERVO_EVENT);
+	Serial.write(s.index); // send my index
+	// write the long value out
+	Serial.write(eventType);
+	Serial.write(s.currentPos);
+	Serial.write(s.targetPos);
+}
+
+void sendStepperEvent(stepper_type& s, int eventType){
+  	// check type of event - STOP vs CURRENT POS
+
+	Serial.write(MAGIC_NUMBER);
+	Serial.write(5); // size = 1 FN + 1 INDEX + 1 eventType + 1 curPos
+	Serial.write(PUBLISH_STEPPER_EVENT);
+	Serial.write(s.index); // send my index
+	// write the long value out
+	Serial.write(eventType);
+	Serial.write(s.currentPos >> 8); // msb
+	Serial.write(s.currentPos & 0xff); // lsb
+}
+
+
+void sendError(int type){
+	Serial.write(MAGIC_NUMBER);
+	Serial.write(2); // size = 1 FN + 1 TYPE
+	Serial.write(PUBLISH_MRLCOMM_ERROR);
+	Serial.write(type);
+}
+
+/* SEEMED LIKE A GOOD IDEA NOT !!!!
+void sendMsg ( int num, ... )
+{
+	va_list arguments;
+	// Initializing arguments to store all values after num
+	va_start ( arguments, num );
+
+	// write header
+	msgBuf[0] = MAGIC_NUMBER;
+	msgBuf[1] = num;
+
+	// copies msg payload to buffer after header
+	for ( int x = 2; x < num+2; x++ )
+	{
+		msgBuf[x] = (byte) va_arg ( arguments, int );
+	}
+	va_end ( arguments );                  // Cleans up the list
+	Serial.write(msgBuf, num + 2);
+	return;
+}
+*/


Adding sound sensor Arduino sketch

Adding sound sensor Arduino sketch

--- Devices/SimpleSoundSensor/SimpleSoundSensor.ino
+++ Devices/SimpleSoundSensor/SimpleSoundSensor.ino
@@ -21,11 +21,8 @@

  -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

- Based upon code from Sunfounder Microsophone Sensor Module
- http://www.sunfounder.com/index.php?c=case_in&a=detail_&id=139&name=
- using an analog sound sensor purchased from Amazon at
- http://www.amazon.com/Analog-Microphone-Controller-Arduino-Equipment/dp/B00H39Y6AQ/ref=sr_1_4?s=electronics&ie=UTF8&qid=1415659062&sr=1-4&keywords=arduino+uno+sound
-
+ Based upon code from Sunfounder Microsophone Sensor Module  http://www.sunfounder.com/index.php?c=case_in&a=detail_&id=139&name= using a different but similar analog sound sensor purchased online.
+
  Modifications by Microsoft Open Technologies, Inc include adding self-describing fields in each output string, and changing
  output format to JSON string. Based upon the variables below, the JSON string would be something like the following, depending upon the values retrieved
  from the Weather Shield:


Add basic GA1A12S202 light sensor Arduino testbed.

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

--- night_sensor/night_feature_arduino_testbed.ino
+++ night_sensor/night_feature_arduino_testbed.ino
@@ -0,0 +1,63 @@
+"""
+@author:     Sze 'Ron' Chau
+@source:     https://github.com/wodiesan/senior_design_spring
+@Desc:       Adafruit Analog Light Sensor, modified by Ron Chau.
+
+ 1. Connect sensor output to Analog Pin 0
+ 2. Connect 5v to VCC and GND to GND
+ 3. Connect 3.3v to the AREF pin
+"""
+
+int led1 = 2;          // LED connected to digital pin 2
+int led2 = 3;          // LED connected to digital pin 3
+int led3 = 4;          // LED connected to digital pin 4
+int sensorPin = A0;    // select the input pin for the potentiometer
+
+float rawRange = 1024; // 3.3v
+float logRange = 5.0; // 3.3v = 10^5 lux
+
+// Random value chosen to test light sensing feature.
+float lightLimit = 600;
+
+void setup()
+{
+  analogReference(EXTERNAL); //
+  Serial.begin(9600);
+  Serial.println("Adafruit Analog Light Sensor Test");
+
+  //LEF pins
+  pinMode(led1, OUTPUT);
+  pinMode(led2, OUTPUT);
+  pinMode(led3, OUTPUT);
+}
+
+void loop()
+{
+  // read the raw value from the sensor:
+  int rawValue = analogRead(sensorPin);
+  Serial.print("Raw = ");
+  Serial.print(rawValue);
+  Serial.print(" - Lux = ");
+
+  Serial.println(RawToLux(rawValue));
+
+  // LEDS on if rawValue greater or equal.
+  if(rawValue <= 400){
+    digitalWrite(led1, HIGH);   // LED on
+    digitalWrite(led2, HIGH);
+    digitalWrite(led3, HIGH);
+  }
+  else{
+    digitalWrite(led1, LOW);   // LEDs off
+    digitalWrite(led2, LOW);
+    digitalWrite(led3, LOW);
+  }
+  delay(1000);
+
+}
+
+float RawToLux(int raw)
+{
+  float logLux = raw * logRange / rawRange;
+  return pow(10, logLux);
+}


Shorten delay in ATTiny-Blink

Shorten delay in ATTiny-Blink

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