четверг, 1 октября 2015 г.

Редактор для светодиодной матрицы 8x8

Я хотел бы представить мой новый мини-проект LED Matrix Editor созданный для тех, кто реализует световые табло на Arduino и, конечно, для всех тех, кто интересуется Arduino.

Это онлайн редактор для создания анимаций для светодиодных точечных матриц.

Screenshot редактора для LED матриц

Данный редактор имеет ряд полезных функций, которые отличают его от подобных программ:

  • не требует установки: редактирование и сохранение происходит онлайн;
  • рисунок создается прямо в браузере при помощи мышки;
  • заполнение строки/столбца матрицы одним кликом мышки;
  • возможность сдвигать рисунок влево/вправо, вверх/вниз одним кликом мышки;
  • возможность инвертирования и очистки кадра;
  • возможность перемещения кадра готовой анимации, которая покадрово сохраняется в нижней панели экрана;
  • возможность редактирования и обновления уже созданного кадра, а также удаление кадров;
  • сохранение кадров в виде кода Си для Arduino;
  • возможность использования "истории" браузера и сохранения анимации в виде ссылки или закладки;
  • встроенный набор ASCII символов;
  • ссылки на статьи с примерами кода.

Я надеюсь, что вы найдете мою программку полезной, и удобной в использовании.

Предположим, что у вас есть LED матрица (выполненная на чипе MAX7219) подобная этой:

*Чип MAX7219 действительно очень неплох; к тому же, для него есть хорошая библиотека LedControl для Arduino.

После того, как вы, используя онлайн редактор, создадите анимацию, необходимо скопировать и вставить сгенерированный редактором код в Arduino IDE:

#include <LedControl.h>

const int DIN_PIN = 7;
const int CS_PIN = 6;
const int CLK_PIN = 5;

const uint64_t IMAGES[] = {
  0x3e2222223e3e0808, 0x3e22223e3e2a0808, 0x3e223e3e2a2a0808, 0xbe3e3e2a2a2a0808,
  0xbe223e3e2a2a0808, 0xbe22223e3e2a0808, 0xbe2222223e3e0808, 0xbe22223e3e2a0808,
  0xbe223e3e2a2a0808, 0xbebe3e2a2a2a0808, 0xbea23e3e2a2a0808, 0xbea2223e3e2a0808,
  0xbea222223e3e0808, 0xbea2223e3e2a0808, 0xbea23e3e2a2a0808, 0xbebebe2a2a2a0808,
  0xbea2be3e2a2a0808, 0xbea2a23e3e2a0808, 0xbea2a2223e3e0808, 0xbea2a23e3e2a0808,
  0xbea2be3e2a2a0808, 0xbebebeaa2a2a0808, 0xbea2bebe2a2a0808, 0xbea2a2be3e2a0808,
  0xbea2a2a23e3e0808, 0xbea2a2be3e2a0808, 0xbea2bebe2a2a0808, 0xbebebeaaaa2a0808,
  0xbea2bebeaa2a0808, 0xbea2a2bebe2a0808, 0xbea2a2a2be3e0808, 0xbea2a2bebe2a0808,
  0xbea2bebeaa2a0808, 0xbebebeaaaaaa0808, 0xbea2bebeaaaa0808, 0xbea2a2bebeaa0808,
  0xbea2a2a2bebe0808, 0xbea2a2a2a2be1c08, 0xbea2a2a2a2a21c1c, 0xbea2a2a2a222001c,
  0xbea2a2a22222001c, 0xbea2a2222222001c, 0xbea222222222001c, 0xbe2222222222001c,
  0x3e2222222222001c, 0x3e2222222222001c, 0x3e22222222221c1c, 0x3e222222223e1c08
};
const int IMAGES_LEN = sizeof(IMAGES) / sizeof(uint64_t);

LedControl display = LedControl(DIN_PIN, CLK_PIN, CS_PIN);


void setup() {
  display.clearDisplay(0);
  display.shutdown(0, false);
  display.setIntensity(0, 10);
}

void displayImage(uint64_t image) {
  for (int i = 0; i < 8; i++) {
    byte row = (image >> i * 8) & 0xFF;
    for (int j = 0; j < 8; j++) {
      display.setLed(0, i, j, bitRead(row, j));
    }
  }
}

int i = 0;

void loop() {
  displayImage(IMAGES[i]);
  if (++i >= IMAGES_LEN ) {
    i = 0;
  }
  delay(100);
}

Компилируем, загружаем и наслаждаемся:

вторник, 29 сентября 2015 г.

Arduino: управление 8-канальным релейным модулем с ПДУ

Arduino поможет реализовать управление домашней электроникой с пульта дистанционного управления: выключение света сразу во всех помещениях, открытие/закрытие штор или роллетов нажатием одной кнопки на ПДУ. Для осуществления этого понадобятся следующие компоненты:

Соединяем:

Arduino, 8-channel relay, IR remote control

Загружаем код для платы Arduino:

#include <IRremote.h>

const int IR_PIN = 2;

const int RELAY_PINS[8] = {12, 11, 10, 9, 8, 7, 6, 5};
int RELAY_STATES[8] = {LOW};

IRrecv irrecv(IR_PIN);

decode_results results;

void setup() {
  irrecv.enableIRIn();

  for (int i = 0; i < 8; i++) {
    pinMode(RELAY_PINS[i], OUTPUT);
  }
}

/**
 * Decode IR code to numeric button 0-9
 * Return pressed button number or -1
 */
int samsungDecode(unsigned long irValue) {
  switch (irValue) {
    case 0xE0E020DF:
      return 1;
    case 0xE0E0A05F:
      return 2;
    case 0xE0E0609F:
      return 3;
    case 0xE0E010EF:
      return 4;
    case 0xE0E0906F:
      return 5;
    case 0xE0E050AF:
      return 6;
    case 0xE0E030CF:
      return 7;
    case 0xE0E0B04F:
      return 8;
    case 0xE0E0708F:
      return 9;
    case 0xE0E08877:
      return 0;
  }
  return -1;
}

/**
 * Toggle single relay or switch ON/OFF all relays
 */
void action(int button) {
  if (button > 0 && button < 9) {
    //toggle single relay
    int i = button - 1;
    if (RELAY_STATES[i] == LOW) {
      digitalWrite(RELAY_PINS[i], HIGH);
      RELAY_STATES[i] = HIGH;
    } else {
      digitalWrite(RELAY_PINS[i], LOW);
      RELAY_STATES[i] = LOW;
    }
  } else if (button == 9) {
    //switch ON all relays
    for (int i = 0; i < 8; i++) {
      digitalWrite(RELAY_PINS[i], HIGH);
      RELAY_STATES[i] = HIGH;
    }
  } else if (button == 0) {
    //switch OFF all relays
    for (int i = 0; i < 8; i++) {
      digitalWrite(RELAY_PINS[i], LOW);
      RELAY_STATES[i] = LOW;
    }
  }
}

int lastPressedButton = -1;

void loop() {
  if (irrecv.decode(&results)) {
    int button = samsungDecode(results.value);
    if (button != lastPressedButton) {
      lastPressedButton = button;
      action(button);
    }
    irrecv.resume();
  } else {
    lastPressedButton = -1;
  }
  delay(250);
}

и наслаждаемся нажатием кнопок:

Кнопки 1-8 пульта управляют включением/выключением реле 1-8; кнопка 9 пульта одновременно включает все реле, а кнопка 0 пульта одновременно выключает все реле.

В предыдущей статье Arduino: считывание кодов с пульта дистанционного управления я выяснил коды для моего пульта Samsung, которые использовал здесь. Если у вас другой пульт, то для реализации потребуется считать его коды.

понедельник, 28 сентября 2015 г.

Arduino: считывание кодов с пульта дистанционного управления

Существует огромное множество различных пультов дистанционного управления: для ТВ, DVD или другой техники. Практически любой из них можно использовать для Arduino. Нужен только инфракрасный датчик и программа, сканирующая передаваемые пультом коды.

Пульты управления, при общении со своим устройством, используют различные наборы кодов, поэтому, для начала необходимо определить код каждой кнопки пульта. Это просто. Подключаем инфракрасный датчик к Arduino:

Arduino Uno + IR sensor

и выполняем эту программу:

#include <IRremote.h>

const int IR_PIN = 10;

IRrecv irrecv(IR_PIN);

decode_results results;

void setup() {
  Serial.begin(9600);  
  irrecv.enableIRIn();
}

char chars[9] = {};

void loop() {
  if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);
    irrecv.resume();
  }
  delay(100);
}

*В программе используется IRremote library.

Открываем монитор последовательного интерфейса среды разработки Arduino (serial monitor), нажимаем необходимые клавиши на ПДУ и на выходе видим:

Serial print scanned codes

