Removed unnecessary return statement

Removed unnecessary return statement

--- src/iris/iris.ino
+++ src/iris/iris.ino
@@ -1,976 +1,975 @@
-#include <SPI.h>
-#include <SD.h>
-#include <TinyGPS++.h>
-#include <Adafruit_GFX.h>
-#include <Adafruit_RA8875.h>
-
-/*
- * It's desired to fire the different tasks with specific intervals.
- * Ex. Fire GPS task with 2000ms intervals and so on...
- */
-#define GPS_TASK_INTERVAL 2000
-#define SERVO_TASK_INTERVAL 50
-#define TFT_TASK_INTERVAL 1000
-
-// Servo positions (approx analog values)
-#define MAX_POSITION 4040    // Maximum position
-#define CENTER_POSITION 2020 // Center position
-#define MIN_POSITION 0	     // Minimum position
-
-// Different A/D resolutions
-#define RESOLUTION_READ 12  // Number of bits we want to use as resolution reading analog input
-#define RESOLUTION_WRITE 12 // Number of bits we want to use as resolution writing analog output
-
-// Different pins
-#define JOYSTICK_PIN A0
-#define SERVO_PIN DAC0
-#define SERVO_FEEDBACK_PIN A1
-#define MODE_SWITCH_PIN 2
-#define TFT_CS 10
-#define TFT_RESET 9
-#define SD_CS 4
-
-// Different baud rates and serial stuff
-#define BAUD_RATE 115200   // Desired baud rate for serial debug communication
-#define GPS_BAUD_RATE 9600 // Seems to be the standard for Adafruits MTK GPS's, could use 4800 also
-#define GPS_SERIAL Serial1 // DUE has 3 hardware USART so we can use one hardware serial for the GPS
-
-// Colors (RGB565)
-#define ARDUINO_BLUE 0x04B3
-#define IRIS_GRAY 0xC618
-
-// Text stuff
-#define NORMAL_LINE_SPACE 16
-#define LARGER_LINE_SPACE 32
-
-#define BUFFPIXEL 20
-
-// Different timers for the different tasks
-unsigned long timerServo = 0;
-unsigned long timerGPS = 0;
-unsigned long timerTFT = 0;
-
-// Controller(PID) parameters
-double Kp = 0.1;
-double Ki = 0.01;
-double Kd = 0.005;
-
-// It's nice to know if SD card has been initialized correctly
-boolean sdInitialized = false;
-
-// Must store last valid given servo position
-int lastValidPosition;
-
-TinyGPSPlus gps;
-Adafruit_RA8875 tft = Adafruit_RA8875(TFT_CS, TFT_RESET);
-Sd2Card sd;
-File file;
-
-void setup()
-{
-  Serial.begin(BAUD_RATE);
-  Serial.println(F("\n**************************************************"));
-  Serial.println(F("Starting Iris v0.9beta...."));
-
-  Serial.println("Beginning serial communication on: " + (String)GPS_SERIAL + " at: " + (String)GPS_BAUD_RATE + "baud...");
-  GPS_SERIAL.begin(GPS_BAUD_RATE);
-  Serial.println(F("Serial communication successfully started..."));
-
-  Serial.println("Setting A/D r/w resolutions, read: " + (String)RESOLUTION_READ + " bits, write: " + (String)RESOLUTION_WRITE + " bits...");
-  // Set A/D r/w resolutions
-  analogReadResolution(RESOLUTION_READ);
-  analogWriteResolution(RESOLUTION_WRITE);
-  Serial.println(F("Resolutions successfully set..."));
-
-  Serial.println(F("Setting pins and their directions..."));
-  // Setting pins and directions
-  pinMode(MODE_SWITCH_PIN, INPUT);
-  Serial.println(F("Pins and directions successfully set..."));
-
-  Serial.println(F("Initializing TFT with resolution 800x480..."));
-  initTFT();
-  Serial.println(F("TFT successfully initialized..."));
-
-  Serial.println(F("Initializing SD card..."));
-  if (!SD.begin(SD_CS))
-  {
-    Serial.println(F("Failed to initialize SD card!"));
-  }
-  else
-  {
-    sdInitialized = true;
-    Serial.println(F("SD card successfully initialized..."));
-  }
-
-  Serial.println(F("Setting other parameters..."));
-  // Set las valid position to center
-  lastValidPosition = CENTER_POSITION;
-  Serial.println(F("Parameters successfully set..."));
-
-  Serial.println(F("Iris successfully started, happy autopiloting ;-)"));
-  Serial.println(F("**************************************************\n"));
-
-  // Now other stuff that's supposed to run only once executed
-  showSplash();
-  //drawText();
-  drawGui();
-}
-
-void loop()
-{
-  resetTimersIfNeeded();
-
-  // GPS task...
-  if (millis() - timerGPS >= GPS_TASK_INTERVAL)
-  {
-    timerGPS = millis();
-    taskGPS();
-  }
-
-  // Servo task...
-  if (millis() - timerServo >= SERVO_TASK_INTERVAL)
-  {
-    timerServo = millis();
-    taskServo();
-  }
-
-  // TFT task
-  if (millis() - timerTFT >= TFT_TASK_INTERVAL)
-  {
-    timerTFT = millis();
-    taskTFT();
-  }
-
-  // It's desired to have as fresh data as possible in our gps object
-  refreshGPSData();
-}
-
-/*************************************************
- *             The different tasks               *
- *************************************************/
-
-/*
- * Task responsible for all GPS handling,
- * except refreshing of GPS data.
- */
-void taskGPS()
-{
-  printGPSData();
-}
-
-/*
- * Task responsible for all interactions with
- * the systems servo, or more correctly, linear actuator.
- */
-void taskServo()
-{
-  // Ensure that nav mode is updated in gui
-  drawNavMode();
-
-  if (isManualMode())
-  {
-    moveServo(getJoystickValue());
-  }
-}
-
-void taskTFT()
-{
-  drawNavMode();
-  drawNavSource();
-  drawGPSData();
-  drawCompassData();
-  drawControllerData();
-}
-
-/*************************************************
- *               GPS functionality               *
- *************************************************/
-
-/*
- * To refresh GPS data.
- */
-void refreshGPSData()
-{
-  while (GPS_SERIAL.available() > 0)
-    gps.encode(GPS_SERIAL.read());
-}
-
-/*
- * To print all GPS data thats interesting for this
- * application to the serial. Mostly this function is
- * used for debugging.
- */
-void printGPSData()
-{
-  Serial.print(F("\nTime: ")); Serial.println(getGPSTime());
-  Serial.print(F("Date: ")); Serial.println(getGPSDate());
-  Serial.print(F("Location: ")); Serial.println(getGPSLocation(true));
-  Serial.print(F("Speed: ")); Serial.println(getGPSSpeed());
-  Serial.print(F("Course: ")); Serial.println(getGPSCourse());
-  Serial.print(F("Altitude: ")); Serial.println(getGPSAltitude());
-  Serial.print(F("Satellites: ")); Serial.println(getGPSSatellites());
-}
-
-/*
- * To get current time from GPS as a String in
- * format hh:mm:ss, the timezone is UTC.
- */
-String getGPSTime()
-{
-  String time;
-  // Check that the current time is valid
-  if (gps.time.isValid())
-  {
-    // Resolving hours...
-    if (gps.time.hour() < 10)
-    {
-      time += "0";
-    }
-    time += (String)gps.time.hour() + ":";
-
-    // ...minutes...
-    if (gps.time.minute() < 10)
-    {
-      time += "0";
-    }
-    time += (String)gps.time.minute() + ":";
-
-    // ...and seconds
-    if (gps.time.second() < 10)
-    {
-      time += "0";
-    }
-    time += (String)gps.time.second();
-
-    return time;
-  }
-
-  return "-";
-}
-
-/*
- * To get current date from GPS as a String in
- * format dd/mm/yyyy.
- */
-String getGPSDate()
-{
-  if (gps.date.isValid())
-  {
-    return (String)gps.date.day() + "/" + (String)gps.date.month() + "/" + (String)gps.date.year();
-  }
-  return "-";
-}
-
-/*
- * To get current location from GPS in Decimal Degree format.
- * Cardinal is also added to the string depending on argument passed in is true.
- * Ex. 60.1574572N,19.94766E
- */
-String getGPSLocation(boolean showCardinals)
-{
-  return getGPSLatitude(showCardinals) + "," + getGPSLongitude(showCardinals);
-}
-
-/*
- * To get latitude in Decimal Degree format as a String, with a
- * precision of six decimals. Cardinal is also added
- * to the string depending on argument passed in is true.
- * Ex. 60.1574572N
- */
-String getGPSLatitude(boolean showCardinal)
-{
-  if (gps.location.isValid())
-  {
-    char latitude [10];
-    ftoa(latitude, gps.location.lat(), 6);
-    if (showCardinal)
-    {
-      return (String)latitude + "N";
-    }
-    return latitude;
-  }
-  return "-";
-}
-
-/*
- * To get longitude in Decimal Degree format as a String, with a
- * precision of six decimals. Cardinal is also added
- * to the string depending on argument passed in is true.
- * Ex. 19.94766E
- */
-String getGPSLongitude(boolean showCardinal)
-{
-  String longitude;
-  if (gps.location.isValid())
-  {
-    char longitude [10];
-    ftoa(longitude, gps.location.lng(), 6);
-    if (showCardinal)
-    {
-      return (String)longitude + "E";
-    }
-    return longitude;
-  }
-  return "-";
-}
-
-/*
- * To get speed from gps in knots as a String.
- * Unit will be added to the String.
- * Ex. 5.6 knots
- */
-String getGPSSpeed()
-{
-  if (gps.speed.isValid())
-  {
-    return (String)gps.speed.knots() + " knots";
-  }
-  return "-";
-}
-
-/*
- * To get current course from GPS as a String.
- * Course is given in degrees. Unit will be added to the String.
- * Ex. 231.34deg
- */
-String getGPSCourse()
-{
-  if (gps.speed.isValid())
-  {
-    return (String)gps.course.deg() + " deg";
-  }
-  return "-";
-}
-
-/*
- * To get altitude in meters from GPS as a String.
- * Unit will be added to the String.
- * Ex. 50.2m
- */
-String getGPSAltitude()
-{
-  if (gps.speed.isValid())
-  {
-    return (String)gps.altitude.meters() + " m";
-  }
-  return "-";
-}
-
-/*
- * To get the number of satellites the GPS
- * has contact with as a String.
- */
-String getGPSSatellites()
-{
-  if (gps.speed.isValid())
-  {
-    return (String)gps.satellites.value();
-  }
-  return "-";
-}
-
-/*
- * To figure out if the GPS got enough satellites
- * in order to establish a good position, a
- * minimum of 3 satellites are needed for this.
- * True will be returned if GPS got 3 or more satellites
- * else false is returned.
- */
-boolean isGPSValidForNavigation()
-{
-  if (gps.speed.isValid())
-  {
-    if (gps.satellites.value() > 2)
-    {
-      return true;
-    }
-    return false;
-  }
-  return false;
-}
-
-/*************************************************
- *       Functionalities for manual input        *
- *************************************************/
-
-/*
- * To get the A/D value from JOYSTICK_PIN,
- * in other words the joysticks position.
- * This value will only be returned if the
- * system is in manual mode, else -1 will
- * be returned
- */
-int getJoystickValue()
-{
-  if (isManualMode() == 1) {
-    return analogRead(JOYSTICK_PIN);
-  }
-  return -1;
-}
-
-/*
- * To figure out if the system is in manual
- * operation mode. If so true will be returned
- * else false.
- */
-boolean isManualMode()
-{
-  return digitalRead(MODE_SWITCH_PIN) == HIGH ? true : false;
-}
-
-/*************************************************
- *              Servo functionality              *
- *************************************************/
-
-/*
- * Moves servo to given position, if it's valid.
- */
-void moveServo(int position)
-{
-  if (MIN_POSITION <= position && position <= MAX_POSITION)
-  {
-    Serial.println("Moving servo to position: " + (String)position);
-    lastValidPosition = position;
-    analogWrite(SERVO_PIN, position);
-  }
-  else
-  {
-    Serial.println("Wanted servo position is invalid, moving servo to last valid position: " + (String)lastValidPosition);
-    analogWrite(SERVO_PIN, lastValidPosition);
-  }
-}
-
-/*
- * Moves servo to it's maximum position.
- */
-void moveServoToMax()
-{
-  Serial.println("Moving servo to max position...");
-  moveServo(MAX_POSITION);
-}
-
-/*
- * Moves servo to it's center position.
- */
-void moveServoToCenter()
-{
-  Serial.println("Moving servo to center position...");
-  moveServo(CENTER_POSITION);
-}
-
-/*
- * Moves servo to it's minimum position.
- */
-void moveServoToMin()
-{
-  Serial.println("Moving servo to min position...");
-  moveServo(MIN_POSITION);
-}
-
-/*
- * To geet feedback from servo.
- */
-int getServoFeedback()
-{
-  int feedback = analogRead(SERVO_FEEDBACK_PIN);
-  Serial.println("Feedback: " + (String)feedback);
-  return feedback;
-}
-
-/*************************************************
- *              TFT functionality              *
- *************************************************/
-
-/*
- * To initialize the tft screeen. The screen will
- * be initialized at a resolution of 800x480. If
- * the screen cannot be initialzed the system will halt.
- */
-void initTFT()
-{
-  // Initialise the display using 'RA8875_800x480'
-  if (!tft.begin(RA8875_800x480))
-  {
-    Serial.println(F("TFT Not Found!"));
-    while (1);
-  }
-  else
-  {
-    Serial.print(F("Successfully communicating with screen over SPI with CS pin: ")); Serial.println(TFT_CS);
-    Serial.print(F("Using screen resolution: ")); Serial.println(RA8875_800x480);
-  }
-  // Enable tft
-  tft.displayOn(true);
-  tft.GPIOX(true); // Enable TFT - display enable tied to GPIOX
-
-  Serial.println("Turning on screen...");
-
-  // Config pwm, mainly backlight is controlled with pwm
-  tft.PWM1config(true, RA8875_PWM_CLK_DIV1024); // PWM output for backlight
-  tft.PWM1out(0);
-}
-
-/*
- * To display a splash screen upon system boot.
- * The splash screen will be dimmed up from black, then
- * showed for about 3 seconds to be dimmed down to black
- * again. If SD card couldn't be found or some error
- * occurred with that, no splash screen will be shown.
- */
-void showSplash()
-{
-  // Ensure screen is "black" using PWM
-  tft.PWM1out(0);
-
-  // If SD card has been initialized show splash
-  if (sdInitialized)
-  {
-    Serial.println(F("SD card initialized, setting background color and loading splash images..."));
-    // Set correct background color
-    tft.fillScreen(ARDUINO_BLUE);
-
-    // Load bmp's
-    bmpDraw("iris.bmp", 234, 40);
-    bmpDraw("desc.bmp", 201, 169);
-
-    Serial.println(F("Images loaded, dimming in and out screen..."));
-
-    // We want to fade up the screen using pwm, nice
-    fadeInTFT(1, 10);
-
-    // Show Splash for 3 seconds
-    delay(3000);
-
-    // And now we fade it down
-    fadeOutTFT(1, 10);
-  }
-  Serial.println(F("Preparing for data rendering, setting background color to black..."));
-
-  // This point the tft should be "black" and empty, in other words prepared for the next step
-  tft.fillScreen(RA8875_BLACK);
-}
-
-/*
- * To draw the main and mostrly static user interface.
- * This is only needed to be done once, after that it should
- * remain the same.
- */
-void drawGui()
-{
-  tft.graphicsMode();
-  drawDoubleVLine(200, 5, 200, 475, ARDUINO_BLUE);
-  drawDoubleHLine(5, 168, 195, 168, ARDUINO_BLUE);
-  drawDoubleHLine(5, 277, 195, 277, ARDUINO_BLUE);
-
-  tft.textMode();
-  tft.textTransparent(RA8875_WHITE);
-  tft.textEnlarge(1);
-  tft.textSetCursor(206, 0);
-  tft.textWrite("Navigation");
-
-  tft.textSetCursor(5, tft.height() - NORMAL_LINE_SPACE - 3);
-  tft.textEnlarge(0);
-  tft.textWrite("Iris - v0.8beta");
-
-  tft.PWM1out(255);
-}
-
-void drawNavMode()
-{
-  tft.textMode();
-  tft.textColor(RA8875_WHITE, RA8875_BLACK);
-  tft.textSetCursor(206, LARGER_LINE_SPACE);
-  tft.textEnlarge(0);
-
-  if (isManualMode())
-  {
-    tft.textWrite("Mode: Manual");
-  }
-  else
-  {
-    tft.textWrite("Mode: Auto  ");
-  }
-}
-
-void drawNavSource()
-{
-  tft.textMode();
-  tft.textColor(RA8875_WHITE, RA8875_BLACK);
-  tft.textSetCursor(400, LARGER_LINE_SPACE);
-  tft.textEnlarge(0);
-
-  if (isGPSValidForNavigation())
-  {
-    tft.textWrite("Source in use: GPS    ");
-  }
-  else
-  {
-    tft.textWrite("Source in use: Compass");
-  }
-}
-
-void drawGPSData()
-{
-  tft.textMode();
-  tft.textColor(RA8875_WHITE, RA8875_BLACK);
-  tft.textSetCursor(5, 0);
-  tft.textEnlarge(1);
-
-  tft.textWrite("GPS Data");
-
-  tft.textEnlarge(0);
-  tft.textSetCursor(5, LARGER_LINE_SPACE);
-  tft.textWrite(("Time(UTC):  " + getGPSTime()).c_str());
-  tft.textSetCursor(5, LARGER_LINE_SPACE + NORMAL_LINE_SPACE);
-  tft.textWrite(("Date:       " + getGPSDate()).c_str());
-  tft.textSetCursor(5, LARGER_LINE_SPACE + NORMAL_LINE_SPACE * 2);
-  tft.textWrite("Location(lat,lon):");
-  tft.textSetCursor(5, LARGER_LINE_SPACE + NORMAL_LINE_SPACE * 3);
-  tft.textWrite(getGPSLocation(true).c_str());
-  tft.textSetCursor(5, LARGER_LINE_SPACE + NORMAL_LINE_SPACE * 4);
-  tft.textWrite(("Speed:      " + getGPSSpeed()).c_str());
-  tft.textSetCursor(5, LARGER_LINE_SPACE + NORMAL_LINE_SPACE * 5);
-  tft.textWrite(("Course:     " + getGPSCourse()).c_str());
-  tft.textSetCursor(5, LARGER_LINE_SPACE + NORMAL_LINE_SPACE * 6);
-  tft.textWrite(("Alitude:    " + getGPSAltitude()).c_str());
-  tft.textSetCursor(5, LARGER_LINE_SPACE + NORMAL_LINE_SPACE * 7);
-  tft.textWrite(("Satellites: " + getGPSSatellites() + "  ").c_str());
-}
-
-void drawCompassData()
-{
-  tft.textMode();
-  tft.textColor(RA8875_WHITE, RA8875_BLACK);
-  tft.textSetCursor(5, 171);
-  tft.textEnlarge(1);
-
-  tft.textWrite("Compass Data");
-  tft.textEnlarge(0);
-  tft.textSetCursor(5, LARGER_LINE_SPACE + 171);
-  tft.textWrite("Course: xxx.xx deg");
-  tft.textSetCursor(5, LARGER_LINE_SPACE + NORMAL_LINE_SPACE + 171);
-  tft.textWrite("X:      xxx.xx");
-  tft.textSetCursor(5, LARGER_LINE_SPACE + NORMAL_LINE_SPACE * 2 + 171);
-  tft.textWrite("Y:      xxx.xx");
-  tft.textSetCursor(5, LARGER_LINE_SPACE + NORMAL_LINE_SPACE * 3 + 171);
-  tft.textWrite("Z:      xxx.xx");
-}
-
-void drawControllerData()
-{
-  // Buffers to store the "String" version of the PID values
-  char KpStr [5];
-  char KiStr [5];
-  char KdStr [5];
-
-  // Casting the doubles to "strings" without loosing any precision
-  dtostrf(Kp, 2, 3, KpStr);
-  dtostrf(Ki, 2, 3, KiStr);
-  dtostrf(Kd, 2, 3, KdStr);
-
-  tft.textMode();
-  tft.textColor(RA8875_WHITE, RA8875_BLACK);
-  tft.textSetCursor(5, 280);
-  tft.textEnlarge(1);
-
-  tft.textWrite("Controller");
-  tft.textEnlarge(0);
-  tft.textSetCursor(5, LARGER_LINE_SPACE + 280);
-  tft.textWrite(("P = " + (String)KpStr).c_str());
-  tft.textSetCursor(5, LARGER_LINE_SPACE + NORMAL_LINE_SPACE + 280);
-  tft.textWrite(("I = " + (String)KiStr).c_str());
-  tft.textSetCursor(5, LARGER_LINE_SPACE + NORMAL_LINE_SPACE * 2 + 280);
-  tft.textWrite(("D = " + (String)KdStr).c_str());
-}
-
-void drawText()
-{
-  tft.PWM1out(255);
-  tft.textMode();
-
-  tft.textTransparent(RA8875_WHITE);
-  tft.textSetCursor(5, 0);
-  tft.textEnlarge(0);
-  tft.textWrite("Våöäåvdfkvnoavkpav*!--<><</)0987, consectetur adipisicing elit..."); // Standard
-  tft.textSetCursor(5, 17);
-  tft.fontArial();
-  tft.textWrite("Lorem ipsum dolor sit amet, consectetur adipisicing elit...");
-  tft.textSetCursor(5, 34);
-  tft.fontRoman();
-  tft.textWrite("Lorem ipsum dolor sit amet, consectetur adipisicing elit...");
-  tft.textSetCursor(0, 51);
-  tft.fontStandard();
-  tft.textEnlarge(1);
-  tft.textWrite("Lorem ipsum dolor sit amet, consectetur adipisicing elit..."); // Standard
-  tft.textSetCursor(0, 85);
-  tft.textEnlarge(2);
-  tft.textWrite("Lorem ipsum dolor sit amet, consectetur adipisicing elit..."); // Standard
-  tft.textSetCursor(0, 130);
-  tft.textEnlarge(3);
-  tft.textWrite("Lorem ipsum dolor sit amet, consectetur adipisicing elit..."); // Standard
-}
-
-/*
- * Turns TFT black with pwm and then fades it in again with
- * given steps as increment and delays each increment with
- * given delay.
- */
-void fadeInTFT(int steps, int del)
-{
-  // Ensure screen is "black" using PWM
-  tft.PWM1out(0);
-
-  for (int i = 1; i < 256; i += steps)
-  {
-    tft.PWM1out(i);
-    delay(del);
-  }
-}
-
-/*
- * Turns TFT fully on with pwm and then fades it out again with
- * given steps as increment and delays each increment with
- * given delay.
- */
-void fadeOutTFT(int steps, int del)
-{
-  // Ensure screen is fully on using PWM
-  tft.PWM1out(255);
-
-  for (int i = 255; i > -1; i -= steps)
-  {
-    tft.PWM1out(i);
-    delay(del);
-  }
-}
-
-/*
- * Convenience function that draws two lines side by side
- * by drawing two lines. One at the given x values and the
- * other at given x value + 1.
- */
-void drawDoubleVLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color)
-{
-  tft.drawLine(x0, y0, x1, y1, color);
-  tft.drawLine(x0 + 1, y0, x1 + 1, y1, color);
-}
-
-/*
- * Convenience function that draws two lines side by side
- * by drawing two lines. One at the given y values and the
- * other at given y value + 1.
- */
-void drawDoubleHLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color)
-{
-  tft.drawLine(x0, y0, x1, y1, color);
-  tft.drawLine(x0, y0 + 1, x1, y1 + 1, color);
-}
-
-/*************************************************
- *       Utilities and other functionality       *
- *************************************************/
-
-/*
- * To reset the different timers used by
- * the different tasks. Reset is only needed
- * the timers has wrapped around.
- */
-void resetTimersIfNeeded()
-{
-  // If our timers wrap around we reset them
-  if (timerGPS > millis())
-  {
-    timerGPS = millis();
-  }
-  if (timerServo > millis())
-  {
-    timerServo = millis();
-  }
-  if (timerTFT > millis())
-  {
-    timerTFT = millis();
-  }
-}
-
-/*
- * Homebrew function to convert a given double to a char
- * array with given precision.
- * Snatched from the Arduino forum:
- *    http://forum.arduino.cc/index.php/topic,44262.0.html
- */
-char *ftoa(char *a, double f, int precision)
-{
-  long p[] = {0, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000};
-  char *ret = a;
-  long l = (long)f;
-
-  itoa(l, a, 10);
-  while (*a != '\0')
-  {
-    a++;
-  }
-
-  *a++ = '.';
-  long d = abs((long)((f - l) * p[precision]));
-  itoa(d, a, 10);
-
-  return ret;
-}
-
-/*
- * Function dtostrf is only available on avr. This little function
- * emulates that one so it could be used on arm.
- */
-char *dtostrf(double val, signed char width, unsigned char prec, char *sout)
-{
-  char fmt[20];
-  sprintf(fmt, "%%%d.%df", width, prec);
-  sprintf(sout, fmt, val);
-  return sout;
-}
-
-/*
- * To get bmp file from SD card named as given filename and then draw it
- * on TFT at given points x and y. If bmp file couldn't be found on the
- * SD card function will return without any further actions. The same happens
- * opened bmp file doesn't have a bit depth of 24bit, also if given
- * x and y points are larger than TFT's dimension this function will return.
- * Function snatched from Adafruits "spitftbitmap" example the Adafruit_ILI9340 library.
- */
-void bmpDraw(char *filename, uint8_t x, uint8_t y) {
-  File     bmpFile;
-  int      bmpWidth, bmpHeight;   // W+H in pixels
-  uint8_t  bmpDepth;              // Bit depth (currently must be 24)
-  uint32_t bmpImageoffset;        // Start of image data in file
-  uint32_t rowSize;               // Not always = bmpWidth; may have padding
-  uint8_t  sdbuffer[3 * BUFFPIXEL]; // pixel buffer (R+G+B per pixel)
-  uint8_t  buffidx = sizeof(sdbuffer); // Current position in sdbuffer
-  boolean  goodBmp = false;       // Set to true on valid header parse
-  boolean  flip    = true;        // BMP is stored bottom-to-top
-  int      w, h, row, col;
-  uint8_t  r, g, b;
-  uint32_t pos = 0, startTime = millis();
-
-  if ((x >= tft.width()) || (y >= tft.height())) return;
-
-  // Open requested file on SD card
-  if ((bmpFile = SD.open(filename)) == NULL) {
-    Serial.print(F("File '")); Serial.print(filename); Serial.println(F("' couldn't be found"));
-    return;
-  }
-
-  // Parse BMP header
-  if (read16(bmpFile) == 0x4D42) { // BMP signature
-    Serial.print(F("File size: ")); Serial.println(read32(bmpFile));
-    (void)read32(bmpFile); // Read & ignore creator bytes
-    bmpImageoffset = read32(bmpFile); // Start of image data
-    Serial.print(F("Image Offset: ")); Serial.println(bmpImageoffset, DEC);
-    // Read DIB header
-    Serial.print(F("Header size: ")); Serial.println(read32(bmpFile));
-    bmpWidth  = read32(bmpFile);
-    bmpHeight = read32(bmpFile);
-    if (read16(bmpFile) == 1) { // # planes -- must be '1'
-      bmpDepth = read16(bmpFile); // bits per pixel
-      Serial.print(F("Bit Depth: ")); Serial.println(bmpDepth);
-      if ((bmpDepth == 24) && (read32(bmpFile) == 0)) { // 0 = uncompressed
-        goodBmp = true; // Supported BMP format -- proceed!
-        Serial.print(F("Image size: ")); Serial.print(bmpWidth); Serial.print(F("x")); Serial.println(bmpHeight);
-
-        // BMP rows are padded (if needed) to 4-byte boundary
-        rowSize = (bmpWidth * 3 + 3) & ~3;
-
-        // If bmpHeight is negative, image is in top-down order.
-        // This is not canon but has been observed in the wild.
-        if (bmpHeight < 0) {
-          bmpHeight = -bmpHeight;
-          flip      = false;
-        }
-
-        // Crop area to be loaded
-        w = bmpWidth;
-        h = bmpHeight;
-        if ((x + w - 1) >= tft.width())
-        {
-          w = tft.width()  - x;
-        }
-        if ((y + h - 1) >= tft.height())
-        {
-          h = tft.height() - y;
-        }
-
-        for (row = 0; row < h; row++) { // For each scanline...
-          // Seek to start of scan line.  It might seem labor-
-          // intensive to be doing this on every line, but this
-          // method covers a lot of gritty details like cropping
-          // and scanline padding.  Also, the seek only takes
-          // place if the file position actually needs to change
-          // (avoids a lot of cluster math in SD library).
-          if (flip) // Bitmap is stored bottom-to-top order (normal BMP)
-            pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize;
-          else     // Bitmap is stored top-to-bottom
-            pos = bmpImageoffset + row * rowSize;
-          if (bmpFile.position() != pos) { // Need seek?
-            bmpFile.seek(pos);
-            buffidx = sizeof(sdbuffer); // Force buffer reload
-          }
-
-          for (col = 0; col < w; col++) { // For each pixel...
-            // Time to read more pixel data?
-            if (buffidx >= sizeof(sdbuffer)) { // Indeed
-              bmpFile.read(sdbuffer, sizeof(sdbuffer));
-              buffidx = 0; // Set index to beginning
-            }
-
-            // Convert pixel from BMP to TFT format, push to display
-            b = sdbuffer[buffidx++];
-            g = sdbuffer[buffidx++];
-            r = sdbuffer[buffidx++];
-            tft.drawPixel(x + col, y + row, color565(r, g, b));
-          }
-        }
-      }
-    }
-  }
-
-  bmpFile.close();
-  if (!goodBmp)
-  {
-    Serial.println(F("BMP format not recognized."));
-  }
-}
-
-/*
- * To read out 16 bit from given file.
- * Function snatched from Adafruits "spitftbitmap" example
- * from the Adafruit_ILI9340 library.
- */
-uint16_t read16(File & f)
-{
-  uint16_t result;
-  ((uint8_t *)&result)[0] = f.read(); // LSB
-  ((uint8_t *)&result)[1] = f.read(); // MSB
-  return result;
-}
-
-/*
- * To read out 32 bit from given file.
- * Function snatched from Adafruits "spitftbitmap" example
- * from the Adafruit_ILI9340 library.
- */
-uint32_t read32(File & f)
-{
-  uint32_t result;
-  ((uint8_t *)&result)[0] = f.read(); // LSB
-  ((uint8_t *)&result)[1] = f.read();
-  ((uint8_t *)&result)[2] = f.read();
-  ((uint8_t *)&result)[3] = f.read(); // MSB
-  return result;
-}
-
-/*
- * To get 16 bit packed color from given 8 bit R,G,B values.
- * Function snatched from the Adafruit_ILI9340 library.
- */
-uint16_t color565(uint8_t r, uint8_t g, uint8_t b) {
-  return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);
-}
+#include <SPI.h>
+#include <SD.h>
+#include <TinyGPS++.h>
+#include <Adafruit_GFX.h>
+#include <Adafruit_RA8875.h>
+
+/*
+ * It's desired to fire the different tasks with specific intervals.
+ * Ex. Fire GPS task with 2000ms intervals and so on...
+ */
+#define GPS_TASK_INTERVAL 2000
+#define SERVO_TASK_INTERVAL 50
+#define TFT_TASK_INTERVAL 1000
+
+// Servo positions (approx analog values)
+#define MAX_POSITION 4040    // Maximum position
+#define CENTER_POSITION 2020 // Center position
+#define MIN_POSITION 0	     // Minimum position
+
+// Different A/D resolutions
+#define RESOLUTION_READ 12  // Number of bits we want to use as resolution reading analog input
+#define RESOLUTION_WRITE 12 // Number of bits we want to use as resolution writing analog output
+
+// Different pins
+#define JOYSTICK_PIN A0
+#define SERVO_PIN DAC0
+#define SERVO_FEEDBACK_PIN A1
+#define MODE_SWITCH_PIN 2
+#define TFT_CS 10
+#define TFT_RESET 9
+#define SD_CS 4
+
+// Different baud rates and serial stuff
+#define BAUD_RATE 115200   // Desired baud rate for serial debug communication
+#define GPS_BAUD_RATE 9600 // Seems to be the standard for Adafruits MTK GPS's, could use 4800 also
+#define GPS_SERIAL Serial1 // DUE has 3 hardware USART so we can use one hardware serial for the GPS
+
+// Colors (RGB565)
+#define ARDUINO_BLUE 0x04B3
+#define IRIS_GRAY 0xC618
+
+// Text stuff
+#define NORMAL_LINE_SPACE 16
+#define LARGER_LINE_SPACE 32
+
+#define BUFFPIXEL 20
+
+// Different timers for the different tasks
+unsigned long timerServo = 0;
+unsigned long timerGPS = 0;
+unsigned long timerTFT = 0;
+
+// Controller(PID) parameters
+double Kp = 0.1;
+double Ki = 0.01;
+double Kd = 0.005;
+
+// It's nice to know if SD card has been initialized correctly
+boolean sdInitialized = false;
+
+// Must store last valid given servo position
+int lastValidPosition;
+
+TinyGPSPlus gps;
+Adafruit_RA8875 tft = Adafruit_RA8875(TFT_CS, TFT_RESET);
+Sd2Card sd;
+File file;
+
+void setup()
+{
+  Serial.begin(BAUD_RATE);
+  Serial.println(F("\n**************************************************"));
+  Serial.println(F("Starting Iris v0.9beta...."));
+
+  Serial.println("Beginning serial communication on: " + (String)GPS_SERIAL + " at: " + (String)GPS_BAUD_RATE + "baud...");
+  GPS_SERIAL.begin(GPS_BAUD_RATE);
+  Serial.println(F("Serial communication successfully started..."));
+
+  Serial.println("Setting A/D r/w resolutions, read: " + (String)RESOLUTION_READ + " bits, write: " + (String)RESOLUTION_WRITE + " bits...");
+  // Set A/D r/w resolutions
+  analogReadResolution(RESOLUTION_READ);
+  analogWriteResolution(RESOLUTION_WRITE);
+  Serial.println(F("Resolutions successfully set..."));
+
+  Serial.println(F("Setting pins and their directions..."));
+  // Setting pins and directions
+  pinMode(MODE_SWITCH_PIN, INPUT);
+  Serial.println(F("Pins and directions successfully set..."));
+
+  Serial.println(F("Initializing TFT with resolution 800x480..."));
+  initTFT();
+  Serial.println(F("TFT successfully initialized..."));
+
+  Serial.println(F("Initializing SD card..."));
+  if (!SD.begin(SD_CS))
+  {
+    Serial.println(F("Failed to initialize SD card!"));
+  }
+  else
+  {
+    sdInitialized = true;
+    Serial.println(F("SD card successfully initialized..."));
+  }
+
+  Serial.println(F("Setting other parameters..."));
+  // Set las valid position to center
+  lastValidPosition = CENTER_POSITION;
+  Serial.println(F("Parameters successfully set..."));
+
+  Serial.println(F("Iris successfully started, happy autopiloting ;-)"));
+  Serial.println(F("**************************************************\n"));
+
+  // Now other stuff that's supposed to run only once executed
+  showSplash();
+  //drawText();
+  drawGui();
+}
+
+void loop()
+{
+  resetTimersIfNeeded();
+
+  // GPS task...
+  if (millis() - timerGPS >= GPS_TASK_INTERVAL)
+  {
+    timerGPS = millis();
+    taskGPS();
+  }
+
+  // Servo task...
+  if (millis() - timerServo >= SERVO_TASK_INTERVAL)
+  {
+    timerServo = millis();
+    taskServo();
+  }
+
+  // TFT task
+  if (millis() - timerTFT >= TFT_TASK_INTERVAL)
+  {
+    timerTFT = millis();
+    taskTFT();
+  }
+
+  // It's desired to have as fresh data as possible in our gps object
+  refreshGPSData();
+}
+
+/*************************************************
+ *             The different tasks               *
+ *************************************************/
+
+/*
+ * Task responsible for all GPS handling,
+ * except refreshing of GPS data.
+ */
+void taskGPS()
+{
+  printGPSData();
+}
+
+/*
+ * Task responsible for all interactions with
+ * the systems servo, or more correctly, linear actuator.
+ */
+void taskServo()
+{
+  // Ensure that nav mode is updated in gui
+  drawNavMode();
+
+  if (isManualMode())
+  {
+    moveServo(getJoystickValue());
+  }
+}
+
+void taskTFT()
+{
+  drawNavMode();
+  drawNavSource();
+  drawGPSData();
+  drawCompassData();
+  drawControllerData();
+}
+
+/*************************************************
+ *               GPS functionality               *
+ *************************************************/
+
+/*
+ * To refresh GPS data.
+ */
+void refreshGPSData()
+{
+  while (GPS_SERIAL.available() > 0)
+    gps.encode(GPS_SERIAL.read());
+}
+
+/*
+ * To print all GPS data thats interesting for this
+ * application to the serial. Mostly this function is
+ * used for debugging.
+ */
+void printGPSData()
+{
+  Serial.print(F("\nTime: ")); Serial.println(getGPSTime());
+  Serial.print(F("Date: ")); Serial.println(getGPSDate());
+  Serial.print(F("Location: ")); Serial.println(getGPSLocation(true));
+  Serial.print(F("Speed: ")); Serial.println(getGPSSpeed());
+  Serial.print(F("Course: ")); Serial.println(getGPSCourse());
+  Serial.print(F("Altitude: ")); Serial.println(getGPSAltitude());
+  Serial.print(F("Satellites: ")); Serial.println(getGPSSatellites());
+}
+
+/*
+ * To get current time from GPS as a String in
+ * format hh:mm:ss, the timezone is UTC.
+ */
+String getGPSTime()
+{
+  String time;
+  // Check that the current time is valid
+  if (gps.time.isValid())
+  {
+    // Resolving hours...
+    if (gps.time.hour() < 10)
+    {
+      time += "0";
+    }
+    time += (String)gps.time.hour() + ":";
+
+    // ...minutes...
+    if (gps.time.minute() < 10)
+    {
+      time += "0";
+    }
+    time += (String)gps.time.minute() + ":";
+
+    // ...and seconds
+    if (gps.time.second() < 10)
+    {
+      time += "0";
+    }
+    time += (String)gps.time.second();
+
+    return time;
+  }
+
+  return "-";
+}
+
+/*
+ * To get current date from GPS as a String in
+ * format dd/mm/yyyy.
+ */
+String getGPSDate()
+{
+  if (gps.date.isValid())
+  {
+    return (String)gps.date.day() + "/" + (String)gps.date.month() + "/" + (String)gps.date.year();
+  }
+  return "-";
+}
+
+/*
+ * To get current location from GPS in Decimal Degree format.
+ * Cardinal is also added to the string depending on argument passed in is true.
+ * Ex. 60.1574572N,19.94766E
+ */
+String getGPSLocation(boolean showCardinals)
+{
+  return getGPSLatitude(showCardinals) + "," + getGPSLongitude(showCardinals);
+}
+
+/*
+ * To get latitude in Decimal Degree format as a String, with a
+ * precision of six decimals. Cardinal is also added
+ * to the string depending on argument passed in is true.
+ * Ex. 60.1574572N
+ */
+String getGPSLatitude(boolean showCardinal)
+{
+  if (gps.location.isValid())
+  {
+    char latitude [10];
+    ftoa(latitude, gps.location.lat(), 6);
+    if (showCardinal)
+    {
+      return (String)latitude + "N";
+    }
+    return latitude;
+  }
+  return "-";
+}
+
+/*
+ * To get longitude in Decimal Degree format as a String, with a
+ * precision of six decimals. Cardinal is also added
+ * to the string depending on argument passed in is true.
+ * Ex. 19.94766E
+ */
+String getGPSLongitude(boolean showCardinal)
+{
+  String longitude;
+  if (gps.location.isValid())
+  {
+    char longitude [10];
+    ftoa(longitude, gps.location.lng(), 6);
+    if (showCardinal)
+    {
+      return (String)longitude + "E";
+    }
+    return longitude;
+  }
+  return "-";
+}
+
+/*
+ * To get speed from gps in knots as a String.
+ * Unit will be added to the String.
+ * Ex. 5.6 knots
+ */
+String getGPSSpeed()
+{
+  if (gps.speed.isValid())
+  {
+    return (String)gps.speed.knots() + " knots";
+  }
+  return "-";
+}
+
+/*
+ * To get current course from GPS as a String.
+ * Course is given in degrees. Unit will be added to the String.
+ * Ex. 231.34deg
+ */
+String getGPSCourse()
+{
+  if (gps.speed.isValid())
+  {
+    return (String)gps.course.deg() + " deg";
+  }
+  return "-";
+}
+
+/*
+ * To get altitude in meters from GPS as a String.
+ * Unit will be added to the String.
+ * Ex. 50.2m
+ */
+String getGPSAltitude()
+{
+  if (gps.speed.isValid())
+  {
+    return (String)gps.altitude.meters() + " m";
+  }
+  return "-";
+}
+
+/*
+ * To get the number of satellites the GPS
+ * has contact with as a String.
+ */
+String getGPSSatellites()
+{
+  if (gps.speed.isValid())
+  {
+    return (String)gps.satellites.value();
+  }
+  return "-";
+}
+
+/*
+ * To figure out if the GPS got enough satellites
+ * in order to establish a good position, a
+ * minimum of 3 satellites are needed for this.
+ * True will be returned if GPS got 3 or more satellites
+ * else false is returned.
+ */
+boolean isGPSValidForNavigation()
+{
+  if (gps.speed.isValid())
+  {
+    if (gps.satellites.value() > 2)
+    {
+      return true;
+    }
+  }
+  return false;
+}
+
+/*************************************************
+ *       Functionalities for manual input        *
+ *************************************************/
+
+/*
+ * To get the A/D value from JOYSTICK_PIN,
+ * in other words the joysticks position.
+ * This value will only be returned if the
+ * system is in manual mode, else -1 will
+ * be returned
+ */
+int getJoystickValue()
+{
+  if (isManualMode() == 1) {
+    return analogRead(JOYSTICK_PIN);
+  }
+  return -1;
+}
+
+/*
+ * To figure out if the system is in manual
+ * operation mode. If so true will be returned
+ * else false.
+ */
+boolean isManualMode()
+{
+  return digitalRead(MODE_SWITCH_PIN) == HIGH ? true : false;
+}
+
+/*************************************************
+ *              Servo functionality              *
+ *************************************************/
+
+/*
+ * Moves servo to given position, if it's valid.
+ */
+void moveServo(int position)
+{
+  if (MIN_POSITION <= position && position <= MAX_POSITION)
+  {
+    Serial.println("Moving servo to position: " + (String)position);
+    lastValidPosition = position;
+    analogWrite(SERVO_PIN, position);
+  }
+  else
+  {
+    Serial.println("Wanted servo position is invalid, moving servo to last valid position: " + (String)lastValidPosition);
+    analogWrite(SERVO_PIN, lastValidPosition);
+  }
+}
+
+/*
+ * Moves servo to it's maximum position.
+ */
+void moveServoToMax()
+{
+  Serial.println("Moving servo to max position...");
+  moveServo(MAX_POSITION);
+}
+
+/*
+ * Moves servo to it's center position.
+ */
+void moveServoToCenter()
+{
+  Serial.println("Moving servo to center position...");
+  moveServo(CENTER_POSITION);
+}
+
+/*
+ * Moves servo to it's minimum position.
+ */
+void moveServoToMin()
+{
+  Serial.println("Moving servo to min position...");
+  moveServo(MIN_POSITION);
+}
+
+/*
+ * To geet feedback from servo.
+ */
+int getServoFeedback()
+{
+  int feedback = analogRead(SERVO_FEEDBACK_PIN);
+  Serial.println("Feedback: " + (String)feedback);
+  return feedback;
+}
+
+/*************************************************
+ *              TFT functionality              *
+ *************************************************/
+
+/*
+ * To initialize the tft screeen. The screen will
+ * be initialized at a resolution of 800x480. If
+ * the screen cannot be initialzed the system will halt.
+ */
+void initTFT()
+{
+  // Initialise the display using 'RA8875_800x480'
+  if (!tft.begin(RA8875_800x480))
+  {
+    Serial.println(F("TFT Not Found!"));
+    while (1);
+  }
+  else
+  {
+    Serial.print(F("Successfully communicating with screen over SPI with CS pin: ")); Serial.println(TFT_CS);
+    Serial.print(F("Using screen resolution: ")); Serial.println(RA8875_800x480);
+  }
+  // Enable tft
+  tft.displayOn(true);
+  tft.GPIOX(true); // Enable TFT - display enable tied to GPIOX
+
+  Serial.println("Turning on screen...");
+
+  // Config pwm, mainly backlight is controlled with pwm
+  tft.PWM1config(true, RA8875_PWM_CLK_DIV1024); // PWM output for backlight
+  tft.PWM1out(0);
+}
+
+/*
+ * To display a splash screen upon system boot.
+ * The splash screen will be dimmed up from black, then
+ * showed for about 3 seconds to be dimmed down to black
+ * again. If SD card couldn't be found or some error
+ * occurred with that, no splash screen will be shown.
+ */
+void showSplash()
+{
+  // Ensure screen is "black" using PWM
+  tft.PWM1out(0);
+
+  // If SD card has been initialized show splash
+  if (sdInitialized)
+  {
+    Serial.println(F("SD card initialized, setting background color and loading splash images..."));
+    // Set correct background color
+    tft.fillScreen(ARDUINO_BLUE);
+
+    // Load bmp's
+    bmpDraw("iris.bmp", 234, 40);
+    bmpDraw("desc.bmp", 201, 169);
+
+    Serial.println(F("Images loaded, dimming in and out screen..."));
+
+    // We want to fade up the screen using pwm, nice
+    fadeInTFT(1, 10);
+
+    // Show Splash for 3 seconds
+    delay(3000);
+
+    // And now we fade it down
+    fadeOutTFT(1, 10);
+  }
+  Serial.println(F("Preparing for data rendering, setting background color to black..."));
+
+  // This point the tft should be "black" and empty, in other words prepared for the next step
+  tft.fillScreen(RA8875_BLACK);
+}
+
+/*
+ * To draw the main and mostrly static user interface.
+ * This is only needed to be done once, after that it should
+ * remain the same.
+ */
+void drawGui()
+{
+  tft.graphicsMode();
+  drawDoubleVLine(200, 5, 200, 475, ARDUINO_BLUE);
+  drawDoubleHLine(5, 168, 195, 168, ARDUINO_BLUE);
+  drawDoubleHLine(5, 277, 195, 277, ARDUINO_BLUE);
+
+  tft.textMode();
+  tft.textTransparent(RA8875_WHITE);
+  tft.textEnlarge(1);
+  tft.textSetCursor(206, 0);
+  tft.textWrite("Navigation");
+
+  tft.textSetCursor(5, tft.height() - NORMAL_LINE_SPACE - 3);
+  tft.textEnlarge(0);
+  tft.textWrite("Iris - v0.8beta");
+
+  tft.PWM1out(255);
+}
+
+void drawNavMode()
+{
+  tft.textMode();
+  tft.textColor(RA8875_WHITE, RA8875_BLACK);
+  tft.textSetCursor(206, LARGER_LINE_SPACE);
+  tft.textEnlarge(0);
+
+  if (isManualMode())
+  {
+    tft.textWrite("Mode: Manual");
+  }
+  else
+  {
+    tft.textWrite("Mode: Auto  ");
+  }
+}
+
+void drawNavSource()
+{
+  tft.textMode();
+  tft.textColor(RA8875_WHITE, RA8875_BLACK);
+  tft.textSetCursor(400, LARGER_LINE_SPACE);
+  tft.textEnlarge(0);
+
+  if (isGPSValidForNavigation())
+  {
+    tft.textWrite("Source in use: GPS    ");
+  }
+  else
+  {
+    tft.textWrite("Source in use: Compass");
+  }
+}
+
+void drawGPSData()
+{
+  tft.textMode();
+  tft.textColor(RA8875_WHITE, RA8875_BLACK);
+  tft.textSetCursor(5, 0);
+  tft.textEnlarge(1);
+
+  tft.textWrite("GPS Data");
+
+  tft.textEnlarge(0);
+  tft.textSetCursor(5, LARGER_LINE_SPACE);
+  tft.textWrite(("Time(UTC):  " + getGPSTime()).c_str());
+  tft.textSetCursor(5, LARGER_LINE_SPACE + NORMAL_LINE_SPACE);
+  tft.textWrite(("Date:       " + getGPSDate()).c_str());
+  tft.textSetCursor(5, LARGER_LINE_SPACE + NORMAL_LINE_SPACE * 2);
+  tft.textWrite("Location(lat,lon):");
+  tft.textSetCursor(5, LARGER_LINE_SPACE + NORMAL_LINE_SPACE * 3);
+  tft.textWrite(getGPSLocation(true).c_str());
+  tft.textSetCursor(5, LARGER_LINE_SPACE + NORMAL_LINE_SPACE * 4);
+  tft.textWrite(("Speed:      " + getGPSSpeed()).c_str());
+  tft.textSetCursor(5, LARGER_LINE_SPACE + NORMAL_LINE_SPACE * 5);
+  tft.textWrite(("Course:     " + getGPSCourse()).c_str());
+  tft.textSetCursor(5, LARGER_LINE_SPACE + NORMAL_LINE_SPACE * 6);
+  tft.textWrite(("Alitude:    " + getGPSAltitude()).c_str());
+  tft.textSetCursor(5, LARGER_LINE_SPACE + NORMAL_LINE_SPACE * 7);
+  tft.textWrite(("Satellites: " + getGPSSatellites() + "  ").c_str());
+}
+
+void drawCompassData()
+{
+  tft.textMode();
+  tft.textColor(RA8875_WHITE, RA8875_BLACK);
+  tft.textSetCursor(5, 171);
+  tft.textEnlarge(1);
+
+  tft.textWrite("Compass Data");
+  tft.textEnlarge(0);
+  tft.textSetCursor(5, LARGER_LINE_SPACE + 171);
+  tft.textWrite("Course: xxx.xx deg");
+  tft.textSetCursor(5, LARGER_LINE_SPACE + NORMAL_LINE_SPACE + 171);
+  tft.textWrite("X:      xxx.xx");
+  tft.textSetCursor(5, LARGER_LINE_SPACE + NORMAL_LINE_SPACE * 2 + 171);
+  tft.textWrite("Y:      xxx.xx");
+  tft.textSetCursor(5, LARGER_LINE_SPACE + NORMAL_LINE_SPACE * 3 + 171);
+  tft.textWrite("Z:      xxx.xx");
+}
+
+void drawControllerData()
+{
+  // Buffers to store the "String" version of the PID values
+  char KpStr [5];
+  char KiStr [5];
+  char KdStr [5];
+
+  // Casting the doubles to "strings" without loosing any precision
+  dtostrf(Kp, 2, 3, KpStr);
+  dtostrf(Ki, 2, 3, KiStr);
+  dtostrf(Kd, 2, 3, KdStr);
+
+  tft.textMode();
+  tft.textColor(RA8875_WHITE, RA8875_BLACK);
+  tft.textSetCursor(5, 280);
+  tft.textEnlarge(1);
+
+  tft.textWrite("Controller");
+  tft.textEnlarge(0);
+  tft.textSetCursor(5, LARGER_LINE_SPACE + 280);
+  tft.textWrite(("P = " + (String)KpStr).c_str());
+  tft.textSetCursor(5, LARGER_LINE_SPACE + NORMAL_LINE_SPACE + 280);
+  tft.textWrite(("I = " + (String)KiStr).c_str());
+  tft.textSetCursor(5, LARGER_LINE_SPACE + NORMAL_LINE_SPACE * 2 + 280);
+  tft.textWrite(("D = " + (String)KdStr).c_str());
+}
+
+void drawText()
+{
+  tft.PWM1out(255);
+  tft.textMode();
+
+  tft.textTransparent(RA8875_WHITE);
+  tft.textSetCursor(5, 0);
+  tft.textEnlarge(0);
+  tft.textWrite("Våöäåvdfkvnoavkpav*!--<><</)0987, consectetur adipisicing elit..."); // Standard
+  tft.textSetCursor(5, 17);
+  tft.fontArial();
+  tft.textWrite("Lorem ipsum dolor sit amet, consectetur adipisicing elit...");
+  tft.textSetCursor(5, 34);
+  tft.fontRoman();
+  tft.textWrite("Lorem ipsum dolor sit amet, consectetur adipisicing elit...");
+  tft.textSetCursor(0, 51);
+  tft.fontStandard();
+  tft.textEnlarge(1);
+  tft.textWrite("Lorem ipsum dolor sit amet, consectetur adipisicing elit..."); // Standard
+  tft.textSetCursor(0, 85);
+  tft.textEnlarge(2);
+  tft.textWrite("Lorem ipsum dolor sit amet, consectetur adipisicing elit..."); // Standard
+  tft.textSetCursor(0, 130);
+  tft.textEnlarge(3);
+  tft.textWrite("Lorem ipsum dolor sit amet, consectetur adipisicing elit..."); // Standard
+}
+
+/*
+ * Turns TFT black with pwm and then fades it in again with
+ * given steps as increment and delays each increment with
+ * given delay.
+ */
+void fadeInTFT(int steps, int del)
+{
+  // Ensure screen is "black" using PWM
+  tft.PWM1out(0);
+
+  for (int i = 1; i < 256; i += steps)
+  {
+    tft.PWM1out(i);
+    delay(del);
+  }
+}
+
+/*
+ * Turns TFT fully on with pwm and then fades it out again with
+ * given steps as increment and delays each increment with
+ * given delay.
+ */
+void fadeOutTFT(int steps, int del)
+{
+  // Ensure screen is fully on using PWM
+  tft.PWM1out(255);
+
+  for (int i = 255; i > -1; i -= steps)
+  {
+    tft.PWM1out(i);
+    delay(del);
+  }
+}
+
+/*
+ * Convenience function that draws two lines side by side
+ * by drawing two lines. One at the given x values and the
+ * other at given x value + 1.
+ */
+void drawDoubleVLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color)
+{
+  tft.drawLine(x0, y0, x1, y1, color);
+  tft.drawLine(x0 + 1, y0, x1 + 1, y1, color);
+}
+
+/*
+ * Convenience function that draws two lines side by side
+ * by drawing two lines. One at the given y values and the
+ * other at given y value + 1.
+ */
+void drawDoubleHLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color)
+{
+  tft.drawLine(x0, y0, x1, y1, color);
+  tft.drawLine(x0, y0 + 1, x1, y1 + 1, color);
+}
+
+/*************************************************
+ *       Utilities and other functionality       *
+ *************************************************/
+
+/*
+ * To reset the different timers used by
+ * the different tasks. Reset is only needed
+ * the timers has wrapped around.
+ */
+void resetTimersIfNeeded()
+{
+  // If our timers wrap around we reset them
+  if (timerGPS > millis())
+  {
+    timerGPS = millis();
+  }
+  if (timerServo > millis())
+  {
+    timerServo = millis();
+  }
+  if (timerTFT > millis())
+  {
+    timerTFT = millis();
+  }
+}
+
+/*
+ * Homebrew function to convert a given double to a char
+ * array with given precision.
+ * Snatched from the Arduino forum:
+ *    http://forum.arduino.cc/index.php/topic,44262.0.html
+ */
+char *ftoa(char *a, double f, int precision)
+{
+  long p[] = {0, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000};
+  char *ret = a;
+  long l = (long)f;
+
+  itoa(l, a, 10);
+  while (*a != '\0')
+  {
+    a++;
+  }
+
+  *a++ = '.';
+  long d = abs((long)((f - l) * p[precision]));
+  itoa(d, a, 10);
+
+  return ret;
+}
+
+/*
+ * Function dtostrf is only available on avr. This little function
+ * emulates that one so it could be used on arm.
+ */
+char *dtostrf(double val, signed char width, unsigned char prec, char *sout)
+{
+  char fmt[20];
+  sprintf(fmt, "%%%d.%df", width, prec);
+  sprintf(sout, fmt, val);
+  return sout;
+}
+
+/*
+ * To get bmp file from SD card named as given filename and then draw it
+ * on TFT at given points x and y. If bmp file couldn't be found on the
+ * SD card function will return without any further actions. The same happens
+ * opened bmp file doesn't have a bit depth of 24bit, also if given
+ * x and y points are larger than TFT's dimension this function will return.
+ * Function snatched from Adafruits "spitftbitmap" example the Adafruit_ILI9340 library.
+ */
+void bmpDraw(char *filename, uint8_t x, uint8_t y) {
+  File     bmpFile;
+  int      bmpWidth, bmpHeight;   // W+H in pixels
+  uint8_t  bmpDepth;              // Bit depth (currently must be 24)
+  uint32_t bmpImageoffset;        // Start of image data in file
+  uint32_t rowSize;               // Not always = bmpWidth; may have padding
+  uint8_t  sdbuffer[3 * BUFFPIXEL]; // pixel buffer (R+G+B per pixel)
+  uint8_t  buffidx = sizeof(sdbuffer); // Current position in sdbuffer
+  boolean  goodBmp = false;       // Set to true on valid header parse
+  boolean  flip    = true;        // BMP is stored bottom-to-top
+  int      w, h, row, col;
+  uint8_t  r, g, b;
+  uint32_t pos = 0, startTime = millis();
+
+  if ((x >= tft.width()) || (y >= tft.height())) return;
+
+  // Open requested file on SD card
+  if ((bmpFile = SD.open(filename)) == NULL) {
+    Serial.print(F("File '")); Serial.print(filename); Serial.println(F("' couldn't be found"));
+    return;
+  }
+
+  // Parse BMP header
+  if (read16(bmpFile) == 0x4D42) { // BMP signature
+    Serial.print(F("File size: ")); Serial.println(read32(bmpFile));
+    (void)read32(bmpFile); // Read & ignore creator bytes
+    bmpImageoffset = read32(bmpFile); // Start of image data
+    Serial.print(F("Image Offset: ")); Serial.println(bmpImageoffset, DEC);
+    // Read DIB header
+    Serial.print(F("Header size: ")); Serial.println(read32(bmpFile));
+    bmpWidth  = read32(bmpFile);
+    bmpHeight = read32(bmpFile);
+    if (read16(bmpFile) == 1) { // # planes -- must be '1'
+      bmpDepth = read16(bmpFile); // bits per pixel
+      Serial.print(F("Bit Depth: ")); Serial.println(bmpDepth);
+      if ((bmpDepth == 24) && (read32(bmpFile) == 0)) { // 0 = uncompressed
+        goodBmp = true; // Supported BMP format -- proceed!
+        Serial.print(F("Image size: ")); Serial.print(bmpWidth); Serial.print(F("x")); Serial.println(bmpHeight);
+
+        // BMP rows are padded (if needed) to 4-byte boundary
+        rowSize = (bmpWidth * 3 + 3) & ~3;
+
+        // If bmpHeight is negative, image is in top-down order.
+        // This is not canon but has been observed in the wild.
+        if (bmpHeight < 0) {
+          bmpHeight = -bmpHeight;
+          flip      = false;
+        }
+
+        // Crop area to be loaded
+        w = bmpWidth;
+        h = bmpHeight;
+        if ((x + w - 1) >= tft.width())
+        {
+          w = tft.width()  - x;
+        }
+        if ((y + h - 1) >= tft.height())
+        {
+          h = tft.height() - y;
+        }
+
+        for (row = 0; row < h; row++) { // For each scanline...
+          // Seek to start of scan line.  It might seem labor-
+          // intensive to be doing this on every line, but this
+          // method covers a lot of gritty details like cropping
+          // and scanline padding.  Also, the seek only takes
+          // place if the file position actually needs to change
+          // (avoids a lot of cluster math in SD library).
+          if (flip) // Bitmap is stored bottom-to-top order (normal BMP)
+            pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize;
+          else     // Bitmap is stored top-to-bottom
+            pos = bmpImageoffset + row * rowSize;
+          if (bmpFile.position() != pos) { // Need seek?
+            bmpFile.seek(pos);
+            buffidx = sizeof(sdbuffer); // Force buffer reload
+          }
+
+          for (col = 0; col < w; col++) { // For each pixel...
+            // Time to read more pixel data?
+            if (buffidx >= sizeof(sdbuffer)) { // Indeed
+              bmpFile.read(sdbuffer, sizeof(sdbuffer));
+              buffidx = 0; // Set index to beginning
+            }
+
+            // Convert pixel from BMP to TFT format, push to display
+            b = sdbuffer[buffidx++];
+            g = sdbuffer[buffidx++];
+            r = sdbuffer[buffidx++];
+            tft.drawPixel(x + col, y + row, color565(r, g, b));
+          }
+        }
+      }
+    }
+  }
+
+  bmpFile.close();
+  if (!goodBmp)
+  {
+    Serial.println(F("BMP format not recognized."));
+  }
+}
+
+/*
+ * To read out 16 bit from given file.
+ * Function snatched from Adafruits "spitftbitmap" example
+ * from the Adafruit_ILI9340 library.
+ */
+uint16_t read16(File & f)
+{
+  uint16_t result;
+  ((uint8_t *)&result)[0] = f.read(); // LSB
+  ((uint8_t *)&result)[1] = f.read(); // MSB
+  return result;
+}
+
+/*
+ * To read out 32 bit from given file.
+ * Function snatched from Adafruits "spitftbitmap" example
+ * from the Adafruit_ILI9340 library.
+ */
+uint32_t read32(File & f)
+{
+  uint32_t result;
+  ((uint8_t *)&result)[0] = f.read(); // LSB
+  ((uint8_t *)&result)[1] = f.read();
+  ((uint8_t *)&result)[2] = f.read();
+  ((uint8_t *)&result)[3] = f.read(); // MSB
+  return result;
+}
+
+/*
+ * To get 16 bit packed color from given 8 bit R,G,B values.
+ * Function snatched from the Adafruit_ILI9340 library.
+ */
+uint16_t color565(uint8_t r, uint8_t g, uint8_t b) {
+  return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);
+}


