Страница 18 из 25
Re: mysensors
Добавлено: Ср мар 30, 2016 4:34 pm
Ivan
maloicds писал(а):Ivan, а
такую библиотеку не пробовали?
Посмотрел
- Не сильно популярна
- Слишком много служебных данных
- Нет сна
Я видел много реализаций MESH на NRF24. И mySensor не самый лучший вариант. Но она популярна и обсуждаема. А значит есть движение вперёд
А можно примеры реализации.
Иными словами в каких случаях это может пригодиться.
А то мало ли я упускаю какую либо полезную возможность.
Спасибо
Этот тип сообщения был добавлен для передачи прошивки, но не как для передачи больших данных между нодами. Я видел что пытались через этот пакет передать thml и даже звук. Но по моему это незачем. Для таких данных лучше использовать wifi
Я когда пытался реализовать трансляцию RS232 в котёл. Использовал собственную надстройку над протоколом. Решил что 4 тип пакета для этого не очень подходит
Re: mysensors
Добавлено: Пн апр 04, 2016 10:49 am
nick7zmail
Пробежался по сайту проекта и по паре тем на форуме.
Позвольте подитожить и скажите новичку - я правильно понял?
mysensors это по факту сеть устройств, чтобы они работали нужен "шлюз". Есть разные шлюзы - wifi(на том же esp8266), mqtt, ethernet, serial, но все они на основе ардуино. Главная вещь в шлюзе это приёмник/передатчик 2.4 gGz. Все исполнительные девайсы - это так же мелкие ардуинки, оснащенные 2,4 gGz передатчиком, и устройством типа сенсоров, сервоприводов, реле и т.п. Всё правильно? Или я где-то что-то не допонял?
И интересует еще по опыту использования - обычная wifi сеть из за них не лагает? На сколько я знаю, сейчас самый распространённый wifi диапазон - 2,4 gGz...помех и перебоев не бывает при опросе датчиков?
Re: mysensors
Добавлено: Пн апр 04, 2016 11:31 am
Ivan
Позвольте подитожить и скажите новичку - я правильно понял?
mysensors это по факту сеть устройств, чтобы они работали нужен "шлюз". Есть разные шлюзы - wifi(на том же esp8266), mqtt, ethernet, serial, но все они на основе ардуино. Главная вещь в шлюзе это приёмник/передатчик 2.4 gGz. Все исполнительные девайсы - это так же мелкие ардуинки, оснащенные 2,4 gGz передатчиком, и устройством типа сенсоров, сервоприводов, реле и т.п. Всё правильно? Или я где-то что-то не допонял?
Да вы правы
И интересует еще по опыту использования - обычная wifi сеть из за них не лагает? На сколько я знаю, сейчас самый распространённый wifi диапазон - 2,4 gGz...помех и перебоев не бывает при опросе датчиков?
В России есть не много частот которые разрешены для пользовательского использования. Одна из них 2.4 - на ней работает большое количество устройств о которых вы даже не догадываетесь. Да они друг другу могут мешать и в сильно зашумленном месте (например многоэтажка где куча вайфай). Но у всех у них есть свой протокол которые гарантирует что это их пакет и есть перезапросы
Re: mysensors
Добавлено: Пн апр 04, 2016 5:55 pm
slgeo
nick7zmail, все верно поняли, поправлю - шлюз можно построить на основе малины без ардуино благодаря нашим форумчанам, которые доработали софт.
Re: mysensors
Добавлено: Чт июн 23, 2016 12:22 am
ipz
Собрал гейт из примера Ивана на базе ESP c дополнительными датчиками. Все прекрасно работает. Думаю прикрутить реле. С форматом команды все понятно из описания API.
Подскажите, пожалуйста (туплю что-то): из МДМ как программно отправить команду на Ethernet гейт Mysensor?
Re: mysensors
Добавлено: Сб июл 02, 2016 10:26 pm
mechgeek
Здравствуйте!
Столкнулся с проблемой которую не удается решить самостоятельно.
Есть ethernet gate, подключен к мажордомо. Есть два устройства: одно-датчик открытия окна, второе: 3 в одном с разл.датчиками и pir сенсором.
Проблема в том, что при подключении они все получают одинаковый node id:1. В итоге в мажордомо куча датчиков в общей куче и я не могу найти способа их разделить кроме как нумеровать датчики сквозной нумерацией через все устройства, что не очень удобно.
Можно ли сделать разный node id для устройств, подключенных к одному гейту?
*** Сообщение запрещено. Включите JavaScript. ***
Re: mysensors
Добавлено: Пн июл 04, 2016 10:40 am
Ivan
mechgeek писал(а):Здравствуйте!
Столкнулся с проблемой которую не удается решить самостоятельно.
Есть ethernet gate, подключен к мажордомо. Есть два устройства: одно-датчик открытия окна, второе: 3 в одном с разл.датчиками и pir сенсором.
Проблема в том, что при подключении они все получают одинаковый node id:1. В итоге в мажордомо куча датчиков в общей куче и я не могу найти способа их разделить кроме как нумеровать датчики сквозной нумерацией через все устройства, что не очень удобно.
Можно ли сделать разный node id для устройств, подключенных к одному гейту?
*** Сообщение запрещено. Включите JavaScript. ***
Странно. Мдуль должен выдавать следующий ID. Сделайте скриншот настроек модуля
Re: mysensors
Добавлено: Пн июл 04, 2016 11:24 am
Alien
Может в скетче жестко прописан ид?
Или другой вариант - память перед перепрошивкой не очищена и номер оказывается тоже жестко вшитым от предыдущего использования.
Re: mysensors
Добавлено: Пн июл 04, 2016 2:26 pm
mechgeek
Может быть и вшит в скетче, но я этого не нашел

