Përmbajtje:

Komunikimi i koduar me valë Arduino: 5 hapa
Komunikimi i koduar me valë Arduino: 5 hapa

Video: Komunikimi i koduar me valë Arduino: 5 hapa

Video: Komunikimi i koduar me valë Arduino: 5 hapa
Video: Как управлять несколькими серводвигателями с помощью одного потенциометра с Arduino 2024, Nëntor
Anonim
Komunikimi i koduar me valë Arduino
Komunikimi i koduar me valë Arduino

Pershendetje te gjitheve, Në këtë artikull të dytë, unë do t'ju shpjegoj se si të përdorni çipin Atecc608a për të siguruar komunikimin tuaj pa tel. Për këtë, unë do të përdor NRF24L01+ për pjesën Wireless dhe Arduino UNO.

Mikro çipi ATECC608A është projektuar nga MicroChip dhe ka marrë mjete të shumta sigurie. Për shembull, ky çip mund të ruajë çelësat ECC, çelësat AES (për AES 128) dhe SHA2 Hash.

Artikulli: NRF24L01 + Arduino UNO + ATECC608A

Gjatë një komunikimi midis dy objekteve IoT, mund të ketë sulme të shumta: Njeriu i butë, Kopja e informacionit dhe më shumë.. Pra, ideja ime është shumë e thjeshtë:

  1. Përdorimi i të dhënave të koduara midis dy ose më shumë objekteve IoT.
  2. Furnizime me kosto të ulët
  3. Mund të punojë me një Arduino UNO

Në rastin tim, unë përdor

  • Atecc608a për të ruajtur çelësin tim AES dhe për të kriptuar/deshifruar të dhënat e mia.
  • Arduino Uno si Mikrokontrollues
  • NRF24L01 për të dërguar të dhënat e mia

Ju duhet të ndiqni këto hapa për këtë projekt:

  1. Vendosni çipin ATECC608A
  2. Bëni qarkun (Nyja Master dhe Nyja e Skllevërve)
  3. Pjesa e kodit
  4. Shko me tej !

Për hapat e parë "Vendosni çipin ATECC608A", kam shkruar një artikull tjetër që shpjegon çdo hap në rregull. Lidhja është këtu:

Tani fillo!

Furnizimet

Për këtë projekt ju nevojiten:

  • 2 Arduino UNO ose Arduino NANO ose Arduino Mega
  • Disa tela
  • 2 Atecc608a (secila kushton më pak se 0.60 $)
  • 2 NRF24L01+
  • 2 kondensator (10 μF)
  • Tabelat e bukës

Lidhje me artikullin tim që shpjegon mënyrën e konfigurimit të çipit ATECC608A -> Si të konfiguroni Atecc608a

Hapi 1: 1. Konfiguroni Atecc608a

1. Vendosni Atecc608a
1. Vendosni Atecc608a
1. Vendosni Atecc608a
1. Vendosni Atecc608a

Unë nuk do të detajoj çdo hap që duhet ndjekur për të ngritur një ATECC608A sepse kam shkruar një artikull të plotë që shpjegon çdo hap për ta bërë atë. Për ta konfiguruar, duhet të ndiqni "Hapin 4" të këtij artikulli të quajtur "2. Konfigurimi i çipit (Atecc608a)"

Lidhja është: Si të krijoni një ATECC608A

Gjithashtu, duhet të vendosni të njëjtin konfigurim për Atecc608a, master side dhe slave side, përndryshe nuk do të jeni në gjendje të deshifroni të dhënat tuaja

Paralajmërim:

Për të konfiguruar këtë çip, duhet të ndiqni çdo hap të artikullit më sipër në rregull. Nëse një hap mungon ose çipi nuk është i kyçur, ju nuk do të jeni në gjendje ta bëni këtë projekt

Pjesa e mbetur:

Hapi që duhet ndjekur për këtë:

  • Krijoni një model konfigurimi
  • Shkruani këtë model në çip
  • Bllokoni zonën e konfigurimit
  • Shkruani çelësin tuaj AES (128 Bits) në një vend të caktuar
  • Bllokoni Zonën e të Dhënave

Hapi 2: 2. Dizajni i Qarkut (Master dhe Skllav)

