Անլար կոդավորված հաղորդակցություն Arduino. 5 քայլ
Անլար կոդավորված հաղորդակցություն Arduino. 5 քայլ
Anonim
Անլար կոդավորված հաղորդակցություն Arduino
Անլար կոդավորված հաղորդակցություն Arduino

Ողջույն բոլորին, Այս երկրորդ հոդվածում ես ձեզ կբացատրեմ, թե ինչպես օգտագործել Atecc608a չիպը `ձեր անլար հաղորդակցությունն ապահովելու համար: Դրա համար ես կօգտագործեմ NRF24L01+ անլար մասի և Arduino UNO- ի համար:

Միկրոչիպը ATECC608A- ն նախագծվել է MicroChip- ի կողմից և ստացել է անվտանգության բազմաթիվ գործիքներ: Օրինակ, այս չիպը կարող է պահել ECC բանալիներ, AES բանալիներ (AES 128 -ի համար) և SHA2 Hash:

Հոդվածը ՝ NRF24L01 + Arduino UNO + ATECC608A

Երկու IoT օբյեկտի միջև հաղորդակցության ընթացքում կարող են լինել բազմաթիվ հարձակումներ. Մարդը մեղմ է, տեղեկատվության պատճենը և ավելին: Այսպիսով, իմ գաղափարը շատ պարզ է.

  1. Երկու կամ ավելի IoT օբյեկտի միջև կոդավորված տվյալների օգտագործումը:
  2. Lowածր արժեքի մատակարարումներ
  3. Կարող է աշխատել Arduino UNO- ի հետ

Իմ դեպքում ես օգտագործում եմ

  • Atecc608a- ն ՝ իմ AES բանալին պահելու և իմ տվյալները գաղտնագրելու/վերծանելու համար:
  • Arduino Uno- ն որպես միկրոկոնտրոլեր
  • NRF24L01 ՝ իմ տվյալները ուղարկելու համար

Այս ծրագրի համար դուք պետք է հետևեք հետևյալ քայլերին.

  1. Կարգավորեք ATECC608A չիպը
  2. Կատարեք միացում (Master Node և Slave Node)
  3. Կոդի մաս
  4. Առաջ գնա !

«Ստեղծեք ATECC608A չիպը» առաջին քայլերի համար ես գրեցի մեկ այլ հոդված, որը բացատրում է յուրաքանչյուր քայլը հերթականությամբ: Հղումն այստեղ է ՝

Հիմա սկսի!

Պարագաներ

Այս նախագծի համար ձեզ հարկավոր է.

  • 2 Arduino UNO կամ Arduino NANO կամ Arduino Mega
  • Որոշ մետաղալարեր
  • 2 Atecc608a (յուրաքանչյուրի արժեքը 0.60 $ -ից պակաս է)
  • 2 NRF24L01+
  • 2 կոնդենսատոր (10 μF)
  • Breadboards

Հղում իմ հոդվածին, որը բացատրում է, թե ինչպես կարգավորել ATECC608A չիպը -> Ինչպես կարգավորել Atecc608a

Քայլ 1: 1. Կարգավորեք Atecc608a- ն

1. Կարգավորեք Atecc608a- ն
1. Կարգավորեք Atecc608a- ն
1. Կարգավորեք Atecc608a- ն
1. Կարգավորեք Atecc608a- ն

Ես չեմ մանրամասնի ATECC608A- ի ստեղծման համար անհրաժեշտ յուրաքանչյուր քայլ, քանի որ ես գրել եմ ամբողջական հոդված, որը բացատրում է դա անելու բոլոր քայլերը: Այն կարգավորելու համար հարկավոր է հետևել սույն հոդվածի «Քայլ 4» -ին, որը կոչվում է «2. Չիպի կազմաձևում (Atecc608a)»

Հղումը հետևյալն է. Ինչպես ստեղծել ATECC608A

Բացի այդ, դուք պետք է նույն կոնֆիգուրացիան դնեք Atecc608a- ի, գլխավոր կողմի և ստրուկ կողմի համար, այլապես չեք կարողանա գաղտնագրել ձեր տվյալները:

Գուշացում

Այս չիպը կարգավորելու համար դուք պետք է հաջորդաբար կատարեք վերը նշված հոդվածի յուրաքանչյուր քայլ: Եթե մեկ քայլ բացակայում է կամ չիպը կողպված չէ, դուք չեք կարողանա անել այս նախագիծը:

Մնացածը ՝

Դրա համար պետք է հետևել հետևյալ քայլերին

  • Ստեղծեք կազմաձևման ձևանմուշ
  • Գրեք այս կաղապարը չիպի վրա
  • Կողպեք կազմաձևման գոտին
  • Գրեք ձեր AES բանալին (128 բիթ) բնիկում
  • Կողպեք տվյալների գոտին

Քայլ 2: 2. Շղթայի ձևավորում (վարպետ և ստրուկ)

2. Շրջանի ձևավորում (վարպետ և ստրուկ)
2. Շրջանի ձևավորում (վարպետ և ստրուկ)
2. Շրջանի ձևավորում (վարպետ և ստրուկ)
2. Շրջանի ձևավորում (վարպետ և ստրուկ)

Այս նախագծում դուք կունենաք Master Node և Slave Node:

Գլխավոր հանգույցը հստակ կտպագրի ստրուկի հանգույցի ուղարկած տվյալները: Այն յուրաքանչյուր պահի կպահանջի տվյալներ ստրուկի հանգույցից:

Ստրուկի հանգույցը կլսի «ցանցը» և երբ ստանա «Պահանջել տվյալներ», այն կստեղծի, կծածկագրի և կուղարկի հիմնական հանգույցին:

Երկու կողմերի համար էլ տիրույթը և ստրուկը միացումն են նույնը.

  • Մեկ arduino Nano
  • Մեկ ATECC608A
  • Մեկ NRF24L01

Ես միացրեցի սխեման այս քայլին (տես վերևի նկարը):

Arduino UNO- ի ATECC608A- ի համար սա 8 փին է: Ես վերևում ավելացրեցի «վերևի տեսքը».

  • ARDUINO 3.3V -> PIN 8 (Atecc608a)
  • ARDUINO GND -> PIN 4 (Atecc608a)
  • ARDUINO A4 (SDL) -> PIN 5 (Atecc608a)
  • ARDUINO A5 (SCL) -> PIN 6 (Atecc608a)

NRF24L01- ի համար 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) -> միայն Slave հանգույցի համար, որը չի օգտագործվում Master ռեժիմում

Ինչու՞ օգտագործել NRF24L01- ի IRQ կապը

IRQ քորոցը շատ օգտակար է, այս քորոցը թույլ է տալիս ասել (LOW), երբ փաթեթը ստացվում է NRF24L01- ի միջոցով, այնպես որ մենք կարող ենք կցել ընդհատում այս քորոցին ՝ ստրուկի հանգույցն արթնացնելու համար:

Քայլ 3: 3. ծածկագիրը (ստրուկ և վարպետ)

3. ծածկագիրը (ստրուկ և վարպետ)
3. ծածկագիրը (ստրուկ և վարպետ)

Ստրուկի հանգույց

Ես օգտագործում եմ էներգախնայողություն ստրուկի Node- ի համար, քանի որ այն ամբողջ ժամանակ լսելու կարիք չունի:

Ինչպես է այն աշխատում. Ստրուկի հանգույցը լսեք և սպասեք «Wake UP packet» ստանալուն: Այս փաթեթը ուղարկվում է Master հանգույցի կողմից ՝ ստրուկից տվյալներ խնդրելու համար:

Իմ դեպքում ես օգտագործում եմ երկու int զանգված.

// Wake UP փաթեթ

const int wake_packet [2] = {20, 02};

Եթե իմ հանգույցը ստանա փաթեթ,

  1. արթնացիր, կարդա այս փաթեթը, եթե փաթեթը «Արթնացիր»,
  2. այն առաջացնում է տվյալներ,
  3. ծածկագրել տվյալները,
  4. ուղարկեք տվյալները վարպետին, սպասեք ACK փաթեթ,
  5. քնել.

AES կոդավորման համար ես օգտագործում եմ բանալին 9 համարի բնիկում:

Սա ստրուկի հանգույցի իմ ծածկագիրն է

#ներառել "Arduino.h" #include "avr/sleep.h" #include "avr/wdt.h"

#ներառել «SPI.h»

#ներառել «nRF24L01.h» #ներառել «RF24.h»

#ներառել «Wire.h»

// ATECC608A գրադարան

#ներառել «ATECCX08A_Arduino/cryptoauthlib.h» #ներառել «AES BASIC/aes_basic.h»

#սահմանել ID_NODE 255 -ը

#սահմանել AES_KEY (uint8_t) 9

ATCAIfaceCfg cfg;

ATCA_STATUS կարգավիճակ;

RF24 ռադիո (9, 10);

const uint64_t masteraddresse = 0x1111111111;

const uint64_t slaveaddresse = 0x1111111100;

/**

* / համառոտ Գործառույթը կատարվում է, երբ ընդհատումը սահմանվում է (IRQ LOW) * * */ void wakeUpIRQ () {while (radio.available ()) {int data [32]; radio.read (& տվյալներ, 32); if (տվյալներ [0] == 20 && տվյալներ [1] == 02) {float temp = 17.6; բոց բզզոց = 16.4;

uint8_t տվյալներ [16];

uint8_t ցիպեր տվյալներ [16];

// Կառուցեք տող ՝ իմ ամբողջ արժեքը սահմանելու համար

// Յուրաքանչյուր արժեք առանձնացված է «|» - ով: իսկ «$» նշանակում է տվյալների վերջը // ARԳՈՇԱՈՄ. Պետք է լինի 11 -ից փոքր երկարությամբ տող tmp_str_data = Լար (ID_NODE) + "|" + Լար (ջերմաստիճան, 1) + "|" + Լար (բզզոց, 1) + "$"; // չափը 11 Serial.println ("tmp_str_data:" + tmp_str_data);

tmp_str_data.getBytes (տվյալները, չափը (տվյալները));

// Գաղտնագրել տվյալները

ATCA_STATUS կարգավիճակ = aes_basic_encrypt (& cfg, data, sizeof (data), cypherdata, AES_KEY); եթե (կարգավիճակ == ATCA_SUCCESS) {երկար ռանդ = պատահական ((երկար) 10000, (երկար) 99999);

// առաջացնել UUID ՝ հիմնված երեք առաջին թվի = ID հանգույցի վրա

Լար uuid = Լար (ID_NODE) + Լար (ռանդ); // Չափը ՝ 8

uint8_t tmp_uuid [8];

uint8_t տվյալներ_ուղարկել [32];

uuid.getBytes (tmp_uuid, sizeof (tmp_uuid) + 1);

memcpy (data_to_ndnd, tmp_uuid, sizeof (tmp_uuid));

memcpy (data_to_nden + sizeof (tmp_uuid), cypherdata, sizeof (cypherdata)); // Դադարեցրեք լսել radio.stopListening ();

bool rslt;

// Ուղարկեք տվյալներ rslt = radio.write (& data_to_send, sizeof (data_to_send)); // Սկսեք լսել radio.startListening (); if (rslt) {// Ավարտի և քնի ռեժիմ Serial.println (F («Կատարված է»)); }}}}}

դատարկ կարգավորում ()

{Serial.begin (9600);

// Գրադարանի կառուցման սկիզբ

cfg.iface_type = ATCA_I2C_IFACE; // Կապի տեսակը -> I2C ռեժիմ cfg.devtype = ATECC608A; // չիպի տեսակը cfg.atcai2c.slave_address = 0XC0; // I2C հասցե (կանխադրված արժեք) cfg.atcai2c.bus = 1; cfg.atcai2c.baud = 100000; cfg.wake_delay = 1500; // Արթնացման հետաձգում (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); // Կցել ընդհատում 3 -ի կապում // Փոփոխել 1 -ը O- ով, եթե ցանկանում եք, որ ընդհատումը լինի 2 -րդ քորոցին // FALLING MODE = Pin at LOW attachInterrupt (1, wakeUpIRQ, FALLING); }

դատարկ շրջան ()

{ // Կարիք չկա }

Վարպետ հանգույց

Գլխավոր հանգույցն արթնանում է յուրաքանչյուր 8 վայրկյանում ՝ ստրուկի հանգույցից տվյալներ պահանջելու համար

Ինչպես է այն աշխատում. Գլխավոր հանգույցը «WakeUP» փաթեթ է ուղարկում ստրուկին և սպասելուց հետո ստրուկի պատասխանը տվյալներով:

Իմ դեպքում ես օգտագործում եմ երկու int զանգված.

// Wake UP փաթեթ

const int wake_packet [2] = {20, 02};

Եթե ստրուկի հանգույցը ուղարկում է ACK փաթեթ, այն բանից հետո, երբ վարպետն ուղարկում է WakeUp փաթեթ.

  1. Վարպետը կարգավորվեց Լսելու ռեժիմում և սպասեք հաղորդակցությանը
  2. Եթե հաղորդակցություն
  3. Հանել 8 առաջին բայթը, թալանել 8 բայթից երեք առաջին բայթը, եթե սա ID հանգույցն է
  4. Քաղեք 16 բայթ շիֆերը
  5. Գաղտնագրել տվյալները
  6. Տպեք տվյալները Սերիալում
  7. Քնելու ռեժիմ

AES կոդավորման համար ես օգտագործում եմ բանալին 9 համարի բնիկում:

Սա Վարպետ հանգույցի իմ ծածկագիրն է

#ներառել «Arduino.h»

#ներառել "avr/sleep.h" #include "avr/wdt.h" #include "SPI.h" #include "nRF24L01.h" #include "RF24.h" #include "Wire.h" // ATECC608A գրադարան #ներառել «ATECCX08A_Arduino/cryptoauthlib.h» #ներառել «AES BASIC/aes_basic.h» #սահմանել ID_NODE 255 #սահմանել AES_KEY (uint8_t) 9 ATCAIfaceCfg cfg; ATCA_STATUS կարգավիճակ; RF24 ռադիո (9, 10); const uint64_t masteraddresse = 0x1111111111; const uint64_t slaveaddresse = 0x1111111100; // Wake UP packet const int wake_packet [2] = {20, 02}; // դիտորդը ընդհատում է ISR- ն (WDT_vect) {wdt_disable (); // անջատել watchdog} void sleepmode () {// անջատել ADC ADCSRA = 0; // մաքրել տարբեր «վերակայման» դրոշներ MCUSR = 0; // թույլ տալ փոփոխություններ, անջատել վերականգնումը WDTCSR = բիթ (WDCE) | բիթ (WDE); // սահմանել ընդհատման ռեժիմ և միջակայք WDTCSR = բիթ (WDIE) | բիթ (WDP3) | բիթ (WDP0); // սահմանել WDIE և 8 վայրկյան ուշացում wdt_reset (); // վերականգնել դիտորդի set_sleep_mode (SLEEP_MODE_PWR_DOWN); noInterrupts (); // ժամանակային հաջորդականությունը հետևում է sleep_enable (); // անջատել brown ‐ out- ը միացնել ծրագրակազմում MCUCR = bit (BODS) | բիթ (BODSE); MCUCR = բիթ (BODS); ընդհատում (); // երաշխավորում է sleep_cpu կատարված հաջորդ հրահանգը (); // չեղյալ համարել քունը որպես նախազգուշական քուն_ընդհատել (); } void setup () {Serial.begin (9600); // Գրադարանի կառուցիչ ներդիր cfg.iface_type = ATCA_I2C_IFACE; // Կապի տեսակը -> I2C ռեժիմ cfg.devtype = ATECC608A; // չիպի տեսակը cfg.atcai2c.slave_address = 0XC0; // I2C հասցե (կանխադրված արժեք) cfg.atcai2c.bus = 1; cfg.atcai2c.baud = 100000; cfg.wake_delay = 1500; // Արթնացման հետաձգում (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; // Ուղարկել տվյալներ rslt = radio.write (& wake_packet, sizeof (wake_packet)); if (rslt) {// Սկսել լսել radio.startListening (); while (radio.available ()) {uint8_t պատասխան [32]; radio.read (& պատասխան, չափս (պատասխան)); uint8_t node_id [3]; uint8_t ցիֆեր [16]; memcpy (node_id, պատասխան, 3); memcpy (cypher, պատասխան + 3, 16); եթե ((int) node_id == ID_NODE) {uint8_t ելք [16]; ATCA_STATUS կարգավիճակ = aes_basic_decrypt (& cfg, cypher, 16, output, AES_KEY); if (կարգավիճակ == ATCA_SUCCESS) {Serial.println ("Գաղտնագրված տվյալներ."); for (size_t i = 0; i <16; i ++) {Serial.print ((char) ելք ); }}}}} այլ {Serial.println («Ack not get for Wakup Packet»); } // Քնի ռեժիմ 8 վայրկյան քնի ռեժիմ (); }

Եթե ունեք հարցեր, ես այստեղ եմ ՝ դրան պատասխանելու համար:

Քայլ 4: 4. Շարունակիր:

Այս օրինակը պարզ է, որպեսզի կարողանաք բարելավել այս նախագիծը

Բարելավումներ

  • AES 128 -ը հիմնական է, և ավելի ապահով լինելու համար կարող եք օգտագործել AES- ի այլ ալգորիթմ ՝ որպես AES CBC:
  • Փոխեք անլար մոդուլը (NRF24L01- ը սահմանափակվում է 23 բայթ բեռնվածությամբ)

Եթե տեսնում եք, որ պետք է կատարելագործվեք, բացատրեք դա քննարկման դաշտում

Քայլ 5: Եզրակացություն

Հուսով եմ, որ այս հոդվածը օգտակար կլինի ձեզ համար: Կներեք, եթե ես սխալվել եմ իմ տեքստում, բայց անգլերենը իմ հիմնական լեզուն չէ, և ես ավելի լավ եմ խոսում, քան գրում եմ:

Շնորհակալություն ամեն ինչ կարդալու համար:

Վայելիր.

Խորհուրդ ենք տալիս: