Skip to content

Development

Discuss Arduino programming, library tips, share example sketches and post your general programming questions.
1.5k Topics 13.5k Posts

Subcategories


  • 56 578
    56 Topics
    578 Posts
    HJ_SKH
    Hi2All! Surprising is here. After about 24hours I refresh HA and suddenly my motion sensor was integrated. There is also second entity > battery : 0 , have to look deeper into that for understanding. Need to change little in the sketch, because don't want every short time 'no movement' so only when there is motion and maybe once a hour indication sensor is alive. Meantime I found 3 other good threats: https://forum.mysensors.org/topic/11200/finally-progress-evidence-based-radio-testing-method-and-capacitors https://forum.mysensors.org/topic/1664/which-are-the-best-nrf24l01-modules/27 https://forum.mysensors.org/topic/9550/build-a-reliable-power-supply-chain Very usefull for me also finally progress because of lacking time in the past. Great jobs are done here! Thanks for this all of you guys or girls!
  • Multiple I2C sensors sketch

    6
    0 Votes
    6 Posts
    4k Views
    TheoLT
    @macieiks I don't think you're question is really related to MySensors, it's more an Arduino related question. The problem you might have is the memory capacity of the Arduino. Here's the sketch for the first mySensor node I made. It uses an I2C lux and i2c barometric pressure sensor and an HDT11 humidity sensor. /** * The MySensors Arduino library handles the wireless radio link and protocol * between your home built sensors/actuators and HA controller of choice. * The sensors forms a self healing radio network with optional repeaters. Each * repeater and gateway builds a routing tables in EEPROM which keeps track of the * network topology allowing messages to be routed to nodes. * * Created by Henrik Ekblad <henrik.ekblad@mysensors.org> * Copyright (C) 2013-2015 Sensnology AB * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors * * Documentation: http://www.mysensors.org * Support Forum: http://forum.mysensors.org * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. * ******************************* * * REVISION HISTORY * Version 1.0 - Henrik EKblad * * DESCRIPTION * This sketch provides an example how to implement a humidity/temperature * sensor using DHT11/DHT-22 * http://www.mysensors.org/build/humidity */ // #define DEBUG #include <SPI.h> #include <MySensor.h> #include <DHT.h> #include <Wire.h> #include <Adafruit_BMP085.h> #include <Adafruit_TSL2561_U.h> #include <Adafruit_Sensor.h> #define CHILD_ID_HUM 0 #define CHILD_ID_TEMP 1 #define CHILD_ID_BARO 2 #define CHILD_ID_LIGHT 3 #define HUMIDITY_SENSOR_DIGITAL_PIN 3 const float ALTITUDE = 28; // <-- adapt this value to your own location's altitude. Lijkt dus in meters te zijn unsigned long SLEEP_TIME = 60000; // Sleep time between reads (in milliseconds) const char *weather[] = { "stable", "sunny", "cloudy", "unstable", "thunderstorm", "unknown" }; enum FORECAST { STABLE = 0, // "Stable Weather Pattern" SUNNY = 1, // "Slowly rising Good Weather", "Clear/Sunny " CLOUDY = 2, // "Slowly falling L-Pressure ", "Cloudy/Rain " UNSTABLE = 3, // "Quickly rising H-Press", "Not Stable" THUNDERSTORM = 4, // "Quickly falling L-Press", "Thunderstorm" UNKNOWN = 5 // "Unknown (More Time needed) }; Adafruit_BMP085 bmp = Adafruit_BMP085(); MySensor gw; Adafruit_TSL2561_Unified tsl = Adafruit_TSL2561_Unified(TSL2561_ADDR_FLOAT, 12345); DHT dht; float lastTemp = -1000; float lastHum = -1; float lastPressure = -1; int lastForecast = -1; int lastLightLevel = -1; const int LAST_SAMPLES_COUNT = 5; float lastPressureSamples[LAST_SAMPLES_COUNT]; // this CONVERSION_FACTOR is used to convert from Pa to kPa in forecast algorithm // get kPa/h be dividing hPa by 10 #define CONVERSION_FACTOR (1.0/10.0) int minuteCount = 0; bool firstRound = true; // average value is used in forecast algorithm. float pressureAvg; // average after 2 hours is used as reference value for the next iteration. float pressureAvg2; float dP_dt; MyMessage msgHum(CHILD_ID_HUM, V_HUM); MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP); MyMessage pressureMsg(CHILD_ID_BARO, V_PRESSURE); MyMessage forecastMsg(CHILD_ID_BARO, V_FORECAST); MyMessage lightMsg(CHILD_ID_LIGHT, V_LIGHT_LEVEL); /**************************************************************************/ /* Displays some basic information on this sensor from the unified sensor API sensor_t type (see Adafruit_Sensor for more information) */ /**************************************************************************/ #ifdef DEBUG void displaySensorDetails(void) { sensor_t sensor; tsl.getSensor(&sensor); Serial.println("------------------------------------"); Serial.print ("Sensor: "); Serial.println(sensor.name); Serial.print ("Driver Ver: "); Serial.println(sensor.version); Serial.print ("Unique ID: "); Serial.println(sensor.sensor_id); Serial.print ("Max Value: "); Serial.print(sensor.max_value); Serial.println(" lux"); Serial.print ("Min Value: "); Serial.print(sensor.min_value); Serial.println(" lux"); Serial.print ("Resolution: "); Serial.print(sensor.resolution); Serial.println(" lux"); Serial.println("------------------------------------"); Serial.println(""); delay(500); } #endif /**************************************************************************/ /* Configures the gain and integration time for the TSL2561 */ /**************************************************************************/ void configureSensor(void) { /* You can also manually set the gain or enable auto-gain support */ // tsl.setGain(TSL2561_GAIN_1X); /* No gain ... use in bright light to avoid sensor saturation */ // tsl.setGain(TSL2561_GAIN_16X); /* 16x gain ... use in low light to boost sensitivity */ tsl.enableAutoRange(true); /* Auto-gain ... switches automatically between 1x and 16x */ /* Changing the integration time gives you better sensor resolution (402ms = 16-bit data) */ tsl.setIntegrationTime(TSL2561_INTEGRATIONTIME_13MS); /* fast but low resolution */ // tsl.setIntegrationTime(TSL2561_INTEGRATIONTIME_101MS); /* medium resolution and speed */ // tsl.setIntegrationTime(TSL2561_INTEGRATIONTIME_402MS); /* 16-bit data but slowest conversions */ /* Update these values depending on what you've set above! */ #ifdef DEBUG Serial.println("------------------------------------"); Serial.print ("Gain: "); Serial.println("Auto"); Serial.print ("Timing: "); Serial.println("13 ms"); Serial.println("------------------------------------"); #endif } void setup() { gw.begin(); #ifdef DEBUG Serial.begin(115200); Serial.println("Light Sensor Test"); Serial.println("115200"); #endif dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); // Send the Sketch Version Information to the Gateway gw.sendSketchInfo("Inside weather conditions", "1.0"); /* Only presenting the sensors if they're available */ if (bmp.begin()) { gw.present(CHILD_ID_BARO, S_BARO); } #ifdef DEBUG else { Serial.println( 'Barometer not found' ); } #endif if(!tsl.begin()) { #ifdef DEBUG /* There was a problem detecting the ADXL345 ... check your connections */ Serial.print( "Ooops, no TSL2561 detected ... Check your wiring or I2C ADDR!" ); #endif // while(1); } else { #ifdef DEBUG /* Display some basic information on this sensor */ displaySensorDetails(); #endif /* Setup the sensor gain and integration time */ configureSensor(); gw.present(CHILD_ID_LIGHT, S_LIGHT_LEVEL); } // Register all sensors to gw (they will be created as child devices) gw.present(CHILD_ID_HUM, S_HUM); gw.present(CHILD_ID_TEMP, S_TEMP); gw.sendBatteryLevel( 100 ); } void loop() { delay(dht.getMinimumSamplingPeriod()); float pressure = bmp.readSealevelPressure(ALTITUDE) / 100.0; float temperature = bmp.readTemperature(); int forecast = sample(pressure); #ifdef DEBUG float dhtTemperature = dht.getTemperature(); Serial.print("Temperature = "); Serial.print(temperature); Serial.println( " *C" ); Serial.print("Pressure = "); Serial.print(pressure); Serial.println(" hPa"); Serial.print("Forecast = "); Serial.println(weather[forecast]); Serial.print( "Dht Temp: " ); Serial.print(dhtTemperature); Serial.println( " *C" ); #endif if (isnan(temperature)) { #ifdef DEBUG Serial.println("Failed reading temperature from DHT"); #endif } else if (temperature != lastTemp) { lastTemp = temperature; gw.send(msgTemp.set(temperature, 1)); #ifdef DEBUG Serial.print("T: "); Serial.println(temperature); #endif } float humidity = dht.getHumidity(); if (isnan(humidity)) { #ifdef DEBUG Serial.println("Failed reading humidity from DHT"); #endif } else if (humidity != lastHum) { lastHum = humidity; gw.send(msgHum.set(humidity, 1)); #ifdef DEBUG Serial.print("H: "); Serial.println(humidity); #endif } sensors_event_t event; // maybe a delay between the sensor readings tsl.getEvent(&event); /* Display the results (light is measured in lux) */ // if (event.light) { // removed test to see if we get a 0 meeting during the evening and night. #ifdef DEBUG Serial.print(event.light); Serial.println(" lux"); #endif if ( event.light != lastLightLevel ) { gw.send(lightMsg.set((uint16_t)event.light)); lastLightLevel = event.light; } /* } // removed test to see if we get a 0 meeting during the evening and night. else { // If event.light = 0 lux the sensor is probably saturated and no reliable data could be generated! #ifdef DEBUG Serial.println("Sensor overload"); #endif } */ if (pressure != lastPressure) { gw.send(pressureMsg.set(pressure, 0)); lastPressure = pressure; } if (forecast != lastForecast) { gw.send(forecastMsg.set(weather[forecast])); lastForecast = forecast; } gw.sleep(SLEEP_TIME); //sleep a bit } float getLastPressureSamplesAverage() { float lastPressureSamplesAverage = 0; for (int i = 0; i < LAST_SAMPLES_COUNT; i++) { lastPressureSamplesAverage += lastPressureSamples[i]; } lastPressureSamplesAverage /= LAST_SAMPLES_COUNT; return lastPressureSamplesAverage; } // Algorithm found here // http://www.freescale.com/files/sensors/doc/app_note/AN3914.pdf // Pressure in hPa --> forecast done by calculating kPa/h int sample(float pressure) { // Calculate the average of the last n minutes. int index = minuteCount % LAST_SAMPLES_COUNT; lastPressureSamples[index] = pressure; minuteCount++; if (minuteCount > 185) { minuteCount = 6; } if (minuteCount == 5) { pressureAvg = getLastPressureSamplesAverage(); } else if (minuteCount == 35) { float lastPressureAvg = getLastPressureSamplesAverage(); float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR; if (firstRound) // first time initial 3 hour { dP_dt = change * 2; // note this is for t = 0.5hour } else { dP_dt = change / 1.5; // divide by 1.5 as this is the difference in time from 0 value. } } else if (minuteCount == 65) { float lastPressureAvg = getLastPressureSamplesAverage(); float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR; if (firstRound) //first time initial 3 hour { dP_dt = change; //note this is for t = 1 hour } else { dP_dt = change / 2; //divide by 2 as this is the difference in time from 0 value } } else if (minuteCount == 95) { float lastPressureAvg = getLastPressureSamplesAverage(); float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR; if (firstRound) // first time initial 3 hour { dP_dt = change / 1.5; // note this is for t = 1.5 hour } else { dP_dt = change / 2.5; // divide by 2.5 as this is the difference in time from 0 value } } else if (minuteCount == 125) { float lastPressureAvg = getLastPressureSamplesAverage(); pressureAvg2 = lastPressureAvg; // store for later use. float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR; if (firstRound) // first time initial 3 hour { dP_dt = change / 2; // note this is for t = 2 hour } else { dP_dt = change / 3; // divide by 3 as this is the difference in time from 0 value } } else if (minuteCount == 155) { float lastPressureAvg = getLastPressureSamplesAverage(); float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR; if (firstRound) // first time initial 3 hour { dP_dt = change / 2.5; // note this is for t = 2.5 hour } else { dP_dt = change / 3.5; // divide by 3.5 as this is the difference in time from 0 value } } else if (minuteCount == 185) { float lastPressureAvg = getLastPressureSamplesAverage(); float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR; if (firstRound) // first time initial 3 hour { dP_dt = change / 3; // note this is for t = 3 hour } else { dP_dt = change / 4; // divide by 4 as this is the difference in time from 0 value } pressureAvg = pressureAvg2; // Equating the pressure at 0 to the pressure at 2 hour after 3 hours have past. firstRound = false; // flag to let you know that this is on the past 3 hour mark. Initialized to 0 outside main loop. } int forecast = UNKNOWN; if (minuteCount < 35 && firstRound) //if time is less than 35 min on the first 3 hour interval. { forecast = UNKNOWN; } else if (dP_dt < (-0.25)) { forecast = THUNDERSTORM; } else if (dP_dt > 0.25) { forecast = UNSTABLE; } else if ((dP_dt > (-0.25)) && (dP_dt < (-0.05))) { forecast = CLOUDY; } else if ((dP_dt > 0.05) && (dP_dt < 0.25)) { forecast = SUNNY; } else if ((dP_dt >(-0.05)) && (dP_dt < 0.05)) { forecast = STABLE; } else { forecast = UNKNOWN; } // uncomment when debugging #ifdef DEBUG Serial.print(F("Forecast at minute ")); Serial.print(minuteCount); Serial.print(F(" dP/dt = ")); Serial.print(dP_dt); Serial.print(F("kPa/h --> ")); Serial.println(weather[forecast]); #endif return forecast; }
  • Reducing number of cpu cycles while sending lots of data

    6
    0 Votes
    6 Posts
    1k Views
    OitzuO
    Also contra: no signing
  • 0 Votes
    4 Posts
    2k Views
    hautomateH
    Ah yes... Thanks, folks! I got my sketches mixed up and was using a 1.5 version.
  • Beginner First node setup issue

    2
    0 Votes
    2 Posts
    666 Views
    mfalkviddM
    Hi @Cyberzoid Welcome to MySensors! A description of how ro read all the output is available at http://forum.mysensors.org/topic/666/debug-faq-and-how-ask-for-help
  • Arduino Sketch Help BPM180 and LCD output

    8
    0 Votes
    8 Posts
    4k Views
    microwhattM
    HAHAHA Thank you ! :)
  • How is a message from the controller written to a digital pin?

    12
    0 Votes
    12 Posts
    3k Views
    martinhjelmareM
    Well you could store the boolean variables for the valves in an array, and use the sensor child id as the index of the variables in the array. You can also use the setSensor setter on the message variable (MSG_V1) to change which sensor child id the message belongs to. That way, you only need to declare one message variable. You can use two setters on the same line like this: // Set child id 1 to 0 to simplify using it as index in an array #define CHILD_ID1 0 // Set child id 2 to 1 which is the next index after index 0. #define CHILD_ID2 1 // Declare an array of type boolean of size 2. boolean VALVES[2]; // Declare the message with CHILD_ID1. MyMessage MSG(CHILD_ID1, V_LIGHT); void setup() { ... } ... void incomingMessage(const MyMessage &message) { if (message.type == V_LIGHT) { // Set array element at index message.sensor to boolean value from message payload. VALVES[message.sensor] = message.getBool(); // Set child id to child id of message.sensor and payload to either 1 or 0 for message, and send message. gw.send(MSG.setSensor(message.sensor).set(message.getBool() ? 1 : 0)); } } Sorry... there was a lot of edits. Now I'm done.... :smile:
  • Can it be done? (Countdown timer that survives wait or sleep)

    21
    0 Votes
    21 Posts
    6k Views
    Mark SwiftM
    @TheoL With regards the LED's, I slightly changed the logic so they count down, rather than up, i.e. they extinguish as each hour passes until the 4th hour. I don't see an issue with the current rain sensor / moisture sensor logic, I'm ensuring a reading is taken, but not seeing it unless they've changed? The number you see there now is only because I was testing, normally they're either lastMoistureValue = moistureValue OR lastRainValue = rainValue The main issue I see is that I need to countdown to be in sync with if (lastMoistureValue == 0 || lastRainValue == 0) so if (lastMoistureValue == 0 || lastRainValue == 0) is true on each loop, then the countdown LED's are reset also. I'll no doubt change the loop wait to much longer once deployed.
  • MQTT Client gateway

    91
    3 Votes
    91 Posts
    52k Views
    rollercontainerR
    Got it to work. Removed serial.print lines and changed sleep() to wait().
  • energy pulse sketch for multiple s0-counters

    1
    0 Votes
    1 Posts
    596 Views
    No one has replied
  • Repeater not working?

    3
    0 Votes
    3 Posts
    1k Views
    ?
    Yeah @hek, i defined it after #include MySensor.h, so it was not properly defined :+1: Thanks!
  • Registered Temperature Sensors on Mysensors, need Help

    3
    0 Votes
    3 Posts
    701 Views
    hekH
    You could probably simplify this sketch a bit... Look in the debug log and check it sends any temp data... If not, add debug in some locations until you find the problem. For instance what temp value you actually get when reading it from the dallas sensor.
  • Is this possible? MQTT & Node request...

    5
    0 Votes
    5 Posts
    1k Views
    noelgeorgiN
    @Mark-Swift check this for node-to-node communication http://forum.mysensors.org/topic/3467/basic-setup-network/2 as @hek said setup a database in nodered to save the values received from node-1 and you could request that from node-2
  • [Solved] How disable sleep timer ?

    7
    0 Votes
    7 Posts
    2k Views
    carlierdC
    Hello @m26872 , I set some serial.print in the code and found that i need to add some node.sleep when an incorrect key is pushed. The problem was due to the fact that the interruption pin is still valid when i restart the loop function ! David.
  • only one arduino to domoticz without radio

    10
    0 Votes
    10 Posts
    6k Views
    M
    @Roland And does it work?
  • Pulse Sensor for electricity sketch question

    3
    0 Votes
    3 Posts
    722 Views
    Bert BroekB
    I think the result is a floating point number but the divider isn't. I'm going to rewrite the formula so it matches my old sketch which was working correctly.
  • Sending Message from SerialGateway Node to RelayActuator

    9
    0 Votes
    9 Posts
    5k Views
    سیدعظیم عباسس
    Thanks that really worked for me.
  • 2.0 beta, compatible with 1.5?

    7
    1 Votes
    7 Posts
    3k Views
    C
    @rollercontainer correct
  • Wireless Communication Message Format

    3
    0 Votes
    3 Posts
    1k Views
    hekH
    Look at the MyMessage.h, it contains the struct that is sent OTA.
  • This topic is deleted!

    1
    0 Votes
    1 Posts
    40 Views
    No one has replied
  • Sensors without a gateway..?

    4
    0 Votes
    4 Posts
    2k Views
    Nca78N
    @Brayton-Larson Hello, old topic but if anyone is interested it's simple to implement. You need to know the node ID of the receiving node, and send it a message from the gateway. In the development version use the receive method/event that will trigger every time your node or gateway receives a message, if the message is sent by the door node, then you can send a message to the receiving node, and use the same receive method in the node to display a message/use the buzzer/... void receive(const MyMessage &msg) { // here process the message, see API/examples } And you can even use the esp8266 gateway to ring the buzzer directly to make it even more simple, then you only need one esp8266 as gateway and arduino/nrf24 as node.

14

Online

11.7k

Users

11.2k

Topics

113.1k

Posts