вторник, 3 мая 2016 г.

Простой термо-гигрометр на ардуино…

 Всем читателям привет! Рад очередной встрече на страницах блога. Сегодня мы попробуем сделать простейший прибор для измерения температуры и влажности, на базе Arduino с выводом информации на LCD экран. А начнем с того что перечислим что нам нужно будет для осуществления этого проекта: датчик влажности или температуры DHT11, LCD дисплей с I2C модулем, резистор на 10 кОм.

Как и что подключать вы без труда поймете из принципиальной схемы. Выводы датчика подключаем S на А0, питание на +5В (к плате ардуино), и минус к GND. Обратите внимание что на датчике 4 вывода, но использоваться будут только 3. Дисплей LCD подключается как и в прошлом проекте: VCC на +5, GND на GND, SDA на А4, SLC на А5.

Итак, все подключили (еще раз сверьтесь со схемой) пора заняться программированием МК. Скетч я нашел готовый в интернете, который неплохо будет работать. Сам скетч беремс яндекс диска жми сюда. Как видите все просто, можно даже и не уметь программировать на Си+, но тем не менее практически работать с МК.

Еще одно важное замечание. Перед тем как начать компиляцию, обязательно установите библиотеки (на этот раз две): DHT и LiquidCrystal_I2C. Так же эти библиотеки можно загрузить с Яндекс диска: библиотека DHT здесь, а LiquidCrystal_I2Cздесь. Вот теперь устанавливаем отсутвующие библиотеки (в стандартный набор библиотек они не входят). Если какой-то из этих библиотек вы не установили то при попытке скомпилировать будет ошибка.
Надеемся, что все у вас получилось. И в случае успеха на экране появиться температура и влажность. Убедимся, что датчик работает: можно на него подышать, и тем самым нагнать и температуру и влажность.

Скетч нашего проекта:

#include <Wire.h> // Добавляем необходимые библиотеки
#include <LiquidCrystal_I2C.h>
#include "DHT.h"
#define DHTPIN A0 // к какому пину будет подключен сигнальный выход датчика
//выбор используемого датчика
#define DHTTYPE DHT11 // DHT 11
//#define DHTTYPE DHT22 // DHT 22 (AM2302)
//#define DHTTYPE DHT21 // DHT 21 (AM2301)
//инициализация датчика
DHT dht(DHTPIN, DHTTYPE);
byte degree[8] = // кодируем символ градуса
{
   B00111,
   B00101,
   B00111,
   B00000,
   B00000,
   B00000,
   B00000,
};
LiquidCrystal_I2C lcd(0x27,16,2); // Задаем адрес и размерность дисплея
void setup()
{
lcd.init(); // Инициализация lcd
lcd.backlight(); // Включаем подсветку
lcd.createChar(1, degree); // Создаем символ под номером 1
Serial.begin(9600);
dht.begin();
}
void loop() {
// Добавляем паузы в несколько секунд между измерениями
delay(2000);
// Reading temperature or humidity takes about 250 milliseconds!
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
float h = dht.readHumidity();
// Read temperature as Celsius
float t = dht.readTemperature();
// Read temperature as Fahrenheit
float f = dht.readTemperature(true);
// Выводим показания влажности и температуры
lcd.setCursor(0, 0); // Устанавливаем курсор в начало 1 строки
lcd.print("Hum = % "); // Выводим текст
lcd.setCursor(7, 0); // Устанавливаем курсор на 7 символ
lcd.print(h, 1); // Выводим на экран значение влажности
lcd.setCursor(0, 1); // Устанавливаем курсор в начало 2 строки
lcd.print("Temp = \1C "); // Выводим текст, \1 - значок градуса
lcd.setCursor(7, 1); // Устанавливаем курсор на 7 символ
lcd.print(t,1); // Выводим значение температуры
}


воскресенье, 1 мая 2016 г.

Работаем с LCD дисплеем 1602


