ARTE
BELLEZZA E BENESSERE
MESTIERE
CULTURA E STORIA
DIVERTIMENTO
AMBIENTE
CIBO E BEVANDE
INGEGNERIA INVERSA
SCIENZE
SPORT
TECNOLOGIA
INDOSSABILI
Ethernet and CSMA/CD
Ed

Creato da

Ed

30. agosto 2026FI
21
0
0
0
0

Ethernet and CSMA/CD

Robert Metcalfe read Abramson's ALOHA papers, saw that eighteen percent was a poor return, and noticed the one thing a radio terminal in Hawaii could not do that a machine on a cable could: LISTEN. His memo at Xerox PARC in May 1973, written with David Boggs, describes a network where every station is attached to the same coaxial cable and must wait until the cable is quiet before speaking. That is carrier sense, and it converts collisions from the normal case to the rare one. There is still a window — two stations that both find the cable quiet in the same instant will still collide — so Ethernet adds the second half: keep listening WHILE transmitting, and the moment you hear something that is not what you sent, stop immediately, send a brief jam so everyone agrees, and back off. A collision now costs a fraction of a frame rather than a whole one. The backoff is binary exponential: after the nth collision, wait a random number of slot times between zero and two-to-the-n minus one. It is the only rule that reduces the retry rate as fast as the load rises, which the previous blueprint measures. Everything else in the standard falls out of one calculation. A station must still be transmitting when the worst-case collision reaches it, so the minimum frame is set by the round-trip time of the longest legal cable. At ten megabits over two and a half kilometres that comes to 512 bit times, which is sixty-four bytes — and that is why a short Ethernet frame is padded. The pad exists so the speed of light does not outrun the transmitter. USE THE RIG FROM THE PREVIOUS BLUEPRINT, UNCHANGED. Add carrier sense, measure it. Add collision detection, measure again. Eighteen percent, thirty-seven percent, and then above eighty-five.
Avanzato
4 hours

Istruzioni

1

Add carrier sense to the ALOHA rig

Take the four-station rig from blueprint 7 exactly as it is and change ONE thing in the firmware: before transmitting, read the shared line and wait until it is idle. Re-run the same load sweep and plot it on the same axes as before. Throughput climbs from the high thirties into the fifties, and it no longer collapses when you push hard — it flattens. That single `while (channelBusy()) ;` is the difference between a shared radio channel and a local network. Nothing else changed: same hardware, same frames, same backoff. Then look at what remains on the scope. Collisions still happen, and they happen only when two stations find the line idle within one propagation time of each other. The window did not close, it shrank to the size of the wire.

Strumenti necessari:

ESP32 Development BoardESP32 Development Board
Digital OscilloscopeDigital Oscilloscope
Desktop ComputerDesktop Computer
2

Add collision detection, and see the jam

Now add the second half. While transmitting, keep reading the line back. If what you read differs from what you are driving, another station is on the cable — abort immediately, drive a short jam pattern so every station agrees a collision occurred, then back off. Put the scope on the shared line, trigger on a collision, and look at it. You will see two overlapping frames, then both stations abandoning them, then the jam, then silence for two different random intervals. That picture is worth more than the throughput number. Re-run the sweep. Utilisation climbs again, and the gain comes entirely from wasted TIME rather than wasted attempts — the collisions are no more numerous, they are just far shorter. Finally, deliberately break the rule that makes it work: make one station's frames very short, shorter than the round trip across your wire. It will finish transmitting before a collision can reach it, declare success, and lose data silently. That is exactly the failure the 64-byte minimum exists to prevent.

Strumenti necessari:

ESP32 Development BoardESP32 Development Board
Digital OscilloscopeDigital Oscilloscope
Desktop ComputerDesktop Computer
3

The same sketch, two lines later

