Small fix

Small fix

--- GrompressorFloat_1_1.ino
+++ GrompressorFloat_1_1.ino
@@ -1,821 +1,819 @@
-#include <Adafruit_GFX.h>
-
-/*
-Grompressor1.ino
-Compressor effect using floating point core. Thanks to Chip Audette!
-Thanks to Paul Stoffregen, www.PJRC.com, that made the great audio library fro Teensy! Plus all the other great stuff!
-This code can be loaded into a Teensy3.5/3.6 with a OnkartGromt OpenEffects project platform. Use a I2C 64x128 OLED screen to show the graphics.
-Hold the On/Off switch for 1 sek to edit the input gain with pot1.
-All in all use the OpenEffectsBox ref2.2 from OnkartGromt with Teensy 3.5/3.6
- */
-#include <EEPROM.h>
-#include <Bounce.h>
-#include <Audio.h>
-#include <Wire.h>
-#include <SPI.h>
-#include <SD.h>
-#include <SerialFlash.h>
-#include <Adafruit_NeoPixel.h>
-#include <Adafruit_GFX.h>
-#include <Adafruit_SSD1306.h>
-#include <math.h>
-#include<string.h>
-#include <OpenAudio_ArduinoLibrary.h> //for AudioConvert_I16toF32, AudioConvert_F32toI16, and AudioEffectGain_F32
-using namespace std;
-
-#define OLED_RESET 4
-Adafruit_SSD1306 display(OLED_RESET);
-//Blue HW:
-#define PIN            8
-//RED HW:
-//#define PIN            3
-
-#define NUMPIXELS      10
-#define bands          6
-Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
-
-// GUItool: begin automatically generated code
-AudioInputI2S        i2sAudioIn1;    //xy=144,485
-AudioConvert_I16toF32    int2Float2;     //xy=317,425
-AudioConvert_I16toF32    int2Float1;     //xy=342,549
-AudioEffectCompressor_F32 comp1;          //xy=510,549
-AudioEffectCompressor_F32 comp2;          //xy=511,425
-AudioConvert_F32toI16    float2Int2;     //xy=654,425
-AudioConvert_F32toI16    float2Int1;     //xy=670,549
-AudioMixer4          mixer1;       //xy=847,444
-AudioMixer4          mixer2;       //xy=851,542
-AudioAnalyzeNoteFrequency notefreq1;
-AudioOutputI2S       i2sAudioOut1;   //xy=1022,482
-AudioConnection         patchCord1(i2sAudioIn1, 0, int2Float2, 0);
-AudioConnection         patchCord2(i2sAudioIn1, 0, mixer1, 1);
-AudioConnection         patchCord3(i2sAudioIn1, 1, int2Float1, 0);
-AudioConnection         patchCord4(i2sAudioIn1, 1, mixer2, 1);
-AudioConnection_F32         patchCord5(int2Float2, comp2);
-AudioConnection_F32         patchCord6(int2Float1, comp1);
-AudioConnection_F32         patchCord7(comp1, float2Int1);
-AudioConnection_F32         patchCord8(comp2, float2Int2);
-AudioConnection         patchCord9(float2Int2, 0, mixer1, 0);
-AudioConnection         patchCord10(float2Int1, 0, mixer2, 0);
-AudioConnection         patchCord11(mixer1, 0, i2sAudioOut1, 0);
-AudioConnection         patchCord12(mixer2, 0, i2sAudioOut1, 1);
-AudioControlSGTL5000     sgtl5000;     //xy=385,640
-// GUItool: end automatically generated code
-AudioAnalyzeRMS          rms1, rms2, rms3, rms4;  //peak indicator/detection
-AudioConnection         patchCord22(i2sAudioIn1, 0, rms2, 0);
-AudioConnection         patchCord23(i2sAudioIn1, 1, rms1, 0);
-AudioConnection         patchCord24(float2Int1, 0, rms3, 0);
-AudioConnection         patchCord25(float2Int1, 0, rms4, 0);
-AudioConnection         patchCord26(float2Int1, 0, notefreq1, 0);
-
-//Pinout board rev1
-int Pot1 = A6;    // select the input pin for the potentiometer
-int Pot2 = A3;    // select the input pin for the potentiometer
-int Pot3 = A2;    // select the input pin for the potentiometer
-int Pot4 = A1;    // select the input pin for the potentiometer
-int CV1 = A10;
-int CV2 = A11;
-
-//For the RED pcb
-//int Tap1 = 0;
-//int Tap2 = 1;
-
-//For Blue/black PCB:
-int Tap1 = 2;
-int Tap2 = 3;
-
-int SW1 = A12;
-int SW2 = A13;
-
-//int ledPin1 = 3;      // select the pin for the LED strip
-int relayL = 4;      // select the pin for the RelayL
-int relayR = 5;      // select the pin for the RelayR
-
-//Variables for values
-boolean Tap1Value = 0;
-boolean Tap2Value = 0;
-float Pot1Value = 0;
-float Pot2Value = 0;
-float Pot3Value = 0;
-float Pot4Value = 0;
-int SW1Value = 0;
-int SW2Value = 0;
-float CV1Value = 0;
-float CV2Value = 0;
-float Pot1ValueOld = 0;  // variable to store the previous value
-float Pot2ValueOld = 0;
-float Pot3ValueOld = 0;
-float Pot4ValueOld = 0;
-int SW1ValueOld = 0;
-int SW2ValueOld = 0;
-int Tap1ValueOld = 1;
-int Tap2ValueOld = 1;
-int CV1ValueOld = 0;
-int CV2ValueOld = 0;
-int Tap1Timer = 0;
-int Tap2Timer = 0;
-float margin  = 0.1;
-//int modulationMode = 0;
-boolean Tap2Pressed = 0;
-//int filterOrder = 24;
-//float ffund = 0;
-
-// Variables
-int ledStateONOFF = LOW;         // the current state of the output pin
-int ledStateONOFF_old = LOW;
-int buttonState0;             // the current reading from the input pin
-int lastButtonState0 = LOW;   // the previous reading from the input pin
-int ledStateBOOST = LOW;         // the current state of the output pin
-int buttonState1;             // the current reading from the input pin
-int lastButtonState1 = LOW;   // the previous reading from the input pin
-
-unsigned long lastDebounceTime0 = 0;  // the last time the output pin was toggled
-unsigned long lastDebounceTime1 = 0;  // the last time the output pin was toggled
-unsigned long debounceDelay = 40;    // the debounce time; increase if the output flickers
-
-float peak = 0.0;
-float peak_2 = 0.0;
-float peak_3 =0.0;
-float peak_4 =0.0;
-float level = 1;
-float InLevel = 1;
-float outLevel = 1;
-float inLevel = 0.05;
-float bypassLevel = 0.42;
-float mixer3Level = 1.0;
-int lastParam = 0;
-
-int updateParam = 0;
-float maxGain = 0;
-float response = 0;
-float thres = -18;
-float hardLimit = 0;
-float attack_1 = 0.01f;
-float decay_1 = 0.2f;
-int Ratio = 3;
-int inlevel = 5;
-
-struct presets {
-  float thres;
-  float attack_1;
-  float decay_1;
-  int Ratio;
-  int inputGain;
-  int actualPreset;
-}  ;
-//new version:
-
-float levelBand[bands] = {30,35, 40, 25, 50,60};
-float levelBandScaled[bands] = {30,35, 40, 25, 50,60};
-float levelBanddB[bands] = {0,0,0, 0, 0,0};
-unsigned int freqBand[bands] = {30, 160, 320, 640, 2000,16000};
-float freqBandDefault[bands] = {80, 160, 320, 640, 2000,16000};
-float freqBandScaled[bands] = {4, 12, 32, 64, 110,110};
-float slopeBand[bands] = {.7,.7,.7,.7,.7,.7};
-float Qlevel[bands] = {1,1,1,1,1,1};
-int updateFilter = 1;
-int savePreset = 0;
-int loadPreset = 0;
-int actualPreset = 1;
-int numberOfPresets = 10;
-unsigned char loByte;
-unsigned char hiByte;
-uint32_t off =pixels.Color(0,0,0);
-uint32_t blue =pixels.Color(0,0,50);
-uint32_t red =pixels.Color(0,50,0);
-uint32_t green =pixels.Color(0,40,0);
-uint32_t yellow =pixels.Color(40,40,0);
-int VUlag = 0;
-const int myInput = AUDIO_INPUT_LINEIN;
-
-Bounce OnOff = Bounce(Tap1, 30 );
-Bounce BoostOnOff = Bounce(Tap2, 30);
-elapsedMillis holdTime;
-elapsedMillis tapInterval;  //timer that is used for tap tempo
-
-void setup() {
-  AudioMemory(60);
-  AudioMemory_F32(40); //allocate Float32 audio data blocks
-  pixels.begin();
-  for (int i = 0;i<NUMPIXELS;i++){
-    pixels.setPixelColor(i,off);
-   }
-  pixels.setPixelColor(0,green);
-  pixels.show();
-  InLevel = float(EEPROM.read(0)/255.0);
-  outLevel = float(EEPROM.read(1));
-  sgtl5000.enable();  // Enable the audio shield
-  sgtl5000.inputSelect(myInput);
-  sgtl5000.volume(0.8);
-  sgtl5000.lineInLevel(15);   // 3.12Vp-p
-  sgtl5000.lineOutLevel(21); // 3.16Vp-p
-  sgtl5000.adcHighPassFilterDisable();
-  //READ PRESET FROM EEPROM
-  if (EEPROM.read(10) == 0) EEPROM.write(10,1);
-
-  //pinMode(ledPin1, OUTPUT); ONLY WITH RED BOARD
-  pinMode(relayL, OUTPUT);
-  pinMode(relayR, OUTPUT);
-  pinMode(Tap1, INPUT);
-  pinMode(Tap2, INPUT);
-
-  mixer1.gain(0, 1);
-  mixer1.gain(1, 0);
-  mixer1.gain(2, 0);
-  mixer1.gain(3, 0);
-  mixer2.gain(0, 1);
-  mixer2.gain(1, 0);
-  mixer2.gain(2, 0);
-  mixer2.gain(3, 0);
-
-  sgtl5000.inputSelect(myInput);
-  sgtl5000.dacVolume (level);
-  sgtl5000.autoVolumeControl(0,0,0,0.7,50,100);  //maxGain,response,hard limit,threshold,attack, decay
-  sgtl5000.autoVolumeDisable();
-  sgtl5000.audioPostProcessorEnable();
-  sgtl5000.eqSelect(3);
-  sgtl5000.eqBands(0,0,0,-1.0,-1.0);
-  sgtl5000.dacVolumeRamp();
-  Serial.begin(115200);
-  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3C (for the 128x64)
-  display.clearDisplay();
-  pixels.show();
-  delay(100);
-  Serial.println("setup complete");
-}
-
-//Main loop
-void loop() {
-  OnOff.update();      //update the bounce
-  BoostOnOff.update();
-
-  // read the value from the pots and buttons:
-  Pot1Value = analogRead(Pot1);    //Level
-  Pot2Value = analogRead(Pot2);    //Width
-  Pot3Value = analogRead(Pot3);    //Freq
-  Pot4Value = analogRead(Pot4);    //Mode
-  Tap1Value = digitalRead(Tap1);   //On off
-  Tap2Value = digitalRead(Tap2);   //Mode/Tap
-  SW1Value = analogRead(SW1);      //Filter char
-  SW2Value = analogRead(SW2);      //Direction
-
-  SW1Value = map(SW1Value, 0, 1023, 5, 0);               //Filter char
-  SW1Value = constrain(SW1Value, 1, 5);
-  SW2Value = map(SW2Value, 0, 1023, 5, 0);               //Direction
-  SW2Value = constrain(SW2Value, 1, 5);
-
-//********************ON -OFF handling**********************
-  buttonState0 = OnOff.read();
-  if (lastButtonState0 != buttonState0){
-      // only toggle the state if the new button state is HIGH
-      if (buttonState0 == LOW) {
-        ledStateONOFF = !ledStateONOFF;
-      }
-  }
-  buttonState1 = BoostOnOff.read();
-  if (lastButtonState1 != buttonState1){
-      // only toggle the state if the new button state is HIGH
-      if (buttonState1 == LOW) {
-        ledStateBOOST = !ledStateBOOST;
-      }
-  }
-  // set the outputs:
-  if (ledStateONOFF != ledStateONOFF_old){
-    pixels.setPixelColor(2, pixels.Color(ledStateONOFF*30,(ledStateONOFF*30),ledStateONOFF*30)); // ONOFF bright white color.
-    digitalWrite(relayL, ledStateONOFF);
-    digitalWrite(relayR, ledStateONOFF);
-    ledStateONOFF_old = ledStateONOFF;
-    pixels.show(); // This sends the updated pixel color to the hardware.
-  }
-  lastButtonState0 = buttonState0;  //save readings to next round
-  lastButtonState1 = buttonState1;
-
-//********************PRESET handling**********************
-//
-if (SW2Value == 1){
-  actualPreset--;
-  if (actualPreset <0)actualPreset = numberOfPresets;
-  delay(50);
-  }
-if (SW2Value == 5){
-  actualPreset++;
-  if (actualPreset > numberOfPresets)actualPreset =0;
-  delay(50);
-  }
-
-//******************** Handle user inputs **********************
-
-if (SW1Value == 1){
-    Ratio ++;
-    if (Ratio >=20)Ratio = 20;
-    updateParam = 1;
-  }
-if (SW1Value == 5){
-   Ratio --;
-   if (Ratio <=0)Ratio = 1;
-   updateParam = 1;
-  }
-int margin = 3;
-
-if ((Pot1Value > Pot1ValueOld+ margin) || (Pot1Value < Pot1ValueOld - margin)){  //LEVEL adjust
-    inlevel = map(Pot1Value, 0, 1023, 15, 0);
-    sgtl5000.lineInLevel(inlevel);   // 3.12Vp-p
-    updateParam = 1;
-}
-
-if ((Pot2Value > Pot2ValueOld+ margin) || (Pot2Value < Pot2ValueOld - margin)){  //Threshold values
-    thres = map(Pot2Value, 0, 1023, 0,-70.0f);
-    updateParam = 1;
-}
-
-if ((Pot3Value > Pot3ValueOld+ margin) || (Pot3Value < Pot3ValueOld - margin)) {    //Attack
-    attack_1 = mapfloat(Pot3Value, 0, 1023, 0.2f,0.001f);
-      Serial.println(attack_1);
-
-    updateParam = 1;
-}
-
-if ((Pot4Value > Pot4ValueOld+ margin) || (Pot4Value < Pot4ValueOld - margin)){  //Release
-    decay_1 = mapfloat(Pot4Value, 0, 1023,2.0, 0.02);
-    updateParam = 1;
-          Serial.println(decay_1);
-}
-if (updateParam == 1){
-    //configure the left and right compressors with the new settings
-    boolean use_HP_filter = true; //enable the software HP filter to get rid of DC
-    setupMyCompressors(use_HP_filter, thres, Ratio, attack_1, decay_1);
-    updateParam = 0;
-    }
-
-//********************Load and saving presets **********************
-if (BoostOnOff.fallingEdge()){
-  holdTime = 0;
-  Serial.println("pushed");
- }
-if (!BoostOnOff.read() && holdTime >1500) {
-        savePreset = 1;
-        pixels.setPixelColor(1, green);
-        pixels.show();
-        Serial.println(holdTime);
-        Serial.println("Save");
-
-  }
-else if (BoostOnOff.risingEdge() && (holdTime >600) && (holdTime <1500)) {
-        actualPreset++;
-        if (actualPreset >=10)actualPreset = 0;
-        loadPreset = 1;
-        pixels.setPixelColor(1, red);
-        pixels.show();
-        Serial.print("Loading new Preset: ");
-        Serial.println(actualPreset);
-        delay(500);
-  }
-else if (BoostOnOff.risingEdge()){
-        loadPreset = 1;
-        Serial.print("Load");
-        Serial.println(holdTime);
-   }
-
-
-if (savePreset == 1){
-    /*
-    uint16_t value = (uint16_t)(levelBand[i]*100);
-    loByte = uint8_t(value & 0x00ff);
-    hiByte = uint8_t((value >> 8 )& 0x00ff);
-    EEPROM.write(20+2*i+actualPreset*70,(loByte));
-    EEPROM.write(20+1+2*i+actualPreset*70,(hiByte));
-    value = (uint16_t)(slopeBand[i]*100);
-    loByte = uint8_t(value & 0x00ff);
-    hiByte = uint8_t((value >> 8 )& 0x00ff);
-    EEPROM.write(40+2*i+actualPreset*70,(loByte));
-    EEPROM.write(40+1+2*i+actualPreset*70,(hiByte));
-    loByte = uint8_t(freqBand[i] & 0x00ff);
-    hiByte = uint8_t((freqBand[i] >> 8 )& 0x00ff);
-    EEPROM.write(60+2*i+actualPreset*70,loByte);
-    EEPROM.write(60+1+2*i+actualPreset*70,hiByte);
-    */
-printParameters(&Serial);
-
-
- Serial.print("Saved");
- Serial.println(actualPreset);
-    display.setCursor(68, 10);
-    display.print("SAVED");
-    display.display();
-    delay(1000);
- savePreset = 0;
- }
-
-if (loadPreset ==1){
-
-    /*
-    unsigned int hg[i];
-    loByte= EEPROM.read(20+2*i+actualPreset*70);
-    hiByte= EEPROM.read(20+1+2*i+actualPreset*70);
-    levelBand[i] = (float)((hiByte << 8) | loByte)/100;
-    loByte= EEPROM.read(40+2*i+actualPreset*70);
-    hiByte= EEPROM.read(40+1+2*i+actualPreset*70);
-    slopeBand[i] = (float)((hiByte << 8) | loByte)/100;
-    loByte = EEPROM.read(60+2*i+actualPreset*70);
-    hiByte = EEPROM.read(60+1+i*2+actualPreset*70);
-    freqBand[i] = (hiByte << 8) | loByte;
-    */
-
-    printParameters(&Serial);
-
-  Serial.print("loading..");
-  Serial.println(actualPreset);
-  loadPreset = 0;
-  updateParam=1;
-    display.setCursor(68, 10);
-    display.print("LOAD");
-    display.display();
-    delay(500);
- }
-display.clearDisplay();
-
-//*******************INPUT/OUTPUT LEVEL ADJUST************************
-if (SW1Value == 5){    //LP pos for input level
- if (!Tap1Value && (Tap1Value == Tap1ValueOld)){    //When Mode/tap is held down you can adjust the input gain of the input
- // Serial.print("TIME");
-   Tap1Timer++;
-  if (Tap1Timer > 15){
-    InLevel = analogRead(Pot1);
-    InLevel = mapfloat(InLevel,0,1023,10,1);
-    InLevel = InLevel * inLevel; //multiply by constant inLevel
-    delay(100);
-    display.setTextSize(1);
-    display.setTextColor(WHITE);
-    display.setCursor(5, 10);
-    display.print("Input:");
-    display.print(InLevel);
-    display.display();
-    }
-  }
-  else if (Tap1Timer > 15){    //only write to EEPROM once
-    EEPROM.write(0, InLevel*255);
-  //  Serial.println(InLevel);
-    Tap1Timer = 0;
-  }
-  else if (Tap1Value){
-  //  peak = peak1.read();   //read the signal output peak
-  if (peak == -1)(peak = 0);
-  //analogWrite(ledPin2, peak*100);
-  //pixels.setPixelColor(1, pixels.Color(peak*100,peak*100,0));
-  //pixels.show();
-  }
-}
-
-if (SW1Value == 1){    //HP pos for Output level
- if (!Tap1Value && (Tap1Value == Tap1ValueOld)){    //When Mode/tap is held down you can adjust the input gain of the input
- // Serial.print("TIME");
-   Tap1Timer++;
-  if (Tap1Timer > 15){
-    outLevel = analogRead(Pot1);
-    outLevel = mapfloat(outLevel,0,1023,10,1);
-    delay(100);
-   // analogWrite(ledPin2, 255);
-    //pixels.setPixelColor(1, pixels.Color(70,70,0));
-    //display.clearDisplay();
-    display.setTextSize(1);
-    display.setTextColor(WHITE);
-    display.setCursor(5, 10);
-    display.print("Output:");
-    display.print(outLevel);
-    display.display();
-    }
-  }
-  else if (Tap1Timer > 15){    //only write to EEPROM once
-    EEPROM.write(1, outLevel);
-    Tap1Timer = 0;
-  }
-  else if (Tap1Value){
-  //  peak = peak1.read();   //read the signal output peak
-  if (peak == -1)(peak = 0);
-  //analogWrite(ledPin2, peak*100);
-  //pixels.setPixelColor(1, pixels.Color((peak)*100,(peak)*100,0));
-  //pixels.show();
-  }
-}
-
- ////// VU meter ////////////
-//Gain reduction meter
-
-for(int i=NUMPIXELS;i>=3;i--){
-  float reduction = abs(comp1.getCurrentGain_dB());
-  int lvl = NUMPIXELS-(reduction/5);       //120*7=840
-  int grade = 360+reduction*960;
-  //Serial.println(peak_2);
-  grade = grade -(120*lvl);
-
-  if ((i > lvl)&&(i == 5))pixels.setPixelColor(i,yellow); // yellow color.
-  if ((i > lvl)&&(i == 4))pixels.setPixelColor(i,red); // red color.
-  else if (i > lvl)pixels.setPixelColor(i,green); // green color.
-  //else if (i == lvl){
- //   pixels.setPixelColor(i, pixels.Color(grade,0,0)); // green color.
-  //}
-  else     {
-    pixels.setPixelColor(i,off); // no color
-  }
-}
-  pixels.show(); // This sends the updated pixel color to the hardware.
-
-///////////end VU meter/////////
-
-///////////////////////////PLOTTING OF COMPRESSOR CURVE//////////////////////////////////
-//Draw background:
-int top = 20;
-int signalWidth = 6;
-display.drawLine(0,top,128,top, WHITE);
-display.drawLine(0,64,0,top, WHITE);
-display.drawLine(signalWidth+1,64,signalWidth+1,top, WHITE);
-display.drawLine(signalWidth*2+2,64,signalWidth*2+2,top, WHITE);
-display.drawLine(127-signalWidth*2-2,64,127-signalWidth*2-2,top, WHITE);
-display.drawLine(127-signalWidth-1,64,127-signalWidth-1,top, WHITE);
-display.drawLine(127,64,127,top, WHITE);
-
-int thresh_disp = map(thres,0,-70,(64-top),10);
-int zeroX = signalWidth*2+8;
-int diffY = (64-thresh_disp) - top;
-int kneeX = zeroX+thresh_disp;
-int kneeY = 64-thresh_disp;
-int Xtop = kneeX + diffY*Ratio;
-
-display.drawLine(zeroX,64, kneeX, kneeY, WHITE);   //first slope
-display.drawLine(kneeX, kneeY, Xtop,top, WHITE);   //second slope
-display.fillRect(127-signalWidth*2-1,top+1,signalWidth,(64-top),BLACK);
-display.fillRect(127-signalWidth,top+1,signalWidth,(64-top),BLACK);
-
-  //read the signal input peak
-if (rms1.available()){
-  peak = rms1.read();
-  float peakDisp1 = top+((64-top)*(1-peak));
-  display.fillRect(1,peakDisp1,signalWidth,(64),WHITE);
-  }
-
-if (rms2.available()) {
-  peak_2 = rms2.read();    //Output peak
-  float peakDisp2 = top+((64-top)*(1-peak_2));
-  display.fillRect(2+signalWidth,peakDisp2,signalWidth,(64),WHITE);
-  }
-//draw gain reduction
- // (comp2.getCurrentGain_dB());
-display.fillRect(127-signalWidth*2-1,top+1,signalWidth,abs(comp1.getCurrentGain_dB()),WHITE);
-display.fillRect(127-signalWidth,top+1,signalWidth,abs(comp2.getCurrentGain_dB()),WHITE);
- /////////////////////END PLOTTING///////////////////////////////
-
- ////// VU meter ////////////
- /*
-VUlag++;
-if (VUlag >0){
-for(int i=3;i<=NUMPIXELS;i++){
-  int lvl = 3+(peak_2*12);       //120*7=840
-  int grade = 360+peak_2*960;
-  //Serial.println(peak_2);
-  grade = grade -(120*lvl);
-  if (i < lvl){
-    pixels.setPixelColor(i, pixels.Color(80,0,0)); // green color.
-  }
-  else if (i == lvl){
-    pixels.setPixelColor(i, pixels.Color(grade,0,0)); // green color.
-  }
-  else     {
-    pixels.setPixelColor(i, pixels.Color(0,0,0)); // no color
-  }
-}
-  pixels.show(); // This sends the updated pixel color to the hardware.
- // VUlag = 0;
-}
-*/
-///////////end VU meter/////////
-
- // int cpuCap = AudioProcessorUsageMax();
-  display.setTextSize(1);
-  display.setTextColor(WHITE);
-  display.setCursor(10, 10);
-
-  display.print("Th:");
-  display.print((int)thres);
-  display.print("dB");
-
-  display.setCursor(17, 23);
-  display.print(Ratio);
-  display.print(":1");
-
-  display.setCursor(100, 10);
-  display.print("P:");
-  display.print(actualPreset);
-
-  display.setCursor(30, 56);
-  display.print("A:");
-  display.print((int)(attack_1*1000));
-  display.print("ms");
-  display.setCursor(70, 56);
-  display.print(" R:");
-  display.print((int)(decay_1*1000));
-  display.display();
-
- /*
-   Serial.print(" Last: ");
-   Serial.print(Pot1ValueOld);
-   Serial.print(" Last: ");
-   Serial.println(Pot1Value);
-
-   Serial.print(" Freq2: ");
-   Serial.print(freqBand[2]);
-   Serial.print(" Freq3: ");
-   Serial.print(freqBand[3]);
-   Serial.print(" Freq4: ");
-   Serial.print(freqBand[4]);
-   Serial.print(" Freq5: ");
-   Serial.println(freqBand[5]);
-   Serial.print(" Peak2: ");
-   Serial.println(peak_2);
-   */
-   Pot1ValueOld = Pot1Value;
-   Pot2ValueOld = Pot2Value;
-   Pot3ValueOld = Pot3Value;
-   Pot4ValueOld = Pot4Value;
-   SW1ValueOld = SW1Value;
-   SW2ValueOld = SW2Value;
-   Tap1ValueOld = Tap1Value;
-   Tap2ValueOld = Tap2Value;
-   CV1ValueOld = CV1Value;
-   CV2ValueOld = CV2Value;
-//   modFreqOld = modFreq;
-//   spanfreqOld = spanfreq;
-//   movingfreqOld = movingfreq;
-
-    //printCPUandMemoryUsage(&Serial);
-   //AudioInterrupts();
-   //AudioNoInterrupts();
- //  pixels.show();
-//printCompressorState(&Serial);
-/*  if (notefreq1.available()){
-  Serial.println(notefreq1.read());
- }
- */
-}
-
-void printCompressorState(Stream *s) {
-  s->print("Current Compressor: Pre-Gain (dB) = ");
-  s->print(comp1.getPreGain_dB());
-  s->print(", Level (dBFS) = ");
-  s->print(comp1.getCurrentLevel_dBFS());
-  s->print(", ");
-  s->print(comp2.getCurrentLevel_dBFS());
-  s->print(", Dynamic Gain L/R (dB) = ");
-  s->print(comp1.getCurrentGain_dB());
-  s->print(", ");
-  s->print(comp2.getCurrentGain_dB());
-  s->println();
-};
-
-void printParameters(Stream *s) {
-    s->print("Preset: ");
-    s->print(actualPreset);
-    s->print(" InputGain: ");
-    s->print(inLevel);
-    s->print(" Treshold: ");
-    s->print(thres);
-    s->print(" Ratio: 1: ");
-    s->print(Ratio);
-    s->print(" Attack: ");
-    s->print(attack_1);
-    s->print(" Release: ");
-    s->println(decay_1);
-};
-/* fscale
- Floating Point Autoscale Function V0.1
- Paul Badger 2007
- Modified from code by Greg Shakar
-
- This function will scale one set of floating point numbers (range) to another set of floating point numbers (range)
- It has a "curve" parameter so that it can be made to favor either the end of the output. (Logarithmic mapping)
-*/
-float fscale( float originalMin, float originalMax, float newBegin, float
-newEnd, float inputValue, float curve){
-
-  float OriginalRange = 0;
-  float NewRange = 0;
-  float zeroRefCurVal = 0;
-  float normalizedCurVal = 0;
-  float rangedValue = 0;
-  boolean invFlag = 0;
-
-
-  // condition curve parameter
-  // limit range
-
-  if (curve > 10) curve = 10;
-  if (curve < -10) curve = -10;
-
-  curve = (curve * -.1) ; // - invert and scale - this seems more intuitive - postive numbers give more weight to high end on output
-  curve = pow(10, curve); // convert linear scale into lograthimic exponent for other pow function
-
-  /*
-   Serial.println(curve * 100, DEC);   // multply by 100 to preserve resolution
-   Serial.println();
-   */
-
-  // Check for out of range inputValues
-  if (inputValue < originalMin) {
-    inputValue = originalMin;
-  }
-  if (inputValue > originalMax) {
-    inputValue = originalMax;
-  }
-
-  // Zero Refference the values
-  OriginalRange = originalMax - originalMin;
-
-  if (newEnd > newBegin){
-    NewRange = newEnd - newBegin;
-  }
-  else
-  {
-    NewRange = newBegin - newEnd;
-    invFlag = 1;
-  }
-
-  zeroRefCurVal = inputValue - originalMin;
-  normalizedCurVal  =  zeroRefCurVal / OriginalRange;   // normalize to 0 - 1 float
-
-  /*
-  Serial.print(OriginalRange, DEC);
-   Serial.print("   ");
-   Serial.print(NewRange, DEC);
-   Serial.print("   ");
-   Serial.println(zeroRefCurVal, DEC);
-   Serial.println();
-   */
-
-  // Check for originalMin > originalMax  - the math for all other cases i.e. negative numbers seems to work out fine
-  if (originalMin > originalMax ) {
-    return 0;
-  }
-
-  if (invFlag == 0){
-    rangedValue =  (pow(normalizedCurVal, curve) * NewRange) + newBegin;
-
-  }
-  else     // invert the ranges
-  {
-    rangedValue =  newBegin - (pow(normalizedCurVal, curve) * NewRange);
-  }
-
-  return rangedValue;
-}
-
-//************EEPROM functions****************
-//This function will write a 2 byte (16bit) uint16_t to the eeprom at
-//the specified address to address + 1.
-void EEPROMWrite_uint16_t(int address, uint16_t value)
-      {
-      //Decomposition from a uint16_t to 2 bytes by using bitshift.
-      //One = Most significant -> Two = Least significant byte
-      byte two = ((value >> 0xFF) & 0xFF);
-      byte one = ((value >> 8) & 0xFF);
-
-      //Write the 2 bytes into the eeprom memory.
-      EEPROM.write(address, two);
-      EEPROM.write(address + 1, one);
-      }
-
-long EEPROMRead_uint16_t(int address)
-      {
-      //Read the 2 bytes from the eeprom memory.
-
-      uint16_t two = EEPROM.read(address);
-      uint16_t one = EEPROM.read(address + 1);
-
-      //Return the recomposed uint16_t by using bitshift.
-      return ((two << 16) & 0xFF) + ((one << 24) & 0xFFFF);
-      }
-
-
-void printCPUandMemoryUsage(Stream *s) {
-  s->print("Usage/Max: ");
-  s->print("comp1 CPU = "); s->print(comp1.processorUsage()); s->print("/"); s->print(comp1.processorUsageMax()); s->print(", ");
-  s->print("all CPU = " ); s->print(AudioProcessorUsage()); s->print("/");  s->print(AudioProcessorUsageMax()); s->print(", ");
-  s->print("Int16 Mem = "); s->print(AudioMemoryUsage()); s->print("/"); s->print(AudioMemoryUsageMax()); s->print(", ");
-  s->print("Float Mem = "); s->print(AudioMemoryUsage_F32()); s->print("/"); s->print(AudioMemoryUsageMax_F32()); s->print(", ");
-  s->println();
-};
-
-/////////////////////////////////////////
-
-float mapfloat(float x, float in_min, float in_max, float out_min, float out_max)
-{
-  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
-}
-
-//define a function to configure the left and right compressors
-void setupMyCompressors(boolean use_HP_filter, float knee_dBFS, float comp_ratio, float attack_sec, float release_sec) {
-  comp1.enableHPFilter(use_HP_filter);   comp2.enableHPFilter(use_HP_filter);
-  comp1.setThresh_dBFS(knee_dBFS);       comp2.setThresh_dBFS(knee_dBFS);
-  comp1.setCompressionRatio(comp_ratio); comp2.setCompressionRatio(comp_ratio);
-
-  float fs_Hz = AUDIO_SAMPLE_RATE;
-  comp1.setAttack_sec(attack_sec, fs_Hz);       comp2.setAttack_sec(attack_sec, fs_Hz);
-  comp1.setRelease_sec(release_sec, fs_Hz);     comp2.setRelease_sec(release_sec, fs_Hz);
-}
+/*
+Grompressor1.ino
+Compressor effect using floating point core. Thanks to Chip Audette!
+Thanks to Paul Stoffregen, www.PJRC.com, that made the great audio library fro Teensy! Plus all the other great stuff!
+This code can be loaded into a Teensy3.5/3.6 with a OnkartGromt OpenEffects project platform. Use a I2C 64x128 OLED screen to show the graphics.
+Hold the On/Off switch for 1 sek to edit the input gain with pot1.
+All in all use the OpenEffectsBox ref2.2 from OnkartGromt with Teensy 3.5/3.6
+ */
+#include <EEPROM.h>
+#include <Bounce.h>
+#include <Audio.h>
+#include <Wire.h>
+#include <SPI.h>
+#include <SD.h>
+#include <SerialFlash.h>
+#include <Adafruit_NeoPixel.h>
+#include <Adafruit_GFX.h>
+#include <Adafruit_SSD1306.h>
+#include <math.h>
+#include<string.h>
+#include <OpenAudio_ArduinoLibrary.h> //for AudioConvert_I16toF32, AudioConvert_F32toI16, and AudioEffectGain_F32
+using namespace std;
+
+#define OLED_RESET 4
+Adafruit_SSD1306 display(OLED_RESET);
+//Blue HW:
+#define PIN            8
+//RED HW:
+//#define PIN            3
+
+#define NUMPIXELS      10
+#define bands          6
+Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
+
+// GUItool: begin automatically generated code
+AudioInputI2S        i2sAudioIn1;    //xy=144,485
+AudioConvert_I16toF32    int2Float2;     //xy=317,425
+AudioConvert_I16toF32    int2Float1;     //xy=342,549
+AudioEffectCompressor_F32 comp1;          //xy=510,549
+AudioEffectCompressor_F32 comp2;          //xy=511,425
+AudioConvert_F32toI16    float2Int2;     //xy=654,425
+AudioConvert_F32toI16    float2Int1;     //xy=670,549
+AudioMixer4          mixer1;       //xy=847,444
+AudioMixer4          mixer2;       //xy=851,542
+AudioAnalyzeNoteFrequency notefreq1;
+AudioOutputI2S       i2sAudioOut1;   //xy=1022,482
+AudioConnection         patchCord1(i2sAudioIn1, 0, int2Float2, 0);
+AudioConnection         patchCord2(i2sAudioIn1, 0, mixer1, 1);
+AudioConnection         patchCord3(i2sAudioIn1, 1, int2Float1, 0);
+AudioConnection         patchCord4(i2sAudioIn1, 1, mixer2, 1);
+AudioConnection_F32         patchCord5(int2Float2, comp2);
+AudioConnection_F32         patchCord6(int2Float1, comp1);
+AudioConnection_F32         patchCord7(comp1, float2Int1);
+AudioConnection_F32         patchCord8(comp2, float2Int2);
+AudioConnection         patchCord9(float2Int2, 0, mixer1, 0);
+AudioConnection         patchCord10(float2Int1, 0, mixer2, 0);
+AudioConnection         patchCord11(mixer1, 0, i2sAudioOut1, 0);
+AudioConnection         patchCord12(mixer2, 0, i2sAudioOut1, 1);
+AudioControlSGTL5000     sgtl5000;     //xy=385,640
+// GUItool: end automatically generated code
+AudioAnalyzeRMS          rms1, rms2, rms3, rms4;  //peak indicator/detection
+AudioConnection         patchCord22(i2sAudioIn1, 0, rms2, 0);
+AudioConnection         patchCord23(i2sAudioIn1, 1, rms1, 0);
+AudioConnection         patchCord24(float2Int1, 0, rms3, 0);
+AudioConnection         patchCord25(float2Int1, 0, rms4, 0);
+AudioConnection         patchCord26(float2Int1, 0, notefreq1, 0);
+
+//Pinout board rev1
+int Pot1 = A6;    // select the input pin for the potentiometer
+int Pot2 = A3;    // select the input pin for the potentiometer
+int Pot3 = A2;    // select the input pin for the potentiometer
+int Pot4 = A1;    // select the input pin for the potentiometer
+int CV1 = A10;
+int CV2 = A11;
+
+//For the RED pcb
+//int Tap1 = 0;
+//int Tap2 = 1;
+
+//For Blue/black PCB:
+int Tap1 = 2;
+int Tap2 = 3;
+
+int SW1 = A12;
+int SW2 = A13;
+
+//int ledPin1 = 3;      // select the pin for the LED strip
+int relayL = 4;      // select the pin for the RelayL
+int relayR = 5;      // select the pin for the RelayR
+
+//Variables for values
+boolean Tap1Value = 0;
+boolean Tap2Value = 0;
+float Pot1Value = 0;
+float Pot2Value = 0;
+float Pot3Value = 0;
+float Pot4Value = 0;
+int SW1Value = 0;
+int SW2Value = 0;
+float CV1Value = 0;
+float CV2Value = 0;
+float Pot1ValueOld = 0;  // variable to store the previous value
+float Pot2ValueOld = 0;
+float Pot3ValueOld = 0;
+float Pot4ValueOld = 0;
+int SW1ValueOld = 0;
+int SW2ValueOld = 0;
+int Tap1ValueOld = 1;
+int Tap2ValueOld = 1;
+int CV1ValueOld = 0;
+int CV2ValueOld = 0;
+int Tap1Timer = 0;
+int Tap2Timer = 0;
+float margin  = 0.1;
+//int modulationMode = 0;
+boolean Tap2Pressed = 0;
+//int filterOrder = 24;
+//float ffund = 0;
+
+// Variables
+int ledStateONOFF = LOW;         // the current state of the output pin
+int ledStateONOFF_old = LOW;
+int buttonState0;             // the current reading from the input pin
+int lastButtonState0 = LOW;   // the previous reading from the input pin
+int ledStateBOOST = LOW;         // the current state of the output pin
+int buttonState1;             // the current reading from the input pin
+int lastButtonState1 = LOW;   // the previous reading from the input pin
+
+unsigned long lastDebounceTime0 = 0;  // the last time the output pin was toggled
+unsigned long lastDebounceTime1 = 0;  // the last time the output pin was toggled
+unsigned long debounceDelay = 40;    // the debounce time; increase if the output flickers
+
+float peak = 0.0;
+float peak_2 = 0.0;
+float peak_3 =0.0;
+float peak_4 =0.0;
+float level = 1;
+float InLevel = 1;
+float outLevel = 1;
+float inLevel = 0.05;
+float bypassLevel = 0.42;
+float mixer3Level = 1.0;
+int lastParam = 0;
+
+int updateParam = 0;
+float maxGain = 0;
+float response = 0;
+float thres = -18;
+float hardLimit = 0;
+float attack_1 = 0.01f;
+float decay_1 = 0.2f;
+int Ratio = 3;
+int inlevel = 5;
+
+struct presets {
+  float thres;
+  float attack_1;
+  float decay_1;
+  int Ratio;
+  int inputGain;
+  int actualPreset;
+}  ;
+//new version:
+
+float levelBand[bands] = {30,35, 40, 25, 50,60};
+float levelBandScaled[bands] = {30,35, 40, 25, 50,60};
+float levelBanddB[bands] = {0,0,0, 0, 0,0};
+unsigned int freqBand[bands] = {30, 160, 320, 640, 2000,16000};
+float freqBandDefault[bands] = {80, 160, 320, 640, 2000,16000};
+float freqBandScaled[bands] = {4, 12, 32, 64, 110,110};
+float slopeBand[bands] = {.7,.7,.7,.7,.7,.7};
+float Qlevel[bands] = {1,1,1,1,1,1};
+int updateFilter = 1;
+int savePreset = 0;
+int loadPreset = 0;
+int actualPreset = 1;
+int numberOfPresets = 10;
+unsigned char loByte;
+unsigned char hiByte;
+uint32_t off =pixels.Color(0,0,0);
+uint32_t blue =pixels.Color(0,0,50);
+uint32_t red =pixels.Color(0,50,0);
+uint32_t green =pixels.Color(0,40,0);
+uint32_t yellow =pixels.Color(40,40,0);
+int VUlag = 0;
+const int myInput = AUDIO_INPUT_LINEIN;
+
+Bounce OnOff = Bounce(Tap1, 30 );
+Bounce BoostOnOff = Bounce(Tap2, 30);
+elapsedMillis holdTime;
+elapsedMillis tapInterval;  //timer that is used for tap tempo
+
+void setup() {
+  AudioMemory(60);
+  AudioMemory_F32(40); //allocate Float32 audio data blocks
+  pixels.begin();
+  for (int i = 0;i<NUMPIXELS;i++){
+    pixels.setPixelColor(i,off);
+   }
+  pixels.setPixelColor(0,green);
+  pixels.show();
+  InLevel = float(EEPROM.read(0)/255.0);
+  outLevel = float(EEPROM.read(1));
+  sgtl5000.enable();  // Enable the audio shield
+  sgtl5000.inputSelect(myInput);
+  sgtl5000.volume(0.8);
+  sgtl5000.lineInLevel(15);   // 3.12Vp-p
+  sgtl5000.lineOutLevel(21); // 3.16Vp-p
+  sgtl5000.adcHighPassFilterDisable();
+  //READ PRESET FROM EEPROM
+  if (EEPROM.read(10) == 0) EEPROM.write(10,1);
+
+  //pinMode(ledPin1, OUTPUT); ONLY WITH RED BOARD
+  pinMode(relayL, OUTPUT);
+  pinMode(relayR, OUTPUT);
+  pinMode(Tap1, INPUT);
+  pinMode(Tap2, INPUT);
+
+  mixer1.gain(0, 1);
+  mixer1.gain(1, 0);
+  mixer1.gain(2, 0);
+  mixer1.gain(3, 0);
+  mixer2.gain(0, 1);
+  mixer2.gain(1, 0);
+  mixer2.gain(2, 0);
+  mixer2.gain(3, 0);
+
+  sgtl5000.inputSelect(myInput);
+  sgtl5000.dacVolume (level);
+  sgtl5000.autoVolumeControl(0,0,0,0.7,50,100);  //maxGain,response,hard limit,threshold,attack, decay
+  sgtl5000.autoVolumeDisable();
+  sgtl5000.audioPostProcessorEnable();
+  sgtl5000.eqSelect(3);
+  sgtl5000.eqBands(0,0,0,-1.0,-1.0);
+  sgtl5000.dacVolumeRamp();
+  Serial.begin(115200);
+  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3C (for the 128x64)
+  display.clearDisplay();
+  pixels.show();
+  delay(100);
+  Serial.println("setup complete");
+}
+
+//Main loop
+void loop() {
+  OnOff.update();      //update the bounce
+  BoostOnOff.update();
+
+  // read the value from the pots and buttons:
+  Pot1Value = analogRead(Pot1);    //Level
+  Pot2Value = analogRead(Pot2);    //Width
+  Pot3Value = analogRead(Pot3);    //Freq
+  Pot4Value = analogRead(Pot4);    //Mode
+  Tap1Value = digitalRead(Tap1);   //On off
+  Tap2Value = digitalRead(Tap2);   //Mode/Tap
+  SW1Value = analogRead(SW1);      //Filter char
+  SW2Value = analogRead(SW2);      //Direction
+
+  SW1Value = map(SW1Value, 0, 1023, 5, 0);               //Filter char
+  SW1Value = constrain(SW1Value, 1, 5);
+  SW2Value = map(SW2Value, 0, 1023, 5, 0);               //Direction
+  SW2Value = constrain(SW2Value, 1, 5);
+
+//********************ON -OFF handling**********************
+  buttonState0 = OnOff.read();
+  if (lastButtonState0 != buttonState0){
+      // only toggle the state if the new button state is HIGH
+      if (buttonState0 == LOW) {
+        ledStateONOFF = !ledStateONOFF;
+      }
+  }
+  buttonState1 = BoostOnOff.read();
+  if (lastButtonState1 != buttonState1){
+      // only toggle the state if the new button state is HIGH
+      if (buttonState1 == LOW) {
+        ledStateBOOST = !ledStateBOOST;
+      }
+  }
+  // set the outputs:
+  if (ledStateONOFF != ledStateONOFF_old){
+    pixels.setPixelColor(2, pixels.Color(ledStateONOFF*30,(ledStateONOFF*30),ledStateONOFF*30)); // ONOFF bright white color.
+    digitalWrite(relayL, ledStateONOFF);
+    digitalWrite(relayR, ledStateONOFF);
+    ledStateONOFF_old = ledStateONOFF;
+    pixels.show(); // This sends the updated pixel color to the hardware.
+  }
+  lastButtonState0 = buttonState0;  //save readings to next round
+  lastButtonState1 = buttonState1;
+
+//********************PRESET handling**********************
+//
+if (SW2Value == 1){
+  actualPreset--;
+  if (actualPreset <0)actualPreset = numberOfPresets;
+  delay(50);
+  }
+if (SW2Value == 5){
+  actualPreset++;
+  if (actualPreset > numberOfPresets)actualPreset =0;
+  delay(50);
+  }
+
+//******************** Handle user inputs **********************
+
+if (SW1Value == 1){
+    Ratio ++;
+    if (Ratio >=20)Ratio = 20;
+    updateParam = 1;
+  }
+if (SW1Value == 5){
+   Ratio --;
+   if (Ratio <=0)Ratio = 1;
+   updateParam = 1;
+  }
+int margin = 3;
+
+if ((Pot1Value > Pot1ValueOld+ margin) || (Pot1Value < Pot1ValueOld - margin)){  //LEVEL adjust
+    inlevel = map(Pot1Value, 0, 1023, 15, 0);
+    sgtl5000.lineInLevel(inlevel);   // 3.12Vp-p
+    updateParam = 1;
+}
+
+if ((Pot2Value > Pot2ValueOld+ margin) || (Pot2Value < Pot2ValueOld - margin)){  //Threshold values
+    thres = map(Pot2Value, 0, 1023, 0,-70.0f);
+    updateParam = 1;
+}
+
+if ((Pot3Value > Pot3ValueOld+ margin) || (Pot3Value < Pot3ValueOld - margin)) {    //Attack
+    attack_1 = mapfloat(Pot3Value, 0, 1023, 0.2f,0.001f);
+      Serial.println(attack_1);
+
+    updateParam = 1;
+}
+
+if ((Pot4Value > Pot4ValueOld+ margin) || (Pot4Value < Pot4ValueOld - margin)){  //Release
+    decay_1 = mapfloat(Pot4Value, 0, 1023,2.0, 0.02);
+    updateParam = 1;
+          Serial.println(decay_1);
+}
+if (updateParam == 1){
+    //configure the left and right compressors with the new settings
+    boolean use_HP_filter = true; //enable the software HP filter to get rid of DC
+    setupMyCompressors(use_HP_filter, thres, Ratio, attack_1, decay_1);
+    updateParam = 0;
+    }
+
+//********************Load and saving presets **********************
+if (BoostOnOff.fallingEdge()){
+  holdTime = 0;
+  Serial.println("pushed");
+ }
+if (!BoostOnOff.read() && holdTime >1500) {
+        savePreset = 1;
+        pixels.setPixelColor(1, green);
+        pixels.show();
+        Serial.println(holdTime);
+        Serial.println("Save");
+
+  }
+else if (BoostOnOff.risingEdge() && (holdTime >600) && (holdTime <1500)) {
+        actualPreset++;
+        if (actualPreset >=10)actualPreset = 0;
+        loadPreset = 1;
+        pixels.setPixelColor(1, red);
+        pixels.show();
+        Serial.print("Loading new Preset: ");
+        Serial.println(actualPreset);
+        delay(500);
+  }
+else if (BoostOnOff.risingEdge()){
+        loadPreset = 1;
+        Serial.print("Load");
+        Serial.println(holdTime);
+   }
+
+
+if (savePreset == 1){
+    /*
+    uint16_t value = (uint16_t)(levelBand[i]*100);
+    loByte = uint8_t(value & 0x00ff);
+    hiByte = uint8_t((value >> 8 )& 0x00ff);
+    EEPROM.write(20+2*i+actualPreset*70,(loByte));
+    EEPROM.write(20+1+2*i+actualPreset*70,(hiByte));
+    value = (uint16_t)(slopeBand[i]*100);
+    loByte = uint8_t(value & 0x00ff);
+    hiByte = uint8_t((value >> 8 )& 0x00ff);
+    EEPROM.write(40+2*i+actualPreset*70,(loByte));
+    EEPROM.write(40+1+2*i+actualPreset*70,(hiByte));
+    loByte = uint8_t(freqBand[i] & 0x00ff);
+    hiByte = uint8_t((freqBand[i] >> 8 )& 0x00ff);
+    EEPROM.write(60+2*i+actualPreset*70,loByte);
+    EEPROM.write(60+1+2*i+actualPreset*70,hiByte);
+    */
+printParameters(&Serial);
+
+
+ Serial.print("Saved");
+ Serial.println(actualPreset);
+    display.setCursor(68, 10);
+    display.print("SAVED");
+    display.display();
+    delay(1000);
+ savePreset = 0;
+ }
+
+if (loadPreset ==1){
+
+    /*
+    unsigned int hg[i];
+    loByte= EEPROM.read(20+2*i+actualPreset*70);
+    hiByte= EEPROM.read(20+1+2*i+actualPreset*70);
+    levelBand[i] = (float)((hiByte << 8) | loByte)/100;
+    loByte= EEPROM.read(40+2*i+actualPreset*70);
+    hiByte= EEPROM.read(40+1+2*i+actualPreset*70);
+    slopeBand[i] = (float)((hiByte << 8) | loByte)/100;
+    loByte = EEPROM.read(60+2*i+actualPreset*70);
+    hiByte = EEPROM.read(60+1+i*2+actualPreset*70);
+    freqBand[i] = (hiByte << 8) | loByte;
+    */
+
+    printParameters(&Serial);
+
+  Serial.print("loading..");
+  Serial.println(actualPreset);
+  loadPreset = 0;
+  updateParam=1;
+    display.setCursor(68, 10);
+    display.print("LOAD");
+    display.display();
+    delay(500);
+ }
+display.clearDisplay();
+
+//*******************INPUT/OUTPUT LEVEL ADJUST************************
+if (SW1Value == 5){    //LP pos for input level
+ if (!Tap1Value && (Tap1Value == Tap1ValueOld)){    //When Mode/tap is held down you can adjust the input gain of the input
+ // Serial.print("TIME");
+   Tap1Timer++;
+  if (Tap1Timer > 15){
+    InLevel = analogRead(Pot1);
+    InLevel = mapfloat(InLevel,0,1023,10,1);
+    InLevel = InLevel * inLevel; //multiply by constant inLevel
+    delay(100);
+    display.setTextSize(1);
+    display.setTextColor(WHITE);
+    display.setCursor(5, 10);
+    display.print("Input:");
+    display.print(InLevel);
+    display.display();
+    }
+  }
+  else if (Tap1Timer > 15){    //only write to EEPROM once
+    EEPROM.write(0, InLevel*255);
+  //  Serial.println(InLevel);
+    Tap1Timer = 0;
+  }
+  else if (Tap1Value){
+  //  peak = peak1.read();   //read the signal output peak
+  if (peak == -1)(peak = 0);
+  //analogWrite(ledPin2, peak*100);
+  //pixels.setPixelColor(1, pixels.Color(peak*100,peak*100,0));
+  //pixels.show();
+  }
+}
+
+if (SW1Value == 1){    //HP pos for Output level
+ if (!Tap1Value && (Tap1Value == Tap1ValueOld)){    //When Mode/tap is held down you can adjust the input gain of the input
+ // Serial.print("TIME");
+   Tap1Timer++;
+  if (Tap1Timer > 15){
+    outLevel = analogRead(Pot1);
+    outLevel = mapfloat(outLevel,0,1023,10,1);
+    delay(100);
+   // analogWrite(ledPin2, 255);
+    //pixels.setPixelColor(1, pixels.Color(70,70,0));
+    //display.clearDisplay();
+    display.setTextSize(1);
+    display.setTextColor(WHITE);
+    display.setCursor(5, 10);
+    display.print("Output:");
+    display.print(outLevel);
+    display.display();
+    }
+  }
+  else if (Tap1Timer > 15){    //only write to EEPROM once
+    EEPROM.write(1, outLevel);
+    Tap1Timer = 0;
+  }
+  else if (Tap1Value){
+  //  peak = peak1.read();   //read the signal output peak
+  if (peak == -1)(peak = 0);
+  //analogWrite(ledPin2, peak*100);
+  //pixels.setPixelColor(1, pixels.Color((peak)*100,(peak)*100,0));
+  //pixels.show();
+  }
+}
+
+ ////// VU meter ////////////
+//Gain reduction meter
+
+for(int i=NUMPIXELS;i>=3;i--){
+  float reduction = abs(comp1.getCurrentGain_dB());
+  int lvl = NUMPIXELS-(reduction/5);       //120*7=840
+  int grade = 360+reduction*960;
+  //Serial.println(peak_2);
+  grade = grade -(120*lvl);
+
+  if ((i > lvl)&&(i == 5))pixels.setPixelColor(i,yellow); // yellow color.
+  if ((i > lvl)&&(i == 4))pixels.setPixelColor(i,red); // red color.
+  else if (i > lvl)pixels.setPixelColor(i,green); // green color.
+  //else if (i == lvl){
+ //   pixels.setPixelColor(i, pixels.Color(grade,0,0)); // green color.
+  //}
+  else     {
+    pixels.setPixelColor(i,off); // no color
+  }
+}
+  pixels.show(); // This sends the updated pixel color to the hardware.
+
+///////////end VU meter/////////
+
+///////////////////////////PLOTTING OF COMPRESSOR CURVE//////////////////////////////////
+//Draw background:
+int top = 20;
+int signalWidth = 6;
+display.drawLine(0,top,128,top, WHITE);
+display.drawLine(0,64,0,top, WHITE);
+display.drawLine(signalWidth+1,64,signalWidth+1,top, WHITE);
+display.drawLine(signalWidth*2+2,64,signalWidth*2+2,top, WHITE);
+display.drawLine(127-signalWidth*2-2,64,127-signalWidth*2-2,top, WHITE);
+display.drawLine(127-signalWidth-1,64,127-signalWidth-1,top, WHITE);
+display.drawLine(127,64,127,top, WHITE);
+
+int thresh_disp = map(thres,0,-70,(64-top),10);
+int zeroX = signalWidth*2+8;
+int diffY = (64-thresh_disp) - top;
+int kneeX = zeroX+thresh_disp;
+int kneeY = 64-thresh_disp;
+int Xtop = kneeX + diffY*Ratio;
+
+display.drawLine(zeroX,64, kneeX, kneeY, WHITE);   //first slope
+display.drawLine(kneeX, kneeY, Xtop,top, WHITE);   //second slope
+display.fillRect(127-signalWidth*2-1,top+1,signalWidth,(64-top),BLACK);
+display.fillRect(127-signalWidth,top+1,signalWidth,(64-top),BLACK);
+
+  //read the signal input peak
+if (rms1.available()){
+  peak = rms1.read();
+  float peakDisp1 = top+((64-top)*(1-peak));
+  display.fillRect(1,peakDisp1,signalWidth,(64),WHITE);
+  }
+
+if (rms2.available()) {
+  peak_2 = rms2.read();    //Output peak
+  float peakDisp2 = top+((64-top)*(1-peak_2));
+  display.fillRect(2+signalWidth,peakDisp2,signalWidth,(64),WHITE);
+  }
+//draw gain reduction
+ // (comp2.getCurrentGain_dB());
+display.fillRect(127-signalWidth*2-1,top+1,signalWidth,abs(comp1.getCurrentGain_dB()),WHITE);
+display.fillRect(127-signalWidth,top+1,signalWidth,abs(comp2.getCurrentGain_dB()),WHITE);
+ /////////////////////END PLOTTING///////////////////////////////
+
+ ////// VU meter ////////////
+ /*
+VUlag++;
+if (VUlag >0){
+for(int i=3;i<=NUMPIXELS;i++){
+  int lvl = 3+(peak_2*12);       //120*7=840
+  int grade = 360+peak_2*960;
+  //Serial.println(peak_2);
+  grade = grade -(120*lvl);
+  if (i < lvl){
+    pixels.setPixelColor(i, pixels.Color(80,0,0)); // green color.
+  }
+  else if (i == lvl){
+    pixels.setPixelColor(i, pixels.Color(grade,0,0)); // green color.
+  }
+  else     {
+    pixels.setPixelColor(i, pixels.Color(0,0,0)); // no color
+  }
+}
+  pixels.show(); // This sends the updated pixel color to the hardware.
+ // VUlag = 0;
+}
+*/
+///////////end VU meter/////////
+
+ // int cpuCap = AudioProcessorUsageMax();
+  display.setTextSize(1);
+  display.setTextColor(WHITE);
+  display.setCursor(10, 10);
+
+  display.print("Th:");
+  display.print((int)thres);
+  display.print("dB");
+
+  display.setCursor(17, 23);
+  display.print(Ratio);
+  display.print(":1");
+
+  display.setCursor(100, 10);
+  display.print("P:");
+  display.print(actualPreset);
+
+  display.setCursor(30, 56);
+  display.print("A:");
+  display.print((int)(attack_1*1000));
+  display.print("ms");
+  display.setCursor(70, 56);
+  display.print(" R:");
+  display.print((int)(decay_1*1000));
+  display.display();
+
+ /*
+   Serial.print(" Last: ");
+   Serial.print(Pot1ValueOld);
+   Serial.print(" Last: ");
+   Serial.println(Pot1Value);
+
+   Serial.print(" Freq2: ");
+   Serial.print(freqBand[2]);
+   Serial.print(" Freq3: ");
+   Serial.print(freqBand[3]);
+   Serial.print(" Freq4: ");
+   Serial.print(freqBand[4]);
+   Serial.print(" Freq5: ");
+   Serial.println(freqBand[5]);
+   Serial.print(" Peak2: ");
+   Serial.println(peak_2);
+   */
+   Pot1ValueOld = Pot1Value;
+   Pot2ValueOld = Pot2Value;
+   Pot3ValueOld = Pot3Value;
+   Pot4ValueOld = Pot4Value;
+   SW1ValueOld = SW1Value;
+   SW2ValueOld = SW2Value;
+   Tap1ValueOld = Tap1Value;
+   Tap2ValueOld = Tap2Value;
+   CV1ValueOld = CV1Value;
+   CV2ValueOld = CV2Value;
+//   modFreqOld = modFreq;
+//   spanfreqOld = spanfreq;
+//   movingfreqOld = movingfreq;
+
+    //printCPUandMemoryUsage(&Serial);
+   //AudioInterrupts();
+   //AudioNoInterrupts();
+ //  pixels.show();
+//printCompressorState(&Serial);
+/*  if (notefreq1.available()){
+  Serial.println(notefreq1.read());
+ }
+ */
+}
+
+void printCompressorState(Stream *s) {
+  s->print("Current Compressor: Pre-Gain (dB) = ");
+  s->print(comp1.getPreGain_dB());
+  s->print(", Level (dBFS) = ");
+  s->print(comp1.getCurrentLevel_dBFS());
+  s->print(", ");
+  s->print(comp2.getCurrentLevel_dBFS());
+  s->print(", Dynamic Gain L/R (dB) = ");
+  s->print(comp1.getCurrentGain_dB());
+  s->print(", ");
+  s->print(comp2.getCurrentGain_dB());
+  s->println();
+};
+
+void printParameters(Stream *s) {
+    s->print("Preset: ");
+    s->print(actualPreset);
+    s->print(" InputGain: ");
+    s->print(inLevel);
+    s->print(" Treshold: ");
+    s->print(thres);
+    s->print(" Ratio: 1: ");
+    s->print(Ratio);
+    s->print(" Attack: ");
+    s->print(attack_1);
+    s->print(" Release: ");
+    s->println(decay_1);
+};
+/* fscale
+ Floating Point Autoscale Function V0.1
+ Paul Badger 2007
+ Modified from code by Greg Shakar
+
+ This function will scale one set of floating point numbers (range) to another set of floating point numbers (range)
+ It has a "curve" parameter so that it can be made to favor either the end of the output. (Logarithmic mapping)
+*/
+float fscale( float originalMin, float originalMax, float newBegin, float
+newEnd, float inputValue, float curve){
+
+  float OriginalRange = 0;
+  float NewRange = 0;
+  float zeroRefCurVal = 0;
+  float normalizedCurVal = 0;
+  float rangedValue = 0;
+  boolean invFlag = 0;
+
+
+  // condition curve parameter
+  // limit range
+
+  if (curve > 10) curve = 10;
+  if (curve < -10) curve = -10;
+
+  curve = (curve * -.1) ; // - invert and scale - this seems more intuitive - postive numbers give more weight to high end on output
+  curve = pow(10, curve); // convert linear scale into lograthimic exponent for other pow function
+
+  /*
+   Serial.println(curve * 100, DEC);   // multply by 100 to preserve resolution
+   Serial.println();
+   */
+
+  // Check for out of range inputValues
+  if (inputValue < originalMin) {
+    inputValue = originalMin;
+  }
+  if (inputValue > originalMax) {
+    inputValue = originalMax;
+  }
+
+  // Zero Refference the values
+  OriginalRange = originalMax - originalMin;
+
+  if (newEnd > newBegin){
+    NewRange = newEnd - newBegin;
+  }
+  else
+  {
+    NewRange = newBegin - newEnd;
+    invFlag = 1;
+  }
+
+  zeroRefCurVal = inputValue - originalMin;
+  normalizedCurVal  =  zeroRefCurVal / OriginalRange;   // normalize to 0 - 1 float
+
+  /*
+  Serial.print(OriginalRange, DEC);
+   Serial.print("   ");
+   Serial.print(NewRange, DEC);
+   Serial.print("   ");
+   Serial.println(zeroRefCurVal, DEC);
+   Serial.println();
+   */
+
+  // Check for originalMin > originalMax  - the math for all other cases i.e. negative numbers seems to work out fine
+  if (originalMin > originalMax ) {
+    return 0;
+  }
+
+  if (invFlag == 0){
+    rangedValue =  (pow(normalizedCurVal, curve) * NewRange) + newBegin;
+
+  }
+  else     // invert the ranges
+  {
+    rangedValue =  newBegin - (pow(normalizedCurVal, curve) * NewRange);
+  }
+
+  return rangedValue;
+}
+
+//************EEPROM functions****************
+//This function will write a 2 byte (16bit) uint16_t to the eeprom at
+//the specified address to address + 1.
+void EEPROMWrite_uint16_t(int address, uint16_t value)
+      {
+      //Decomposition from a uint16_t to 2 bytes by using bitshift.
+      //One = Most significant -> Two = Least significant byte
+      byte two = ((value >> 0xFF) & 0xFF);
+      byte one = ((value >> 8) & 0xFF);
+
+      //Write the 2 bytes into the eeprom memory.
+      EEPROM.write(address, two);
+      EEPROM.write(address + 1, one);
+      }
+
+long EEPROMRead_uint16_t(int address)
+      {
+      //Read the 2 bytes from the eeprom memory.
+
+      uint16_t two = EEPROM.read(address);
+      uint16_t one = EEPROM.read(address + 1);
+
+      //Return the recomposed uint16_t by using bitshift.
+      return ((two << 16) & 0xFF) + ((one << 24) & 0xFFFF);
+      }
+
+
+void printCPUandMemoryUsage(Stream *s) {
+  s->print("Usage/Max: ");
+  s->print("comp1 CPU = "); s->print(comp1.processorUsage()); s->print("/"); s->print(comp1.processorUsageMax()); s->print(", ");
+  s->print("all CPU = " ); s->print(AudioProcessorUsage()); s->print("/");  s->print(AudioProcessorUsageMax()); s->print(", ");
+  s->print("Int16 Mem = "); s->print(AudioMemoryUsage()); s->print("/"); s->print(AudioMemoryUsageMax()); s->print(", ");
+  s->print("Float Mem = "); s->print(AudioMemoryUsage_F32()); s->print("/"); s->print(AudioMemoryUsageMax_F32()); s->print(", ");
+  s->println();
+};
+
+/////////////////////////////////////////
+
+float mapfloat(float x, float in_min, float in_max, float out_min, float out_max)
+{
+  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
+}
+
+//define a function to configure the left and right compressors
+void setupMyCompressors(boolean use_HP_filter, float knee_dBFS, float comp_ratio, float attack_sec, float release_sec) {
+  comp1.enableHPFilter(use_HP_filter);   comp2.enableHPFilter(use_HP_filter);
+  comp1.setThresh_dBFS(knee_dBFS);       comp2.setThresh_dBFS(knee_dBFS);
+  comp1.setCompressionRatio(comp_ratio); comp2.setCompressionRatio(comp_ratio);
+
+  float fs_Hz = AUDIO_SAMPLE_RATE;
+  comp1.setAttack_sec(attack_sec, fs_Hz);       comp2.setAttack_sec(attack_sec, fs_Hz);
+  comp1.setRelease_sec(release_sec, fs_Hz);     comp2.setRelease_sec(release_sec, fs_Hz);
+}


