23. 4. 2017

WeMos D1 mini a NRF24l01


Dnes jsem řešila, jak k WeMos D1 připojit modul NRF24l01. Na internetu se na tohle ptá spousta lidí, ale našla jsem hlavně odpovědi typu "to nejde", "použij jen esp", nebo "je blbost používat nrf s esp" a pod. Žádná použitelná odpověď.
A moje odpověď zní, jde to.

WeMos D1 mini

Proč?

A proč vlastně chceme použít ESP s NRF? Třeba jako gateway do internetu pro domácí síť vlastních senzorů a zařízení komunikujících přes NRF které má malou spotřebou oproti nenažranosti ESP.

Bez další omáčky a teorie přejdu rovnou k věci.

Vezmeme si dva moduly NRF24l01 s arduinem z předchozího článku a místo jednoho Arduina si zapojíme WeMos D1 mini.

Knihovnu RF24 od uživatele TMRh20 stáhneme v manažeru knihoven, nebo na GitHubu. Testováno s verzí knihovny 1.1.7. Novější snad budou fungovat stejně.

NRF24l01


Aby jsme mohli poslat kod do WeMos D1, potřebujeme si do IDE nainstalovat novou desku. Návod na přidání desky wemos D1 a všech ostatních ESP8266 je pěkně popsaný na webu arduino návody, takže to opisovat asi ani nemá smysl.

Teď si zapojíme jedno NRF na WeMos.

NRF24l01
WeMos D1 mini

Zapojíme si modul NRF s WeMos podle tabulky. Opět pozor napájet musíme jen 3,3V, ale logika může být 3,3 až 5V. Nebo k zapojení a napájení můžeme použít napájecí modul zmíněný už minule.
A jak jsem psala minule, na testování to stačí. Pro vyšší výkony je lepší mít externí zdroj napětí 3,3V pro NRF.
napájecí modul pro NRF24l01

NRF24L01WeMos D1
GNDGND
Vcc3,3V
CED2 = GPIO4
CSD8 = GPIO15
MOSID7 = GPIO13
MISOD6 = GPIO12
SCKD5 = GPIO14


Po zapojení se můžeme přesunout k programu.

Vysílač na WeMos D1

Změna kódu oproti minule je v podstatě jen v nastavení čísel pinů CE a CS, před čísla pinů je nutné přidat písmeno "D" jako digitální, a nebo použít samostatné číslo podle GPIO pinu.

V IDE si vybereme desku, nastavíme CPU frekvenci 80Mhz, flash size 4M, Upload speed 921600 a port. Mělo by to být už přednastavený, ale já tam měla jinou rychlost uploadu a ten pokaždé selhal.
nastavení WeMos D1 v IDE pro upload kodu

#include <SPI.h>
#include <ESP8266WiFi.h>
#include "nRF24L01.h"
#include "RF24.h"

//*** wemos d1
#define CE D2 
#define CS D8
//MOSI = D7 = GPIO 13
//MISO = D6 = GPIO 12
//SCK = D5 = GPIO 14
//CE = D2 = GPIO 4
//CS = D8 = GPIO 15
//VCC = 3,3V!
//***

RF24 radio(CE, CS);

// nastavíme si adresy a kanál vysílání
const byte vysilac[] = "TX001";
const byte prijimac[] = "RX001";
int kanal = 66;

void setup(void) {
  Serial.begin(9600);
  radio.begin();

  // nastavení rychlosti komunikace
  // možnosti jsouRF24_250KBPS, RF24_1MBPS, RF24_2MBPS
  radio.setDataRate(RF24_1MBPS);
  //kanál na kterém budeme komunikovat
  radio.setChannel(kanal);

  // TX & Rx addr for reading
  radio.openWritingPipe(prijimac);
  radio.openReadingPipe(1, vysilac);
  radio.startListening();
  radio.printDetails();

  // nastavení výkonu nRF modulu,
  // možnosti jsou RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH and RF24_PA_MAX,
  // pro HIGH a MAX je nutný externí 3,3V zdroj
  radio.setPALevel(RF24_PA_MIN);
}

// něco proměnných
int len = 40; // délka zprávy kterou očekáváme
char MyCon[40];
char gotmsg[40];
int poradi = 1;
bool state = false;
int prvni = 0;
String druhy = "";
long startmillis;
long endmillis;

