Archive for Arduino

Merkurino 01 – Arduino nano pro roboty

Řešili jste někdy, jak jednoduše ovládat nějaký stroj s motory a několika senzory? Abyste se zároven nemuseli moc zabývat kabeláží a kam a jak namontovat různé moduly? Podívejte se na projekt Merkurino:

Základem je standardní procesor AVR Mega328 s programováním v prostředí Arduino, standardní modul Arduino Nano r3. To má 8 analogových vstupů a 14 digitálních výstupů, a samozřejmě se všechny dají přenastavit jak vstupní, tak výstupní.

Základní sestava obsahuje:

  • Arduino Nano rev.3
  • LCD 16×2,
  • 6x HW PWM výstup
  • samostatný 3x H-můstek 500mA, 9V
  • 6x analogové tlačítko pro ovládání na pinu A0
  • 3x dvojité analogové tlačítko piny A5-A7
  • 4x plné vstupy A1-A4, třípin
  • napájení: 5V z Arduino Nano nebo lépe externí 7-15V DC (7805)

 

Pohled ze strany displeje:
DSCN0028

Pohled ze strany arduina a konektorů, zde je zapojen na I²C modul reálného času:
DSCN0030

Schema zapojení v1.3:
merkurino_01-v1.3-f

Schema zapojení v1.4.4:

merkurino01_sch_v1-4-4

Rozměry desky:
merkurino_01-v1.3-f-dokumentace – rozmery

Rozmístění konektorů v.1.3.f:

Merkurino 01 – rozmístění konektorů

Rozmístění konektorů v.1.4.4:

merkurino01_con_v1-4-4

Dokumentace ke stažení : merkurino-01-datasheet.pdf

Merkurino 01 – displej LCD a klávesnice

Jak použít LCD displej 16×2 na Merkurinu – Arduinu Nano.

Jediná změna oproti standardnímu použití u Arduina jsou použité piny.

Kód je zde:

/**********************************************************************
Tento program otestuje Merkurino 01 s displejem a klávesnicí
MerkurRobot.cz 2014
**********************************************************************/
//Jednoduché použití LiquidCrystal knihovny
#include <LiquidCrystal.h> 
// použité piny pro Merkurino 01 LCD panel
LiquidCrystal lcd(13, 12, 8, 7, 4, 2);
// definice proměnných 
int lcd_key = 0;
int adc_key_in = 0;
#define btnRIGHT 0
#define btnUP 1
#define btnDOWN 2
#define btnLEFT 3
#define btnENTER 4
#define btnESC 5
#define btnNONE 6

