Programowanie mikrokontrolerów MOTEINO R6 odbywa się identycznie, jak modułów Arduino i ich klonów oraz mikrokontrolerów ESP8266. Do programowania wykorzystujemy program Arduino IDE. Program pobieramy z oficjalnej strony https://www.arduino.cc/en/Main/Software i instalujemy. Na dzień pisania niniejszego artykułu dostępna była wersja 1.8.10 Arduino IDE i dalszy opis konfiguracji środowiska Arduino IDE odnosi się do tej wersji.

Po zainstalowaniu Arduino IDE uruchamiamy program. Musimy teraz dodać mikrokontrolery innych producentów, abyśmy mogli je programować. Klikamy na Plik >> Preferencje. W otwartym oknie klikamy na przycisk [1] i w okienku [2] wpisujemy poniższe adresy URL definicji modułów ESP8266 oraz MOTEINO:

https://arduino.esp8266.com/stable/package_esp8266com_index.json
https://lowpowerlab.github.io/MoteinoCore/package_LowPowerLab_index.json

Następnie uruchamiamy menadżera płytek z menu Narzędzia >> Płytka: xxxxx >> Menadżer płytek. W polu wyszukiwania wpisujemy słowo Moteino i instalujemy dwie definicje płytek jak na poniższym ekranie:

Identycznie instalujemy definicje płytek mikrokontrolerów opartych na ESP8266 wpisując w polu wyszukiwania słowo ESP8266. I tu ważna uwaga: wybieramy wersję definicji 2.5.0. Na wyższych wersjach definicji płytek ESP8266 kompilacje oparte o biblioteki SUPLA nie będą działać poprawnie. Ze względu na instalację niższej dostępnej definicji, oprogramowanie Arduino IDE będzie nam pokazywało co jakiś czas komunikat o dostępności aktualizacji płytek. Nie pozwalamy aktualizować definicji dla mikrokontrolerów ESP8266.

Programy pisane w środowisku Arduino IDE wykorzystują gotowe biblioteki funkcji odpowiadające za poprawne działanie np. czujników lub elementów wykonawczych podłączonych do naszego mikrokontrolera. Biblioteki możemy zainstalować na dwa sposoby:

  1. W Arduino IDE menu Narzędzia >> Zarządzaj bibliotekami. W polu wyszukiwania wpisujemy nazwę potrzebnej biblioteki i instalujemy ją.
  2. Pobieramy potrzebną bibliotekę ze źródła (najczęściej z repozytorium GitHub), rozpakowujemy plik *.zip i folder z biblioteką kopiujemy do Dokumenty\Arduino\libraries (taka struktura folderów w systemie Windows 10 została utworzona przez instalator Arduino IDE).

Ja preferuję pierwszy sposób wyszukując potrzebne biblioteki w menadżerze bibliotek po ich nazwie. Dopiero kiedy menadżer bibliotek nie znajduje konkretnej potrzebnej biblioteki, pobieram ją ręcznie.

Do zaprogramowania mikrokontrolera MOTEINO R6 niezbędny jest jeszcze konwerter USB – UART FTDI pracujący w logice 3.3 V (konwerter musi obsługiwać linię DTR/RTS). Doskonale sprawdza się taki model. Możemy podłączyć go bezpośrednio do MONTEINO R6 bez użycia przewodów (przed podłączeniem do portu USB komputera należy upewnić się, że konwerter jest poprawnie podłączony do płytki MOTEINO R6). W celu kalibracji pomiaru napięcia baterii niezbędne będą również przewody (4 szt.) „męsko – żeńskie” (przy użyciu proponowanego konwertera).

PROGRAM

Jeśli mamy przygotowane środowisko oraz niezbędny sprzęt, możemy przystąpić do wgrania programu oraz kalibracji układu pomiaru napięcia zasilania.

/*
T/H Transmiter RB-10
Copyright (C) 2019 Robert Błaszczak

Niniejszy program jest wolnym oprogramowaniem; możesz go 
rozprowadzać dalej i/lub modyfikować na warunkach Powszechnej
Licencji Publicznej GNU, wydanej przez Fundację Wolnego
Oprogramowania - według wersji 2-giej tej Licencji lub którejś
z późniejszych wersji. 
Niniejszy program rozpowszechniany jest z nadzieją, iż będzie on 
użyteczny - jednak BEZ JAKIEJKOLWIEK GWARANCJI, nawet domyślnej 
gwarancji PRZYDATNOŚCI HANDLOWEJ albo PRZYDATNOŚCI DO OKREŚLONYCH 
ZASTOSOWAŃ. W celu uzyskania bliższych informacji - Powszechna 
Licencja Publiczna GNU. 
Z pewnością wraz z niniejszym programem otrzymałeś też egzemplarz 
Powszechnej Licencji Publicznej GNU (GNU General Public License);
jeśli nie - napisz do Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA.
*/