use SX22Command instead of SXCommand

use SX22Command instead of SXCommand

--- examples/SxXBee2/SxXBee2.ino
+++ examples/SxXBee2/SxXBee2.ino
@@ -1,6 +1,7 @@
 /*
  * SxXBee2.ino
- *
+ *
+ *  Changed on: 16.10.2015   corrected SX22Command
  *  Changed on: 12.10.2015   new protocol rev1.1
  *  Changed on: 04.09.2015   broadcast of power state
  *  Created on: 28.08.2015
@@ -18,13 +19,13 @@

 #include <SX22b.h>   // this is the Selectrix library
-#include <SXCommand.h>   // this is the Selectrix Command library
+#include <SX22Command.h>   // this is the Selectrix Command library
 #include <XBee.h> // XBee library by Andrew Rapp

 #define LED  13   // LED indicator at pin 13

 SX22b sx;                // selectrix library
-SXCommand sxcmd;      // holds command data
+SX22Command sxcmd;      // holds command data

 static int ledState = LOW;
 static byte oldSx[MAX_CHANNEL_NUMBER];


Print individual flag bits on battery degraded


Report more aggressively on SPI or RFID reader failes. Report if the RED led is on.

--- test/PoE-test/voordeur-asis-2017/voordeur-asis-2017.ino
+++ test/PoE-test/voordeur-asis-2017/voordeur-asis-2017.ino
@@ -29,6 +29,9 @@
 #define SOLENOID_ENGAGED  (HIGH)

 #define AARTLED_GPIO      (16)
+
+// #define WIRECHECK_GPIO	  (0)
+// #define WIRECHECK_REDLED  (HIGH)

 #define DOOR_OPEN_DELAY         (5*1000)   //  10 seconds -- how long to hold the relay engaged; in milli seconds.
 #define CACHE_FALLBACK_TIMEOUT  (500)       // 0.5 second  -- how long to wait for a reply before checking the cache.
@@ -250,8 +253,6 @@
   mfrc522.PCD_WriteRegister(mfrc522.ComIrqReg, 0x7F);
 }

-
-
 static long lastReconnectAttempt = 0;

 boolean reconnect() {
@@ -690,7 +691,26 @@
       }
       break;
     case OPEN:
+      break;
     case CLOSED:
+#ifdef WIRECHECK_GPIO
+      {
+	static unsigned long lastWireFail = 0;
+        if (digitalRead(WIRECHECK_GPIO) == WIRECHECK_REDLED) {
+	   lastWireFail = millis();
+	} else {
+           if (millis() - lastWireFail > 2 * DOOR_OPEN_DELAY && lastWireFail != 0) {
+		lastWireFail += 300 * 1000; // 5 minute reporting interval.
+
+                 char msg[255];
+                 snprintf(msg, sizeof(msg), "[%s] RED led still on - despite closed door. Possible wire issue.", pname);
+                 Serial.println(msg);
+                 client.publish(log_topic, msg);
+           }
+        }
+      }
+#endif
+      break;
     default:
       break;
   };
@@ -722,7 +742,15 @@
       mfrc522.PCD_Reset();
       if (!mfrc522.PCD_PerformSelfTest()) {
         cnt_failed_rfid++;
-        if (cnt_failed_rfid > 2)
+
+        char msg[256];
+        snprintf(msg, sizeof(msg), "[%s] RFID selftest failed (%d times since boot%s).",
+		pname, cnt_failed_rfid,
+		(cnt_failed_rfid == 3) ? " and will reboot on next fail." : "");
+        Serial.println(msg);
+        client.publish(log_topic, msg);
+
+        if (cnt_failed_rfid > 3)
           ESP.restart();
       };
       mfrc522.PCD_Reset();


Update rx5808-pro-diversityGc9n.ino

Update rx5808-pro-diversityGc9n.ino

--- rx5808-pro-diversityGc9n/rx5808-pro-diversityGc9n.ino
+++ rx5808-pro-diversityGc9n/rx5808-pro-diversityGc9n.ino
@@ -551,11 +551,11 @@
             ///////////////////////FAVORITIES SAVE Gc9n
             if (last_state!=STATE_SETUP_MENU  && state_last_used!=STATE_FAVORITE ) // if you didnt came from menu setup  save favorite
             {
-                if ( EEPROM.read(EEPROM_ADR_TUNE_FAV[10]) != 255) //ALL FAVS full gc9n
+                if ( EEPROM.read(EEPROM_ADR_TUNE_FAV[9]) != 255) //ALL FAVS full gc9n
                   {
                     int lfav;
                     lfav=EEPROM.read(EEPROM_ADR_TUNE_FAV_LAST);
-                    if (lfav<10)
+                    if (lfav==9)
                     {
                       lfav=0;
                     }
@@ -592,7 +592,7 @@
               for(int i = 0; i<10; i++) {temp_EEPROM_ADR_TUNE_FAV[i] =255;   }  //empty temp

               //--REORGANIZE FAVS  GC9n
-                  byte MaxFav=0;
+                  int MaxFav=0;
                   for(int i = 0; i<10; i++)
                     {

@@ -614,12 +614,16 @@
                         //DELETED SUCCESFULLY AND GO TO FIRST FAV (IF EXISTS)
                         drawScreen.FavReorg(MaxFav);
                         RefreshFav=false;
-                        delay(500);
+                        delay(300);
                         EEPROM.write(EEPROM_ADR_TUNE_FAV_LAST,0);
+                         channelIndex=EEPROM.read(EEPROM_ADR_TUNE_FAV[0]) ;
+                         lfavs=0;
                         channelIndex=EEPROM.read(EEPROM_ADR_TUNE_FAV[0]) ;
                         drawScreen.FavSel(1);
                         channel=channel_from_index(channelIndex);
                         EEPROM.write(EEPROM_ADR_TUNE,channelIndex);
+
+
                         //drawScreen.screenSaver(diversity_mode, pgm_read_byte_near(channelNames + channelIndex), pgm_read_word_near(channelFreqTable + channelIndex), call_sign);
             }
            ///END LONG PRESS IN FAVORITES WILL DELETE THE CURRENT FAVORITE CHANNEL
@@ -751,6 +755,7 @@
                       if (EEPROM.read(EEPROM_ADR_TUNE_FAV[i])!=255)
                       {  FirstFav=i;
                         HaveFav=true;
+
                         }
                 }
                 RefreshFav=true;
@@ -761,12 +766,6 @@
               delay(KEY_DEBOUNCE); // debounce
                   lfavs++;
                   if (lfavs>FirstFav){lfavs=0;}
-//                 Serial.println  ("UPEEPROM.read(EEPROM_ADR_TUNE_FAV[lfavs]) ");
-//                 Serial.print  (EEPROM.read(EEPROM_ADR_TUNE_FAV[lfavs]) );
-//                 Serial.print  (" lfavs");
-//                 Serial.println  (lfavs );
-//                 Serial.print  (" FirstFav");
-//                 Serial.println  (FirstFav );
                     channelIndex=EEPROM.read(EEPROM_ADR_TUNE_FAV[lfavs]) ;
                     if (channelIndex!=255)
                      {


Single click to wake up from screensaver

--- src/cyclop_plus/cyclop_plus.ino
+++ src/cyclop_plus/cyclop_plus.ino
@@ -129,6 +129,7 @@
 uint16_t alarmOnPeriod = 0;
 uint16_t alarmOffPeriod = 0;
 uint8_t options[MAX_OPTIONS];
+boolean saveScreenActive = 0;

 //******************************************************************************
 //* function: setup
@@ -213,8 +214,10 @@
       break;

     case SINGLE_CLICK: // up the frequency
-      currentChannel = nextChannel( currentChannel );
-      setRTC6715Frequency(getFrequency(currentChannel));
+      if (!( options[SAVE_SCREEN_OPTION] && saveScreenActive )) { // Single click to wake up
+        currentChannel = nextChannel( currentChannel );
+        setRTC6715Frequency(getFrequency(currentChannel));
+      }
       drawChannelScreen(currentChannel, 0);
       break;

@@ -835,6 +838,9 @@
 //******************************************************************************
 void drawStartScreen( void ) {
   uint8_t i;
+
+  saveScreenActive = 0;
+
   display.clearDisplay();
   display.drawLine(0, 0, 127, 0, WHITE);
   display.setTextColor(WHITE);
@@ -867,6 +873,8 @@
 void drawChannelScreen( uint8_t channel, uint16_t rssi) {
   char buffer[22];
   uint8_t i;
+
+  saveScreenActive = 0;

   display.clearDisplay();
   display.setTextColor(WHITE);
@@ -903,6 +911,8 @@
 //* function: drawAutoScanScreen
 //******************************************************************************
 void drawAutoScanScreen( void ) {
+  saveScreenActive = 0;
+
   display.clearDisplay();
   display.setTextColor(WHITE);
   display.setCursor(10, 0);
@@ -923,6 +933,8 @@
 //* function: drawScannerScreen
 //******************************************************************************
 void drawScannerScreen( void ) {
+  saveScreenActive = 0;
+
   display.clearDisplay();
   display.drawLine(0, 55, 127, 55, WHITE);
   display.setTextColor(WHITE);
@@ -943,6 +955,8 @@
   static uint8_t last_position = 14;
   static uint8_t last_value = 0;

+  saveScreenActive = 0;
+
   // The scan graph only uses the 100 positions in the middle of the screen
   position = position + 14;

@@ -966,6 +980,8 @@
 //*         : value = 0 to 100
 //******************************************************************************
 void drawBattery(uint8_t xPos, uint8_t yPos, uint8_t value ) {
+  saveScreenActive = 0;
+
   display.drawRect(3 + xPos,  0 + yPos, 4, 2, WHITE);
   display.drawRect(0 + xPos, 2 + yPos, 10, 20, WHITE);
   display.drawRect(2 + xPos,  4 + yPos, 6, 16, BLACK);
@@ -986,6 +1002,9 @@
 //******************************************************************************
 void drawOptionsScreen(uint8_t option ) {
   uint8_t i, j;
+
+  saveScreenActive = 0;
+
   display.clearDisplay();
   display.setCursor(0, 0);
   display.setTextSize(1);
@@ -1037,5 +1056,6 @@
 {
   display.clearDisplay();
   display.display();
-}
-
+  saveScreenActive = 1;
+}
+


clock: Add alpha blending!

clock: Add alpha blending!

--- src/sketch.ino
+++ src/sketch.ino
@@ -13,10 +13,13 @@
 const uint32_t HR = 60L * MIN;
 const uint32_t HALFDAY = 12L * HR;

-#define RGB(r, g, b) (((uint32_t(r) & 0xff) << 16) | ((uint32_t(g) & 0xff) << 8) | (uint32_t(b) & 0xff))
-#define R(rgb) ((uint32_t(rgb)>>16) & 0xff)
-#define G(rgb) ((uint32_t(rgb)>>8) & 0xff)
-#define B(rgb) ((uint32_t(rgb)) & 0xff)
+static uint32_t RGB(byte r, byte g, byte b, byte a=0) {
+    return uint32_t(a) << 24 | uint32_t(r) << 16 | uint32_t(g) << 8 | uint32_t(b);
+}
+static byte R(uint32_t color) { return color >> 16; }
+static byte G(uint32_t color) { return color >> 8; }
+static byte B(uint32_t color) { return color; }
+static byte A(uint32_t color) { return color >> 24; }

 Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, LED_PIN, NEO_GRB | NEO_KHZ800);

@@ -26,9 +29,28 @@
 uint32_t epochTime = 0;
 float drift = 1;

-const long CLOCK_MARK_COLOR = RGB(0, 0, 10);
+const long CLOCK_MARK_COLOR = RGB(0, 0, 255);

-int set_color_at_clock(uint32_t num, uint32_t max, uint32_t color) {
+void setPixelColor(uint16_t location, uint32_t newColor, uint8_t alpha) {
+    if (alpha > 250) {
+        strip.setPixelColor(location, newColor);
+    } else if (alpha == 1) {
+        // pass
+    } else {
+        uint32_t existingColor = strip.getPixelColor(location);
+        uint8_t rev_alpha = 255 - alpha;
+        strip.setPixelColor(location, RGB(
+            (R(existingColor) * rev_alpha + R(newColor) * alpha) >> 8,
+            (G(existingColor) * rev_alpha + G(newColor) * alpha) >> 8,
+            (B(existingColor) * rev_alpha + B(newColor) * alpha) >> 8));
+    }
+}
+
+void setPixelColor(uint16_t location, uint8_t r, uint8_t g, uint8_t b, uint8_t alpha) {
+    setPixelColor(location, RGB(R(r), G(g), B(b)), alpha);
+}
+
+int set_color_at_clock(uint32_t num, uint32_t max, uint32_t color, uint8_t alpha) {
     num %= max;
     float value = float(num) / max;
     value += 0.25 / CLOCK_FACE_SIZE;
@@ -38,13 +60,13 @@
     while (t_value < 0) t_value += 4;
     t_value = t_value * CLOCK_FACE_SIZE;
     float ratio = 1 - t_value + int(t_value);
-    int location = int(t_value) % NUM_LEDS;
+    uint16_t location = uint16_t(t_value) % NUM_LEDS;
     float r = ratio*ratio;
-    strip.setPixelColor(location, RGB(R(color)*r,G(color)*r,B(color)*r));
+    setPixelColor(location, color, sqrt(r) * alpha);
     location = (location + 1) % NUM_LEDS;
     ratio = 1 - ratio;
     r = ratio*ratio;
-    strip.setPixelColor(location, RGB(R(color)*r,G(color)*r,B(color)*r));
+    setPixelColor(location, color, sqrt(r) * alpha);
 }

 byte read() {
@@ -110,15 +132,15 @@
     }

     for (int i=0; i<4; i++) {
-        set_color_at_clock(i * 3 + 1, 12, CLOCK_MARK_COLOR);
-        strip.setPixelColor(21 * i + 9, CLOCK_MARK_COLOR);
-        strip.setPixelColor(21 * i + 10, CLOCK_MARK_COLOR);
-        set_color_at_clock(i * 3 + 11, 12, CLOCK_MARK_COLOR);
+        set_color_at_clock(i * 3 + 1, 12, CLOCK_MARK_COLOR, 20);
+        setPixelColor(21 * i + 9, CLOCK_MARK_COLOR, 20);
+        setPixelColor(21 * i + 10, CLOCK_MARK_COLOR, 20);
+        set_color_at_clock(i * 3 + 11, 12, CLOCK_MARK_COLOR, 20);
     }

-    set_color_at_clock(time/1000, MIN/1000, RGB(5, 5, 5));
-    set_color_at_clock(time, HR, RGB(0, 20, 20));
-    set_color_at_clock(time, HALFDAY, RGB(15, 20, 15));
+    set_color_at_clock(time/1000, MIN/1000, RGB(255, 255, 255), 5);
+    set_color_at_clock(time, HR, RGB(0, 255, 255), 50);
+    set_color_at_clock(time, HALFDAY, RGB(150, 255, 150), 50);

     lastMillis = nowMillis;
     strip.show();


Added FLAGS_OUTPUT_ADDRESS_MODE to Dcc.init() to make it work again after the DCC Addressing changes

--- examples/NmraDccAccessoryDecoder_Pulsed_8/NmraDccAccessoryDecoder_Pulsed_8.ino
+++ examples/NmraDccAccessoryDecoder_Pulsed_8/NmraDccAccessoryDecoder_Pulsed_8.ino
@@ -9,7 +9,7 @@
 #define NOTIFY_TURNOUT_MSG

 // You can also print other Debug Messages uncommenting the line below
-#define DEBUG_MSG
+//#define DEBUG_MSG

 // Un-Comment the line below to force CVs to be written to the Factory Default values
 // defined in the FactoryDefaultCVs below on Start-Up
@@ -134,7 +134,7 @@
 #endif

   // Call the main DCC Init function to enable the DCC Receiver
-  Dcc.init( MAN_ID_DIY, DCC_DECODER_VERSION_NUM, CV29_ACCESSORY_DECODER, 0 );
+  Dcc.init( MAN_ID_DIY, DCC_DECODER_VERSION_NUM, FLAGS_OUTPUT_ADDRESS_MODE | FLAGS_DCC_ACCESSORY_DECODER, 0 );

 #ifdef DEBUG_MSG
   Serial.print("\nNMRA DCC 8-Turnout Accessory Decoder. Ver: "); Serial.println(DCC_DECODER_VERSION_NUM,DEC);


Add midi note to toggle metronome status

--- ableton-midi-foot-controller.ino
+++ ableton-midi-foot-controller.ino
@@ -103,6 +103,7 @@
 const byte CURRENT_PART = 3;
 const byte NEXT_PART = 4;
 const byte SONG_SIGNATURE = 5;
+const byte METRONOME = 6;

 const byte SONG_OFFSET = 10;

@@ -117,6 +118,7 @@
 const byte REPEAT_MIDI_NOTE = CONTROL_OFFSET;
 const byte SEND_CONFIGURATION = CONTROL_OFFSET + 1;
 const byte STOP_CLIPS = CONTROL_OFFSET + 2;
+const byte METRONOME_MIDI_NOTE = CONTROL_OFFSET + 3;

 const byte INVALID_MIDI_NOTE = 254;
 byte midiNoteToSend = INVALID_MIDI_NOTE;
@@ -543,6 +545,12 @@
     bankDownButton.turnLedOff();
   }

+  if (bankDownButton.isJustReleased()) {
+    midiNoteSendStart = 0;
+    midiNoteToSend = METRONOME_MIDI_NOTE;
+  }
+
+
   if (stopButton.isJustPressed()) {
     stopButton.turnLedOn();
   }


Removed serial calls. Also cleaned the init state files. Saving state works.

--- BackEnd/BackEnd.ino
+++ BackEnd/BackEnd.ino
@@ -498,7 +498,7 @@
       #endif
       */

