Andurino IDE - Odczyt stanu pinu cyfrowego podłączonego do Supli

xsobster
Posts: 14
Joined: Sat Dec 02, 2017 10:19 pm

Sat May 05, 2018 9:34 am

Witam Serdecznie , Bardzo proszę o pomoc.
Chciałbym odczytywać stany pinów podłączonych do Supli ( jako przekaźniki ) w Andurino IDE.
Na ta chwile wgrałem soft z https://majsterkowo.pl/supla-nodemcu-v3 ... ogle-home/

Chciałbym "widzieć " na serial monitor wartość stanu przekaźników . Podłączając przycisk mono stabilny mam reakcje na serial monitorze (dodatkowa zmienna A) oraz na Supli , ale sterując Suplą widzę zmianę na Supli ale nie na serial monitor.
Stan cyfrowy ( 0; 1 ) potrzebny mi jest do sterowania serwa (otwarte / zamknięte) .

Oraz bardzo proszę o objaśnienie lub ewentualne przykłady użycia w praktyce tych komend może uda mi się rozwiązać moj problem
1. SuplaDevice.suplaDigitalRead
2. void channelValueChanged(int channel_number, char v, double d, char var);

Dzięki
User avatar
pzygmunt
Posts: 5780
Joined: Tue Jan 19, 2016 9:26 am
Location: Paczków
Contact:

Sat May 05, 2018 9:44 am

Wepnij się w digitalRead i digitalWrite.

Code: Select all

int supla_DigitalRead(int channelNumber, uint8_t pin) {
   
    int result = digitalRead(pin);
    Serial.print("Read(");
    Serial.print(pin);
    Serial.print("): ");
    Serial.println(result);
    return result;
}

void supla_DigitalWrite(int channelNumber, uint8_t pin, uint8_t val) {

    Serial.print("Write(");
    Serial.print(pin);
    Serial.print(",");
    Serial.print(val);
    Serial.println(")");
    digitalWrite(pin, val);
}

void setup() {
....
   SuplaDevice.setDigitalReadFuncImpl(&supla_DigitalRead);
   SuplaDevice.setDigitalWriteFuncImpl(&supla_DigitalWrite);
....
}
SuplaDevice.suplaDigitalRead - prywatna metoda umożliwiająca wpięcie w/w callbacka
channelValueChanged - powiadomienie serwera o zmianie stanu kanału
xsobster
Posts: 14
Joined: Sat Dec 02, 2017 10:19 pm

Sat May 05, 2018 10:22 am

Dziękuje za odpowiedz. Bardzo pomogła i rozwiązała problem. Mam tylko jeszcze jedno pytanie. Potrzebuje użyć wartości result w pętli loop, wobec tego zadeklarowałem result jako zmienną globalną i zacząłem wyświetlać ją w serial monitorze oddzielnie . Niestety przy podłączeniu większej ilości przekaźników w zmienna result (w pentli loop) jest ma stan ostatniego przełączanego przekaźnika. Czy da się do każdego stanu przekaźnika dodać jego indywidualną zmienną np result0 - stan kanału zero, result1 - stan kanału jeden.
User avatar
pzygmunt
Posts: 5780
Joined: Tue Jan 19, 2016 9:26 am
Location: Paczków
Contact:

Sat May 05, 2018 10:25 am

Nie lepiej odczytywać rzeczywisty stan GPIO bezpośrednio z portu i w momencie gdy się tego potrzebuje ?
[edit]
..., a jak bardzo chcesz to zapisywać do zmiennej globalnej to

Code: Select all

int result[100];

int supla_DigitalRead(int channelNumber, uint8_t pin) {
    result[pin] = digitalRead(pin);
    return result[pin];
}
xsobster
Posts: 14
Joined: Sat Dec 02, 2017 10:19 pm

Sat May 05, 2018 11:01 am

Dzięki jeszcze raz. Po wielu próbach w końcu udało mi się to zrozumieć i zaimplementować twój kod. Mam nadzieje, że z resztą sobie poradze
Pozdrawiam.
xsobster
Posts: 14
Joined: Sat Dec 02, 2017 10:19 pm

Tue May 08, 2018 7:22 pm

Podczas tworzenia mojego projektu, napotkałem się na jeden jeszcze problem który ciężko mi jest samemu rozwiązać.
Chciałbym aby moc sterować urządzeniem poprzez przyciski nawet kiedy nastąpi brak połączenia z internetem (serwerem) .

Moim pomysłem było sprawdzenie statusu połączenia i używając funkcji " Switch Case " - dla wartości Status = 17 i pozostałych.
Niestety jeżeli moduł nie ma połączenia próbuje je odnowić omijając pętle loop .

Proszę o pomoc, - Z góry dziękuje




