Rearranged a lot of code, better interrupt handling

--- DigitalVFO.ino
+++ DigitalVFO.ino
@@ -18,19 +18,18 @@
 // Digital VFO program name & version
 const char *ProgramName = "DigitalVFO";
 const char *Version = "1.0";
+const char *MinorVersion = ".1";
 const char *Callsign = "vk4fawr";

 // display constants - below is for ubiquitous small HD44780 16x2 display
 const int NumRows = 2;
 const int NumCols = 16;

-// macro to get number of elements in an array
-#define ALEN(a)    (sizeof(a)/sizeof(a[0]))
-
-// string holding one entire blank row (allocated in setup())
-char *BlankRow = NULL;
-
-// define data pins we connect to the LCD
+//-----
+// Pins used by microcontroller to control devices.
+//-----
+
+// define microcontroller data pins we connect to the LCD
 const byte lcd_RS = 7;
 const byte lcd_ENABLE = 8;
 const byte lcd_D4 = 9;
@@ -38,26 +37,32 @@
 const byte lcd_D6 = 11;
 const byte lcd_D7 = 12;

-// define data pins used by the rotary encoder
+// define the display connections
+LiquidCrystal lcd(lcd_RS, lcd_ENABLE, lcd_D4, lcd_D5, lcd_D6, lcd_D7);
+
+// define microcontroller pins controlling brightness and contrast
+const byte mc_Brightness = 5;
+const byte mc_Contrast = 6;
+
+// define microcontroller pins connected to the rotary encoder
 const int re_pinA = 2;     // encoder A pin
 const int re_pinB = 3;     // encoder B pin
 const int re_pinPush = 4;  // encoder pushbutton pin

-// define pin controlling brightness and contrast
-const byte mc_Brightness = 5;
-const byte mc_Contrast = 6;
-
-// define pins that control the DDS-60
+// define microcontroller pins that control the DDS-60
 const byte DDS_FQ_UD = 14;    // connected to AD9851 device select pin
 const byte DDS_W_CLK = 15;    // connected to AD9851 clock pin
 const byte DDS_DATA = 16;     // connected to AD9851 D7 (serial data) pin

+//-----
+// Data and values used by the LCD code.
+//-----

 // max and min frequency showable
 const unsigned long MaxFreq = 30000000L;
 const unsigned long MinFreq = 1000000L;

-// size of frequency display in chars (30MHz is maximum frequency)
+// number of digits in the frequency display
 const int NumFreqChars = 8;

 // address in display CGRAM for definable and other characters
@@ -93,8 +98,19 @@
                                10000000,    // 7
                                100000000};  // 8

-// define the display connections
-LiquidCrystal lcd(lcd_RS, lcd_ENABLE, lcd_D4, lcd_D5, lcd_D6, lcd_D7);
+// string holding one entire blank row (allocated in setup())
+char *BlankRow = NULL;
+
+// the "in use" display character, "→"
+const int InUseChar = 0x7e;
+
+// default LCD contrast & brightness
+const unsigned int DefaultLcdContrast = 70;
+const unsigned int DefaultLcdBrightness = 150;
+
+//-----
+// Events and the event queue.
+//-----

 // define the VFOevents
 enum Event
@@ -109,12 +125,12 @@
   vfo_DClick,
 };

-// the "in use" display character, "→"
-const int InUseChar = 0x7e;
-
-// default LCD contrast & brightness
-const unsigned int DefaultLcdContrast = 70;
-const unsigned int DefaultLcdBrightness = 150;
+// define the length of the event queue
+const int EventQueueLength = 10;
+
+//-----
+// VFO modes.
+//-----

 // VFO modes - online or standby
 enum Mode
@@ -122,21 +138,27 @@
   vfo_Standby,
   vfo_Online
 };
+
+//-----
+// Miscellaneous.
+//-----

 // stuff for the calibrate action
 const int MinClockOffset = -32000;
 const int MaxClockOffset = +32000;
 const int MaxOffsetDigits = 5;

-// define the length of the event queue
-const int EventQueueLength = 10;
+// macro to get number of elements in an array
+#define ALEN(a)    (sizeof(a)/sizeof((a)[0]))

 //##############################################################################
 // The VFO state variables and typedefs
+//
+// The data here will be saved in EEPROM at various times.
+// Code for the device will contain internal variables that aren't saved.
 //##############################################################################

-//typedef unsigned int Mode;
 enum Mode VfoMode;          // VFO mode

 typedef unsigned long Frequency;
@@ -207,7 +229,8 @@
 }

 //----------------------------------------
-// Convert an event number to a display string.   Used only for debug.
+// Convert an event number to a display string.
+// Used only for debug.
 //----------------------------------------

 const char *event2display(VFOEvent event)
@@ -224,11 +247,11 @@
     case vfo_DClick:    return "vfo_DClick";
   }

-  return "UNKNOWN!";
-}
-
-//----------------------------------------
-// show the credits
+  return "UNKNOWN EVENT";
+}
+
+//----------------------------------------
+// Show the credits on the LCD.
 //----------------------------------------

 void show_credits(void)
@@ -243,12 +266,12 @@
 }

 //----------------------------------------
-// display a simple banner on the LCD
+// Display a simple banner on the LCD.
 //----------------------------------------

 void banner(void)
 {
-  Serial.printf(F("%s %s (%s)\n"), ProgramName, Version, Callsign);
+  Serial.printf(F("%s %s%s (%s)\n"), ProgramName, Version, MinorVersion, Callsign);

   show_credits();
   delay(900);    // wait a bit
@@ -269,7 +292,6 @@
 //     buf      address of buffer for byte results
 //     bufsize  size of the 'buf' buffer
 //     value    the Frequency value to convert
-//
 // The function won't overflow the given buffer, it will truncate at the left.
 // For example, given the value 1234 and a buffer of length 7, will fill the
 // buffer with 0001234.  Given 123456789 it will fill with 3456789.
@@ -287,7 +309,7 @@
     int rem = value % 10;

     value = value / 10;
-    *ptr-- = char(rem);
+    *ptr-- = char(rem);     // FIXME: don't require char()?
   }
 }

@@ -313,9 +335,6 @@

 // handler for selection of an item (vfo_Click event)
 typedef void (*ItemAction)(struct Menu *, int);
-
-// handler for custom item (vfo_RRight, vfo_RLeft events)
-typedef int (*ItemIncDec)(int item_num, int delta);

 // structure defining a menu item
 struct MenuItem
@@ -333,8 +352,11 @@
   struct MenuItem **items;    // array of pointers to MenuItem data
 };

+//----------------------------------------
 // dump a MenuItem to the console
 // only called from dump_menu()
+//----------------------------------------
+
 void dump_menuitem(struct MenuItem *menuitem)
 {
   Serial.printf(F("  menuitem address=%08x\n"), menuitem);
@@ -343,7 +365,10 @@
   Serial.printf(F("  action=%08x\n"), menuitem->action);
 }

+//----------------------------------------
 // dump a Menu and contained MenuItems to the console
+//----------------------------------------
+
 void dump_menu(const char *msg, struct Menu *menu)
 {
   Serial.printf(F("----------------- Menu --------------------\n"));
@@ -360,7 +385,7 @@
 }

 //----------------------------------------
-// Draw the menu on the screen.
+// Draw a menu on the screen.
 //     menu  pointer to a Menu structure
 // Only draws the top row.
 //----------------------------------------
@@ -377,6 +402,7 @@
 // Draw a standard menuitem on the screen.
 //     menu      pointer to a Menu structure
 //     item_num  the item number to show
+// Custome menuitems are drawn by their handler.
 //----------------------------------------

 void menuitem_draw(struct Menu *menu, int item_num)
@@ -497,17 +523,27 @@
 //##############################################################################
 // The system event queue.
 // Implemented as a circular buffer.
+// Since the RE code that pushes to the queue is event-driven, we must be
+// careful to disable/enable interrupts at the appropriate places.
 //##############################################################################

+// the queue itself
 VFOEvent event_queue[EventQueueLength];
-int queue_fore = 0;   // fore pointer into circular buffer
-int queue_aft = 0;    // aft pointer into circular buffer
+
+// queue pointers
+int queue_fore = 0;   // points at next event to be popped
+int queue_aft = 0;    // points at next free slot for a pushed event
+
+//----------------------------------------
+// Push an event onto the event queue.
+//     event  number of the event to push
+// If queue is full, abort()!
+//
+// This routine is called only from interrupt code, so needs no protection.
+//----------------------------------------

 void event_push(VFOEvent event)
 {
-  // Must protect from RE code fiddling with queue
-  noInterrupts();
-
   // put new event into next empty slot
   event_queue[queue_fore] = event;

@@ -516,15 +552,21 @@
   if (queue_fore >= EventQueueLength)
     queue_fore = 0;

+  interrupts();
+
   // if queue full, abort
   if (queue_aft == queue_fore)
   {
-      event_dump_queue("ERROR: event queue full:");
+      event_dump_queue("ERROR: event queue full!");
       abort("Event queue full");
   }
-
-  interrupts();
-}
+}
+
+//----------------------------------------
+// Pop next event from the queue.
+//
+// Returns vfo_None if queue is empty.
+//----------------------------------------

 VFOEvent event_pop(void)
 {
@@ -533,20 +575,27 @@

   // if queue empty, return None event
   if (queue_fore == queue_aft)
+  {
+    interrupts();
     return vfo_None;
+  }

   // get next event
   VFOEvent event = event_queue[queue_aft];

   // move aft pointer up one slot, wrap if necessary
   ++queue_aft;
-  if (queue_aft  >= EventQueueLength)
+  if (queue_aft >= EventQueueLength)
     queue_aft = 0;

   interrupts();

   return event;
 }
+
+//----------------------------------------
+// Returns the number of events in the queue.
+//----------------------------------------

 int event_pending(void)
 {
@@ -565,6 +614,10 @@
   return result;
 }

+//----------------------------------------
+// Clear out any events in the queue.
+//----------------------------------------
+
 void event_flush(void)
 {
   // Must protect from RE code fiddling with queue
@@ -575,6 +628,12 @@

   interrupts();
 }
+
+//----------------------------------------
+// Dump the queue contents to the console.
+//     msg  address of message to show
+// Debug code.
+//----------------------------------------

 void event_dump_queue(const char *msg)
 {
@@ -603,8 +662,8 @@
 //##############################################################################

 //----------------------------------------
-// Display an unsigned long on the display with selected column underlined.
-//     value       the number to display
+// Display a value on the display with selected column underlined.
+//     value       the number to show
 //     sel_col     the selection offset of digit to underline
 //                 (0 is rightmost digit, increasing to the left)
 //     num_digits  the number of digits to show on the display
@@ -768,7 +827,9 @@

 //----------------------------------------
 // Initialize the rotary encoder stuff.
-// Return 'true' if button was pressed down during setup.
+//
+// Return 'true' if button was down during setup.
+// This is used to reset some VFO display values if necessary.
 //----------------------------------------

 bool re_setup(void)
@@ -794,8 +855,7 @@

 void pinPush_isr(void)
 {
-  noInterrupts();
-
+  // sample the pin value
   re_down = ! (PIND & 0x10);

   if (re_down)
@@ -816,7 +876,8 @@
       {
         // check to see if we have a single click very recently
         if (last_click != 0)
-        {   // did have single click before this
+        {
+          // yes, did have single click before this release
           unsigned long dclick_delta = last_up_time - last_click;

           // if short time since last click, issue double-click event
@@ -833,6 +894,7 @@
         }
         else
         {
+          // no, this is an isolated release
           event_push(vfo_Click);
           last_click = last_up_time;    // single-click, prepare for possible double
         }
@@ -843,8 +905,6 @@
       }
     }
   }
-
-  interrupts();
 }

 //----------------------------------------
@@ -853,11 +913,8 @@

 void pinA_isr(void)
 {
-  byte reading;
-
-  noInterrupts();
-
-  reading = PIND & 0xC;
+  // sample the pin state
+  byte reading = PIND & 0xC;

   if (reading == B00001100 && aFlag)
   { // check that we have both pins at detent (HIGH) and that we are expecting detent on
@@ -879,8 +936,6 @@
     // show we're expecting pinB to signal the transition to detent from free rotation
     bFlag = 1;
   }
-
-  interrupts();
 }

 //----------------------------------------
@@ -889,11 +944,8 @@

 void pinB_isr(void)
 {
-  byte reading;
-
-  noInterrupts();
-
-  reading = PIND & 0xC;
+  // sample the pin value
+  byte reading = PIND & 0xC;

   if (reading == B00001100 && bFlag)
   { // check that we have both pins at detent (HIGH) and that we are expecting detent on
@@ -915,8 +967,6 @@
     // show we're expecting pinA to signal the transition to detent from free rotation
     aFlag = 1;
   }
-
-  interrupts();
 }

@@ -926,8 +976,8 @@

 // Define the address in EEPROM of various things.
 // The "NEXT_FREE" value is the address of the next free slot address.
-// Ignore "redefine errors" - silly compiler!
-// The idea is that we are free to rearrange objects below with minimum fuss
+// Ignore "redefine errors" - not very helpful in this case!
+// The idea is that we are free to rearrange objects below with minimum fuss.

 // start storing at address 0
 #define NEXT_FREE   (0)
@@ -1084,7 +1134,7 @@
 //##############################################################################

 //----------------------------------------
-// Pulse 'pin' high and then low.
+// Pulse 'pin' high and then low very quickly.
 //----------------------------------------

 void dds_pulse_high(byte pin)
@@ -1107,7 +1157,8 @@
 }

 //----------------------------------------
-// frequency of sinewave (datasheet page 12) will be <sys clock> * <frequency tuning word> / 2^32
+// Frequency of sinewave (datasheet page 12) will be "<sys clock> * <frequency tuning word> / 2^32".
+// Rearranging: FTW = (frequency * 2^32) / sys_clock .
 //
 // 'VfoClockOffset' is the value the 'Calibrate' menu tweaks, initially 0.
 //----------------------------------------
@@ -1183,10 +1234,10 @@
 void setup(void)
 {
   // initialize the BlankRow global to a blank string length of a display row
-  BlankRow = (char *) malloc(NumCols + 1);     // size of one display row
+  BlankRow = (char *) malloc(NumCols + 1);
   for (int i = 0; i < NumCols; ++i)
     BlankRow[i] = ' ';
-  BlankRow[NumCols] = '\0';
+  BlankRow[NumCols] = '\0';     // don't forget the string terminator

   // initialize the serial console
   Serial.begin(115200);
@@ -1245,10 +1296,7 @@
   // dump EEPROM values
   dump_eeprom();

-  // we sometimes see random events on powerup, flush them here
-//  event_flush();
-
-  // get going
+  // show the main screen and continue in loop()
   show_main_screen();
 }

