Мы продолжаем публикацию обзора онлайн-курса "Строим роботов и другие устройства на Arduino", начало здесь.


Итак, долго ли коротко, закончилась вторая неделя онлайн-курса робототехники от МФТИ. Признаться, неделя оказалась очень насыщенная всевозможными темами.


Вот примерный перечень, который я выделил для себя:


  • Делитель напряжения. Использование фоторезистора и термистора
  • Аналоговый сигнал. Разрядность сигнала
  • Обмен данными через последовательный порт. Среда Processing
  • Цифровой сигнал. Кнопки и варианты подключения. Подтягивающий резистор
  • Логические выражения, операторы if и else
  • Зуммер, светодиодная шкала, семисегментный индикатор
  • Микросхемы. Логический инвертор 74HC04, сдвиговый регистр 74HC595
  • Отладка программ
  • Внешние модули
  • Вариант готовой системы мониторинга, отображающей температуру и уровень освещенности на светодиодной шкале, а также динамиком, срабатывающим при превышении определенной температуры

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



Первое что пришло на ум — модернизация датчика освещенности. Реализация, предложенная в уроке, просто снимала значение с фоторезистора и посылала его в последовательный порт.


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


В редакторе Fritzing у меня получилось такое устройство.



Таким образом оно выглядит вживую.




За основу были взяты схемы работы со сдвиговым регистром и фоторезистором.


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


Теперь дело за малым — доработать исходный код. За основу была взята все та же программа для вывода значения на семисегментный индикатор.


Код программы
// Пины, необходимые для работы сдвигового регистра
#define DATA_PIN    13
#define LATCH_PIN   12
#define CLOCK_PIN   11
// Пины кнопок, отвечающих за установку минимального и максимального значения
#define BTN_MIN     3
#define BTN_MAX     2
// Пин, с которого будем снимать значения фоторезистора
#define SENS_PIN    A5

// Значения выводов регистра для индикатора, соответствующие цифрам
byte d0 = 0b01111101;
byte d1 = 0b00100100;
byte d2 = 0b01111010;
byte d3 = 0b01110110;
byte d4 = 0b00100111;
byte d5 = 0b01010111;
byte d6 = 0b01011111;
byte d7 = 0b01100100;
byte d8 = 0b01111111;
byte d9 = 0b01110111;

// Предопределенные значения минимального и максимального уровня освещенности
int min_light = 0;
int max_light = 1023;

// Текущее значение датчика
int value;
// Значение, ограниченное мин. и макс. уровнем
int output;
// Выводимая цифра
int digit;

void setup()
{
  // Установка пинов сдвигового регистра
  pinMode(DATA_PIN, OUTPUT);
  pinMode(CLOCK_PIN, OUTPUT);
  pinMode(LATCH_PIN, OUTPUT);
  // Включаем порт для вывода отладочной информации
  Serial.begin(9600);
  // Установка пинов для кнопок
  pinMode(BTN_MIN, INPUT_PULLUP);
  pinMode(BTN_MAX, INPUT_PULLUP);
}

