Archive for Arduino

Merkurino a akcelerometr 6050 i2c

Někdy vás možná napadlo, že by bylo užitečné vědět reálný náklon vozítka nebo ovladače.

K tomu se hodí integrovaný akcelerometr s gyroskopem a jako bonus navíc je digitální teploměr.

Data získáte pouze dvěma datovými vodiči plus napájení zem a 3-5V.
Vcc – in4(+5V)
GND – in4(gnd)
SCL – inA5a(data)
SDA – in4(data)

merkurino a gyroskop 6050 i2c 4w

Kód programu s výstupem na seriovou linku a LCD displej 16×2 je zde:

//upravený program: Test MPU6050 a LCD 16x2
// zdroj: http://blog.filipeflop.com/sensores/tutorial-acelerometro-mpu6050-arduino.html

//připojení knihoven
 #include<Wire.h>
 #include <LiquidCrystal.h>
// zapojení lcd
 LiquidCrystal lcd(13, 12, 8, 7, 4, 2);

//definice I2C MPU6050
 const int MPU=0x68;
 //proměnné pro akcelerometr a gyroskop
 int AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;
 void setup()
 {
   Serial.begin(115200);
   //Inicializace LCD
   lcd.begin(16, 2);
   Wire.begin();
   Wire.beginTransmission(MPU);
   Wire.write(0x6B);

  //Inicializace MPU-6050
   Wire.write(0);
   Wire.endTransmission(true);

  //Informacoes iniciais do display
   lcd.setCursor(0,0);
   lcd.print();
   lcd.setCursor(0,1);
   lcd.print();
   delay(1000);
 }
 void loop()
 {
   Wire.beginTransmission(MPU);
   Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H)
   Wire.endTransmission(false);
   //odeslání požadavku do snímače
   Wire.requestFrom(MPU,14,true);
   //čtení hodnot 
   AcX=Wire.read()<<8|Wire.read(); //0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L) 
   AcY=Wire.read()<<8|Wire.read(); //0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
   AcZ=Wire.read()<<8|Wire.read(); //0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
   Tmp=Wire.read()<<8|Wire.read(); //0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
   GyX=Wire.read()<<8|Wire.read(); //0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
   GyY=Wire.read()<<8|Wire.read(); //0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
   GyZ=Wire.read()<<8|Wire.read(); //0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)

  //zápis hodnoty X z acelerometru na serial a LCD
   Serial.print(); Serial.print(AcX);
   lcd.setCursor(0,0);
   //lcd.print("X=");
   lcd.print(AcX/10);
   lcd.print();

  //zápis hodnoty Y z acelerometru na serial a LCD
   Serial.print(); Serial.print(AcY);
   lcd.setCursor(6,0);
   //lcd.print("Y=");
   lcd.print(AcY/10);
   lcd.print();

  //zápis hodnoty Z z acelerometru na serial a LCD
   Serial.print(); Serial.print(AcZ);
   lcd.setCursor(11,0);
   //lcd.print("Z=");
   lcd.print(AcZ/10);
   lcd.print();

  //zápis teploty na serial a přepočet na Celsius
   Serial.print(); Serial.print(Tmp/340.00+36.53);

  //zápis hodnoty X z gyroskopu na serial a LCD
   Serial.print(); Serial.print(GyX);
   lcd.setCursor(0,1);
   //lcd.print("X=");
   lcd.print(GyX/10);
   lcd.print();

  //zápis hodnoty X z gyroskopu na serial a LCD 
   Serial.print(); Serial.print(GyY);
   lcd.setCursor(6,1);
   //lcd.print(" Y=");
   lcd.print(GyY/10);
   lcd.print();

  //zápis hodnoty X z gyroskopu na serial a LCD
   Serial.print(); Serial.println(GyZ);
   lcd.setCursor(10,1);
   //lcd.print("Z=");
   lcd.print(GyZ/10);
   lcd.print();

  //zápis teploty na LCD
  lcd.setCursor(14,1);
   //lcd.print(" T:");
   lcd.print(Tmp/340.00+36.53);
   lcd.print();

  //počkej 300ms
   delay(300);
 }

 

