Mục lục:

Giao tiếp không dây LoRa 3Km đến 8Km với thiết bị E32 (sx1278 / sx1276) chi phí thấp cho Arduino, Esp8266 hoặc Esp32: 15 bước
Giao tiếp không dây LoRa 3Km đến 8Km với thiết bị E32 (sx1278 / sx1276) chi phí thấp cho Arduino, Esp8266 hoặc Esp32: 15 bước

Video: Giao tiếp không dây LoRa 3Km đến 8Km với thiết bị E32 (sx1278 / sx1276) chi phí thấp cho Arduino, Esp8266 hoặc Esp32: 15 bước

Video: Giao tiếp không dây LoRa 3Km đến 8Km với thiết bị E32 (sx1278 / sx1276) chi phí thấp cho Arduino, Esp8266 hoặc Esp32: 15 bước
Video: [B09.02] Giao tiếp Arduino với Lora E32 2024, Tháng bảy
Anonim
Giao tiếp không dây LoRa 3Km đến 8Km với thiết bị E32 (sx1278 / sx1276) chi phí thấp cho Arduino, Esp8266 hoặc Esp32
Giao tiếp không dây LoRa 3Km đến 8Km với thiết bị E32 (sx1278 / sx1276) chi phí thấp cho Arduino, Esp8266 hoặc Esp32

Tôi tạo một thư viện để quản lý EBYTE E32 dựa trên dòng thiết bị LoRa của Semtech, thiết bị rất mạnh mẽ, đơn giản và rẻ tiền.

Bạn có thể tìm phiên bản 3Km tại đây, phiên bản 8Km tại đây

Chúng có thể hoạt động trong khoảng cách từ 3000m đến 8000m, và chúng có rất nhiều tính năng và thông số. Vì vậy, tôi tạo thư viện này để đơn giản hóa việc sử dụng.

Đó là một giải pháp để lấy dữ liệu từ các cảm biến đô thị hoặc để điều khiển máy bay không người lái.

Quân nhu

Arduino UNO

Wemos D1 mini

LoRa E32 TTL 100 phiên bản 3Km

Phiên bản LoRa E32 TTL 1W 8Km

Bước 1: Thư viện

Thư viện
Thư viện

Bạn có thể tìm thấy thư viện của tôi ở đây.

Tải về.

Nhấp vào nút DOWNLOADS ở góc trên cùng bên phải, đổi tên thư mục không nén LoRa_E32.

Kiểm tra xem thư mục LoRa_E32 có chứa LoRa_E32.cpp và LoRa_E32.h hay không.

Đặt thư mục thư viện LoRa_E32 thư mục / thư viện / thư mục của bạn. Bạn có thể cần tạo thư mục con thư viện nếu thư mục đầu tiên của bạn.

Khởi động lại IDE.

Bước 2: Sơ đồ chân

Sơ đồ chân
Sơ đồ chân
Sơ đồ chân
Sơ đồ chân
Sơ đồ chân
Sơ đồ chân

Như bạn thấy, bạn có thể thiết lập các chế độ khác nhau thông qua các chân M0 và M1.

Có một số chân có thể được sử dụng theo cách tĩnh, nhưng nếu bạn kết nối Nó với bộ vi điều khiển và định cấu hình chúng trong thư viện, bạn sẽ đạt được hiệu suất và bạn có thể kiểm soát tất cả các chế độ thông qua phần mềm, nhưng chúng tôi sẽ giải thích rõ hơn tiếp theo.

Bước 3: Pin AUX

Pin AUX
Pin AUX
Pin AUX
Pin AUX
Pin AUX
Pin AUX

Như tôi đã nói Việc kết nối tất cả các chân với đầu ra của vi điều khiển là không quan trọng, bạn có thể đặt các chân M0 và M1 thành CAO hoặc THẤP để có được cấu hình desidered, và nếu bạn không kết nối AUX, thư viện hãy đặt độ trễ hợp lý để đảm bảo. rằng hoạt động đã hoàn tất.

Chân AUX

Khi truyền dữ liệu có thể được sử dụng để đánh thức MCU bên ngoài và trả về mức CAO khi kết thúc truyền dữ liệu.

