Сообщество - Arduino & Pi
Добавить пост

Arduino & Pi

1 378 постов 20 575 подписчиков

Популярные теги в сообществе:

Что же такое исключения в C++

Исключения в C++ - это механизм, который позволяет обнаруживать и обрабатывать ошибки во время выполнения программы. Исключения могут быть сгенерированы оператором throw или автоматически при возникновении некоторых ошибок, таких как деление на ноль, выход за границы массива или нехватка памяти. Исключения могут быть перехвачены и обработаны с помощью конструкции try…catch, которая определяет блок кода, в котором может произойти исключение, и блок кода, в котором исключение обрабатывается.

Исключения могут иметь различные типы, которые определяют характер ошибки и передают дополнительную информацию об исключении. Некоторые типы исключений являются стандартными и определены в библиотеке <stdexcept>. Основные из них:

  • logic_error: общий тип исключений, которые возникают из-за ошибок логики или программирования.

  • invalid_argument: исключение, которое возникает, когда аргумент функции недопустим или некорректен.

  • domain_error: исключение, которое возникает, когда аргумент функции выходит за пределы допустимого домена.

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

  • out_of_range: исключение, которое возникает, когда попытка доступа к элементу контейнера, который находится за его границами.

  • runtime_error: общий тип исключений, которые возникают во время выполнения из-за ошибок среды или системы.

  • range_error: исключение, которое возникает, когда результат операции выходит за пределы допустимого диапазона.

  • overflow_error: исключение, которое возникает, когда результат арифметической операции превышает максимально допустимое значение.

  • underflow_error: исключение, которое возникает, когда результат арифметической операции меньше минимально допустимого значения.

Кроме стандартных типов исключений, можно определять свои собственные типы исключений, наследуясь от класса exception или его потомков. Например:

#include <iostream>

#include <exception>

using namespace std;

// Определение собственного типа исключения

class MyException : public exception {

public:

// Переопределение метода what(), который возвращает сообщение об исключении

const char* what() const noexcept override {

return "My exception occurred";

}

};

// Функция, которая генерирует исключение типа MyException

void func() {

throw MyException();

}

int main() {

try {

func(); // Вызов функции, которая генерирует исключение

}

catch (MyException& e) { // Перехват исключения типа MyException

cout << e.what() << endl; // Вывод сообщения об исключении

}

return 0;

}

В этом примере определяется класс MyException, который наследуется от класса exception и переопределяет метод what(), который возвращает сообщение об исключении. Затем в функции func() генерируется исключение типа MyException с помощью оператора throw. В функции main() используется конструкция try…catch для перехвата и обработки исключения типа MyException. В блоке catch выводится сообщение об исключении с помощью метода what().

Исключения в C++ позволяют эффективно и безопасно обрабатывать ошибки в программе, а также разделять код, который может вызвать ошибку, от кода, который может ее обработать.

Интересные факты и фичи языков программирования у нас в канале, заходи :)

Показать полностью

Про мютексы в golang

Мьютекс в golang - это способ синхронизации доступа к общим ресурсам, которые могут быть одновременно использованы несколькими горутинами.

Мьютекс имеет два состояния:

  • Заблокирован

  • Разблокирован

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

Для работы с мьютексами в golang используется пакет sync, который предоставляет тип sync.Mutex. У мьютекса есть методы Lock() и Unlock(), которые позволяют блокировать и разблокировать доступ к общему ресурсу. Например, если у нас есть переменная counter, которая может быть изменена несколькими горутинами, то мы можем использовать мьютекс для защиты ее значения от гонки данных. Вот пример кода, который демонстрирует это:

package main

import (

"fmt"

"sync"

)

var counter int = 0 // общий ресурс

var mutex sync.Mutex // мьютекс

func main() {

ch := make(chan bool) // канал

for i := 1; i < 5; i++ {

go work(i, ch) // запускаем горутину

}

for i := 1; i < 5; i++ {

<-ch // ожидаем завершения горутины

}

fmt.Println("The End")

}

