Оглавление:

Синус-дракон: 10 шагов (с картинками)
Синус-дракон: 10 шагов (с картинками)

Видео: Синус-дракон: 10 шагов (с картинками)

Видео: Синус-дракон: 10 шагов (с картинками)
Видео: Синдром дракона. 10 Серия. Сериал. Психологический Триллер 2024, Июль
Anonim
Синус-дракон
Синус-дракон

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

Китайский дракон является «символом силы, силы и удачи», и на азиатском субконтиненте он часто имеет высокую культурную и традиционную ценность. Говорят, что китайский дракон не только приносит удачу, но и обладает мощными способностями, контролирующими «воду, осадки, тайфуны и наводнения». В конце концов, китайский дракон был признан подходящим для представления данных о погоде.

Визуализация

Синус-Дракон управляется в шести основных точках в трех отдельных секциях, представляющих прогноз погоды на три трехчасовых интервала. Для каждого 3-часового интервала будет включена следующая информация:

  • Описание погоды - определяет цвет текущей информации о погоде.
  • Температура - указывает высоту тела
  • Влажность - мигание светодиодных сегментов
  • Скорость ветра - контролирует скорость движения тела влево и вправо.

Необходимые материалы

  1. Фанера 3 мм / картон
  2. Деревянные дюбели 5 мм или палочки для еды
  3. 2 фотона частиц
  4. 3 Обтягивающие игрушки
  5. 6 серводвигателей
  6. Светильники NeoPixel (либо прядь, либо отдельные светильники, сшитые вместе)
  7. Много супер клея
  8. Проводящая нить
  9. Акриловая краска
  10. Декоративная ткань
  11. Лазерный резак
  12. 3д принтер

Шаг 1: вверх и вниз

Вверх и вниз!
Вверх и вниз!
Вверх и вниз!
Вверх и вниз!
Вверх и вниз!
Вверх и вниз!

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

  1. Загрузите файлы Adobe Illustrator (.ai) и распечатайте их с помощью лазерного резака.

    upDownBoxWithPlatform.ai следует распечатать на картоне

  2. Загрузите файлы 3D-печати (.stl) и распечатайте их на своем любимом 3D-принтере.

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

  3. Соберите первые два компонента и склейте их, как показано на рисунках 3-5.

    1. Платформа
    2. Канавки для диска
  4. Теперь соберите коробку, следуя приведенным ниже советам.

    1. Провода сервопривода должны проходить через прямоугольное отверстие сбоку коробки.
    2. Самый короткий конец дискового токаря прикрепляется к сервоголовке, а более длинный конец проходит через отверстие на другой стороне коробки с круглым отверстием на нем. Это показано на рисунке 6.
  5. Теперь нам нужно что-то, чтобы платформа оставалась ровной при повороте диска. Разрежьте палочки для еды на палочки длиной 75 мм (рисунок 7) и приклейте их через верх коробки к верхней части платформы с помощью горячего клея. Убедитесь, что клюшки установлены под углом 90 градусов к платформе.
  6. Вставьте палку длиной 212 мм в среднее отверстие в верхней части коробки на платформе.

Милая! Теперь у вас есть законченная коробка (рисунок 8) для движения дракона вверх и вниз. Теперь повторите описанные выше шаги еще два раза!

Шаг 2: А как насчет левого и правого ?

А как насчет левого и правого ?!
А как насчет левого и правого ?!
А как насчет левого и правого ?!
А как насчет левого и правого ?!
А как насчет левого и правого ?!
А как насчет левого и правого ?!
А как насчет левого и правого ?!
А как насчет левого и правого ?!

