Czujniki kontaktronowe np. poczty lowPower ver 868MHz pod bramkę

QLQ
Posts: 2512
Joined: Sun Sep 03, 2017 9:13 am

Post

Mam dobre wieści :)
Na gorąco chcę Was poinformować , że właśnie wstępnie zrobiłem jak w temacie czujnik działający na Moteino - czyli z bardzo małym poborem prądu pod skrzynkę na listy - mam tu na myśli zasilanie z bateryjne / akku. Zmodyfikowałem kod nadajnika @Robert Błaszczak plus moje wypociny z fragmentem kodu czytającego stan pinu A2 (docelowo będzie więcej pinów pod np czujniki kontaktronowe ).
Sprzęt działa - pin A2 bez VCC3,3V - stan "0" podanie VCC3.3V na pin A2 - stan "1".

Wiem , że pewnie dla wielu z Was zaawansowanych programistów jest napisanie czegoś takiego bardzo proste, ja natomiast dopiero raczkuje w tym temacie i się uczę ale sprawia mi to ogromną frajdę - jestem wręcz uzależniony od Supli (@pzygmunt czy jest jakaś terapia odwykowa ? :D :lol: )

Ok - do rzeczy poniżej screen oraz kod nadajnika, niestety jeszcze teraz muszę wygłówkować jak

Code: Select all

 "status" 
wlepić do bramki w

Code: Select all

SuplaDevice.addSensorNO(mail_sensor);
Clip.jpg
.
Kod nadajnika 868MHz:

Code: Select all

