Mục lục:
- Quân nhu
- Bước 1: 1. Thiết lập Atecc608a
- Bước 2: 2. Thiết kế mạch (Master và Slave)
- Bước 3: 3. Mã (Slave và Master)
- Bước 4: 4. Đi xa hơn
- Bước 5: Kết luận
Video: Giao tiếp mã hóa không dây Arduino: 5 bước
2024 Tác giả: John Day | [email protected]. Sửa đổi lần cuối: 2024-01-30 13:31
Chào mọi người, Trong bài viết thứ hai này, tôi sẽ giải thích cho bạn cách sử dụng chip Atecc608a để đảm bảo giao tiếp không dây của bạn. Đối với điều này, tôi sẽ sử dụng NRF24L01 + cho phần Không dây và Arduino UNO.
Vi chip ATECC608A được thiết kế bởi MicroChip và có nhiều công cụ bảo mật. Ví dụ, chip này có thể lưu trữ các Khóa ECC, Khóa AES (cho AES 128) và SHA2 Hash.
Bài viết: NRF24L01 + Arduino UNO + ATECC608A
Trong quá trình giao tiếp giữa hai Đối tượng IoT, có thể tồn tại nhiều cuộc tấn công: Người đàn ông nhẹ nhàng, Bản sao thông tin và hơn thế nữa.. Vì vậy, ý tưởng của tôi rất đơn giản:
- Sử dụng dữ liệu được mã hóa giữa hai hoặc nhiều đối tượng IoT.
- Nguồn cung cấp chi phí thấp
- Có thể hoạt động với Arduino UNO
Trong trường hợp của tôi, tôi sử dụng
- Atecc608a để lưu trữ Khóa AES của tôi và để mã hóa / giải mã dữ liệu của tôi.
- Arduino Uno làm Vi điều khiển
- NRF24L01 để gửi dữ liệu của tôi
Bạn cần làm theo các bước sau cho dự án này:
- Thiết lập chip ATECC608A
- Làm mạch (Master Node và Slave Node)
- Phần mã
- Đi xa hơn !
Đối với các bước đầu tiên "Thiết lập chip ATECC608A", tôi đã viết một bài báo khác giải thích từng bước theo thứ tự. Liên kết ở đây:
Bây giờ bắt đầu!
Quân nhu
Đối với dự án này, bạn cần:
- 2 Arduino UNO hoặc Arduino NANO hoặc Arduino Mega
- Một số dây
- 2 Atecc608a (mỗi chiếc có giá dưới 0,60 đô la)
- 2 NRF24L01 +
- 2 tụ điện (10 μF)
- Bảng bánh mì
Liên kết đến bài viết của tôi giải thích cách thiết lập chip ATECC608A -> Cách thiết lập Atecc608a
Bước 1: 1. Thiết lập Atecc608a
Tôi sẽ không trình bày chi tiết từng bước cần làm để thiết lập ATECC608A vì tôi đã viết một bài báo đầy đủ giải thích mọi bước để thực hiện. Để thiết lập nó, bạn cần làm theo "Bước 4" của bài viết này có tên "2. Cấu hình chip (Atecc608a)"
Liên kết là: Cách thiết lập ATECC608A
Ngoài ra, bạn cần đặt cùng một cấu hình cho Atecc608a, phía chính và phía phụ, nếu không, bạn sẽ không thể giải mã dữ liệu của mình
Cảnh báo:
Để thiết lập chip này, bạn cần làm theo từng bước của bài viết trên theo thứ tự. Nếu thiếu một bước hoặc chip không khóa, bạn sẽ không thể thực hiện dự án này
Phần còn lại:
Bước để làm theo cho điều này:
- Tạo mẫu cấu hình
- Ghi mẫu này vào chip
- Khóa vùng cấu hình
- Viết Khóa AES của bạn (128 Bit) vào một chỗ trống
- Khóa vùng dữ liệu
Bước 2: 2. Thiết kế mạch (Master và Slave)
Trong dự án này, bạn sẽ có Master Node và Slave Node.
Nút chính sẽ in rõ ràng dữ liệu được gửi bởi nút phụ. Nó sẽ yêu cầu dữ liệu từ nút nô lệ mỗi X lần.
Nút phụ sẽ lắng nghe "mạng" và khi nhận được "Dữ liệu yêu cầu", nó sẽ tạo ra nó, mã hóa nó và gửi đến nút chủ.
Đối với cả hai bên, mạch chủ và mạch phụ đều giống nhau:
- Một Arduino Nano
- Một ATECC608A
- Một NRF24L01
Mình gắn mạch ở bước này (cf hình trên).
Đối với ATECC608A với Arduino UNO, đây là chân 8 soic. Tôi đã thêm "chế độ xem hàng đầu" ở trên:
- ARDUINO 3.3V -> PIN 8 (Atecc608a)
- ARDUINO GND -> PIN 4 (Atecc608a)
- ARDUINO A4 (SDL) -> PIN 5 (Atecc608a)
- ARDUINO A5 (SCL) -> PIN 6 (Atecc608a)
Đối với NRF24L01 vào Arduino:
- ARDUINO 3.3V -> VCC (nrf24l01)
- ARDUINO GND -> GND (nrf24l01)
- ARDUINO 9 -> CE (nrf24l01)
- ARDUINO 10 -> CSN (nrf24l01)
- ARDUINO 11 -> MOSI (nrf24L01)
- ARDUINO 12 -> MISO (nrf24l01)
- ARDUINO 13 -> SCK (nrf24l01)
- ARDUINO 3 -> IRQ (nrf24l01) -> chỉ dành cho nút Slave, không được sử dụng trong chế độ Chính
Tại sao sử dụng chân IRQ của NRF24L01
Chân IRQ rất hữu ích, chân này cho phép nói (THẤP) khi một gói được NRF24L01 nhận, vì vậy chúng ta có thể gắn một Interrupt vào chân này để đánh thức nút phụ.
Bước 3: 3. Mã (Slave và Master)
Nút nô lệ
Tôi sử dụng tiết kiệm năng lượng cho Node nô lệ vì nó không cần phải lắng nghe mọi lúc.
Cách thức hoạt động: nút nô lệ lắng nghe và đợi để nhận một "gói Wake UP". Gói tin này được gửi bởi nút Master để hỏi dữ liệu từ máy chủ.
Trong trường hợp của tôi, tôi sử dụng một mảng gồm hai int:
// Gói Wake UP
const int aw_packet [2] = {20, 02};
Nếu nút của tôi nhận được một gói,
- nó thức dậy, hãy đọc gói tin này, nếu gói đó là "Wake UP",
- nó tạo ra dữ liệu,
- mã hóa dữ liệu,
- gửi dữ liệu đến cái chính, đợi một gói ACK,
- ngủ.
Đối với Mã hóa AES, tôi sử dụng một khóa ở vị trí số 9.
Đây là mã của tôi cho nút Slave
#include "Arduino.h" #include "avr / sleep.h" #include "avr / wdt.h"
#include "SPI.h"
#include "nRF24L01.h" #include "RF24.h"
#include "Wire.h"
// Thư viện ATECC608A
#include "ATECCX08A_Arduino / cryptoauthlib.h" #include "AES BASIC / aes_basic.h"
#define ID_NODE 255
#define AES_KEY (uint8_t) 9
ATCAIfaceCfg cfg;
Trạng thái ATCA_STATUS;
Đài RF24 (9, 10);
const uint64_t masteraddresse = 0x1111111111;
const uint64_t slaveaddresse = 0x1111111100;
/**
* / short Hàm được thực thi khi ngắt được thiết lập (IRQ LOW) * * * / voidakeUpIRQ () {while (radio.available ()) {int data [32]; radio.read (& data, 32); if (data [0] == 20 && data [1] == 02) {float temp = 17,6; float hum = 16,4;
dữ liệu uint8_t [16];
uint8_t cypherdata [16];
// Xây dựng một chuỗi để đặt tất cả Giá trị của tôi
// Mỗi giá trị được phân tách bằng dấu "|" và "$" có nghĩa là cuối dữ liệu // CẢNH BÁO: Độ dài phải nhỏ hơn 11 String tmp_str_data = String (ID_NODE) + "|" + Chuỗi (tạm thời, 1) + "|" + Chuỗi (hum, 1) + "$"; // kích thước của 11 Serial.println ("tmp_str_data:" + tmp_str_data);
tmp_str_data.getBytes (dữ liệu, sizeof (dữ liệu));
// Mã hóa dữ liệu
ATCA_STATUS status = aes_basic_encrypt (& cfg, data, sizeof (data), cypherdata, AES_KEY); if (status == ATCA_SUCCESS) {long rand = random ((long) 10000, (long) 99999);
// tạo một UUID dựa trên ba số đầu tiên = nút ID
String uuid = String (ID_NODE) + String (rand); // Kích thước của 8
uint8_t tmp_uuid [8];
uint8_t data_to_send [32];
uuid.getBytes (tmp_uuid, sizeof (tmp_uuid) + 1);
memcpy (data_to_send, tmp_uuid, sizeof (tmp_uuid));
memcpy (data_to_send + sizeof (tmp_uuid), cypherdata, sizeof (cypherdata)); // Ngừng nghe radio.stopListening ();
bool rslt;
// Gửi dữ liệu rslt = radio.write (& data_to_send, sizeof (data_to_send)); // Bắt đầu nghe radio.startListening (); if (rslt) {// Chế độ kết thúc và nghỉ Serial.println (F ("Xong")); }}}}}
void setup ()
{Serial.begin (9600);
// Nhập hằng số cho thư viện
cfg.iface_type = ATCA_I2C_IFACE; // Kiểu giao tiếp -> Chế độ I2C cfg.devtype = ATECC608A; // Loại chip cfg.atcai2c.slave_address = 0XC0; // Địa chỉ I2C (giá trị mặc định) cfg.atcai2c.bus = 1; cfg.atcai2c.baud = 100000; cfg.wake_delay = 1500; // Độ trễ đánh thức (1500 ms) cfg.rx_retries = 20;
radio.begin ();
radio.setDataRate (RF24_250KBPS); radio.maskIRQ (1, 1, 0); radio.enableAckPayload (); radio.setRetries (5, 5);
radio.openWritingPipe (masteraddresse);
radio.openReadingPipe (1, slaveaddresse); // Gắn ngắt vào chân 3 // Sửa đổi 1 bởi O nếu bạn muốn ngắt vào chân 2 // FALLING MODE = Pin tại LOW attachmentInterrupt (1, awUpIRQ, FALLING); }
void loop ()
{ // Không cần }
Nút chính
Node chính thức dậy sau mỗi 8 giây để yêu cầu dữ liệu từ Node nô lệ
Cách thức hoạt động: Nút chính gửi một gói "WakeUP" đến nô lệ và sau khi đợi một câu trả lời của nô lệ với dữ liệu.
Trong trường hợp của tôi, tôi sử dụng một mảng gồm hai int:
// Gói Wake UP
const int aw_packet [2] = {20, 02};
Nếu nút phụ gửi gói ACK sau khi nút chính gửi gói WakeUp:
- Thiết lập chính ở chế độ Nghe và chờ liên lạc
- Nếu giao tiếp
- Trích xuất 8 byte đầu tiên, lấy ba byte đầu tiên trong số 8 byte, nếu đây là nút ID
- Trích xuất 16 byte của cypher
- Giải mã dữ liệu
- In dữ liệu trong Serial
- Chế độ ngủ
Đối với Mã hóa AES, tôi sử dụng một khóa ở vị trí số 9.
Đây là mã của tôi cho nút Chính
#include "Arduino.h"
#include "avr / sleep.h" #include "avr / wdt.h" #include "SPI.h" #include "nRF24L01.h" #include "RF24.h" #include "Wire.h" // Thư viện ATECC608A #include "ATECCX08A_Arduino / cryptoauthlib.h" #include "AES BASIC / aes_basic.h" #define ID_NODE 255 #define AES_KEY (uint8_t) 9 ATCAIfaceCfg cfg; Trạng thái ATCA_STATUS; Đài RF24 (9, 10); const uint64_t masteraddresse = 0x1111111111; const uint64_t slaveaddresse = 0x1111111100; // Đánh thức gói tin const int aw_packet [2] = {20, 02}; // cơ quan giám sát ngắt ISR (WDT_vect) {wdt_disable (); // vô hiệu hóa cơ quan giám sát} void sleepmode () {// vô hiệu hóa ADC ADCSRA = 0; // xóa các cờ "đặt lại" khác nhau MCUSR = 0; // cho phép thay đổi, vô hiệu hóa thiết lập lại WDTCSR = bit (WDCE) | bit (WDE); // thiết lập chế độ ngắt và một khoảng WDTCSR = bit (WDIE) | bit (WDP3) | bit (WDP0); // thiết lập WDIE, và độ trễ 8 giây wdt_reset (); // thiết lập lại watchdog set_sleep_mode (SLEEP_MODE_PWR_DOWN); noInterrupts (); // dãy định thời theo sau sleep_enable (); // tắt bật màu nâu trong phần mềm MCUCR = bit (BODS) | bit (BODSE); MCUCR = bit (BODS); ngắt (); // đảm bảo lệnh tiếp theo được thực thi sleep_cpu (); // hủy bỏ chế độ ngủ để đề phòng sleep_disable (); } void setup () {Serial.begin (9600); // Nhập hằng số cho thư viện cfg.iface_type = ATCA_I2C_IFACE; // Kiểu giao tiếp -> Chế độ I2C cfg.devtype = ATECC608A; // Loại chip cfg.atcai2c.slave_address = 0XC0; // Địa chỉ I2C (giá trị mặc định) cfg.atcai2c.bus = 1; cfg.atcai2c.baud = 100000; cfg.wake_delay = 1500; // Độ trễ đánh thức (1500 ms) cfg.rx_retries = 20; radio.begin (); radio.setDataRate (RF24_250KBPS); radio.maskIRQ (1, 1, 0); radio.enableAckPayload (); radio.setRetries (5, 5); radio.openWritingPipe (slaveaddresse); radio.openReadingPipe (1, masteraddresse); } void loop () {bool rslt; // Gửi dữ liệu rslt = radio.write (& aw_packet, sizeof (aw_packet)); if (rslt) {// Bắt đầu nghe radio.startListening (); while (radio.available ()) {uint8_t answer [32]; radio.read (& answer, sizeof (answer)); uint8_t node_id [3]; uint8_t cypher [16]; memcpy (node_id, answer, 3); memcpy (cypher, answer + 3, 16); if ((int) node_id == ID_NODE) {uint8_t output [16]; ATCA_STATUS status = aes_basic_decrypt (& cfg, cypher, 16, output, AES_KEY); if (status == ATCA_SUCCESS) {Serial.println ("Dữ liệu được giải mã:"); for (size_t i = 0; i <16; i ++) {Serial.print ((char) output ); }}}}} else {Serial.println ("Không nhận được cho Gói Wakup"); } // Chế độ ngủ 8 giây sleepmode (); }
Nếu bạn có câu hỏi, tôi ở đây để trả lời nó
Bước 4: 4. Đi xa hơn
Ví dụ này đơn giản để bạn có thể cải thiện dự án này
Cải tiến:
- AES 128 là cơ bản và bạn có thể sử dụng một thuật toán khác của AES là AES CBC để an toàn hơn.
- Thay đổi mô-đun không dây (NRF24L01 bị giới hạn bởi trọng tải 23 Byte)
- …
Nếu bạn thấy cần cải thiện, hãy giải thích điều đó trên khu vực thảo luận
Bước 5: Kết luận
Tôi hy vọng bài viết này sẽ hữu ích cho bạn. Xin lỗi nếu tôi đã nhầm lẫn trong văn bản của mình nhưng tiếng Anh không phải là ngôn ngữ chính của tôi và tôi nói tốt hơn tôi viết.
Cảm ơn vì đã đọc tất cả mọi thứ.
Hãy tận hưởng nó.
Đề xuất:
Giao tiếp không dây SmartHome: Kiến thức cơ bản về MQTT: 3 bước
Giao tiếp không dây SmartHome: Khái niệm cơ bản về MQTT: Khái niệm cơ bản về MQTT: ** Tôi sẽ thực hiện một loạt bài về Tự động hóa gia đình, tôi sẽ xem xét các bước tôi đã thực hiện để tìm hiểu mọi thứ tôi đã làm trong tương lai. Tài liệu hướng dẫn này là cơ sở về cách thiết lập MQTT để sử dụng trong Tài liệu hướng dẫn trong tương lai của tôi. Chào
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: Tôi tạo một thư viện để quản lý EBYTE E32 dựa trên dòng Semtech của thiết bị LoRa, thiết bị rất mạnh mẽ, đơn giản và rẻ tiền. Bạn có thể tìm thấy 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
Phạm vi xa, 1,8 km, Giao tiếp không dây Arduino đến Arduino với HC-12.: 6 bước (có hình ảnh)
Phạm vi xa, 1,8 km, Giao tiếp không dây Arduino với Arduino Với HC-12.: Trong tài liệu hướng dẫn này, bạn sẽ học cách giao tiếp giữa các Arduinos trong một khoảng cách xa lên đến 1,8 km trong môi trường ngoài trời. HC-12 là một cổng nối tiếp không dây. mô-đun giao tiếp rất hữu ích, cực kỳ mạnh mẽ và dễ sử dụng. Đầu tiên, bạn sẽ
Giao tiếp không dây sử dụng mô-đun thu phát NRF24L01 cho các dự án dựa trên Arduino: 5 bước (có hình ảnh)
Giao tiếp không dây sử dụng mô-đun thu phát NRF24L01 cho các dự án dựa trên Arduino: Đây là hướng dẫn thứ hai của tôi về rô bốt và bộ điều khiển vi mô. Thực sự đáng kinh ngạc khi thấy rô-bốt của bạn còn sống và hoạt động như mong đợi và tin tôi rằng sẽ thú vị hơn nếu bạn điều khiển rô-bốt hoặc những thứ khác không dây với tốc độ nhanh và
Giao tiếp nối tiếp không dây bằng Bluefruit: 4 bước
Giao tiếp nối tiếp không dây sử dụng Bluefruit: Đây là hướng dẫn từng bước đơn giản để thay thế dây của bạn bằng kết nối bluetooth năng lượng thấp: Tôi đã mất một lúc để tìm ra điều này vì hầu như không có bất kỳ tài liệu nào về việc này với công nghệ năng lượng thấp bluetooth hiện đại như vậy với tư cách là Bluefrui