Теперь мы не можем забывать о левом и правом движениях Синус-Дракона, не так ли? Перейдем ко второму шагу!

  1. Загрузите файлы Adobe Illustrator (.ai) и распечатайте их с помощью лазерного резака.

    1. leftRightBoxWithPlatforms.ai следует распечатать на картоне.
    2. Файл armTurner.ai должен быть напечатан на материале толщиной 3 мм.
  2. Загрузите файлы 3D-печати (.stl) и распечатайте их на своем любимом 3D-принтере.

    Убедитесь, что вы распечатали две руки! Цвет здесь не имеет значения

  3. Соберите две платформы вместе, как показано на рисунке 3, с помощью горячего клея.
  4. Соберите коробку. Хотя это может быть непросто, но легче добиться:

    1. Вставьте две платформы между двумя большими прорезями по обе стороны коробки.
    2. Поместите первую руку на верхнюю платформу.
    3. Проденьте токарный рычаг через рычаг, а затем через верхнюю платформу.
    4. Поместите вторую руку на верхнюю часть нижней платформы.
    5. Пропустите рычаг токаря через второй рычаг, а затем нижнюю платформу.
    6. Вставляем рычажок в прямоугольное отверстие на 3D-принтере.
    7. Другой конец токаря идет поверх серводвигателя.
    8. Добавьте в коробку верхнюю, нижнюю и заднюю части.

Ваша окончательно собранная коробка должна выглядеть как на шестой картинке. Теперь вы можете повторить это еще два раза!

К концу этого шага у вас должно быть шесть коробок с тремя системами движения вверх / вниз и влево / вправо.

Шаг 3: Поднятие тела… КАК?

Поддерживая тело… КАК?
Поддерживая тело… КАК?

Хороший вопрос! Вот тогда и появляются эти напечатанные на 3D-принтере обтягивающие держатели. Загрузите прилагаемый файл.stl и распечатайте его на 3D-принтере. Обязательно напечатайте всего 6 держателей для 6 разных коробок.

Если вы видели изображение обтягивающего держателя выше, сюрприз испорчен - это цвет нашего синего дракона!

Шаг 4: Но эти коробки не такие красивые …

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

Загрузите эти файлы Adobe Illustrator и вырежьте их с помощью лазерного резака. Дизайн облаков был нарисован вручную одним из авторов. Не стесняйтесь изменять их, удаляя их внутри файла иллюстратора и добавляя свой собственный дизайн по своему усмотрению! Ниже приведены рекомендуемые шаги, чтобы собрать все воедино.

  1. Соберите и склейте все три части из первого файла (outerBoxFinal_1) вместе.
  2. Не добавляйте пока кусок из второго файла (outerBoxFinal_2).
  3. Поместите фрагмент из третьего файла (outerBoxFinal_3) в нижнюю часть коробки, и он должен закрываться вверху. Клей ТОЛЬКО на дно коробки.
  4. Напечатайте innerBoxesPlatform дважды. Склейте две детали с большими прямоугольными отверстиями. Затем склейте три оставшихся части вместе. Наконец, приклейте его к другому клееному комплекту с отверстиями в них.
  5. Поместите платформу на дно большого ящика.
  6. Вставьте все 6 коробок меньшего размера в соответствующие места на платформе.
  7. Теперь поместите кусок из второго файла (outerBoxFinal_2) в верхнюю часть коробки и приклейте по краю. Отверстия на верхней части должны совпадать с отверстиями на меньших коробках. Если нет, переставьте коробки поменьше. Ни в коем случае не добавляйте клей в коробки меньшего размера.
  8. Если вы используете макетную плату с липкой лентой внизу, поместите ее рядом с центром нижней части в месте, где при закрытии коробки макетная плата вместе с фотонами должна исчезнуть. На нижней части есть небольшие прорези, которые упрощают подключение к фотонам снаружи.

Шаг 5: Обтягивающие игрушки ?? О боже

Обтягивающие игрушки ?? О боже!
Обтягивающие игрушки ?? О боже!
Обтягивающие игрушки ?? О боже!
Обтягивающие игрушки ?? О боже!

Тело дракона:

1. Соедините три слинки вместе с помощью горячего клея или скотча.

2. Измерьте длину и диаметр брюк и отрежьте кусок декоративной ткани.

3. Соедините два конца ткани и сшейте их.

4. После того, как вы закончите сшивать их, наденьте обтягивающие брюки, как носки.

5. Пришейте концы обтягивающей ткани к сшитой ткани.

Шаг 6: Распечатайте своего дракона

Части дракона, напечатанные на 3D-принтере:

1. Детали взяты с

2. Мы использовали только голову, ноги и глаза.

3. После 3D-печати детали разгладьте ее наждачной бумагой и ацетоном.

4. Раскрасьте детали так, как хотите их украсить.