Arduino a několik SPI modulů

Jak připojit několik SPI zařízení k Arduinu, vysvětlí tento obrázek:

3x SPI

Z něj je vidět, že moduly jsou připojeny paralelně až na vstup SS, který je pro každý modul zvlášť. Tím totiž zapínáme a vypínáme komunikaci pro konkrétní modul.

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(" ");
    
}

 

Arduino a Fake FTDI – jak nainstalovat „správně“ driver

Možná jste slyšeli, že firma FTDI, jedna z nejznámějších výrobců čipů pro převodníky, se naštvala na výrobce plagiátů jejích výrobků. A pustila do světa legálně „vir“, který ničí tyto čipy. Stane se to, že přepíše uvnitř čipu paměť tak, že Windowsy neví, jaký driver mají nainstalovat a převodník je nepoužitelný.

Ale…

…není tomu tak napořád!

Takže pokud máte například Arduino s tímto čipem, který laik nemá šanci poznat a Windowsy vám ho přepsaly, stačí se řídit podle tohoto videa (krok za krokem):

Instalace:

Stručný postup:

  • stáhnete si ze stránek FTDI drivery v .zip (starší verze nevadí) – http://www.ftdichip.com/Drivers/VCP.htm část „No Longer Supported“ 32/64bit
  • rozbalíte do adresáře
  • aktualizujete ručně driver,
  • windows samy najdou nové zařízení
  • ještě jednou aktualizujete ručně, a máte hotovo 🙂

Závěr:

čip není opraven, jen je nainstalován. V jiném počítači musíte postupovat stejně.

Pozn.:

pro opravu jsem našel tuto diskusi, ale nevyzkoušel:

http://forum.gsmhosting.com/vbb/f684/ft232r-repair-official-guide-1875025/

Pozn2:

pokud by vám nefungoval výše zmíněný návod, zkuste postup (díky uživateli Ropax1) pro Windows XP:

Staci si pouze stahnout CDM ze stranky http://www.ftdichip.com/Drivers/VCP.htm. V kolonce comments je hyperlink Available as „setup executable“. To se stahne, spustí a je hotovo. (Chvíli bude počítači trvat, než si uvědomí, že je driver nainstalovaný.)

 

Merkurino 01 a krokový motor s A4988

Dnes si povíme něco o ovládání krokových motorů pomocí Arduina/Merkurina 01.

Co k tomu potřebujete:

  • Merkurino 01
  • unipolární krokový motor („ten se 4 dráty“)
  • modul pro ovládání krokových motorů – driver A4988 step+dir
  • propojovací vodiče
  • napájecí zdroj

Jak to funguje:

Určitě jste si všimli, že příklady v Arduinu obsahují návody Stepper – speed control a další.
To je určeno pro zapojení, kdy je motor zapojen přes dvojitý můstek (H-bridge) a procesor řídí taktování jednotlivých cívek přímo.

Na internetu najdete nejčastěji nabídku můstku s obvodem L298, který však přes ujišťování prodejců není vhodný pro motory typu Nema17, protože nemá zpětnou vazbu pro snímání proudu. Důsledkem je velká tepelná ztráta na chladiči a motoru a velký příkon.

Moderní zapojení využívá obvody se zpětnou vazbou, které se řídí pouze dvěmi signálními vodiči – step a dir. Dobře dostupný je obvod A4988 na malé desce s 2×8 piny vhodnými na pokusy v nepájivém poli.

Step je krok, Dir je směr. Takže stačí jen dokola posílat LOW a HIGH na vstup Step a pomocí Dir přepínat směr.

Schema zapojení:

Arduino + modul A4988

Arduino + modul A4988

Příklad zapojení:

Merkurino + a4988

Merkurino + a4988

Merkurino + a4988 1

Merkurino + a4988 1

Program, který jednou otočí tam a vrátí se do stejné pozice:

//základní zapojení Arduino/Merkurino 01 a modulu s A4988: 
//spojit dohromady reset a sleep 
//spojit VDD k Arduino 3.3v nebo 5v 
//spojit GND k Arduino GND (GND near VDD) 
//spojit 1A a 1B k stepper cívce 1 (nutno ověřit, jinak dojde ke zničení A4988)
//spojit 2A a 2B k stepper cívce 2 
//spojit VMOT k napájení ( +8 až +35V ) 
//spojit GRD k GND - zemi ( 0V ) 
 