2. Dizajni i Qarkut (Master dhe Skllav)
2. Dizajni i Qarkut (Master dhe Skllav)
2. Dizajni i Qarkut (Master dhe Skllav)
2. Dizajni i Qarkut (Master dhe Skllav)

Në këtë projekt, ju do të keni një Nyje Master dhe një Nyje Skllave.

Nyja kryesore do të printojë qartë të dhënat e dërguara nga nyja e skllavit. Do të kërkojë të dhëna nga nyja e skllavit çdo herë X.

Nyja skllevër do të dëgjojë "rrjetin" dhe kur të marrë një "Kërkesë të dhënash", ajo do t'i krijojë, do t'i kriptojë dhe do t'i dërgojë në nyjen kryesore.

Për të dyja anët, mjeshtri dhe skllavi qark janë të njëjta:

  • Një arduino Nano
  • Një ATECC608A
  • Një NRF24L01

Unë e bashkangjita qarkun në këtë hap (cf foto më lart).

Për ATECC608A në Arduino UNO, kjo është një soik 8 pin. Shtova "pamjen kryesore" më lart:

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

Për NRF24L01 tek 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) -> vetëm për nyjen skllave, nuk përdoret në modalitetin Master

Pse të përdorni pin IRQ të NRF24L01

Kodi IRQ është shumë i dobishëm, ky pin ju lejon të thoni (LOW) kur një paketë merret nga NRF24L01, kështu që ne mund t'i bashkojmë një Interrupt këtij pin për të zgjuar nyjen e skllavit.

Hapi 3: 3. Kodi (Skllavi dhe Mjeshtri)

3. Kodi (Skllavi dhe Mjeshtri)
3. Kodi (Skllavi dhe Mjeshtri)

Nyja e skllevërve

Unë përdor kursimin e energjisë për Nyjen e skllavit sepse nuk ka nevojë të dëgjojë gjatë gjithë kohës.

Si funksionon: nyja e skllavit dëgjoni dhe prisni për të marrë një paketë "Wake UP". Kjo paketë dërgohet nga nyja Master për të kërkuar të dhëna nga skllavi.

Në rastin tim, unë përdor një grup prej dy int:

// Paketa Wake UP

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

Nëse nyja ime merr një paketë,

  1. zgjohuni, lexoni këtë paketë, nëse paketa është një "Wake UP",
  2. gjeneron të dhëna,
  3. enkriptoni të dhënat,
  4. dërgoni të dhënat tek masteri, prisni një paketë ACK,
  5. fle.

Për Kriptimin AES, unë përdor një çelës në numrin e slotit 9.

Ky është kodi im për nyjen Slave

#përfshi "Arduino.h" #përfshi "avr/sleep.h" #include "avr/wdt.h"

#përfshi "SPI.h"

#përfshi "nRF24L01.h" #përfshi "RF24.h"

#përfshi "Wire.h"

// Biblioteka ATECC608A

#përfshi "ATECCX08A_Arduino/cryptoauthlib.h" #përfshi "AES BASIC/aes_basic.h"

#përcakto ID_NODE 255

#përcakto AES_KEY (uint8_t) 9

ATCAIfaceCfg cfg;

Statusi ATCA_STATUS;

Radio RF24 (9, 10);

const uint64_t masteraddresse = 0x1111111111;

const uint64_t slaveaddresse = 0x1111111100;

/**

* / shkurtër Funksioni i ekzekutuar kur vendoset ndërprerja (IRQ LOW) * * */ void wakeUpIRQ () {ndërsa (radio.disponueshme ()) {int të dhënat [32]; radio.leximi (& të dhënat, 32); nëse (të dhënat [0] == 20 && të dhëna [1] == 02) {temperatura e notimit = 17.6; human notues = 16.4;

uint8_t të dhëna [16];

uint8_t cipherdata [16];

// Ndërtoni një varg për të vendosur të gjithë vlerën time

// Çdo vlerë ndahet me një "|" dhe "$" nënkupton fundin e të dhënave // PARALAJMRIM: Duhet të jetë më pak se 11 gjatësi Vija tmp_str_data = Vargu (ID_NODE) + "|" + Vargu (temp, 1) + "|" + Varg (hum, 1) + "$"; // madhësia e 11 Serial.println ("tmp_str_data:" + tmp_str_data);

tmp_str_data.getBytes (të dhëna, madhësia e (të dhënave));

// Kriptoni të dhënat

Statusi ATCA_STATUS = aes_basic_encrypt (& cfg, të dhëna, madhësia e (të dhënave), cipherdata, AES_KEY); nëse (statusi == ATCA_SUCCESS) {rand i gjatë = i rastësishëm ((i gjatë) 10000, (i gjatë) 99999);

// gjeneroni një UUID bazuar në tre numrin e parë = nyjen ID

String uuid = String (ID_NODE) + String (rand); // Madhësia 8

uint8_t tmp_uuid [8];

uint8_t të dhëna_ për të dërguar [32];

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

memcpy (të dhëna_ për të dërguar, tmp_uuid, madhësia (tmp_uuid));

memcpy (të dhënat_për_dërguar + madhësia (tmp_uuid), cipherdata, madhësia (cypherdata)); // Ndaloni dëgjimin e radios.stopListening ();

bool rslt;

// Dërgoni të dhëna rslt = radio.write (& data_to_send, sizeof (data_to_send)); // Filloni të dëgjoni radio.startListening (); if (rslt) {// Fundi dhe modaliteti i fjetjes Serial.println (F ("U krye")); }}}}}

void setup ()

{Serial.fillo (9600);

// Filloni konstruktorin për bibliotekën

cfg.iface_type = ATCA_I2C_IFACE; // Lloji i komunikimit -> Mënyra I2C cfg.devtype = ATECC608A; // Lloji i çipit cfg.atcai2c.slave_adresa = 0XC0; // I2C adresa (vlera e paracaktuar) cfg.atcai2c.bus = 1; cfg.atcai2c.baud = 100000; cfg.vonesa e zgjimit = 1500; // Vonesa e zgjimit (1500 ms) cfg.rx_retries = 20;

radio.filloj ();

radio.setDataRate (RF24_250KBPS); radio.maskIRQ (1, 1, 0); radio.enableAckPayload (); radio.setRetries (5, 5);

radio.hapurShkrimPub (masteraddresse);

radio.hapurReadingPipe (1, slaveaddresse); // Bashkëngjitni ndërprerjen në kunjin 3 // Ndryshoni 1 me O nëse doni ndërprerjen në kunjin 2 // M FNDSIA E RALLNDSIS = Kunja në LOW attachInterrupt (1, wakeUpIRQ, FALLING); }

lak void ()

{// Nuk ka nevojë}

Master Nyje

Nyja kryesore zgjohet çdo 8 sekonda për të kërkuar të dhëna nga Nyja e skllavit

Si funksionon: Nyja kryesore dërgoni një paketë "WakeUP" te skllavi dhe pasi prisni një përgjigje të skllavit me të dhëna.

Në rastin tim, unë përdor një grup prej dy int:

// Paketa Wake UP

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

Nëse nyja skllevër dërgon një paketë ACK pasi master dërgoi një paketë WakeUp:

  1. Master i konfiguruar në modalitetin Listen dhe prisni një komunikim
  2. Nëse komunikimi
  3. Nxirrni 8 bajtët e parë, plaçkitni tre bajtët e parë nga 8 bajtët, nëse kjo është nyja ID
  4. Nxjerr 16 byte ciferi
  5. Dekriptoni të dhënat
  6. Shtypni të dhënat në Serial
  7. Mënyra e gjumit

Për Kriptimin AES, unë përdor një çelës në numrin e slotit 9.

Ky është kodi im për nyjen Master

#përfshi "Arduino.h"

#include "avr/sleep.h" #include "avr/wdt.h" #include "SPI.h" #include "nRF24L01.h" #include "RF24.h" #include "Wire.h" // biblioteka ATECC608A #përfshi "ATECCX08A_Arduino/cryptoauthlib.h" #përfshi "AES BASIC/aes_basic.h" #përcakto ID_NODE 255 #përcakto AES_KEY (uint8_t) 9 ATCAIfaceCfg cfg; Statusi ATCA_STATUS; Radio RF24 (9, 10); const uint64_t masteraddresse = 0x1111111111; const uint64_t slaveaddresse = 0x1111111100; // Zgjohuni pakon const int wake_packet [2] = {20, 02}; // qen mbikëqyrës ndërpret ISR (WDT_vect) {wdt_disable (); // çaktivizo vëzhguesin} void sleepmode () {// çaktivizo ADC ADCSRA = 0; // pastroni flamuj të ndryshëm të "rivendosjes" MCUSR = 0; // lejoni ndryshimet, çaktivizoni rivendosjen WDTCSR = bit (WDCE) | bit (WDE); // vendosni modalitetin e ndërprerjes dhe një interval WDTCSR = bit (WDIE) | bit (WDP3) | bit (WDP0); // vendos WDIE, dhe 8 sekonda vonesë wdt_reset (); // rivendosni set_sleep_mode të rojes (SLEEP_MODE_PWR_DOWN); joNdërpret (); // sekuenca e kohës ndjek sleep_enable (); // çaktivizo aktivizimin e daljes në ngjyrë kafe në softuerin MCUCR = bit (BODS) | bit (BODSE); MCUCR = bit (BODS); ndërpret (); // garanton udhëzimin tjetër të ekzekutuar sleep_cpu (); // anuloni gjumin si një masë paraprake sleep_disable (); } void setup () {Serial.begin (9600); // Nis konstruktorin për bibliotekën cfg.iface_type = ATCA_I2C_IFACE; // Lloji i komunikimit -> Mënyra I2C cfg.devtype = ATECC608A; // Lloji i çipit cfg.atcai2c.slave_adresa = 0XC0; // I2C adresa (vlera e paracaktuar) cfg.atcai2c.bus = 1; cfg.atcai2c.baud = 100000; cfg.vonesa e zgjimit = 1500; // Vonesa e zgjimit (1500 ms) cfg.rx_retries = 20; radio.filloj (); radio.setDataRate (RF24_250KBPS); radio.maskIRQ (1, 1, 0); radio.enableAckPayload (); radio.setRetries (5, 5); radio.hapurShkrimiPub (slaveaddresse); radio.hapurReadingPipe (1, masteraddresse); } void loop () {bool rslt; // Dërgo të dhëna rslt = radio.write (& pack_packet, sizeof (wake_packet)); if (rslt) {// Filloni të dëgjoni radio.startListening (); ndërsa (radio.disponueshme ()) {uint8_t përgjigje [32]; radio.leximi (& përgjigja, madhësia e (përgjigjes)); uint8_t nyja_id [3]; uint8_t cifër [16]; memcpy (nyja_id, përgjigje, 3); memcpy (cifër, përgjigje + 3, 16); nëse ((int) node_id == ID_NODE) {uint8_t dalje [16]; Statusi ATCA_STATUS = aes_basic_decrypt (& cfg, cypher, 16, output, AES_KEY); if (statusi == ATCA_SUCCESS) {Serial.println ("Të dhënat e deshifruara:"); për (madhësia_t i = 0; i <16; i ++) {Serial.print ((char) dalja ); }}}}} tjetër {Serial.println ("Ack not marrë për Wakup Packet"); } // Mënyra e gjumit 8 sekonda modaliteti i gjumit (); }

Nëse keni pyetje, unë jam këtu për t'iu përgjigjur

Hapi 4: 4. Shkoni më tej

Ky shembull është i thjeshtë kështu që ju mund ta përmirësoni këtë projekt

Përmirësimet:

  • AES 128 është bazë dhe ju mund të përdorni një algoritëm tjetër të AES si AES CBC për të qenë më i sigurt.
  • Ndryshoni modulin pa tel (NRF24L01 është i kufizuar nga një ngarkesë prej 23 Bajt)

Nëse shihni përmirësim, shpjegojeni atë në fushën e diskutimit

Hapi 5: Përfundimi

Shpresoj se ky artikull do të jetë i dobishëm për ju. Më falni nëse kam gabuar në tekstin tim, por anglishtja nuk është gjuha ime kryesore dhe flas më mirë sesa shkruaj.

Faleminderit që lexuat gjithçka.

Shijoje.

Recommended: