OK

Při poskytování služeb nám pomáhají soubory cookie. Používáním našich služeb vyjadřujete souhlas s naším používáním souborů cookie. Více informací

Úvodní stránka » GSM » Jak jednoduše na GSM-IX.díl - Analogové vstupy AGS

Jak jednoduše na GSM-IX.díl - Analogové vstupy AGS

Dneska se zaměříme na problematiku analogových vstupů zejména pro snímání diskrétních hodnot pomocí  Arduino GSM Shieldu (AGS). Dostal jsem od Vás nějaké dotazy a reakce v tomto duchu, že dva diskrétní vstupy oddělené optočleny je mnohdy málo a zda existuje nějaká možnost přímého připojení dalších digitálních vstupů na AGS. Pochopitelně tato možnost existuje, AGS nezabírá všechny digitální porty, ale ukážu Vám způsob, který je daleko efektivnější, protože má velmi malou spotřebu portů. Nebudu se zabývat analogovým vstupem pro měření analogového napětí na něm - exisuje na to řada příkladů, analogové napětí ale přeci jen měřit budeme. Tak tedy celé tajemství spočívá v něčem, co nazýváme odporový dělič. Jako modelový příklad jsem vzal 3 suché kontakty a připojil je na jediný analogový vstup A0 přes patřičný odporový dělič, viz. obrázek níže:

Jak je z obrázku patrné, budou kontakty spínat různé kobinace odporů a tím pádem na děliči - vstupní svorce A0 budou vznikat různé úbytky napětí. Ke spočítání těchto úbytků stačí prostá znalost ohmova zákona a abychom nemuseli otročit u každé kombinace kontaktů, pak je dobré to hodit do excelu. S uvedenou kombinací hodnot odporů mi vyšla tato tabulka:

Máme 3 kontakty, můžeme mít tedy 8 různých kombinací jejich stavů. U každého kontaktu K1 až K3 je hodnota 0 (sepnuto) nebo 1 (rozepnuto) - pozor, platí tady opačná logika z pohledu elektrického, z pohledu programátorského to pochopitelně můžeme snadno změnit. Sepnutý kontakt vyzkratuje daný odpor a vznikne tak patřičný úbytek napětí dle různě protékajícího proudu na děliči.

Pro programové zpracování nás bude zajímat poslední sloupec, ve kterém je již vyjádřená diskrétní hodnota u dané kombinace kontaktů. Vezmete-li si hned první řádek, pak všechny kontakty jsou sepnuté a na analogovém vstupu je plných 5V a to odpovídá analogovému převodu na hodnotu 1023 při zavolání procedury analogRead(A0); Volba hodnot odporů (emipricky) se jeví jako optimální, neboť máme mezi jednotlivými stavy dostatečný manévrovací prostor pro nastavení mezí a hysterezí. Upozorňuji ale na jednu věc - berte v potas, že Váš USB port , ke kterému máte AGS připojený, může dávat napětí mezi 4,8V až 5,4V, patrně při převodu a různé kombinaci neuvidíte přesně vypočtené konstanty. Poměry se zlepší, jakmile budete shield napájet 12V/1A adaptérem, pak bude reference odvozená od interního stabilizátoru, který dává těch skoro přesných a stabilních 5V. Nicméně, i tak bude možné nastavit meze zcela v pohodě pro jednoznačnou detekci kombinace kontaktů.

Jistě je možné přidat ještě jeden kontakt a jeden odpor (více bych už asi neriskoval kvůli množství kombinací a náročnosti přesnosti měření jedotlivých stavů), ale zde berte v potas, že se dostáváte na 16 různých stavů. 3 kontakty na analogový vstup se mi jeví jako optimální.

A ještě jedno upozornění plynoucí ze schématu - je potřeba na A0 "vyřadit" trimr, pokud budete připojovat celou sestavu odporů tak, jak je na výše uvedeném obrázku, nebo můžete ušetřit jeden rezistor - a toto spíše doporučuji - a nastavit na trimru přesně hodnotu 4k7 mezi zem a svorkou A0. Neměl by to být problém, trimry jsou víceotáčkové, takže do 4k7 se jistě trefíte a drobná odchylka nevadí.

Sketch

Zkusme si tedy naprogramovat výše uvedenou teorii a vytvořit program, který bude hlídat stav kontaktů a při jakékoliv změně pošle SMS se stavem všech kontaktů. Dále zaimplementujeme možnost na shield zavolat a zpětnou vazbou bude SMSka s informací o stavu kontaktů. Tím mírně plním slib z minula, pro jednoduchost si necháme na později I2C sběrnici - která by se mimochodem dala také hezky využít pro čtení až 8-mi kontaktů pomoci notoricky známeho portového expandéru PCF8574. To si nechme ale na jiný článek.

Sketch je poměrně primitivní a důležité komentáře jsou uvedeny. Pravda je to trochu neprogramátorsky napsané, ale preferuji v tomto případě přehlednost před nejrůznějšími obraty jazyka c++ tak, aby z toho měli něco i začátečníci. Tak tedy inicializaci knihovny jsem vysvětlil v předchozích dílech seriálu, definoval jsem si rovnou textový obsah SMS, který si pak dle naměřené hodnoty v hlavní smyčce přiřadím ke skutečnému stavu kontaktů. Hlídám taky, zda SMSku s daným stavem jsem již poslal či nikoliv. Reaguji také na zavolání do AGS a pokud je shoda s autorizovaným číslem, pak odešlu SMS s posledně známým stavem kontaktů.

 

#include <ArduinotechGSMShield.h>
#include <SoftwareSerial.h>
#define LED 7
#define SERVIS_NUMBER "739822476"

//Vytvoření instance třídy AGS

AGS modul(1);
uint8_t infoStatus;
String number;

//definice kombinací kontaktů
String status[8] =
{ 
  "K1=1,K2=1,K3=1",
  "K1=1,K2=1,K3=0",
  "K1=1,K2=0,K3=1",
  "K1=1,K2=0,K3=0",
  "K1=0,K2=1,K3=1",
  "K1=0,K2=1,K3=0",
  "K1=0,K2=0,K3=1",
  "K1=0,K2=0,K3=0" 
};
bool SMSsent;
String SMScontent;
String oldContent;
uint16_t analog;

//Vstupní parametry a inicializace shieldu

void setup()
{
  pinMode(LED, OUTPUT);
  digitalWrite(LED, LOW);
  modul.begin();
  digitalWrite(LED, HIGH);
  oldContent = status[0];
}

/*Hlavní smyčka – měří napětí na analogovém vstupu A0 při jeho změně
vyhodnotí stav a odešle SMS.
Pak je hlídán příchod příchozího volání
a na SERVIS_NUMBER,
je odeslána SMSka s aktuálním stavem kontaktů -
analogového vstupu A0,
pokud se volající číslo shoduje se SERVIS_NUMBER
*/ void loop() {  //měř A0 a zjišťuj kombinace, nachystej obsah SMS  analog = analogRead(A0);  if (analog < 340) SMScontent = status[0];  if ((analog < 400) && (analog > 360)) SMScontent = status[1];  if ((analog < 435) && (analog > 390)) SMScontent = status[2];  if ((analog < 540) && (analog > 495)) SMScontent = status[3];  if ((analog < 490) && (analog > 450)) SMScontent = status[4];  if ((analog < 620) && (analog > 580)) SMScontent = status[5];  if ((analog < 720) && (analog > 670)) SMScontent = status[6];  if (analog > 1000) SMScontent = status[7];    //porovnej obsah předešlé SMS a pokud je změna, ulož ji a odešli  if (oldContent != SMScontent)  {    oldContent = SMScontent;    modul.sendSMS(SERVIS_NUMBER, SMScontent);  }    infoStatus = modul.checkCallAndSMS();  if (infoStatus == 1)  {    number = modul.getNumber();    Serial.println("Call from:" + number);    modul.callEnd();    if (number == SERVIS_NUMBER)    {      modul.sendSMS(SERVIS_NUMBER, SMScontent);    }    else modul.callEnd();  }  delay(500); }

Sketch naleznete na mém GitHub repository zde.

Takže toto je obecný přístup k problematice čtení více kontaktů na jediném analogovém vstupu, tento přístup se také používá pro připojení maticových klávesnic tak, aby jste si nespotřebovali všechny digitální vstupy Arduina. Examplů na netu jistě najdete mnoho. Protože se mi množí požadavky na objasnění problematiky GPRS, bude tomu věnován další článek, který sepíšu někdy o svátcích. V mezičase, koho problematika GPRS zajímá doporučuji nastudovat věci kolem Thingspeak - je to opravdu výborný portál pro ukládání dat z různých senzorů, provádění různých analýz nad daty a hlavně možností spustit si hezkou vizualizaci a to jak privátně, tak veřejně přístupnou. Právě do tohoto portálu budu příště GPRS data posílat.

PF

Přidat komentář

Zvýrazněné položky jsou povinné.

Přehled komentářů

  1. Čtení analog (Jarda, 16.3.2016 23:19:58) Odpovědět

    Při čtení analogového vstupu jsem narazil na problém. Pokud zatížím na arduino jiné výstupy, např sepnu relé, rozsvítím diodu, posune se při nízkých hodnotách čtení jeho velikost až o 40 jednotek, při vypnutí opět klesne, tedy dostane se mimo rozsah nastavených hodnot. Zkoušel jsem externí zdroj, použít AREF, bez jakéhokoliv výsledku. Nevíte o nějakém řešení tohoto problému, vyjma použití externího modulu.

    Admin:
    Dobrý den,
    Záleží, jak to máte napájené - předpokládám, že UNO máte zapíchlé v USB PC - tím pádem je reference pro měření na analogových portech odvozená od kavality stabilizace USB 5V Vašeho PC, což je problém, vím to z vlastní praxe. V momentě, kdy by jste měl pouze externí napájení, pak se reference odvodí od 5V stabilizátoru UNO a ten bývá mnohem stabilnější. Dále pak máte možnost na AREF přivés přesný a stabilní zdroj napětí, od kterého se bude odvozovat měření. Pak nezapomeňte definovat analogReference(EXTERNAL). Defaultně je nastaveno AREF na 5V - tedy buď 5V zdroj, který se ale dostane ke slovu po odpojení USB a připojení externího napájení alespoň 7V (aby vznikl 2V rozdíl pro účinnou stablizaci) nebo je těch 5V odvozenných od USB. Málokdy potkáte USB s 5V přesně, tohle bych viděl jako příčinu. 40 jednotek z rozsahu 1024 je zhruba 4% chyba a to by tak odpovídalo houpání napětí na USBéčku. Ovšem zatížení LEDkou, která má 2mA je opravdu zvláštní, ta relé zase naopak nijak nesouvisí se zatížením 5V zdroje - ta jsou napájená přímo z externího vstupu. Trochu bych asi měřil, co mám na AREF. Snad tyto úvahy pomohou.

    PF


TOP produkty

NodeMCU s ESP8266

NodeMCU s ESP8266
350 Kč s DPH

Arduinotech GSM shield

Arduinotech GSM shield
877 Kč s DPH

Kontakt

Ing. Petr Foltýn
Kunčice pod Ondřejníkem 814, 73913
TOPlist