//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 stp = 3; // 13;  // spojit pin 13 k step 
int dir = 5; // 12;  // spojit pin 12 k dir 
int a = 99;     //  čítač kroků 
int pauza = 10;   // pauza mezi kroky motoru [ms]
int pauza1 = 2000;   // pauza mezi otočením směru [ms]

 
void setup() 
{               
  pinMode(stp, OUTPUT); //
  pinMode(dir, OUTPUT);       
  digitalWrite(dir, LOW); 
  lcd.begin(16, 2); // start LCD library
}  
 
void loop() //loop-----------------------------
{ 
   otvirat();
   delay(pauza1);
   zavirat();
   delay(pauza1);
} //konec loop--------------------------- 

void otvirat() // otvirat ----------------------
{
   digitalWrite(dir, HIGH); //nastavení směru otáčení
    for ( a = 100; a < 300; a++)
    {
      digitalWrite(stp, HIGH); 
      delay(pauza);               
      digitalWrite(stp, LOW); 
      delay(pauza); 
      lcd.setCursor(0,0);
      lcd.print(a);lcd.print("+");
    }
} //konec otvirat----------------------
void zavirat() // zavirat ----------------------
{
   digitalWrite(dir, LOW); //nastavení obráceného směru otáčení
    for (int a = 300; a>100; a--)
    {
      digitalWrite(stp, HIGH); 
      delay(pauza);               
      digitalWrite(stp, LOW); 
      delay(pauza); 
      lcd.setCursor(0,0);
      lcd.print(a);lcd.print("-"); 
    }
  
} //konec zavirat----------------------

Merkurino – ovládáme modelářské servo potenciometrem

Postavili jste si pěkný domeček pro  pěstování úžasných a lahodných bylinek nebo chcete na dálku kabelem ovládat modelářské servo?

Zapojení je jednoduché:

Merkurino se servem a potenciometrem

Merkurino se servem a potenciometrem

Pokud vám připadá použití příliš samoúčelné, připojte místo potenciometru  termistor nebo fotoodpor a už se bude „něco“ ovládat samo

Příklad kódu s ovládáním také tlačítky

/*******************************************************
Tento program otestuje Merkurino 01 s potenciometrem a modelářským servem
2014, MerkurRobot.cz
********************************************************/ 
//jednoduché použití LiquidCrystal knihovny
#include <LiquidCrystal.h> 
#include <Servo.h> 
Servo myservo;  // vytvoření objektu servo pro ovládání serva
// 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;
int val;    // proměnná pro hodnotu serva 
int pot;    // proměnná pro hodnotu potenciometru 
int pot1;    // proměnná pro hodnotu potenciometru 
int potpin = 2;  // analog pin použitý pro připojení potenciometru