/*
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 <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 101                     // 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 2                       // 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 "qwertyuiopasdfgh"     //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 1
    #define BATT_READ_LOOPS SEND_LOOPS * 1
  //#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 MAIL_READ_LOOPS SEND_LOOPS * 1
#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

//#######################################################################
#define mail_sensor A2 //  - nr pinu czujnika - w moteino oznzaczony "A2"
//#######################################################################



RFM69_ATC radio;
SPIFlash flash(SS_FLASHMEM, 0xEF30);

char Mstr[10];
char Bstr[10];
double B,M;
char buffer[60];
int status = HIGH;
int32_t retries = 0;

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, "| Skrzynka pocztowa | SUPLA TRANSMITER R@F %d MHz.", FREQUENCY==RF69_433MHZ ? 433 : FREQUENCY==RF69_868MHZ ? 868 : 915);
  SPln(buffer);
  Wire.begin();
  Wire.setClock(500000);
 
  
  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;
unsigned long mailReadLoops =0;
word Battery1024 = 0;
byte BatteryLevel = 0;
word newstatus;
byte sendLen;


void loop() {

ReadMail();
  
  if (battReadLoops--<=0) {
    ReadBattery();
    battReadLoops = BATT_READ_LOOPS-1;
  }
 if (mailReadLoops--<=0) {
    ReadMail();
    mailReadLoops = MAIL_READ_LOOPS-1;
  }
  
  if (sendLoops--<=0) {
    sendLoops = SEND_LOOPS-1;

     dtostrf(BatteryLevel, 0, 0, Bstr);
     dtostrf(status, 0, 0, Mstr);
       
    sprintf(buffer, "%s|%s", Bstr, Mstr);

    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 ReadMail(){
  int newstatus = digitalRead(mail_sensor);
    if (((newstatus == HIGH) ? "1" : "0")) {       
        status = newstatus;
    } 
    else if (--retries == 0) {  
        status = newstatus;
  	}
  SP("STAN_SKRZYNKI:  "); SP(newstatus); 
}

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);
}
You do not have the required permissions to view the files attached to this post.
Last edited by QLQ on Sat Nov 30, 2019 10:57 am, edited 2 times in total.
jak coś nie działa to włącz zasilanie.....
User avatar
pzygmunt
Posts: 20302
Joined: Tue Jan 19, 2016 9:26 am
Location: Paczków
Been thanked: 59 times

Post

Brawo :)
SUPLA.... Nareszcie w domu.
QLQ
Posts: 2512
Joined: Sun Sep 03, 2017 9:13 am

Post

Jest dobrze , jest progres :D :o :roll: Nadajnik nadaje wartość "1" bramka odbiera "1" , nadajnik nadaje "0" bramka ładnie odbiera "0".
(przyjmijmy na razie że: 0 - nie ma poczty , 1 jest poczta)
.
Clip_2.jpg
Jak teraz ""0","1" wrzucić do "status"

Code: Select all

SuplaDevice.addSensorNO(status);
??

Kod bramki:

Code: Select all

/*
Bramka RB-10G
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 <RFM69_ATC.h>                    //Pobierz z: https://github.com/lowpowerlab/rfm69

#define NODEID 2                          //Unikalny numer bramki (1 - 254).
#define NETWORKID 101                     //Numer sieci (1 - 254) w której działą bramka SUPLA oraz inne transmitery. Bramka oraz max. 6 transmiterów musi działać w sieci o takim samym ID.
#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 "qwertyuiopasdfgh"     //Klucz kodowania - 16 znaków (ani mniej, ani więcej) - identyczny w bramce SUPLA i we wszystkich transmiterach.
#define ENABLE_ATC                        //Wstaw znacznik komentarza jeśli chcesz wyłączyć automatyczną kontrolę transmisji (ATC).

#define SERIAL_BAUD 115200                //Prędkość transmisji portu szeregowego.

#define SUPLADEVICE_CPP
#include <SuplaDevice.h>

#define SUPLA_SERVER "svrX.supla.org"
#define LOCATION_ID 333
#define LOCATION_PASSWORD "bbbb"
// pobierz identyfikator urządzenia ze strony https://www.supla.org/arduino/get-guid i wprowadź go poniżej
#define GUID {0x03,0x83,0xE5,0x06,0xA1,0x27,0xD8,0xE1,0x57,0xB2,0x3C,0xAF,0xF0,0x0D,0xF7,0x30};

RFM69_ATC radio(D8, D2, false);
bool promiscuousMode = false;

const unsigned long period = 120000;      //Czas (2 minut) po którym bramka uznaje brak odczytu z transmitera i ustawia wartości wysyłane do Supla Cloud na 0.
double temperature = 0.0;
double humidity = 0.0;
double pressure = 0.0;
double lux = 0.0;
int status;
unsigned long startMillis = 0;
unsigned long currentMillis = 0;
unsigned long RFNodesCount = 0;

typedef struct {
  int nodeid;
  int channelNumber;
  double temperature;
  double batteryLevel;
  int status;
  unsigned long lastContact;
} RF_TemperatureandHumidityNode;

RF_TemperatureandHumidityNode RFNodes[6];




void setup() {
  Serial.begin(SERIAL_BAUD);
  
//   SuplaDevice.setTemperatureHumidityCallback(&get_temperature_and_humidity);

SuplaDevice.addSensorNO(status);
   
   
   
  char guid[SUPLA_GUID_SIZE] = GUID;
  uint8_t mac[6] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06};
  SuplaDevice.setName("BRAMKA MAIL RB-10G");
  SuplaDevice.begin(guid, mac, SUPLA_SERVER, LOCATION_ID, LOCATION_PASSWORD);
  
  radio.initialize(FREQUENCY,NODEID,NETWORKID);

#ifdef IS_RFM69HW_HCW
  radio.setHighPower();
#endif

  radio.encrypt(ENCRYPTKEY);
  radio.promiscuous(promiscuousMode);

  char buff[105];
  sprintf(buff, "BRAMKA RB-10G. Start komunikacji radiowej na częstotliwości %d MHz...", FREQUENCY==RF69_433MHZ ? 433 : FREQUENCY==RF69_868MHZ ? 868 : 915);
  Serial.println(buff);
}

byte ackCount = 0;
uint32_t packetCount = 0;

String getValue(String data, char separator, int index)
{
  int found = 0;
  int strIndex[] = {0, -1};
  int maxIndex = data.length() - 1;

  for (int i = 0; i <= maxIndex && found <= index; i++) {
    if (data.charAt(i) == separator || i == maxIndex) {
      found++;
      strIndex[0] = strIndex[1] + 1;
      strIndex[1] = (i == maxIndex) ? i + 1 : i;
    }
  }

  return found > index ? data.substring(strIndex[0], strIndex[1]) : "";
}

void readRadioData() {

  String value = "";
  if (radio.receiveDone())
  {
    int foundIdx = -1;

    for (int i = 0; i < RFNodesCount; i++)
      if (RFNodes[i].nodeid == radio.SENDERID)
      {
        foundIdx = i;
        break;
      }

    Serial.println("Odbieram dane...");
    if (foundIdx == -1)
    {
      if (RFNodesCount < 6)
      {
        Serial.println("Znalazłem nowy transmiter. Dodaję go do SUPLA Cloud");
        RFNodes[RFNodesCount].nodeid = radio.SENDERID;
        RFNodes[RFNodesCount].lastContact = millis();
        RFNodes[RFNodesCount].channelNumber = radio.SENDERID - 1;
        RFNodes[RFNodesCount].temperature = 0.0;
        
        RFNodes[RFNodesCount].batteryLevel = 0;
        RFNodes[RFNodesCount].status = 0;
        
        foundIdx = RFNodesCount;
        RFNodesCount++;
      } else {
        Serial.println("Maksymalna ilość transmiterów przekroczona!");
        foundIdx = 0;
      }
    } else
    {
      RFNodes[foundIdx].temperature = 0.0;
    }

    Serial.print("#[");
    Serial.print(++packetCount);
    Serial.print(']');
    Serial.print('['); Serial.print(radio.SENDERID, DEC); Serial.print("] ");

    value = "";
    for (byte i = 0; i < radio.DATALEN; i++)
      if (radio.DATA[i] != ' ')
        value += (char)radio.DATA[i];

    Serial.println(value);

    
    String battLevelStr = getValue(value, '|', 0);
    String statusStr = getValue(value, '|', 0);

    Serial.print("Poziom baterii: ");
    Serial.println(battLevelStr);
    Serial.print("Stan skrzynki mail: ");
    Serial.println(status);

    
    RFNodes[foundIdx].batteryLevel = battLevelStr.toFloat();
    RFNodes[foundIdx].status = statusStr.toFloat();
    RFNodes[foundIdx].lastContact = millis();

    Serial.print("Poziom sygnału transmitera [RX_RSSI]:"); Serial.print(radio.RSSI); Serial.print(" dBm");

    if (radio.ACKRequested())
    {
      byte theNodeID = radio.SENDERID;
      radio.sendACK();
      
      if (ackCount++ % 3 == 0)
      {
        Serial.print(" ACK TEST - Transmiter ");
        Serial.print(theNodeID);
        delay(5);
        radio.sendWithRetry(theNodeID, "ACK TEST", 8, 0);
      }
    }
    Blink(LED_BUILTIN, 100);
    Serial.println();
    Serial.println();
  }

  for (int i = 0; i < RFNodesCount; i++)
  {
    if (millis() - RFNodes[i].lastContact >= period)
    {
//      RFNodes[i].temperature = -375;
     
      RFNodes[i].batteryLevel = 0;
      RFNodes[i].status = HIGH;
      Serial.print("Brak odczytu z czujnika ");
      Serial.println (RFNodes[i].nodeid);
    };
  }
}

void Blink(byte PIN, int DELAY_MS)
{
  pinMode(PIN, OUTPUT);
  digitalWrite(PIN,LOW);
  delay(DELAY_MS);
  digitalWrite(PIN,HIGH);
}

void loop() {
  readRadioData();
  SuplaDevice.iterate();
}
You do not have the required permissions to view the files attached to this post.
jak coś nie działa to włącz zasilanie.....
QLQ
Posts: 2512
Joined: Sun Sep 03, 2017 9:13 am

Post

Idę spać ... :mrgreen:
jak coś nie działa to włącz zasilanie.....
krycha88
Posts: 5575
Joined: Fri Nov 16, 2018 7:25 am
Been thanked: 5 times

Post

do swojej bramki dodaj to :)

Code: Select all

#define VIRTUAL_PIN_SENSOR      99


setup() {
	SuplaDevice.addSensorNO(VIRTUAL_PIN_SENSOR);
	SuplaDevice.setDigitalReadFuncImpl(&supla_DigitalRead);
}

int supla_DigitalRead(int channelNumber, uint8_t pin) {
	if (pin == VIRTUAL_PIN_SENSOR) return status;
  
	return digitalRead(pin);
}
https://gui-generic-builder.supla.io/
QLQ
Posts: 2512
Joined: Sun Sep 03, 2017 9:13 am

Post

krycha88 wrote: Sat Nov 30, 2019 7:02 am do swojej bramki dodaj to :)

Code: Select all

#define VIRTUAL_PIN_SENSOR      99


setup() {
	SuplaDevice.addSensorNO(VIRTUAL_PIN_SENSOR);
	SuplaDevice.setDigitalReadFuncImpl(&supla_DigitalRead);
}

int supla_DigitalRead(int channelNumber, uint8_t pin) {
	if (pin == VIRTUAL_PIN_SENSOR) return status;
  
	return digitalRead(pin);
}
Dziękuję @krycha88 - teraz wiem jak się robi wirtualne piny :)
ale. Niby się wszystko kompiluje ale nie zwraca do Clouda :(
Wszystko ładnie działa - jak zamiast "return status" podstawię na sztywno return 1 zmienia się stan w Cloud - czyli Funcja supla_Digital_Read nie widzi poprawniestatus - nie jest globalny ??
jak coś nie działa to włącz zasilanie.....
QLQ
Posts: 2512
Joined: Sun Sep 03, 2017 9:13 am

Post

NO TO DZIAŁA !! :lol: :lol: :D :D :shock:

zrobiłem tak:

Code: Select all

int supla_DigitalRead(int channelNumber, uint8_t pin) {
  if (pin = VIRTUAL_PIN_SENSOR) return RFNodes[0].status;
  
  return digitalRead(pin);
}
EDIT:
pliki z kodem:
mail.rar
.
Filmik z działania: https://youtu.be/1xnUiJQL0tU
You do not have the required permissions to view the files attached to this post.
jak coś nie działa to włącz zasilanie.....
Zibi
Posts: 646
Joined: Wed Jul 31, 2019 9:20 am
Location: Białogard

Post

QLQ kawal dobrej roboty.
andras
Posts: 636
Joined: Fri Dec 30, 2016 5:51 pm
Has thanked: 2 times
Been thanked: 4 times

Post

QLQ super , czy wiesz może gdzie kupić Moteino ?
User avatar
makrz
Posts: 401
Joined: Tue Nov 27, 2018 1:43 pm
Location: Opole

Post

W sprawie moteino piszcie do tego gościa.
Ma tego dużo, tylko jakieś problemy z allegro.

Return to “Nowości”