Начало работы с STM32 в Keil MDK-ARM

Статья посвящается Пановой Ксении.

Все картинки в этой статье кликабельны.

STM32 — это семейство 32-разрядных микроконтроллеров фирмы STMicroelectronics.

Микроконтроллеры содержат микропроцессорное ядро ARM, точнее ARM Cortex-M. Это ядро присуще не только микроконтроллерам STM32, оно существует само по себе, и на его основе выпускается множество микроконтроллеров от разных производителей.

Keil MDK-ARM (произносится «Кеил эм-ди-кей арм») — это среда разработки для микроконтроллеров с ядром ARM Cortex-M.

Читать далее Начало работы с STM32 в Keil MDK-ARM

Реклама

Настройка общей папки в VirtualBox

В статье приводится способ настройки общей папки, когда на виртуальной машине установлен Linux, в частности Ubuntu 18.04.

Первым делом нужно установить дополнения гостевой ОС.

Подключение образа дополнений гостевой ОС в VirtualBox
Подключаем образ диска дополнений гостевой ОС.
Запускам установщик дополнений в появившемся окне.

В настройках виртуальной машины нужно выбрать общие папки. Нужно поставить галочки «Авто-подключение» и «Создать постоянную папку.»

VirtualBox выбор общей папки

После сохранения настроек, на рабочем столе виртуальной машины появится папка с префиксом sf_. Это и есть общая папка.

Но пока в эту папку нет доступа. Чтобы доступ появился, нужно добавить своего пользователя в группу vboxsf. Это делается в терминале с помощью следующей команды.

sudo usermod -a -G vboxsf <USERNAME>

Где вместо <USERNAME>, нужно указать ваше имя пользователя.

Доступ в папку откроется после перезагрузки виртуальной машины.

С++: Типобезопасное перечисление (enum class) в unordered_map

Это статья о языке программирования C++.

Элементы обычного перечисление (enum) запросто могут применяться в качестве ключа в unordered_map. Следующий пример показывает, как сопоставить элемент перечисления с текстовым значением.

#include <string>
#include <iostream>
#include <unordered_map>

enum Color { Red, Blue, Green, };

int main()
{
    std::unordered_map<int, std::string> colors{
        {Red, "Red"},
        {Blue, "Blue"},
        {Green, "Green"},
    };
    
    std::cout << colors.at(Red) << std::endl;
}

Выполнить код.

Этот пример выведет в консоль слово «Red». Заметьте, что тип ключа — int.

Такое перечисление не типобезопасно и устарело. Язык C++11 предоставляет типобезопасные перечисления (enum class). У такого перечисления для доступа к элементам надо указывать имя перечисления.

Ниже приведен пример типобезопасного перечисления.

enum class Month
{
    January,
    February,
    March,
    April,
    May,
    June,
    July,
    August,
    September,
    October,
    November,
    December,
};

Чтобы получить доступ к элементу January, нужно написать Month::January.

Элементы такого перечисления можно использовать в аналогичном unordered_map, но только с явным привидением типа с помощью static_cast. Пример:

int main()
{
    std::unordered_map<int, std::string> colors{
        {static_cast<int>(Month::January), "January"},
        {static_cast<int>(Month::February), "February"},
    };
    
    std::cout << colors.at(static_cast<int>(Month::January)) << std::endl;
}

Использование static_cast делает код громоздким.

Код ниже показывает, как создать unordered_map, у которого в качестве ключа элементы типобезопасного перечисления, и где не требуется приведение типа.

#include <string>
#include <iostream>
#include <unordered_map>

struct EnumClassHash
{
    template <typename T>
    std::size_t operator()(T t) const
    {
        return static_cast<std::size_t>(t);
    }
};

enum class Month
{
    January,
    February,
    March,
    April,
    May,
    June,
    July,
    August,
    September,
    October,
    November,
    December,
};

int main()
{
    std::unordered_map<Month, std::string, EnumClassHash> months{
        {Month::January,   "January"},
        {Month::February,  "February"},
        {Month::March,     "March"},
        {Month::April,     "April"},
        {Month::May,       "May"},
        {Month::June,      "June"},
        {Month::July,      "July"},
        {Month::August,    "August"},
        {Month::September, "September"},
        {Month::October,   "October"},
        {Month::November,  "November"},
        {Month::December,  "December"},
    };
    
    std::cout << months.at(Month::January) << std::endl;
}

Выполнить код.

