Система полива растений на основе микроконтроллера

Я пытаюсь построить автоматическую систему полива растений, используя 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;
 }

Я не могу подтвердить, что остальная часть вашего кода правильная, потому что я не смотрел, и это первая очевидная проблема. Исправьте это и обновите ваш вопрос, если у вас все еще есть проблемы.

Другие вопросы по тегам