Archive for Řídící jednotky

Merkurino a infračervené dálkové ovládání – 1. díl

Merkurino, IR přijímač, IR vysílač

Jak přijímat signál z dálkového infračerveného ovladače?
Pořiďte si sadu se senzorem a malým dálkovým ovladačem.

Potřebné díly:

  • Merkurino 01 s USB kabelem
  • přijímací modul (snímač) např. s TSOP31238 nebo s HX1838
  • kompatibilní dálkový ovladač
  • 3 kablíky(vodiče) s dutinkami na obou koncích F-F

Merkurino propojíme s infračerveným snímačem pomocí kablíků a dáme si pozor na správné zapojení.

Pro funkci potřebujeme pouze 1 datový pin a 2 napájecí.
Datový pin zapojíme na D3 a napájecí Vcc na libovolných +5V a Gnd na zem(gnd).

Dálkový ovladač může být libovolný, ale kompatibilní se snímačem. Laicky řečeno jsou obvyklé 2 frekvence: 36 a 38kHz. Je to sice „skoro“ stejné, ale přijímač si vybere jen tu svoji. Další krok je dekodování – někteří výrobci si utvořili svůj způsob kodování a použitá knihovna některé umí dešifrovat. Pusťte si monitor a vyzkoušejte různé ovladače, které máte k dispozici nebo najdete po okolí. Pokud se vám po opakovaném stisknutí tlačítka objeví stejný řetězec (hex číslo), máte vyhráno – můžete ho použít.

Příště si povíme o praktickém použití.

Pro funkci programu potřebujeme nahrát/nainstalovat knihovnu IRremote.h

Kódy tlačítek jsou vypisovány přes USB port do terminálu Arduina: Ctrl+Shift+m

Příklad programu:

/*	
 Knihovnu získáte zde: https://github.com/shirriff/Arduino-IRremote
 Rozbalte (Unzip) adresář do  Libraries. Adresář přejmenujte na  IRremote
*/
#include <IRremote.h>
int input_pin = 3; //set D3 as input signal pin
IRrecv irrecv(input_pin);
decode_results signals;
void setup()
{
	Serial.begin(9600);
	irrecv.enableIRIn(); // enable input from IR receiver
}
void loop() {
if (irrecv.decode(&signals)) {
		Serial.println(signals.value, HEX);
		irrecv.resume(); // get the next signal
	}
}

Merkurino a ultrazvukový dálkoměr HC-SC04

Jak měřit vzdálenost 3,5cm až 3,5metru?
Jednoduché a poměrně přesné a spolehlivé řešení je s ultrazvukovým dálkoměrem HC-SC04.

Potřebné díly:

    • Merkurino 01 s USB kabelem
    • ultrazvukový dálkoměr HC-SC04
    • kablíky(vodiče) s dutinkami na obou koncích F-F

Merkurino propojíme s modulem HC-SC04 pomocí kablíků a dáme si pozor na správné zapojení.

Pro funkci potřebujeme pouze 2 datové piny a 2 napájecí.
Echopin zapojíme na D9, Trigpin na D10 a napájecí Vcc na libovolných +5V a Gnd na zem(gnd).

Vzdálenost je vypisována přes USB port do terminalu Arduina: Ctrl+Shift+m

Mimo měřící rozsah je vypisována 0.

Příklad programu:

#define ECHOPIN 9        // Echo pin z HC-SC04 na pin 9
#define TRIGPIN 10        // Trig pin z HC-SC04 na pin 10

void setup()
{
//Nastaví sériovou komunikaci
Serial.begin(9600);
//Nastaví pin 2 jako vstupní
pinMode(ECHOPIN, INPUT);
//Nastaví pin 3 jako výstupní
pinMode(TRIGPIN, OUTPUT); 
}

void loop()
{
 // Vyšle impuls do modulu HC-SR04
  digitalWrite(TRIGPIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIGPIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIGPIN, LOW);
  
  // Spočítá vzdálenost
  float distance = pulseIn(ECHOPIN, HIGH);
  distance = distance*0.017315f;
  
  // odešle informace na sérivý port
  Serial.print(distance);
  Serial.print("cm\n");
  
  //počká 1 sekundu
  delay(1000);  
}

 

Merkurino 01 – připojení motorů s PWM

Pokud chceme připojit k merkurinu přímo jeden až tři motory, použijeme obvykle toto zapojení:

merkurino-01-připojení motoru

Doporučené napětí je 9V dc.

Na Merkurinu jsou vyvedeny všechny PWM výstupy nahoře na dvouřadém konektoru (out-pwm).

Výstupy označené 3 5 6 9 10 11 odpovídají na arduinu D3, D5, D6, D9, D10 a D11.
Horní řada jsou země (gnd).
Neosazené 2 otvory jsou připraveny pro ty, kteří potřebují dalších +5V.