Ключевую роль здесь играет класс EnumClassHash. Он указывается в качестве шаблонного параметра при объявлении unordered_map. Этот класс возвращает хеш от элемента перечисления, при чем делает это максимально эффективным способом. В качестве хеша выступает значение самого элемента перечисления.

Таким образом можно создавать сколько угодно unordered_map c различными перечислениями, используя один единственный класс EnumClassHash. Иначе пришлось бы в пространстве имен std определять хеш-функцию для каждого перечисления.

Данный способ почерпнут в одном вопросе на StackOverflow.

Быстрая ручная нарезка провода МГТФ

Установка Time Doctor на Ubuntu 18.04

На данный момент нет версии Time Doctor для недавно вышедшей Ubuntu 18.04.

В инструкции приведен способ установки Time Doctor для Ubuntu 16.04 на Ubuntu 18.04. Все действия выполняются в командной строке.

    1. Добавим репозитории от Ubuntu 16.04. Для этого создадим и откроем файл /etc/apt/sources.list.d/ubuntu16_04.list следующей командой:
      sudo nano /etc/apt/sources.list.d/ubuntu16_04.list
    2. Вставим в файл следующий список репозиториев:
      deb http://ru.archive.ubuntu.com/ubuntu/ xenial main restricted
      deb http://ru.archive.ubuntu.com/ubuntu/ xenial-updates main restricted
      deb http://ru.archive.ubuntu.com/ubuntu/ xenial universe
      deb http://ru.archive.ubuntu.com/ubuntu/ xenial-updates universe
      deb http://ru.archive.ubuntu.com/ubuntu/ xenial multiverse
      deb http://ru.archive.ubuntu.com/ubuntu/ xenial-updates multiverse
      deb http://ru.archive.ubuntu.com/ubuntu/ xenial-backports main restricted universe multiverse
      deb http://security.ubuntu.com/ubuntu xenial-security main restricted
      deb http://security.ubuntu.com/ubuntu xenial-security universe
      deb http://security.ubuntu.com/ubuntu xenial-security multiverse
      
    3. Сохраним файл комбинацией клавиш Ctrl+O и закроем комбинацией Ctrl+X.
    4. Обновим базу пакетов следующей командой:
      sudo apt update
    5. Установим зависимости следующей командой:
      sudo apt install libssl1.0-dev libx11-xcb1 libxcb1 libssl1.0.0 libqtcore4 libqtgui4 libqt4-dbus libqt4-network libqt4-sql libqt4-sql-sqlite libqt4-svg libqt4-xml libqt4-xmlpatterns gksu gdebi libjpeg8 libpng12-0 libcv2.4 libxcb-record0
      
    6. Качаем Time Doctor для Ubuntu 16.04 c официального сайта.
    7. Устанавливаем скаченный пакет следующей командой (название файла можем отличаться):
      sudo dpkg -i timedoctorlite_2.3.49-14ubuntu16.04_amd64.deb
    8. Пакет должен успешно установиться.
    9. Запускаем Time Doctor и проверяем, что все работает. Запустить можно следующей командой (если у вас Lite-версия):
      timedoctorlite
    10. Восстанавливаем исходное состояние пакетов в системе
      sudo rm /etc/apt/sources.list.d/ubuntu16_04.list
      sudo apt update
    11. Ставим лайк статье, если она оказалась полезной. Или пишем в комментариях, что у вас не получилось.

Получение пользовательского токена от eBay