void loop(void) {
  //radio.stopListening();
  if (!state) {
    //radio.openWritingPipe(pipe);
    Serial.println("odesilam");
    startmillis = millis();
    //vysílání
    // TX & Rx addr for transmiting
    radio.openWritingPipe(vysilac);
    radio.openReadingPipe(0, prijimac);
    radio.stopListening();

    sprintf(MyCon, "%i:%s:%i:", poradi, "kanal", kanal);
    radio.write(&MyCon, sizeof(MyCon)); // odeslání zprávy

    Serial.println(MyCon);//***
    poradi++;
    Serial.println("odeslano");
    state = true;
    Serial.println("cekam na odpoved");

    // příjímání
    // TX & Rx addr for reading
    radio.openWritingPipe(prijimac);
    radio.openReadingPipe(1, vysilac);
    radio.startListening();
  }

  while (state) {
    if (radio.available()) {
      //Serial.println("radio available"); // příjem
      radio.read( &gotmsg, len);

      prvni = atoi(strtok(gotmsg, ":"));
      druhy = strtok(NULL, ":");

      Serial.print("mam odpoved: ");
      Serial.print(prvni);Serial.print(", ");
      Serial.println(druhy);
      state = false;
    }

    // timeout
    endmillis = millis() - startmillis;
    if ((endmillis >= 1000) && (state)) {
      Serial.println("timeout");
      state = false;
    }
  }

  Serial.print("delka komunikace je ");
  Serial.print(endmillis);
  Serial.println("ms");
  delay(2000);
} 
  

Přijímač na Arduinu

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"

//*** arduino nano
#define CE 9
#define CS 10
//MOSI = 11
//MISO = 12
//SCK = 13
//VCC = 3,3V!
//**

RF24 radio(CE, CS);

// adresy a kanál
const byte vysilac[] = "TX001";
const byte prijimac[] = "RX001";
int kanal = 66;

void setup(void) {
  Serial.begin(115200);
  radio.begin();

  // nastavení rychlosti komunikace
  // možnosti jsouRF24_250KBPS, RF24_1MBPS, RF24_2MBPS
  radio.setDataRate(RF24_1MBPS);
  //kanál na kterém budeme komunikovat
  radio.setChannel(kanal);

  // TX & Rx addr for reading
  radio.openWritingPipe(prijimac);
  radio.openReadingPipe(1, vysilac);
  radio.startListening();
  //radio.printDetails();

  // nastavení výkonu nRF modulu,
  // možnosti jsou RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH and RF24_PA_MAX,
  // pro HIGH a MAX je nutný externí 3,3V zdroj
  radio.setPALevel(RF24_PA_MIN);
  Serial.println("rdy");
}

// něco proměnných
int len = 40;
char MyCon[40]; //***
char gotmsg[40];
bool state = false;
int prvni = 0;
String druhy = "";
int treti = 0;

void loop(void) {
  //Serial.print("state ");Serial.println(state);
  if (!state) {
    if (radio.available()) {
      Serial.println("radio available");
      while (radio.available()) {
        radio.read( &gotmsg, len );

        prvni = atoi(strtok(gotmsg, ":"));
        String druhy = strtok(NULL, ":");
        int treti = atoi(strtok(NULL, ":"));

        Serial.print("mam zpravu: ");
        Serial.print(prvni);Serial.print(", ");
        Serial.print(druhy);Serial.print(": ");
        Serial.println(treti);
        state = true;
      }
    }
  }

  if (state) {
    // TX & Rx addr for transmiting
    radio.openWritingPipe(vysilac);
    radio.openReadingPipe(0, prijimac);
    radio.stopListening();
    delay(60);// pauza před odesláním 
    //aby se druhý modul stihl přepnout pro příjem

    // odeslat odpoved
    Serial.println("odpovidam");
    sprintf(MyCon, "%i:%s:", prvni, "OK");
    Serial.println(MyCon);
    radio.write(&MyCon, strlen(MyCon));
    state = false;
    Serial.println("odpoved odeslana");

    // a zase přepnout na příjem
    // TX & Rx addr for reading
    radio.openWritingPipe(prijimac);
    radio.openReadingPipe(1, vysilac);
    radio.startListening();
  }
}


Funkce je naprosto stejná jak v předchozím článku, takže to už nebudu přepisovat.

Nakonec ještě přihodím sketche ke stažení z mého google disku. Plus odkaz na můj e-shop kde si moduly můžete zakoupit NRF24l01, nebo NRF24l01 +PA LNA s vyšším dosahem.

Žádné komentáře:

Okomentovat