#include <Wire.h>                         //Zawarty w Arduino IDE (www.arduino.cc)
#include <SPI.h>                          //Zawarty w Arduino IDE (www.arduino.cc)
#include <RFM69_ATC.h>                    //Pobierz z: https://github.com/lowpowerlab/rfm69
#include <SPIFlash.h>                     //Pobierz z: https://github.com/lowpowerlab/spiflash
#include "Adafruit_Si7021.h"              //Pobierz z: https://github.com/adafruit/Adafruit_Si7021
#include <LowPower.h>                     //Pobierz z: https://github.com/lowpowerlab/lowpower

#define NODEID 1                          // Unikalny numer transmitera (1 - 6) pracującego w sieci o takim samym ID, który jest jednocześnie numerem czujnika w SUPLA Cloud.
#define NETWORKID 100                     // Numer sieci (1 - 254) w której działą bramka RB-10G oraz inne transmitery. Bramka oraz max. 6 transmiterów musi działać w sieci o takim samym ID.
#define GATEWAYID 1                       // Numer bramki (0 - 254), do której łączy się transmiter.

#define FREQUENCY RF69_868MHZ             //Jeśli posiadasz moduł radiowy pracujący z inną częstotliwością zamień parametr na RF69_433MHZ lub RF69_915MHZ.
//#define IS_RFM69HW_HCW                  //Usuń zacznik komentarza, jeśli posiadasz moduł radiowy w wersji RFM69HW/HCW.
#define ENCRYPTKEY "sampleEncryptKey"     //Klucz kodowania - 16 znaków (ani mniej, ani więcej) - identyczny w bramce RB-10G i we wszystkich transmiterach.

#define ENABLE_ATC                        //Wstaw znacznik komentarza jeśli chcesz wyłączyć automatyczną kontrolę transmisji (ATC).
#define ATC_RSSI -80                      //Poziom sygnału radiowego (odcięcie) dla ATC.

period_t sleepTime = SLEEP_4S;            //Zdefiniowany czas uśpienia transmitera 4 sekundy (zgodnie z LowPower library (LowPower.h)).
#define SEND_LOOPS 13                     //Ilość pętli uśpienia transmitera (np. 4 sekundy * 15 = 60 sekund). Ilość pętli należy dobrać do konkretnej płytki Monteino.
#define BATT_READ_LOOPS SEND_LOOPS * 30   //Ilość pętli, po których wykonywany jest pomiar napięcia na baterii (np. 60 sekund * 30 = 30 minut).

//#define SERIAL_ENABLE                   //Usuń znaki komentarza '//' aby włączyć wyświetlanie na porcie szeregowym.

#define BATT0 730                         //Odczytana wartość napięcia BATTx poniżej której poziom baterii ustawiany jest na wartość 0 (3.10V).
#define BATT1 1002                        //Odczytana wartość napięcia BATTx poniżej której poziom baterii ustawiany jest na wartość 1 (3.20V).
#define BATT2 1008                        //Odczytana wartość napięcia BATTx poniżej której poziom baterii ustawiany jest na wartość 2 (3.25V).

#ifdef SERIAL_ENABLE
  #define SERIAL_BAUD 115200
  #define SP(input) {Serial.print(input);}
  #define SPln(input) {Serial.println(input);}
  #define SFLUSH() {Serial.flush();}
#else
  #define SERIAL_BAUD 115200
  #define SP(input);
  #define SPln(input);
  #define SFLUSH();
#endif

RFM69_ATC radio;
SPIFlash flash(SS_FLASHMEM, 0xEF30);
Adafruit_Si7021 Si7021 = Adafruit_Si7021();
char Tstr[10];
char Hstr[10];
char Bstr[10];
double T,H,B;
char buffer[60];


void setup() {
  Serial.begin(SERIAL_BAUD);

  radio.initialize(FREQUENCY, NODEID, NETWORKID);
  #ifdef IS_RFM69HW_HCW
    radio.setHighPower();
  #endif
  radio.encrypt(ENCRYPTKEY);
  radio.enableAutoPower(ATC_RSSI);
  sprintf(buffer, "T/H SUPLA TRANSMITER RB-10 %d MHz.", FREQUENCY==RF69_433MHZ ? 433 : FREQUENCY==RF69_868MHZ ? 868 : 915);
  SPln(buffer);
  Wire.begin();
  Wire.setClock(400000);
  Si7021.begin();
  if (flash.initialize()) flash.sleep();

  for (uint8_t i=0; i<=A5; i++)
  {
    if (i == RF69_SPI_CS) continue;
    if (i == SS_FLASHMEM) continue;
    pinMode(i, OUTPUT);
    digitalWrite(i, LOW);
  }
  pinMode(A1, INPUT);
  SFLUSH();
}

char input = 0;
unsigned long sendLoops = 0;
unsigned long battReadLoops = 0;
word Battery1024 = 0;
byte BatteryLevel = 0;
byte sendLen;


