суббота, 25 февраля 2012 г.

Raspberry Pi FAQ. Теория и практика (обновление)

Raspberry Pi/Pi2 - одноплатный мини-компьютер «на ладони» (85x54 мм) на базе процессора ARM 11 (ARM1176JZF-S) c тактовой частотой 700 МГц (или ARMv7 Cortex-A7 с тактовой 900 МГц для Pi2) с потребляемой мощностью от полутора до 3.5 Вт и RAM256/512MB для модели Pi и до 6 ватт потребления с RAM 1GB для Pi2. Для подключения монитора или телевизора на борту размещены композитный видеовыход и разъем HDMI. Кроме того, заводские OEM ЖК-экраны могут быть подключены через интерфейс DSI. Выдаваемое разрешение можно варьировать от 640х350 (EGA) до 1920х1200 (WUXGA) в формате PAL или NTCS и поддержкой OpenGL ES 2.0, кодеков MPEG-2, h.264/MPEG-4 AVC и VC-1 в режиме до 1080p@30 FPS, гигабайт оперативной памяти типа LPDDR2 SDRAM. Следует оговорить, что ОЗУ по-прежнему общее как для процессора, так и для графического ядра. Последний фактор важен тем, что высоконагруженным процессам следует выделять поменьше квантов процессорного времени для комфортной работы.


 В качестве низкоуровневых интерфейсов доступны:
  1. 8 портов ввода-вывода общего назначения
  2. UART (Serial)
  3. Шина I²C/TWI
  4. Шина SPI с селектором между двумя устройствами

Пины питания: 3.3 В, 5 В и земля. Колонки или наушники могут быть подключены через стандартное гнездо для 3,5 мм джеков. Также звук может передаваться через интерфейс HDMI. На Raspberry Pi Model B установлен Ethernet-адаптер на 10/100 Мбит с выходом на стандартное гнездо 8P8C (RJ45). Поддержка Wi-Fi может быть добавлена с помощью обычного USB Wi-Fi «свистка».


ТТХ одноплатного компьютера Raspberry Pi 2:


ЛИТЕРАТУРА и ДОКУМЕНТАЦИЯ
  1. Журналы MagPI http://www.themagpi.com (возможен онлайн-просмотр, так и скачивание PDF)
  2. http://wiki.freepascal.org/Installing_Lazarus
  3. http://raspberrypi.ru/doc
В ЧЕМ ПРОГРАММИРОВАТЬ? КОНТРОЛЬ GPIO

1. Python

Скачиваем PIP sudo curl https://raw.github.com/pypa/pip/master/contrib/get-pip.py | python
Устанавливаем RPi.GPIO модуль для Python sudo pip install rpi.gpio
И управляем GPIO:
import RPi.GPIO as GPIO
GPIO.setup(7, GPIO.OUT)
GPIO.output(7, True)
GPIO.output(7,False)
2. Lazarus

Страница помощи http://wiki.freepascal.org/Lazarus_on_Raspberry_Pi
Компоненты и библиотеки: http://wiki.freepascal.org/Components_and_Code_examples
Документация: http://wiki.freepascal.org/Lazarus_Documentation
Инсталляция: http://wiki.freepascal.org/Installing_Lazarus
Пример контроля GPIO:
unit Unit1;

{Demo application for GPIO on Raspberry Pi}
{Inspired by the Python input/output demo application by Gareth Halfacree}
{written for the Raspberry Pi User Guide, ISBN 978-1-118-46446-5}

{This application reads the status of a push-button}

{$mode objfpc}{$H+}


interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ButtonPanel, Unix, BaseUnix;

type

  { TForm1 }
 

  TForm1 = class(TForm)
    ApplicationProperties1: TApplicationProperties;
    GPIO18CheckBox: TCheckBox;
    LogMemo: TMemo;
    procedure ApplicationProperties1Idle(Sender: TObject; var Done: Boolean);
    procedure FormActivate(Sender: TObject);
    procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
  private
    { private declarations }
  public
    { public declarations }
  end;

const
  PIN_18: PChar = '18';
  IN_DIRECTION: PChar = 'in';

var
  Form1: TForm1;
  gReturnCode: longint; {stores the result of the IO operation}

implementation

{$R *.lfm}

{ TForm1 }


procedure TForm1.FormActivate(Sender: TObject);
var
  fileDesc: integer;