The identical file from blueprint 7. Change MODE to MODE_CSMA and re-run the sweep: the only functional difference is `while (!busIdle()) ;` before transmitting. Then set MODE_CSMA_CD. Now the transmitter reads the bus back mid-bit and, if what it hears differs from what it is driving, jams and aborts immediately instead of finishing a frame that is already destroyed. Plot all four curves on one set of axes. The step from blind to slotted is a shared clock; the step to CSMA is one line; the step to CSMA/CD is one comparison inside the bit loop. Three small changes, and the channel goes from eighteen percent to most of the wire.
shared_medium.inocpp
// ONE sketch, four protocols. This is the rig for blueprints 7 and 8, and the point is
// that ONLY the MODE constant changes between them -- same hardware, same frames, same
// backoff, so the throughput differences are the protocols and nothing else.
//
//   MODE_ALOHA_PURE     transmit whenever ready.                    expect ~18 %
//   MODE_ALOHA_SLOTTED  transmit only on a slot boundary.           expect ~37 %
//   MODE_CSMA           wait for the channel to go idle first.      expect much more
//   MODE_CSMA_CD        also listen WHILE sending, and abort.       expect more again
//
// Wiring: every station drives SHARED open-drain (output LOW, or input to release) with
// a single 4k7 pull-up on the whole bus. Anyone may pull it low; nobody can force it
// high. That is what makes two simultaneous transmitters produce garbage.
//   GPIO4  = SHARED bus       GPIO5 = slot clock in (slotted modes)
//   Set STATION to 0,1,2,3 on the four boards.

#define MODE_ALOHA_PURE     0
#define MODE_ALOHA_SLOTTED  1
#define MODE_CSMA           2
#define MODE_CSMA_CD        3

const int MODE    = MODE_ALOHA_PURE;   // <-- the only line that changes
const int STATION = 0;                 // <-- 0..3, different on each board

const int PIN_BUS  = 4;
const int PIN_SLOT = 5;

const unsigned BIT_US    = 200;        // one bit time
const int      FRAME_BITS = 40;        // 5 bytes
const unsigned SLOT_US   = BIT_US * FRAME_BITS;

inline void busDrive(int level) {
  if (level) pinMode(PIN_BUS, INPUT);          // release: the pull-up takes it high
  else       { pinMode(PIN_BUS, OUTPUT); digitalWrite(PIN_BUS, LOW); }
}
inline int busRead() { return digitalRead(PIN_BUS); }
inline bool busIdle() { pinMode(PIN_BUS, INPUT); return digitalRead(PIN_BUS) == HIGH; }

unsigned long sent = 0, delivered = 0, collisions = 0;

// Send one frame. Returns false if CSMA/CD detected a collision and aborted.
bool sendFrame(uint8_t *frame, int n) {
  for (int i = 0; i < n; i++) {
    for (int b = 7; b >= 0; b--) {
      int bit = (frame[i] >> b) & 1;
      busDrive(bit);
      delayMicroseconds(BIT_US / 2);
      if (MODE == MODE_CSMA_CD && busRead() != bit) {
        // What we hear is not what we are driving: somebody else is on the bus.
        busDrive(0);                              // JAM, so everyone agrees
        delayMicroseconds(BIT_US * 4);
        busDrive(1);
        collisions++;
        return false;                             // abort NOW, not at the end of the frame
      }
      delayMicroseconds(BIT_US / 2);
    }
  }
  busDrive(1);
  return true;
}

void waitSlot() {
  while (digitalRead(PIN_SLOT) == LOW)  ;
  while (digitalRead(PIN_SLOT) == HIGH) ;         // falling edge = slot boundary
}

void setup() {
  Serial.begin(115200);
  delay(300);
  pinMode(PIN_BUS, INPUT);
  pinMode(PIN_SLOT, INPUT_PULLUP);
  randomSeed(STATION * 7919 + micros());
  Serial.printf("# station %d, mode %d\n", STATION, MODE);
  Serial.println("# offered,delivered,collisions  -- sweep OFFER_PCT and plot the pair");
}

const int OFFER_PCT = 30;              // <-- sweep this from 5 to 100 and record each point