Добавил скрины настроек модуля и заявление ноды (там датчики с обоих устройств в куче).

- 1.jpg (49.96 КБ) 12983 просмотра

- 2.jpg (33.51 КБ) 12983 просмотра
Вряд ли это проблема модуля, т.к. MYSConnect выдает тоже самое.
Вложил франкенштейн-код ноды. Кстати обнаружил еще одну проблему. Зависает DHT-11 (т.е. не обновляет температуру и влажность). При выключении/включении показывает корректную температуру и влажность, а потом опять зависает.
Код: Выделить всё
#include <SPI.h>
#include <MySensor.h>
#include <DHT.h>
#include <Wire.h>
#define VERSION "1.2"
#define DEBUG 0
#define REPEATER 0
//-----------------------------------------------------------------------------------------------
#define MAX_U_LONG 4294967295;
// Sensor-Child-IDs
#define CHILD_ID_LIGHT 1
#define CHILD_ID_MOTION 2
#define CHILD_ID_TEMP 3
#define CHILD_ID_HUM 4
// Sensors PIN Config
#define HUMIDITY_SENSOR_DIGITAL_PIN 4 // The digital input you attached DHT sensot
#define MOT_SENSOR_PIN 2 // The digital input you attached your motion sensor. (Only 2 and 3 generates interrupt!)
#define INTERRUPT MOT_SENSOR_PIN-2 // Usually the interrupt = pin -2 (on uno/nano anyway)
#define LIGHT_SENSOR_ANALOG_PIN 0 //Подключен фоторезистор
// Send time limits
#define TIME_MAX_REPLAY_LUX 600000 // Maximum time to send values (Lux) even if not changed
#define TIME_MAX_REPLAY_TH 600000 // Maximum time to send values (TH) even if not changed
#define TIME_MIN_REPLAY_LUX 1000 // Minimum time to send values (Lux) even if changed
#define TIME_MIN_REPLAY_TH 60000 // Minimum time to send values (TH) even if changed
#define TIME_MIN_REPLAY_MOT 1000 // Minimum time to send values (Motion) even if changed
#define MAX_DIFF_T 1 // Send immediately when the difference is greater than X degree
#define MAX_DIFF_H 5 // Send immediately when the difference is greater than X percent
#define INTERRUPT_MODE CHANGE
//unsigned long SLEEP_TIME = 1000; // Sleep time between Distance reads (in milliseconds)
// Aufpassen bei SleepTime wg. Watchdog!
#define SLEEP_TIME 1000 // Sleep time between Distance reads (in milliseconds) (be careful with watchdogbe careful with watchdog (if used)!)
//-----------------------------------------------------------------------------------------------
MySensor gw;
MyMessage msgLux(CHILD_ID_LIGHT, V_LIGHT_LEVEL);
float lastLux=-1;
MyMessage msgMot(CHILD_ID_MOTION, V_TRIPPED);
uint16_t lastMot=0;
int oldBatLevel;
boolean metric = true;
DHT dht;
float lastTemp=-999;
float lastHum=-1;
MyMessage msgHum(CHILD_ID_HUM, V_HUM);
MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
//-----------------------------------------------------------------------------------------------
boolean mot_present = true; // can not be autodetected
boolean dht_present = false;
boolean lux_present = false;
//-----------------------------------------------------------------------------------------------
void setup()
{
#if REPEATER == 1
// The third argument enables repeater mode.
// Keep node awake all time (no slepping!). Pump the radio network by calling process() in your loop(). The MySensors library will take care of all routing in the background.
gw.begin(NULL, AUTO, true);
#else
// Normal Node
gw.begin();
#endif
// Init Sensors
// autodetect DHT
dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN);
// warm up
delay(dht.getMinimumSamplingPeriod());
float temperature = dht.getTemperature();
dht_present=!isnan(temperature);
#if DEBUG > 0
if(!dht_present) {
Serial.println("LightSensor not found");
} else {
Serial.println("LightSensor found");
}
#endif
lux_present = true;
oldBatLevel=-1;
// sets the motion sensor digital pin as input
pinMode(MOT_SENSOR_PIN, INPUT);
// Send the sketch version information to the gateway and Controller
const char *sketch_name = "Universal sensor (";
if(mot_present) { sketch_name = strcat(const_cast<char*>(sketch_name),"M"); }
if(lux_present) { sketch_name = strcat(const_cast<char*>(sketch_name),"L"); }
if(dht_present) { sketch_name = strcat(const_cast<char*>(sketch_name),"TH"); }
sketch_name = strcat(const_cast<char*>(sketch_name),")");
#if DEBUG > 0
Serial.print("Sketch: ");
Serial.print(sketch_name);
Serial.print(" Version: ");
Serial.println(VERSION);
#endif
gw.sendSketchInfo(sketch_name, VERSION);
// Register all sensors to gw (they will be created as child devices)
if(mot_present) {
gw.present(CHILD_ID_MOTION, S_MOTION);
}
if(lux_present) {
gw.present(CHILD_ID_LIGHT, S_LIGHT_LEVEL);
}
if(dht_present) {
gw.present(CHILD_ID_HUM, S_HUM);
gw.present(CHILD_ID_TEMP, S_TEMP);
}
//metric = gw.getConfig().isMetric;
#if defined (INTERRUPT)
if(mot_present) {
attachInterrupt(INTERRUPT, sendMot, INTERRUPT_MODE);
}
#endif
//BATTERY_MODE_BANDGAP_MESSUREMENT
// setupBattery(BATTERY_MODE_EXTERNAL_MESSUREMENT, DEF_BATTERY_ENABLE_PIN, DEF_BATTERY_ADC_PIN, DEF_BATTERY_FACT, DEF_BATTERY_TIME);
}
void loop()
{
sendBat();
sendLux();
sendTH();
#if REPEATER == 0
Serial.println("1->");
#if defined (INTERRUPT)
// Sleep until interrupt comes in on motion sensor. Send update every X minutes.
if(mot_present) {
detachInterrupt(INTERRUPT);
}
#endif
Serial.println("2->");
unsigned long periode = 60000;
unsigned long timeMark = cMillis();
while((cMillis()-timeMark)<periode) {
if(sleep(INTERRUPT, INTERRUPT_MODE, SLEEP_TIME)) {
sendMot();
}
}
Serial.println("3->");
Serial.println(cMillis());
#if DEBUG == 1
Serial.println(cMillis());
#endif
#if defined (INTERRUPT)
if(mot_present) {
attachInterrupt(INTERRUPT, sendMot, INTERRUPT_MODE);
}
#endif
Serial.println("4->");
#endif
#if REPEATER != 0
Serial.println("X->");
sendMot();
// process radio messages (use for repeater and aktor nodes)
gw.process();
#endif
}
//-----------------------------------------------------------------------------------------------
// TODO: ggf. nach MSUtils verlagern
unsigned long timeCorrection = 0;
unsigned long cMillis() {
return millis()+timeCorrection;
}
void sleep(unsigned long ms) {
gw.sleep(ms);
timeCorrection += ms;
}
bool sleep(uint8_t interrupt, uint8_t mode, unsigned long ms) {
bool ret = gw.sleep(interrupt,mode, ms);
if(ret) {
// interrupted
// Statistisch dürfe im Mittel dir Hälfte der Zeit ein akzeptabler Wert bei Interrupts sein
timeCorrection += (ms/2);
} else {
timeCorrection += ms;
}
return ret;
}
//-----------------------------------------------------------------------------------------------
unsigned long lastTimeTH=cMillis()+TIME_MIN_REPLAY_TH+1;
void sendTH()
{
if(!dht_present) return;
unsigned long time = cMillis();
// Zeitdifferenz zum letzten Senden
unsigned long delayTime = 0;
// Auf Ueberlauf pruefen
if(time<lastTimeTH)
{
// Ueberlauf: Delay ist Zeit zum MaxWert plus Zeit ab Null
delayTime = MAX_U_LONG-lastTimeTH+time;
} else {
// Kein Ueberlauf: einfache Differenz
delayTime = time-lastTimeTH;
}
#if DEBUG > 1
Serial.print("TimeDiff: ");
Serial.println(delayTime);
#endif
// Mindestabstand beachten
if(delayTime<TIME_MIN_REPLAY_TH)
{
return;
}
// Senden, nur wenn sich der Wert geändert hat
// Nach verstreichen eines definierten Intervals soll in jedem Fall gesendet werden
boolean sendAnyway = delayTime >= TIME_MAX_REPLAY_TH;
// DHT22 braucht 2 Sekunden
// delay(dht.getMinimumSamplingPeriod());
float temperature = dht.getTemperature();
if (isnan(temperature)) {
#if DEBUG > 0
Serial.println("Failed reading temperature from DHT");
#endif
}
else if (sendAnyway || (abs(temperature - lastTemp) > MAX_DIFF_T))
{
lastTemp = temperature;
if (!metric) {
temperature = dht.toFahrenheit(temperature);
}
#if DEBUG > 0
Serial.print("T: ");
Serial.println(temperature);
#endif
gw.send(msgTemp.set(temperature, 1));
lastTimeTH=cMillis();
}
float humidity = dht.getHumidity();
if (isnan(humidity)) {
#if DEBUG > 0
Serial.println("Failed reading humidity from DHT");
#endif
}
else if (sendAnyway || abs(humidity - lastHum) > MAX_DIFF_H)
{
lastHum = humidity;
#if DEBUG > 0
Serial.print("H: ");
Serial.println(humidity);
#endif
gw.send(msgHum.set(humidity, 1));
lastTimeTH=cMillis();
}
}
unsigned long lastTimeLux=cMillis()+TIME_MIN_REPLAY_LUX+1;
void sendLux()
{
if(!lux_present) return;
// Prüfen, ob Sensor antwortet
unsigned long time = cMillis();
// Zeitdifferenz zum letzten Senden
unsigned long delayTime = 0;
// Auf Ueberlauf pruefen
if(time<lastTimeLux)
{
// Ueberlauf: Delay ist Zeit zum MaxWert plus Zeit ab Null
delayTime = MAX_U_LONG-lastTimeLux+time;
} else {
// Kein Ueberlauf: einfache Differenz
delayTime = time-lastTimeLux;
}
#if DEBUG > 1
Serial.print("TimeDiff: ");
Serial.println(delayTime);
#endif
// Mindestabstand beachten
if(delayTime<TIME_MIN_REPLAY_LUX)
{
return;
}
// Senden, nur wenn sich der Wert geändert hat
// Nach verstreichen eines definierten Intervals soll in jedem Fall gesendet werden
boolean sendAnyway = delayTime >= TIME_MAX_REPLAY_LUX;
float lux = (1023-analogRead(LIGHT_SENSOR_ANALOG_PIN)); // /10.23;
#if DEBUG > 1
Serial.print("Lux: ");
Serial.println(lux);
#endif
float diff = abs(lux - lastLux);
boolean doSend = false;
// Weil exponentielle Funktion, mehrere Stufen
if(lastLux<1) {
doSend = diff>0.5;
} else if (lastLux<5) {
doSend = diff>1;
} else if (lastLux<10) {
doSend = diff>2;
} else if (lastLux<100) {
doSend = diff>10;
} else if (lastLux<1000) {
doSend = diff>100;
} else if (lastLux<10000) {
doSend = diff>1000;
} else {
doSend = diff>10000;
}
//if (sendAnyway || aDiff > pAbw) {
if (sendAnyway || doSend) {
#if DEBUG > 0
Serial.print("send Lux: ");
Serial.println(lux);
#endif
//gw.send(msgLux.set(lux));
gw.send(msgLux.set(lux,2));
lastLux = lux;
// Zeit merken
lastTimeLux=cMillis();
}
}
unsigned long lastTimeMot=cMillis()+TIME_MIN_REPLAY_MOT+1;
void sendMot()
{
if(!mot_present) return;
unsigned long time = cMillis();
// Zeitdifferenz zum letzten Senden
unsigned long delayTime = 0;
// Auf Ueberlauf pruefen
if(time<lastTimeMot)
{
// Ueberlauf: Delay ist Zeit zum MaxWert plus Zeit ab Null
delayTime = MAX_U_LONG-lastTimeMot+time;
} else {
// Kein Ueberlauf: einfache Differenz
delayTime = time-lastTimeMot;
}
// Mindestabstand beachten
if(delayTime<TIME_MIN_REPLAY_MOT)
{
return;
}
// Read digital motion value
boolean tripped = digitalRead(MOT_SENSOR_PIN) == HIGH;
// digitalWrite(5,tripped?1:0); //TEST TODO
#if DEBUG > 1
Serial.print("Motion: ");
Serial.println(tripped);
#endif
if(tripped && !lastMot) // muss zwischendurch mal 'false' werden
{
#if DEBUG > 0
Serial.print("send Motion: ");
Serial.println(tripped);
#endif
gw.send(msgMot.set(tripped?"1":"0")); // Send tripped value to gw
//gw.send(msgMot.set("1")); // Send tripped value to gw **********************************
// Zeit merken
lastTimeMot=cMillis();
}
lastMot = tripped;
}
/**
* Cyclic battery measurement function.
*/
void sendBat(void) {
//uint8_t batteryVoltage;
int batLevel = getBatteryLevel();
if (oldBatLevel != batLevel)
{
//gw.powerUp();
gw.sendBatteryLevel(batLevel);
oldBatLevel = batLevel;
}
}
// Battery measure
int getBatteryLevel ()
{
int results = (readVcc() - 2000) / 10;
if (results > 100)
results = 100;
if (results < 0)
results = 0;
return results;
} // end of getBandgap
// when ADC completed, take an interrupt
EMPTY_INTERRUPT (ADC_vect);
long readVcc() {
long result;
// Read 1.1V reference against AVcc
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
delay(2); // Wait for Vref to settle
noInterrupts ();
// start the conversion
ADCSRA |= _BV (ADSC) | _BV (ADIE);
set_sleep_mode (SLEEP_MODE_ADC); // sleep during sample
interrupts ();
sleep_mode ();
// reading should be done, but better make sure
// maybe the timer interrupt fired
while (bit_is_set(ADCSRA,ADSC));
result = ADCL;
result |= ADCH<<8;
result = 1126400L / result; // Back-calculate AVcc in mV
return result;
}
Re: mysensors
Добавлено: Вт июл 05, 2016 4:16 pm
mechgeek
Поймал вот такую ошибку.
Fatal error: Cannot redeclare cmp() (previously declared in C:\_majordomo\htdocs\modules\objects\objects.class.php(514) : eval()'d code:13) in C:\_majordomo\htdocs\modules\objects\objects.class.php(514) : eval()'d code on line 19
2016-07-05 15:48:44 Send: 1;2;1;0;16;0
2016-07-05 15:48:39 Set: Node:1; Sensor:4; Type:1; Ack:0; Sub:1; Msg:33.0
2016-07-05 15:48:39 Set: Node:1; Sensor:3; Type:1; Ack:0; Sub:0; Msg:28.0
2016-07-05 15:48:14 Set: Node:1; Sensor:2; Type:1; Ack:0; Sub:16; Msg:1
2016-07-05 15:47:45 Set: Node:1; Sensor:2; Type:1; Ack:0; Sub:16; Msg:1
2016-07-05 15:47:15 Set: Node:1; Sensor:2; Type:1; Ack:0; Sub:16; Msg:1
После никакие данные с гейта не поступают.
Иногда автоматически переподцепляется к гейту, иногда нужно перезапустить мажордомо.