Zrobiłem sobie w ramach przygotowania do większego projektu termometr na ds'ie, temperaturę wskazuje pięknie gdyby nie jeden mały szczegół. Sypie błędami. średnio co 5 sekund wyskakuje mi temperatura 500st, 80st. ect ect. Tu moje pytanie: czy da się to wyeliminować programowo, czy zrobiłem jakiegoś babola w programie?
Program:
Z tego powstanie stacja w domu na Atmedze16 na 15 czujników do szklarni (każdy na osobnej linii bo będą się zakłócać + odległość w sumie 100m i różne warunki na poszczególnych częściach przewodów) + pare przycisków i wyświetlacze (temperatura + nazwa szklarni)
Proszę o jakieś rozwiązanie sypania błędami pomiarów? może wyciąganie średniej z 10 odczytów? czujnik działa na 9-bit. ale chciałbym go zrobić na rozdziałce co 0.1 stopnia. (w końcu ważne czy mam 0.4 stopnia czy już 1 - roślini muszą żyć xD)
Program:
#include <avr/io.h>
#include <avr/delay.h>
#include <avr/signal.h>
#include <stdlib.h>
#define F_CPU 1000000
#define RED _BV(7) //
#define GREEN _BV(5) //jakies
#define IN 4 //smieci
#define DEL_TIME 500 //
#define WE 7
#define PORT_1Wire PIND
#define set DDRD&=~_BV(WE)
#define clear DDRD|=_BV(WE)
#define dziesiatkiON PORTB |=_BV(1);
#define dziesiatkiOFF PORTB &= ~_BV(1);
#define jednosciON PORTB |=_BV(2);
#define jednosciOFF PORTB &=~_BV(2);
#define setkiON PORTB |=_BV(0);
#define setkiOFF PORTB &=~_BV(0);
#define DOFF PORTB &=~ ((1 << 0) | (1 << 1) | (1 << 2));
char buf[8];
char x [10] = {0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9};
volatile int a;
volatile int wyswietlacz;
//*************************************************************************************
void send(char bit);
unsigned char read(void);
void send_byte(char wartosc);
unsigned char read_byte(void);
void error(int i);
volatile liczba;
volatile dziesiatki;
volatile jednosci;
volatile setki;
//*************************************************************************************
unsigned char RESET_PULSE(void)
{
unsigned char PRESENCE;
clear;
_delay_us(500);
set;
_delay_us(30);
if(bit_is_clear(PORT_1Wire, WE)) {PRESENCE = 1;} else {PRESENCE = 0;}
_delay_us(470);
if(bit_is_set(PORT_1Wire, WE)) {PRESENCE = 1;}
else {PRESENCE = 0;}
return PRESENCE;
}
//*************************************************************************************
void send(char bit)
{
clear;
_delay_us(5);
if(bit == 1)
set;
_delay_us(80);
set;
}
//*************************************************************************************
unsigned char read(void)
{
unsigned char PRESENCE = 0;
clear;
_delay_us(2);
set;
_delay_us(15);
if(bit_is_set(PORT_1Wire, WE)) PRESENCE = 1;
else PRESENCE = 0;
return (PRESENCE);
}
//*************************************************************************************
void send_byte(char wartosc)
{
unsigned char i;
unsigned char pom;
for(i=0; i<8; i++)
{
pom = wartosc >> i;
pom &= 0x01;
send(pom);
}
_delay_us(100);
}
//*************************************************************************************
unsigned char read_byte(void)
{
unsigned char i;
unsigned char wartosc = 0;
for(i=0; i<8; i++)
{
if(read()) wartosc |= 0x01 << i;
_delay_us(15);
}
return (wartosc);
}
int main( void )
{
liczba=1;
DDRB = 0xFF; // Ustawienie bitu LED jako wyjścia
TCCR1B |= (1 << WGM12); // Ustawia timer w tryb CTC
OCR1A = 3333; // Ustawia wartość pożądaną na 1Hz dla preskalera 64
TCCR1B |= (1 << CS10); // Ustawia timer z preskalerem Fcpu/256
TIMSK |= (1 << OCIE1A); // Zezwolenie na przerwania dla CTC
sei(); // Zezwolenie globalne na przerwania
DDRC = 0xFF;
PORTC = 0x00;
PORTB = 0xFF;
wyswietlacz=0;
dziesiatkiOFF;
jednosciOFF;
//*****************************************************************************
RESET_PULSE();
send_byte(0xCC);
send_byte(0x4E);
send_byte(0x00);
send_byte(0x00);
send_byte(0x7F); // ROZDZIALKA 9 BIT
_delay_ms(500);
_delay_ms(500);
RESET_PULSE();
send_byte(0xCC);
send_byte(0x48);
//*****************************************************************************
while(1)
{
wyswietl_temp();
_delay_ms(200);
dziesiatki = (liczba/10)%10;
jednosci = liczba%10;
setki = liczba/100;
}
}
//*************************************************************************************
//*************************************************************************************
//*************************************************************************************
void wyswietl_temp(void)
{
int i;
unsigned char sprawdz;
char temp1 = 0, temp2 = 0;
_delay_ms(200);
sprawdz = RESET_PULSE();
if(sprawdz == 1)
{
send_byte(0xCC);
send_byte(0x44);
_delay_ms(100);
sprawdz = RESET_PULSE();
send_byte(0xCC);
send_byte(0xBE);
temp1 = read_byte();
temp2 = read_byte();
int t = (temp1 + (temp2 * 256)) / 16;
liczba=t;
}
else
{
liczba=999;
}
}
//*************************************************************************************
ISR(TIMER1_COMPA_vect)
{
DOFF;
switch (a)
{
case 2:
setkiON;
PORTC = x[setki];
a=0;
break;
case 1:
dziesiatkiON;
PORTC = x[dziesiatki];
a++;
break;
case 0:
jednosciON;
PORTC = x[jednosci];
a++;
break;
}
}
Z tego powstanie stacja w domu na Atmedze16 na 15 czujników do szklarni (każdy na osobnej linii bo będą się zakłócać + odległość w sumie 100m i różne warunki na poszczególnych częściach przewodów) + pare przycisków i wyświetlacze (temperatura + nazwa szklarni)
Proszę o jakieś rozwiązanie sypania błędami pomiarów? może wyciąganie średniej z 10 odczytów? czujnik działa na 9-bit. ale chciałbym go zrobić na rozdziałce co 0.1 stopnia. (w końcu ważne czy mam 0.4 stopnia czy już 1 - roślini muszą żyć xD)