Всем читателям привет! Рад нашей новой встрече на страницах блога. Спасибо вам что посещаете мои странички. Сегодня мы научимся работать с жидкокристаллическим дисплеем (далее LCD). Так же разберемся с некоторыми проблемами, с которыми вы можете столкнуться. А пока начнём с самого начала.


Несколько важных замечаний:
1.       Дисплеи могут отличаться количеством символов и строк. Например 1602 означает что у нас двухстрочный дисплей с длиной строки в 16 символов. 1604 означает что у нас четерехстрочный дисплей, с длиной строки в 16 символов.
2.       Мы будем работать с дисплеем с I2C модулем, благодаря чему управление LCD дисплеем будет осуществляться двумя проводами (подключенные к А4 и А5), конечно же дисплей нужно будет еще запитать двумя проводами, которые мы подключим к пинам «земля» и «+5В». Благодаря I2C модулю мы избавимся от кучи проводов!
3.       Для записи скетча в плату ардуино, мы будем пользоваться программами старых версий (1.6.4 для «Виндовс 7 или 8» и 1.6.0. для «ХР»). При использовании новой версии 1.6.7 возникает проблема – не все символы (или только один) будут выводиться на экран дисплея. Возможно что в новых версиях эту проблему исправят)… Я предлагаю использовать архив с уже готовой к работе программы (то есть не требует установки на компьютер, это важно если у вас на компостере уже установлена новая версия).
4.       У дисплея может быть другой IIC адрес, вместо 0x27 может оказаться 0x3F. Чтобы точно определить адрес можете воспользоваться «сканером». Просто запишите скетч «сканер» подключите дисплей и включите ардуино. Откройте окно «порта» и посмотрите какой адрес у вашего устройства.
5.       Для работы дисплея мы будем использовать библиотеку LiquidCrystal_I2C. Если вы используете программу из архива, то установка библиотеки не потребуется (она уже имеется в архиве).

// i2c_scanner
#include <Wire.h>
  
void setup()
{
  Wire.begin();
   Serial.begin(9600);
  while (!Serial);             // Leonardo: wait for serial monitor
  Serial.println("\nI2C Scanner");
}

 void loop()
{
  byte error, address;
  int nDevices;
   Serial.println("Scanning...");
   nDevices = 0;
  for(address = 1; address < 127; address++ )
  {
        Wire.beginTransmission(address);
    error = Wire.endTransmission();
     if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");
       nDevices++;
    }
    else if (error==4)
    {
      Serial.print("Unknow error at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.println(address,HEX);
    }   
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");
   delay(5000);           // wait 5 seconds for next scan
}


Теперь приступим к сборке схемы. Все очень просто: нам нужно подключить 4 вывода от I2C модуля к плате ардуино. При этом подключаем выводы так: GND — GND, VCC — 5V, SDA — A4, SCL — A5. На картинках и фотографиях все предельно понятно (поэтому в этот раз мы обойдемся без схемы). Благодаря I2C плате мы можем управлять LCD двумя проводами. А вот какбы выглядела наша схема без этой "волшебной" платы:

А теперь самое время записать скетч в плату ардуино. Скетч выведет на экран «R6LCA RadioScout» а в нижней начнет отчет времени в секундах слева, а справа будет «LCD 1602». Сам скетч:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);  // Устанавливаем дисплей
void setup()
{
  lcd.init();                    
  lcd.backlight();// Включаем подсветку дисплея
  lcd.print("R6LCA RadioScout");
  lcd.setCursor(8, 1);
  lcd.print("LCD 1602");
}
void loop()
{
  // Устанавливаем курсор на вторую строку и нулевой символ.
  lcd.setCursor(0, 1);
  // Выводим на экран количество секунд с момента запуска ардуины
  lcd.print(millis()/1000);

}
Как видите все действительно просто. По крайней мере изучив материал блога, у вас точно все должно получиться. Но не будем останавливаться на таком простом примере. Ведь у нас есть датчик температуры и влажности, и даже датчик атмосферного давления. Вы наверно уже догадались над чем нам предстоит еще поработать. Так что до новых встреч! 