begin
  { Prepare SoC pin 18 (pin 12 on GPIO port) for access: }
  try
    fileDesc := fpopen('/sys/class/gpio/export', O_WrOnly);
    gReturnCode := fpwrite(fileDesc, PIN_18[0], 2);
    LogMemo.Lines.Add(IntToStr(gReturnCode));
  finally
    gReturnCode := fpclose(fileDesc);
    LogMemo.Lines.Add(IntToStr(gReturnCode));
  end;
  { Set SoC pin 18 as input: }
  try
    fileDesc := fpopen('/sys/class/gpio/gpio18/direction', O_WrOnly);
    gReturnCode := fpwrite(fileDesc, IN_DIRECTION[0], 2);
    LogMemo.Lines.Add(IntToStr(gReturnCode));
  finally
    gReturnCode := fpclose(fileDesc);
    LogMemo.Lines.Add(IntToStr(gReturnCode));
  end;
end;

procedure TForm1.ApplicationProperties1Idle(Sender: TObject; var Done: Boolean);
var
  fileDesc: integer;
  buttonStatus: string[1] = '1';
begin
  try
    { Open SoC pin 18 (pin 12 on GPIO port) in read-only mode: }
    fileDesc := fpopen('/sys/class/gpio/gpio18/value', O_RdOnly);
    if fileDesc > 0 then
    begin
      { Read status of this pin (0: button pressed, 1: button released): }
      gReturnCode := fpread(fileDesc, buttonStatus[1], 1);
      LogMemo.Lines.Add(IntToStr(gReturnCode) + ': ' + buttonStatus);
      LogMemo.SelStart := Length(LogMemo.Lines.Text) - 1;
      if buttonStatus = '0' then
        GPIO18CheckBox.Checked := true
      else
        GPIO18CheckBox.Checked := false;
    end;
  finally
    { Close SoC pin 18 (pin 12 on GPIO port) }
    gReturnCode := fpclose(fileDesc);
    LogMemo.Lines.Add(IntToStr(gReturnCode));
    LogMemo.SelStart := Length(LogMemo.Lines.Text) - 1;
  end;
end;

procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
var
  fileDesc: integer;
begin
  { Free SoC pin 18: }
  try
    fileDesc := fpopen('/sys/class/gpio/unexport', O_WrOnly);
    gReturnCode := fpwrite(fileDesc, PIN_18[0], 2);
    LogMemo.Lines.Add(IntToStr(gReturnCode));
  finally
    gReturnCode := fpclose(fileDesc);
    LogMemo.Lines.Add(IntToStr(gReturnCode));
  end;
end;

end.
Модуль контроля:
unit pigpio;
{ BCM2835 GPIO Registry Driver, also can use to manipulate cpu other registry areas
 
 This code is tested only Broadcom bcm2835 cpu, different arm cpus may need different
 gpio driver implementation
 
 2013 Gabor Szollosi
}
{$mode objfpc}{$H+}


interface

uses
  Classes, SysUtils;

const
  REG_GPIO = $20000; //bcm2835 gpio register 0x2000 0000
  // hex 0x1000 so simply calculate 0x2000 0000 / 0x1000  = 0x2000 0
  PAGE_SIZE = 4096;
  BLOCK_SIZE = 4096;
  // The BCM2835 has 54 GPIO pins.
  //  BCM2835 data sheet, Page 90 onwards.
  // There are 6 control registers, each control the functions of a block
  //  of 10 pins.
 

  CLOCK_BASE = (REG_GPIO + $101);
  GPIO_BASE =  (REG_GPIO + $200);
  GPIO_PWM =   (REG_GPIO + $20C);

     INPUT = 0;
     OUTPUT = 1;
     PWM_OUTPUT = 2;
     LOW = False;
     HIGH = True;
     PUD_OFF = 0;
     PUD_DOWN = 1;
     PUD_UP = 2;

   // PWM

  PWM_CONTROL = 0;
  PWM_STATUS  = 4;
  PWM0_RANGE  = 16;
  PWM0_DATA   = 20;
  PWM1_RANGE  = 32;
  PWM1_DATA   = 36;

  PWMCLK_CNTL = 160;
  PWMCLK_DIV  = 164;

  PWM1_MS_MODE    = $8000;  // Run in MS mode
  PWM1_USEFIFO    = $2000; // Data from FIFO
  PWM1_REVPOLAR   = $1000;  // Reverse polarity
  PWM1_OFFSTATE   = $0800;  // Ouput Off state
  PWM1_REPEATFF   = $0400;  // Repeat last value if FIFO empty
  PWM1_SERIAL     = $0200;  // Run in serial mode
  PWM1_ENABLE     = $0100;  // Channel Enable

  PWM0_MS_MODE    = $0080;  // Run in MS mode
  PWM0_USEFIFO    = $0020;  // Data from FIFO
  PWM0_REVPOLAR   = $0010;  // Reverse polarity
  PWM0_OFFSTATE   = $0008;  // Ouput Off state
  PWM0_REPEATFF   = $0004;  // Repeat last value if FIFO empty
  PWM0_SERIAL     = $0002;  // Run in serial mode
  PWM0_ENABLE     = $0001;  // Channel Enable


