From baba55f93be261b27924173e528f5d3e2cc6f4ce Mon Sep 17 00:00:00 2001 From: Ole Artz Date: Thu, 23 Jun 2022 15:30:40 +0200 Subject: [PATCH] LANTelnetToI2C_Board: power-on read latest change board setting from on-Board EEPROM. Quickstart docu was also fixed. --- .../LANTelnetToI2C_Board.ino | 127 ++++++++++++++---- ...kstart 4CH ADC_Ethernet Portable Board.pdf | Bin 67355 -> 67385 bytes 2 files changed, 102 insertions(+), 25 deletions(-) diff --git a/esp32/EthernetUART/LANTelnetToI2C_Board/LANTelnetToI2C_Board.ino b/esp32/EthernetUART/LANTelnetToI2C_Board/LANTelnetToI2C_Board.ino index ebd1dee..5dd0abd 100644 --- a/esp32/EthernetUART/LANTelnetToI2C_Board/LANTelnetToI2C_Board.ino +++ b/esp32/EthernetUART/LANTelnetToI2C_Board/LANTelnetToI2C_Board.ino @@ -1,15 +1,16 @@ /* ##################################################### # ### ### # -# ### CODE for ESP32 of LANToI2C_Board_264 ### # +# ### CODE for ESP32 of LANToI2C_Board ### # # ### for START TELNET SERVER ### # # ### for LAN to I2C ### # # ### connected to 4 CH ADC ### # # ### connected to 0.91 OLED Display ### # +# ### use EEPROM to save settings ### # # ### ### # # ### author: O.Artz ### # # ### ### # -# ### UPDATE 2022-06-07 ### # +# ### UPDATE 2022-06-21 ### # # ### ### # ##################################################### @@ -27,10 +28,25 @@ ETH Disconnected/stopped -> Orange LED on #include //for external ADC #include //for Telnet Server Connection #include //for I2C Connection +#include //to save settings //__________________________________________ #include //for OLED display driver #include //for display control +// define the number of bytes you want to access +/* + * Address Value + * 0x11 ADC measurment range + * 0x12 Unit + * 0x13, 0x14 Device Transformationfactor + * 0x21, 0x22 Voltage divider + * 0x31, 0x32 Offset CH 0 + * 0x33, 0x34 Offset CH 1 + * 0x35, 0x36 Offset CH 2 + * 0x37, 0x38 Offset CH 3 + */ +#define EEPROM_SIZE 512 + // for screen #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 32 // OLED display height, in pixels @@ -109,20 +125,20 @@ volatile static bool eth_connected = false; bool show_connection = true; uint8_t rxcnt = 0, txpoint = 0; uint8_t rxbuf[11], txbuf[12]; -uint8_t val, new_gain, new_unit; +uint8_t new_gain, new_unit; float vol_div_fac, dev_trans_fac; uint16_t new_vol_div_fac, new_dev_trans_fac; +int16_t new_offset_val; int16_t adc0, adc1, adc2, adc3; float fadc0, fadc1, fadc2, fadc3; float offset0, offset1, offset2, offset3; -int16_t new_offset_val; int chan_offset_num, offset_val; uint8_t setGAIN = 0xFFFF; float setADCconversion; float acGAIN[] = {0.1875, 0.125, 0.0625, 0.03125, 0.015625, 0.0078125}; adsGain_t asetGAIN[] = {GAIN_TWOTHIRDS, GAIN_ONE, GAIN_TWO, GAIN_FOUR, GAIN_EIGHT, GAIN_SIXTEEN}; int counter = 0; -String possible_units[] = {"mV", "mA", "mbar", "degC"}; +String possible_units[] = {"mV", "mA", "mbar", "mPa" "degC"}; String unit; void WiFiEvent(WiFiEvent_t event) { @@ -212,6 +228,7 @@ void setup() { connection_screen(); // test_screen(); + EEPROM.begin(EEPROM_SIZE); //Setting for external ADC measurment range // val ADS1015 ADS1115 // ------- ------- @@ -222,39 +239,57 @@ void setup() { // 4 ads.setGain(GAIN_EIGHT); // 8x gain +/- 0.512V 1 bit = 0.25mV 0.015625mV // 5 ads.setGain(GAIN_SIXTEEN); // 16x gain +/- 0.256V 1 bit = 0.125mV 0.0078125mV - val = 2; // chose as default for external adc setting - set_adc_gain(val); +// new_gain = 2; // chose as default for external adc setting + new_gain = EEPROM.read(0x11); + set_adc_gain(new_gain); // Chose right Unit // val Unit // 0 mV // 1 mA // 2 mbar -// 3 degC +// 3 mPa +// 4 degC - new_unit = 0; //default mV +// new_unit = 0; //default + new_unit = EEPROM.read(0x12); set_unit(new_unit); - -// Channel Offset - new_offset_val = 0; //default - chan_offset_num = 5; //default all channels - set_offset(new_offset_val, chan_offset_num); - + // Device Transformationfactor - new_dev_trans_fac = 1000; //default +// new_dev_trans_fac = 1000, //default + new_dev_trans_fac = EEPROM.read(0x13) | EEPROM.read(0x14) << 8; set_device_transformation_factor(new_dev_trans_fac); // Input voltage divider - new_vol_div_fac = 1000; //default w/o voltage devider, 1000 cause will devider by 1000 to sent float by telnet +// new_vol_div_fac = 1000; //default w/o voltage devider, 1000 cause will devider by 1000 to sent float by telnet + new_vol_div_fac = EEPROM.read(0x21) | EEPROM.read(0x22) << 8; set_voltage_divider_factor(new_vol_div_fac); +// Channel Offset +// new_offset_val = 0; //default +// CH 0 + new_offset_val = EEPROM.read(0x31) | EEPROM.read(0x32) << 8; + chan_offset_num = 0; + set_offset(new_offset_val, chan_offset_num); +// CH 1 + new_offset_val = EEPROM.read(0x33) | EEPROM.read(0x34) << 8; + chan_offset_num = 1; + set_offset(new_offset_val, chan_offset_num); +// CH 2 + new_offset_val = EEPROM.read(0x35) | EEPROM.read(0x36) << 8; + chan_offset_num = 2; + set_offset(new_offset_val, chan_offset_num); +// CH 3 + new_offset_val = EEPROM.read(0x37) | EEPROM.read(0x38) << 8; + chan_offset_num = 3; + set_offset(new_offset_val, chan_offset_num); + Serial.print("\nADC Settings"); Serial.print("\nActual Gainfactor: "); - Serial.print(asetGAIN[val]); + Serial.print(asetGAIN[new_gain]); Serial.print("\nConversionfactor: "); Serial.print(setADCconversion); Serial.println(); - } void restart_screen() { @@ -268,13 +303,15 @@ void restart_screen() { // the library initializes this with an Adafruit splash screen. // display.display(); - delay(1000); // Pause for 2 seconds + delay(1000); // Pause for 1 second display.clearDisplay(); } void start_screen() { // show ikf logo and initials of the programmer display.clearDisplay(); + display.ssd1306_command(SSD1306_SETCONTRAST); + display.ssd1306_command(0); // val=0 := 0% up to val = 255 := 100% display.setTextSize(1); // Normal 1:1 pixel scale display.setTextColor(SSD1306_WHITE); // Draw white text display.cp437(true); // Use full 256 char 'Code Page 437' font @@ -345,6 +382,8 @@ void show_CH(String unit) { display.setTextSize(1); if (unit.length() == 4) { display.setCursor(SCREEN_WIDTH * 10 / 28, SCREEN_HEIGHT * 2 / 5); + } else if (unit.length() == 3) { + display.setCursor(SCREEN_WIDTH * 23 / 56, SCREEN_HEIGHT * 2 / 5); } else if (unit.length() == 2) { display.setCursor(SCREEN_WIDTH * 11 / 28, SCREEN_HEIGHT * 2 / 5); } @@ -371,6 +410,8 @@ void show_VAL(int dadc0, int dadc1, int dadc2, int dadc3, String unit) { display.setTextSize(1); if (unit.length() == 4) { display.setCursor(SCREEN_WIDTH * 10 / 28, SCREEN_HEIGHT * 2 / 5); + } else if (unit.length() == 3) { + display.setCursor(SCREEN_WIDTH * 23 / 56, SCREEN_HEIGHT * 2 / 5); } else if (unit.length() == 2) { display.setCursor(SCREEN_WIDTH * 11 / 28, SCREEN_HEIGHT * 2 / 5); } @@ -450,12 +491,12 @@ void set_offset(int16_t new_offset_val, int chan_offset_num) { } } -void set_voltage_divider_factor(float new_vol_div_fac) { +void set_voltage_divider_factor(uint16_t new_vol_div_fac) { // to set the correct voltage divider factor vol_div_fac = new_vol_div_fac/1000.0; } -void set_device_transformation_factor(float new_dev_trans_fac) { +void set_device_transformation_factor(uint16_t new_dev_trans_fac) { // to transformate adc values in device values (units) dev_trans_fac = new_dev_trans_fac/1000.0; } @@ -645,6 +686,8 @@ void getdata(uint8_t buf) { // (hex_to_int(rxbuf[7])*16+hex_to_int(rxbuf[8]))&0xFF; new_gain = (hex_to_int(rxbuf[9])); set_adc_gain(new_gain); + EEPROM.write(0x11, new_gain); + EEPROM.commit(); send_answer_hex(&rxbuf[0], new_gain); } @@ -654,7 +697,9 @@ void getdata(uint8_t buf) { if (hex_to_int(rxbuf[4]) == 0) { new_unit = (hex_to_int(rxbuf[9])); set_unit(new_unit); - + EEPROM.write(0x12, new_unit); + EEPROM.commit(); + send_answer_hex(&rxbuf[0], new_unit); } @@ -662,6 +707,9 @@ void getdata(uint8_t buf) { if (hex_to_int(rxbuf[4]) == 1) { new_dev_trans_fac = (hex_to_int(rxbuf[6]) * 4096 + hex_to_int(rxbuf[7]) * 256 + hex_to_int(rxbuf[8]) * 16 + hex_to_int(rxbuf[9])); set_device_transformation_factor(new_dev_trans_fac); + EEPROM.write(0x13, new_dev_trans_fac); + EEPROM.write(0x14, new_dev_trans_fac >> 8); + EEPROM.commit(); send_answer_hex(&rxbuf[0], new_dev_trans_fac); } @@ -670,7 +718,9 @@ void getdata(uint8_t buf) { if (hex_to_int(rxbuf[4]) == 2) { new_vol_div_fac = (hex_to_int(rxbuf[6]) * 4096 + hex_to_int(rxbuf[7]) * 256 + hex_to_int(rxbuf[8]) * 16 + hex_to_int(rxbuf[9])); set_voltage_divider_factor(new_vol_div_fac); - + EEPROM.write(0x21, new_vol_div_fac); + EEPROM.write(0x22, new_vol_div_fac >> 8); + EEPROM.commit(); send_answer_hex(&rxbuf[0], new_vol_div_fac); } } @@ -678,7 +728,34 @@ void getdata(uint8_t buf) { //offset new_offset_val = (hex_to_int(rxbuf[6]) * 4096 + hex_to_int(rxbuf[7]) * 256 + hex_to_int(rxbuf[8]) * 16 + hex_to_int(rxbuf[9])); chan_offset_num = (hex_to_int(rxbuf[4])); - set_offset(new_offset_val, chan_offset_num); + set_offset(new_offset_val, chan_offset_num); + if (chan_offset_num == 0) { + EEPROM.write(0x31, new_offset_val); + EEPROM.write(0x32, new_offset_val >> 8); + EEPROM.commit(); + } else if (chan_offset_num == 1) { + EEPROM.write(0x33, new_offset_val); + EEPROM.write(0x34, new_offset_val >> 8); + EEPROM.commit(); + } else if (chan_offset_num == 2) { + EEPROM.write(0x35, new_offset_val); + EEPROM.write(0x36, new_offset_val >> 8); + EEPROM.commit(); + } else if (chan_offset_num == 3) { + EEPROM.write(0x37, new_offset_val); + EEPROM.write(0x38, new_offset_val >> 8); + EEPROM.commit(); + } else if (chan_offset_num == 5) { + EEPROM.write(0x31, new_offset_val); + EEPROM.write(0x32, new_offset_val >> 8); + EEPROM.write(0x33, new_offset_val); + EEPROM.write(0x34, new_offset_val >> 8); + EEPROM.write(0x35, new_offset_val); + EEPROM.write(0x36, new_offset_val >> 8); + EEPROM.write(0x37, new_offset_val); + EEPROM.write(0x38, new_offset_val >> 8); + EEPROM.commit(); + } send_answer_hex(&rxbuf[0], new_offset_val); } diff --git a/esp32/EthernetUART/LANTelnetToI2C_Board/quickstart 4CH ADC_Ethernet Portable Board.pdf b/esp32/EthernetUART/LANTelnetToI2C_Board/quickstart 4CH ADC_Ethernet Portable Board.pdf index a51eb1c4ab4cbf9d732eeab0adc879f8f0c0434d..b8558eb3a58124153d90b351423afba0d2b058dc 100644 GIT binary patch delta 7421 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 -- 2.43.0