diff --git a/CG_scale.ino b/CG_scale.ino index cc6d543..800faac 100644 --- a/CG_scale.ino +++ b/CG_scale.ino @@ -4,11 +4,12 @@ (c) 2019 by M. Lehmann ------------------------------------------------------------------ */ -#define CGSCALE_VERSION "1.0" +#define CGSCALE_VERSION "1.1" /* ****************************************************************** history: + V1.1 02.02.19 Supports ESP8266, webpage integrated, STA and AP mode V1.0 12.01.19 first release @@ -51,17 +52,36 @@ #include #include -// Settings in separate file -#include "settings.h" +// libraries for ESP8266 +#if defined(ESP8266) +#include +#include +#include +#include +#include +#endif + +// load settings +#if defined(__AVR__) +#include "settings_AVR.h" +#elif defined(ESP8266) +#include "settings_ESP8266.h" +#endif // HX711 constructor (dout pin, sck pint): HX711_ADC LoadCell_1(PIN_LOADCELL1_DOUT, PIN_LOADCELL1_PD_SCK); HX711_ADC LoadCell_2(PIN_LOADCELL2_DOUT, PIN_LOADCELL2_PD_SCK); HX711_ADC LoadCell_3(PIN_LOADCELL3_DOUT, PIN_LOADCELL3_PD_SCK); +// webserver constructor +#if defined(ESP8266) +ESP8266WebServer server(80); +IPAddress apIP(ip[0], ip[1], ip[2], ip[3]); +File fsUploadFile; // a File object to temporarily store the received file +#endif + // serial menu -enum -{ +enum { MENU_HOME, MENU_LOADCELLS, MENU_DISTANCE_X1, @@ -73,14 +93,18 @@ enum MENU_LOADCELL1_CALIBRATION_FACTOR, MENU_LOADCELL2_CALIBRATION_FACTOR, MENU_LOADCELL3_CALIBRATION_FACTOR, + MENU_RESISTOR_R1, + MENU_RESISTOR_R2, MENU_BATTERY_MEASUREMENT, MENU_SHOW_ACTUAL, +#if defined(ESP8266) + MENU_WIFI_INFO, +#endif MENU_RESET_DEFAULT }; // EEprom parameter addresses -enum -{ +enum { P_NUMBER_LOADCELLS = 1, P_DISTANCE_X1 = 2, P_DISTANCE_X2 = P_DISTANCE_X1 + sizeof(float), @@ -90,7 +114,19 @@ enum P_LOADCELL3_CALIBRATION_FACTOR = P_LOADCELL2_CALIBRATION_FACTOR + sizeof(float), P_ENABLE_BATVOLT = P_LOADCELL3_CALIBRATION_FACTOR + sizeof(float), P_REF_WEIGHT = P_ENABLE_BATVOLT + sizeof(float), - P_REF_CG = P_REF_WEIGHT + sizeof(float) + P_REF_CG = P_REF_WEIGHT + sizeof(float), + P_RESISTOR_R1 = P_REF_CG + sizeof(float), + P_RESISTOR_R2 = P_RESISTOR_R1 + sizeof(float), +#if defined(__AVR__) + EEPROM_SIZE = P_RESISTOR_R2 + sizeof(float) +#elif defined(ESP8266) + P_SSID_STA = P_RESISTOR_R2 + sizeof(float), + P_PASSWORD_STA = P_SSID_STA + MAX_SSID_PW_LENGHT + 1, + P_SSID_AP = P_PASSWORD_STA + MAX_SSID_PW_LENGHT + 1, + P_PASSWORD_AP = P_SSID_AP + MAX_SSID_PW_LENGHT + 1, + P_MODELNAME = P_PASSWORD_AP + MAX_SSID_PW_LENGHT + 1, + EEPROM_SIZE = P_MODELNAME + MAX_MODELNAME_LENGHT + 1 +#endif }; // battery image 12x6 @@ -126,7 +162,7 @@ static const unsigned char CGtransImage[] U8X8_PROGMEM = { }; // set default text -static const String PROGMEM newValueText = "Set new value:"; +static const String newValueText = "Set new value:"; // load default values uint8_t nLoadcells = NUMBER_LOADCELLS; @@ -136,9 +172,17 @@ float distanceX3 = DISTANCE_X3; float calFactorLoadcell1 = LOADCELL1_CALIBRATION_FACTOR; float calFactorLoadcell2 = LOADCELL2_CALIBRATION_FACTOR; float calFactorLoadcell3 = LOADCELL3_CALIBRATION_FACTOR; +float resistorR1 = RESISTOR_R1; +float resistorR2 = RESISTOR_R2; bool enableBatVolt = ENABLE_VOLTAGE; float refWeight = REF_WEIGHT; float refCG = REF_CG; +#if defined(ESP8266) +char ssid_STA[MAX_SSID_PW_LENGHT + 1] = SSID_STA; +char password_STA[MAX_SSID_PW_LENGHT + 1] = PASSWORD_STA; +char ssid_AP[MAX_SSID_PW_LENGHT + 1] = SSID_AP; +char password_AP[MAX_SSID_PW_LENGHT + 1] = PASSWORD_AP; +#endif // declare variables float weightLoadCell1 = 0; @@ -147,54 +191,123 @@ float weightLoadCell3 = 0; float lastWeightLoadCell1 = 0; float lastWeightLoadCell2 = 0; float lastWeightLoadCell3 = 0; +float weightTotal = 0; +float CG_length = 0; +float CG_trans = 0; +float batVolt = 0; unsigned long lastTimeMenu = 0; unsigned long lastTimeLoadcell = 0; -bool displayInit = false; bool updateMenu = true; int menuPage = 0; +String errMsg[5] = ""; +int errMsgCnt = 0; +#if defined(ESP8266) +String wifiMsg = ""; +bool wifiSTAmode = true; +char curModelName[MAX_MODELNAME_LENGHT + 1] = ""; +#endif // Restart CPU +#if defined(__AVR__) void(* resetCPU) (void) = 0; +#elif defined(ESP8266) +void resetCPU() {} +#endif -// save calibration factors +// save calibration factor void saveCalFactor1() { LoadCell_1.setCalFactor(calFactorLoadcell1); EEPROM.put(P_LOADCELL1_CALIBRATION_FACTOR, calFactorLoadcell1); +#if defined(ESP8266) + EEPROM.commit(); +#endif } void saveCalFactor2() { LoadCell_2.setCalFactor(calFactorLoadcell2); EEPROM.put(P_LOADCELL2_CALIBRATION_FACTOR, calFactorLoadcell2); +#if defined(ESP8266) + EEPROM.commit(); +#endif } void saveCalFactor3() { LoadCell_3.setCalFactor(calFactorLoadcell3); EEPROM.put(P_LOADCELL3_CALIBRATION_FACTOR, calFactorLoadcell3); +#if defined(ESP8266) + EEPROM.commit(); +#endif +} + + +// run auto calibration +bool runAutoCalibrate() { + Serial.print(F("\nAutocalibration is running")); + for (int i = 0; i <= 20; i++) { + Serial.print(F(".")); + delay(100); + } + // calculate weight + float toWeightLoadCell2 = ((refCG - distanceX1) * refWeight) / distanceX2; + float toWeightLoadCell1 = refWeight - toWeightLoadCell2; + float toWeightLoadCell3 = 0; + if (nLoadcells == 3) { + toWeightLoadCell1 = toWeightLoadCell1 / 2; + toWeightLoadCell3 = toWeightLoadCell1; + } + // calculate calibration factors + calFactorLoadcell1 = calFactorLoadcell1 / (toWeightLoadCell1 / weightLoadCell1); + calFactorLoadcell2 = calFactorLoadcell2 / (toWeightLoadCell2 / weightLoadCell2); + if (nLoadcells == 3) { + calFactorLoadcell3 = calFactorLoadcell3 / (toWeightLoadCell3 / weightLoadCell3); + } + saveCalFactor1(); + saveCalFactor2(); + saveCalFactor3(); + // finish + Serial.println(F("done")); +} + + +// check if a loadcell has error +bool getLoadcellError() { + bool err = false; + + if (LoadCell_1.getTareTimeoutFlag()) { + errMsg[++errMsgCnt] = "ERROR: Timeout TARE Lc1\n"; + err = true; + } + + if (LoadCell_2.getTareTimeoutFlag()) { + errMsg[++errMsgCnt] = "ERROR: Timeout TARE Lc2\n"; + err = true; + } + + if (nLoadcells == 3) { + if (LoadCell_3.getTareTimeoutFlag()) { + errMsg[++errMsgCnt] = "ERROR: Timeout TARE Lc3\n"; + err = true; + } + } + + return err; } void setup() { - // init OLED display - 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")); + // init serial + Serial.begin(9600); - 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() ); +#if defined(ESP8266) + // init filesystem + SPIFFS.begin(); + EEPROM.begin(EEPROM_SIZE); +#endif // read settings from eeprom if (EEPROM.read(P_NUMBER_LOADCELLS) != 0xFF) { @@ -237,40 +350,236 @@ void setup() { EEPROM.get(P_REF_CG, refCG); } - // init Loadcells - LoadCell_1.begin(); - LoadCell_2.begin(); - LoadCell_3.begin(); - - // tare - while (!LoadCell_1.startMultiple(STABILISINGTIME) && !LoadCell_2.startMultiple(STABILISINGTIME) && !LoadCell_3.startMultiple(STABILISINGTIME)) { + if (EEPROM.read(P_RESISTOR_R1) != 0xFF) { + EEPROM.get(P_RESISTOR_R1, resistorR1); } - // set calibration factor + if (EEPROM.read(P_RESISTOR_R2) != 0xFF) { + EEPROM.get(P_RESISTOR_R2, resistorR2); + } + +#if defined(ESP8266) + if (EEPROM.read(P_SSID_STA) != 0xFF) { + EEPROM.get(P_SSID_STA, ssid_STA); + } + + if (EEPROM.read(P_PASSWORD_STA) != 0xFF) { + EEPROM.get(P_PASSWORD_STA, password_STA); + } + + if (EEPROM.read(P_SSID_AP) != 0xFF) { + EEPROM.get(P_SSID_AP, ssid_AP); + } + + if (EEPROM.read(P_PASSWORD_AP) != 0xFF) { + EEPROM.get(P_PASSWORD_AP, password_AP); + } + + if (EEPROM.read(P_MODELNAME) != 0xFF) { + EEPROM.get(P_MODELNAME, curModelName); + } + + // load current model + if (!openModelJson(curModelName)) { + curModelName[0] = '\0'; + } + +#endif + + // init OLED display + 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() ); + + // init & tare Loadcells + LoadCell_1.begin(); LoadCell_1.setCalFactor(calFactorLoadcell1); + + LoadCell_2.begin(); LoadCell_2.setCalFactor(calFactorLoadcell2); - LoadCell_3.setCalFactor(calFactorLoadcell3); + + if (nLoadcells == 3) { + LoadCell_3.begin(); + LoadCell_3.setCalFactor(calFactorLoadcell3); + } // stabilize scale values - for (int i = 0; i <= 5; i++) { + while (millis() < STABILISINGTIME) { LoadCell_1.update(); LoadCell_2.update(); - LoadCell_3.update(); - delay(200); + if (nLoadcells == 3) { + LoadCell_3.update(); + } } - // init serial - Serial.begin(9600); + LoadCell_1.tare(); + LoadCell_2.tare(); + if (nLoadcells == 3) { + LoadCell_3.tare(); + } + + getLoadcellError(); + + +#if defined(ESP8266) + + // Start by connecting to a WiFi network + WiFi.mode(WIFI_STA); + WiFi.begin(ssid_STA, password_STA); + + wifiMsg += TimeToString(millis()); + wifiMsg += " STA mode - connect with wifi: "; + wifiMsg += ssid_STA; + wifiMsg += "\n"; + + long timeoutWiFi = millis(); + + while (WiFi.status() != WL_CONNECTED) { + delay(500); + if (WiFi.status() == WL_NO_SSID_AVAIL) { + wifiMsg += TimeToString(millis()); + wifiMsg += " No SSID available\n"; + break; + } else if (WiFi.status() == WL_CONNECT_FAILED) { + wifiMsg += TimeToString(millis()); + wifiMsg += " Connection failed\n"; + break; + } else if ((millis() - timeoutWiFi) > TIMEOUT_CONNECT) { + wifiMsg += TimeToString(millis()); + wifiMsg += " Timeout\n"; + break; + } + } + + if (WiFi.status() != WL_CONNECTED) { + // if WiFi not connected, switch to access point mode + wifiSTAmode = false; + wifiMsg += TimeToString(millis()); + wifiMsg += " AP mode - create access point: "; + wifiMsg += ssid_AP; + WiFi.mode(WIFI_AP); + WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0)); + WiFi.softAP(ssid_AP, password_AP); + wifiMsg += "\n"; + wifiMsg += TimeToString(millis()); + wifiMsg += " IP: "; + wifiMsg += WiFi.softAPIP().toString(); + } else { + wifiMsg += TimeToString(millis()); + wifiMsg += " Connected, IP: "; + wifiMsg += WiFi.localIP().toString(); + } + + // init mDNS + String hostName = "disabled"; +#if ENABLE_MDNS + hostName = ssid_AP; + hostName.replace(" ", ""); + hostName.toLowerCase(); + char hostString[32]; + hostName.toCharArray(hostString, 32); + MDNS.begin(hostString); + hostName += ".local"; +#endif + wifiMsg += "\n"; + wifiMsg += TimeToString(millis()); + wifiMsg += " Hostname: "; + wifiMsg += hostName; + + // 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 + server.on("/getHead", getHead); + server.on("/getValue", getValue); + server.on("/getRawValue", getRawValue); + server.on("/getParameter", getParameter); + server.on("/getWiFiNetworks", getWiFiNetworks); + server.on("/saveParameter", saveParameter); + server.on("/autoCalibrate", autoCalibrate); + server.on("/tare", runTare); + server.on("/saveModel", saveModel); + server.on("/openModel", openModel); + server.on("/deleteModel", deleteModel); + + // When the client upload file + server.on("/models.html", HTTP_POST, []() { + server.send(200, "text/plain", ""); + }, handleFileUpload); + + // If the client requests any URI + server.onNotFound([]() { + if (!handleFileRead(server.uri())) + server.send(404, "text/plain", "404: Not Found"); + }); + + // init webserver + server.begin(); + +#if ENABLE_MDNS + // Add service to MDNS-SD + MDNS.addService("http", "tcp", 80); +#endif + +#endif } void loop() { +#if defined(ESP8266) + +#if ENABLE_MDNS + MDNS.update(); +#endif + + server.handleClient(); +#endif + LoadCell_1.update(); LoadCell_2.update(); - LoadCell_3.update(); - + if (nLoadcells == 3) { + LoadCell_3.update(); + } // update loadcell values if ((millis() - lastTimeLoadcell) > UPDATE_INTERVAL_LOADCELL) { @@ -279,7 +588,7 @@ void loop() { // get Loadcell weights weightLoadCell1 = LoadCell_1.getData(); weightLoadCell2 = LoadCell_2.getData(); - if (nLoadcells > 2) { + if (nLoadcells == 3) { weightLoadCell3 = LoadCell_3.getData(); } @@ -294,15 +603,10 @@ void loop() { lastWeightLoadCell3 = weightLoadCell3; } - // update display and serial menu if ((millis() - lastTimeMenu) > UPDATE_INTERVAL_OLED_MENU) { - lastTimeMenu = millis(); - float weightTotal; - float CG_length = 0; - float CG_trans = 0; - float batVolt = 0; + lastTimeMenu = millis(); // total model weight weightTotal = weightLoadCell1 + weightLoadCell2 + weightLoadCell3; @@ -315,21 +619,24 @@ void loop() { CG_length = ((weightLoadCell2 * distanceX2) / weightTotal) + distanceX1; // CG transverse axis - if (nLoadcells > 2) { + if (nLoadcells == 3) { CG_trans = (distanceX3 / 2) - (((weightLoadCell1 + weightLoadCell2 / 2) * distanceX3) / weightTotal); } + } else { + CG_length = 0; + CG_trans = 0; } // read battery voltage if (enableBatVolt) { - batVolt = (analogRead(VOLTAGE_PIN) / 1024.0) * V_REF * (float(RESISTOR_R1 + RESISTOR_R2) / RESISTOR_R2) / 1000.0; + batVolt = (analogRead(VOLTAGE_PIN) / 1024.0) * V_REF * ((resistorR1 + resistorR2) / resistorR2) / 1000.0; } // print to display char buff[8]; int pos_weightTotal = 7; int pos_CG_length = 28; - if (nLoadcells < 3) { + if (nLoadcells == 2) { pos_weightTotal = 17; pos_CG_length = 45; if (!enableBatVolt) { @@ -338,41 +645,48 @@ void loop() { } } - oledDisplay.firstPage(); do { - // print battery - if (enableBatVolt) { - oledDisplay.drawXBMP(88, 1, 12, 6, batteryImage); - dtostrf(batVolt, 2, 2, buff); - oledDisplay.setFont(u8g2_font_5x7_tr); - oledDisplay.setCursor(123 - oledDisplay.getStrWidth(buff), 7); + if (errMsgCnt == 0) { + // print battery + if (enableBatVolt) { + oledDisplay.drawXBMP(88, 1, 12, 6, batteryImage); + dtostrf(batVolt, 2, 2, buff); + oledDisplay.setFont(u8g2_font_5x7_tr); + oledDisplay.setCursor(123 - oledDisplay.getStrWidth(buff), 7); + oledDisplay.print(buff); + oledDisplay.print(F("V")); + } + + // 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("V")); - } + oledDisplay.print(F(" g")); - // 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 > 2) { - oledDisplay.drawXBMP(2, 47, 18, 18, CGtransImage); - dtostrf(CG_trans, 5, 1, buff); - oledDisplay.setCursor(93 - oledDisplay.getStrWidth(buff), 64); + // 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() ); @@ -390,65 +704,60 @@ void loop() { case MENU_LOADCELLS: nLoadcells = Serial.parseInt(); EEPROM.put(P_NUMBER_LOADCELLS, nLoadcells); +#if defined(ESP8266) + EEPROM.commit(); +#endif menuPage = 0; updateMenu = true; break; case MENU_DISTANCE_X1: distanceX1 = Serial.parseFloat(); EEPROM.put(P_DISTANCE_X1, distanceX1); +#if defined(ESP8266) + EEPROM.commit(); +#endif menuPage = 0; updateMenu = true; break; case MENU_DISTANCE_X2: distanceX2 = Serial.parseFloat(); EEPROM.put(P_DISTANCE_X2, distanceX2); +#if defined(ESP8266) + EEPROM.commit(); +#endif menuPage = 0; updateMenu = true; break; case MENU_DISTANCE_X3: distanceX3 = Serial.parseFloat(); EEPROM.put(P_DISTANCE_X3, distanceX3); +#if defined(ESP8266) + EEPROM.commit(); +#endif menuPage = 0; updateMenu = true; break; case MENU_REF_WEIGHT: refWeight = Serial.parseFloat(); EEPROM.put(P_REF_WEIGHT, refWeight); +#if defined(ESP8266) + EEPROM.commit(); +#endif menuPage = 0; updateMenu = true; break; case MENU_REF_CG: refCG = Serial.parseFloat(); EEPROM.put(P_REF_CG, refCG); +#if defined(ESP8266) + EEPROM.commit(); +#endif menuPage = 0; updateMenu = true; break; case MENU_AUTO_CALIBRATE: if (Serial.read() == 'J') { - Serial.print(F("Autocalibration is running")); - for (int i = 0; i <= 20; i++) { - Serial.print(F(".")); - delay(100); - } - // calculate weight - float toWeightLoadCell2 = ((refCG - distanceX1) * refWeight) / distanceX2; - float toWeightLoadCell1 = refWeight - toWeightLoadCell2; - float toWeightLoadCell3 = 0; - if (nLoadcells > 2) { - toWeightLoadCell1 = toWeightLoadCell1 / 2; - toWeightLoadCell3 = toWeightLoadCell1; - } - // calculate calibration factors - calFactorLoadcell1 = calFactorLoadcell1 / (toWeightLoadCell1 / weightLoadCell1); - calFactorLoadcell2 = calFactorLoadcell2 / (toWeightLoadCell2 / weightLoadCell2); - if (nLoadcells > 2) { - calFactorLoadcell3 = calFactorLoadcell3 / (toWeightLoadCell3 / weightLoadCell3); - } - saveCalFactor1(); - saveCalFactor2(); - saveCalFactor3(); - // finish - Serial.println(F("done")); + runAutoCalibrate(); menuPage = 0; updateMenu = true; } @@ -471,6 +780,24 @@ void loop() { menuPage = 0; updateMenu = true; break; + case MENU_RESISTOR_R1: + resistorR1 = Serial.parseFloat(); + EEPROM.put(P_RESISTOR_R1, resistorR1); +#if defined(ESP8266) + EEPROM.commit(); +#endif + menuPage = 0; + updateMenu = true; + break; + case MENU_RESISTOR_R2: + resistorR2 = Serial.parseFloat(); + EEPROM.put(P_RESISTOR_R2, resistorR2); +#if defined(ESP8266) + EEPROM.commit(); +#endif + menuPage = 0; + updateMenu = true; + break; case MENU_BATTERY_MEASUREMENT: if (Serial.read() == 'J') { enableBatVolt = true; @@ -478,27 +805,36 @@ void loop() { enableBatVolt = false; } EEPROM.put(P_ENABLE_BATVOLT, enableBatVolt); - menuPage = 0; - updateMenu = true; - break; - case MENU_SHOW_ACTUAL: - Serial.readString(); +#if defined(ESP8266) + EEPROM.commit(); +#endif menuPage = 0; updateMenu = true; break; case MENU_RESET_DEFAULT: - //chr = Serial.read(); if (Serial.read() == 'J') { // reset eeprom - for (int i = 0; i < 100; i++) { + for (int i = 0; i < EEPROM_SIZE; i++) { EEPROM.write(i, 0xFF); } Serial.end(); +#if defined(ESP8266) + EEPROM.commit(); + // delete json model file + if (SPIFFS.exists(MODEL_FILE)) { + SPIFFS.remove(MODEL_FILE); + } +#endif resetCPU(); } menuPage = 0; updateMenu = true; break; + default: + Serial.readString(); + menuPage = 0; + updateMenu = true; + break; } Serial.readString(); @@ -512,32 +848,92 @@ void loop() { case MENU_HOME: Serial.print(F("\n\n********************************************\nCG scale by M.Lehmann - V")); Serial.print(CGSCALE_VERSION); - Serial.print(F("\n\n1 - Set number of load cells (")); + Serial.print(F("\n\n")); + + Serial.print(MENU_LOADCELLS); + Serial.print(F(" - Set number of load cells (")); Serial.print(nLoadcells); - Serial.print(F(")\n2 - Set distance X1 (")); + + Serial.print(F(")\n")); + Serial.print(MENU_DISTANCE_X1); + Serial.print(F(" - Set distance X1 (")); Serial.print(distanceX1); - Serial.print(F("mm)\n3 - Set distance X2 (")); + + Serial.print(F("mm)\n")); + Serial.print(MENU_DISTANCE_X2); + Serial.print(F(" - Set distance X2 (")); Serial.print(distanceX2); - Serial.print(F("mm)\n4 - Set distance X3 (")); + + Serial.print(F("mm)\n")); + Serial.print(MENU_DISTANCE_X3); + Serial.print(F(" - Set distance X3 (")); Serial.print(distanceX3); - Serial.print(F("mm)\n5 - Set reference weight (")); + + Serial.print(F("mm)\n")); + Serial.print(MENU_REF_WEIGHT); + Serial.print(F(" - Set reference weight (")); Serial.print(refWeight); - Serial.print(F("g)\n6 - Set reference CG (")); + + Serial.print(F("g)\n")); + Serial.print(MENU_REF_CG); + Serial.print(F(" - Set reference CG (")); Serial.print(refCG); - Serial.print(F("mm)\n7 - Start autocalibration\n8 - Set calibration factor of load cell 1 (")); + + Serial.print(F("mm)\n")); + Serial.print(MENU_AUTO_CALIBRATE); + Serial.print(F(" - Start autocalibration\n")); + + Serial.print(MENU_LOADCELL1_CALIBRATION_FACTOR); + Serial.print(F(" - Set calibration factor of load cell 1 (")); Serial.print(calFactorLoadcell1); - Serial.print(F(")\n9 - Set calibration factor of load cell 2 (")); + + Serial.print(F(")\n")); + Serial.print(MENU_LOADCELL2_CALIBRATION_FACTOR); + Serial.print(F(" - Set calibration factor of load cell 2 (")); Serial.print(calFactorLoadcell2); - Serial.print(F(")\n10 - Set calibration factor of load cell 3 (")); + + Serial.print(F(")\n")); + Serial.print(MENU_LOADCELL3_CALIBRATION_FACTOR); + Serial.print(F(" - Set calibration factor of load cell 3 (")); Serial.print(calFactorLoadcell3); - Serial.print(F(")\n11 - Enable battery voltage measurement (")); + + Serial.print(F(")\n")); + Serial.print(MENU_RESISTOR_R1); + Serial.print(F(" - Set value of resistor R1 (")); + Serial.print(resistorR1); + + Serial.print(F("ohm)\n")); + Serial.print(MENU_RESISTOR_R2); + Serial.print(F(" - Set value of resistor R2 (")); + Serial.print(resistorR2); + + Serial.print(F("ohm)\n")); + Serial.print(MENU_BATTERY_MEASUREMENT); + Serial.print(F(" - Enable battery voltage measurement (")); if (enableBatVolt) { Serial.print(F("enabled)\n")); } else { Serial.print(F("disabled)\n")); } - Serial.print(F("12 - Show actual values\n13 - Reset to factory defaults\n\n")); - Serial.print(F("Please choose the menu number:")); + + Serial.print(MENU_SHOW_ACTUAL); + Serial.print(F(" - Show actual values\n")); + +#if defined(ESP8266) + Serial.print(MENU_WIFI_INFO); + Serial.print(F(" - Show WiFi network info\n")); +#endif + + Serial.print(MENU_RESET_DEFAULT); + Serial.print(F(" - Reset to factory defaults\n")); + + Serial.print(F("\n")); + for (int i = 1; i <= errMsgCnt; i++) { + Serial.print(errMsg[i]); + } + + Serial.print(F("\nPlease choose the menu number:")); + updateMenu = false; break; case MENU_LOADCELLS: @@ -603,6 +999,18 @@ void loop() { Serial.print(newValueText); updateMenu = false; break; + case MENU_RESISTOR_R1: + Serial.print(F("\n\nValue of resistor R1: ")); + Serial.println(resistorR1); + Serial.print(newValueText); + updateMenu = false; + break; + case MENU_RESISTOR_R2: + Serial.print(F("\n\nValue of resistor R2: ")); + Serial.println(resistorR2); + Serial.print(newValueText); + updateMenu = false; + break; case MENU_BATTERY_MEASUREMENT: Serial.print(F("\n\nEnable battery voltage measurement (J/N)?\n")); updateMenu = false; @@ -612,7 +1020,7 @@ void loop() { Serial.print(weightLoadCell1); Serial.print(F("g Lc2: ")); Serial.print(weightLoadCell2); - if (nLoadcells > 2) { + if (nLoadcells == 3) { Serial.print(F("g Lc3: ")); Serial.print(weightLoadCell3); } @@ -620,7 +1028,7 @@ void loop() { Serial.print(weightTotal); Serial.print(F("g CG length: ")); Serial.print(CG_length); - if (nLoadcells > 2) { + if (nLoadcells == 3) { Serial.print(F("mm CG trans: ")); Serial.print(CG_trans); Serial.print(F("mm")); @@ -632,6 +1040,53 @@ void loop() { } Serial.println(); break; +#if defined(ESP8266) + case MENU_WIFI_INFO: + { + Serial.println("\n\n********************************************\nWiFi network information\n"); + Serial.println("# Startup log:"); + Serial.println(wifiMsg); + Serial.println("# end of log"); + + if(wifiSTAmode == false){ + Serial.print("\nConnected clients: "); + Serial.println(WiFi.softAPgetStationNum()); + } + + Serial.println("\nAvailable WiFi networks:"); + int wifiCnt = WiFi.scanNetworks(); + if (wifiCnt == 0) { + Serial.println("no networks found"); + } else { + for (int i = 0; i < wifiCnt; ++i) { + // Print SSID and RSSI for each network found + Serial.print(i + 1); + Serial.print(": "); + Serial.print(WiFi.SSID(i)); + Serial.print(" ("); + Serial.print(WiFi.RSSI(i)); + Serial.print("dBm) "); + switch (WiFi.encryptionType(i)) { + case ENC_TYPE_WEP: + Serial.print("WEP"); + break; + case ENC_TYPE_TKIP: + Serial.print("WPA"); + break; + case ENC_TYPE_CCMP: + Serial.print("WPA2"); + break; + case ENC_TYPE_AUTO: + Serial.print("Auto"); + break; + } + Serial.println(""); + } + } + } + updateMenu = false; + break; +#endif case MENU_RESET_DEFAULT: Serial.print(F("\n\nReset to factory defaults (J/N)?\n")); updateMenu = false; @@ -643,3 +1098,473 @@ void loop() { } } } + + +#if defined(ESP8266) + +// send headvalues to client +void getHead() { + String response = ssid_AP; + response += "&"; + for (int i = 1; i <= errMsgCnt; i++) { + response += errMsg[i]; + } + response += "&"; + response += CGSCALE_VERSION; + server.send(200, "text/html", response); +} + + +// send values to client +void getValue() { + char buff[8]; + String response = ""; + dtostrf(weightTotal, 5, 1, buff); + response += buff; + response += "g&"; + dtostrf(CG_length, 5, 1, buff); + response += buff; + response += "mm&"; + dtostrf(CG_trans, 5, 1, buff); + response += buff; + response += "mm&"; + dtostrf(batVolt, 5, 2, buff); + response += buff; + response += "V"; + server.send(200, "text/html", response); +} + + +// send raw values to client +void getRawValue() { + char buff[8]; + String response = ""; + dtostrf(weightLoadCell1, 5, 1, buff); + response += buff; + response += "g&"; + dtostrf(weightLoadCell2, 5, 1, buff); + response += buff; + response += "g&"; + dtostrf(weightLoadCell3, 5, 1, buff); + response += buff; + response += "g"; + server.send(200, "text/html", response); +} + + +// send parameters to client +void getParameter() { + char buff[8]; + String response = ""; + float weightTotal_saved = 0; + float CG_length_saved = 0; + float CG_trans_saved = 0; + + StaticJsonBuffer jsonBuffer; + //DynamicJsonBuffer jsonBuffer(JSONBUFFER_SIZE); + + if (SPIFFS.exists(MODEL_FILE)) { + // read json file + File f = SPIFFS.open(MODEL_FILE, "r"); + JsonObject& root = jsonBuffer.parseObject(f); + f.close(); + // check if model exists + if (root.success() && root.containsKey(curModelName)) { + JsonObject& object = root[curModelName]; + weightTotal_saved = object["wt"]; + CG_length_saved = object["cg"]; + CG_trans_saved = object["cglr"]; + } + } + + // parameter list + response += nLoadcells; + response += "&"; + response += distanceX1; + response += "&"; + response += distanceX2; + response += "&"; + response += distanceX3; + response += "&"; + response += refWeight; + response += "&"; + response += refCG; + response += "&"; + response += calFactorLoadcell1; + response += "&"; + response += calFactorLoadcell2; + response += "&"; + response += calFactorLoadcell3; + response += "&"; + response += resistorR1; + response += "&"; + response += resistorR2; + response += "&"; + if (enableBatVolt) { + response += "ON"; + } else { + response += "OFF"; + } + response += "&"; + response += ssid_STA; + response += "&"; + response += password_STA; + response += "&"; + response += ssid_AP; + response += "&"; + response += password_AP; + response += "&"; + response += curModelName; + response += "&"; + dtostrf(weightTotal_saved, 5, 1, buff); + response += buff; + response += "g&"; + dtostrf(CG_length_saved, 5, 1, buff); + response += buff; + response += "mm&"; + dtostrf(CG_trans_saved, 5, 1, buff); + response += buff; + response += "mm"; + server.send(200, "text/html", response); +} + + +// send available WiFi networks to client +void getWiFiNetworks() { + String response = ""; + int n = WiFi.scanNetworks(); + if (n > 0) { + for (int i = 0; i < n; ++i) { + response += WiFi.SSID(i); + if (i < n - 1) response += "&"; + } + } + server.send(200, "text/html", response); +} + + +// save parameters +void saveParameter() { + if (server.hasArg("nLoadcells")) nLoadcells = server.arg("nLoadcells").toFloat(); + if (server.hasArg("distanceX1")) distanceX1 = server.arg("distanceX1").toFloat(); + if (server.hasArg("distanceX2")) distanceX2 = server.arg("distanceX2").toFloat(); + if (server.hasArg("distanceX3")) distanceX3 = server.arg("distanceX3").toFloat(); + if (server.hasArg("refWeight")) refWeight = server.arg("refWeight").toFloat(); + if (server.hasArg("refCG")) refCG = server.arg("refCG").toFloat(); + if (server.hasArg("calFactorLoadcell1")) calFactorLoadcell1 = server.arg("calFactorLoadcell1").toFloat(); + if (server.hasArg("calFactorLoadcell2")) calFactorLoadcell2 = server.arg("calFactorLoadcell2").toFloat(); + if (server.hasArg("calFactorLoadcell3")) calFactorLoadcell3 = server.arg("calFactorLoadcell3").toFloat(); + if (server.hasArg("resistorR1")) resistorR1 = server.arg("resistorR1").toFloat(); + if (server.hasArg("resistorR2")) resistorR2 = server.arg("resistorR2").toFloat(); + if (server.hasArg("enableBatVolt")) { + if (server.arg("enableBatVolt") == "ON") { + enableBatVolt = true; + } else { + enableBatVolt = false; + } + } + if (server.hasArg("ssid_STA")) server.arg("ssid_STA").toCharArray(ssid_STA, MAX_SSID_PW_LENGHT + 1); + if (server.hasArg("password_STA")) server.arg("password_STA").toCharArray(password_STA, MAX_SSID_PW_LENGHT + 1); + if (server.hasArg("ssid_AP")) server.arg("ssid_AP").toCharArray(ssid_AP, MAX_SSID_PW_LENGHT + 1); + if (server.hasArg("password_AP")) server.arg("password_AP").toCharArray(password_AP, MAX_SSID_PW_LENGHT + 1); + + EEPROM.put(P_NUMBER_LOADCELLS, nLoadcells); + EEPROM.put(P_DISTANCE_X1, distanceX1); + EEPROM.put(P_DISTANCE_X2, distanceX2); + EEPROM.put(P_DISTANCE_X3, distanceX3); + EEPROM.put(P_REF_WEIGHT, refWeight); + EEPROM.put(P_REF_CG, refCG); + saveCalFactor1(); + saveCalFactor2(); + saveCalFactor3(); + EEPROM.put(P_RESISTOR_R1, resistorR1); + EEPROM.put(P_RESISTOR_R2, resistorR2); + EEPROM.put(P_ENABLE_BATVOLT, enableBatVolt); + EEPROM.put(P_SSID_STA, ssid_STA); + EEPROM.put(P_PASSWORD_STA, password_STA); + EEPROM.put(P_SSID_AP, ssid_AP); + EEPROM.put(P_PASSWORD_AP, password_AP); + EEPROM.commit(); + + // save current model to json + saveModelJson(curModelName); + + server.send(200, "text/plain", "saved"); +} + + +// calibrate cg scale +void autoCalibrate() { + while (!runAutoCalibrate()); + server.send(200, "text/plain", "parameters saved"); +} + + +// tare cg scale +void runTare() { + LoadCell_1.tare(); + LoadCell_2.tare(); + if (nLoadcells == 3) { + LoadCell_3.tare(); + } + if (!getLoadcellError()) { + server.send(200, "text/plain", "tare completed"); + return; + } + server.send(404, "text/plain", "404: tare failed !"); +} + + +// save new model +void saveModel() { + if (server.hasArg("modelname")) { + if (saveModelJson(server.arg("modelname"))) { + server.send(200, "text/plain", "saved"); + return; + } + } + server.send(404, "text/plain", "404: Save model failed !"); +} + + +// open model +void openModel() { + if (server.hasArg("modelname")) { + if (openModelJson(server.arg("modelname"))) { + server.send(200, "text/plain", "opened"); + return; + } + } + server.send(404, "text/plain", "404: Open model failed !"); +} + + +// delete model +void deleteModel() { + if (server.hasArg("modelname")) { + if (deleteModelJson(server.arg("modelname"))) { + server.send(200, "text/plain", "deleted"); + return; + } + } + server.send(404, "text/plain", "404: Delete model failed !"); +} + + +// convert the file extension to the MIME type +String getContentType(String filename) { + if (filename.endsWith(".html")) return "text/html"; + else if (filename.endsWith(".png")) return "text/css"; + else if (filename.endsWith(".css")) return "text/css"; + else if (filename.endsWith(".js")) return "application/javascript"; + else if (filename.endsWith(".map")) return "application/json"; + else if (filename.endsWith(".ico")) return "image/x-icon"; + else if (filename.endsWith(".gz")) return "application/x-gzip"; + return "text/plain"; +} + + +// send file to the client (if it exists) +bool handleFileRead(String path) { + + // If a folder is requested, send the index file + if (path.endsWith("/")) path += "index.html"; + String contentType = getContentType(path); + String pathWithGz = path + ".gz"; + + // If the file exists, either as a compressed archive, or normal + if (SPIFFS.exists(pathWithGz) || SPIFFS.exists(path)) { + if (SPIFFS.exists(pathWithGz)) + path += ".gz"; + File file = SPIFFS.open(path, "r"); + size_t sent = server.streamFile(file, contentType); + file.close(); + return true; + } + + return false; +} + + +// upload a new file to the SPIFFS +void handleFileUpload() { + + HTTPUpload& upload = server.upload(); + + if (upload.status == UPLOAD_FILE_START) { + String filename = upload.filename; + if (!filename.startsWith("/")) filename = "/" + filename; + if (filename != MODEL_FILE ) server.send(500, "text/plain", "wrong file !"); + // Open the file for writing in SPIFFS (create if it doesn't exist) + fsUploadFile = SPIFFS.open(filename, "w"); + filename = String(); + } else if (upload.status == UPLOAD_FILE_WRITE) { + // Write the received bytes to the file + fsUploadFile.write(upload.buf, upload.currentSize); + } else if (upload.status == UPLOAD_FILE_END) { + // If the file was successfully created + if (fsUploadFile) { + fsUploadFile.close(); + // Redirect the client to the success page + server.sendHeader("Location", "/models.html"); + server.send(303); + } else { + server.send(500, "text/plain", "500: couldn't create file"); + } + } + +} + + +// save model to json file +bool saveModelJson(String modelName) { + + if (modelName.length() > MAX_MODELNAME_LENGHT) { + return false; + } + + StaticJsonBuffer jsonBuffer; + //DynamicJsonBuffer jsonBuffer(JSONBUFFER_SIZE); + + if (SPIFFS.exists(MODEL_FILE)) { + // read json file + File f = SPIFFS.open(MODEL_FILE, "r"); + JsonObject& root = jsonBuffer.parseObject(f); + f.close(); + if (!root.success()) { + return false; + } + // check if model exists + if (root.containsKey(modelName)) { + writeModelData(root[modelName]); + } else { + // otherwise create new + writeModelData(root.createNestedObject(modelName)); + } + // write to file + if (root.success()) { + f = SPIFFS.open(MODEL_FILE, "w"); + root.printTo(f); + f.close(); + } else { + return false; + } + } else { + // creat new json + JsonObject& root = jsonBuffer.createObject(); + writeModelData(root.createNestedObject(modelName)); + // write to file + if (root.success()) { + File f = SPIFFS.open(MODEL_FILE, "w"); + root.printTo(f); + f.close(); + } else { + return false; + } + } + + return true; +} + + +// read model data from json file +bool openModelJson(String modelName) { + + StaticJsonBuffer jsonBuffer; + //DynamicJsonBuffer jsonBuffer(JSONBUFFER_SIZE); + + if (SPIFFS.exists(MODEL_FILE)) { + // read json file + File f = SPIFFS.open(MODEL_FILE, "r"); + JsonObject& root = jsonBuffer.parseObject(f); + f.close(); + if (!root.success()) { + return false; + } + // check if model exists + if (root.containsKey(modelName)) { + JsonObject& object = root[modelName]; + // load parameters from model + distanceX1 = object["x1"]; + distanceX2 = object["x2"]; + distanceX3 = object["x3"]; + } else { + return false; + } + + // save current model name to eeprom + modelName.toCharArray(curModelName, MAX_MODELNAME_LENGHT + 1); + EEPROM.put(P_MODELNAME, curModelName); + EEPROM.commit(); + + return true; + } + + return false; +} + + +// delete model from json file +bool deleteModelJson(String modelName) { + + StaticJsonBuffer jsonBuffer; + //DynamicJsonBuffer jsonBuffer(JSONBUFFER_SIZE); + + if (SPIFFS.exists(MODEL_FILE)) { + // read json file + File f = SPIFFS.open(MODEL_FILE, "r"); + JsonObject& root = jsonBuffer.parseObject(f); + f.close(); + if (!root.success()) { + return false; + } + // check if model exists + if (root.containsKey(modelName)) { + root.remove(modelName); + } else { + return false; + } + // if no models in json, kill it + if (root.size() == 0) { + SPIFFS.remove(MODEL_FILE); + } else { + // write to file + if (root.success()) { + File f = SPIFFS.open(MODEL_FILE, "w"); + root.printTo(f); + f.close(); + } else { + return false; + } + } + return true; + } + + return false; + +} + +void writeModelData(JsonObject& object) { + object["wt"] = weightTotal; + object["cg"] = CG_length; + object["cglr"] = CG_trans; + object["x1"] = distanceX1; + object["x2"] = distanceX2; + object["x3"] = distanceX3; +} + +// convert time to string +char * TimeToString(unsigned long t) +{ + static char str[13]; + int h = t / 3600000; + t = t % 3600000; + int m = t / 60000; + t = t % 60000; + int s = t / 1000; + int ms = t - (s * 1000); + sprintf(str, "%02ld:%02d:%02d.%03d", h, m, s, ms); + return str; +} + +#endif diff --git a/data/CG_scale_mechanics.png.gz b/data/CG_scale_mechanics.png.gz new file mode 100644 index 0000000..d9e3a56 Binary files /dev/null and b/data/CG_scale_mechanics.png.gz differ diff --git a/data/airplane.png b/data/airplane.png new file mode 100755 index 0000000..be0b7e3 Binary files /dev/null and b/data/airplane.png differ diff --git a/data/battery.png b/data/battery.png new file mode 100644 index 0000000..c3fd449 Binary files /dev/null and b/data/battery.png differ diff --git a/data/bootstrap.min.css.gz b/data/bootstrap.min.css.gz new file mode 100755 index 0000000..055b91a Binary files /dev/null and b/data/bootstrap.min.css.gz differ diff --git a/data/bootstrap.min.js.gz b/data/bootstrap.min.js.gz new file mode 100755 index 0000000..368d3d1 Binary files /dev/null and b/data/bootstrap.min.js.gz differ diff --git a/data/cg.png b/data/cg.png new file mode 100644 index 0000000..d0866d2 Binary files /dev/null and b/data/cg.png differ diff --git a/data/cglr.png b/data/cglr.png new file mode 100644 index 0000000..2601837 Binary files /dev/null and b/data/cglr.png differ diff --git a/data/home.png b/data/home.png new file mode 100755 index 0000000..7ac34cd Binary files /dev/null and b/data/home.png differ diff --git a/data/index.html.gz b/data/index.html.gz new file mode 100755 index 0000000..c9a3c1f Binary files /dev/null and b/data/index.html.gz differ diff --git a/data/jquery-3.3.1.slim.min.js.gz b/data/jquery-3.3.1.slim.min.js.gz new file mode 100644 index 0000000..6471788 Binary files /dev/null and b/data/jquery-3.3.1.slim.min.js.gz differ diff --git a/data/models.html.gz b/data/models.html.gz new file mode 100755 index 0000000..2c67509 Binary files /dev/null and b/data/models.html.gz differ diff --git a/data/settings.html.gz b/data/settings.html.gz new file mode 100755 index 0000000..097ef8f Binary files /dev/null and b/data/settings.html.gz differ diff --git a/data/settings.png b/data/settings.png new file mode 100755 index 0000000..e767b2b Binary files /dev/null and b/data/settings.png differ diff --git a/data/weight.png b/data/weight.png new file mode 100755 index 0000000..19309bb Binary files /dev/null and b/data/weight.png differ diff --git a/settings.h b/settings_AVR.h similarity index 95% rename from settings.h rename to settings_AVR.h index 5222660..0285de2 100644 --- a/settings.h +++ b/settings_AVR.h @@ -1,6 +1,6 @@ /* ----------------------------------------------------------- - Settings + Settings for AVR based MCUs ----------------------------------------------------------- General settings for the CG scale. */ @@ -44,6 +44,7 @@ CG scale with 3 Loadcells: |---X1---|---------X2----------| */ + #define PIN_LOADCELL1_DOUT A2 #define PIN_LOADCELL1_PD_SCK A3 @@ -99,8 +100,8 @@ U8G2_SH1106_128X64_NONAME_1_HW_I2C oledDisplay(U8G2_R0, /* reset=*/ U8X8_PIN_NON #define V_REF 5000 // set supply voltage from 1800 to 5500mV // voltage divider -#define RESISTOR_R1 10000 // Ohms -#define RESISTOR_R2 10000 // Ohms +#define RESISTOR_R1 10000 // ohm +#define RESISTOR_R2 10000 // ohm /* voltage input diff --git a/settings_ESP8266.h b/settings_ESP8266.h new file mode 100644 index 0000000..bdef9ee --- /dev/null +++ b/settings_ESP8266.h @@ -0,0 +1,147 @@ +/* + ----------------------------------------------------------- + Settings for ESP8266 based MCUs + ----------------------------------------------------------- + General settings for the CG scale. +*/ + +// **** Loadcell hardware settings **** + +#define NUMBER_LOADCELLS 3 // if set to 2, the parameters of loadcell 3 are ignored + +#define DISTANCE_X1 30 // mm +#define DISTANCE_X2 350 // mm +#define DISTANCE_X3 220 // mm + +#define LOADCELL1_CALIBRATION_FACTOR 900 // user set calibration factor +#define LOADCELL2_CALIBRATION_FACTOR 900 // user set calibration factor +#define LOADCELL3_CALIBRATION_FACTOR 900 // user set calibration factor + +/* +CG scale with 2 Loadcells: + + +<- ||=== Loadcell 1 ========== Loadcell 2 + + | | | + |---X1---|---------X2----------| + + + +CG scale with 3 Loadcells: + + -- || Loadcell 1 + | || || + | || || + | || || +<- X3 || ||================ Loadcell 2 + | || || + | || || + | || || + -- || Loadcell 3 + + | | | + |---X1---|---------X2----------| +*/ + + +#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 + + + +// **** Measurement settings **** + +#define STABILISINGTIME 3000 // ms + +#define UPDATE_INTERVAL_OLED_MENU 500 // ms +#define UPDATE_INTERVAL_LOADCELL 100 // ms + +#define SMOOTHING_LOADCELL1 0.4 // IIR filter: smoothing value from 0.00-1.00 +#define SMOOTHING_LOADCELL2 0.4 // IIR filter: smoothing value from 0.00-1.00 +#define SMOOTHING_LOADCELL3 0.4 // IIR filter: smoothing value from 0.00-1.00 + +#define MINIMAL_CG_WEIGHT 10 // g if lower, no CG is displayed (0mm) +#define MINIMAL_TOTAL_WEIGHT 1 // g if lower, weight = 0 is displayed + + + +// **** Calibration settings **** + +#define REF_WEIGHT 1500 // g +#define REF_CG 100 // mm + + + +// **** Display settings **** + +// 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); + + + +// **** Voltage measurement settings **** + +// Enable voltage measurement +#define ENABLE_VOLTAGE true + +// analog input pin +#define VOLTAGE_PIN A0 + +// supply voltage +#define V_REF 3300 // set supply voltage from 1800 to 5500mV + +// voltage divider +#define RESISTOR_R1 20000 // ohm +#define RESISTOR_R2 10000 // ohm + +/* + voltage input + | + | + | | + | | R1 + | | + | + analog Pin <------+ + | + | | + | | R2 + | | + | + | + GND +*/ + + + +// **** Wifi settings **** + +#define MAX_SSID_PW_LENGHT 32 + +// Station mode: connect to available network +#define SSID_STA "myWiFi" +#define PASSWORD_STA "" +#define TIMEOUT_CONNECT 30000 //ms + +// Access point mode: create own network +#define SSID_AP "CG scale" +#define PASSWORD_AP "" +const char ip[4] = {1,2,3,4}; // default IP address + +#define ENABLE_MDNS false // experimental (speed is slow): Enable mDNS to reach the webpage with hostname.local + + +// **** Model memory settings **** + +#define MAX_MODELNAME_LENGHT 32 // max chars +#define MODEL_FILE "/models.json" // file to store models +#define JSONBUFFER_SIZE 20000 // max file size in bytes