@@ -1517,6 +1565,7 @@
   show_credits();

   // handle events in our own little event loop
+  // we want to wait until some sort of click
   while (true)
   {
     // handle any pending event
@@ -1706,8 +1755,8 @@
 // Set the current 'hold click' time and save to EEPROM if 'actioned'.
 //   menu      address of 'calling' menu
 //   item_num  index of MenuItem we were actioned from
-// This works differently from brightness/contrast.  We show menuitems
-// of the time to use.
+// This works differently from brightness/contrast.
+// We show menuitems of the time to use.
 //----------------------------------------

 void holdclick_action(struct Menu *menu, int item_num)
@@ -1772,8 +1821,8 @@
 // Set the current 'doubleclick' time and save to EEPROM if 'actioned'.
 //   menu      address of 'calling' menu
 //   item_num  index of MenuItem we were actioned from
-// This works differently from brightness/contrast.  We show menuitems
-// of the time to use.
+// This works differently from brightness/contrast.
+// We show menuitems of the time to use.
 //----------------------------------------

 void doubleclick_action(struct Menu *menu, int item_num)
@@ -1838,11 +1887,11 @@
 // Adjust the DDS-60 clock tweak to allow frequency calibration.
 //   menu      address of 'calling' menu
 //   item_num  index of MenuItem we were actioned from
-// Only works if the VFO is online.
+// If VFO is on standby, force it online, tweak, and then offline again.
 //
 // In line with all other action menuitems we want to observer the effects
 // of changing the value, but also only want to make a permanent change on
-// a 'click' action.
+// a 'click' action only.
 //----------------------------------------

 void calibrate_action(struct Menu *menu, int item_num)
@@ -1959,6 +2008,7 @@
   lcd.write(BlankRow);
   lcd.setCursor(0, 1);
   lcd.write(mode2display(VfoMode));
+// FIXME: if we display something else on bottom row change this code!
 }

 //----------------------------------------
@@ -2003,12 +2053,6 @@

 void loop(void)
 {
-#ifdef JUNK
-  // remember old values, update screen if changed
-  Frequency old_freq = VfoFrequency;
-  int old_position = VfoSelectDigit;
-#endif
-
   // handle all events in the queue
   while (event_pending() > 0)
   {


Only save freq to EEPROM when DDS goes online

--- DigitalVFO.ino
+++ DigitalVFO.ino
@@ -2268,10 +2268,13 @@

     // update the display, write changes to EEPROM
     display_sel_value(VfoFrequency, VfoSelectDigit, NumFreqChars, NumCols - NumFreqChars - 2, 0);
-    save_to_eeprom();         // FIXME: worry about frequent writes?
+//    save_to_eeprom();         // FIXME: worry about frequent writes?

     // if online, update DDS-60
     if (VfoMode == vfo_Online)
+    {
+      save_to_eeprom();
       dds_update(VfoFrequency);
-  }
-}
+    }
+  }
+}


1.0.2

1.0.2

DIYino Compatibility

--- Lightsaber.ino
+++ Lightsaber.ino
@@ -1110,14 +1110,14 @@
 		return;

 // wait for MPU interrupt or extra packet(s) available
-	while (!mpuInterrupt && mpuFifoCount < packetSize) {
+//	while (!mpuInterrupt && mpuFifoCount < packetSize) {
 		/* other program behavior stuff here
 		 *
 		 * If you are really paranoid you can frequently test in between other
 		 * stuff to see if mpuInterrupt is true, and if so, "break;" from the
 		 * while() loop to immediately process the MPU data
 		 */
-	}
+//	}

 // reset interrupt flag and get INT_STATUS byte
 	mpuInterrupt = false;
@@ -1291,7 +1291,7 @@
 /*
  * If no other interrupt has been triggered, and if my calculation are right
  * this timer has an almost 44100 khz frequency triggering :
- * each 22 s this method is called and modifies the blade brightness
+ * each 22 µs this method is called and modifies the blade brightness
  * The parameter is defined in ignition block
  */
 #ifdef LIGHT_EFFECTS


Lift baud rates, remove unneeded cmd responses

--- MagnusCore.ino
+++ MagnusCore.ino
@@ -30,13 +30,14 @@

 // Serial I/O
-int8_t command[64];
+const int ioSize = 64;
+int8_t command[ioSize];
 int8_t in_index = 0;

 void start_serial(void)
 {
   in_index = 0;
-  Serial.begin(9600);
+  Serial.begin(115200);
 }

 bool collect_serial(void)
