const int latchPin = 5; // Pin podpięty do Pin 12 układu 74HC595 (Latch)
const int dataPin = 6; // Pin podpięty do Pin 14 układu 74HC595 (Data)
const int clockPin = 7; // Pin podpięty do Pin 11 układu 74HC595 (Clock)
int reg = 1; // Pin do którego podpięty jest potencjometr
float valr ; // wartości odczytywane z potencjometru
boolean buttonPin = 13; // Pin do którego podpięty jest przycisk
int val = LOW; // Część dotycząca działania przycisku
int prev = LOW;
#define ST_OFF 0
#define ST_ON 1
int status = ST_OFF;
float temp_o;
float temp; // zmienne temperatury
int temp1;
int temp2; // pierwsza i druga cyfra temperatury
byte obr; // wartość obrotów w bitach (max 255)
int obr_p; // obroty zamienione z bitów na procenty (max 100)
int obr_p1;
int obr_p2;
int obr_p3; //poszczególne cyfry wartości obrotów
unsigned long temp_o_time = millis()+300; // czas (0.3s) sprawdzania temperatury od której są regulowane wentylatory
unsigned long temp_time = millis()+1000; // czas (1s) odświeżania temperatury na wyświetlaczu
unsigned long button_time = millis()+50; // czas (0.05s) co który sprawdzania czy przycisk został wciśnięty)
//int i = 0;
const byte numbers[12] = {0b11111100, //0
0b01100000, //1
0b11011010, //2
0b11110010, //3
0b01100110, //4
0b10110110, //5
0b10111110, //6
0b11100000, //7
0b11111110, //8
0b11100110, //9
0b10000001, //kropka
0b00000010 //krecha
};
void show( byte number)
{
for(int j = 0; j <= 7; j++)
{
byte toWrite = number & (0b10000000 >> j);
if(!toWrite)
{
continue;
}
shiftIt(toWrite);
delayMicroseconds(150);
}
}
void shiftIt (byte data)
{
digitalWrite(latchPin, LOW);
for (int k=0; k <= 7; k++)
{
digitalWrite(clockPin, LOW);
if ( data & (1 << k) )
{
digitalWrite(dataPin, HIGH);
}
else
{
digitalWrite(dataPin, LOW);
}
digitalWrite(clockPin, HIGH);
}
digitalWrite(clockPin, LOW);
digitalWrite(latchPin, HIGH);
}
// ta górna część kodu bez komentarza dotyczy wyświetlania cyfr za pomocą rejestru przesuwnego m74hc595b1
void setPwmFrequency(int pin, int divisor)
{
byte mode;
if(pin == 5 || pin == 6 || pin == 9 || pin == 10)
{
switch(divisor) {
case 1: mode = 0x01; break;
case 8: mode = 0x02; break;
case 64: mode = 0x03; break;
case 256: mode = 0x04; break;
case 1024: mode = 0x05; break;
default: return;
}
if(pin == 5 || pin == 6)
{
TCCR0B = TCCR0B & 0b11111000 | mode;
}
else
{
TCCR1B = TCCR1B & 0b11111000 | mode;
}
}
}
// Z kolei ta dotyczy zmiany częstotliwości sygnału PWM, musiałem ją zmienić bo na normalnej wentylatory strasznie piszczały.
void setup()
{
pinMode(reg, INPUT);
pinMode(buttonPin, INPUT);
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(2, OUTPUT); //
pinMode(3, OUTPUT); //
pinMode(4, OUTPUT); //
pinMode(8, OUTPUT); //
pinMode(9, OUTPUT); // te piny idą na wyświetlacze które działają na zasadzie multiplexowania
pinMode(10, OUTPUT); // z tego pinu idzie syg na tranzystor który kręci wentylatorami
Serial.begin(57600);
}
void display_status()
{
switch (status)
{
case ST_OFF: // w tej części jest opisane co następuje po przyciśnięciu przycisku
valr = analogRead(reg); // wartość odczytana z potencjometru
obr=map(valr, 0, 1023, 0, 255); // jest to sterowanie ręczne, widać to po tym że dla wartości maksymalnej odczytanej z potencjometru (1023) obroty wentylatora mają mieć obroty 255 czyli też max
if(valr >1024 ) // w kodzie jest pełno takich udziwnień jak to ale niestety inaczej nie chciało to działać jak należy
{
obr = 255;
}
setPwmFrequency(10, 1); // tutaj jest ustawiana częstotliwość sygnału PWM oraz wybierany jest pin, czyli na pin 10 dajemy 1 jako dzielnik częstotliwości sygnału PWM (patrz funkcja dotycząca tego sygnału)
analogWrite(10, obr);
if(valr<=0) // jeżeli potencjometr wykaże wartość 0 to na wyświetlaczu mają się pokazywać kreseczki
{
digitalWrite(4, LOW);
show(numbers[11]);
digitalWrite(4, HIGH);
show(numbers[11]); //pierwszy wyświetlacz
digitalWrite(8, LOW);
show(numbers[11]);
digitalWrite(8, HIGH);
show(numbers[11]); //drugi wyświetlacz
digitalWrite(9, LOW);
show(numbers[11]);
digitalWrite(9, HIGH);
show(numbers[temp1]); // trzeci wyswietlacz,
}
break;
case ST_ON: // kolejne wciśnięcie przycisku czyli tryb auto
obr=map(temp_o, 34, 45, 80, 255); // dla temperatury od 34 do 45 obroty proporcjonalnie od 80 do 255. Od 80 bo od około takiej wartości wentylatory startują
if(temp_o <=33 )
{
obr = 0;
}
if(temp_o >45 )
{
obr = 255;
} // warunki, czyli żeby nie wyskakiwały dziwne kwiatki.
setPwmFrequency(10, 1);
analogWrite(10, obr);
break;
}
}
void next_status()
{
switch (status)
{
case ST_OFF:
status = ST_ON;
break;
case ST_ON:
status = ST_OFF;
break; //znowu przycisk
}
}
void loop()
{
unsigned long time = millis();
if (time>=button_time)
{
val = digitalRead(buttonPin);
if (val == HIGH && prev == LOW)
{
next_status();
}
prev = val;
display_status();
button_time=time+50; // i znów kawałek kodu dotyczącego przycisku, tutaj jest sprawdzane czy jest wciśnięty czy nie i czy ma przełączać następną instrukcję czyli tryb auto i tryb ręczny
}
analogRead(0);
if (time>=temp_o_time)
{
temp_o = analogRead(0)*5/1024.0;
temp_o = temp_o - 0.5;
temp_o = temp_o / 0.01; // pobieranie wartości z czujnika i przetwarzanie tego na st. Celsjusza
temp_o_time=time+300; // czas co jaki jest to robione
}
if (time>=temp_time)
{
temp=temp_o;
temp_time=time+1000; // czas co jaki będzie odświeżany wyświetlacz z temperaturą
}
// no i dalej jest Mexyk czyt. burdel :P ta część kodu odpowiada za wyświetlanie prawidłowo cyfr
temp1=temp/10; // temperatura jest dzielona przez 10 by wyłuskać pierwszą cyfrę (cyfra dziesiątek)
digitalWrite(2, LOW);
show(numbers[temp1]); // wyświetla tę cyferkę
digitalWrite(2, HIGH);
show(numbers[temp2]);
temp2=temp-temp1*10; // cyfra jedności temperatury
digitalWrite(3, LOW);
show(numbers[temp2]);
digitalWrite(3, HIGH);
show(numbers[10]); // tutaj jest kropka
if (obr>0 && obr<255 ) // teraz czas na obroty, cyfry do wyświetlania są "wyłuskiwane" analogicznie jak przy temperaturze
{
obr_p=(obr*100)/255;
obr_p1=obr_p-obr_p2*10;
digitalWrite(4, LOW);
show(numbers[obr_p1]);
digitalWrite(4, HIGH);
show(numbers[obr_p2]);
obr_p2=obr_p/10;
digitalWrite(8, LOW);
show(numbers[obr_p2]);
digitalWrite(8, HIGH);
show(numbers[obr_p3]);
obr_p3=obr_p/100;
digitalWrite(9, LOW);
show(numbers[obr_p3]);
digitalWrite(9, HIGH);
show(numbers[temp1]);
}
if (obr>254 ) // miałem problemy z cyfrą 100 więc wklepałem ją na chama
{
digitalWrite(4, LOW);
show(numbers[0]);
digitalWrite(4, HIGH);
show(numbers[0]);
digitalWrite(8, LOW);
show(numbers[0]);
digitalWrite(8, HIGH);
show(numbers[1]);
digitalWrite(9, LOW);
show(numbers[1]);
digitalWrite(9, HIGH);
show(numbers[temp1]);
}
if(obr<=0) // tutaj kreseczki po raz drugi
{
digitalWrite(4, LOW);
show(numbers[11]);
digitalWrite(4, HIGH);
show(numbers[11]);
digitalWrite(8, LOW);
show(numbers[11]);
digitalWrite(8, HIGH);
show(numbers[11]);
digitalWrite(9, LOW);
show(numbers[11]);
digitalWrite(9, HIGH);
show(numbers[temp1]);
}
}
Szkoda że nie zadbałeś o ładniejsze wykończenie panelu przedniego. Mogłeś poświęcić trochę czasu na zeszlifowanie tych paskudnych zadziorów z blachy.
Aby poprawić widoczność cyfr, przysłoń wszystkie wyświetlacze arkuszem półprzezroczystego ciemno brązowego lub czerwonego tworzywa.
Plus za normalny schemat.
Chciałem całość zakryć jakimś przyciemnianym plexiglas ale odkładałem to i już tak zostało.
Daję 4, bo średnio mi się podoba wykonanie panelu przedniego, mogłeś się postarać lepiej wpasować te wyświetlacze w tę kratownicę :/
a gdzie tranzystory zasilające wyswietlacz 7seg? Bezposrednio z portu procka jest niedopuszczalne.
One są zasilane z rejestru, z procka idą zwykłe sygnały załączające i wyłączające te 5 wyświetlaczy. Działa mi to już ponad pół roku a komputer pracuje średnio 9h dziennie.
Bardzo fajny projekt , trochę skomplikowany fajnie by wyglądało gdybyś przed wyświetlaczem dał kawałek przyciemnianego plastiku żeby nie było tak widać wyświetlacza gdy komp jest wyłączony ode mnie 5/5
Fajny projekt. Ale oczywiście muszę się przyczepić: nie lepiej użyć formy “wentylator” zamiast “wiatraczek”?
Gdzie wpiąłeś ten dodatkowy kondensator? Bo w shemacie go nie widzę
Już poprawione te wiatraczki :), dodatkowy kondensator jest w tym samym miejscu co 100uF, nie mam pojęcia jak to może pomagać. Zastąpienie tych dwóch na jeden o większej pojemności nie dało żadnego efektu.
Prawdopodobnie dwa kondensatory po sobie lepiej filtrują sygnał niż jeden większy. Jeśli chodzi o czujniki to może mieć to duże znaczenie
Wiatraki to masz na Polu:) A twoja obudowa to i tak piekarnik szkoda kasy.
Nie podoba mi się jak włącza się wentylator w trybie automatycznym. Włącza się i od razu wyłącza i tak parę razy. Nie wiem czy jest to szkodliwe dla samego wentylatora czy innych komponentów, ale na pewno nie wygląda dobrze :)
Nie zwróciłem na to uwagi ale masz rację, postaram się to naprawić.
Jak wy narzekacie, normalnie masakra. To be, a to brzydko, a to źle. Projekt zrobiny w kilimacie industarall, bardzo fajny. Założenie filtru czerwonego na wyświetlacz jest dobrym pomysłem i tak powinieneś zrobić. Tak przy okazji jak się wstawia takie piękne listingi ?? Daje -5 za brak filtra na wyświetlaczu oraz za asymetryczne ustawienie cyfr wzgledem okienka.
Jeśli ci chodzi o dodawanie listingu w artykule to tutaj masz odpowiedź http://scr.hu/0tu/nkkby
Nic mi nie powiedział ten screen. Ja nic takiego nie mam. Gdy piszę post nie mam takiego menu.
Mógłbyś jeszcze zrobić wersję z wyświetlaczem LCD ?
Jeśli na wyświetlaczu tego rodzaju http://nettigo.pl/products/362 to pewnie, powinno to być nawet prostsze.
Dobry projekt szukam coś podobnego tylko do silnika 12w 100w
Powinieneś wprowadzić histerezę, żeby po ochłodzeniu wnętrza do zadanej wartości wentylatory popracowały jeszcze przez jakiś czas. Zapobiegnie to takiemu włączaniu i wyłączani wentylatora jak w 50 sekundzie drugiego filmiku.
Czy mógłbyś mi pomóc z ową histerezą ? zrobiłem sobie właśnie ten projekt ale na wyświetlaczu LCD i paroma innymi zmiankami. Męczę się już od jakiegoś czasu i nie mogę wymyśleć jak zastosować histerezę w tym przypadku… a faktycznie strasznie denerwuje to “mruganie” przy granicznych wartościach.