Projetei um sensor de umidade para plantas que rastreia a quantidade de água que a planta possui e pisca um LED se a planta precisar de água. Você pode fazer o sensor aprender o tipo de planta e, assim, alterar suas configurações durante a execução. Ele detecta baixa voltagem na bateria. Eu fiquei sem flash e ram, mas consegui escrever tudo em código C para fazer com que este produto funcionasse perfeitamente.
Eu usei o pic10f que você mencionou.
Aqui está o código que eu criei para o meu sensor de água da planta. Eu usei o pic10f220, pois possui um módulo ADC, ele tem a mesma memória que o pic10f200, tentarei encontrar o esquemático amanhã.
O código está em espanhol, mas é muito simples e deve ser facilmente entendido. Quando o Pic10F sair do modo de suspensão, ele será redefinido para que você precise verificar se foi um PowerUp ou uma redefinição e agir em conformidade. A configuração da planta é mantida no aríete, pois nunca realmente desliga.
MAIN.C
/*
Author: woziX (AML)
Feel free to use the code as you wish.
*/
#include "main.h"
void main(void)
{
unsigned char Humedad_Ref;
unsigned char Ciclos;
unsigned char Bateria_Baja;
unsigned char Humedad_Ref_Bkp;
OSCCAL &= 0xfe; //Solo borramos el primer bit
WDT_POST64(); //1s
ADCON0 = 0b01000000;
LEDOFF();
TRIS_LEDOFF();
for(;;)
{
//Se checa si es la primera vez que arranca
if(FIRST_RUN())
{
Ciclos = 0;
Humedad_Ref = 0;
Bateria_Baja = 0;
}
//Checamos el nivel de la bateria cuando arranca por primera vez y cada 255 ciclos.
if(Ciclos == 0)
{
if(Bateria_Baja)
{
Bateria_Baja--;
Blink(2);
WDT_POST128();
SLEEP();
}
if(BateriaBaja())
{
Bateria_Baja = 100; //Vamos a parpadear doble por 100 ciclos de 2 segundos
SLEEP();
}
Ciclos = 255;
}
//Checamos si el boton esta picado
if(Boton_Picado)
{
WDT_POST128();
CLRWDT();
TRIS_LEDON();
LEDON();
__delay_ms(1000);
TRIS_ADOFF();
Humedad_Ref = Humedad();
Humedad_Ref_Bkp = Humedad_Ref;
}
//Checamos si esta calibrado. Esta calibrado si Humedad_Ref es mayor a cero
if( (!Humedad_Ref) || (Humedad_Ref != Humedad_Ref_Bkp) )
{
//No esta calibrado, hacer blink y dormir
Blink(3);
SLEEP();
}
//Checamos que Humedad_Ref sea mayor o igual a 4 antes de restarle
if(Humedad_Ref <= (255 - Offset_Muy_Seca))
{
if(Humedad() > (Humedad_Ref + Offset_Muy_Seca)) //planta casi seca
{
Blink(1);
WDT_POST32();
SLEEP();
}
}
if(Humedad() >= (Humedad_Ref)) //planta seca
{
Blink(1);
WDT_POST64();
SLEEP();
}
if(Humedad_Ref >= Offset_Casi_Seca )
{
//Si Humedad_Ref es menor a Humedad, entonces la tierra esta seca.
if(Humedad() > (Humedad_Ref - Offset_Casi_Seca)) //Planta muy seca
{
Blink(1);
WDT_POST128();
SLEEP();
}
}
SLEEP();
}
}
unsigned char Humedad (void)
{
LEDOFF();
TRIS_ADON();
ADON();
ADCON0_CH0_ADON();
__delay_us(12);
GO_nDONE = 1;
while(GO_nDONE);
TRIS_ADOFF();
ADCON0_CH0_ADOFF();
return ADRES;
}
//Regresa 1 si la bateria esta baja (fijado por el define LOWBAT)
//Regresa 0 si la bateria no esta baja
unsigned char BateriaBaja (void)
{
LEDON();
TRIS_ADLEDON();
ADON();
ADCON0_ABSREF_ADON();
__delay_us(150); //Delay largo para que se baje el voltaje de la bateria
GO_nDONE = 1;
while(GO_nDONE);
TRIS_ADOFF();
LEDOFF();
ADCON0_ABSREF_ADOFF();
return (ADRES > LOWBAT ? 1 : 0);
}
void Blink(unsigned char veces)
{
while(veces)
{
veces--;
WDT_POST64();
TRIS_LEDON();
CLRWDT();
LEDON();
__delay_ms(18);
LEDOFF();
TRIS_ADOFF();
if(veces)__delay_ms(320);
}
}
MAIN.H
/*
Author: woziX (AML)
Feel free to use the code as you wish.
*/
#ifndef MAIN_H
#define MAIN_H
#include <htc.h>
#include <pic.h>
__CONFIG (MCPU_OFF & WDTE_ON & CP_OFF & MCLRE_OFF & IOSCFS_4MHZ );
#define _XTAL_FREQ 4000000
#define TRIS_ADON() TRIS = 0b1101
#define TRIS_ADOFF() TRIS = 0b1111
#define TRIS_LEDON() TRIS = 0b1011
#define TRIS_LEDOFF() TRIS = 0b1111
#define TRIS_ADLEDON() TRIS = 0b1001
#define ADCON0_CH0_ADON() ADCON0 = 0b01000001; // Canal 0 sin ADON
#define ADCON0_CH0_ADOFF() ADCON0 = 0b01000000; // Canal 0 con adON
#define ADCON0_ABSREF_ADOFF() ADCON0 = 0b01001100; //Referencia interna absoluta sin ADON
#define ADCON0_ABSREF_ADON() ADCON0 = 0b01001101; //referencia interna absoluta con ADON
//Llamar a WDT_POST() tambien cambia las otras configuracion de OPTION
#define WDT_POST1() OPTION = 0b11001000
#define WDT_POST2() OPTION = 0b11001001
#define WDT_POST4() OPTION = 0b11001010
#define WDT_POST8() OPTION = 0b11001011
#define WDT_POST16() OPTION = 0b11001100
#define WDT_POST32() OPTION = 0b11001101
#define WDT_POST64() OPTION = 0b11001110
#define WDT_POST128() OPTION = 0b11001111
#define Boton_Picado !GP3
#define FIRST_RUN() (STATUS & 0x10) //Solo tomamos el bit TO
//Offsets
#define Offset_Casi_Seca 5
#define Offset_Muy_Seca 5
//Low Bat Threshold
#define LOWBAT 73
/*
Los siguientes valores son aproximados
LOWBAT VDD
50 3.07
51 3.01
52 2.95
53 2.90
54 2.84
55 2.79
56 2.74
57 2.69
58 2.65
59 2.60
60 2.56
61 2.52
62 2.48
63 2.44
64 2.40
65 2.36
66 2.33
67 2.29
68 2.26
69 2.23
70 2.19
71 2.16
72 2.13
73 2.10
74 2.08
75 2.05
76 2.02
77 1.99
78 1.97
*/
#define LEDON() GP2 = 0; //GPIO = GPIO & 0b1011
#define LEDOFF() GP2 = 1; //GPIO = GPIO | 0b0100
#define ADON() GP1 = 0; //GPIO = GPIO & 0b1101
#define ADOFF() GP1 = 1; //GPIO = GPIO | 0b0010
unsigned char Humedad (void);
unsigned char BateriaBaja (void);
void Delay_Parpadeo(void);
void Blink(unsigned char veces);
#endif
Deixe-me saber se você tiver dúvidas, tentarei responder com base no que me lembro. Eu codifiquei isso há vários anos, então não verifique minhas habilidades de codificação, elas melhoraram :).
Nota final. Eu usei o compilador Hi-Tech C.