Arduino. Изучаем вместе

Всё о ЧПУ (CNC). Компоненты, станки, программы.
Аватара пользователя
ROW

Arduino. Изучаем вместе

Сообщение #61 ROW » 21 фев 2018, 18:02

Сообщение не по теме
KimIV писал(а):Источник цитаты что даташиты я не читаю а исследую тыкая иголочкой и стукая молотком
от это непраильна! я потом в даташите не найду, где это написано и затыкаю тебя, что под рукой будет иголочкой, аль паяльником раскаленным! :jokingly: ладно пойду дальше сайт ломать, ковыряй свою ардуину :D
Свернуть
Мозг есть у всех, только не все разобрались с инструкцией к нему!

Аватара пользователя
vovasm

Arduino. Изучаем вместе

Сообщение #62 vovasm » 21 фев 2018, 22:32

О подпишусь, мучаю ардуинку давненько.
по рекомендую CyberLib.h имхо стоковые функции просто тормозыне ну можно напрямую в порты пихать, время тоже кстати скетчи облегчает ещё, так что сразу привыкай к ней про стоковые забудь.

да вот ещё шпор немного для печати с тырнета наюзаных, если форум подавит картинки могу выложить куданибудь всю пачку если надо
Вложения
Arduino. Изучаем вместе - Arduino Leonardo bascom.png
Arduino. Изучаем вместе - NANO_PINS.png
Arduino. Изучаем вместе - arduino-pro-mini-5v-16mhz-headerli-96_1490729289.3711.png
Arduino. Изучаем вместе - pic3369020.png
Дети растут, игрушки дорожают...

Аватара пользователя
Денис#

Arduino. Изучаем вместе

Сообщение #63 Денис# » 22 фев 2018, 01:52

Не помню, была такая картинка?

Arduino. Изучаем вместе - ARDUINO_V2.jpg
Заниматься стОит только тем, что считается невозможным.


Аватара пользователя
Автор темы
KimIV

Arduino. Изучаем вместе

Сообщение #65 KimIV » 24 фев 2018, 20:59

Обрабатываем нажатия кнопки

Освоение чтения состояний кнопок, нажата/не нажата, начнём с самого простого примера из книги "Практическая энциклопедия ARDUINO", а потом этот пример усложним насколько хватит фантазии :jokingly:

Итак, вот схема и код скетча из книги. Я пока только исправил некритичную опечатку в коде - поменял местами комментарии про HIGH и LOW.

Arduino. Изучаем вместе - 14_1.png


Код: Выделить всё

const int LED=10;    // Контакт 10 для подключения светодиода
const int BUTTON=2;  // Контакт 2 для подключения кнопки

void setup()
{
  // Сконфигурировать контакт светодиода как выход
  pinMode(LED, OUTPUT);
  // Сконфигурировать контакт кнопки как вход
  pinMode(BUTTON, INPUT);
}

void loop()
{
  if (digitalRead(BUTTON) == LOW)
  {
    // Выключаем светодиод, подавая на вывод 0 (LOW)
    digitalWrite(LED, LOW);
  }
  else
  {
    // Включаем светодиод, подавая на вывод 1 (HIGH)
    digitalWrite(LED, HIGH);
  }
}


Моя реализация схемы из книги. Работает она следующим образом. Изначально цифровой вывод 2 ардуино через резистор R2 притянут к массе и на нём низкий нулевой уровень. Нажатие на кнопку SB1 подаёт +5 В на вывод 2. В функции loop() выполняется чтение уровня сигнала на выводе 2 функцией digitalRead(). Считанное значение сравнивается с низким уровнем и если так оно и есть, то на цифровой выход 10 подаётся сигнал низкого уровня, а иначе - высокого уровня. К выходу 10 подключен светодиод VD1 и он зажигается при высоком значении уровня сигнала на выходе 10.

Arduino. Изучаем вместе - 14_2.jpg
Arduino. Изучаем вместе - 14_3.png


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

Ну что ж, а теперь начинаем фантазировать. Для начала выполним инверсию, то есть пусть светодиод по умолчанию горит, а гаснуть он будет по нажатию кнопки :crazy: Для реализации этого в условии if меняем равенство на неравенство.

Код: Выделить всё

  if (digitalRead(BUTTON) != LOW)


Вживую процесс погасания светодиода при нажатии на кнопку можно посмотреть в сборном видео в конце данного сообщения.

Следующая фантазия - режим триггера. Изначально светодиод погашен. Нажимаем на кнопку, светодиод загорелся и продолжил гореть после отпускания кнопки. При повторном нажатии на кнопку светодиод гаснет. Снова нажали - загорелся, ещё нажали - погас и т.д. Код скетча будет следующим.

Код: Выделить всё

