diff --git a/2023-12_ethernet-real-data-rates.md b/2023-12_ethernet-real-data-rates.md index 4263e4168db248ce83a8dcba5686bac2bbb321a1..dda243c2750aefbbbde0727f4004476061c214c3 100644 --- a/2023-12_ethernet-real-data-rates.md +++ b/2023-12_ethernet-real-data-rates.md @@ -73,4 +73,82 @@ So, for quicksies, and to settle this current debate, I should try not-pinging w ### Non-Pining Speed Tests - setup Arduino to, after one packet rx (to get an IP to tx-back-to) just free-form wrips packets up north, and occasionally prints rates to the OLED -- setup an async (?) version of the python inheritor, and collect them data \ No newline at end of file +- setup an async (?) version of the python inheritor, and collect them data + +So... this does improve the rate substantially: + + + +I think actually these are blocking calls, so flow-control down below is as simple as running the thing over-and-over: + +```cpp +void loop() { + // just tx, forever, see if we break flowcontrol + digitalWrite(DEBUG_PIN, HIGH); + EUDP.beginPacket(txIP, txPort); + EUDP.write(replyBuffer, 64); + EUDP.endPacket(); + txCount ++; + digitalWrite(DEBUG_PIN, LOW); +} +``` + +Then I am rx'ing that in a python asyncio structure... + +```python +import socket, time, asyncio +from plot_stamps import plot_stamps +import numpy as np + + +# 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) + + +# bind the socket to our local addr and port, +# 0.0.0.0 is a mask: listens on all interfaces (?) +sock.bind(('0.0.0.0', 8888)) + + +# test stats +stamp_count = 10000 +stamps = np.zeros(stamp_count) +stamp_counter = 0 +pck_len = 64 + + +# ingest packets to test app +def handle_pck(data): + global stamps, stamp_counter, pck_len + if (stamp_counter >= stamp_count): + return + stamps[stamp_counter] = time.perf_counter() * 1e6 + stamp_counter += 1 + if (stamp_counter >= stamp_count): + plot_stamps(stamps, stamp_count, pck_len) + + +# let's setup an async receiver: +async def receiver(socket, handler): + while True: + data = socket.recv(1024) + handler(data) + await asyncio.sleep(0) + +async def main(): + + task = asyncio.create_task(receiver(sock, handle_pck)) + + await asyncio.gather(task) + +asyncio.run(main()) +``` + +But the take-away is that... we can probably do this (this being getting-past 5MBit/sec) if we take our wiznet code seriously and crank the SPI rates. + +However, I would like also to test my suspicion about the raspberry-pi-spi uplink into some python code... I might take an aside down that path, before returning here to see about crikety crankity-ing the SPI rates in a copy-pasta'd ethernet library implementation. \ No newline at end of file diff --git a/code/ethernet/ethernet_sink/plot_stamps.py b/code/ethernet/ethernet_sink/plot_stamps.py index b9c0df777e511bb6bc7889ae45570ee32c482e47..805d3d03592b2bb2e34fdd10a64864a8528d8581 100644 --- a/code/ethernet/ethernet_sink/plot_stamps.py +++ b/code/ethernet/ethernet_sink/plot_stamps.py @@ -17,7 +17,7 @@ def plot_stamps(stamps, stamp_count, pck_len): # Plotting fig, ax1 = plt.subplots(figsize=(11, 3)) - ax1.set_xlim([50, 4000]) + ax1.set_xlim([50, 2000]) # Primary x-axis (time deltas) df['deltas'].plot(kind='hist', bins=50, ax=ax1) diff --git a/code/ethernet/ethernet_sink/sink.py b/code/ethernet/ethernet_sink/sink.py index b3c0278940fea106a0175dc3e5209567412cee13..73da5c1ce7b1413430a68790a8eb9c11d124b8ce 100644 --- a/code/ethernet/ethernet_sink/sink.py +++ b/code/ethernet/ethernet_sink/sink.py @@ -1,7 +1,6 @@ -import socket, time +import socket, time, asyncio from plot_stamps import plot_stamps import numpy as np -import pandas as pd # Arduino's network settings @@ -13,28 +12,60 @@ arduino_port = 8888 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) +# bind the socket to our local addr and port, +# 0.0.0.0 is a mask: listens on all interfaces (?) +sock.bind(('0.0.0.0', 8888)) + + # test stats -stamp_count = 100000 +stamp_count = 10000 stamps = np.zeros(stamp_count) +stamp_counter = 0 +pck_len = 64 + + +def handle_pck(data): + global stamps, stamp_counter, pck_len + if (stamp_counter >= stamp_count): + return + stamps[stamp_counter] = time.perf_counter() * 1e6 + stamp_counter += 1 + if (stamp_counter >= stamp_count): + plot_stamps(stamps, stamp_count, pck_len) + + +# let's setup an async receiver: +async def receiver(socket, handler): + while True: + data = socket.recv(1024) + handler(data) + await asyncio.sleep(0) + +async def main(): + + task = asyncio.create_task(receiver(sock, handle_pck)) + + await asyncio.gather(task) + +asyncio.run(main()) # test data -pck_len = 64 -out_pck = bytearray(pck_len) +# out_pck = bytearray(pck_len) -for i in range(stamp_count): - # Send a message - # message = b'Hello, Arduino!' - sock.sendto(out_pck, (arduino_ip, arduino_port)) - # print(f'Transmitted...') +# for i in range(stamp_count): +# # Send a message +# # message = b'Hello, Arduino!' +# sock.sendto(out_pck, (arduino_ip, arduino_port)) +# # print(f'Transmitted...') - # Receive response - data, addr = sock.recvfrom(1024) - # print(f'Received message: {data}') +# # Receive response +# data, addr = sock.recvfrom(1024) +# # print(f'Received message: {data}') - stamps[i] = time.perf_counter() * 1e6 +# stamps[i] = time.perf_counter() * 1e6 -print('stamps', stamps) +# print('stamps', stamps) -plot_stamps(stamps, stamp_count, pck_len) \ No newline at end of file +# plot_stamps(stamps, stamp_count, pck_len) \ No newline at end of file diff --git a/code/ethernet/ethernet_source/ethernet_source.ino b/code/ethernet/ethernet_source/ethernet_source.ino index 4ecb8159c8f0cc8145d9288774c2a48d10bfc5fa..f5586f08279558ffca4de273d2b8b91f8ee61281 100644 --- a/code/ethernet/ethernet_source/ethernet_source.ino +++ b/code/ethernet/ethernet_source/ethernet_source.ino @@ -99,21 +99,33 @@ uint32_t lastUpdate = 0; uint32_t updateInterval = 500; uint32_t rxCount = 0; +uint32_t txCount = 0; + +IPAddress txIP(192, 168, 1, 178); +uint32_t txPort = 8888; void loop() { - size_t len = EUDP.parsePacket(); - if(len){ - digitalWrite(DEBUG_PIN, HIGH); - // get the pck, - rxCount ++; - // display_print("rx " + String(len)); - EUDP.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE); - // reply to the pck, - EUDP.beginPacket(EUDP.remoteIP(), EUDP.remotePort()); - EUDP.write(replyBuffer, len); - EUDP.endPacket(); - digitalWrite(DEBUG_PIN, LOW); - } + // just tx, forever, see if we break flowcontrol + digitalWrite(DEBUG_PIN, HIGH); + EUDP.beginPacket(txIP, txPort); + EUDP.write(replyBuffer, 64); + EUDP.endPacket(); + txCount ++; + digitalWrite(DEBUG_PIN, LOW); + + // size_t len = EUDP.parsePacket(); + // if(len){ + // digitalWrite(DEBUG_PIN, HIGH); + // // get the pck, + // rxCount ++; + // // display_print("rx " + String(len)); + // EUDP.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE); + // // reply to the pck, + // EUDP.beginPacket(EUDP.remoteIP(), EUDP.remotePort()); + // EUDP.write(replyBuffer, len); + // EUDP.endPacket(); + // digitalWrite(DEBUG_PIN, LOW); + // } // report status // TODO: use only one line of the disp for this, @@ -128,7 +140,7 @@ void loop() { } else if (Ethernet.linkStatus() == LinkOFF) { display_print("Link OFF"); } else if (Ethernet.linkStatus() == LinkON){ - display_print("ON: " + (Ethernet.localIP().toString()) + "\n" + String(rxCount)); + display_print("ON: " + (Ethernet.localIP().toString()) + "\n" + String(rxCount) + "\nTX: " + String(txCount)); } else if (Ethernet.linkStatus() == Unknown){ display_print("Link UNKNOWN"); } diff --git a/images/2023-12-28_eth-oneway-64.png b/images/2023-12-28_eth-oneway-64.png new file mode 100644 index 0000000000000000000000000000000000000000..4ffdd3f42582c989c0ab3e5c28a825ed0ea62a2f Binary files /dev/null and b/images/2023-12-28_eth-oneway-64.png differ