problem in SoilMoistSensor
-
hi
i have problem in SoilMoistSensor too
with out water value is -8 -9 % ...
with water this is -30 -40 +20% . . .
-
(thread moved to Troubleshooting from My Project)
Description of My Project: Show off and share your great projects here! We love pictures!
Description of Troubleshooting: Help! Everything just falls apartThe above post seems to fit the description for Troubleshooting much better.
-
@mfalkvidd ok
-
I haven't used the SoilMoistSensor sketch, but the comments at the top of the file says that it reports level, not percent, and that the levels you are describing are reasonable.
What numbers are you expecting?
-
@mfalkvidd
this is not true !
in my app (imperihome) is -1% now !!! and after sense is -8 or -28 or +20 and . . .
-
why not post the sketch you are using?
-
@BulldogLowell hi
I use same code in mysesors.org without any changes#include <math.h> // Conversion equation from resistance to %
#include <SPI.h>
#include <MySensor.h>// Setting up format for reading 3 soil sensors
#define NUM_READS 10 // Number of sensor reads for filtering
#define CHILD_ID 0MySensor gw; // Arduino initialization
MyMessage msg(CHILD_ID, V_LEVEL);
unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds)long buffer[NUM_READS];
int index;typedef struct { // Structure to be used in percentage and resistance values matrix to be filtered (have to be in pairs)
int moisture;
long resistance;
} values;const long knownResistor = 4700; // Constant value of known resistor in Ohms
int supplyVoltage; // Measured supply voltage
int sensorVoltage; // Measured sensor voltagevalues valueOf[NUM_READS]; // Calculated moisture percentages and resistances to be sorted and filtered
int i; // Simple index variable
void setup() {
// initialize serial communications at 9600 bps:
Serial.begin(115200);
gw.begin();
gw.sendSketchInfo("Soil Moisture Sensor Reverse Polarity", "1.0");
gw.present(CHILD_ID, S_HUM);
// initialize the digital pins as an output.
// Pin 6,7 is for sensor 1
// initialize the digital pin as an output.
// Pin 6 is sense resistor voltage supply 1
pinMode(6, OUTPUT);// initialize the digital pin as an output.
// Pin 7 is sense resistor voltage supply 2
pinMode(7, OUTPUT);}
void loop() {
measure(6,7,1); Serial.print ("\t"); Serial.println (average()); long read1 = average(); measure(7,6,0); Serial.print ("\t"); Serial.println (average()); long read2= average(); long sensor1 = (read1 + read2)/2; Serial.print ("resistance bias =" ); Serial.println (read1-read2); Serial.print ("sensor bias compensated value = "); Serial.println (sensor1); Serial.println (); //send back the values gw.send(msg.set((long int)ceil(sensor1))); // delay until next measurement (msec) gw.sleep(SLEEP_TIME);
}
void measure (int phase_b, int phase_a, int analog_input)
{
// read sensor, filter, and calculate resistance value
// Noise filter: median filterfor (i=0; i<NUM_READS; i++) {
// Read 1 pair of voltage values digitalWrite(phase_a, HIGH); // set the voltage supply on delayMicroseconds(25); supplyVoltage = analogRead(analog_input); // read the supply voltage delayMicroseconds(25); digitalWrite(phase_a, LOW); // set the voltage supply off delay(1); digitalWrite(phase_b, HIGH); // set the voltage supply on delayMicroseconds(25); sensorVoltage = analogRead(analog_input); // read the sensor voltage delayMicroseconds(25); digitalWrite(phase_b, LOW); // set the voltage supply off // Calculate resistance // the 0.5 add-term is used to round to the nearest integer // Tip: no need to transform 0-1023 voltage value to 0-5 range, due to following fraction long resistance = (knownResistor * (supplyVoltage - sensorVoltage ) / sensorVoltage) ; delay(1); addReading(resistance); Serial.print (resistance); Serial.print ("\t");
}
}// Averaging algorithm
void addReading(long resistance){
buffer[index] = resistance;
index++;
if (index >= NUM_READS) index = 0;
}long average(){
long sum = 0;
for (int i = 0; i < NUM_READS; i++){
sum += buffer[i];
}
return (long)(sum / NUM_READS);
}
-
Well, I really don't like a few things in that sketch, like the struct that is never used, for example.
or using a global variable as an array index:
int i; // Simple index variable
or superfluous nonsense comments:
// initialize serial communications at 9600 bps: Serial.begin(115200);
The other thing is that the "average" function may be using junk until you take 10 readings, and that takes 5 minutes to clear out:
long buffer[NUM_READS];
try this instead which will initialize the array to zeroes:
long buffer[NUM_READS] = {0};
also, we ought to modify the addReading() and average() functions to size itself for the first 9 readings....
There may be other datatype issues, but let's start here.
-
@BulldogLowell said:
or superfluous nonsense comments:
my friend i am weak in coding, I just use this device for my home . so please Correction the code and send to me . please
thank you
-
well, I have no way of testing
but I would do like this:
#include <math.h> // Conversion equation from resistance to % #include <SPI.h> #include <MySensor.h> #include "CircularBuffer.h" #define NUM_READS 10 // Number of sensor reads for filtering #define CHILD_ID 0 CircularBuffer forward(NUM_READS); CircularBuffer reverse(NUM_READS); MySensor gw; // Arduino initialization MyMessage msg(CHILD_ID, V_LEVEL); unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds) long buffer[NUM_READS]; const long knownResistor = 4700; // Constant value of known resistor in Ohms void setup() { Serial.begin(9600); gw.begin(); gw.sendSketchInfo("Soil Moisture Sensor Reverse Polarity", "1.0"); gw.present(CHILD_ID, S_HUM); pinMode(6, OUTPUT); pinMode(7, OUTPUT); } void loop() { forward.addElement(measure(6, 7, 1)); reverse.addElement(measure(7, 6, 0)); Serial.print ("forward average:"); Serial.println (forward.mean()); Serial.print ("reverse average:"); Serial.println (reverse.mean()); float sensor1 = long((forward.mean() + reverse.mean()) / 2.0); Serial.print ("resistance bias =" ); Serial.println (forward.mean() - reverse.mean()); Serial.print ("sensor bias compensated value = "); Serial.println (sensor1); Serial.println (); gw.send(msg.set((long int)ceil(sensor1))); gw.sleep(SLEEP_TIME); } long int measure (int phase_b, int phase_a, int analog_input) { for (int i = 0; i < NUM_READS; i++) { // Read 1 pair of voltage values digitalWrite(phase_a, HIGH); // set the voltage supply on delayMicroseconds(25); long int supplyVoltage = analogRead(analog_input); // read the supply voltage delayMicroseconds(25); digitalWrite(phase_a, LOW); // set the voltage supply off delay(1); digitalWrite(phase_b, HIGH); // set the voltage supply on delayMicroseconds(25); long int sensorVoltage = analogRead(analog_input); // read the sensor voltage delayMicroseconds(25); digitalWrite(phase_b, LOW); // set the voltage supply off delay(1); return long((knownResistor * (supplyVoltage - sensorVoltage ) / sensorVoltage)); } }
1: Start wiht a new sketch
2: add two tabs to the sketch like this:
3: paste these library files into the two tabs:
CircularBuffer.h#ifndef CircularBuffer_h #define CircularBuffer_h #include <Arduino.h> class CircularBuffer { public: CircularBuffer(size_t size); void addElement(float newElement); float mean(); float maxVal(); float minVal(); float sigma(); size_t numElements(); float arrayElement(int location); private: float* array; float* next; size_t size; int index = 0; int num_elements = 0; }; #endif
CircularBuffer.cpp
#include "CircularBuffer.h" #include <Arduino.h> CircularBuffer::CircularBuffer(size_t arraySize) { size = arraySize; array = new float[arraySize]; next = &array[0]; } void CircularBuffer::addElement(float newElement) { *next = newElement; index++; if (index >= size) { index = 0; } next = &array[index]; if (++num_elements > size) { num_elements = size; } } float CircularBuffer::arrayElement(int location) { return array[location]; } float CircularBuffer::mean() { float average = 0; for (int i = 0; i < num_elements; i++) { average += array[i]; } return average / num_elements; } size_t CircularBuffer::numElements() { return num_elements; } float CircularBuffer::maxVal() { float maximum; for (int i = 0; i < num_elements; i++) { if (i == 0) { maximum = array[0]; } else if (array[i] > maximum) { maximum = array[i]; } } return maximum; } float CircularBuffer::minVal() { float minimum; for (int i = 0; i < num_elements; i++) { if (i == 0) { minimum = array[0]; } else if (array[i] < minimum) { minimum = array[i]; } } return minimum; } float CircularBuffer::sigma() { float average = mean(); float sigma = 0; for(int i = 0; i < min(size, num_elements) ; i++) { sigma += ((array[i] - average) * (array[i] - average)); } return sqrt(sigma / min(size, num_elements)); }
-
@BulldogLowell said:
#include "CircularBuffer.h"
#include <Arduino.h>CircularBuffer::CircularBuffer(size_t arraySize)
{
size = arraySize;
array = new float[arraySize];
next = &array[0];
}void CircularBuffer::addElement(float newElement)
{
*next = newElement;
index++;
if (index >= size)
{
index = 0;
}
next = &array[index];
if (++num_elements > size)
{
num_elements = size;
}
}float CircularBuffer::arrayElement(int location)
{
return array[location];
}float CircularBuffer::mean()
{
float average = 0;
for (int i = 0; i < num_elements; i++)
{
average += array[i];
}
return average / num_elements;
}size_t CircularBuffer::numElements()
{
return num_elements;
}float CircularBuffer::maxVal()
{
float maximum;
for (int i = 0; i < num_elements; i++)
{
if (i == 0)
{
maximum = array[0];
}
else if (array[i] > maximum)
{
maximum = array[i];
}
}
return maximum;
}
float CircularBuffer::minVal()
{
float minimum;
for (int i = 0; i < num_elements; i++)
{
if (i == 0)
{
minimum = array[0];
}
else if (array[i] < minimum)
{
minimum = array[i];
}
}
return minimum;
}
float CircularBuffer::sigma()
{
float average = mean();
float sigma = 0;
for(int i = 0; i < min(size, num_elements) ; i++)
{
sigma += ((array[i] - average) * (array[i] - average));
}
return sqrt(sigma / min(size, num_elements));
}this is not true .i test with full water and few water and no water but Numbers in disarray for example first secend is -8% and next 2% and next -16% and next 24% and next -7% . . .
-
@Reza said:
this is not true .i test with full water and few water and no water but Numbers in disarray for example first secend is -8% and next 2% and next -16% and next 24% and next -7% . . .
I don't know what "this is not true" is meant to say...
As I mentioned, I cannot test. Perhaps you could show the Serial output using this modification of the sketch, changing the sleep in loop() to this:
delay(1000);
-
@BulldogLowell
amount of humidity should be between 0 and 100% . is it true ? but my sensor showed me the different numbers.for example -8% -30% and....
-