-      Serial.print("ERROR reading file. Content: ");
+//      Serial.print("ERROR reading file. Content: ");
 //      Serial.println(sJsonFile);

       // The file is empty for some reason. Let's use the standard init function
@@ -512,14 +512,14 @@
         trace_info("%s(): SUCCESS reading file. Content: %s\n", __func__, sJsonFile);
       #endif
       */
-      Serial.print("SUCCESS reading file. Content: ");
+ //     Serial.print("SUCCESS reading file. Content: ");
 //      Serial.println(sJsonFile);
     }
   }
   else
   {
-     Serial.print("ERROR opening file: ");
-     Serial.println(_sFullFilePath);
+  //   Serial.print("ERROR opening file: ");
+  //   Serial.println(_sFullFilePath);
      return;
   }
   /*
@@ -1808,7 +1808,7 @@
     updateBoardState();

 // TESTING
-  getSerialCommand();
+//  getSerialCommand();

   if (millis() - g_last_print > 10000)
   {


Return after finding sensor early

Return after finding sensor early

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

--- src/sketch.ino
+++ src/sketch.ino
@@ -179,7 +179,7 @@
     }
     for (int i=0; i<accelSteps; i++) {
         oneStep(map(i, 0, accelSteps, pulse, startstoppulse));
-        if (i>(accelSteps - decelLook) && digitalRead(sensorPin)) break;
+        if (i>(accelSteps - decelLook) && digitalRead(sensorPin)) return;
         if (alarmState) return;
     }
     findSensor(startstoppulse);
@@ -202,7 +202,6 @@
     }
     for (int i=0; i<accelsteps; i++) {
         oneStep(map(i, 0, accelsteps, pulse, startstoppulse));
-        if (i>(accelSteps - decelLook) && digitalRead(sensorPin)) break;
         if (alarmState) return;
     }
 }
@@ -225,7 +224,7 @@
     }
     for (int i=0; i<decelsteps; i++) {
         oneStep(map(i, 0, decelsteps, endpulse, max(maxPulse, endpulse)));
-        if (i>(accelSteps - decelLook) && digitalRead(sensorPin)) break;
+        if (i>(accelSteps - decelLook) && digitalRead(sensorPin)) return;
         if (alarmState) return;
     }
     findSensor(max(maxPulse, endpulse));
@@ -260,7 +259,7 @@
     }
     for (int i=0; i<accelsteps; i++) {
         oneStep(map(i, 0, accelsteps, pulse, maxPulse));
-        if (i>(accelsteps - decelLook) && digitalRead(sensorPin)) break;
+        if (i>(accelsteps - decelLook) && digitalRead(sensorPin)) return pulse;
         if (alarmState) return 0;
     }
     findSensor(maxPulse);


Added crucial function that makes boilerhub do things.

--- Arduino/hardware/REV10/REV10SecureBHR/REV10SecureBHR.ino
+++ Arduino/hardware/REV10/REV10SecureBHR/REV10SecureBHR.ino
@@ -754,6 +754,9 @@
     // Conversely, if not true, should have time to safely log outputs, etc.
     const uint8_t nearOverrunThreshold = OTV0P2BASE::GSCT_MAX - 8; // ~64ms/~32 serial TX chars of grace time...

+    // Update internal boiler hub state and
+    BoilerHub.processCallsForHeat(second0, hubManager.inHubMode());
+
     // Sleep in low-power mode (waiting for interrupts) until seconds roll.
     // NOTE: sleep at the top of the loop to minimise timing jitter/delay from Arduino background activity after loop() returns.
     // DHD20130425: waking up from sleep and getting to start processing below this block may take >10ms.


update

update

--- _09_ir_tx_rx/_09_ir_tx_rx.ino
+++ _09_ir_tx_rx/_09_ir_tx_rx.ino
@@ -66,6 +66,7 @@
 // Timer
 Timer t;
 long temp_Mills;
+long pir_Mills;
 int tvIsOnEvent;
 int tvIsOffEvent;

@@ -199,6 +200,7 @@

   // Timer start
   temp_Mills = millis();
+  pir_Mills = millis();

   // ir
   irrecv.enableIRIn();
@@ -210,13 +212,13 @@
   digitalWrite(SETUP_IN_PIN, HIGH);
   digitalWrite(WRK_MODE_IN_PIN, HIGH);

-  pinMode(PIR_IN_PIN, INPUT);
+  pinMode(PIR_IN_PIN, INPUT_PULLUP);

   // buzzer
   pinMode(BZ_OU_PIN, OUTPUT);
   digitalWrite(BZ_OU_PIN, HIGH);

-  delay(3000);
+  delay(2000);

   // PIR
   attachInterrupt(0, PIRCHECKING, CHANGE);
@@ -390,8 +392,14 @@

 void PIRCHECKING()
 {
-  pirOnOff = digitalRead(PIR_IN_PIN);
-  Serial.println("PIR rising called");
+  if (( millis() - pir_Mills ) < 600 ) {
+    return;
+  } else {
+
+    pirOnOff = !digitalRead(PIR_IN_PIN);
+    Serial.println("PIR rising called");
+    pir_Mills = millis();
+  }
 }

@@ -529,7 +537,7 @@
         default:
           return;
           break;
-
+
       }
     }
   } else {
@@ -570,7 +578,7 @@
   tempCinside = getdalastemp();
   displayTemperature(tempCinside);
   displaytimeleft();
-  Serial.println(digitalRead(PIR_IN_PIN));
+  Serial.println(!digitalRead(PIR_IN_PIN));
 }

 // update every 5 mins


Just some white space

Just some white space

--- arduboy-game/arduboy-game.ino
+++ arduboy-game/arduboy-game.ino
@@ -787,7 +787,7 @@
   char hiScore[7];
   hiScore[6] = '\0';
   for (byte i = 0; i < 4; i++) {
-    strncpy(hiScore, highScoreTable + (((9 * i) + 3) * sizeof(char)), 6);
+    strncpy(hiScore, highScoreTable + ((9 * i) + 3), 6);
     if (score > strtol(hiScore, NULL, 10)) {
        return i;
     }
@@ -890,7 +890,7 @@

   // then copy new result into correct place
   for (currPos = 0; currPos < 9; currPos++) {
-    highScoreTable[currPos + ((9 * newHiPos) * sizeof(char))] = textBuf[currPos];
+    highScoreTable[currPos + (9 * newHiPos)] = textBuf[currPos];
   }
 }


Integrated changes into main.

Integrated changes into main.

--- oktopus-autopilote/oktopus-autopilote.ino
+++ oktopus-autopilote/oktopus-autopilote.ino
@@ -22,13 +22,14 @@
  * Defines
  */
 #define SECONDS 1000
