{"id":18837019,"url":"https://github.com/xreef/ebyte_rf_e70_series_library","last_synced_at":"2025-04-14T06:21:47.535Z","repository":{"id":218343507,"uuid":"706560042","full_name":"xreef/EByte_RF_E70_Series_Library","owner":"xreef","description":"Arduino RF EBYTE E70 CC1310 device library complete and tested with Arduino, esp8266, esp32, STM32 and Raspberry Pi Pico (rp2040 boards)..","archived":false,"fork":false,"pushed_at":"2024-06-19T11:00:18.000Z","size":2027,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-27T20:07:24.276Z","etag":null,"topics":["arduino","arduino-library","arduino-mkr","arduino-nano-33","cc1310","e70","ebyte","esp32","esp8266","library","pico","raspberry-pi-pico","rp2040","stm32","streaming"],"latest_commit_sha":null,"homepage":"https://mischianti.org/category/my-libraries/ebyte-lora-e70-arduino-en/","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xreef.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-10-18T07:33:15.000Z","updated_at":"2024-10-11T15:46:35.000Z","dependencies_parsed_at":"2024-02-10T08:22:43.495Z","dependency_job_id":"764654ca-3ad7-4022-a421-7ce61c8674c2","html_url":"https://github.com/xreef/EByte_RF_E70_Series_Library","commit_stats":null,"previous_names":["xreef/ebyte_lora_e70_series_library","xreef/ebyte_rf_e70_series_library"],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xreef%2FEByte_RF_E70_Series_Library","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xreef%2FEByte_RF_E70_Series_Library/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xreef%2FEByte_RF_E70_Series_Library/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xreef%2FEByte_RF_E70_Series_Library/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xreef","download_url":"https://codeload.github.com/xreef/EByte_RF_E70_Series_Library/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248830899,"owners_count":21168366,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arduino","arduino-library","arduino-mkr","arduino-nano-33","cc1310","e70","ebyte","esp32","esp8266","library","pico","raspberry-pi-pico","rp2040","stm32","streaming"],"created_at":"2024-11-08T02:33:18.993Z","updated_at":"2025-04-14T06:21:47.509Z","avatar_url":"https://github.com/xreef.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"﻿Ebyte RF E70 CC1310: library (esp32, esp8266, STM32, Arduino, Raspberry Pi Pico)\n============================================================================================\n\n![Renzo Mischianti](https://lh3.googleusercontent.com/a/ACg8ocKfEyFEMAl0BWM4Ues1akNqg3-3VFJhAjaXyauxNOrVrnln=s96-c?sz=50) Renzo Mischianti\n\n[Support forum](https://mischianti.org/forums/forum/mischiantis-libraries/ebyte-lora-e70-uart-devices-cc1310/)\n\n![Cover](https://mischianti.org/wp-content/uploads/2024/01/Ebyte-LoRa-E70-CC1310-exploring-library-esp32-STM32-Arduino-Raspberry-Pi-Pico-1024x552.jpg)\n\nEbyte RF E70 CC1310: exploring library (esp32, STM32, Arduino, Raspberry Pi Pico)\n\nThe world of wireless communication has been revolutionized by the advent of Long Range (RF) technology, offering a blend of long-range capabilities and low power consumption. The EByte RF E70 module stands out as a prominent player among the various emerging modules. This article delves into the features, applications, and operational modes of the EByte E70, providing insights into its capabilities and potential uses.\n\nThe E70 is based on CC1310 series device. This device is not just a microcontroller (MCU); it is a fully integrated wireless MCU designed specifically for low-power, long-range wireless applications. The CC1310 combines a powerful ARM Cortex-M3 processor with a highly efficient sub-1 GHz radio, making it an ideal solution for a wide range of applications, from smart metering to industrial automation and environmental monitoring.\n\nIntroduction to EByte RF E70\n------------------------------\n\nThe EByte E70 is a RF module designed for long-range wireless communication. It operates in the sub-gigahertz frequency bands, making it ideal for various applications that require long-range communication and low power consumption. Its versatility and efficiency have made it a popular choice in IoT (Internet of Things) applications, smart city projects, and industrial automation.\n\nCHANGELOG\n-----------------------------\n2024-02-10 0.0.11  Name issue, change name and description\n2024-01-01 0.0.10  Try to remove resource folder to permit to install from Arduino Library Manager\n2024-01-01 0.0.9   First release\n\n\nKey Features of the EByte E70\n-----------------------------\n\n1.  **Long-Range Communication**: The E70 module is known for its exceptional range, capable of transmitting data over several kilometers, depending on environmental conditions.\n2.  **Low Power Consumption**: It’s optimized for low power usage, extending the battery life of devices, which is crucial for IoT applications.\n3.  **Multiple Operation Modes**: The E70 supports various modes like transparent mode, fixed mode, continuous mode, and sub-package mode, offering flexibility in different use cases.\n4.  **Configurable Parameters**: Users can configure parameters like frequency, power output, and data rate, making them adaptable to various communication needs.\n5.  **Forward Error Correction (FEC)**: FEC is a method for error control in data transmission. It adds redundancy to the transmitted information using a predetermined algorithm. This redundancy allows the receiver to detect and correct errors without the need for retransmission.\n\n![FEC](https://mischianti.org/wp-content/uploads/2023/12/EByte-LoRa-FEC-Forward-Error-Correction-example.jpg)\n\n\nDevice specifications\n---------------------\n\n*   The communication distance tested is up to 1.5/6km\n*   Maximum transmission power of 1W, software multi-level adjustable；\n*   Support air date rate of 2.5kbps～168kbps；\n*   Low power consumption for battery-supplied applications；\n*   Can achieve up to 115200bps continuous frame unlimited-packet length transmission\n*   E70-xxxT30S Support 2.6 ~ 5.5V power supply, more than 5V power supply to ensure the best performance;\n*   E70-xxxT14S/S2 support 2.2 ~ 3.8V power supply, more than 3.3V power supply to ensure the best performance;\n*   Industrial grade standard design, support -40 ~ 85 °C for working over a long time；\n\n*   Support high-speed continuous transmission, send and receive unlimited data packet length；\n*   Support continuous data frame without packetization, perfect support for ModBus protocol；\n*   Support custom subcontracting settings to improve communication efficiency；\n*   Support fixed-point transmission/broadcast transmission/channel monitoring;\n*   Support RSSI signal strength reading;\n*   Support over-the-air wake-up, i.e. low-power function, suitable for battery-powered solutions;\n*   Developed based on CC1310 chip, built-in dual-core ARM;\n*   Ultra-small volume design;\n*   Ultra-low receiving current, only about 8mA;\n*   E70-433 T30S maximum transmit power of 30dBm, the other three models are 25mW, softwaremulti-level adjustable;\n*   Under ideal conditions, the communication distance can reach 1.5km;\n*   E70-433T30S built-in PA+LNA, transmission power 1W, communication distance up to 6km;\n*   Supports the global license-free ISM 433MHz band;\n*   Support 2.5K~168kbps air transmission rate;\n*   Support 2.2~3.8V power supply, greater than 3.3V power supply can ensure the best performance;\n*   E70-433T30S supports 2.6~5.5V power supply , morethan 5V power supply can ensure the best performance;\n*   Dual antenna optional (IPEX/stamp hole) is convenient for users to develop and facilitate integration.\n\nLibrary\n-------\n\nI created a library to simplify usage. You can find It on my GitHub\n\n![](https://github-readme-stats.vercel.app/api/pin/?username=xreef\u0026repo=EByte_RF_E70_Series_Library\u0026show_owner=true)\n\nOr you can directly download from Arduino library manager.\n\nRF E70 variants\n-----------------\n\nE70 has various form factors, the design changes, and also specifications.\n\n![Dimensions of EByte RF E70 xxxTxxS Module](https://mischianti.org/wp-content/uploads/2023/12/EByte-LoRa-e70-xxxTxxS-size-1.jpg)\n\n**E70-433T30S**:\n\n*   Logic level voltage: 3.3v and 5v support\n*   Transmit Power: **30dBm** (higher power, capable of longer-distance transmission)\n*   Receive Sensitivity: **\\-107 to -109 dBm**\n*   Reference Distance: **6000m**\n\n![EByte RF E70 xxxT1xxS Module Dimensions](https://mischianti.org/wp-content/uploads/2023/12/EByte-LoRa-e70-xxxT1xxS-size.jpg)\n\n**E70-433T14S**:\n\n![Advertisement](https://mischianti.org/wp-content/uploads/2020/05/pcbWay-banner-mobile-300x200-1.gif)\n\n*   Logic level voltage: only 3.3v\n*   Transmit Power: **14dBm** (lower power compared to the T30S)\n*   Receive Sensitivity: **\\-109 to -111 dBm** for T14S and **\\-108 dBm** for T14S2 (slightly better sensitivity for the T14S)\n*   Reference Distance: **1500m**\n\n![Dimensions of the EByte RF E70 xxxT1xxS2 Module](https://mischianti.org/wp-content/uploads/2023/12/EByte-LoRa-e70-xxxT1xxS2-size-1.jpg)\n\n**E70-433T14S2**:\n\n*   Logic level voltage: only 3.3v\n*   Update of S version.\n*   Receive Sensitivity: **\\-109 to -111 dBm** for T14S and **\\-108 dBm** for T14S2 (slightly better sensitivity for the T14S)\n*   Form factors are simpler to manage.\n\n![Dimensions of EByte RF e70 xxxMTxxS](https://mischianti.org/wp-content/uploads/2023/12/EByte-LoRa-e70-xxxMTxxS-size.jpg)\n\n**E70-433MT14S**:\n\n*   Logic level voltage: only 3.3v\n*   Transmit Power: **14dBm** (same as T14S and T14S2)\n*   Receive Sensitivity: **\\-108 dBm** (same as T14S2)\n*   Reference Distance: **1500m** (same as T14S and T14S2)\n\n### RF Parameters\n\n![img.png](resources/EByte%20E70%20RF%20parameter.png)\n\n### Pinout\n![Advertisement](https://www.mischianti.org/wp-content/uploads/2023/01/sunfounder_mobile_300x200.jpg)\n\n### Hardware parameters\n\n![img.png](resources/EByte%20E70%20hardware%20parameter.png)\n\nPinout E70 xxxT14S2\n-------------------\n\nFor my test, I’m going to use an E70 S2 version because It’s a comfortable form factor with an onboard SMA antenna.\n\n![EByte E70 400/433/868/900/915 T14S2 pinout](https://mischianti.org/wp-content/uploads/2023/12/EByte-E70-xxxT14S2-pinout-low-res.jpg)\n\nConnections note\n----------------\n\n**You can find all kinds of wiring diagrams in the previous articles of the series.**\n\n![img.png](resources/EByte%20E70%20modes.png)\nConstructor\n-----------\n\nI made a set of numerous constructors because we can have more options and situations to manage.\n\n\t\tRF\\_E70(byte txE70pin, byte rxE70pin, UART\\_BPS\\_RATE bpsRate = UART\\_BPS\\_RATE\\_9600);\n\t\tRF\\_E70(byte txE70pin, byte rxE70pin, byte auxPin, UART\\_BPS\\_RATE bpsRate = UART\\_BPS\\_RATE\\_9600);\n\t\tRF\\_E70(byte txE70pin, byte rxE70pin, byte auxPin, byte m0Pin, byte m1Pin, byte m2Pin, UART\\_BPS\\_RATE bpsRate = UART\\_BPS\\_RATE\\_9600);\n\nThe first set of constructors is created to delegate Serial and other pins to the library.\n\n*   `txE70pin` and `rxE70pin` are the pins to connect to UART. They are **mandatory**.\n*   `auxPin` is a pin that checks the operation, transmission, and receiving status (we are going to explain better next), that pin **isn’t mandatory**; if you don’t set It, I apply a delay to permit the operation to complete itself (with latency, i**f you have trouble, like freeze device, you must put a pull-up 4.7k resistor or better connect to the device** ).\n*   `m0pin`, `m1Pin` and `m2Pin` are the pins to change operation MODE (see the table upper); I think these pins in “production” are going to connect directly to HIGH or LOW. Still, for a test, they are helpful for the library to manage.\n*   `bpsRate` is the baud rate of SoftwareSerial is typically 9600 (the only baud rate in programming/sleep mode)\n\nA simple example is\n\nA simple example is\n\n#include \"RF_E70.h\"\n\nRF_E70 e70ttl(2, 3);  // e70 TX e70 RX\n// RF_E70 e70ttl(2, 3, 5, 6, 7);  // e70 TX e70 RX\nWe can use a SoftwareSerial directly with another constructor\n\n\t\tRF_E70(HardwareSerial* serial, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);\n\t\tRF_E70(HardwareSerial* serial, byte auxPin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);\n\t\tRF_E70(HardwareSerial* serial, byte auxPin, byte m0Pin, byte m1Pin, byte m2Pin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);\nThe example upper with this constructor can be done like so.\n\n#include \u003cSoftwareSerial.h\u003e\n#include \"RF_E70.h\"\n\nSoftwareSerial mySerial(2, 3); // e70 TX e70 RX\nRF_E70 e70ttl(\u0026mySerial);\n// RF_E70 e70ttl(\u0026mySerial, 5, 6, 7, 8);\nThe last set of constructors is to permit an HardwareSerial instead of SoftwareSerial.\n\n\t\tRF_E70(SoftwareSerial* serial, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);\n\t\tRF_E70(SoftwareSerial* serial, byte auxPin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);\n\t\tRF_E70(SoftwareSerial* serial, byte auxPin, byte m0Pin, byte m1Pin, byte m2Pin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);\nFor esp32, you have three additional constructors to permit to manage pins for HardWare serial.\n\n\t\t\tRF_E70(byte txE70pin, byte rxE70pin, HardwareSerial* serial, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600, uint32_t serialConfig = SERIAL_8N1);\n\t\t\tRF_E70(byte txE70pin, byte rxE70pin, HardwareSerial* serial, byte auxPin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600, uint32_t serialConfig = SERIAL_8N1);\n\t\t\tRF_E70(byte txE70pin, byte rxE70pin, HardwareSerial* serial, byte auxPin, byte m0Pin, byte m1Pin, byte m2Pin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600, uint32_t serialConfig = SERIAL_8N1);\n\n\nBegin\n-----\n\nThe begin command is used to startup Serial and pins in input and output mode.\n\nvoid begin();\nin execution is\n\n\t// Startup all pins and UART\n\te70ttl.begin();\nConfiguration and method to get information\nThere are many methods for managing configuration and getting information about the device.\n\n\n### Response containers\n\nTo simplify the response management, I created a set of containers, which is very useful for managing errors and returning generic data.\n\n### ResponseStatus\n\nThe ResponseStatus is a status container and has two simple entry points, with this you can get the status code and the description of the status code\n\n\tSerial.println(c.getResponseDescription()); // Description of code\n\tSerial.println(c.code); // 1 if Success\nThe code is\n\n```\nE70_SUCCESS = 1,\nERR_E70_UNKNOWN,\t/* something shouldn't happened */\nERR_E70_NOT_SUPPORT,\nERR_E70_NOT_IMPLEMENT,\nERR_E70_NOT_INITIAL,\nERR_E70_INVALID_PARAM,\nERR_E70_DATA_SIZE_NOT_MATCH,\nERR_E70_BUF_TOO_SMALL,\nERR_E70_TIMEOUT,\nERR_E70_HARDWARE,\nERR_E70_HEAD_NOT_RECOGNIZED,\nERR_E70_NO_RESPONSE_FROM_DEVICE,\nERR_E70_WRONG_UART_CONFIG,\nERR_E70_WRONG_FORMAT,\nERR_E70_PACKET_TOO_BIG,\nERR_E70_NO_STREAM_FOUND\n```\n\n### ResponseContainer\n\nThis container is created to manage String response and has two entry points.\n\n`data` with the string returned from the message and `status` an instance of `RepsonseStatus`.\n\n\t\tResponseContainer rs = e70ttl.receiveMessage();\n\t\tString message = rs.data;\n\n\t\tSerial.println(rs.status.getResponseDescription());\n\t\tSerial.println(message);\n\nBut this command goes to read all the data in the buffer. If you receive three messages, you are going to read all three notes at one time, and my simple solution is to use an end character to send at the end of the message, to default I use \\\\0 (null character)\n\n\t\tResponseContainer rs = e70ttl.receiveMessageUntil();\n                // You can specify a custom delimiter also\n\t\t// ResponseContainer rs = e70ttl.receiveMessageUntil('|');\n\n\t\tString message = rs.data;\n\n\t\tSerial.println(rs.status.getResponseDescription());\n\t\tSerial.println(message);\n\n### ResponseStructContainer\n\nThe `ResponseStructContainer` is the more “complex” container. I use this to manage structures. It has the same entry points as ResponseContainer, but data is a void pointer to manage complex structures.\n\n\tResponseStructContainer c;\n\tc = e70ttl.getConfiguration();\n\t// It's important get configuration pointer before all other operation\n\tConfiguration configuration = \\*(Configuration\\*) c.data;\n\tSerial.println(c.status.getResponseDescription());\n\tSerial.println(c.status.code);\n    c.close();\n\nEvery time you use a `ResponseStructContainer` you must close It with `close()`\n\ngetConfiguration and setConfiguration\n-------------------------------------\n\nThe first method is getConfiguration, and you can use It to retrieve all data stored on the device.\n\n\t\tResponseStructContainer getConfiguration();\n\nHere is a usage example.\n\n\n\tResponseStructContainer c;\n\tc = e70ttl.getConfiguration();\n\t// It's important get configuration pointer before all other operation\n\tConfiguration configuration = \\*(Configuration\\*) c.data;\n\tSerial.println(c.status.getResponseDescription());\n\tSerial.println(c.status.code);\n    Serial.println(configuration.SPED.getUARTBaudRate());\n    c.close();\n\nThe structure of the configuration has all the data of settings, and I added a series of functions to get all the descriptions of a single data.\n\n\tconfiguration.ADDL = 0x00;  // First part of address\n\tconfiguration.ADDH = 0x00; // Second part\n\n\n\tconfiguration.SPED.uartBaudRate = UART\\_BPS\\_9600; // Serial baud rate\n\tconfiguration.SPED.airDataRate = AIR\\_DATA\\_RATE\\_000\\_025; // Air baud rate\n\tconfiguration.SPED.uartParity = MODE\\_00\\_8N1; // Parity bit\n\n\tconfiguration.CHAN.CHAN = 4;\n\tconfiguration.CHAN.subPacketSetting = SPS\\_0064\\_010;\n\n\tconfiguration.OPTION.fec = FEC\\_1\\_ON; // Packet size\n\tconfiguration.OPTION.fixedTransmission = FT\\_TRANSPARENT\\_TRANSMISSION; // Need to send special command\n\tconfiguration.OPTION.transmissionPower = POWER\\_30; // Device power\n\tconfiguration.OPTION.ioDriveMode = IO\\_D\\_MODE\\_PUSH\\_PULLS\\_PULL\\_UPS; // IO Drive\n\tconfiguration.OPTION.wirelessWakeupTime = WAKE\\_UP\\_1000; // Wake up time\n\nYou have the equivalent function for all attributes to get all descriptions:\n\nvoid printParameters(struct Configuration configuration) {\nSerial.println(\"----------------------------------------\");\n\n\tSerial.print(F(\"Configuration packet: \"));\n    byte\\* byteArray = (byte\\*)\u0026configuration;  // Cast the address of config to a byte pointer\n    for (int i = 0; i \u003c sizeof(Configuration); i++) {\n        if (byteArray\\[i\\] \u003c 16) {\n            Serial.print('0');  // Print a leading zero for single-digit hex values\n        }\n        Serial.print(byteArray\\[i\\], HEX);  // Print each byte of the struct in hexadecimal\n        Serial.print(\" \");\n    }\n    Serial.println(F(\" \"));\n\n\tSerial.print(F(\"HEAD : \"));  Serial.print(configuration.COMMAND, HEX);Serial.print(\" \");\n\tSerial.println(F(\" \"));\n\tSerial.print(F(\"AddH : \"));  Serial.println(configuration.ADDH, HEX);\n\tSerial.print(F(\"AddL : \"));  Serial.println(configuration.ADDL, HEX);\n\tSerial.println(F(\" \"));\n\tSerial.print(F(\"Chan : \"));  Serial.print(configuration.CHAN.CHAN, DEC); Serial.print(\" -\u003e \"); Serial.println(configuration.CHAN.getChannelDescription());\n\tSerial.print(F(\"Packet size : \"));  Serial.print(configuration.CHAN.subPacketSetting, BIN); Serial.print(\" -\u003e \"); Serial.println(configuration.CHAN.getSubPacketSetting());\n\tSerial.println(F(\" \"));\n\tSerial.print(F(\"SpeedParityBit     : \"));  Serial.print(configuration.SPED.uartParity, BIN);Serial.print(\" -\u003e \"); Serial.println(configuration.SPED.getUARTParityDescription());\n\tSerial.print(F(\"SpeedUARTDatte     : \"));  Serial.print(configuration.SPED.uartBaudRate, BIN);Serial.print(\" -\u003e \"); Serial.println(configuration.SPED.getUARTBaudRateDescription());\n\tSerial.print(F(\"SpeedAirDataRate   : \"));  Serial.print(configuration.SPED.airDataRate, BIN);Serial.print(\" -\u003e \"); Serial.println(configuration.SPED.getAirDataRateDescription());\n\tSerial.println(F(\" \"));\n\tSerial.print(F(\"OptionFECPacketSett: \"));  Serial.print(configuration.OPTION.fec, BIN);Serial.print(\" -\u003e \"); Serial.println(configuration.OPTION.getFECDescription());\n\tSerial.print(F(\"OptionTranPower    : \"));  Serial.print(configuration.OPTION.transmissionPower, BIN);Serial.print(\" -\u003e \"); Serial.println(configuration.OPTION.getTransmissionPowerDescription());\n\tSerial.print(F(\"OptionIODrive: \"));  Serial.print(configuration.OPTION.ioDriveMode, BIN);Serial.print(\" -\u003e \"); Serial.println(configuration.OPTION.getIODroveModeDescription());\n\tSerial.print(F(\"OptionFixedTransmission: \"));  Serial.print(configuration.OPTION.fixedTransmission, BIN);Serial.print(\" -\u003e \"); Serial.println(configuration.OPTION.getFixedTransmissionDescription());\n\tSerial.print(F(\"OptionWirelessWakeUPTime: \"));  Serial.print(configuration.OPTION.wirelessWakeupTime, BIN);Serial.print(\" -\u003e \"); Serial.println(configuration.OPTION.getWirelessWakeUPTimeDescription());\n\n\n\tSerial.println(\"----------------------------------------\");\n}\n\nIn the same way, setConfiguration wants a configuration structure, so I think the better way to manage configuration is to retrieve the current one, apply the only change you need and set It again.\n\n\t\tResponseStatus setConfiguration(Configuration configuration, PROGRAM\\_COMMAND saveType = WRITE\\_CFG\\_PWR\\_DWN\\_LOSE);\n\n`configuration` is the structure previously shown, `saveType` permit you to choose if the change becomes permanent or only for the current session.\n\n\tResponseStructContainer c;\n\tc = e70ttl.getConfiguration();\n\t// It's important get configuration pointer before all other operation\n\tConfiguration configuration = \\*(Configuration\\*) c.data;\n\tSerial.println(c.status.getResponseDescription());\n\tSerial.println(c.status.code);\n\n\tprintParameters(configuration);\n\tconfiguration.ADDL = 0x00;  // First part of address\n\tconfiguration.ADDH = 0x00; // Second part\n\n\n\tconfiguration.SPED.uartBaudRate = UART\\_BPS\\_9600; // Serial baud rate\n\tconfiguration.SPED.airDataRate = AIR\\_DATA\\_RATE\\_000\\_025; // Air baud rate\n\tconfiguration.SPED.uartParity = MODE\\_00\\_8N1; // Parity bit\n\n\tconfiguration.CHAN.CHAN = 4;\n\tconfiguration.CHAN.subPacketSetting = SPS\\_0064\\_010;\n\n\tconfiguration.OPTION.fec = FEC\\_1\\_ON; // Packet size\n\tconfiguration.OPTION.fixedTransmission = FT\\_TRANSPARENT\\_TRANSMISSION; // Need to send special command\n\tconfiguration.OPTION.transmissionPower = POWER\\_30; // Device power\n\tconfiguration.OPTION.ioDriveMode = IO\\_D\\_MODE\\_PUSH\\_PULLS\\_PULL\\_UPS; // IO Drive\n\tconfiguration.OPTION.wirelessWakeupTime = WAKE\\_UP\\_1000; // Wake up time\n\n\t// Set configuration changed and set to not hold the configuration\n\tResponseStatus rs = e70ttl.setConfiguration(configuration, WRITE\\_CFG\\_PWR\\_DWN\\_LOSE);\n\tSerial.println(rs.getResponseDescription());\n\tSerial.println(rs.code);\n\tprintParameters(configuration);\n    c.close()\n\nThe parameters are all managed as constant:\n\n\nCheck buffer\n------------\n\nFirst, we must introduce a simple but practical method to check if something is in the receiving buffer.\n\nint available();\n\nIt’s simple to return how many bytes you have in the current stream.\n\nSend receive messages\n---------------------\n\n### Normal transmission mode\n\nNormal/Transparent transmission mode sends messages to all devices with the same address and channel.\n\n![EByte RF Transmission Types Comparative Diagram](https://mischianti.org/wp-content/uploads/2023/12/EByte-LoRa-difference-from-transmission-type-diagram-1024x579.jpg)\n\nThere are a lot of methods to send/receive messages, and we are going to explain in detail:\n\n        ResponseStatus sendMessage(const String message);\n        ResponseContainer receiveMessage();\n\nThe first method is sendMessage, which sends a String to a device in **Normal mode**.\n\n\tResponseStatus rs = e70ttl.sendMessage(\"Prova\");\n\tSerial.println(rs.getResponseDescription());\n\nThe other device does on the loop.\n\n       if (e70ttl.available()  \u003e 1){\n\t\tResponseContainer rs = e70ttl.receiveMessage();\n\t\tString message = rs.data; // First ever get the data\n\t\tSerial.println(rs.status.getResponseDescription());\n\t\tSerial.println(message);\n\t}\n\nPay attention if you receive multiple messages in the buffer and don’t want to read them all at one time. You must use `ResponseContainer rs = e70ttl.receiveMessageUntil();` with a delimiter put on the end of sending a message.\n\n#### Manage structure\n\nIf you want to send a complex structure, you can use this method\n\n        ResponseStatus sendMessage(const void \\*message, const uint8\\_t size);\n        ResponseStructContainer receiveMessage(const uint8\\_t size);\n\nIt’s used to send structure, for example:\n\n\tstruct Messaggione {\n\t\tchar type\\[5\\];\n\t\tchar message\\[8\\];\n\t\tbool mitico;\n\t};\n        struct Messaggione messaggione = {\"TEMP\", \"Peple\", true};\n        ResponseStatus rs = e70ttl.sendMessage(\u0026messaggione, sizeof(Messaggione));\n\tSerial.println(rs.getResponseDescription());\n\nand the other side, you can receive the message so\n\n\t\tResponseStructContainer rsc = e70ttl.receiveMessage(sizeof(Messaggione));\n\t\tstruct Messaggione messaggione = \\*(Messaggione\\*) rsc.data;\n\t\tSerial.println(messaggione.message);\n\t\tSerial.println(messaggione.mitico);\n        rsc.close();\n\n#### Read partial structure\n\nIf you want to read the first part of the message to manage more types of structure, you can use this method.\n\nResponseContainer receiveInitialMessage(const uint8\\_t size);\n\nI create It to receive a string with type or other to identify the structure to load.\n\n\t\tstruct Messaggione { // Partial structure without type\n\t\t\tchar message\\[8\\];\n\t\t\tbool mitico;\n\t\t};\n\n\t\tchar type\\[5\\]; // first part of structure\n\t\tResponseContainer rs = e70ttl.receiveInitialMessage(sizeof(type));\n                // Put string in a char array (not needed)\n\t\tmemcpy ( type, rs.data.c\\_str(), sizeof(type) );\n\n\t\tSerial.println(\"READ TYPE: \");\n\t\tSerial.println(rs.status.getResponseDescription());\n\t\tSerial.println(type);\n\n                // Read the rest of structure\n\t\tResponseStructContainer rsc = e70ttl.receiveMessage(sizeof(Messaggione));\n\t\tstruct Messaggione messaggione = \\*(Messaggione\\*) rsc.data;\n        rsc.close();\n\nFixed mode instead of normal mode\n---------------------------------\n\nSimilarly, I create a set of methods to use with the fixed transmission.\n\n### Fixed transmission\n\n**You need to change only the sending method** because the destination device doesn’t **receive the preamble with Address and Channel when setting the fixed mode.**\n\nSo for the String message, you have\n\n        ResponseStatus sendFixedMessage(byte ADDH, byte ADDL, byte CHAN, const String message);\n        ResponseStatus sendBroadcastFixedMessage(byte CHAN, const String message);\n\nand for the structure, you have\n\n        ResponseStatus sendFixedMessage(byte ADDH, byte ADDL, byte CHAN, const void \\*message, const uint8\\_t size);\n        ResponseStatus sendBroadcastFixedMessage(byte CHAN, const void \\*message, const uint8\\_t size );\n\nHere is a simple example\n\n\tResponseStatus rs = e70ttl.sendFixedMessage(0, 0, 0x17, \u0026messaggione, sizeof(Messaggione));\n//\tResponseStatus rs = e70ttl.sendFixedMessage(0, 0, 0x17, \"Ciao\");\n\nFixed transmission has more scenarios\n\n![EByte RF Fixed Transmission Example Diagram](https://mischianti.org/wp-content/uploads/2023/12/EByte-LoRa-Fixed-Transmission-example-schema.jpg)\n\nIf you send it to a specific device (second scenario Fixed transmission), you must add ADDL, ADDH, and CHAN to identify It directly.\n\nResponseStatus rs = e70ttl.sendFixedMessage(2, 2, 0x17, \"Message to a device\");\n\nIf you want to send a message to all devices in a specified Channel, you can use this method.\n\nResponseStatus rs = e70ttl.sendBroadcastFixedMessage(0x17, \"Message to a devices of a channel\");\n\n![EByte RF Network Broadcast Transmission Diagram](https://mischianti.org/wp-content/uploads/2023/12/EByte-LoRa-Broadcast-Transmission-example-schema.jpg)\n\nEByte RF Network Broadcast Transmission Diagram\n\nIf you wish to receive all broadcast messages in the network, you must set your `ADDH` and `ADDL` with `BROADCAST_ADDRESS`.\n\n        ResponseStructContainer c;\n\tc = e70ttl.getConfiguration();\n\t// It's important get configuration pointer before all other operation\n\tConfiguration configuration = \\*(Configuration\\*) c.data;\n\tSerial.println(c.status.getResponseDescription());\n\tSerial.println(c.status.code);\n\n\tprintParameters(configuration);\n\tconfiguration.ADDL = BROADCAST\\_ADDRESS;\n\tconfiguration.ADDH = BROADCAST\\_ADDRESS;\n\n\t// Set configuration changed and set to not hold the configuration\n\tResponseStatus rs = e70ttl.setConfiguration(configuration, WRITE\\_CFG\\_PWR\\_DWN\\_LOSE);\n\tSerial.println(rs.getResponseDescription());\n\tSerial.println(rs.code);\n\tprintParameters(configuration);\n        c.close();\n\nContinuous mode\n---------------\n\nE70 offers the continuous mode by setting the same ADDH, ADDL, and CHAN. You can stream a lot of data or continuous data.\n\n![EByte RF continuous mode diagram](https://mischianti.org/wp-content/uploads/2024/01/EByte-LoRa-continuous-mode-diagram.jpg)\n\nEByte RF continuous mode diagram\n\n### Continuous Mode\n\n1.  **Operation**: In continuous mode, the EByte E70 module sends or receives data in a continuous stream. This means that once the transmission starts, it will keep sending data until stopped. It’s similar to a traditional radio broadcast.\n2.  **Usage**: This mode is useful for applications where a constant flow of information is needed, without interruptions. It’s ideal for real-time data transmission, like streaming audio or telemetry.\n3.  **Advantages**:\n    *   **Real-time data transmission**: Useful for applications requiring live updates.\n    *   **No interruption**: Continuous data flow without the need for packet reassembly or handling.\n4.  **Challenges**:\n    *   **Power consumption**: Typically, continuous mode consumes more power due to the constant transmission.\n    *   **Bandwidth usage**: It can use more bandwidth, which might not be ideal in crowded RF environments.\n\n### Sub-Packet Mode\n\n1.  **Operation**: In sub-packet mode, data is divided into smaller packets before transmission. Each packet is sent separately and then reassembled at the receiver’s end.\n2.  **Usage**: This mode is ideal for applications that don’t require real-time transmission and can tolerate some delay, such as sending sensor data at intervals.\n3.  **Advantages**:\n    *   **Energy efficiency**: More energy-efficient as the module can go into a low-power state between transmissions.\n    *   **Error handling**: Easier to implement error checking and correction, as it’s done on a per-packet basis.\n    *   **Adaptive data rates**: Can adjust the data rate for each packet depending on network conditions.\n4.  **Challenges**:\n    *   **Latency**: There is a delay in data reassembly, which might not be suitable for real-time applications.\n    *   **Complexity**: Requires more complex logic for packet handling and reassembly.\n\n### Key Differences\n\n*   **Data Transmission Method**: Continuous mode transmits data in a constant stream, while sub-packet mode breaks data into smaller packets.\n*   **Power Consumption**: Continuous mode generally consumes more power due to the constant transmission.\n*   **Real-time Capability**: Continuous mode is better for real-time data needs, whereas sub-packet mode is suitable for delayed or periodic data transmission.\n*   **Error Handling and Flexibility**: Sub-packet mode provides more flexibility in error handling and adjusting to network conditions.\n\nWhen you use continuous transmission mode, the module sends a continuous stream of data. To target this data to a specific address, you would typically configure the sender and receiver with matching addresses. This means that both the transmitting and receiving modules should be set up to recognize and use these specified addresses.\n\n### Simple stream\n\nTo send a simple stream (without any preamble) you can use\n\nResponseStatus RF\\_E70::streamMessage(Stream \\*streamLocal)\n\nA possible implementation can be the stream of a file.\n\n\t\t\tFile inputFile = SPIFFS.open(input);\n\n\t\t\tif (!inputFile) {\n\t\t\t    Serial.println(\"There was an error opening the file for reading\");\n\t\t\t} else  {\n\t\t\t\tResponseStatus rs = e70ttl.streamMessage(\u0026inputFile);\n\t\t\t\t// Check If there is some problem of succesfully send\n\t\t\t\tSerial.println(rs.getResponseDescription());\n\t\t\t}\n\nThat takes a stream as a parameter. To receive It, you can wait for the data.\n\n    if (e70ttl.available()\u003e0) {\n    \tSerial.println(\"Start!\");\n\n  \t  // open file in write \n    \tFile output = SPIFFS.open(\"/tmp.png\", FTP\\_FILE\\_WRITE\\_CREATE);\n\n    \twhile (e70ttl.available()\u003e0) {\n\t\t\twhile (e70ttl.available()\u003e0) {\n\t\t\t\tif (output.write(e70ttl.read())==0) {Serial.println(\"ERROR WRITE!\"); };\n\t\t\t}\n\t    \tdelay(10);\n    \t}\n\n    \toutput.close();\n\n    \tSerial.println(\"Complete!\");\n    }\n\nAs you can see, you can use read, which is a classical `stream.read()`.\n\n### Stream with preamble\n\nNot all situations can be a continuous stream; sometimes, we need to send data as a byte array; in this situation, you need a preamble with the file information, and you can use the command.\n\nResponseStatus RF\\_E70::streamStructMessage(const void \\*message, const uint8\\_t size, Stream \\*streamLocal)\n\nYou can identify the first part of the send method It’s the same as the send struct described before; the last parameter is the stream to send.\n\nTo receive all, you must first call the command to get the structure (preamble)\n\nResponseStructContainer RF\\_E70::receiveStreamMessage(const uint8\\_t size)\n\nThen, we get the stream as already described.\n\nThanks\n------\n\n[Deploy status](https://downloads.arduino.cc/libraries/logs/github.com/xreef/EByte_RF_E70_Series_Library/)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxreef%2Febyte_rf_e70_series_library","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxreef%2Febyte_rf_e70_series_library","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxreef%2Febyte_rf_e70_series_library/lists"}