FLProg Создание пользовательских блоков на языке С (Урок вне очереди)

Чертеж FLProg в ближайшее время обрел хватить огромную популярность, и мне закончило хватать медли на творенье агрегатов для той периферии, тот или иной нужна юзерам. В то же период посреди юзеров веб-сайта нашлось достаточное численность жителей нашей планеты, тот или другой хорошо разбираются в языке C и могли бы мне направить в развитии программы. Я решил пустить им соответственный инструмент. Эким образом, в версии 1.10.3 возникла потенциал творить пользовательские установки с встроенным кодом на С. Это привело к достаточно неожиданным результатам. Сиим прибором заинтересовались не совсем только разбирающиеся в программировании юзеры, да и те, кто ранее ни черкал не сточки кода. Они начали строчить первоначально простые установки (к примеру, получение логарифма посреди нормальных у меня экого установки не водилось), заканчивая теснее серьезными агрегатами с использованием библиотек. Потому я жажду мало поломать задуманную последовательность уроков по занятию с програмкой, и вне очереди расскажу, как творить сходственные установки.

Чертеж FLProg в ближайшее время обрел довольно большущую популярность, и мне не стало хватать поры на творение установок для той периферии, тот или иной нужна юзерам. В то же пора посреди юзеров веб-сайта нашлось достаточное численность жителей нашей планеты, тот или иной недурно разбираются в языке C и могли бы мне посодействовать в развитии программы. Я решил пустить им соответственный инструмент. Эким образом, в версии 1.10.3 взяла вероятность творить пользовательские агрегаты с встроенным кодом на С. Это привело к достаточно неожиданным результатам. Сиим прибором заинтересовались не совсем только разбирающиеся в программировании юзеры, да и те, кто ранее ни черкал не сточки кода. Они начали черкать вначале простые агрегаты (к примеру, получение логарифма посреди обыкновенных у меня экого агрегата не водилось), заканчивая теснее серьезными агрегатами с употреблением библиотек. Оттого я жажду всего ничего поломать задуманную последовательность уроков по службе с програмкой, и вне очереди расскажу, как творить сходственные агрегаты.

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

Раскроется окно с выбором языка программирования для агрегата. Доступны языки FBD, LAD и Code. Языки LAD и FBD будут осмотрены в остальных уроках, а на данный момент предпочитаем Code.

Раскрывается окно редактора агрегата юзера. В высшей части находятся закладки характеристик (1), в нижней закладки секций кода (2).

Наполняем главные характеристики.

Входы и выходы агрегата создаются подобно. Входов у нашего агрегата не будет, оттого дозволяем эту закладку и перебегаем к закладке Выходы блока. У агрегата будет три выхода направление по оси X, Y, и Z. Для творения выхода жмем клавишу Добавить выход.

Раскроется окно творения входа. Оно чрезвычайно схоже на окно творения переменной в генеральной програмке, оттого тщательно обрисовывать его не буду. Значения на выход агрегата подаются в формате Float оттого тип входов предпочитаем экий же. К наименованию выхода приноравливаются ограничения, приноравливающиеся к наименованию переменных в С., так как оно будет фигурировать в коде. В написании комментариев никаких ограничений нет.

Эким же образом творим другие выходы.

Сейчас зададим параметр, тот или другой юзер будет задавать при употреблении агрегата. Это будет чувствительность датчика. В согласовании с изображением она выбирается из линии: 0.88, 1.3, 1.9, 2.5, 4.0, 4.7, 5.6, 8.1

Перебегаем на закладку Характеристики пользователя и жмем клавишу Добавить параметр.

Раскроется окно творения параметра юзера. Так как параметр у нас вида Float, этот тип и предпочитаем. Никаких ограничений по наименованию параметра нет, так как в результирующем коде это заглавие будет заменено значением параметра. Так же нет никаких ограничений по тексту комментария.

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

Сейчас займемся библиотекой. Перейдем на закладку Библиотеки. Употребляемые в службе агрегата библиотеки можнож загрузить конкретно в установка. Для этого нужно надавить клавишу Загрузить библиотеку.

Раскроется окно выбора папки с библиотекой.

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

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

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

Сейчас перейдем в зону кода

1-ая закладка секция DeclareSection. На данной для нас закладке нужно прописать подключение нужных библиотек, объявление переменных, массивов и структур. Заполним эту секцию, ориентируясь на пример из библиотеки.

Код секции Declare из образца./*HMC5883L_Example.pde – Example sketch for integration with an HMC5883L triple axis magnetomerwe.Copyright (C) 2011 Love Electronics (loveelectronics.co.uk)This program is free software: you can redistribute it and/or modifyit under the terms of the version 3 GNU General Public License aspublished by the Free Software Foundation.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program. If not, see <http://www.gnu.org/licenses/>.*/// Reference the I2C Library#include <Wire.h>// Reference the HMC5883L Compass Library#include <HMC5883L.h>// Store our compass as a variable.HMC5883L compass;// Record any errors that may occur in the compass.int error = 0;// Out setup routine, here we will configure the microcontroller and compass.