comments and docs updated

comments and docs updated

--- jenny5-firmware/jenny5-firmware.ino
+++ jenny5-firmware/jenny5-firmware.ino
@@ -67,11 +67,11 @@
   Serial.println(F("Px# // Gets the position of the potentiometer x. Outputs Px p#"));
   Serial.println(F("Ix# // Gets the value of infrared sensor x. Outputs Ix v#"));

-  Serial.println(F("GSx# // Gets the parameters for stepper motor x: speed acceleration num_sensors. Outputs GSx s a 1#"));
+  Serial.println(F("GSx# // Gets the parameters for stepper motor x: speed acceleration num_sensors_attached. Outputs GSx s a 1#"));
   Serial.println(F("GDx# // Gets the parameters for dc motor x: speed num_sensors sensor_index1, sensor_type1 sensor_index1, sensor_type1. Outputs GDx s a 1 0 0#"));
-  Serial.println(F("GVx# // Gets the parameters for dc motor x: speed num_sensors sensor_index1, sensor_type1 sensor_index1, sensor_type1. Outputs GVx s a 1 0 0#"));
-  Serial.println(F("GPx# // Gets the parameters for potentiometer x: min max home. Outputs PPx l u h#"));
-  Serial.println(F("GUx# // Gets the parameters for ultrasound x: trig_pin echo_pin. Outputs UPx t e#"));
+  Serial.println(F("GPx# // Gets the parameters for potentiometer x: min max home direction. Outputs GPx n u h d#"));
+  Serial.println(F("GUx# // Gets the parameters for ultrasound x: trig_pin echo_pin. Outputs GUx t e#"));
+  Serial.println(F("GBx# // Gets the parameters for button x: out_pin direction. Outputs GBx p d#"));

   Serial.println(F("CS n d1 s1 e1 d2 s2 e2# // Creates the stepper motors controller and set some of its parameters. n is the number of motors, d, s, e are dir, step and enable pins. Outputs CS# when done."));
   Serial.println(F("CD n p1 d11 d12 e1 p2 d21 d22 e2# // Creates the dc motors controller and set some of its parameters. n is the number of motors, p is the pwm_pin, d1 and d2 are the direction pins and e is the enable pins. Outputs CD# when done."));
