/* MS-DOS hardware serial COM port to WiFi UDP - No display (no UI) Compiled for ESP-12E and loaded to NodeMCU 1.0 (ESP-12F Module) using Arduino IDE Version 2.0.2 LM Sep. 2022 - CC attribution - https://creativecommons.org/licenses/by/3.0/us/ Jan. 2023 - Add pushbutton (DOS2UDP Rev-1) - Extend DOS2UDP as DOS2UDP+USB (Hdwr serial to USB virtual serial) */ #include #include #include //#define UNIX // Comment-out for Windows listener const boolean BIDIR = false; // If true, interface is bidirectional // (Not implemented) // General #define BAUD 115200 // USB Serial monitor (not software serial) #define PB1 A0 // Rev-1 Pushbutton on A0 // USB virtual serial extension const boolean DOS2USB = true; // False to disable // WiFi access credentials #define WIFI_SSID "WiFi network name goes here" #define WIFI_PASS "WiFi password goes here" #ifdef UNIX IPAddress udpIPaddress = {192,168,1,186}; // Linux UDP Listener address #else IPAddress udpIPaddress = {192,168,1,67}; // Windows 11 UDP Listener address #endif #define udpPort 22200 // UDP listening port // UDP - Instantiate WiFiUDP Udp; // Message buffers const int UDP_BUFFER_DIM = 256; char udpRxBuffer[UDP_BUFFER_DIM]; // For bidirectional interface // Software serial // https://github.com/plerup/espsoftwareserial/ #define SS_TX 12 #define SS_RX 13 #define SS_BAUD 9600 // Set to the same as computer // Instantiate SoftwareSerial DOS6; // Computer serial interface const int RX_BUFFER_DIM = 256; char serRxBuffer[RX_BUFFER_DIM]; // -> IDP transmit int rxNdx = 0; const byte CR = 0x0D; // CR = Procomm EOL (deprecated Macintosh format) const byte ENF = 0x1A; // For test function pong(); [Symbol EOF is not available] // Time const unsigned long DEBOUNCE = 10; const unsigned long JIFFY = 100; const unsigned long QTRSEC = 250; const unsigned long HALFSEC = 500; const unsigned long ONESEC = 1000; const unsigned long LONG_PRESS = ONESEC; // Minimum button press duration to be considered a long press void setup() { pinMode(PB1, INPUT); pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, HIGH); // Off Serial.begin(BAUD); delay(JIFFY); Serial.println(); // Initialize WiFi WiFi.begin(WIFI_SSID, WIFI_PASS); Serial.print("Connecting to "); Serial.print(WIFI_SSID); // Wait for connection while (WiFi.status() != WL_CONNECTED) { delay(JIFFY); Serial.print("."); } Serial.println(); Serial.print("Connected! IP address: "); Serial.println(WiFi.localIP()); // Initialize software serial (transceiver interface) DOS6.begin(SS_BAUD, SWSERIAL_8N1, SS_RX, SS_TX, false); if (!DOS6) { Serial.println("Software serial initialization failed."); while (true) ; // Do not proceed } Serial.println(F("Software serial initialized.")); Serial.println ("Setup complete"); flashLED(); // Indicate setup() complete (if no Serial) if (DOS2USB) { // Draw dividing line before uploaded text for (int i=0; i<80; i++) Serial.print('-'); Serial.println(); Serial.println(); } } void loop() { // Full duplex serListen(); if (BIDIR) udpListen(); if (btn1Pressed()) pong(); } void serListen() { byte data_byte; while (DOS6.available()) { data_byte = DOS6.read(); if (!DOS2USB) { Serial.print("0x"); Serial.print(data_byte, HEX); Serial.print(" "); } if (rxNdx < RX_BUFFER_DIM) { serRxBuffer[rxNdx++] = data_byte; if (data_byte == CR) { if (!DOS2USB) Serial.println(); uploadData(); } } else { // Buffer full if (!DOS2USB) Serial.println(); uploadData(); serRxBuffer[rxNdx++] = data_byte; } } } void uploadData() { if (DOS2USB) sendUSB(); sendUDP(); } void sendUDP() { Udp.beginPacket(udpIPaddress, udpPort); Udp.write(serRxBuffer); Udp.endPacket(); zeroRxBuffer(); } void zeroRxBuffer() { for (int i=0; i 31) Serial.print(c); } // Do NOT clear receive buffer! } // Debug, etc. void flashLED(int nTimes) { for (int i=0; i 511) return false; while (analogRead(PB1) < 512) delay(DEBOUNCE); return true; } int btn1PressType() { // Distinguishes short versus long press if (analogRead(PB1) > 511) return 0; long startPress = millis(); while (analogRead(PB1) < 512) ; delay(DEBOUNCE); if ((millis() - startPress) < LONG_PRESS) return 1; return 2; } void pong() { // UDP analogy to ping flashLED(); zeroRxBuffer(); for (int n=0; n<4; n++) { // For now, hard code number of repetitions for (rxNdx=0; rxNdx<32; rxNdx++) // And bytes per repetition serRxBuffer[rxNdx] = (byte) (rxNdx % 10 + 48); // 0123456789...01 serRxBuffer[rxNdx] = CR; uploadData(); delay(JIFFY); } serRxBuffer[0] = ENF; serRxBuffer[1] = CR; uploadData(); flashLED(); }