From 7ca5c34a245999f4f5e2e768f5c54acf87410217 Mon Sep 17 00:00:00 2001 From: Ole Artz Date: Tue, 19 Jul 2022 11:21:40 +0200 Subject: [PATCH] LANTelnetToI2C_Board: add comments, code gets a new structure --- .../LANTelnetToI2C_Board.ino | 578 +++++++++--------- ...kstart 4CH ADC_Ethernet Portable Board.pdf | Bin 67385 -> 67152 bytes 2 files changed, 302 insertions(+), 276 deletions(-) diff --git a/esp32/EthernetUART/LANTelnetToI2C_Board/LANTelnetToI2C_Board.ino b/esp32/EthernetUART/LANTelnetToI2C_Board/LANTelnetToI2C_Board.ino index 5dd0abd..aad779a 100644 --- a/esp32/EthernetUART/LANTelnetToI2C_Board/LANTelnetToI2C_Board.ino +++ b/esp32/EthernetUART/LANTelnetToI2C_Board/LANTelnetToI2C_Board.ino @@ -10,7 +10,7 @@ # ### ### # # ### author: O.Artz ### # # ### ### # -# ### UPDATE 2022-06-21 ### # +# ### UPDATE 2022-07-19 ### # # ### ### # ##################################################### @@ -24,7 +24,9 @@ Telnet work -> Green LED on ETH Disconnected/stopped -> Orange LED on */ -// load needed Libaries +/* + * #################################### load libraries + */ #include //for external ADC #include //for Telnet Server Connection #include //for I2C Connection @@ -33,7 +35,9 @@ ETH Disconnected/stopped -> Orange LED on #include //for OLED display driver #include //for display control -// define the number of bytes you want to access +/* + * #################################### define parameters to fixed values + */ /* * Address Value * 0x11 ADC measurment range @@ -45,68 +49,20 @@ ETH Disconnected/stopped -> Orange LED on * 0x35, 0x36 Offset CH 2 * 0x37, 0x38 Offset CH 3 */ +// define the number of bytes you want to access #define EEPROM_SIZE 512 -// for screen +// Display #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 32 // OLED display height, in pixels - -// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins) -// The pins for I2C are defined by the Wire-library. -// On an arduino UNO: A4(SDA), A5(SCL) -// On an arduino MEGA 2560: 20(SDA), 21(SCL) -// On an arduino LEONARDO: 2(SDA), 3(SCL), ... #define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin) -#define SCREEN_ADDRESS 0x3C //< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32 +#define SCREEN_ADDRESS 0x3C // See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); -#define NUMFLAKES 10 // Number of snowflakes in the animation example - #define imageWidth 106 #define imageHeight 32 -const unsigned char logo_bmp[] PROGMEM = { - 0xfc, 0x0f, 0xc0, 0x03, 0xf8, 0x3f, 0xff, 0xfc, 0x0f, 0xff, 0xff, 0xff, - 0xff, 0x80, 0xfc, 0x0f, 0xc0, 0x07, 0xf8, 0x3f, 0xff, 0xfc, 0x0f, 0xff, - 0xff, 0xff, 0xff, 0x00, 0xfc, 0x0f, 0xc0, 0x0f, 0xf0, 0x3f, 0xff, 0xfc, - 0x0f, 0xff, 0xff, 0xff, 0xfe, 0x40, 0xfc, 0x0f, 0xc0, 0x1f, 0xe0, 0x3f, - 0xff, 0xfc, 0x0f, 0xff, 0xff, 0xff, 0xfc, 0xc0, 0xfc, 0x0f, 0xc0, 0x3f, - 0xc0, 0x3f, 0xff, 0xfc, 0x0f, 0xff, 0xff, 0xff, 0xf1, 0xc0, 0xfc, 0x0f, - 0xc0, 0x3f, 0x80, 0x3f, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xe7, 0xc0, - 0xfc, 0x0f, 0xc0, 0x7f, 0x00, 0x3f, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, - 0x8f, 0xc0, 0xfc, 0x0f, 0xc0, 0xfe, 0x00, 0x3f, 0x00, 0x00, 0x0f, 0xff, - 0xff, 0xff, 0x3f, 0xc0, 0xfc, 0x0f, 0xc1, 0xfc, 0x00, 0x3f, 0x00, 0x00, - 0x0f, 0xff, 0xff, 0xfc, 0xff, 0xc0, 0xfc, 0x0f, 0xc3, 0xf8, 0x00, 0x3f, - 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf1, 0xff, 0xc0, 0xfc, 0x0f, 0xc7, 0xf8, - 0x00, 0x3f, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x8f, 0xff, 0xc0, 0xfc, 0x0f, - 0xcf, 0xf0, 0x00, 0x3f, 0x00, 0x00, 0x0f, 0xff, 0xfc, 0x3f, 0xff, 0xc0, - 0xfc, 0x0f, 0xcf, 0xe0, 0x00, 0x3f, 0x00, 0x00, 0x0f, 0xff, 0xe0, 0xff, - 0xff, 0xc0, 0xfc, 0x0f, 0xdf, 0xe0, 0x00, 0x3f, 0xff, 0xf0, 0x0f, 0xfe, - 0x0f, 0xff, 0xff, 0xc0, 0xfc, 0x0f, 0xff, 0xf0, 0x00, 0x3f, 0xff, 0xf0, - 0x0f, 0x80, 0xff, 0xff, 0xff, 0xc0, 0xfc, 0x0f, 0xff, 0xf8, 0x00, 0x3f, - 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0xff, 0xf8, - 0x00, 0x3f, 0xff, 0xf0, 0x00, 0x00, 0xff, 0xff, 0xff, 0xc0, 0xfc, 0x0f, - 0xfd, 0xfc, 0x00, 0x3f, 0xff, 0xf0, 0x0f, 0xf8, 0x1f, 0xff, 0xff, 0xc0, - 0xfc, 0x0f, 0xf8, 0xfc, 0x00, 0x3f, 0x00, 0x00, 0x0f, 0xff, 0xc1, 0xff, - 0xff, 0xc0, 0xfc, 0x0f, 0xf0, 0xfe, 0x00, 0x3f, 0x00, 0x00, 0x0f, 0xff, - 0xf8, 0x7f, 0xff, 0xc0, 0xfc, 0x0f, 0xe0, 0x7f, 0x00, 0x3f, 0x00, 0x00, - 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xc0, 0xfc, 0x0f, 0xe0, 0x7f, 0x00, 0x3f, - 0x00, 0x00, 0x0f, 0xff, 0xff, 0xe3, 0xff, 0xc0, 0xfc, 0x0f, 0xc0, 0x3f, - 0x80, 0x3f, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf8, 0xff, 0xc0, 0xfc, 0x0f, - 0xc0, 0x3f, 0x80, 0x3f, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xfe, 0x3f, 0xc0, - 0xfc, 0x0f, 0xc0, 0x1f, 0xc0, 0x3f, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, - 0x9f, 0xc0, 0xfc, 0x0f, 0xc0, 0x0f, 0xe0, 0x3f, 0x00, 0x00, 0x0f, 0xff, - 0xff, 0xff, 0xc7, 0xc0, 0xfc, 0x0f, 0xc0, 0x0f, 0xe0, 0x3f, 0x00, 0x00, - 0x0f, 0xff, 0xff, 0xff, 0xf3, 0xc0, 0xfc, 0x0f, 0xc0, 0x07, 0xf0, 0x3f, - 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xf9, 0xc0, 0xfc, 0x0f, 0xc0, 0x07, - 0xf0, 0x3f, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xfc, 0xc0, 0xfc, 0x0f, - 0xc0, 0x03, 0xf8, 0x3f, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xfe, 0x40, - 0xfc, 0x0f, 0xc0, 0x03, 0xfc, 0x3f, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, - 0xff, 0x00, 0xfc, 0x0f, 0xc0, 0x01, 0xfc, 0x3f, 0x00, 0x00, 0x0f, 0xff, - 0xff, 0xff, 0xff, 0x80}; -//__________________________________________ - -// how many clients should be able to telnet to this ESP32 +//number of clients for this telnet server #define MAX_SRV_CLIENTS 10 #define SDA 5 @@ -119,9 +75,16 @@ Adafruit_ADS1115 ads(0x48); //Use this for the 16-Bit version WiFiServer server(2323); WiFiClient serverClients[MAX_SRV_CLIENTS]; +/* + * #################################### declare all needed variables + */ + // used to check the number every time, cause could changed volatile static bool eth_connected = false; +//reset of the EEPROM +bool eeprom_reset = false; // =true for reset + bool show_connection = true; uint8_t rxcnt = 0, txpoint = 0; uint8_t rxbuf[11], txbuf[12]; @@ -141,6 +104,9 @@ int counter = 0; String possible_units[] = {"mV", "mA", "mbar", "mPa" "degC"}; String unit; +/* + * #################################### communication functions + */ void WiFiEvent(WiFiEvent_t event) { // ensure the ethernet connection (status) switch (event) { @@ -216,82 +182,77 @@ void start_telnet() { digitalWrite(15, HIGH); } -void setup() { - //initalize the board - start_telnet(); - // for I2C Connection - Wire.begin(SDA, SCL); // Initiate the Wire library - - // for display__________________________________________________________ - restart_screen(); - start_screen(); - connection_screen(); - // test_screen(); - - EEPROM.begin(EEPROM_SIZE); -//Setting for external ADC measurment range -// val ADS1015 ADS1115 -// ------- ------- -// 0 ads.setGain(GAIN_TWOTHIRDS); // 2/3x gain +/- 6.144V 1 bit = 3mV 0.1875mV -// 1 ads.setGain(GAIN_ONE); // 1x gain +/- 4.096V 1 bit = 2mV 0.125mV -// 2 ads.setGain(GAIN_TWO); // 2x gain +/- 2.048V 1 bit = 1mV 0.0625mV -// 3 ads.setGain(GAIN_FOUR); // 4x gain +/- 1.024V 1 bit = 0.5mV 0.03125mV -// 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 - -// 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 mPa -// 4 degC - -// new_unit = 0; //default - new_unit = EEPROM.read(0x12); - set_unit(new_unit); - -// Device Transformationfactor -// 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 = 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); +void send_answer_buf(uint8_t *buf, size_t len) { + uint8_t i; + for (i = 0; i < MAX_SRV_CLIENTS; i++) { + if (serverClients[i] && serverClients[i].connected()) { + serverClients[i].write(buf, len); + delay(1); + } + } +} - Serial.print("\nADC Settings"); - Serial.print("\nActual Gainfactor: "); - Serial.print(asetGAIN[new_gain]); - Serial.print("\nConversionfactor: "); - Serial.print(setADCconversion); - Serial.println(); +void send_answer_hex(uint8_t *rxbuf, uint16_t v) { + txbuf[0] = 'A'; + txbuf[1] = rxbuf[1]; + txbuf[2] = rxbuf[2]; + txbuf[3] = rxbuf[3]; // Switch deactivated + txbuf[4] = rxbuf[4]; + txbuf[5] = rxbuf[5]; + txbuf[6] = nib_to_hex(v, 3); + txbuf[7] = nib_to_hex(v, 2); + txbuf[8] = nib_to_hex(v, 1); + txbuf[9] = nib_to_hex(v, 0); + txbuf[10] = '\n'; + txbuf[11] = 0; + size_t len = 12; + send_answer_buf(txbuf, len); } +/* + * #################################### display functions + */ +const unsigned char logo_bmp[] PROGMEM = { + 0xfc, 0x0f, 0xc0, 0x03, 0xf8, 0x3f, 0xff, 0xfc, 0x0f, 0xff, 0xff, 0xff, + 0xff, 0x80, 0xfc, 0x0f, 0xc0, 0x07, 0xf8, 0x3f, 0xff, 0xfc, 0x0f, 0xff, + 0xff, 0xff, 0xff, 0x00, 0xfc, 0x0f, 0xc0, 0x0f, 0xf0, 0x3f, 0xff, 0xfc, + 0x0f, 0xff, 0xff, 0xff, 0xfe, 0x40, 0xfc, 0x0f, 0xc0, 0x1f, 0xe0, 0x3f, + 0xff, 0xfc, 0x0f, 0xff, 0xff, 0xff, 0xfc, 0xc0, 0xfc, 0x0f, 0xc0, 0x3f, + 0xc0, 0x3f, 0xff, 0xfc, 0x0f, 0xff, 0xff, 0xff, 0xf1, 0xc0, 0xfc, 0x0f, + 0xc0, 0x3f, 0x80, 0x3f, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xe7, 0xc0, + 0xfc, 0x0f, 0xc0, 0x7f, 0x00, 0x3f, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, + 0x8f, 0xc0, 0xfc, 0x0f, 0xc0, 0xfe, 0x00, 0x3f, 0x00, 0x00, 0x0f, 0xff, + 0xff, 0xff, 0x3f, 0xc0, 0xfc, 0x0f, 0xc1, 0xfc, 0x00, 0x3f, 0x00, 0x00, + 0x0f, 0xff, 0xff, 0xfc, 0xff, 0xc0, 0xfc, 0x0f, 0xc3, 0xf8, 0x00, 0x3f, + 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf1, 0xff, 0xc0, 0xfc, 0x0f, 0xc7, 0xf8, + 0x00, 0x3f, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x8f, 0xff, 0xc0, 0xfc, 0x0f, + 0xcf, 0xf0, 0x00, 0x3f, 0x00, 0x00, 0x0f, 0xff, 0xfc, 0x3f, 0xff, 0xc0, + 0xfc, 0x0f, 0xcf, 0xe0, 0x00, 0x3f, 0x00, 0x00, 0x0f, 0xff, 0xe0, 0xff, + 0xff, 0xc0, 0xfc, 0x0f, 0xdf, 0xe0, 0x00, 0x3f, 0xff, 0xf0, 0x0f, 0xfe, + 0x0f, 0xff, 0xff, 0xc0, 0xfc, 0x0f, 0xff, 0xf0, 0x00, 0x3f, 0xff, 0xf0, + 0x0f, 0x80, 0xff, 0xff, 0xff, 0xc0, 0xfc, 0x0f, 0xff, 0xf8, 0x00, 0x3f, + 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0xff, 0xf8, + 0x00, 0x3f, 0xff, 0xf0, 0x00, 0x00, 0xff, 0xff, 0xff, 0xc0, 0xfc, 0x0f, + 0xfd, 0xfc, 0x00, 0x3f, 0xff, 0xf0, 0x0f, 0xf8, 0x1f, 0xff, 0xff, 0xc0, + 0xfc, 0x0f, 0xf8, 0xfc, 0x00, 0x3f, 0x00, 0x00, 0x0f, 0xff, 0xc1, 0xff, + 0xff, 0xc0, 0xfc, 0x0f, 0xf0, 0xfe, 0x00, 0x3f, 0x00, 0x00, 0x0f, 0xff, + 0xf8, 0x7f, 0xff, 0xc0, 0xfc, 0x0f, 0xe0, 0x7f, 0x00, 0x3f, 0x00, 0x00, + 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xc0, 0xfc, 0x0f, 0xe0, 0x7f, 0x00, 0x3f, + 0x00, 0x00, 0x0f, 0xff, 0xff, 0xe3, 0xff, 0xc0, 0xfc, 0x0f, 0xc0, 0x3f, + 0x80, 0x3f, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf8, 0xff, 0xc0, 0xfc, 0x0f, + 0xc0, 0x3f, 0x80, 0x3f, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xfe, 0x3f, 0xc0, + 0xfc, 0x0f, 0xc0, 0x1f, 0xc0, 0x3f, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, + 0x9f, 0xc0, 0xfc, 0x0f, 0xc0, 0x0f, 0xe0, 0x3f, 0x00, 0x00, 0x0f, 0xff, + 0xff, 0xff, 0xc7, 0xc0, 0xfc, 0x0f, 0xc0, 0x0f, 0xe0, 0x3f, 0x00, 0x00, + 0x0f, 0xff, 0xff, 0xff, 0xf3, 0xc0, 0xfc, 0x0f, 0xc0, 0x07, 0xf0, 0x3f, + 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xf9, 0xc0, 0xfc, 0x0f, 0xc0, 0x07, + 0xf0, 0x3f, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xfc, 0xc0, 0xfc, 0x0f, + 0xc0, 0x03, 0xf8, 0x3f, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xfe, 0x40, + 0xfc, 0x0f, 0xc0, 0x03, 0xfc, 0x3f, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, + 0xff, 0x00, 0xfc, 0x0f, 0xc0, 0x01, 0xfc, 0x3f, 0x00, 0x00, 0x0f, 0xff, + 0xff, 0xff, 0xff, 0x80 +}; + void restart_screen() { // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS, false, false)) { @@ -350,20 +311,6 @@ void connection_screen() { delay(5000); // Pause for 5 seconds } -void test_screen() { - // used as a test case - display.clearDisplay(); - display.setTextSize(1); // Normal 1:1 pixel scale - display.setTextColor(SSD1306_WHITE); // Draw white text - display.setCursor(0, 0); - display.cp437(true); // Use full 256 char 'Code Page 437' font - display.write("CHECKER"); - display.display(); - display.startscrollright(0x00, 0x07); - delay(4100); - display.stopscroll(); -} - void show_CH(String unit) { // show the position of the measured adc values by their label name and the acutally set unit globaly display.clearDisplay(); @@ -420,59 +367,9 @@ void show_VAL(int dadc0, int dadc1, int dadc2, int dadc3, String unit) { display.display(); } -void loop() { - // for recieving and transmitting by Telnet Server Connection - uint8_t i; - if (eth_connected == true) { - // check if there are any new clients - if (server.hasClient()) { - for (i = 0; i < MAX_SRV_CLIENTS; i++) { - // find free/disconnected spot - if (!serverClients[i] || !serverClients[i].connected()) { - if (serverClients[i]) - serverClients[i].stop(); - serverClients[i] = server.available(); - if (!serverClients[i]) - Serial.println("available broken"); - Serial.print("\nNew client: "); - Serial.print(i); - Serial.print(' '); - Serial.println(serverClients[i].remoteIP()); - break; - } - } - if (i >= MAX_SRV_CLIENTS) { - // no free/disconnected spot so reject - server.available().stop(); - } - } - // check clients for data - String getstring; - - for (i = 0; i < MAX_SRV_CLIENTS; i++) { - if (serverClients[i] && serverClients[i].connected()) { - if (serverClients[i].available()) { - // get data from the telnet client and push it to I2C - while (serverClients[i].available()) { - getstring = char(serverClients[i].read()); - for (uint8_t m = 0; m < getstring.length(); m++) { - getdata(getstring.charAt(m)); - } - } - } - } else { - if (serverClients[i]) { - serverClients[i].stop(); - } - } - } - } - - get_adc_val(); // get the actual measured values from adc - - delay(100); -} - +/* + * #################################### setting functions + */ void set_offset(int16_t new_offset_val, int chan_offset_num) { // to calibrate the channels with an offset value if (chan_offset_num == 0) { @@ -513,60 +410,9 @@ void set_adc_gain(uint8_t new_gain) { setADCconversion = acGAIN[new_gain]; } -void get_adc_val() { - // Get the actual ADC measurment values in dimension of mV - adc0 = ads.readADC_SingleEnded(0); - adc1 = ads.readADC_SingleEnded(1); - adc2 = ads.readADC_SingleEnded(2); - adc3 = ads.readADC_SingleEnded(3); - - fadc0 = adc0 * setADCconversion * vol_div_fac * dev_trans_fac + offset0; - fadc1 = adc1 * setADCconversion * vol_div_fac * dev_trans_fac + offset1; - fadc2 = adc2 * setADCconversion * vol_div_fac * dev_trans_fac + offset2; - fadc3 = adc3 * setADCconversion * vol_div_fac * dev_trans_fac + offset3; - - String sadc0 = String(fadc0); - String sadc1 = String(fadc1); - String sadc2 = String(fadc2); - String sadc3 = String(fadc3); - - int dadc0 = fadc0; - int dadc1 = fadc1; - int dadc2 = fadc2; - int dadc3 = fadc3; - - //String unit = possible_units[new_unit]; - String sbuf = String("\nAIN0: " + sadc0 + ' ' + unit + "\n" + "AIN1: " + sadc1 + ' ' + unit + "\n" + "AIN2: " + sadc2 + ' ' + unit + "\n" + "AIN3: " + sadc3 + ' ' + unit + "\n "); - - Serial.print(sbuf); // for serial output - - size_t len = sbuf.length(); - - uint8_t buf[len]; - sbuf.toCharArray((char *)buf, len); // Copies the String’s characters to the supplied buffer. - - counter += 1; - if (counter == 1) { - if (eth_connected == true) { - if (show_connection == true) { - connection_screen(); - show_connection = false; - } - } - show_CH(unit); - } else if (counter == 100) { - counter = 0; - } else { - show_VAL(dadc0, dadc1, dadc2, dadc3, unit); - } - - if (eth_connected == false) { - show_connection = true; - } - - send_answer_buf(buf, len); // for telnet continous output -} - +/* + * #################################### converter + */ uint8_t nib_to_hex(uint16_t in, uint8_t nib) { uint8_t t = (in >> (nib * 4)) & 0xF; if (t <= 9) { @@ -590,33 +436,9 @@ void sub1(uint8_t *c1, uint8_t *c2) { *c2 = nib_to_hex(b, 0); } -void send_answer_buf(uint8_t *buf, size_t len) { - uint8_t i; - for (i = 0; i < MAX_SRV_CLIENTS; i++) { - if (serverClients[i] && serverClients[i].connected()) { - serverClients[i].write(buf, len); - delay(1); - } - } -} - -void send_answer_hex(uint8_t *rxbuf, uint16_t v) { - txbuf[0] = 'A'; - txbuf[1] = rxbuf[1]; - txbuf[2] = rxbuf[2]; - txbuf[3] = rxbuf[3]; // Switch deactivated - txbuf[4] = rxbuf[4]; - txbuf[5] = rxbuf[5]; - txbuf[6] = nib_to_hex(v, 3); - txbuf[7] = nib_to_hex(v, 2); - txbuf[8] = nib_to_hex(v, 1); - txbuf[9] = nib_to_hex(v, 0); - txbuf[10] = '\n'; - txbuf[11] = 0; - size_t len = 12; - send_answer_buf(txbuf, len); -} - +/* + * #################################### chaining + */ void forward_msg(uint8_t i) { sub1(&rxbuf[1], &rxbuf[2]); memcpy((uint8_t *)txbuf, (uint8_t *)rxbuf, i); @@ -633,6 +455,9 @@ uint8_t is_my_address(uint8_t s) { return 0; } } +/* + * #################################### head functions + */ void getdata(uint8_t buf) { // get data by register mode @@ -819,3 +644,204 @@ void getdata(uint8_t buf) { if (rxcnt >= 10 || buf == '\n' || buf == '\r') { rxcnt = 0;} } + +void get_adc_val() { + // Get the actual ADC measurment values in dimension of mV + adc0 = ads.readADC_SingleEnded(0); + adc1 = ads.readADC_SingleEnded(1); + adc2 = ads.readADC_SingleEnded(2); + adc3 = ads.readADC_SingleEnded(3); + + fadc0 = adc0 * setADCconversion * vol_div_fac * dev_trans_fac + offset0; + fadc1 = adc1 * setADCconversion * vol_div_fac * dev_trans_fac + offset1; + fadc2 = adc2 * setADCconversion * vol_div_fac * dev_trans_fac + offset2; + fadc3 = adc3 * setADCconversion * vol_div_fac * dev_trans_fac + offset3; + + String sadc0 = String(fadc0); + String sadc1 = String(fadc1); + String sadc2 = String(fadc2); + String sadc3 = String(fadc3); + + int dadc0 = fadc0; + int dadc1 = fadc1; + int dadc2 = fadc2; + int dadc3 = fadc3; + + //String unit = possible_units[new_unit]; + String sbuf = String("\nAIN0: " + sadc0 + ' ' + unit + "\n" + "AIN1: " + sadc1 + ' ' + unit + "\n" + "AIN2: " + sadc2 + ' ' + unit + "\n" + "AIN3: " + sadc3 + ' ' + unit + "\n "); + + Serial.print(sbuf); // for serial output + + size_t len = sbuf.length(); + + uint8_t buf[len]; + sbuf.toCharArray((char *)buf, len); // Copies the String’s characters to the supplied buffer. + + counter += 1; + if (counter == 1) { + if (eth_connected == true) { + if (show_connection == true) { + connection_screen(); + show_connection = false; + } + } + show_CH(unit); + } else if (counter == 100) { + counter = 0; + } else { + show_VAL(dadc0, dadc1, dadc2, dadc3, unit); + } + + if (eth_connected == false) { + show_connection = true; + } + + send_answer_buf(buf, len); // for telnet continous output +} + +void setup() { + //initalize the board + start_telnet(); + // for I2C Connection + Wire.begin(SDA, SCL); // Initiate the Wire library + + // for display__________________________________________________________ + restart_screen(); + start_screen(); + connection_screen(); + // test_screen(); + + // eeprom + EEPROM.begin(EEPROM_SIZE); + + if (eeprom_reset == 1) { + for (int i = 0 ; i < EEPROM.length() ; i++) { + EEPROM.write(i, 0); + } + } + +/* Setting for external ADC measurment range + val ADS1015 ADS1115 + ------- ------- + 0 ads.setGain(GAIN_TWOTHIRDS); // 2/3x gain +/- 6.144V 1 bit = 3mV 0.1875mV + 1 ads.setGain(GAIN_ONE); // 1x gain +/- 4.096V 1 bit = 2mV 0.125mV + 2 ads.setGain(GAIN_TWO); // 2x gain +/- 2.048V 1 bit = 1mV 0.0625mV + 3 ads.setGain(GAIN_FOUR); // 4x gain +/- 1.024V 1 bit = 0.5mV 0.03125mV + 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 +*/ + +// new_gain = 2; // chose as default for external adc setting + new_gain = EEPROM.read(0x11); + if (new_gain == 0xff) { + new_gain = 1; + } + set_adc_gain(new_gain); + +/* Chose right Unit + val Unit + 0 mV + 1 mA + 2 mbar + 3 mPa + 4 degC +*/ + new_unit = EEPROM.read(0x12); + if (new_unit == 0xff) { + new_unit = 0; //default + } + set_unit(new_unit); + +// Device Transformationfactor + new_dev_trans_fac = EEPROM.read(0x13) | EEPROM.read(0x14) << 8; + if (new_dev_trans_fac == 0 || new_dev_trans_fac == 0xff) { + new_dev_trans_fac = 1000; //default + } + set_device_transformation_factor(new_dev_trans_fac); + +// Input voltage divider + new_vol_div_fac = EEPROM.read(0x21) | EEPROM.read(0x22) << 8; + if (new_vol_div_fac == 0 || new_vol_div_fac == 0xff) { + new_vol_div_fac = 1000; //default w/o voltage devider, 1000 cause will devider by 1000 to sent float by telnet + } + 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[new_gain]); + Serial.print("\nConversionfactor: "); + Serial.print(setADCconversion); + Serial.println(); +} + +void loop() { + // for recieving and transmitting by Telnet Server Connection + uint8_t i; + if (eth_connected == true) { + // check if there are any new clients + if (server.hasClient()) { + for (i = 0; i < MAX_SRV_CLIENTS; i++) { + // find free/disconnected spot + if (!serverClients[i] || !serverClients[i].connected()) { + if (serverClients[i]) + serverClients[i].stop(); + serverClients[i] = server.available(); + if (!serverClients[i]) + Serial.println("available broken"); + Serial.print("\nNew client: "); + Serial.print(i); + Serial.print(' '); + Serial.println(serverClients[i].remoteIP()); + break; + } + } + if (i >= MAX_SRV_CLIENTS) { + // no free/disconnected spot so reject + server.available().stop(); + } + } + // check clients for data + String getstring; + + for (i = 0; i < MAX_SRV_CLIENTS; i++) { + if (serverClients[i] && serverClients[i].connected()) { + if (serverClients[i].available()) { + // get data from the telnet client and push it to I2C + while (serverClients[i].available()) { + getstring = char(serverClients[i].read()); + for (uint8_t m = 0; m < getstring.length(); m++) { + getdata(getstring.charAt(m)); + } + } + } + } else { + if (serverClients[i]) { + serverClients[i].stop(); + } + } + } + } + + get_adc_val(); // get the actual measured values from adc + + delay(100); +} 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 b8558eb3a58124153d90b351423afba0d2b058dc..c5ebc6057a499ad4785fdfc5917e947bcdc0114f 100644 GIT binary patch delta 22063 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 a_&R#~26|t;#)(2f5g1N+c|8*x=l=ouIkOo6 delta 22205 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�A2Zc<2$H3o2PsAA7uj9?M4bP(?k&Qv{h02V0`>N+Y+7{=l2(S#v7en#jtl{ z`eS^YKcAFK50@mCt9^Rak$jc1+E4LS2PUZ-aXjFbag>puaBe0(L?PA9t$R3hAv2AH+g20PTn$7 z*X$e^^+BB}$WKOcd^CQ>=1By&$2^Zt7sL}J`H||w61K>gl{T;@F1dM{!qeUQfOx7a~^w6t87 zVosac=mFmc?q@IlqS$h^a^)yHp|6hlrUpvw#^gPAxRv9`-`HYKZ@XjO+;LQP)*b#qxLn;Gisx_I#@T~>kikt>eapg!;1DGIe}E7CFMP;hBU&7`!)pD2DZyc6(54s& zNw)O`1LRtd9EiC7YEVRSx;|%l?Mw6U1jU#HeL{iJ1p6L!sazg#)bYjDmEhiV(iPIA zovpT@X~_B&>ZjQHcxu#BjWzxB$P%IL6Q6V^x;rzYpk4SCTt)7Y^?B8=X=C4J=^>Z4 zoV7FZx{tL2jjv}!=cesHnHn%vT7mH4D0|IkK$LANE(kj`z8*_myKbi6gD6?|4ASq}BR5Xo@;_;K0KvuoKeK8redYij<>rDZh* z9B{;U(ze%bLt|N|i-apX!rpu93ATXFqS7v*hP<4|x+^t8vJ1~U>pL8{h=KZmJ7T|#_L z*usKpa~JOH{6!J@#D@5Pfibcr0}euy?=a|O_ieeK$uZVk%x|#3uD=*Ki~UlF*0MD@5O0lA}HAc1QH>G>p55nDFFN@@C}asX%hd-5wZw8 zJQNIv?-;1zVPM$bD>xXc{+EUT!~b3(!LUD9|0M4a5SG;r)VC9e=-~r~gD_+vrjF=e zam<~)iN0Qr&fZ`IgzUf!`8Rp-U**J5&<$y|U+uk|SwW%y8qG`$`X_|KDw_!6%gj_AvZv%|~%7eYkr`2JnFrN5`M8qVIw-i=6L649(N`@i_7#zHH9($rBuIPch@;6D`u$3W1# zcg)f-yM5uTnt|Pk;TSY}cVYwt3f;Xs1d@fN?kbR_{p^c`tM6_n0*QwG-8$fZeMhj4 zaCc%P2J+J>u(Y3MX2*4Rfk=!xeD{t~tU>zGj&=Sh1Ol?VPb>|#yJ{2ywL{~NjDV||6N#+bxN`$p zgszdt6(ShHn#MoB=z*=lnn<)h5{Ad=V-R`})}@1@Sp{SC&}cXwf!D*UBeA^yG_n78 zo1J^FM|8wpb#`?1_H_rVA)z`5JQAmehv4<`x=@6!o;prP7o(#Khw8DGkevscw~xJ- W&rL7qE4(Na90ui8P|!EU^Zp0#9?UWT -- 2.43.0