void loop() {
  if (battReadLoops--<=0) {
    ReadBattery();
    battReadLoops = BATT_READ_LOOPS-1;
  }
  
  if (sendLoops--<=0) {
    sendLoops = SEND_LOOPS-1;
    
    T = Si7021.readTemperature();
    H = Si7021.readHumidity();
    dtostrf(T, 3, 2, Tstr);
    dtostrf(H, 3, 2, Hstr);
    dtostrf(BatteryLevel, 0, 0, Bstr);
    sprintf(buffer, "%s|%s|%s", Tstr, Hstr, Bstr);

    sendLen = strlen(buffer);
    radio.sendWithRetry(GATEWAYID, buffer, sendLen);
    SP("Wysłane dane: "); SP(buffer); SPln();
  }
  
  if (radio.receiveDone()) {
    SPln();
  }
  
  SFLUSH();
  flash.sleep();
  radio.sleep();
  
  LowPower.powerDown(sleepTime, ADC_OFF, BOD_OFF);
  
  SPln("SLEEP");
}


void ReadBattery() {
  unsigned int readings = 0;

  analogWrite(A0, 1024);
  for (byte i = 0; i < 6; i++)
    readings += analogRead(A1);
  analogWrite(A0, 0);

  Battery1024 = (readings / 3);

  if (Battery1024 >= BATT2) {
  BatteryLevel = 3;
  }
  else if (Battery1024 < BATT2 && Battery1024 >= BATT1) {
    BatteryLevel = 2;
  }
  else if (Battery1024 < BATT1 && Battery1024 >= BATT0) {
    BatteryLevel = 1;
  }
  else if (Battery1024 < BATT0) {
    BatteryLevel = 0;
  }
  SP("BATTx: "); SP(Battery1024); SP(" | Poziom baterii (0 - 3): ");SPln(BatteryLevel);
}

Powyższy kod programu jest opatrzony komentarzami, więc nie powinno być problemu z jego interpretacją. Aby zaprogramować nasz mikrokontroler, w Arduino IDE wybieramy płytkę Moteino / Moteino USB i wybieramy właściwy port COM przypisany do naszego konwertera USB – UART FTDI.

Osobnego omówienia wymaga proces kalibracji pomiaru napięcia zasilania oraz dobrania interwału pomiaru temperatury i wilgotności. Konieczność kalibracji wynika z tolerancji elementów elektronicznych (rezystorów). Do kalibracji najwygodniej użyć regulowanego zasilacza stabilizowanego (zakres 2.0 – 5.0 V) oraz multimetru cyfrowego.
Podłączamy zmontowany układ transmitera do konwertera USB – UART FTDI za pomocą 4 przewodów z pominięciem zasilania 3.3 V. Połączenie powinno wyglądać w ten sposób:

Do zacisków baterii podłączamy zasilacz stabilizowany z ustawionym napięciem 3.6 V i podłączamy konwerter do portu USB komputera. Modyfikujemy zmienne konfiguracyjne programu w następujący sposób:

#define SEND_LOOPS 1
#define BATT_READ_LOOPS SEND_LOOPS * 1

oraz usuwamy komentarz (znaki //) w wierszu 43 aby włączyć komunikację do monitora portu szeregowego. W Arduino IDE włączamy monitor portu szeregowego ustawiony na 115200 oraz zaznaczamy opcję Pokaż znacznik czasu. Następnie wgrywamy program ze zmodyfikowanymi zmiennymi. W monitorze portu szeregowego powinniśmy widzieć odczyty temperatury, wilgotności oraz poziomu baterii (0 – 3) i wartości mierzonej na wejściu analogowym (BATTx):. Zmieniamy napięcie zasilania na 3.25 V i zapisujemy wartość BATTx, następnie obniżamy napięcie zasilania do 3.20 V i zapisujemy wartość BATTx. Trzeci krok to obniżenie napięcia zasilania do wartości 3.10 V i zapisanie wartości BATTx. Zapisane wartości wpisujemy odpowiednio w zmienne BATT2, BATT1 i BATT0 w liniach 47 – 45 i ponownie wgrywamy program do MOTEINO. Sprawdzamy czy odczytywany poziom baterii w skali 0 – 3 jest zgodny z naszymi założeniami.

Dostosowanie interwału wysłania danych pomiarowych jest znacznie prostsze. Modyfikujemy zmienne SEND_LOOPS na wartość 13 oraz BATT_READ_LOOPS SEND_LOOPS na * 30 i wgrywamy ponownie program. W monitorze portu szeregowego z włączonym znacznikiem czasu sprawdzamy, czy interwał 13 daje odczyty co ok. 1 minutę. U mnie te ustawienia oscylowały na 13 i 14 w zależności od płytki MOTEINO (płytki nie mają zegara czasu rzeczywistego, stąd możliwe są odchyły).
Po tej kalibracji możemy wyłączyć komunikację z monitorem portu szeregowego poprzez dodanie znaków komentarza w wierszu 43 i ostatecznie wgrać program do mikrokontrolera. Wyłączenie komunikacji ma delikatny wpływ na niższy pobór energii przez mikrokontroler.

Kod programu do pobrania: https://download.blaszczak.pl/?dir=SUPLA/RB-10.

<<< CZĘŚĆ 1 <<< <<< CZĘŚĆ 3 <<<
Spodobał Ci się artykuł? Udostępnij go.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *