Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Arduino - tutorijali, pitanja, primjeri i projekti
#1
Otvaram temu s ciljem da objedinimo sva moguća pitanja, literature i projekte vezano uz Arduino platformu u jednoj temi.

Nadam se da nisam jedini na forumu koji koristi dotičnu platformu pa da će ubrzo ova tema biti puna projekata i literature Smile
Reply
#2
Evo jedne moje, doduše početničke kreacije, radi se o detektoru osvjetljenja, ništa posebno, vježbanje malo, kada bi se senzor kalibrirao onda bi se mogao sklop koristiti kao mjerač osvjetljenja di bi se vrijednost isčitavala u serijskom monitoru.

Jedino što sam primjetio da kada se pritisne gumb ponekad odreagira odmah kako treba, a ponekad samo blinkne led, kao da dio programa krene ali onda se zaustavi. Koliko sam uspio na netu vidjeti, ljudi to rješavaju sa 47 nF keramikom između pina za tipkalo na MCU i mase. Možda je bolje da to sredim softverski sa debounce. I izbaciti eksterne pulldown otpore i zamjeniti sa internim.

evo koda 
Code:
const int senzor = A0;
const int crveno = 4;
const int zeleno = 7;
const int tipkalo1 = 2;
const int tipkalo2 = 8;

int svjetlost = 0;
int zadrska = 20;
int tipka1 = 0;
int tipka2 = 0;
int brojac1 = 0;
int brojac2 = 0;

void setup(){
 pinMode(zeleno, OUTPUT);
 pinMode(crveno, OUTPUT);
 pinMode(tipkalo1, INPUT);
 pinMode(tipkalo2, INPUT);
 Serial.begin(9600);
}
void loop(){
 svjetlost = analogRead(senzor);
 tipka1 = digitalRead(tipkalo1);
 tipka2 = digitalRead(tipkalo2);
 delay(zadrska);
 if(tipka2 == HIGH) brojac2++;
 if(brojac2 == 1 && brojac1 == 1){
   delay(zadrska);
   Serial.println(svjetlost);
 }
 if(brojac2 == 2){
   tipka2 = 0;
   brojac2 = 0;
 }
 if(tipka1 == HIGH) brojac1++;
 delay(zadrska);
 if(brojac1 == 1){
 if(svjetlost < 200){
   digitalWrite(zeleno, LOW);
   digitalWrite(crveno, HIGH);
   delay(zadrska);
 }else if(svjetlost > 200 && svjetlost < 400){
   digitalWrite(zeleno, HIGH);
   digitalWrite(crveno, HIGH);
   delay(zadrska);
 }else{
   digitalWrite(zeleno, HIGH);
   digitalWrite(crveno, LOW);
   delay(zadrska);
 }
}
 if(brojac1 == 2){
   delay(zadrska);
   digitalWrite(zeleno, LOW);
   digitalWrite(crveno, LOW);
   tipka1 = 0;
   brojac1 = 0;
   tipka2 = 0;
   brojac2 = 0;
}
}

Sklop ima dva tipkala, jednim palimo i gasimo slanje podataka na serijski monitor, jednim palimo i gasimo sve funkcije (standby).
evo i jedne slike, na protoboardu
[Image: 2ev8ehl.jpg]
Reply
#3
Bravo, eto vidis da nije nista tesko Wink

Za debounce pogledaj ovu temu:
http://forum.yu3ma.net/showthread.php?tid=690
Reply
#4
Može se koristiti softverski deobunce, i to je moja preporuka. Medjutim da ne bih preporučio interne pull-up otpornike za primenu u uređajima koji bi trebalo da budu robustni i za industrijsku primenu.
Interni pull-up otpornici se uglavnom realizuju upotrebom internih FET tranzistora i ekvivalent su otpornicima od nekih 100-ak kohm-a. To znači da su slabi (weak). Mnogo je bolje postaviti otponike manjih vredosti otpora, recimo za 5V logiku, ja koristim 1k-2k2, jer je time obezbeđen mnogo stabilniji naponski nivo, jer je i struja veća.