пятница, 29 апреля 2016 г.

Тест сервомотора….

Прошло уже четыре месяца как начал осваивать ардуино с нуля (начало изучения как раз приходиться на начало января 2016 года). Как говориться уже успел разобраться со многим: и с программированием, и с датчиками. Вот наконец подошло время и для сервомотора. Модуль у меня самый что ни на есть простейший и самый наверно недорогой - TowerPro SG90. Для начала давайте познакомимся с его техническими данными:


Технические характеристики
- рабочее напряжение: 3,5-6В
- диапазон вращения: 180°
- скорость вращения без нагрузки при 4,8В: 60° за 0,12с
- скорость вращения без нагрузки при 6В: 60° за 0,10с
- максимальный крутящий момент: 1,6 кг·см
- габаритные размеры ДхШхВ: 23х12х29мм
- вес: 9г

Механизм сервопривода выполнен из пластика. В комплекте с сервоприводом идёт комплект крепежа и пластиковых качелек. Для подключения сервопривода не требуется силового драйвера. То есть наш сервомотор можно подключить напрямую к плате ардуино. Но еще нужно разобраться какие провода сервомотора куда подключать.


В моем случае сервомотор имеет три разноцветных провода, которые нужно подключить к источнику питания (+5 В), земле (GND) и к управляющему пину ардуино. Соответственно серый провод подключается к земле, желтый к 9 пину ардуино, оранжевый к +5 В. Схема подключения сервомотора к ардуино несложная, но на всякий случай нарисую ее. Самое главное это не только подключить сервомотор, но так же еще научиться управлять им. Для начала используем переменный резистор, поворачивая его мы будем изменять его сопротивление и при этом сервомотор будет поворачиваться на заданный угол.
Конечно же управлять сервомотором дело сложное. Но за нас уже подумали и написали библиотеку: «Servo.h», искать ее не нужно: так как она уже входит в стандартную библиотеку. Так что смело подключаем ее в скетче. Да и сам скетч привожу ниже:


#include <Servo.h> // подключаем библиотеку сервы
#define POT_MAX_ANGLE 200.0 // макс. Угол поворота ручки потенциометра в градусах
Servo myServo;

void setup() {
myServo.attach(9); // подключаем серву к 9 пину
}

void loop() {
int val = analogRead (A0); // считываем данные с потенциометра
int angle = int (val/1024.0*POT_MAX_ANGLE); // рассчитываем угол поворота серва
angle = constrain(angle,0,180); // ограничиваем угол поворота от 0 до 180
myServo.write(angle); // даем команду серве задать угол поворота
}

 Вот и все! Загружаем скетч в микроконтроллер, и начинаем тестирование. Действительно с помощью поворота ручки переменного резистора мы управляем углом поворота сервомотора в пределах от 0 до 180 градусов. Все получилось удачно и отлично все работает, чего желаю и всем читателям.


суббота, 23 апреля 2016 г.

Телеграфный ключ на базе ардуино...


Привет всем читателям! Продолжаю рассказывать об интересных проектах. Сегодня не просто проект ардуино, а ардуино для радиолюбителей. Возможно в этом посте кто-то найдет для себя что-то полезное. И если это так то будем считать, что все не зря. А теперь начнем, но начнем с небольшой предыстории…
Начал изучать ардуино не просто так. А с целью сделать множество проектов, в том числе и радиолюбительских. Один проект уже завершен (то есть уже есть рабочая конструкция) это уже наверняка знакомый моим читателям «Радиомаяк-1». Так же будем совершенствовать и далее ардуино-маяк, и со временем расскажем о проекте «Радиомаяк-2». Но сегодня проект для любителей телеграфа: мы будем делать телеграфный ключ, причем автоматический. Для тех кто не знает, что это такое вкратце поясню: есть ручной (или вертикальный) где нужно самому отстукивать точки и тире, и есть автоматический. В автоматическом есть рычажок, у которого два положения: в одном положении генерируются точки, в другом тире. Это значительно упрощает работу, да и руки не так устают…