Projekt :
Sterowanie serwami przy pomocy przycisków oraz Supli . Dwie diody do sygnalizacji pracy serw, oraz jedna do sprawdzenie statusu dostępu do internetu , a docelowo jak się uda sterowanie na jednym urządzeniu 6 szt serw oraz ich sygnalizacja .
User avatar
Piotr61
Posts: 53
Joined: Fri Sep 15, 2017 12:59 pm

Tue May 08, 2018 9:54 pm

Do obsługi przycisków użyj przerwań od timera.
Np.

Code: Select all

os_timer_t timer;
void buttons_timer() {
	if(!digitalRead(14)) {
		//pin 14 zwarty do GND - zrób coś
	}
}


void setup() {
 
....
  os_timer_disarm(&timer);
  os_timer_setfn(&timer, (os_timer_func_t *)buttons_timer, NULL);
  os_timer_arm(&timer, 50, 1);
"Dopóki nie skorzystałem z Internetu, nie wiedziałem, że na świecie jest tylu idiotów" - Stanisław Lem
xsobster
Posts: 14
Joined: Sat Dec 02, 2017 10:19 pm

Wed May 09, 2018 7:47 am

Piotr61 wrote:
Tue May 08, 2018 9:54 pm
Do obsługi przycisków użyj przerwań od timera.
Np.

Code: Select all

os_timer_t timer;
void buttons_timer() {
	if(!digitalRead(14)) {
		//pin 14 zwarty do GND - zrób coś
	}
}


void setup() {
 
....
  os_timer_disarm(&timer);
  os_timer_setfn(&timer, (os_timer_func_t *)buttons_timer, NULL);
  os_timer_arm(&timer, 50, 1);


Tylko przyciski będą działać ale co z programem które inicjują w pentli loop?
User avatar
Piotr61
Posts: 53
Joined: Fri Sep 15, 2017 12:59 pm

Wed May 09, 2018 9:26 am

xsobster wrote:
Wed May 09, 2018 7:47 am
Tylko przyciski będą działać ale co z programem które inicjują w pentli loop?
Hmm..., całą konfigurację urządzenia ZAWSZE wykonuję w setup(), a w loop() w zasadzie tylko iterate() i jakieś mniej ważne przypadki.
Problem tkwi w funkcji/metodzie begin(), bo jeśli urządzenie nie może nawiązać połączenia, to program kręci się w kółko w pętli while ...

Code: Select all

     void supla_arduino_eth_setup(uint8_t mac[6], IPAddress *ip) {
 
         WiFi.begin(supla_esp_cfg.WIFI_SSID, supla_esp_cfg.WIFI_PWD);
 
         while (WiFi.status() != WL_CONNECTED) {
             delay(500);
         }
     }
Jeżeli chcesz aby Twoje urządzenia działały nawet przy braku połączenia z siecią, to musisz zmienić koncepcję budowy programu.
Może pokażesz jak to u Ciebie wygląda :?:

Piotr.
"Dopóki nie skorzystałem z Internetu, nie wiedziałem, że na świecie jest tylu idiotów" - Stanisław Lem
xsobster
Posts: 14
Joined: Sat Dec 02, 2017 10:19 pm

Wed May 09, 2018 8:26 pm

Piotrku proszę bardzo
Jeśli ktoś może to niech rzuci okiem

Code: Select all

#include <Servo.h>
#include <Adafruit_Sensor.h>
#include <SPI.h>
#include <Ethernet.h>
#include <srpc.h>
#include <log.h>
#include <eh.h>
#include <proto.h>
#define SUPLADEVICE_CPP
#include <SuplaDevice.h>
#include <lck.h>
#include <WiFiClient.h>
#include <ESP8266WiFiType.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiScan.h>
#include <ESP8266WiFiMulti.h>
#include <WiFiServer.h>
#include <ESP8266WiFiGeneric.h>
#include <WiFiClientSecure.h>
#include <ESP8266WiFiAP.h>
#include <ESP8266WiFiSTA.h>
#include <WiFiUdp.h>
WiFiClient client;
Servo myservo2;
Servo myservo0;
int button2;
int button0;
int r16=0;
int r15=0;
int del=80;
int s;
int pos2_0 = 145;//pozycja początkowa górne servo
int pos2_1 = 1;//pozycja otwarta górne servo
int pos2_2 = 145;//pozycja zamknięta górne servo

int pos0_0 = 0;//pozycja początkowa dolne servo
int pos0_1 = 0;//pozycja zamknięta dolne servo
int pos0_2 = 98;//pozycja otwarta dolne servo


// Setup Supla connection
const char* ssid     = "xxx";
const char* password = "xxx";



int result[100];
int supla_DigitalRead(int channelNumber, uint8_t pin) {
  result[pin] = digitalRead(pin);
  return result[pin];
}

void supla_DigitalWrite(int channelNumber, uint8_t pin, uint8_t val) {

  Serial.print("Write(");
  Serial.print(pin);
  Serial.print(",");
  Serial.print(val);
  Serial.println(")");
  digitalWrite(pin, val);
}

void status_func(int status, const char *msg) {
 s=status;

}

void setup() {
  Serial.begin(115200);
  //delay(10);
  myservo2.attach(13);
  myservo0.attach(12);
  myservo2.write(pos2_0);
  myservo0.write(pos0_0);
  pinMode(2, OUTPUT);//ŚWIECENIE DIODY OZNACZA SERVO GÓRNE OTWIERA LUB JEST W TRAKCIE
  pinMode(5, OUTPUT);////ŚWIECENIE DIODY OZNACZA SERVO DOLNE OTWIERA LUB JEST W TRAKCIE
  pinMode(10, OUTPUT);// dioda wi fi

  pinMode(14, INPUT_PULLUP);//przycisk sterujący górnym serwem
  pinMode(4, INPUT_PULLUP);//przycisk sterujący dolnym serwem
  SuplaDevice.addRelay(15);//PRZEKAŹNIK SUPLA STERUJĄCY OTWIERANIEM PRZZ SERVO GÓRNE
  SuplaDevice.addRelay(16);//PRZEKAŹNIK SUPLA STERUJĄCY OTWIERANIEM PRZZ SERVO DOLNE
  digitalWrite(10, HIGH); // ŚWIECENIE DIODY OZNACZA ZERWANE POŁĄCZENIE Z SERWEREM SUPLI

  SuplaDevice.setDigitalReadFuncImpl(&supla_DigitalRead);
  SuplaDevice.setDigitalWriteFuncImpl(&supla_DigitalWrite);
  SuplaDevice.setStatusFuncImpl(&status_func);


  // ?Replace the falowing GUID
  char GUID[SUPLA_GUID_SIZE] = {XXX};
  // ?with GUID that you can retrieve from https://www.supla.org/arduino/get-guid

  // Ethernet MAC address
uint8_t mac[6] = {XXX};

  SuplaDevice.begin(GUID,              // Global Unique Identifier
                    mac,               // Ethernet MAC address
                    "svr2.supla.org",  // SUPLA server address
                    XXX,                 // Location ID
                    "XXXX");               // Location Password

}

void loop() {


 Serial.print("s"  );
 Serial.println(s);
 Serial.print("r15  "); 
 Serial.println(r15);
 Serial.print("r16  ");
 Serial.println(r16);
 
//FUNKCJA SWITCH CASE PRZEŁĄCZA NA WYKONYWANY PROGRAM W PRZYPADKU GDY JEST POŁĄCZENIa Z SUPLOM I JEGO BRAKIEM
switch (s) {
  case 17:// URZADZENIE JEST ZALOGOWANE I DZIAŁA POPRAWNIE Z SUPLĄ
  digitalWrite(10, LOW);
  TSD_SuplaChannelNewValue value0;
  value0.SenderID = 0;
  value0.ChannelNumber = 0; 
  value0.DurationMS = 0;

  button0 = digitalRead(14); 
  if (digitalRead(14) == LOW) { 
    
    value0.value[0] = !value0.value[0]; 
    SuplaDevice.channelSetValue(&value0); 
    while (digitalRead(14) == LOW); 
    delay(10);
  }

  TSD_SuplaChannelNewValue value2;
  value2.SenderID = 0;
  value2.ChannelNumber = 1; 
  value2.DurationMS = 0;

  button2 = digitalRead(4); 
  if (digitalRead(4) == LOW) { 
    value2.value[0] = !value2.value[0]; 
    SuplaDevice.channelSetValue(&value2); 
    while (digitalRead(4) == LOW); 
    delay(10);
  }
//swiecenie diod w zależności od wartości załączenia przekaźnika w supli
if(result[15]==1){
  digitalWrite(2, HIGH);
  }
if(result[15]==0){
  digitalWrite(2, LOW);
  }
if(result[16]==1){
  digitalWrite(5, HIGH);
  }
if(result[16]==0){
  digitalWrite(5, LOW);
  }
//POWOLNE OTWIERANIE I ZAMYKANIE CO JEDEN STOPIEŃ WYKONYWANE PRZEZ SERVO GÓRNE
  if (result[15] == 1 && pos2_0 > pos2_1 ) {
    pos2_0 = pos2_0 - 1;
    myservo2.write(pos2_0);
    delay(del);
  }
  if (result[15] == 1 && pos2_0 == pos2_1) {
    myservo2.write(pos2_1);
  }

  if (result[15] == 0 && pos2_0 < pos2_2) {
    pos2_0 = pos2_0 + 1;
    myservo2.write(pos2_0);
    delay(del);
  }
  if (result[15] == 0 && pos2_0 == pos2_2)
  {
    myservo2.write(pos2_2);
  }

//POWOLNE OTWIERANIE I ZAMYKANIE CO JEDEN STOPIEŃ WYKONYWANE PRZEZ SERVO DOLNE
  if (result[16] == 1 && pos0_0 < pos0_2 ) {
    pos0_0 = pos0_0 + 1;
    myservo0.write(pos0_0);
 
    delay(del);
  }
  if (result[16] == 1 && pos0_0 ==pos0_2) {
    myservo0.write(pos0_2);

  }

  if (result[16] == 0 && pos0_0 > pos0_1) {
    pos0_0 = pos0_0 - 1;
    myservo0.write(pos0_0);
  
    delay(del);
  }
  if (result[16] == 0 && pos0_0 == pos0_1)
  {
    myservo0.write(pos0_1);
 
  }

    break;
 
  default://UTRATA POŁĄCZENIA Z SUPLĄ
digitalWrite(10, HIGH);

  if (digitalRead(14) == LOW) { //jeśli stan jest niski   
    r15=1;    
    while (digitalRead(14) == LOW); //przycisk długo wciśnięty
    delay(10);
  }
  if (digitalRead(4) == LOW) { //jeśli stan jest niski   
    r16=1;    
    while (digitalRead(4) == LOW); //przycisk długo wciśnięty
    delay(10);
  }
if(r15==1){
  digitalWrite(2, HIGH);
  }
if(r15==0){
  digitalWrite(2, LOW);
  }
if(r16==1){
  digitalWrite(5, HIGH);
  }
if(r16==0){
  digitalWrite(5, LOW);
  }

  if (r15 == 1 && pos2_0 > pos2_1 ) {
    pos2_0 = pos2_0 - 1;
    myservo2.write(pos2_0);
    delay(del);
  }
  if (r15 == 1 && pos2_0 == pos2_1) {
    myservo2.write(pos2_1);
  }

  if (r15 == 0 && pos2_0 < pos2_2) {
    pos2_0 = pos2_0 + 1;
    myservo2.write(pos2_0);
    delay(del);
  }
  if (r15 == 0 && pos2_0 == pos2_2)
  {
    myservo2.write(pos2_2);
  }


  if (r16 == 1 && pos0_0 < pos0_2 ) {
    pos0_0 = pos0_0 + 1;
    myservo0.write(pos0_0);
 
    delay(del);
  }
  if (r16 == 1 && pos0_0 ==pos0_2) {
    myservo0.write(pos0_2);

  }

  if (r16 == 0 && pos0_0 > pos0_1) {
    pos0_0 = pos0_0 - 1;
    myservo0.write(pos0_0);
  
    delay(del);
  }
  if (r16 == 0 && pos0_0 == pos0_1)
  {
    myservo0.write(pos0_1);
 
  }
   
}

  SuplaDevice.iterate();
}


// Supla.org ethernet layer
int supla_arduino_tcp_read(void *buf, int count) {
  _supla_int_t size = client.available();

  if ( size > 0 ) {
    if ( size > count ) size = count;
    return client.read((uint8_t *)buf, size);
  };

  return -1;
};

int supla_arduino_tcp_write(void *buf, int count) {
  return client.write((const uint8_t *)buf, count);
};

bool supla_arduino_svr_connect(const char *server, int port) {
  return client.connect(server, 2015);
  
}

bool supla_arduino_svr_connected(void) {
  return client.connected();
}

void supla_arduino_svr_disconnect(void) {
  client.stop();
}

void supla_arduino_eth_setup(uint8_t mac[6], IPAddress *ip) {

  Serial.println("WiFi init");
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");

  }

  Serial.print("\nlocalIP: ");
  Serial.println(WiFi.localIP());
  Serial.print("subnetMask: ");
  Serial.println(WiFi.subnetMask());
  Serial.print("gatewayIP: ");
  Serial.println(WiFi.gatewayIP());
}

SuplaDeviceCallbacks supla_arduino_get_callbacks(void) {
  SuplaDeviceCallbacks cb;

  cb.tcp_read = &supla_arduino_tcp_read;
  cb.tcp_write = &supla_arduino_tcp_write;
  cb.eth_setup = &supla_arduino_eth_setup;
  cb.svr_connected = &supla_arduino_svr_connected;
  cb.svr_connect = &supla_arduino_svr_connect;
  cb.svr_disconnect = &supla_arduino_svr_disconnect;
  cb.get_temperature = NULL;
  cb.get_temperature_and_humidity = NULL;
  cb.get_rgbw_value = NULL;
  cb.set_rgbw_value = NULL;

  return cb;

}
Last edited by xsobster on Wed May 09, 2018 9:06 pm, edited 3 times in total.
Post Reply