Khi nhận AUX sẽ THẤP và trả về CAO khi bộ đệm trống.

Nó cũng được sử dụng để tự kiểm tra nhằm khôi phục hoạt động bình thường (ở chế độ bật nguồn và ngủ / chương trình).

Bước 4: Lược đồ được kết nối đầy đủ Esp8266

Lược đồ được kết nối đầy đủ Esp8266
Lược đồ được kết nối đầy đủ Esp8266
Lược đồ được kết nối đầy đủ Esp8266
Lược đồ được kết nối đầy đủ Esp8266

giản đồ kết nối esp8266 đơn giản hơn vì Nó hoạt động ở cùng một điện áp của giao tiếp logic (3.3v).

Điều quan trọng là phải thêm điện trở kéo lên (4, 7Kohm) để có được sự ổn định tốt.

Bước 5: Lược đồ được kết nối đầy đủ Arduino

Lược đồ được kết nối đầy đủ Arduino
Lược đồ được kết nối đầy đủ Arduino
Lược đồ được kết nối đầy đủ Arduino
Lược đồ được kết nối đầy đủ Arduino

Điện áp làm việc của Arduino là 5v, vì vậy chúng ta cần thêm một bộ chia điện áp trên chân RX M0 và M1 của mô-đun LoRa để tránh hư hỏng, bạn có thể tham khảo thêm thông tin tại đây Bộ chia điện áp: máy tính và ứng dụng.

Bạn có thể sử dụng điện trở 2Kohm cho GND và 1Kohm từ tín hiệu hơn là đặt cùng nhau trên RX.

Bước 6: Thư viện: Khối mã lệnh

Tôi đã tạo một tập hợp khá nhiều hàm tạo, vì chúng ta có thể có nhiều tùy chọn và tình huống hơn để quản lý.

LoRa_E32 (byte rxPin, byte txPin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);

LoRa_E32 (byte rxPin, byte txPin, byte auxPin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600); LoRa_E32 (byte rxPin, byte txPin, byte auxPin, byte m0Pin, byte m1Pin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);

Tập hợp các hàm khởi tạo đầu tiên được tạo để ủy quyền quản lý Serial và các chân khác cho thư viện.

rxPin và txPin là chân để kết nối với UART và chúng là bắt buộc.

auxPin là một chân kiểm tra trạng thái hoạt động, truyền và nhận (chúng tôi sẽ giải thích rõ hơn tiếp theo), chân đó Không bắt buộc, nếu bạn không đặt Nó, tôi áp dụng độ trễ để cho phép hoạt động tự hoàn thành (với độ trễ).

m0pin và m1Pin là các chân để thay đổi CHẾ ĐỘ hoạt động (xem bảng phía trên), tôi nghĩ rằng các chân này trong “sản xuất” sẽ kết nối trực tiếp CAO hoặc THẤP, nhưng để kiểm tra chúng hữu ích được thư viện quản lý.

bpsRate là tần số âm thanh của SoftwareSerial thông thường là 9600 (tốc độ truyền duy nhất ở chế độ lập trình / ngủ)

Một ví dụ đơn giản là

#include "LoRa_E32.h" LoRa_E32 e32ttl100 (2, 3); // RX, TX // LoRa_E32 e32ttl100 (2, 3, 5, 6, 7); // RX, TX

Chúng ta có thể sử dụng trực tiếp một SoftwareSerial với một phương thức khởi tạo khác

LoRa_E32 (Sê-ri HardwareSerial *, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);

LoRa_E32 (Nối tiếp HardwareSerial *, byte auxPin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);

LoRa_E32 (Nối tiếp HardwareSerial *, byte auxPin, byte m0Pin, byte m1Pin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);

Ví dụ trên với hàm tạo này có thể làm như vậy.

#include #include "LoRa_E32.h"

SoftwareSerial mySerial (2, 3); // RX, TX

LoRa_E32 e32ttl100 (& mySerial);

// LoRa_E32 e32ttl100 (& mySerial, 5, 7, 6);

Tập hợp hàm tạo cuối cùng là cho phép sử dụng HardwareSerial thay vì SoftwareSerial.