-#define TEST_DELAY 15*SECONDS
+#define START_DELAY 10*SECONDS
 #define __BOAT__ 1
 #define MOTOR_SPEED 22
 #define TEMPERATURE_THRESHOLD 50
 #define SONAR_THRESHOLD 1
 #define PROXIMITY_THRESHOLD 1
-#define STATIONNARY_DELAY 5*SECONDS
+#define STATIONNARY_DELAY 10*SECONDS
+#define RUN_TIME 180*SECONDS
 /********************************************/

@@ -47,8 +48,8 @@
   EmergencyHandler emergencyHandler("Dry", TEMPERATURE_THRESHOLD, SONAR_THRESHOLD, PROXIMITY_THRESHOLD);
 #endif

-GPS gps;
-XbeeReceiver xbee;
+  GPS gps;
+  XbeeReceiver xbee;
 /********************************************/

@@ -70,21 +71,23 @@
   double rudder = 0.0;
   int servoValue = 0;
   int escValue = 0;
-  int gpsValue = 0;
-  uint32_t timer1;
-  uint32_t timer2;
+  double gpsValueLat = 0.0;
+  double gpsValueLon = 0;
+  unsigned long timer1;
+  unsigned long timer2;
   double distanceToTarget = 0.00;
-  double destinationPoint[1][2] = { 45.379184, 71.9239 }; //test campus
+  //double destinationPoint[1][2] = { 45.379184, 71.9239 }; //test campus
+  double destinationPoint[1][2] = {45.39545,71.92775};
   double startPoint[1][2];
   int gpsListCounter = 2;
   double listPointsX[10] = {0};
   double listPointsY[10] = {0};
 #endif /* __BOAT__ */