Шаг 7: Время усилить вашего дракона с NeoPixels

Время сделать шаг вперед вашего дракона с NeoPixels!
Время сделать шаг вперед вашего дракона с NeoPixels!
Время сделать шаг вперед вашего дракона с NeoPixels!
Время сделать шаг вперед вашего дракона с NeoPixels!

Легкий сегмент:

1. Вы можете просто использовать неопиксельную нить для создания света, если хотите (у нас закончились нити).

2. Мы использовали 20 неопиксельных фонарей и соединили их проводами. Эти провода были припаяны к ним и подключены к фотону с помощью красной проводки, чтобы он соответствовал теме дракона.

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

Сборка деталей: Закрепите легкий сегмент внутри тела дракона нитками или проволокой. Убедитесь, что вы можете подключить свет к фотону внутри базовой коробки. Прикрепите к туловищу голову, лапы и хвост с помощью клея. Как только они будут на месте, закрепите тело в узких держателях, которые мы напечатали ранее. Теперь тело готово к программированию.

Шаг 8: Время программирования

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

Теперь о первом микроконтроллере…

В файл Arduino (.ino) включите следующие библиотеки и определения:

#include "neopixel.h"

#include "ArduinoJson.h"

#define PIXEL_PIN D4

#define PIXEL_COUNT 18

Затем объявите следующие переменные:

Adafruit_NeoPixel strip = Adafruit_NeoPixel (PIXEL_COUNT, PIXEL_PIN);

Servo servoLeftRight_1; Servo servoUpDown_1; Servo servoLeftRight_2; Servo servoUpDown_2; int positionLeftRight_1 = 0; int positionUpDown_1 = 0; int leftRight_1 = 1; int upDown_1 = 1; int positionLeftRight_2 = 100; // должно быть от 0 до 180 (в градусах) int positionUpDown_2 = 180; // должно быть от 0 до 180 (в градусах) int leftRight_2 = 1; // 0 = влево, 1 = вправо int upDown_2 = 1; // 0 = вверх, 1 = вниз const size_t bufferSizeCurrent = JSON_ARRAY_SIZE (1) + JSON_OBJECT_SIZE (1) + 2 * JSON_OBJECT_SIZE (2) + JSON_OBJECT_SIZE (4) + JSON_OBJECT_SIZE (4) + JSON_OBJECT_SIZE (5)_SIZSIZ) + JSON_OBJECT_SIZE (5) + JSON_JSON_JSON_JSON_JSON_SIZE (5) + JSON_JECT 390; const size_t bufferSizeForecast = 38 * JSON_ARRAY_SIZE (1) + JSON_ARRAY_SIZE (38) + 2 * JSON_OBJECT_SIZE (0) + 112 * JSON_OBJECT_SIZE (1) + 39 * JSON_OBJECT_SIZE (1) + 39 * JSON_OBJECT_SIZE (2) * JSON_OBJECT_SIZE (2) + JSON_JSON_SIZECT (2) + JSON_JSON_SIZECT (2) + JSON_JSON_SIZECT (2) + JSON_JSON_SIZECT (2) + JSON_JSON_SIZECT (2) + JSON_JSON_SIZECT (2) + JSON_JSON_SIZECT) (5) + 76 * JSON_OBJECT_SIZE (8) + 12490; Строка weatherArray [3]; float temperatureArray [3]; float влажностьArray [3]; float windSpeedArray [3]; Строка timestampArray [3]; int upDownMaxDegree [3]; int leftRightSpeed [3]; String allData5DaysForecast;

Щелкните здесь, чтобы узнать, как настроить веб-перехватчики. Когда вы закончите, добавьте следующие объявления и функции и при необходимости внесите соответствующие изменения:

void getWeather5DayForecast () {Particle.publish ("get_weather5DayForecast"); allData5DaysForecast = ""; } Таймер timerWeatherForecast (60000, getWeather5DayForecast); void getCurrentWeather () {Particle.publish ("get_currentWeather"); } Таймер timerWeatherCurrent (60000, getCurrentWeather);

Следующие функции управляют движением дракона вверх / вниз и влево / вправо:

void changeLeftRight1 () {если (leftRight_1) {positionLeftRight_1 = positionLeftRight_1 + leftRightSpeed [0]; если (positionLeftRight_1> 100) {leftRight_1 = 0; }} еще {positionLeftRight_1 = positionLeftRight_1 - leftRightSpeed [0]; если (positionLeftRight_1 <0) {leftRight_1 = 1; }} servoLeftRight_1.write (positionLeftRight_1); }

void changeLeftRight2 () {

если (leftRight_2) {positionLeftRight_2 = positionLeftRight_2 + leftRightSpeed [1]; если (positionLeftRight_2> 100) {leftRight_2 = 0; }} еще {positionLeftRight_2 = positionLeftRight_2 - leftRightSpeed [1]; если (positionLeftRight_2 <0) {leftRight_2 = 1; }} servoLeftRight_2.write (positionLeftRight_2); }

void changeUpDown1 () {

если (upDown_1) {positionUpDown_1 ++; если (positionUpDown_1> upDownMaxDegree [0]) {upDown_1 = 0; }} еще {positionUpDown_1--; если (positionUpDown_1 <1) {upDown_1 = 1; }} servoUpDown_1.write (positionUpDown_1); }

void changeUpDown2 () {

если (upDown_2) {positionUpDown_2 ++; если (positionUpDown_2> upDownMaxDegree [1]) {upDown_2 = 0; }} еще {positionUpDown_2--; если (positionUpDown_2 <1) {upDown_2 = 1; }} servoUpDown_2.write (positionUpDown_2); }

Чтобы можно было менять движения в интервале, созданы таймеры.

Таймер timerLeftRight1 (100, changeLeftRight1);

Таймер timerLeftRight2 (100, changeLeftRight2); Таймер timerUpDown1 (10, changeUpDown1); Таймер timerUpDown2 (10, changeUpDown2);

Затем, наконец, добавляется функция настройки. Обязательно внесите соответствующие изменения в строки кода, связанные с веб-перехватчиками.