void loop()
{
  // Получаем значение с фоторезистора
  value = analogRead(SENS_PIN);
  output = value;

  // Если нажаты кнопки - устанавливаем пороговые значения
  if (!digitalRead(BTN_MIN)) min_light = value;
  if (!digitalRead(BTN_MAX)) max_light = value - 10;

  // Применяем ограничения сверху и снизу
  if (value < min_light) output = min_light;
  if (value > max_light) output = max_light;
  // Получаем цифру, которую должны вывести на индикатор
  digit = map(value, min_light, max_light, 0, 9);

  // Отладочная информация
  Serial.println("Value: " + String(value) + " Output: " + String(output) + " Min: " + String(min_light) + " Max: " + String(max_light) + " Current : " + String(value) + " Digit: " + String(digit));

  // Непосредственный вывод цифры на индикатор
  if (digit == 0)
  {
    digitalWrite(LATCH_PIN, LOW);
    shiftOut(DATA_PIN, CLOCK_PIN, LSBFIRST, d0);
    digitalWrite(LATCH_PIN, HIGH);
  }
  else if (digit == 1)
  {
    digitalWrite(LATCH_PIN, LOW);
    shiftOut(DATA_PIN, CLOCK_PIN, LSBFIRST, d1);
    digitalWrite(LATCH_PIN, HIGH);
  }
  else if (digit == 2)
  {
    digitalWrite(LATCH_PIN, LOW);
    shiftOut(DATA_PIN, CLOCK_PIN, LSBFIRST, d2);
    digitalWrite(LATCH_PIN, HIGH);
  }
  else if (digit == 3)
  {
    digitalWrite(LATCH_PIN, LOW);
    shiftOut(DATA_PIN, CLOCK_PIN, LSBFIRST, d3);
    digitalWrite(LATCH_PIN, HIGH);
  }
  else if (digit == 4)
  {
    digitalWrite(LATCH_PIN, LOW);
    shiftOut(DATA_PIN, CLOCK_PIN, LSBFIRST, d4);
    digitalWrite(LATCH_PIN, HIGH);
  }
  else if (digit == 5)
  {
    digitalWrite(LATCH_PIN, LOW);
    shiftOut(DATA_PIN, CLOCK_PIN, LSBFIRST, d5);
    digitalWrite(LATCH_PIN, HIGH);
  }
  else if (digit == 6)
  {
    digitalWrite(LATCH_PIN, LOW);
    shiftOut(DATA_PIN, CLOCK_PIN, LSBFIRST, d6);
    digitalWrite(LATCH_PIN, HIGH);
  }
  else if (digit == 7)
  {
    digitalWrite(LATCH_PIN, LOW);
    shiftOut(DATA_PIN, CLOCK_PIN, LSBFIRST, d7);
    digitalWrite(LATCH_PIN, HIGH);
  }
  else if (digit == 8)
  {
    digitalWrite(LATCH_PIN, LOW);
    shiftOut(DATA_PIN, CLOCK_PIN, LSBFIRST, d8);
    digitalWrite(LATCH_PIN, HIGH);
  }
  else if (digit == 9)
  {
    digitalWrite(LATCH_PIN, LOW);
    shiftOut(DATA_PIN, CLOCK_PIN, LSBFIRST, d9);
    digitalWrite(LATCH_PIN, HIGH);
  }
  // Задержка для более плавного вывода значения
  delay(10);
}

Из особенностей — при установке максимального уровня освещенности пришлось вычитать некоторую константу (max_light = value — 10), подобранную эмпирическим путем. Это необходимо для того, чтобы избежать “дребезжания” при максимальном уровне освещенности, т. к. значение напряжения, снятого с фоторезисторе нестабильно.


Компилируем скетч, загружаем в Arduino и проверяем.


Сначала в мониторе порта...




А затем вживую



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


В заключение еще раз повторю, что неделя получилась очень насыщенная на различные темы. Отметим, что с момента публикации курса в Arduino IDE появилась встроенная функция Serial Plotter, которая частично перекрывает рассматриваемые в уроках функции среды Processing. Также в конце недели авторы пришли к идее модульности, когда конечное устройство собирается из готовых элементов — модулей, например, кнопки с уже встроенным подтягивающим резистором, готового датчика света, где фоторезистор и обычный резистор уже собраны в делитель напряжения, и тому подобных. Однако, устройство можно без труда собрать на макетной плате, что и было сделано. Вопрос читателям, приходилось ли вам самостоятельно изготавливать корпус для ваших устройств? Какие материалы вы для этого использовали? Может быть, картон, фанеру, оргстекло или, что не редкость сегодня, печатали на 3D-принтере?

Поделиться с друзьями
-->