func work(number int, ch chan bool) {

mutex.Lock() // блокируем мьютекс

counter = 0 // сбрасываем значение счетчика

for k := 1; k <= 5; k++ {

counter++ // увеличиваем счетчик

fmt.Println("Goroutine", number, "-", counter) // выводим результат

}

mutex.Unlock() // разблокируем мьютекс

ch <- true // отправляем сигнал в канал

}

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

Интересные факты и фичи языков программирования у нас в канале, заходи :)

Показать полностью

Реализация собственного контейнера с помощью initializer_list

Initializer_list - это специальный класс шаблона, который представляет собой список инициализации, то есть набор значений, заключенных в фигурные скобки. Например, {1, 2, 3} - это список инициализации, который содержит три целых числа. Initializer_list позволяет передавать такие списки в качестве аргументов функций или конструкторов, а также использовать их для инициализации объектов различных типов, включая собственные контейнеры1.

Для того, чтобы реализовать собственный контейнер с помощью initializer_list, нужно выполнить следующие шаги:

  • Определить класс контейнера, который хранит элементы в некоторой структуре данных, например, в массиве, векторе или списке. Класс контейнера должен иметь методы для доступа, добавления и удаления элементов, а также другие операции, которые необходимы для работы с контейнером.

  • Определить конструктор контейнера, который принимает в качестве параметра объект типа initializer_list. В теле конструктора нужно скопировать элементы из initializer_list в структуру данных контейнера, используя методы begin() и end() для получения итераторов на начало и конец списка инициализации.

  • Определить оператор присваивания контейнера, который также принимает в качестве параметра объект типа initializer_list. В теле оператора нужно очистить старые данные контейнера и скопировать элементы из initializer_list в структуру данных контейнера, аналогично конструктору.

Вот пример реализации собственного контейнера, который хранит элементы в векторе:

#include <iostream>

#include <vector>

#include <initializer_list>

// Класс контейнера

template <typename T>

class MyContainer {

private:

std::vector<T> data; // Структура данных для хранения элементов

public:

// Конструктор по умолчанию

MyContainer() {}

// Конструктор, принимающий список инициализации

MyContainer(std::initializer_list<T> il) {

// Копирование элементов из списка инициализации в вектор

for (auto it = il.begin(); it != il.end(); ++it) {

data.push_back(*it);

}

}

// Оператор присваивания, принимающий список инициализации

MyContainer& operator=(std::initializer_list<T> il) {

// Очистка старых данных

data.clear();

// Копирование элементов из списка инициализации в вектор

for (auto it = il.begin(); it != il.end(); ++it) {

data.push_back(*it);

}

return *this;

}

// Метод для вывода элементов контейнера на экран

void print() const {

for (const auto& elem : data) {

std::cout << elem << " ";

}

std::cout << std::endl;

}

};

int main() {

// Создание объекта контейнера с помощью списка инициализации

MyContainer<int> c1 = {1, 2, 3, 4, 5};

c1.print(); // 1 2 3 4 5

// Присваивание контейнеру нового списка инициализации

c1 = {6, 7, 8, 9, 10};

c1.print(); // 6 7 8 9 10

return 0;

}

Интересные факты и фичи языков программирования у нас в канале, заходи :)

Показать полностью

Почему синтаксис языка C именно такой

Синтаксис языка C был разработан Деннисом Ритчи в 1970-х годах как упрощенная и универсальная версия языка B, который в свою очередь был основан на языке BCPL.

Почему синтаксис языка C именно такой Разработка, Программирование, Программист, IT, Инновации, Linux

Язык C был спроектирован так, чтобы быть близким к машинному коду и эффективно работать с памятью и процессором. Он также был вдохновлен некоторыми идеями из других языков, таких как ALGOL 68 и PL/I.