Программа вывела коды для нажатых клавиш. Для примера, пульт от Samsung SmartTV использует такие коды для своих кнопок:

  • E0E020DF 1
  • E0E0A05F 2
  • E0E0609F 3
  • E0E010EF 4
  • E0E0906F 5
  • E0E050AF 6
  • E0E030CF 7
  • E0E0B04F 8
  • E0E0708F 9
  • E0E08877 0

суббота, 26 сентября 2015 г.

Arduino: вывести значения аналогового датчика на LED дисплей

Ниже представлен довольно простой способ вывода значений аналогового датчика на LED дисплей. Для примера взят датчик света.

На собранном макете показан вывод значения освещенного датчика:

Output light sensor value to led display

и того же датчика в затемненном состоянии:

Output light sensor value to led display (closed)

Электронные компоненты, использованные в примере:

LED дисплей имеет 5 контактов:

  • DIN - data in (информационный вход)
  • CS - chip select (номер LED дисплея)
  • CLK - clock pulse source (источник тактовых импульсов)
  • GND - земля
  • 5 V - питание

DIN, CS и CLK подключаются к Arduino через контакты 7, 6 и 5, соответственно.

Датчик света имеет 3 контакта:

  • GND
  • 5V
  • Signal

Signal подключается к Arduino на аналоговый контакт 1.

Эта программа считывает данные сенсора 10 раз в секунду и отображает усредненный результат:

#include <LedControl.h>

const int DIN_PIN = 7;
const int CS_PIN = 6;
const int CLK_PIN = 5;

const int SENSOR_PIN = 1;

LedControl display = LedControl(DIN_PIN, CLK_PIN, CS_PIN);

void setup() {
  display.clearDisplay(0);
  display.shutdown(0, false);
  display.setIntensity(0, 10);
}

void displayNumber(int number) {
  display.clearDisplay(0);
  for (int i = 0; i < 8; i++) {
    int digit = number % 10;
    number /= 10;
    display.setDigit(0, i, digit, false);
    if (number == 0) {
      break;
    }
  }
}

void loop() {
  int value = 0;
  for (int i = 0; i < 10; i++) {
    value += analogRead(SENSOR_PIN);
    delay(100);
  }
  value /= 10;

  displayNumber(value);
}

вторник, 21 июля 2015 г.

Arduino: вывести несколько чисел на LED дисплей

В предыдущей статье рассказывалось о том, как вывести число вот на такой светодиодный дисплей:
Но очень хочется выводить сразу несколько чисел на один дисплей (например: температуру и влажность, или расстояние и время). Это довольно просто запрограммировать на Си.
Итак, как и в предыдущем примере, DIN, CS и CLK соединены с пинами 7, 9 и 8. Рабочий макет выглядит так:



В данном примере реализовано два счётчика: один двухразрядный, второй пятиразрядный (разряды десятичные). Первый счётчик увеличивается от 0 до 99, и сбрасывается при достижении максимального значений. Второй - уменьшается с 99999 до 0, и сбрасывается после минимума. В каждом цикле на цифровой дисплей выводится одновременно оба числа, а разделителем служит пустое знакоместо между ними.
Пример кода:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <LedControl.h>

#define dinPin 7
#define clkPin 8
#define csPin 9

LedControl display = LedControl(dinPin, clkPin, csPin);

void setup() {
  display.clearDisplay(0);
  display.shutdown(0, false);
  display.setIntensity(0, 10);
}

void displayString(const char *chars8) {
  display.clearDisplay(0);
  for (int i = 0; i < 8 && chars8[i] != 0; i++) {
    display.setChar(0, 7 - i, chars8[i], false);
  }
}

int counter1 = 0;
long counter2 = 99999;

char chars[9] = "12345678";

void loop() {

  snprintf(chars, 9, "%-2d %5ld", counter1, counter2);
  displayString(chars);

  counter1++;
  counter2--;

  if (counter1 > 99) {
    counter1 = 0;
  }

  if (counter2 < 0) {
    counter2 = 99999;
  }

  delay(250);
}

В этом примере два числа вначале упаковываются в массив символов, а потом выводятся функцией displayString(). Для формирования строки используется функция snprintf(); она более безопасна, чем sprintf(). Первое число выравнивается по левому краю дисплея, второе - по правому.
Для работы этого кода необходима библиотека LedControl, о которой написано на официальном сайте Arduino.


Набор компонентов, используемых в этом примере:
LED дисплей на MAX7219 Arduino Nano Макетная плата

воскресенье, 19 июля 2015 г.