Takođe, još jedna napomena: veoma česta praksa je da se nakon veze pull-up i tastera ka masi redno vezuje ka pinu mikrokontrolera i 100-220R otpornik. Gledano logikom programera ovo je potpuno nepotrebno, međutim prvi izlazak na teren sa uređajem koji ih nema može vas razočarati čestim resetovanjem mikrokontrolera, i ponekad "latch-up" pojavom na samom pinu. Dodavanjem ovog otpornika povećavamo pouzdanost rada mikrokontrolera od nekog parazitnog impulsa od spoljne elektronike, tako da nemojte štedeti na ovim stvarima ako će se vaš uređaj konačno naći negde van laboratorijskog stola...
Reply
#5
Onda je definitivno bolje postaviti vanjski pull-up, jer uređaji koje planiram neće biti samo na labaratorijskom stolu, imat će neku korisnu funkciju, trentutno se motam oko PWM-a, imam na balkonu alternator 12V 500W koji sam čeka da postane BLDC Smile), dolazi mi i LCD display 16×2, bit će tu projekata.

Zanima me da li se može nabaviti drugi Atmega328P i njega staviti na arduino ploču ? ili napraviti neki univerzalni arduino pomoću kojeg bi bilo moguće programirati i druge vrste Atmel MCU ?
Reply
#6
Vidi ovo ti moze biti zanimljivo:
http://www.aliexpress.com/item/leaflabs-...54802.html
Ja porucio par komada i ocekujem da mi stigne.
Reply
#7
Ovo je puno moćnija stvarčica od arduina sa Atmega328, samo 4 dolara ?? Ja cu si odmah naručiti 10 kom čim plaća bude Smile

Ovo je savrseno za BLDC kontroler projekt Big Grin
Reply
#8
Došao LCD 16×2 i 5 komada LM35DZ, naravno odmah se bacio na izradu termometra Smile

Mjerno područje mu je od 3 do 30 stupnjeva, moram napraviti par modifikacija da mjeri ispod nule, u datasheetu od LM35 se mogu naći svi podaci potrebni kako bi se ispisala točna temperatura na zaslonu.

Bilo je malo zafrkancije dok nisam uspio sve uskladiti da radi savršeno, bez zaostalih simbola na zaslonu.
Simbol za stupanj sam sam kreirao jer postojeći sa tipkovnice nije funkcionirao. Još sam kreirao i naša slova sa kvačicama i par simbola koje ću koristiti u budućnosti.

Možda prijeđem na LM50 zbog mjerenja negativne vrijednosti temperature jer s njim nije potrebno koristiti negativni napon.

Okačim par slika sutra Smile

@mikikg

jel stigao maple mini ?
Reply
#9
Nije jos, tek su pre neki dan poslali i na to jos 25-30 dana … Tako mu to sa kineskom postom ...
Reply
#10
Inace super ti ovo sa Arduino napreduje … nisi ni bio svestan sta propustas Smile … secam se da sam ti kontrolere preporucio jos na pocetku naseg druzenja jer sam video kod tebe potencial koji mozes da se upotrebis Wink
Nema veze samo polako, skontaces to, ima tu svasta jos zanimljivo istraziti …
Reply
#11
Evo ovdje stavljam prvi kompletiran Arduino projekt, radi se o termometru unutarnje temperature.


Koristio sam Arduino Uno, LM35DZ temperaturni senzor te LCD 16×2 baziran na Hitacijevom HD44780 LCD kontroleru.

Sam senzor mjeri od +2 do +150 stupnjeva, a u mojem projektu mjeri od +5 do +30, pošto je ovo zasad samo termometar unutarnje temperature, više i niže temperature nisu potrebne, zato moj program izbacuje poruke: "Temperatura previsoka !" za temperaturu iznad 30 stupnjeva i "Temperatura preniska !" za temperaturu ispod 4-5 stupnja. 