В статье описывается:

  • Взаимодействие продавца с сайтом приложения и с сайтом eBay для предоставления приложению токена.
  • Получение токена приложением.
    1. Продавец заходит на сайт приложения и нажимает кнопку “Войти” или иным способом сообщает приложению, что намеревается им воспользоваться.
    2. Приложение отправляет к eBay запрос GetSessionID, в котором указывает URL для перенаправления. Приложение получает в ответ SessionID, который будет идентифицировать продавца, когда он войдет на eBay. Примеры запроса GetSessionID.
    3. Приложение перенаправляет пользователя на страницу входа eBay. URL этой страницы формируется с использованием SessionID и URL для перенаправления. Формат формируемого URL следующий:
    4. Продавец входит на eBay.
      Форма входа eBay
    5. eBay перенаправляет продавца на форму подтверждения, чтобы он дал согласие на предоставление доступа приложению. Вид формы определяется настройками.
    6. Когда продавец кликает кнопку “I agree”, eBay перенаправляет его по адресу, который указан в настройках в поле “Your auth accepted URL”.
    7. Когда продавец попадает по этому адресу, приложение посылает к eBay запрос FetchToken, содержащий SessionID, и в ответ получает токен. Примеры запроса FetchToken. Это один из немногих запросов, который требует учетные данные приложения. То есть, чтобы сделать запрос, приложение должно добавить в HTTP-заголовок следующие данные: App ID, Dev ID и Cert ID.
      Для большинства других запросов учетные данные не требуются. Вместо них приложение добавляет токен в RequesterCredentials. Если используется SOAP, то RequesterCredentials должен быть в заголовке SOAP. Если используется XML, то RequesterCredentials включается в тело запроса. Дополнительные сведения см. в разделе Security на странице Making a Trading API Call.
    8. Запрос FetchToken возвращает приложению пользовательский токен продавца и срок годности токена. Приложение сохраняет эти данные для дальнейшего использования.
    9. Приложение делает запрос GeteBayOfficialTime, чтобы проверить новый токен.

Ссылки

  1. Оригинальная статья Getting a Token for a User.

 

Минимальный проект «Hello, World!» с помощью Java и Gradle

Gradle — это набирающая популярность система автоматической сборки проектов на языке Java.

Проект должен содержать минимум два файла:

  • build.gradle — файл конфигурации сборки Gradle.
  • Файл с исходным кодом на языке Java, например Main.java.

Важна структура папок. build.gradle должен находиться в корневой папке проекта. Файл Main.java должен находиться в папке «src/main/java».

Структура проекта должна быть, как на следующей картинке.
Java Gradle Project Structure

Содержимое файла Main.java следующее.

public class Main {
    public static void main (String[] args) {
        System.out.println("Hello, world!");
    }
}

Содержимое файла build.gradle следующее.

apply plugin: 'java'
apply plugin: 'application'

mainClassName = 'Main'

jar {
    manifest {
        attributes 'Main-Class': mainClassName
    }
}

В этом файле подключаются плагины, которые предоставляет все необходимо для сборки. Кроме того, в файле указывается точка входа программы — это класс Main.

Проект собирается командой gradle build, которую нужно выполнить в папке проекта. После чего создается папка build/libs, в которой можно найти исполняемый jar-файл.

Запустить программу можно следующей командой.

java -jar build/libs/project_name.jar

Или с помощью Gradle следующей командой.

gradle run

Такой проект можно открыть в IDE NetBeans. Для этого в NetBeans должен быть установлен плагин Gradle Support. Чтобы установить плагин, нужно запустить меню Tools -> Plugins и в диалоговом окне найти Gradle Support.

Успехов.

Аргументы командной строки в разных языках программирования

C и C++

int  main(int argc, char* argv[])
{
    argc;    // количество аргументов + 1
    argv[0]; // имя программы
    argv[1]; // первый аргумент
    argv[2]; // второй аргумент
    // ...
}

Bash

#!/bin/bash

# $# — количество аргументов
#
# $* — аргументы одной строкой
# $@ — список аргументов

echo $0    # имя скрипта
echo $1    # первый аргумент
echo $2    # второй аргумент
# ...
echo $9    # девятый аргумент
echo $(10) # десятый аргумент
echo $(11) # одиннадцатый аргумент
# ...

Cmd.exe

echo %0 REM имя срипта
echo %1 REM первый аргумент
echo %2 REM первый аргумент
REM ...
echo %9 REM девятый аргумент

Python

import sys

sys.argv      # список аргументов
len(sys.argv) # количество аргументов + 1
sys.argv[0]   # имя скрипта
sys.argv[1]   # первый аргумент
sys.argv[2]   # второй аргумент
# ...

Java

public class CommandLine {
    static public void main(String args[]) {
        args.length; // количество аргументов
        args[0];     // первый аргумент
        args[1];     // второй аргумент
        // ...
    }
}

C Sharp

class MainClass
{
    static int Main(string[] args)
    {
        args.Length; // количество аргументов
        args[0];     // первый аргумент
        args[1];     // второй аргумент
        // ...
    }
}

Вывод функций ЛАЧХ и ЛФЧХ в программе Maxima

Maxima — это консольная математическая программа для аналитических расчетов. Программа имеет версию с графическим интерфейсом, которая называется wxMaxima, ее можно бесплатно скачать с официального сайта.