Arduino: вывести число на цифровой LED дисплей MAX7219

Для Arduino есть несколько типов светодиодных модулей для вывода чисел.
Например, вот такой 8-значный цифровой индикатор на микросхеме MAX7219:
Он подсоединяется к плате Arduino пятью пинами:
  1. DIN - data in
  2. CS - chip select
  3. CLK - clock pulse source
  4. GND
  5. 5 V

В данном примере элементы соединены вот так:


Здесь DIN, CS и CLK соединены с пинами 7, 9 и 8.

На сайте Arduino есть большая статья LedControl, в которой рассказывается о принципе управления светодиодными матрицами. Однако там нет простого примера показывающего, как вывести на дисплей не цифру, а число.

Код ниже рализует обычный счётчик, который увеличивает своё значение раз в секунду и выводит его на цифровой дисплей:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <LedControl.h>

#define dinPin 7
#define clkPin 8
#define csPin 9

LedControl display = LedControl(dinPin, clkPin, csPin);

void setup() {
  display.clearDisplay(0);
  display.shutdown(0, false);
  display.setIntensity(0, 10);
}

void displayNumber(int number) {
  display.clearDisplay(0);
  for (int i = 0; i < 8; i++) {
    int digit = number % 10;
    number /= 10;
    display.setDigit(0, i, digit, false);
    if (number == 0) {
      break;
    }
  }
}

int number = 9995;

void loop() {
  displayNumber(number++);
  delay(1000);
}

В данном примере для вывода числа используется функция displayNumber, которая записывает значение каждого десятичного разряда в соответствующий цифровой сегмент.
Для работы этого кода необходима библиотека LedControl.


Электронные компоненты, используемые в этом примере:
8-значный LED дисплей Arduino Nano Макетная плата

вторник, 3 февраля 2015 г.

Заземление металлических элементов брони кабеля связи на кабельном вводе


Заземление металлических элементов брони оптических кабелей связи на кабельном вводе в здание является обязательным при производстве работ. Особенно, если бронированные оптические кабели прокладываются по территории заказчика от одной площадки до другой, без выхода на городскую территорию. Например, на базах отдыха от главного здания до коттеджей. Так как в этих случаях, чаще всего, выбирается наименее дорогой кабель для канализации и грунта, с броней из стальных проволок, и, из-за стесненных условий, не осуществляется переход на станционный кабель после ввода в здание.

Для такого способа ввода кабеля в здание РД 45.155-2000 "Заземление и выравнивание потенциалов аппаратуры ВОЛП" регламентируется следующий вариант заземления металлических элементов:
Линейный оптический кабель прокладывается непосредственно до вводно-кабельного устройства без выполнения перехода его на станционный кабель. При этом оптический кабель (ОК) помещается в поливинидхроридную трубу из не поддерживающего горения материала. На участках, не защищенных трубой, на наружную оболочку ОК наносится дополнительное покрытие (выполняется обмотка поливинилхлоридной лентой).
На металлических бронепокровах ОК внутри помещения ввода кабелей, в непосредственной близости от водного канала, должен быть выполнен кольцевой разрыв на длине 100-150 мм. Линейная сторона бронепокрова медным проводом сечением не менее 4 мм2 подключается к кабельному щитку заземления через съемные перемычки или клеммный щиток согласно Рис. 1. Подключение, для обеспечения контроля состояния изолирующих шланговых покровов ОК, должно быть выполнено с возможностью временного электрического отключения бронепокровов ОК от кабельного щитка заземления.
Станционная сторона участка ОК подключается в оптическом оконечном устройстве к кольцевому потенциаловыравнивающему проводнику или, при отсутствии такового, к клемме защитного заземления. 
Рис.1 Схема ввода оптического кабеля в здание обслуживаемого объекта связи
1 - станционный колодец кабельной канализации; 2 - канал кабельной канализации; 3 - узел герметизации кабельного канала; 4 - ОК; 5 - помещение ввода кабелей; 6 - металлический бронепокров ОК; 7 - участок снятия бронепокрова ОК; 8 - дополнительное покрытие ОК; 9, 10 - проводник заземления; 11 - клеммный щиток; 12 - накладная муфта для упрочнения ОК на участке снятия бронепокрова.

Варианты кабельных щитков заземления:

Щиток заземления с изоляторами производства "Связьстройдеталь":






Или щиток заземления Щ-07003 и щиток изолирующий Щ-07004 производства "Волоконно-оптическая техника-ЮГ"