@@ -305,14 +305,14 @@
       }

       if (tmp_str[i] == 'G' || tmp_str[i] == 'g') { // for debugging purpose
-        if (tmp_str[i + 1] == 'S' || tmp_str[i + 1] == 's') { // gets stepper motor speed and acceleration
+        if (tmp_str[i + 1] == 'S' || tmp_str[i + 1] == 's') { // gets stepper motor speed and acceleration num sensors attached
           int motor_index;
-          byte num_sensors;
+          byte num_sensors_attached;
           float motor_speed, motor_acceleration;
           sscanf(tmp_str + i + 2, "%d", &motor_index);
           stepper_motors_controller.get_speed_and_acceleration(motor_index, &motor_speed, &motor_acceleration);
-          num_sensors = stepper_motors_controller.get_num_attached_sensors(motor_index);
-          sprintf(tmp_serial_out, "GS%d %d %d %d#", motor_index, (int)motor_speed, (int)motor_acceleration, num_sensors);
+          num_sensors_attached = stepper_motors_controller.get_num_attached_sensors(motor_index);
+          sprintf(tmp_serial_out, "GS%d %d %d %d#", motor_index, (int)motor_speed, (int)motor_acceleration, num_sensors_attached);
           strcat(serial_out, tmp_serial_out);
           i += 4;
         }
@@ -325,7 +325,7 @@
           strcat(serial_out, tmp_serial_out);
           i += 4;
         }
-        else if (tmp_str[i + 1] == 'P' || tmp_str[i + 1] == 'p') { // get potentiometer min max home
+        else if (tmp_str[i + 1] == 'P' || tmp_str[i + 1] == 'p') { // get potentiometer min max home dir
           int pot_index, pot_min, pot_max, pot_home, pot_dir;
           byte pot_pin;
           sscanf(tmp_str + i + 2, "%d", &pot_index);
@@ -334,7 +334,7 @@
           strcat(serial_out, tmp_serial_out);
           i += 5;
         }
-        else if (tmp_str[i + 1] == 'U' || tmp_str[i + 1] == 'u') { // get potentiometer min max home
+        else if (tmp_str[i + 1] == 'U' || tmp_str[i + 1] == 'u') { // get ultrasound trig_pin echo_pin
           int ultrasound_index;
           byte trig_pin, echo_pin;
           sscanf(tmp_str + i + 2, "%d", &ultrasound_index);


Add drawCircle method

Add drawCircle method

--- dee-oh-tee.ino
+++ dee-oh-tee.ino
@@ -2,16 +2,17 @@

 const int buttonPin = 10;

-const int minPanAngle = 700;
-const int maxPanAngle = 2300;
+const int minServoAngle = 700;
+const int maxServoAngle = 2300;
+const int numberOfUsableDegrees = maxServoAngle - minServoAngle;
+const int centerServoAngle = minServoAngle + numberOfUsableDegrees / 2;

 Servo panServo;
 Servo tiltServo;

-int panAngleDegrees;
-int tiltServoDegrees;
-
 void setup() {
+  Serial.begin(9600);
+
   pinMode(buttonPin, INPUT_PULLUP);

   // 0, 2, 3, 4, 5, 6, 7, 10, 12, 13
@@ -19,19 +20,69 @@
   tiltServo.attach(4);
 }

+int convertNormalizedAngleToServoAngle(int normalizedAngle) {
+  return normalizedAngle + minServoAngle;
+}
+
+void drawCircle() {
+  const int maxDisplacementFromCenter = numberOfUsableDegrees / 2;
+  const int tiltAngleCenter = minServoAngle + maxDisplacementFromCenter;
+
+  for (int targetDegrees = 0; targetDegrees <= numberOfUsableDegrees; targetDegrees += 3) {
+    const int targetPanServoDegrees = convertNormalizedAngleToServoAngle(targetDegrees);
+
+    panServo.writeMicroseconds(targetPanServoDegrees);
+
+    const int targetTiltDegrees = maxDisplacementFromCenter - sqrt(pow(maxDisplacementFromCenter, 2) - pow(targetDegrees - maxDisplacementFromCenter, 2));
+    const int targetTiltServoDegrees = convertNormalizedAngleToServoAngle(targetTiltDegrees);
+    tiltServo.writeMicroseconds(targetTiltServoDegrees);
+
+    Serial.print("tilt angle = ");
+    Serial.print(targetTiltDegrees);
+    Serial.println();
+
+    delay(15);
+  }
+
+  for (int targetDegrees = numberOfUsableDegrees; targetDegrees > 0; targetDegrees -= 3) {
+    const int targetPanServoDegrees = convertNormalizedAngleToServoAngle(targetDegrees);
+
+    panServo.writeMicroseconds(targetPanServoDegrees);
+
+    const int targetTiltDegrees = maxDisplacementFromCenter + sqrt(pow(maxDisplacementFromCenter, 2) - pow(targetDegrees - maxDisplacementFromCenter, 2));
+    const int targetTiltServoDegrees = convertNormalizedAngleToServoAngle(targetTiltDegrees);
+    tiltServo.writeMicroseconds(targetTiltServoDegrees);
+
+    delay(15);
+  }
+}
+
+void performRangeTest() {
+  const int maxDisplacementFromCenter = numberOfUsableDegrees / 2;
+
+  for (int targetDegrees = -maxDisplacementFromCenter; targetDegrees <= maxDisplacementFromCenter; targetDegrees += 3) {
+    const int targetServoDegrees = convertNormalizedAngleToServoAngle(targetDegrees);
+    panServo.writeMicroseconds(targetServoDegrees);
+    tiltServo.writeMicroseconds(targetServoDegrees);
+    delay(15);
+  }
+  for (int targetDegrees = maxDisplacementFromCenter; targetDegrees >= -maxDisplacementFromCenter; targetDegrees -= 3) {
+    const int targetServoDegrees = convertNormalizedAngleToServoAngle(targetDegrees);
+    panServo.writeMicroseconds(targetServoDegrees);
+    tiltServo.writeMicroseconds(targetServoDegrees);
+    delay(15);
+  }
+}
+
 void loop() {
-  int buttonState = digitalRead(buttonPin);
+  const int buttonState = digitalRead(buttonPin);

   if (buttonState == LOW) {
-    for (panAngleDegrees = minPanAngle; panAngleDegrees <= maxPanAngle; panAngleDegrees += 3) {
-      panServo.writeMicroseconds(panAngleDegrees);
-      tiltServo.writeMicroseconds(panAngleDegrees);
-      delay(15);
-    }
-    for (panAngleDegrees = maxPanAngle; panAngleDegrees >= minPanAngle; panAngleDegrees -= 3) {
-      panServo.writeMicroseconds(panAngleDegrees);
-      tiltServo.writeMicroseconds(panAngleDegrees);
-      delay(15);
-    }
+    const int initialTiltAngle = tiltServo.read();
+    const int initialPanAngle = panServo.read();
+
+//    performRangeTest();
+
+    drawCircle();
   }
 }


change limit of cloud detection

change limit of cloud detection

--- arduino/sadr_meteo_no_firmata/sadr_meteo_no_firmata.ino
+++ arduino/sadr_meteo_no_firmata/sadr_meteo_no_firmata.ino
@@ -45,9 +45,9 @@
 #define  K5 100.

 //Clear sky corrected temperature (temp below means 0% clouds)
-#define CLOUD_TEMP_CLEAR  -15
+#define CLOUD_TEMP_CLEAR  -22
 //Totally cover sky corrected temperature (temp above means 100% clouds)
-#define CLOUD_TEMP_OVERCAST  -5
+#define CLOUD_TEMP_OVERCAST  -10
 //Activation treshold for cloudFlag (%)
 #define CLOUD_FLAG_PERCENT  30


Add Serial-over-MIDI communication channel.

WALT commands will also be read from MIDI channel pressure messages, and
sending a MIDI program change message for program number 1 will change
WALT responses to be sent via. MIDI system exclusive messages -- rather
than the USB serial interface (any other program number will disable
this feature).

--- arduino/walt/walt.ino
+++ arduino/walt/walt.ino
@@ -46,6 +46,12 @@

 #define NOTE_DELAY 10000 // 10 ms

+// Message types for MIDI encapsulation
+#define MIDI_MODE_TYPE 4  // Program Change
+#define MIDI_COMMAND_TYPE 5  // Channel Pressure
+
+#define MIDI_SYSEX_BEGIN '\xF0'
+#define MIDI_SYSEX_END '\xF7'

 // On Teensy LC probably need to use the high current pins
 // for most LEDs.
@@ -75,6 +81,9 @@

 boolean led_state;
 char tmp_str[256];
+
+boolean serial_over_midi;
+String send_buffer;

 struct trigger {
   long t;  // time of latest occurrence in microseconds
@@ -108,11 +117,52 @@
   led_state = !led_state;
 }

+void send(char c) { send_buffer += c; }
+void send(String s) { send_buffer += s; }
+
+void send(long l) {
+  char s[32];
+  sprintf(s, "%ld", l);
+  send(s);
+}
+
+void send(unsigned long l) {
+  char s[32];
+  sprintf(s, "%lud", l);
+  send(s);
+}
+
+void send(short i) { send((long)i); }
+void send(int i) { send((long)i); }
+void send(unsigned short i) { send ((unsigned long)i); }
+void send(unsigned int i) { send ((unsigned int)i); }
+
+void send_now() {
+  if (serial_over_midi) {
+    usbMIDI.sendSysEx(send_buffer.length(), (const uint8_t *)send_buffer.c_str());
+    usbMIDI.send_now();
+    send_buffer = MIDI_SYSEX_BEGIN;
+  } else {
+    Serial.write(send_buffer.c_str(), send_buffer.length());
+    Serial.send_now();
+    send_buffer = String();
+  }
+}
+
+void send_line() {
+  if (!serial_over_midi) {
+    send('\n');
+  } else {
+    send(MIDI_SYSEX_END);
+  }
+  send_now();
+}
+
 void send_trigger(struct trigger t) {
   char s[256];
   sprintf(s, "G %c %ld %d %d", t.tag, t.t, t.value, t.count);
-  Serial.println(s);
-  Serial.send_now();
+  send(s);
+  send_line();
 }

 // flips case for a give char. Unchanged if not in [A-Za-z].
@@ -128,8 +178,8 @@

 // Print the same char as the cmd but with flipped case
 void send_ack(char cmd) {
-  Serial.println(flip_case(cmd));
-  Serial.send_now();
+  send(flip_case(cmd));
+  send_line();
 }

 void init_clock() {
@@ -174,6 +224,8 @@
   digitalWrite(LED_PIN_INT, led_state);
   // digitalWrite(LED_PIN_RED, HIGH);
   Serial.begin(115200);
+
+  serial_over_midi = false;

   init_vars();
 }
@@ -187,15 +239,15 @@
   for (i = 0; i < 1000; i++) {
     v = analogRead(PD_SCREEN_PIN);
     t = time_us;
-    Serial.print(t);
-    Serial.print(" ");
-    Serial.println(v);
+    send(t);
+    send(' ');
+    send(v);
+    send_line();
     delayMicroseconds(450);
   }
   digitalWrite(DEBUG_LED2, LOW);
-  Serial.send_now();
-  Serial.println("end");
-  Serial.send_now();
+  send("end");
+  send_line();
 }

 void process_command(char cmd) {
@@ -208,9 +260,9 @@
       interrupts();
       send_ack(CMD_SYNC_ZERO);
     } else if (cmd == CMD_TIME_NOW) {
-      Serial.print("t ");
-      Serial.println(time_us);
-      Serial.send_now();
+      send("t ");
+      send(time_us);
+      send_line();
     } else if (cmd == CMD_PING) {
       send_ack(CMD_PING);
     } else if (cmd == CMD_PING_DELAYED) {
@@ -224,10 +276,10 @@
       if (clock.last_sent < CLOCK_SYNC_N) {
         t = clock.sync_times[clock.last_sent];
       }
-      Serial.print(clock.last_sent + 1);
-      Serial.print(":");
-      Serial.println(t);
-      Serial.send_now();
+      send(clock.last_sent + 1);
+      send(':');
+      send(t);
+      send_line();
     } else if (cmd == CMD_SYNC_SEND) {
       clock.last_sent = -1;
       // Send CLOCK_SYNC_N times
@@ -235,23 +287,20 @@
         delayMicroseconds(737); // TODO: change to some congifurable random
         char c = '1' + i;
         clock.sync_times[i] = time_us;
-        Serial.print(c);
-        Serial.send_now();
+        send(c);
+        send_line();
       }
-      // TODO: This newline is useful for debugging, think if it's ok with the rest.
-      Serial.println();
-      Serial.send_now();
     } else if (cmd == CMD_RESET) {
       init_vars();
       send_ack(CMD_RESET);
     } else if (cmd == CMD_VERSION) {
-      Serial.print(flip_case(cmd));
-      Serial.print(" ");
-      Serial.println(VERSION);
-      Serial.send_now();
+      send(flip_case(cmd));
+      send(' ');
+      send(VERSION);
+      send_line();
     } else if (cmd == CMD_GSHOCK) {
-      Serial.println(gshock.t); // TODO: Serialize trigger
-      Serial.send_now();
+      send(gshock.t);  // TODO: Serialize trigger
+      send_line();
       gshock.t = 0;
       gshock.count = 0;
       gshock.probe = true;
@@ -264,10 +313,10 @@
     } else if (cmd == CMD_BEEP) {
       long beep_time = time_us;
       tone(MIC_PIN, 5000 /* Hz */);
-      Serial.print(flip_case(cmd));
-      Serial.print(" ");
-      Serial.println(beep_time);
-      Serial.send_now();
+      send(flip_case(cmd));
+      send(' ');
+      send(beep_time);
+      send_line();
     } else if (cmd == CMD_BEEP_STOP) {
       noTone(MIC_PIN);
       send_ack(CMD_BEEP_STOP);
@@ -279,10 +328,10 @@
       send_ack(CMD_MIDI);
     } else if (cmd == CMD_NOTE) {
       unsigned long note_time = time_us + NOTE_DELAY;
-      Serial.print(flip_case(cmd));
-      Serial.print(" ");
-      Serial.println(note_time);
-      Serial.send_now();
+      send(flip_case(cmd));
+      send(' ');
+      send(note_time);
+      send_line();
       while (time_us < note_time);
       usbMIDI.sendNoteOn(60, 99, 1);
       usbMIDI.send_now();
@@ -313,8 +362,9 @@
       // This blocks all other execution for about 1 second
       run_brightness_curve();
     } else {
-      Serial.print("Unknown command:");
-      Serial.println(cmd);
+      send("Unknown command: ");
+      send(cmd);
+      send_line();
     }
   }

@@ -346,13 +396,12 @@
   }

   // Probe MIDI