В общем дело нужное и можно начать разрабатывать алгоритм. Но тут решил еще немного поискать в интернете не делал ли кто-то уже нечто подобное? И оказалось, что да делали. Так что решил на этот раз мне изобретать велосипед, а просто взять уже готовый скетч и попробовать как все будет работать. Во основе простой CW ключ от UA1CBM. Сразу скажу скетч от UA1CBM заслуживает самых высоких похвал: эффективный и очень грамотный алгоритм работы. Единственное это нельзя управлять скоростью передачи…

А управлять скоростью как раз не так и сложно. Тем более что в проекте «Радиомаяк-2» это задача решена. Правда там используется другой алгоритм формирования точек и тире, но это не такая уж и проблема. Здесь управлять скоростью оказалось делом простым, так что дополнил скетч буквально несколькими строчками и все готово…
Теперь наступает самое интересное. Нужно собрать прототип схемы, а так же добавить еще переменный резистор. Прототип собираю на макетной плате (или как еще иначе ее называют «бредборд»). И хотя схема несложная, но прототип ее на макетке выглядит сложно. Поэтому обязательно привожу схему (кстати схему чертил в программе rusplan, в которой самостоятельно начертил и плату ардуино). Вот наконец схема собрана, и пора приступать к тестам…

Подключаю ардуино через USB к компьютеру, приступаю к программированию микроконтроллера. Вот скетч компилируется (без ошибок – ура!) и начинается загрузка. Все прошло без проблем. Приступаю к тесту. Пока самого манипулятора у меня нет (нужно будет обязательно сделать), то вместо него я использовал две кнопки. Конечно они работают, но н так хорошо, как манипулятор. Но тем не менее первые тесты прошли: работает в принципе не плохо. Вот только скорость еще велика, немного меняю данные в скетче (опытным путем) и после двух приближений получаю вполне отличный результат. Теперь скорость меняется и все прекрасно работает.

Для тех кто желает повторить проект, скетч приведу ниже. Если скорость покажется вам «не очень» то ее можно подрегулировать изменив данные в скетче. Обратите внимание на сточку cw_delay= map(val, 0, 1024, 60, 130). Теперь смотрите: изменять нужно только два последних числа (в моем примере: 60 и 130). Далее чем числа больше – тем будет меньше скорость. В моем первоначальном скетче было 40 и 140: скорость очень большая в одном из крайних положений переменного резистора, и очень маленькая в другом. Так что подобрал экспериментально 60 и 130. Но там сами смотрите… А теперь обещенный скетч:



/*
Simple CW key by UA1CBM
Speed control CW by RN6LLV
*/

const int dashPin = 3; // тире
const int ditPin = 2; // точки
const int ledPin = 13; // the number of the LED pin
const int pot=0; // потенциометр на порт А0
int val;
int cw_delay;

void setup() {
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(dashPin, INPUT);
pinMode(ditPin, INPUT);
}

void loop(){
val=analogRead(pot); // чтение данных с потенциометра
cw_delay= map(val, 0, 1024, 60, 130);
//cw_delay= (val/7);

if (digitalRead(dashPin) == HIGH) //Тире
{
// turn LED on:
digitalWrite(ledPin, HIGH);
delay(3*cw_delay);
// turn LED off:
digitalWrite(ledPin, LOW);
delay(cw_delay);
}

if (digitalRead(ditPin) == HIGH) //Тире
{
// turn LED on:
digitalWrite(ledPin, HIGH);
delay(cw_delay);
// turn LED off:
digitalWrite(ledPin, LOW);
delay(cw_delay);
}
}


понедельник, 18 апреля 2016 г.