@@ -59,7 +60,7 @@
     else
     {
       command[in_index] = ch;
-      if ( in_index < sizeof(command) - 1 ) {
+      if ( in_index < (sizeof(command)/sizeof(command[0])) - 2 ) {
         in_index++;
       }
       //if( in_index >= 32 ) //sizeof(command) )
@@ -117,22 +118,19 @@
       case 'e':
         owner = enlightened;
         //percent = getPercent(&command[1]);
-        Serial.println("OK");
         break;
       case 'R':
       case 'r':
         owner = resistance;
         //percent = getPercent(&command[1]);
-        Serial.println("OK");
         break;
       case 'n':
       case 'N':
         owner = neutral;
         percent = 100;
-        Serial.println("OK");
         break;
       default:
-        Serial.println("?");
+        break;
         //Serial.print((char *)command); Serial.print(" - ");Serial.print(command[0],DEC);Serial.print(": ");
         //Serial.print("owner "); Serial.print(owner,DEC); Serial.print(", percent "); Serial.println(percent,DEC);
     }


clean up

clean up

test with 6 ports giving from 57 to 60 fps

--- VertigoLED.ino
+++ VertigoLED.ino
@@ -58,7 +58,7 @@

 boolean locateMode = 0;
 uint16_t offset;
-uint8_t portSyncFlag;
+uint16_t portSyncFlag;
 uint8_t syncFlag;

 unsigned long currentMillis;
@@ -82,7 +82,7 @@
   LEDS.show();
   delay(300);
   for (int i = 0; i <  8 * NUM_PIXELS_PR_STRIP; i++) {
-    LEDS.setPixel(i,0x00000000);  //set full white
+    LEDS.setPixel(i,0x00000000);  //set 0
   }
   LEDS.show();
   delay(100);
@@ -195,31 +195,35 @@
               ArtDmx* dmx = (ArtDmx*)udp_buffer;
               int port = node.getAddress(dmx->SubUni, dmx->Net) - node.getStartAddress();
               bitSet(portSyncFlag, port);
-              //if (port >= 0 && port < config.numPorts) {
+              if (port >= 0 && port < config.numPorts) {
                 // Calculate length of DMX packet. Requires bit swap length from dmx packet
                 // int dmx_length = ((dmx->Length & 0xF) << 8) + ((dmx->Length & 0xF0) >> 8); //is this really necessary? madmapper always sends a full univers
+                //move the data to the ports used by FastLED to avoid confusion
                 if (port<3) {
                   offset = 2688+(port*128);
                 }else {
                   offset = 1536+(port*128);
                 }
+                //write the dmx data to the Octo frame buffer
                 for (int i = 0; i < 128; i++) {
-                  LEDS.setPixel(i+offset, dmx->Data[i*4], dmx->Data[4*i+1], dmx->Data[4*i+2], dmx->Data[4*i+3]);
-                }
-
-                //  uint32_t* dmxData = (uint32_t*) dmx->Data;
-              //}
+                  LEDS.setPixel(i+offset, dmx->Data[4*i+1], dmx->Data[i*4], dmx->Data[4*i+2], dmx->Data[4*i+3]);
+                }
+              }
               break;}
             // OpSync
             case 0x5200: {
               LEDS.show();
-              if (portSyncFlag == 0b00111111) {
+              if (portSyncFlag == 63) {
                 syncFlag++;
                 portSyncFlag = 0;
                 currentMillis = millis();
               }
-              if (currentMillis-previousMillis >= 1000) {
-                fps = syncFlag;
+              if (currentMillis-previousMillis >= 990) {
+                if(currentMillis-previousMillis > 1000) {
+                  fps = syncFlag-1;
+                }else{
+                  fps = syncFlag;
+                }
                 syncFlag = 0;
                 Serial.printf("fps = %d \n",fps);
                 previousMillis = currentMillis;


Delete GPSLCD.ino

Delete GPSLCD.ino

--- GPSLCD.ino
+++ GPSLCD.ino
@@ -1,612 +0,0 @@
-/* GPS LCD
-
-    By GK Grotsky
-    8/30/16
-
-  This program communicate with the u-blox NEO-6M GPS module
-  through a software serial interface. It then displays certain GPS
-  parameters on a I2C 16x2 (or 20x4) character LCD display module. The
-  GPS messages are received by the on-board Arduino UART circuit using
-  the SoftwareSerial library. It then uses the TinyGPS++ library to
-  decode the GPS NMEA messages. The parameters are then displayed on a
-  16x4 (or 20x4) LCD using the LiquidCrystal_I2C library.
-
-  Note: Both the 16x2 and 20x4 LCDs are supported as these are the most popular
-        LCDs available.
-*/
-#include "GPSLCD.h"
-#include <TinyGPS++.h>
-#include <SoftwareSerial.h>
-#include <LiquidCrystal_I2C.h>
-
-TinyGPSPlus gps; // This is the GPS object that will pretty much do all the grunt work with the NMEA data
-SoftwareSerial GPSModule(10, 11); // RX, TX
-LiquidCrystal_I2C lcd(I2C_ADDR, En_pin, Rw_pin, Rs_pin, D4_pin, D5_pin, D6_pin, D7_pin); // Initializes class variables and defines the I2C address of the LCD
-bool dataValid; // Data is valid from the GPS module
-GPSStruct GPSData; // Holds the GPS data coming from the GPS module
-
-// The setup (runs once at start up)
-void setup()
-{
-  pinMode(BACKLIGHT_SW, INPUT);
-
-#ifdef _16x2
-  // Selects either speed or heading to be displayed
-  pinMode(SPEED_ALTITUDE_SW, INPUT);
-#else
-  // Selects either altitude or the date/time to be displayed
-  pinMode(ALTITUDE_DATE_TIME_SW, INPUT);
-#endif
-
-  GPSModule.begin(9600); // This opens up communications to the software serial tx and rx lines
-  GPSModule.flush();
-
-  lcd.begin (COLUMN, ROW); // Defines LCD type
-  lcd.setBacklightPin(BACKLIGHT_PIN, POSITIVE); // Sets the pin to control the backlight
-  lcd.clear(); // Clear the LCD
-  lcd.home (); // Go to the home position on the LCD
-} // setup
-
-// The loop (runs forever and a day :-))
-void loop()
-{
-  static uint32_t pastSatellites = 0;
-  static uint8_t initializingCounter = 0;
-  static unsigned long prevInitializationTime = INITIALIZATION_INTERVAL;
-  static unsigned long prevCreditTime = TOGGLETIME_INTERVAL;
-  static unsigned long prevInvalidSatellitesTime = TOGGLETIME_INTERVAL;
-  static bool leftInitialization = false;
-  static bool creditToggle = true;
-  static bool InvalidSatellitesToggle = true;
-#ifndef _16x2
-  static unsigned long prevDateTime = TOGGLETIME_INTERVAL;
-  static unsigned long prevHeadingTime = TOGGLETIME_INTERVAL;
-  static bool dateTimeToggle = true;
-  static bool headingToggle = true;
-#endif
-#ifdef DATA_VALID_OVERRIDE
-  const bool dataValidOverride = true; // Set true to override data valid for debugging
-#else
-  const bool dataValidOverride = false; // Set false not to override data valid
-#endif
-#ifdef BACKLIGHT_OVERRIDE
-  // Override LCD backlight switch
-  // Force LCD backlight on/off
-  lcd.setBacklight(BACKLIGHT_ONOFF);
-#else
-  // Turn LCD backlight on/off
-  lcd.setBacklight(digitalRead(BACKLIGHT_SW));
-#endif
-  unsigned long now = millis();
-
-  while (GPSModule.available()) // While there are characters to come from the GPS
-  {
-    bool b = gps.encode(GPSModule.read()); // This feeds the serial NMEA data into the GPS library one char at a time
-  }
-
-  // Get the GPS data valid flags
-  dataValid =
-    gps.location.isValid()   &&
-    gps.speed.isValid()      &&
-    gps.altitude.isValid()   &&
-    gps.course.isValid()     &&
-    gps.date.isValid()       &&
-    gps.time.isValid()       &&
-    gps.satellites.isValid() &&
-    gps.hdop.isValid();
-
-  // Check if the GPS data is valid or data valid override is set (for debugging)
-  if (dataValid || dataValidOverride) {
-#ifndef DATA_VALID_OVERRIDE
-    // Store the real GPS data
-    GPSData.satellites = gps.satellites.value();
-    GPSData.lat        = gps.location.lat();
-    GPSData.lon        = gps.location.lng();
-    GPSData.speed      = gps.speed.mph();
-    GPSData.altitude   = gps.altitude.feet();
-#ifndef _16x2
-    GPSData.heading    = gps.course.deg();
-    GPSData.hdop       = gps.hdop.value();
-    GPSData.year       = gps.date.year();
-    GPSData.month      = gps.date.month();
-    GPSData.day        = gps.date.day();
-    GPSData.hour       = gps.time.hour();
-    GPSData.minute     = gps.time.minute();
-    GPSData.second     = gps.time.second();
-#endif // #ifndef _16x2
-#else // #ifndef DATA_VALID_OVERRIDE
-    // Store the fake GPS data (for debugging)
-    GPSData.satellites = 0; // Invalid satellites
-    GPSData.lat        = 39.16d; // East coast
-    GPSData.lon        = -77.07d; //   "
-    GPSData.speed      = 55.0d;
-    GPSData.altitude   = 555.0d;
-#ifndef _16x2
-    GPSData.heading    = 60.0d; // ENE or NE (16 cardinal points or 8 cardinal points)
-    GPSData.hdop       = 240;
-    GPSData.year       = 2016;
-    GPSData.month      = 11; // Day before ST starts
-    GPSData.day        = 5;  //      "
-    GPSData.hour       = 23; // 7pm my local time
-    GPSData.minute     = 10;
-    GPSData.second     = 25;
-#endif // #ifndef _16x2
-#endif // #ifndef DATA_VALID_OVERRIDE
-    // Clear the screen once when leaving initialization
-    if (!leftInitialization) {
-      leftInitialization = true;
-      lcd.clear(); // Clear the LCD
-    }
-    // Display the latest info from the gps object which it derived from the data sent by the GPS unit
-    // Send data to the LCD
-#ifdef _16x2 //------------------------------------------------------
-    lcd.home (); // Go to 1st line
-    lcd.print("Lat: ");
-    lcd.print(GPSData.lat);
-    lcd.setCursor (11, 0);
-    lcd.print("SV:");
-    if ((pastSatellites != GPSData.satellites) || (GPSData.satellites == 0)) {
-      pastSatellites = GPSData.satellites;
-      if (GPSData.satellites == 0) {
-        // Toggle invalid satellites indicator every TOGGLETIME_INTERVAL seconds
-        if (now - prevInvalidSatellitesTime > TOGGLETIME_INTERVAL / 4) {
-          prevInvalidSatellitesTime = now;
-          if (InvalidSatellitesToggle) {
-            InvalidSatellitesToggle = false;
-            lcd.print("XX");
-          }
-          else {
-            InvalidSatellitesToggle = true;
-            lcd.print("  ");
-          } // if (InvalidSatellitesToggle)
-        } // if (now - prevInvalidSatellitesTime > TOGGLETIME_INTERVAL)
-      } // if (GPSData.satellites == 0)
-      else if (GPSData.satellites <= 9) {
-        lcd.print(" "); // Blank leading char
-        lcd.print(GPSData.satellites);
-      }
-      else {
-        lcd.print(GPSData.satellites);
-      }
-    } // if ((pastSatellites != GPSData.satellites) || (GPSData.satellites == 0))
-    lcd.setCursor (0, 1); // Go to 2nd line
-    lcd.print("Lon: ");
-    lcd.print(GPSData.lon);
-    if ((digitalRead(SPEED_ALTITUDE_SW))) {
-      lcd.setCursor (12, 1);
-      if (GPSData.speed < SPEED_CUTOUT) {
-        lcd.print("0  ");
-      }
-      else {
-        lcd.print((int16_t)GPSData.speed);
-        lcd.print(" "); // Clear the extra char
-      }
-    }
-    else {
-      lcd.print("     "); // Clear the extra chars
-      if (GPSData.altitude <= 99.9) {
-        lcd.setCursor (14, 1);
-      }
-      else {
-        lcd.setCursor (13, 1);
-      }
-      lcd.print((int16_t)GPSData.altitude); // Altitude
-      // Toggle credit every TOGGLETIME_INTERVAL seconds
-      if (now - prevCreditTime > (TOGGLETIME_INTERVAL / 2)) {
-        prevCreditTime = now;
-        if (creditToggle) { // Display credit
-          creditToggle = false;
-          lcd.print("     "); // Clear the extra chars
-          lcd.print(CREDIT); // Yours truly :-)
-        }
-        else {
-          creditToggle = true;
-          lcd.print("        "); // Clear the extra chars
-        }
-      } // if (now - prevCreditTime > TOGGLETIME_INTERVAL)
-    } // if ((digitalRead(SPEED_ALTITUDE_SW)))
-#else // 20x4 ----------------------------------------------------
-    lcd.home (); // Go to 1st line
-    lcd.print("Lat: ");
-    lcd.print(GPSData.lat);
-    lcd.setCursor (15, 0);
-    lcd.print("SV:");
-    if ((pastSatellites != GPSData.satellites) || (GPSData.satellites == 0)) {
-      pastSatellites = GPSData.satellites;
-      if (GPSData.satellites == 0) {
-        // Toggle invalid satellites indicator every TOGGLETIME_INTERVAL seconds
-        if (now - prevInvalidSatellitesTime > TOGGLETIME_INTERVAL / 3) {
-          prevInvalidSatellitesTime = now;
-          if (InvalidSatellitesToggle) {
-            InvalidSatellitesToggle = false;
-            lcd.print("XX");
-          }
-          else {
-            InvalidSatellitesToggle = true;
-            lcd.print("  ");
-          } // if (InvalidSatellitesToggle)
-        } // if (now - prevInvalidSatellitesTime > TOGGLETIME_INTERVAL)
-      } // if (GPSData.satellites == 0)
-      else if (GPSData.satellites <= 9) {
-        lcd.print(" "); // Blank leading char
-        lcd.print(GPSData.satellites);
-      }
-      else {
-        lcd.print(GPSData.satellites);
-      }
-    } // if ((pastSatellites != GPSData.satellites) || (GPSData.satellites == 0))
-    lcd.setCursor (0, 1); // Go to 2nd line
-    lcd.print("Lon: ");
-    lcd.print(GPSData.lon);
-#ifndef CONVERT_TO_LOCAL
-    // Only display if time/date is selected
-    if (!(digitalRead(ALTITUDE_DATE_TIME_SW))) {
-      lcd.print("      "); // Clear the extra chars
-      uint8_t DOW = dayOfWeek(GPSData.year, GPSData.month, GPSData.day);
-      if (IsDST(GPSData.day, GPSData.month, DOW)) {
-        lcd.print("DST");
-      }
-      else {
-        lcd.print(" ST");
-      }
-    }
-    else {
-      lcd.print("         "); // Clear the extra chars
-    }
-#else // #ifndef CONVERT_TO_LOCAL
-    //Display Horizontal Dilution of Precision (Hdop) with the format X.X
-    // It comes in from the GPS module as XXX
-    uint32_t hdopInteger = GPSData.hdop / 100;
-    uint32_t hdopFarction = (GPSData.hdop - (hdopInteger * 100)) / 10;
-    lcd.print(" Hdop:");
-    if (hdopInteger < 10) {
-      lcd.print(hdopInteger); // Integer part
-      lcd.print(".");
-      lcd.print(hdopFarction); // Fraction part
-    }
-    else {
-      lcd.print("XXX");
-    }
-#endif // #ifndef CONVERT_TO_LOCAL
-    lcd.setCursor (0, 2); // Go to 3rd line
-    lcd.print("Spd: ");
-    if (GPSData.speed < SPEED_CUTOUT) {
-      lcd.print("0  ");
-    }
-    else {
-      lcd.print((int16_t)GPSData.speed);
-      lcd.print(" "); // Clear the extra chars
-    }
-    lcd.setCursor (12, 2);
-    lcd.print("Hdg: ");
-    if (GPSData.speed < SPEED_CUTOUT) {
-      lcd.print("0  ");
-    }
-    else {
-      // Toggle heading every TOGGLETIME_INTERVAL seconds
-      if (now - prevHeadingTime > TOGGLETIME_INTERVAL) {
-        prevHeadingTime = now;
-        if (headingToggle) { // Display cardinal heading
-          headingToggle = false;
-          lcd.print(cardinal(GPSData.heading));
-        }
-        else { // Display degrees heading
-          headingToggle = true;
-          lcd.print((int16_t)GPSData.heading);
-          if (GPSData.heading <= 99.9) lcd.print(" "); // Clear the extra char
-        } // if (headingToggle)
-      } // if (now - prevHeadingTime > TOGGLETIME_INTERVAL)
-    } // if (GPSData.speed < SPEED_CUTOUT)
-    lcd.setCursor (0, 3); // Go to 4th line
-    if ((digitalRead(ALTITUDE_DATE_TIME_SW))) {
-      lcd.print("Alt: ");
-      lcd.print((int16_t)GPSData.altitude);
-      // Toggle credit every TOGGLETIME_INTERVAL seconds
-      if (now - prevCreditTime > (TOGGLETIME_INTERVAL / 2)) {
-        prevCreditTime = now;
-        if (creditToggle) { // Display credit
-          creditToggle = false;
-          lcd.print("         "); // Clear the extra chars
-          lcd.print(CREDIT); // Yours truly :-)
-        }
-        else {
-          creditToggle = true;
-          lcd.print("            "); // Clear the extra chars
-        }
-      } // if (now - prevCreditTime > TOGGLETIME_INTERVAL)
-      prevDateTime = TOGGLETIME_INTERVAL;
-      dateTimeToggle = true; // Default first to display date
-    } // if ((digitalRead(ALTITUDE_DATE_TIME_SW)))
-    else {
-      // Toggle date/time every TOGGLETIME_INTERVAL seconds
-      if (now - prevDateTime > TOGGLETIME_INTERVAL) {
-        prevDateTime = now;
-        if (dateTimeToggle) {
-          // Display date
-          dateTimeToggle = false;
-          lcd.print("Date: ");
-          uint8_t hour = GPSData.hour;
-          uint8_t day  = GPSData.day;
-          uint8_t month = GPSData.month;
-          uint16_t year = GPSData.year;
-#ifdef CONVERT_TO_LOCAL
-          // Convert UTC date to local date
-          bool DST = convertToLocal (&hour, &year, &month,
-                                     &day, GPSData.lon, true); // true means date conversion
-#endif // #ifdef CONVERT_TO_LOCAL
-          if (month < 10) lcd.print("0");
-          lcd.print(month);
-          lcd.print("/");
-          if (day < 10) lcd.print("0");
-          lcd.print(day);
-          lcd.print("/");
-          lcd.print(year);
-          printDay (dayOfWeek (year, month, day));
-        } // if (dateTimeToggle)
-        else {
-          // Display time
-          dateTimeToggle = true;
-          lcd.print("Time: ");
-          uint8_t hour = GPSData.hour;
-          uint8_t day  = GPSData.day;
-          uint8_t month = GPSData.month;
-          uint16_t year = GPSData.year;
-#ifdef CONVERT_TO_LOCAL
-          // Convert UTC time to local time (no need to convert the date)
-          bool DST = convertToLocal (&hour, &year, &month,
-                                     &day, GPSData.lon, false); // false means no date conversion
-#else // #ifdef CONVERT_TO_LOCAL
-#ifdef DISPLAY_12_HOUR
-          if (hour == 0) { // 12 hour clocks don't display 0
-            hour = 12;
-          }
-#endif // #ifdef DISPLAY_12_HOUR
-#endif // #ifdef CONVERT_TO_LOCAL
-#ifdef DISPLAY_12_HOUR
-          char AMPM[] = "am";
-          if (hour >= 12) { // Convert to 12 hour format
-            if (hour > 12) hour -= 12;
-            strcpy (AMPM, "pm");
-          }
-#endif
-          if (hour < 10) lcd.print("0");
-          lcd.print(hour);
-          lcd.print(":");
-          if (GPSData.minute < 10) lcd.print("0");
-          lcd.print(GPSData.minute);
-          lcd.print(":");
-          if (GPSData.second < 10) lcd.print("0");
-          lcd.print(GPSData.second);
-#ifdef DISPLAY_12_HOUR
-          lcd.print(AMPM);
-#endif // #ifdef DISPLAY_12_HOUR
-#ifdef CONVERT_TO_LOCAL
-#ifdef DISPLAY_12_HOUR
-          (DST) ? lcd.print(" DST") : lcd.print("  ST");
-#else // #ifdef DISPLAY_12_HOUR
-          (DST) ? lcd.print("   DST") : lcd.print("    ST");
-#endif // #ifdef DISPLAY_12_HOUR
-#endif // #ifndef CONVERT_TO_LOCAL
-#ifndef CONVERT_TO_LOCAL
-#ifdef DISPLAY_12_HOUR
-          lcd.print(" UTC");
-#else // #ifdef DISPLAY_12_HOUR
-          lcd.print("   UTC");
-#endif // #ifdef DISPLAY_12_HOUR
-#endif // #ifndef CONVERT_TO_LOCAL
-        } // if (dateTimeToggle)
-      } // if (now - prevDateTime > TOGGLETIME_INTERVAL)
-    } // if ((digitalRead(ALTITUDE_DATE_TIME_SW)))
-#endif //------------------------------------------------------------
-  } // if (dataValid)
-  else {
-    // GPS data is not valid, so it must be initializing
-#ifdef _16x2 //------------------------------------------------------
-    // Display initialization screen once every INITIALIZATION_INTERVAL
-    if (now - prevInitializationTime > INITIALIZATION_INTERVAL) {
-      prevInitializationTime = now;
-      lcd.setCursor (6, 0); // Go to 1st line
-      lcd.print("GPS");
-      lcd.setCursor (11, 0);
-      lcd.print("v");
-      lcd.print(VERSION);
-      lcd.setCursor (2, 1); // Go to 2nd line
-      lcd.print("Initializing");
-      lcd.setCursor (15, 1);
-      if (++initializingCounter > 9) initializingCounter = 1; // Limit 1 - 9
-      lcd.print(initializingCounter);
-      leftInitialization = false;
-    }
-#else // 20x4 -------------------------------------------------------
-    // Display initialization screen once every INITIALIZATION_INTERVAL
-    if (now - prevInitializationTime > INITIALIZATION_INTERVAL) {
-      prevInitializationTime = now;
-      lcd.setCursor (8, 0); // Go to 1st line
-      lcd.print("GPS");
-      lcd.setCursor (14, 0);
-      lcd.print("v");
-      lcd.print(VERSION);
-      lcd.setCursor (4, 1); // Go to 2nd line
-      lcd.print("Initializing");
-      lcd.setCursor (6, 2); // Go to 3rd line
-      lcd.print("Data Not");
-      lcd.setCursor (7, 3); // Go to 4th line
-      lcd.print("Valid");
-      lcd.setCursor (19, 3);
-      if (++initializingCounter > 9) initializingCounter = 1; // Limit 1 - 9
-      lcd.print(initializingCounter);
-      leftInitialization = false;
-    }
-#endif //------------------------------------------------------------
-  } // GPS data is not valid
-} // loop
-
-#ifndef _16x2
-/* Helper functions start here
-
-  Ripped off from Electrical Engineering Stack Exchange
-  http://electronics.stackexchange.com/questions/66285/how-to-calculate-day-of-the-week-for-rtc
-  ------------------------------------------------------------
-   Returns the number of days to the start of the specified year, taking leap
-   years into account, but not the shift from the Julian calendar to the
-   Gregorian calendar. Instead, it is as though the Gregorian calendar is
-   extrapolated back in time to a hypothetical "year zero".
-*/
-uint16_t leap (uint16_t year)
-{
-  return year * 365 + (year / 4) - (year / 100) + (year / 400);
-}
-/* Returns a number representing the number of days since March 1 in the
-   hypothetical year 0, not counting the change from the Julian calendar
-   to the Gregorian calendar that occurred in the 16th century. This
-   algorithm is loosely based on a function known as "Zeller's Congruence".
-   This number MOD 7 gives the day of week, where 0 = Monday and 6 = Sunday.
-*/
-uint16_t zeller (uint16_t year, uint8_t month, uint8_t day)
-{
-  year += ((month + 9) / 12) - 1;
-  month = (month + 9) % 12;
-  return leap (year) + month * 30 + ((6 * month + 5) / 10) + day + 1;
-}
-
-// Returns the day of week for a given date.
-uint8_t dayOfWeek (uint16_t year, uint8_t month, uint8_t day)
-{
-  return (zeller (year, month, day) % 7) + 1;
-}
-//----------------------------------------------------------
-
-// Print the day of the week on the LCD
-void printDay(uint8_t day)
-{
-  if (day == 7) day = 0;
-  switch (day)
-  {
-    case 0:  lcd.print(" Mon"); break;
-    case 1:  lcd.print(" Tue"); break;
-    case 2:  lcd.print(" Wed"); break;
-    case 3:  lcd.print(" Thu"); break;
-    case 4:  lcd.print(" Fri"); break;
-    case 5:  lcd.print(" Sat"); break;
-    case 6:  lcd.print(" Sun"); break;
-    default: lcd.print(" Err");
-  }
-}
-
-// Compute the cardinal points of the compass
-const char* cardinal(double course)
-{
-#ifdef _16CARDINAL
-  const char* directions[] = {"N  ", "NNE", "NE ", "ENE", "E  ", "ESE", "SE ", "SSE",
-                              "S  ", "SSW", "SW ", "WSW", "W  ", "WNW", "NW ", "NNW"
-                             };
-#else
-  const char* directions[] = {"N  ", "N  ", "NE ", "NE ", "E  ", "E  ", "SE ", "SE ",
-                              "S  ", "S  ", "SW ", "SW ", "W  ", "W  ", "NW ", "NW "
-                             };
-#endif // #ifdef _16CARDINAL
-  uint8_t direction = (uint8_t)((course + 11.25d) / 22.5d);
-  return directions[direction % 16];
-}
-
-/* Ripped off from Stackoverflow
-  http://stackoverflow.com/questions/5590429/calculating-daylight-saving-time-from-only-date
-
-  Check to see if it's Daylight Savings Time (DST)
-*/
-bool IsDST(uint8_t day, uint8_t month , uint8_t DOW)
-{
-  // Make Day of Week (DOW) match with what Stackoverflow suggests
-  // for DOW (Sunday = 0 to Saturday = 6)
-  switch (DOW)
-  {
-    case 6:  DOW = 0; break; // Sun
-    case 7:  DOW = 1; break; // Mon
-    case 1:  DOW = 2; break; // Tue
-    case 2:  DOW = 3; break; // Wed
-    case 3:  DOW = 4; break; // Thu
-    case 4:  DOW = 5; break; // Fri
-    case 5:  DOW = 6; break; // Sat
-    default: break;
-  }
-  // January, February, and December are out
-  if (month < 3 || month > 11) {
-    return false;
-  }
-  // April to October are in
-  if (month > 3 && month < 11) {
-    return true;
-  }
-  int8_t previousSunday = (int8_t)(day - DOW);
-  // In march, we are DST if our previous Sunday was on or after the 8th
-  if (month == 3) {
-    return previousSunday >= 8;
-  }
-  // In November we must be before the first Sunday to be DST
-  // That means the previous Sunday must be before the 1st
-  return previousSunday <= 0;
-}
-
-#ifdef CONVERT_TO_LOCAL
-/* Convert UTC time and date to local time and date
-   Difference between UTC time/date (at Greenwich) and local time/date is 15 minutes
-   per 1 degree of longitude. See the following:
-   http://www.edaboard.com/thread101516.html
-*/
-bool convertToLocal (uint8_t* hour, uint16_t* year, uint8_t* month,
-                     uint8_t* day, const double lon, bool convertDate) {
-
-  uint8_t DaysAMonth [] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
-
-  // Get Day of Week (DOW)
-  uint8_t DOW = dayOfWeek(*year, *month, *day);
-  // Get Daylight Saving Time (DST) or Standard Time (ST)
-  bool DST = IsDST(*day, *month, DOW);
-  // Compute local time (hours)
-  int8_t UTCOffset = (int8_t)(lon / 15.0d); // UTC offset
-  if (UTCOffset < 0) {
-    // West of Greenwich, subtract
-    UTCOffset = abs(UTCOffset); // Make offset positive
-    if (DST) --UTCOffset; // Compensate for DST
-    if (*hour <= UTCOffset) *hour += 24;
-    *hour = *hour - UTCOffset; // Subtract offset
-  }
-  else {
-    // East of Greenwich, add
-    if (DST) ++UTCOffset; // Compensate for DST
-    if (*hour <= UTCOffset) *hour += 24;
-    *hour = *hour + UTCOffset; // Add offset
-  }
-  // Convert date if convertDate flag is set
-  // Portions of the following code (with some modifications) ripped off from Instructables
-  // http://www.instructables.com/id/GPS-time-UTC-to-local-time-conversion-using-Arduin/?ALLSTEPS
-  if (convertDate) {
-    if ((24 - *hour) <= UTCOffset) { // A new UTC day started
-      if (*year % 4 == 0) DaysAMonth[1] = 29; //leap year check (the simple method)
-      if (*hour < 24) {
-        *day -= 1;
-        if (*day < 1) {
-          if (*month == 1) {
-            *month = 12;
-            *year -= 1;
-          } // if (*month == 1)
-          else {
-            *month -= 1;
-          }
-          *day = DaysAMonth[*month - 1];
-        } // if (*day < 1)
-      } // if (*hour < 24)
-      else if (*hour >= 24) {
-        day += 1;
-        if (*day > DaysAMonth[*month - 1]) {
-          *day = 1;
-          *month += 1;
-          if (*month > 12) *year += 1;
-        } // if (*day > DaysAMonth[*month - 1])
-      } // if (*hour >= 24)
-    } // if ((24 - *hour) <= UTCOffset)
-  } // if (convertDate)
-  return (DST);
-}
-#endif // #ifdef CONVERT_TO_LOCAL
-#endif // #ifndef _16x2


rm speark playmusic example

rm speark playmusic example

--- examples/Basics/Speaker/Speaker.ino
+++ examples/Basics/Speaker/Speaker.ino
@@ -31,8 +31,6 @@
   M5.begin();

   M5.Lcd.printf("M5Stack Speaker test:\r\n");
-  M5.Speaker.setVolume(8);
-  M5.Speaker.playMusic(m5stack_startup_music, 25000);
 }

 void loop() {
@@ -44,13 +42,8 @@
   if(M5.BtnB.wasPressed())
   {
     M5.Lcd.printf("wasPressed B \r\n");
-    M5.Speaker.tone(3000, 200); //frequency 3000, with a duration of 200ms
+    M5.Speaker.tone(NOTE_DH2, 200); //frequency 3000, with a duration of 200ms
   }

-  if(M5.BtnC.wasPressed())
-  {
-    M5.Lcd.printf("wasPressed C \r\n");
-    M5.Speaker.playMusic(m5stack_startup_music, 25000); //play the M5Stack startup sound
-  }
   M5.update();
 }


Added ability to have a ".harold" hidden folder in addition to previous options.

--- Harold.ino
+++ Harold.ino
@@ -1,101 +0,0 @@
-//RFID uses Software Serial
-#include <SoftwareSerial.h>
-//iButton uses OneWire
-#include <OneWire.h>
-
-//iButton Variables
-OneWire  ds(7);
-byte addr[8];
-int but[6] = {0,149,107,48,13,0};
-String keyStatus = "";
-
-//RFID Variables
-SoftwareSerial RFID(2, 3);
-String msg;
-
-void setup()
-{
-  //Set up RFID
-  Serial.begin(9600);
-  RFID.begin(9600);
-  //Set up iButton
-  pinMode(13, OUTPUT);
-  //Print a ready message
-  Serial.println("ready");
-}
-
-//The char in iButton
-char c;
-
-void loop(){
-
-  //Checks serial for RFID info
-  checkRFID();
-  //Checks OneWire for iButton info
-  checkiButton();
-
-}
-
-void checkRFID() {
-
-  //When there is RFID info available, read through each character
-  while(RFID.available() > 0){
-    c=RFID.read();
-    msg += c;
-  }
-  //When the RFID info length is 14, print it and set message to null
-  if (msg.length() == 14) {
-    Serial.println(msg);
-    //Keep a delay so that it doesn't mistakenly read the same iButton more than once
-    delay(1000);
-  }
-  msg = "";
-  delay(200);
-
-}
-
-void checkiButton() {
-
-  //Get info on the key
-  getKeyCode();
-  //if the key is good go through this
-  if(keyStatus=="ok"){
-      int i;
-      //For CSH iButtons there are 7 code segments in hexidecimal
-      for( i = 7; i >= 0; i--) {
-
-        //Adds leading zeros to hex if only one character long
-        if( addr[i] < 0x10){
-        Serial.print("0");
-        }
-
-        //Prints rest of hex
-       Serial.print(addr[i], HEX);
-
-      }
-
-       //Keep a delay so that it doesn't mistakenly read the same iButton more than once
-      delay(1000);
-      //Makes a new line
-      Serial.println();
-
-  }
-  else if (keyStatus!="") {
-    Serial.print(keyStatus);
-  }
-  }
-
-//This does a lot of weird stuff about seeing if the data in the iButton is worth getting
-void getKeyCode(){
-  byte present = 0;
-  byte data[12];
-  keyStatus="";
-
-  if ( !ds.search(addr)) {
-      ds.reset_search();
-      return;
-  }
-
-  keyStatus="ok";
-  ds.reset();
-}


[Firmware] User friendly mDNS instance name

--- firmware/lm-wifilamp/x50_ota.ino
+++ firmware/lm-wifilamp/x50_ota.ino
@@ -6,6 +6,12 @@
 }

 void otaSetup() {
+  String name = "The Cave WiFi lamp (";
+  name += chipId;
+  name += ")";
+
+  MDNS.setInstanceName(name);
+
   String ssid = HOSTNAME_PREFIX;
   ssid += chipId;
   ArduinoOTA.setHostname(ssid.c_str());


Update ArduCAM_Shield_V2_short_movie_clip.ino

--- ArduCAM/examples/Shield_V2/ArduCAM_Shield_V2_short_movie_clip/ArduCAM_Shield_V2_short_movie_clip.ino
+++ ArduCAM/examples/Shield_V2/ArduCAM_Shield_V2_short_movie_clip/ArduCAM_Shield_V2_short_movie_clip.ino
@@ -94,8 +94,14 @@
 // set the CS as an output:
 pinMode(SD_CS, OUTPUT);
 pinMode(SPI_CS, OUTPUT);
+digitalWrite(SPI_CS, HIGH);
 // initialize SPI:
 SPI.begin();
+//Reset the CPLD
+myCAM.write_reg(0x07, 0x80);
+delay(100);
+myCAM.write_reg(0x07, 0x00);
+delay(100);
 while(1){
   //Check if the ArduCAM SPI bus is OK
   myCAM.write_reg(ARDUCHIP_TEST1, 0x55);


Don't wait for a connection to an AP when we're supposed to be the AP.

--- hardware/esp8266com/esp8266/libraries/ESP8266WiFi/examples/WiFiAccessPoint/WiFiAccessPoint.ino
+++ hardware/esp8266com/esp8266/libraries/ESP8266WiFi/examples/WiFiAccessPoint/WiFiAccessPoint.ino
@@ -55,9 +55,6 @@
 	/* You can remove the password parameter if you want the AP to be open. */
 	WiFi.softAP(ssid, password);

-	while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); }
-
-	Serial.println("done");
 	IPAddress myIP = WiFi.softAPIP();
 	Serial.print("AP IP address: ");
 	Serial.println(myIP);


Fix BuzzerKonami example indexes beyond the end of the defined array(!)

--- build/shared/examples/09.EducationalBP_MKII/BuzzerKonami/BuzzerKonami.ino
+++ build/shared/examples/09.EducationalBP_MKII/BuzzerKonami/BuzzerKonami.ino
@@ -70,7 +70,7 @@
 }
 void loop()
 {
-  for (int thisNote = 0; thisNote < 80; thisNote++) {
+  for (int thisNote = 0; (sizeof(melody)/sizeof(int)); thisNote++) {

     // to calculate the note duration, take one second
     // divided by the note type.


speaker support

speaker support

--- Modules/att_buzzer/att_buzzer.ino
+++ Modules/att_buzzer/att_buzzer.ino
@@ -1,7 +1,6 @@
 // Attiny85 buzzer
 // Worked for me at 8mhz
-// Attiny Pin 4 >> 220 Ohm resistor >> Piezo buzzer >> GND
-//
+// Attiny Pin 4 >> 220 Ohm resistor >> Piezo buzzer or 8 Ohm / 1 Watt speaker >> GND
 // Largely copied from http://www.technoblogy.com/show?20MO

 // Can be 1 or 4


pin 13

pin 13

--- Otto_avoid_mhs/Otto_avoid_mhs.ino
+++ Otto_avoid_mhs/Otto_avoid_mhs.ino
@@ -27,8 +27,8 @@
   #define PIN_RL 4 //servo[4]
   #define PIN_RR 5 //servo[5]

-  #define ECHOPIN 8        // Pin to receive echo pulse
-  #define TRIGPIN 9        // Pin to send trigger pulse
+  #define ECHOPIN 9        // Pin to receive echo pulse
+  #define TRIGPIN 8        // Pin to send trigger pulse

 ///////////////////////////////////////////////////////////////////
 //-- Global Variables -------------------------------------------//


new water boundaries

new water boundaries

--- plantstation.ino
+++ plantstation.ino
@@ -75,8 +75,8 @@
 boolean waterPumpIsOn = false;
 unsigned long wateringSeconds = 61000;
 unsigned long prevWatering = 0;
-int waterMaxVal = 369;
-int waterMinVal = 110;
+int waterMaxVal = 690;
+int waterMinVal = 0;

 //===== For timed events =========================
 // todo - timed events use regule marers for 1 min 1 hour etc and divide blah


LPG serial tester

LPG serial tester

--- tests/LpgSerial/LpgSerial.ino
+++ tests/LpgSerial/LpgSerial.ino
@@ -24,11 +24,11 @@
     }

     if (pinState == LOW && serial2Change) {
-        serial2Length = (uint8_t) (millis() - serial2LastTime); //if it is low, end the time
+        serial2Length = (uint8_t)(millis() - serial2LastTime); //if it is low, end the time
         serial2LastTime = millis();
         serial2Change = false;

-        if (serial2Length >= 2 && serial2Length <= 6) { // 5ms read
+        if (serial2Length >= 1 && serial2Length <= 6) { // 5ms read
             dataBuff += 0 << serial2Offset;
             serial2Offset++;

@@ -43,7 +43,7 @@
         //
         // 110100000001 // act LPG full

-        if (serial2Length > 8) { // 15 downs
+        if (serial2Length > 8 || serial2Offset > 11) { // 15 downs
             serial2Readed = true;
             serial2Length = 0;
             serial2Offset = 0;
@@ -65,6 +65,7 @@

 void setup() {
     pinMode(pinInput, INPUT);
+    digitalWrite(pinInput, LOW);

 //    attachInterrupt(digitalPinToInterrupt(pinInput), serialEvent2, FALLING );
     Serial.begin(115200);


Round double to int just for simplicity

Round double to int just for simplicity

--- ARTF_Sensors/examples/LowPowerMoistureWithSD/LowPowerMoistureWithSD.ino
+++ ARTF_Sensors/examples/LowPowerMoistureWithSD/LowPowerMoistureWithSD.ino
@@ -62,7 +62,7 @@
     int reading = analogRead(MOISTURE_PIN);
     moistureReadings[i] = (double)reading / (double)MOISTURE_MAX_READING;

-    output += String(i) + ". Analog:" + String(reading) + "; Calculated:" + String(moistureReadings[i]) + "\n";
+    output += String(i) + ". Analog:" + String(reading) + "; Calculated:" + String((int)(moistureReadings[i] * 100)) + "\n";

     delay(300);
   }


hmm, but those end stops have to come from some where …


Fix the fix.

Fix the fix.

--- res/Examples/MIDI_SimpleSynth/MIDI_SimpleSynth.ino
+++ res/Examples/MIDI_SimpleSynth/MIDI_SimpleSynth.ino
@@ -18,12 +18,12 @@

 // -----------------------------------------------------------------------------

-void handleGateChanged(bool inGateActive)
+inline void handleGateChanged(bool inGateActive)
 {
     digitalWrite(sGatePin, inGateActive ? HIGH : LOW);
 }

-void pulseGate()
+inline void pulseGate()
 {
     handleGateChanged(false);
     delay(1);
@@ -32,7 +32,7 @@

 // -----------------------------------------------------------------------------

-void handleNotesChanged()
+void handleNotesChanged(bool isFirstNote = false)
 {
     if (midiNotes.empty())
     {
@@ -50,7 +50,15 @@
         if (midiNotes.getLast(currentNote))
         {
             tone(sAudioOutPin, sNotePitches[currentNote]);
-            pulseGate(); // Retrigger envelopes. Remove for legato effect.
+
+            if (isFirstNote)
+            {
+                handleGateChanged(true);
+            }
+            else
+            {
+                pulseGate(); // Retrigger envelopes. Remove for legato effect.
+            }
         }
     }
 }
@@ -59,8 +67,9 @@

 void handleNoteOn(byte inChannel, byte inNote, byte inVelocity)
 {
+    const bool firstNote = midiNotes.empty();
     midiNotes.add(MidiNote(inNote, inVelocity));
-    handleNotesChanged();
+    handleNotesChanged(firstNote);
 }

 void handleNoteOff(byte inChannel, byte inNote, byte inVelocity)


added direction for motor when have to stop because a button has been touched

--- jenny5-firmware/jenny5-firmware.ino
+++ jenny5-firmware/jenny5-firmware.ino
@@ -39,7 +39,7 @@
 void setup()
 {
   first_start = 0;
-  strcpy(firmware_version, "2017.01.09.0");
+  strcpy(firmware_version, "2017.01.11.0");

   current_buffer[0] = 0;

@@ -340,12 +340,14 @@
           }
           else if (tmp_str[j] == 'B' || tmp_str[j] == 'b') {
             int sensor_index;
-            sscanf(tmp_str + j + 1, "%d", &sensor_index);
+            int _direction;
+            int num_consumed;
+            sscanf(tmp_str + j + 1, "%d%d", &sensor_index, &_direction, &num_consumed);
             if (motor_type == 'S' || motor_type == 's') // attach to stepper motors controller
-              stepper_motors_controller.add_sensor(motor_index, BUTTON, sensor_index, 0, 0, 0, 0);
+              stepper_motors_controller.add_sensor(motor_index, BUTTON, sensor_index, 0, 0, 0, _direction);
             else if (motor_type == 'D' || motor_type == 'd') // attach to DC motors controller
               dc_motors_controller_TB6612FNG.add_sensor(motor_index, BUTTON, sensor_index);
-            j += 2;
+            j += 1 + num_consumed;
             k++;
           }
           else


Renamed Blynk macro.

Renamed Blynk macro.

--- thermometer01.ino
+++ thermometer01.ino
@@ -135,7 +135,8 @@
 #ifdef BLYNK_CLOUD
 const unsigned int PERIOD_PUBLISH_BLYNK = 30000;
 char BLYNK_TOKEN[] = CREDENTIALS_BLYNK_TOKEN;
-#define BLYNK_VPIN_BOOT_VALUE  V1
+#define BLYNK_VPIN_BOOTS       V1
+#define BLYNK_VPIN_RECONNECTS  V10
 #define BLYNK_VPIN_RSSI_VALUE  V2
 #define BLYNK_VPIN_TEMP_VALUE  V3
 #define BLYNK_VPIN_TEMP_GRAF   V11
@@ -145,7 +146,6 @@
 #define BLYNK_VPIN_TEMP_RESET  V7
 #define BLYNK_VPIN_TEMP_LED1   V8
 #define BLYNK_VPIN_TEMP_LED2   V9
-#define BLYNK_VPIN_RECONNECTS  V10
 #if defined(BLYNK_SIGNAL_TEMP)
 WidgetLED ledTempInc(BLYNK_VPIN_TEMP_LED1);
 WidgetLED ledTempDec(BLYNK_VPIN_TEMP_LED2);
@@ -492,10 +492,10 @@
 //-------------------------------------------------------------------------
 // Blynk reads
 //-------------------------------------------------------------------------
-#ifdef BLYNK_VPIN_BOOT_VALUE
-BLYNK_READ(BLYNK_VPIN_BOOT_VALUE)
-{
-    Blynk.virtualWrite(BLYNK_VPIN_BOOT_VALUE, bootCount);
+#ifdef BLYNK_VPIN_BOOTS
+BLYNK_READ(BLYNK_VPIN_BOOTS)
+{
+    Blynk.virtualWrite(BLYNK_VPIN_BOOTS, bootCount);
 }
 #endif


temporarily disabled in order for the SL to work on Arduino models with only 2KB of memory

--- saltlamp.ino
+++ saltlamp.ino
@@ -20,8 +20,8 @@
 #include "modules/saltlamp_PWM.h"
 #include "modules/saltlamp_TEMP.h"
 #include "modules/saltlamp_433.h"
-#include "modules/saltlamp_IR.h"
-#include "modules/saltlamp_US.h"
+// #include "modules/saltlamp_IR.h"
+// #include "modules/saltlamp_US.h"

 // Variables for parsing PC commands
 String ser_string = "";
@@ -58,14 +58,14 @@
 saltlamp_433 ftt433(Serial, response_msg, DEVS);
 // saltlamp_IR IR(Serial, response_msg, DEVS);

-saltlamp_US US(Serial, response_msg, DEVS);
-void saltlamp_US_interrupt1() { US.measure(); }
+// saltlamp_US US(Serial, response_msg, DEVS);
+// void saltlamp_US_interrupt1() { US.measure(); }

 void loop()
 {
 	DI.loop();
 	AI.loop();
-	US.loop();
+// 	US.loop();
 	TEMP.loop();
 // 	IR.loop();
 	ftt433.loop();
@@ -94,8 +94,8 @@
 			OW.parse(ser_command, ser_pin, ser_value);
 		} else if (ser_module == "TEMP") {
 			TEMP.parse(ser_command, ser_pin, ser_value);
-		} else if (ser_module == "US") {
-			US.parse(ser_command, ser_pin, ser_value);
+// 		} else if (ser_module == "US") {
+// 			US.parse(ser_command, ser_pin, ser_value);
 		} else if (ser_module == "SYS") {
 			SYS.parse(ser_command, ser_pin, ser_value);
 		} else if (ser_module == "433") {


Swapped HIGH and LOW for len pin

Swapped HIGH and LOW for len pin

--- quick_release.ino
+++ quick_release.ino
@@ -50,7 +50,7 @@
     pinMode(STIM_OUT, OUTPUT);
     pinMode(STIM_LED, OUTPUT);
     // Initial pin states
-    digitalWrite(LEN_OUT, LOW);
+    digitalWrite(LEN_OUT, HIGH);
     digitalWrite(LEN_LED, LOW);
     digitalWrite(SHUT_OUT, LOW);
     digitalWrite(SHUT_LED, LOW);
@@ -96,7 +96,7 @@
     digitalWrite(SHUT_OUT, HIGH); // shutter opened before step delay
     digitalWrite(SHUT_LED, HIGH); // may open during pre-delay in future
     delay(shutterdelay);
-    digitalWrite(LEN_OUT, HIGH);
+    digitalWrite(LEN_OUT, LOW);
     digitalWrite(LEN_LED, HIGH);
     delayMicroseconds(stepdelay);
     digitalWrite(EXPOSE_OUT, HIGH);
@@ -109,6 +109,6 @@
     digitalWrite(SHUT_OUT, LOW);
     digitalWrite(SHUT_LED, LOW);
     delay(postexposure);
-    digitalWrite(LEN_OUT, LOW);
+    digitalWrite(LEN_OUT, HIGH);
     digitalWrite(LEN_LED, LOW);
 }


Update RobotControl.ino

Update RobotControl.ino

--- Arduino/RobotControl/RobotControl.ino
+++ Arduino/RobotControl/RobotControl.ino
@@ -50,13 +50,10 @@
       break;
     case (2):
       //droite
-
-      digitalWrite(MD1,HIGH);
-      digitalWrite(MD2,LOW);
-
-      digitalWrite(MG1,LOW);
-      digitalWrite(MG2,HIGH);
-
+      digitalWrite(MD1,LOW);
+      digitalWrite(MD2,HIGH);
+
+      digitalWrite(MG1,HIGH);
       break;

     case (3):
@@ -70,11 +67,12 @@

     case (4):
       //gauche
-      digitalWrite(MD1,LOW);
-      digitalWrite(MD2,HIGH);
-
-      digitalWrite(MG1,HIGH);
       digitalWrite(MG2,LOW);
+      digitalWrite(MD1,HIGH);
+      digitalWrite(MD2,LOW);
+
+      digitalWrite(MG1,LOW);
+      digitalWrite(MG2,HIGH);
       break;

     default:


Added license to example

Added license to example

--- examples/usage.ino
+++ examples/usage.ino
@@ -1,3 +1,7 @@
+/* Part of EEPROM (24XX512) Arduino library
+ * Copyright (C) 2017 Kane Wallmann
+ * See LICENCE.txt for license (MIT)*/
+
 #include <Wire.h>
 #include <EEPROM_24XX512.h>


Commit.

Commit.

--- skypointer.ino
+++ skypointer.ino
@@ -1,104 +1,104 @@
-#include <SerialCommand.h>
-#include "SkyPointer_MotorShield.h"
+#include <SerialCommand.h>
+#include "SkyPointer_MotorShield.h"

-MotorShield shield = MotorShield();
-
-AccelStepper AZ(AccelStepper::DRIVER, XSTEP, XDIR);
-AccelStepper ALT(AccelStepper::DRIVER, YSTEP, YDIR);
-
-SerialCommand sCmd;
-
-void ProcessGoto() {
-    uint16_t pos, simPos, tgt1, tgt2;
-    int16_t delta1, delta2; // SIGNED
-
-    // Get target positions
-    tgt1 = MOD(atoi(sCmd.next()), USTEPS_REV);
-    tgt2 = MOD(atoi(sCmd.next()), USTEPS_REV);
-
-    // AZ motor
-    // Get current position and calculate simmetric position
-    pos = MOD(AZ.currentPosition(), USTEPS_REV);
-    simPos = MOD(pos + USTEPS_REV/2, USTEPS_REV);
-    // Distance to go (positive / negative)
-    delta1 = tgt1 - pos;
-    // Distance from simmetric position
-    delta2 = simPos - tgt1;
-
-    /* Correct delta1 if necessary
-    The direction can be specified in the move() method by the sign of the
-    relative distance to go. If positive, the motor turns forward, or
-    backward otherwhise.
-    */
-    if (pos < USTEPS_REV/2) {
-        // Transform delta to its (negative) simmetric.
-        delta1 = (delta2 < 0) ? delta1 - USTEPS_REV : delta1;
-    }
-    else {
-        // Transform delta to its (positive) simmetric.
-        delta1 = (delta2 > 0) ? delta1 + USTEPS_REV : delta1;
-    }
-    // Rotate AZ motor
-    AZ.move(delta1);
-
-    // ALT motor
-    // Get current position and calculate simmetric position
-    pos = MOD(ALT.currentPosition(), USTEPS_REV);
-    simPos = MOD(pos + USTEPS_REV/2, USTEPS_REV);
-    // Distance to go (positive / negative)
-    delta1 = tgt2 - pos;
-    // Distance from simmetric position
-    delta2 = simPos - tgt2;
-
-    /* Correct delta1 if necessary
-    The direction can be specified in the move() method by the sign of the
-    relative distance to go. If positive, the motor turns forward, or
-    backward otherwhise.
-    */
-    if (pos < USTEPS_REV/2) {
-        // Transform delta to its (negative) simmetric.
-        delta1 = (delta2 < 0) ? delta1 - USTEPS_REV : delta1;
-    }
-    else {
-        // Transform delta to its (positive) simmetric.
-        //delta1 = (delta2 > 0) ? MOD(delta1 + USTEPS_REV, USTEPS_REV) : delta1;
-        delta1 = (delta2 > 0) ? delta1 + USTEPS_REV : delta1;
-    }
-    // Rotate ALT motor
-    ALT.move(delta1);
-
-    Serial.print("OK\r");
-}
-
-void Unrecognized() {
-    Serial.print("NK\r");
-}
-
-void setup() {
-    pinMode(XSTEP, OUTPUT);
-    pinMode(XDIR, OUTPUT);
-    //pinMode(ENABLE, OUTPUT);
-
-    AZ.setPinsInverted(false, false, true);
-    AZ.setMaxSpeed(MAX_SPEED);
-    AZ.setAcceleration(ACCEL);
-    AZ.setEnablePin(ENABLE);
-
-    ALT.setPinsInverted(false, false, true);
-    ALT.setMaxSpeed(MAX_SPEED);
-    ALT.setAcceleration(ACCEL);
-    ALT.setEnablePin(ENABLE);
-
-    sCmd.addCommand("G", ProcessGoto);
-    sCmd.addDefaultHandler(Unrecognized);
-
-    Serial.begin(BAUDRATE);
-}
-
-void loop() {
-    sCmd.readSerial();
-    AZ.run();
-    ALT.run();
-
-}
+MotorShield shield = MotorShield();
+
+AccelStepper AZ(AccelStepper::DRIVER, XSTEP, XDIR);
+AccelStepper ALT(AccelStepper::DRIVER, YSTEP, YDIR);
+
+SerialCommand sCmd;
+
+void ProcessGoto() {
+    uint16_t pos, simPos, tgt1, tgt2;
+    int16_t delta1, delta2; // SIGNED
+
+    // Get target positions
+    tgt1 = MOD(atoi(sCmd.next()), USTEPS_REV);
+    tgt2 = MOD(atoi(sCmd.next()), USTEPS_REV);
+
+    // AZ motor
+    // Get current position and calculate simmetric position
+    pos = MOD(AZ.currentPosition(), USTEPS_REV);
+    simPos = MOD(pos + USTEPS_REV/2, USTEPS_REV);
+    // Distance to go (positive / negative)
+    delta1 = tgt1 - pos;
+    // Distance from simmetric position
+    delta2 = simPos - tgt1;
+
+    /* Correct delta1 if necessary
+    The direction can be specified in the move() method by the sign of the
+    relative distance to go. If positive, the motor turns forward, or
+    backward otherwhise.
+    */
+    if (pos < USTEPS_REV/2) {
+        // Transform delta to its (negative) simmetric.
+        delta1 = (delta2 < 0) ? delta1 - USTEPS_REV : delta1;
+    }
+    else {
+        // Transform delta to its (positive) simmetric.
+        delta1 = (delta2 > 0) ? delta1 + USTEPS_REV : delta1;
+    }
+    // Rotate AZ motor
+    AZ.move(delta1);
+
+    // ALT motor
+    // Get current position and calculate simmetric position
+    pos = MOD(ALT.currentPosition(), USTEPS_REV);
+    simPos = MOD(pos + USTEPS_REV/2, USTEPS_REV);
+    // Distance to go (positive / negative)
+    delta1 = tgt2 - pos;
+    // Distance from simmetric position
+    delta2 = simPos - tgt2;
+
+    /* Correct delta1 if necessary
+    The direction can be specified in the move() method by the sign of the
+    relative distance to go. If positive, the motor turns forward, or
+    backward otherwhise.
+    */
+    if (pos < USTEPS_REV/2) {
+        // Transform delta to its (negative) simmetric.
+        delta1 = (delta2 < 0) ? delta1 - USTEPS_REV : delta1;
+    }
+    else {
+        // Transform delta to its (positive) simmetric.
+        //delta1 = (delta2 > 0) ? MOD(delta1 + USTEPS_REV, USTEPS_REV) : delta1;
+        delta1 = (delta2 > 0) ? delta1 + USTEPS_REV : delta1;
+    }
+    // Rotate ALT motor
+    ALT.move(delta1);
+
+    Serial.print("OK\r");
+}
+
+void Unrecognized() {
+    Serial.print("NK\r");
+}
+
+void setup() {
+    pinMode(XSTEP, OUTPUT);
+    pinMode(XDIR, OUTPUT);
+    //pinMode(ENABLE, OUTPUT);
+
+    AZ.setPinsInverted(false, false, true);
+    AZ.setMaxSpeed(MAX_SPEED);
+    AZ.setAcceleration(ACCEL);
+    AZ.setEnablePin(ENABLE);
+
+    ALT.setPinsInverted(false, false, true);
+    ALT.setMaxSpeed(MAX_SPEED);
+    ALT.setAcceleration(ACCEL);
+    ALT.setEnablePin(ENABLE);
+
+    sCmd.addCommand("G", ProcessGoto);
+    sCmd.addDefaultHandler(Unrecognized);
+
+    Serial.begin(BAUDRATE);
+}
+
+void loop() {
+    sCmd.readSerial();
+    AZ.run();
+    ALT.run();
+
+}


Functions writeErrorToEEPROM() and readErrorFromEEPROM() implemented but not working correctly. Write is OK but reading the stored values gives a wrong result.

--- skypointer.ino
+++ skypointer.ino
@@ -53,7 +53,43 @@
 // Motor 2 on port 2, 200 steps/rev
 SkyPointer_MicroStepper *motor2 = MS.getMicroStepper(STEPS, 2);

-
+/****************************************************************************
+ * Functions for writing/reading mechanical errors to/from EPRROM
+ ***************************************************************************/
+void writeErrorToEEPROM (int n, double Z) {
+    // Writes to EEPROM the n-th error correction, where n = 1, 2 or 3
+    /*
+    Values are converted to a double int by multiplying by 100.000.000
+    The longest value is 4-byte long:
+        LSB =
+
+        MSB =
+    */
+
+    for (unsigned int k = 0; k < 12; k++) {
+        EEPROM.write (k, 0);
+    }
+
+    long _z = long(Z * 1e8);
+
+    for (unsigned int k = 0; k < 4; k++) {
+        // Write the 3 lowest bytes (not the sign)
+        Serial.println(int((_z >> 8*k) & 0xFF), HEX);
+        EEPROM.write(4*(n-1) + k, (int) ((_z >> 8*k) & 0xFF));
+    }
+}
+
+double readErrorFromEEPROM (int n) {
+    // Reads the n-th error stored in the EEPROM and converts it to double,
+    // where n = 1, 2 or 3
+    long res = 0;
+    for (unsigned int k = 0; k < 3; k++) {
+        res += long((EEPROM.read(4*(n-1)+k)) << 8*k);
+    }
+    Serial.println(res, HEX);
+    return 0;
+}
+/****************************************************************************/
 // Interruption routine
 void ISR_rotate() {
   #ifdef DEBUG
@@ -199,41 +235,6 @@
 void Unrecognized() {
   Serial.print("NK\r");
 }
-
-
-/****************************************************************************
- * Functions for writing/reading mechanical errors to/from EPRROM
- ***************************************************************************/
-void writeMechanicalErrors (double z1) {
-    // Writes mechanical error corrections to EEPROM
-    // Convert values to long int
-    long _z1 = long (z1 * 1e8);
-    EEPROM.write (0x00, _z1);
-    EEPROM.write (0x01, _z1 >> 8);
-    EEPROM.write (0x02, _z1 >> 16);
-    /*
-    long _z2 = long (z2 * 1e8);
-    EEPROM.write (0x03, _z2 >> 16);
-    EEPROM.write (0x04, _z2 >> 8);
-    EEPROM.write (0x05, _z2);
-
-    long _z3 = long (z3 * 1e8);
-    EEPROM.write (0x06, _z3 >> 16);
-    EEPROM.write (0x07, _z3 >> 8);
-    EEPROM.write (0x08, _z3);
-    */
-}
-
-double readMechanicalError (int n) {
-    // Reads one of the three mechanical errors, defined by the int n
-    long res = 0;
-
-    for (unsigned int k = 0; k < 3; k++) {
-        res |= (Serial.println(EEPROM.read(3*n + k)) << 8*k );
-    }
-    return double(res);
-}
-
 /****************************************************************************/

 void setup() {
@@ -261,25 +262,18 @@
   // Start motor shield
   MS.begin();
   motor1->setSpeed(RPM);
-  motor2->setSpeed(RPM);
-
-
-  double M = -0.99999999; // Longest possible value in HEX (negative value)
-  //double M = Z3;
-  Serial.print("Z1 = "); Serial.println(M, 8);
-  long z1  = long(M * 1e8);
-  Serial.print("HEX = "); Serial.println(z1, HEX);
-  int a = int(z1 & 0xFF);
-  Serial.print("B0 = "); Serial.println(a, HEX);
-  int b = int((z1 & 0xFF00) >> 8);
-  Serial.print ("B1 = "); Serial.println(b, HEX);
-  int c = int((z1 & 0xFF0000) >> 16);
-  Serial.print("B2 = "); Serial.println(c, HEX);
-  int d = int((z1 & 0xFF000000) >> 24);
-  Serial.print("B3 = "); Serial.println(d, HEX);
-
-}
-
+  motor2->setSpeed(RPM);
+
+  long err = Z1 * 1e8;
+  Serial.print ("Val = "); Serial.println (err, DEC);
+  Serial.print ("HEX = "); Serial.println (err, HEX);
+
+  writeErrorToEEPROM (1, Z1);
+
+  readErrorFromEEPROM (1);
+
+
+}

 void loop() {
   sCmd.readSerial();  // Read commands from serial port


Fix compiling on a case sensitive file systems

--- wled00/wled00.ino
+++ wled00/wled00.ino
@@ -51,7 +51,7 @@
 #endif

 #include <EEPROM.h>
-#include <WiFiUDP.h>
+#include <WiFiUdp.h>
 #include <DNSServer.h>
 #ifndef WLED_DISABLE_OTA
  #include <ArduinoOTA.h>


Fix for default configuration parameter of REST API.

--- src/main.ino
+++ src/main.ino
@@ -77,7 +77,7 @@
   os_strcpy(cfg.wifi_psk, WIFI_PSK);

   // REST API
-  cfg.api = MQTT_HOMEASSISTANT_DISCOVERY_ENABLED;
+  cfg.api = REST_API_ENABLED;
   os_strcpy(cfg.api_key, ADMIN_PASSWORD);

   EEPROM_write(cfg);


Print String Output containing LatLong Information

Addition of single string output containing full decimal LatLong data

--- arduino/GPS_HardwareSerial_Parsing_Mod/GPS_HardwareSerial_Parsing_Mod.ino
+++ arduino/GPS_HardwareSerial_Parsing_Mod/GPS_HardwareSerial_Parsing_Mod.ino
@@ -30,6 +30,7 @@

 uint32_t timer = millis();

+String currLatLong;

 void setup()
 {
@@ -60,6 +61,8 @@

   // Ask for firmware version
   GPSSerial.println(PMTK_Q_RELEASE);
+
+  //currLatLong = "null";
 }

 void loop() // run over and over again
@@ -104,6 +107,9 @@
       Serial.print("Angle: "); Serial.println(GPS.angle);
       Serial.print("Altitude: "); Serial.println(GPS.altitude);
       Serial.print("Satellites: "); Serial.println((int)GPS.satellites);
+
+      currLatLong = String(fabs(GPS.latitudeDegrees), 6) + "deg" + GPS.lat + ", " + String(fabs(GPS.longitudeDegrees), 6) + "deg" + GPS.lon;
+      Serial.print("Output Processed LatLong String: "); Serial.println(currLatLong);
     }
   }
 }


Code cleanup

Code cleanup

--- files/template_photonik/template_photonik_wifi/template_photonik_wifi.ino
+++ files/template_photonik/template_photonik_wifi/template_photonik_wifi.ino
@@ -4,7 +4,7 @@
 Date: 2015-02-04
 Homepage: http://www.sensebox.de
 Author: Jan Wirwahn
-Note: Sketch for SB-Photonik-WiFi
+Note: Sketch for SB-Photonik-WiFi.
 */
 #include <Wire.h>
 #include <SPI.h>
@@ -29,8 +29,7 @@
 #define ADAFRUIT_CC3000_VBAT  5
 #define ADAFRUIT_CC3000_CS    10
 #define IDLE_TIMEOUT_MS  3000
-// Use hardware SPI for the remaining pins
-// On an UNO, SCK = 13, MISO = 12, and MOSI = 11
+
 Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT,
                                          SPI_CLOCK_DIVIDER); // you can change this clock speed
 //Server values
@@ -80,7 +79,6 @@
     delay(100); // ToDo: Insert a DHCP timeout!
   }
   ip = 0;
-  // Try looking up the website's IP address
   Serial.print(WEBSITE); Serial.print(F(" -> "));
   while (ip == 0) {
     if (! cc3000.getHostByName(WEBSITE, &ip)) {
@@ -142,14 +140,6 @@
   Adafruit_CC3000_Client client = cc3000.connectTCP(ip, 8000);

   if (client.connected()) {
-    /*
-    clientclient.print(F("GET "));
-    client.print(F("/"));
-    client.print(F(" HTTP/1.1\r\n"));
-    client.print(F("Host: ")); client.fastrprint(WEBSITE); .fastrprint(F("\r\n"));
-    www.print(F("\r\n"));
-    www.println();
-    */
     client.print("POST /boxes/");
     client.print(SENSEBOX_ID);
     client.print("/");
@@ -173,7 +163,6 @@

   Serial.println(F("-------------------------------------"));

-  /* Read data until either the connection is closed, or the idle timeout is reached. */
   unsigned long lastRead = millis();
   while (client.connected() && (millis() - lastRead < IDLE_TIMEOUT_MS)) {
     while (client.available()) {
@@ -189,10 +178,8 @@
       sampleType = 1;
     }else sampleType++;
   }
-  /* You need to make sure to clean up after yourself or the CC3000 can freak out */
-  /* the next time your try to connect ... */
-  Serial.println(F("\n\nDisconnecting"));
-//  cc3000.disconnect();
+
+  Serial.println(F("\n\nConnection closed."));

  delay(1000);
 }
@@ -200,9 +187,6 @@
 String floatToString(float number, int precision)
 {
   String stringNumber = "";
-  //int prec;
-  //only temperature (case 1) has a decimal place
-  //if (sampleType == 1) prec = 1; else prec = 0;
   char tempChar[10];
   dtostrf(number, 1, precision, tempChar);
   stringNumber += tempChar;


線の長さの微調整

線の長さの微調整

--- 2_example/example63_google/example63_google.ino
+++ 2_example/example63_google/example63_google.ino
@@ -49,7 +49,7 @@
 ???の部分を #define GScriptId の""内へコピーしてください。

 ※注意事項：???の部分が他人に知られると、アカウント内の予定表が閲覧されます。
-*/
+*******************************************************************************/

 #ifdef CQ_PUB_IOT_EXPRESS
     #define PIN_BUZZER 12                   // GPIO 12にスピーカを接続


Add files via upload

Add files via upload

fixed some issue with blinking with one eye.
fixed some warnings from original code

--- Teensy3.1_Eyes-master/uncannyEyes/uncannyEyes.ino
+++ Teensy3.1_Eyes-master/uncannyEyes/uncannyEyes.ino
@@ -77,7 +77,7 @@
 typedef struct {
   int8_t   pin;       // Optional button here for indiv. wink
   uint8_t  state;     // NOBLINK/ENBLINK/DEBLINK
-  int32_t  duration;  // Duration of blink state (micros)
+  uint32_t  duration;  // Duration of blink state (micros)
   uint32_t startTime; // Time (micros) of last state change
 } eyeBlink;

@@ -99,8 +99,7 @@
 uint16_t a2_value;
 bool auto_eyes = true;
 bool auto_blink = true;
-bool blinkR = false;
-bool blinkL = false;
+bool blink_eye[2];
 bool force_blink = false;
 // INITIALIZATION -- runs once at startup ----------------------------------

@@ -110,6 +109,8 @@
   a0_value = 512;
   a1_value = 512;
   a2_value = 256;
+  blink_eye[0] = false;
+  blink_eye[1] = false;
   uint8_t e;

   Serial.begin(115200);
@@ -253,7 +254,7 @@

 void frame( // Process motion for a single frame of left or right eye
   uint16_t        iScale) {     // Iris scale (0-1023) passed in
-  static uint32_t frames   = 0; // Used in frame rate calculation
+  //static uint32_t frames   = 0; // Used in frame rate calculation
   static uint8_t  eyeIndex = 0; // eye[] array counter
   int16_t         eyeX, eyeY;
   uint32_t        t = micros(); // Time at start of function
@@ -263,9 +264,6 @@
   if(++eyeIndex >= NUM_EYES) eyeIndex = 0; // Cycle through eyes, 1 per call

   // X/Y movement
-
-//#if defined(JOYSTICK_X_PIN) && (JOYSTICK_X_PIN >= 0) && \
-//    defined(JOYSTICK_Y_PIN) && (JOYSTICK_Y_PIN >= 0)
 if (!auto_eyes){
   // Read X/Y from joystick, constrain to circle
   int16_t dx, dy;
@@ -358,13 +356,9 @@
     if((t - eye[eyeIndex].blink.startTime) >= eye[eyeIndex].blink.duration) {
       // Yes -- increment blink state, unless...
       if((eye[eyeIndex].blink.state == ENBLINK) &&  // Enblinking and...
-        //((digitalRead(BLINK_PIN) == LOW) ||         // blink or wink held...
         ((force_blink) ||         // blink or wink held...
-          digitalRead(eye[eyeIndex].blink.pin) == LOW)) {
+         blink_eye[eyeIndex])) {
         // Don't advance state yet -- eye is held closed instead
-        force_blink = false;
-        blinkR = false;
-        blinkL = false;
       } else { // No buttons, or other state...
         if(++eye[eyeIndex].blink.state > DEBLINK) { // Deblinking finished?
           eye[eyeIndex].blink.state = NOBLINK;      // No longer blinking
@@ -387,13 +381,7 @@
         }
       }
     //} else if(digitalRead(eye[eyeIndex].blink.pin) == LOW) { // Wink!
-    } else if(blinkR) { // Wink!
-      //blinkR = false;
-      eye[eyeIndex].blink.state     = ENBLINK;
-      eye[eyeIndex].blink.startTime = t;
-      eye[eyeIndex].blink.duration  = random(45000, 90000);
-    } else if(blinkL) { // Wink!
-      //blinkL = false;
+    } else if(blink_eye[eyeIndex]) { // Wink!
       eye[eyeIndex].blink.state     = ENBLINK;
       eye[eyeIndex].blink.startTime = t;
       eye[eyeIndex].blink.duration  = random(45000, 90000);
@@ -457,9 +445,6 @@
   drawEye(eyeIndex, iScale, eyeX, eyeY, n, lThreshold);
 }

-
-// AUTONOMOUS IRIS SCALING (if no photocell or dial) -----------------------
-
 #if !defined(IRIS_PIN) || (IRIS_PIN < 0)

 // Autonomous iris motion uses a fractal behavior to similate both the major
@@ -523,14 +508,14 @@
       force_blink=false;
     }
     else if(serial_in.startsWith("blinkR")){
-      blinkR = true;
+      blink_eye[1] = true;
       auto_blink=false;
     }
     else if(serial_in.startsWith("blinkL")){
-      blinkL = true;
+      blink_eye[0] = true;
       auto_blink=false;
     }
-    else if(serial_in.startsWith("blink") && !blinkL && !blinkR){
+    else if(serial_in.startsWith("blink") && !blink_eye[0] && !blink_eye[1]){
       force_blink=true;
       auto_blink=false;
     }
@@ -541,32 +526,13 @@
     serial_in_complete = false;
   }

-
-#ifdef IRIS_PIN && (IRIS_PIN >= 0) // Interactive iris
-
-  //uint16_t v = analogRead(IRIS_PIN);       // Raw dial/photocell reading
-#ifdef IRIS_PIN_FLIP
-  a2_value = 1023 - a2_value;
-#endif
   uint16_t a2_value_mapped = map(a2_value, 0, 1023, IRIS_MIN, IRIS_MAX); // Scale to iris range
-#ifdef IRIS_SMOOTH // Filter input (gradual motion)
-  static uint16_t irisValue = (IRIS_MIN + IRIS_MAX) / 2;
-  irisValue = ((irisValue * 15) + a2_value_mapped) / 16;
-  frame(irisValue);
-#else // Unfiltered (immediate motion)
+
   frame(a2_value_mapped);
-#endif // IRIS_SMOOTH
-
-#else  // Autonomous iris scaling -- invoke recursive function
-
-  newIris = random(IRIS_MIN, IRIS_MAX);
-  split(oldIris, newIris, micros(), 10000000L, IRIS_MAX - IRIS_MIN);
-  oldIris = newIris;
-
-#endif // IRIS_PIN
-blinkR = false;
-blinkL = false;
-force_blink=false;
+
+  blink_eye[0] = false;
+  blink_eye[1] = false;
+  force_blink=false;
 }


Simplified bluetooth rc handler: no fading, setPWMs directly

--- FablightFirmware/FablightFirmware.ino
+++ FablightFirmware/FablightFirmware.ino
@@ -29,8 +29,55 @@

 //-------------------------------------------------------------------------
+// Bluetooth receive handler
+// Bluetooth command format: "%04x%02x%02x%02x%02x", fadeTime, white, ref, green, blue
+void handle_bluetooth()
+{
+    static uint8_t index=0, err=0;
+    static uint16_t  red=0, green=0, blue=0, white=0;

+    while(bluetooth.available()) {
+        char c = bluetooth.read();
+        Serial.write(c);
+        if(c == '\r' || c == '\n') { // line ending terminates command
+            Serial.write('\n');
+            bluetooth.write('.');
+            if (!err && index==12)
+                setPWMs(white, red, green, blue);
+            index = 0;
+            err = 0;
+            continue;
+        } else if (err || index > 12) {
+            err = 1;
+            continue;
+        } else { // hex ascii to integer
+            if (c >= '0' && c <= '9') {
+                c -= '0';
+            } else if (c >= 'A' && c <= 'F') {
+                c -= 'A' - 10;
+            } else {
+                err = 1;
+                continue;
+            }
+            switch(index++) {
+                case 0: case 1: case 2: case 3: break;
+                case 4: white = c<<8; break;
+                case 5: white |= c<<4; break;
+                case 6: red = c<<8; break;
+                case 7: red |= c<<4; break;
+                case 8: green = c<<8; break;
+                case 9: green |= c<<4; break;
+                case 10: blue = c<<8; break;
+                case 11: blue |= c<<4; break;
+                default: err = 1; break;
+            }
+        }
+    }
+}

+//--------------------------------------------------------------------------------
+
+/*
 // bluetooth handler with fade action
 void handle_bluetooth() {
  	static int index = 0;
@@ -68,7 +115,7 @@
  		index++;
  	}
  }
-
+ */

 //-------------------------------------------------------------------------


Add drawEllipse method

Add drawEllipse method

--- dee-oh-tee.ino
+++ dee-oh-tee.ino
@@ -57,6 +57,35 @@
   }
 }

+void drawEllipse(int centerX, int centerY, int radiusX, int radiusY, int xDegreesPerCycle) {
+  const int maxDisplacementFromCenter = numberOfUsableDegrees / 2;
+  const int tiltAngleCenter = minServoAngle + maxDisplacementFromCenter;
+
+  for (int targetDegrees = 0; targetDegrees <= numberOfUsableDegrees; targetDegrees += xDegreesPerCycle) {
+    const int targetPanServoDegrees = convertNormalizedAngleToServoAngle(targetDegrees);
+
+    panServo.writeMicroseconds(targetPanServoDegrees);
+
+    const int targetTiltDegrees = (maxDisplacementFromCenter + centerY) - sqrt(pow(radiusY, 2) * (1.0 - pow(targetDegrees - maxDisplacementFromCenter - centerX, 2) / pow(radiusX, 2)));
+    const int targetTiltServoDegrees = convertNormalizedAngleToServoAngle(targetTiltDegrees);
+    tiltServo.writeMicroseconds(targetTiltServoDegrees);
+
+    delay(15);
+  }
+
+  for (int targetDegrees = numberOfUsableDegrees; targetDegrees > 0; targetDegrees -= xDegreesPerCycle) {
+    const int targetPanServoDegrees = convertNormalizedAngleToServoAngle(targetDegrees);
+
+    panServo.writeMicroseconds(targetPanServoDegrees);
+
+    const int targetTiltDegrees = (maxDisplacementFromCenter + centerY ) + sqrt(pow(radiusY, 2) * (1.0 - pow(targetDegrees - maxDisplacementFromCenter - centerX, 2) / pow(radiusX, 2)));
+    const int targetTiltServoDegrees = convertNormalizedAngleToServoAngle(targetTiltDegrees);
+    tiltServo.writeMicroseconds(targetTiltServoDegrees);
+
+    delay(15);
+  }
+}
+
 void performRangeTest() {
   const int maxDisplacementFromCenter = numberOfUsableDegrees / 2;

@@ -83,6 +112,8 @@

 //    performRangeTest();

-    drawCircle();
+//    drawCircle();
+
+    drawEllipse(0, -(numberOfUsableDegrees / 3), numberOfUsableDegrees / 2, numberOfUsableDegrees / 8, 15);
   }
 }


implemented ir remote measurements

implemented ir remote measurements

--- main/main/main.ino
+++ main/main/main.ino
@@ -38,9 +38,11 @@
 const byte pinTone = 4;
 const byte pinMelody = 7;

+#ifdef __SUPPORT_RGBLED__
 const byte pinRGBR = 10;
 const byte pinRGBG = 5;
 const byte pinRGBB = 6;
+#endif //__SUPPORT_RGBLED__

 #ifdef __SUPPORT_GSM_MODULE__
 bool replyGSM = false;
@@ -52,8 +54,10 @@
 int melodyEndTime = 0;
 swRTC rtc;

+#ifdef __SUPPORT_RGBLED__
 bool animateRGB = false;
 byte aniR, aniG, aniB; // animated r,g,b led value
+#endif // __SUPPORT_RGBLED__

 #ifdef __SUPPORT_GSM_MODULE__
 SoftwareSerial gsmPort(2,3);
@@ -72,8 +76,10 @@
   {"rtc", "show RTC time", showTime},
   {"tone", "tone milli-seconds, play a tone in milliseconds", playTone},
   {"melody", "play melody", playMelody},
+#ifdef __SUPPORT_RGBLED__
   {"rgb", "rgb rrr,ggg,bbb to set a rgb LED color", cmdRGB},
   {"playrgb", "playrgb milli-seconds, rgb as animation", cmdPlayRGB},
+#endif //#ifdef __SUPPORT_RGBLED__
   {"endOfCmd", "end of commands", emptyFunc},
 };

@@ -175,10 +181,12 @@

   pinMode(pinMelody, OUTPUT);

+#ifdef __SUPPORT_RGBLED__
   pinMode(pinRGBR, OUTPUT);
   pinMode(pinRGBG, OUTPUT);
   pinMode(pinRGBB, OUTPUT);
   setRGBvalue(255,255,255);
+#endif //#ifdef __SUPPORT_RGBLED__

   Serial.begin(115200);

@@ -194,6 +202,8 @@

   setupRTC();

+  IRRemoteSetup();
+
 }

 /*
@@ -261,7 +271,12 @@
   // put your main code here, to run repeatedly:
   int buttonValue;

+  IRRemoteMeasure();
+
+#ifdef __SUPPORT_RGBLED__
   onAnimateRGB();
+#endif //#ifdef __SUPPORT_RGBLED__
+
 #ifdef __SUPPORT_GSM_MODULE__
   softserialCheck();
 #endif // #ifdef __SUPPORT_GSM_MODULE__
@@ -380,12 +395,12 @@
 /*--------------------------------------------------------------*/
 /*----------------------Melody----------------------------------*/
 /*--------------------------------------------------------------*/
-int melody[] = {
+const int melody[] = {
   NOTE_C4, NOTE_G3, NOTE_G3, NOTE_A3, NOTE_G3, 0, NOTE_B3, NOTE_C4
 };

 /* define melody durations in milliseconds */
-int melodyDurations[] = {
+const int melodyDurations[] = {
   200, 400, 400, 200, 200, 200, 200, 200
 };

@@ -427,6 +442,9 @@
 }

 /******************************/
+/* section RGB LED functions */
+/******************************/
+#ifdef __SUPPORT_RGBLED__
 void setRGBvalue(byte r, byte g, byte b)
 {
   analogWrite(pinRGBR, r);
@@ -502,5 +520,88 @@
   delay(3);

 }
-
-
+#endif //#ifdef __SUPPORT_RGBLED__
+
+/**
+ *================================================================
+ * Section IR remote functions
+ * https://github.com/marduino/arduino/wiki
+ *
+ * https://github.com/arduino/ArduinoCore-samd/blob/master/cores/arduino/main.cpp
+ */
+
+/* a start high pulse of 2400 micro-seconds indicates start transferring a set of bits */
+#define IR_REMOTE_START_TIMING    2100
+
+/* a 'one' timing means to set a bit to 1, indicated by 1200micro-seconds high pulse */
+#define IR_REMOTE_ONE_TIMING      900
+
+/* a 'zero' timing means to set a bit to 0, indicated by 600micro-seconds high pulse */
+#define IR_REMOTE_ZERO_TIMING     400
+
+unsigned long startTiming;
+bool isDataValid;
+int irData;
+byte irDataIdx;
+
+const int pinIRRemote = 2;
+
+
+void IRRemoteSetup()
+{
+  startTiming = 0;
+  irDataIdx = 0;
+  irData = 0;
+  isDataValid = false;
+  pinMode(pinIRRemote, INPUT);
+}
+
+/*
+ * Continua
+ */
+void IRRemoteMeasure()
+{
+  int value;
+  unsigned long dur;
+
+  value = digitalRead(pinIRRemote);
+  if ((startTiming == 0) && (HIGH == value))
+  {
+    startTiming = micros();
+    return;
+  }
+
+  /* wait until pin value turn to low, always return when HIGH */
+  if (HIGH == value)
+  {
+    return;
+  }
+
+  dur = micros() - startTiming;
+  startTiming = 0;
+
+  /* read data if is a valid data frame */
+  if (isDataValid == true) {
+    /* convert data according with timing */
+    if (dur >= IR_REMOTE_ONE_TIMING)
+    {
+       bitSet(irData, irDataIdx);
+    }
+    else if(dur >= IR_REMOTE_ZERO_TIMING)
+    {
+      bitClear(irData, irDataIdx);
+    }
+  }
+  /* check duration if it is a new start frame */
+  else if (dur >= IR_REMOTE_START_TIMING)
+  {
+      isDataValid = true;
+      irDataIdx = 0;
+      irData = 0;
+  }
+
+  Serial.println(dur, OCT);
+
+}
+
+


Arduino displays temp on lcd display

Arduino displays temp on lcd display

--- arduino_temp_bluetooth.ino
+++ arduino_temp_bluetooth.ino
@@ -1,5 +1,7 @@

+#include <Wire.h>
 #include <CurieBLE.h>
+#include "rgb_lcd.h"

 BLEPeripheral blePeripheral;       // BLE Peripheral Device (the board you're programming)
 BLEService tempService("72664d13-e5bd-4dfd-b184-6fa5b5f9c2e6");
@@ -14,35 +16,45 @@
 const int B=4275;                 // B value of the thermistor
 const int R0 = 100000;            // R0 = 100k

+rgb_lcd lcd;
+
+const int colorR = 255;
+const int colorG = 255;
+const int colorB = 255;

 void setup() {
   Serial.begin(9600);
   pinMode(4, OUTPUT);

-  Serial.println("INit.");
+  Serial.println("Init.");
+  //Setup bluetooth
   blePeripheral.setLocalName("TempMonitorSketch");
   blePeripheral.setAdvertisedServiceUuid(tempService.uuid());
   blePeripheral.addAttribute(tempService);
   blePeripheral.addAttribute(tempCharacteristic);
   tempCharacteristic.setValue(oldTemperature);

-  /* Now activate the BLE device.  It will start continuously transmitting BLE
-     advertising packets and will be visible to remote BLE central devices
-     until it receives a new connection */
+  //Setup display
+  lcd.begin(16, 2);
+  lcd.setRGB(colorR, colorG, colorB);
+
   blePeripheral.begin();
-  Serial.println("Bluetooth device active, waiting for connections...");
+  lcd.print("Bluetooth device active, waiting for connections...");
 }

 void loop() {
   // listen for BLE peripherals to connect:
   BLECentral central = blePeripheral.central();

-  Serial.println("Wait");
+  //Print temp while waiting
+  float newTemperature = readTemperature();
+  printTemperature(newTemperature);
+
   // if a central is connected to peripheral:
   if (central) {
-    Serial.print("Connected to central: ");
+    lcd.print("Connected to central: ");
     // print the central's MAC address:
-    Serial.println(central.address());
+    lcd.println(central.address());
     // turn on the LED to indicate the connection:
     digitalWrite(4, HIGH);

@@ -53,7 +65,9 @@
       // if 200ms have passed, check the battery level:
       if (currentMillis - previousMillis >= 200) {
         previousMillis = currentMillis;
-        updateTempLevel();
+        float newTemperature = readTemperature();
+        printTemperature(newTemperature);
+        updateTempLevel(newTemperature);
       }
     }
     // when the central disconnects, turn off the LED:
@@ -61,17 +75,20 @@
     Serial.print("Disconnected from central: ");
     Serial.println(central.address());
   }
+
+   delay(200);
 }

-void updateTempLevel() {
+float readTemperature() {
   int val = analogRead(A0);

-  float R = 1023.0/((float)val)-1.0;
+  float R = 1023.0/((float)val*0.66)-1.0;
   R = 100000.0*R;

-  float temperature = 1.0/(log(R/100000.0)/B+1/298.15)-273.15;//convert to temperature via datasheet ;
+  return (1.0/(log(R/100000.0)/B+1/298.15)-273.15);
+}

-
+void updateTempLevel(float temperature) {
   if (temperature != oldTemperature) {
     Serial.print("Temp is % is now: ");
     Serial.println(temperature);
@@ -79,3 +96,9 @@
     oldTemperature = temperature;
   }
 }
+
+void printTemperature(float temperature) {
+  lcd.setCursor(0, 0);
+  lcd.clear();
+  lcd.print(temperature);
+}


Set initial value of characteristics

Set initial value of characteristics

--- libraries/CurieBle/examples/ButtonLED/ButtonLED.ino
+++ libraries/CurieBle/examples/ButtonLED/ButtonLED.ino
@@ -47,6 +47,9 @@
   blePeripheral.addAttribute(ledCharacteristic);
   blePeripheral.addAttribute(buttonCharacteristic);

+  ledCharacteristic.setValue(0);
+  buttonCharacteristic.setValue(0);
+
   // advertise the service
   blePeripheral.begin();


update cc3200 button firmware

update cc3200 button firmware

--- devices/cc3200_launchpad/example_energia_button/example_energia_button.ino
+++ devices/cc3200_launchpad/example_energia_button/example_energia_button.ino
@@ -22,11 +22,11 @@
 //access point should only work for b and g
 char ssid[] = "nsynapse";
 char password[] = "elec6887";
-const char* uuid = "61ba1b0e47e34a98abb4b1d1bae10960";
+const char* uuid = "35bf1b1e47e34a98abb4b1d1bae10960";
 WiFiServer server(8000);
 WiFiUDP Udp;
 byte mac[6];
-String mac_string;
+char mac_string[24] = {0,};

 int push1_state = LOW;
@@ -71,11 +71,7 @@
   }

   WiFi.macAddress(mac);
-  for(int i=0;i<sizeof(mac);i++) {
-    mac_string += String(mac[sizeof(mac)-1-i],HEX);
-    if(i<(sizeof(mac)-1))
-      mac_string += ":";
-  }
+  sprintf(mac_string,"%02x:%02x:%02x:%02x:%02x:%02x",mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);

   printWifiStatus();

@@ -86,7 +82,7 @@
   if(announce) {
     aJson.addStringToObject(announce, "devicename", "TI-CC3200");
     aJson.addStringToObject(announce, "uuid", uuid);
-    aJson.addStringToObject(announce, "mac", mac_string.c_str());
+    aJson.addStringToObject(announce, "mac", mac_string);
     aJson.addStringToObject(announce, "manufacturer", "Texas Instrument");
     aJson.addStringToObject(announce, "author", "cossb");
     aJson.addStringToObject(announce, "component", "cc3200button");
@@ -98,7 +94,7 @@
   if(frame) {
     aJson.addStringToObject(frame, "devicename", "TI-CC3200");
     aJson.addStringToObject(frame, "uuid", uuid);
-    aJson.addStringToObject(frame, "mac", mac_string.c_str());
+    aJson.addStringToObject(frame, "mac", mac_string);
     aJson.addStringToObject(frame, "component", "cc3200button");
     aJson.addStringToObject(frame, "command","buttonread");
     aJson.addBooleanToObject(frame, "button1", false);


resolved an error in arduino agent code

resolved an error in arduino agent code

--- features/iot-plugins-feature/arduino-plugin-feature/org.wso2.carbon.device.mgt.iot.arduino.feature/src/main/resources/agent/Connect.ino
+++ features/iot-plugins-feature/arduino-plugin-feature/org.wso2.carbon.device.mgt.iot.arduino.feature/src/main/resources/agent/Connect.ino
@@ -102,7 +102,7 @@
     jsonPayLoad += String(DEVICE_OWNER);
     jsonPayLoad += "\",\"deviceId\":\"";
     jsonPayLoad += String(DEVICE_ID);
-    jsonPayLoad += "}, \"payloadData\":{";
+    jsonPayLoad += "\"}, \"payloadData\":{";

     if(DEBUG) {
         Serial.print("JSON Payload: ");


add controller functions

add controller functions

--- arduino/opencr_arduino/opencr/libraries/OpenManipulator/example/Arduino/Chain/d_open_manipulator_chain/d_open_manipulator_chain.ino
+++ arduino/opencr_arduino/opencr/libraries/OpenManipulator/example/Arduino/Chain/d_open_manipulator_chain/d_open_manipulator_chain.ino
@@ -28,6 +28,7 @@
 void setup()
 {
   Serial.begin(57600);
+  DEBUG.begin(57600);
   while (!Serial)
     ;

@@ -50,16 +51,7 @@

 void loop()
 {
-  getData(0.100f);
-
-
-  // if (Serial.available())
-  // {
-  //   MUTEX::wait();
-  //   fromProcessing(Serial.readStringUntil('\n'));
-  //   MUTEX::release();
-  // }
-
+  getData(100);
   // switch(seq)
   // {
   //   case 0:
@@ -148,21 +140,21 @@
   static uint8_t state = 0;
   static uint32_t tick = 0;

-  bool rc100_flag      = false;
+  bool rc100_flag = false;
   bool processing_flag = false;

-  uint16_t get_rc100_data     = 0;
+  uint16_t get_rc100_data = 0;
   String get_processing_data = "";

   if (availableRC100())
   {
-    get_rc100_data = rc100.readData();
+    get_rc100_data = readRC100Data();
     rc100_flag = true;
   }

   if (availableProcessing())
   {
-    get_processing_data = Serial.readStringUntil('\n');
+    get_processing_data = readProcessingData();
     processing_flag = true;
   }

@@ -172,32 +164,32 @@
       if (rc100_flag)
       {
         MUTEX::wait();
-        fromRC100(get_rc100_data);
+        fromRC100(get_rc100_data);
         MUTEX::release();

         tick = millis();
-        state  = 1;
+        state = 1;
       }
       else if (processing_flag)
       {
         MUTEX::wait();
-        fromProcessing(get_processing_data);
+        fromProcessing(get_processing_data);
         MUTEX::release();

         tick = millis();
-        state  = 1;
+        state = 1;
       }
      break;
-
+
     case 1:
       if ((millis() - tick) >= wait_time)
       {
         state = 0;
       }
      break;
-
-    default :
-     state = 0;
+
+    default:
+      state = 0;
      break;
   }
 }


add i2c scanner

add i2c scanner

--- src/gps-oled-temp-controller.ino
+++ src/gps-oled-temp-controller.ino
@@ -3,7 +3,7 @@
 #include <DHT.h>

 #define PIN_RESET 255  //
-#define DC_JUMPER 0  // I2C Addres: 0 - 0x3C, 1 - 0x3D
+#define DC_JUMPER 0  // I2C Addres: 0 - 0x3C, 1 - 0x3D - OLED Display

 #define DHTPIN D4
 #define DHTTYPE DHT22
@@ -62,7 +62,11 @@

 void setup()
 {
+  Wire.begin();
+
   Serial.begin(9600);
+
+  Serial.println("\nI2C Scanner");
   Serial.println("DHT22 Test!");

   dht.begin();
@@ -84,6 +88,8 @@
 {
   getTemp();

+  scanI2CDevices();
+
   // Check if we need to update seconds, minutes, hours:
   if (lastDraw + CLOCK_SPEED < millis())
   {
@@ -215,4 +221,45 @@
   Serial.print(" *C ");
   Serial.print(hif);
   Serial.println(" *F");
+}
+
+void scanI2CDevices() {
+  byte error, address;
+  int nDevices;
+
+  Serial.println("Scanning...");
+
+  nDevices = 0;
+  for(address = 1; address < 127; address++ )
+  {
+    // The i2c_scanner uses the return value of
+    // the Write.endTransmisstion to see if
+    // a device did acknowledge to the address.
+    Wire.beginTransmission(address);
+    error = Wire.endTransmission();
+
+    if (error == 0)
+    {
+      Serial.print("I2C device found at address 0x");
+      if (address<16)
+        Serial.print("0");
+      Serial.print(address,HEX);
+      Serial.println("  !");
+
+      nDevices++;
+    }
+    else if (error==4)
+    {
+      Serial.print("Unknow error at address 0x");
+      if (address<16)
+        Serial.print("0");
+      Serial.println(address,HEX);
+    }
+  }
+  if (nDevices == 0)
+    Serial.println("No I2C devices found\n");
+  else
+    Serial.println("done\n");
+
+  delay(5000);           // wait 5 seconds for next scan
 }


thanks to encoder, can retain homing even after motor off & on

--- arduino/motor_driver/motor_driver.ino
+++ arduino/motor_driver/motor_driver.ino
@@ -78,6 +78,7 @@

 double goalSpeed = 0;
 float homingSpeed = 3.0;
+bool homed = false;

 const int BACKOFF_STEPS = 600; // how many encoder steps to reverse out of endstop (so Zero is this far from the switch)

@@ -174,6 +175,7 @@
       goalSpeed = 0;
       pidSetpoint = encoder0Pos;
       state = OK;
+      homed = true;
     }
   }

@@ -538,7 +540,8 @@
     int p = m.getInt(m.size()-1);
     if (p) {
       if (state==MOTOROFF) {
-        state = NOTHOMED;
+        if (homed) state = OK;
+        else state = NOTHOMED;
       }
       motorEnable(true);
     }


Initial Commit. v1 - 16x2 LCD working on an Arduino 9 Selectable modes, adjustable tolerances. v1 Mostly complete.