LoRa_E32 (sê-ri SoftwareSerial *, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);

LoRa_E32 (SoftwareSerial * serial, byte auxPin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);

LoRa_E32 (SoftwareSerial * serial, byte auxPin, byte m0Pin, byte m1Pin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);

Bước 7: Bắt đầu

Lệnh bắt đầu được sử dụng để khởi động Serial và các chân ở chế độ đầu vào và đầu ra.

void begin ();

trong quá trình thực hiện là

// Khởi động tất cả các chân và UART

e32ttl100.begin ();

Bước 8: Phương pháp cấu hình và thông tin

Có một tập hợp các phương pháp để quản lý cấu hình và lấy thông tin của thiết bị.

ResponseStructContainer getConfiguration ();

ResponseStatus setConfiguration (Cấu hình cấu hình, PROGRAM_COMMAND saveType = WRITE_CFG_PWR_DWN_LOSE);

ResponseStructContainer getModuleInformation ();

void printParameters (cấu hình struct Configuration);

ResponseStatus resetModule ();

Bước 9: Vùng chứa phản hồi

Để đơn giản hóa việc quản lý phản hồi, tôi tạo một bộ vùng chứa, đối với tôi rất hữu ích để quản lý lỗi và trả về dữ liệu chung.

Trạng thái đáp ứng

Đây là một vùng chứa trạng thái và có 2 điểm nhập đơn giản, với điểm này bạn có thể lấy mã trạng thái và mô tả mã trạng thái

Serial.println (c.getResponseDescription ()); // Mô tả mã

Serial.println (c.code); // 1 nếu thành công

Mã là

THÀNH CÔNG = 1, ERR_UNKNOWN, ERR_NOT_SUPPORT, ERR_NOT_IMPLEMENT, ERR_NOT_INITIAL, ERR_INVALID_PARAM, ERR_DATA_SIZE_NOT_MATCH, ERR_BUF_TOO_SMALL, ERR_TIMEOUT, ERR_HARDWARE, ERR_HEAD_NOT_RECOGNIZED

ResponseContainer

Vùng chứa này được tạo để quản lý phản hồi Chuỗi và có 2 điểm vào.

dữ liệu với chuỗi được trả về từ tin nhắn và trạng thái là một phiên bản của RepsonseStatus.

ResponseContainer rs = e32ttl.receiveMessage ();

Thông báo chuỗi = rs.data;

Serial.println (rs.status.getResponseDescription ());

Serial.println (tin nhắn);

ResponseStructContainer

Đây là vùng chứa “phức tạp” hơn, tôi sử dụng nó để quản lý cấu trúc, Nó có cùng điểm vào của ResponseContainer nhưng dữ liệu là một con trỏ void để quản lý cấu trúc phức tạp.

ResponseStructContainer c;

c = e32ttl100.getConfiguration (); // Điều quan trọng là lấy con trỏ cấu hình trước tất cả các thao tác khác

Cấu hình cấu hình = * (Cấu hình *) c.data;

Serial.println (c.status.getResponseDescription ());

Serial.println (c.status.code);

getConfiguration và setConfiguration

Phương pháp đầu tiên là getConfiguration, bạn có thể sử dụng Nó để truy xuất tất cả dữ liệu được lưu trữ trên thiết bị.

ResponseStructContainer getConfiguration ();

Đây là một ví dụ sử dụng.

ResponseStructContainer c;

c = e32ttl100.getConfiguration (); // Điều quan trọng là lấy con trỏ cấu hình trước tất cả các thao tác khác

Cấu hình cấu hình = * (Cấu hình *) c.data;

Serial.println (c.status.getResponseDescription ());

Serial.println (c.status.code);

Serial.println (config. SPED.getUARTBaudRate ());

Cấu trúc của cấu hình có tất cả dữ liệu của cài đặt, và tôi thêm một loạt chức năng để có được tất cả các mô tả về dữ liệu đơn lẻ.