void loop() {
  static int tries = 0;
  if ((int)random(100) >= OFFER_PCT) { delayMicroseconds(SLOT_US); return; }

  uint8_t frame[5] = {0xAA, (uint8_t)STATION, (uint8_t)(sent & 0xFF), 0x00, 0x00};

  if (MODE >= MODE_CSMA)
    while (!busIdle()) ;                          // CARRIER SENSE: the one added line

  if (MODE == MODE_ALOHA_SLOTTED) waitSlot();

  sent++;
  bool ok = sendFrame(frame, 5);

  // Success is judged by the monitor station pulling the bus low as an acknowledgement
  // within one slot. No acknowledgement means the frame was destroyed.
  if (ok) {
    unsigned long t0 = micros();
    bool ack = false;
    while (micros() - t0 < SLOT_US) if (busRead() == LOW) { ack = true; break; }
    if (ack) { delivered++; tries = 0; }
    else     { collisions++; ok = false; }
  }

  if (!ok) {                                       // BINARY EXPONENTIAL BACKOFF
    tries++;
    unsigned long slots = random(0, 1L << (tries > 10 ? 10 : tries));
    delayMicroseconds(SLOT_US * slots);
  }

  if (sent % 200 == 0)
    Serial.printf("%lu,%lu,%lu\n", sent, delivered, collisions);
}

Materiali per questo passaggio:

Resistor KitResistor Kit1 pezzo
Jumper Wire SetJumper Wire Set1 pezzo

Strumenti necessari:

ESP32 Development BoardESP32 Development Board
Breadboard - ClassicBreadboard - Classic
Digital OscilloscopeDigital Oscilloscope
Desktop ComputerDesktop Computer
4

Where 64 bytes comes from, and what listening buys

Caricamento del notebook Jupyter…

Strumenti necessari:

Desktop ComputerDesktop Computer
5

Compendium: the frame, and why the standard outlived the cable

THE FRAME, FIELD BY FIELD, AND WHY EACH EXISTS. A 7-byte preamble of alternating bits lets the receiver's clock recovery lock on — this is blueprint 1's problem solved the other way, with one long synchronisation per frame instead of two bits per byte, which is far cheaper on 1500 bytes and impossible without a crystal. Then a start-of-frame delimiter whose last two bits break the pattern, so the byte boundary is unambiguous. Six bytes of destination and six of source, globally unique because the top half is assigned to the manufacturer. A type field, so one cable can carry several unrelated protocols at once — which is precisely what let IP arrive later without changing anything. And a 32-bit CRC, blueprint 2, catching every burst under 32 bits. THE SIBLING, MEASURED, on the same rig. Pure ALOHA 18.4 %: cannot sense the channel at all. Slotted 36.8 %: a shared clock. CSMA above 80 %: can sense before speaking. CSMA/CD above 90 %: can sense while speaking. Every step costs a stronger physical assumption, and the last one is why WiFi cannot do it — a radio is deafened by its own transmitter, so 802.11 uses collision AVOIDANCE and a request-to-send handshake instead. The cable earned its throughput by being a medium you can listen to. WHAT KILLED IT AND WHY IT DOES NOT MATTER. Nobody has shared an Ethernet cable in decades: every station has its own switched full-duplex port and CSMA/CD is dead code in the standard. What survived is the FRAME — preamble, addresses, type, CRC — unchanged from 1980 and carried today over twisted pair, fibre and radio at a hundred thousand times the original rate. The access method was the clever part and the frame format was the durable one.

Materiali

2

Strumenti richiesti

4

CC0 Pubblico dominio

Questo progetto è rilasciato sotto CC0. Sei libero di copiare, modificare, distribuire e utilizzare quest'opera per qualsiasi scopo, senza chiedere permesso.

Supporta il Maker acquistando prodotti tramite il suo progetto dove guadagna una Commissione Maker stabilita dai venditori, oppure crea una nuova iterazione di questo progetto e includilo come collegamento nel tuo progetto per condividere i ricavi.

Commenti

(0)

Accedi per partecipare alla discussione

Caricamento commenti...