Плавное мигание светодиодом или осваиваем массивы…

Конечно же можно все реализовать при помощи тригонометрической функции (sin). Используя данную функцию, можно на аналоговом выходе получить сигнал синусоидальной формы. Если к такому выходу подключить светодиод, то он будет плавно «мигать»: то плавно разгораться, то плавно угасать…
Но данная функция будет «напрягать» непрерывным вычислительным процессом сам микроконтроллер, ведь цикл условно говоря бесконечный, и каждый раз микроконтроллер должен рассчитывать одни и те же значения, что является нерациональным решением. Более практично вычислить заранее значений синусов, и представить данные в виде массива.
Выполнить все необходимые расчёты и создать массив данных удобно в небольшой программе Sinus Tab. По сути вам ничего не нужно делать: просто запустите программу, и нажмите кнопку «CALC». В окне программы появиться массив чисел, которые мы скопируем и вставим в программу Ардуино.

После запуска программы (скетч можно взять здесь: жми сюда...) мы увидим, как светодиод будет плавно мигать: то плавно разгораясь, то плавно угасать. Но гораздо интереснее подключить вместо светодиода RC цепь, и далее на выход цепи осциллограф. Как вы думаете какой мы тогда сможем увидеть сигнал? Наверно вы догадались: синусоиду, но нам же интересно поэкспериментировать!
Теперь давайте разберем подробнее что из себя представляет такая RC цепь. А это не что иное как простейший ЦАП (цифровой аналоговый преобразователь). То есть благодаря такой цепи мы сможем цифровой сигнал «превратить» в аналоговый. Номиналы радиодеталей: конденсатор 1 мкФ, резистор 10кОм. Вот и все! Пробуем все теперь на практике, и действительно очень интересно наблюдать как цифровой сигнал прямоугольной формы превращается в синусоиду…

Но вернемся опять к нашему скетчу. Все же не очень хорошо, когда для генерации данных используется сторонняя программа. А нельзя ли сделать так: пусть один раз микроконтроллер все же просчитает нужное значение (в нашем следующем примере 180 значений) и запишет их в массив. А уже потом во втором цикле (так называемая «петля») будет брать готовые вычисленные ранее значения. Скетч заметно стал меньше:
int ledPin=11;
float mas [180];
int led;

void setup() {
pinMode (ledPin, OUTPUT);
for (int x=0; x<180; x++)
{
  mas[x]=(255*(sin(x*3.1415/180))); // запись расчетных значений в массив
}
}

void loop() {
 for(int y=0; y<180; y++)
 {
  analogWrite (ledPin, mas[y]);
  delay (10);
 }
}
Но заметьте, что все работает точно так же: светодиод плавно мигает. Причем скетч в котором мы хранили массив использует 1 510 байт (4%) памяти устройства. Всего доступно 32 256 байт. Глобальные переменные используют 268 байт (13%) динамической памяти, оставляя 1 780 байт для локальных переменных. Максимум: 2 048 байт.

Теперь сравним со вторым скетчем, где данные рассчитываются и помещаются в массив. Второй скетч использует 2 632 байт (8%) памяти устройства. Всего доступно 32 256 байт. Глобальные переменные используют 731 байт (35%) динамической памяти, оставляя 1 317 байт для локальных переменных. Максимум: 2 048 байт.

 Вот такое неожиданный результат! Но впрочем проверить пожалуй стоило. До встречи в следующем уроке. 

среда, 13 апреля 2016 г.

Ардуино: меняем не только скорость передачи, но и длительность паузы.

Всем читателям моего блога привет! Спасибо что заходите в гости. Сегодня мы продолжим улучшать наш проект «Радиомаяк-2». В прошлый раз мы с помощью переменного резистора научились управлять скоростью передачи азбукой Морзе. Теперь давайте научимся управлять длительностью пауз в конце каждой передачи. Опять возникает вопрос а зачем? А вот для чего: после того как маяк отправил морзянкой сообщение, необходимо выдержать паузу длительностью от 1 минуты или больше. За это время «отдохнет» передатчик, вернее выходной транзистор (который может нагреваться) …