Допустим имеется передаточная функция W(s) . Нужно получить две функций:

  • L(\omega) — ЛАЧХ (логарифмическая амплитудная частотная характеристика),
  • \Phi(\omega) — ЛФЧХ (логарифмическая фазовая частотная характеритиска),

где: \omega — угловая частота, рад/с.

Пример расчет ЛАЧХ и ЛФЧХ для передаточной функции апериодического звена второго порядка.


/* Передаточная функция */
W(s) := k/((1 + T[3]*s)*(1+T[4]*s)) $

/* Функция десятичного логарифма */
log10(x) := log(x) / log(10) $

print("ЛАЧХ") $
L(%omega) = 20 * log(cabs(W(%i*%omega)));

print("ЛФЧХ") $
%Phi(%omega) = carg(W(%i*%omega));

Вывод программ следующий.

ЛАЧХ

\mathrm{L}\left( \omega\right) =20\cdot \mathrm{log}\left( \frac{\left| k\right| }{\sqrt{{{T}_{3}^{2}}\cdot {{\omega}^{2}}+1}\cdot \sqrt{{{T}_{4}^{2}}\cdot {{\omega}^{2}}+1}}\right)

ЛФЧХ

\Phi\left(\omega\right) =-\mathrm{atan}\left( {{T}_{4}}\cdot \omega\right) -\mathrm{atan}\left( {{T}_{3}}\cdot \omega\right) +\mathrm{atan2}\left( 0,k\right)

В окне программы расчет выглядит следующим образом.

Вывод функций ЛАЧХ и ЛФЧХ в программе Maxima

Для тех, кто никогда не пользовался программой, объясню, что тут происходит. С помощью /* */ можно оставлять комментарии.

Сначала задается передаточная функция W(s) . Затем задается функция десятичного логарифма, потому что, к сожалению, она отсутствует в программе.

  • %i — мнимая единица.
  • %Phi — греческая буква \Phi
  • %omega — греческая буква \omega
  • функция cabs() возвращает модуль комплексного числа.
  • функция carg() возвращает аргумент комплексного числа.

Раскрой коробки картонной четырехклапанной

Любая прямоугольная коробка имеет 3 размера, 2 из которых образуют сторону с клапанами. Возможно 3 варианта раскроя для одних и тех же размеров, в зависимости от стороны с клапанами. Разные варианты имеют разные габариты и разные площади раскроя. С помощью расчета нужно подобрать вариант для оптимального расходования листов картона.

Коробка

Картонная коробка с размерами

Размеры a и b образуют сторону с клапанами.

Размер d должен быть достаточным для надежного склеивания коробки, например 5 см. Картон надежно склеивается клеем ПВА.

Должно соблюдаться условие:

b \geq a

На изображениях в статье не учитывается толщина картона.

Раскрой на одном листе картона

Раскрой развертка картонной коробки

Обязательное условие:

b \geq a

Размеры минимального листа картона рассчитываются по следующим формулам.

E = 2 (a + b) +d

F = c + a

Раскрой на двух листах картона

Если нет достаточно большого листа картона, то коробку можно сделать из двух небольших листов картона. В этом случае будет два хвоста для склейки.

Раскрой развертка картонной коробки из двух половин

Обязательное условие:

b \geq a

Размеры минимального листа картона рассчитываются по следующим формулам.

G = a + b +d

F = c + a

Таблица для расчета раскроя

Пример расчета раскроя опубликован в Гугл Таблицах. Рассчитывается 3 варианта раскроя в зависимости от стороны расположения клапанов. Можете создать копию документа (Файл -> Создать копию) и подставить свои размеры коробки.

 

 

Ввод символа рубля с клавиатуры

В Линуксе можно настроить специальную клавишу Compose, которая упрощает ввод символов, которых нет на клавиатуре.

По умолчанию определен ввод многих символов, но пока среди них нет символа рубля ₽.

Чтобы вводить символ рубля комбинаций клавиш Compose дефис p (английская), запустите в терминале следующую команду.

echo -e 'include "%L"\n<Multi_key><minus><p>:"₽"' > ~/.XCompose

Эта команда создаст в домашней папке файл .XCompose с определенным содержимым. Ввод символа будет доступен только пользователю, которому принадлежит эта домашняя папка.

Если файл .XCompose уже существует, то следует использовать следующую команду.

echo -e '\n<Multi_key><minus><p>:"₽"' >> ~/.XCompose

Удачи!