int read_LCD_buttons() // procedura čtení tlačítek  --------------------------
{
  adc_key_in = analogRead(0); // čtení "napětí" na vstupu A0
  //lcd.setCursor(12,1);lcd.print(adc_key_in); lcd.print("   ");
  if (adc_key_in > 1000) return btnNONE; // žádné tlačítko není stisknuto
  // pro Merkurino 01 plati tyto hodnoty:
  if (adc_key_in < 40) return btnESC; 
  if (adc_key_in < 110) return btnLEFT;
  if (adc_key_in < 300) return btnDOWN;
  if (adc_key_in < 450) return btnUP;
  if (adc_key_in < 700) return btnRIGHT;
  if (adc_key_in < 850) return btnENTER;
  
  return btnNONE; // žádné tlačítko není stisknuto// konec procedura čtení tlačítek  --------------------------
void setup()  //--- procedura setup --------------------------
{
  lcd.begin(16, 2); // start the library
  lcd.setCursor(0,0);
  lcd.print("Stiskni tlacitko"); // print a simple message
}  //--- konec procedura setup --------------------------
void loop() //--- začátek nekonečné smyčky --------------------------
{
  lcd.setCursor(8,1); // přemístí kursor na 2. řádek (1) a 9. pozici
  lcd.print(millis()/1000); // zobrazí vteřiny od zapnutí 
  lcd.setCursor(0,1); // přemístí kursor na začátek 2. řádku
  lcd_key = read_LCD_buttons(); // zavolej čtení tlačítka
  switch (lcd_key) // vyvolej akci podle stisknutého tlačítka
  {
    case btnRIGHT:
    {
      lcd.print("vpravo  ");
      break;
    }
    case btnLEFT:
    {
      lcd.print("vlevo   ");
      break;
    }
    case btnUP:
    {
      lcd.print("nahoru     ");
      break;
    }
    case btnDOWN:
    {
      lcd.print("dolu   ");
      break;
    }
    case btnENTER:
    {
      lcd.print("potvrd ");
      break;
    }
    case btnESC:
    {
      lcd.print("zpet    ");
      break;
    }
    case btnNONE:
    {
      lcd.print("nic   ");
      break;
    }
  }
} //--- konec nekonečné smyčky --------------------------

Udělej si (3) – skutečné hodiny RTC

Tak to vám jednou se probudím, a ono tma. Že bych si nastavil budík? To raději jako správný kutil si ho musím udělat. Opravdový kutil začne přesýpačkami, ale nenašel jsem správné skleničky, tak mi zbylo zas jen Arduino.

Co budete potřebovat:

  • 1x Arduino (Uno, Duemilanova, Due, Leonardo)
  • 1x nepájivé pole
  • dráty jako propojovací vodiče
  • 1x integrovaný obvod DS1307
  • 1x krystal 32,768 kHz
  • 2x rezistor 2k2
  • 1x baterii 3 až 3,6V

Součástky a  materiál koupíte např. zde: Stavebnice.com/eshop

Jak zapojit:

RTC - i2c - DS1307

Jak vidíte, zapojení je velmi jednoduché.
Rezistory (= odpory) mohou být 1k5 – 10k.
Zde zobrazená baterie může být nahrazena jakoukoliv nenabíjecí, jen si ohlídejte napětí a polaritu.
Komunikace mezi Arduinem a DS1307 je přes AnalogIn piny A4 a A5.

Pro spuštění ještě musíte nahrát knihovnu RTC s DS1307 a „Sketch -> Import Library“

Knihovnu stáhněte zde: RTClib-ds1307

a rozbalte do adresáře ..arduino-0018libraries

Vyzkoušeno ve verzi 0018, 0022 a 1.0

Ukázka programu 4.1 – hodiny reálného času RTC:

// Funkce data a času DS1307 RTC zapojenému přes I2C a knihovnu Wire
#include <Wire.h>
#include "RTClib.h"

RTC_DS1307 RTC;

void setup () {

 Serial.begin(57600);
 Wire.begin();
 RTC.begin();

 if (! RTC.isrunning()) {
 Serial.println("RTC is NOT running!");
 // následující řádka nastaví RTC datum a čas po zkompilování podle počítače
 RTC.adjust(DateTime(__DATE__, __TIME__ ));
 }
}

void loop () {
 DateTime now = RTC.now();

 // příkaz Serial.print() pošle data přes USB do počítače,
 // kde je zobrazíme v terminálu - Ctrl+Shift+M.

 Serial.print(now.year(), DEC);
 Serial.print('/');
 Serial.print(now.month(), DEC);
 Serial.print('/');
 Serial.print(now.day(), DEC);
 Serial.print(' ');
 Serial.print(now.hour(), DEC);
 Serial.print(':');
 Serial.print(now.minute(), DEC);
 Serial.print(':');
 Serial.print(now.second(), DEC);
 Serial.println();

 Serial.print(" since midnight 1/1/1970 = ");
 Serial.print(now.unixtime());
 Serial.print("s = ");
 Serial.print(now.unixtime() / 86400);
 Serial.println("d");

 // chceme-li přičíst ke stávajícímu datu a času 7 dní a 30 sekund
 DateTime future (now.unixtime() + 7 * 86400L + 30);

 Serial.print(" now + 7d + 30s: ");
 Serial.print(future.year(), DEC);
 Serial.print('/');
 Serial.print(future.month(), DEC);
 Serial.print('/');
 Serial.print(future.day(), DEC);
 Serial.print(' ');
 Serial.print(future.hour(), DEC);
 Serial.print(':');
 Serial.print(future.minute(), DEC);
 Serial.print(':');
 Serial.print(future.second(), DEC);
 Serial.println();

 Serial.println();
 delay(1000);

} //------ konec ------------

Příště si povíme, jak připojit LCD display a hodiny budou svítit do tmy 🙂

Udělej si (2) – posuvný registr

Kurz pro začátečníky – Jak zvětšit počet výstupů arduina pomocí posuvných registrů, angl. Shift Register

Co budete potřebovat:

1x Arduino (Uno, Duemilanova, Due, Leonardo)
1x integrovaný obvod 74HC595N
8x Led dioda (na barvě nezáleží)
8x rezistor 220 až 330 Ohm
1x nepájivé pole
dráty jako propojovací vodiče

Součástky a  materiál koupíte např. zde: Stavebnice.com/eshop

Jak zapojit:


Posuvný registr 74hc595



Na obrázku jsou zobrazena dvě nepájivá pole z důvodu přehlednosti. Zapojení lze samozřejmě zrealizovat na jednom.

LED diody mají obvykle jednu nožičku delší – ta se připojuje na plus. Nebo v tomto zapojení k odporu.

Ukázka programu 2.1 – světélka se hýbou:

//Pin zapojen do ST_CP of 74HC595
int latchPin = 8;
//Pin zapojen do SH_CP of 74HC595
int clockPin = 12;
//Pin zapojen do DS of 74HC595
int dataPin = 11;

void setup() {
 //nastaveni pinu jako vystupnich pro ovladani posuvneho registru
 pinMode(latchPin, OUTPUT);
 pinMode(clockPin, OUTPUT);
 pinMode(dataPin, OUTPUT);
}

void loop() {
 // pocita od 0 do 255 a zobrazi cislo na LEDky
 // 255 v dekadicky se zobrazi binarne 0b11111111
 for (int numberToDisplay = 0; numberToDisplay < 0b11111111; numberToDisplay++) {
 // nastav latchPin na LOW
 digitalWrite(latchPin, LOW);
 // a zacni posilat data po osmi bitech (protoze pouzivame 8 vystupu):
 shiftOut(dataPin, clockPin, MSBFIRST, numberToDisplay);  

 //kdyz zmenime latchPin z LOW do HIGH, tak se nam zobrazi data na vystupech:
 digitalWrite(latchPin, HIGH);
 // pauza pro cteni dalsich dat:
 delay(150);
 //digitalWrite(latchPin, LOW);
 //shiftOut(dataPin, clockPin, MSBFIRST, 0b01011011);
 //digitalWrite(latchPin, HIGH);
 //delay(550);
 }
}

Ukázka programu 2.2 – jak posílat data jednotlivě:

//Pin connected to ST_CP of 74HC595
int latchPin = 8;
//Pin connected to SH_CP of 74HC595
int clockPin = 12;
////Pin connected to DS of 74HC595
int dataPin = 11;

void setup() {
 //set pins to output so you can control the shift register
 pinMode(latchPin, OUTPUT);
 pinMode(clockPin, OUTPUT);
 pinMode(dataPin, OUTPUT);
}

void loop() {
 digitalWrite(latchPin, LOW);
 shiftOut(dataPin, clockPin, MSBFIRST, 0b00000000);
 digitalWrite(latchPin, HIGH);
 delay(150);
 digitalWrite(latchPin, LOW);
 shiftOut(dataPin, clockPin, MSBFIRST, 0b00011000);
 digitalWrite(latchPin, HIGH);
 delay(150);
 digitalWrite(latchPin, LOW);
 shiftOut(dataPin, clockPin, MSBFIRST, 0b00111100);
 digitalWrite(latchPin, HIGH);
 delay(150);
 digitalWrite(latchPin, LOW);
 shiftOut(dataPin, clockPin, MSBFIRST, 0b01111110);
 digitalWrite(latchPin, HIGH);
 delay(150);
 digitalWrite(latchPin, LOW);
 shiftOut(dataPin, clockPin, MSBFIRST, 0b11111111);
 digitalWrite(latchPin, HIGH);
 delay(150);
 }

Příště si povíme, jak rozšířit počet výstupů násobným připojením dalších posuvných registrů.


Udělej si (1) – doplnění o použití 6xPWM

Arduino umožňuje použít přímo až 6 PWM výstupů.

Příklad programu:

// program pro ovladani 6x PWM
// napr. 3x H-mustek
// plati pro Arduino s ATmega168 a ATmega328, to jsou běžná Arduina
// vystup pouze na piny 3, 5, 6, 9, 10 a 11
// potenciometr 5 až 50kOhm na analogovém vstupu 0 

int Ledpin11=11; //definice vystupnich pinu
int Ledpin10=10;
int Ledpin9=9;
int Ledpin6=6;
int Ledpin5=5;
int Ledpin3=3;

int analogpin=0;  // definice vstupu
int value=0;      // hodnota potenciometru
int x;

void setup()
 {
 Serial.begin(9600);
 pinMode(Ledpin11, OUTPUT);
 pinMode(Ledpin10, OUTPUT);
 pinMode(Ledpin9, OUTPUT);
 pinMode(Ledpin6, OUTPUT);
 pinMode(Ledpin5, OUTPUT);
 pinMode(Ledpin3, OUTPUT);
 }

void loop()
 {
 value=analogRead(analogpin);
 x=map(value,0,1023,0,255);
 analogWrite(Ledpin11,x);
 analogWrite(Ledpin10,255-x);
 analogWrite(Ledpin9,x);
 analogWrite(Ledpin6,255-x);
 analogWrite(Ledpin5,x);
 analogWrite(Ledpin3,255-x);
 Serial.println(x);
 delay(100);
 }

Udělej si (1) – Arduino – jak ovládat „napětí“

Kurz pro začátečníky – Jak ovládat napětí pomocí mikroprocesoru a potenciometru

Co budete potřebovat:

1x Arduino (Uno, Duemilanova, Due, Leonardo)
1x Led dioda (na barvě nezáleží)
1x rezistor 330 Ohm
1x potenciometr 5 kOhm
1x nepájivé pole
1x dráty jako propojovací vodiče

Součástky a  materiál koupíte např. zde: Stavebnice.com/eshop

Jak to bude vypadat pečlivě zapojené:


PWM - potenciometr a Ledka


Poznámka:

dejte pozor na zapojení, aby se v případě zkratu nepoškodil usb port na počítači.

Výpis programu:

int Ledpin=9;                  //vystup na LED
 int analogpin=0;              //vstup potenciometru
 int value=0;                  //promenna pro hodnotu potenciometru
 int x;                        //prevedena hodnota z 0..1023 na 0..255
void setup()
 {
 Serial.begin(9600);           //inicializace terminalu
 pinMode(Ledpin, OUTPUT);      //nastaveni digitalniho vystupu
 }
void loop()                    //hlavni smycka
 {
 value=analogRead(analogpin);  //precist potenciometr
 x=map(value,0,1023,0,255);    //prevod hodnot z potenciometru na PWM rozsah
 analogWrite(Ledpin,x);        //vystup PWM
 Serial.println(x);            //vystup na terminal
 delay(100);                   //pauza
 }

Jak to vlastně funguje:

Celé ovládání „napětí“ je založeno na takzvaném principu PWM – pulzně-šířkové modulaci.

Když zapneme vypínačem napětí do žárovky (motoru, ledky, odporu), dodáváme tím 100% elektrické energie.

Předpokládejme, že žárovka má spotřebu 10 Wattů.
Když ji rozsvítíme na 1 hodinu, má spotřebu 10 Wh (10 watt-hodin = 10 Wattů za hodinu).
Když ji rozsvítíme na půl hodiny a půl hodiny bude zhasnutá, bude mít celkovou spotřebu 5 Wh.
Když toto rozsvěcení a zhasínání budeme dělat hodně rychle, alespoň 50x za vteřinu, bude se zdát, že žárovka svítí zhruba polovičním svitem.

A toto je celé tajemství „napěťové“ regulace v digitálním světě 🙂

Pro názornost a konkrétní aplikaci pro arduino je tento obrázek:



PWM plnění



Příští týden si vyzkoušíme pasivní regulaci otáček stejnosměrného motoru pomocí tranzistoru a h-můstku.

Enkoder – světelná závora a reflex

Jak zjistit přesný počet otáček a pootočení?
No přece pomocí enkoderu.


Světelná závora


Je to docela prosté zařízení:
na hřídelku připevníme kolečko se soustřednými otvory. Těmi svítíme na fototranzistor. Když se kolečko bude otáčet, fototranzistor bude spínat a rozepínat obvod a my ho budeme vyhodnocovat. Můžeme samosebou použít i mechanický přerušovač, záleží na použití.

Možnost připojení přes tvarovač: http://merkurrobot.cz/?p=1350

Model postavený z merkuru a světelné infračervené závory:


Enkoder - sestava


Pokud chceme zjistit, jestli se hřídel nebo kolo otáčí, musíme použít enkodery 2.
Enkoderová kola připevníme „skoro“ stejně, jen budou malinko oproti sobě pootočena, aby dávala posunuté signály pro vyhodnocení podle následující tabulky:


Enkoder - vyhodnocení směru


Pokud si takový pokus chcete vyzkoušet třeba s arduinem, můžete pak použít tento program na sestavě arduino+LCD display.
Program není zrovna nejrychlejší, proto je vhodný jen pro pomalé otáčení.
Vysokorychlostní enkodery popíšeme zase příště.

//---------PROGRAM PRO OBSLUHU 2 ENKODERU------------------------------------
#include <LiquidCrystal.h>
#include <LCDKeypad.h>

int sensorValue0 = 0;  // promenna pro cteni analog. tlacitek
int sensorValue1 = 0;  // variable to store the value coming from the sensor
int sensorValue2 = 0;  // vstup enkoderu 2
int sensorValue3 = 0;  // vstup enkoderu 3
int sensorValue4 = 0;  // variable to store the value coming from the sensor
int sensorValue5 = 0;  // variable to store the value coming from the sensor
int enkoder2 = 0;  // 0=sviti, 1=nesviti
int enkoder3 = 0;  // 0=sviti, 1=nesviti
int stav = 0; // enc2 enc3 stav
              //  0    0    1
              //  0    1    2
              //  1    0    3 
              //  1    1    4
int stav_old = 0; // minuly stav: 1..4, 0=pocatecni inicializace
int smer = 0; // stav 1->3 = vpred
              // stav 3->1 = vzad
int pozice = 0;  //kde se zrovna vozik nachazi            

LCDKeypad lcd;

void setup()    //------------------------------------------------------
{
 // int i,k;

  
  lcd.clear();lcd.begin(16, 2);
  lcd.print("cti analogove");
  lcd.setCursor(0,1);
  lcd.print("   vstupy");
  delay(1000);
  lcd.setCursor(0, 0);
  lcd.print("0:   1:   c:");
  lcd.setCursor(0, 1);
  lcd.print("2:   3:   4:   ");
  
}

void loop() {   // ------------------------------------------
                // ------ hlavni smycka ---------------------
                // ------------------------------------------
       cti_vstupy();
       vpred_vzad();
//    zobraz_vstupy();
    zobraz_pozici();

}  // ------ konec hlavni smycka ---------------------
   // ------------------------------------------------

void cti_vstupy()   //------------------------------------------------------
{
  sensorValue0 = analogRead(0);    // read the value from the sensorPin 0..5
  sensorValue1 = analogRead(1);    // read the value from the sensorPin 0..5
  sensorValue2 = analogRead(2);    // read the value from the sensorPin 0..5
    if (sensorValue2 > 500) {enkoder2=0;} else {enkoder2=1;}
  sensorValue3 = analogRead(3);    // read the value from the sensorPin 0..5
    if (sensorValue3 > 500) {enkoder3=0;} else {enkoder3=1;}
      
}  // --- konec cti_vstupy --------------------------
void zobraz_vstupy()   //------------------------------------------------------
{
  lcd.setCursor(2, 1);  // enkoder 2
     if (enkoder2==0) {lcd.print("o");} else {lcd.print(" ");}
  lcd.setCursor(3, 1);  // enkoder 3
     if (enkoder3==0) {lcd.print("o");} else {lcd.print(" ");}
  lcd.print(" ");
}

void zobraz_pozici()   //------------------------------------------------------
{
  lcd.setCursor(12, 0);
  lcd.print(pozice);lcd.print(" ");
  lcd.setCursor(14, 1);
  lcd.print(stav);
}

void vpred_vzad()   //------------------------------------------------------
{
  // enc2 enc3 stav
  //  0    0    1
  //  0    1    2
  //  1    0    3 
  //  1    1    4
  // smer -  stav 1->3 = vzad
  //         stav 3->1 = vpred
  // pozice - kde se zrovna vozik nachazi  
     if ( enkoder2 == 0 && enkoder3 == 0 ) stav = 1; // 1
     if ( enkoder2 == 0 && enkoder3 == 1 ) stav = 2; // 2
     if ( enkoder2 == 1 && enkoder3 == 0 ) stav = 3; // 3
     if ( enkoder2 == 1 && enkoder3 == 1 ) stav = 4; // 4
     
     if (stav_old != stav )
     {   
            if (stav_old == 1 && stav == 3) {++pozice;lcd.setCursor(13, 1);lcd.print("+"); lcd.print(stav_old); }
            if (stav_old == 3 && stav == 1) {--pozice;lcd.setCursor(13, 1);lcd.print("-"); lcd.print(stav_old); }
     }
     //else {}
     
     stav_old = stav;

}  // --- konec vpred_vzad ----------------------------

Schema zapojení:


Schéma optozávory


Varianta A:

optozávora U má vyvedeny vývody IR LED a fototranzistoru pouze na piny.
Úpravu signálu a připojení na napájení je nutné udělat externě, aby mohl být zpracováván procesorem.

Varianta B:

optozávora je zapojena způsobem „společný emitor“. Výstup možno zapojit třípinově rovnou do MCU.

Varianta C:

optozávora je zapojena způsobem „společný kolektor“. Výstup možno zapojit třípinově rovnou do MCU. Rozdíl oproti variantě B je, že lze pomocí odporu R6 nastavit výstup přesněji.

Možnost připojení přes tvarovač: http://merkurrobot.cz/?p=1350

Variantu A a B je možno zakoupit např. zde – Stavebnice.com a Snailinstrument.cz

Arduino – dnešní světový hit

23.8.2012

Po delší době přemýšlení konečně nazrál čas pro připojení Arduina do Merkuru.

Začnu základními komponentami, které jsem použil:

1. Arduino s procesorem AVR ATmega328 (a „tiskárnový“ kabel USB)

2. LCD keypad – dvouřádkový LCD displej s podsvícením a analogovými tlačítky.

Arduino Duemilanove klon

Arduino LCD Keypad Shield

.

.

.

.

.

.

.

.

.
Vlevo tedy vidíte základní desku s procesorem a přípojnými konektory.

Vpravo takzvaný Shield, který se nasune do přípojných konektorů, tudíž nepotřebujete žádné kablíky a jiné vodiče na propojení.

Po spojení obou desek vypadá základní sestava takto:

Arduino s LCD_keyb shield

Arduino + LCD_keyb + kabel usb

.

.

.

.

.

.

.

Proč jsem použil displej?

Jako všichni jsem začal s ledkama a nepájivé kontaktní pole, ale u mobilního stroje (vibrace) nebo přenášení jsem měl problémy s tím, že rezistory (odpory) v něm moc dobře nedrží a jsou trochu nespolehlivé. Displej zabere 6 digitálních výstupů.

Navíc je na desce i 5 tlačítek zapojených šikovně tak, že zaberou jen jeden analogový vstup.

Desku Arduino koupíte např. zde: www.stavebnice.com/eshop/product_info.php?products_id=354

Desku LCD Keypad Shield např. zde: www.stavebnice.com/eshop/product_info.php?products_id=509