cấu hình. ADDL = 0x0; // Phần đầu của addressconfiguration. ADDH = 0x1; // Phần thứ hai của cấu hình địa chỉ. CHAN = 0x19; // Cấu hình kênh. OPTION.fec = FEC_0_OFF; // Chuyển tiếp cấu hình công tắc sửa lỗi. OPTION.fixedTransmission = FT_TRANSPARENT_TRANSMISSION; // Cấu hình chế độ truyền. OPTION.ioDriveMode = IO_D_MODE_PUSH_PULLS_PULL_UPS; // Cấu hình quản lý kéo lên. OPTION.transmissionPower = POWER_17; // Cấu hình công suất truyền dBm. OPTION.wirelessWakeupTime = WAKE_UP_1250; // Chờ thời gian đánh thức cấu hình. SPED.airDataRate = AIR_DATA_RATE_011_48; // Cấu hình tốc độ dữ liệu không khí. SPED.uartBaudRate = UART_BPS_115200; // Cấu hình tốc độ baud truyền thông. SPED.uartParity = MODE_00_8N1; // Bit chẵn lẻ

Bạn có chức năng tương đương cho tất cả thuộc tính để nhận tất cả mô tả:

Serial.print (F ("Chan:")); Serial.print (cấu hình. CHAN, DEC); Serial.print ("->"); Serial.println (config.getChannelDescription ()); Serial.println (F ("")); Serial.print (F ("SpeedParityBit:")); Serial.print (config. SPED.uartParity, BIN); Serial.print ("->"); Serial.println (config. SPED.getUARTParityDescription ()); Serial.print (F ("SpeedUARTDatte:")); Serial.print (configuration. SPED.uartBaudRate, BIN); Serial.print ("->"); Serial.println (config. SPED.getUARTBaudRate ()); Serial.print (F ("SpeedAirDataRate:")); Serial.print (configuration. SPED.airDataRate, BIN); Serial.print ("->"); Serial.println (config. SPED.getAirDataRate ()); Serial.print (F ("OptionTrans:")); Serial.print (configuration. OPTION.fixedTransmission, BIN); Serial.print ("->"); Serial.println (configuration. OPTION.getFixedTransmissionDescription ()); Serial.print (F ("OptionPullup:")); Serial.print (config. OPTION.ioDriveMode, BIN); Serial.print ("->"); Serial.println (configuration. OPTION.getIODroveModeDescription ()); Serial.print (F ("OptionWakeup:")); Serial.print (configuration. OPTION.wirelessWakeupTime, BIN); Serial.print ("->"); Serial.println (configuration. OPTION.getWirelessWakeUPTimeDescription ()); Serial.print (F ("OptionFEC:")); Serial.print (configuration. OPTION.fec, BIN); Serial.print ("->"); Serial.println (configuration. OPTION.getFECDescription ()); Serial.print (F ("OptionPower:")); Serial.print (configuration. OPTION.transmissionPower, BIN); Serial.print ("->"); Serial.println (config. OPTION.getTransmissionPowerDescription ());

Đồng thời setConfiguration muốn một chuỗi cấu hình, vì vậy tôi nghĩ cách tốt hơn để quản lý cấu hình là truy xuất cấu hình hiện tại, áp dụng thay đổi duy nhất bạn cần và đặt lại.

ResponseStatus setConfiguration (Cấu hình cấu hình, PROGRAM_COMMAND saveType = WRITE_CFG_PWR_DWN_LOSE);

cấu hình là chương trình hiển thị trước strucutre, saveType cho phép bạn lựa chọn nếu thay đổi trở thành vĩnh viễn chỉ dành cho phiên hiện tại.