const int LED=10;             // Контакт 10 для подключения светодиода
const int BUTTON=2;           // Контакт 2 для подключения кнопки
int prevStatusLED = LOW;      // Предыдущий уровень на выходе для светодиода
boolean pressButton = false;  // Кнопка нажата

void setup()
{
  // Сконфигурировать контакт светодиода как выход
  pinMode(LED, OUTPUT);
  // Сконфигурировать контакт кнопки как вход
  pinMode(BUTTON, INPUT);
}

void loop()
{
  // Проверка нажатия кнопки
  if (digitalRead(BUTTON) == HIGH && !pressButton)
  {
    if (prevStatusLED == LOW)
    {
      digitalWrite(LED, HIGH);
      prevStatusLED = HIGH;
    }
    else
    {
      digitalWrite(LED, LOW);
      prevStatusLED = LOW;
    }
    pressButton = true;
  }
  if (digitalRead(BUTTON) == LOW)
  {
    delay(20);                // Защита от дребезга контактов
    pressButton = false;
  }
}


По сравнению с предыдущим кодом здесь добавлены две новые глобальные переменные:
- prevStatusLED - запоминает состояние светодиода и по сути является именно тем триггером, который поддерживает устойчивые состояния светодиода.
- pressButton - в совокупности с функцией delay(20) обеспечивает антидребезг контактов кнопки, исключая таким образом ложные и неправильные срабатывания.

Хочу обратить всеобщее внимание на тот факт, что мы последовательно реализовали ТРИ алгоритма работы сборки "КНОПКА - СВЕТОДИОД":
- Зажигание светодиода при нажатии на кнопку и погасание при отпускании кнопки.
- Погасание светодиода при нажатии на кнопку и зажигание при отпускании кнопки.
- Зажигание светодиода при нажатии на кнопку и погасание при следующем нажатии.
И при этом мы не вносили в схему никаких изменений. Всё было реализовано на программном уровне. В этом и заключается главная прелесть и главное преимущество микроконтроллеров!

https://youtu.be/C1Ydkh8Ix04
Ты должен делать добро из зла, потому что его больше не из чего делать. Уоренн Роберт Пенн.

Аватара пользователя
Автор темы
KimIV

Arduino. Изучаем вместе

Сообщение #66 KimIV » 25 фев 2018, 18:33

Управляем одной кнопкой несколькими светодиодами

Ставлю задачу.

Сделать так, чтобы одна кнопка управляла включением и выключением нескольких светодиодов следующим образом. Изначально светодиоды погашены. Первое нажатие на кнопку зажигает первый (слева) светодиод. Второе нажатие кнопки гасит первый светодиод и зажигает второй. Третье нажатие гасит второй и зажигает третий и т.д. до восьмого светодиода. После зажигания и погашения восьмого светодиода должен быть статус, когда погашены все светодиоды. А последующие нажатия кнопки должны всё повторить и так по кругу.

Собираю на макетке схему из восьми сетодиодов и одной кнопки. Для светодиодов задействую цифровые выводы от 0 до 7. За состоянием кнопки будет следить 13-ый цифровой вывод.

Arduino. Изучаем вместе - 15_1.jpg
Arduino. Изучаем вместе - 15_2.png


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

Код: Выделить всё

void setup() {
  // Выводы 0-7 назначаем выходами
  for (int i=0; i<=8; i++)
  {
    pinMode(i, OUTPUT);
  }

  // На выходы 0-7 подаём высокий уровень, зажигаем светодиоды
  for (int i=0; i<=8; i++)
  {
    digitalWrite(i, HIGH);
  }
  delay(1000);
  // На выходы 0-7 подаём низкий уровень, зажигаем светодиоды
  for (int i=0; i<=8; i++)
  {
    digitalWrite(i, LOW);
  }
}

void loop() {
}


Пытаюсь загрузить скетч в память контроллера, но не тут-то было. Натыкаюсь на ошибку "avrdude: stk500_recv(): programmer is not responding". Что делал и что НЕ помогло:
1. Перетыкание USB в том числе и в другой разъём.
2. Перезагрузка компьютера.
Полез в интернет и вот здесь наткнулся на интересную инфу о том, что предыдущие скетчи могут мешать загрузке новых. Вернее, не так. Предыдущие скетчи могут так запрограммировать входы/выходы, что в новой схеме это приведёт к каким-либо косякам: к коротким замыканиям, неустойчивым состояниям и прочему. Поэтому рекомендуется сначала прошить контроллер новым скетчем и только после этого собирать схему. Так-что похоже, что я словил вторые свои грабли на ардуине. Ведь я сначала собрал схему, а потом прошивал, не очистив память контроллера от предыдущей прошивки. Но эта инфа всего лишь дала мне толчок в нужном направлении, а предыдущий скетч тут был ни причём. Начав по порядку, а именно с нулевого цифрового вывода, выдернув проводок, успешно загрузив скетч, вставив проводок и опять получив ошибку, понял, что этот вывод (цифровой нулевой) можно использовать в схеме только после перепрошивки. А если на него что-то схемно уже навешано, как в моём случае светодиод с резистором, то это приводит к ошибке "avrdude: stk500_recv(): programmer is not responding" при загрузке скетча. Также должен отметить, что светодиод, подключенный к первому выводу как-то странно помыргивал. Вообщем, я решил отказаться от их использования и всю схему сдвинул на два вывода, задействовав со 2 по 9 выводы. Проверил, загрузив скетч. Всё отлично! Все 8 светодиодов зажигаются на секунду и гаснут. Можно двигаться дальше.