LCD radi u 4 bitnom načinu rada, može raditi i u 8 bitnom, ali ne vidim potrebu za time, samo bi si bezveze dodatna 4 pina zauzeli .

Evo i koda programa za one koji bi željeli isprobati :

Code:
#include<LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

byte stupanj[8] = {
 B00100,
 B01010,
 B00100,
 B00000,
 B00000,
 B00000,
 B00000,
};

byte slovo[8] = {
 B00010,
 B00100,
 B01110,
 B10001,
 B10000,
 B10001,
 B01110,
 B00000,
};

byte slovo2[8] = {
 B01010,
 B00100,
 B01110,
 B10001,
 B10000,
 B10001,
 B01110,
 B00000,
};

const int lm35 = A0;
float temp = 0;

void setup(){
 lcd.begin(16,2);
 lcd.createChar(0, stupanj);
 lcd.createChar(2, slovo2);
 lcd.setCursor(3, 0);
 lcd.print("Termometar");
 delay(3000);
 lcd.setCursor(2, 1);
 lcd.print("Verzija  2.0  ");
 delay(3000);
 lcd.clear();
 delay(500);
 lcd.display();
 lcd.setCursor(0, 0);
 lcd.print("Senzor: LM35DZ");
 lcd.setCursor(0, 1);
 lcd.print("Veli");
 lcd.setCursor(4, 1);
 lcd.write(2);
 lcd.setCursor(5, 1);
 lcd.print("ina: 5.692b");
 delay(3500);
 lcd.clear();
 delay(500);
}

void loop(){
 temp = analogRead(lm35);
 temp = temp * 0.439453125;
 lcd.setCursor(0, 0);
 lcd.print("Temperatura sobe ");
 lcd.setCursor(2, 1);
 lcd.print(temp,1);
 lcd.setCursor(6, 1);
 lcd.write(byte(0));
 lcd.setCursor(7, 1);
 lcd.print("C");
 lcd.setCursor(8, 1);
 lcd.print("  ");
 delay(200);
 lcd.display();
 if(temp > 21){
   lcd.setCursor(10, 1);
   lcd.print("Toplo");
   lcd.setCursor(15, 1);
   lcd.print(" ");
} else if(temp < 21 && temp > 19.5){
   lcd.setCursor(10, 1);
   lcd.print("Ugodno");
} else{
   lcd.setCursor(10, 1);
   lcd.print("Hladno");
}
 if(temp > 28){
   lcd.createChar(1, slovo);
   lcd.setCursor(10, 1);
   lcd.print("Vru");
   lcd.setCursor(13, 1);
   lcd.write(1);
   lcd.setCursor(14, 1);
   lcd.print("e");
   lcd.setCursor(15, 1);
   lcd.print(" ");
}
 if(temp > 30){
   lcd.display();
   lcd.clear();
   lcd.setCursor(3, 0);
   lcd.print("Temperatura");
   lcd.setCursor(3, 1);
   lcd.print("previsoka!");
   delay(2000);
   lcd.noDisplay();
   delay(2000);
 }
 if(temp < 3){
   lcd.display();
   lcd.clear();
   lcd.setCursor(3, 0);
   lcd.print("Temperatura");
   lcd.setCursor(3, 1);
   lcd.print("preniska!");
   delay(2000);
   lcd.noDisplay();
   delay(2000);
  }
}

U početku sam koristio naredbu map i switch case ali sam se ipak odlučio za if i if else jer sam imao neke nestabilnosti pri nižim temperaturama dok sam koristio RGY ledicu za indikaciju temperature.

Formula za prikaz točne temperature je: (5.0 * 1000 / 1024) / 10, gdje je 5.0 napon napajanja (ja sam korisio 4.5V jer mi tolko dolazi na senzor), 1000 je ovdje da bi se volti pretvorili u milivolte, a 1024 je maksimalna vrijednost koju ADC od Arduina može prikazati (8 bit), a 10 je konstanta (10mV po °C) i za 4.5V napajanje je rezultat 0.439453125