type

  { TIoPort }

  TIoPort = class // IO bank object
  private       

  public
   FGpio: ^LongWord;
   FClk: ^LongWord;
   FPwm: ^LongWord;
   procedure SetPinMode(gpin, mode: byte);
   function GetBit(gpin : byte):boolean;inline; // gets pin bit}
   procedure ClearBit(gpin : byte);inline;// write pin to 0
   procedure SetBit(gpin : byte);inline;// write pin to 1
   procedure SetPullMode(gpin, mode: byte);
   procedure PwmWrite(gpin : byte; value : LongWord);inline;// write pin to pwm value
  end;

  { TIoDriver }

  TIoDriver = class
  private

  public
    destructor Destroy;override;
    function MapIo:boolean;// creates io memory mapping
    procedure UnmapIoRegisrty(FMap: TIoPort);// close io memory mapping
    function CreatePort(PortGpio, PortClk, PortPwm: LongWord):TIoPort; // create new IO port
  end;

var

    fd: integer;// /dev/mem file handle
    procedure delayNanoseconds (howLong : LongWord);


implementation

uses
  baseUnix, Unix;

procedure delayNanoseconds (howLong : LongWord);
var
  sleeper, dummy : timespec;
begin
  sleeper.tv_sec  := 0 ;
  sleeper.tv_nsec := howLong ;
  fpnanosleep (@sleeper,@dummy) ;
end;
{ TIoDriver }
destructor TIoDriver.Destroy;
begin
  inherited Destroy;
end;

function TIoDriver.MapIo: boolean;
begin
 Result := True;
 fd := fpopen('/dev/mem', O_RdWr or O_Sync); // Open the master /dev/memory device
  if fd < 0 then
  begin
    Result := False; // unsuccessful memory mapping
  end;
end;

procedure TIoDriver.UnmapIoRegisrty(FMap:TIoPort);
begin
  if FMap.FGpio <> nil then
 begin
   fpMUnmap(FMap.FGpio,PAGE_SIZE);
   FMap.FGpio := Nil;
 end;
 if FMap.FClk <> nil then
 begin
   fpMUnmap(FMap.FClk,PAGE_SIZE);
   FMap.FClk := Nil;
 end;
 if FMap.FPwm <> nil then
 begin
   fpMUnmap(FMap.FPwm ,PAGE_SIZE);
   FMap.FPwm := Nil;
 end;
end;

function TIoDriver.CreatePort(PortGpio, PortClk, PortPwm: LongWord): TIoPort;
begin
  Result := TIoPort.Create;// new io port, pascal calls new fpMap, where offst is page sized 4096 bytes!!!
  Result.FGpio := FpMmap(Nil, PAGE_SIZE, PROT_READ or PROT_WRITE, MAP_SHARED, fd, PortGpio); // port config gpio memory
  Result.FClk:= FpMmap(Nil, PAGE_SIZE, PROT_READ or PROT_WRITE, MAP_SHARED, fd, PortClk);; // port clk
  Result.FPwm:= FpMmap(Nil, PAGE_SIZE, PROT_READ or PROT_WRITE, MAP_SHARED, fd, PortPwm);; // port pwm
end;

procedure TIoPort.SetPinMode(gpin, mode: byte);
var
  fSel, shift, alt : byte;
  gpiof, clkf, pwmf : ^LongWord;
