【问题标题】:micro-controller based plant watering system基于微控制器的植物浇水系统
【发布时间】:2015-12-07 19:21:36
【问题描述】:

我正在尝试使用 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);
   }
 }

代码有什么问题吗?因为在燃烧它之后,我从模拟传感器输入得到湿土壤的低电压和干土壤的高电压,这没问题……但问题是,在 borh 情况下,我总是在 PC0 处得到高电压……没有变化在干湿土壤的值中..在这种情况下,实际问题在哪里..电路设计或代码有什么问题吗?还有一件事,谁能告诉我测量我从 PC0 获得的输出值的正确方法,这反过来又是打开/关闭泵?

【问题讨论】:

    标签: microcontroller avr atmega atmelstudio


    【解决方案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,那么 ADCSRAADIF 位置有一个 1,它会被再次写入。但最好还是更明确地说明你的意思。同样,您可以将这两个操作组合成一个作业。

    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;
     }
    

    我无法确认您的其余代码和接线是否正确,因为我没有查看,这是第一个明显的问题。修复它,如果仍有问题,请更新您的问题。

    【讨论】:

    • 你能告诉我测量我从 PC0 获得的输出值的正确方法吗?这反过来又打开/关闭泵? @UncleO
    • @user3114849 我不明白你的问题。您可以在 PC0 和地之间直接连接示波器或电压表。您还可以连接到二极管、线圈和晶体管之间的结。然后它将读取与 PC0 相反的内容。当 PC0 为 0 V 时,接点为 12 V。当 PC0 为 5 V 时,接点为 0 V。(但这些不是编程问题。期待学究们尽快解决您的问题!)
    猜你喜欢
    • 2023-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多