Синтаксис языка C характеризуется следующими особенностями:

  • Чувствительность к регистру. В языке есть встроенная поддержка числовых, символьных и строковых литералов, которые обрамляются кавычками.

  • Использование фигурных скобок для обозначения блоков кода и точки с запятой для разделения операторов.

  • Использование префиксной нотации для объявления переменных и функций, а также для указания их типов и модификаторов.

  • Использование инфиксной нотации для арифметических, логических и битовых операций, а также для сравнения и присваивания значений.

  • Использование постфиксной нотации для обращения к элементам массивов и структур, а также для вызова функций и инкремента или декремента переменных.

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

  • Использование препроцессора для включения других файлов, определения макросов и условной компиляции.

Синтаксис языка C оказал влияние на многие другие языки программирования, такие как C++, C#, Java и Objective-C, которые расширили или модифицировали его для своих целей. Некоторые языки, такие как Perl и Python, также заимствовали некоторые элементы синтаксиса C, такие как операторы и скобки, но сильно отличаются в других аспектах.

Интересные факты и фичи языков программирования у нас в канале, заходи :)

Показать полностью 1

Немного подкопотника компиляторов

Под капотом компиляторов находятся различные этапы обработки исходного кода, такие как лексический, синтаксический и семантический анализ, оптимизация, генерация и компоновка кода. Каждый этап выполняет определенную задачу, например, разбиение кода на токены, построение дерева разбора, проверка типов и областей видимости, устранение лишнего или неэффективного кода, преобразование кода в машинные инструкции или байт-код, связывание модулей и библиотек в исполняемый файл и т.д.

Компиляторы могут быть разными по своему устройству, функциональности и целям. Например, есть компиляторы, которые транслируют код с одного языка на другой, например, Babel или TypeScript. Есть компиляторы, которые оптимизируют код для конкретной архитектуры или платформы, например, GCC или LLVM. Есть компиляторы, которые используют динамическую компиляцию, то есть компилируют код во время его исполнения, например, JIT-компиляторы в Java или .NET. Есть компиляторы, которые реализуют специальные возможности или фичи языков, например, векторизация, макросы, рефлексия и т.д.

Интересные факты и фичи языков программирования у нас в канале, заходи :)

Часы на лампах ИВ-9

Мне давно приглянулись накальные индикаторы ИВ-9 и ИВ-16 (то же, только чуть короче за счёт отсутствия десятичной точки), но в интернете крайне мало проектов на них, поэтому когда появилась возможность, я решил сделать свой. Вот что получилось:

Часы на лампах ИВ-9 Arduino, Самоделки, Электроника, Часы, Подарки, Своими руками, Ламповые часы, Видео, YouTube, Длиннопост

Прежде чем заняться разработкой собственного проекта, я наткнулся на этот, показавшийся мне интересным: https://cxem.net/mc/mc490.php. Заказал 5 плат (немного изменив их под себя - проект частично открытый), собрал одну с индикаторами ИВ-16:

Часы на лампах ИВ-9 Arduino, Самоделки, Электроника, Часы, Подарки, Своими руками, Ламповые часы, Видео, YouTube, Длиннопост

Получилось неплохо, но некоторые моменты мне не понравились. Во-первых, несмотря на наличие нескольких режимов (анимаций, эффектов) смены цифр, среди них не было моего любимого - плавной смены цифр с наложением их друг на друга. Во-вторых, мне не очень понравилось управление двумя кнопками, я предпочитаю делать три: "ок" для входа в меню и подтверждения, "+" и "-" для установки показаний. В-третьих, часы работают от 5В, а 3В для питания индикаторов микроконтроллер формирует методом ШИМ - это позволяет сэкономить на отдельном преобразователе, но есть мнение, что в случае какого-то сбоя, на лампы может пойти 5В, что выведет их из строя. Часто такое пишут в комментариях к часам nixie clock, где микроконтроллер формирует примерно +180В для них. Кроме того (и это уже не предположение, а факт, обнаруженный после сборки) , при подключении к сети на долю секунды на лампы идут эти самые 5 Вольт (видимо, пока микроконтроллер не дошёл до выполнения функции формирования ШИМ сигнала).