Abychom mohli připojit motory k procesoru, musíme použít zesilovač proudu, takzvané H-můstky. Na obrázku jsou vpravo.

Poznámka: H-můstky jsou oddělené od ostatních součástek, společná je pouze zem (gnd).

Vstupy s TTL logikou jsou přes nezámkový jednořadý konektor.
Výstupy jsou zámkové „bílé“ konektory, zapojené signál-zem-signál.
Předtím, než motory připojíte, můžete sledovat výstupní signál (napětí) přes dvojici antiparalelních LED.

Pokud potřebujete otočit směr motoru a nechcete zasahovat do kódu programu, nemusíte přepojovat motor, ale stačí přehodit (otočit) vstupy.

Pro napájení můstků můžete použít jeden ze dvou způsobů:

  1. hlavní vstupní napětí zleva, konektor A1 powerjack.
    V tom případě spojíte spojkou (zde červený jumper vpravo)
  2. externí napětí od 3V do 9V na konektoru PwrBridge vpravo nahoře.
    V tom případě MUSÍTE rozpojit červený jumper – napájecí napětí by se „pohádala“ a deska by „shořela“.

UPOZORNĚNÍ: Nezapomínejte na maximální výkonovou ztrátu h-můstků (to je maximální odebíraný proud motorů). Doporučené je použití PWM od 30%, pak zvyšujete výkon a prstem můžete otestovat, jestli se můstky (pod LCD displejem vlevo) nadměrně nezahřívají.

Zkouška teploty: připojím motor a postupně navyšuji výkon

analogWrite(3, fadeValue); 
//3 = výstup D3; fadeValue = výstupní PWM "výkon" , hodnota plnění je 0 až 255

pokud prst udržím = ok,
pokud se zahřeje během 5 sekund tak, že neudržím prst = něco je špatně.

Testovací program je zde:

//Sample using LiquidCrystal library
#include <LiquidCrystal.h> 
/*******************************************************
 upravil Ladislav Vohralik 2015, MerkurRobot.cz
********************************************************/
// select the pins used on the LCD panel
LiquidCrystal lcd(13, 12, 8, 7, 4, 2);
// define some values used by the panel and buttons
int lcd_key = 0;
int adc_key_in = 0;
int motor_sel =0;
int motor1_speed = 0;
int motor2_speed = 0;
int motor3_speed = 0;
int motor1a_out = 3;    // motor 1a connected to PWM digital pin 3
int motor1b_out = 5;    // motor 1a connected to PWM digital pin 5
int motor2a_out = 6;    // motor 1a connected to PWM digital pin 6
int motor2b_out = 9;    // motor 1a connected to PWM digital pin 9
int motor3a_out = 10;    // motor 1a connected to PWM digital pin 10
int motor3b_out = 11;    // motor 1a connected to PWM digital pin 11
int x =0; // pomocná 
int y =0; // pomocná 
int fadeValue = 0;