В общем дело нужное. Все что нам нужно сделать, так это немного изменить саму схему: ввести в нее еще один переменный резистор, и естественно немного изменить и сам скетч. Начнем со скетча. По сути код почти и не измениться: разве что только придется добавить еще одну строку кода, где будет вестись «считывание» данных со второго переменного резистора.

const int pot=0; // задаем А0 для потенциометраR1
const int pot1=1; // задаем А1 для потенциометра R2
float val=0; // задаем начальное значение переменной R1
float val1=0; // R2

void setup() {
  // put your setup code here, to run once:
pinMode (7, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
val=analogRead (pot); // чтение данных с R1
val1=analogRead (pot1); // чтение данных с R2
}

Но нам конечно же нужно не только считать данные с переменных резисторов R1 и R2, но так же немного преобразовать полученные данные. Для этого мы просто изменим немного строки скетча, где сразу же и произведем обработку этих данных.

int dot = 100; // длительность точки
int tir = 300; // длительность тире
int iedPin = 7; // звук на 7 пин
int pause = 600; // пауза знака
const int pot=0;
const int pot1=1;
float val=280;
float val1=1;
float vals=1;
void setup()
{
  pinMode (7, OUTPUT);
}

void loop()
{
   val=map (analogRead (pot),0,1024,160,350);
 vals=val/250;
 dot=100*vals;
 tir=300*vals;

  val1=map (analogRead (pot1),0,1024,1,10);
delay(1000*val1);
  }

В общем первую задачу мы выполнили. Готовый скетч вы можете взять с Яндекс диска: жми сюда!. Теперь осталось собрать схему. Вот когда уже появляется путаница проводов, и без схемы никуда. Попытался начертить схему в разных программах, нет, пока лучше, чем карандаш и бумага не нашел варианта. Надеюсь, что Вы смогли все правильно подключить. И тогда все получиться: можно управлять скоростью передачи и длинной пауз. А теперь вопрос для закрепления материала: что нужно изменить в скетче чтобы время паузы увеличить с 1 до 4 минут? Удачи!


вторник, 12 апреля 2016 г.

Ардуино: меняем скорость передачи морзянки переменным резистором..

Всем читателям привет! Недавно мы учились с помощью переменного резистора управлять частотой вспышек светодиода. Теперь наступило время применить наши знания для нашего проекта «Радиомаяк-2». В этой версии маяк станет управляемым, и первое что мы сделаем это научим ардуино передавать сигналы азбукой Морзе с разной скоростью…

Сделаем упрощенную модель маяка: это сократим в тестовой версии длину передаваемого текста. Так что в тестовой версии наш маяк будет передавать только: «VVV DE». Все что нам нужно будет сделать так это только переписать скетч. Вам совсем это делать необязательно можете воспользоваться сразу готовым (загрузить тестовый скетч с Яндекс диска можно по ссылке здесь).


Нам даже не нужно будет изменять схему с прошлого урока, но если вы еще не делали то схема простейшая. Подключите к 7 пину ардуино через резистор 220 Ом светодиод и пищалку, вот собственно и все. Переменный резистор подключите так: крайние выводы к +5 и земле, а средний вывод к А0.  Далее запишите скетч в ардуино и приступайте к тестам. А теперь несколько вопросов для закрепления. Вопрос №1 какую роль играет А0? Вопрос №2 что в скетче нужно изменить чтобы еще расширить диапазон изменения скорости? Вопрос №3 что нужно сделать, чтобы в нашем проекте можно было не только менять скорость передачи азбукой Морзе, но и управлять длительностью паузы после передачи всего текста? Надеемся что вопросы не оказались для Вас слишком трудными, а мы скоро увидимся в новом уроке по ардуино.