-  if(midi.probe) {
-    if(usbMIDI.read()) {
-      midi.t = time_us;
-      midi.count++;
-      midi.probe = false;
-      led_state = !led_state;
-    }
+  boolean has_midi = usbMIDI.read(1);
+  if(has_midi && midi.probe && usbMIDI.getType() == 1) {  // Type 1: note on
+    midi.t = time_us;
+    midi.count++;
+    midi.probe = false;
+    led_state = !led_state;
   }

   // Probe screen
@@ -385,6 +434,16 @@
   }

   // Check if we got incoming commands from the host
+  if (has_midi) {
+    if (usbMIDI.getType() == MIDI_MODE_TYPE) {
+      short program = usbMIDI.getData1();
+      serial_over_midi = (program == 1);
+      send_buffer = (serial_over_midi ? MIDI_SYSEX_BEGIN : String());
+    } else if (usbMIDI.getType() == MIDI_COMMAND_TYPE) {
+      char cmd = usbMIDI.getData1();
+      process_command(cmd);
+    }
+  }
   if (Serial.available()) {
     char cmd = Serial.read();
     process_command(cmd);


-Re-factored 'tfttask.ino'.

-Re-factored 'tfttask.ino'.

--- tfttask.ino
+++ tfttask.ino
@@ -6,12 +6,12 @@
   const uint16_t TFT_TEMP_COLOR         = ILI9341_WHITE;
   const uint16_t TFT_BACK_COLOR         = ILI9341_BLACK;
   const uint8_t  TFT_BACKLIGHT_BITDEPTH = 16;               /*min 11 bits, max 16 bits */
-  const uint8_t  TFT_BACKLIGHT_CHANNEL = NUMBER_OF_CHANNELS;
-
-  const uint32_t tftTaskdelayTime     =   ( 1000 / UPDATE_FREQ_TFT) / portTICK_PERIOD_MS;
-  const uint64_t SPI_MutexMaxWaitTime =                         100 / portTICK_PERIOD_MS;
+  const uint8_t  TFT_BACKLIGHT_CHANNEL  = NUMBER_OF_CHANNELS;

-  bool firstRun = true;
+  const time_t tftTaskdelayTime         =   ( 1000 / UPDATE_FREQ_TFT) / portTICK_PERIOD_MS;
+  const time_t SPI_MutexMaxWaitTime     =                         100 / portTICK_PERIOD_MS;
+
+  bool firstRun                         = true;

   //setup backlight pwm
   ledcAttachPin( TFT_BACKLIGHT_PIN, TFT_BACKLIGHT_CHANNEL );
@@ -21,7 +21,8 @@

   if ( !xSemaphoreTake( x_SPI_Mutex, SPI_MutexMaxWaitTime ) )
   {
-    Serial.println( "tft init - No SPI bus available." );
+    Serial.println( "No tft init. - No SPI bus available. Exiting task." );
+    vTaskDelete( NULL );
   }
   else
   {
@@ -42,6 +43,7 @@

   while (1)
   {
+
     if ( !xSemaphoreTake( x_SPI_Mutex, SPI_MutexMaxWaitTime ) )
     {
       Serial.println( "Skipped tft update. SPI bus not available.");
@@ -54,33 +56,22 @@
       const uint16_t BARS_WIDTH       = ILI9341_TFTHEIGHT / 5;
       const float    HEIGHT_FACTOR    = BARS_HEIGHT / 100.0;

-      uint32_t average = 0;
-
       if ( firstRun )
       {
         tft.fillScreen( TFT_BACK_COLOR );
         firstRun = false;
       }

+      uint32_t averageLedBrightness = 0;
+
+      uint16_t channelColor565[NUMBER_OF_CHANNELS];
+
+      tft.startWrite();
       for ( uint8_t channelNumber = 0; channelNumber < NUMBER_OF_CHANNELS; channelNumber++ )
       {
-        average += ledcRead( channelNumber );
-      }
-      average = average / NUMBER_OF_CHANNELS;
-
-      uint16_t rawBrightness = map( tftBrightness, 0, 100, 0, ( 0x00000001 << TFT_BACKLIGHT_BITDEPTH ) - 1 );
-      ledcWrite( TFT_BACKLIGHT_CHANNEL, ( average > rawBrightness ) ? rawBrightness : average );
-
-      for ( uint8_t channelNumber = 0; channelNumber < NUMBER_OF_CHANNELS; channelNumber++ )
-      {
-        uint8_t r, g, b;
-        uint32_t color = strtol( &channel[channelNumber].color[1], NULL, 16 );
-        r = ( color & 0xFF0000 ) >> 16; // Filter the 'red' bits from color. Then shift right by 16 bits.
-        g = ( color & 0x00FF00 ) >> 8;  // Filter the 'green' bits from color. Then shift right by 8 bits.
-        b = ( color & 0x0000FF );       // Filter the 'blue' bits from color. No shift needed.
+        averageLedBrightness += ledcRead( channelNumber );

         // redraw the top part of the bar
-        tft.startWrite();
         tft.writeFillRect( channelNumber * BARS_WIDTH + BARS_BORDER,
                            BARS_BOTTOM - BARS_HEIGHT,
                            BARS_WIDTH - BARS_BORDER * 2,
@@ -93,16 +84,24 @@
                                  BARS_WIDTH - BARS_BORDER * 2,
                                  tft.color565( r, g, b ) );
         */
+
+        uint32_t color = strtol( &channel[channelNumber].color[1], NULL, 16 );
+        channelColor565[channelNumber] = tft.color565( ( color & 0xFF0000 ) >> 16, ( color & 0x00FF00 ) >> 8, color & 0x0000FF  );
+
+        // redraw the bottom part of the bar
         tft.writeFillRect( channelNumber * BARS_WIDTH + BARS_BORDER,
                            BARS_BOTTOM - channel[channelNumber].currentPercentage * HEIGHT_FACTOR,
                            BARS_WIDTH - BARS_BORDER * 2,
                            channel[channelNumber].currentPercentage * HEIGHT_FACTOR,
-                           tft.color565( r, g, b ) );
-        tft.endWrite();
+                           channelColor565[channelNumber]);
+      }
+      tft.endWrite();

+      for ( uint8_t channelNumber = 0; channelNumber < NUMBER_OF_CHANNELS; channelNumber++ )
+      {
         tft.setCursor( channelNumber * BARS_WIDTH + 9, BARS_BOTTOM + 4 );
         tft.setTextSize( 1 );
-        tft.setTextColor( tft.color565( r, g, b ) , TFT_BACK_COLOR );
+        tft.setTextColor( channelColor565[channelNumber] , TFT_BACK_COLOR );

         char content[8];
         if ( TFT_SHOW_RAW )
@@ -119,10 +118,10 @@
       tft.setTextSize( 2 );
       if ( numberOfFoundSensors )
       {
+        tft.setTextColor( TFT_TEMP_COLOR , TFT_BACK_COLOR );
         for ( uint8_t thisSensor = 0; thisSensor < numberOfFoundSensors; thisSensor++ )
         {
           tft.setCursor( thisSensor * 90, BARS_BOTTOM + 15 );
-          tft.setTextColor( TFT_TEMP_COLOR , TFT_BACK_COLOR );
           tft.printf( " %.1f%cC", sensor[thisSensor].temp / 16.0, char(247) );
         }
       }
@@ -134,6 +133,13 @@
         tft.setTextColor( TFT_DATE_COLOR , TFT_BACK_COLOR );
         tft.print( asctime( &timeinfo ) );
       }
+
+      averageLedBrightness = averageLedBrightness / NUMBER_OF_CHANNELS;
+
+      uint16_t rawBrightness = map( tftBrightness, 0, 100, 0, backlightMaxvalue );
+
+      ledcWrite( TFT_BACKLIGHT_CHANNEL, ( averageLedBrightness > rawBrightness ) ? rawBrightness : averageLedBrightness );
+
       xSemaphoreGive( x_SPI_Mutex );
     }
     vTaskDelay( tftTaskdelayTime / portTICK_PERIOD_MS );


blabla

blabla

--- longhand_firmware_due/longhand_firmware_due.ino
+++ longhand_firmware_due/longhand_firmware_due.ino
@@ -1,6 +1,6 @@
 #include <SPI.h>
 #include <SD.h>
-#include "parameters.h"						// all settings are inside parameters.h
+#include "parameters.h"
 #include "pins.h"
 #include "LongPoint.h"
 #include "Arduino.h"


Update Relay.ino

Update Relay.ino

--- Examples/Relay/Relay.ino
+++ Examples/Relay/Relay.ino
@@ -2,12 +2,6 @@
  *  This example may switch a Light ON after Sunset and turn it OFF before Sunrise
  */

-#include <ESP8266WiFi.h>
-#include <PubSubClient.h>
-#include <ESP8266httpUpdate.h>
-#include <ESP8266HTTPClient.h>
-#include <ArduinoJson.h>
-#include <FS.h>
 #include <ESPMetRED.h>

 const char* MQTT_PUBLISH_TOPIC = "ESPMetRED/OUT";


Update of wifi manual entry.

Update of wifi manual entry.

--- rubberDucky_arduino.ino
+++ rubberDucky_arduino.ino
@@ -11,205 +11,219 @@
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. */
-
+
 #include <Keyboard.h>
-#include <SPI.h>
-
+
+
 /*
 https://youtu.be/6VjhmbJWDeI
-Pairing the remote is a first step. When bulk setting up a single
-remote can be used and the packagd remotes paired later in the
-classroom using the Chromecast button longpress to pair.
-
-After pairing the language select screen will appear.
-The Arduino code below can be run at this point.
-*/
-
+Pairing the remote is a first step. When bulk setting up a single
+remote can be used and the packaged remotes paired later in the
+classroom using the Chromecast button long press to pair.
+
+After pairing the language select screen will appear.
+The Arduino code below can be run at this point.
+*/
+
 #define wifi_name "" // Define SSID for your wireless connection.
 #define wifi_pass "" // Define the password for your wireless connection.
 #define account_name "" // Define Google Workspace account used to connect for casting.
 #define account_pass "" // Define Google Workspace account password used to connect for casting.

 /*
-If the language of setup is not English select the
+If the language of setup is not English select the
 position of the language on a 0 index
 */
 int languagepos = 0;

-/*
-WiFi SSIDs are ordered by strength. A saturted network
-environment may be more difficult to target. Identify
-the SSID position based on a 0 index.
-*/
-int wifipos = 0;
-
-/**
- * The setup function runs once when you press the reset button on the
- * Arduino or power-on the Arduino
- *
- * @return {void}
- */
-
+/**
+* Sets the position of the Security selection for the network
+*/
+int security_type = 0; //0 for none, 1 for WEP, 2 for WPA/WPA2-Personal
+
+/**
+* Navigates to the Manual entry of network.
+*/
+int wifipos = 20;  //20 down clicks. Click and enter manually
+
+/**
+* The setup function runs once when you press the reset button on the
+* Arduino or power-on the Arduino
+*
+* @return {void}
+*/
+
 void setup() {
-  Keyboard.begin();  //begin the keyboard.
-  wait(10);          //Provide a buffer to cancel by removing the arduino
-  start();           //Run the Chromecast setup
-}
-
+ Keyboard.begin();  //begin the keyboard.
+ wait(10);          //Provide a buffer to cancel by removing the arduino
+ start();           //Run the Chromecast setup
+}
+
 /**
 * The start function runs each step of the setup process with waits for UI
-* renderign between. Timing can be adjusted here. Going too fast will
-* result in setup failures and a requirement to factory reset or complete
+* rendering between. Timing can be adjusted here. Going too fast will
+* result in setup failures and a requirement to factory reset or complete
 * manually.
 * @return {void}
 */
 void start() {
-  selectLanguage();  //selects the language at the languagepos index assigned above
-  wait(1);           //waiting 1 second to allow UI to render
-  setupOnTv();       //Select setup to be on the TV
-  wait(1);           //waiting 1 second to allow UI to render
-  wifi();            //Select WiFi and enter credentials
-  wait(60);          //Connecting. If your network is potentially slower increase this wait to accomodate
-  konami();          //Enters the unique setup code
-  wait(3);           //waiting 3 second to allow UI to render
-  optIn();           //selects the OptIn dialogs. Please ensure manual review before proceeding.
-  wait(8);           //waiting 8 second to allow UI to render
-  googleAccount();   //Enters the Google account credentials for Cast Moderator
-  wait(8);           //waiting 8 second to allow UI to render
-  legalAccepts();    //Accepts the legal notifications. Please ensure manual review before proceeding.
-  wait(5);           //waiting 5 second to allow UI to render
-  googleServices();  //accepts or deselects the the Google Services. Please ensure manual review before proceeding.
-  wait(5);           //waiting 1 second to allow UI to render
-  noRemoteSetup();   //Select No Remote setup for audio controls. Audio controls can be setup in room later.
-}
-
-/**
-* No loop required for this functionality.
-* Advanced users can assign a pin to a button
+ selectLanguage();  //selects the language at the languagepos index assigned above
+ wait(1);           //waiting 1 second to allow UI to render
+ setupOnTv();       //Select setup to be on the TV
+ wait(1);           //waiting 1 second to allow UI to render
+ wifi();            //Select WiFi and enter credentials
+ wait(60);          //Connecting. If your network is potentially slower increase this wait to accommodate
+ wait(900);          //Wait for the Update. May need to be adjusted for slower networks.
+ konami();          //Enters the unique setup code
+ wait(3);           //waiting 3 second to allow UI to render
+ optIn();           //selects the OptIn dialogs. Please ensure manual review before proceeding.
+ wait(8);           //waiting 8 second to allow UI to render
+ googleAccount();   //Enters the Google account credentials for Cast Moderator
+ wait(8);           //waiting 8 second to allow UI to render
+ legalAccepts();    //Accepts the legal notifications. Please ensure manual review before proceeding.
+ wait(5);           //waiting 5 second to allow UI to render
+ googleServices();  //accepts or deselects the the Google Services. Please ensure manual review before proceeding.
+ wait(5);           //waiting 1 second to allow UI to render
+ noRemoteSetup();   //Select No Remote setup for audio controls. Audio controls can be setup in room later.
+}
+
+/**
+* No loop required for this functionality.
+* Advanced users can assign a pin to a button
 * for use in triggering the start function.
 */
 void loop() {
 }
-
+
 /**
 * Select the Language
 * @return {void}
 */
 void selectLanguage() {
-  if (languagepos > 0) {
-    for (int i = 0; i <= languagepos; i++) {
-      Keyboard.write(KEY_DOWN_ARROW);
-      wait(1);
-    }
-  }
-  Keyboard.write(KEY_RETURN);
-}
-
-/**
-* Skip the Google Home setup as it does not allow the setup
+ if (languagepos > 0) {
+   for (int i = 0; i <= languagepos; i++) {
+     Keyboard.write(KEY_DOWN_ARROW);
+     wait(1);
+   }
+ }
+ Keyboard.write(KEY_RETURN);
+}
+
+/**
+* Skip the Google Home setup as it does not allow the setup
 * for Cast Moderator.
 * Select Setup on TV
 * @return {void}
 */
 void setupOnTv() {
-  wait(1);
-  Keyboard.write(KEY_DOWN_ARROW);
-  wait(1);
-  Keyboard.write(KEY_RETURN);
-  wait(5);
-}
-
+ wait(1);
+ Keyboard.write(KEY_DOWN_ARROW);
+ wait(1);
+ Keyboard.write(KEY_RETURN);
+ wait(5);
+}
+
 /**
 * Set the WiFi credentials
 * @return {void}
 */
 void wifi() {
-  if (wifipos > 0) {
-    for (int i = 0; i <= wifipos; i++) {
-      Keyboard.write(KEY_DOWN_ARROW);
-      wait(1);
-    }
-  }
-  Keyboard.write(KEY_RETURN);
-  wait(1);
-  Keyboard.print(wifi_pass);
-  Keyboard.write(KEY_RETURN);
-}
-
+ if (wifipos > 0) {
+   for (int i = 0; i <= wifipos; i++) {
+     Keyboard.write(KEY_DOWN_ARROW);
+   }
+ }
+ Keyboard.write(KEY_RETURN);
+ wait(1);
+ Keyboard.print(wifi_name);
+ Keyboard.write(KEY_RETURN);
+ wait(1);
+ if(security_type>0){
+   for (int i = 0; i < security_type; i++) {
+     Keyboard.write(KEY_DOWN_ARROW);
+     wait(1);
+   }
+ }
+ Keyboard.write(KEY_RETURN);
+ wait(1);
+ Keyboard.print(wifi_pass);
+ Keyboard.write(KEY_RETURN);
+}
+
 /**
 * Execute the konami code to get access to Cast Moderator
 * @return {void}
 */
 void konami() {
-  Keyboard.write(KEY_ESC);  //Closes the keyboard
-  wait(1);                  //Waiting 1 second to allow UI to render
-  back();                   //Returns to the wifi for special code entry
-  wait(5);                  //waiting 5 second to allow UI to render
-  for (int i = 0; i < 7; i++) {
-    Keyboard.write(KEY_UP_ARROW);
-  }
-}
-
-/**
-* Agree to Cast Moderator seelctions and reminders
+ Keyboard.write(KEY_ESC);  //Closes the keyboard
+ wait(1);                  //Waiting 1 second to allow UI to render
+ back();                   //Returns to the wifi for special code entry
+ wait(5);                  //waiting 5 second to allow UI to render
+ for (int i = 0; i < 7; i++) {
+   Keyboard.write(KEY_UP_ARROW);
+ }
+}
+
+/**
+* Agree to Cast Moderator selections and reminders
 * @return {void}
 */
 void optIn() {
-  wait(1);
-  Keyboard.write(KEY_RETURN);  //Using Cast Moderator
-  wait(3);
-  Keyboard.write(KEY_RETURN);  //Organization Access
-  wait(1);
-  Keyboard.write(KEY_RETURN);  //Setup
-  wait(1);
-  Keyboard.write(KEY_RETURN);  //Device Isn't Private
-  wait(1);
-  Keyboard.write(KEY_RETURN);  //Cast Moderator is set up
-}
-
-/**
-* Enter the Google Account credentials
+ wait(1);
+ Keyboard.write(KEY_RETURN);  //Using Cast Moderator
+ wait(3);
+ Keyboard.write(KEY_RETURN);  //Organization Access
+ wait(1);
+ Keyboard.write(KEY_RETURN);  //Setup
+ wait(1);
+ Keyboard.write(KEY_RETURN);  //Device Isn't Private
+ wait(1);
+ Keyboard.write(KEY_RETURN);  //Cast Moderator is set up
+}
+
+/**
+* Enter the Google Account credentials
 * @return {void}
 */
 void googleAccount() {
-  Keyboard.print(account_name);
-  Keyboard.write(KEY_RETURN);
-  wait(5);
-  Keyboard.print(account_pass);
-  Keyboard.write(KEY_RETURN);
-}
-
-/**
-* Accept Terms of Service and Additional Legal
+ Keyboard.print(account_name);
+ Keyboard.write(KEY_RETURN);
+ wait(5);
+ Keyboard.print(account_pass);
+ Keyboard.write(KEY_RETURN);
+}
+
+/**
+* Accept Terms of Service and Additional Legal
 * @return {void}
 */
 void legalAccepts() {
-  Keyboard.write(KEY_RETURN);  //Accept TOS
-  wait(3);
-  Keyboard.write(KEY_RETURN);  //Accept Additional Legal Terms
-}
-
+ Keyboard.write(KEY_RETURN);  //Accept TOS
+ wait(3);
+ Keyboard.write(KEY_RETURN);  //Accept Additional Legal Terms
+}
+
 /**
 * Deselect or accept Google Services.
 * @return {void}
 */
 void googleServices() {
-  wait(2);
-  Keyboard.write(KEY_RETURN);
-}
-
-/**
-* Skip the the Audio setup with the remote. This can be completed later.
+ wait(2);
+ Keyboard.write(KEY_RETURN);
+}
+
+/**
+* Skip the the Audio setup with the remote. This can be completed later.
 * @return {void}
 */
 void noRemoteSetup() {
-  Keyboard.write(KEY_RIGHT_ARROW);
-  wait(1);
-  Keyboard.write(KEY_RIGHT_ARROW);
-  wait(1);
-  Keyboard.write(KEY_RETURN);
-}
-
+ Keyboard.write(KEY_RIGHT_ARROW);
+ wait(1);
+ Keyboard.write(KEY_RIGHT_ARROW);
+ wait(1);
+ Keyboard.write(KEY_RETURN);
+}
+
 /**
 * Wait in integer seconds
 * @param {integer}
@@ -217,30 +231,31 @@
 */
 void wait(int seconds = 1);
 void wait(int seconds) {
-  for (int i = 0; i < seconds; i++) {
-    blink();
-  }
-}
-
+ for (int i = 0; i < seconds; i++) {
+   blink();
+ }
+}
+
 /**
 * Back key signal
 * @return {void}
 */
 void back() {
-  Keyboard.press(KEY_LEFT_GUI);
-  delay(200);
-  Keyboard.write(KEY_BACKSPACE);
-  wait(1);
-  Keyboard.releaseAll();
-}
-
+ Keyboard.press(KEY_LEFT_GUI);
+ delay(200);
+ Keyboard.write(KEY_BACKSPACE);
+ wait(1);
+ Keyboard.releaseAll();
+}
+
 /**
 * LED Blink
 * @return {void}
 */
 void blink() {
-  digitalWrite(LED_BUILTIN, HIGH);  // turn the LED on
-  delay(500);                       // wait for half a second
-  digitalWrite(LED_BUILTIN, LOW);   // turn the LED off
-  delay(500);                       // wait for half a second
-}+ digitalWrite(LED_BUILTIN, HIGH);  // turn the LED on
+ delay(500);                       // wait for half a second
+ digitalWrite(LED_BUILTIN, LOW);   // turn the LED off
+ delay(500);                       // wait for half a second
+}
+


