Мой коллега MVP Питер Новак из Германии указал мне на этот удивительный набор на Amazon.de, в котором есть огромный набор датчиков.
Он поставляется с 37 датчиками и периферийными устройствами, которыми можно управлять с помощью Raspberry PI2. Первоначально он был сделан для PI B +, но, поскольку он совместим по выводам с PI 2, это работает нормально. Он поставляется с мини-диском с примером кода, но, к сожалению, это все C — вам нужно скомпилировать его с помощью GCC. Не программируя на C с конца 90-х, это не тот код, с которым мне очень удобно возиться. С другой стороны, я также с нетерпением жду, чтобы это пылилось до появления Windows 10 для устройств.
Теперь все примеры кода на C, которые идут с этим комплектом, используют библиотеку wiringPI , созданную одним Гордоном Хендерсоном . Я в основном использовал эту библиотеку как основу для работы с C #. Сначала вы должны установить библиотеку. У Гордона есть простое пошаговое руководство о том, как это сделать. Просто откройте консоль, перейдите в каталог, куда вы хотите загрузить исходные коды библиотеки, и следуйте его инструкциям. «Установка» в Linux, очевидно, означает установку git, клонирование репозитория и запуск файла сборки, который, по-видимому, компилирует весь shebang и ставит это «где-то». Конечным результатом является то, что вы можете скомпилировать примеры программ на С, которые поставляются с комплектом, используя библиотеку Гордона для управления датчиками.
Затем есть этот парень, Даниэль Рише , который создал простую библиотеку для оболочки на C #. Как это работает, ошеломительно просто — он просто использует DllImport, чтобы обернуть вызовы в библиотеку C и сделать их доступными для C #. Я не видел эту технику в гневе с 1999 года, в проекте Visual Basic 6. Но, по-видимому, это все еще работает — и, что более важно, — оно, очевидно, работает и под Mono, даже если импортированный код вообще не приходит из DLL, а является файлом «так».
Он вроде описывает, что вам нужно сделать — после установки библиотеки Гордона вы переходите (все еще в командной строке, конечно) к подпапке «wiringPi» папки, в которой вы начали сборку, а затем запускаете три команды для создания: разделяемые библиотеки:
cc -shared wiringPi.o -o libwiringPi.so
cc -shared wiringPiI2C.o -o libwiringPiI2C.so
cc -shared wiringPiSPI.o -o libwiringPiSPI.so
И, очевидно, вы можете просто удалить папку, в которую вы скачали исходники wiringPi. Библиотека установлена и может использоваться.
Теперь пример Дэниела показывает, как, к сожалению, для моей цели не хватает одной ключевой функции — для управления светодиодом вам потребуется доступ к процедурам «softPwm» wiringPi. Просматривая источники Си, я нашел файл softPwm.c с процедурами, которые мне нужны для доступа. Итак, я создал свой собственный класс оболочки:
using System.Runtime.InteropServices;
namespace WiringPi
{
public class SoftPwm
{
[DllImport("libwiringPi.so", EntryPoint = "softPwmCreate")]
public static extern void Create(int pin, int initialValue, int pwmRange);
[DllImport("libwiringPi.so", EntryPoint = "softPwmWrite")]
public static extern void Write(int pin, int value);
[DllImport("libwiringPi.so", EntryPoint = "softPwmStop")]
public static extern void Stop(int pin);
}
}
Как видите, все это довольно уродливо — все общедоступно, оно очень близко следует макету исходного кода и в настоящее время полностью не объектно-ориентировано. Но как бы то ни было, все еще рано, и это временная мера, пока Windows 10 все равно не появится. Это делает несколько подпрограмм C доступными для C # — например, подпрограмма C «softPwmWrite», которая помещает значение в вывод GPIO, становится доступной как SoftPwm.Write.
И тогда я могу написать следующую простую программу, которая позволяет многоцветному светодиоду, входящему в комплект SunFounder, получать все виды цветов:
using System;
using System.Threading;
using WiringPi;
namespace SunfounderTest
{
class Program
{
const int LedPinRed = 0;
const int LedPinGreen = 1;
const int LedPinBlue = 2;
static void Main(string[] args)
{
if (Init.WiringPiSetup() != -1)
{
SoftPwm.Create(LedPinRed, 0, 100);
SoftPwm.Create(LedPinGreen, 0, 100);
SoftPwm.Create(LedPinBlue, 0, 100);
Console.WriteLine("Init succeeded");
for (var i = 1; i < 3; i++)
{
ShowColor(255, 0, 0, "Red");
ShowColor(0, 255, 0, "Green");
ShowColor(0, 0, 255, "Blue");
ShowColor(255, 255, 0, "Yellow");
ShowColor(255, 0, 255, "Pink");
ShowColor(0, 255, 255, "Cyan");
ShowColor(195, 0, 255, "Purple");
ShowColor(255, 255, 255, "White");
}
SoftPwm.Stop(LedPinRed);
SoftPwm.Stop(LedPinGreen);
SoftPwm.Stop(LedPinBlue);
}
else
{
Console.WriteLine("Init failed");
}
}
private static void ShowColor(int r, int g, int b, string label)
{
SetLedColor(r, g, b);
Console.WriteLine(label);
Thread.Sleep(1000);
}
private static void SetLedColor(int r, int g, int b)
{
SoftPwm.Write(LedPinRed, r);
SoftPwm.Write(LedPinGreen, g);
SoftPwm.Write(LedPinBlue, b);
}
}
}
Я даже не начну притворяться, что я на самом деле полностью понимаю, что я делаю — и я даже меньше понимаю почему — но сначала вам нужно вызвать метод Init.WiringPiSetup — который уже был упакован Дэниелом — а затем вам нужно вызовите «Create» на трех выводах — только тогда вы можете установить значение для выводов, используя SoftPwm.Write. Я обернул вызовы этим в SetLedColor, который принимает значения красного, зеленого и синего (примерно 0-255), который, в свою очередь, обернут в процедуру, которая записывает информацию о прогрессе и немного ждет, прежде чем прогрессировать. И в конце вам нужно будет вызвать Stop на всех трех контактах, чтобы светодиод снова погас, иначе он с удовольствием останется включенным.
Чистый эффект: если вы подключите светодиодный контакт R к GPIO17, контакт G к 18, контакт B к 27 и контакт заземления к одному из заземления, светодиод будет мигать во всем диапазоне цветов.
Это будет работать только если вы запустите приложение с помощью sudo, поэтому
sudo mono SunfounderTest.exe
Раздражает то, что в образцах, поставляемых с этим набором, эти штифты 17, 18 и 27 обозначены как 0, 1 и 2. Это, очевидно, имеет исторические причины. На этой странице в element14 я нашел схему вывода с переводом с одного имени на другое. Обратите внимание, что контактный номер 11 называется как GPIO17, так и GPIO_GEN0. Это соответствует контакту 1 в коде . Я предполагаю, что где-то есть какая-то логика, но я еще должен это обнаружить ?
Как обычно, вы можете найти демонстрационное решение здесь . Имейте в виду — не весь код мой, часть его от Даниэля Рича