Jedino sam mislio sve funkcije razdvojit u svoje petlje pa ih onda nakraju sjediniti u void loop(). Preglednosti radi. 


Morao sam se malo poigrati dok nisam uspio sve moguće probleme riješiti, a bilo ih je tipa da poslije blinkajućih poruka display se jednostavno ugasio, a to sam rješio sa lcd.display() poslije delay-a u glavnom djelu programa koji ispisuje temperaturu. Onda je bilo i problema za zaostalim slovima, pa je poslije Ugodno došlo Toplo pa je zadnje o ostalo i onda je pisalo Toploo.



Sada mi je plan uzeti par displaya, jedna sa RGB osvjetljenjem pa malo se time igrati i uzeti 20×4 LCD.


Evo jedan video da vidite termometar u funkciji, svi savjeti i kritike dobrodošli Smile

Reply
#12
Inače evo stranice koju ja koristim kada izrađujem posebna slova, da se ne mučite kao ja sa matematičkom bilježnicom i sjenčanjem kockica xD

Liquid Crystal Display Custom Character Designer

@mikikg

Ma bježao sam od mikrokontrolera kao vrag od timijana, ali sad kad vidim koliko zapravo oni pojednostavljuju stvari totalno sam se navukao na njih, trenutno imam 3 knjige za arduino i lijepo polako ih paralelno čitam i uspoređujem kaj ima u jednoj, a da u drugoj nije navedeno, pa onda sad naručim malo moćnije procesore, pa onda i neki switcher sa MCU mora past Smile 

Pa i taj BLDC Smile 

Evo jednog senzora koji bi bio dobar izbor za negativne temperature, ima ugrađeni offset pa je moguće negativne temperature mjeriti samo sa pozitivnim +5V napajanjem Smile Radi se o AD22100
Reply
#13
Jel ima neko volje da mi to objasni ili ako ima nekakav link na našem jeziku, dakle svaki korak u programiranju može i ovog iznad projekta kako koja funkcija i kod da se to sve upari?
Reply
#14
Mogu ti ja objasniti sutra poslijepodne, trenutno nisam doma niti imam pristup računalu trenutno :/

Nažalost ja nisam našao literaturu na našem jeziku, sve je na engleskom...
Reply
#15
Odlučio sam uzeti TMP36 senzor, 10 komada za kojih 14 dolara. On mjeri do -40 i za rad zahtjeva napajanje od 5V
Reply
#16
Evo pa da ti pojasnim barem za moj program 


#include<LiquidCrystal.h>  <--- ova naredba poziva library za LCD zaslone, bez nje sve kasnije naredbe poput lcd.print() nebi funkcionirale, tj kompajler bi javljao grešku da naredba ne postoji
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);  <--- ova naredba definira pinove koje ćemo koristiti za kontrolu LCD-a. ona ti je oblika (rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7), a najčešće će ti biti ovakvog oblika LiquidCrystal lcd(rs, enable, d4, d5, d6, d7); rw slobodno spojiš na masu jer stanje na tom pinu odlučuje oćemo li čitati sa LCD-a ili zapisivati na njega, a pošto u 90% slučajeva zapisujemo njega slobodno na GND spojiš. 

byte stupanj[8] = { <--- ovom varijablom byte stvaramo svoje posebne znakove, gdje doslovno palimo piksel po piksel :)
 B00100,
 B01010,
 B00100,
 B00000,
 B00000,
 B00000,
 B00000,
};

byte slovo[8] = {
 B00010,
 B00100,
 B01110,
 B10001,
 B10000,
 B10001,
 B01110,
 B00000,
};

byte slovo2[8] = {
 B01010,
 B00100,
 B01110,
 B10001,
 B10000,
 B10001,
 B01110,
 B00000,
};

