КОРЗИНА
магазина
8 (499) 500-14-56 | ПН. - ПТ. 12:00-18:00
ЛЕСНОРЯДСКИЙ ПЕРЕУЛОК, 18С2, БЦ "ДМ-ПРЕСС"

Электромеханическая семисегментная цифра

Общие сведения

Набор Сделай сам №10 - «Механический циферблат» — набор для сборки электромеханической семисегментной цифры. Может быть использован как в одиночном экземпляре, так и в составе из нескольких штук. В наборе есть всё необходимое для сборки одной семисегментной цифры, которую можно подключить либо напрямую к Aruduino, либо при помощи модулей Расширителей выводов

Для подключения сервоприводов дополнительно понадобится:

Оборудование:

Библиотеки:

Подключение сервоприводов

Установим Trema Shield на Piranha UNO

Подключим модули

Подключим сервоприводы согласно следующей таблице:

Сегмент Расширитель Вывод
A нечет 1
B нечет 2
C чет 0
D чет 1
E чет 2
F нечет 0
G нечет 3

Для удобства сборки рекомендуем подписать сервоприводы соответствующими буквами

Сборка механики

Перед установкой сервоприводов необходимо запустить калибровочный скетч.

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

// Подключаем библиотеку для работы с аппаратной шиной I2C, до подключения библиотеки iarduino_I2C_Expander.
#include <Wire.h>
// Подключаем библиотеку для работы с модулями расширителей выводов.
#include <iarduino_I2C_Expander.h>

// Подключаем файл с объектом механических часов.
#include <MechaClock.h>

// Создаём массив объектов библиотеки расширителя выводов, указывая адреса
// (не забудьте устонавить адреса расширителей)
iarduino_I2C_Expander gpio[2]{9, 10};

/* Сегменты

      _a
    f|_|b
    e|g|c
     d^
 */

/* Калибровка сервоприводов */

//!!! Сегменты E и B работают в обратном направлении !!!

// Положение ВКЛ. сегментов
uint8_t ON[DIGITS][SEGMENTS] {
    {
    //  g   f   e   d   c   b   a
        90, 10, 90, 10, 10, 90, 10
    }
};

// Положение ВЫКЛ. сегментов
uint8_t OFF[DIGITS][SEGMENTS] {
    {
    //  g   f   e   d   c   b   a
        10, 90, 10, 90, 90, 10, 90
    }
};

Digit myDigit;

// Функция очистки буфера последовательного порта
void discardSerial()
{
    while(Serial.available())
        Serial.read();
}

void setup()
{
    Serial.begin(9600);
    delay(500);

    Serial.println(F("Скетч калибровки сервоприводов механических часов."));
    Serial.println();
    Serial.println(F("Адреса расширителей выводов в десятеричной системе:"));

    bool flag = false;
    for (auto& i:gpio) {

        if(i.begin()) {

            Serial.print(i.getAddress());
            Serial.print("\t");
        }
        else {

            Serial.print("failed");
            Serial.print("\t");
            flag = true;
        }
    }

    Serial.println();

    if (flag) {
        Serial.println(
                F("Один из расширителей не обнаружен."
                " Проверьте подключение и адрес "
                "модуля и запустите скетч заново.")
                  );
        goto exit;
    }

    myDigit = Digit(gpio, 0);
    myDigit.set('8');

    Serial.println(
            F("Все сервоприводы сегментов установлены в положение\r\n"
            "ВКЛ. Если вы уже выполняли это шаг, пропустите его\r\n"
            ", если нет, отключите питание и установите качалки\r\n"
            "сервоприводов и сегменты цифр. Качалки должны\r\n"
            "\"смотреть\" на сколько это возможно вверх от \r\n"
            "оснований (цифры показывают восьмёрки)")
            );

    delay(1000);

    Serial.println();

    Serial.println(F("Карта сегментов:"));
    Serial.println();

    Serial.println(F("      A"));
    Serial.println(F("    #####"));
    Serial.println(F("   #     #"));
    Serial.println(F(" F #     # B"));
    Serial.println(F("   #  G  #"));
    Serial.println(F("    #####"));
    Serial.println(F("   #     #"));
    Serial.println(F(" E #     # C"));
    Serial.println(F("   #  D  #"));
    Serial.println(F("    #####"));
    Serial.println();

    Serial.println(
            F("Для продолжения введите любой символ в поле ввода"
            " и нажмите \"Отправить\" или <Enter>.")
              );

    while(!Serial.available());

    Serial.println(F("Начинаем процесс калибровки. Для выхода из калибровки"
            " введите \"exit\" и нажмите <Enter> или \"Отправить\""));

    Serial.println(F("Для дострочного вывода углов сервоприводов и выхода"
            " введите \"printout\" и нажмите <Enter> или \"Отправить\""));

    delay(2000);

    uint8_t dig = 0;
    uint8_t seg = SEGMENTS;

    char current_seg = 'A';

    do {
        Serial.println("Калибруем сегмент"
                + String(current_seg) + " "
                + String(dig+1)
                + "-й цифры");

        uint8_t on_deg = 0;

        if (current_seg == 'B' || current_seg == 'E')

            Serial.println(F("Угол сервопривода этого сегмента должен"
                    "быть ближе к 90 градусам в положении ВКЛ."));

        else

            Serial.println(F("Угол сервопривода этого сегмента должен"
                    "быть ближе к 0 градусам в положении ВКЛ."));

        Serial.print(F("текущее значение: "));
        Serial.println(ON[dig][seg-1]);

        Serial.println(
                F("Введите новое значение... (если калибровка"
                " текущего сегмента закончена, введите \"n\""
                " и нажмите <Enter> или \"Отправить\")")
                  );

        // Опустошаем буфер последовательного порта
        discardSerial();

        // Ждём ввода пользователя
        while(!Serial.available());

        // Читаем введённые данные
        String s = Serial.readStringUntil('\n');

        // Удаляем непечатные символы
        s.trim();

        // Выходим из калибровки по желанию
        if (s == "exit")

            goto exit;

        // Переходим к следующему сегменту
        else if (s == "n") {

            seg--;
            current_seg++;
        }

        else if (s == "printout")

            goto printout;

        // Записываем новые показания в массив
        else {
            on_deg = uint8_t(s.toInt());
            ON[dig][seg-1] = on_deg;
            myDigit.set('8');
        }

        if (seg == 0) {
            dig++;
            seg = SEGMENTS;
            current_seg = 'A';
        }

    } while(dig != 1);

printout:

    Serial.println();
    Serial.println(F("Калибровка завершена."));
    Serial.println();

    Serial.println(F("Замените следующие данные в скетче"
               " управления одной цифрой:"));
    Serial.println();

    Serial.println(F("uint8_t ON[DIGITS][SEGMENTS] {"));
    Serial.println(F("\t{"));

    //int k = 1;

    Serial.println(F("\t//\tg    f    e    d    c    b    a"));
    Serial.print("\t\t");

    bool first_seg = true;
    for (auto& j:ON[0]) {
        if (!first_seg)
            Serial.print(",  ");
        first_seg = false;
        Serial.print(j);
    }

    Serial.println();
    Serial.println("\t}");
    Serial.println("};");

exit:
    Serial.println();
    Serial.println(F("Выходим из калибровки."));

    // "Отпускаем все серво"
    myDigit.release();
}

