changed to correct topic name

changed to correct topic name

--- Arduino/Teensy36CarTwistStamped.ino
+++ Arduino/Teensy36CarTwistStamped.ino
@@ -137,7 +137,7 @@

 }

-ros::Subscriber<geometry_msgs::TwistStamped> driveSubscriber("/jetsoncar_teleop_joystick/cmd_vel", &driveCallback) ;
+ros::Subscriber<geometry_msgs::TwistStamped> driveSubscriber("/cmd_vel", &driveCallback) ;

 void setup() {
   pinMode(38, INPUT);


PedestrianLight - enhancements

PedestrianLight - enhancements

--- PedestrianLight/PedestrianLight.ino
+++ PedestrianLight/PedestrianLight.ino
@@ -2,25 +2,26 @@
   Pedestrian light
  */

-const int carRedPin = 13;
-const int carYellowPin = 12;
-const int carGreenPin = 8;
-const int pedRedPin = 7;
-const int pedGreenPin = 4;
+const int carRedPin = 12;
+const int carYellowPin = 11;
+const int carGreenPin = 10;
+const int pedRedPin = 9;
+const int pedGreenPin = 8;
+const int pedWaitPin = 13;
 const int buttonPin = 2;

-int carRedState = 0;
-int carYellowState = 0;
-int carGreenState = 0;
-int pedRedState = 0;
-int pedGreenState = 0;
+unsigned long time;
+int buttonState;
+int lightState = 0;
+boolean pedPushed = false;
+unsigned long waitUntil = 0;

-unsigned long time = 0;
-int buttonState = 0;
-boolean pedPushed = false;
-boolean pedHasGreen = false;
-unsigned long waitUntil = 0;
-int switchStep = 0;
+int carRedState = LOW;
+int carYellowState = LOW;
+int carGreenState = HIGH;
+int pedRedState = HIGH;
+int pedGreenState = LOW;
+int pedWaitState = LOW;

 void setup() {
   pinMode(carRedPin, OUTPUT);
@@ -28,73 +29,78 @@
   pinMode(carGreenPin, OUTPUT);
   pinMode(pedRedPin, OUTPUT);
   pinMode(pedGreenPin, OUTPUT);
+  pinMode(pedWaitPin, OUTPUT);
   pinMode(buttonPin, INPUT);
-
-  carRedState = LOW;
-  carYellowState = LOW;
-  carGreenState = HIGH;
-  pedRedState = HIGH;
-  pedGreenState = LOW;
 }

 void loop() {
   time = millis();
   buttonState = digitalRead(buttonPin);

-  if (buttonState == HIGH && pedPushed == false && pedHasGreen == false) {
+  if (buttonState == HIGH && (lightState == 0 || lightState >= 5)) {
     pedPushed = true;
-    if (waitUntil == 0 || waitUntil < time + 5000) {
-      waitUntil = time + 5000;
-    }
+    pedWaitState = HIGH;
   }

-  if (pedPushed == true && time > waitUntil) {
-    switch (switchStep) {
-    case 0:
+  switch (lightState) {
+  case 0:
+    if (pedPushed == true) {
+      pedPushed = false;
+      if (waitUntil == 0 || waitUntil < time + 5000) {
+        waitUntil = time + 5000;
+      }
+      lightState++;
+    }
+    break;
+  case 1:
+    if (time > waitUntil) {
       carYellowState = HIGH;
       carGreenState = LOW;
       waitUntil = time + 2000;
-      switchStep++;
-      break;
-    case 1:
+      lightState++;
+    }
+    break;
+  case 2:
+    if (time > waitUntil) {
       carRedState = HIGH;
       carYellowState = LOW;
       waitUntil = time + 2000;
-      switchStep++;
-      break;
-    case 2:
+      lightState++;
+    }
+    break;
+  case 3:
+    if (time > waitUntil) {
       pedRedState = LOW;
       pedGreenState = HIGH;
-      switchStep = 0;
-      pedPushed = false;
-      pedHasGreen = true;
+      pedWaitState = LOW;
       waitUntil = time + 10000;
-      break;
+      lightState++;
     }
-  }
-
-  if (pedHasGreen == true && time > waitUntil) {
-    switch (switchStep) {
-    case 0:
+    break;
+  case 4:
+    if (time > waitUntil) {
       pedRedState = HIGH;
       pedGreenState = LOW;
       waitUntil = time + 2000;
-      switchStep++;
-      break;
-    case 1:
+      lightState++;
+    }
+    break;
+  case 5:
+    if (time > waitUntil) {
       carYellowState = HIGH;
       waitUntil = time + 2000;
-      switchStep++;
-      break;
-    case 2:
+      lightState++;
+    }
+    break;
+  case 6:
+    if (time > waitUntil) {
       carRedState = LOW;
       carYellowState = LOW;
       carGreenState = HIGH;
-      switchStep = 0;
-      pedHasGreen = false;
       waitUntil = time + 20000;
-      break;
+      lightState = 0;
     }
+    break;
   }

   digitalWrite(carRedPin, carRedState);
@@ -102,5 +108,8 @@
   digitalWrite(carGreenPin, carGreenState);
   digitalWrite(pedRedPin, pedRedState);
   digitalWrite(pedGreenPin, pedGreenState);
+  digitalWrite(pedWaitPin, pedWaitState);
+
+  delay(50);
 }


adicionado definição de nomes de funções

--- EMP-B-Due.ino
+++ EMP-B-Due.ino
@@ -26,6 +26,10 @@
     #define DESLIGA LOW
     #define VERDADEIRO true
     #define FALSO false
+  // Nomes de Funções
+    #define NomeGeral "Geral"
+    #define NomeDosador "Dosador"
+    #define NomeDatador "Datador"
   // Botões de Entrada Um Clique
     unsigned long atraso = 50;
     int estbt_geral; // Estado do Botão Geral
@@ -156,18 +160,18 @@

 void modoTeste(){
   if (maquina_ligada){
-    liga(led_geral, "Led Geral");
+    liga(led_geral, NomeGeral);
   } else {
-    desliga(led_geral, "Led Geral");
+    desliga(led_geral, NomeGeral);
   }
   if (dosador_ligado){
-    liga(led_dosador, "Led Dosador");
+    liga(led_dosador, NomeDosador);
   } else {
-    desliga(led_dosador, "Led Dosador");
+    desliga(led_dosador, NomeDosador);
   }
   if (datador_ligado){
-    liga(led_datador, "Led Datador");
+    liga(led_datador, NomeDatador);
   } else {
-    desliga(led_datador, "Led Datador");
+    desliga(led_datador, NomeDatador);
   }
 }


Variable type changes starfield drawing.

--- arduboy-game/arduboy-game.ino
+++ arduboy-game/arduboy-game.ino
@@ -324,7 +324,7 @@
 }

 void drawStarLayer() {
-  for (int i = 0; i < numStars; i++) {
+  for (byte i = 0; i < numStars; i++) {
      arduboy.drawPixel(stars[i].x, stars[i].y, 3);
   }
 }


improved code and added comments

improved code and added comments

--- arduino/pi_rover/pi_rover.ino
+++ arduino/pi_rover/pi_rover.ino
@@ -36,7 +36,8 @@
   Serial.begin(9600);
   Serial.print("Ready\n");
   pinMode(ledPin, OUTPUT);
-
+
+  // calibrate the servo during setup
   servo.attach(9);

   servo.write(0);
@@ -44,7 +45,6 @@
   servo.write(180);
   delay(500);
   servo.write(90);
-
   delay(350);

   servo.detach();
@@ -67,16 +67,18 @@
   }

   if (safetyDriveMode) {
+
+    // set the interval for measuring distance
     int checkDistanceInterval = map(
       motorSpeed,
       0, maxMotorSpeed,
-      500, 100
+      400, 50 // in milliseconds
     );

     int distanceToStop = map(
       motorSpeed,
       0, maxMotorSpeed,
-      15, 60
+      15, 60 // in centimeter
     );

     runEvery(checkDistanceInterval) {
@@ -93,6 +95,8 @@
     }

     if (debugMode) {
+      // the "checkDistanceInterval" and "distanceToStop" is dynamically set based on how fast
+      // the robot is moving. this output shows us every 2 seconds how its configured for the moment
       runEvery(2000) {
         Serial.print("Safety drive: check interval "+String(checkDistanceInterval)+
         ", distance to stop: "+String(distanceToStop)+"\n");
@@ -145,7 +149,8 @@

   String command = getCommandFromInput(input);
   int argument = getArgumentFromInput(input);
-
+
+  // yes, a switch-case-construct would be better, but its not supporting strings as case value.. only integers
   if(command == "battery") {
     result = checkBatteryStatus(argument);
   } else if(command == "distance") {
@@ -164,8 +169,11 @@
     result = halt(argument);
   } else if(command == "debug") {
     result = debug(argument);
-  } else {
-    result = "unknown command: " + command + ", arg: " + argument;
+  // here we can add additional functions:
+  // } else if(command == "doSomething") {
+  //   result = doSomething(argument);
+  } else {
+    result = "unknown command: " + command;
   }

   return result;
@@ -173,7 +181,7 @@

 String lookDirection(int argument) {
   String result;
-
+
   if (argument >= 0 && argument <= 180) {

     digitalWrite(ledPin, HIGH);
@@ -187,15 +195,17 @@
     if (servo.read() > argument) {
       waitTimeInMs = servo.read() - argument;
     } else {
-      waitTimeInMs = servo.read() + argument;
+      waitTimeInMs = argument - servo.read();
     }
-
+
+    waitTimeInMs = (waitTimeInMs + 100) * 2;
+
     servo.write(argument);
-
-    Serial.print(waitTimeInMs);
-
-    delay(waitTimeInMs * 3);
-
+
+    // give the servo some time to do its job
+    delay(waitTimeInMs);
+
+    // we detach the servo variable from its pin to save energy
     servo.detach();

     digitalWrite(ledPin, LOW);
@@ -216,6 +226,7 @@
   }

   isMovingForward = true;
+  isMovingBackward = false;

   turnMotorsOn();

@@ -233,7 +244,8 @@
   {
     setMotorSpeed(speedInPercentage);
   }
-
+
+  isMovingForward = false;
   isMovingBackward = true;

   turnMotorsOn();
@@ -253,17 +265,18 @@
     0, maxMotorSpeed,
     0, 100
   );
-
+
+  // to pull the brake strongly we move for a short time in the opposite direction
   if (isMovingForward)
   {
     backward(80);
-    delay(currentMotorSpeedInPercentage * 2);
   }
   else if(isMovingBackward)
   {
     forward(80);
-    delay(currentMotorSpeedInPercentage * 2);
-  }
+  }
+
+  delay(currentMotorSpeedInPercentage * 2);

   turnMotorsOff();

@@ -272,7 +285,6 @@

   return "ok";
 }
-

 String left(int speedInPercentage)


Increased size of val_arrary to 18

Increased size of val_arrary to 18

--- libraries/FreeIMU/examples/FreeIMU_serial_ARM_CPU/FreeIMU_serial_ARM_CPU.ino
+++ libraries/FreeIMU/examples/FreeIMU_serial_ARM_CPU/FreeIMU_serial_ARM_CPU.ino
@@ -45,7 +45,7 @@
 float ypr[3]; // yaw pitch roll
 char str[128];
 float val[11];
-float val_array[17];
+float val_array[18];

 // Set the FreeIMU object and LSM303 Compass
 FreeIMU my3IMU = FreeIMU();


algo pintu ketok

algo pintu ketok

--- PintuKetok/PintuKetok.ino
+++ PintuKetok/PintuKetok.ino
@@ -11,17 +11,33 @@
 	#define PIN_ON	LOW
 #endif

-unsigned long lasthit;

-#define SEQ_LENGTH 3
+#define SEQ_LENGTH 4
 int seq[SEQ_LENGTH] = {3, 1, 3, 1};
 /**	contoh: {3, 1, 3, 1}
 		3 ketok, 1 ketok, 3 ketok, 1 ketok, (toktoktok tok toktoktok tok)
 		ketuk pramuka: {3, 3, 7}
 **/
 #define GAP 1000
+#define TOLERANCE 500 //-- milisecond
+unsigned long lasthit;
 unsigned long smallgap;
+unsigned long thisgap;
 int seq_pos, seq_sub;
+
+unsigned long selisih(unsigned long a, unsigned long b)
+{
+	//--selisih untuk unsigned
+	if (a>b)
+		return a-b;
+	else
+		return b-a;
+}
+
+void reset_seq()
+{
+	seq_sub = 0; seq_pos = 0;
+}

 void setup() {
 	Serial.begin(9600);
@@ -33,10 +49,42 @@

 void loop ()
 {
+	while (digitalRead(PIN_INPUT, PIN_DEFAULT));
 	lasthit = millis();
-	if (digitalRead(PIN_INPUT, PIN_ON))
+	while (digitalRead(PIN_INPUT, PIN_ON));
+	thisgap = millis() - lasthit;
+
+	if (seq_pos==0 && seq_sub==0)
+		smallgap = thisgap;
+
+	if (selisih(thisgap, smallgap)<TOLERANCE)
 	{
-		while (digitalRead(PIN_INPUT, PIN_ON));
-		smallgap =
+		//-- small gap, expecting seq_sub complete
+		if (seq_sub<seq[seq_pos])
+		{
+			//-- ok, advance to next
+			seq_sub = seq_sub+1;
+		}
+		else
+		{
+			reset_seq();
+		}
+	}
+	else
+	{
+		//-- big gap, expecting seq_pos advance
+		if (seq_sub==seq[seq_pos])
+		{
+			seq_sub = 0;
+			seq_pos = seq_pos+1;
+			if (seq_pos>=(SEQ_LENGTH-1))
+			{
+				//-- finish
+			}
+		}
+		else
+		{
+			reset_seq();
+		}
 	}
 }


Added elapsed time report to serial monitor

--- RFIDreader/RFIDreader.ino
+++ RFIDreader/RFIDreader.ino
@@ -6,9 +6,11 @@

    Input:
       RFID tag
+      Signal from Pin 4

    Output:
       Serial number of tag scanned
+      Elapsed time

    Operation:
       Reader waits until a tag is scanned, then prints the serial number of the tag
@@ -26,7 +28,7 @@
 char get_readID[] = { 0xAA , 0x00, 0x03, 0x25, 0x26, 0x00, 0x00, 0xBB };
 byte response[11];
 bool standby;
-unsigned long elapsed_time = 0;
+unsigned long elapsed_time;

 void setup() {
   Serial.begin(57600);
@@ -42,6 +44,7 @@
   digitalWrite(ledPin, LOW);
   standby = true;
   response[7] = NULL;
+  elapsed_time = 0;

   // read response from RDM880 and print
   int i = 0;
@@ -57,6 +60,8 @@
       // Machine is ready to fire, get ready to track time
       standby = false;
       elapsed_time = accumulator(standby) / 1000;
+      Serial.print("Elapsed Time: ");
+      Serial.print(elapsed_time);
       }
     }
   }


Changed to interrupt driven button management

--- src/cyclop_plus_plus/cyclop_plus_plus.ino
+++ src/cyclop_plus_plus/cyclop_plus_plus.ino
@@ -38,6 +38,7 @@
 #include <avr/pgmspace.h>
 #include <string.h>
 #include <EEPROM.h>
+#include <EnableInterrupt.h>

 /*******************************************************************************
   Minimosd Display Protocol Definition v1.0
@@ -105,6 +106,7 @@
 unsigned int  averageAnalogRead( unsigned char pin );
 void          batteryMeter(unsigned char x, unsigned char y, bool showNumbers = false);
 unsigned char bestChannelMatch( unsigned int frequency );
+void          buttonPressInterrupt();
 void          drawAutoScanScreen(void);
 void          drawBattery(unsigned char xPos, unsigned char yPos, unsigned char value, bool showNumbers = false );
 void          drawChannelScreen( unsigned char channel);
@@ -183,9 +185,11 @@
 //******************************************************************************
 //* Other file scope variables
 unsigned char lastClick = NO_CLICK;
+unsigned char clickType = NO_CLICK;
 unsigned char currentChannel = 0;
 unsigned char lastChannel = 0;
 unsigned char ledState = LED_ON;
+unsigned long pauseStart = 0;
 unsigned long displayUpdateTimer = 0;
 unsigned long eepromSaveTimer = 0;
 unsigned long forceDisplayTimer = 0;
@@ -200,6 +204,9 @@
 rtc6715 receiver( SPI_CLOCK_PIN, SLAVE_SELECT_PIN, SPI_DATA_PIN );
 unsigned char softPositions[48];

+
+
+
 //******************************************************************************
 //* function: setup
 //******************************************************************************
@@ -212,8 +219,8 @@
   digitalWrite(LED_PIN, LED_ON);

   // initialize button pin
-  pinMode(BUTTON_PIN, INPUT);
-  digitalWrite(BUTTON_PIN, INPUT_PULLUP);
+  pinMode(BUTTON_PIN, INPUT_PULLUP);
+  enableInterrupt(BUTTON_PIN, buttonPressInterrupt, CHANGE);

   // initialize alarm
   pinMode(ALARM_PIN, OUTPUT );
@@ -434,50 +441,55 @@
 }

 //******************************************************************************
-//* function: get_click_type
-//*         : Polls the specified pin and returns the type of click that was
-//*         : performed NO_CLICK, SINGLE_CLICK, DOUBLE_CLICK, LONG_CLICK,
-//*         : LONG_LONG_CLICK or WAKEUP_CLICK
-//******************************************************************************
-unsigned char getClickType(unsigned char buttonPin) {
-  unsigned int timer = 0;
-  unsigned char click_type = NO_CLICK;
-
-  // check if the key has been pressed
-  if (digitalRead(buttonPin) == !BUTTON_PRESSED)
-    return ( NO_CLICK );
-
-  while (digitalRead(buttonPin) == BUTTON_PRESSED) {
-    timer++;
-    delay(5);
-  }
-  if (timer < 120)                  // 120 * 5 ms = 0.6s
-    click_type = SINGLE_CLICK;
-  if (timer >= 80 && timer < 300 )  // 300 * 5 ms = 1.5s
-    click_type = LONG_CLICK;
-  if (timer >= 300)
-    click_type = LONG_LONG_CLICK;
-
-  // If the screen saver is active a short key press is just a wakeup call
-  if (saveScreenActive) {
-    saveScreenActive = 0;
-    if ( click_type == SINGLE_CLICK )
-      return ( WAKEUP_CLICK );
-  }
-
-  // Check if there is a second click
-  timer = 0;
-  while ((digitalRead(buttonPin) == !BUTTON_PRESSED) && (timer++ < 40)) {
-    delay(5);
-  }
-  if (timer >= 40)                  // 40 * 5 ms = 0.2s
-    return click_type;
-
-  if (digitalRead(buttonPin) == BUTTON_PRESSED ) {
-    click_type = DOUBLE_CLICK;
-    while (digitalRead(buttonPin) == BUTTON_PRESSED) ;
-  }
-  return (click_type);
+//* function: buttonPressInterrupt
+//******************************************************************************
+void buttonPressInterrupt() {
+  static long clickStart = 0;
+
+  if ( digitalRead(BUTTON_PIN) == BUTTON_PRESSED ) {// Button was pressed
+    clickStart = millis();
+  }
+  else {   // Button was released
+    if ( pauseStart) {
+      clickType = DOUBLE_CLICK;
+      clickStart = 0;
+      pauseStart = 0;
+    }
+    else
+    {
+      if ( saveScreenActive ) {
+        clickType = WAKEUP_CLICK;
+        clickStart = 0;
+        saveScreenActive = 0;
+      }
+      else if (( millis() - clickStart) > 1500 )
+        clickType = LONG_LONG_CLICK;
+      else if (( millis() - clickStart) > 350 )
+        clickType = LONG_CLICK;
+      else
+        clickType = SINGLE_CLICK;
+      clickStart = 0;
+      pauseStart = millis();
+    }
+  }
+}
+
+//******************************************************************************
+//* function: getClickType
+//******************************************************************************
+uint8_t getClickType(uint8_t buttonPin) {
+  uint8_t tempClickType = NO_CLICK;
+
+  if (pauseStart && (millis() - pauseStart) < 350)
+    return NO_CLICK;
+
+  pauseStart = 0;
+
+  if ( clickType ) {
+    tempClickType = clickType;
+    clickType = NO_CLICK;
+  }
+  return tempClickType;
 }

 //******************************************************************************
@@ -683,7 +695,7 @@
   else if (channelIndex < 32)
     name[0] = 'f';
   else if (channelIndex < 40)
-    name[0] = 'r';
+    name[0] = 'c';
   else
     name[0] = 'l';
   name[1] = (channelIndex % 8) + '0' + 1;


The robot firmware now can select from more than 2 (4) pipes

--- firmware/2017/firmware_CCcontrol/firmware_CCcontrol.ino
+++ firmware/2017/firmware_CCcontrol/firmware_CCcontrol.ino
@@ -47,9 +47,9 @@
 RF24 radio(CE,CS);                        // Set up nRF24L01 radio on SPI bus plus pins 3 & 2 for nano

-const uint64_t pipes[2] = { 0xABCDABCD71LL, 0x544d52687CLL };   // Radio pipe addresses for the 2 nodes to communicate.
+const uint64_t pipes[4] = { 0xABCDABCD71LL, 0x544d52687CLL, 0x644d52687CLL, 0x744d52687CLL};
 uint64_t pipeEnvia=pipes[0];
-uint64_t pipeRecebe=pipes[1];
+uint64_t pipeRecebe=pipes[3];

 struct dataStruct{
@@ -500,4 +500,4 @@

   contadorA_media+=(motorA_direction*contadorA-contadorA_media)/10;
   contadorB_media+=(motorB_direction*contadorB-contadorB_media)/10;
-}
+}


Add a bunch of comments, use ARRAYSIZE more consistantly.

--- SAMD_pins.ino
+++ SAMD_pins.ino
@@ -19,7 +19,10 @@
 #define PRINTLN(...) mySerial.println(__VA_ARGS__)

-
+/*
+ * Standard Arduio setup() function.
+ * Turn on some of the interesting features so we can see how it works.
+ */
 void setup() {
   mySerial.begin(9600);
   while (!mySerial)
@@ -41,7 +44,7 @@
 }

 void loop() {
-  for (int pin = 0; pin < PINS_COUNT; pin++) {
+  for (int pin = 0; pin < PINS_COUNT; pin++) {  // For all defined pins
     if (print_pinno(pin)) {  // Does pin exist?

       int bitno = g_APinDescription[pin].ulPin;
@@ -78,6 +81,10 @@
 }

+/*
+ * Print an Arduino pin number, and it's "name."
+ * (in particular, check for the Analog pins and label them)
+ */
 boolean print_pinno(int i)
 {
   int pintype = g_APinDescription[i].ulPinType;
@@ -98,8 +105,17 @@
 }

+// Convenient macro
 #define ARRAYSIZE(a) (sizeof a/sizeof a[0])

+/*
+ * Table of functions to do decoding of individual pinmux values.
+ * In general, each PMUX value has a standard function "class", and then
+ * you have to do further decoding based on port/bit and perhaps peripheral
+ * internals to figure out the details.  (For example, a SERCOM PMUX value
+ * can apply to one of six different SERCOM modules on a SAMD21, and an ANALOG
+ * PMUX value could be ADC, REF, DAC, or TouchController.)
+ */
 void (*PMUX_decode_func[8])(int, int) = {
   decode_EIC,
   decode_ADC,
@@ -111,13 +127,18 @@
   decode_CLK
 };

+/*
+ * Print the raw PMUX value
+ * Call via the function table for name and
+details.
+ */
 void print_pinmux(int pin, int pmuxval)
 {
   PRINT("PMUX");
   PRINT("(");
   PRINT(pmuxval);
   PRINT(") ");
-  if (pmuxval < (sizeof PMUX_decode_func/sizeof PMUX_decode_func[0])) {
+  if (pmuxval < ARRAYSIZE(PMUX_decode_func)) {
     PMUX_decode_func[pmuxval](pin, pmuxval);
   }
 }
@@ -142,12 +163,22 @@

 void decode_EIC(int pin, int pmux)
 {
-  PRINT(pinmux_names[pmux]);
-}
+  PRINT(pinmux_names[pmux]);   // default action
+}
+
 void decode_ADC(int pin, int pmux)
 {
-  PRINT(pinmux_names[pmux]);
-}
+  PRINT(pinmux_names[pmux]);   // default action
+}
+
+/*
+ * Sercom and Sercom ALT decoding.
+ * pins can have one of two sercom settings, which are similar but rather
+ * randomly (?) assigned to sercom functions.  The "P0" part refers to the
+ * "pad" within the sercom unit (each Sercom has up to 4 pads.)  Mapping
+ * between "pad" and actual function is controlled by fields in the CTRLA reg
+ */
+
 const char *pin_to_SERCOMA_info[] = {
   /* PA00 */ nullstr,
   /* PA01 */ nullstr,
@@ -198,8 +229,17 @@
 /* PB17 */ "5 P1"
 };

+/*
+ * SERCOM_INSTS is defined in the Atmel chip-specific samXXXX.h file, as a
+ * list of all the Sercom units available on that specific chip.  (some chips
+ * have more than others.
+ */
+
 Sercom * sercomports[] = SERCOM_INSTS;

+/*
+ * Sercom configuration type indexed by CTRLA.MODE
+ */
 char *sercomtype_names[] = {
   "(USART)",
   "(UART)",
@@ -209,6 +249,7 @@
   "(I2C Master)"
 };

+
 void decode_SERCOM(int pin, int pmux)
 {
   PortGroup *port = digitalPinToPort(pin);
@@ -218,7 +259,7 @@

   PRINT(pinmux_names[pmux]);
   if (port == &PORT->Group[0]) {
-    if (bitno < (sizeof pin_to_SERCOMA_info/sizeof pin_to_SERCOMA_info[0])) {
+    if (bitno < ARRAYSIZE(pin_to_SERCOMA_info)) {
       PRINT(pin_to_SERCOMA_info[bitno]);
       /*
        * Get sercom number from the string.  (Ugly, but saves space.)
@@ -227,7 +268,7 @@
     }
   }
   if (port == &PORT->Group[1]) {
-    if (bitno < (sizeof pin_to_SERCOMB_info/sizeof pin_to_SERCOMB_info[0])) {
+    if (bitno < ARRAYSIZE(pin_to_SERCOMB_info)) {
       PRINT(pin_to_SERCOMB_info[bitno]);
       /*
        * Get sercom number from the string.  (Ugly, but saves space.)
@@ -243,6 +284,10 @@
     }
   }
 }
+
+/*
+ * Tables for SercomALT PMUX value
+ */

 const char *pin_to_SERCOMALTA_info[] = {
 /* PA00 */ "1 P0",
@@ -349,6 +394,13 @@
   }
 }

+/*
+ * Decoding for Timer PMUX values.
+ * SAMD has two types of timers a "Timer/Counter" (TC) and a
+ * "Timer/Counter for Control (TCC).  Both can be used to implement the
+ * Arduino PWM-based analogWrite() functionality.
+ */
+
 const char *pin_to_tc_info_a[] = {
 /* PA00 */ "TCC2/WO0",
 /* PA01 */ "TCC2/WO1",
@@ -498,6 +550,10 @@
     }
   }
 }
+
+/*
+ * "COM" are special communications peripherals like USB, SWD, or ISS
+ */
 void decode_COMM(int pin, int pmux)
 {
   PortGroup *port = digitalPinToPort(pin);
@@ -515,9 +571,12 @@
 }
 void decode_CLK(int pin, int pmux)
 {
-  PRINT(pinmux_names[pmux]);
-}
-
+  PRINT(pinmux_names[pmux]);   // default action
+}
+
+/*
+ * Given an Arduino pin number, print the datasheet-style Port and Bit numbers
+ */
 void print_portname(int pin)
 {
   PortGroup *port = digitalPinToPort(pin);
@@ -530,7 +589,7 @@
     PRINT("PB");
   }
   if (bitno < 10) {
-    PRINT("0");
+    PRINT("0");      // Output formatting with possible leading 0
   }
   PRINT(bitno);
   PRINT("  ");


Add SERCOM and COM decoding. Add port/bit names (PA02, PB31, etc.)

--- SAMD_pins.ino
+++ SAMD_pins.ino
@@ -2,65 +2,7 @@
 #include <SPI.h>

 #define mySerial SerialUSB
-
-/*
- *   Pin multiplexer value names (PMUXn.PMUXE/O)
- */
-const char *pinmux_names[8] = {
-  "EIC",   // "A": External Interrupts
-  "ADC",   // "B": REF, ADC, AC, PTC, DAC
-  "SERCOM",   /* "C": SerCom */
-  "SERCOMALT",  /* "D": Alternate SERCOM */
-  "TC/TCC",     /* "E": TC or TCC Timer */
-  "TCC",        /* "F": TCC Timer*/
-  "COM",        /* "G": Other Comm - USB, I2S */
-  "AC/GCLK"     /* "H": Analog Comparator or GCLKs */
-};
-
-
-void decode_EIC(int pin, int pmux)
-{
-  mySerial.print(pinmux_names[pmux]);
-}
-void decode_ADC(int pin, int pmux)
-{
-  mySerial.print(pinmux_names[pmux]);
-}
-void decode_SERCOM(int pin, int pmux)
-{
-  mySerial.print(pinmux_names[pmux]);
-}
-void decode_SERCOMA(int pin, int pmux)
-{
-  mySerial.print(pinmux_names[pmux]);
-}
-void decode_TC(int pin, int pmux)
-{
-  mySerial.print(pinmux_names[pmux]);
-}
-void decode_TCC(int pin, int pmux)
-{
-  mySerial.print(pinmux_names[pmux]);
-}
-void decode_COMM(int pin, int pmux)
-{
-  mySerial.print(pinmux_names[pmux]);
-}
-void decode_CLK(int pin, int pmux)
-{
-  mySerial.print(pinmux_names[pmux]);
-}
-
-void (*PMUX_decode_func[8])(int, int) = {
-  decode_EIC,
-  decode_ADC,
-  decode_SERCOM,
-  decode_SERCOMA,
-  decode_TC,
-  decode_TCC,
-  decode_COMM,
-  decode_CLK
-};
+#define ARRAYSIZE(a) (sizeof a/sizeof a[0])

 void setup() {
   mySerial.begin(9600);
@@ -75,6 +17,8 @@
   Serial.begin(9600);
   SPI.begin();
   Wire.begin();
+  analogWrite(10, 55);
+  analogWrite(12, 55);
   for (int j = 0; j < 6; j++)
     (void) analogRead(j);  // read from analog pins
   pinMode(13, OUTPUT);
@@ -87,6 +31,8 @@
       int bitno = g_APinDescription[pin].ulPin;
       PortGroup *port = digitalPinToPort(pin);
       int pmuxval;
+
+      print_portname(pin);

       if (port->PINCFG[bitno].bit.PMUXEN) {  // Is pinmux enabled?
         // If pinmux is enabled, further report it's value
@@ -135,6 +81,17 @@
   return true;
 }

+void (*PMUX_decode_func[8])(int, int) = {
+  decode_EIC,
+  decode_ADC,
+  decode_SERCOM,
+  decode_SERCOMA,
+  decode_TC,
+  decode_TCC,
+  decode_COMM,
+  decode_CLK
+};
+
 void print_pinmux(int pin, int pmuxval)
 {
   mySerial.print("PMUX");
@@ -146,3 +103,275 @@
   }
 }

+
+char *nullstr = "";
+
+/*
+ *   Pin multiplexer value names (PMUXn.PMUXE/O)
+ */
+const char *pinmux_names[8] = {
+  "EIC",   // "A": External Interrupts
+  "ADC",   // "B": REF, ADC, AC, PTC, DAC
+  "SERCOM",   /* "C": SerCom */
+  "SERCOM",  /* "D": Alternate SERCOM */
+  "TC/TCC",     /* "E": TC or TCC Timer */
+  "TCC",        /* "F": TCC Timer*/
+  "COM",        /* "G": Other Comm - USB, I2S */
+  "AC/GCLK"     /* "H": Analog Comparator or GCLKs */
+};
+
+
+void decode_EIC(int pin, int pmux)
+{
+  mySerial.print(pinmux_names[pmux]);
+}
+void decode_ADC(int pin, int pmux)
+{
+  mySerial.print(pinmux_names[pmux]);
+}
+const char *pin_to_SERCOMA_info[] = {
+  /* PA00 */ nullstr,
+  /* PA01 */ nullstr,
+  /* PA02 */ nullstr,
+/* PA03 */ nullstr,
+/* PA04 */ nullstr,
+/* PA05 */ nullstr,
+/* PA06 */ nullstr,
+/* PA07 */ nullstr,
+/* PA08 */ "0 P0",
+/* PA09 */ "0 P1",
+/* PA10 */ "0 P2",
+/* PA11 */ "0 P3",
+/* PA12 */ "2 P0",
+/* PA13 */ "2 P1",
+/* PA14 */ "2 P2",
+/* PA15 */ "2 P3",
+/* PA16 */ "1 P0",
+/* PA17 */ "1 P1",
+/* PA18 */ "1 P2",
+/* PA19 */ "1 P3",
+/* PA20 */ "5 P2",
+/* PA21 */ "5 P3",
+/* PA22 */ "3 P0",
+/* PA23 */ "3 P1",
+/* PA24 */ "3 P2",
+/* PA25 */ "3 P3"
+};
+
+const char *pin_to_SERCOMB_info[] = {
+/* PB00 */ nullstr,
+/* PB01 */ nullstr,
+/* PB02 */ nullstr,
+/* PB03 */ nullstr,
+/* PB04 */ nullstr,
+/* PB05 */ nullstr,
+/* PB06 */ nullstr,
+/* PB07 */ nullstr,
+/* PB08 */ nullstr,
+/* PB09 */ nullstr,
+/* PB10 */ nullstr,
+/* PB11 */ nullstr,
+/* PB12 */ "4 P0",
+/* PB13 */ "4 P1",
+/* PB14 */ "4 P2",
+/* PB15 */ "4 P3",
+/* PB16 */ "5 P0",
+/* PB17 */ "5 P1"
+};
+
+Sercom * sercomports[] = SERCOM_INSTS;
+
+char *sercomtype_names[] = {
+  "(USART)",
+  "(UART)",
+  "(SPI Slave)",
+  "(SPI Master)",
+  "(I2C Slave)",
+  "(I2C Master)"
+};
+
+void decode_SERCOM(int pin, int pmux)
+{
+  PortGroup *port = digitalPinToPort(pin);
+  int bitno = g_APinDescription[pin].ulPin;
+  int sercomno, sercomtype;
+  Sercom *s;
+
+  mySerial.print(pinmux_names[pmux]);
+  if (port == &PORT->Group[0]) {
+    if (bitno < (sizeof pin_to_SERCOMA_info/sizeof pin_to_SERCOMA_info[0])) {
+      mySerial.print(pin_to_SERCOMA_info[bitno]);
+      /*
+       * Get sercom number from the string.  (Ugly, but saves space.)
+       */
+      sercomno = *pin_to_SERCOMA_info[bitno] - '0';
+    }
+  }
+  if (port == &PORT->Group[1]) {
+    if (bitno < (sizeof pin_to_SERCOMB_info/sizeof pin_to_SERCOMB_info[0])) {
+      mySerial.print(pin_to_SERCOMB_info[bitno]);
+      /*
+       * Get sercom number from the string.  (Ugly, but saves space.)
+       */
+      sercomno = *pin_to_SERCOMB_info[bitno] - '0';
+    }
+  }
+  if (sercomno > 0) {  // If the string was null, sercomno will be -48
+    s = sercomports[sercomno];
+    sercomtype = s->USART.CTRLA.bit.MODE;
+    if (sercomtype < ARRAYSIZE(sercomtype_names)) {
+      mySerial.print(sercomtype_names[sercomtype]);
+    }
+  }
+}
+
+const char *pin_to_SERCOMALTA_info[] = {
+/* PA00 */ "1 P0",
+/* PA01 */ "1 P1",
+/* PA02 */ nullstr,
+/* PA03 */ nullstr,
+/* PA04 */ "0 P0",
+/* PA05 */ "0 P1",
+/* PA06 */ "0 P2",
+/* PA07 */ "0 P3",
+/* PA08 */ "2 P0",
+/* PA09 */ "2 P1",
+/* PA10 */ "2 P2",
+/* PA11 */ "2 P3",
+/* PA12 */ "4 P0",
+/* PA13 */ "4 P1",
+/* PA14 */ "4 P2",
+/* PA15 */ "4 P3",
+/* PA16 */ "3 P0",
+/* PA17 */ "3 P1",
+/* PA18 */ "3 P2",
+/* PA19 */ "3 P3",
+/* PA20 */ "3 P2",
+/* PA21 */ "3 P3",
+/* PA22 */ "5 P0",
+/* PA23 */ "5 P1",
+/* PA24 */ "5 P2",
+/* PA25 */ "5 P3",
+/* PA26 */ nullstr,
+/* PA27 */ nullstr,
+/* PA28 */ nullstr,
+/* PA29 */ nullstr,
+/* PA30 */ "1 P2",
+/* PA31 */ "1 P3",
+};
+
+const char *pin_to_SERCOMALTB_info[] = {
+/* PB00 */ "5 P2",
+/* PB01 */ "5 P3",
+/* PB02 */ "5 P0",
+/* PB03 */ "5 P1",
+/* PB04 */ nullstr,
+/* PB05 */ nullstr,
+/* PB06 */ nullstr,
+/* PB07 */ nullstr,
+/* PB08 */ "4 P0",
+/* PB09 */ "4 P1",
+/* PB10 */ "4 P2",
+/* PB11 */ "4 P3",
+/* PB12 */ nullstr,
+/* PB13 */ nullstr,
+/* PB14 */ nullstr,
+/* PB15 */ nullstr,
+/* PB16 */ nullstr,
+/* PB17 */ nullstr,
+/* PB18 */ nullstr,
+/* PB19 */ nullstr,
+/* PB20 */ nullstr,
+/* PB21 */ nullstr,
+/* PB22 */ "5 P2",
+/* PB23 */ "5 P3",
+/* PB24 */ nullstr,
+/* PB25 */ nullstr,
+/* PB26 */ nullstr,
+/* PB27 */ nullstr,
+/* PB28 */ nullstr,
+/* PB29 */ nullstr,
+/* PB30 */ "5 P0",
+/* PB31 */ "5 P1"
+};
+
+void decode_SERCOMA(int pin, int pmux)
+{
+  PortGroup *port = digitalPinToPort(pin);
+  int bitno = g_APinDescription[pin].ulPin;
+  int sercomno, sercomtype;
+  Sercom *s;
+
+  mySerial.print(pinmux_names[pmux]);
+  if (port == &PORT->Group[0]) {
+    if (bitno < ARRAYSIZE(pin_to_SERCOMALTA_info)) {
+      mySerial.print(pin_to_SERCOMALTA_info[bitno]);
+      /*
+       * Get sercom number from the string.  (Ugly, but saves space.)
+       */
+      sercomno = *pin_to_SERCOMALTA_info[bitno] - '0';
+    }
+  }
+  if (port == &PORT->Group[1]) {
+    if (bitno < ARRAYSIZE(pin_to_SERCOMALTB_info)) {
+      mySerial.print(pin_to_SERCOMALTB_info[bitno]);
+      /*
+       * Get sercom number from the string.  (Ugly, but saves space.)
+       */
+      sercomno = *pin_to_SERCOMALTB_info[bitno] - '0';
+    }
+  }
+  if (sercomno > 0) {  // If the string was null, sercomno will be -48
+    s = sercomports[sercomno];
+    sercomtype = s->USART.CTRLA.bit.MODE;
+    if (sercomtype < ARRAYSIZE(sercomtype_names)) {
+      mySerial.print(sercomtype_names[sercomtype]);
+    }
+  }
+}
+
+void decode_TC(int pin, int pmux)
+{
+  mySerial.print(pinmux_names[pmux]);
+}
+void decode_TCC(int pin, int pmux)
+{
+  mySerial.print(pinmux_names[pmux]);
+}
+void decode_COMM(int pin, int pmux)
+{
+  PortGroup *port = digitalPinToPort(pin);
+  int bitno = g_APinDescription[pin].ulPin;
+
+  mySerial.print(pinmux_names[pmux]);
+  // PA23..PA25 are for USB
+  if (port == &PORT->Group[0] && (bitno >= 23 && bitno <= 25)) {
+    mySerial.print("(USB)");
+  }
+  // PA30..PA31 are for SWD (Serial JTAG debug)
+  if (port == &PORT->Group[0] && (bitno >= 30 && bitno <= 31)) {
+    mySerial.print("(SWD)");
+  }
+}
+void decode_CLK(int pin, int pmux)
+{
+  mySerial.print(pinmux_names[pmux]);
+}
+
+void print_portname(int pin)
+{
+  PortGroup *port = digitalPinToPort(pin);
+  int bitno = g_APinDescription[pin].ulPin;
+
+  if (port == &PORT->Group[0]) {
+    mySerial.print("PA");
+  }
+  if (port == &PORT->Group[1]) {
+    mySerial.print("PB");
+  }
+  if (bitno < 10) {
+    mySerial.print("0");
+  }
+  mySerial.print(bitno);
+  mySerial.print("  ");
+}


Added join and leave functions

Added join and leave functions


make HALT do something in test firmware

make HALT do something in test firmware

--- arduino-test/arduino-test.ino
+++ arduino-test/arduino-test.ino
@@ -45,6 +45,8 @@
 #define TICK_DELAY 30
 unsigned long next_tick = millis() + TICK_DELAY;

+#define HALT_MASK (1<<6)
+
 void loop() {
     byte a0_7, a8_15, a16_24, ctrl;

@@ -58,11 +60,14 @@
     ctrl = spi_communicate(MX7219_NOP, 0);

     spi_communicate(MX7219_DIGIT_0 + 0, ctrl);
-    spi_communicate(MX7219_DIGIT_0 + 1, a0_7);
-    spi_communicate(MX7219_DIGIT_0 + 2, a8_15);
-    spi_communicate(MX7219_DIGIT_0 + 3, a16_24);
-    spi_communicate(MX7219_DIGIT_0 + 4, chase & 0xff);
-    spi_communicate(MX7219_DIGIT_0 + 5, (chase>>8) & 0xff);
+
+    if(ctrl & HALT_MASK) {
+        spi_communicate(MX7219_DIGIT_0 + 1, a0_7);
+        spi_communicate(MX7219_DIGIT_0 + 2, a8_15);
+        spi_communicate(MX7219_DIGIT_0 + 3, a16_24);
+        spi_communicate(MX7219_DIGIT_0 + 4, chase & 0xff);
+        spi_communicate(MX7219_DIGIT_0 + 5, (chase>>8) & 0xff);
+    }

     unsigned long now = millis();
     if(now > next_tick) {
@@ -77,6 +82,12 @@
         if(chase >= 1UL<<16) {
             chase = 1;
         }
+
+        if(!(ctrl & HALT_MASK)) {
+            for(int i=1; i<=5; ++i) {
+                spi_communicate(MX7219_DIGIT_0 + i, random(0x100));
+            }
+        }
     }
 }


Revise indentation

Revise indentation

--- RouterReset_Yun/RouterReset_Yun.ino
+++ RouterReset_Yun/RouterReset_Yun.ino
@@ -29,35 +29,36 @@
 char lastStatus = ' '; // 0 = down, 1 = up

 void setup() {
-    pinMode(redLED, OUTPUT);
-    pinMode(greenLED, OUTPUT);
-    pinMode(yellowLED, OUTPUT);
-    pinMode(routerPin, OUTPUT);
-    pinMode(routerLED, OUTPUT);
-    digitalWrite(routerPin, HIGH);
-    analogWrite(routerLED, routerLEDlevel);
-    pinMode(switchPin, INPUT);
-    digitalWrite(switchPin, HIGH);

-    digitalWrite(redLED, HIGH);
-    digitalWrite(greenLED, HIGH);
-    digitalWrite(yellowLED, HIGH);
-    delay(1000);
-    digitalWrite(redLED, LOW);
-    digitalWrite(greenLED, LOW);
-    digitalWrite(yellowLED, LOW);
+  pinMode(redLED, OUTPUT);
+  pinMode(greenLED, OUTPUT);
+  pinMode(yellowLED, OUTPUT);
+  pinMode(routerPin, OUTPUT);
+  pinMode(routerLED, OUTPUT);
+  digitalWrite(routerPin, HIGH);
+  analogWrite(routerLED, routerLEDlevel);
+  pinMode(switchPin, INPUT);
+  digitalWrite(switchPin, HIGH);

-    Bridge.begin();  // make contact with the linux processor
+  digitalWrite(redLED, HIGH);
+  digitalWrite(greenLED, HIGH);
+  digitalWrite(yellowLED, HIGH);
+  delay(1000);
+  digitalWrite(redLED, LOW);
+  digitalWrite(greenLED, LOW);
+  digitalWrite(yellowLED, LOW);

-    digitalWrite(redLED, HIGH);
-    digitalWrite(greenLED, HIGH);
-    digitalWrite(yellowLED, HIGH);
-    delay(startUpDelaySec*1000);
-    digitalWrite(redLED, LOW);
-    digitalWrite(greenLED, LOW);
-    digitalWrite(yellowLED, LOW);
+  Bridge.begin();  // make contact with the linux processor

-    logEvent("startup");
+  digitalWrite(redLED, HIGH);
+  digitalWrite(greenLED, HIGH);
+  digitalWrite(yellowLED, HIGH);
+  delay(startUpDelaySec*1000);
+  digitalWrite(redLED, LOW);
+  digitalWrite(greenLED, LOW);
+  digitalWrite(yellowLED, LOW);
+
+  logEvent("startup");
 }

 void loop() {
@@ -75,7 +76,7 @@
     delay(secBetweenPings_Down*1000);
     internetStatus = pingGoogle();
   }
-
+
   if(internetStatus[0] == '0') {
     resetRouter();
     delay(secBetweenPings_Down*1000);


Removed old blocking version of Arduino firmware

--- arduino/private/ledpuff/ledpuff.ino
+++ arduino/private/ledpuff/ledpuff.ino
@@ -1,488 +0,0 @@
-#include <Wire.h> // For I2C communication
-
-//This is the I2C Address of the MCP4725, by default (A0 pulled to GND).
-//Please note that this breakout is for the MCP4725A0.
-#define MCP4725_ADDR 0x60   // DAC
-#define MAXDACUNIT 4095       // 2^12-1 (ie 12 bits)
-#define MINDACUNIT 0
-// For converstion from laser power to DAC units
-// For laser 11140001, Rig 1
-//#define LASERSLOPE 27
-//#define LASEROFFSET 2400
-// For laser 11140002, Rig 2
-//#define LASERSLOPE 36
-//#define LASEROFFSET 2100
-// For laser 11140002, Rig 3
-//#define LASERSLOPE 30
-//#define LASEROFFSET 2500
-// For laser 11140002, Rig 4
-#define LASERSLOPE 36
-#define LASEROFFSET 2100
-//For devices with A0 pulled HIGH, use 0x61
-
-/*
-  Conditioning
-  to regulate camera, CS (LED, tone, whisker puff, ...), US.
- */
-
-// Outputs
-int greenled = 7;
-int camera = 8;
-int led = 9;
-int whisker = 10;
-int tonech = 11;
-int laser = 12;
-int puff = 13;
-
-// Used internally to select channels for CS/US
-int csout = 0;  // Not used yet
-int usout = 0;  // Used for 2nd order conditioning to use "US" as CS2
-
-// Task variables (time in ms, freq in hz)
-int campretime = 200;
-int camposttime = 800;
-int csdur = 500;
-int csch = 1;   // default to LED
-int usch = 3;   // default to ipsi corneal puff
-int ISI = 200;
-int usdur = 20;
-int residual;
-int tonefreq5 = 10000;
-
-// Added as temporary fix to allow laser stim during trial
-int laserdelay = 0; // delay from CS onset until laser onset
-int laserdur = 0; // duration of laser pulse
-int laserpower = 0; // in the future we should use float
-
-unsigned long trialtime = 0; // For keeping track of elapsed time during trial
-
-// the setup routine runs once when you press reset:
-void setup() {
-  // initialize the digital pin as an output.
-  pinMode(camera, OUTPUT);
-  pinMode(led, OUTPUT);
-  pinMode(puff, OUTPUT);
-  pinMode(whisker, OUTPUT);
-  pinMode(tonech, OUTPUT);
-  pinMode(greenled, OUTPUT);
-  pinMode(laser, OUTPUT);
-
-  // Default all output pins to LOW - for some reason they were floating high on the Due before I (Shane) added this
-  digitalWrite(camera, LOW);
-  digitalWrite(led, LOW);
-  digitalWrite(puff, LOW);
-  digitalWrite(whisker, LOW);
-  digitalWrite(tonech, LOW);
-  digitalWrite(greenled, LOW);
-  digitalWrite(laser, LOW);
-
-  Serial.begin(115200);
-  Wire.begin();
-
-  DACWrite(0);
-}
-
-// the loop routine runs over and over again forever:
-void loop() {
-  // Consider using attachInterrupt() to allow better realtime control of starting and stopping, etc.
-
-  checkVars();
-  if (Serial.available() > 0) {
-    if (Serial.peek() == 1) { // This is the header for triggering; difference from variable communication is that only one byte is sent telling to trigger
-      Serial.read();  // Clear the value from the buffer
-      Triggered();
-    }
-  }
-  delay(1);
-}
-
-
-// Check to see if Matlab is trying to send updated variables
-void checkVars() {
-  int header;
-  int value;
-  // Matlab sends data in 3 byte packets: first byte is header telling which variable to update,
-  // next two bytes are the new variable data as 16 bit int
-  // Header is coded numerically such that 1=trigger, 2=continuous, 3=CS channel, 4=CS dur,
-  // 0 is reserved for some future function, possibly as a bailout (i.e. stop reading from buffer).
-  while (Serial.available() > 2) {
-    header = Serial.read();
-    value = Serial.read() | Serial.read() << 8;
-
-    if (header == 0) {
-      break;
-    }
-
-    switch (header) {
-      case 3:
-        campretime = value;
-        break;
-      case 4:
-        csch = value;
-        break;
-      case 5:
-        csdur = value;
-        break;
-      case 6:
-        usdur = value;
-        break;
-      case 7:
-        ISI = value;
-        break;
-      case 8:
-        tonefreq5 = value;
-        break;
-      case 9:
-        camposttime = value;
-        break;
-      case 10:
-        usch = value;
-        break;
-      case 11:
-        laserdelay = value;
-        break;
-      case 12:
-        laserdur = value;
-        break;
-      case 13:
-        laserpower = value;
-        break;
-    }
-    delay(4); // Delay enough to allow next 3 bytes into buffer (24 bits/9600 bps = 2.5 ms, so double it for safety).
-  }
-}
-
-
-// --- function executed to start a trial ----
-void Triggered() {
-  unsigned long now;
-  // triggering camera
-  digitalWrite(camera, HIGH);  // Camera will collect the number of frames that we specify while TTL is high
-
-  // NOTE: I removed the single short pulse because camera is now configured for "TTL High" instead of "Rising-Edge"
-  //  delay(1);
-  //  digitalWrite(camera, LOW);
-  //  residual=campretime-1;
-  residual = campretime;
-  if (residual > 0) {
-    delay(residual);          // wait
-  }
-
-  // starting a trial
-  trialtime = millis();
-
-  if (csdur <= ISI) {
-    doTrace();
-  }
-  else { doDelay(); }
-
-  now = millis();
-  if (now - trialtime < camposttime) {
-    //delay(int(now - trialtime));
-    delay(camposttime - int(now - trialtime));
-  }
-
-  // Camera will only collect the number of frames that we specify so we only have to reset TTL
-  // to low before starting the next trial. The hitch is that if we set it low too early we won't
-  // collect all of the frames that we asked for and the camera will get stuck; hence the extra delay.
-  delay(10); // Delay a little while longer just to be safe - so the camera doesn't get stuck with more frames to acquire
-  digitalWrite(camera, LOW);
-}
-
-/* We one of two functions depending on whether we're doing something like "trace"
-or something like "delay" conditioning
-*/
-
-void doDelay() {
-
-  csON();
-
-  if (laserdur > 0) {
-    delay(laserdelay);
-    laserOn();
-    delay(ISI-laserdelay);
-  }
-  else { delay(ISI); }
-
-  usON();
-
-  if (csdur < (ISI+usdur)) {
-   delay(csdur-ISI);
-   csOFF();
-   residual = usdur - (csdur-ISI);
-  }
-  else {
-    residual = usdur;
-  }
-
-  delay(residual);                  // wait for remainder of us (or all if cs is longer)
-
-  usOFF();
-
-  if (laserdur > 0) {
-    residual = (laserdelay + laserdur) - ISI - usdur;
-    if (residual > 0) {
-      delay(residual);
-      residual = csdur - (laserdelay + laserdur);
-    }
-    laserOff();
-  }
-  else {
-    residual = csdur - ISI - usdur;
-  }
-
-  if (residual > 0) {
-    delay(residual);          // wait for whatever additional time cs is on
-  }
-
-  csOFF();
-
-}
-
-void doTrace() {
-
-  csON();
-
-  delay(csdur);
-
-  csOFF();
-
-  residual = ISI-csdur;
-
-  if (residual > 0) {
-    delay(residual);    // residual is trace period
-  }
-
-  usON();
-  delay(usdur);                  // wait for us
-  usOFF();
-
-}
-
-void doDelayWithLaser() {
-  csON();
-
-  // We have to figure out what the order of state transitions should be
-  // This seems better implemented as a DAG (directed acyclic graph), where
-  // each node is a state transition and the edges are delays.
-  // Can we do this relatively easily in Arduino? We first need to sort based on
-  // delays from trial onset, then make a priority queue for each state transition and
-  // it's associated residual delay.
-
-  delay(ISI);
-
-  usON();
-
-  if (csdur < (ISI+usdur)) {
-   delay(csdur-ISI);
-   csOFF();
-   residual = usdur - (csdur-ISI);
-  }
-  else {
-    residual = usdur;
-  }
-
-  delay(residual);                  // wait for remainder of us (or all if cs is longer)
-
-  usOFF();
-
-  residual = csdur - ISI - usdur;
-  if (residual > 0) {
-    delay(residual);          // wait for whatever additional time cs is on
-  }
-
-  csOFF();
-
-}
-
-void csON() {
- if (csdur > 0) {
-    switch (csch) {
-      case 1:
-        digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
-        break;
-      case 2:
-        digitalWrite(whisker, HIGH);   // turn the LED on (HIGH is the voltage level)
-        break;
-      case 5:
-        tone(tonech, tonefreq5, csdur);
-        break;
-      case 6:
-        tone(tonech, tonefreq5, csdur);
-        break;
-      case  7:
-        digitalWrite(greenled, HIGH); // turn the green LED on (HIGH is the voltage level)
-        break;
-    }
-  }
-}
-
-
-void csOFF() {
-     if (csdur > 0) {
-    switch (csch) {
-      case 1:
-        digitalWrite(led, LOW);   // turn the LED on (HIGH is the voltage level)
-        break;
-      case 2:
-        digitalWrite(whisker, LOW);   // turn the LED on (HIGH is the voltage level)
-        break;
-      case 7:
-        digitalWrite(greenled, LOW); //  turn the green LED off (LOW is the voltage level)
-        break;
-    }
-  }
-}
-
-void usON() {
-    if (usdur > 0) {
-
-    switch (usch) {
-      case 1:
-        usout = led;
-        break;
-      case 2:
-        usout = whisker;
-        break;
-      case 3:
-        usout = puff;
-        break;
-      case 7:
-        usout = greenled;
-        break;
-      case 5:      // Tone is a special case that we have to handle differently
-        tone(tonech, tonefreq5, usdur);
-        usout = 0;
-        break;
-      case 6:      // Tone is a special case that we have to handle differently
-        tone(tonech, tonefreq5, usdur);
-        usout = 0;
-        break;
-      default:
-        usout = 0;
-    }
-  }
-
-  if (usout > 0) {
-  digitalWrite(usout, HIGH);   // turn the PUFF on (HIGH is the voltage level)
-  }
-}
-
-void usOFF() {
-  if (usout > 0) {
-  digitalWrite(usout, LOW);    // turn the PUFF off (HIGH is the voltage level)
-  }
-}
-
-void laserOn(){
-  // digitalWrite(laser, HIGH);
-  DACWrite(powerToDACUnits(laserpower));
-}
-
-
-void laserOff() {
-  // digitalWrite(laser, LOW);
-  DACWrite(MINDACUNIT);
-}
-
-void DACWrite(int DACvalue) {
-
-  Wire.beginTransmission(MCP4725_ADDR);
-  Wire.write(64);                     // cmd to update the DAC
-  Wire.write(DACvalue >> 4);        // the 8 most significant bits...
-  Wire.write((DACvalue & 15) << 4); // the 4 least significant bits...
-  Wire.endTransmission();
-
-}
-
-int powerToDACUnits(int power) {
-
-  int DACUnits = power * LASERSLOPE + LASEROFFSET;
-
-  if (power == 0) {return 0;}
-
-  if (DACUnits < MAXDACUNIT) {return DACUnits;}
-  else {return MAXDACUNIT;}
-
-}
-
-/*
- Tone generator for Arduino Due
- v1  use timer, and toggle any digital pin in ISR
-   funky duration from arduino version
-   TODO use FindMckDivisor?
-   timer selected will preclude using associated pins for PWM etc.
-    could also do timer/pwm hardware toggle where caller controls duration
-*/
-
-
-// timers TC0 TC1 TC2   channels 0-2 ids 0-2  3-5  6-8     AB 0 1
-// use TC1 channel 0
-#define TONE_TIMER TC1
-#define TONE_CHNL 0
-#define TONE_IRQ TC3_IRQn
-
-// TIMER_CLOCK4   84MHz/128 with 16 bit counter give 10 Hz to 656KHz
-//  piano 27Hz to 4KHz
-
-static uint8_t pinEnabled[PINS_COUNT];
-static uint8_t TCChanEnabled = 0;
-static boolean pin_state = false ;
-static Tc *chTC = TONE_TIMER;
-static uint32_t chNo = TONE_CHNL;
-
-volatile static int32_t toggle_count;
-static uint32_t tone_pin;
-
-// frequency (in hertz) and duration (in milliseconds).
-
-void tone(uint32_t ulPin, uint32_t frequency, int32_t duration)
-{
-  const uint32_t rc = VARIANT_MCK / 256 / frequency;
-  tone_pin = ulPin;
-  toggle_count = 0;  // strange  wipe out previous duration
-  if (duration > 0 ) toggle_count = 2 * frequency * duration / 1000;
-  else toggle_count = -1;
-
-  if (!TCChanEnabled) {
-    pmc_set_writeprotect(false);
-    pmc_enable_periph_clk((uint32_t)TONE_IRQ);
-    TC_Configure(chTC, chNo,
-                 TC_CMR_TCCLKS_TIMER_CLOCK4 |
-                 TC_CMR_WAVE |         // Waveform mode
-                 TC_CMR_WAVSEL_UP_RC ); // Counter running up and reset when equals to RC
-
-    chTC->TC_CHANNEL[chNo].TC_IER = TC_IER_CPCS; // RC compare interrupt
-    chTC->TC_CHANNEL[chNo].TC_IDR = ~TC_IER_CPCS;
-    NVIC_EnableIRQ(TONE_IRQ);
-    TCChanEnabled = 1;
-  }
-  if (!pinEnabled[ulPin]) {
-    pinMode(ulPin, OUTPUT);
-    pinEnabled[ulPin] = 1;
-  }
-  TC_Stop(chTC, chNo);
-  TC_SetRC(chTC, chNo, rc);    // set frequency
-  TC_Start(chTC, chNo);
-}
-
-void noTone(uint32_t ulPin)
-{
-  TC_Stop(chTC, chNo);  // stop timer
-  digitalWrite(ulPin, LOW); // no signal on pin
-}
-
-// timer ISR  TC1 ch 0
-void TC3_Handler ( void ) {
-  TC_GetStatus(TC1, 0);
-  if (toggle_count != 0) {
-    // toggle pin  TODO  better
-    digitalWrite(tone_pin, pin_state = !pin_state);
-    if (toggle_count > 0) toggle_count--;
-  } else {
-    noTone(tone_pin);
-  }
-}
-
-
-


Updated the example.

Updated the example.

--- examples/JsonGeneratorExample/JsonGeneratorExample.ino
+++ examples/JsonGeneratorExample/JsonGeneratorExample.ino
@@ -12,8 +12,8 @@
     Serial.begin(9600);

     JsonArray<2> array;
-    array.add(48.756080, 6);
-    array.add(2.302038, 6);
+    array.add<6>(48.756080); // 6 is the number of decimals to print
+    array.add<6>(2.302038);  // if not specified, 2 digits are printed

     JsonHashTable<3> root;
     root.add("sensor", "gps");


add note on MISO/MOSI directions

add note on MISO/MOSI directions

--- src/monitor-firmware.ino
+++ src/monitor-firmware.ino
@@ -1,10 +1,13 @@
 // Firmware for monitor board

 // Pin definitions
-#define MISO    2
-#define MOSI    3
+#define MISO    2   // NB: (1)
+#define MOSI    3   // NB: (1)
 #define SCLK    4
 #define DLOAD   8
+
+// (1) Since the monitor board is a slave device w.r.t. the processor board,
+// MISO is an OUTPUT and MOSI is an INPUT.

 // MAX7219 registers. Note that these are bit-reversed since the MAX7219
 // expects data to be shifted in MSB first.
@@ -39,8 +42,8 @@

 void setup() {
     // Setup all pin modes
-    pinMode(MISO, OUTPUT);
-    pinMode(MOSI, INPUT);
+    pinMode(MISO, OUTPUT);  // NB: (1)
+    pinMode(MOSI, INPUT);   // NB: (1)
     pinMode(SCLK, OUTPUT);
     pinMode(DLOAD, OUTPUT);


[Arduino] Implemented acceleration readout and code cleanup.

Signed-off-by: Juri Berlanda <5bfdca9e82c53adb0603ce7083f4ba4f2da5cacf@hotmail.com>

--- Arduino/vj-flight-controller/vj-flight-controller.ino
+++ Arduino/vj-flight-controller/vj-flight-controller.ino
@@ -51,7 +51,7 @@
 // Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation
 // is used in I2Cdev.h
 #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
-    #include "Wire.h"
+#include "Wire.h"
 #endif

 // class default I2C address is 0x68
@@ -78,44 +78,6 @@
    http://arduino.cc/forum/index.php/topic,109987.0.html
    http://code.google.com/p/arduino/issues/detail?id=958
  * ========================================================================= */
-
-
-
-// uncomment "OUTPUT_READABLE_QUATERNION" if you want to see the actual
-// quaternion components in a [w, x, y, z] format (not best for parsing
-// on a remote host such as Processing or something though)
-//#define OUTPUT_READABLE_QUATERNION
-
-// uncomment "OUTPUT_READABLE_EULER" if you want to see Euler angles
-// (in degrees) calculated from the quaternions coming from the FIFO.
-// Note that Euler angles suffer from gimbal lock (for more info, see
-// http://en.wikipedia.org/wiki/Gimbal_lock)
-//#define OUTPUT_READABLE_EULER
-
-// uncomment "OUTPUT_READABLE_YAWPITCHROLL" if you want to see the yaw/
-// pitch/roll angles (in degrees) calculated from the quaternions coming
-// from the FIFO. Note this also requires gravity vector calculations.
-// Also note that yaw/pitch/roll angles suffer from gimbal lock (for
-// more info, see: http://en.wikipedia.org/wiki/Gimbal_lock)
-#define OUTPUT_READABLE_YAWPITCHROLL
-
-// uncomment "OUTPUT_READABLE_REALACCEL" if you want to see acceleration
-// components with gravity removed. This acceleration reference frame is
-// not compensated for orientation, so +X is always +X according to the
-// sensor, just without the effects of gravity. If you want acceleration
-// compensated for orientation, us OUTPUT_READABLE_WORLDACCEL instead.
-//#define OUTPUT_READABLE_REALACCEL
-
-// uncomment "OUTPUT_READABLE_WORLDACCEL" if you want to see acceleration
-// components with gravity removed and adjusted for the world frame of
-// reference (yaw is relative to initial orientation, since no magnetometer
-// is present in this case). Could be quite handy in some cases.
-//#define OUTPUT_READABLE_WORLDACCEL
-
-// uncomment "OUTPUT_TEAPOT" if you want output that matches the
-// format used for the InvenSense teapot demo
-//#define OUTPUT_TEAPOT
-

 #define LED_PIN 13 // (Arduino is 13, Teensy is 11, Teensy++ is 6)
@@ -139,7 +101,7 @@
 float ypr[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity vector

 // packet structure for InvenSense teapot demo
-uint8_t teapotPacket[14] = { '$', 0x02, 0,0, 0,0, 0,0, 0,0, 0x00, 0x00, '\r', '\n' };
+uint8_t teapotPacket[14] = { '$', 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0x00, '\r', '\n' };

@@ -149,7 +111,7 @@

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

@@ -159,192 +121,152 @@
 // ================================================================

 void setup() {
-    // join I2C bus (I2Cdev library doesn't do this automatically)
-    #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
-        Wire.begin();
-        TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz)
-    #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
-        Fastwire::setup(400, true);
-    #endif
-
-    // initialize serial communication
-    // (115200 chosen because it is required for Teapot Demo output, but it's
-    // really up to you depending on your project)
-    Serial.begin(115200);
-    while (!Serial); // wait for Leonardo enumeration, others continue immediately
-
-    // NOTE: 8MHz or slower host processors, like the Teensy @ 3.3v or Ardunio
-    // Pro Mini running at 3.3v, cannot handle this baud rate reliably due to
-    // the baud timing being too misaligned with processor ticks. You must use
-    // 38400 or slower in these cases, or use some kind of external separate
-    // crystal solution for the UART timer.
-
-    // initialize device
-    Serial.println(F("Initializing I2C devices..."));
-    mpu.initialize();
-
-    // verify connection
-    Serial.println(F("Testing device connections..."));
-    Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));
-
-    // wait for ready
-    Serial.println(F("\nSend any character to begin DMP programming and demo: "));
-    while (Serial.available() && Serial.read()); // empty buffer
-    while (!Serial.available());                 // wait for data
-    while (Serial.available() && Serial.read()); // empty buffer again
-
-    // load and configure the DMP
-    Serial.println(F("Initializing DMP..."));
-    devStatus = mpu.dmpInitialize();
-
-    // supply your own gyro offsets here, scaled for min sensitivity
-    //mpu.setXGyroOffset(220);
-    //mpu.setYGyroOffset(-376);
-    //mpu.setZGyroOffset(-85);
-    //mpu.setZAccelOffset(1788); // 1688 factory default for my test chip
-
-    // make sure it worked (returns 0 if so)
-    if (devStatus == 0) {
-        // turn on the DMP, now that it's ready
-        Serial.println(F("Enabling DMP..."));
-        mpu.setDMPEnabled(true);
-
-        // enable Arduino interrupt detection
-        Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
-        attachInterrupt(digitalPinToInterrupt(3), dmpDataReady, RISING);
-        mpuIntStatus = mpu.getIntStatus();
-
-        // set our DMP Ready flag so the main loop() function knows it's okay to use it
-        Serial.println(F("DMP ready! Waiting for first interrupt..."));
-        dmpReady = true;
-
-        // get expected DMP packet size for later comparison
-        packetSize = mpu.dmpGetFIFOPacketSize();
-    } else {
-        // ERROR!
-        // 1 = initial memory load failed
-        // 2 = DMP configuration updates failed
-        // (if it's going to break, usually the code will be 1)
-        Serial.print(F("DMP Initialization failed (code "));
-        Serial.print(devStatus);
-        Serial.println(F(")"));
+  // join I2C bus (I2Cdev library doesn't do this automatically)
+#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
+  Wire.begin();
+  TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz)
+#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
+  Fastwire::setup(400, true);
+#endif
+
+  // initialize serial communication
+  // (115200 chosen because it is required for Teapot Demo output, but it's
+  // really up to you depending on your project)
+  Serial.begin(115200);
+  while (!Serial); // wait for Leonardo enumeration, others continue immediately
+
+  // NOTE: 8MHz or slower host processors, like the Teensy @ 3.3v or Ardunio
+  // Pro Mini running at 3.3v, cannot handle this baud rate reliably due to
+  // the baud timing being too misaligned with processor ticks. You must use
+  // 38400 or slower in these cases, or use some kind of external separate
+  // crystal solution for the UART timer.
+
+  // initialize device
+  Serial.println(F("Initializing I2C devices..."));
+  mpu.initialize();
+
+  // verify connection
+  Serial.println(F("Testing device connections..."));
+  Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));
+
+  // load and configure the DMP
+  Serial.println(F("Initializing DMP..."));
+  devStatus = mpu.dmpInitialize();
+
+  // supply your own gyro offsets here, scaled for min sensitivity
+  //mpu.setXGyroOffset(220);
+  //mpu.setYGyroOffset(-376);
+  //mpu.setZGyroOffset(-85);
+  //mpu.setZAccelOffset(1788); // 1688 factory default for my test chip
+
+  // make sure it worked (returns 0 if so)
+  if (devStatus == 0) {
+    // turn on the DMP, now that it's ready
+    Serial.println(F("Enabling DMP..."));
+    mpu.setDMPEnabled(true);
+
+    // enable Arduino interrupt detection
+    Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
+    attachInterrupt(digitalPinToInterrupt(3), dmpDataReady, RISING);
+    mpuIntStatus = mpu.getIntStatus();
+
+    // set our DMP Ready flag so the main loop() function knows it's okay to use it
+    Serial.println(F("DMP ready! Waiting for first interrupt..."));
+    dmpReady = true;
+
+    // get expected DMP packet size for later comparison
+    packetSize = mpu.dmpGetFIFOPacketSize();
+  } else {
+    // ERROR!
+    // 1 = initial memory load failed
+    // 2 = DMP configuration updates failed
+    // (if it's going to break, usually the code will be 1)
+    Serial.print(F("DMP Initialization failed (code "));
+    Serial.print(devStatus);
+    Serial.println(F(")"));
+  }
+
+  // configure LED for output
+  pinMode(LED_PIN, OUTPUT);
+
+  while (Serial.available() && Serial.read()); // empty buffer
+}
+
+
+
+// ================================================================
+// ===                    MAIN PROGRAM LOOP                     ===
+// ================================================================
+
+void loop() {
+  char command;
+
+  // if programming failed, don't try to do anything
+  if (!dmpReady) return;
+
+  // reset interrupt flag and get INT_STATUS byte
+  mpuInterrupt = false;
+  mpuIntStatus = mpu.getIntStatus();
+
+  // get current FIFO count
+  fifoCount = mpu.getFIFOCount();
+
+  // check for overflow (this should never happen unless our code is too inefficient)
+  if ((mpuIntStatus & 0x10) || fifoCount == 1024) {
+    // reset so we can continue cleanly
+    mpu.resetFIFO();
+    Serial.println(F("FIFO overflow!"));
+    // otherwise, check for DMP data ready interrupt (this should happen frequently)
+  } else if (mpuIntStatus & 0x02) {
+    // wait for correct available data length, should be a VERY short wait
+    while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();
+
+    // read a packet from FIFO
+    mpu.getFIFOBytes(fifoBuffer, packetSize);
+
+    // track FIFO count here in case there is > 1 packet available
+    // (this lets us immediately read more without waiting for an interrupt)
+    fifoCount -= packetSize;
+
+    // Get Euler angles in degrees and Acceleration in world-frame
+    mpu.dmpGetQuaternion(&q, fifoBuffer);
+    mpu.dmpGetAccel(&aa, fifoBuffer);
+    mpu.dmpGetGravity(&gravity, &q);
+    mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
+    mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity);
+    mpu.dmpGetLinearAccelInWorld(&aaWorld, &aaReal, &q);
+
+    if (Serial.available()) {
+      command = Serial.read();
+      switch (command) {
+        case 'i':
+          Serial.println("i\ttrue");
+          break;
+        case 'g':
+          Serial.print("g\t");
+          Serial.print(ypr[0] * 180 / M_PI);
+          Serial.print("\t");
+          Serial.print(ypr[1] * 180 / M_PI);
+          Serial.print("\t");
+          Serial.println(ypr[2] * 180 / M_PI);
+          break;
+        case 'a':
+          Serial.print("a\t");
+          Serial.print(aaWorld.x);
+          Serial.print("\t");
+          Serial.print(aaWorld.y);
+          Serial.print("\t");
+          Serial.println(aaWorld.z);
+          break;
+        default:
+          Serial.print("ERROR - Command ");
+          Serial.print(command);
+          Serial.println(" unknown!");
+      }
+
+      // blink LED to indicate activity
+      blinkState = !blinkState;
+      digitalWrite(LED_PIN, blinkState);
     }
-
-    // configure LED for output
-    pinMode(LED_PIN, OUTPUT);
-}
-
-
-
-// ================================================================
-// ===                    MAIN PROGRAM LOOP                     ===
-// ================================================================
-
-void loop() {
-    // if programming failed, don't try to do anything
-    if (!dmpReady) return;
-
-    // wait for MPU interrupt or extra packet(s) available
-    while (!mpuInterrupt && fifoCount < 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;
-    mpuIntStatus = mpu.getIntStatus();
-
-    // get current FIFO count
-    fifoCount = mpu.getFIFOCount();
-
-    // check for overflow (this should never happen unless our code is too inefficient)
-    if ((mpuIntStatus & 0x10) || fifoCount == 1024) {
-        // reset so we can continue cleanly
-        mpu.resetFIFO();
-        Serial.println(F("FIFO overflow!"));
-
-    // otherwise, check for DMP data ready interrupt (this should happen frequently)
-    } else if (mpuIntStatus & 0x02) {
-        // wait for correct available data length, should be a VERY short wait
-        while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();
-
-        // read a packet from FIFO
-        mpu.getFIFOBytes(fifoBuffer, packetSize);
-
-        // track FIFO count here in case there is > 1 packet available
-        // (this lets us immediately read more without waiting for an interrupt)
-        fifoCount -= packetSize;
-
-        #ifdef OUTPUT_READABLE_YAWPITCHROLL
-            // display Euler angles in degrees
-            mpu.dmpGetQuaternion(&q, fifoBuffer);
-            mpu.dmpGetGravity(&gravity, &q);
-            mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
-            if (Serial.available()) {
-              Serial.read();
-              Serial.print("ypr\t");
-              Serial.print(ypr[0] * 180/M_PI);
-              Serial.print("\t");
-              Serial.print(ypr[1] * 180/M_PI);
-              Serial.print("\t");
-              Serial.println(ypr[2] * 180/M_PI);
-            }
-        #endif
-
-        #ifdef OUTPUT_READABLE_REALACCEL
-            // display real acceleration, adjusted to remove gravity
-            mpu.dmpGetQuaternion(&q, fifoBuffer);
-            mpu.dmpGetAccel(&aa, fifoBuffer);
-            mpu.dmpGetGravity(&gravity, &q);
-            mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity);
-            Serial.print("areal\t");
-            Serial.print(aaReal.x);
-            Serial.print("\t");
-            Serial.print(aaReal.y);
-            Serial.print("\t");
-            Serial.println(aaReal.z);
-        #endif
-
-        #ifdef OUTPUT_READABLE_WORLDACCEL
-            // display initial world-frame acceleration, adjusted to remove gravity
-            // and rotated based on known orientation from quaternion
-            mpu.dmpGetQuaternion(&q, fifoBuffer);
-            mpu.dmpGetAccel(&aa, fifoBuffer);
-            mpu.dmpGetGravity(&gravity, &q);
-            mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity);
-            mpu.dmpGetLinearAccelInWorld(&aaWorld, &aaReal, &q);
-            Serial.print("aworld\t");
-            Serial.print(aaWorld.x);
-            Serial.print("\t");
-            Serial.print(aaWorld.y);
-            Serial.print("\t");
-            Serial.println(aaWorld.z);
-        #endif
-
-        #ifdef OUTPUT_TEAPOT
-            // display quaternion values in InvenSense Teapot demo format:
-            teapotPacket[2] = fifoBuffer[0];
-            teapotPacket[3] = fifoBuffer[1];
-            teapotPacket[4] = fifoBuffer[4];
-            teapotPacket[5] = fifoBuffer[5];
-            teapotPacket[6] = fifoBuffer[8];
-            teapotPacket[7] = fifoBuffer[9];
-            teapotPacket[8] = fifoBuffer[12];
-            teapotPacket[9] = fifoBuffer[13];
-            Serial.write(teapotPacket, 14);
-            teapotPacket[11]++; // packetCount, loops at 0xFF on purpose
-        #endif
-
-        // blink LED to indicate activity
-        blinkState = !blinkState;
-        digitalWrite(LED_PIN, blinkState);
-    }
+  }
 }


Update SparkCore.ino

Update SparkCore.ino

--- firmware/examples/Transports/SparkCore/SparkCore.ino
+++ firmware/examples/Transports/SparkCore/SparkCore.ino
@@ -21,9 +21,10 @@
 // Go to the Project Settings (nut icon).
 char auth[] = "YourAuthToken";

-
-// Attach a Button widget (Switch) to the Digital pin 7 - and control the built-in blue led.
-// No coding is required for direct pin control!
+// Attach a Button widget (mode: Switch) to the Digital pin 7 - and control the built-in blue led.
+// Attach a Graph widget to Analog pin 1
+// Attach a Gauge widget to Analog pin 2
+// No coding is required for direct pin operations!

 void setup()
 {
@@ -32,9 +33,9 @@
     Blynk.begin(auth);
 }

-// Attach a Button widget to the Virtual pin 1 - and send sweet tweets!
+// Attach a Button widget (mode: Push) to the Virtual pin 1 - and send sweet tweets!
 BLYNK_WRITE(1) {
-    if (param.asInt()) { // On button down...
+    if (param.asInt() == 1) { // On button down...
         // Tweeting!
         // Note:
         //   We allow 1 tweet per minute for now.


added led init at 0 (no light at the begining)

--- light/main.ino
+++ light/main.ino
@@ -14,6 +14,10 @@
   pinMode(REDPIN, OUTPUT);
   pinMode(GREENPIN, OUTPUT);
   pinMode(BLUEPIN, OUTPUT);
+
+  analogWrite(REDPIN,   0);
+  analogWrite(BLUEPIN,  0);
+  analogWrite(GREENPIN, 0);

   Serial.begin(9600);
 }


Delete slave_lcd_grove.ino

Delete slave_lcd_grove.ino

--- au/slave_lcd_grove.ino
+++ au/slave_lcd_grove.ino
@@ -1,78 +0,0 @@
-#include <SoftwareSerial.h>
-#include "RS485_protocol.h"
-#include <Wire.h>
-#include "rgb_lcd.h"
-
-rgb_lcd lcd;
-
-const int colorR = 255;
-const int colorG = 0;
-const int colorB = 0;
-
-SoftwareSerial rs485 (2, 3);  // receive pin, transmit pin
-const byte ENABLE_PIN = 4;
-
-void fWrite (const byte what)
-  {
-  rs485.write (what);
-  }
-
-int fAvailable ()
-  {
-  return rs485.available ();
-  }
-
-int fRead ()
-  {
-  return rs485.read ();
-  }
-
-void setup()
-{
-  rs485.begin (38400);
-  pinMode (ENABLE_PIN, OUTPUT);  // driver output enable
-  lcd.begin(16, 2);
-
-    lcd.setRGB(colorR, colorG, colorB);
-
-    // Print a message to the LCD.
-    lcd.print("hello, world!");
-}
-
-void loop()
-{
-  byte buf [100];
-
-  byte received = recvMsg (fAvailable, fRead, buf, sizeof (buf));
-
-  if (received)
-    {
-    if (buf [0] != 1)
-      return;  // not my device
-
-    if (buf [1] != 2)
-      return;  // unknown command
-
-    byte msg [] = {
-       0,  // device 0 (master)
-       3,  // turn light on command received
-    };
-
-    delay (100);  // give the master a moment to prepare to receive
-    digitalWrite (ENABLE_PIN, HIGH);  // enable sending
-    sendMsg (fWrite, msg, sizeof msg);
-    digitalWrite (ENABLE_PIN, LOW);  // disable sending
-
-  //  analogWrite (11, buf [2]);  // set light level
-
-
-lcd.setCursor(0, 1);
-    // print the number of seconds since reset:
-    lcd.print(buf [2]);
-
-    lcd.setCursor(10, 1);
-    lcd.print(buf [1]);
-
-   }  // end if something received
-
-}  // end of loop


Clear text string on emergency stop

Clear text string on emergency stop

--- software/firmware/LogoBotWifiScribbler/LogoBotWifiScribbler.ino
+++ software/firmware/LogoBotWifiScribbler/LogoBotWifiScribbler.ino
@@ -248,6 +248,7 @@
             break;
         case LOGO_CMD_SE:
             bot.emergencyStop();
+			text = "";
             break;
         case LOGO_CMD_BZ:
             bot.buzz(f1);


Results of the auto formatter

Results of the auto formatter

--- Arduino/BlueCube/BlueCube.ino
+++ Arduino/BlueCube/BlueCube.ino
@@ -1,5 +1,5 @@
 /*
- *  File:     BlueCube.ino
+ *  File:     BlueCube.ino
  *  Version:  0.8
  *  Author:   Adam Reed (adam@secretcode.ninja)
  *  Licence:  BSD 3-Clause Licence
@@ -13,9 +13,9 @@

     BLUEFRUIT_HWSERIAL_NAME   Name of the HW serial port the Bluefruit BLE
                               device is connected to
-
+
     - Bluetooth
-    BLUEFRUIT_UART_MODE_PIN   The pin that has been connected to 'MOD'
+    BLUEFRUIT_UART_MODE_PIN   The pin that has been connected to 'MOD'
     MINIMUM_FIRMWARE_VERSION  Minimum firmware version to have some features
     MODE_LED_BEHAVIOUR        LED activity, valid options are
                               "DISABLE" or "MODE" or "BLEUART" or


Add serial control

Add serial control

--- arduino/scetch/scetch.ino
+++ arduino/scetch/scetch.ino
@@ -4,6 +4,7 @@
 const byte emPin = 33;
 const byte prrPin = 31;
 const byte buttonPin = A0;
+const byte ledPin = 13;

 const byte powerLevel = 50;

@@ -12,13 +13,16 @@
 const byte latchToEeMillis = 100;
 const byte eeToEmMillis = 100;
 const byte periodMillis = 100;
-
 const byte latchDurationMillis = 10;

-const byte ledPin = 13;
+const char enableKey = 'e';
+const char disableKey = 'd';
+const char powerKey = 'p';

 boolean laserEnabled = false;
 boolean inAfterStartState = true;
+
+

 void setup() {
   pinMode(adjPowerPin, OUTPUT);
@@ -39,10 +43,26 @@
   } else if (digitalRead(buttonPin) == LOW && laserEnabled == false) {
     inAfterStartState = false;
   }
+  checkSerial();
+}
+
+void checkSerial() {
+  static char buffer[80];
+  int len = readline(Serial.read(), buffer, 80);
+  if (len > 0) {
+    String message = buffer;
+    if (message.charAt(0) == enableKey && laserEnabled == false) {
+      enableLaser();
+      submitPower((byte)message.charAt(1));
+    } else if (message.charAt(0) == disableKey && laserEnabled == true) {
+      disableLaser();
+    } else if (message.charAt(0) == powerKey && laserEnabled == true) {
+      submitPower((byte)message.charAt(1));
+    }
+  }
 }

 void disableLaser() {
-  Serial.println("Disabling");
   digitalWrite(emPin, LOW);
   delay(periodMillis);
   digitalWrite(eePin, LOW);
@@ -51,10 +71,10 @@
   digitalWrite(prrPin, LOW);
   laserEnabled = false;
   digitalWrite(ledPin, LOW);
+  Serial.println(disableKey);
 }

 void enableLaser() {
-  Serial.println("Enabling");
   digitalWrite(prrPin, HIGH);
   submitPower(powerLevel);
   delay(periodMillis);
@@ -67,6 +87,8 @@
   digitalWrite(emPin, HIGH);
   laserEnabled = true;
   digitalWrite(ledPin, HIGH);
+  Serial.println(enableKey);
+  Serial.println((char)powerLevel);
 }

 void submitPower(byte lvl) {
@@ -74,3 +96,27 @@
     analogWrite(adjPowerPin, map(lvl, 0, 100, 0, 200));
   }
 }
+
+int readline(int readch, char *buffer, int len)
+{
+  static int pos = 0;
+  int rpos;
+
+  if (readch > 0) {
+    switch (readch) {
+      case '\n': // Ignore new-lines
+        break;
+      case '\r': // Return on CR
+        rpos = pos;
+        pos = 0;  // Reset position index ready for next time
+        return rpos;
+      default:
+        if (pos < len - 1) {
+          buffer[pos++] = readch;
+          buffer[pos] = 0;
+        }
+    }
+  }
+  // No end of line has been found, so return -1.
+  return -1;
+}


Arduino sends ID when asked

Arduino sends ID when asked

Signed-off-by: Mark Knoop <f1b5a91d4d6ad523f2610114591c007e75d15084@markknoop.com>

--- src/sketch.ino
+++ src/sketch.ino
@@ -59,11 +59,15 @@
     pinMode(stepPin, OUTPUT);
     pinMode(dirPin, OUTPUT);
     pinMode(sensorPin, INPUT_PULLUP);
+    pinMode(A0, INPUT_PULLUP);
+    pinMode(A1, INPUT_PULLUP);
+    pinMode(A2, INPUT_PULLUP);
+    pinMode(A3, INPUT_PULLUP);
     digitalWrite(dirPin, HIGH);
     Serial.begin(9600);
     findsensor(maxPulse);
     defaults();
-    Serial.write(sReady);
+    sendid();
 }

 void defaults() {
@@ -73,6 +77,18 @@
     endPitch = 36;
     dir = true;
     recentre = true;
+}
+
+void sendid() {
+    if (!digitalRead(A0)) {
+        Serial.write(sReady + 0);
+    } else if (!digitalRead(A1)) {
+        Serial.write(sReady + 1);
+    } else if (!digitalRead(A2)) {
+        Serial.write(sReady + 2);
+    } else if (!digitalRead(A3)) {
+        Serial.write(sReady + 3);
+    }
 }

 int pitchToPulse(float pitch) {
@@ -345,7 +361,7 @@
             return;
         } else if (data == rQuery) {
             findsensor(maxPulse);
-            Serial.write(sReady);
+            sendid();
             flashled();
         } else if (data == rTurn) {
             turn(halfTurns, startPitch, dir);


tonePitchFollower works!

tonePitchFollower works!

--- html/examples/02.Digital/tonePitchFollower/tonePitchFollower.ino
+++ html/examples/02.Digital/tonePitchFollower/tonePitchFollower.ino
@@ -1,16 +1,22 @@
+//  This example is Chibitronics Love to Code tested!
 /*
   Pitch follower

  Plays a pitch that changes based on a changing analog input

  circuit:
- * 8-ohm speaker on digital pin 8
- * photoresistor on analog 0 to 5V
- * 4.7K resistor on analog 0 to ground
+ * 8-ohm speaker on A3
+ pick one of:
+ * photoresistor on A1 to A2 (set to VMCU by code)
+ * 4.7K resistor on A1 to A0 (set to ground by code)
+ -OR-
+ * potentiometer with middle terminal to A1, and side terminals to A0 and A2

  created 21 Jan 2010
  modified 31 May 2012
  by Tom Igoe, with suggestion from Michael Flynn
+ modified 25 May 2016
+ by bunnie

 This example code is in the public domain.

@@ -21,12 +27,20 @@

 void setup() {
   // initialize serial communications (for debugging only):
-  Serial.begin(9600);
+  Serial.begin(115200);
+
+  pinMode(A0, OUTPUT);
+  digitalWrite(A0, LOW);   // A0 is the - reference
+
+  pinMode(A2, OUTPUT);
+  digitalWrite(A2, HIGH);  // A2 is the + voltage
+
+  pinMode(A1, INPUT);      // A1 is the sensor input
 }

 void loop() {
   // read the sensor:
-  int sensorReading = analogRead(A0);
+  int sensorReading = analogRead(A1);
   // print the sensor reading so you know its range
   Serial.println(sensorReading);
   // map the analog input range (in this case, 400 - 1000 from the photoresistor)
@@ -36,7 +50,7 @@
   int thisPitch = map(sensorReading, 400, 1000, 120, 1500);

   // play the pitch:
-  tone(9, thisPitch, 10);
+  tone(A3, thisPitch, 10);
   delay(1);        // delay in between reads for stability
 }


Delete C_CDELEM-Arduino.ino

Delete C_CDELEM-Arduino.ino

--- BMS_Francais/Examples/C_CDELEM-Arduino/C_CDELEM-Arduino.ino
+++ BMS_Francais/Examples/C_CDELEM-Arduino/C_CDELEM-Arduino.ino
@@ -1,56 +0,0 @@
-/*-------------------------------------------------------------------------------------------------------------------------------------------*
- * SE2R : C_CDELEM - Fonction de commande de booléen avec prise en compte de forçage et de défaut - Arduino                       12/06/2015 *
- *-------------------------------------------------------------------------------------------------------------------------------------------*
- *        C_CDELEM(boolean CDE, boolean DFT, boolean RES[], int CFG)                                                              12/06/2015 *
- *                CDE : Commande calculée ou donnée par l'utilisateur (peut être le résultat d'une fonction appelée plus haut)               *
- *                DFT : Défaut de l'équipement commandé. True signale un équipement en état normal. Un false signale un défaut               *
- *                RES : [00] Commande de l'équipement - forcément un tableau de taille au moins 1                                            *
- *                CFG : Commande de forçage.                                                                                *
- *                      <0 : RES maintenu à false                                                                                *
- *                      0  : RES figée dans son dernier état connu                                                                           *
- *                      1  : RES soumise à CDE et à DEF                                                                                *
- *                      2  : RES soumise seulement à DEF (comme si CDE était true en permanence)                                             *
- *                      3  : RES  maintenu à true                                                                                *
- *                      >3 : RES maintenu à false                                                                                *
- *-------------------------------------------------------------------------------------------------------------------------------------------*
- * Copyright SE2R under the APACHE Licence                                                                                *
- *-------------------------------------------------------------------------------------------------------------------------------------------*
- * Plate-formes testées : Arduino Leonardo, Arduino Uno, Industruino                                                                         *
- *-------------------------------------------------------------------------------------------------------------------------------------------*
- * 03/06/2015 : DD, SE2R : Testée et validée sur banc                                                                                *
- * 12/06/2015 : DD, SE2R : Ajout des commentaires d'appartenance à C_CDELEM                                                                  *
- *-------------------------------------------------------------------------------------------------------------------------------------------*/
-
-// Déclaration des bibliothèques nécessaires à l'exécution du programme ---------------------------------------------------------------------*
-#include <BMS.h>                         // Biblio   - SE2R - Fonctions BMS
-BMS BMS;
-
-// Déclaration des variables nécessaires à l'exécution de la fonction -----------------------------------------------------------------------*
-boolean FCO_XXXX;                        // C_CDELEM - Commande de marche depuis l'extérieur
-boolean ED2_DGL_XXXX;                    // C_CDELEM - Etat de l'information de défaut
-boolean FCC_XXXX[1];                     // C_CDELEM - Etat de la commande à transmettre à la sortie
-int VCO_XXXX;                            // C_CDELEM - Commande de forçage, ici en position auto
-void setup() {                           // Initialisation ----------------------------------------------------------------------------------*
-  pinMode(0, INPUT);                     // C_CDELEM - Affectation de la voie 00 en tant qu'entrée
-  pinMode(1, INPUT);                     // C_CDELEM - Affectation de la voie 01 en tant qu'entrée de commande
-  pinMode(7, OUTPUT);                    // C_CDELEM - Affectation de la voie 07 en tant que sortie
-  VCO_XXXX = 1;                          // C_CDELEM - Passage du forçage en position auto
-  Serial.begin(9600);                    // Port COM - Paramétrage du port série
-}
-void loop() {                            // Exécution ---------------------------------------------------------------------------------------*
-  if (digitalRead(2) == LOW) { ED2_DGL_XXXX = true; } else { ED2_DGL_XXXX = false; }  // Entrée de défaut NF (shunt = normal)
-  if (digitalRead(3) == LOW) { FCO_XXXX = true; } else { FCO_XXXX = false; }          // Entrée de demande de marche NO (shunt = demande)
-  BMS.C_CDELEM(FCO_XXXX, ED2_DGL_XXXX, FCC_XXXX, VCO_XXXX);
-  if (FCC_XXXX[0]) { digitalWrite(7, HIGH); } else { digitalWrite(7, LOW); }
-  Serial.print("Demande : ");
-  Serial.print("\t");
-  Serial.print(FCO_XXXX);
-  Serial.print("\t");
-  Serial.print("Defaut : ");
-  Serial.print("\t");
-  Serial.print(ED2_DGL_XXXX);
-  Serial.print("\t");
-  Serial.print("Commande : ");
-  Serial.print("\t");
-  Serial.println(FCC_XXXX[0]);
-}


Alpha3

Alpha3

When adding a new node number it triggers an ACK loop problem in a very
old RoomNode. Once triggered the loop continues forever until ACK's a
removed. On checking the eeprom, the node to  present then when the old
RoomNode fires again there isn't a problem anymore.

--- examples/RF12/RF12demo/RF12demo.ino
+++ examples/RF12/RF12demo/RF12demo.ino
@@ -1020,9 +1020,8 @@
         df_append((const char*) rf12_data - 2, rf12_len + 2);
 #endif
       if (RF12_WANTS_ACK && (config.nodeId & COLLECT) == 0) {
-        Serial.println(" -> ack");
         testCounter = 0;
-        if ((rf12_hdr & (RF12_HDR_MASK + RF12_HDR_DST)) == 31) {          // Special Node 31 source ?
+        if ((rf12_hdr & (RF12_HDR_MASK | RF12_HDR_DST)) == 31) {          // Special Node 31 source ?
           for (byte i = 1; i < 31; i++) {
             if (nodes[i] == 0xFF) {
               testbuf[0] = i + 0xE0;                                      // Change Node number request matched in RF12Tune3
@@ -1046,25 +1045,26 @@
             Serial.println();
           }
         }
+
+        if ((rf12_hdr & (RF12_HDR_MASK | RF12_HDR_DST)) < 31) { // Source node packets only
+          if (nodes[(rf12_hdr & RF12_HDR_MASK)] == 0xFF) {
+            byte len = 32;
+            Serial.print("New Node ");
+            Serial.println(rf12_hdr & RF12_HDR_MASK);
+            nodes[(rf12_hdr & RF12_HDR_MASK)] = 0;
+            if (rf12_len < 33)
+              len = rf12_len;
+
+              for (byte i = 0; i < len; ++i) {  // variable n
+///////////////////////////////////////////////  Problem when the line below is not commented out   //////////////////
+              eeprom_write_byte(RF12_EEPROM_ADDR + ((rf12_hdr & RF12_HDR_MASK)*32) + i, rf12_data[i]);
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+            }
+          }
+        }
+        Serial.println(" -> ack");
         rf12_sendStart(RF12_ACK_REPLY, testbuf, testCounter);
       }
-///////////////// This code can't come after the sendStart above since the buffer is no longer present /////////////////
-///////////////// How to write to eeprom without delaying sending the ACK?                             /////////////////
-Serial.println(rf12_hdr, HEX);
-    if ((rf12_hdr & (RF12_HDR_MASK | RF12_HDR_DST)) < 31) { // Source node packets only
-      if (nodes[(rf12_hdr & RF12_HDR_MASK)] == 0xFF) {
-        byte len = 32;
-        Serial.print("New Node ");
-        Serial.println(rf12_hdr & RF12_HDR_MASK);
-        nodes[(rf12_hdr & RF12_HDR_MASK)] = 0;
-        if (rf12_len < 33)
-          len = rf12_len;
-
-        for (byte i = 0; i < len; ++i) {  // variable n
-          eeprom_write_byte(RF12_EEPROM_ADDR + ((rf12_hdr & RF12_HDR_MASK)*32) + i, rf12_data[i]);
-        }
-      }
-    }
       activityLed(0);
     }
   }