Strona 1 z 1

Stacje meteo i nietylko

: niedziela 08 wrz 2013, 10:36
autor: fredek
Udało mi się w końcu dokończyć projekt mini stacji meteo :grin:
Tak się prezentuje:
Obrazek

A tak wygląda interface www

Wszystkim steruje ATMega32A, obsługuje 2 wyświetlacze (tekstowy 2x16 i graficzny nokiowski), czujnik temperatury DS18B20, wilgotności DHT-22, ciśnienia BMP-085, klawiaturę matrycową, buzzerek, RTC na DS1307, pamięć 24C32 i kartę sieciową ENC28J60.

: niedziela 08 wrz 2013, 12:23
autor: Marooned
fredek, masz gdzieś większe info o bebechach? (forum Elektrody?)
Ja chcę swoją zmontować na balkonie i połączyć skrętką do "centrum dowodzenia", więc podglądam projekty innych.

: niedziela 08 wrz 2013, 13:03
autor: fredek
Marooned: pełnego schematu w eagle nie mam... robiłem to z modułów kupowanych na e-bay jak miałem trochę wolnego czasu.
Moja płytka jest tylko jedna ze sterowaniem podświetleniem wyświetlaczy i buzzerka, konwerterem napięcia dla karty sieciowej i rozprowadzenie sygnałów I2C, SPI oraz 1wire do modułów. Oprogramowanie w C też pisałem na raty, Barney też pomógł (napisał libs-a do wyświetlacza nokii i BMP-085, robił też optymalizacje kodu dla eth i statystyk).

: niedziela 08 wrz 2013, 13:20
autor: Marooned
Schematu nie oczekiwałem (każdy projekt jest nieco inny) tylko takich ogólnych (choć konkretnych) info.
Dzięki :)

Ja w swoim domu zaszywam 10 DS18B20, na zewnątrz też DS18B20 + właśnie jakieś (jeszcze nie sprecyzowane) czujniki ciśnienia, wilgotności i zobaczymy, co jeszcze wydumam.

: niedziela 08 wrz 2013, 13:54
autor: fredek
Marooned pisze:Ja w swoim domu zaszywam 10 DS18B20, na zewnątrz też DS18B20 + właśnie jakieś (jeszcze nie sprecyzowane) czujniki ciśnienia, wilgotności i zobaczymy, co jeszcze wydumam.
To takie 2 uwagi w ramach OT:
1. W pewnym momencie miałem 7 czujników 1wire na testach i bez tablicowania ID z rom-code to ciężko było się w tym połapać, pamiętaj o tym. Przy tych czujnikach to pisz funkcje nieblokujące - zapomnij o _delay_ms, tylko timery na przerwaniach i liczniki. Rezystor podciągający do VCC też możesz dać mniejszy dla trybu normal np. 3k a dla parasite nawet 1,5kOhma zwłaszcza jak masz dużo kabla.
2. Czujniki ciśnienia i temperatury też mają czujniki temperatury (dla kompensacji) także możesz je wykorzystać, są całkiem dokładne i szybciej działają. Tylko musisz je wystawić poza obudowę urządzenia jak mają pokazywać dokładną temperaturę.

Powodzenia!

: niedziela 08 wrz 2013, 14:11
autor: Marooned
Sieć 1-wire będzie obsługiwana przez Raspberry Pi i jej bibliotekę. Tylko zewnętrzna stacja w planach jest po skrętce [jeszcze nie wybrałem typu komunikacji] (plus pewnie jakiś AVR), bo każdy z 3 czujników jest na inną magistralę. DS na 1-wire, wilgoć jakiś niekompatybilny "1-wire", ciśnienie I2C. Nie znalazłem 2 ostatnich na 1-wire.

A co do połapania się, to w planach oczywiście najpierw odczytanie ID dla każdego czujnika przed wpięciem do magistrali by potem wiedzieć który gdzie. A w ostateczności można też jeden ogrzać i zobaczyć który ID pokazuje skok temperatury :mrgreen:

Ok, nie będziemy już ciągnąć off-topicu bo mnie pogonią :)

: niedziela 08 wrz 2013, 20:37
autor: DNF
Panowie, jeśli chcecie sobie pogawożyć nt stacji meteo, to mogę Wam wydzielić temat. Chcecie? :D

: niedziela 08 wrz 2013, 21:30
autor: fredek
DNF, przenoś, może Barney się swoją też pochwali... pewnie więcej ludzi majstruje takie dziwactwa ;)

: niedziela 08 wrz 2013, 21:53
autor: belushi
Nie majstruje, bo za głupi na to, ale chętnie poczyta, może coś wykmini.

B
co zawsze chciał mieć stacje, różne stacje ;)

