@mfalkvidd
I have assembled a copy of @carlierd 's office plant monitor since it looked kinda neat.
When I first tried to upload @carlierd 's Moisture_sensor.ino it complained that several libraries were missing.
So I started google-fu around to find them.
What was missing was:
MyTransportRFM69.h
MyTransport.h
MySigningAtsha204Soft.h
MySigning.h
MyMessage.h
aswell as drivers, that I placed in folder /utility/
ATSHA204.h
RFM69.h
sha256.h
The code is as follows. I have only pressed include mysensors' library since it complained that it was missing.
/**
* 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.
*
* Code and idea from mfalkvidd (http://forum.mysensors.org/user/mfalkvidd).
*
*/
/**************************************************************************************/
/* Moisture sensor. */
/* */
/* Version : 1.2.5 */
/* Date : 11/04/2016 */
/* Modified by : David Carlier */
/**************************************************************************************/
/* --------------- */
/* RST | | A5 */
/* RX | | A4 */
/* TX | ARDUINO | A3 */
/* RFM69 (DIO0) --------- D2 | UNO | A2 */
/* D3 | | A1 --------- Moisture probe */
/* Power --------- D4 | ATMEGA 328p | A0 --------- Moisture probe */
/* +3v --------- VCC | | GND --------- GND */
/* GND --------- GND | 8MHz int. | REF */
/* OSC | | VCC --------- +3v */
/* OSC | | D13 --------- RFM69 (SCK) */
/* D5 | | D12 --------- RFM69 (MISO) */
/* D6 | | D11 --------- RFM69 (MOSI) */
/* D7 | | D10 --------- RFM69 (NSS) */
/* LED --------- D8 | | D9 */
/* --------------- */
/* */
/* +3v = 2*AA */
/* */
/**************************************************************************************/
#include <SPI.h>
#include <MySensors.h>
#include <MyTransportRFM69.h>
#include <MySigningAtsha204Soft.h>
//Define functions
#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
#define N_ELEMENTS(array) (sizeof(array)/sizeof((array)[0]))
//Constants for MySensors
#define SKETCH_NAME "Moisture Sensor"
#define SKETCH_VERSION "1.2.6"
#define CHILD_ID_MOISTURE 0
#define CHILD_ID_VOLTAGE 1
#define LED_PIN 8
#define THRESHOLD 1.1 // Only make a new reading with reverse polarity if the change is larger than 10%
#define STABILIZATION_TIME 1000 // Let the sensor stabilize before reading
//#define BATTERY_FULL 3143 // 2xAA usually gives 3.143V when full
#define BATTERY_FULL 3100 // CR2032 usually gives 3.1V when full
#define BATTERY_ZERO 2340 // 2.34V limit for 328p at 8MHz
#define SLEEP_TIME 7200000 // Sleep time between reads (in milliseconds) (close to 2 hours)
const int SENSOR_ANALOG_PINS[] = {A0, A1};
//Variables
byte direction = 0;
int oldMoistureLevel = -1;
//Construct MySensors library
MySigningAtsha204Soft signer;
MyHwATMega328 hw;
MyTransportRFM69 transport;
MySensor node(transport, hw, signer);
MyMessage msgMoisture(CHILD_ID_MOISTURE, V_HUM);
MyMessage msgVolt(CHILD_ID_VOLTAGE, V_VOLTAGE);
/**************************************************************************************/
/* Initialization */
/**************************************************************************************/
void setup()
{
//Get time (for setup duration)
#ifdef DEBUG
unsigned long startTime = millis();
#endif
//Setup LED pin
pinMode(LED_PIN, OUTPUT);
blinkLedFastly(3);
//Set moisutre sensor pins
for (int i = 0; i < N_ELEMENTS(SENSOR_ANALOG_PINS); i++)
{
pinMode(SENSOR_ANALOG_PINS[i], OUTPUT);
digitalWrite(SENSOR_ANALOG_PINS[i], LOW);
}
//Start MySensors and send the sketch version information to the gateway
node.begin();
node.sendSketchInfo(SKETCH_NAME, SKETCH_VERSION);
//Register all sensors
node.present(CHILD_ID_MOISTURE, S_HUM);
node.present(CHILD_ID_VOLTAGE, S_MULTIMETER);
//Setup done !
blinkLedFastly(3);
//Print setup debug
#ifdef DEBUG
int duration = millis() - startTime;
Serial.print("[Setup duration: "); Serial.print(duration, DEC); Serial.println(" ms]");
#endif
}
/**************************************************************************************/
/* Main loop */
/**************************************************************************************/
void loop()
{
//Get time (for a complete loop)
#ifdef DEBUG
unsigned long startTime = millis();
#endif
//Get moisture level
int moistureLevel = readMoisture();
//Send rolling average of 2 samples to get rid of the "ripple" produced by different resistance in the internal pull-up resistors
//See http://forum.mysensors.org/topic/2147/office-plant-monitoring/55 for more information
//Check if it was first reading, save current value as old
if (oldMoistureLevel == -1)
{
oldMoistureLevel = moistureLevel;
}
//Verify if current measurement is not too far from the previous one
if (moistureLevel > (oldMoistureLevel * THRESHOLD) || moistureLevel < (oldMoistureLevel / THRESHOLD))
{
//The change was large, so it was probably not caused by the difference in internal pull-ups.
//Measure again, this time with reversed polarity.
moistureLevel = readMoisture();
}
//Store current moisture level
oldMoistureLevel = moistureLevel;
//Report data to the gateway
long voltage = getVoltage();
node.send(msgMoisture.set((moistureLevel + oldMoistureLevel) / 2.0 / 10.23, 1));
node.send(msgVolt.set(voltage / 1000.0, 2));
int batteryPcnt = round((voltage - BATTERY_ZERO) * 100.0 / (BATTERY_FULL - BATTERY_ZERO));
if (batteryPcnt > 100) {batteryPcnt = 100;}
node.sendBatteryLevel(batteryPcnt);
//Print debug
#ifdef DEBUG
Serial.print((moistureLevel + oldMoistureLevel) / 2.0 / 10.23);
Serial.print("%");
Serial.print(" ");
Serial.print(voltage / 1000.0);
Serial.print("v");
Serial.print(" ");
Serial.print(batteryPcnt);
Serial.print("%");
int duration = millis() - startTime;
Serial.print(" ");
Serial.print("["); Serial.print(duration, DEC); Serial.println(" ms]");
Serial.flush();
#endif
//Sleep until next measurement
blinkLedFastly(1);
node.sleep(SLEEP_TIME);
}
/**************************************************************************************/
/* Allows to get moisture. */
/**************************************************************************************/
int readMoisture()
{
//Power on the sensor and read once to let the ADC capacitor start charging
pinMode(SENSOR_ANALOG_PINS[direction], INPUT_PULLUP);
analogRead(SENSOR_ANALOG_PINS[direction]);
//Stabilize and read the value
node.sleep(STABILIZATION_TIME);
int moistureLevel = (1023 - analogRead(SENSOR_ANALOG_PINS[direction]));
//Turn off the sensor to conserve battery and minimize corrosion
pinMode(SENSOR_ANALOG_PINS[direction], OUTPUT);
digitalWrite(SENSOR_ANALOG_PINS[direction], LOW);
//Make direction alternate between 0 and 1 to reverse polarity which reduces corrosion
direction = (direction + 1) % 2;
return moistureLevel;
}
/**************************************************************************************/
/* Allows to fastly blink the LED. */
/**************************************************************************************/
void blinkLedFastly(byte loop)
{
byte delayOn = 150;
byte delayOff = 150;
for (int i = 0; i < loop; i++)
{
blinkLed(LED_PIN, delayOn);
delay(delayOff);
}
}
/**************************************************************************************/
/* Allows to blink a LED. */
/**************************************************************************************/
void blinkLed(byte pinToBlink, int delayInMs)
{
digitalWrite(pinToBlink,HIGH);
delay(delayInMs);
digitalWrite(pinToBlink,LOW);
}
/**************************************************************************************/
/* Allows to get the real Vcc (return value in mV). */
/* http://provideyourown.com/2012/secret-arduino-voltmeter-measure-battery-voltage/ */
/**************************************************************************************/
long getVoltage()
{
ADMUX = (0<<REFS1) | (1<<REFS0) | (0<<ADLAR) | (1<<MUX3) | (1<<MUX2) | (1<<MUX1) | (0<<MUX0);
delay(50); // Let mux settle a little to get a more stable A/D conversion
//Start a conversion
ADCSRA |= _BV( ADSC );
//Wait for it to complete
while (bit_is_set(ADCSRA, ADSC));
//Compute and return the value
uint8_t low = ADCL; // must read ADCL first - it then locks ADCH
uint8_t high = ADCH; // unlocks both
long result = (high << 8) | low;
result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
return result; // Vcc in millivolts
}
I have just installed Arduino IDE, and are using the latest mysensors library 2.1.1.
Another thing it complains about is:
Invalid library found in C:\...\Arduino\libraries\Moisture_sensor: C:\...\Arduino\libraries\Moisture_sensor```
which is wierd since I have just copy+pasted it from here:
https://www.openhardware.io/view/123/Office-plant-monitor
aswell as built the sensor from there.
If you can help, I would be very glad, as I just hoped it would be smooth sailing using mysensors. Build, upload and let it work its magic.
Tack på förhand!
Simon