And this is the sketchbook zip: pompie.zip
Next time I will talk trough the code.
Saturday, May 5, 2007
Friday, April 27, 2007
Friday, March 30, 2007
The arduino source:
/* Pompie software to control the pump of a pond
* (c) Marco Dumont
* This is completly "do what you like with it" sourcecode
* The pupose is a device that switches the pump to the filter, a natural swamp filter off ->
* when it is to hot >30 or to cold <0>
* The time the pump is on is limited - the plants need time to filter the nutrians, so fuzzy controls should be used.
* Another advantage is that this saves energy.
*/
#define ledPin 13 // LED connected to digital pin 13
#define pumpPin 12 // Pin switching the pump on/off
#define airPin 11 // Pin switching the airpump on/off
#define analog_temp_air 0 //analog temp of the air at 1 meter
#define analog_temp_surface 1 //temp of the watersurface
#define analog_temp_swamp 2 //temp of the water in the swamp
#define analog_water_level 3 //waterlevel
#define log_points_total 48 //number of log points
unsigned short log_point = 0;
unsigned short log_times[log_points_total];
unsigned int log_temps_swamp[log_points_total];
unsigned int log_temps_air[log_points_total];
unsigned int log_temps_surface[log_points_total];
unsigned int log_water[log_points_total];
//part of clock, here for compilation.
unsigned int c_hour = 0;
unsigned int c_second = 0;
//pump
unsigned int p_pump = LOW; //is pump on or of
unsigned int p_pump_time = 1800; //duration
unsigned int p_pump_frequency = 10; //pump n times
unsigned int p_pump_interval = 3600; //pump n times
unsigned int p_pump_max_time = 1800; //maximum durtion of pump != 0
unsigned int p_pump_max_frequency = 10;//maximum times of acivity of pump != 0
unsigned int p_pump_max_interval = 3600;//maximum time between pumps.
void p_calculate()
{
if (p_pump == LOW && c_hour > 5) // we do not annoy the nabours
{
// calculate the duration
float temp;
temp = min(min(analogRead(analog_temp_air),analogRead(analog_temp_surface)), analogRead(analog_temp_swamp));
if (temp < temp =" temp" temp =" temp" w =" (float(readLevelOfWater())" temp =" w;" p_pump_frequency ="=" p_pump_frequency =" p_pump_max_frequency" p_pump_time =" p_pump_max_time"> 0.200 &&amp; p_pump_frequency > 0 && p_pump_time > 0 && p_pump_interval <= 0 ) { p_pump = HIGH; digitalWrite(pumpPin, HIGH);// pump on digitalWrite(ledPin, HIGH);// led on if (p_pump_interval <= 0) { p_pump_interval = p_pump_max_interval; } } } } void p_reset() { p_pump_time = p_pump_max_time; p_pump_frequency = p_pump_max_frequency; if (p_pump == HIGH) { p_pump = LOW; digitalWrite(pumpPin, LOW);// pump off digitalWrite(ledPin, LOW);// led off } } void p_clock_tick() { if (c_hour > 5) {
if (p_pump == HIGH)
{
p_pump_time--;
if (p_pump_time <= 0) { p_pump = LOW; digitalWrite(pumpPin, LOW);// pump off digitalWrite(ledPin, LOW);// led off p_pump_frequency--; log_times[log_point]++; } } else { if (p_pump_frequency > 0)
{
p_pump_interval--;
}
}
}
}
void log_calc()
{
if (log_temps_swamp[log_point] == 0)
{
log_temps_swamp[log_point] = analogRead(analog_temp_swamp);
log_temps_air[log_point] = analogRead(analog_temp_air);
log_temps_surface[log_point] = analogRead(analog_temp_surface);
}
else {
log_temps_swamp[log_point] = (analogRead(analog_temp_swamp) + log_temps_swamp[log_point]) / 2;
log_temps_air[log_point] = (analogRead(analog_temp_air) + log_temps_air[log_point]) / 2;
log_temps_surface[log_point] = (analogRead(analog_temp_surface) + log_temps_surface[log_point]) / 2;
}
if (log_water[log_point] == 0)
{
log_water[log_point] = readLevelOfWater();
}
}
/* clock
*/
unsigned long c_lastMillis = 0; // will store next time the clock was updated
void c_tick()
{
unsigned long now = millis();
if (now - c_lastMillis >= 1000)
{
c_lastMillis = now;
c_second++;
p_clock_tick(); //notify the pump
if ( c_second > 3600 )
{
c_second = c_second % 3600;
c_hour++;
log_calc();
if (c_hour > 23)
{
c_hour = 0;
p_reset(); // reset pump module
log_point++;
log_point = log_point % (log_points_total + 1);
}
}
}
else
{
if (now - c_lastMillis <> 10000) {
c_second++;
c_lastMillis = now;
}
}
}
int readLevelOfWater()
{
int w = analogRead(analog_water_level) - 1023 ;
if (w < w =" w">_air),analogRead(analog_temp_surface)) <>25C fuzzy or air of water
min(analogRead(analog_temp_air),analogRead(analog_temp_surface)) > 190) ) // <0c c_lastmillis =" millis();" i="0;" log_point =" 0;" bytein =" 0;"> 0 && byteIn >= 0) {
byteIn = Serial.read();
switch (byteIn) {
case 'e' :
{
c_hour = 0;
c_second = 0;
break;
}
case 'h' :
{
c_hour++;
break;
}
case 'm' :
{
c_second = c_second + 60;
break;
}
case 's' :
{
c_second = c_second + 10;
break;
}
case 'f' :
{
p_pump_interval = 30;
break;
}
case 't' :
{
Serial.print(c_hour, DEC);
Serial.print(':');
Serial.print(c_second / 60, DEC);
Serial.print(':');
Serial.println (c_second % 60, DEC);
Serial.print("lst");
Serial.println(c_lastMillis, DEC);
Serial.print("now");
Serial.println(millis(), DEC);
break;
}
case 'i' :
{
Serial.print(analogRead(analog_temp_air), DEC);
Serial.print('-');
Serial.print(analogRead(analog_temp_surface), DEC);
Serial.print ('-');
Serial.print(analogRead(analog_temp_swamp), DEC);
Serial.print('-');
Serial.println(readLevelOfWater(),DEC);
break;
}
case 'p' :
{
if (p_pump) Serial.print("on");
Serial.print("i");
Serial.print(p_pump_interval, DEC);
Serial.print("p");
Serial.print(p_pump_time, DEC);
Serial.print("f");
Serial.println(p_pump_frequency, DEC);
break;
}
case 'x' :
{
Serial.print("what / days;");
for (int i=0; i <= log_points_total; i++) { if (i == log_point) Serial.print("c"); else Serial.print(i, DEC); if (i != log_points_total) Serial.print(";"); } Serial.println (); Serial.print("surface;"); for (int i=0; i <= log_points_total; i++) { Serial.print((log_temps_surface[i]), DEC); if (i != log_points_total) Serial.print (";"); } Serial.println(); Serial.print("swamp;"); for (int i=0; i <= log_points_total; i++) { Serial.print((log_temps_swamp[i]), DEC); if (i != log_points_total) Serial.print(";"); } Serial.println(); Serial.print("air;"); for (int i=0; i <= log_points_total; i++) { Serial.print((log_temps_air[i]), DEC); if (i != log_points_total) Serial.print(";"); } Serial.println(); Serial.print("water;"); for (int i=0; i <= log_points_total; i++) { Serial.print(log_water[i], DEC); if (i != log_points_total) Serial.print(";"); } Serial.println(); break; } default : { Serial.println("e = reset clock, h hour + 1, s sec + 1, m min + 1, i sens., p pump inf, x exp. log"); } } } }
/* Pompie software to control the pump of a pond
* (c) Marco Dumont
* This is completly "do what you like with it" sourcecode
* The pupose is a device that switches the pump to the filter, a natural swamp filter off ->
* when it is to hot >30 or to cold <0>
* The time the pump is on is limited - the plants need time to filter the nutrians, so fuzzy controls should be used.
* Another advantage is that this saves energy.
*/
#define ledPin 13 // LED connected to digital pin 13
#define pumpPin 12 // Pin switching the pump on/off
#define airPin 11 // Pin switching the airpump on/off
#define analog_temp_air 0 //analog temp of the air at 1 meter
#define analog_temp_surface 1 //temp of the watersurface
#define analog_temp_swamp 2 //temp of the water in the swamp
#define analog_water_level 3 //waterlevel
#define log_points_total 48
unsigned short log_point = 0;
unsigned short log_times[log_points_total];
unsigned int log_temps_swamp[log_points
unsigned int log_temps_air[log_points_total
unsigned int log_temps_surface[log_points
unsigned int log_water[log_points_total];
//part of clock, here for compilation.
unsigned int c_hour = 0;
unsigned int c_second = 0;
//pump
unsigned int p_pump = LOW; //is pump on or of
unsigned int p_pump_time = 1800; //duration
unsigned int p_pump_frequency = 10; //pump n times
unsigned int p_pump_interval = 3600; //pump n times
unsigned int p_pump_max_time = 1800; //maximum durtion of pump != 0
unsigned int p_pump_max_frequency = 10;//maximum times of acivity of pump != 0
unsigned int p_pump_max_interval = 3600;//maximum time between pumps.
void p_calculate()
{
if (p_pump == LOW && c_hour > 5) // we do not annoy the nabours
{
// calculate the duration
float temp;
temp = min(min(analogRead(analog_temp
if (temp < temp =" temp" temp =" temp" w =" (float(readLevelOfWater())" temp =" w;" p_pump_frequency ="=" p_pump_frequency =" p_pump_max_frequency" p_pump_time =" p_pump_max_time"> 0.200 &&amp; p_pump_frequency > 0 && p_pump_time > 0 && p_pump_interval <= 0 ) { p_pump = HIGH; digitalWrite(pumpPin, HIGH);// pump on digitalWrite(ledPin, HIGH);// led on if (p_pump_interval <= 0) { p_pump_interval = p_pump_max_interval; } } } } void p_reset() { p_pump_time = p_pump_max_time; p_pump_frequency = p_pump_max_frequency; if (p_pump == HIGH) { p_pump = LOW; digitalWrite(pumpPin, LOW);// pump off digitalWrite(ledPin, LOW);// led off } } void p_clock_tick() { if (c_hour > 5) {
if (p_pump == HIGH)
{
p_pump_time--;
if (p_pump_time <= 0) { p_pump = LOW; digitalWrite(pumpPin, LOW);// pump off digitalWrite(ledPin, LOW);// led off p_pump_frequency--; log_times[log_point]++; } } else { if (p_pump_frequency > 0)
{
p_pump_interval--;
}
}
}
}
void log_calc()
{
if (log_temps_swamp[log_point] == 0)
{
log_temps_swamp[log_point] = analogRead(analog_temp_swamp);
log_temps_air[log_point] = analogRead(analog_temp_air);
log_temps_surface[log_point] = analogRead(analog_temp_surface
}
else {
log_temps_swamp[log_point] = (analogRead(analog_temp_swamp) + log_temps_swamp[log_point]) / 2;
log_temps_air[log_point] = (analogRead(analog_temp_air) + log_temps_air[log_point]) / 2;
log_temps_surface[log_point] = (analogRead(analog_temp
}
if (log_water[log_point] == 0)
{
log_water[log_point] = readLevelOfWater();
}
}
/* clock
*/
unsigned long c_lastMillis = 0; // will store next time the clock was updated
void c_tick()
{
unsigned long now = millis();
if (now - c_lastMillis >= 1000)
{
c_lastMillis = now;
c_second++;
p_clock_tick(); //notify the pump
if ( c_second > 3600 )
{
c_second = c_second % 3600;
c_hour++;
log_calc();
if (c_hour > 23)
{
c_hour = 0;
p_reset(); // reset pump module
log_point++;
log_point = log_point % (log_points_total + 1);
}
}
}
else
{
if (now - c_lastMillis <> 10000) {
c_second++;
c_lastMillis = now;
}
}
}
int readLevelOfWater()
{
int w = analogRead(analog_water_level) - 1023 ;
if (w < w =" w">_air),analogRead(analog_temp
min(analogRead(analog_temp_air
byteIn = Serial.read();
switch (byteIn) {
case 'e' :
{
c_hour = 0;
c_second = 0;
break;
}
case 'h' :
{
c_hour++;
break;
}
case 'm' :
{
c_second = c_second + 60;
break;
}
case 's' :
{
c_second = c_second + 10;
break;
}
case 'f' :
{
p_pump_interval = 30;
break;
}
case 't' :
{
Serial.print(c_hour, DEC);
Serial.print(':');
Serial.print(c_second / 60, DEC);
Serial.print(':');
Serial.println (c_second % 60, DEC);
Serial.print("lst");
Serial.println(c_lastMillis, DEC);
Serial.print("now");
Serial.println(millis(), DEC);
break;
}
case 'i' :
{
Serial.print(analogRead(analog_temp_air), DEC);
Serial.print('-');
Serial.print(analogRead(analog_temp
Serial.print ('-');
Serial.print(analogRead(analog_temp_swamp), DEC);
Serial.print('-');
Serial.println(readLevelOfWater(),DEC);
break;
}
case 'p' :
{
if (p_pump) Serial.print("on");
Serial.print("i");
Serial.print(p_pump_interval, DEC);
Serial.print("p");
Serial.print(p_pump_time, DEC);
Serial.print("f");
Serial.println(p_pump_frequency, DEC);
break;
}
case 'x' :
{
Serial.print("what / days;");
for (int i=0; i <= log_points_total; i++) { if (i == log_point) Serial.print("c"); else Serial.print(i, DEC); if (i != log_points_total) Serial.print(";"); } Serial.println (); Serial.print("surface;"); for (int i=0; i <= log_points_total; i++) { Serial.print((log_temps_surface[i]), DEC); if (i != log_points_total) Serial.print (";"); } Serial.println(); Serial.print("swamp;"); for (int i=0; i <= log_points_total; i++) { Serial.print((log_temps_swamp[i]), DEC); if (i != log_points_total) Serial.print(";"); } Serial.println(); Serial.print("air;"); for (int i=0; i <= log_points_total; i++) { Serial.print((log_temps_air[i]), DEC); if (i != log_points_total) Serial.print(";"); } Serial.println(); Serial.print("water;"); for (int i=0; i <= log_points_total; i++) { Serial.print(log_water[i], DEC); if (i != log_points_total) Serial.print(";"); } Serial.println(); break; } default : { Serial.println("e = reset clock, h hour + 1, s sec + 1, m min + 1, i sens., p pump inf, x exp. log"); } } } }
Thursday, February 1, 2007
Detecting rain
Pompie needs to detect rain: not only is my pond a home for my goldfish. It's also a means to dispose of access rain water. So the filter, in which the rain water is drained, doesn't need extra water from the pond when it is raining. The rain detector will be two L shaped aluminum strips of about 5 cm glued together with an isolator in between. Connected to an IO port of Arduino by a 10k resistor as the circuit describes.
- No rain will have a 1.
- With rain the readout will be 0.
Sunday, January 14, 2007
Water level
To sense the water level I needed something solid state, durable and easy to make. The above circuit is the design I'm going to use. It consist out of 10 resistors of 1k in a serial configuration and one of 10k to limit current. It will be connected to 5v in order not to harm any fish. How it works? The resistors of 1k will be mounted on a plastic tube and a aluminum strip will be glued to the other side. When the water level is very high all the resistors will be shorted and no current will go the the Arduino. When the water level is very low all the 1k resistors will be active, in total 10k, so current will go to the Arduino. When the water level is somewhere in between some of the resistors will be shorted and some will not be shorted, resulting in a different current.
Friday, January 12, 2007
Switching 220VAC
I'm going to use a S202T01 to switch the 220V. They are easy to get, you can load them with 2A and where made for this job. The 220 Ohm resistor is tested and works OK with a Arduino. For Pompie the circuit has to be double for the air- and waterpump.
The S202T01 consists out of two triacs and a led to switch them on and off. The AC and DC parts are completely separated and to be safe a used screw-connectors to wire them to 220V.
Next: water level sensor
Wednesday, January 10, 2007
Temperature
In order for Pompie to work correct Pompie need to sense the temperature. The circuit on the left uses a 15k resistor to limit current, a 15k NTC for the temp. The reason for 15k is the graph of measurements shows an almost strait line, another reason is that the scale is perfect for the dot on the globe I live. Say you need a NTC to measure the temperature and your location it will never be lower than let's say 10C its advisable you use different values, start with 5k and make a similar graph. The third reason is that the program can detect a faulty wire. To make a graph:
- Melting water = 0C
- My freezer freezes at -18C
- My central heating is set to 20C
- My (and your) hands are about 32C
Code to test the NTC is the same as the tutorial for the potmeter.
http://www.arduino.cc/en/Tutorial/Potentiometer
Next will be switching 220VAC
Monday, January 8, 2007
Pupose
My pond has two parts:
- A normal pond for plants and a few goldfish.
- A natural filter, gravel, sand and plants to filter out any nutrients and poo produced by the goldfish.
This is an excellent job for the Arduino board, pump and air will switch 220VAC and three AD ports will be used to sense the temperature.
- At the surface of the pond.
- One meter in the air.
- In the filter.
The whole program needs to be fuzzy and datacollecting just for fun and usage of the USB / Serial port.
This is the Arduino Pompie blog
Pompie is a device to control the pump of my pond. It's based on the Arduino board. To help others I publish my findings, problems and code on this blog.
Have fun with it...
Have fun with it...
Subscribe to:
Posts (Atom)