: niedziela 08 wrz 2013, 22:48
autor: bulwa11
Od dawna mi się marzy taka stacja bo mam małego hopla na punkcie pogody. Nie chwaląc się prowadzę od prawie 3 lat zapiski dzień po dniu z danymi (subiektywnymi) pogodowymi (temp max, min, zachmurzenie max, min, rodzaj opadu, skala opadu, w zimie pokrywa śnieżna, zmiana pokrywy, inne zjawiska (burza, grad, susza itp) i takie tam. Nie wiem po co mi to, ale fajne :mrgreen:
Brakuje jednak pomiaru wilgotności, ilości opadu, wiatru i najlepiej automatyzacji. Może kiedyś ;-)



Tak to wygląda:

Obrazek

: niedziela 15 wrz 2013, 23:41
autor: barney
Obrazek Obrazek Obrazek Obrazek Obrazek Obrazek Obrazek Obrazek Obrazek Obrazek Obrazek Obrazek Obrazek Obrazek Obrazek Obrazek Obrazek Obrazek Obrazek Obrazek Obrazek

Po lewej stronie procka zegar RTC oraz czujnik ciśnienia BMP085. Na połowie prawej strony od procka buzzer, układ dekodera klawiatury matrycowej oraz dekoder cyfry IW18. Na samym prawym brzegu część wysokonapięciowa do IW18.

Jak widać wykonanie "na pająka" :smile: Napięcie do IW18 to ~42V (max dla przetwornicy).

Wydaje mi się, że ciekawie rozwiązałem kwestie multipleksowania:
Segmenty do IW18 to cały PORTA bezpośrednio na bufor TD62783AP. Cyfry idą najpierw na MH7442, potem są negowane na 7400 i dopiero teraz idą na drugi bufor TD62783AP. Ten sam sygnał do MH7442 dla IW18 jest wykorzystywany do multipleksowania klawiatury matrycowej (za pomocą drugiego MH7442), według mojego pomysłu: http://forum.atnel.pl/topic3584.html. Pozwoliło to obskoczyć IW18 oraz klawiaturę wykorzystując jedynie 12 pinów uC (8segmenty + 3BCD + 1 do detekcji klawisza). :cool:

: poniedziałek 16 wrz 2013, 09:27
autor: kisi
barney, czy nie miałeś problemów z BMP085? Mój egzemplarz troszkę fiksuje, tzn. pokazuje jakieś z sufitu ciśnienie. Owszem mogę wprowadzić korektę, ale obawiam się czy aby błąd nie jest nieliniowy i odstępstwo od nomy będzie większe.

: poniedziałek 16 wrz 2013, 16:15
autor: fredek
kisi, sprawdzałeś na innym egzemplarzu czy też jest problem?
Może algorytm obliczeń ma jakieś błędy, łatwo to sprawdzić bo na 13 stronie pdf od czujnika są przykładowe dane i obliczenia, warto zweryfikować.
Błędy mogą też wynikać z niewłaściwej inicjacji lub za szybkiego odczytu - bez zachowania czasu potrzebnego na konwersję danych i odpowiedź przez czujnik.

: poniedziałek 16 wrz 2013, 16:55
autor: barney
Miałem trochę problemów na etapie pisania libsa, a potem już bez problemów. Algorytm podany w specyfikacji nie lubi się z rzutowaniem do int przez kompilator, trzeba zrobić trochę jawnych rzutowań.

bBPM085.h

Kod: Zaznacz cały

/*
 * 		BMP085	library
 * 		Autor:	barney
 */

#include <avr/io.h>

#ifndef BBMP085_H_
#define BBMP085_H_

uint8_t	bmp085_init			&#40;uint8_t	oversampling_setting&#41;;	// if return !=0 then data communication problem
void	bmp085_temp_start	&#40;void&#41;;
int16_t	bmp085_temp_read	&#40;void&#41;;
void	bmp085_press_start	&#40;void&#41;;
int32_t	bmp085_press_read	&#40;void&#41;;
										// Modes of pressure measurement &#40;oversampling_setting&#41;
										// Number of internal samples is 2^define
#define	BMP085_PRESS_ULP	0			// wait 4.5		ms
#define	BMP085_PRESS_STD	1			// wait 7.5		ms
#define	BMP085_PRESS_HR		2			// wait 13.5	ms
#define	BMP085_PRESS_UHR	3			// wait 25.5	ms

