Система полива растений на основе микроконтроллера
Я пытаюсь построить автоматическую систему полива растений, используя ATmega16. Мы используем датчик влажности для нашего проекта. Ниже приведено изображение датчика влажности, который мы использовали.
Принципиальная схема выглядит следующим образом:
Ниже приведен фрагмент кода, который мы использовали:
#include<avr/io.h>
int adc(void);
void pump(void);
int adc_value;
int main(void)
{
DDRC=0x01; //Defining PC0 as output
ADCSRA=0x87; //Setting the mode of operation
ADMUX=0x00; //Selection of channel and bit alignment
while(1)
{
adc_value=adc(); //reading moisture level
pump(); //Pump activator routine
}
return 0;
}
int adc(void)
{
int lower_bits,higher_bits,result;
ADCSRA|=(1<<6); //Turning on conversion
while(ADIF==0);
lower_bits=ADCL;
higher_bits=ADCH;
result=lower_bits|higher_bits<<8; //Accessing converted value by shifting
return result;
}
void pump(void)
{
if(adc_value>=700) //Pump ON trigger point
{
PORTC|=(1<<0);
}
else if(adc_value<=600) //Pump Off trigger point
{
PORTC&=~(1<<0);
}
}
Что-то не так в коде? потому что после его сжигания я получаю низкое напряжение для влажной почвы и высокое напряжение для сухой почвы от аналогового входа датчика, что в порядке... но проблема в том, что я всегда получаю высокое напряжение на PC0 в любых случаях.. там без изменений в значениях для сухого и влажного грунта.. в таком случае, где настоящая проблема.. есть ли что-то не так в схеме или в коде? И еще одна вещь, может ли кто-нибудь сказать мне правильный способ измерения выходного значения, которое я получаю от PC0, который в свою очередь включает / выключает насос?
1 ответ
Вы не очищаете ADIF
флаг до начала конвертации. Это будет всегда читать 1 после первого раза до конца. Добавьте строку, чтобы очистить флаг (записав 1 в бит флага. Да, записав 1, вы получите 0. Это не обычный регистр).
Кроме того, вы не правильно читаете флаг. ADIF
немного в байте, поэтому вам нужно прочитать байт с битовой маской. (Вы были на самом деле тестирование 2==0
, как ADIF
определяется как 2.)
int adc(void)
{
int lower_bits,higher_bits,result;
ADCSRA |= (1 << ADIF); // <<<<<< Add this to clear flag
ADCSRA |= (1 << ADSC); //ADCSRA|=(1<<6); //Turning on conversion
while(ADCSRA & (1 << ADIF) == 0); //while(ADIF==0); <<<<<< Change this
lower_bits=ADCL;
higher_bits=ADCH;
result=lower_bits|(higher_bits<<8); //Accessing converted value by shifting
return result;
}
На самом деле, вы уже случайно сбросили флажок. Если это был 1, то ADCSRA
имеет 1 в ADIF
положение, и это снова пишется. Но все же лучше быть более точным в том, что вы хотите сделать. Кроме того, вы можете объединить два действия в одном назначении.
int adc(void)
{
int lower_bits,higher_bits,result;
ADCSRA |= (1 << ADSC)|(1 << ADIF); //Turn on conversion and clear flag
while(ADCSRA & (1 << ADIF) == 0); //wait for flag
lower_bits=ADCL;
higher_bits=ADCH;
result=lower_bits|(higher_bits<<8); //Accessing converted value by shifting
return result;
}
Я не могу подтвердить, что остальная часть вашего кода правильная, потому что я не смотрел, и это первая очевидная проблема. Исправьте это и обновите ваш вопрос, если у вас все еще есть проблемы.