void loop()
{
    delay(1000);
}

Сборка корпуса

Установите все сервоприводы в раму, как показано на рисунке:

После установки сервоприводов, установите раму на основание и соберите корпус:

Примеры

Скетч для одной цифры

Данный скетч выводит цифры от 0 до 9 на электромеханическую цифру.

// Подключаем библиотеку для работы с аппаратной шиной I2C, до подключения библиотеки iarduino_I2C_Expander.
#include <Wire.h>
// Подключаем библиотеку расширителей выводов
// (Она должна быть подключена до бибилотеки механических часов!)
#include <iarduino_I2C_Expander.h>

// Подключаем библоитеку механических часов
#include <MechaClock.h>

// Создаём массив объектов расширителей выводов, указывая их адреса
iarduino_I2C_Expander gpio[]{9, 10};

// Создаём объект цифры
Digit myDigit;

// Положение ВКЛ. сегментов. Сюда необходимо вставить результат калибровки
uint8_t ON[DIGITS][SEGMENTS] {
    {
    //  g   f   e   d   c   b   a
        90,  5,  92,  2,  0,  98, 10
    }
};

// Положение ВЫКЛ. сегментов
uint8_t OFF[DIGITS][SEGMENTS] {
    {
    //  g   f   e   d   c   b   a
        20, 90, 10, 90, 90, 10, 90
    }
};

void setup()
{
    // Инициируем расширители выводов
    for (auto& i:gpio) {
        i.begin();
    }

    /* Инициируем объект цифры передавая указатель на массив объектов
     * расширителей выводов в первом параметре и номер цифры. В данном
     * случае у нас одна цифра, поэтому её порядковый номер 0.
     */
    myDigit = Digit(gpio, 0);
}

void loop()
{
    for (size_t i = 0; i < 10; i++) {
        myDigit.set('0' + i);
        delay(1000);
    }
}

Скетч для нескольких цифр

Скетч выводит секунды до 99 с момента перезагрузки микроконтроллера

#include <Wire.h>
#include <iarduino_I2C_Expander.h>
#include <MechaClock.h>

// Интервал переключения сегментов в мс
#define INTERVAL 0

// количество цифр
#define DIG_NUM 2

// Создаём массив объектов расширитерей выводов, указывая адреса в десятиричной
// системе счисления
iarduino_I2C_Expander gpio[]{9, 10, 11, 12};

// Если у вас три цифры - установите соответсвующие адреса на дополнительных расширителях выводов
// и укажите их при создании объектов, например:
// iarduino_I2C_Expander gpio[]{9, 10, 11, 12, 13, 14};


// Положение ВКЛ. сегментов
uint8_t ON[DIGITS][SEGMENTS] {
    { // Углы сервоприводов первой цифры
    //  g   f   e   d   c   b   a
        10, 10, 90, 10, 10, 90, 10
    },
    { // Углы сервоприводов второй цифры
    //  g   f   e   d   c   b   a
        10, 10, 90, 10, 10, 90, 10
    }
};

// Положение ВЫКЛ. сегментов
uint8_t OFF[DIGITS][SEGMENTS] {
    {
    //  g   f   e   d   c   b   a
        90, 90, 10, 90, 90, 10, 90
    },
    {
    //  g   f   e   d   c   b   a
        90, 90, 10, 90, 90, 10, 90
    }
};

Display myDisp(gpio, INTERVAL, DIG_NUM);

void setup()
{
    Serial.begin(9600);

    while(!Serial);

    for (auto& i:gpio) {
        i.begin();
    }
}

void loop()
{
    // Выводим цифры раз в секунду...
    for (size_t i = 0; i < 100; i++) {

        /* Если у Вас меньше 4-х цифр, в функцию print необходимо
           передать второй параметр. В случае с двумя цифрами это
           POS2, в случае с тремя - POS3. Если Вы используете 4
           цифры, то можно не передавать второй параметр. Если
           Вам необходимо использовать больше 4-х цифр -
           свяжитесь с нами: [email protected] */
        myDisp.print(i, POS2);

        delay(1000);
    }
}

Ссылки




Обсуждение

Гарантии и возврат Используя сайт Вы соглашаетесь с условями