/*
 * 		FIRST RUN
 * 			 ||
 * 			 ||
 * 			\  /
 * 			 \/
 * 		bmp085_init	<===========\\
 * 			 ||					YES
 * 			 ||					||
 * 			 |/	<===== NO = change number of
 * 			 ||				pressure samples?
 * 			 ||					||
 * 			\  /				||
 * 			 \/					||
 * 		bmp085_temp_start		||
 * 			 ||					||
 * 			 ||					||
 * 			\  /				||
 * 			 \/					||
 * 		wait >4.5ms				||
 * 			 ||					||
 * 			 ||					||
 * 			\  /				||
 * 			 \/					||
 * 		bmp085_temp_read		||
 * 			 ||					||
 * 		  pressure?	= NO ======>/|
 * 		  	 ||					||
 * 		  	 YES				||
 * 		  	 ||					||
 * 		  	\  /				||
 * 		  	 \/					||
 * 		bmp085_press_start		||
 * 		  	 ||					||
 * 		  	 ||					||
 * 		  	\  /				||
 * 			 \/					||
 * 		wait >define			||
 * 			 ||					||
 * 			 ||					||
 * 			\  /				||
 * 			 \/					||
 * 		bmp085_press_read =====>//
 */

#include "../I2C_TWI/i2c_twi.h"			// Connecting this library with i2c lib
inline	void	bmp085_start	&#40;void&#41;
&#123;
	TWI_start &#40;&#41;;
&#125;
inline	void	bmp085_write	&#40;uint8_t	command&#41;
&#123;
	TWI_write &#40;command&#41;;
&#125;
inline	uint8_t	bmp085_read		&#40;uint8_t	command&#41;
&#123;
	return	TWI_read &#40;command&#41;;
&#125;
inline	void	bmp085_stop		&#40;void&#41;
&#123;
	TWI_stop &#40;&#41;;
&#125;

#define BMP085_NAME_READ	0b11101111
#define BMP085_NAME_WRITE	0b11101110
#define BMP085_ACK	1
#define BMP085_NACK	0

#endif /* BBMP085_H_ */
bBMP085.c

Kod: Zaznacz cały

/*
 * 		BMP085	library
 * 		Autor&#58;	barney
 */

#include "bBMP085.h"

static struct
&#123;
	uint8_t oss;
	int32_t	b5;
	struct
	&#123;
		int16_t		ac1;
		int16_t		ac2;
		int16_t		ac3;
		uint16_t	ac4;
		uint16_t	ac5;
		uint16_t	ac6;
		int16_t		b1;
		int16_t		b2;
		int16_t		mb;
		int16_t		mc;
		int16_t		md;
	&#125; memory;
&#125; bmp085;

static	uint16_t	bmp085_read_eeprom	&#40;uint8_t	adress&#41;
&#123;
	register	uint16_t	data;
	bmp085_start	&#40;&#41;;
	bmp085_write	&#40;BMP085_NAME_WRITE&#41;;
	bmp085_write	&#40;adress&#41;;
	bmp085_start	&#40;&#41;;
	bmp085_write	&#40;BMP085_NAME_READ&#41;;
	data = bmp085_read &#40;BMP085_ACK&#41;;
	data = &#40;data<<8&#41; + bmp085_read&#40;BMP085_NACK&#41;;
	bmp085_stop		&#40;&#41;;
	if &#40;&#40;!data&#41; || &#40;data==0xFFFF&#41;&#41; bmp085.oss=0xFF;
	return	data;
&#125;

uint8_t		bmp085_init			&#40;uint8_t	oversampling_setting&#41;
&#123;
	bmp085.oss=0;		// Using oss as error value.

	bmp085.memory.ac1=bmp085_read_eeprom &#40;0xAA&#41;;
	bmp085.memory.ac2=bmp085_read_eeprom &#40;0xAC&#41;;
	bmp085.memory.ac3=bmp085_read_eeprom &#40;0xAE&#41;;
	bmp085.memory.ac4=bmp085_read_eeprom &#40;0xB0&#41;;
	bmp085.memory.ac5=bmp085_read_eeprom &#40;0xB2&#41;;
	bmp085.memory.ac6=bmp085_read_eeprom &#40;0xB4&#41;;
	bmp085.memory.b1= bmp085_read_eeprom &#40;0xB6&#41;;
	bmp085.memory.b2= bmp085_read_eeprom &#40;0xB8&#41;;
	bmp085.memory.mb= bmp085_read_eeprom &#40;0xBA&#41;;
	bmp085.memory.mc= bmp085_read_eeprom &#40;0xBC&#41;;
	bmp085.memory.md= bmp085_read_eeprom &#40;0xBE&#41;;

	if &#40;bmp085.oss&#41;	return bmp085.oss;
	bmp085.oss=oversampling_setting;
	return 0;
&#125;