При переносе в установка убраны излишние комменты, желая ограничений по их использованию никаких хороших от ограничений самого языка С нет. Так же добавлены некие переменные, тот или иной понадобятся позднее в коде. В уникальном образце они объявлены в секции Loop. Тут они перенесены в секцию Declare.

На нынешний на днях в разделе Declare можнож употреблять объявления переменных всех видов, объявление массивов и структур. Корректно обрабатывается директива #define.
Нельзя употреблять объявление экого облика:

typedef struct{……}test;

Его нужно переработать в экий вид:

struct test{……};

Нельзя употреблять тип extern. Это оказалась довольно большущий вопросом, и я полагаюсь в последнее время ее решить.

Сейчас перейдем к секции SetupSection. Тут код переносится из образца фактически один-одинехонек к один-одинешенек.

Код из примераvoid setup(){ // Initialize the serial port. Serial.begin(9600); Serial.println("Starting the I2C interface."); Wire.begin(); // Start the I2C interface. Serial.println("Constructing new HMC5883L"); compass = HMC5883L(); // Construct a new HMC5883 compass. Serial.println("Setting scale to +/- 1.3 Ga"); error = compass.SetScale(1.3); // Set the scale of the compass. if(error != 0) // If there is an error, print it out. Serial.println(compass.GetErrorText(error)); Serial.println("Setting measurement mode to continous."); error = compass.SetMeasurementMode(Measurement_Continuous); // Set the measurement mode to Continuous if(error != 0) // If there is an error, print it out. Serial.println(compass.GetErrorText(error));}

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

Обратите интерес, что заместо параметра точности вставлено имя параметра Точность. При компиляции агрегата заместо этого имени будет вставлено значение, тот или другой ввел юзер.

Сейчас перейдем к секции Loop.

Уникальный код из образца библиотекиvoid loop(){ // Retrive the raw values from the compass (not scaled). MagnetometerRaw raw = compass.ReadRawAxis(); // Retrived the scaled values from the compass (scaled to the configured scale). MagnetometerScaled scaled = compass.ReadScaledAxis(); // Values are accessed like so: int MilliGauss_OnThe_XAxis = scaled.XAxis;// (or YAxis, or ZAxis) // Calculate heading when the magnetometer is level, then correct for signs of axis. float heading = atan2(scaled.YAxis, scaled.XAxis); // Once you have your heading, you must then add your ‘Declination Angle’, which is the ‘Error’ of the magnetic field in your location. // Find yours here: http://www.magnetic-declination.com/ // Mine is: 2 37′ W, which is 2.617 Degrees, or (which we need) 0.0456752665 radians, I will use 0.0457 // If you cannot find your Declination, comment out these two lines, your compass will be slightly off. float declinationAngle = 0.0457; heading += declinationAngle; // Correct for when signs are reversed. if(heading < 0) heading += 2*PI; // Check for wrap due to addition of declination. if(heading > 2*PI) heading -= 2*PI; // Convert radians to degrees for readability. float headingDegrees = heading * 180/M_PI; // Output the data via the serial port. Output(raw, scaled, heading, headingDegrees); // Normally we would delay the application by 66ms to allow the loop // to run at 15Hz (default bandwidth for the HMC5883L). // However since we have a long serial out (104ms at 9600) we will let // it run at its natural speed. // delay(66);}

Так же как в секции Setup убираем заголовок секции и ограничивающие скобки. Они буду вставлены в код автоматом програмкой. Так же убираем объявление переменных в секции Loop. В данной для нас секции чрезвычайно не лучше объявлять временные переменные, так как ежели установка будет применяться в проекте пару раз, то произойдет ошибка повторного декларирования переменной.
В итоге достается экий код:

В баста кода мы вызываем функцию Output (raw, scaled, heading, headingDegrees). В принципе можнож водилось обойтись без нее, но я решил бросить ее для образца творения функции. Оттого перебегаем на закладку FunctionSection
Для творения новейшей функции жмем клавишу Добавить функцию.

Раскроется окно ввода заголовка функции, куда вводим ее определение.

Опосля творения заголовка строчим код функции.

Уникальный код функции из примераvoid Output(MagnetometerRaw raw, MagnetometerScaled scaled, float heading, float headingDegrees){ Serial.print("Raw:t"); Serial.print(raw.XAxis); Serial.print(" "); Serial.print(raw.YAxis); Serial.print(" "); Serial.print(raw.ZAxis); Serial.print(" tScaled:t"); Serial.print(scaled.XAxis); Serial.print(" "); Serial.print(scaled.YAxis); Serial.print(" "); Serial.print(scaled.ZAxis); Serial.print(" tHeading:t"); Serial.print(heading); Serial.print(" Radians t"); Serial.print(headingDegrees); Serial.println(" Degrees t");}

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

Занятие над агрегатом окончена.

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

Заканчиваем службу нажатием клавиши Выход.

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

Для самых долготерпеливых тот или иной прочитали до точки видео версия принесенного урока.