const int lm35 = A0;  <--- ovime analogni ulaz A0 nazivamo lm35, a naredbom const ga definiramo kao konstantom i ona se tijekom programa ne mjenja.
float temp = 0;  <--- ovdje ćemo spremati podatke koje dobivamo sa senzora, float nam omogućuje pohranjivanje vrijednosti sa decimalnim zapisom. Tablice možeš nać na netu

void setup(){   <--- ova petlja nam služi da postavimo ulaze i izlaze, da uspostavimo serijsku komunikaciju i tako dalje i ona se pokreće samo pri paljenju MCU jednom i više ne.
 lcd.begin(16,2);  <--- definiramo dimenzije našeg LCD-a
 lcd.createChar(0, stupanj); <--- stvaramo naše simbole koje smo ranije ispisali
 lcd.createChar(2, slovo2);
 lcd.setCursor(3, 0); <--- postavljamo kursor na prvi red i 4. segment.
 lcd.print("Termometar"); <--- ispisujemo riječ termometar
 delay(3000); <--- čekamo 3 sekunde
 lcd.setCursor(2, 1); 
 lcd.print("Verzija  2.0  "); 
 delay(3000); 
 lcd.clear(); <--- čistimo sav tekst sa LCD-a
 delay(500);  
 lcd.display(); <-- uključujemo prikaz na displeju
 lcd.setCursor(0, 0);  <--- postavljamo kursor na početak
 lcd.print("Senzor: LM35DZ"); 
 lcd.setCursor(0, 1);

 lcd.print("Veli");
 lcd.setCursor(4, 1);
 lcd.write(2); <--- ovime zapisujemo naš simbol, on je drugi po redu pa stavljamo 2
 lcd.setCursor(5, 1);
 lcd.print("ina: 5.692b");
 delay(3500);
 lcd.clear();
 delay(500);
}

void loop(){
 temp = analogRead(lm35);  <--- čitamo vrijednost senzora i zapisujemo ju u varijablu temp
 temp = temp * 0.439453125;  <--- aritmetičkim operacijama prilagođavamo vrijednosti senzora da odgovaraju temperaturi u stupnjevima celzijusima
 lcd.setCursor(0, 0);
 lcd.print("Temperatura sobe ");
 lcd.setCursor(2, 1);
 lcd.print(temp,1);
 lcd.setCursor(6, 1);
 lcd.write(byte(0));
 lcd.setCursor(7, 1);
 lcd.print("C");
 lcd.setCursor(8, 1);
 lcd.print("  ");
 delay(200);
 lcd.display();<--- ova naredba je potrebna kako bi se prikaz temperature i osjeta uključio nakon blinkajućih poruka jer smo kod njih koristili lcd.display i lcd.noDisplay za blinkanje. Kad više ne ispunjavamo uvjet za blinkanje, program nastavi vrtiti ispis temperarture, a kako blinkanje završava sa lcd.noDisplay() ako ne uključimo display nećemo niti imati prikaz temperature. On je na kraju jer ako ga stavimo na početak onda će se za vrijeme blinkanja mješati poruka i prikaz temperature.
 if(temp > 21){  <---  ovime se ispitujemo dali je temperatura veća od 21 i ako je onda se izvršava program unutar vitičaste zagrade, ako nije, te se komande ne izvršavaju jer uvjeti nisu ispunjeni.. 
   lcd.setCursor(10, 1);
   lcd.print("Toplo");
   lcd.setCursor(15, 1);
   lcd.print(" ");
} else if(temp < 21 && temp > 19.5){
   lcd.setCursor(10, 1);
   lcd.print("Ugodno");
} else{
   lcd.setCursor(10, 1);
   lcd.print("Hladno");
}
 if(temp > 28){
   lcd.createChar(1, slovo);
   lcd.setCursor(10, 1);
   lcd.print("Vru");
   lcd.setCursor(13, 1);
   lcd.write(1);
   lcd.setCursor(14, 1);
   lcd.print("e");
   lcd.setCursor(15, 1);
   lcd.print(" ");
}
 if(temp > 30){
   lcd.display();
   lcd.clear();
   lcd.setCursor(3, 0);
   lcd.print("Temperatura");
   lcd.setCursor(3, 1);
   lcd.print("previsoka!");
   delay(2000);
   lcd.noDisplay();
   delay(2000);
 }
 if(temp < 3){
   lcd.display();
   lcd.clear();
   lcd.setCursor(3, 0);
   lcd.print("Temperatura");
   lcd.setCursor(3, 1);
   lcd.print("preniska!");
   delay(2000);
   lcd.noDisplay();
   delay(2000);
  }
}


