v2.11
new HW with integrated OLED (Wifi Kit 8) and some fixes
This commit is contained in:
		
							
								
								
									
										489
									
								
								CG_scale.ino
									
									
									
									
									
								
							
							
						
						
									
										489
									
								
								CG_scale.ino
									
									
									
									
									
								
							@@ -4,18 +4,32 @@
 | 
			
		||||
                      (c) 2019 by M. Lehmann
 | 
			
		||||
  ------------------------------------------------------------------
 | 
			
		||||
*/
 | 
			
		||||
#define CGSCALE_VERSION "2.0"
 | 
			
		||||
#define CGSCALE_VERSION "2.11"
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  ******************************************************************
 | 
			
		||||
  history:
 | 
			
		||||
  V2.11   18.08.20     code is now compatible with standard OLED displays
 | 
			
		||||
                       and original code base (default pw length = 32)
 | 
			
		||||
  V2.1    18.07.20     added support for ESP8266 based Wifi Kit 8
 | 
			
		||||
  (by Pulsar07/           (https://heltec.org/project/wifi-kit-8/)
 | 
			
		||||
   R.Stransky             is a ESP8266 with
 | 
			
		||||
                            a build in OLED 128x32
 | 
			
		||||
                            battery connector with charging management
 | 
			
		||||
                            reset and GPIO0 button
 | 
			
		||||
                        support for a tare button (PIN_TARE_BUTTON)
 | 
			
		||||
                        bug fixed: wifi password now with up to 64 chars
 | 
			
		||||
                        bug fixed: wifi data (ssid/passwd) with special
 | 
			
		||||
                          character (e.g. +) is now supported
 | 
			
		||||
                        for specified battery type, voltage is displayed
 | 
			
		||||
                        using uncompressed html files makes WEB GUI much faster
 | 
			
		||||
  V2.01   29.01.20      small bug fixes with AVR
 | 
			
		||||
  V2.0    26.01.20      Webpage rewritten, no bootstrap framework needed
 | 
			
		||||
                        add translation to webpage (en, de)
 | 
			
		||||
                        optimized for measuring with landinggears
 | 
			
		||||
                        updated to ArduinoJson V6
 | 
			
		||||
                        firmware update over web interface
 | 
			
		||||
  V1.2.1  31.03.19      small bug fixed 
 | 
			
		||||
  V1.2.1  31.03.19      small bug fixed
 | 
			
		||||
                        values in model database are rounded
 | 
			
		||||
                        mDNS and OTA did not work in AP mode
 | 
			
		||||
  V1.2    23.02.19      Add OTA (over the air update)
 | 
			
		||||
@@ -87,7 +101,7 @@
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// HX711 constructor array (dout pin, sck pint):
 | 
			
		||||
HX711_ADC LoadCell[]{HX711_ADC(PIN_LOADCELL1_DOUT, PIN_LOADCELL1_PD_SCK),HX711_ADC(PIN_LOADCELL2_DOUT, PIN_LOADCELL2_PD_SCK),HX711_ADC(PIN_LOADCELL3_DOUT, PIN_LOADCELL3_PD_SCK)};
 | 
			
		||||
HX711_ADC LoadCell[] {HX711_ADC(PIN_LOADCELL1_DOUT, PIN_LOADCELL1_PD_SCK), HX711_ADC(PIN_LOADCELL2_DOUT, PIN_LOADCELL2_PD_SCK), HX711_ADC(PIN_LOADCELL3_DOUT, PIN_LOADCELL3_PD_SCK)};
 | 
			
		||||
 | 
			
		||||
// webserver constructor
 | 
			
		||||
#if defined(ESP8266)
 | 
			
		||||
@@ -142,6 +156,12 @@ bool updateMenu = true;
 | 
			
		||||
int menuPage = 0;
 | 
			
		||||
String errMsg[5];
 | 
			
		||||
int errMsgCnt = 0;
 | 
			
		||||
int oledDisplayHeight;
 | 
			
		||||
int oledDisplayWidth;
 | 
			
		||||
const uint8_t *oledFontLarge;
 | 
			
		||||
const uint8_t *oledFontNormal;
 | 
			
		||||
const uint8_t *oledFontSmall;
 | 
			
		||||
const uint8_t *oledFontTiny;
 | 
			
		||||
#if defined(ESP8266)
 | 
			
		||||
String updateMsg = "";
 | 
			
		||||
bool wifiSTAmode = true;
 | 
			
		||||
@@ -156,6 +176,200 @@ void(* resetCPU) (void) = 0;
 | 
			
		||||
void resetCPU() {}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void initOLED() {
 | 
			
		||||
  oledDisplay.begin();
 | 
			
		||||
  oledDisplayHeight = oledDisplay.getDisplayHeight();
 | 
			
		||||
  oledDisplayWidth = oledDisplay.getDisplayWidth();
 | 
			
		||||
  printConsole(T_BOOT, "init OLED display: " + String(oledDisplayWidth) + String("x") + String(oledDisplayHeight));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  oledFontLarge  = u8g2_font_helvR12_tr;
 | 
			
		||||
  oledFontNormal = u8g2_font_helvR10_tr;
 | 
			
		||||
  oledFontSmall  = u8g2_font_5x7_tr;
 | 
			
		||||
  oledFontTiny   = u8g2_font_4x6_tr;
 | 
			
		||||
 | 
			
		||||
  if (oledDisplayHeight <= 32) {
 | 
			
		||||
    oledFontLarge  = u8g2_font_helvR10_tr;
 | 
			
		||||
    oledFontNormal = u8g2_font_6x12_tr;
 | 
			
		||||
  }
 | 
			
		||||
  int ylineHeight = oledDisplayHeight / 3;
 | 
			
		||||
 | 
			
		||||
  oledDisplay.setFont(oledFontNormal);
 | 
			
		||||
 | 
			
		||||
  oledDisplay.firstPage();
 | 
			
		||||
  do {
 | 
			
		||||
    oledDisplay.setFont(oledFontLarge);
 | 
			
		||||
    if (oledDisplayHeight <= 32) {
 | 
			
		||||
      oledDisplay.drawXBMP(5, 0, 18, 18, CGImage);
 | 
			
		||||
    } else {
 | 
			
		||||
      oledDisplay.drawXBMP(20, 12, 18, 18, CGImage);
 | 
			
		||||
    }
 | 
			
		||||
    oledDisplay.setFont(oledFontLarge);
 | 
			
		||||
 | 
			
		||||
    if (oledDisplayHeight <= 32) {
 | 
			
		||||
      oledDisplay.setCursor(30, 12);
 | 
			
		||||
    } else {
 | 
			
		||||
      oledDisplay.setCursor(45, 28);
 | 
			
		||||
    }
 | 
			
		||||
    oledDisplay.print(F("CG scale"));
 | 
			
		||||
 | 
			
		||||
    oledDisplay.setFont(oledFontSmall);
 | 
			
		||||
    if (oledDisplayHeight <= 32) {
 | 
			
		||||
      oledDisplay.setCursor(30, 22);
 | 
			
		||||
    } else {
 | 
			
		||||
      oledDisplay.setCursor(35, 55);
 | 
			
		||||
    }
 | 
			
		||||
    oledDisplay.print(F("Version: "));
 | 
			
		||||
    oledDisplay.print(CGSCALE_VERSION);
 | 
			
		||||
    if (oledDisplayHeight <= 32) {
 | 
			
		||||
      oledDisplay.setCursor(5, 31);
 | 
			
		||||
    } else {
 | 
			
		||||
      oledDisplay.setCursor(20, 64);
 | 
			
		||||
    }
 | 
			
		||||
    oledDisplay.print(F("(c) 2019 M.Lehmann et al."));
 | 
			
		||||
 | 
			
		||||
  } while ( oledDisplay.nextPage() );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void printOLED(String aLine1, String aLine2, String aLine3 = String(""));
 | 
			
		||||
 | 
			
		||||
void printOLED(String aLine1, String aLine2, String aLine3) {
 | 
			
		||||
  int ylineHeight = oledDisplayHeight / 3;
 | 
			
		||||
 | 
			
		||||
  oledDisplay.firstPage();
 | 
			
		||||
  do {
 | 
			
		||||
    oledDisplay.setFont(oledFontNormal);
 | 
			
		||||
    oledDisplay.setCursor(0, ylineHeight * 1);
 | 
			
		||||
    oledDisplay.print(aLine1);
 | 
			
		||||
    oledDisplay.setCursor(0, ylineHeight * 2);
 | 
			
		||||
    oledDisplay.print(aLine2);
 | 
			
		||||
    if (aLine3 == "") {
 | 
			
		||||
      oledDisplay.drawLine(0, ylineHeight * 2 + 2, oledDisplayWidth, ylineHeight * 2 + 2);
 | 
			
		||||
      oledDisplay.setFont(oledFontTiny);
 | 
			
		||||
      oledDisplay.setCursor(0, oledDisplayHeight);
 | 
			
		||||
      oledDisplay.print("IP:" + WiFi.localIP().toString());
 | 
			
		||||
      String signature = "CG scale: V" + String(CGSCALE_VERSION);
 | 
			
		||||
      oledDisplay.setCursor(oledDisplayWidth - oledDisplay.getStrWidth(signature.c_str()), oledDisplayHeight);
 | 
			
		||||
      oledDisplay.print(signature);
 | 
			
		||||
    } else {
 | 
			
		||||
      oledDisplay.setCursor(0, oledDisplayHeight);
 | 
			
		||||
      oledDisplay.print(aLine3);
 | 
			
		||||
    }
 | 
			
		||||
  } while ( oledDisplay.nextPage() );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void printScaleOLED() {
 | 
			
		||||
  // print to display
 | 
			
		||||
  char buff1[8];
 | 
			
		||||
  char buff[12];
 | 
			
		||||
  char buff2[8];
 | 
			
		||||
  int pos_weightTotal = 7;
 | 
			
		||||
  int pos_CG_length = 28;
 | 
			
		||||
  if (nLoadcells == 2) {
 | 
			
		||||
    pos_weightTotal = 17;
 | 
			
		||||
    pos_CG_length = 45;
 | 
			
		||||
    if (batType == 0) {
 | 
			
		||||
      pos_weightTotal = 12;
 | 
			
		||||
      pos_CG_length = 40;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  oledDisplay.firstPage();
 | 
			
		||||
  do {
 | 
			
		||||
    if (errMsgCnt == 0) {
 | 
			
		||||
      // print battery
 | 
			
		||||
      if (batType > B_OFF) {
 | 
			
		||||
        oledDisplay.drawXBMP(48, 1, 12, 6, batteryImage);
 | 
			
		||||
        float percentVolt = percentBat(batVolt / batCells);
 | 
			
		||||
        dtostrf(percentVolt, 3, 0, buff);
 | 
			
		||||
        oledDisplay.drawBox(49, 2, (percentVolt / (100 / 8)), 4);
 | 
			
		||||
 | 
			
		||||
        oledDisplay.setFont(oledFontSmall);
 | 
			
		||||
        oledDisplay.setCursor(78 - oledDisplay.getStrWidth(buff), 7);
 | 
			
		||||
        if (batType > B_VOLT) {
 | 
			
		||||
          dtostrf(percentVolt, 3, 0, buff);
 | 
			
		||||
          oledDisplay.print(buff);
 | 
			
		||||
          oledDisplay.print(F("%/"));
 | 
			
		||||
        }
 | 
			
		||||
        dtostrf(batVolt, 2, 2, buff);
 | 
			
		||||
        oledDisplay.print(buff);
 | 
			
		||||
        oledDisplay.print(F("V"));
 | 
			
		||||
      }
 | 
			
		||||
 
 | 
			
		||||
      // print total weight
 | 
			
		||||
      oledDisplay.setFont(oledFontNormal);
 | 
			
		||||
      dtostrf(weightTotal, 7, 1, buff);
 | 
			
		||||
      if (oledDisplayHeight <= 32) {
 | 
			
		||||
        oledDisplay.setCursor(1, 18);
 | 
			
		||||
        oledDisplay.print(F("M  = "));
 | 
			
		||||
      } else {
 | 
			
		||||
        oledDisplay.drawXBMP(2, pos_weightTotal, 18, 18, weightImage);
 | 
			
		||||
        oledDisplay.setCursor(93 - oledDisplay.getStrWidth(buff), pos_weightTotal + 17);
 | 
			
		||||
      }
 | 
			
		||||
      oledDisplay.print(buff);
 | 
			
		||||
      oledDisplay.print(F(" g"));
 | 
			
		||||
 | 
			
		||||
      // print CG longitudinal axis
 | 
			
		||||
      dtostrf(CG_length, 7, 1, buff);
 | 
			
		||||
      if (oledDisplayHeight <= 32) {
 | 
			
		||||
        oledDisplay.setCursor(1, 32);
 | 
			
		||||
        oledDisplay.print(F("CG = "));
 | 
			
		||||
      } else {
 | 
			
		||||
        oledDisplay.drawXBMP(2, pos_CG_length, 18, 18, CGImage);
 | 
			
		||||
        oledDisplay.setCursor(93 - oledDisplay.getStrWidth(buff), pos_CG_length + 16);
 | 
			
		||||
      }
 | 
			
		||||
      oledDisplay.print(buff);
 | 
			
		||||
      oledDisplay.print(F(" mm"));
 | 
			
		||||
 | 
			
		||||
      // print CG transverse axis
 | 
			
		||||
      if (nLoadcells == 3) {
 | 
			
		||||
        if (oledDisplayHeight <= 32) {
 | 
			
		||||
          oledDisplay.setCursor(78, 32);
 | 
			
		||||
          oledDisplay.print(F("LR="));
 | 
			
		||||
          dtostrf(CG_trans, 3, 0, buff);
 | 
			
		||||
        } else {
 | 
			
		||||
          oledDisplay.drawXBMP(2, 47, 18, 18, CGtransImage);
 | 
			
		||||
          oledDisplay.setCursor(93 - oledDisplay.getStrWidth(buff), 64);
 | 
			
		||||
          dtostrf(CG_trans, 7, 1, buff);
 | 
			
		||||
        }
 | 
			
		||||
        oledDisplay.print(buff);
 | 
			
		||||
        oledDisplay.print(F(" mm"));
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      oledDisplay.setFont(oledFontSmall);
 | 
			
		||||
      for (int i = 1; i <= errMsgCnt; i++) {
 | 
			
		||||
        oledDisplay.setCursor(0, 7 * i);
 | 
			
		||||
        oledDisplay.print(errMsg[i]);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  } while ( oledDisplay.nextPage() );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef PIN_TARE_BUTTON
 | 
			
		||||
void handleTareBtn() {
 | 
			
		||||
  static unsigned long lastTaraBtn = 0;
 | 
			
		||||
  if ((millis() - lastTaraBtn) > 20) {
 | 
			
		||||
    lastTaraBtn = millis();
 | 
			
		||||
    static int tareBtnCnt = 0;
 | 
			
		||||
    if (digitalRead(PIN_TARE_BUTTON)) {
 | 
			
		||||
      tareBtnCnt = 0;
 | 
			
		||||
    } else {
 | 
			
		||||
      tareBtnCnt++;
 | 
			
		||||
      if (tareBtnCnt > 10) {
 | 
			
		||||
        Serial.println("tare button pressed");
 | 
			
		||||
        printOLED("TARE ==>", "  tare load cells ...");
 | 
			
		||||
        // avoid keybounce
 | 
			
		||||
        tareBtnCnt = -1000;
 | 
			
		||||
        tareLoadcells();
 | 
			
		||||
        delay(2000);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// save calibration factor
 | 
			
		||||
void saveCalFactor(int nLC) {
 | 
			
		||||
@@ -167,7 +381,7 @@ void saveCalFactor(int nLC) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void updateLoadcells(){
 | 
			
		||||
void updateLoadcells() {
 | 
			
		||||
  for (int i = LC1; i <= LC3; i++) {
 | 
			
		||||
    if (i < nLoadcells) {
 | 
			
		||||
      LoadCell[i].update();
 | 
			
		||||
@@ -176,7 +390,7 @@ void updateLoadcells(){
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void tareLoadcells(){
 | 
			
		||||
void tareLoadcells() {
 | 
			
		||||
  for (int i = LC1; i <= LC3; i++) {
 | 
			
		||||
    if (i < nLoadcells) {
 | 
			
		||||
      LoadCell[i].tare();
 | 
			
		||||
@@ -185,7 +399,7 @@ void tareLoadcells(){
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void printNewValueText(){
 | 
			
		||||
void printNewValueText() {
 | 
			
		||||
  Serial.print(F("Set new value:"));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -210,7 +424,7 @@ bool runAutoCalibrate() {
 | 
			
		||||
    calFactorLoadcell[i] = calFactorLoadcell[i] / (toWeightLoadCell[i] / weightLoadCell[i]);
 | 
			
		||||
    saveCalFactor(i);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  // finish
 | 
			
		||||
  Serial.println(F("done"));
 | 
			
		||||
}
 | 
			
		||||
@@ -250,7 +464,7 @@ int percentBat(float cellVoltage) {
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  float cellempty = pgm_read_float( &percentList[batTypeArray][0][0]);
 | 
			
		||||
  float cellfull = pgm_read_float( &percentList[batTypeArray][elementCount][0]);
 | 
			
		||||
 | 
			
		||||
@@ -262,9 +476,9 @@ int percentBat(float cellVoltage) {
 | 
			
		||||
    for (int i = 0; i <= elementCount; i++) {
 | 
			
		||||
      float curVolt = pgm_read_float(&percentList[batTypeArray][i][0]);
 | 
			
		||||
      if (curVolt >= cellVoltage && i > 0) {
 | 
			
		||||
        float lastVolt = pgm_read_float(&percentList[batTypeArray][i-1][0]);
 | 
			
		||||
        float lastVolt = pgm_read_float(&percentList[batTypeArray][i - 1][0]);
 | 
			
		||||
        float curPercent = pgm_read_float(&percentList[batTypeArray][i][1]);
 | 
			
		||||
        float lastPercent = pgm_read_float(&percentList[batTypeArray][i-1][1]);
 | 
			
		||||
        float lastPercent = pgm_read_float(&percentList[batTypeArray][i - 1][1]);
 | 
			
		||||
        result = float((cellVoltage - lastVolt) / (curVolt - lastVolt)) * (curPercent - lastPercent) + lastPercent;
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
@@ -279,12 +493,13 @@ int percentBat(float cellVoltage) {
 | 
			
		||||
void setup() {
 | 
			
		||||
 | 
			
		||||
  // init serial
 | 
			
		||||
  Serial.begin(9600);
 | 
			
		||||
  Serial.begin(115200);
 | 
			
		||||
  Serial.println();
 | 
			
		||||
  delay(1000);
 | 
			
		||||
 | 
			
		||||
#if defined(ESP8266)
 | 
			
		||||
  printConsole(T_BOOT, "startup CG scale V" + String(CGSCALE_VERSION));
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  // init filesystem
 | 
			
		||||
  SPIFFS.begin();
 | 
			
		||||
  EEPROM.begin(EEPROM_SIZE);
 | 
			
		||||
@@ -367,24 +582,7 @@ void setup() {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  // init OLED display
 | 
			
		||||
#if defined(ESP8266)
 | 
			
		||||
  printConsole(T_BOOT, "init OLED display");
 | 
			
		||||
#endif
 | 
			
		||||
  oledDisplay.begin();
 | 
			
		||||
  oledDisplay.firstPage();
 | 
			
		||||
  do {
 | 
			
		||||
    oledDisplay.drawXBMP(20, 12, 18, 18, CGImage);
 | 
			
		||||
    oledDisplay.setFont(u8g2_font_helvR12_tr);
 | 
			
		||||
    oledDisplay.setCursor(45, 28);
 | 
			
		||||
    oledDisplay.print(F("CG scale"));
 | 
			
		||||
 | 
			
		||||
    oledDisplay.setFont(u8g2_font_5x7_tr);
 | 
			
		||||
    oledDisplay.setCursor(35, 55);
 | 
			
		||||
    oledDisplay.print(F("Version: "));
 | 
			
		||||
    oledDisplay.print(CGSCALE_VERSION);
 | 
			
		||||
    oledDisplay.setCursor(20, 64);
 | 
			
		||||
    oledDisplay.print(F("(c) 2019 M. Lehmann"));
 | 
			
		||||
  } while ( oledDisplay.nextPage() );
 | 
			
		||||
  initOLED();
 | 
			
		||||
 | 
			
		||||
  // init & tare Loadcells
 | 
			
		||||
  for (int i = LC1; i <= LC3; i++) {
 | 
			
		||||
@@ -392,7 +590,7 @@ void setup() {
 | 
			
		||||
      LoadCell[i].begin();
 | 
			
		||||
      LoadCell[i].setCalFactor(calFactorLoadcell[i]);
 | 
			
		||||
#if defined(ESP8266)
 | 
			
		||||
      printConsole(T_BOOT, "init Loadcell " + String(i+1));
 | 
			
		||||
      printConsole(T_BOOT, "init Loadcell " + String(i + 1));
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
@@ -408,28 +606,32 @@ void setup() {
 | 
			
		||||
 | 
			
		||||
#if defined(ESP8266)
 | 
			
		||||
 | 
			
		||||
  printConsole(T_BOOT, "Wifi: STA mode - connecing with: " + String(ssid_STA));
 | 
			
		||||
 | 
			
		||||
  // Start by connecting to a WiFi network
 | 
			
		||||
  WiFi.persistent(false);
 | 
			
		||||
  WiFi.mode(WIFI_STA);
 | 
			
		||||
  WiFi.begin(ssid_STA, password_STA);
 | 
			
		||||
 | 
			
		||||
  printConsole(T_BOOT, "Wifi: STA mode - connect with: " + String(ssid_STA));
 | 
			
		||||
 | 
			
		||||
  long timeoutWiFi = millis();
 | 
			
		||||
 | 
			
		||||
  while (WiFi.status() != WL_CONNECTED) {
 | 
			
		||||
    delay(500);
 | 
			
		||||
    Serial.print(".");
 | 
			
		||||
    if (WiFi.status() == WL_NO_SSID_AVAIL) {
 | 
			
		||||
      printConsole(T_ERROR, "Wifi: No SSID available");
 | 
			
		||||
      printConsole(T_ERROR, "\nWifi: No SSID available");
 | 
			
		||||
      break;
 | 
			
		||||
    } else if (WiFi.status() == WL_CONNECT_FAILED) {
 | 
			
		||||
      printConsole(T_ERROR, "Wifi: Connection failed");
 | 
			
		||||
      printConsole(T_ERROR, "\nWifi: Connection failed");
 | 
			
		||||
      break;
 | 
			
		||||
    } else if ((millis() - timeoutWiFi) > TIMEOUT_CONNECT) {
 | 
			
		||||
      printConsole(T_ERROR, "Wifi: Timeout");
 | 
			
		||||
      printConsole(T_ERROR, "\nWifi: Timeout");
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  if (WiFi.status() != WL_CONNECTED) {
 | 
			
		||||
    // if WiFi not connected, switch to access point mode
 | 
			
		||||
    wifiSTAmode = false;
 | 
			
		||||
@@ -442,7 +644,7 @@ void setup() {
 | 
			
		||||
    printConsole(T_RUN, "Wifi: Connected, IP: " + String(WiFi.localIP().toString()));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  // Set Hostname
 | 
			
		||||
  String hostname = "disabled";
 | 
			
		||||
#if ENABLE_MDNS
 | 
			
		||||
@@ -452,40 +654,22 @@ void setup() {
 | 
			
		||||
  if (!MDNS.begin(hostname, WiFi.localIP())) {
 | 
			
		||||
    hostname = "mDNS failed";
 | 
			
		||||
    printConsole(T_ERROR, "Wifi: " + hostname);
 | 
			
		||||
  }else{
 | 
			
		||||
  } else {
 | 
			
		||||
    hostname += ".local";
 | 
			
		||||
    printConsole(T_RUN, "Wifi: " + hostname);
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  if (wifiSTAmode) {
 | 
			
		||||
    printOLED("WiFi: " + String(ssid_STA),
 | 
			
		||||
              "Host: " + String(hostname),
 | 
			
		||||
              "IP  : " + WiFi.localIP().toString());
 | 
			
		||||
  } else {
 | 
			
		||||
    printOLED("WiFi: " + String(ssid_AP),
 | 
			
		||||
              "Host: " + String(hostname),
 | 
			
		||||
              "IP  : " + WiFi.softAPIP().toString());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // print wifi status
 | 
			
		||||
  oledDisplay.firstPage();
 | 
			
		||||
  do {
 | 
			
		||||
    oledDisplay.setFont(u8g2_font_5x7_tr);
 | 
			
		||||
    oledDisplay.setCursor(0, 14);
 | 
			
		||||
    oledDisplay.print(F("WiFi:"));
 | 
			
		||||
    oledDisplay.setCursor(0, 39);
 | 
			
		||||
    oledDisplay.print(F("Host:"));
 | 
			
		||||
    oledDisplay.setCursor(0, 64);
 | 
			
		||||
    oledDisplay.print(F("IP:"));
 | 
			
		||||
 | 
			
		||||
    oledDisplay.setFont(u8g2_font_helvR10_tr);
 | 
			
		||||
    oledDisplay.setCursor(28, 14);
 | 
			
		||||
    if (wifiSTAmode) {
 | 
			
		||||
      oledDisplay.print(ssid_STA);
 | 
			
		||||
    } else {
 | 
			
		||||
      oledDisplay.print(ssid_AP);
 | 
			
		||||
    }
 | 
			
		||||
    oledDisplay.setCursor(28, 39);
 | 
			
		||||
    oledDisplay.print(hostname);
 | 
			
		||||
    oledDisplay.setCursor(28, 64);
 | 
			
		||||
    if (wifiSTAmode) {
 | 
			
		||||
      oledDisplay.print(WiFi.localIP());
 | 
			
		||||
    } else {
 | 
			
		||||
      oledDisplay.print(WiFi.softAPIP());
 | 
			
		||||
    }
 | 
			
		||||
  } while ( oledDisplay.nextPage() );
 | 
			
		||||
  delay(3000);
 | 
			
		||||
 | 
			
		||||
  // When the client requests data
 | 
			
		||||
@@ -520,10 +704,10 @@ void setup() {
 | 
			
		||||
  printConsole(T_RUN, "Webserver is up and running");
 | 
			
		||||
 | 
			
		||||
  // init OTA (over the air update)
 | 
			
		||||
  if(enableOTA){    
 | 
			
		||||
  if (enableOTA) {
 | 
			
		||||
    ArduinoOTA.setHostname(ssid_AP);
 | 
			
		||||
    ArduinoOTA.setPassword(password_AP);
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
    ArduinoOTA.onStart([]() {
 | 
			
		||||
      String type;
 | 
			
		||||
      if (ArduinoOTA.getCommand() == U_FLASH) {
 | 
			
		||||
@@ -535,16 +719,16 @@ void setup() {
 | 
			
		||||
      updateMsg = "Updating " + type;
 | 
			
		||||
      printConsole(T_UPDATE, type);
 | 
			
		||||
    });
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
    ArduinoOTA.onEnd([]() {
 | 
			
		||||
      updateMsg = "successful..";
 | 
			
		||||
      printUpdateProgress(100, 100);
 | 
			
		||||
    });
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
    ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
 | 
			
		||||
      printUpdateProgress(progress, total);
 | 
			
		||||
    });
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
    ArduinoOTA.onError([](ota_error_t error) {
 | 
			
		||||
      if (error == OTA_AUTH_ERROR) {
 | 
			
		||||
        updateMsg = "Auth Failed";
 | 
			
		||||
@@ -563,14 +747,14 @@ void setup() {
 | 
			
		||||
    ArduinoOTA.begin();
 | 
			
		||||
    printConsole(T_RUN, "OTA is up and running");
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // https update 
 | 
			
		||||
 | 
			
		||||
  // https update
 | 
			
		||||
  httpsClient.setInsecure();
 | 
			
		||||
  if(enableUpdate){
 | 
			
		||||
  if (enableUpdate) {
 | 
			
		||||
    // check for update
 | 
			
		||||
    httpsUpdate(PROBE_UPDATE);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -584,12 +768,16 @@ void loop() {
 | 
			
		||||
  MDNS.update();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  if(enableOTA){
 | 
			
		||||
  if (enableOTA) {
 | 
			
		||||
    ArduinoOTA.handle();
 | 
			
		||||
  }
 | 
			
		||||
  server.handleClient();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef PIN_TARE_BUTTON
 | 
			
		||||
  handleTareBtn();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  updateLoadcells();
 | 
			
		||||
 | 
			
		||||
  // update loadcell values
 | 
			
		||||
@@ -607,6 +795,7 @@ void loop() {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  // update display and serial menu
 | 
			
		||||
  if ((millis() - lastTimeMenu) > UPDATE_INTERVAL_OLED_MENU) {
 | 
			
		||||
 | 
			
		||||
@@ -623,9 +812,9 @@ void loop() {
 | 
			
		||||
      CG_length = ((weightLoadCell[LC2] * model.distance[X2]) / weightTotal) + model.distance[X1];
 | 
			
		||||
 | 
			
		||||
#if defined(ESP8266)
 | 
			
		||||
      if(model.mechanicsType == 2){
 | 
			
		||||
      if (model.mechanicsType == 2) {
 | 
			
		||||
        CG_length = ((weightLoadCell[LC2] * model.distance[X2]) / weightTotal) - model.distance[X1];
 | 
			
		||||
      }else if(model.mechanicsType == 3){
 | 
			
		||||
      } else if (model.mechanicsType == 3) {
 | 
			
		||||
        CG_length = ((weightLoadCell[LC2] * model.distance[X2]) / weightTotal) * -1 + model.distance[X1];
 | 
			
		||||
      }
 | 
			
		||||
#endif
 | 
			
		||||
@@ -643,80 +832,9 @@ void loop() {
 | 
			
		||||
    // read battery voltage
 | 
			
		||||
    if (batType > B_OFF) {
 | 
			
		||||
      batVolt = (analogRead(VOLTAGE_PIN) / 1024.0) * V_REF * ((resistor[R1] + resistor[R2]) / resistor[R2]) / 1000.0;
 | 
			
		||||
#if ENABLE_PERCENTLIST
 | 
			
		||||
      if (batType > B_VOLT) {
 | 
			
		||||
        batVolt = percentBat(batVolt / batCells);
 | 
			
		||||
      }
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // print to display
 | 
			
		||||
    char buff[8];
 | 
			
		||||
    int pos_weightTotal = 7;
 | 
			
		||||
    int pos_CG_length = 28;
 | 
			
		||||
    if (nLoadcells == 2) {
 | 
			
		||||
      pos_weightTotal = 17;
 | 
			
		||||
      pos_CG_length = 45;
 | 
			
		||||
      if (batType == 0) {
 | 
			
		||||
        pos_weightTotal = 12;
 | 
			
		||||
        pos_CG_length = 40;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    oledDisplay.firstPage();
 | 
			
		||||
    do {
 | 
			
		||||
      if (errMsgCnt == 0) {
 | 
			
		||||
        // print battery
 | 
			
		||||
        if (batType > B_OFF) {
 | 
			
		||||
          oledDisplay.drawXBMP(88, 1, 12, 6, batteryImage);
 | 
			
		||||
          if (batType == B_VOLT) {
 | 
			
		||||
            dtostrf(batVolt, 2, 2, buff);
 | 
			
		||||
          } else {
 | 
			
		||||
            dtostrf(batVolt, 3, 0, buff);
 | 
			
		||||
            oledDisplay.drawBox(89, 2, (batVolt / (100 / 8)), 4);
 | 
			
		||||
          }
 | 
			
		||||
          oledDisplay.setFont(u8g2_font_5x7_tr);
 | 
			
		||||
          oledDisplay.setCursor(123 - oledDisplay.getStrWidth(buff), 7);
 | 
			
		||||
          oledDisplay.print(buff);
 | 
			
		||||
          if (batType == B_VOLT) {
 | 
			
		||||
            oledDisplay.print(F("V"));
 | 
			
		||||
          } else {
 | 
			
		||||
            oledDisplay.print(F("%"));
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // print total weight
 | 
			
		||||
        oledDisplay.drawXBMP(2, pos_weightTotal, 18, 18, weightImage);
 | 
			
		||||
        dtostrf(weightTotal, 5, 1, buff);
 | 
			
		||||
        oledDisplay.setFont(u8g2_font_helvR12_tr);
 | 
			
		||||
        oledDisplay.setCursor(93 - oledDisplay.getStrWidth(buff), pos_weightTotal + 17);
 | 
			
		||||
        oledDisplay.print(buff);
 | 
			
		||||
        oledDisplay.print(F(" g"));
 | 
			
		||||
 | 
			
		||||
        // print CG longitudinal axis
 | 
			
		||||
        oledDisplay.drawXBMP(2, pos_CG_length, 18, 18, CGImage);
 | 
			
		||||
        dtostrf(CG_length, 5, 1, buff);
 | 
			
		||||
        oledDisplay.setCursor(93 - oledDisplay.getStrWidth(buff), pos_CG_length + 16);
 | 
			
		||||
        oledDisplay.print(buff);
 | 
			
		||||
        oledDisplay.print(F(" mm"));
 | 
			
		||||
 | 
			
		||||
        // print CG transverse axis
 | 
			
		||||
        if (nLoadcells == 3) {
 | 
			
		||||
          oledDisplay.drawXBMP(2, 47, 18, 18, CGtransImage);
 | 
			
		||||
          dtostrf(CG_trans, 5, 1, buff);
 | 
			
		||||
          oledDisplay.setCursor(93 - oledDisplay.getStrWidth(buff), 64);
 | 
			
		||||
          oledDisplay.print(buff);
 | 
			
		||||
          oledDisplay.print(F(" mm"));
 | 
			
		||||
        }
 | 
			
		||||
      } else {
 | 
			
		||||
        oledDisplay.setFont(u8g2_font_5x7_tr);
 | 
			
		||||
        for (int i = 1; i <= errMsgCnt; i++) {
 | 
			
		||||
          oledDisplay.setCursor(0, 7 * i);
 | 
			
		||||
          oledDisplay.print(errMsg[i]);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    } while ( oledDisplay.nextPage() );
 | 
			
		||||
    printScaleOLED();
 | 
			
		||||
 | 
			
		||||
    // serial connection
 | 
			
		||||
    if (Serial) {
 | 
			
		||||
@@ -839,7 +957,7 @@ void loop() {
 | 
			
		||||
      switch (menuPage)
 | 
			
		||||
      {
 | 
			
		||||
        case MENU_HOME: {
 | 
			
		||||
            Serial.print(F("\n\n********************************************\nCG scale by M.Lehmann - V"));
 | 
			
		||||
            Serial.print(F("\n\n********************************************\nCG scale by M.Lehmann et al. - V"));
 | 
			
		||||
            Serial.print(CGSCALE_VERSION);
 | 
			
		||||
            Serial.print(F("\n\n"));
 | 
			
		||||
 | 
			
		||||
@@ -851,7 +969,7 @@ void loop() {
 | 
			
		||||
            for (int i = X1; i <= X3; i++) {
 | 
			
		||||
              Serial.print(MENU_DISTANCE_X1 + i);
 | 
			
		||||
              Serial.print(F("  - Set distance X"));
 | 
			
		||||
              Serial.print(i+1);
 | 
			
		||||
              Serial.print(i + 1);
 | 
			
		||||
              Serial.print(F(" ("));
 | 
			
		||||
              Serial.print(model.distance[i]);
 | 
			
		||||
              Serial.print(F("mm)\n"));
 | 
			
		||||
@@ -872,9 +990,9 @@ void loop() {
 | 
			
		||||
 | 
			
		||||
            for (int i = LC1; i <= LC3; i++) {
 | 
			
		||||
              Serial.print(MENU_LOADCELL1_CALIBRATION_FACTOR + i);
 | 
			
		||||
              if((MENU_LOADCELL1_CALIBRATION_FACTOR + i) < 10) Serial.print(F(" "));
 | 
			
		||||
              if ((MENU_LOADCELL1_CALIBRATION_FACTOR + i) < 10) Serial.print(F(" "));
 | 
			
		||||
              Serial.print(F(" - Set calibration factor of load cell "));
 | 
			
		||||
              Serial.print(i+1);
 | 
			
		||||
              Serial.print(i + 1);
 | 
			
		||||
              Serial.print(F(" ("));
 | 
			
		||||
              Serial.print(calFactorLoadcell[i]);
 | 
			
		||||
              Serial.print(F(")\n"));
 | 
			
		||||
@@ -883,7 +1001,7 @@ void loop() {
 | 
			
		||||
            for (int i = R1; i <= R2; i++) {
 | 
			
		||||
              Serial.print(MENU_RESISTOR_R1 + i);
 | 
			
		||||
              Serial.print(F(" - Set value of resistor R"));
 | 
			
		||||
              Serial.print(i+1);
 | 
			
		||||
              Serial.print(i + 1);
 | 
			
		||||
              Serial.print(F(" ("));
 | 
			
		||||
              Serial.print(resistor[i]);
 | 
			
		||||
              Serial.print(F("ohm)\n"));
 | 
			
		||||
@@ -1112,10 +1230,16 @@ void getValue() {
 | 
			
		||||
    response += buff;
 | 
			
		||||
    response += "V";
 | 
			
		||||
  } else {
 | 
			
		||||
    dtostrf(batVolt, 5, 0, buff);
 | 
			
		||||
    float percentVolt = percentBat(batVolt / batCells);
 | 
			
		||||
    dtostrf(percentVolt, 5, 0, buff);
 | 
			
		||||
    response += buff;
 | 
			
		||||
    response += "%";
 | 
			
		||||
    response += "%/";
 | 
			
		||||
    dtostrf(batVolt, 5, 2, buff);
 | 
			
		||||
    response += buff;
 | 
			
		||||
    response += "V";
 | 
			
		||||
  }
 | 
			
		||||
  Serial.print("send response: ");
 | 
			
		||||
  Serial.println(response);
 | 
			
		||||
  server.send(200, "text/html", response);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1138,9 +1262,13 @@ void getRawValue() {
 | 
			
		||||
    response += buff;
 | 
			
		||||
    response += "V";
 | 
			
		||||
  } else {
 | 
			
		||||
    dtostrf(batVolt, 5, 0, buff);
 | 
			
		||||
    float percentVolt = percentBat(batVolt / batCells);
 | 
			
		||||
    dtostrf(percentVolt, 5, 0, buff);
 | 
			
		||||
    response += buff;
 | 
			
		||||
    response += "%";
 | 
			
		||||
    response += "%/";
 | 
			
		||||
    dtostrf(batVolt, 5, 2, buff);
 | 
			
		||||
    response += buff;
 | 
			
		||||
    response += "V";
 | 
			
		||||
  }
 | 
			
		||||
  server.send(200, "text/html", response);
 | 
			
		||||
}
 | 
			
		||||
@@ -1234,14 +1362,14 @@ void getWiFiNetworks() {
 | 
			
		||||
  bool ssidSTAavailable = false;
 | 
			
		||||
  String response = "";
 | 
			
		||||
  int n = WiFi.scanNetworks();
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  if (n > 0) {
 | 
			
		||||
    for (int i = 0; i < n; ++i) {
 | 
			
		||||
      response += WiFi.SSID(i);
 | 
			
		||||
      if(WiFi.SSID(i) == ssid_STA) ssidSTAavailable = true;
 | 
			
		||||
      if (WiFi.SSID(i) == ssid_STA) ssidSTAavailable = true;
 | 
			
		||||
      if (i < n - 1) response += "&";
 | 
			
		||||
    }
 | 
			
		||||
    if(!ssidSTAavailable){
 | 
			
		||||
    if (!ssidSTAavailable) {
 | 
			
		||||
      response += "&";
 | 
			
		||||
      response += ssid_STA;
 | 
			
		||||
    }
 | 
			
		||||
@@ -1293,7 +1421,7 @@ void saveParameter() {
 | 
			
		||||
  EEPROM.put(P_ENABLE_OTA, enableOTA);
 | 
			
		||||
  EEPROM.commit();
 | 
			
		||||
 | 
			
		||||
  if(model.name != ""){
 | 
			
		||||
  if (model.name != "") {
 | 
			
		||||
    saveModelJson(model.name);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -1554,7 +1682,7 @@ bool deleteModelJson(String modelName) {
 | 
			
		||||
void writeModelData(JsonObject object) {
 | 
			
		||||
  char buff[8];
 | 
			
		||||
  String stringBuff;
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  dtostrf(weightTotal, 5, 1, buff);
 | 
			
		||||
  stringBuff = buff;
 | 
			
		||||
  stringBuff.trim();
 | 
			
		||||
@@ -1579,14 +1707,13 @@ void writeModelData(JsonObject object) {
 | 
			
		||||
// print update progress screen
 | 
			
		||||
void printUpdateProgress(unsigned int progress, unsigned int total) {
 | 
			
		||||
  printConsole(T_UPDATE, updateMsg);
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  oledDisplay.firstPage();
 | 
			
		||||
  do {
 | 
			
		||||
    oledDisplay.setFont(u8g2_font_helvR08_tr);
 | 
			
		||||
    oledDisplay.setFont(oledFontSmall);
 | 
			
		||||
    oledDisplay.setCursor(0, 12);
 | 
			
		||||
    oledDisplay.print(updateMsg);
 | 
			
		||||
 | 
			
		||||
    oledDisplay.setFont(u8g2_font_5x7_tr);
 | 
			
		||||
    oledDisplay.setCursor(107, 35);
 | 
			
		||||
    oledDisplay.printf("%u%%\r", (progress / (total / 100)));
 | 
			
		||||
 | 
			
		||||
@@ -1611,10 +1738,10 @@ char * TimeToString(unsigned long t)
 | 
			
		||||
  return str;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void printConsole(int t, String msg){
 | 
			
		||||
void printConsole(int t, String msg) {
 | 
			
		||||
  Serial.print(TimeToString(millis()));
 | 
			
		||||
  Serial.print(" [");
 | 
			
		||||
  switch(t) {
 | 
			
		||||
  switch (t) {
 | 
			
		||||
    case T_BOOT:
 | 
			
		||||
      Serial.print("BOOT");
 | 
			
		||||
      break;
 | 
			
		||||
@@ -1640,7 +1767,7 @@ void printConsole(int t, String msg){
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// https update
 | 
			
		||||
bool httpsUpdate(uint8_t command){  
 | 
			
		||||
bool httpsUpdate(uint8_t command) {
 | 
			
		||||
  if (!httpsClient.connect(HOST, HTTPS_PORT)) {
 | 
			
		||||
    printConsole(T_ERROR, "Wifi: connection to GIT failed");
 | 
			
		||||
    return false;
 | 
			
		||||
@@ -1648,44 +1775,44 @@ bool httpsUpdate(uint8_t command){
 | 
			
		||||
 | 
			
		||||
  const char * headerKeys[] = {"Location"} ;
 | 
			
		||||
  const size_t numberOfHeaders = 1;
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  HTTPClient https;
 | 
			
		||||
  https.setUserAgent("cgscale");
 | 
			
		||||
  https.setRedirectLimit(0);
 | 
			
		||||
  https.setFollowRedirects(true);
 | 
			
		||||
 | 
			
		||||
  String url = "https://" + String(HOST) + String(URL);
 | 
			
		||||
  if (https.begin(httpsClient, url)) { 
 | 
			
		||||
  if (https.begin(httpsClient, url)) {
 | 
			
		||||
    https.collectHeaders(headerKeys, numberOfHeaders);
 | 
			
		||||
 | 
			
		||||
    printConsole(T_HTTPS, "GET: " + url);
 | 
			
		||||
    int httpCode = https.GET();
 | 
			
		||||
    if (httpCode > 0) {         
 | 
			
		||||
    if (httpCode > 0) {
 | 
			
		||||
      // response
 | 
			
		||||
      if (httpCode == HTTP_CODE_FOUND) {      
 | 
			
		||||
      if (httpCode == HTTP_CODE_FOUND) {
 | 
			
		||||
        String newUrl = https.header("Location");
 | 
			
		||||
        gitVersion = newUrl.substring(newUrl.lastIndexOf('/')+2).toFloat();
 | 
			
		||||
        if(gitVersion > String(CGSCALE_VERSION).toFloat()){
 | 
			
		||||
        gitVersion = newUrl.substring(newUrl.lastIndexOf('/') + 2).toFloat();
 | 
			
		||||
        if (gitVersion > String(CGSCALE_VERSION).toFloat()) {
 | 
			
		||||
          printConsole(T_UPDATE, "Firmware update available: V" + String(gitVersion));
 | 
			
		||||
        }else{
 | 
			
		||||
        } else {
 | 
			
		||||
          printConsole(T_UPDATE, "Firmware version found on GitHub: V" + String(gitVersion) + " - current firmware is up to date");
 | 
			
		||||
        }
 | 
			
		||||
      }else if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
 | 
			
		||||
      } else if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
 | 
			
		||||
        Serial.println(https.getString());
 | 
			
		||||
      }else{
 | 
			
		||||
      } else {
 | 
			
		||||
        printConsole(T_ERROR, "HTTPS: GET... failed, " + https.errorToString(httpCode));
 | 
			
		||||
        https.end();
 | 
			
		||||
        return false;
 | 
			
		||||
      }
 | 
			
		||||
    }else {
 | 
			
		||||
    } else {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
    https.end();    
 | 
			
		||||
  }else {
 | 
			
		||||
    https.end();
 | 
			
		||||
  } else {
 | 
			
		||||
    printConsole(T_ERROR, "Wifi: Unable to connect");
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@ Schwerpunktwaage auf Arduinobasis zum auswiegen von Flugmodellen. Es werden rela
 | 
			
		||||
Die wichtigsten Funktionen:
 | 
			
		||||
 | 
			
		||||
- unterstützt Waagen mit 2 oder 3 Wiegezellen
 | 
			
		||||
- unterstützt ESP8266 und Arduino mit ATmega328, ATmega32u4
 | 
			
		||||
- unterstützt ESP8266 (auch Wifi Kit 8) und Arduino mit ATmega328, ATmega32u4
 | 
			
		||||
- automatische Kalibrierung anhand eines Referenzobjekts, dadurch kein mühsames eruieren der Kalibrierwerte
 | 
			
		||||
- Anzeige durch OLED Display
 | 
			
		||||
- Batteriespannnung kann gemessen werden
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										880
									
								
								data/index.html
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										880
									
								
								data/index.html
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,880 @@
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html lang="en">
 | 
			
		||||
<head>
 | 
			
		||||
    <meta charset="utf-8">
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
 | 
			
		||||
    <meta name="description" content="">
 | 
			
		||||
    <meta name="author" content="M. Lehmann">
 | 
			
		||||
    <title>CG scale by M. Lehmann</title>
 | 
			
		||||
    <style>
 | 
			
		||||
        body {
 | 
			
		||||
            font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
 | 
			
		||||
            background: #DCDCDC;
 | 
			
		||||
            margin:0;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        /***** remove standard-styles *****/
 | 
			
		||||
        input, select, textarea {
 | 
			
		||||
          -webkit-appearance: none;
 | 
			
		||||
          -moz-appearance: none;
 | 
			
		||||
          appearance: none;
 | 
			
		||||
          border:none;
 | 
			
		||||
          border-radius: 4px;
 | 
			
		||||
          font-size: 1em;
 | 
			
		||||
          width: 100%
 | 
			
		||||
        } 
 | 
			
		||||
 | 
			
		||||
        /***** navbar *****/
 | 
			
		||||
 | 
			
		||||
        .navbar {
 | 
			
		||||
            list-style-type: none;
 | 
			
		||||
            margin: 0;
 | 
			
		||||
            padding: 0;
 | 
			
		||||
            top: 0;
 | 
			
		||||
            width: 100%;
 | 
			
		||||
            background-color: #555;
 | 
			
		||||
            position: fixed;
 | 
			
		||||
            overflow: auto;
 | 
			
		||||
            z-index: 10;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .navbar logo {
 | 
			
		||||
            float: left;
 | 
			
		||||
            display: block;
 | 
			
		||||
            padding: 12px;
 | 
			
		||||
            color: white;
 | 
			
		||||
            text-decoration: none;
 | 
			
		||||
            font-size: 32px;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .navbar a {
 | 
			
		||||
            float: right;
 | 
			
		||||
            display: block;
 | 
			
		||||
            padding: 12px;
 | 
			
		||||
            color: white;
 | 
			
		||||
            text-decoration: none;
 | 
			
		||||
            font-size: 32px;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .navbar a:hover {
 | 
			
		||||
            background-color: #000;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .active {
 | 
			
		||||
            background-color: #1E90FF;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        .navbar .icon {
 | 
			
		||||
            display: none;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        .navbar .badge {
 | 
			
		||||
          position: absolute;
 | 
			
		||||
          top: 0px;
 | 
			
		||||
          right: 0px;
 | 
			
		||||
          padding: 5px 8px;
 | 
			
		||||
          border-radius: 30%;
 | 
			
		||||
          background: red;
 | 
			
		||||
          color: white;
 | 
			
		||||
          font-size: 20px;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        @media screen and (max-width: 600px) {
 | 
			
		||||
            .navbar a:not(:first-child) {display: none;}
 | 
			
		||||
            .navbar a.icon {
 | 
			
		||||
                float: right;
 | 
			
		||||
                display: block;
 | 
			
		||||
            }
 | 
			
		||||
            .navbar.responsive {position: relative;}
 | 
			
		||||
            .navbar.responsive .icon {
 | 
			
		||||
                position: absolute;
 | 
			
		||||
                right: 0;
 | 
			
		||||
                top: 0;
 | 
			
		||||
                height: auto;
 | 
			
		||||
            }
 | 
			
		||||
            .navbar.responsive a {
 | 
			
		||||
                float: none;
 | 
			
		||||
                display: block;
 | 
			
		||||
                text-align: left;
 | 
			
		||||
            }
 | 
			
		||||
            .navbar.responsive logo{display: none;}
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /***** tab *****/
 | 
			
		||||
 | 
			
		||||
        * {
 | 
			
		||||
          box-sizing: border-box;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .wrapper {
 | 
			
		||||
          width: 100%;
 | 
			
		||||
          margin: 0 auto;
 | 
			
		||||
        }
 | 
			
		||||
        .tabs {
 | 
			
		||||
          position: relative;
 | 
			
		||||
          margin: 3rem 0;
 | 
			
		||||
          background: #1abc9c;
 | 
			
		||||
        }
 | 
			
		||||
        .tabs::before,
 | 
			
		||||
        .tabs::after {
 | 
			
		||||
          content: "";
 | 
			
		||||
          display: table;
 | 
			
		||||
        }
 | 
			
		||||
        .tabs::after {
 | 
			
		||||
          clear: both;
 | 
			
		||||
        }
 | 
			
		||||
        .tab {
 | 
			
		||||
          float: left;
 | 
			
		||||
        }
 | 
			
		||||
        .tab-switch {
 | 
			
		||||
          display: none;
 | 
			
		||||
        }
 | 
			
		||||
        .tab-label {
 | 
			
		||||
          position: relative;
 | 
			
		||||
          display: block;
 | 
			
		||||
          line-height: 2.75em;
 | 
			
		||||
          height: 3em;
 | 
			
		||||
          padding: 0 1.618em;
 | 
			
		||||
          background: #1abc9c;
 | 
			
		||||
          border-right: 0.125rem solid #16a085;
 | 
			
		||||
          color: #2c3e50;
 | 
			
		||||
          cursor: pointer;
 | 
			
		||||
          top: 0;
 | 
			
		||||
          transition: all 0.25s;
 | 
			
		||||
        }
 | 
			
		||||
        .tab-label:hover {
 | 
			
		||||
          top: -0.25rem;
 | 
			
		||||
          transition: top 0.25s;
 | 
			
		||||
        }
 | 
			
		||||
        .tab-content {
 | 
			
		||||
          height: 1320px;
 | 
			
		||||
          width: 100%;
 | 
			
		||||
          position: absolute;
 | 
			
		||||
          z-index: 1;
 | 
			
		||||
          top: 2.75em;
 | 
			
		||||
          left: 0;
 | 
			
		||||
          padding: 1.618rem;
 | 
			
		||||
          background: #FFFFFF;
 | 
			
		||||
          color: #2c3e50;
 | 
			
		||||
          opacity: 0;
 | 
			
		||||
          transition: all 0.35s;
 | 
			
		||||
        }
 | 
			
		||||
        .tab-switch:checked + .tab-label {
 | 
			
		||||
          background: #FFFFFF;
 | 
			
		||||
          color: #2c3e50;
 | 
			
		||||
          border-bottom: 0;
 | 
			
		||||
          transition: all 0.35s;
 | 
			
		||||
          z-index: 1;
 | 
			
		||||
          top: -0.0625rem;
 | 
			
		||||
        }
 | 
			
		||||
        .tab-switch:checked + label + .tab-content {
 | 
			
		||||
          z-index: 2;
 | 
			
		||||
          opacity: 1;
 | 
			
		||||
          transition: all 0.35s;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /***** button *****/
 | 
			
		||||
 | 
			
		||||
        .button {
 | 
			
		||||
            border: none;
 | 
			
		||||
            border-radius: 4px;
 | 
			
		||||
            color: white;
 | 
			
		||||
            padding: 7px 16px;
 | 
			
		||||
            text-align: center;
 | 
			
		||||
            text-decoration: none;
 | 
			
		||||
            display: inline-block;
 | 
			
		||||
            font-size: 16px;
 | 
			
		||||
            margin: 4px 2px;
 | 
			
		||||
            -webkit-transition-duration: 0.4s; /* Safari */
 | 
			
		||||
            transition-duration: 0.4s;
 | 
			
		||||
            cursor: pointer;
 | 
			
		||||
        }   
 | 
			
		||||
 | 
			
		||||
        .tareButton {
 | 
			
		||||
            background-color: white; 
 | 
			
		||||
            color: black; 
 | 
			
		||||
            border: 2px solid #778899;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .tareButton:hover {
 | 
			
		||||
            background-color: #778899;
 | 
			
		||||
            color: white;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .saveButton {
 | 
			
		||||
            background-color: white; 
 | 
			
		||||
            color: black; 
 | 
			
		||||
            border: 2px solid #1abc9c;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .saveButton:hover {
 | 
			
		||||
            background-color: #1abc9c;
 | 
			
		||||
            color: white;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        /***** Labels *****/
 | 
			
		||||
 | 
			
		||||
        big{
 | 
			
		||||
            display: inline-block;
 | 
			
		||||
            padding: 10px 2px;
 | 
			
		||||
            padding-top: 15px;
 | 
			
		||||
            font-size: 16px;
 | 
			
		||||
            color: #3c3c3c;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        .big_short{
 | 
			
		||||
            width: 12%; 
 | 
			
		||||
            text-align: left; 
 | 
			
		||||
            color: #808080;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        small{
 | 
			
		||||
            display: inline-block;
 | 
			
		||||
            padding: 10px 2px;
 | 
			
		||||
            font-size: 12px;
 | 
			
		||||
            color: #808080;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        .titlebar {
 | 
			
		||||
            margin-left:30px; 
 | 
			
		||||
            margin-top:95px; 
 | 
			
		||||
            font-size:25px; 
 | 
			
		||||
            float: left;
 | 
			
		||||
            width:40%;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        .buttonbar {
 | 
			
		||||
            margin-right:20px; 
 | 
			
		||||
            margin-top:85px; 
 | 
			
		||||
            float: right;
 | 
			
		||||
            text-align:right;
 | 
			
		||||
            width:50%;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        .main_container {
 | 
			
		||||
            padding-left:20px; 
 | 
			
		||||
            padding-right: 20px; 
 | 
			
		||||
            padding-top:105px; 
 | 
			
		||||
            padding-bottom: 1300px
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        .basic_img {
 | 
			
		||||
            height:50px; 
 | 
			
		||||
            padding-left:30px; 
 | 
			
		||||
            vertical-align:middle
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        .basic_text_cont{
 | 
			
		||||
            padding-left:20px; 
 | 
			
		||||
            vertical-align:middle; 
 | 
			
		||||
            float: right; 
 | 
			
		||||
            width: 70%;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        .basic_value{
 | 
			
		||||
            color:#000000; 
 | 
			
		||||
            font-size:40px; 
 | 
			
		||||
            width: 100%;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        .basic_value_saved{
 | 
			
		||||
            color:#808080; 
 | 
			
		||||
            font-size:17px; 
 | 
			
		||||
            width: 100%;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        @media screen and (max-width: 600px) {
 | 
			
		||||
            .titlebar {
 | 
			
		||||
                width:100%;
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            .buttonbar {
 | 
			
		||||
                margin-left:20px;
 | 
			
		||||
                margin-top:20px; 
 | 
			
		||||
                float: left;
 | 
			
		||||
                text-align:left;
 | 
			
		||||
                width:100%;
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            .main_container {
 | 
			
		||||
                padding-top:165px; 
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        /***** Input *****/
 | 
			
		||||
        
 | 
			
		||||
        input{
 | 
			
		||||
            background-color:white;
 | 
			
		||||
            border: 1px solid #bbb;
 | 
			
		||||
            padding:.75em 1em .5em 1em;
 | 
			
		||||
            font-size: 16px;
 | 
			
		||||
            color: #3c3c3c;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        .input_short{
 | 
			
		||||
            float: right; 
 | 
			
		||||
            width: 86%;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        input:active,
 | 
			
		||||
        
 | 
			
		||||
        /***** selectbox *****/
 | 
			
		||||
 | 
			
		||||
        select {
 | 
			
		||||
            /*width:100%;*/
 | 
			
		||||
            border: 1px solid #bbb;
 | 
			
		||||
            padding:.75em 1em .5em 1em;
 | 
			
		||||
            background-color:white;
 | 
			
		||||
            background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAKCAYAAAA6jzeaAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMDE0IDc5LjE1Njc5NywgMjAxNC8wOC8yMC0wOTo1MzowMiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTQgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MkVERjJERkRBQkVCMTFFNEFDN0Q5QjI0MDk3OTlBRjkiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MkVERjJERkVBQkVCMTFFNEFDN0Q5QjI0MDk3OTlBRjkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDoyRURGMkRGQkFCRUIxMUU0QUM3RDlCMjQwOTc5OUFGOSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDoyRURGMkRGQ0FCRUIxMUU0QUM3RDlCMjQwOTc5OUFGOSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PuR/G+4AAAENSURBVHjatJG9agJREIVnTeIbBPIMVnmCIAhqmUpiYTp3i5Q+ihC5lUVEiYW1BGy0SJsq4AMEAoFACKSw2XwDpxB/UNh14ONw587cOcyN4jgumtkTPIcQJnZkJElyizShRd/KMkQBRtBwEzx8d6QBrxurb2gZw008wh+cw4AB9wcM+P0ALtTXy2yCVc7QOvzCGfQZ1N5jwPN91Xl9Xf2ZN2E8tEBq8KNcYODDhgE/B917XU19losJGXlFKvANEXQZ3JEB167yfl9RfS4RpWm6ufJr5AUulZrquzy+oIqBN8sxtkzISAnxv75aS39qA++WcxR2JTWoDB9KuZZPYWCvCRlZIjcwd9X5JPEvwABY010Pev8kyQAAAABJRU5ErkJggg==');
 | 
			
		||||
            background-position: right;
 | 
			
		||||
            background-repeat: no-repeat;
 | 
			
		||||
            font-size: 16px;
 | 
			
		||||
            color: #3c3c3c;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Hide browser-styling in IE10 */
 | 
			
		||||
        select::-ms-expand {
 | 
			
		||||
          display:none;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Hide custom-icons in lower versions of Internet Explorer (< IE10). */
 | 
			
		||||
        .lt-ie10 select { 
 | 
			
		||||
            background-image: none; 
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
    </style>
 | 
			
		||||
    
 | 
			
		||||
    <script>       
 | 
			
		||||
        var CG_trans_visible = true;
 | 
			
		||||
        var batVolt_visible = true;
 | 
			
		||||
        var curModelName = "";
 | 
			
		||||
        var targetCGmin = 0;
 | 
			
		||||
        var targetCGmax = 0;
 | 
			
		||||
        var mType = 0;
 | 
			
		||||
        
 | 
			
		||||
        var imgFW190 = new Image();
 | 
			
		||||
        imgFW190.src = "fw190.png";
 | 
			
		||||
        
 | 
			
		||||
        var translation;
 | 
			
		||||
        var languages = {
 | 
			
		||||
          "en":{   
 | 
			
		||||
            "measure":"Measure",
 | 
			
		||||
            "tareBtn":"Tare",
 | 
			
		||||
            "saveBtn":"Save",
 | 
			
		||||
            "tabConfig":"Config",
 | 
			
		||||
            "gearTyp":"Landing gear type:",
 | 
			
		||||
            "gearTyp2":"2 point with tailspur",
 | 
			
		||||
            "gearTyp3":"3 point with nosewheel",
 | 
			
		||||
            "distances":"Distances in mm:",
 | 
			
		||||
            "tabBasic":"Basic",
 | 
			
		||||
            "weightTotalSaved":"not saved",
 | 
			
		||||
            "CG_lengthSaved":"not saved",
 | 
			
		||||
            "CG_transSaved":"not saved",
 | 
			
		||||
            "tabExpert":"Extended",
 | 
			
		||||
            "targetCG":"Target CG in mm:"
 | 
			
		||||
          },
 | 
			
		||||
          "de":{
 | 
			
		||||
            "measure":"Messen",
 | 
			
		||||
            "tareBtn":"Tare",
 | 
			
		||||
            "saveBtn":"Speichern",
 | 
			
		||||
            "tabConfig":"Konfig",
 | 
			
		||||
            "gearTyp":"Fahrwerktyp:",
 | 
			
		||||
            "gearTyp2":"2 Punkt mit Hecksporn",
 | 
			
		||||
            "gearTyp3":"3 Punkt mit Bugrad",
 | 
			
		||||
            "distances":"Distanzen in mm:",
 | 
			
		||||
            "tabBasic":"Basis",
 | 
			
		||||
            "weightTotalSaved":"nicht gespeichert",
 | 
			
		||||
            "CG_lengthSaved":"nicht gespeichert",
 | 
			
		||||
            "CG_transSaved":"nicht gespeichert",
 | 
			
		||||
            "tabExpert":"Erweitert",
 | 
			
		||||
            "targetCG":"Soll CG in mm:"
 | 
			
		||||
          }
 | 
			
		||||
        };
 | 
			
		||||
        
 | 
			
		||||
        
 | 
			
		||||
        function setTranslation(defaultLang) {
 | 
			
		||||
            var lang = navigator.languages ? navigator.languages[0] : navigator.language;
 | 
			
		||||
            lang = lang.substr(0, 2);
 | 
			
		||||
 | 
			
		||||
            translation = languages[lang] || languages[defaultLang];
 | 
			
		||||
            
 | 
			
		||||
            for (var item in translation) {
 | 
			
		||||
                var docElement = document.getElementById(item);
 | 
			
		||||
                if(docElement){
 | 
			
		||||
                    docElement.innerHTML = translation[item];
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        
 | 
			
		||||
        
 | 
			
		||||
        function getHead(){        
 | 
			
		||||
            var request = new XMLHttpRequest();
 | 
			
		||||
            request.onreadystatechange = function(){
 | 
			
		||||
                if(this.readyState == 4 && this.status == 200){
 | 
			
		||||
                    if(this.responseText != null){
 | 
			
		||||
                        var responseString = this.responseText;
 | 
			
		||||
                        var value = responseString.split("&");
 | 
			
		||||
                        document.getElementById("ssid").innerHTML = value[0];
 | 
			
		||||
                        document.getElementById("errMsg").innerHTML = value[1];
 | 
			
		||||
                        document.getElementById("cgscaleVersion").innerHTML = value[2];
 | 
			
		||||
                        // check if new version available
 | 
			
		||||
                        if(parseFloat(value[3]) > parseFloat(value[2])){
 | 
			
		||||
                            var a = document.getElementById('settingsBtn');
 | 
			
		||||
                            a.insertAdjacentHTML('beforeend', '<span class="badge">1</span>');
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            request.open("GET", "getHead", true);
 | 
			
		||||
            request.send();
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        function getParameter(){
 | 
			
		||||
            var request = new XMLHttpRequest();
 | 
			
		||||
            request.onreadystatechange = function(){
 | 
			
		||||
                if(this.readyState == 4 && this.status == 200){
 | 
			
		||||
                    if(this.responseText != null){
 | 
			
		||||
                        var responseString = this.responseText;
 | 
			
		||||
                        var value = responseString.split("&");
 | 
			
		||||
                        
 | 
			
		||||
                        if(value[0] == "2"){
 | 
			
		||||
                            CG_trans_visible = false;
 | 
			
		||||
                            document.getElementById("cglrContainer").outerHTML = "";
 | 
			
		||||
                        }
 | 
			
		||||
                        if(value[11] == "0"){
 | 
			
		||||
                            batVolt_visible = false;
 | 
			
		||||
                            document.getElementById("batContainer").outerHTML = "";
 | 
			
		||||
                        }
 | 
			
		||||
                        
 | 
			
		||||
                        
 | 
			
		||||
                        curModelName = value[17];
 | 
			
		||||
                        if (curModelName != "") {
 | 
			
		||||
                            document.getElementById("modelName").innerHTML = curModelName;
 | 
			
		||||
                            setValue("distanceX1", value[1]);
 | 
			
		||||
                            setValue("distanceX2", value[2]);
 | 
			
		||||
                            setValue("distanceX3", value[3]);
 | 
			
		||||
                            document.getElementById("weightTotalSaved").innerHTML = value[18];
 | 
			
		||||
                            document.getElementById("CG_lengthSaved").innerHTML = value[19];
 | 
			
		||||
                            if(CG_trans_visible == true){
 | 
			
		||||
                                document.getElementById("CG_transSaved").innerHTML = value[20];
 | 
			
		||||
                            }
 | 
			
		||||
                            setValue("targetCGmin", value[21]);
 | 
			
		||||
                            setValue("targetCGmax", value[22]);
 | 
			
		||||
                            targetCGmin = parseFloat(value[21]);
 | 
			
		||||
                            targetCGmax = parseFloat(value[22]);
 | 
			
		||||
                            mType = parseInt(value[23]);
 | 
			
		||||
                            if(mType == 0){
 | 
			
		||||
                                document.getElementById("tab-2").checked = true;
 | 
			
		||||
                            }else if(mType == 1){
 | 
			
		||||
                                document.getElementById("tab-config").hidden = false;
 | 
			
		||||
                                document.getElementById("tab-1").checked = true;
 | 
			
		||||
                                document.getElementById("gearTyp").outerHTML = "";
 | 
			
		||||
                                document.getElementById("gearTypeImg").src = "CG_scale_mechanics.png";
 | 
			
		||||
                            }else if(mType > 1){
 | 
			
		||||
                                document.getElementById("tab-config").hidden = false;
 | 
			
		||||
                                document.getElementById("tab-1").checked = true;
 | 
			
		||||
                                document.getElementById("mechanicsType").hidden = false;
 | 
			
		||||
                                setValue("mechanicsType", value[23]);
 | 
			
		||||
                                changeGearImg();
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            request.open("GET", "getParameter", true);
 | 
			
		||||
            request.send();
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        function getValue(){
 | 
			
		||||
            var request = new XMLHttpRequest();
 | 
			
		||||
            request.onreadystatechange = function(){
 | 
			
		||||
                if(this.readyState == 4 && this.status == 200){
 | 
			
		||||
                    if(this.responseText != null){
 | 
			
		||||
                        var responseString = this.responseText;
 | 
			
		||||
                        var value = responseString.split("&");
 | 
			
		||||
                        document.getElementById("weightTotal").innerHTML = value[0];
 | 
			
		||||
                        document.getElementById("CG_length").innerHTML = value[1];                        
 | 
			
		||||
                        if(CG_trans_visible == true){
 | 
			
		||||
                            document.getElementById("CG_trans").innerHTML = value[2];
 | 
			
		||||
                        }
 | 
			
		||||
                        if(batVolt_visible == true){
 | 
			
		||||
                            drawBattery(value[3]);
 | 
			
		||||
                        }
 | 
			
		||||
                        drawExpert(value[0],value[1],value[2]);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            request.open("GET", "getValue", true);
 | 
			
		||||
            request.send();
 | 
			
		||||
            setTimeout('getValue()', 1200);
 | 
			
		||||
        }
 | 
			
		||||
            
 | 
			
		||||
        function saveModel(){
 | 
			
		||||
            if (curModelName != "") {
 | 
			
		||||
                var data = "?";
 | 
			
		||||
                data += "modelname=" + curModelName;
 | 
			
		||||
                data += "&targetCGmin=" + document.getElementById("targetCGmin").value;
 | 
			
		||||
                data += "&targetCGmax=" + document.getElementById("targetCGmax").value;
 | 
			
		||||
                if(parseInt(mType) > 0){
 | 
			
		||||
                    data += "&distanceX1=" + document.getElementById("distanceX1").value;
 | 
			
		||||
                    data += "&distanceX2=" + document.getElementById("distanceX2").value;
 | 
			
		||||
                    data += "&distanceX3=" + document.getElementById("distanceX3").value;
 | 
			
		||||
                }
 | 
			
		||||
                data += "&mechanicsType=" + mType;
 | 
			
		||||
                var request = new XMLHttpRequest();
 | 
			
		||||
                request.onreadystatechange = function(){
 | 
			
		||||
                    if(this.readyState == 4 && this.status == 200){
 | 
			
		||||
                        alert(curModelName + " saved");
 | 
			
		||||
                        location.reload();
 | 
			
		||||
                    }else if(this.readyState == 4 && this.status == 404){
 | 
			
		||||
                        alert("Model not saved !");
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                request.open("GET", "saveModel" + data, true);
 | 
			
		||||
                request.send();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        function setValue(id, value)
 | 
			
		||||
        {    
 | 
			
		||||
            var element = document.getElementById(id);
 | 
			
		||||
            element.value = value;
 | 
			
		||||
        }
 | 
			
		||||
                
 | 
			
		||||
        function tare(){
 | 
			
		||||
            document.getElementById("weightTotal").innerHTML = "TARE";
 | 
			
		||||
            var request = new XMLHttpRequest();
 | 
			
		||||
            request.onreadystatechange = function(){
 | 
			
		||||
                if(this.readyState == 4 && this.status == 404){
 | 
			
		||||
                    alert("Tare failed !");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            request.open("GET", "tare", true);
 | 
			
		||||
            request.send();
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        function drawBattery(value){
 | 
			
		||||
            document.getElementById("batValue").innerHTML = value;
 | 
			
		||||
            
 | 
			
		||||
            var canvas = document.getElementById('batCanvas');
 | 
			
		||||
            var ctx = canvas.getContext('2d');
 | 
			
		||||
            ctx.clearRect(0,0,canvas.width, canvas.height);
 | 
			
		||||
            
 | 
			
		||||
            // battery icon
 | 
			
		||||
            var r = 5;
 | 
			
		||||
            var l = 40;
 | 
			
		||||
            var h = 20;
 | 
			
		||||
            var bl = 3;
 | 
			
		||||
            var bh = 3;
 | 
			
		||||
            var ox = 2;
 | 
			
		||||
            var oy = 2;
 | 
			
		||||
            // battery fill 
 | 
			
		||||
            var fr = 2;
 | 
			
		||||
            var fl = 34; //100%
 | 
			
		||||
            var fh = 14;
 | 
			
		||||
            var fx = 5;
 | 
			
		||||
            var fy = 5;
 | 
			
		||||
            
 | 
			
		||||
            var percentpos = value.indexOf('%');
 | 
			
		||||
            if(percentpos != -1){
 | 
			
		||||
                var percent = Number(value.substring(0, percentpos));
 | 
			
		||||
                fl = fl/100*percent;
 | 
			
		||||
            }else{
 | 
			
		||||
                fl = 0;
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
            // draw icon
 | 
			
		||||
            ctx.beginPath();
 | 
			
		||||
            ctx.lineWidth = 2;
 | 
			
		||||
            ctx.moveTo(ox, oy+r);
 | 
			
		||||
            ctx.arc(ox+r, oy+r, r, (Math.PI / 180) * 180, (Math.PI / 180) * 270, false);
 | 
			
		||||
            ctx.lineTo(ox+(l-r), oy);
 | 
			
		||||
            ctx.arc(ox+(l-r), oy+r, r, (Math.PI / 180) * 270, 0, false);
 | 
			
		||||
            ctx.lineTo(ox+l, h/2-bh+oy);
 | 
			
		||||
            ctx.lineTo(ox+l+bl, h/2-bh+oy);
 | 
			
		||||
            ctx.lineTo(ox+l+bl, h/2+bh+oy);
 | 
			
		||||
            ctx.lineTo(ox+l, h/2+bh+oy);
 | 
			
		||||
            ctx.lineTo(ox+l, oy+h-r);
 | 
			
		||||
            ctx.arc(ox+(l-r), oy+h-r, r, 0, (Math.PI / 180) * 90, false);
 | 
			
		||||
            ctx.lineTo(ox+r, oy+h);
 | 
			
		||||
            ctx.arc(ox+r, oy+h-r, r, (Math.PI / 180) * 90, (Math.PI / 180) * 180, false);
 | 
			
		||||
            ctx.lineTo(ox, oy+r);
 | 
			
		||||
            ctx.strokeStyle = "#FFFFFF";
 | 
			
		||||
            ctx.stroke();
 | 
			
		||||
            
 | 
			
		||||
            // draw filled value
 | 
			
		||||
            if(fl>1){
 | 
			
		||||
                ctx.beginPath();
 | 
			
		||||
                ctx.fillStyle = "#FFFFFF";
 | 
			
		||||
                ctx.moveTo(fx, fy+fr);
 | 
			
		||||
                ctx.arc(fx+fr, fy+fr, fr, (Math.PI / 180) * 180, (Math.PI / 180) * 270, false);
 | 
			
		||||
                ctx.lineTo(fx+(fl-fr), fy);
 | 
			
		||||
                ctx.arc(fx+(fl-fr), fy+fr, fr, (Math.PI / 180) * 270, 0, false);
 | 
			
		||||
                ctx.lineTo(fx+fl, fy+fh-fr);
 | 
			
		||||
                ctx.arc(fx+(fl-fr), fy+fh-fr, fr, 0, (Math.PI / 180) * 90, false);
 | 
			
		||||
                ctx.lineTo(fx+fr, fy+fh);
 | 
			
		||||
                ctx.arc(fx+fr, fy+fh-fr, fr, (Math.PI / 180) * 90, (Math.PI / 180) * 180, false);
 | 
			
		||||
                ctx.lineTo(fx, fy+fr);
 | 
			
		||||
                ctx.fill();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        function drawExpert(weight,cg,cglr){        
 | 
			
		||||
            var tolerance = (targetCGmax-targetCGmin)/2;
 | 
			
		||||
            var centerVal = parseFloat(cg) - (tolerance + targetCGmin);
 | 
			
		||||
            
 | 
			
		||||
            var canvas = document.getElementById("expertCanvas");
 | 
			
		||||
            var ctx = canvas.getContext("2d");
 | 
			
		||||
            ctx.clearRect(0,0,canvas.width, canvas.height);
 | 
			
		||||
            
 | 
			
		||||
            // print profil
 | 
			
		||||
            var pHeight = 400;
 | 
			
		||||
            var pHeightOffset = 170;
 | 
			
		||||
            
 | 
			
		||||
            ctx.beginPath();
 | 
			
		||||
            ctx.lineWidth = 3;
 | 
			
		||||
            ctx.moveTo(canvas.width/1000*5, pHeight/500*100+pHeightOffset);
 | 
			
		||||
            ctx.bezierCurveTo(canvas.width/1000*20, pHeight/500*-40+pHeightOffset, canvas.width/1000*1000, pHeight/500*95+pHeightOffset, canvas.width/1000*995, pHeight/500*100+pHeightOffset);
 | 
			
		||||
            ctx.moveTo(canvas.width/1000*5, pHeight/500*100+pHeightOffset);
 | 
			
		||||
            ctx.bezierCurveTo(canvas.width/1000*5, pHeight/500*140+pHeightOffset, canvas.width/1000*1000, pHeight/500*104+pHeightOffset, canvas.width/1000*995, pHeight/500*100+pHeightOffset);
 | 
			
		||||
            ctx.stroke();
 | 
			
		||||
            
 | 
			
		||||
            // print difference
 | 
			
		||||
            ctx.font = "25px Trebuchet MS";
 | 
			
		||||
            var strCenterVal = centerVal.toFixed(1)+"mm";
 | 
			
		||||
            var maxProgresPx = 100;
 | 
			
		||||
            var progresPx = (maxProgresPx / 2 / tolerance) * centerVal;
 | 
			
		||||
            if(progresPx > 0){
 | 
			
		||||
                if(progresPx < maxProgresPx/2){
 | 
			
		||||
                    ctx.fillStyle = "#00b300";
 | 
			
		||||
                }else{
 | 
			
		||||
                    ctx.fillStyle = "#FF0000";
 | 
			
		||||
                    if(progresPx > maxProgresPx){
 | 
			
		||||
                        progresPx = maxProgresPx;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                ctx.fillRect(225, 125+pHeightOffset, progresPx, 25);
 | 
			
		||||
                
 | 
			
		||||
                ctx.fillStyle = "#808080";
 | 
			
		||||
                ctx.textAlign = "left";
 | 
			
		||||
                ctx.fillText(strCenterVal, 232 + progresPx, 147+pHeightOffset);
 | 
			
		||||
            }else if(progresPx < 0){
 | 
			
		||||
                if(progresPx > maxProgresPx / 2 * -1){
 | 
			
		||||
                    ctx.fillStyle = "#00b300";
 | 
			
		||||
                }else{
 | 
			
		||||
                    ctx.fillStyle = "#FF0000";
 | 
			
		||||
                    if(progresPx < maxProgresPx * -1){
 | 
			
		||||
                        progresPx = maxProgresPx * -1;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                ctx.fillRect(225 + progresPx, 125+pHeightOffset, progresPx * -1, 25);
 | 
			
		||||
                
 | 
			
		||||
                ctx.fillStyle = "#808080";
 | 
			
		||||
                ctx.textAlign = "right";
 | 
			
		||||
                ctx.fillText(strCenterVal, 218 + progresPx, 147+pHeightOffset);
 | 
			
		||||
            }else{
 | 
			
		||||
                ctx.fillStyle = "#808080";
 | 
			
		||||
                ctx.textAlign = "left";
 | 
			
		||||
                ctx.fillText(strCenterVal, 190, 147+pHeightOffset);
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            // print CG
 | 
			
		||||
            var cgimg = document.getElementById("cgimg");
 | 
			
		||||
            ctx.drawImage(cgimg, 198, 180+pHeightOffset,55,55);
 | 
			
		||||
            ctx.font = "42px Trebuchet MS";
 | 
			
		||||
            ctx.fillStyle = "#000000";
 | 
			
		||||
            ctx.textAlign = "left";
 | 
			
		||||
            ctx.fillText(cg, 300, 224+pHeightOffset);
 | 
			
		||||
            
 | 
			
		||||
            // print weight
 | 
			
		||||
            var weightimg = document.getElementById("weightimg");
 | 
			
		||||
            ctx.drawImage(weightimg, 198, 50,55,55);
 | 
			
		||||
            ctx.font = "42px Trebuchet MS";
 | 
			
		||||
            ctx.fillStyle = "#000000";
 | 
			
		||||
            ctx.textAlign = "left";
 | 
			
		||||
            ctx.fillText(weight, 300, 94);
 | 
			
		||||
            
 | 
			
		||||
            // print CG L-R
 | 
			
		||||
            if(CG_trans_visible == true){
 | 
			
		||||
                var cglrHeightOffset = 550;
 | 
			
		||||
                ctx.drawImage(imgFW190, 50, cglrHeightOffset);
 | 
			
		||||
 | 
			
		||||
                // print difference
 | 
			
		||||
                ctx.font = "25px Trebuchet MS";
 | 
			
		||||
                maxProgresPx = 100;
 | 
			
		||||
                progresPx = (maxProgresPx / 2 / tolerance) * parseFloat(cglr);
 | 
			
		||||
                if(progresPx > 0){
 | 
			
		||||
                    ctx.fillStyle = "#FF0000";
 | 
			
		||||
                    if(progresPx > maxProgresPx){
 | 
			
		||||
                        progresPx = maxProgresPx;
 | 
			
		||||
                    }
 | 
			
		||||
                    ctx.fillRect(362, cglrHeightOffset+175, progresPx, 25);
 | 
			
		||||
 | 
			
		||||
                    ctx.fillStyle = "#808080";
 | 
			
		||||
                    ctx.textAlign = "left";
 | 
			
		||||
                    ctx.fillText(cglr, 369 + progresPx, cglrHeightOffset+197);
 | 
			
		||||
                }else if(progresPx < 0){
 | 
			
		||||
                    ctx.fillStyle = "#FF0000";
 | 
			
		||||
                    if(progresPx < maxProgresPx * -1){
 | 
			
		||||
                        progresPx = maxProgresPx * -1;
 | 
			
		||||
                    }
 | 
			
		||||
                    ctx.fillRect(362 + progresPx, cglrHeightOffset+175, progresPx * -1, 25);
 | 
			
		||||
 | 
			
		||||
                    ctx.fillStyle = "#808080";
 | 
			
		||||
                    ctx.textAlign = "right";
 | 
			
		||||
                    ctx.fillText(cglr, 355 + progresPx, cglrHeightOffset+197);
 | 
			
		||||
                }else{
 | 
			
		||||
                    ctx.fillStyle = "#808080";
 | 
			
		||||
                    ctx.textAlign = "left";
 | 
			
		||||
                    ctx.fillText(cglr, 320, cglrHeightOffset+197);
 | 
			
		||||
                }
 | 
			
		||||
            }      
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        function mobileNavbar() {
 | 
			
		||||
          var x = document.getElementById("Navbar");
 | 
			
		||||
          if (x.className === "navbar") {
 | 
			
		||||
            x.className += " responsive";
 | 
			
		||||
          } else {
 | 
			
		||||
            x.className = "navbar";
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        function changeGearImg() {
 | 
			
		||||
            mType = document.getElementById("mechanicsType").value;
 | 
			
		||||
            if(mType == 2){
 | 
			
		||||
                document.getElementById("gearTypeImg").src="pc6.png";
 | 
			
		||||
            }else if(mType == 3){
 | 
			
		||||
                document.getElementById("gearTypeImg").src="pc7.png";
 | 
			
		||||
            } 
 | 
			
		||||
        }
 | 
			
		||||
    </script>
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
    <div class="navbar" id="Navbar">
 | 
			
		||||
        <logo id="batContainer">
 | 
			
		||||
            <canvas id="batCanvas" height="24" width="50" style="vertical-align:middle;"></canvas>
 | 
			
		||||
            <span id="batValue" style="color:#FFFF; padding-right:20px; vertical-align:middle; font-size:17px;">-</span>
 | 
			
		||||
        </logo>
 | 
			
		||||
        <logo id="ssid" style="vertical-align:middle; font-size:32px;"></logo>
 | 
			
		||||
        
 | 
			
		||||
        <a id="settingsBtn" href="/settings.html"><img height="32" src="data:image/png;base64,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"></a>
 | 
			
		||||
        
 | 
			
		||||
        <a href="/models.html"><img height="32" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHgAAAB4CAQAAACTbf5ZAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QAAKqNIzIAAAAJcEhZcwAADdcAAA3XAUIom3gAAAAHdElNRQfjARQRDAuYnHU3AAAEUUlEQVR42u2bPWsVQRSG30n8IEiwDAiSJinEUgixE2ySNG6p2KTzAxK21F+gnRAEtbJIEVFQCzEBIWClSFqNmMZEERRENBEVTY7FvWaWZHdnxsyZc+/JfSuRZe953Lu+95nZBTrppJOy0CKVJ5OejAv4SgXwCvVKz8YDPExVuSY9Gw+woXcVwH/omPR0PMg3Kq/xAnVLT8cBPELVyaWn4wDeS18qgb/RYen5OJBnaq7xA+npOIBPU10y6fniA/fSzxpgjY1Ms7XXWF8j0/laYH2NTH20Xousr5HpGdUnl54wNvAlB7C2RqZBckVbI1easdZGrjRjrY1cY8Y6G7nGjFugkbvin9IQHjkP6sYtRY1ca8YaG7nWjIUbmeErDZjfmPM4rBdT6YGZ4jBjfY3sMGONjewwY32N7DDjFmjk2MAuM7bR4shOM9bWyE4zttHhyB5mbKPDkT3M2CZLMxPLL63NPAw4dkpBI3uZsU37N7KXGdskaeQuWtr2weOxTu5lxjZpHJmmtgGv0dFoZ/czY5ucH3i05GNf0oFIZ/czYxv+RqYe+l7ywbejnX8mCDhFI1d4zXiks/uasU3GDTxZ+rGR7mRvM7bhduTKn4CR7mRvM7bhbuSSamokyp3sbcY23I1cUk3/Mh7h7P5mbMPryKXV1EiUOznAjG1yTuDyamokwp0cYMY2vI1c+x/Lju/kIDO2YWlk0xxpQtGieDFrWME8ps2LrcADWJKejTX3cdF8LAADtIQB6alYs4wx86q44jErPRFz+vGY+nYTMNCP68WvdA8+o0d6JuYQhjevsPmBp9LzsMfgbHHV8rH0PAly0tg/0yDeSM/DnlXedenWy0YReER6mgR5XwQek54mQZ7stloaslf4hHpc4J5ZsMCj0tOwZxkTxZ+W2oHfYtR82gSmAdWuRLiLIbMIAHuaf6X1+q5iGfOYNgtb/wl4l3iOtM4ST2Mg7kW8yy22iMe+TPv8P4BzNlz2hfhDtBGMy7wQz7vVciEYl3erhX0zbS4YmHczjXm79CD9CsRl3y7l3RA/E3x9M15c7kce7gTicj/ywPxQy376GoSb4KEW3seWRoNwkzy2xPhgGkA3g3Db/VFx6qIPAbjt/zIAHQ+6vgoeLr0agKvhhR56HQCcSU+7c9wQC072CgDnzkPmfeQqJlMBMybAgnPpWWPg+ltw0vbl+0qfgvE6bh3nzHo6YLZ4W3D7ty8QYMHJ25frKz2GfV7HTZrVtMBM8bRgHS/geVuwjlcsAW8LzqXnjAfsY8Ht7r4FXB8Lbn/3LQD7WLCO9m0Cuy1Yg/sWgN0WnEnPGBPXbcFa2rcJ7NoL1tO+TWCXBefSE8bFdVmwePvGlod6C9bivjYOC9bUvoDTgnW1L+DcC86k54sPXGfButoXcFiwtvYFHBacS0/HAVxtweLty4FbbcGa3LcAXG3B2tq3CVxlwfratwlcZcGZ9GSddKI6fwE0tGCKyFWJ8wAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxOS0wMS0yMFQxNjoxMjoxMSswMTowMP08UIkAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTktMDEtMjBUMTY6MTI6MTErMDE6MDCMYeg1AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAABJRU5ErkJggg=="></a>
 | 
			
		||||
        
 | 
			
		||||
        <a class="active" href="/index.html"><img height="32" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAABmJLR0QA/wD/AP+gvaeTAAAI2UlEQVR4nO2de7BVVR3Hv+vci0ACopGSFiBUNIOPKLIpZkwpmTGmCCl6OGNEjlNaZJP2GHoZMznljNWQM3mzGbWXj4iiEm+lVCCBoukoEiiaZIHdlNf1csHL/fTH2kcOl3POWvu9z2F/Zu5w72Gv3/qu3zpnr8f+rd+RSkpKSkpKSkpKSkpKssXkLcAXYIykNwQ/4yWNknS8pLHB75LUK2l38O+LknZK2ippizFmX9aao1DIDgmcf66k8yVNlzRV0qkxzf5H0hZJD0laLemvReykwnQIMEPSfNlOeIukzpSrHJC0UbZzlhtjHky5Pi9y7RDgNEkfkLRQ0pvy1CJps6Q7JN1ijHk6Zy3ZApwPdAOHKB6HgLuB8/L2U+oA7wbW5evvUNwHvBcozK09EYBZwMP5+jYWD9EOnxhgPHArMJivPxPjt8Br8vZraIAO4LPAnpQcczCha6KwG/gMUEnDd4nfG4FXS/qZ7PQ1LgOSHpW0QXaKukXSU5JOlPSYo+wZknZJmizpjZJmSDpH0plKZkp9j6SLjTHPJWArHbCD9s6Y78AdwE3ARdgFYr16pnnYmdag7JjA9k0JaZ2VrlcjAFSApUSfxvYDtwPvATo86ovcIUPsdAJzgDsCDVEYAL5BQjOx2EaA4yTdLOkjEYq/IOmHkpYZY3aGqHOy7CKuGQuMMU+FsDle0mJJn5S9JYblp5IWGWNeilA2GYBR2EVUWPYCXwVGuWvJlqBNXwP2RWjXKuD4vISPAzaEFDwIdAGn5CI6BNgpexfhp+zrgVdmLXYM8GBIoU9SxAHQATAT2ByyrY8AY7MSOBy4N6TAZcCITASmADAS+EHINv8JGJ62sAp2RuLLXuDDqYrKEGAesCtE+1fgMWuMI2hZCDEA/wKmpCYoY4ApQZvC8L20xCwIKaS2U16XiqgMASYCT0f0QZQlQVMxryfevtR24ORERWUIcHLQhqjsxq6dnDg3yLAD022S6m5jeLJKUk+M8nnTI2lFjPInSLqdJAZ54PoY7wyw407LP+ABDOHH0KF8J66Is4GXPCpqtIfVFp1RxdEpPvt4B4Ez4lR+n2dnXAj8fMjrN7ZTZ1QJ/PL9IW1dDszGbjS6WBPJL8AnPIwDLAmu76jplLbsjCpDOmU5MCx4/euePrskbIVjgB4Pw/dS8+QMGAZ8vN06Axhd5zUTtHVYzWsV4M8efnuOMBurwJc9jL5IGy366gGMwO78ercTOB3o9fDfVb4GXxH0oIsrI7e0BQBmAJuAxRHKft7DfzuAkT7GFnsYexxIO9QzF7BPEb8IHADuIUIwQ2Bjk4cfr3AZOg6/FemcyC0uMMCZ2BgssBujk2LYmuvhx39SMwbVMzLPw8jqqCKLCnaG+CWOfK5+aQJ213r4833NDPzKw8DsuEKLBDAZ+MuQNnaTwEwRG0Dh4s5GhU/CHXnxcBJCiwB22noZR8+IdpFgdCKHb4GN2A8cHVQBXO7RmwuTEponwCQaP/X8aMJ1LfLw62X1Cq5xFNpHAaNEwgJcSuNHCfVvH/HqG417XbJ6aKFRuGNhf5y02CwBTgF+06R9/yWlZzbALQ7fHqA2fAgbMejigjTEZgHwQeB/jvbNT7H+Cz38O7u2wHWOi/eRdgRFCgAnAj/xcMbNKesYjjvw7traAhsdFy9PU3AaYD/1//bojGepN8tJXs+vHTo2VC8ciXsfP/R+Tl4AY3Hfs6sMktG6CrjSoWUAGCHgLA/h52QhOi7ABYQLRrghQ21v99AzrTrgNaOfAo4fwFuBG7Bhnr3AC4SLw91GhtN47Fb+AYem+Z2yWRKasdUYcyAL0T5gD/F0SVqgI49ThIk6H5S00BjTm6S2Zhhj+oEnJDU7tzK1IneHeJ+xSBtgnKR1kj6keGdbvmuMWZOMqlBsc/z/1IqkCY6LCtEh2OcSv1Tzd5gPmyV9Jb6iSLg6ZEKn3AFwC4Bza/7uMsZ0xdMViYslvTOmjQFJHzPG9Cegxwl2j6p2n2q8o8iYTh1ObdSI04KfKnGz8kTlcwnYuNYY80ACdnw5VTaRji+jK5KOiqgoGtjt8Okxzfxd0tIE5KRJa3SIpCSi55fkeiDTj9EVSYVbY9QhTqB3lVYIyhhRkZTJABeTJLIleB+7zpG+iqS+vFV4sEnx3jj7JT2ekJY06avIJossNMGKelUME3cZYwrfTkl9nZL2Oi56TNLva/5em56eplwjaa48DhkNYVDSN5OX48VaSd+u+XuObFKcRuwR8DvHhld3upr9wcbZhmVJ3rqrAH90aF1ZkfSMw06RAqqXSro+xPXXSfpWSlqi4Dpn+IyALzh67SAFO/SPjbDc2kTzP2gWEZgD2AeBrtNoV3XKveE1TNJZku5PX7YfxpgVwEpJMyXNkjRREpK2yyYWW2eMOZSjxHqcLfdaaFv1PIOLy7NQ3M5g0wK6mFAJkgY/77A3MwvRbc47HP/fY4zZXp1CbnRcPJuUkj4eCwS+e5fjsgekw3P69Y6Lx8neA0ui8WZJr3Jcs1463CE+a42L4ig6xvHx3d0v/4Y9sOIKtXwyPb3tDfCEw7c91SGhIknBFPEPDrtTaJH4rCIBvE3u5zndxphB6ch9IZ/kKp+KKuwYxsdnR/seG8jlypbWR9YJHlsYbKLQ/Q6fPk9NIOLLn5AgEsOVC3ekpE+npL8dWSzJte30i4aBiPjFn+4CTkhcepuBDfre7eHP5uMycL+HkWsyalfLgk297uJvPoZcwddgx5KJGbSrJQFei80F42Kej7EObNJjF7dl0LaWBLjTw39b8d2Owp5U9WFuym1rOYD3e/puURijHcCjHkZ3ACel2L6WApt8YYeH3x6hQYLluh+ZYOV+tat+2Wly4b4tM0f2SLpRkuvh2NWRHqDR+KsonqUdvrUsJYDzAh/V4644hidh0xTV0k0LfN1E3mBX6SuH+K4Xz4TKzQxfERjrx37zWlskn8kK4BLsMgEg/l4gNmvOj4C4xwGOWYDpgQ/LN3NJSUlJSUlJSUlJSUlJSUlJSdvwfwHi8+3WbSyxAAAAAElFTkSuQmCC"></a>
 | 
			
		||||
        
 | 
			
		||||
        <a href="javascript:void(0);" class="icon" onclick="mobileNavbar()">
 | 
			
		||||
          <img height="32px" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAbElEQVRYhe3WsQmAMBRF0fslhZWII7j/Ki7hAoZUVj4b0RFewH8g9X1VEvi7kLQBk6nfQtIBzKYBdTCFX/YBIWk1DrlM3ZQ6EpJG94C8iq0KcD7HwdVNKX1C0oLxS5ZvgX1AAXagmvrN1O3IDf2SJImhb9e9AAAAAElFTkSuQmCC">
 | 
			
		||||
        </a>
 | 
			
		||||
    </div>
 | 
			
		||||
    
 | 
			
		||||
    <div>
 | 
			
		||||
        <div class="titlebar">
 | 
			
		||||
            <span style="color: #808080;" id="measure"></span><span id="modelName" style="padding-left:10px; color: #1abc9c;"></span>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="buttonbar">
 | 
			
		||||
            <button type="button" class="button tareButton" onclick="tare()" id="tareBtn"></button> 
 | 
			
		||||
            <button type="button" class="button saveButton" onclick="saveModel()" id="saveBtn"></button>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    
 | 
			
		||||
    <div class="wrapper main_container">
 | 
			
		||||
      <div class="tabs">
 | 
			
		||||
        <div class="tab" hidden id="tab-config">
 | 
			
		||||
          <input type="radio" name="css-tabs" id="tab-1" class="tab-switch">
 | 
			
		||||
          <label for="tab-1" class="tab-label" id="tabConfig"></label>
 | 
			
		||||
          <div class="tab-content">
 | 
			
		||||
              <div>
 | 
			
		||||
                <big id="gearTyp"></big>
 | 
			
		||||
                <select hidden id="mechanicsType" onchange="changeGearImg()">
 | 
			
		||||
                    <option value="2" id="gearTyp2"></option>
 | 
			
		||||
                    <option value="3" id="gearTyp3"></option>
 | 
			
		||||
                </select>
 | 
			
		||||
              </div>
 | 
			
		||||
              <div style="margin-top:50px; margin-left: 30px; margin-bottom: 50px;">
 | 
			
		||||
                <img style="max-width: 100%" id="gearTypeImg" src="">
 | 
			
		||||
              </div>
 | 
			
		||||
              <div>
 | 
			
		||||
                <big id="distances"></big>
 | 
			
		||||
              </div>
 | 
			
		||||
              <div style="margin-bottom: 10px">
 | 
			
		||||
                <big class="big_short">X1:</big>
 | 
			
		||||
                <input type="text" id="distanceX1" class="input_short">
 | 
			
		||||
              </div>
 | 
			
		||||
              <div style="margin-bottom: 10px">
 | 
			
		||||
                <big class="big_short">X2:</big>
 | 
			
		||||
                <input type="text" id="distanceX2" class="input_short">
 | 
			
		||||
              </div>
 | 
			
		||||
              <div>
 | 
			
		||||
                <big class="big_short">X3:</big>
 | 
			
		||||
                <input type="text" id="distanceX3" class="input_short">
 | 
			
		||||
              </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="tab">
 | 
			
		||||
          <input type="radio" name="css-tabs" id="tab-2" class="tab-switch">
 | 
			
		||||
          <label for="tab-2" class="tab-label" id="tabBasic"></label>
 | 
			
		||||
          <div class="tab-content">
 | 
			
		||||
              <div style="padding-bottom:50px; padding-top: 30px;">
 | 
			
		||||
                  <img id="weightimg" class="basic_img" src="data:image/png;base64,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">
 | 
			
		||||
                  <div class="basic_text_cont" >
 | 
			
		||||
                      <div class="basic_value" id="weightTotal">-</div>
 | 
			
		||||
                      <div class="basic_value_saved" id="weightTotalSaved"></div>
 | 
			
		||||
                  </div>
 | 
			
		||||
              </div>
 | 
			
		||||
              
 | 
			
		||||
              <div style="padding-bottom:50px">
 | 
			
		||||
                  <img id="cgimg" class="basic_img" src="data:image/png;base64,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">
 | 
			
		||||
                  <div class="basic_text_cont" >
 | 
			
		||||
                      <div class="basic_value" id="CG_length">-</div>
 | 
			
		||||
                      <div class="basic_value_saved" id="CG_lengthSaved"></div>
 | 
			
		||||
                  </div>
 | 
			
		||||
              </div>
 | 
			
		||||
              <div id="cglrContainer">
 | 
			
		||||
                  <img class="basic_img" src="data:image/png;base64,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">
 | 
			
		||||
                  <div class="basic_text_cont" >
 | 
			
		||||
                      <div class="basic_value" id="CG_trans">-</div>
 | 
			
		||||
                      <div class="basic_value_saved" id="CG_transSaved"></div>
 | 
			
		||||
                  </div>
 | 
			
		||||
              </div>
 | 
			
		||||
              <div style="color:#FF0000; padding-left:30px; padding-top:20px; font-size:17px;">
 | 
			
		||||
                  <span id="errMsg"></span>
 | 
			
		||||
              </div>
 | 
			
		||||
          </div>    
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="tab">
 | 
			
		||||
          <input type="radio" name="css-tabs" id="tab-3" class="tab-switch">
 | 
			
		||||
          <label for="tab-3" class="tab-label" id="tabExpert"></label>
 | 
			
		||||
          <div class="tab-content">
 | 
			
		||||
              <div>
 | 
			
		||||
                <big id="targetCG"></big>
 | 
			
		||||
              </div>
 | 
			
		||||
              <div style="margin-bottom: 10px">
 | 
			
		||||
                <big class="big_short">min:</big>
 | 
			
		||||
                <input type="text" id="targetCGmin" class="input_short" onchange="targetCGmin = parseFloat(this.value)">
 | 
			
		||||
              </div>
 | 
			
		||||
              <div>
 | 
			
		||||
                <big class="big_short">max:</big>
 | 
			
		||||
                <input type="text" id="targetCGmax" class="input_short" onchange="targetCGmax = parseFloat(this.value)">
 | 
			
		||||
              </div>
 | 
			
		||||
              <div style="margin-top:50px; text-align: center;">
 | 
			
		||||
                <canvas id="expertCanvas" width="700" height="1000" style="max-width: 100%"></canvas>
 | 
			
		||||
              </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>    
 | 
			
		||||
    
 | 
			
		||||
    <div style="color:#808080; text-align:center; font-size:12px;">(c) 2019 M. Lehmann - Version: <span id="cgscaleVersion">--</span></div>
 | 
			
		||||
    <script>   
 | 
			
		||||
        setTranslation("en");
 | 
			
		||||
        drawExpert("-","-","-");
 | 
			
		||||
        getHead();
 | 
			
		||||
        getParameter();
 | 
			
		||||
        getValue();
 | 
			
		||||
    </script>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										531
									
								
								data/models.html
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										531
									
								
								data/models.html
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,531 @@
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html lang="en">
 | 
			
		||||
<head>
 | 
			
		||||
    <meta charset="utf-8">
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
 | 
			
		||||
    <meta name="description" content="">
 | 
			
		||||
    <meta name="author" content="M. Lehmann">
 | 
			
		||||
    <title>CG scale by M. Lehmann</title>
 | 
			
		||||
    
 | 
			
		||||
    <style>
 | 
			
		||||
        body {
 | 
			
		||||
            font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
 | 
			
		||||
            background: #DCDCDC;
 | 
			
		||||
            margin:0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /***** navbar *****/
 | 
			
		||||
 | 
			
		||||
        .navbar {
 | 
			
		||||
            list-style-type: none;
 | 
			
		||||
            margin: 0;
 | 
			
		||||
            padding: 0;
 | 
			
		||||
            top: 0;
 | 
			
		||||
            width: 100%;
 | 
			
		||||
            background-color: #555;
 | 
			
		||||
            position: fixed;
 | 
			
		||||
            overflow: auto;
 | 
			
		||||
            z-index: 10;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .navbar logo {
 | 
			
		||||
            float: left;
 | 
			
		||||
            display: block;
 | 
			
		||||
            padding: 12px;
 | 
			
		||||
            color: white;
 | 
			
		||||
            text-decoration: none;
 | 
			
		||||
            font-size: 32px;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .navbar a {
 | 
			
		||||
            float: right;
 | 
			
		||||
            display: block;
 | 
			
		||||
            padding: 12px;
 | 
			
		||||
            color: white;
 | 
			
		||||
            text-decoration: none;
 | 
			
		||||
            font-size: 32px;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .navbar a:hover {
 | 
			
		||||
            background-color: #000;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .active {
 | 
			
		||||
            background-color: #1E90FF;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        .navbar .icon {
 | 
			
		||||
            display: none;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        .navbar .badge {
 | 
			
		||||
          position: absolute;
 | 
			
		||||
          top: 0px;
 | 
			
		||||
          right: 0px;
 | 
			
		||||
          padding: 5px 8px;
 | 
			
		||||
          border-radius: 30%;
 | 
			
		||||
          background: red;
 | 
			
		||||
          color: white;
 | 
			
		||||
          font-size: 20px;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        @media screen and (max-width: 600px) {
 | 
			
		||||
            .navbar a:not(:first-child) {display: none;}
 | 
			
		||||
            .navbar a.icon {
 | 
			
		||||
                float: right;
 | 
			
		||||
                display: block;
 | 
			
		||||
            }
 | 
			
		||||
            .navbar.responsive {position: relative;}
 | 
			
		||||
            .navbar.responsive .icon {
 | 
			
		||||
                position: absolute;
 | 
			
		||||
                right: 0;
 | 
			
		||||
                top: 0;
 | 
			
		||||
                height: auto;
 | 
			
		||||
            }
 | 
			
		||||
            .navbar.responsive a {
 | 
			
		||||
                float: none;
 | 
			
		||||
                display: block;
 | 
			
		||||
                text-align: left;
 | 
			
		||||
            }
 | 
			
		||||
            .navbar.responsive logo{display: none;}
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        
 | 
			
		||||
        /***** Table *****/
 | 
			
		||||
        
 | 
			
		||||
        table {
 | 
			
		||||
            border-collapse: collapse;
 | 
			
		||||
            width: 100%;
 | 
			
		||||
            cursor: pointer;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        th {
 | 
			
		||||
            padding: 8px;
 | 
			
		||||
            text-align: left;
 | 
			
		||||
            border-bottom: 1px solid #ddd;
 | 
			
		||||
            background-color:#1abc9c;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        td {
 | 
			
		||||
            height: 40px;
 | 
			
		||||
            padding: 8px;
 | 
			
		||||
            text-align: left;
 | 
			
		||||
            border-bottom: 1px solid #ddd;
 | 
			
		||||
            background-color:#ffffff;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        tr:hover td{background-color:#f5f5f5;}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        /***** button *****/
 | 
			
		||||
 | 
			
		||||
        .button {
 | 
			
		||||
            border: none;
 | 
			
		||||
            border-radius: 3px;
 | 
			
		||||
            color: white;
 | 
			
		||||
            padding: 3px 10px;
 | 
			
		||||
            text-align: center;
 | 
			
		||||
            text-decoration: none;
 | 
			
		||||
            display: inline-block;
 | 
			
		||||
            font-size: 16px;
 | 
			
		||||
            margin: 4px 2px;
 | 
			
		||||
            -webkit-transition-duration: 0.4s; /* Safari */
 | 
			
		||||
            transition-duration: 0.4s;
 | 
			
		||||
            cursor: pointer;
 | 
			
		||||
        }   
 | 
			
		||||
 | 
			
		||||
        .openButton {
 | 
			
		||||
            background-color: white; 
 | 
			
		||||
            color: black; 
 | 
			
		||||
            border: 2px solid #1abc9c;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .openButton:hover {
 | 
			
		||||
            background-color: #1abc9c;
 | 
			
		||||
            color: white;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .deleteButton {
 | 
			
		||||
            background-color: white; 
 | 
			
		||||
            color: black; 
 | 
			
		||||
            border: 2px solid #DC143C;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .deleteButton:hover {
 | 
			
		||||
            background-color: #DC143C;
 | 
			
		||||
            color: white;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        .newButton {
 | 
			
		||||
            padding: 7px 16px;
 | 
			
		||||
            background-color: white; 
 | 
			
		||||
            color: black; 
 | 
			
		||||
            border: 2px solid #778899;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .newButton:hover {
 | 
			
		||||
            background-color: #778899;
 | 
			
		||||
            color: white;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        /***** Labels *****/
 | 
			
		||||
        
 | 
			
		||||
        .titlebar {
 | 
			
		||||
            margin-left:30px; 
 | 
			
		||||
            margin-top:95px; 
 | 
			
		||||
            font-size:25px; 
 | 
			
		||||
            float: left;
 | 
			
		||||
            width:40%;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        .buttonbar {
 | 
			
		||||
            margin-right:20px; 
 | 
			
		||||
            margin-top:85px; 
 | 
			
		||||
            float: right;
 | 
			
		||||
            text-align:right;
 | 
			
		||||
            width:50%;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        .main_container {
 | 
			
		||||
            padding-left:20px; 
 | 
			
		||||
            padding-right: 20px; 
 | 
			
		||||
            padding-top:152px; 
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        @media screen and (max-width: 600px) {
 | 
			
		||||
            .titlebar {
 | 
			
		||||
                width:100%;
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            .buttonbar {
 | 
			
		||||
                margin-left:20px;
 | 
			
		||||
                margin-top:20px; 
 | 
			
		||||
                float: left;
 | 
			
		||||
                text-align:left;
 | 
			
		||||
                width:100%;
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            .main_container {
 | 
			
		||||
                padding-top:212px; 
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
    </style>
 | 
			
		||||
    
 | 
			
		||||
    <script>
 | 
			
		||||
        var CG_trans_visible = true;
 | 
			
		||||
        var batVolt_visible = true;
 | 
			
		||||
        var curModelName = "";
 | 
			
		||||
        
 | 
			
		||||
        var translation;
 | 
			
		||||
        var languages = {
 | 
			
		||||
          "en":{   
 | 
			
		||||
            "modeltitle":"Model",
 | 
			
		||||
            "saveBtn":"New model",
 | 
			
		||||
            "thName":"Name"
 | 
			
		||||
          },
 | 
			
		||||
          "de":{
 | 
			
		||||
            "modeltitle":"Modell",
 | 
			
		||||
            "saveBtn":"Neues Modell",
 | 
			
		||||
            "thName":"Name"
 | 
			
		||||
          }
 | 
			
		||||
        };
 | 
			
		||||
        
 | 
			
		||||
        
 | 
			
		||||
        function setTranslation(defaultLang) {
 | 
			
		||||
            var lang = navigator.languages ? navigator.languages[0] : navigator.language;
 | 
			
		||||
            lang = lang.substr(0, 2);
 | 
			
		||||
 | 
			
		||||
            translation = languages[lang] || languages[defaultLang];
 | 
			
		||||
            
 | 
			
		||||
            for (var item in translation) {
 | 
			
		||||
                var docElement = document.getElementById(item);
 | 
			
		||||
                if(docElement){
 | 
			
		||||
                    docElement.innerHTML = translation[item];
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        function getHead(){
 | 
			
		||||
            var request = new XMLHttpRequest();
 | 
			
		||||
            request.onreadystatechange = function(){
 | 
			
		||||
                if(this.readyState == 4 && this.status == 200){
 | 
			
		||||
                    if(this.responseText != null){
 | 
			
		||||
                        var responseString = this.responseText;
 | 
			
		||||
                        var value = responseString.split("&");
 | 
			
		||||
                        document.getElementById("ssid").innerHTML = value[0];
 | 
			
		||||
                        document.getElementById("cgscaleVersion").innerHTML = value[2];
 | 
			
		||||
                        // check if new version available
 | 
			
		||||
                        if(parseFloat(value[3]) > parseFloat(value[2])){
 | 
			
		||||
                            var a = document.getElementById('settingsBtn');
 | 
			
		||||
                            a.insertAdjacentHTML('beforeend', '<span class="badge">1</span>');
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            request.open("GET", "getHead", true);
 | 
			
		||||
            request.send();
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        function getParameter(){
 | 
			
		||||
            var request = new XMLHttpRequest();
 | 
			
		||||
            request.onreadystatechange = function(){
 | 
			
		||||
                if(this.readyState == 4 && this.status == 200){
 | 
			
		||||
                    if(this.responseText != null){
 | 
			
		||||
                        var responseString = this.responseText;
 | 
			
		||||
                        var value = responseString.split("&");
 | 
			
		||||
                        if(value[0] == "2"){
 | 
			
		||||
                            CG_trans_visible = false;
 | 
			
		||||
                        }
 | 
			
		||||
                        if(value[11] == "0"){
 | 
			
		||||
                            batVolt_visible = false;
 | 
			
		||||
                            document.getElementById("batContainer").outerHTML = "";
 | 
			
		||||
                        }
 | 
			
		||||
                        curModelName = value[17];
 | 
			
		||||
                        if (curModelName != "") {
 | 
			
		||||
                            document.getElementById("modelName").innerHTML = curModelName;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            request.open("GET", "getParameter", true);
 | 
			
		||||
            request.send();
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        function getValue(){
 | 
			
		||||
            var request = new XMLHttpRequest();
 | 
			
		||||
            request.onreadystatechange = function(){
 | 
			
		||||
                if(this.readyState == 4 && this.status == 200){
 | 
			
		||||
                    if(this.responseText != null){
 | 
			
		||||
                        var responseString = this.responseText;
 | 
			
		||||
                        var value = responseString.split("&");
 | 
			
		||||
                        if(batVolt_visible == true){
 | 
			
		||||
                            drawBattery(value[3]);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            request.open("GET", "getValue", true);
 | 
			
		||||
            request.send();
 | 
			
		||||
            setTimeout('getValue()', 5000);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        function getModels(){
 | 
			
		||||
            var request = new XMLHttpRequest();
 | 
			
		||||
            request.onreadystatechange = function(){
 | 
			
		||||
                if(this.readyState == 4 && this.status == 200){
 | 
			
		||||
                    var root = JSON.parse(this.responseText);
 | 
			
		||||
                    var table = document.getElementById("models");
 | 
			
		||||
                    if(CG_trans_visible == false){
 | 
			
		||||
                        document.getElementById("cgLRrow").outerHTML = "";
 | 
			
		||||
                        
 | 
			
		||||
                    }
 | 
			
		||||
                    for (name in root) {
 | 
			
		||||
                        var row = table.insertRow();
 | 
			
		||||
                        var cellName = row.insertCell(0);
 | 
			
		||||
                        var cellWeight = row.insertCell(1);
 | 
			
		||||
                        var cellCG = row.insertCell(2);
 | 
			
		||||
                        cellName.innerHTML = name;
 | 
			
		||||
                        cellWeight.innerHTML = root[name].wt;
 | 
			
		||||
                        cellCG.innerHTML = root[name].cg;
 | 
			
		||||
                        if(CG_trans_visible == true){
 | 
			
		||||
                            var cellcglr = row.insertCell(3);
 | 
			
		||||
                            var cellButton = row.insertCell(4);
 | 
			
		||||
                            cellcglr.innerHTML = root[name].cglr;
 | 
			
		||||
                        }else{
 | 
			
		||||
                            var cellButton = row.insertCell(3);
 | 
			
		||||
                        }
 | 
			
		||||
                        if(name != curModelName){
 | 
			
		||||
                            var htmlbutton = '<div><button type="button" class="button openButton" onclick="openModel(\'';
 | 
			
		||||
                            htmlbutton += name;
 | 
			
		||||
                            htmlbutton += '\')"><img style="height:20px; vertical-align:middle" src="data:image/png;base64,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"></button><button type="button" class="button deleteButton" onclick="deleteModel(\'';
 | 
			
		||||
                            htmlbutton += name;
 | 
			
		||||
                            htmlbutton += '\')"><img style="height:20px; vertical-align:middle" src="data:image/png;base64,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"></button></div>';
 | 
			
		||||
                            cellButton.innerHTML = htmlbutton;
 | 
			
		||||
                        }else{
 | 
			
		||||
                            row.setAttribute("class", "table-active");
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            request.open("GET", "models.json", true);
 | 
			
		||||
            request.send();
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        function saveModel(){
 | 
			
		||||
            var modelname = prompt("Please enter new model name:");
 | 
			
		||||
            if (modelname != "") {
 | 
			
		||||
                var request = new XMLHttpRequest();
 | 
			
		||||
                request.onreadystatechange = function(){
 | 
			
		||||
                    if(this.readyState == 4 && this.status == 200){
 | 
			
		||||
                        location.reload();
 | 
			
		||||
                    }else if(this.readyState == 4 && this.status == 404){
 | 
			
		||||
                        alert("Model not saved !");
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                request.open("GET", "saveModel?modelname=" + modelname, true);
 | 
			
		||||
                request.send();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        function openModel(modelname){
 | 
			
		||||
            if (modelname != "") {
 | 
			
		||||
                var request = new XMLHttpRequest();
 | 
			
		||||
                request.onreadystatechange = function(){
 | 
			
		||||
                    if(this.readyState == 4 && this.status == 200){
 | 
			
		||||
                        location.reload();
 | 
			
		||||
                    }else if(this.readyState == 4 && this.status == 404){
 | 
			
		||||
                        alert("Model not open !");
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                request.open("GET", "openModel?modelname=" + modelname, true);
 | 
			
		||||
                request.send();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        function deleteModel(modelname){
 | 
			
		||||
            if (modelname != "" && confirm("Do you want to delete: " + modelname + "?")){
 | 
			
		||||
                var request = new XMLHttpRequest();
 | 
			
		||||
                request.onreadystatechange = function(){
 | 
			
		||||
                    if(this.readyState == 4 && this.status == 200){
 | 
			
		||||
                        location.reload();
 | 
			
		||||
                    }else if(this.readyState == 4 && this.status == 404){
 | 
			
		||||
                        alert("Model not deleted !");
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                request.open("GET", "deleteModel?modelname=" + modelname, true);
 | 
			
		||||
                request.send();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        function download(file)
 | 
			
		||||
        {
 | 
			
		||||
         window.location=file;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        function drawBattery(value){
 | 
			
		||||
            document.getElementById("batValue").innerHTML = value;
 | 
			
		||||
            
 | 
			
		||||
            var canvas = document.getElementById('batCanvas');
 | 
			
		||||
            var ctx = canvas.getContext('2d');
 | 
			
		||||
            ctx.clearRect(0,0,canvas.width, canvas.height);
 | 
			
		||||
            
 | 
			
		||||
            // battery icon
 | 
			
		||||
            var r = 5;
 | 
			
		||||
            var l = 40;
 | 
			
		||||
            var h = 20;
 | 
			
		||||
            var bl = 3;
 | 
			
		||||
            var bh = 3;
 | 
			
		||||
            var ox = 2;
 | 
			
		||||
            var oy = 2;
 | 
			
		||||
            // battery fill 
 | 
			
		||||
            var fr = 2;
 | 
			
		||||
            var fl = 34; //100%
 | 
			
		||||
            var fh = 14;
 | 
			
		||||
            var fx = 5;
 | 
			
		||||
            var fy = 5;
 | 
			
		||||
            
 | 
			
		||||
            var percentpos = value.indexOf('%');
 | 
			
		||||
            if(percentpos != -1){
 | 
			
		||||
                var percent = Number(value.substring(0, percentpos));
 | 
			
		||||
                fl = fl/100*percent;
 | 
			
		||||
            }else{
 | 
			
		||||
                fl = 0;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // draw icon
 | 
			
		||||
            ctx.beginPath();
 | 
			
		||||
            ctx.lineWidth = 2;
 | 
			
		||||
            ctx.moveTo(ox, oy+r);
 | 
			
		||||
            ctx.arc(ox+r, oy+r, r, (Math.PI / 180) * 180, (Math.PI / 180) * 270, false);
 | 
			
		||||
            ctx.lineTo(ox+(l-r), oy);
 | 
			
		||||
            ctx.arc(ox+(l-r), oy+r, r, (Math.PI / 180) * 270, 0, false);
 | 
			
		||||
            ctx.lineTo(ox+l, h/2-bh+oy);
 | 
			
		||||
            ctx.lineTo(ox+l+bl, h/2-bh+oy);
 | 
			
		||||
            ctx.lineTo(ox+l+bl, h/2+bh+oy);
 | 
			
		||||
            ctx.lineTo(ox+l, h/2+bh+oy);
 | 
			
		||||
            ctx.lineTo(ox+l, oy+h-r);
 | 
			
		||||
            ctx.arc(ox+(l-r), oy+h-r, r, 0, (Math.PI / 180) * 90, false);
 | 
			
		||||
            ctx.lineTo(ox+r, oy+h);
 | 
			
		||||
            ctx.arc(ox+r, oy+h-r, r, (Math.PI / 180) * 90, (Math.PI / 180) * 180, false);
 | 
			
		||||
            ctx.lineTo(ox, oy+r);
 | 
			
		||||
            ctx.strokeStyle = "#FFFFFF";
 | 
			
		||||
            ctx.stroke();
 | 
			
		||||
            
 | 
			
		||||
            // draw filled value
 | 
			
		||||
            if(fl>1){
 | 
			
		||||
                ctx.beginPath();
 | 
			
		||||
                ctx.fillStyle = "#FFFFFF";
 | 
			
		||||
                ctx.moveTo(fx, fy+fr);
 | 
			
		||||
                ctx.arc(fx+fr, fy+fr, fr, (Math.PI / 180) * 180, (Math.PI / 180) * 270, false);
 | 
			
		||||
                ctx.lineTo(fx+(fl-fr), fy);
 | 
			
		||||
                ctx.arc(fx+(fl-fr), fy+fr, fr, (Math.PI / 180) * 270, 0, false);
 | 
			
		||||
                ctx.lineTo(fx+fl, fy+fh-fr);
 | 
			
		||||
                ctx.arc(fx+(fl-fr), fy+fh-fr, fr, 0, (Math.PI / 180) * 90, false);
 | 
			
		||||
                ctx.lineTo(fx+fr, fy+fh);
 | 
			
		||||
                ctx.arc(fx+fr, fy+fh-fr, fr, (Math.PI / 180) * 90, (Math.PI / 180) * 180, false);
 | 
			
		||||
                ctx.lineTo(fx, fy+fr);
 | 
			
		||||
                ctx.fill();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    
 | 
			
		||||
        function mobileNavbar() {
 | 
			
		||||
          var x = document.getElementById("Navbar");
 | 
			
		||||
          if (x.className === "navbar") {
 | 
			
		||||
            x.className += " responsive";
 | 
			
		||||
          } else {
 | 
			
		||||
            x.className = "navbar";
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
    </script>
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
    <div class="navbar" id="Navbar">
 | 
			
		||||
        <logo id="batContainer">
 | 
			
		||||
            <canvas id="batCanvas" height="24" width="50" style="vertical-align:middle;"></canvas>
 | 
			
		||||
            <span id="batValue" style="color:#FFFF; padding-right:20px; vertical-align:middle; font-size:17px;">-</span>
 | 
			
		||||
        </logo>
 | 
			
		||||
        <logo id="ssid" style="vertical-align:middle; font-size:32px;"></logo>
 | 
			
		||||
        
 | 
			
		||||
        <a id="settingsBtn" href="/settings.html"><img height="32" src="data:image/png;base64,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"></a>
 | 
			
		||||
        
 | 
			
		||||
        <a class="active" href="/models.html"><img height="32" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHgAAAB4CAQAAACTbf5ZAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QAAKqNIzIAAAAJcEhZcwAADdcAAA3XAUIom3gAAAAHdElNRQfjARQRDAuYnHU3AAAEUUlEQVR42u2bPWsVQRSG30n8IEiwDAiSJinEUgixE2ySNG6p2KTzAxK21F+gnRAEtbJIEVFQCzEBIWClSFqNmMZEERRENBEVTY7FvWaWZHdnxsyZc+/JfSuRZe953Lu+95nZBTrppJOy0CKVJ5OejAv4SgXwCvVKz8YDPExVuSY9Gw+woXcVwH/omPR0PMg3Kq/xAnVLT8cBPELVyaWn4wDeS18qgb/RYen5OJBnaq7xA+npOIBPU10y6fniA/fSzxpgjY1Ms7XXWF8j0/laYH2NTH20Xousr5HpGdUnl54wNvAlB7C2RqZBckVbI1easdZGrjRjrY1cY8Y6G7nGjFugkbvin9IQHjkP6sYtRY1ca8YaG7nWjIUbmeErDZjfmPM4rBdT6YGZ4jBjfY3sMGONjewwY32N7DDjFmjk2MAuM7bR4shOM9bWyE4zttHhyB5mbKPDkT3M2CZLMxPLL63NPAw4dkpBI3uZsU37N7KXGdskaeQuWtr2weOxTu5lxjZpHJmmtgGv0dFoZ/czY5ucH3i05GNf0oFIZ/czYxv+RqYe+l7ywbejnX8mCDhFI1d4zXiks/uasU3GDTxZ+rGR7mRvM7bhduTKn4CR7mRvM7bhbuSSamokyp3sbcY23I1cUk3/Mh7h7P5mbMPryKXV1EiUOznAjG1yTuDyamokwp0cYMY2vI1c+x/Lju/kIDO2YWlk0xxpQtGieDFrWME8ps2LrcADWJKejTX3cdF8LAADtIQB6alYs4wx86q44jErPRFz+vGY+nYTMNCP68WvdA8+o0d6JuYQhjevsPmBp9LzsMfgbHHV8rH0PAly0tg/0yDeSM/DnlXedenWy0YReER6mgR5XwQek54mQZ7stloaslf4hHpc4J5ZsMCj0tOwZxkTxZ+W2oHfYtR82gSmAdWuRLiLIbMIAHuaf6X1+q5iGfOYNgtb/wl4l3iOtM4ST2Mg7kW8yy22iMe+TPv8P4BzNlz2hfhDtBGMy7wQz7vVciEYl3erhX0zbS4YmHczjXm79CD9CsRl3y7l3RA/E3x9M15c7kce7gTicj/ywPxQy376GoSb4KEW3seWRoNwkzy2xPhgGkA3g3Db/VFx6qIPAbjt/zIAHQ+6vgoeLr0agKvhhR56HQCcSU+7c9wQC072CgDnzkPmfeQqJlMBMybAgnPpWWPg+ltw0vbl+0qfgvE6bh3nzHo6YLZ4W3D7ty8QYMHJ25frKz2GfV7HTZrVtMBM8bRgHS/geVuwjlcsAW8LzqXnjAfsY8Ht7r4FXB8Lbn/3LQD7WLCO9m0Cuy1Yg/sWgN0WnEnPGBPXbcFa2rcJ7NoL1tO+TWCXBefSE8bFdVmwePvGlod6C9bivjYOC9bUvoDTgnW1L+DcC86k54sPXGfButoXcFiwtvYFHBacS0/HAVxtweLty4FbbcGa3LcAXG3B2tq3CVxlwfratwlcZcGZ9GSddKI6fwE0tGCKyFWJ8wAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxOS0wMS0yMFQxNjoxMjoxMSswMTowMP08UIkAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTktMDEtMjBUMTY6MTI6MTErMDE6MDCMYeg1AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAABJRU5ErkJggg=="></a>
 | 
			
		||||
        
 | 
			
		||||
        <a href="/index.html"><img height="32" src="data:image/png;base64,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"></a>
 | 
			
		||||
        
 | 
			
		||||
        <a href="javascript:void(0);" class="icon" onclick="mobileNavbar()">
 | 
			
		||||
          <img height="32px" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAbElEQVRYhe3WsQmAMBRF0fslhZWII7j/Ki7hAoZUVj4b0RFewH8g9X1VEvi7kLQBk6nfQtIBzKYBdTCFX/YBIWk1DrlM3ZQ6EpJG94C8iq0KcD7HwdVNKX1C0oLxS5ZvgX1AAXagmvrN1O3IDf2SJImhb9e9AAAAAElFTkSuQmCC">
 | 
			
		||||
        </a>
 | 
			
		||||
    </div>
 | 
			
		||||
    
 | 
			
		||||
    <div>
 | 
			
		||||
        <div class="titlebar">
 | 
			
		||||
            <span style="color: #808080;" id="modeltitle"></span><span id="modelName" style="padding-left:10px; color: #1abc9c;"></span>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="buttonbar">
 | 
			
		||||
            <button type="button" class="button newButton" onclick="saveModel()" id="saveBtn"></button>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    
 | 
			
		||||
    <div class="main_container">
 | 
			
		||||
    <table id="models">
 | 
			
		||||
            <tr>
 | 
			
		||||
                <th id="thName"></th>
 | 
			
		||||
                <th><img style="height:30px; vertical-align:middle" src="data:image/png;base64,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"></th>
 | 
			
		||||
                <th><img style="height:30px; vertical-align:middle" src="data:image/png;base64,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"></th>
 | 
			
		||||
                <th id="cgLRrow"><img style="height:30px; vertical-align:middle" src="data:image/png;base64,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"></th>
 | 
			
		||||
                <th></th>
 | 
			
		||||
            </tr>
 | 
			
		||||
    </table>
 | 
			
		||||
    </div>
 | 
			
		||||
    
 | 
			
		||||
    <div style="color:#808080; text-align:center; font-size:12px; padding-top:30px;">(c) 2019 M. Lehmann - Version: <span id="cgscaleVersion">--</span></div>
 | 
			
		||||
    <script>
 | 
			
		||||
        setTranslation("en");
 | 
			
		||||
        getHead();
 | 
			
		||||
        getParameter();
 | 
			
		||||
        getModels();
 | 
			
		||||
        getValue();
 | 
			
		||||
    </script>    
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										1062
									
								
								data/settings.html
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										1062
									
								
								data/settings.html
									
									
									
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											Binary file not shown.
										
									
								
							@@ -45,15 +45,35 @@ CG scale with 3 Loadcells:
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define PIN_LOADCELL1_DOUT            D6
 | 
			
		||||
#define PIN_LOADCELL1_PD_SCK          D5
 | 
			
		||||
 | 
			
		||||
#define PIN_LOADCELL2_DOUT            D2
 | 
			
		||||
#define PIN_LOADCELL2_PD_SCK          D1
 | 
			
		||||
// Wifi Kit 8 (https://heltec.org/project/wifi-kit-8/) 
 | 
			
		||||
// is a ESP8266 based board, with integrated OLED and battery management
 | 
			
		||||
#define WIFI_KIT_8 1
 | 
			
		||||
#ifdef WIFI_KIT_8
 | 
			
		||||
  #define PIN_LOADCELL1_DOUT            D6
 | 
			
		||||
  #define PIN_LOADCELL1_PD_SCK          D7
 | 
			
		||||
  
 | 
			
		||||
#define PIN_LOADCELL3_DOUT            D7
 | 
			
		||||
#define PIN_LOADCELL3_PD_SCK          D0
 | 
			
		||||
  #define PIN_LOADCELL2_DOUT            D3
 | 
			
		||||
  
 | 
			
		||||
  #define PIN_LOADCELL2_PD_SCK          D8
 | 
			
		||||
    
 | 
			
		||||
  #define PIN_LOADCELL3_DOUT            D0
 | 
			
		||||
  #define PIN_LOADCELL3_PD_SCK          D0
 | 
			
		||||
 | 
			
		||||
  // D3 can be used in parallel to the load cell with Wifi Kit 8
 | 
			
		||||
  #define PIN_TARE_BUTTON               D3
 | 
			
		||||
 | 
			
		||||
  #define MAX_SSID_PW_LENGHT            64
 | 
			
		||||
#else
 | 
			
		||||
  #define PIN_LOADCELL1_DOUT            D6
 | 
			
		||||
  #define PIN_LOADCELL1_PD_SCK          D5
 | 
			
		||||
  
 | 
			
		||||
  #define PIN_LOADCELL2_DOUT            D2
 | 
			
		||||
  #define PIN_LOADCELL2_PD_SCK          D1
 | 
			
		||||
  
 | 
			
		||||
  #define PIN_LOADCELL3_DOUT            D7
 | 
			
		||||
  #define PIN_LOADCELL3_PD_SCK          D0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// **** Measurement settings ****
 | 
			
		||||
@@ -81,9 +101,13 @@ CG scale with 3 Loadcells:
 | 
			
		||||
 | 
			
		||||
// Please UNCOMMENT the display used
 | 
			
		||||
 | 
			
		||||
U8G2_SH1106_128X64_NONAME_1_HW_I2C oledDisplay(U8G2_R0, /* reset=*/ U8X8_PIN_NONE, /* clock=*/ D3, /* data=*/ D4);
 | 
			
		||||
//U8G2_SSD1306_128X64_NONAME_1_HW_I2C oledDisplay(U8G2_R0, /* reset=*/ U8X8_PIN_NONE, /* clock=*/ D3, /* data=*/ D4);
 | 
			
		||||
 | 
			
		||||
#ifdef WIFI_KIT_8
 | 
			
		||||
  // Wifi Kit 8 has a fixed wired 128x32 display
 | 
			
		||||
  U8G2_SSD1306_128X32_UNIVISION_1_HW_I2C oledDisplay(U8G2_R0, /* reset=*/ 16, /* clock=*/ 5, /* data=*/ 4);
 | 
			
		||||
#else
 | 
			
		||||
  U8G2_SH1106_128X64_NONAME_1_HW_I2C oledDisplay(U8G2_R0, /* reset=*/ U8X8_PIN_NONE, /* clock=*/ D3, /* data=*/ D4);
 | 
			
		||||
  //U8G2_SSD1306_128X64_NONAME_1_HW_I2C oledDisplay(U8G2_R0, /* reset=*/ U8X8_PIN_NONE, /* clock=*/ D3, /* data=*/ D4);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// **** Voltage measurement settings ****
 | 
			
		||||
@@ -129,7 +153,9 @@ U8G2_SH1106_128X64_NONAME_1_HW_I2C oledDisplay(U8G2_R0, /* reset=*/ U8X8_PIN_NON
 | 
			
		||||
 | 
			
		||||
// **** Wifi settings ****
 | 
			
		||||
 | 
			
		||||
#ifndef MAX_SSID_PW_LENGHT
 | 
			
		||||
#define MAX_SSID_PW_LENGHT          32
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Station mode: connect to available network
 | 
			
		||||
#define SSID_STA                    "myWiFi"
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user