Пишу следующий код

Код: Выделить всё

const int BUTTON = 13;  // Контакт 13 для подключенния кнопки
int tekButton = LOW;    // Текущее состояние кнопки
int prevButton = LOW;   // Предыдущее состояние кнопки
int Status = 0;         // Хранилище состояния системы:
                        //  0 - светодиоды погашены
                        //  1 - горит первый светодиод
                        //  2 - горит второй светодиод
                        //  3 - горит третий светодиод
                        //  4 - горит четвёртый светодиод
                        //  5 - горит пятый светодиод
                        //  6 - горит шестой светодиод
                        //  7 - горит седьмой светодиод
                        //  8 - горит восьмой светодиод

void setup() {
  // Выводы 2 - 9 назначаем выходами
  for (int i = 2; i <= 9; i++)
  {
    pinMode(i, OUTPUT);
  }
  // Вывод 13 назначаем входом
  pinMode(13, INPUT);

}

// Функция сглаживания дребезга. Принимает в качестве
// аргумента предыдущее состояние кнопки и выдаёт фактическое.
boolean debounce(boolean last)
{
  boolean current = digitalRead(BUTTON);  // Считываем состояние кнопки
  if (last != current)                    // Если изменилось...
  {
    delay(5);                             // Ждём 5 мс
    current = digitalRead(BUTTON);        // Считываем состояние кнопки
    return current;                       // Возвращаем состояние кнопки
  }
}

void loop() {
  tekButton = debounce(prevButton);       // Считываем состояние кнопки
  if (prevButton == LOW && tekButton == HIGH)   // Если нажатие...
  {
    Status++;                   // Увеличиваем Status на единицу
    if (Status > 8)             // Если Status вышел за допустимые пределы
    {
      Status = 0;               // Обнуляем
    }
  }
  prevButton = tekButton;

  // На выходы 2 - 9 подаём низкий уровень, гасим светодиоды
  for (int i = 2; i <= 9; i++)
  {
    digitalWrite(i, LOW);
  }

  if (Status > 0)                     // Если Status больше нуля...
  {
    digitalWrite(Status + 1, HIGH);   // Зажигаем соответствующий светодиод
  }
}


Функцию debounce() я честно скоммуниздил из книги "Практическая энциклопедия ARDUINO" из примера обработки нажатия кнопки. Но остальное всё сам написал. Кстати, в среде программистов тырить чьи-нибудь удачные, эффективные, да и просто понравившиеся коды - это нормальная практика. На то он и открытый код, чтобы его могли изучать и использовать все, кому не лень в нём разбираться.

Итак, что делает данный скетч?
В функции setup() выводы со 2-го по 9-ый назначаются выходами, а 13-ый вывод - входом.
В функции loop() считываем состояние кнопки функцией debounce(). Если есть нажатие, то увеличиваем статус на единицу. Если после увеличения статус превысил допустимый верхний предел, то обнуляем его. В переменной prevButton сохраняем текущее состояние кнопки. Далее гасим все светодиоды и если статус больше нуля, то зажигаем светодиод, соответствующий статусу.

https://youtu.be/X1lWJJk3BEk
Ты должен делать добро из зла, потому что его больше не из чего делать. Уоренн Роберт Пенн.

Аватара пользователя
Автор темы
KimIV

Arduino. Изучаем вместе

Сообщение #67 KimIV » 25 фев 2018, 22:34

Автопереключение при длительном нажатии

Я вот тут подумал, что когда на одну кнопку вешают какие-либо переключения между неким множеством состояний, то часто используют длительное нажатие (удержание) кнопки в качестве автоматического переключателя, который начинает последовательно перебирать все возможные варианты, а пользователь отпускает кнопку на нужном. То есть пользователю уже не нужно много раз тыкать кнопку, чтобы добраться до нужного состояния, а просто нажать и подождать, когда это состояние включится. И мне стало интересным реализовать такой функционал, тем более, что на макетке уже собрана подходящая схема - одна кнопка и 8 светодиодов.

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

Код: Выделить всё