Комментарии (15)


  1. Leerooooy
    10.04.2017 14:36
    +2

    Хм, в моем «церковно-приходском» рядовом политехе для 10-11 классов были курсы вводные, где учили работать с голыми DSP и CPLD, а для 1-2 курсов добавляли еще ARM и FPGA. За 8 лет универы так скатились?

    Этих курсов на ардуино бесчисленное количество: от ютубов до всяких детских кружков. МФТИ вроде как претендует на «топовый» универ, но тогда мне кажется надо и уровень знаний давать должный.

    Сертификат обо окончании курсов по ардуине — это просто шедевр! Кому он нужен будет? На собеседование работодателя посмешить?


    1. nemilya
      10.04.2017 15:36

      Я встречал людей, кто достаточно скептически относятся к Arduino, и у них свои аргументы. Но для начинающих, на мой взгляд Ардуино — это самый оптимальный вариант. И многие российские школьники/студенты не знаю даже про Ардуино!

      Получив опыт работы с микроэлектроникой на базе Ардуино — можно переходить при желании, и потребности — на более серёзную элементную базу. Ведь главное — это навык.

      И так же суть любого обучения — это пробудить интерес, а не вызвать отторжение. И часто успех зависит не от того что преподаётся, а кем и как — если у преподавателя есть энтузиазм и профессионализм — то он передаётся слушателям, ученикам — и они с интересом изучают «голые DPS и CPLD» и т.п. и т.д.

      По поводу того, что есть множество курсов и детских кружков — был бы рад, если это было так. Но по факту — курсы либо на английском, либо переводные, либо совсем небольшие. А в детских кружках (которых было много в советское время) — как правило в основном Лего…

      Если у вас есть ссылки на русскоязычные бесплатные видео-курсы по Ардуино для начинающих, на уровне этого 6-ти недельного курса — будут рад их посмотреть.

      А по поводу сертификата — это стандартный механизм от Coursera, и на выбор слушателя)

      Лично я хочу выразить благодарность Киберфизике и МФТИ, авторам курса — что нашли время на создание этого 6-ти недельного курса, и что не безразлична популяризация технического творчества (в том числе среди молодежи).


      1. Leerooooy
        10.04.2017 15:48
        +2

        Для начинающих вначале не плохо бы раскурить математику школьную, физику (первые 2 семестра), электроту (1 семестр). И только потом браться за ардуино. Приходится часто собеседовать народ, в том числе с МФТИ, и большинство заходят в тупик на просьбах:
        1) Чем TTL отличается от CMOS?
        2) Схематически покажите цифровой выход на МК

        Большинство из них готовы показать кучу «проектов» на ардуине и всяких малинах, но понятия не имеют как оно работает.

        Ардуина отличный инструмент, но не для новичков! На ней можно быстро наговнокодить и проверить датчик или простенький алгоритм, но изучать ее в качестве первой платформ — это путь в никуда. И самое печально, что об этом забывают рассказать на таких курсах, а новичку просто из-за неопытности этого понять не дано.

        Начинать надо с низшего уровня работы с железом, хотя бы ознакомительно и потом уже лезть наверх. Ардуино — это все таки верхний уровень и не дает понимания «а как оно там вообще работает». Она нужна, чтобы повысить скорость разработки (ну или для гуманитариев) и никак не для обучения.


        1. vconst
          10.04.2017 15:55
          +2

          Ардуино, это скорее для тех кто может программировать, но не знает электроники. Главное в нем — это предсказуемый результат в разработке. Придумал домашний самодельный девайс или промышленный прототип, взял модуль, прочитал как работает, скачал библиотеку, набросал логику, воткнул все в отладочную плату — и оно сразу работает.

          Гуманитарий программу не напишет, максимум — склеит франкенштейна из нагугленной копипасты и будет чесать репу: «Почему же оно не работает?..»

          Но Ардуино для студентов?.. В Физтехе?! Я в растерянности…


        1. red_dragon
          11.04.2017 14:31

          1) Чем TTL отличается от CMOS?
          2) Схематически покажите цифровой выход на МК


          А это вобще зачем знать? Какая мне разница, по какой технологии выполнен МК учитывая, что подавляющая часть современных микросхем КМОП, ну или производные. Для чего это принципиально?
          Зачем показывать схемотически цифровой выход MK? Для какой цели?

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

          Да ерунда всё это. А программировать надо начинать в машинных кодах? Так можно дойти до того, что чтобы пользоваться телефоном, надо его разработать с нуля. Утрирую конечно, но…
          Человек всё время существования пытается упростить себе жизнь. И это правильно. Объясните мне, зачем мне понимать: «а как оно там вообще работает», если это понимание мне ненужно для комфортного достижения цели?


      1. gbg
        11.04.2017 16:33

        Студентов, ранее изучавших Бейсик, практически невозможно обучить хорошему программированию. Как потенциальные программисты они подверглись необратимой умственной деградации.
        Э. Дейкстра

        Первый опыт важен в любой деятельности. Получение первого опыта с корявым фреймворком, который скрывает важные детали работы контроллера, ломается и чинится магическим образом (добавили либу — все свалилось), насаждает антипаттерн «формирование задержек при помощи delay вместо конечного автомата на прерываниях» — порождает не менее корявых программистов, которых потом придется переучивать.


        1. nemilya
          12.04.2017 12:26

          Поискал источник цитаты, это было сказано в июне 1975 года, вот здесь, это было за пару лет до моего рождения)

          Кстати будучи школьником начал изучать именно Бейсик — был вполне рад этому, позднее появился ZX Spectrum — где смог программировать игры, на этом самом Бейсике — и это приносило радость. Да, та самая клавиатура где команды Бейсика были прописаны на клавишах…

          В моём случае — Бейсик был стимулом к дальнейшему изучению программирования — далее были С, Perl, Php, Python, Ruby.

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

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

          Сейчас и достаточно давно — наблюдается спад в сфере ИТ (не только в России, но и во всём мире). Компьютер стал обыденным устройством и программирование уже не столь интересно. На мой взгляд в текущих тенденциях — робототехника может привлечь опять к сфере ИТ.

          Кстати появление микрокомпьютера RaspberryPi — обязано решению именно этой проблемы — как привлечь детей к ИТ (разработчик Eben Upton — кто спроектировал и сделал этот МК — осознал, что компьютеры современную молодежь уже не привлекают, как было в его время, и решил сделать что-то особенное).


          Вероятно вы справедливо критикуете Ардуино, но что вы можете предложить взамен платформы для начинающих для Physical Computing? Мне кажется любой open-source проект — это плод коллективных усилий.

          Кстати я не против если вместо Arduino будет RPi и Python. Но это сути не меняет. Любой специалист становится таким через личный опыт, через интерес который кем-то как-то был заложен в детстве/юности.

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

          К сожалению у учителей в школах как правило нет времени на эксперименты, выходящие за рамки программы, да и не все хотят что-то менять. А самоходов не так много, как например Денис Копосов — учитель информатики из Архангельска кто с 2008 года самостоятельно развивает на базе класса информатики - начала инженерного образования в школе. И поэтому важны такие курсы по основам электроники и робототехники, что сделали сотрудники МФТИ — самостоятельное образование.


          1. gbg
            12.04.2017 13:13

            Проблема в том, что в программировании (математике, электротехнике, etc) есть действительно сложные и важные вещи, которые нужно понимать.

            Для достижения этого понимания есть два пути.
            1) Изучать все с самого начала — что такое регистры, как работает процессор, что такое инструкции процессора, что такое прерывание, какие регистры за это отвечают и так далее. Этот путь долгий, занудный и у большинства вызывает реакцию «это чЁ ваще». Че так сложна-то, епты внатуре?

            2) Спрятать все эти сложности за «дружественной» к юзеру средой. Да, эта среда позволит программировать хоть задницей, и благодаря этому, начнет быстро и решительно набирать популярность.

            Идти «сложным путем» желающих будет крайне мало, так как социальное давление массы заставит большинство использовать «дружественную» среду, и враждебно (так как осилить они не в состоянии) относиться к программированию с полным осознанием происходящего. Как итог — имеем идиократию, а также кучу вещей, которые могли бы работать чудесно (экономично, быстро, стабильно), но работают как есть, потому что делать «чудесно» — дураков нет.

            О том, как \"сообщество\" способно заставить вас признать черное белым


            1. red_dragon
              13.04.2017 08:04
              +1

              А Вы знаете порядок работы цилиндров двигателя своего автомобиля и зависимость УОЗ от числа оборотов коленвала в минуту? Или вы просто умеете переключать передачи и крутить руль? В последнем случае, вы плохой водитель. От вас все эти пробки, дтп и ямы на дорогах. Как вам такая логика?

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

              Или вот ещё такой вопрос. Есть, например, некий matlab. Он очень быстро оперирует матрицами, лучше прочих программ, так или иначе умеющих это. Но я не знаю, каким образом так получается. Не имею представления, что там за принципы реализованы. Однако, этот инструмент позволяет мне достигать цели с наименьшими затратами времени и наивысшим комфортом. И что мне от этого перестать использовать matlab и начать писать собственную софтину, чтобы не прослыть быдлом, а потом долго вылавливать баги и глюки, и пытаться хоть чуть-чуть приблизиться по скорости к эталону?

              Ну и на всякий случай, я знаю, что такое прерывания и таймеры, могу запрограммировать ШИМ и прочее. Но, я научился этому исключительно тогда, когда мне это понадобилось. А сначала был бэйсик на самопальном спектруме, который я собрал, тогда ещё не особенно разбираясь в электронике. А глядя на себя нынешнего, можно сказать, что и совсем не разбираясь. Но цели я тогда достиг.


              1. gbg
                13.04.2017 11:03

                Порядок работы цилиндров моего автомобиля 1-3-4-2.

                Почитайте о дырявых абстрацкиях у Спольски.

                Ваши аналогии построены на неверном принципе. Вы говорите о том, что гипотетический «пользователь» не должен знать, о том, как устроено то, чем он пользуется внутри. Это хорошо. Однако в программировании программист не пользователь, а «дорабатыватель». И чтобы пользоваться чьей-то абстракцией, нужно хотя бы в общих чертах иметь представление о том, что происходит на уровне ниже.


                1. red_dragon
                  14.04.2017 10:55

                  1342, классика?

                  Да нет же. Программист — это тоже пользователь. Он использует определённые инструменты, для достижения цели. Можно вручную вводить код за кодом в память компьютера в двоичном виде, используя тумблеры и кнопки. А можно воспользоваться некоторым уровнем абстракции, в виде языка высокого уровня и набором библиотек к нему, чтобы упростить себе жизнь. И в последнем случае, совершенно не обязательно знать, в каком порядке переключать тумблеры, и на сколько секунд нажимать кнопку «ввод». Тут важно понять, что есть разные программисты, и у них разные цели. Гвоздь забивается молотком, а саморез заворачивается отвёрткой.

                  Нет совершенно никакой разницы между пользователем и «дорабатывателем», она условна. Домохозяйке, чистящей картофель в картофелечистке, нет совершенно никакого дела, как это делается вручную. А затем готовить картошку на электрической, или газовой плите, а не на костре. При этом она может быть и огонь то разводить не умеет, не говоря уже о понимании того, как добывают газ и получают электричество. Но она «дорабатывает» картошку именно таким образом. И достигает поставленной перед собой цели, для чего совершенно не обязательно досконально постичь всё мироустройство.


            1. Korhog
              19.04.2017 10:14

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

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

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

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

              А с подходом про два пути можно в каждой теме про новый или обновленный фреймворк или IDE писать что все очень плохо.


    1. lexnekr
      10.04.2017 15:36
      +2

      МФТИ — крутой ВУЗ.
      Но это не мешает им выпускать иногда и простые для понимания вещи.
      Например, недавно был запущен курс "Математика для всех", где многие математические концепции (инвариант, потологию и т.п.) объясняют «на пальцах». В этом курсе сейчас есть техническая проблема (курсеру как всегда глючит, поэтому она не публикует тесты с исправленными вопросами, поэтому многие не могут набрать 100%).
      Но курс клёвый и именно «посмотреть по фану» (я смотрел за ужином вместо сериальчика).

      Почему бы даже крутому ВУЗу не делать иногда простые вещи?


    1. cvn
      11.04.2017 08:57

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


  1. caway
    11.04.2017 08:56

    Вывод цифры интересен…
    Так не проще?

    byte da[10] = {
        0b01111101,
        0b00100100,
        0b01111010,
        0b01110110,
        0b00100111,
        0b01010111,
        0b01011111,
        0b01100100,
        0b01111111,
        0b01110111 };
    
    ...
    
        // Непосредственный вывод цифры на индикатор
        digitalWrite( LATCH_PIN, LOW );
        shiftOut( DATA_PIN, CLOCK_PIN, LSBFIRST, da[digit] );
        digitalWrite( LATCH_PIN, HIGH );
    
        // Задержка для более плавного вывода значения
        ...