-const char GPS = 'G';
-const char Manuel = 'M';
-char mode = 'E';
-NMEAData currentGpsData;
+  const char GPS = 'G';
+  const char Manuel = 'M';
+  char mode = 'E';
+  NMEAData currentGpsData;
 /********************************************/

@@ -96,8 +99,6 @@
    */
   gps.enable();
   xbee.begin();
-
-  delay(2*SECONDS);

 #if __BOAT__>0

@@ -105,99 +106,124 @@
   moistureSensor.enable();
   rudderServo.enable();
   temperatureSensor.enable();
-  proximitySensorArray.enable();
+  //proximitySensorArray.enable();

   PIDController.enableCruisingMode();
-
-  currentGpsData = gps.getData();
+
   while(currentGpsData.latitude < 4500 && currentGpsData.longitude < 7000){
     currentGpsData = gps.getData();
   }
+  Serial.print("GPS data lat & lon: ");
+  Serial.print(currentGpsData.latitude);
+  Serial.print(" & ");
+  Serial.println(currentGpsData.longitude);
+  /*
   startPoint[0][0] = ((currentGpsData.latitude-4500)/60)+45;
   startPoint[0][1] = ((currentGpsData.longitude-7100)/60)+71;
+  */
+  startPoint[0][0] = 45.39554;
+  startPoint[0][1] = 71.9274;
   trajectory.getData(startPoint,destinationPoint,listPointsX,listPointsY);
