From 3ed0c826e177df00a9eea6ad6c0ea8e2b9569e1d Mon Sep 17 00:00:00 2001 From: Jan Michel Date: Fri, 16 Dec 2022 14:05:38 +0100 Subject: [PATCH] add MDC Power Disitributor uC code --- .../MdcPowerDistributor.ino | 311 ++++++++++++++++++ 1 file changed, 311 insertions(+) create mode 100644 esp32/EthernetUART/MdcPowerDistributor/MdcPowerDistributor.ino diff --git a/esp32/EthernetUART/MdcPowerDistributor/MdcPowerDistributor.ino b/esp32/EthernetUART/MdcPowerDistributor/MdcPowerDistributor.ino new file mode 100644 index 0000000..ceb2a69 --- /dev/null +++ b/esp32/EthernetUART/MdcPowerDistributor/MdcPowerDistributor.ino @@ -0,0 +1,311 @@ + /* + +Telnet Port 2323 + +Visual Status via Board LEDs: +ETH Start -> Green LED blink for 1 sec +Telnet work -> Green LED on +ETH Disconnected/stopped -> Orange LED on +*/ + +void getdata(uint8_t buf); + +//load needed Libaries +#include +#include + + +//number of clients for this telnet server +#define MAX_SRV_CLIENTS 5 +#define SDA 16 +#define SCL 4 +#define FIRMWARE_VERSION 1 + +#define CB0 5 +#define CB1 33 +#define CB2 14 +#define CB3 32 + + +WiFiServer server(2323); +WiFiClient serverClients[MAX_SRV_CLIENTS]; + +volatile static bool eth_connected = false; +static unsigned long lastTemperatureRead = 0; +uint16_t MEAS_temperature = 0xab12; +uint8_t CONF_GPIO = 0; +uint8_t rxcnt = 0, txpoint = 0; +uint8_t rxbuf[15]; +uint8_t txbuf[12]; + +void WiFiEvent(WiFiEvent_t event) { + switch (event){ + case ARDUINO_EVENT_ETH_START: +// Serial.println("ETH Started"); + //set eth hostname here + digitalWrite(2,LOW); + digitalWrite(15,HIGH); + delay(500); + digitalWrite(15, LOW); + ETH.setHostname("esp32-ethernet"); + break; + + case ARDUINO_EVENT_ETH_CONNECTED: +// Serial.println("ETH Connected"); + digitalWrite(2,LOW); + digitalWrite(15,HIGH); + break; + + case ARDUINO_EVENT_ETH_GOT_IP: +// Serial.print("ETH MAC: "); +// Serial.print(ETH.macAddress()); +// Serial.print(", IPv4: "); +// Serial.print(ETH.localIP()); +// if (ETH.fullDuplex()) { +// Serial.print(", FULL_DUPLEX"); +// } +// Serial.print(", "); +// Serial.print(ETH.linkSpeed()); +// Serial.println("Mbps"); + eth_connected = true; + break; + + case ARDUINO_EVENT_ETH_DISCONNECTED: +// Serial.println("ETH Disconnected"); + digitalWrite(15,LOW); + digitalWrite(2,HIGH); + eth_connected = false; + break; + + case ARDUINO_EVENT_ETH_STOP: +// Serial.println("ETH Stopped"); + digitalWrite(15,LOW); + digitalWrite(2,HIGH); + eth_connected = false; + break; + + default: + break; + } +} + +void setup() { + pinMode(2, OUTPUT); // yellow LED + pinMode(15, OUTPUT); // green LED + + pinMode(CB0, OUTPUT); + pinMode(CB1, OUTPUT); + pinMode(CB2, OUTPUT); + pinMode(CB3, OUTPUT); + + //init UART + Serial.begin(57600); +// Serial.println("\nConnecting"); + + //init temperature sensor + Wire.begin(SDA,SCL); + Wire.beginTransmission(0x48); + Wire.write(0x1); + Wire.write(3 << 5); //resolution 12 Bit + Wire.endTransmission(); + Wire.beginTransmission(0x48); + Wire.write((uint8_t)0x00); + Wire.endTransmission(); + + + //start the telnet server + WiFi.onEvent(WiFiEvent); + delay(1000); + ETH.begin(1,17,23,18,ETH_PHY_LAN8720,ETH_CLOCK_GPIO0_IN); + server.begin(); + server.setNoDelay(true); + + while (eth_connected == false); + +// Serial.print("ready! Use 'telnet "); +// Serial.print(ETH.localIP()); +// Serial.println(" 2323' to connect"); + //visual status for telnet work + digitalWrite(2,LOW); + digitalWrite(15,HIGH); + } + +void loop() { + 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("New 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 + 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 the UART + while(serverClients[i].available()) { + int character = serverClients[i].read(); + if( character >= 0 ) + getdata(character); + } + } + } + else { + if (serverClients[i]) { + serverClients[i].stop(); + } + } + } + + //read UART data and send to Ethernet + if(Serial.available()) { + size_t len = Serial.available(); + uint8_t sbuf[len]; + Serial.readBytes(sbuf, len); + //push UART data to all connected telnet clients + for(i = 0; i < MAX_SRV_CLIENTS; i++) { + if (serverClients[i] && serverClients[i].connected()) { + serverClients[i].write(sbuf, len); +// delay(1); + } + } + } + } + + // read temperature sensor + unsigned long time = millis(); + if(time - lastTemperatureRead >= 3000) { + lastTemperatureRead = time; + Wire.requestFrom(0x48,2); + byte MSB = Wire.read(); + byte LSB = Wire.read(); + MEAS_temperature = (((int32_t) MSB << 8) | (int32_t) LSB)*100/256; + } + } + +/****************************** + * Helper functions + * ****************************/ +uint8_t nib_to_hex(uint16_t in, uint8_t nib) { + // convert integer or nibbles into hex value + uint8_t t = (in >> (nib * 4)) & 0xF; + if (t <= 9) { + return t + 0x30; + } + return t - 10 + 0x61; + } + +uint8_t hex_to_int(uint8_t h) {//assumes valid number + // convert hex value to integer + if (h < 0x40) return h - 0x30; + if (h < 0x50) return h - 0x41 + 10; + return h - 0x61 + 10; + } + + + + +//Forward message to UART +void forward_msg(uint8_t i) { + Serial.write(rxbuf,i); + } + + +uint8_t is_my_address(uint8_t s) { + if ((rxbuf[1] == 'F' || rxbuf[1] == 'f') && (rxbuf[2] == 'F' || rxbuf[2] == 'f')) { + return 1; + } + else { + forward_msg(s); + return 0; + } + } + +//Send own reply to Ethernet +void send_answer_buf(uint8_t *d, uint8_t length) { + for(uint8_t i = 0; i < MAX_SRV_CLIENTS; i++) { + if (serverClients[i] && serverClients[i].connected()) { + serverClients[i].write(d, length); + } + } + } + +//compose response string +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]; + 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; + send_answer_buf(txbuf,10); + } + + +/****************************** + * Receive & Interpret commands + * ****************************/ + +void getdata(uint8_t buf) { + + if (rxcnt != 0 || (buf == 'S' || buf == 'W' || buf == 'R')) { + rxbuf[rxcnt++] = buf; + } + if (buf == '\n' || buf == '\r') { // End of Command + if (rxbuf[0] == 'S') { + forward_msg(rxcnt); + } + else if (rxcnt == 11 && is_my_address(11)) {// message with correct length is for this uC + if (rxbuf[0] == 'R') { + if (hex_to_int(rxbuf[5]) == 4) { //Register 4: Temperature in 1/100 °C + send_answer_hex(&rxbuf[0], MEAS_temperature); + } + if (hex_to_int(rxbuf[5]) == 5) { //Register 5: Information + send_answer_hex(&rxbuf[0], FIRMWARE_VERSION << 4); + } + if (hex_to_int(rxbuf[5]) == 0xa) { //Register A: 4 GPIO pins + send_answer_hex(&rxbuf[0], CONF_GPIO); + } + } + if (rxbuf[0] == 'W') { + if (hex_to_int(rxbuf[5]) == 0xa) { //Register A: 4 GPIO pins + CONF_GPIO = hex_to_int(rxbuf[9]); + send_answer_hex(&rxbuf[0], CONF_GPIO); + (CONF_GPIO & 1) ? digitalWrite(CB0,HIGH):digitalWrite(CB0,LOW); + (CONF_GPIO & 2) ? digitalWrite(CB1,HIGH):digitalWrite(CB1,LOW); + (CONF_GPIO & 4) ? digitalWrite(CB2,HIGH):digitalWrite(CB2,LOW); + (CONF_GPIO & 8) ? digitalWrite(CB3,HIGH):digitalWrite(CB3,LOW); + } + } + } + } + + if (rxcnt >= 11 || buf == '\n' || buf == '\r') { + rxcnt = 0; + } + } + + + + + -- 2.43.0