#define btnRIGHT 0
#define btnUP 1
#define btnDOWN 2
#define btnLEFT 3
#define btnSELECT 4
#define btnESC 5
#define btnNONE 6
// read the buttons
int read_LCD_buttons()
{
adc_key_in = analogRead(0); // read the value from the sensor
// my buttons when read are centered at these valies: 0, 144, 329, 504, 741
// we add approx 50 to those values and check to see if we are close
if (adc_key_in > 1000) return btnNONE; // 
if (adc_key_in < 12) return btnESC; 
if (adc_key_in < 25) return btnLEFT;
if (adc_key_in < 111) return btnDOWN;
if (adc_key_in < 222) return btnUP;
if (adc_key_in < 555) return btnRIGHT;
if (adc_key_in < 850) return btnSELECT;

return btnNONE; // when all others fail, return this...
}
void setup()
{
  lcd.begin(16, 2); // start the library
  lcd.setCursor(0,0);
  lcd.print("motor/speed"); // print a simple message
  // set motor: up/down
  // motor: 1..3
  // motor=4 all=stop Low
  // motor=0 lock setting
  // set speed: left/right 
  // speed: -99..0..99%

}
void loop()
{
   // test output ----------------- 
  for(fadeValue = -255 ; fadeValue <= 255; fadeValue +=25) { 
    // sets the value (range from 0 to 255):
    if  (fadeValue >= 0) {
       analogWrite(3, fadeValue);
       analogWrite(5, 0);
    }
    x = abs(fadeValue);
    x = x * 1;
    if  (fadeValue < 0) {
       analogWrite(3, 0);
       analogWrite(5, x);
    }
    vypis_na_lcd();
    // wait for 550 milliseconds to see the dimming effect    
    delay(550);                            
  } 
  for(int fadeValue = 255 ; fadeValue > -255; fadeValue -=25) { 
    // sets the value (range from 0 to 255):
    if  (fadeValue >= 0) {
       analogWrite(3, fadeValue);
       analogWrite(5, 0);
    }
    x = abs(fadeValue);
    x = x * 1;
    if  (fadeValue < 0) {
       analogWrite(3, 0);
       analogWrite(5, x);
    }
    
    // wait for 550 milliseconds to see the dimming effect    
    delay(550);                            
  } 
  
     // konec test output ----------------- 

  lcd.setCursor(0,1); // move to the begining of the second line
  lcd_key = read_LCD_buttons(); // read the buttons
  switch (lcd_key) // depending on which button was pushed, we perform an action
    {
    case btnRIGHT:
      {
      //set speed up
      if ((motor_sel == 1) and (motor1_speed < 99)) { 
        motor1_speed = motor1_speed + 11;
        lcd.setCursor(3,1);
        //lcd.print("");
        lcd.print(motor1_speed);
        lcd.print(" ");
        x = abs(motor1_speed);
        if (motor1_speed > 0) {
          analogWrite(motor1a_out, x); 
          analogWrite(motor1b_out, 0);         
        }
        if (motor1_speed <= 0) {
          analogWrite(motor1a_out, 0); 
          analogWrite(motor1b_out, x);  
        }
      }
      delay(100);
      break;
      }
    case btnLEFT:
      {
      //set speed down
      if ((motor_sel == 1) and (motor1_speed > -99)) { 
        motor1_speed = motor1_speed - 11;
        lcd.setCursor(3,1);
        //lcd.print("");
        lcd.print(motor1_speed);
        lcd.print(" ");
      }
      delay(100);
      break;
      }
    case btnUP:
      {
      //select motor
      if (motor_sel < 3) { 
        motor_sel = motor_sel+1;
        lcd.setCursor(1,1);
        //lcd.print(" m");
        lcd.print(motor_sel);
      }
      delay(300);
      break;
      }
    case btnDOWN:
      {
      //select motor
      if (motor_sel > 1) { 
        motor_sel = motor_sel-1;
        lcd.setCursor(1,1);
        //lcd.print("");
        lcd.print(motor_sel);
      }
      delay(300);
      break;
      }
    case btnSELECT:
      {
      lcd.print("SELECT ");
      break;
      }
    case btnESC:
      {
      lcd.print("ESC    ");
      break;
      }
    case btnNONE:
      {
      lcd.setCursor(0,1);
      lcd.print("M");
      break;
      }
    }
    
    lcd.setCursor(8,0);
    //lcd.print(motor_sel);
    //lcd.print(" ");
    lcd.print("m");
    lcd.print(motor1_speed);
    lcd.print("x");
    lcd.print(x);
      
}  // konec loop ------------

int test_output(int x,int y){   //  funkce test_output ------------
  int led_1 = x;
  int led_2 = y; 
  // fade in from min to max in increments of 5 points:
  for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) { 
    // sets the value (range from 0 to 255):
    analogWrite(led_1, fadeValue);         
    // wait for 30 milliseconds to see the dimming effect    
    delay(30);                            
  } 
  // fade out from max to min in increments of 5 points:
  for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) { 
    // sets the value (range from 0 to 255):
    analogWrite(led_1, fadeValue);         
    // wait for 30 milliseconds to see the dimming effect    
    delay(30);                            
  } 
  int result = led_1;
  return result;
}  // konec funkce test_output ------------

int vypis_na_lcd(){
    lcd.setCursor(0,0);
    lcd.print(" x ");
    lcd.print(x);
    lcd.print(" y ");
    lcd.print(fadeValue);
    lcd.print(" ");
    
}

 

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 🙂

Tvarovač signálu

Jak připojit optozávoru (optokopler, optickou závoru, reflexní čidlo, …) k procesoru?

Pokud máme jednoduchou dvojici LED – fototranzistor, můžete použít toto jednoduché zapojení.
Není to přímo Schmittův klopný obvod s hysterezí, ale velmi dobře ošetří vstupy MCU.

Optické závory jsem popisoval zde: http://merkurrobot.cz/?p=1280

Jako bonus je na této desce ještě ošetření „dorazů“ motoru.
Funkce je následující – na konci (dorazu) pohybu motoru se umístí přepínač, který se rozepne a motor se zastaví. Když potřebujeme opačný pohyb, proud teče přes připojenou diodu.

Schema:



Schéma sledovače s korekcí signálu


Osazená deska:


Tvarovač 5

Tvarovač 5 - pohled ze zdola


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