void setup () {// запускаем таймеры погоды timerWeatherForecast.start (); timerWeatherCurrent.start (); // Неопиксели strip.begin (); // Поместите здесь инициализацию типа pinMode и начните функции. // Настраиваем Micro Servo servoLeftRight_1.attach (D1); servoUpDown_1.attach (D0); servoLeftRight_2.attach (D3); servoUpDown_2.attach (D2); servoLeftRight_1.write (positionLeftRight_1); // инициализировать положение сервопривода servoUpDown_1.write (positionUpDown_1); // инициализировать положение сервопривода servoLeftRight_2.write (positionLeftRight_2); // инициализируем положение сервопривода servoUpDown_2.write (positionUpDown_2); // инициализируем положение сервопривода timerLeftRight1.start (); timerLeftRight2.start (); timerUpDown1.start (); timerUpDown2.start (); // Открываем консоль Serial.begin (9600); задержка (2000); Serial.println («Привет!»); // Подпишемся на веб-перехватчики get_weather5DayForecast и get_currentWeather Particle.subscribe ("hook-response / get_weather5DayForecast", gotWeather5DayForecast, MY_DEVICES); Particle.subscribe ("ответ на крючок / get_currentWeather / 0", gotCurrentWeatherData, MY_DEVICES); getCurrentWeather (); getWeather5DayForecast (); }

В этом проекте функция цикла не используется. Мы не можем забыть функции для обработки данных, полученных от веб-перехватчиков!

void gotWeather5DayForecast (const char * event, const char * data) {allData5DaysForecast + = data; // сохраняет все данные в одну строку. int allData5DaysForecastLen = allData5DaysForecast.length (); char buffer [allData5DaysForecastLen + 1]; allData5DaysForecast.toCharArray (буфер, allData5DaysForecastLen + 1); // создаем буфер для строки int bufferLength = sizeof (buffer); DynamicJsonBuffer jsonBufferWeather (bufferLength); JsonObject & root = jsonBufferWeather.parseObject (буфер); // Проверяем успешность синтаксического анализа. if (! root.success ()) {//Serial.println("Парсинг прогноза погоды на 5 дней… ОШИБКА! "); возвращение; } int i = 1; JsonArray & list = root ["список"]; для (JsonObject & currentObject: список) {если (я <3) {JsonObject & main = currentObject ["основной"]; температура поплавка = основная ["темп"]; int влажность = основная ["влажность"]; JsonObject & weather = currentObject ["погода"] [0]; const char * weatherInfo = погода ["основная"]; float windSpeed = currentObject ["ветер"] ["скорость"]; const char * timestamp = currentObject ["dt_txt"]; int tempFah = convertToFahrenheit (температура); int servoMaxDegree = updateUpDown (tempFah); upDownMaxDegree = servoMaxDegree; int servoIncrement = updateleftRight (windSpeed); leftRightSpeed = servoIncrement; setColor (weatherInfo, i); temperatureArray = tempFah; влажностьArray = влажность; weatherArray = weatherInfo; windSpeedArray = windSpeed; timestampArray = отметка времени; i ++; } else {перерыв; }}}

void gotCurrentWeatherData (const char * event, const char * data) {DynamicJsonBuffer jsonBufferWeather (bufferSizeCurrent); JsonObject & root = jsonBufferWeather.parseObject (данные); // Проверяем успешность синтаксического анализа. if (! root.success ()) {//Serial.println("Парсинг на текущую погоду… ОШИБКА! "); возвращение; } JsonObject & weather = root ["погода"] [0]; const char * weather_main = погода ["основная"]; JsonObject & main = root ["главный"]; float main_temp = main ["темп"]; int main_humidity = main ["влажность"]; float wind_speed = корень ["ветер"] ["скорость"]; const char * timestamp = root ["dt_txt"]; int tempFah = convertToFahrenheit (main_temp); int servoMaxDegree = updateUpDown (tempFah); upDownMaxDegree [0] = servoMaxDegree; int servoIncrement = updateleftRight (wind_speed); leftRightSpeed [0] = servoIncrement; setColor (weather_main, 0); weatherArray [0] = weather_main; temperatureArray [0] = tempFah; влажностьArray [0] = main_humidity; windSpeedArray [0] = wind_speed; timestampArray [0] = отметка времени; }

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

int updateUpDown (float temp) {// Сопоставьте градус диапазону [0, 180] float servoMaxDegree = temp * 45/31 + (990/31); Serial.print ("новая степень сервопривода:"); Serial.println (servoMaxDegree); return servoMaxDegree; }

int updateleftRight (float windSpeed) {

// Сопоставление скорости ветра с диапазоном [1, 100] float servoIncrement = windSpeed * 99/26 + 1; Serial.print ("новое значение приращения сервопривода:"); Serial.println (servoIncrement); return servoIncrement; }

int convertToFahrenheit (float tempKel) {

int tempFah = tempKel * 9,0 / 5,0 - 459,67; return tempFah; }

void setColor (String weatherDesc, int index) {

int ledIndex = 0; если (индекс == 0) {ledIndex = 0; } иначе, если (индекс == 1) {ledIndex = 6; } иначе, если (индекс == 2) {ledIndex = 12; } else {return; } if (weatherDesc == "Clear") {// желтый for (int j = ledIndex; j <ledIndex + 6; j ++) {strip.setPixelColor (j, strip. Color (253, 219, 62)); // желтая полоса. show (); задержка (20); }} else if (weatherDesc == "Clouds") {// серый for (int j = ledIndex; j <ledIndex + 6; j ++) {strip.setPixelColor (j, strip. Color (223, 229, 237)); // серая полоса.show (); задержка (20); }} else if (weatherDesc == "Snow") {// белый for (int j = ledIndex; j <ledIndex + 6; j ++) {strip.setPixelColor (j, strip. Color (255, 225, 225)); // белая полоса.show (); задержка (20); }} else if (weatherDesc == "Rain") {// синий for (int j = ledIndex; j <ledIndex + 6; j ++) {strip.setPixelColor (j, strip. Color (119, 191, 246)); // синяя полоска.show (); задержка (20); }} else {// красный цвет for (int j = ledIndex; j <ledIndex + 6; j ++) {strip.setPixelColor (j, strip. Color (254, 11, 5)); // красный strip.show (); задержка (20); }}}

Как только вы добавите все в свой файл Arduino, скомпилируйте его. Если ошибок нет, прошейте код на первый Photon. Следующий шаг предоставит вам аналогичный код, который будет прошит на втором Photon.

Шаг 9: Программирование продолжается

Поскольку код для второго Photon почти идентичен коду для первого, весь код копируется и вставляется ниже:

#include "ArduinoJson.h"

Servo servoLeftRight_3;

Servo servoUpDown_3;

int positionLeftRight_3 = 45;

int positionUpDown_3 = 0; int leftRight_3 = 1; int upDown_3 = 1;

const size_t bufferSizeCurrent = JSON_ARRAY_SIZE (1) + JSON_OBJECT_SIZE (1) + 2 * JSON_OBJECT_SIZE (2) + JSON_OBJECT_SIZE (4) + JSON_OBJECT_SIZE (5) + JSON_OBJECT_SIZE (6) + JSON_OBJECT_SIZE_0;

const size_t bufferSizeForecast = 38 * JSON_ARRAY_SIZE (1) + JSON_ARRAY_SIZE (38) + 2 * JSON_OBJECT_SIZE (0) + 112 * JSON_OBJECT_SIZE (1) + 39 * JSON_OBJECT_SIZE (1) + 39 * JSON_OBJECT_SIZE (2) * JSON_OBJECT_SIZECT (2) + JSON_JSON_SIZECT (2) + JSON_JSON_SIZECT (2) + JSON_JSON_SIZECT (2) + JSON_JSON_SIZECT (2) + JSON_JSON_JECT_SIZECT (2) + JSON_JSON_SIZECT (2) + JSON_JSON_SIZECT) (5) + 76 * JSON_OBJECT_SIZE (8) + 12490;

Строка weatherArray [3];

float temperatureArray [3]; float влажностьArray [3]; float windSpeedArray [3]; Строка timestampArray [3]; int upDownMaxDegree [3]; int leftRightSpeed [3];

String allData5DaysForecast;

недействительным getWeather5DayForecast ()

{Particle.publish ("get_weather5DayForecast2"); allData5DaysForecast = ""; }

Таймер timerWeatherForecast (60000, getWeather5DayForecast); // 10, 800, 000 мс = 3 дня

недействительным getCurrentWeather ()

{Particle.publish ("get_currentWeather2"); }

Таймер timerWeatherCurrent (60000, getCurrentWeather);

void changeLeftRight3 () {

если (leftRight_3) {positionLeftRight_3 = positionLeftRight_3 + leftRightSpeed [2]; если (positionLeftRight_3> 100) {leftRight_3 = 0; }} еще {positionLeftRight_3 = positionLeftRight_3 - leftRightSpeed [2]; если (positionLeftRight_3 <0) {leftRight_3 = 1; }} servoLeftRight_3.write (positionLeftRight_3); }

void changeUpDown3 () {

если (upDown_3) {positionUpDown_3 ++; если (positionUpDown_3> upDownMaxDegree [2]) {upDown_3 = 0; }} еще {positionUpDown_3--; если (positionUpDown_3 <1) {upDown_3 = 1; }} servoUpDown_3.write (positionUpDown_3); }

Таймер timerLeftRight3 (100, changeLeftRight3);

Таймер timerUpDown3 (10, changeUpDown3);

void setup () {

// запускаем таймеры погоды timerWeatherForecast.start (); timerWeatherCurrent.start (); // Поместите здесь инициализацию типа pinMode и начните функции. // Настройка Micro Servo servoLeftRight_3.attach (D1); servoUpDown_3.attach (D0);

servoLeftRight_3.write (positionLeftRight_3); // инициализируем положение сервопривода

servoUpDown_3.write (positionUpDown_3); // инициализируем положение сервопривода

timerLeftRight3.start ();

timerUpDown3.start (); // Открываем консоль Serial.begin (9600); задержка (2000); Serial.println («Привет!»); // Подпишемся на веб-перехватчики get_weather5DayForecast и get_currentWeather Particle.subscribe ("hook-response / get_weather5DayForecast2", gotWeather5DayForecast, MY_DEVICES); Particle.subscribe ("ответ на крючок / get_currentWeather2 / 0", gotCurrentWeatherData, MY_DEVICES); getCurrentWeather (); getWeather5DayForecast (); }

void gotWeather5DayForecast (событие const char *, данные const char *)

{allData5DaysForecast + = данные; // сохраняет все данные в одну строку. int allData5DaysForecastLen = allData5DaysForecast.length (); char buffer [allData5DaysForecastLen + 1]; allData5DaysForecast.toCharArray (буфер, allData5DaysForecastLen + 1); // создаем буфер для строки int bufferLength = sizeof (buffer); DynamicJsonBuffer jsonBufferWeather (bufferLength); JsonObject & root = jsonBufferWeather.parseObject (буфер); //Serial.println(allData5DaysForecast); // Проверяем успешность синтаксического анализа. if (! root.success ()) {//Serial.println("Парсинг прогноза погоды на 5 дней… ОШИБКА! "); возвращение; } int i = 1; JsonArray & list = root ["список"]; для (JsonObject & currentObject: список) {если (я <3) {JsonObject & main = currentObject ["основной"]; температура поплавка = основная ["темп"]; int влажность = основная ["влажность"]; JsonObject & weather = currentObject ["погода"] [0]; const char * weatherInfo = погода ["основная"]; float windSpeed = currentObject ["ветер"] ["скорость"]; const char * timestamp = currentObject ["dt_txt"]; int tempFah = convertToFahrenheit (температура); int servoMaxDegree = updateUpDown (tempFah); upDownMaxDegree = servoMaxDegree; int servoIncrement = updateleftRight (windSpeed); leftRightSpeed = servoIncrement; temperatureArray = tempFah; влажностьArray = влажность; weatherArray = weatherInfo; windSpeedArray = windSpeed; timestampArray = отметка времени; i ++; } else {перерыв; }}}

void gotCurrentWeatherData (событие const char *, данные const char *)

{DynamicJsonBuffer jsonBufferWeather (bufferSizeCurrent); JsonObject & root = jsonBufferWeather.parseObject (данные); //Serial.println(data); // Проверяем успешность синтаксического анализа. if (! root.success ()) {//Serial.println("Парсинг на текущую погоду… ОШИБКА! "); возвращение; } JsonObject & weather = root ["погода"] [0]; const char * weather_main = погода ["основная"]; JsonObject & main = root ["главный"]; float main_temp = main ["темп"]; int main_humidity = main ["влажность"]; float wind_speed = корень ["ветер"] ["скорость"]; const char * timestamp = root ["dt_txt"]; int tempFah = convertToFahrenheit (main_temp); int servoMaxDegree = updateUpDown (tempFah); upDownMaxDegree [0] = servoMaxDegree; int servoIncrement = updateleftRight (wind_speed); leftRightSpeed [0] = servoIncrement; weatherArray [0] = weather_main; temperatureArray [0] = tempFah; влажностьArray [0] = main_humidity; windSpeedArray [0] = wind_speed; timestampArray [0] = отметка времени; }

int updateUpDown (float temp) {

// Отображение степени в диапазон [0, 180] float servoMaxDegree = temp * 45/31 + (990/31); Serial.print ("новая степень сервопривода:"); Serial.println (servoMaxDegree); return servoMaxDegree; }

int updateleftRight (float windSpeed) {

// Сопоставление скорости ветра с диапазоном [1, 100] float servoIncrement = windSpeed * 99/26 + 1; Serial.print ("новое значение приращения сервопривода:"); Serial.println (servoIncrement); return servoIncrement; }

int convertToFahrenheit (float tempKel) {

int tempFah = tempKel * 9,0 / 5,0 - 459,67; return tempFah; }

Ты сделал это! Вы прошли через раздел программирования проекта! Теперь обязательно выполните всю проводку и соединения от серводвигателей и неопикселей к макетной плате и микроконтроллерам. ПРИМЕЧАНИЕ: вставьте дополнительные дюбели / палочки для еды через вертикальные прорези на коробках для левого и правого движений тела. Другой конец следует соединить с телом дракона.

Шаг 10: Наслаждайтесь своим драконом

Поздравляю! Вы построили Синус-Дракона с нуля! Теперь все, что вам нужно сделать, это расслабиться и наслаждаться окружающим дисплеем!

ПРИМЕЧАНИЕ. Этот проект был разработан как часть курсовой работы Джоан Бемпонг и Саундарья Мутувел. Страницу курса можно найти здесь.

Рекомендуемые: