2013-05-08 4 views
0

PWM 출력을 제어하는 ​​온도 기반 팬을 생성하는 작업이 할당되었습니다. 나는 Arduino Uno을 AVRISPmkII 프로그래머와 ATmega328 컨트롤러와 함께 사용하고 있습니다. 이제 과제는 I²C 와이어에 4 MLX90614 센서를 연결하는 것입니다 (각 센서에 다른 슬레이브 주소를 할당했는데 동일한 주소를 가진 I²C에 연결할 수 없기 때문입니다).Arduino Uno 코드에 다중 MLX90614 (온도 센서)

각 센서의 온도를 읽고 최대 온도를 얻을 수 있습니다. 그러나 PWM을 통해 4 개의 팬을 제어 할 때 문제가 발생합니다. 나는 각 센서에서 온도를 읽고, 최대 온도를 얻은 다음 PWM 출력보다 설정된 온도 범위에 따라 팬 속도를 제어해야한다. 코드의 문제는 무엇입니까?

#include <i2cmaster.h> 

int PWMoutput=0; 
int Temp[4]; 
int sensor[4]={0xAC<<1, 0xCC<<1, 0xC0<<1, 0xB0<<1}; // Array with address of four mlx90614 sensors 
int Maxtemp; 

int fan = 9;  // FAN connected to digital pin 9 

//------------------------------------------------// 
//------------------SETUP-------------------------// 
//------------------------------------------------// 

void setup() 
{ 
    Serial.begin(9600);      // Start serial communication at 9600 bit/s. 
    i2c_init();        // Initialise the I²C bus. 
    PORTC = (1 << PORTC4) | (1 << PORTC5); // Enable pullups. 

    // Initialize the digital pin as an output. 
    pinMode(fan, OUTPUT); 
} 

//------------------------------------------------// 
//-------------------MAIN-------------------------// 
//------------------------------------------------// 

void loop() 
{ 
    Maxtemp=readtemp(0); 
    setfanmode(Maxtemp); 
         // Prints all readings in the serial port 
    i=0; 

    /*while(i<1) 
    { 
     Serial.print("Sensor"); 
     Serial.println(i,DEC); 
     Serial.print("Celcius: "); 
     Serial.println(Temp[i],DEC); 
     i++; 

    }*/ 

    Serial.print("Maximum: Celcius: "); 
    Serial.println(Maxtemp); 
} 

void setfanmode(int degree) // Setting the fan speed modes according to 
          // the temperature in Celcius 
          // with PWM Duty cycle to 0%, 50% and 100%. 
{ 
    if (degree<=30) 
     PWMoutput=0; 
    else if(degree<=60) 
     PWMoutput=127; 
    else if(degree<=80) 
     PWMoutput=255; 
} 

int maxtemp()    // Reading max temperature 
{ 
    int i=1; 
    int temperature; 
    while (i<4) 
    { 
     if (Temp[i-1]<Temp[i]) 
      temperature=Temp[i]; 
     i++; 
    } 
    return(temperature); 
} 

float readtemp(int sensornumb) 
{ 
    int data_low = 0; 
    int data_high = 0; 
    int pec = 0; 

    // Write 
    i2c_start_wait(sensor[sensornumb]+I2C_WRITE); 
    i2c_write(0x07); 

    // Read 
    i2c_rep_start(sensor[sensornumb]+I2C_READ); 
    data_low = i2c_readAck();  // Read 1 byte and then send ack. 
    data_high = i2c_readAck();  // Read 1 byte and then send ack. 
    pec = i2c_readNak(); 
    i2c_stop(); 

    // This converts high and low bytes together and processes temperature, 
    // MSB is a error bit and is ignored for temperatures. 
    double tempFactor = 0.02;  // 0.02 degrees per LSB (measurement 
            // resolution of the MLX90614). 
    double tempData = 0x0000;  // Zero out the data. 
    int frac;      // Data past the decimal point. 

    // This masks off the error bit of the high byte, then moves it left 
    // 8 bits and adds the low byte. 
    tempData = (double)(((data_high & 0x007F) << 8) + data_low); 
    tempData = (tempData * tempFactor)-0.01; 
    float celcius = tempData - 273.15; 

    // Returns temperature in Celcius. 
    return celcius; 
} 
+0

일반적으로 ** 절대 전역 변수를 사용하지 마십시오. arduino 코드를 수행 할 때 loop() 및 setup()에서 변수를 사용해야 할 때 예외가 있습니다. 그렇지 않으면, 당신은 당신의 프로그램이 어떻게 흐를 지, 그리고 변수가 어떻게 함수에 의해 취해지고, 변형되고 사용되는지, 또 다른 함수에서 사용되어 그 알고리즘의 목표에 도달 할 수 있도록 되돌아 갈지를 생각해야한다. 즉 PWMOutput, Temp 및 Maxtemp는 변수가 아니어야합니다. 'int fan '은 메모리 비용을 줄이기 위해'#define FAN 9'가되어야하고 'sensor'는 같은 이유로 const int sensor [4] = ...가 될 것입니다. – zmo

+0

전역 변수는 마이크로 컨트롤러 프로젝트에서 매우 일반적입니다. 나는 zmo의 조언이 적용되지 않는다고 생각합니다. – Noah

답변

0

모든 코드를 읽지는 않았지만 팬에게 전혀 명령하지 않는 것처럼 보입니다.

/* setting the fan speed modes according to 
* the temperature in celcius 
* with PWM Duty cycle to 0%, 50% & 100% 
*/ 
void setfanmode(int degree) 
{ 
    int PWMoutput; 

    if (degree<=30) 
    PWMoutput=0; 
    else if(degree<=60) 
    PWMoutput=127;  
    else if(degree<=80) 
    PWMoutput=255; 
    analogWrite(fan, PWMoutput); 
} 

'setfanmode'기능이 작동하게합니다. 하지만 나머지 코드에서는 오류를 확인하지 않았습니다. 당신이 컨트롤에 여러 팬을 가지고있는 경우, 다음으로 기능을 변경 할 수 있습니다 :

void setfanmode(int degree, int fanpin) 
{ 
    int PWMoutput; 

    if (degree<=30) 
    PWMoutput=0; 
    else if(degree<=60) 
    PWMoutput=127;  
    else if(degree<=80) 
    PWMoutput=255; 
    analogWrite(fanpin, PWMoutput); 
} 

그리고 당신이 여러 팬을 제어하기위한 코드를 변환하는 방법을 상상시키는거야.