Let op: niet meer kopen (vervanger). De Chirp (home) grondvochtigheidssensor voor planten is verouderd. Deze moeder van de serie vochtigheidssensoren die nu de markt verovert is voor de Arduino achterhaald door klonen zoals bijvoorbeeld de capaciteit sensor. Ze zijn gebaseerd op capaciteitsmetingen. Grote voordelen zijn dat ze niet kunnen oxideren en dat de capaciteit sterk afhangt van het vochtgehalte in de grond.
De Chirp kan op zichzelf worden gebruikt als er een 3Vdc CR2032 lithium knoopbatterij wordt ingestopt. Hij zal dan overdag een akoestische tjirp geven zodra de grond te droog wordt. Als sensor in een tuin of kas irrigatie is hij voor ons ongeschikt omdat hij slechts kan communiceren met I²C en daardoor moet een Arduino binnen 30cm van de Chirp worden geplaatst. Bovendien is het I²C verbinden van de Chirp als sensor met de Arduino ronduit onhandig. Als controle sensor in ons floralabo kan hij wel worden gebruikt. Behalve Chirp verkoopt ook Adafruit deze vochtigheidssensor.
Gebruik als sensor |
After reset Chirp reads capacitance and light levels. That can take from 1 up to 9 seconds if dark. If any I2C communication is received during that time, Chirp will switch into sensor mode - it will not chirp, just respond to I2C requests. The default address of the Chirp is 0x20
|
Zelfstandig gebruik |
Zodra er een knoopbatterij (3Vdc CR2032) wordt ingestoken of een voedingsspanning (3-5Vdc) wordt aangesloten op de Chirp (manual) zal de Chirp een korte tjilp afgeven. In theorie dan want bij mij doen ze niets indien er een batterij wordt ingestopt.
When you insert the battery, Chirp will emit one short chirp, briefly flash the LED and another short chirp after measurement is complete. This means that the device is working properly. It will instantly measure the moisture level on the sensor pad and save it as the “dry point” - the alarm level of moisture. Druk op het knopje in de droogste stand. |
Aansluiten op Arduino |
De Chirp (home) bevat een standaard AVR 6 pin ISP programming header, also for serial communication? Chirp kan ook worden gebruikt als sensor aan een Arduino. In dat geval moeten er 4 pinnen worden aangesloten aan de Arduino. 2 pinnen voor de voeding en 2 pinnen aan de I²C pinnen van je Arduino.
Pin 1: MISO
Enkel voor programmeren.
Pin 2: Vcc 3-5
Voedingsspanning.
Pin 3: SCK / SCL
Dubbelfunctie.
Pin 4: MOSI /SDA
Not preferred but it would help
Pin 5: Reset
Not preferred but it would help
Pin 6: Gnd
De aarde aansluiting.
I²C aansluiting
Vergeet niet om 2 optrekweerstanden in je I²C aansluiting op te nemen. Optrekweerstanden I²C 10kΩ 4k7Ω 2k2Ω / 100kΩ lijkt te veel. Test2 = 4k7Ω. Het LEDje blijft nu iedere seconde knipperen, maar ik krijg nog steeds geen serieuze waardes uitgelezen. Volgens deze site moeten de optrekweerstanden 10kΩ zijn. Maar nu loopt de boel vast bij iedere meting en komt geeneens langs de bootcyclus. Terug gewisseld naar 4k7Ω. Ook 2k2Ω is nog een veelgebruikte mogelijkheid.
|
Eerste ervaringen |
When dry this sensor reads around 350 and when watered 500. These measurements can be reproduced but the correct positioning of the sensor is important. Also any change in position will give a significant change in measured values.
|
The blue line (CJCMU) represents a capacitive moisture sensor. The red and yellow line are both from a resistiv sensor. The yellow represents the measurements of the one input pin and the red line of the other input pin.
All three sensors show enough responsivness to be used as a watering system. |
Werking |
Chirp gebruikt capacitieve eigenschappen om de vochtigheid te meten (explanation). Een 1MHz blokgolf wordt gegenereerd met PWM op een ATtiny44A µcontroller. Dit kan met het in de ATtiny44A ingebouwde kristal en systeemklok. Deze blokgolf wordt dan via een weerstand naar een grote `pad` gestuurd.
Deze `pad` vormt tezamen met de omringende grond een parasitaire condensator. De weerstand en de condensator vormen tezamen een laag doorlaat filter waarvan de afsnijd frequentie wordt bepaald door de veranderende capaciteit van de condensator. De grond rond de sonde gedraagt zich als de elektrolyt van een condensator waarvan de de dielektrische constante varieert met de hoeveelheid vocht in de grond. Daardoor verandert ook de capaciteit van onze condensator.
The filtered square wave is fed into a peak detector formed of out a diode and a capacitor - the diode lets through positive peaks and the capacitor stores the maximum voltage of those peaks. This voltage is measured by an ADC in the microcontroller. De hart van het programma is als volgt:
uint16_t getCapacitance() {
PRR &= ~_BV(PRADC); //enable ADC in power reduction
ADCSRA |= _BV(ADEN);
PRR &= ~_BV(PRTIM0);
startExcitationSignal();
getADC1();
uint16_t result = getADC1();
stopExcitationSignal();
PORTB &= ~_BV(PB2);
PRR |= _BV(PRTIM0);
ADCSRA &=~ _BV(ADEN);
PRR |= _BV(PRADC);
return result;
} |
Nog uit zoeken:
Kan je meerdere CJMCUs aansluiten op 1 controller, oftewel kan je het busadres instellen?
Hoe kan je de lichtsterkte afvragen?
Hoe kan je de verbinding stabiel krijgen?
Kan ik de reset combineren?
//This is an include, so no parsing needed
$qry2 = ("SELECT onderdelen.*,
soortonderdeel.id
FROM onderdelen
JOIN soortonderdeel ON onderdelen.idsrtodd = soortonderdeel.id
WHERE onderdelen.partid = $idpart
;");
$result2 = pg_query($con1, $qry2);
$row4 = pg_fetch_array($result2); //Make the fields accesible
foreach( $row4 AS $key => $val ){
$$key = stripslashes( $val );
}
$jaar = substr($changeddate,0,4);
$maand = substr($changeddate,5,2);
$dag = substr($changeddate,8,2);
$lastupdate = ("$jaar $maand $dag");
$prtsrttxt = get_txt($con1, 26, 1, $idsrtodd);
$jaar = substr($createddate,0,4);
$maand = substr($createddate,5,2);
$dag = substr($createddate,8,2);
$create_stamp = ("$dag $maand $jaar");
//GENERAL INFO FOR EVERY USER **************************************************
echo (" ");
echo (""); //Header
$tmp = get_txt($con1, 9, $koekje[2], 3923); //Fieldname at screen
if ($koekje[3]=="1") { //If this user wants to translate then
echo ("$tmp"); //If desired
}else{ echo ("$tmp"); } //Else just show if no need to translate
if ($koekje[0]>0 and $koekje[3]>0){ //User is logged in and translates
echo (" (edit)");
}
echo ("Algemene informatie test | ");
if ($codetext) { //Code like KY-026 or NA-41
echo ("");
$tmp = get_txt($con1, 9, $koekje[2], 3739); //Fieldname at screen
if ($koekje[3]=="1") { //If this user wants to translate then
echo ("$tmp"); //Class for colour
}else{ //So you are not allowed to translate
echo $tmp; //Show screenname of this field in user language
} //End of If you want to translate this fieldname at screen
echo ("  | ");
if ($codelink) {
echo ("$codetext");
}else{
echo ("$codetext");
} //End of if ($pinoutlink)
echo (" | ");
} //End of if ($codetext)
$tmp = get_txt($con1, 9, $koekje[2], 3741); //Fieldname at screen
if ($prijseurinclbtw > 0){ //Show price indication
$prijs_formatted = number_format($prijseurinclbtw / 100, 2, ',', '.');
echo ("$tmp   | ");
echo ("");
if ($urlprijs){
echo ("€  $prijs_formatted");
}else{
echo ("€  $prijs_formatted");
} //End of if ($urlprijs > "")
echo (" | ");
} //End of if ($prijseurinclbtw > 0)
if ($sketchtext) { //Link to OWN SOFTWARE
$tmp = get_txt($con1, 9, $koekje[2], 3738); //Fieldname at screen
echo ("$tmp   | ");
if ($sketchlink) {
echo ("$sketchtext");
}else{
echo ("$sketchtext");
} //End of if ($sketchlink)
echo (" | ");
} //End of if ($sketchtext)
$tmp = get_txt($con1, 9, $koekje[2], 3744); //Fieldname at screen
if ($pinouttext) { //Pinout
echo ("$tmp   | ");
if ($pinoutlink) {
echo ("$pinouttext");
}else{
echo ("$pinouttext");
} //End of if ($pinoutlink)
echo (" | ");
}
$tmp = get_txt($con1, 9, 1, 3735); //Fieldname at screen
$tmp2 = get_txt($con1, 26, 1, $row4[16]); //Group name in its language
echo ("$tmp   | "); //MENU GROUP
echo ("");
echo ("$tmp2 | ");
if ($koekje[0]>0 and $koekje[3]>0){ //User is logged in and translates
$tmp = get_txt($con1, 9, $koekje[2], 3918); //Fieldname at screen LANGUAGE
if ($row4[26] == 1) {$imgname = "nederland.png";}
if ($row4[26] == 2) {$imgname = "deutschland.png";}
if ($row4[26] == 3) {$imgname = "uk.png";}
if ($row4[26] == 4) {$imgname = "france.png";}
echo ("$tmp | ");
echo ("");
echo (" | ");
$tmp = get_txt($con1, 9, $row4[27], 3919); //Fieldname at screen
$statuskey = get_status_key($con1, $status);
$tmp2 = get_txt($con1, 61, $koekje[2], $statuskey); //Fieldname at screen
echo ("$tmp   | "); //STATUS
echo ("$status $tmp2 | ");
}
$tmp = get_txt($con1, 9, 1, 3966); //Fieldname at screen
echo ("$tmp   | "); //LAST CHANGED
$tmp = substr($changeddate, 0, 10);
echo ("$tmp | ");
echo (" ");
return;
////////////////////////////////////////////////////////////////////////////////
function get_status_key($con, $num){
$qry = ("SELECT id FROM status WHERE nr = $num ;");
$result = pg_query($con, $qry);
$row = pg_fetch_array($result);
return ("$row[0]");
}
// LIST ALL SOFTWARE THAT WILL RUN OM THIS PART *****************************
// INCLUDED IN ALL ROBOTS TO CHECK THEIR DIRECTORY
$qry2=("SELECT tblsystext.txtname
, software.urlmain
, software.sftname
, software.sftid
, software.controller
FROM software
LEFT JOIN tblsystext ON software.controller = tblsystext.recordid
WHERE position(' $idpart ' in software.prtlst) > 0
AND software.rstid = 2
AND tblsystext.lanid = $koekje[2]
AND tblsystext.txlid = 19
ORDER BY sftname ASC
, controller ASC
;");
$result = pg_query($con1, $qry2);
if (pg_num_rows($result)>0) { //Only if at least 1 program exists
echo (' ');
echo (""); //Header
$tmp = get_txt($con1, 9, $koekje[2], 3922); //Fieldname at screen
if ($koekje[3]=="1") { //If this user wants to translate then
echo ("$tmp"); //If desired
}else{ echo ("$tmp"); } //Else just show if no need to translate
echo (" |
---|
");
while($col = pg_fetch_array($result)){
$col[0] = ("$col[0]");
echo (" ");
echo ("$col[2]   | ");
echo ("$col[0] | ");
if ($koekje[0] > 0 and $koekje[3]>0){ //User is logged in and translates
echo ("");
echo ("(Edit) | ");
}
echo (' ');
}
echo (' ');
}
?>
// LIST ALL ROBOTS THAT INCLUDE THIS PART ***********************************
// $idpart
// INCLUDED IN ALL ROBOTS TO CHECK THEIR DIRECTORY
$qry_bpp=("SELECT farmbotversie.id
, farmbotversie.part_list
, tblsystext.txtname
FROM farmbotversie
LEFT JOIN tblsystext ON farmbotversie.id = tblsystext.recordid
WHERE tblsystext.txlid = 27
AND tblsystext.lanid = $koekje[2]
ORDER BY tblsystext.txtname ASC
;");
$result_bpp = pg_query($con1, $qry_bpp);
$header = 0;
while($colbpp = pg_fetch_array($result_bpp)){ //Only if at least 1 robot exists
if(substr_count($colbpp[1], " $idpart ") > 0){
if ($header == 0) {
echo ("");
echo (""); //Header
$tmp = get_txt($con1, 9, $koekje[2], 3879); //Fieldname at screen
if ($koekje[3]=="1") { //If this user wants to translate then
echo ("$tmp"); //If desired
}else{ echo ("$tmp"); } //Else just show if no need to translate
echo (" | ");
$header++;
} //End of if ($header == 0)
echo ("");
echo ("$colbpp[2]");
//Show software van deze bot
$qry=("SELECT software_basedir
FROM farmbotversie
WHERE id = $colbpp[0];");
$result = pg_query($con1, $qry);
$col = pg_fetch_array ($result ,0);
$dir1 = "/var/www/html/robotigs/software/$col[0]";
$arr1 = glob($dir1, GLOB_ONLYDIR);
if (isset($arr1[0])){
$folder = $arr1[0];
$countertmp = 0;
echo ("");
foreach (scandir($folder, 1) as $filename) {
if ($filename<>"." AND $filename <>".."){
if ($countertmp == 0){
$countertmp++;
} //End of if ($countertmp == 0)
$tmp = "/";
$dir = substr($folder, 14) ."/";
$link = $tmp .$dir .$filename;
$showname = substr($filename, 0 ,-4);
echo ("- ");
echo "$showname";
echo ("
");
} //End of if ($filename<>"." AND $filename <>".."){
} //End of foreach (scandir($folder, 1) as $filename)
echo ("");
} //End of if (isset($arr1[0]))
echo (" | ");
}
}
if ($header > 0){
echo (" ");
}
?>
Warning: include(/var/www/html/robotigs/includes/wishlistperpart.php): Failed to open stream: No such file or directory in /var/www/html/robotigs/includes/parts_header.php on line 128
Warning: include(): Failed opening '/var/www/html/robotigs/includes/wishlistperpart.php' for inclusion (include_path='.:/usr/share/php') in /var/www/html/robotigs/includes/parts_header.php on line 128
| //Location:/robotigs/includes/ picts_show.php
// Requieres: $pict_list and several picture handling javascript routines
//*** FROM HERE ON THE PICTURE CORNER STARTS -----------------------------------
if ($pict_list){ //There are 1 or more pictures to be printed
echo ("");
$counter = 0;
$aantal = str_word_count($pict_list, 0, "0123456789");
$lijst = str_word_count($pict_list, 1, "0123456789");
while($counter < $aantal){
$pictkey = $lijst[$counter];
$qryy1 = ("SELECT *
FROM illustrations
WHERE ill_id = $pictkey
;");
$resulty1 = pg_query($con1, $qryy1);
while($row = pg_fetch_array($resulty1)){ //Fields accesible by their name
foreach( $row AS $key => $val ){
$$key = stripslashes( $val );
}
}
$image = ("/robotigs/documentatie/plaatjes/$ill_name");
$pictfull = str_replace('_small', '', $image); //Pictfull=biggest version
$alt = ("Just wait till your 57....");
$txtname = get_txt($con1, 18, $koekje[2], $ill_id); //Robot illustrations subtitles
echo ("");
echo (' ');
$nummer = $counter + 1;
$txtAfb = get_txt($con1, 9, $koekje[2], 3865); //Pic Afb
if ($koekje[0]>0 and $koekje[3]>0){ //User is logged in and translates
echo ("$txtAfb $nummer: ");
echo ("$txtname");
echo (" ");
echo ("Ontkoppelen ");
if ($counter==0){
echo ("Up ");
}else{
echo ("Up ");
}
if ($nummer == $aantal){
echo ("Down");
}else{
echo ("Down");
}
}else{ //Else of if Meaning the current useer is logged in
echo ("$txtAfb $nummer: $txtname");
}
echo (''); //End of this picture
$counter++; //Prepair for next picture
}
echo (' | '); //All pictures are printed
} //End of if there are 1 or more pictures to be printed ----------------------
?>