Jeszcze się do tego nie zabrałem.
Natomiast do listy niedziałających rzeczy dołączył Button
Jeszcze się do tego nie zabrałem.
Kod: Zaznacz cały
/*
Copyright (C) AC SOFTWARE SP. Z O.O.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <Arduino.h>
#include <SuplaDevice.h>
#include "timer.h"
#if defined(ARDUINO_ARCH_ESP32)
#include <Ticker.h>
#endif
namespace {
#if defined(ARDUINO_ARCH_ESP8266)
ETSTimer supla_esp_timer;
ETSTimer supla_esp_fastTimer;
void esp_timer_cb(void *timer_arg) {
(void)(timer_arg);
SuplaDevice.onTimer();
}
void esp_fastTimer_cb(void *timer_arg) {
(void)(timer_arg);
SuplaDevice.onFastTimer();
}
#elif defined(ARDUINO_ARCH_ESP32)
Ticker supla_esp_timer;
Ticker supla_esp_fastTimer;
void esp_timer_cb() {
SuplaDevice.onTimer();
}
void esp_fastTimer_cb() {
SuplaDevice.onFastTimer();
}
#else
ISR(TIMER1_COMPA_vect) {
SuplaDevice.onTimer();
}
ISR(TIMER2_COMPA_vect) {
SuplaDevice.onFastTimer();
}
#endif
}; // namespace
namespace Supla {
void initTimers() {
#if defined(ARDUINO_ARCH_ESP8266)
os_timer_disarm(&supla_esp_timer);
os_timer_setfn(&supla_esp_timer, (os_timer_func_t *)esp_timer_cb, NULL);
os_timer_arm(&supla_esp_timer, 10, 1);
os_timer_disarm(&supla_esp_fastTimer);
os_timer_setfn(&supla_esp_fastTimer, (os_timer_func_t *)esp_fastTimer_cb, NULL);
os_timer_arm(&supla_esp_fastTimer, 1, 1);
#elif defined(ARDUINO_ARCH_ESP32)
supla_esp_timer.attach_ms(10, esp_timer_cb);
supla_esp_fastTimer.attach_ms(1, esp_fastTimer_cb);
#else
// Timer 1 for interrupt frequency 100 Hz (10 ms)
TCCR1A = 0; // set entire TCCR1A register to 0
TCCR1B = 0; // same for TCCR1B
TCNT1 = 0; // initialize counter value to 0
// set compare match register for 1hz increments
OCR1A = 155; // (16*10^6) / (100*1024) - 1 (must be <65536) == 155.25
// turn on CTC mode
TCCR1B |= (1 << WGM12);
// Set CS12 and CS10 bits for 1024 prescaler
TCCR1B |= (1 << CS12) | (1 << CS10);
// enable timer compare interrupt
TIMSK1 |= (1 << OCIE1A);
sei(); // enable interrupts
// TIMER 2 for interrupt frequency 2000 Hz (0.5 ms)
cli(); // stop interrupts
TCCR2A = 0; // set entire TCCR2A register to 0
TCCR2B = 0; // same for TCCR2B
TCNT2 = 0; // initialize counter value to 0
// set compare match register for 2000 Hz increments
OCR2A = 249; // = 16000000 / (32 * 2000) - 1 (must be <256)
// turn on CTC mode
TCCR2B |= (1 << WGM21);
// Set CS22, CS21 and CS20 bits for 32 prescaler
TCCR2B |= (0 << CS22) | (1 << CS21) | (1 << CS20);
// enable timer compare interrupt
TIMSK2 |= (1 << OCIE2A);
sei(); // allow interrupts
#endif
}
}; // namespace Supla
Thanks. I didn't have time yet to check it. How does it work? It isn't done on interruptions, because those require part of application to be copied to RAM and it doesn't work for virtual methods in classes (that's where I stuck previously).
Kod: Zaznacz cały
void fillStateData(TDSC_ChannelState &channelState) {
channelState.Fields |= SUPLA_CHANNELSTATE_FIELD_IPV4 |
SUPLA_CHANNELSTATE_FIELD_MAC |
SUPLA_CHANNELSTATE_FIELD_WIFIRSSI |
SUPLA_CHANNELSTATE_FIELD_WIFISIGNALSTRENGTH;
channelState.IPv4 = WiFi.localIP();
WiFi.macAddress(channelState.MAC);
int rssi = WiFi.RSSI();
channelState.WiFiRSSI = rssi;
if (rssi > -50) {
channelState.WiFiSignalStrength = 100;
} else if (rssi <= -100) {
channelState.WiFiSignalStrength = 0;
} else {
channelState.WiFiSignalStrength = 2 * (rssi + 100);
}
}
Ok, so it works, but SuplaDevice code is not thread safe. I was thinking about moving it to another core and putting into some loop, but this ticker will actually do the same and code looks more consistent with esp8266/avr implementation.elmaya pisze: ↑śr gru 02, 2020 12:33 pm Ticker does not use interrupts but runs on core 0. "arduino uses core 1"
it works fine even when disconnected from the network "I have only noticed a small difference with the buttons, less response when disconnected but nothing dramatic"
Also consider completing "esp32_wifi.h" by adding:Kod: Zaznacz cały
void fillStateData(TDSC_ChannelState &channelState) { channelState.Fields |= SUPLA_CHANNELSTATE_FIELD_IPV4 | SUPLA_CHANNELSTATE_FIELD_MAC | SUPLA_CHANNELSTATE_FIELD_WIFIRSSI | SUPLA_CHANNELSTATE_FIELD_WIFISIGNALSTRENGTH; channelState.IPv4 = WiFi.localIP(); WiFi.macAddress(channelState.MAC); int rssi = WiFi.RSSI(); channelState.WiFiRSSI = rssi; if (rssi > -50) { channelState.WiFiSignalStrength = 100; } else if (rssi <= -100) { channelState.WiFiSignalStrength = 0; } else { channelState.WiFiSignalStrength = 2 * (rssi + 100); } }
1. Czy licznik impulsów używa przerwania (w sensie - czy każdy impuls/zbocze opadające zostanie zliczone? dałoby to możliwość zliczania szybkich impulsów, czy wręcz pomiar RPM itp, czy testowany jest co X ms stan pinu i tylko tyle?)
Aktualny licznik impulsów sprawdza stan wejścia cyklicznie i jeszcze dodatkowo używa "filtrów" wymagających, aby stan był utrzymywany przez jakiś czas (aby nie zliczać tzw. "drgań styków").
W Supli licznik impulsów przechowuje dane w zmiennych typu "unsigned integer" (na 64 bitach). Więc o ile doliczenie do 0 w dół jest możliwe, to liczb ujemnych się tutaj nie pokaże. Może lepiej byłoby robić osobny licznik na dane z drugiego pinu?
Możesz to zrealizować poprzez ustawienie Button-u na tym 3-cim pinie i ustawić w nim akcję resetowania licznika impulsów.
Brzmi jak fajny projekt DIY, ale nie ma zastosowania do Supli. Kanały bram pokazują tylko 3 stany: całkowicie otwarta, częściowo otwarta, zamknięta. Nic więcej w takim kanale się nie wyświetli.Hrumque pisze: ↑pn lip 04, 2022 7:42 am - monitorowanie pozycji i kierunku ruchu (pozycji) bramy, windy, wiadra w studni itp urządzeń (gdzie znamy tylko kierunek ruchu, oraz możemy zliczać impulsy np silnika napędowego, a krańcówka w pozycji zero - zerowałaby licznik impulsów, więc zawsze wiedzielibyśmy idealnie o pozycji aktualnej, a nie tak, że po X ruchach tam i spowrotem się przesunie o kilka impulsów i rozjedzie wszystko)
Falownik nie wie jaki jest bilans energii na liczniku, więc wystawienie przez niego sygnału nic Ci nie da. Tutaj jest po prostu potrzebny licznik dwukierunkowy.Hrumque pisze: ↑pn lip 04, 2022 7:42 am - zastosowanie prostych liczników energii (dających na wyjściu tylko impuls przy zliczeniu - bez wskazywania kierunku przepływu energii) z osobnym sygnałem np z falownika (czy produkujemy prąd, czy go konsumujemy - a tu wystarczy fotoelement przylepiony przy diodzie statusu na obudowie falownika, by łapać stan pracy)
Tutaj lepiej zrobić sobie jakiś czujnik poziomu cieczy.Hrumque pisze: ↑pn lip 04, 2022 7:42 am - liczniki wody wpływającej i wypływającej np. z zbiornika deszczówki (sam licznik-impulsator daje takie same impulsy w obu kierukach przepływu, drugi sensor kierunku przepływu (wystarczy pływak z magnesem i kontaktron, w zależności od kierunku przepływu byłby przesuwany w lewo lub prawo) dałby pełny nadzór nad obiektem