begin
  fSel := (gpin div 10)*4 ;  //Select Gpfsel 0 to 5 register
  shift := (gpin mod 10)*3 ;  //0-9 pin shift
  gpiof := Pointer(LongWord(Self.FGpio)+fSel);
  if (mode = INPUT) then
    gpiof^ := gpiof^ and ($FFFFFFFF - (7 shl shift))  //7 shl shift komplemens - Sets bits to zero = input
  else if (mode = OUTPUT) then
  begin
    gpiof^ := gpiof^ and ($FFFFFFFF - (7 shl shift)) or (1 shl shift);
  end
  else if (mode = PWM_OUTPUT) then
  begin
    Case gpin of
      12,13,40,41,45 : alt:= 4 ;
      18,19          : alt:= 2 ;
      else alt:= 0 ;
    end;
    If alt > 0 then
    begin
      gpiof^ := gpiof^ and ($FFFFFFFF - (7 shl shift)) or (alt shl shift);
      clkf := Pointer(LongWord(Self.FClk)+PWMCLK_CNTL);
      clkf^ := $5A000011 or (1 shl 5) ;                  //stop clock
      delayNanoseconds(200);
      clkf := Pointer(LongWord(Self.FClk)+PWMCLK_DIV);
      clkf^ := $5A000000 or (32 shl 12) ;   // set pwm clock div to 32 (19.2/3 = 600KHz)
      clkf := Pointer(LongWord(Self.FClk)+PWMCLK_CNTL);
      clkf^ := $5A000011 ;                               //start clock
      Self.ClearBit(gpin);
      pwmf := Pointer(LongWord(Self.FPwm)+PWM_CONTROL);
      pwmf^ := 0 ;                  // Disable PWM
      delayNanoseconds(200);
      pwmf := Pointer(LongWord(Self.FPwm)+PWM0_RANGE);
      pwmf^ := $400 ;                             //max: 1023
      delayNanoseconds(200);
      pwmf := Pointer(LongWord(Self.FPwm)+PWM1_RANGE);
      pwmf^ := $400 ;                             //max: 1023
      delayNanoseconds(200);
      // Enable PWMs
      pwmf := Pointer(LongWord(Self.FPwm)+PWM0_DATA);
      pwmf^ := 0 ;                                //start value
      pwmf := Pointer(LongWord(Self.FPwm)+PWM1_DATA);
      pwmf^ := 0 ;                                //start value
      pwmf := Pointer(LongWord(Self.FPwm)+PWM_CONTROL);
      pwmf^ := PWM0_ENABLE or PWM1_ENABLE ;
    end;
  end;
end;

procedure TIoPort.SetBit(gpin : byte);
var
   gpiof : ^LongWord;
begin
  gpiof := Pointer(LongWord(Self.FGpio) + 28 + (gpin shr 5) shl 2);
  gpiof^ := 1 shl gpin;
end;

procedure TIoPort.ClearBit(gpin : byte);
var
   gpiof : ^LongWord;
begin
  gpiof := Pointer(LongWord(Self.FGpio) + 40 + (gpin shr 5) shl 2);
  gpiof^ := 1 shl gpin;
end;

function TIoPort.GetBit(gpin : byte):boolean;
var
   gpiof : ^LongWord;
begin
  gpiof := Pointer(LongWord(Self.FGpio) + 52 + (gpin shr 5) shl 2);
  if (gpiof^ and (1 shl gpin)) = 0 then Result := False else Result := True;
end;

procedure TIoPort.SetPullMode(gpin, mode: byte);
var
   pudf, pudclkf : ^LongWord;
begin
  pudf := Pointer(LongWord(Self.FGpio) + 148 );
  pudf^ := mode;   //mode = 0, 1, 2 :Off, Down, Up
  delayNanoseconds(200);
  pudclkf := Pointer(LongWord(Self.FGpio) + 152 + (gpin shr 5) shl 2);
  pudclkf^ := 1 shl gpin ;
  delayNanoseconds(200);
  pudf^ := 0 ;
  pudclkf^ := 0 ;
end;

procedure TIoPort.PwmWrite(gpin : byte; value : Longword);
var
   pwmf : ^LongWord;
   port : byte;
begin
  Case gpin of
      12,18,40 : port:= PWM0_DATA ;
      13,19,41,45 : port:= PWM1_DATA ;
      else exit;
  end;
  pwmf := Pointer(LongWord(Self.FPwm) + port);
  pwmf^ := value and $FFFFFBFF; // $400 complemens