changed fade module

changed fade module

allows for changing fade time mid-fade now

--- Modules/Modifier/Fade/ArduinoCodes/FadeATtiny/FadeATtiny.ino
+++ Modules/Modifier/Fade/ArduinoCodes/FadeATtiny/FadeATtiny.ino
@@ -18,6 +18,8 @@
 **  By Majeed Kazemitabaar
 **  Modified on 8/25/15.
 **  By Majeed Kazemitabaar
+**  Modified on 6/21/16
+**  By Alex Jiao
 **
 **  MakerWear Link:
 **  Github Link:      github.com/myjeeed/MakerWear
@@ -54,7 +56,9 @@
 {
   int pot_value;
   int input_val = cutAndMap(input.filteredAnalogRead(AVERAGE), 50, 975, 4, 1023);
-
+  pot_value = analogRead(potentiometer_pin);
+  fading_delay = cutAndMap(pot_value, 0, 1023, 50000/(900), 0);           //50000 experimentally determined
+
   if(input_val > THRESH_HIGH){
     can_fade = 1;
   }
@@ -70,8 +74,8 @@
   if(can_fade == 1 && low_detect == 1 && fading == 0){  //start fading
     fading = 1;
     brightness = input_val;
-    pot_value = analogRead(potentiometer_pin);
-    fading_delay = cutAndMap(pot_value, 0, 1023, 0, 50000/(4*input_val));           //50000 experimentally determined
+    /*pot_value = analogRead(potentiometer_pin);
+    fading_delay = cutAndMap(pot_value, 0, 1023, 50000/(4*input_val), 0);   */        //50000 experimentally determined
   }
   else if(can_fade == 1 && add_trigger == 1 && fading == 1){   //add brightness if HIGH input comes mid-fade
     brightness += add_value;


[cyclops_plus_plus] - ensure that max alarm level doesn't exceed the maximum allowed dutycycle (255)

--- src/cyclop_plus_plus/cyclop_plus_plus.ino
+++ src/cyclop_plus_plus/cyclop_plus_plus.ino
@@ -352,7 +352,7 @@
     if (millis() > alarmTimer) {
       alarmSoundOn = !alarmSoundOn;
       if (alarmSoundOn) {
-        analogWrite( ALARM_PIN, 1 << options[ALARM_LEVEL_OPTION] );
+        analogWrite( ALARM_PIN, (1 << options[ALARM_LEVEL_OPTION]) - 1 );
         alarmTimer = millis() + alarmOnPeriod;
       }
       else {
@@ -910,7 +910,7 @@

   while (getClickType(BUTTON_PIN) == NO_CLICK) {
     for (i = 0; i < 3; i++) {
-      analogWrite( ALARM_PIN, 1 << options[ALARM_LEVEL_OPTION] );
+      analogWrite( ALARM_PIN, (1 << options[ALARM_LEVEL_OPTION]) - 1 );
       delay(ALARM_MAX_ON);
       analogWrite( ALARM_PIN, 0 );
       delay(ALARM_MAX_OFF);


Add drawSineWave

Add drawSineWave

--- dee-oh-tee.ino
+++ dee-oh-tee.ino
@@ -123,6 +123,19 @@
   }
 }

+void drawSineWave(int startX, int endX, int yOffset, int amplitude, int numberOfPeriods) {
+  const float lengthOfPeriod = (float)(endX - startX) / numberOfPeriods;
+  const float lengthOfPeriodInRadians = lengthOfPeriod / (2.0 * M_PI);
+
+  for (int x = startX; x < endX; x++) {
+    moveToPoint(x, amplitude * sinf((float)x / lengthOfPeriodInRadians) + yOffset, 1);
+  }
+
+  for (int x = endX; x > startX; x--) {
+    moveToPoint(x, -amplitude * sinf((float)x / lengthOfPeriodInRadians) + yOffset, 1);
+  }
+}
+
 void drawRectangle(int startX, int startY, int width, int height, int xDegreesPerCycle) {
   if (startX + width > USABLE_DEGREES || startY + height > USABLE_DEGREES) {
     Serial.print("The requested rectangle goes beyond the servo's usable range");
@@ -160,6 +173,8 @@

 //    performRangeTest();

+//    drawSineWave(-USABLE_DEGREES / 2, USABLE_DEGREES / 2, USABLE_DEGREES / 4, USABLE_DEGREES / 8, 2);
+
 //    drawCircle(0, 0, numberOfUsableDegrees / 2, 15, CLOCKWISE);

     drawEllipse(0, 0, USABLE_DEGREES / 4, USABLE_DEGREES / 4, 3, CLOCKWISE);


Correct deg to rad conversion on offset correction Change motor sign to adapt to mechanical set up

--- Arduino/Complete/src/src.ino
+++ Arduino/Complete/src/src.ino
@@ -219,7 +219,7 @@
   // Linear encoder position
   Input2 = halfSteps*LINEAR_RESOLUTION/2/LINEAR_USED_RANGE;
   // Correct for lever arm (potentiometer not on axis)
-  Input2+= Input1* POT_OFFSET;
+  Input2+= (rawAngle_deg - NEUTRAL_ANGLE_DEG)* POT_OFFSET*3.14/180;

   // Line tension
   Input3 = analogRead(LINE_TENSION_PIN)/512 - 1;
@@ -273,7 +273,7 @@
 {
   // Order in the range -127/127
    ST.motor(1, power1);
-   ST.motor(2, power2);
+   ST.motor(2, -power2);
 }

 void int0()


ac code add

ac code add

--- _04-mqtt-lcd-dust-sensor/_04-mqtt-lcd-dust-sensor-nano/_04-mqtt-lcd-dust-sensor-nano.ino
+++ _04-mqtt-lcd-dust-sensor/_04-mqtt-lcd-dust-sensor-nano/_04-mqtt-lcd-dust-sensor-nano.ino
@@ -41,7 +41,7 @@

 // -----------------------------------------
 long startMills;
-
+long ac_startMills;
 // ------------------------------------------
 // IR
 const int AC_TYPE  = 0;
@@ -167,6 +167,20 @@
   AC_AIR_ACLEAN = air_clean;
 }

+void ac_sleepmomde_change() {
+  if ( AC_POWER_ON == 0 ) {
+    ac_air_clean(0);
+    delay(100);
+    ac_activate(28, 0);
+    delay(100);
+  } else {
+    ac_power_down();
+    delay(100);
+    ac_air_clean(1);
+    delay(100);
+  }
+}
+
 // IR
 void dumpInfo (decode_results *results)
 {
@@ -178,6 +192,7 @@

   if ( results->bits > 0 && results->bits == 32 ) {
     if ( results->value == 0xFF02FD ) {
+       ac_sleepmomde_change();
        sleepmode = HIGH;
     } else if ( results->value == 0xFF9867 ) {
        sleepmode = LOW;
@@ -190,7 +205,10 @@
 void setup()
 {
   Serial.begin(38400);
+
   startMills = millis();
+  ac_startMills = 0;
+
   Serial.println("Starting dust Sensor");
   pinMode(ledPower, OUTPUT);

@@ -224,7 +242,6 @@
     delayMicroseconds(sleepTime);

     startMills = millis();
-
   }

   if (irrecv.decode(&results)) {
@@ -241,8 +258,10 @@
     delay(5000);
   */

-
-
+  if ((sleepmode == HIGH) && ( ac_startMills >= 1800000 )) {
+     ac_sleepmomde_change;
+     ac_startMills = millis();
+  }
 }

 void requestEvent()


Settable base midi note in via_midi

Settable base midi note in via_midi

--- firmware/via_midi/via_midi.ino
+++ firmware/via_midi/via_midi.ino
@@ -79,8 +79,7 @@
                 chan = midi_note_to_drum(note);
                 if (chan>=0) {
                     if (stat == midi::NoteOn)
-                         //drum.hit( chan, vel );
-                         drum.hit( chan, 20 );
+                         else drum.hit( chan, 20 );
                     else drum.release( chan );
                 }
             break;
@@ -88,19 +87,19 @@
     }
 }

-
+#define MIDI_BASE_NOTE  60-12
 int8_t midi_note_to_drum(uint8_t note)
 {
     switch (note)
     {
-        case 60: return 0;  // = C on middle octave
-        case 62: return 1;
-        case 64: return 2;
-        case 65: return 3;
-        case 67: return 4;
-        case 69: return 5;
-        case 71: return 6;
-        case 72: return 7;
+        case MIDI_BASE_NOTE +  0: return 0;
+        case MIDI_BASE_NOTE +  2: return 1;
+        case MIDI_BASE_NOTE +  4: return 2;
+        case MIDI_BASE_NOTE +  5: return 3;
+        case MIDI_BASE_NOTE +  7: return 4;
+        case MIDI_BASE_NOTE +  9: return 5;
+        case MIDI_BASE_NOTE + 11: return 6;
+        case MIDI_BASE_NOTE + 12: return 7;
     }
     return -1;
 }


Version 1.5 24th January 2017

Version 1.5 24th January 2017

Adds support for strings, including the string functions subseq for extracting a substring from a string, string= for comparing strings, length for finding the length of a string, and stringp for testing for strings.