+  for (int i = 1; i < 10; i++){
+    Serial.println(listPointsX[i], 4);
+    Serial.println(listPointsY[i], 4);
+  }

   nextGpsData.longitude = listPointsY[2];
   nextGpsData.latitude = listPointsX[2];

-  delay(TEST_DELAY);
+  delay(START_DELAY);
+
   timer1 = millis();
   timer2 = millis();
-
+
   moisture = moistureSensor.getData();
   temperature = temperatureSensor.getData();
   rudderServo.setAngle(0);
-
+
   //currentEmergencyState = emergencyHandler.testConditions(moisture, temperature, sonar, proximitySensorData);

 #endif /* __BOAT__ */
- /********************************************/
 }

 void loop() {

   currentGpsData = gps.getData();
-
-
-#if __BOAT__>0
-
-  xbee.receiveData(); //Update les valeurs du servo, esc et GPS de la sation fixe
-  mode = xbee.getMode();  //Retourne le mode de communication de la station fixe (Manuel,GPS)
-  Serial.print("xbee: ");
-  Serial.print(mode);
-  if(mode == Manuel){
-    servoValue = xbee.getServoValue();
-    escValue = xbee.getEscValue();
-    rudderServo.setAngle(servoValue);
+
+#if __BOAT__>0
+
+  xbee.receiveData();
+  mode = xbee.getMode();
+  if(mode == Manuel)
+  {
+    servoValue = (int)xbee.getServoValue();
+    escValue = (int)xbee.getEscValue();
+    Serial.println(servoValue);
+    Serial.println(escValue);
+    rudderServo.setPosition(servoValue);
     esc.setSpeed(escValue, 0, 100);
   }
-  else if(mode == GPS){
-    gpsValue = xbee.getGPSValue();
+  else if(mode == GPS)
+  {
+    gpsValueLat = xbee.getGpsLatitude();
+    gpsValueLon = xbee.getGpsLongitude();
     esc.setSpeed(MOTOR_SPEED, 0, 100);
   }
-  /*currentEmergencyState = emergencyHandler.testConditions(moisture, temperature, sonar, proximitySensorData);
+  /*
+  currentEmergencyState = emergencyHandler.testConditions(moisture, temperature, sonar, proximitySensorData);
   while (currentEmergencyState != 0) {
     emergencyHandler.handleEmergency(currentEmergencyState);
     Serial.println("In emergency state loop.");
     currentEmergencyState = emergencyHandler.testConditions(moisture, temperature, sonar, proximitySensorData);
   }
-  */
-  if (getDistanceBetweenGPSPoints(currentGpsData, nextGpsData) < PIDController.InertialDerivationDistance && gpsListCounter < listPointsX[0]+1){
-    gpsListCounter = gpsListCounter + 1;
-    nextGpsData.longitude = listPointsY[gpsListCounter];
-    nextGpsData.latitude = listPointsX[gpsListCounter];
-    esc.setSpeed(0, 0, 100);
-    delay(STATIONNARY_DELAY);
-  }
-  else if (getDistanceBetweenGPSPoints(currentGpsData, nextGpsData) < PIDController.InertialDerivationDistance && gpsListCounter == listPointsX[0]+1){
-    esc.setSpeed(0, 0, 100);
-    delay(STATIONNARY_DELAY);
-  }
-  else{
-    esc.setSpeed(MOTOR_SPEED, 0, 100);
-  }
-
-  if (timer1 > millis())  timer1 = millis();
-  if (timer2 > millis())  timer2 = millis();
-
-  if (millis() - timer1 > TS*SECONDS) {
+ */
+ if (timer1 > millis())  timer1 = millis();
+ if (timer2 > millis())  timer2 = millis();

-    timer1 = millis();
-    heading = gyroscope.getData(LSM_303);
-    theta = PIDController.compute_theta(currentGpsData, nextGpsData, heading);
-    rudder = PIDController.control_rudder(theta);
-    rudderServo.setAngle(rudder);
-    Serial.println(getDistanceBetweenGPSPoints(currentGpsData, nextGpsData));
-  }
-
-  if (millis() - timer2 > 5000) {
-
-      timer2 = millis();
-      moisture = moistureSensor.getData();
-      temperature = temperatureSensor.getData();
+ if (currentGpsData.latitude > 4000 && currentGpsData.latitude < 5000 && currentGpsData.longitude > 6000 && currentGpsData.longitude < 8000 && mode != Manuel)
+ {
+    if (getDistanceBetweenGPSPoints(currentGpsData, nextGpsData) < PIDController.InertialDerivationDistance && gpsListCounter < listPointsX[0]+1)
+    {
+      gpsListCounter = gpsListCounter + 1;
+      nextGpsData.longitude = listPointsY[gpsListCounter];
+      nextGpsData.latitude = listPointsX[gpsListCounter];
+      esc.setSpeed(0, 0, 100);
+      delay(STATIONNARY_DELAY);
+    }
+    else if (getDistanceBetweenGPSPoints(currentGpsData, nextGpsData) < PIDController.InertialDerivationDistance && gpsListCounter == listPointsX[0]+1)
+    {
+      esc.setSpeed(0, 0, 100);
+    }
+    else
+    {
+      esc.setSpeed(MOTOR_SPEED, 0, 100);
+    }
+
+    if (millis() - timer1 > TS*SECONDS)
+    {
+      timer1 = millis();

-      moistureSensor.printData(moisture);
-      temperatureSensor.printData(temperature);
-  }
+      heading = gyroscope.getData(LSM_303);
+      theta = PIDController.computeTheta(currentGpsData, nextGpsData, heading);
+      gyroscope.printData(heading);
+      Serial.print("Theta: ");
+      Serial.println(theta);
+      rudder = PIDController.controlRudder(theta);
+      rudderServo.setAngle(rudder);
+    }
+ }
+
+ if (millis() - timer2 > RUN_TIME)
+ {
+    esc.setSpeed(0,0,100);
+    while(true)
+    {
+      servoValue = (int)xbee.getServoValue();
+      escValue = (int)xbee.getEscValue();
+      servoValue = servoValue > MOTOR_SPEED ? MOTOR_SPEED : servoValue;
+      rudderServo.setPosition(servoValue);
+      esc.setSpeed(escValue, 0, 100);
+    }
+ }
 #endif /* __BOAT__ */
 }


Maximale Temperatur

Maximale Temperatur

Maximale Temperatur neu definiert
Klein Flickern wenn smoker fertig (Ausgabe smoker finished)

--- GoTender.ino
+++ GoTender.ino
@@ -136,8 +136,8 @@
 // Private constants **********************************************************
 const char        SOFTWARE_VERSION[10]  = "V0.8";
 #define				UART_SPEED				( 115200 )
-#define           MAX_TEMPERATURE_OVEN ( 300 )
-#define           MAX_TEMPERATURE_MEAT ( 300 )
+#define           MAX_TEMPERATURE_OVEN ( 240 )
+#define           MAX_TEMPERATURE_MEAT ( 240 )

 // Private macros *************************************************************
@@ -1091,6 +1091,10 @@
                {
                   if ( currentNumOfSmokerCycles < numOfSmokerCycles )
                   {
+                     #ifdef DEBUG
+                        Serial.println( "currentNumOfSmokerCycles: " + pulsingCounterSmokerS );
+                     #endif
+
                      if ( pulsingCounterSmokerS == 0) // Smoker On
                      {
                         startSmoker( true );
@@ -1114,10 +1118,20 @@
                      }

                   }
+                  else if ( currentNumOfSmokerCycles == numOfSmokerCycles)
+                  {
+                     startSmoker( false );
+                     displayCommandSmall2("Smoker finished");
+                     #ifdef DEBUG
+                        Serial.println(F("Smoker finished"));
+                     #endif
+
+
+                     currentNumOfSmokerCycles++;
+                  }
                   else
                   {
-                     startSmoker( false );
-                     displayCommandSmall2("Smoker Stop");
+                     startSmoker( false );
                   }
                }
             }
@@ -1154,6 +1168,7 @@
             numOfSmokerCycles = NUM_OF_SMOKER_CYCLES_BUTTON;
             armSmoker( true );
             Serial.println(F("ButtonStateSmoker"));
+            // pulsingCounterS = 0; // TBD: Wenn du willst, dass der Smoker sofort wieder startet, diese Zeile auskommentieren.
          }