С учётом всего этого я решил разрабатывать собственную схему. За основу была взята схема из представленного выше проекта: Atmega328 в корпусе TQFP32 (в дальнейшем возможно применение микроконтроллеров с меньшим объёмом памяти, без загрузчика для отладки), DS3231M, 74HC595 и ULN2003. Я даже не стал рисовать собственную схему, а изменил имеющуюся в графическом редакторе:

Часы на лампах ИВ-9 Arduino, Самоделки, Электроника, Часы, Подарки, Своими руками, Ламповые часы, Видео, YouTube, Длиннопост

Для питания индикаторов нужно 3 Вольта, для всего остального - пять. Я решил использовать блок питания на 5В, а напряжение для индикаторов получать с помощью отдельного импульсного понижающего преобразователя:

Часы на лампах ИВ-9 Arduino, Самоделки, Электроника, Часы, Подарки, Своими руками, Ламповые часы, Видео, YouTube, Длиннопост

Схемы рисовал уже после сборки часов, так что в них могут быть какие-то мелкие ошибки. Преобразователь настроен на напряжение питания индикаторов, плюс падение напряжения на сдвиговых регистрах и транзисторных сборках. В случае, если в микроконтроллере произойдёт программный сбой, на лампы никак не попадут 5 Вольт. Да, возможен и выход из строя NCP1529, но его я считаю крайне маловероятным.

Платы получились вот такие:

Часы на лампах ИВ-9 Arduino, Самоделки, Электроника, Часы, Подарки, Своими руками, Ламповые часы, Видео, YouTube, Длиннопост

На них предусмотрен разъём для подключения USB-Serial TTL конвертера для прошивки и возможности отладки, который позже можно убрать. Также предусмотрена возможность установки RTC в двух разных корпусах.

После пайки всех деталей и ламп получилось следующее:

Часы на лампах ИВ-9 Arduino, Самоделки, Электроника, Часы, Подарки, Своими руками, Ламповые часы, Видео, YouTube, Длиннопост
Часы на лампах ИВ-9 Arduino, Самоделки, Электроника, Часы, Подарки, Своими руками, Ламповые часы, Видео, YouTube, Длиннопост

Микроконтроллер и кварц я выпаял с платы Ардуино, так что загрузчик там уже был - не пришлось прошивать его отдельно через ISP. Подключил адаптер с СН340 и начал писать прошивку как для обычной платы Arduino nano. У меня на неё ушло несколько дней, результат очень порадовал:

В этом экземпляре лампы были установлены какие попало: первая - с другим углом наклона спиралей, четвёртая - тусклая. Позже был собран второй, дальше на фото и видео будет он.

Для корпуса была заказана вот такая заготовка из древесины бубинго:

Часы на лампах ИВ-9 Arduino, Самоделки, Электроника, Часы, Подарки, Своими руками, Ламповые часы, Видео, YouTube, Длиннопост

Её хватило на 3 корпуса:

Часы на лампах ИВ-9 Arduino, Самоделки, Электроника, Часы, Подарки, Своими руками, Ламповые часы, Видео, YouTube, Длиннопост

Получились они вот такими:

Часы на лампах ИВ-9 Arduino, Самоделки, Электроника, Часы, Подарки, Своими руками, Ламповые часы, Видео, YouTube, Длиннопост

Оставалось только сделать отверстия для кнопок и шнура питания, а также для крепления платы и нижней крышки. Позже он был покрыт тунговым маслом:

Часы на лампах ИВ-9 Arduino, Самоделки, Электроника, Часы, Подарки, Своими руками, Ламповые часы, Видео, YouTube, Длиннопост
Часы на лампах ИВ-9 Arduino, Самоделки, Электроника, Часы, Подарки, Своими руками, Ламповые часы, Видео, YouTube, Длиннопост

