понедельник, 13 апреля 2015 г.

Servo SG90

Попробовал, что такое servo, в применении к ардуино. Вот простая и понятная статья: http://wiki.amperka.ru/%D1%80%D0%BE%D0%B1%D0%BE%D1%82%D0%BE%D1%82%D0%B5%D1%85%D0%BD%D0%B8%D0%BA%D0%B0:%D1%81%D0%B5%D1%80%D0%B2%D0%BE%D0%BF%D1%80%D0%B8%D0%B2%D0%BE%D0%B4%D1%8B.
Заранее почитав про управление моторчиками, обзавелся специальным шилдом Motor Drive Shield Expansion Board L293D (http://www.ebay.com/itm/170910733083). Как я понял, это китайский клон шилда от AdaFruit https://learn.adafruit.com/adafruit-motor-shield.

Кратко про сам шилд: на UNO он садится настолько плотно, что низ платы упирается в разъемы. И создается впечатление, что один из контактов мотора будет коротить на корпус USB. На всякий случай наклеил бумажку. Также важно, что шилд не проходной, больше ничего прямо на контакты ардуины не подцепить. Можно его ставить последним в "пироге", но в принципе, смысл этого шилда чисто обучающий, в готовом изделии можно просто повторить часть его схемы для реиспользования отлаженного кода.


Даташит на серво: http://datasheet.sparkgo.com.br/SG90Servo.pdf. Самое интересное там - "can rotate approximately 180 degrees", что сразу намекает на игрушечность.
Подключается серво к одному из двух трехпиновых разъемов. Никакой хитрой схемы за ними нет, пятивольтовое питание и выходы 10 и 9 с ардуины напрямую. Пины на плате подписаны, соответствие по цветам описано в даташите.

Код взял из вышеупомянутой статьи, увидел, что крутится машинка реально быстро, немного дописал, чтобы попробовать вращать плавно.
Результат:
#include <Servo.h>

Servo myservo;

void setup()
{
  myservo.attach(10);
}

void loop()
{
//  myservo.write(90);  // устанавливаем сервопривод в серединное положение
//  delay(500);
//  myservo.write(0);  // устанавливаем сервопривод в крайнее левое положение
//  delay(500);
//  myservo.write(180);  // устанавливаем сервопривод в крайнее правое положение
//  delay(500);
int i;
  for (i=0;i<=180;i++)
  {
    myservo.write(i);
    delay(100);
  }
  for (i=180;i>=0;i--)
  {
    myservo.write(i);
    delay(100);
  }
}
Надо отметить, что точность у этой игрушки невелика, крайние положения могут оказываться немного в других местах в каждом цикле. Диапазон вращения и правда "приблизительно 180", чуть меньше 180. Можно приближенно считать, что myservo.write() передается желаемый угол в градусах. Еще понятия "левое положение" и "правое положение" довольно относительны. У меня получилось, что "крайнее левое положение" - это "до упора по часовой стрелке, если смотреть со стороны рабочего органа".

воскресенье, 12 апреля 2015 г.

I2C RTC Arduino

Подключил модуль реального времени к ардуине. Основной вывод - можно пользоваться I2C протоколом, абсолютно его не понимая. По описанию протокола он позволяет подключать множество устройств к одной двухпроводной шине, каждому назначается свой ID, путем опроса можно общаться с любым.
Купил модуль I2C RTC DS1307 AT24C32 Real Time Clock Module for Arduino 51 AVR ARM PIC (http://www.aliexpress.com/item/Free-Shipping-I2C-RTC-DS1307-AT24C32-Real-Time-Clock-Module-for-Arduino-51-AVR-ARM-PIC/1786267095.html, были дешевле, но без отзывов на тот момент). Батарейка CR2032 была в запасах.
Запаял семипиновую гребенку SQ, DS, SCL, SDA, VCC, GND, BAT (на втором ряду контактов выводов меньше, решил, вдруг пригодятся).
Как потом выяснилось, реально нужны только 4 - SCL, SDA, VCC, GND.
А дальше просто нагуглил статью http://www.instructables.com/id/Sleep-Cycle-Alarm-Clock-with-Motion-Sensor/?ALLSTEPS. Там по ссылкам взял две либы, DS1307RTC и Time. Что удивило, в либе ни слова про то, куда подключать модуль, похоже I2C в ардуино стандартизирован. Описание подключения взял в самой статье: Attach the RTC to 5V, Ground, A4, and A5.
Дальше просто взял пример из DS1307RTC - ReadTest. Он первым делом написал, что нужно сначала запустить соседний пример SetTime. Запустил, время выставилось, и теперь ReadTest выдает это:
DS1307RTC Read Test
-------------------
Ok, Time = 08:24:25, Date (D/M/Y) = 12/4/2015
Ok, Time = 08:24:26, Date (D/M/Y) = 12/4/2015

Итак, понимания работы I2C не появилось. Как задается ID модуля? Почему используются аналоговые пины?