Ako nekaj nije jasno pitaj, ja sam probao to bolje odgovoriti, ali nažalost imam obaveza pa sam možda štogod preskočio.

Zapamti da se program uvijek izvršava odozgora prema dolje i zato treba logički razmišljat, ovdje ti je dobar primjer blinkajuća poruka, upališ uređaj, on prođe void setup petlju i izvrši sve naredbe koje smo unjeli u tu petlju i program nastavlja dalje, upali display i prikazuje temperaturu i ona prijeđe 30 stupnjeva i poruke počnu, e sad da ti je lcd.display odmah na početku loop petlje on bi ti izmješao tekst potpuno jer bi blinknuo poruku i ti bi odmah upalio display i prikazao temperaturu i prije nego on dode opet do uvjeta te poruke, a ako ti njega staviš na kraj, on neće odmah prikazivati tekst nego će proć prikaz, upalit display ispitati uvjete i ako je temperatura i dalje od 30 opet zablinkat poruku, a ako je manja od 30 onda se vraća na početak i ispisuje temperaturu. :) 
Reply
#17
Ovo je baš lep praktični tutorijal.
Lepo si objasnio naradbe i logiku programa.
Face up...make your stand and realise you're living in the golden years!
Reply
#18
Hvala TDA,

Trudim se objasniti što bolje i ukazati na one sitnice za koje će netko misliti da su nebitne, a zapravo kasnije zadaju glavobolje Smile

Bit će tu jos projekata, dolazi mi grafički lcd i 3*4 tipkovnica, bit će unaprijeđenja postojećeg termometra i tako dalje :-)
Reply
#19
Super si ovo objasni, svaka ti čast.
Hvala ti puno, dosta je pomoglo. Smile

Čekam još djelove da mi dođu, u planu mi je da uradim realno vrijeme i datum (digitalni sat sa datumom), elementi su sledeći: Arduino UNO + CD4017 + I2C RTC DS1307 AT24C32, ako imaš kakav program provjeren, pa da ga razmotrim dok dijelovi ne dođu?
Reply
#20
Za tak nekaj trenutno nemam, sada malo proučavam programiranje ostalih Atmelovih MCU sa arduinom jer imam dosta projekata koji će biti u stalnoj uporabi, a moraš i sam priznati da je Arduino IDE jako jednostavan Smile i zasad sam našao načine za attiny MCU, znači da se program napiše u Arduino IDE-u i učita u neki novi mikrokontroler, koji nije nužno Atmega328P kakav se nalazi na Arduino UNO.

Ima dosta videa na youtubeu, sad pokušavam sabrat sve to jer vidim da se Arduino može upotrijebiti kao ISP za ostale čipove, samo treba dodati core fajlove u IDE direktorij i to je to. Sutra ujutro ili tijekom četvrtka bi trebao postati materjal.

Ako neki članovi imaju neke savjete oko toga slobodno neka podjele s nama Smile

Ja sam mislio koristiti Arduino nano (čekam da stigne) kao Arduino ISP, znači on bi bio samo kao programator za ostale Atmel MCU, poput ostalih vrsta atmega i attiny MCU, i ostalih ako se nađu odgovarajući core fajlovi.
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)