Stacje meteo i nietylko

....nie pasujące gdzie indziej...
Awatar użytkownika
fredek
Posty: 372
Rejestracja: poniedziałek 03 maja 2010, 13:58
Lokalizacja: Łódź

Stacje meteo i nietylko

Post 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.
Ostatnio zmieniony środa 14 maja 2014, 19:25 przez fredek, łącznie zmieniany 1 raz.
Awatar użytkownika
Marooned
Posty: 148
Rejestracja: poniedziałek 03 cze 2013, 14:29
Lokalizacja: Poznań

Post 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.
"In the brave new world of the year 2000, a kiss can still break your heart." - Program from Cirque du Soleil's Alegría

Nad tymi gwiazdami jest wszechświat szybujących potworów! Wiedziałaś?
Awatar użytkownika
fredek
Posty: 372
Rejestracja: poniedziałek 03 maja 2010, 13:58
Lokalizacja: Łódź

Post 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).
Awatar użytkownika
Marooned
Posty: 148
Rejestracja: poniedziałek 03 cze 2013, 14:29
Lokalizacja: Poznań

Post 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.
"In the brave new world of the year 2000, a kiss can still break your heart." - Program from Cirque du Soleil's Alegría

Nad tymi gwiazdami jest wszechświat szybujących potworów! Wiedziałaś?
Awatar użytkownika
fredek
Posty: 372
Rejestracja: poniedziałek 03 maja 2010, 13:58
Lokalizacja: Łódź

Post 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!
Awatar użytkownika
Marooned
Posty: 148
Rejestracja: poniedziałek 03 cze 2013, 14:29
Lokalizacja: Poznań

Post 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ą :)
"In the brave new world of the year 2000, a kiss can still break your heart." - Program from Cirque du Soleil's Alegría

Nad tymi gwiazdami jest wszechświat szybujących potworów! Wiedziałaś?
DNF
Posty: 4606
Rejestracja: piątek 23 lis 2007, 19:07
Lokalizacja: Bydgoszcz

Post autor: DNF »

Panowie, jeśli chcecie sobie pogawożyć nt stacji meteo, to mogę Wam wydzielić temat. Chcecie? :D
Awatar użytkownika
fredek
Posty: 372
Rejestracja: poniedziałek 03 maja 2010, 13:58
Lokalizacja: Łódź

Post autor: fredek »

DNF, przenoś, może Barney się swoją też pochwali... pewnie więcej ludzi majstruje takie dziwactwa ;)
belushi
Posty: 381
Rejestracja: poniedziałek 27 wrz 2010, 15:45
Lokalizacja: Rzeszow

Post 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 ;)
Awatar użytkownika
bulwa11
Posty: 305
Rejestracja: niedziela 04 wrz 2011, 00:43
Lokalizacja: Brzesko

Post 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
Obrazek

Solarforce L2 XM-L T5 4B mod Grega || X1 XM-L2 T6 3C mod Grega || 3x MH 150W @CDM-T 942 || MH HQI-BT 400W/D
Awatar użytkownika
barney
Posty: 268
Rejestracja: niedziela 18 lip 2010, 11:47
Lokalizacja: Łask

Post 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:
kisi
Posty: 743
Rejestracja: poniedziałek 26 lis 2007, 08:41
Lokalizacja: Bielsko-Biała

Post 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.
Awatar użytkownika
fredek
Posty: 372
Rejestracja: poniedziałek 03 maja 2010, 13:58
Lokalizacja: Łódź

Post 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.
Awatar użytkownika
barney
Posty: 268
Rejestracja: niedziela 18 lip 2010, 11:47
Lokalizacja: Łask

Post 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:
kisi
Posty: 743
Rejestracja: poniedziałek 26 lis 2007, 08:41
Lokalizacja: Bielsko-Biała

Post 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.
ODPOWIEDZ