И всё готово:

Часы на лампах ИВ-9 Arduino, Самоделки, Электроника, Часы, Подарки, Своими руками, Ламповые часы, Видео, YouTube, Длиннопост
Часы на лампах ИВ-9 Arduino, Самоделки, Электроника, Часы, Подарки, Своими руками, Ламповые часы, Видео, YouTube, Длиннопост
Часы на лампах ИВ-9 Arduino, Самоделки, Электроника, Часы, Подарки, Своими руками, Ламповые часы, Видео, YouTube, Длиннопост

То ли из-за особенностей индикаторов, то ли из-за плохой камеры, я не смог сделать хорошие фотографии и видео. В реальности спирали светятся красивее.

Часы на лампах ИВ-9 Arduino, Самоделки, Электроника, Часы, Подарки, Своими руками, Ламповые часы, Видео, YouTube, Длиннопост
Часы на лампах ИВ-9 Arduino, Самоделки, Электроника, Часы, Подарки, Своими руками, Ламповые часы, Видео, YouTube, Длиннопост

При другом освещении:

Часы на лампах ИВ-9 Arduino, Самоделки, Электроника, Часы, Подарки, Своими руками, Ламповые часы, Видео, YouTube, Длиннопост

И ещё. А также сравнение с часами на ИН-16:

Часы на лампах ИВ-9 Arduino, Самоделки, Электроника, Часы, Подарки, Своими руками, Ламповые часы, Видео, YouTube, Длиннопост

И пара видео. Обычная смены цифр:

И плавная:

Календарь, будильник, термометр и прочее я посчитал лишним. Есть лишь два режима смены цифр (в первом - три уровня яркости).

Для заинтересовавшихся: эти часы есть в посте Часы Nixie clock и не только в сообществе, где можно писать цены.

matvey6191@gmail.com

Показать полностью 19 3

Особенности шаблонного программирования на C++

Шаблоны в C++ - это механизм обобщённого программирования, который позволяет создавать функции и классы, работающие с разными типами данных, не зная их заранее.

Особенности шаблонного программирования на C++ Программирование, Программист, IT, Arduino, Linux, Разработка, C++, Информационная безопасность

Шаблоны в C++ отличаются от универсальных типов в других языках, таких как C# и Java, тем, что они поддерживают не только параметры типов, но и параметры значений, также называемые параметрами выражений.

Шаблоны в C++ также позволяют использовать специализацию, частичную специализацию и перегрузку для адаптации поведения шаблонов к конкретным типам или ситуациям.

Шаблоны в C++ реализуются на этапе компиляции, то есть компилятор генерирует отдельный код для каждого типа, с которым используется шаблон. Это приводит к высокой производительности, но также к увеличению размера исполняемого файла.

Пример использования шаблона функции в C++:

// Объявление шаблона функции swap, которая меняет местами два значения

template<typename T>

void swap(T& a, T& b) {

T temp = a; // Создание временной переменной типа T

a = b; // Присваивание значения b переменной a

b = temp; // Присваивание значения temp переменной b

}

// Вызов шаблона функции swap с разными типами аргументов

int x = 10, y = 20;

swap(x, y); // Автоматический вывод типа T как int

std::cout << x << " " << y << std::endl; // Вывод 20 10

std::string s1 = "Hello", s2 = "World";

swap(s1, s2); // Автоматический вывод типа T как std::string

std::cout << s1 << " " << s2 << std::endl; // Вывод World Hello

Интересные факты и фичи языков программирования у нас в канале, заходи :)

Показать полностью

GPIO на Windows

Знатоки компьютерного фарша, подскажите пожалуйста, можно ли замутить что-нибудь подобное на рядовом виндовом железе?

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

Прогать ардуины/дёргать LPT я знаю, как)

Возможно, решение есть где-то в контроллерах RGB подсветки, но я не в курсе деталей работы.

Отличная работа, все прочитано!