end;

end.
3. Bash

GPIO контакты Raspberry Pi являются файлами, а значит:
sudo su -
echo "4" > /sys/class/gpio/export
echo "4" > /sys/class/gpio/export
echo "out" > /sys/class/gpio/gpio4/direction
echo "1" > /sys/class/gpio/gpio4/value
echo "0" > /sys/class/gpio/gpio4/value
Для чтения входов:
echo "0" > /sys/class/gpio/export
echo "in" > /sys/class/gpio/gpio0/direction
cat /sys/class/gpio/gpio0/value
4. Си под GCC

Для управления GPIO потребуется библиотека bcm2835-1.17. Контроль над светодиодом:
// GPIO-test.c
// Программа включает на 1 секунду светодиод,
// подключённый к порту Р1_03
// Компиляция командой gcc -o GPIO-test GPIO-test.c -lrt -lbcm2835


#include <bcm2835.h>
 
#define PIN RPI_GPIO_P1_03      // Для RPi ревизии v1
//#define PIN RPI_V2_GPIO_P1_03 // Для RPi ревизии v2

int main()
{
    if (!bcm2835_init())    // Инициализация GPIO
        return 1;               //Завершение программы, если инициализация не удалась

    bcm2835_gpio_fsel(PIN, BCM2835_GPIO_FSEL_OUTP); //Устанавливаем порт Р1_03 на вывод
    bcm2835_gpio_write(PIN, LOW);                                   // Устанавливаем порт в 0, светодиод горит
    bcm2835_delay(1000);                                                  // Ждём 1000 мс
    bcm2835_gpio_write(PIN, HIGH);                                  // Устанавливаем порт в 1, светодиод не горит
    return 0;
}
5. Scratch Design Studio 

Scratch (правильно читать - скретч) - среда разработки под расперри от группы Lifelong Kindergarten MIT Media Lab для детей от 8 до 16 лет и предназначена для создания своих собственных интерактивных историй, игр и мультфильмов дома, школе и библиотеке. Скретч помогает детям учиться думать творчески и критически, работать вместе. Продукт и среда открыты и бесплатны.

Руководство для начинающих: 1 | 2
Видеоуроки: http://scratch.mit.edu/help/videos
Официальный сайт проекта: http://scratch.mit.edu
Скачать: Mac OS X | Windows | Debian + Ubuntu

6. JAVA

Предварительно установите пакет sudo apt-get update && sudo apt-get install oracle-java7-jdk
Ознакомиться: http://www.raspberrypi.org/archives/4920

ОБРАЗЫ ОС
  1. http://www.raspberrypi.org/downloads (Raspbian, OpenELEC, RISC OS, Pidora, Arch, RaspBMC)
  2. http://pidora.ca
  3. MS Windows 10 IoT (бесплатно) - IOT Core Rpi.ISO (517 МБ)
ПРОЕКТЫ на базе платформы
  1. Raspberry Pi WiFi Radio 
  2. Retro Gaming with Raspberry Pi
  3. Cross Stitch 
  4. TIMESQUARE Watch Kit 
  5. Управление машиной через Web интерфейс GPIO Raspberry Pi 
  6. SIP телефон-клиент PJSIP + Linphonec 
  7. Soft DVR. Эмулятор видеорегистратора с циклической записью с IP-WEB камеры (ж.Радиолюбитель, 2015, №11) 
  8. Raspberry Pi: расширяем количество GPIO за счет интерфейса CSI
  9. Raspberry Pi Camera Board
  10. Система биометрической идентификации по лицу на базе OpenCV 
ГДЕ ПРИОБРЕСТИ? (Интернет-магазины)

Украина | Али-Экспресс | E-bay

Комментариев нет:

Отправить комментарий

В комментариях уважайте собеседника, внимательно читайте посты и не додумывайте. Просьбы и предложения из разряда: «можно ваш Skype/Viber/телефон», «напишите мне в vk/FB», а также другие им подобные — игнорируются. Выход новых версий ПО, внешняя ссылка, переставшая работать с течением времени и т.п. не является основанием для претензий. Желающие спокойно подискутировать и высказаться — Welcome. Желающие спонсировать блог — Donate. Нарушение этих простых правил ведет к бану и удалению комментариев без предупреждения.