ResponseStructContainer c; c = e32ttl100.getConfiguration (); // Điều quan trọng là lấy con trỏ cấu hình trước tất cả các thao tác khác Cấu hình cấu hình = * (Cấu hình *) c.data; Serial.println (c.status.getResponseDescription ()); Serial.println (c.status.code); printParameters (cấu hình); cấu hình. ADDL = 0x0; cấu hình. ADDH = 0x1; cấu hình. CHAN = 0x19; cấu hình. OPTION.fec = FEC_0_OFF; cấu hình. OPTION.fixedTransmission = FT_TRANSPARENT_TRANSMISSION; cấu hình. OPTION.ioDriveMode = IO_D_MODE_PUSH_PULLS_PULL_UPS; cấu hình. OPTION.transmissionPower = POWER_17; cấu hình. OPTION.wirelessWakeupTime = WAKE_UP_1250; cấu hình. SPED.airDataRate = AIR_DATA_RATE_011_48; cấu hình. SPED.uartBaudRate = UART_BPS_115200; cấu hình. SPED.uartParity = MODE_00_8N1; // Đặt cấu hình đã thay đổi và đặt thành không giữ cấu hình ResponseStatus rs = e32ttl100.setConfiguration (configuration, WRITE_CFG_PWR_DWN_LOSE); Serial.println (rs.getResponseDescription ()); Serial.println (rs.code); printParameters (cấu hình);

Tất cả các tham số đều được quản lý dưới dạng hằng số:

Bước 10: Tùy chọn cấu hình cơ bản

Tùy chọn cấu hình cơ bản
Tùy chọn cấu hình cơ bản

Bước 11: Gửi nhận tin nhắn

Trước tiên, chúng tôi phải giới thiệu một phương pháp đơn giản nhưng hữu ích để kiểm tra xem có thứ gì đó nằm trong bộ đệm nhận hay không

int có sẵn ();

Nó chỉ đơn giản là trả về số byte bạn có trong luồng hiện tại.

Bước 12: Chế độ truyền bình thường

Chế độ truyền bình thường
Chế độ truyền bình thường

Chế độ truyền bình thường / trong suốt được sử dụng để gửi tin nhắn đến tất cả các thiết bị có cùng địa chỉ và kênh.

Có rất nhiều phương pháp để gửi / nhận tin nhắn, chúng tôi sẽ giải thích chi tiết:

ResponseStatus sendMessage (thông điệp const String);

ResponseContainer nhậnMessage ();

Phương thức đầu tiên là sendMessage và được sử dụng để gửi một chuỗi đến một thiết bị ở chế độ Bình thường.

ResponseStatus rs = e32ttl.sendMessage ("Prova"); Serial.println (rs.getResponseDescription ());

Các thiết bị khác chỉ cần thực hiện trên vòng lặp