void	bmp085_temp_start	&#40;void&#41;
&#123;
	bmp085_start	&#40;&#41;;
	bmp085_write	&#40;BMP085_NAME_WRITE&#41;;
	bmp085_write	&#40;0xF4&#41;;
	bmp085_write	&#40;0x2E&#41;;
	bmp085_stop		&#40;&#41;;
&#125;

int16_t	bmp085_temp_read	&#40;void&#41;
&#123;
	bmp085_start	&#40;&#41;;
	bmp085_write	&#40;BMP085_NAME_WRITE&#41;;
	bmp085_write	&#40;0xF6&#41;;
	bmp085_start	&#40;&#41;;
	bmp085_write	&#40;BMP085_NAME_READ&#41;;
	int32_t	ut=	bmp085_read	&#40;BMP085_ACK&#41;;
	ut= &#40;ut<<8&#41; + bmp085_read &#40;BMP085_NACK&#41;;
	bmp085_stop		&#40;&#41;;

	int32_t	x1 = &#40;&#40;&#40;int32_t&#41; ut - bmp085.memory.ac6&#41; * bmp085.memory.ac5&#41;>>15 ;
	int32_t	x2 = &#40;&#40;int32_t&#41; bmp085.memory.mc<<11&#41; / &#40;x1 + bmp085.memory.md&#41;;
	bmp085.b5 = x1 + x2;
//	bmp085.b5 = 3912;
	return &#40;bmp085.b5 + 8&#41;>>4;
&#125;

void	bmp085_press_start	&#40;void&#41;
&#123;
	bmp085_start	&#40;&#41;;
	bmp085_write	&#40;BMP085_NAME_WRITE&#41;;
	bmp085_write	&#40;0xF4&#41;;
	bmp085_write	&#40;0x34+&#40;bmp085.oss<<6&#41;&#41;;
	bmp085_stop		&#40;&#41;;
&#125;

int32_t	bmp085_press_read	&#40;void&#41;
&#123;
	bmp085_start	&#40;&#41;;
	bmp085_write	&#40;BMP085_NAME_WRITE&#41;;
	bmp085_write	&#40;0xF6&#41;;
	bmp085_start	&#40;&#41;;
	bmp085_write	&#40;BMP085_NAME_READ&#41;;
	int32_t	up=	bmp085_read	&#40;BMP085_ACK&#41;;
	up= &#40;up<<8&#41; + bmp085_read &#40;BMP085_ACK&#41;;
	up= &#40;&#40;up<<8&#41; + bmp085_read &#40;BMP085_NACK&#41;&#41; >> &#40;8-bmp085.oss&#41;;
	bmp085_stop		&#40;&#41;;

	int32_t		b6=bmp085.b5-4000;
	int32_t		x1=&#40;bmp085.memory.b2*&#40;&#40;b6*b6&#41;>>12&#41;&#41;>>11;
	int32_t		x2=&#40;bmp085.memory.ac2*b6&#41;>>11;
	int32_t		x3=x1+x2;
	int32_t		b3=&#40;&#40;&#40;&#40;&#40;int32_t&#41;bmp085.memory.ac1<<2&#41;+x3&#41;<<bmp085.oss&#41;+2&#41;>>2;
				x1=&#40;bmp085.memory.ac3*b6&#41;>>13;
				x2=&#40;bmp085.memory.b1*&#40;&#40;b6*b6&#41;>>12&#41;&#41;>>16;
				x3=&#40;&#40;x1+x2&#41;+2&#41;>>2;
	uint32_t	b4=&#40;bmp085.memory.ac4*&#40;uint32_t&#41;&#40;x3+32768&#41;&#41;>>15;
	uint32_t	b7=&#40;&#40;uint32_t&#41;up-b3&#41;*&#40;50000>>bmp085.oss&#41;;
	int32_t		p;
	if &#40;b7<0x80000000&#41;
		p=&#40;b7<<1&#41;/b4;
	else
		p=&#40;b7/b4&#41;<<1;
				x1=&#40;p>>8&#41;*&#40;p>>8&#41;;
				x1=&#40;x1*3038&#41;>>16;
				x2=&#40;-7357*p&#41;>>16;
	return	p+&#40;&#40;x1+x2+3791&#41;>>4&#41;;
&#125;
Taki kod działa u mnie bez najmniejszych problemów już z pół roku. Pamiętaj, że to ty musisz zapewnić odstęp czasowy między funkcjami żądania, a odczytu :wink:

: wtorek 17 wrz 2013, 06:54
autor: kisi
OK, dzięki za listing, będę analizował. Gdzieś na forach wyczytałem że czujnik (scalak) ten jest wrażliwy na przegrzanie w czasie procesu produkcyjnego...
Sam go nie lutowałem, kupiłem gotowy moduł i chciałem wykorzystać w swojej stacji używając do tego arduino.