Added the I2C object to the struct, added error state to configureToWrite

--- software/_proto_DriverFirmware/MainControlFirmware/MainControlFirmware.ino
+++ software/_proto_DriverFirmware/MainControlFirmware/MainControlFirmware.ino
@@ -28,14 +28,18 @@
 //Create program-wide objects
 SoftwareSerial PCComm(11,10);  //Rx, Tx

-I2cDiscreteIoExpander device(0);
+//I2cDiscreteIoExpander device(0);
 I2cDiscreteIoExpander device2(1);

 Timer t;  //Instantiate timer

-class Display {
+struct Display {
 	public:
-		Display();
+		Display(int deviceID);
+		~Display();
+		void dispRight();
+		void dispLeft();
+		I2cDiscreteIoExpander * device;
 		uint16_t current;
 		uint16_t left;
 		uint16_t right;
@@ -59,6 +63,7 @@
 const uint16_t dispLeft = (dispRight<<8);
 const uint8_t charsL [16] = {0b1000000,0b1111001,0b0100100,0b0110000,0b0011001,0b0010010,0b0000010,0b1111000,0b0000000,0b0010000,0b0001000,0b0000011,0b1000110,0b0100001,0b0000110,0b0001110};  //Contains the constants for the 7seg values
 const uint8_t nothingL = 0b1111111;
+const uint8_t errorL = 0b0110110;

 enum MasterStates {
   POLLING,
@@ -70,7 +75,8 @@

 void loop()
 {
-  static Display disp[2];
+  static Display disp(0);
+  static Display disp2(1);

   static uint16_t timing = 0;
   static uint16_t i = 0;
@@ -84,24 +90,28 @@

 	i = ++i%10;

-	configureToWrite(disp[0].left, LEFT, '5' , ' ');
-	configureToWrite(disp[0].right, RIGHT, '3', i + 48);
+	configureToWrite(disp.left, LEFT, 'F' , 'F');
+	configureToWrite(disp.right, RIGHT, '3', i + 48);
+	configureToWrite(disp2.left, LEFT, 'f' , 'F');
+	configureToWrite(disp2.right, RIGHT, '3', i + 48);
   }

   switch(CurrentState) {
     case DISPLEFT:
-	  disp[0].current = disp[0].left;
+	  disp.dispLeft();
+	  disp2.dispLeft();
       CurrentState = DISPRIGHT;
       break;
     case DISPRIGHT:
-	  disp[0].current = disp[0].right;
+	  disp.dispRight();
+	  disp2.dispRight();
       CurrentState = DISPLEFT;
       break;
   }

-  status = device.digitalWrite(disp[0].current);
-  status2 = device2.digitalWrite(disp[0].current);
+  status = disp.device->digitalWrite(disp.current);
+  status2 = disp2.device->digitalWrite(disp.current);

   /*
@@ -151,6 +161,9 @@
 	else if (left_digit == ' '){
 		to_write += nothingL;
 	}
+	else {
+		to_write += errorL;
+	}

 	if(isdigit(right_digit)){
 		to_write += (charsL[(int)right_digit - 48] << 8);
@@ -161,14 +174,30 @@
 	else if (right_digit == ' '){
 		to_write += (nothingL << 8);
 	}
+	else {
+		to_write += (errorL << 8);
+	}

 }

 //Display constructor
-Display::Display(){
+Display::Display(int deviceID){
+	device = new I2cDiscreteIoExpander(deviceID);
 	current = 0;
 	left = 0;
 	right = 0;
+}
+
+Display::~Display(){
+	delete device;
+}
+
+void Display::dispRight(){
+	current = right;
+}
+
+void Display::dispLeft(){
+	current = left;
 }

 //Display struct classes


ch change

ch change

--- _08_hc-sr04/_02_hc-sr04_lib/_02_hc-sr04_lib.ino
+++ _08_hc-sr04/_02_hc-sr04_lib/_02_hc-sr04_lib.ino
@@ -5,6 +5,7 @@
 #include <Average.h>
 #include <Ultrasonic.h>
 #include <IRremote.h>
+
 IRsend irsend;

 Ultrasonic ultraleft(5,6,30000);   // (Trig PIN,Echo PIN)
@@ -13,6 +14,14 @@
 Average<float> ave(5);

 int power_status = 1 ;
+
+unsigned long  tv_input = 0x20DFD02F;
+unsigned long  tv_right = 0x20DF609F;
+unsigned long  tv_left  = 0x20DFE01F;
+unsigned long  tv_enter = 0x20DF22DD;
+
+int tv_cur_input_no  = 1;
+int tv_move_input_no = 3;

 void setup() {
   Serial.begin (38400);
@@ -31,6 +40,26 @@
   pinMode(2, OUTPUT); // GND for IR
   digitalWrite(2, LOW);

+}
+
+void tv_input_to_blank(){
+  irsend.sendNEC(tv_input, 32);
+  delay(3000);
+  for ( int i = 0 ; i < ( tv_move_input_no - tv_cur_input_no) ; i++ ) {
+    irsend.sendNEC(tv_right, 32);
+    delay(300);
+  }
+  irsend.sendNEC(tv_enter, 32);
+}
+
+void tv_input_to_cur(){
+  irsend.sendNEC(tv_input, 32);
+  delay(3000);
+  for ( int i = 0 ; i < ( tv_move_input_no - tv_cur_input_no) ; i++ ) {
+    irsend.sendNEC(tv_left, 32);
+    delay(300);
+  }
+  irsend.sendNEC(tv_enter, 32);
 }

 long check_distance() {
@@ -59,15 +88,15 @@
   Serial.println(int(ave.stddev()));

   if ( ( ave.stddev() < 10) && ( int(ave.mean()) <= 60 )  && ( power_status == 1) ) {
-    Serial.println("tv off");
-    irsend.sendNEC(0x20DF10EF, 32); // LG TV power code
+    Serial.println("to blank ch");
+    tv_input_to_blank();
     delay(50);
     power_status = 0;
   }

   if ( ( ave.stddev() < 10) && ( int(ave.mean()) > 100 )  && ( power_status == 0) ) {
-    Serial.println("tv on");
-    irsend.sendNEC(0x20DF10EF, 32); // LG TV power code
+    Serial.println("to cur ch");
+    tv_input_to_cur();
     delay(50);
     power_status = 1;
   }


new place for net_serial

new place for net_serial

--- arduino/examples/SLink/SLink.ino
+++ arduino/examples/SLink/SLink.ino
@@ -2,7 +2,7 @@
 #include <AESLib.h>
 #include <cs1a/cs1a.h>
 #include <telehash.h>
-#include <net_serial.h>
+#include <telehash/net_serial.h>

 #define sp Serial.print
 #define speol Serial.println
@@ -70,7 +70,7 @@
   mesh_on_discover(mesh,"auto",mesh_add); // accept anyone
   mesh_on_link(mesh, "test", link_check); // testing the event being triggered
   status = 0;
-//  net = net_serial_new(mesh, NULL, NULL);
+  net = net_serial_new(mesh, NULL);

   LOG("%s",lob_json(mesh_json(mesh)));
 }


Makes sync_get_int return int32_t and use atol

--- sync.ino
+++ sync.ino
@@ -54,7 +54,7 @@
  * Reads serial stream until SYNC_DELIMITER is found or out of space, then
  * uses atoi to convert the string into an integer, returning the result.
  */
-int16_t sync_get_int() {
+int32_t sync_get_int() {
   uint8_t readpos = 0;
   uint8_t c;

@@ -65,7 +65,7 @@
   } while (readpos < sizeof(_sbuf)-1 && Sync.abort == 0);

   _sbuf[readpos] = '\0';
-  return atoi(_sbuf);
+  return atol(_sbuf);
 }

 /**


small fix in output

small fix in output

--- sketch_lg_heartbeat/sketch_lg_heartbeat.ino
+++ sketch_lg_heartbeat/sketch_lg_heartbeat.ino
@@ -53,13 +53,12 @@
 }

 void loop() {
-  static int counter = 0;

   SerialUSB.print("loops (minutes) since restart: ");
   SerialUSB.println(loopcnt);

-  counter++;
-  if ((counter % 5) == 0) lg_heartbeat(); // every 5 loops
+  loopcnt++;
+  if ((loopcnt % 5) == 0) lg_heartbeat(); // every 5 loops

   delay(60000); // one loop per minute
 }


comments optimized

comments optimized

--- PaperTapePuncher.ino
+++ PaperTapePuncher.ino
@@ -16,10 +16,14 @@
 #define PinBit6 7
 #define PinBit7 8
 #define PinTransportHole 9
-//#define PinTransportMotor 11
-#define PinTransportMotor 16
-//#define PinStepSensor 12
-#define PinStepSensor 14
+
+// Arduino Pro Mini (ATMega328)
+#define PinTransportMotor 11
+#define PinStepSensor 12
+
+// Arduino Pro Micro (ATmega32U4)
+//#define PinTransportMotor 16
+//#define PinStepSensor 14

 #define highTime 2
 #define lowTime 18


Minor code changes, updated preamble

Minor code changes, updated preamble

--- examples/SevenSegTest_tiny/SevenSegTest_tiny.ino
+++ examples/SevenSegTest_tiny/SevenSegTest_tiny.ino
@@ -1,6 +1,8 @@
 /* SevenSegTest_tiny
   This is a demonstration of using the Adafruit 4-digit
   7-segment LED backpack with an ATtiny uC.
+  http://www.adafruit.com/category/37_103
+
   It requires the TinyWireM library for I2C communication
   and the Tiny_LEDBackpack library for the various display
   functions.
@@ -35,10 +37,8 @@
 #include <TinyWireM.h>
 #include <Tiny_LEDBackpack.h>

-
 Tiny_7segment sevenseg = Tiny_7segment();
 int led = 10; // indicator LED for ATtiny84. Connect with 100-470ohm resistor
-

 #define i2c_addr 0x70 // stock address for Adafruit 7-segment LED backpack

@@ -51,7 +51,7 @@
   sevenseg.begin(i2c_addr); // initialize HT16K33 controller
 //  sevenseg.blinkRate(2); // set blink rate (0,1,2 or 3)
   sevenseg.clear(); // clear all digits on display
-  sevenseg.writeDisplay();
+  sevenseg.writeDisplay(); // push data to display
   delay(1000);
 }

@@ -60,33 +60,34 @@
   sevenseg.writeDisplay(); // push data to display
   delay(500);
   // Example of writing a multi-digit integer to the display
-  sevenseg.print(4203); // print integer
+  sevenseg.print(1234); // print integer
   sevenseg.writeDisplay(); // push data to display
   delay(500);
   // Example of writing a multi-digit floating point number
   // to the display. The 2nd argument specifies
   // how many digits to display after the decimal. Omit the
   // 2nd argument for integer values.
-  sevenseg.print(12.2, 1); // print a floating point number
+  sevenseg.print(56.7, 1); // print a floating point number
   sevenseg.writeDisplay(); // push data to display
   delay(500);
   sevenseg.clear(); // clear display before writing raw digit
   sevenseg.writeDisplay();
-  // The clear command doesn't need a writeDisplay call afterwards

   // Example of writing a single digit to a specified position on the
   // display. The 1st argument is the digit position (0,1,3,4), 2nd
   // value is the numeric value to display (0-9, a-F), and the 3rd
   // value is whether to show the decimal point. Note that if you
   // don't clear the display ahead of time, any previously displayed
-  // values in other digits will remain visible.
+  // values in other digits will remain visible. Digit position 2 is
+  // the colon, so we don't try to write numbers to it.
   sevenseg.writeDigitNum(3, 9, true); // position 3, value 9, show decimal)
   sevenseg.writeDisplay(); // push the data to the display
   delay(500);

   //-----------------------------------------------------------------
   // Example of a hard-coded write using the
-  // TinyWireM library by itself.
+  // TinyWireM library by itself. This doesn't use the Tiny_LEDBackpack
+  // library at all.
 //  delay(100);
 //  TinyWireM.beginTransmission(0x70); // device address
 //  TinyWireM.send(0x02); // digit address (0x00, 0x02, 0x06, 0x08)
@@ -132,7 +133,7 @@
   // The binary representation would be b01110111.
   //           The bit positions are -->b76543210
   // The corresponding integer value is 119 for A.
-  // Use a binary to decimal calculator to convert.
+  // Use a binary-to-decimal calculator to convert.
   // Below is a list of codes for letters and symbols
 //  sevenseg.writeDigitRaw(0,119); // 119 = "A"
 //  sevenseg.writeDigitRaw(0,124); // 124 = "b"
@@ -168,9 +169,11 @@
 //  sevenseg.writeDigitRaw(0,128); // 128 = "." decimal
 //  sevenseg.writeDigitRaw(0,0); // blank
 //  sevenseg.writeDigitRaw(2,255); // 255 = ":"  colon, always position 2
-//  ****Always follow a writeDigitRaw command with the
-//  writeDisplay(); command to push the data to the
-//  display.*****
+/* *********************
+   Always follow a writeDigitRaw command with the
+   writeDisplay(); command to push the data to the
+   display.
+************************ */
 //  sevenseg.writeDisplay(); // push data to display

   // Example using writeDigitRaw to write numbers or characters


fixed example code

fixed example code

--- examples/rgb_led_color_lib/rgb_led_color_lib.ino
+++ examples/rgb_led_color_lib/rgb_led_color_lib.ino
@@ -6,7 +6,7 @@
 #include <Color.h>

 // these are the pins connected to the RGB LEDs
-int leds[] = {5,6,9};
+int leds[] = {9,10,11};
 Color cur_color = Color(1,1,1);
 float hue = 0;

@@ -14,7 +14,11 @@
 void setup()
 {
   for(int i = 0 ; i < 3; i++ ){
-    pinMode(leds[i], OUTPUT);
+    pinMode(leds[i], OUTPUT);
+    digitalWrite(leds[i], LOW);
+    delay(300);
+    digitalWrite(leds[i], HIGH);
+    delay(300);
   }
 }

@@ -28,8 +32,8 @@
 void rainbow(){
   hue += 0.06;
   if ( hue >=1 ) hue = 0;
-  sat = 1.0;
-  val = 0.4;
+  float sat = 0.8;
+  float val = 0.2;
   cur_color.convert_hcl_to_rgb(hue,sat,val);
   display_color(cur_color);
   delay(20);


disable serial output by default

disable serial output by default

--- examples/RF12/roomNode/roomNode.ino
+++ examples/RF12/roomNode/roomNode.ino
@@ -13,8 +13,8 @@
 #include <avr/sleep.h>
 #include <util/atomic.h>

-#define SERIAL  1   // set to 1 to also report readings on the serial port
-#define DEBUG   1   // set to 1 to display each loop() run and PIR trigger
+#define SERIAL  0   // set to 1 to also report readings on the serial port
+#define DEBUG   0   // set to 1 to display each loop() run and PIR trigger

 #define SHT11_PORT  1   // defined if SHT11 is connected to a port
 #define LDR_PORT    4   // defined if LDR is connected to a port's AIO pin


Register button pressed on button up

Register button pressed on button up

WIP anyway, this firmware will drastically change

--- firmware/HotPotato/HotPotato.ino
+++ firmware/HotPotato/HotPotato.ino
@@ -76,7 +76,7 @@
 */
 ISR (PCINT0_vect) {
   // TO-DO: Investigate ways to debounce the button
-  if (digitalRead(BUTTON_PIN) == HIGH) {
+  if (digitalRead(BUTTON_PIN) == LOW) {
     buttonPressed = true;
   }
 }


fix

fix

Signed-off-by: Robert Nelson <d6c41255011d14bfa93d8562b946ca186cfa0c7b@gmail.com>

--- BatteryCharger/BatteryCharger.ino
+++ BatteryCharger/BatteryCharger.ino
@@ -130,10 +130,10 @@

 		//Turn on
 		if ( relay_mode == RELAY_A1_ON ) {
-			if ( busvoltage_A > 13 ) {
+			if ( busvoltage_A > 13.1 ) {
 				turnon;
 			}
-			else if (( busvoltage_A > 12.6 ) && ( current_mA_B > 400 )) {
+			if (( busvoltage_A > 12.6 ) && ( current_mA_B > 400 )) {
 				turnon;
 			}
 		}
@@ -143,9 +143,9 @@
 			if ( busvoltage_A < 12.1 ) {
 				turnoff;
 			}
-			else if (( current_mA_A > 100 ) && ( current_mA_A < 200 )) {
-				turnon;
-			}
+//			else if (( current_mA_A > 100 ) && ( current_mA_A < 200 )) {
+//				turnoff;
+//			}
 		}

 		counter++;