const int BUTTON = 13;  // Контакт 13 для подключенния кнопки
int tekButton = LOW;    // Текущее состояние кнопки
int prevButton = LOW;   // Предыдущее состояние кнопки
int Status = 0;         // Хранилище состояния системы:
                        //  0 - светодиоды погашены
                        //  1 - горит первый светодиод
                        //  2 - горит второй светодиод
                        //  3 - горит третий светодиод
                        //  4 - горит четвёртый светодиод
                        //  5 - горит пятый светодиод
                        //  6 - горит шестой светодиод
                        //  7 - горит седьмой светодиод
                        //  8 - горит восьмой светодиод
int prevStatus = 0;     // Предыдущий статус
const int holdTime = 500;       // Время удержания кнопки в мс
int currentTime = millis();     // Время работы скетча в мс

void setup() {
  // Выводы 2 - 9 назначаем выходами
  for (int i = 2; i <= 9; i++)
  {
    pinMode(i, OUTPUT);
  }
  // Вывод 13 назначаем входом
  pinMode(13, INPUT);
}

// Функция сглаживания дребезга. Принимает в качестве
// аргумента предыдущее состояние кнопки и выдаёт фактическое.
boolean debounce(boolean last)
{
  boolean current = digitalRead(BUTTON);  // Считываем состояние кнопки
  if (last != current)                    // Если изменилось...
  {
    delay(5);                             // Ждём 5 мс
    current = digitalRead(BUTTON);        // Считываем состояние кнопки
  }
  return current;                         // Возвращаем состояние кнопки
}

// Функция изменения статуса
void incStatus()
{
  Status++;                   // Увеличиваем Status на единицу
  if (Status > 8)             // Если Status вышел за допустимые пределы
  {
    Status = 0;               // Обнуляем
  }
}

void loop() {
  tekButton = debounce(prevButton);

  if (prevButton == HIGH && tekButton == HIGH)  // Если кнопка нажата длительное время
  {
    if (millis() - currentTime > holdTime)      // Если время удержания кнопки больше заданного
    {
      incStatus();              // Изменяем статус
      currentTime = millis();   // Текущее время
    }
  }

  if (prevButton == LOW && tekButton == HIGH)   // Если нажатие...
  {
    incStatus();              // Изменяем статус
    currentTime = millis();   // Текущее время
  }

  // Гасим светодиоды только если статус изменился
  if (Status != prevStatus)
  {
    // На выходы 2 - 9 подаём низкий уровень, гасим светодиоды
    for (int i = 2; i <= 9; i++)
    {
      digitalWrite(i, LOW);
    }
  }

  if (Status > 0)                     // Если Status больше нуля...
  {
    digitalWrite(Status + 1, HIGH);   // Зажигаем соответствующий светодиод
  }
  prevButton = tekButton;
  prevStatus = Status;
}


В скетч введены следующие изменения:
1. Добавлена проверка длительного нажатия кнопки.
2. Строки изменения статуса вынесены в функцию incStatus(), потому что эти строки используются в двух местах. При кратком нажатии на кнопку и при длительном удержании кнопки. Поэтому повторяющийся код удобно организовывать в виде самостоятельной функции.
3. Организовано сохранение предыдущего состояния в переменной prevStatus для того, чтобы гасить светодиоды только в случае изменения статуса. Иначи они мерцали, что проявлялось в виде неполной яркости свечения.

https://youtu.be/Mg05jt9_wYQ
Ты должен делать добро из зла, потому что его больше не из чего делать. Уоренн Роберт Пенн.

artolik

Arduino. Изучаем вместе

Сообщение #68 artolik » 05 мар 2018, 15:18

Доброго времени уважаемые. Игорь вы создали эту тему с целью в дальнейшем использовать arduino для управления чпу станочком? Если это так,то и я мог бы поделиться с участниками своими мыслями на эту тему.

Аватара пользователя
Автор темы
KimIV

Arduino. Изучаем вместе

Сообщение #69 KimIV » 05 мар 2018, 15:22

artolik писал(а):Источник цитаты Игорь вы создали эту тему с целью в дальнейшем использовать arduino для управления чпу станочком?

Да.

PS. Анатолий, предлагаю делиться любыми мыслями. А если эти мысли выйдут за рамки данной темы, то будут перенесены в другую тему :) :hi:
Ты должен делать добро из зла, потому что его больше не из чего делать. Уоренн Роберт Пенн.

Аватара пользователя
ROW

Arduino. Изучаем вместе

Сообщение #70 ROW » 05 мар 2018, 17:01

artolik писал(а):Источник цитаты сделаю парочку фото станочка и опишу его.

А можно прям отдельной темой? :hi: :good2:

Отправлено спустя 40 минут 29 секунд:
 ! Сообщение модератора ROW
про станочек artolik, с ЧПУ на Ардуино сделал отдельную тему здесьпишите туда
Мозг есть у всех, только не все разобрались с инструкцией к нему!


Вернуться в «Системы ЧПУ»