if (e32ttl.available ()> 1) {ResponseContainer rs = e32ttl.receiveMessage (); Thông báo chuỗi = rs.data; // Đầu tiên lấy dữ liệu Serial.println (rs.status.getResponseDescription ()); Serial.println (tin nhắn); }

Bước 13: Quản lý cấu trúc

Nếu bạn muốn gửi một kết cấu phức tạp, bạn có thể sử dụng phương pháp này

ResponseStatus sendMessage (const void * message, const uint8_t size); ResponseStructContainer acceptMessage (const uint8_t size);

Nó được sử dụng để gửi strucutre, ví dụ:

struct Messaggione {char type [5]; thông báo char [8]; bool mitico; }; struct Messaggione messaggione = {"TEMP", "Peple", true}; ResponseStatus rs = e32ttl.sendMessage (& messaggione, sizeof (Messaggione)); Serial.println (rs.getResponseDescription ());

và phía bên kia, bạn có thể nhận được tin nhắn như vậy

ResponseStructContainer rsc = e32ttl.receiveMessage (sizeof (Messaggione)); struct Messaggione messaggione = * (Messaggione *) rsc.data; Serial.println (messaggione.message); Serial.println (messaggione.mitico);

Đọc cấu trúc từng phần

Nếu bạn muốn đọc phần đầu tiên của thông báo để quản lý nhiều loại strucutre hơn, bạn có thể sử dụng phương pháp này.

ResponseContainer nhậnInitialMessage (kích thước const uint8_t);

Tôi tạo Nó để nhận một chuỗi có kiểu hoặc khác để xác định cấu trúc cần tải.

struct Messaggione {// Một phần strucutre không có thông báo typechar [8]; bool mitico; }; kiểu char [5]; // phần đầu của cấu trúc ResponseContainer rs = e32ttl.receiveInitialMessage (sizeof (type)); // Đặt chuỗi vào một mảng char (không cần thiết) memcpy (type, rs.data.c_str (), sizeof (type)); Serial.println ("LOẠI ĐỌC:"); Serial.println (rs.status.getResponseDescription ()); Serial.println (kiểu); // Đọc phần còn lại của cấu trúc ResponseStructContainer rsc = e32ttl.receiveMessage (sizeof (Messaggione)); struct Messaggione messaggione = * (Messaggione *) rsc.data;

Bước 14: Chế độ cố định thay vì chế độ bình thường

Đồng thời, tôi tạo một bộ phương pháp để sử dụng với đường truyền cố định

Truyền cố định

Bạn chỉ cần thay đổi phương thức gửi vì thiết bị đích không nhận được phần mở đầu với chế độ cố định Địa chỉ và Kênh quando ở chế độ cố định.

Vì vậy, đối với tin nhắn Chuỗi, bạn có

ResponseStatus sendFixedMessage (byte ADDL, byte ADDH, byte CHAN, const String message); ResponseStatus sendBroadcastFixedMessage (byte CHAN, const String message);

và đối với cấu trúc bạn có

ResponseStatus sendFixedMessage (byte ADDL, byte ADDH, byte CHAN, const void * message, const uint8_t size); ResponseStatus sendBroadcastFixedMessage (byte CHAN, const void * message, const uint8_t size);

Đây là một ví dụ đơn giản

ResponseStatus rs = e32ttl.sendFixedMessage (0, 0, 0x17, & messaggione, sizeof (Messaggione)); // ResponseStatus rs = e32ttl.sendFixedMessage (0, 0, 0x17, "Ciao");

Truyền cố định có nhiều kịch bản hơn

Nếu bạn gửi đến một thiết bị cụ thể (kịch bản thứ hai Truyền cố định), bạn phải thêm ADDL, ADDH và CHAN để xác định nó trực tiếp.

ResponseStatus rs = e32ttl.sendFixedMessage (2, 2, 0x17, "Thông báo tới thiết bị");

Nếu bạn muốn gửi tin nhắn đến tất cả thiết bị trong một Kênh cụ thể, bạn có thể sử dụng phương pháp này.

ResponseStatus rs = e32ttl.sendBroadcastFixedMessage (0x17, "Thông báo tới thiết bị của một kênh");

Nếu bạn muốn nhận tất cả tin nhắn quảng bá trong mạng, bạn phải đặt ADDH và ADDL của mình bằng BROADCAST_ADDRESS.

ResponseStructContainer c; c = e32ttl100.getConfiguration (); // Điều quan trọng là lấy con trỏ cấu hình trước tất cả các thao tác khác Cấu hình cấu hình = * (Cấu hình *) c.data; Serial.println (c.status.getResponseDescription ()); Serial.println (c.status.code); printParameters (cấu hình); cấu hình. ADDL = BROADCAST_ADDRESS; cấu hình. ADDH = BROADCAST_ADDRESS; // Đặt cấu hình đã thay đổi và đặt thành không giữ cấu hình ResponseStatus rs = e32ttl100.setConfiguration (configuration, WRITE_CFG_PWR_DWN_LOSE); Serial.println (rs.getResponseDescription ()); Serial.println (rs.code); printParameters (cấu hình);

Bước 15: Cảm ơn

Bây giờ bạn có tất cả thông tin để thực hiện công việc của mình, nhưng tôi nghĩ Điều quan trọng là phải đưa ra một số ví dụ thực tế để phá vỡ tất cả các khả năng có thể xảy ra.

  1. Thiết bị LoRa E32 cho Arduino, esp32 hoặc esp8266: cài đặt và cách sử dụng cơ bản
  2. Thiết bị LoRa E32 cho Arduino, esp32 hoặc esp8266: thư viện
  3. Thiết bị LoRa E32 cho Arduino, esp32 hoặc esp8266: cấu hình
  4. Thiết bị LoRa E32 cho Arduino, esp32 hoặc esp8266: truyền cố định
  5. Thiết bị LoRa E32 cho Arduino, esp32 hoặc esp8266: tiết kiệm năng lượng và gửi dữ liệu có cấu trúc

Đề xuất: