diff --git a/2023-12_ethernet-real-data-rates.md b/2023-12_ethernet-real-data-rates.md new file mode 100644 index 0000000000000000000000000000000000000000..53714379b78ec53771e58fd67a34d64458d16d3d --- /dev/null +++ b/2023-12_ethernet-real-data-rates.md @@ -0,0 +1,29 @@ +## 2023 12 27 + +OK, I'd like to do something similar to [this prior test](https://gitlab.cba.mit.edu/jakeread/teensy-udp) and to the usb-rates in this repo, but using the W5500-EVB-Pico, an RP2040 Pico with a WizNet Ethernet chip bolted onto the end of it. + +For these tests I am interested in maximum data ingest and histograms. + +So let's see, [this](https://goughlui.com/2022/10/23/quick-review-wiznet-w5100s-evb-pico-w5500-evb-pico-development-boards/) notes that we need to do Ethernet.init(17) to set the CS pin properly, but otherwise we can just use the [arduino Ethernet library](https://github.com/arduino-libraries/Ethernet/tree/master/examples) straight up, that's nice. + +To connect, we can also wrap the wiz up in a [websocket](https://github.com/skaarj1989/mWebSockets) - maybe - or just write transmission-loss-catching UDP link layer stuff, TBD. + +There's also, ofc, some [messy earle core stuff](https://arduino-pico.readthedocs.io/en/latest/ethernet.html) - they use a different Ethernet stack, it seems. I'm gunsta try the Arduino library first. + +There is also some confusion about [max frame sizes](https://forum.arduino.cc/t/ethernet-udp-is-limited-to-104-bytes/506441) (make sure to read to the end of that post) which I should just test myself. + +## 2023 12 28 + +OK, this is looking alive-ish? I should see about getting a UDP ping with Python and then I can record the setup / etc. + +- SET Ethernet Interface (in laptop OS) to use fixed IP, + - i.e. I am using 192.168.1.178 +- SET the same to use Subnet Mask 255.255.255.0 +- Assign Static IP in Arduino to i.e. 192.168.1.177 + +OK, now I can ping a message down and up, god bless... speed testy time. + +### Polling Speed Test + +AFAIK, UDP can source and sink packets at either end of the pipe - it's just a straight IP datagram. It seems like the normal pattern is to use it "transactionally" - i.e. send-req-get-res, and I will need to bootstrap delivery guarantees, etc. I suspect that I will ultimately want TCP here to get those tasty delivery guarantees etc. + diff --git a/code/ethernet/ethernet_sink/sink.py b/code/ethernet/ethernet_sink/sink.py new file mode 100644 index 0000000000000000000000000000000000000000..ca1db1f22a39813ddbbca473e1308b8cdb1ee4b9 --- /dev/null +++ b/code/ethernet/ethernet_sink/sink.py @@ -0,0 +1,17 @@ +import socket + +# Arduino's network settings +arduino_ip = '192.168.1.177' +arduino_port = 8888 + +# Create a UDP socket +sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + +# Send a message +message = b'Hello, Arduino!' +sock.sendto(message, (arduino_ip, arduino_port)) +print(f'Transmitted...') + +# Receive response +data, addr = sock.recvfrom(1024) +print(f'Received message: {data}') diff --git a/code/ethernet/ethernet_source/ethernet_source.ino b/code/ethernet/ethernet_source/ethernet_source.ino new file mode 100644 index 0000000000000000000000000000000000000000..252b1e80cc9b89ed351ea1fbe41115d9c924eac1 --- /dev/null +++ b/code/ethernet/ethernet_source/ethernet_source.ino @@ -0,0 +1,168 @@ +/* + DHCP-based IP printer + + This sketch uses the DHCP extensions to the Ethernet library + to get an IP address via DHCP and print the address obtained. + using an Arduino WIZnet Ethernet shield. + + Circuit: + Ethernet shield attached to pins 10, 11, 12, 13 + + created 12 April 2011 + modified 9 Apr 2012 + by Tom Igoe + modified 02 Sept 2015 + by Arturo Guadalupi + + */ + +// https://github.com/arduino-libraries/Ethernet/blob/master/examples/DhcpAddressPrinter/DhcpAddressPrinter.ino +// https://github.com/arduino-libraries/Ethernet/blob/master/examples/UDPSendReceiveString/UDPSendReceiveString.ino + +#include <SPI.h> +#include <Ethernet.h> +#include <Adafruit_GFX.h> +#include <Adafruit_SSD1306.h> +#include <Wire.h> + +#define DEBUG_PIN 4 + +#define SCREEN_WIDTH 128 // OLED display width, in pixels +#define SCREEN_HEIGHT 64 // OLED display height, in pixels + +#define X_POS 0 +#define Y_POS 0 +#define TXT_SIZE 1 + +// even for displays with i.e. "0x78" printed on the back, +// the address that works is 0x3C, IDK +#define SCREEN_ADDRESS 0x3C + +Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire1); + +// warning: is blocking, takes ~ 33ms ! +void display_print(String msg){ + display.clearDisplay(); + display.setCursor(X_POS, Y_POS); + display.print(msg); + display.display(); +} + +// AFAIK we can just make this up for the time being, +// but should maybe accomodate proper MAC using a MAC IC or sth sth +byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; + +IPAddress ip(192, 168, 1, 177); +unsigned int localPort = 8888; + +char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; // is 24, we should test sizes, should go up to nearly 1500 per frame ! +char replyBuffer[] = "ack!"; + +EthernetUDP EUDP; + +void setup() { + // want that LED, + pinMode(LED_BUILTIN, OUTPUT); + digitalWrite(LED_BUILTIN, HIGH); + + // a scope debug out + pinMode(DEBUG_PIN, OUTPUT); + digitalWrite(DEBUG_PIN, LOW); + + // confirm our I2C pins are here ? + Wire1.setSDA(2); + Wire1.setSCL(3); + + // initialize the screen, + // oddly, SWITCHCAPVCC is the option that works even though OLED is hooked to 5V + display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS); + display.clearDisplay(); + display.display(); + display.setTextColor(SSD1306_WHITE); + display.setTextSize(TXT_SIZE); + display.setTextWrap(true); + display.dim(false); + display_print("bonjour..."); + + // You can use Ethernet.init(pin) to configure the CS pin + Ethernet.init(17); + display_print("ethernet beginning..."); + + // start the Ethernet connection: + Ethernet.begin(mac, ip); + + // and the udp link + EUDP.begin(localPort); +} + +uint32_t lastUpdate = 0; +uint32_t updateInterval = 500; + +uint32_t rxCount = 0; + +void loop() { + size_t len = EUDP.parsePacket(); + if(len){ + rxCount ++; + display_print("rx " + String(len)); + EUDP.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE); + } + + // report status + // TODO: use only one line of the disp for this, + // keep a string-thing somewhere, just update sections of it ? + // i.e. display.println(str1), /// etc... + if(lastUpdate + updateInterval < millis()){ + digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); + lastUpdate = millis(); + // write again, + digitalWrite(DEBUG_PIN, HIGH); + // display_print("STAMP: " + String(lastUpdate)); + if (Ethernet.hardwareStatus() == EthernetNoHardware) { + display_print("Ethernet shield was not found."); + } else if (Ethernet.linkStatus() == LinkOFF) { + display_print("Link OFF"); + } else if (Ethernet.linkStatus() == LinkON){ + display_print("ON: " + String(rxCount) + " " + (Ethernet.localIP().toString())); + } else if (Ethernet.linkStatus() == Unknown){ + display_print("Link UNKNOWN"); + } + digitalWrite(DEBUG_PIN, LOW); + } + + // maintain is required to renew DHCP leases, but we are static-ip'ing this mf'er I think + // see docs: https://www.arduino.cc/reference/en/libraries/ethernet/ethernet.maintain/ + // switch (Ethernet.maintain()) { + // case 1: + // //renewed fail + // display_print("Error: renewed fail"); + // break; + // case 2: + // //renewed success + // display_print("Renew, IP: " + Ethernet.localIP()); + // break; + // case 3: + // //rebind fail + // display_print("Error: rebind fail"); + // break; + // case 4: + // //rebind success + // //print your local IP address: + // display_print("Rebind, IP: " + Ethernet.localIP()); + // break; + + // default: + // //nothing happened + // break; + // } +} + +// TODO: run the display from the second core, since +// `Wire` uses blocking writes, for when we +// are going hardo-perf-mode, + +// void setup1(){ +// } + +// void loop1(){ +// } \ No newline at end of file diff --git a/code/serial_multi_sink_asyncio/cobs_usb_serial_async.py b/code/usb_serial/serial_multi_sink_asyncio/cobs_usb_serial_async.py similarity index 100% rename from code/serial_multi_sink_asyncio/cobs_usb_serial_async.py rename to code/usb_serial/serial_multi_sink_asyncio/cobs_usb_serial_async.py diff --git a/code/serial_multi_sink_asyncio/multi_sink_asyncio.py b/code/usb_serial/serial_multi_sink_asyncio/multi_sink_asyncio.py similarity index 100% rename from code/serial_multi_sink_asyncio/multi_sink_asyncio.py rename to code/usb_serial/serial_multi_sink_asyncio/multi_sink_asyncio.py diff --git a/code/serial_multi_sink_asyncio/multi_sink_blocking.py b/code/usb_serial/serial_multi_sink_asyncio/multi_sink_blocking.py similarity index 100% rename from code/serial_multi_sink_asyncio/multi_sink_blocking.py rename to code/usb_serial/serial_multi_sink_asyncio/multi_sink_blocking.py diff --git a/code/serial_multi_sink_asyncio/serial_list.py b/code/usb_serial/serial_multi_sink_asyncio/serial_list.py similarity index 100% rename from code/serial_multi_sink_asyncio/serial_list.py rename to code/usb_serial/serial_multi_sink_asyncio/serial_list.py diff --git a/code/serial_multi_sink_blocking/cobs_usb_serial.py b/code/usb_serial/serial_multi_sink_blocking/cobs_usb_serial.py similarity index 100% rename from code/serial_multi_sink_blocking/cobs_usb_serial.py rename to code/usb_serial/serial_multi_sink_blocking/cobs_usb_serial.py diff --git a/code/serial_multi_sink_blocking/multi_sink_blocking.py b/code/usb_serial/serial_multi_sink_blocking/multi_sink_blocking.py similarity index 100% rename from code/serial_multi_sink_blocking/multi_sink_blocking.py rename to code/usb_serial/serial_multi_sink_blocking/multi_sink_blocking.py diff --git a/code/serial_multi_sink_blocking/serial_list.py b/code/usb_serial/serial_multi_sink_blocking/serial_list.py similarity index 100% rename from code/serial_multi_sink_blocking/serial_list.py rename to code/usb_serial/serial_multi_sink_blocking/serial_list.py diff --git a/code/serial_multi_sink_multiprocessing/cobs_usb_serial_multi.py b/code/usb_serial/serial_multi_sink_multiprocessing/cobs_usb_serial_multi.py similarity index 100% rename from code/serial_multi_sink_multiprocessing/cobs_usb_serial_multi.py rename to code/usb_serial/serial_multi_sink_multiprocessing/cobs_usb_serial_multi.py diff --git a/code/serial_multi_sink_multiprocessing/multi_sink_multiprocessing.py b/code/usb_serial/serial_multi_sink_multiprocessing/multi_sink_multiprocessing.py similarity index 100% rename from code/serial_multi_sink_multiprocessing/multi_sink_multiprocessing.py rename to code/usb_serial/serial_multi_sink_multiprocessing/multi_sink_multiprocessing.py diff --git a/code/serial_multi_sink_multiprocessing/plot_stamps.py b/code/usb_serial/serial_multi_sink_multiprocessing/plot_stamps.py similarity index 100% rename from code/serial_multi_sink_multiprocessing/plot_stamps.py rename to code/usb_serial/serial_multi_sink_multiprocessing/plot_stamps.py diff --git a/code/serial_multi_sink_multiprocessing/serial_list.py b/code/usb_serial/serial_multi_sink_multiprocessing/serial_list.py similarity index 100% rename from code/serial_multi_sink_multiprocessing/serial_list.py rename to code/usb_serial/serial_multi_sink_multiprocessing/serial_list.py diff --git a/code/serial_sink/cobs_usb_serial.py b/code/usb_serial/serial_sink/cobs_usb_serial.py similarity index 100% rename from code/serial_sink/cobs_usb_serial.py rename to code/usb_serial/serial_sink/cobs_usb_serial.py diff --git a/code/serial_sink/serial_list.py b/code/usb_serial/serial_sink/serial_list.py similarity index 100% rename from code/serial_sink/serial_list.py rename to code/usb_serial/serial_sink/serial_list.py diff --git a/code/serial_sink/sink.py b/code/usb_serial/serial_sink/sink.py similarity index 100% rename from code/serial_sink/sink.py rename to code/usb_serial/serial_sink/sink.py diff --git a/code/serial_sink_simple/serial_list.py b/code/usb_serial/serial_sink_simple/serial_list.py similarity index 100% rename from code/serial_sink_simple/serial_list.py rename to code/usb_serial/serial_sink_simple/serial_list.py diff --git a/code/serial_sink_simple/sink_simple.py b/code/usb_serial/serial_sink_simple/sink_simple.py similarity index 100% rename from code/serial_sink_simple/sink_simple.py rename to code/usb_serial/serial_sink_simple/sink_simple.py diff --git a/code/serial_source/COBSUSBSerial.cpp b/code/usb_serial/serial_source/COBSUSBSerial.cpp similarity index 100% rename from code/serial_source/COBSUSBSerial.cpp rename to code/usb_serial/serial_source/COBSUSBSerial.cpp diff --git a/code/serial_source/COBSUSBSerial.h b/code/usb_serial/serial_source/COBSUSBSerial.h similarity index 100% rename from code/serial_source/COBSUSBSerial.h rename to code/usb_serial/serial_source/COBSUSBSerial.h diff --git a/code/serial_source/cobs.cpp b/code/usb_serial/serial_source/cobs.cpp similarity index 100% rename from code/serial_source/cobs.cpp rename to code/usb_serial/serial_source/cobs.cpp diff --git a/code/serial_source/cobs.h b/code/usb_serial/serial_source/cobs.h similarity index 100% rename from code/serial_source/cobs.h rename to code/usb_serial/serial_source/cobs.h diff --git a/code/serial_source/serial_source.ino b/code/usb_serial/serial_source/serial_source.ino similarity index 100% rename from code/serial_source/serial_source.ino rename to code/usb_serial/serial_source/serial_source.ino diff --git a/code/serial_source_simple/serial_source_simple.ino b/code/usb_serial/serial_source_simple/serial_source_simple.ino similarity index 100% rename from code/serial_source_simple/serial_source_simple.ino rename to code/usb_serial/serial_source_simple/serial_source_simple.ino