### Identify Packet with SerialTransfer::currentPacketID() Source: https://context7.com/powerbroker2/serialtransfer/llms.txt Use currentPacketID() to get the ID of the most recently parsed packet when polling directly. This allows for conditional handling of different packet types. Ensure available() is called before checking the packet ID. ```cpp #include "SerialTransfer.h" SerialTransfer myTransfer; char fileName[16]; char fileChunk[252]; void setup() { Serial.begin(115200); Serial1.begin(115200); myTransfer.begin(Serial1); } void loop() { if (myTransfer.available()) { switch (myTransfer.currentPacketID()) { case 0: // filename packet myTransfer.rxObj(fileName); Serial.print("Receiving file: "); Serial.println(fileName); break; case 1: // data chunk packet for (uint8_t i = 2; i < myTransfer.bytesRead; i++) Serial.print((char)myTransfer.packet.rxBuff[i]); break; default: Serial.println("Unknown packet ID"); break; } } } ``` -------------------------------- ### SerialTransfer::begin() Source: https://context7.com/powerbroker2/serialtransfer/llms.txt Initializes the SerialTransfer instance, attaching it to a hardware or software serial port. It supports both simple and advanced configurations, including optional debugging and custom timeout settings. ```APIDOC ## SerialTransfer::begin() ### Description Attaches the `SerialTransfer` instance to a hardware or software `Stream` port. The simple overload accepts optional debug and timeout parameters; the advanced overload takes a `configST` struct for callbacks and fine-grained configuration. ### Method `SerialTransfer::begin(Stream &port, configST config = configST())` ### Parameters #### Path Parameters - **port** (Stream&) - The hardware or software serial port to attach to. - **config** (configST, optional) - A struct for advanced configuration options like debug, timeout, and callbacks. ### Request Example ```cpp #include "SerialTransfer.h" SerialTransfer myTransfer; void setup() { Serial.begin(115200); // debug output Serial1.begin(115200); // transfer port // Simple init — debug ON by default, 50 ms timeout myTransfer.begin(Serial1); // Advanced init with configST // configST myConfig; // myConfig.debug = true; // myConfig.debugPort = &Serial; // myConfig.timeout = 100; // ms // myConfig.callbacks = callbackArr; // myConfig.callbacksLen = sizeof(callbackArr) / sizeof(functionPtr); // myTransfer.begin(Serial1, myConfig); } ``` ``` -------------------------------- ### SPI Master and Slave Communication with SPITransfer Source: https://context7.com/powerbroker2/serialtransfer/llms.txt Demonstrates how to set up and use the SPITransfer class for both the master (transmitter) and slave (receiver) sides of an SPI communication link. Ensure SPI is enabled by commenting out `#define DISABLE_SPI_SERIALTRANSFER 1` in `SerialTransfer.h`. ```cpp // ---- SPI Master (transmitter) ---- #include "SPITransfer.h" SPITransfer myTransfer; struct __attribute__((packed)) STRUCT { char z; float y; } testStruct; char arr[] = "hello"; void setup() { digitalWrite(SS, HIGH); SPI.begin(); SPI.setClockDivider(SPI_CLOCK_DIV8); myTransfer.begin(SPI); testStruct.z = '$'; testStruct.y = 4.5; } void loop() { uint16_t sendSize = 0; sendSize = myTransfer.txObj(testStruct, sendSize); sendSize = myTransfer.txObj(arr, sendSize); myTransfer.sendData(sendSize); delay(500); } ``` ```cpp // ---- SPI Slave (receiver) ---- #include "SPITransfer.h" SPITransfer myTransfer; struct __attribute__((packed)) STRUCT { char z; float y; } testStruct; char arr[6]; volatile bool procNewPacket = false; void setup() { SPCR |= bit(SPE); // enable SPI in slave mode pinMode(MISO, OUTPUT); SPI.attachInterrupt(); myTransfer.begin(SPI); } void loop() { if (procNewPacket) { procNewPacket = false; uint16_t recSize = 0; recSize = myTransfer.rxObj(testStruct, recSize); recSize = myTransfer.rxObj(arr, recSize); Serial.print(testStruct.z); Serial.print(testStruct.y); Serial.print(" | "); Serial.println(arr); // Output: $4.50 | hello } } ISR(SPI_STC_vect) { if (myTransfer.available()) procNewPacket = true; } ``` -------------------------------- ### Initialize SerialTransfer with Serial Port Source: https://context7.com/powerbroker2/serialtransfer/llms.txt Initializes the SerialTransfer instance with a hardware or software serial port. The simple overload uses default debug and timeout settings, while the advanced overload allows for custom configuration. ```cpp #include "SerialTransfer.h" SerialTransfer myTransfer; void setup() { Serial.begin(115200); // debug output Serial1.begin(115200); // transfer port // Simple init — debug ON by default, 50 ms timeout myTransfer.begin(Serial1); // Advanced init with configST // configST myConfig; // myConfig.debug = true; // myConfig.debugPort = &Serial; // myConfig.timeout = 100; // ms // myConfig.callbacks = callbackArr; // myConfig.callbacksLen = sizeof(callbackArr) / sizeof(functionPtr); // myTransfer.begin(Serial1, myConfig); } ``` -------------------------------- ### Send Single Object with SerialTransfer::sendDatum() Source: https://context7.com/powerbroker2/serialtransfer/llms.txt Use sendDatum() for payloads consisting of exactly one object. It packs and sends the object in a single step. Ensure SerialTransfer is initialized with the desired serial port. ```cpp #include "SerialTransfer.h" SerialTransfer myTransfer; struct __attribute__((packed)) Command { uint8_t cmdID; int16_t value; } cmd; void setup() { Serial1.begin(115200); myTransfer.begin(Serial1); } void loop() { cmd.cmdID = 0x01; cmd.value = -300; myTransfer.sendDatum(cmd); // packs and sends sizeof(Command) = 3 bytes delay(1000); } ``` -------------------------------- ### Unpack C++ Objects from RX Buffer Source: https://context7.com/powerbroker2/serialtransfer/llms.txt Copies bytes from the receive buffer into C++ objects. The order and size of objects unpacked must exactly match those stuffed using `txObj()` on the sender side. ```cpp #include "SerialTransfer.h" SerialTransfer myTransfer; struct __attribute__((packed)) SensorData { float temperature; float humidity; uint8_t nodeID; } sensorData; char label[5]; void setup() { Serial.begin(115200); Serial1.begin(115200); myTransfer.begin(Serial1); } void loop() { if (myTransfer.available()) { uint16_t recSize = 0; recSize = myTransfer.rxObj(sensorData, recSize); // reads 6 bytes recSize = myTransfer.rxObj(label, recSize); // reads 5 bytes Serial.print("Node "); Serial.print(sensorData.nodeID); Serial.print(" Temp: "); Serial.print(sensorData.temperature); Serial.print(" Hum: "); Serial.print(sensorData.humidity); Serial.print(" Label: "); Serial.println(label); // Output: Node 7 Temp: 23.50 Hum: 61.20 Label: node } } ``` -------------------------------- ### I2C Data Transfer (Receiver) Source: https://context7.com/powerbroker2/serialtransfer/llms.txt This code configures an I2C slave device to receive data using the I2CTransfer library. A callback function is registered to handle incoming data. Ensure the Wire library is included and the I2CTransfer library is initialized with the correct slave address and configuration. ```cpp // ---- I2C Receiver (slave at address 0x08) ---- #include "I2CTransfer.h" I2CTransfer myTransfer; struct __attribute__((packed)) STRUCT { char z; float y; } testStruct; char arr[6]; void onReceive() { uint16_t recSize = 0; recSize = myTransfer.rxObj(testStruct, recSize); recSize = myTransfer.rxObj(arr, recSize); Serial.print(testStruct.z); Serial.print(testStruct.y); Serial.print(" | "); Serial.println(arr); // Output: $4.50 | hello } const functionPtr callbackArr[] = { onReceive }; void setup() { Serial.begin(115200); Wire.begin(0x08); // slave address configST myConfig; myConfig.debug = true; myConfig.callbacks = callbackArr; myConfig.callbacksLen = 1; myTransfer.begin(Wire, myConfig); } void loop() { /* ISR-driven, nothing needed here */ } ``` -------------------------------- ### SPITransfer — SPI interface Source: https://context7.com/powerbroker2/serialtransfer/llms.txt The SPITransfer class provides the same txObj / rxObj / sendData / available API over SPI. It can be enabled by commenting out `#define DISABLE_SPI_SERIALTRANSFER 1` in `SerialTransfer.h`. The slave side uses the `SPI_STC_vect` ISR. ```APIDOC ## SPITransfer ### Description Provides the `txObj`, `rxObj`, `sendData`, and `available` API over SPI, mirroring the functionality of the UART and I2C interfaces. This class is disabled by default and can be enabled by commenting out a specific define in the library's header file. The slave implementation utilizes the `SPI_STC_vect` interrupt service routine. ### Usage **Master (Transmitter) Example:** ```cpp #include "SPITransfer.h" SPITransfer myTransfer; struct __attribute__((packed)) STRUCT { char z; float y; } testStruct; char arr[] = "hello"; void setup() { digitalWrite(SS, HIGH); SPI.begin(); SPI.setClockDivider(SPI_CLOCK_DIV8); myTransfer.begin(SPI); testStruct.z = '$'; testStruct.y = 4.5; } void loop() { uint16_t sendSize = 0; sendSize = myTransfer.txObj(testStruct, sendSize); sendSize = myTransfer.txObj(arr, sendSize); myTransfer.sendData(sendSize); delay(500); } ``` **Slave (Receiver) Example:** ```cpp #include "SPITransfer.h" SPITransfer myTransfer; struct __attribute__((packed)) STRUCT { char z; float y; } testStruct; char arr[6]; volatile bool procNewPacket = false; void setup() { SPCR |= bit(SPE); // enable SPI in slave mode pinMode(MISO, OUTPUT); SPI.attachInterrupt(); myTransfer.begin(SPI); } void loop() { if (procNewPacket) { procNewPacket = false; uint16_t recSize = 0; recSize = myTransfer.rxObj(testStruct, recSize); recSize = myTransfer.rxObj(arr, recSize); Serial.print(testStruct.z); Serial.print(testStruct.y); Serial.print(" | "); Serial.println(arr); // Output: $4.50 | hello } } ISR(SPI_STC_vect) { if (myTransfer.available()) procNewPacket = true; } ``` ``` -------------------------------- ### Resetting SerialTransfer Buffers and State Source: https://context7.com/powerbroker2/serialtransfer/llms.txt Demonstrates the use of `SerialTransfer::reset()` to clear hardware receive buffers, payload buffers, and reset the internal state machine. This is useful for recovering from parse errors or manually restarting the communication. ```cpp #include "SerialTransfer.h" SerialTransfer myTransfer; void setup() { Serial1.begin(115200); myTransfer.begin(Serial1); } void loop() { if (myTransfer.available()) { if (myTransfer.status < 0) { Serial.print("Error code: "); Serial.println(myTransfer.status); myTransfer.reset(); // flush and restart } else { // process packet ... } } } ``` -------------------------------- ### SerialTransfer::reset() Source: https://context7.com/powerbroker2/serialtransfer/llms.txt Flushes all bytes from the hardware receive buffer, zeroes the TX and RX payload buffers, and resets the internal finite state machine to the `find_start_byte` state. This function is called automatically on any parse error but can also be invoked manually. ```APIDOC ## SerialTransfer::reset() ### Description Clears all bytes from the hardware receive buffer, zeroes the TX and RX payload buffers, and resets the internal finite state machine to the `find_start_byte` state. This function is automatically called upon encountering any parse error, but it can also be explicitly called by the user. ### Method Signature `void reset();` ### Usage Example ```cpp #include "SerialTransfer.h" SerialTransfer myTransfer; void setup() { Serial1.begin(115200); myTransfer.begin(Serial1); } void loop() { if (myTransfer.available()) { if (myTransfer.status < 0) { Serial.print("Error code: "); Serial.println(myTransfer.status); myTransfer.reset(); // flush and restart } else { // process packet ... } } } ``` ``` -------------------------------- ### SerialTransfer: File Transfer over UART (Multi-Packet) Source: https://context7.com/powerbroker2/serialtransfer/llms.txt Demonstrates sending and receiving large files over UART by splitting them into multiple packets. Packet ID 0 is used for the filename, and Packet ID 1 is used for data chunks. ```APIDOC ## SerialTransfer ### Description Supports transferring large files (e.g., CSVs, JPEGs) by splitting them across multiple packets using packet IDs to distinguish the filename packet (ID 0) from data chunk packets (ID 1). ### Transmitter Example ```cpp #include "SerialTransfer.h" SerialTransfer myTransfer; const int fileSize = 2000; char file[fileSize] = "...file content here..."; char fileName[] = "data.csv"; void setup() { Serial1.begin(115200); myTransfer.begin(Serial1); } void loop() { myTransfer.sendDatum(fileName); // Send filename as packet ID 0 uint16_t numPackets = fileSize / (MAX_PACKET_SIZE - 2); if (fileSize % MAX_PACKET_SIZE) numPackets++; for (uint16_t i = 0; i < numPackets; i++) { uint8_t dataLen = MAX_PACKET_SIZE - 2; uint16_t fileIndex = i * dataLen; if ((fileIndex + dataLen) > fileSize) dataLen = fileSize - fileIndex; uint8_t sz = myTransfer.txObj(fileIndex); // 2-byte index sz = myTransfer.txObj(file[fileIndex], sz, dataLen); // chunk myTransfer.sendData(sz, 1); // packet ID 1 delay(100); } delay(10000); } ``` ### Receiver Example ```cpp #include "SerialTransfer.h" SerialTransfer myTransfer; const int fileSize = 2000; char file[fileSize]; char fileName[16]; void setup() { Serial.begin(115200); Serial1.begin(115200); myTransfer.begin(Serial1); } void loop() { if (myTransfer.available()) { if (myTransfer.currentPacketID() == 0) { myTransfer.rxObj(fileName); Serial.print("File: "); Serial.println(fileName); } else if (myTransfer.currentPacketID() == 1) { for (uint8_t i = 2; i < myTransfer.bytesRead; i++) Serial.print((char)myTransfer.packet.rxBuff[i]); } } } ``` ``` -------------------------------- ### SerialTransfer::txObj() Source: https://context7.com/powerbroker2/serialtransfer/llms.txt Stuff an object into the TX buffer. This template function copies a specified number of bytes from any C++ object into the internal transmit buffer, returning the next available index for chaining. ```APIDOC ## SerialTransfer::txObj() ### Description Template function that copies `len` bytes of any object (primitive, array, struct) into the internal transmit buffer (`txBuff`) starting at `index`. Returns the next free index so calls can be chained. ### Method `template uint16_t txObj(T &obj, uint16_t index, uint16_t len = sizeof(T))` ### Parameters #### Path Parameters - **obj** (T&) - The object to stuff into the buffer. - **index** (uint16_t) - The starting index in the transmit buffer. - **len** (uint16_t, optional) - The number of bytes to copy from the object. Defaults to the size of the object. ### Request Example ```cpp #include "SerialTransfer.h" SerialTransfer myTransfer; struct __attribute__((packed)) SensorData { float temperature; float humidity; uint8_t nodeID; } sensorData; char label[] = "node"; void setup() { Serial1.begin(115200); myTransfer.begin(Serial1); sensorData.temperature = 23.5; sensorData.humidity = 61.2; sensorData.nodeID = 7; } void loop() { uint16_t sendSize = 0; sendSize = myTransfer.txObj(sensorData, sendSize); // writes 6 bytes, returns 6 sendSize = myTransfer.txObj(label, sendSize); // writes 5 bytes, returns 11 myTransfer.sendData(sendSize); // transmit 11-byte payload delay(500); } ``` ``` -------------------------------- ### SerialTransfer::rxObj() Source: https://context7.com/powerbroker2/serialtransfer/llms.txt Unpack an object from the RX buffer. This template function copies bytes from the internal receive buffer into a specified object, mirroring the order used by `txObj()`. ```APIDOC ## SerialTransfer::rxObj() ### Description Template function that copies `len` bytes from the internal receive buffer (`rxBuff`) starting at `index` into any object. Mirror of `txObj()`; the index parameter must match the order objects were stuffed on the sender. ### Method `template uint16_t rxObj(T &obj, uint16_t index, uint16_t len = sizeof(T))` ### Parameters #### Path Parameters - **obj** (T&) - The object to unpack data into. - **index** (uint16_t) - The starting index in the receive buffer. - **len** (uint16_t, optional) - The number of bytes to copy into the object. Defaults to the size of the object. ### Request Example ```cpp #include "SerialTransfer.h" SerialTransfer myTransfer; struct __attribute__((packed)) SensorData { float temperature; float humidity; uint8_t nodeID; } sensorData; char label[5]; void setup() { Serial.begin(115200); Serial1.begin(115200); myTransfer.begin(Serial1); } void loop() { if (myTransfer.available()) { uint16_t recSize = 0; recSize = myTransfer.rxObj(sensorData, recSize); // reads 6 bytes recSize = myTransfer.rxObj(label, recSize); // reads 5 bytes Serial.print("Node "); Serial.print(sensorData.nodeID); Serial.print(" Temp: "); Serial.print(sensorData.temperature); Serial.print(" Hum: "); Serial.print(sensorData.humidity); Serial.print(" Label: "); Serial.println(label); // Output: Node 7 Temp: 23.50 Hum: 61.20 Label: node } } ``` ``` -------------------------------- ### SerialTransfer::available() Source: https://context7.com/powerbroker2/serialtransfer/llms.txt Check for and parse incoming data. This non-blocking function polls for incoming data, parses bytes in the hardware buffer, advances the internal FSM, and returns the number of payload bytes in `rxBuff` when a complete packet is received. ```APIDOC ## SerialTransfer::available() ### Description Check for and parse incoming data. This non-blocking function polls for incoming data, parses all bytes currently in the hardware buffer, advances the internal FSM, and returns the number of payload bytes in `rxBuff` when a complete packet is received (`status == NEW_DATA`). It returns 0 otherwise. ### Method `uint8_t available()` ### Parameters None ### Request Example ```cpp #include "SerialTransfer.h" SerialTransfer myTransfer; float receivedVal = 0; void setup() { Serial.begin(115200); Serial1.begin(115200); myTransfer.begin(Serial1); } void loop() { uint8_t bytesIn = myTransfer.available(); if (myTransfer.status == NEW_DATA) { myTransfer.rxObj(receivedVal); Serial.println(receivedVal); } else if (myTransfer.status == CRC_ERROR) Serial.println("CRC mismatch — packet dropped"); else if (myTransfer.status == STALE_PACKET_ERROR) Serial.println("Packet timed out"); } ``` ### Response #### Success Response (200) Returns the number of payload bytes in `rxBuff` when a complete packet is received. Returns 0 otherwise. #### Response Example None provided. ``` -------------------------------- ### Callback-driven Receive with SerialTransfer::tick() Source: https://context7.com/powerbroker2/serialtransfer/llms.txt Use tick() with registered callbacks for automatic packet dispatching. The library calls the appropriate callback function based on the received packet ID. Ensure callbacks are correctly configured in the SerialTransfer object. ```cpp #include "SerialTransfer.h" SerialTransfer myTransfer; void onPacket0() { Serial.println("Packet ID 0 received"); } void onPacket1() { Serial.println("Packet ID 1 received"); } const functionPtr callbacks[] = { onPacket0, onPacket1 }; void setup() { Serial.begin(115200); Serial1.begin(115200); configST cfg; cfg.debug = true; cfg.callbacks = callbacks; cfg.callbacksLen = 2; myTransfer.begin(Serial1, cfg); } void loop() { myTransfer.tick(); // calls onPacket0() or onPacket1() automatically } ``` -------------------------------- ### SerialTransfer::tick() Source: https://context7.com/powerbroker2/serialtransfer/llms.txt Callback-driven receive loop. This wrapper around `available()` is intended for use with registered callback functions. It returns `true` when a full packet has been parsed and the appropriate callback (indexed by packet ID) has been dispatched. ```APIDOC ## SerialTransfer::tick() ### Description Callback-driven receive loop. This function is a wrapper around `available()` and is intended for use with registered callback functions. It returns `true` when a full packet has been parsed and the appropriate callback (indexed by packet ID) has been dispatched. ### Method `bool tick()` ### Parameters None ### Request Example ```cpp #include "SerialTransfer.h" SerialTransfer myTransfer; void onPacket0() { Serial.println("Packet ID 0 received"); } void onPacket1() { Serial.println("Packet ID 1 received"); } const functionPtr callbacks[] = { onPacket0, onPacket1 }; void setup() { Serial.begin(115200); Serial1.begin(115200); configST cfg; cfg.debug = true; cfg.callbacks = callbacks; cfg.callbacksLen = 2; myTransfer.begin(Serial1, cfg); } void loop() { myTransfer.tick(); // calls onPacket0() or onPacket1() automatically } ``` ### Response #### Success Response (200) Returns `true` when a full packet has been parsed and the appropriate callback has been dispatched. Returns `false` otherwise. #### Response Example None provided. ``` -------------------------------- ### I2C Data Transfer (Transmitter) Source: https://context7.com/powerbroker2/serialtransfer/llms.txt Use this code to transmit structured data and arrays over I2C using the I2CTransfer library. The transmitter acts as the I2C master. Ensure the Wire library is included and the I2CTransfer library is initialized. ```cpp // ---- I2C Transmitter (master) ---- #include "I2CTransfer.h" I2CTransfer myTransfer; struct __attribute__((packed)) STRUCT { char z; float y; } testStruct; char arr[] = "hello"; void setup() { Wire.begin(); myTransfer.begin(Wire); // master mode (no address argument) testStruct.z = '$'; testStruct.y = 4.5; } void loop() { uint16_t sendSize = 0; sendSize = myTransfer.txObj(testStruct, sendSize); sendSize = myTransfer.txObj(arr, sendSize); myTransfer.sendData(sendSize, 0, 0x08); // payload len, packetID=0, target=0x08 delay(500); } ``` -------------------------------- ### Multi-Packet File Transfer over UART (Transmitter) Source: https://context7.com/powerbroker2/serialtransfer/llms.txt Use this code to send large files over UART by splitting them into multiple packets. Ensure the SerialTransfer library is initialized and the serial port is configured. ```cpp #include "SerialTransfer.h" SerialTransfer myTransfer; const int fileSize = 2000; char file[fileSize] = "...file content here..."; char fileName[] = "data.csv"; void setup() { Serial1.begin(115200); myTransfer.begin(Serial1); } void loop() { myTransfer.sendDatum(fileName); // Send filename as packet ID 0 uint16_t numPackets = fileSize / (MAX_PACKET_SIZE - 2); if (fileSize % MAX_PACKET_SIZE) numPackets++; for (uint16_t i = 0; i < numPackets; i++) { uint8_t dataLen = MAX_PACKET_SIZE - 2; uint16_t fileIndex = i * dataLen; if ((fileIndex + dataLen) > fileSize) dataLen = fileSize - fileIndex; uint8_t sz = myTransfer.txObj(fileIndex); // 2-byte index sz = myTransfer.txObj(file[fileIndex], sz, dataLen); // chunk myTransfer.sendData(sz, 1); // packet ID 1 delay(100); } delay(10000); } ``` -------------------------------- ### Stuff C++ Objects into TX Buffer Source: https://context7.com/powerbroker2/serialtransfer/llms.txt Copies bytes from C++ objects (primitives, arrays, structs) into the transmit buffer. Multiple calls can be chained to append data, and the function returns the next available index for subsequent writes. ```cpp #include "SerialTransfer.h" SerialTransfer myTransfer; struct __attribute__((packed)) SensorData { float temperature; float humidity; uint8_t nodeID; } sensorData; char label[] = "node"; void setup() { Serial1.begin(115200); myTransfer.begin(Serial1); sensorData.temperature = 23.5; sensorData.humidity = 61.2; sensorData.nodeID = 7; } void loop() { uint16_t sendSize = 0; sendSize = myTransfer.txObj(sensorData, sendSize); // writes 6 bytes, returns 6 sendSize = myTransfer.txObj(label, sendSize); // writes 5 bytes, returns 11 myTransfer.sendData(sendSize); // transmit 11-byte payload delay(500); } ``` -------------------------------- ### Send Framed Data with SerialTransfer::sendData() Source: https://context7.com/powerbroker2/serialtransfer/llms.txt Use sendData() to frame and send bytes from the TX buffer. An optional packetID can distinguish packet types. Ensure txObj() is used to populate the buffer before calling sendData(). ```cpp #include "SerialTransfer.h" SerialTransfer myTransfer; float voltage = 3.14; uint32_t timestamp = 1234567; void setup() { Serial1.begin(115200); myTransfer.begin(Serial1); } void loop() { uint16_t sz = 0; sz = myTransfer.txObj(voltage, sz); // 4 bytes sz = myTransfer.txObj(timestamp, sz); // 4 bytes myTransfer.sendData(sz, 2); // packet ID = 2 delay(200); } ``` -------------------------------- ### SerialTransfer::sendData() Source: https://context7.com/powerbroker2/serialtransfer/llms.txt Frames and sends exactly `messageLen` bytes from `txBuff` as a single packet. The optional `packetID` (0–255) lets the receiver distinguish multiple packet types. ```APIDOC ## SerialTransfer::sendData() ### Description Transmit the TX buffer with a packet ID. This function frames and sends exactly `messageLen` bytes from `txBuff` as a single packet. The optional `packetID` (0–255) allows the receiver to distinguish between multiple packet types. ### Method `void sendData(size_t messageLen, uint8_t packetID = 0)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```cpp #include "SerialTransfer.h" SerialTransfer myTransfer; float voltage = 3.14; uint32_t timestamp = 1234567; void setup() { Serial1.begin(115200); myTransfer.begin(Serial1); } void loop() { uint16_t sz = 0; sz = myTransfer.txObj(voltage, sz); // 4 bytes sz = myTransfer.txObj(timestamp, sz); // 4 bytes myTransfer.sendData(sz, 2); // packet ID = 2 delay(200); } ``` ### Response #### Success Response (200) None #### Response Example None provided. ``` -------------------------------- ### Receive Data with SerialTransfer::available() Source: https://context7.com/powerbroker2/serialtransfer/llms.txt Use available() for non-blocking receive polling. It parses incoming bytes and returns the number of payload bytes when a complete packet is received. Check the status property for NEW_DATA, CRC_ERROR, or STALE_PACKET_ERROR. ```cpp #include "SerialTransfer.h" SerialTransfer myTransfer; float receivedVal = 0; void setup() { Serial.begin(115200); Serial1.begin(115200); myTransfer.begin(Serial1); } void loop() { uint8_t bytesIn = myTransfer.available(); if (myTransfer.status == NEW_DATA) { myTransfer.rxObj(receivedVal); Serial.println(receivedVal); } else if (myTransfer.status == CRC_ERROR) Serial.println("CRC mismatch — packet dropped"); else if (myTransfer.status == STALE_PACKET_ERROR) Serial.println("Packet timed out"); } ``` -------------------------------- ### Multi-Packet File Transfer over UART (Receiver) Source: https://context7.com/powerbroker2/serialtransfer/llms.txt This code receives files sent over UART using SerialTransfer. It distinguishes between filename packets (ID 0) and data chunk packets (ID 1). Ensure the SerialTransfer library is initialized and the serial ports are configured. ```cpp #include "SerialTransfer.h" SerialTransfer myTransfer; const int fileSize = 2000; char file[fileSize]; char fileName[16]; void setup() { Serial.begin(115200); Serial1.begin(115200); myTransfer.begin(Serial1); } void loop() { if (myTransfer.available()) { if (myTransfer.currentPacketID() == 0) { myTransfer.rxObj(fileName); Serial.print("File: "); Serial.println(fileName); } else if (myTransfer.currentPacketID() == 1) { for (uint8_t i = 2; i < myTransfer.bytesRead; i++) Serial.print((char)myTransfer.packet.rxBuff[i]); } } } ``` -------------------------------- ### I2CTransfer: I2C Interface Source: https://context7.com/powerbroker2/serialtransfer/llms.txt Enables data transfer over an I2C bus, mirroring the SerialTransfer API. Supports master (transmitter) and slave (receiver) modes. ```APIDOC ## I2CTransfer::begin() / I2CTransfer::sendData() ### Description `I2CTransfer` mirrors the UART API but operates over a `TwoWire` (`Wire`) bus. The sender specifies a target I2C address in `sendData()`; the receiver registers a callback via `configST` that is invoked automatically by the Wire ISR. ### Transmitter Example ```cpp // ---- I2C Transmitter (master) ---- #include "I2CTransfer.h" I2CTransfer myTransfer; struct __attribute__((packed)) STRUCT { char z; float y; } testStruct; char arr[] = "hello"; void setup() { Wire.begin(); myTransfer.begin(Wire); // master mode (no address argument) testStruct.z = '$'; testStruct.y = 4.5; } void loop() { uint16_t sendSize = 0; sendSize = myTransfer.txObj(testStruct, sendSize); sendSize = myTransfer.txObj(arr, sendSize); myTransfer.sendData(sendSize, 0, 0x08); // payload len, packetID=0, target=0x08 delay(500); } ``` ### Receiver Example ```cpp // ---- I2C Receiver (slave at address 0x08) ---- #include "I2CTransfer.h" I2CTransfer myTransfer; struct __attribute__((packed)) STRUCT { char z; float y; } testStruct; char arr[6]; void onReceive() { uint16_t recSize = 0; recSize = myTransfer.rxObj(testStruct, recSize); recSize = myTransfer.rxObj(arr, recSize); Serial.print(testStruct.z); Serial.print(testStruct.y); Serial.print(" | "); Serial.println(arr); // Output: $4.50 | hello } const functionPtr callbackArr[] = { onReceive }; void setup() { Serial.begin(115200); Wire.begin(0x08); // slave address configST myConfig; myConfig.debug = true; myConfig.callbacks = callbackArr; myConfig.callbacksLen = 1; myTransfer.begin(Wire, myConfig); } void loop() { /* ISR-driven, nothing needed here */ } ``` ``` -------------------------------- ### SerialTransfer::sendDatum() Source: https://context7.com/powerbroker2/serialtransfer/llms.txt Convenience wrapper that calls txObj() + sendData() in a single step for payloads consisting of exactly one object. Returns the number of payload bytes sent. ```APIDOC ## SerialTransfer::sendDatum() ### Description Transmit a single object in one call. This is a convenience wrapper that calls `txObj()` and `sendData()` in a single step for payloads consisting of exactly one object. It returns the number of payload bytes sent. ### Method `size_t sendDatum(const void *data, size_t size, uint8_t packetID = 0)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```cpp #include "SerialTransfer.h" SerialTransfer myTransfer; struct __attribute__((packed)) Command { uint8_t cmdID; int16_t value; } cmd; void setup() { Serial1.begin(115200); myTransfer.begin(Serial1); } void loop() { cmd.cmdID = 0x01; cmd.value = -300; myTransfer.sendDatum(cmd); // packs and sends sizeof(Command) = 3 bytes delay(1000); } ``` ### Response #### Success Response (200) Returns the number of payload bytes sent. #### Response Example None provided. ``` -------------------------------- ### SerialTransfer::currentPacketID() Source: https://context7.com/powerbroker2/serialtransfer/llms.txt Identify the last received packet. Returns the 8-bit ID from the most recently parsed packet. Use this when `available()` is polled directly (without callbacks) to dispatch handling logic based on packet type. ```APIDOC ## SerialTransfer::currentPacketID() ### Description Identify the last received packet. This function returns the 8-bit ID from the most recently parsed packet. It is intended to be used when `available()` is polled directly (without using callbacks) to dispatch handling logic based on the packet type. ### Method `uint8_t currentPacketID()` ### Parameters None ### Request Example ```cpp #include "SerialTransfer.h" SerialTransfer myTransfer; char fileName[16]; char fileChunk[252]; void setup() { Serial.begin(115200); Serial1.begin(115200); myTransfer.begin(Serial1); } void loop() { if (myTransfer.available()) { switch (myTransfer.currentPacketID()) { case 0: // filename packet myTransfer.rxObj(fileName); Serial.print("Receiving file: "); Serial.println(fileName); break; case 1: // data chunk packet for (uint8_t i = 2; i < myTransfer.bytesRead; i++) Serial.print((char)myTransfer.packet.rxBuff[i]); break; default: Serial.println("Unknown packet ID"); break; } } } ``` ### Response #### Success Response (200) Returns the 8-bit ID of the most recently parsed packet. #### Response Example None provided. ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.