#define btnRIGHT 0
#define btnUP 1
#define btnDOWN 2
#define btnLEFT 3
#define btnENTER 4
#define btnESC 5
#define btnNONE 6
// read the buttons
int read_LCD_buttons() // procedura pro čtení tlačítek ---------------
{
adc_key_in = analogRead(0); // přečti klávesnici na A0
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 pro čtení tlačítek ---------------

void setup() // procedura setup ---------------
{
    Serial.begin(9600);
  pinMode(A1, OUTPUT); // nastavení "vstupu" A1 jako "výstup"
  myservo.attach(A1);  // servo je připojeno na "vstup" A1
lcd.begin(16, 2); // start LCD library
lcd.setCursor(0,0); // nastavení pozice kurzoru
lcd.print("Stiskni tlacitko"); 
} // konec  procedura setup ---------------

void loop() // začátek nekonečné smyčky ---------------
{
lcd.setCursor(8,1); // nastavení pozice kurzoru
lcd.print(millis()/1000); // zobraz sekundy od zapnutí
lcd.setCursor(0,1); // nastavení pozice kurzoru
lcd_key = read_LCD_buttons(); // read the buttons
  val = adc_key_in;
  val = map(val, 0, 1023, 0, 179);     // změní měřítko hodnoty z potenciometru na servo (rozsah 0-1023 na 0-179) 

switch (lcd_key) // podle stisknutého tlačítka zobrazí text a natočí servo:
{
case btnRIGHT:
{
lcd.print("vpravo  ");
  myservo.write(val);  // natočí servo podle tlačítka  vpravo 
  
break;
}
case btnLEFT:
{
lcd.print("vlevo   ");
  myservo.write(val);  // natočí servo podle tlačítka   vlevo

break;
}
case btnUP:
{
lcd.print("nahoru     ");
  myservo.write(val);  // natočí servo podle tlačítka  nahoru

break;
}
case btnDOWN:
{
lcd.print("dolu   ");
  myservo.write(val);  // natočí servo podle tlačítka  dolu
break;
}
case btnENTER:
{
lcd.print("potvrd ");
  myservo.write(val);  // natočí servo podle tlačítka  potvrd
break;
}
case btnESC:
{
lcd.print("zpet    ");
  myservo.write(val);  // natočí servo podle tlačítka  zpet
break;
}
case btnNONE:  // když není stisknuto žádné tlačítko, natočí servo podle potenciometru:
{
lcd.print("nic   ");
  pot = analogRead(potpin); // přečti potenciometr na A2
  pot = map(pot, 0, 1023, 0, 179);     // scale it to use it with the servo (value between 0 and 180) 
  myservo.write(pot);                  // sets the servo position according to the scaled value 
  if ( pot!= pot1 ){    // uložení stávající hodnoty potenciometru
    pot1 = pot;         // aby se posílala pouze změna (pootočení)
    Serial.println(pot); 
  }
break;
}
}
} // konec nekonečné smyčky ---------------

Merkurino a vlastní znaky na LCD

Merkurino / Arduino může jednoduše ovládat nastavení znakové sady na znakovém LCD  displeji.
Každý znak je definován maticí bodů 8 řádků x 5 sloupců.
Základní tabulku anglických znaků – malá a VELKÁ písmena bez diakritiky a číslice má displej uložen v paměti, proto ho stačí jen zavolat. Pokud chceme vlastní znaky, musíme si je nadefinovat sami.

Vlastní znaky

Vlastní znaky

Příklad kódu je zde:

#include <LiquidCrystal.h>
// upravil: L. Vohralík, 2014, MerkurRobot.cz
LiquidCrystal lcd(13, 12, 8, 7, 4, 2);

byte smiley[8] = {  //definice znaku smiley
  B00000,           // jednička svítí
  B10001,           // nula nesvítí
  B00000,
  B00000,
  B10001,
  B01110,
  B00000,
};
byte r_hacek[8] = {  //definice znaku r s háčkem = ř
  B01010,           // jednička svítí
  B00100,           // nula nesvítí
  B01110,
  B01001,
  B01000,
  B01000,
  B00000,
};
byte mezera[8] = {  //definice znaku mezera
  0, 0, 0, 0, 0, 0, 0,
};

void setup() {
  lcd.createChar(0, smiley);   //odeslání definice 1. znaku (znak 0)
  lcd.createChar(1, r_hacek);   //odeslání definice 2. znaku
  lcd.createChar(2, mezera);   //odeslání definice 3. znaku
  lcd.begin(16, 2);            //inicializace displeje
  lcd.write(byte(0));    //zobrazí smajlík (znak 0)
  lcd.write(byte(1));    //zobrazí ř (znak 1)
  lcd.write(byte(0));    //zobrazí smajlík (znak 0)
  lcd.write(byte(2));     //zobrazí mezeru (znak 2)
  lcd.write("ahoj");     //zobrazí text
  
}

void loop() {}

Merkurino 01 a hodiny RTC

Jak si naprogramovat budík? Jak spouštět čerpadlo jen v určitý čas podle změřené teploty?

K Merkurinu (Arduinu) stačí připojit modul s obvodem reálného času (DS1307) do konektoru pro seriovou komunikaci zvanou I2C.

modul RTC na i2c

modul RTC na i2c

Zapojení je jednoduché, stačí 4 vodiče nebo piny.
0V (Gnd),
+5V (Vcc),
data (Sda) na vstup A4 a
hodiny (Scl) na vstup A5.

Zobrazení reálného času

Zobrazení reálného času

připojení modulu

Připojení modulu

Příklad nastavení a čtení času:

// popis Merkurino 01: www.MerkurRobot.cz
// rtc modul na i2c - jen čtení času s ds1307
#include "Wire.h" // knihovna pro i2c komunikaci
#define DS1307_ADDRESS 0x68
byte zero = 0x00; //workaround for issue #527

#include <LiquidCrystal.h>
LiquidCrystal lcd(13, 12, 8, 7, 4, 2);
// definice proměnných
int lcd_key = 0;
int adc_key_in = 0;

char cas[8]; //pole znaků pro čas
char datum[10]; //pole znaků pro datum

void setup(){   // procedura setup ----------------------------
  Wire.begin();
  Serial.begin(9600);
  //setDateTime(); //MUST CONFIGURE IN FUNCTION
         //pokud chceme nastavit čas v hodinách,
         //zrušit lomítka a nastavit ve funkci přesný čas.
         //Po nastavení opět zapoznámkovat
  lcd.begin(16, 2); // start LCD library
  lcd.setCursor(0,0); // nastavení pozice kurzoru
  lcd.print("Nyni");  
  lcd.setCursor(0,1); //
  lcd.print("je:");                  
} // konec procedura setup ----------------------------

//----------------------------------------------------------
void loop(){  // procedura loop ----------------------------
  printDate();
  lcd.setCursor(8,0); // nastavení pozice kurzoru
  lcd.print(cas);
  lcd.setCursor(6,1); // nastavení pozice kurzoru
  lcd.print(datum);
  delay(1000);
} // konec procedura loop ----------------------------------
//----------------------------------------------------------

// procedury pro nastavení a čtení času v hodinách ds1307 -------
void setDateTime(){ 
  byte second =00; //0-59
  byte minute =53; //0-59
  byte hour =14; //0-23
  byte weekDay = 0; //1-7 (0-6, neděle – sobota
  byte monthDay =19; //1-31
  byte month = 9; //1-12
  byte year= 14; //0-99 (msd’s 4-digit year ignored
  Wire.beginTransmission(DS1307_ADDRESS);
  Wire.write(zero); //stop Oscillator
  Wire.write(decToBcd(second));
  Wire.write(decToBcd(minute));
  Wire.write(decToBcd(hour));
  Wire.write(decToBcd(weekDay));
  //DS1307 RTC Libraries And Examples V2.1.Docx 11
  Wire.write(decToBcd(monthDay));
  Wire.write(decToBcd(month));
  Wire.write(decToBcd(year));
  Wire.write(zero); //start
  Wire.endTransmission();
}
byte decToBcd(byte val){
  // Convert normal decimal numbers to binary coded decimal
  return ( (val/10*16) + (val%10) );
}
byte bcdToDec(byte val){
  // Convert binary coded decimal to normal decimal numbers
  return ( (val/16*10) + (val%16) );
}
void printDate(){
  // Reset the register pointer
  Wire.beginTransmission(DS1307_ADDRESS);
  Wire.write(zero);
  Wire.endTransmission();
  Wire.requestFrom(DS1307_ADDRESS, 7);
  int second = bcdToDec(Wire.read());
  int minute = bcdToDec(Wire.read());
  int hour = bcdToDec(Wire.read() & 0b111111); //24 hour time
  int weekDay = bcdToDec(Wire.read()); //0-6 -> sunday -Saturday
  int monthDay = bcdToDec(Wire.read());
  int month = bcdToDec(Wire.read());
  int year = bcdToDec(Wire.read());
  //print the date EG 23.01.2011 23:59:59
  sprintf(cas,"%02d:%02d:%02d",hour,minute,second);
  sprintf(datum,"%02d.%02d.20%02d",monthDay,month,year);
  Serial.print(datum); Serial.print(" "); Serial.print(cas);
  Serial.println();
  
}
// konec procedur pro nastavení a čtení času v hodinách ds1307 -------