Batch 3.docx

  • Uploaded by: Srikar K
  • 0
  • 0
  • October 2019
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Batch 3.docx as PDF for free.

More details

  • Words: 33,695
  • Pages: 127
Introduction to Embedded Systems:

Embedded systems are electronic devices that incorporate microprocessors with in Their implementations. The main purposes of the microprocessors are to simplify the system design and provide flexibility. Having a microprocessor in the device means that removing the bugs, making modifications, or adding new features are only matters of rewriting the software that controls the device. Or in other words embedded computer systems are electronic systems that include a microcomputer to perform a specific dedicated application. The computer is hidden inside these products. Embedded systems are ubiquitous. Every week millions of tiny computer chips come pouring out of factories finding their way into our everyday products. Embedded systems are self-contained programs that are embedded within a piece of hardware. Whereas a regular computer has many different applications and software that can be applied to various tasks, embedded systems are usually set to a specific task that cannot be altered without physically manipulating the circuitry. Another way to think of an embedded system is as a computer system that is created with optimal efficiency, thereby allowing it to complete specific functions as quickly as possible. Embedded systems designers usually have a significant grasp of hardware technologies. They used specific programming languages and software to develop embedded systems and manipulate the equipment. When searching online, companies offer embedded systems development kits and other embedded systems tools for use by engineers and businesses. Embedded systems technologies are usually fairly expensive due to the necessary development time and built in efficiencies, but they are also highly valued in specific industries. Smaller businesses may wish to hire a consultant to determine what sort of embedded systems will add value to your organization.

An embedded system is a system which is going to do a predefined specified task is the embedded system and is even defined as combination of both software and hardware. A generalpurpose definition of embedded systems is that they are devices used to control, monitor or assist the operation of equipment, machinery or plant. "Embedded" reflects the fact that they are an integral part of the system. At the other extreme a general-purpose computer may be used to control the operation of a large complex processing plant, and its presence will be obvious. All embedded systems are including computers or microprocessors. Some of these computers are however very simple systems as compared with a personal computer. The very simplest embedded systems are capable of performing only a single function or set of functions to meet a single predetermined purpose. In more complex systems an application program that enables the embedded system to be used for a particular purpose in a specific application determines the functioning of the embedded system. The ability to have programs means that the same embedded system can be used for a variety of different purposes. In some cases a microprocessor may be designed in such a way that application software for a particular purpose can be added to the basic software in a second process, after which it is not possible to make further changes. The applications software on such processors is sometimes referred to as firmware. The simplest devices consist of a single microprocessor (often called a "chip”), which may itself be packaged with other chips in a hybrid system or Application Specific Integrated Circuit (ASIC). Its input comes from a detector or sensor and its output goes to a switch or activator which (for example) may start or stop the operation of a machine or, by operating a valve, may control the flow of fuel to an engine. As the embedded system is the combination of both software and hardware

Embedded System

Software

Hardware

o

ALP

o

Processor

o

C

o

Peripherals

o

VB

o

memory

Etc.,

Figure: Block diagram of Embedded System Software deals with the languages like ALP, C, and VB etc., and Hardware deals with Processors, Peripherals, and Memory. Memory: It is used to store data or address. Peripherals: These are the external devices connected Processor: It is an IC which is used to perform some task Applications of embedded systems 

Manufacturing and process control



Construction industry



Transport



Buildings and premises



Domestic service



Communications



Office systems and mobile equipment



Banking, finance and commercial



Medical diagnostics, monitoring and life support



Testing, monitoring and diagnostic systems

Processors are classified into four types like: 

Micro Processor (µp)



Micro controller (µc)



Digital Signal Processor (DSP)



Application Specific Integrated Circuits (ASIC)

Micro Processor (µp) A silicon chip that contains a CPU. In the world of personal computers, the terms microprocessor and CPU are used interchangeably. At the heart of all personal computers and most workstations sits a microprocessor. Microprocessors also control the logic of almost all digital devices, from clock radios to fuel-injection systems for automobiles. Three basic characteristics differentiate microprocessors 

Instruction set: The set of instructions that the microprocessor can execute.



Bandwidth : The number of bits processed in a single instruction.



Clock speed : Given in megahertz (MHz), the clock speed determines how many

instructions per second the processor can execute. In both cases, the higher the value, the more powerful the CPU. For example, a 32-bit microprocessor that runs at 50MHz is more powerful than a 16-bit microprocessor that runs at 25MHz. In addition to bandwidth and clock speed, microprocessors are classified as being either RISC (reduced instruction set computer) or CISC (complex instruction set computer). A microprocessor has three basic elements, as shown above. The ALU performs all arithmetic computations, such as addition, subtraction and logic operations (AND, OR, etc). It is controlled by the Control Unit and receives its data from the Register Array. The Register Array is a set of registers used for storing data. These registers can be accessed by the ALU very quickly. Some registers have specific functions - we will deal with these later. The Control Unit controls the entire process. It provides the timing and a control signal for getting data into and out of the registers and the ALU and it synchronizes the execution of instructions (we will deal with instruction execution at a later date).

Three Basic Elements of a Microprocessor Micro Controller (µc): A microcontroller is a small computer on a single integrated circuit containing a processor core, memory, and programmable input/output peripherals. Program memory in the form of NOR flash or OTP ROM is also often included on chip, as well as a typically small amount of RAM. Microcontrollers are designed for embedded applications, in contrast to the microprocessors used in personal computers or other general purpose applications.

ALU CU Memory

Figure: Block Diagram of Micro

Timer, Counter, serial communication ROM, ADC, DAC, Timers, USART, Oscillators Controller (µc)

Etc.,

Digital Signal Processors (DSPs):

Digital Signal Processors is one which performs scientific and mathematical operation. Digital Signal Processor chips - specialized microprocessors with architectures designed specifically for the types of operations required in digital signal processing. Like a general-purpose microprocessor, a DSP is a programmable device, with its own native instruction code. DSP chips are capable of carrying out millions of floating point operations per second, and like their better-known general-purpose cousins, faster and more powerful versions are continually being introduced. DSPs can also be embedded within complex "system-on-chip" devices, often containing both analog and digital circuitry. Application Specific Integrated Circuit (ASIC) ASIC is a combination of digital and analog circuits packed into an IC to achieve the desired control/computation function ASIC typically contains 

CPU cores for computation and control



Peripherals to control timing critical functions



Memories to store data and program



Analog circuits to provide clocks and interface to the real world which is analog

in nature 

I/Os to connect to external components like LEDs, memories, monitors etc.

Computer Instruction Set There are two different types of computer instruction set there are: 1. RISC (Reduced Instruction Set Computer) and 2. CISC (Complex Instruction Set computer) Reduced Instruction Set Computer (RISC) A RISC (reduced instruction set computer) is a microprocessor that is designed to perform a smaller number of types of computer instruction so that it can operate at a higher speed (perform more million instructions per second, or millions of instructions per second). Since each instruction type that a computer must perform requires additional transistors and circuitry, a

larger list or set of computer instructions tends to make the microprocessor more complicated and slower in operation. Besides performance improvement, some advantages of RISC and related design improvements are: 

A new microprocessor can be developed and tested more quickly if one of its aims is to

be less complicated. 

Operating system and application programmers who use the microprocessor's instructions

will find it easier to develop code with a smaller instruction set. 

The simplicity of RISC allows more freedom to choose how to use the space on a

microprocessor. Higher-level language compilers produce more efficient code than formerly because they have always tended to use the smaller set of instructions to be found in a RISC computer. RISC characteristics 

Simpleinstructionset:

In a RISC machine, the instruction set contains simple, basic instructions, from which more complex instructions can be composed. 

Samelengthinstructions.

Each instruction is the same length, so that it may be fetched in a single operation. 

1machine-cycleinstructions.

Most instructions complete in one machine cycle, which allows the processor to handle several instructions at the same time. This pipelining is a key technique used to speed up RISC machines. Complex Instruction Set Computer (CISC) CISC, which stands for Complex Instruction Set Computer, is a philosophy for designing chips that are easy to program and which make efficient use of memory. Each instruction in a CISC instruction set might perform a series of operations inside the processor. This reduces the number of instructions required to implement a given program, and allows the programmer to learn a small but flexible set of instructions.

The advantages of CISC At the time of their initial development, CISC machines used available technologies to optimize computer performance. 

Microprogramming is as easy as assembly language to implement, and much less

expensive than hardwiring a control unit. 

The ease of micro-coding new instructions allowed designers to make CISC machines

upwardly compatible: a new computer could run the same programs as earlier computers because the new computer would contain a superset of the instructions of the earlier computers. 

As each instruction became more capable, fewer instructions could be used to implement

a given task. This made more efficient use of the relatively slow main memory. 

Because micro program instruction sets can be written to match the constructs of high-

level languages, the compiler does not have to be as complicated.

Disadvantages of CISC Still, designers soon realized that the CISC philosophy had its own problems, including: 

Earlier generations of a processor family generally were contained as a subset in every

new version --- so instruction set & chip hardware become more complex with each generation of computers. 

So that as many instructions as possible could be stored in memory with the least possible

wasted space, individual instructions could be of almost any length---this means that different instructions will take different amounts of clock time to execute, slowing down the overall performance of the machine. 

Many specialized instructions aren't used frequently enough to justify their existence ---

approximately 20% of the available instructions are used in a typical program. 

CISC instructions typically set the condition codes as a side effect of the instruction. Not

only does setting the condition codes take time, but programmers have to remember to examine the condition code bits before a subsequent instruction changes them.

Memory Architecture There two different type’s memory architectures there are: 

Harvard Architecture



Von-Neumann Architecture

Harvard Architecture Computers have separate memory areas for program instructions and data. There are two or more internal data buses, which allow simultaneous access to both instructions and data. The CPU fetches program instructions on the program memory bus. The Harvard architecture is a computer architecture with physically separate storage and signal pathways for instructions and data. The term originated from the Harvard Mark I relay-based computer, which stored instructions on punched tape (24 bits wide) and data in electromechanical counters. These early machines had limited data storage, entirely contained within the central processing unit, and provided no access to the instruction storage as data. Programs needed to be loaded by an operator, the processor could not boot itself.

Figure: Harvard Architecture Modern uses of the Harvard architecture:

The principal advantage of the pure Harvard architecture - simultaneous access to more than one memory system - has been reduced by modified Harvard processors using modern CPU cache systems. Relatively pure Harvard architecture machines are used mostly in applications where tradeoffs, such as the cost and power savings from omitting caches, outweigh the programming penalties from having distinct code and data address spaces. 

Digital signal processors (DSPs) generally execute small, highly-optimized audio or video

processing algorithms. They avoid caches because their behavior must be extremely reproducible. The difficulties of coping with multiple address spaces are of secondary concern to speed of execution. As a result, some DSPs have multiple data memories in distinct address spaces to facilitate SIMD and VLIW processing. Texas Instruments TMS320 C55x processors, as one example, have multiple parallel data busses (two write, three read) and one instruction bus. 

Microcontrollers are characterized by having small amounts of program (flash memory) and

data (SRAM) memory, with no cache, and take advantage of the Harvard architecture to speed processing by concurrent instruction and data access. The separate storage means the program and data memories can have different bit depths, for example using 16-bit wide instructions and 8-bit wide data. They also mean that instruction pre-fetch can be performed in parallel with other activities. Examples include, the AVR by Atmel Corp, the PIC by Microchip Technology, Inc. and the ARM Cortex-M3 processor (not all ARM chips have Harvard architecture).

Even in these cases, it is common to have special instructions to access program memory as data for read-only tables, or for reprogramming.

Von-Neumann Architecture A computer has a single, common memory space in which both program instructions and data are stored. There is a single internal data bus that fetches both instructions and data. They cannot be performed at the same time The von Neumann architecture is a design model for a stored-program digital computer that uses a central processing unit (CPU) and a single separate storage structure ("memory") to hold both instructions and data. It is named after the mathematician and early computer scientist John von Neumann. Such computers implement a universal Turing machine and have a sequential architecture.

A stored-program digital computer is one that keeps its programmed instructions, as well as its data, in read-write, random-access memory (RAM). Stored-program computers were advancement over the program-controlled computers of the 1940s, such as the Colossus and the ENIAC, which were programmed by setting switches and inserting patch leads to route data and to control signals between various functional units. In the vast majority of modern computers, the same memory is used for both data and program instructions. The mechanisms for transferring the data and instructions between the CPU and memory are, however, considerably more complex than the original von Neumann architecture. The terms "von Neumann architecture" and "stored-program computer" are generally used interchangeably, and that usage is followed in this article.

Figure: Schematic of the Von-Neumann Architecture. Basic Difference between Harvard and Von-Neumann Architecture 

The primary difference between Harvard architecture and the Von Neumann architecture

is in the Von Neumann architecture data and programs are stored in the same memory and managed by the same information handling system. 

Whereas the Harvard architecture stores data and programs in separate memory devices

and they are handled by different subsystems. 

In a computer using the Von-Neumann architecture without cache; the central processing

unit (CPU) can either be reading and instruction or writing/reading data to/from the memory. Both of these operations cannot occur simultaneously as the data and instructions use the same system bus.



In a computer using the Harvard architecture the CPU can both read an instruction and

access data memory at the same time without cache. This means that a computer with Harvard architecture can potentially be faster for a given circuit complexity because data access and instruction fetches do not contend for use of a single memory pathway. 

Today, the vast majority of computers are designed and built using the Von Neumann

architecture template primarily because of the dynamic capabilities and efficiencies gained in designing, implementing, operating one memory system as opposed to two. Von Neumann architecture may be somewhat slower than the contrasting Harvard Architecture for certain specific tasks, but it is much more flexible and allows for many concepts unavailable to Harvard architecture such as self programming, word processing and so on. 

Harvard architectures are typically only used in either specialized systems or for very

specific uses. It is used in specialized digital signal processing (DSP), typically for video and audio processing products. It is also used in many small microcontrollers used in electronics applications such as Advanced RISK Machine (ARM) based products for many vendors.

Characteristics Two major areas of differences are cost and power consumption. Since many embedded systems are produced in the tens of thousands to millions of units range, reducing cost is a major concern. Embedded systems often use a (relatively) slow processor and small memory size to minimize costs.The slowness is not just clock speed. The whole architecture of the computer is often intentionally simplified to lower costs. For example, embedded systems often use peripherals controlled by synchronous serial interfaces, which are ten to hundreds of times slower than comparable peripherals used in PCs.Programs on an embedded system often must run with real-time constraints with limited hardware resources: often there is no disk drive, operating system, keyboard or screen. A flash drive may replace rotating media, and a small keypad and LCD screen may be used instead of a PC's keyboard and screen.Firmware is the

name for software that is embedded in hardware devices, e.g. in one or more ROM/Flash memory IC chips. Embedded systems are routinely expected to maintain 100% reliability while running continuously for long periods, sometimes measured in years. Firmware is usually developed and tested too much stricter requirements than is general-purpose software, which can usually be easily restarted if a problem occurs.

Platform There are many different CPU architectures used in embedded designs. This in contrast to the desktop computer market, which as of this writing (2003) is limited to just a few competing architectures, mainly the Intel/AMD x86, and the Apple/Motorola/IBM PowerPC, used in the Apple Macintosh.One common configuration for embedded systems is the system on a chip, an application-specific integrated circuit, for which the CPU was purchased as intellectual property to add to the IC's design.

Tools Like a typical computer programmer, embedded system designers use compilers, assemblers and debuggers to develop an embedded system. Those software tools can come from several sources: Software companies that specialize in the embedded market Ported from the GNU software development tools. Sometimes, development tools for a personal computer can be used if the embedded processor is a close relative to a common PC processor. Embedded system designers also use a few software tools rarely used by typical computer programmers.Some designers keep a utility program to turn data files into code, so that they can include any kind of data in a program. Most designers also have utility

programs to add a checksum or CRC to a program, so it can check its program data before executing it.

Operating system They often have no operating system, or a specialized embedded operating system (often a real-time operating system), or the programmer is assigned to port one of these to the new system.

Debugging Debugging is usually performed with an in-circuit emulator, or some type of debugger that can interrupt the micro controller’s internal microcode. The microcode interrupt lets the debugger operate in hardware in which only the CPU works. The CPU-based debugger can be used to test and debug the electronics of the computer from the viewpoint of the CPU. This feature was pioneered on the PDP-11. Developers should insist on debugging which shows the high-level language, with breakpoints and single stepping, because these features are widely available. Also, developers should write and use simple logging facilities to debug sequences of real-time events.PC or mainframe programmers first encountering this sort of programming often become confused about design priorities and acceptable methods. Mentoring, code-reviews and ego less programming are recommended.

Design of embedded systems The electronics usually uses either a microprocessor or a micro controller. Some large or old systems use general-purpose mainframes computers or minicomputers.

Start-up

All embedded systems have start-up code. Usually it disables interrupts, sets up the electronics, tests the computer (RAM, CPU and software), and then starts the application code. Many embedded systems recover from short-term power failures by restarting (without recent self-tests). Restart times under a tenth of a second are common. Many designers have found one of more hardware plus software-controlled LEDs useful to indicate errors during development (and in some instances, after product release, to produce troubleshooting diagnostics). A common scheme is to have the electronics turn off the LED(s) at reset, whereupon the software turns it on at the first opportunity, to prove that the hardware and start-up software have performed their job so far. After that, the software blinks the LED(s) or sets up light patterns during normal operation, to indicate program execution progress and/or errors. This serves to reassure most technicians/engineers and some users.

The control loop In this design, the software simply has a loop. The loop calls subroutines. Each subroutine manages a part of the hardware or software. Interrupts generally set flags, or update counters that are read by the rest of the software.A simple API disables and enables interrupts. Done right, it handles nested calls in nested subroutines, and restores the preceding interrupt state in the outermost enable. This is one of the simplest methods of creating an exokernel.Typically, there's some sort of subroutine in the loop to manage a list of software timers, using a periodic real time interrupt. When a timer expires, an associated subroutine is run, or flag is set.Any expected hardware event should be backed-up with a software timer. Hardware events fail about once in a trillion times. That's about once a year with modern hardware. With a million mass-produced devices, leaving out a software timer is a business disaster State machines may be implemented with a function-pointer per state-machine (in C++, C or assembly, anyway). A change of state stores a different function into the pointer. The function pointer is executed every time the loop runs. Many designers recommend reading each IO device once per loop, and storing the result so the logic acts on consistent values.

Many designers prefer to design their state machines to check only one or two things per state. Usually this is a hardware event, and a software timer. Designers recommend that hierarchical state machines should run the lower-level state machines before the higher, so the higher run with accurate information. Complex functions like internal combustion controls are often handled with multi-dimensional tables. Instead of complex calculations, the code looks up the values. The software can interpolate between entries, to keep the tables small and cheap One major weakness of this system is that it does not guarantee a time to respond to any particular hardware event. Careful coding can easily assure that nothing disables interrupts for long. Thus interrupt code can run at very precise timings. Another major weakness of this system is that it can become complex to add new features. Algorithms that take a long time to run must be carefully broken down so only a little piece gets done each time through the main loop.This system's strength is its simplicity, and on small pieces of software the loop is usually so fast that nobody cares that it is not predictable. Another advantage is that this system guarantees that the software will run. There is no mysterious operating system to blame for bad behavior.

User interfaces User interfaces for embedded systems vary wildly, and thus deserve some special comment. Designers recommend testing the user interface for usability at the earliest possible instant. A quick, dirty test is to ask an executive secretary to use cardboard models drawn with magic markers, and manipulated by an engineer. The videotaped result is likely to be both humorous and very educational. In the tapes, every time the engineer talk, the interface has failed: It would cause a service call. Exactly one person should approve the user interface. Ideally, this should be a customer, the major distributor or someone directly responsible for selling the system. The decision maker should be able to decide. The problem is that a committee will never make up its mind, and neither will some people. Not doing this causes avoidable, expensive delays. A usability test is more important than any number of opinions. Interface designers at PARC, Apple Computer, Boeing and HP minimize the number of types of user actions. For example, use two buttons (the

absolute minimum) to control a menu system (just to be clear, one button should be "next menu entry" the other button should be "select this menu entry"). A touch-screen or screen-edge buttons also minimize the types of user actions. Another basic trick is to minimize and simplify the type of output. Designs should consider using a status light for each interface plug, or failure condition, to tell what failed. A cheap variation is to have two light bars with a printed matrix of errors that they select- the user can glue on the labels for the language that she speaks. For example, Boeing's standard test interface is a button and some lights. When you press the button, all the lights turn on. When you release the button, the lights with failures stay on. The labels are in Basic English. For another example, look at a small computer printer. You might have one next to your computer. Notice that the lights are labeled with stick-on labels that can be printed in any language. Really look at it. Designers use colors. Red means the users can get hurt- think of blood. Yellow means something might be wrong. Green means everything's OK. Another essential trick is to make any modes absolutely clear on the user's display. If an interface has modes, they must be reversible in an obvious way. Most designers prefer the display to respond to the user. The display should change immediately after a user action. If the machine is going to do anything, it should start within 7 seconds, or give progress reports. If a design needs a screen, many designers use plain text. It can be sold as a temporary expedient. Why is it better than pictures? Users have been reading signs for years. A GUI is pretty and can do anything, but typically adds a year from artist, approval and translator delays and one or two programmers to a project's cost, without adding any value. Often, a clever GUI actually confuses users. If a design needs to point to parts of the machine (as in copiers), these are labeled with numbers on the actual machine, that are visible with the doors closed. A network interface is just a remote screen. It needs the same caution as any other user interface. One of the most successful general-purpose screen-based interfaces is the two menu buttons and a line of text in the user's native language. It's used in pagers, mediumpriced printers, network switches, and other medium-priced situations that require complex behavior from users When there's text, there are languages. The default

language should be the one most widely understood. Right now this is English. French and Spanish follow. Most designers recommend that one use the native character sets, no matter how painful. People with peculiar character sets feel coddled and loved when their language shows up on machinery they use. Text should be translated by professional translators, even if native speakers are on staff. Marketing staff have to be able to tell foreign distributors that the translations are professional. A foreign organization should give the highest-volume distributor the duty to review and correct any translations in his native language. This stops critiques by other native speakers, who tend to believe that no foreign organization will ever know their language as well as they.

AT89C51 MICROCONTROLLER

FEATURES  80C51 based architecture

 4-Kbytes of on-chip Reprogrammable Flash Memory  128 x 8 RAM  Two 16-bit Timer/Counters  Full duplex serial channel  Boolean processor  Four 8-bit I/O ports, 32 I/O lines  Memory addressing capability –

64K ROM and 64K RAM

 Power save modes: –

Idle and power-down

 Six interrupt sources  Most instructions execute in 0.3 us  CMOS and TTL compatible  Maximum speed: 40 MHz @ Vcc = 5V  Industrial temperature available  Packages available: – 40-pin DIP – 44-pin PLCC – 44-pin PQFP

GENERAL DESCRIPTION: THE MICROCONTROLLER:

A microcontroller is a general purpose device, but that is meant to read data, perform limited calculations on that data and control its environment based on those calculations. The prime use of a microcontroller is to control the operation of a machine using a fixed program that is stored in ROM and that does not change over the lifetime of the system. The microcontroller design uses a much more limited set of single and double byte instructions that are used to move data and code from internal memory to the ALU. The microcontroller is concerned with getting data from and to its own pins; the architecture and instruction set are optimized to handle data in bit and byte size. The AT89C51 is a low-power, high-performance CMOS 8-bit microcontroller with 4k bytes of Flash Programmable and erasable read only memory (EROM). The device is manufactured using Atmel’s high-density nonvolatile memory technology and is functionally compatible with the industry-standard 80C51 microcontroller instruction set and pin out. By combining versatile 8-bit CPU with Flash on a monolithic chip, the Atmel’s AT89c51 is a powerful microcomputer, which provides a high flexible and cost- effective solution to many embedded control applications.

Pin configuration of AT89c51 Microcontroller

AT89C51 Block Diagram

PIN DESCRIPTION: VCC Supply voltage GND Ground Port 0 Port 0 is an 8-bit open drain bi-directional I/O port. As an output port, each pin can sink eight TTL inputs. When 1s are written to port 0 pins, the pins can be used as high impedance inputs. Port 0 can also be configured to be the multiplexed low order address/data bus during access to external program and data memory. In this mode, P 0 has internal pull-ups. Port 0 also receives the code bytes during Flash programming and outputs the code bytes during program verification. External pull-ups are required during program verification. Port 1 Port 1 is an 8-bit bi-directional I/O port with internal pull-ups. The port 1output buffers can sink/source four TTL inputs. When 1s are written to port 1 pins, they are pulled high by the internal pull-ups can be used as inputs. As inputs, Port 1 pins that are externally being pulled low will source current (1) because of the internal pull-ups.

Port 2 Port 2 is an 8-bit bi-directional I/O port with internal pull-ups. The port 2 output buffers can sink/source four TTL inputs. When 1s are written to port 2 pins, they are pulled high by the internal pull-ups can be used as inputs. As inputs, Port 2 pins that are externally being pulled low will source current because of the internal pull-ups.

Port 2 emits the high-order address byte during fetches from external program memory and during access to DPTR. In this application Port 2 uses strong internal pull-ups when emitting 1s. During accesses to external data memory that use 8-bit data address (MOVX@R1), Port 2 emits the contents of the P2 Special Function Register. Port 2 also receives the high-order address bits and some control signals during Flash programming and verification. Port 3 Port 3 is an 8-bit bi-directional I/O port with internal pull-ups. The port 3 output buffers can sink/source four TTL inputs. When 1s are written to port 3 pins, they are pulled high by the internal pull-ups can be used as inputs. As inputs, Port 3 pins that are externally being pulled low will source current because of the internal pull-ups. Port 3 also receives some control signals for Flash Programming and verification

Port pin

Alternate Functions

P3.0

RXD(serial input port)

P3.1

TXD(serial input port)

P3.2

INT0(external interrupt 0)

P3.3

INT1(external interrupt 1)

P3.4

T0(timer 0 external input)

P3.5

T1(timer 1 external input)

P3.6

WR(external data memory write strobe)

P3.7

RD(external data memory read strobe)

RST Rest input A on this pin for two machine cycles while the oscillator is running resets the device.

ALE/PROG: Address Latch Enable is an output pulse for latching the low byte of the address during access to external memory. This pin is also the program pulse input (PROG) during Flash programming. In normal operation ALE is emitted at a constant rate of 1/16 the oscillator frequency and may be used for external timing or clocking purpose. Note, however, that one ALE pulse is skipped during each access to external Data memory. _____ PSEN Program Store Enable is the read strobe to external program memory when the AT89c51 is executing code from external program memory PSEN is activated twice each machine cycle, except that two PSEN activations are skipped during each access to external data memory. __ EA /VPP External Access Enable (EA) must be strapped to GND in order to enable the device to fetch code from external program memory locations starting at 0000h up to FFFFH. Note, however, that if lock bit 1 is programmed EA will be internally latched on reset. EA should be strapped to Vcc for internal program executions. This pin also receives the 12-volt programming enable voltage (Vpp) during Flash programming when 12-volt programming is selected. XTAL1 Input to the inverting oscillator amplifier and input to the internal clock operating circuit. XTAL 2

Output from the inverting oscillator amplifier.

OPERATING DESCRIPTION The detail description of the AT89C51 included in this description is: • Memory Map and Registers • Timer/Counters • Interrupt System MEMORY MAP AND REGISTERS Memory The AT89C51 has separate address spaces for program and data memory. The program and data memory can be up to 64K bytes long. The lower 4K program memory can reside onchip. The AT89C51 has 128 bytes of on-chip RAM. The lower 128 bytes can be accessed either by direct addressing or by indirect addressing. The lower 128 bytes of RAM can be divided into 3 segments as listed below 1. Register Banks 0-3: locations 00H through 1FH (32 bytes). The device after reset defaults to register bank 0. To use the other register banks, the user must select them in software. Each register bank contains eight 1-byte registers R0-R7. Reset initializes the stack point to location 07H, and is incremented once to start from 08H, which is the first register of the second register bank. 2. Bit Addressable Area: 16 bytes have been assigned for this segment 20H-2FH. Each one of the 128 bits of this segment can be directly addressed (0-7FH). Each of the 16 bytes in this segment can also be addressed as a byte. 3. Scratch Pad Area: 30H-7FH are available to the user as data RAM. However, if the data pointer has been initialized to this area, enough bytes should be left aside to prevent SP data destruction.

SPECIAL FUNCTION REGISTERS The Special Function Registers (SFR's) are located in upper 128 Bytes direct addressing area. The SFR Memory Map in shows that. Not all of the addresses are occupied. Unoccupied addresses are not implemented on the chip. Read accesses to these addresses in general return random data, and write accesses have no effect. User software should not write 1s to these unimplemented locations, since they may be used in future microcontrollers to invoke new features. In that case, the reset or inactive values of the new bits will always be 0, and their active values will be 1. The functions of the SFR’s are outlined in the following sections. Accumulator (ACC) ACC is the Accumulator register. The mnemonics for Accumulator-specific instructions, however, refer to the Accumulator simply as A.

B Register (B) The B register is used during multiply and divide operations. For other instructions it can be treated as another scratch pad register. Program Status Word (PSW) The PSW register contains program status information. Stack Pointer (SP) The Stack Pointer Register is eight bits wide. It is incremented before data is stored during PUSH and CALL executions. While the stack may reside anywhere in on chip RAM, the Stack Pointer is initialized to 07H after a reset. This causes the stack to begin at location 08H. Data Pointer (DPTR) The Data Pointer consists of a high byte (DPH) and a low byte (DPL). Its function is to hold a 16-bit address. It may be manipulated as a 16-bit register or as two independent 8-bit registers. Serial Data Buffer (SBUF) The Serial Data Buffer is actually two separate registers, a transmit buffer and a receive buffer register. When data is moved to SBUF, it goes to the transmit buffer, where it is held for serial transmission. (Moving a byte to SBUF initiates the transmission.) When data is moved from SBUF, it comes from the receive buffer. Timer Registers Register pairs (TH0, TL0) and (TH1, TL1) are the 16-bit Counter registers for Timer/Counters 0 and 1, respectively. Control Registers Special Function Registers IP, IE, TMOD, TCON, SCON, and PCON contain control and status bits for the interrupt system, the Timer/Counters, and the serial port.

TIMER/COUNTERS The IS89C51 has two 16-bit Timer/Counter registers: Timer 0 and Timer 1. All two can be configured to operate either as Timers or event counters. As a Timer, the register is incremented every machine cycle. Thus, the register counts machine cycles. Since a machine cycle consists of 12 oscillator periods, the count rate is 1/12 of the oscillator frequency. As a Counter, the register is incremented in response to a 1-to-0 transition at its corresponding external input pin, T0 and T1. The external input is sampled during S5P2 of every machine cycle. When the samples show a high in one cycle and a low in the next cycle, the count is incremented. The new count value appears in the register during S3P1 of the cycle following the one in which the transition was detected. Since two machine cycles (24 oscillator periods) are required to recognize a 1-to-0 transition, the maximum count rate is 1/24 of the oscillator frequency. There are no restrictions on the duty cycle of the external input signal, but it should be held for at least one full machine cycle to ensure that a given level is sampled at least once before it changes.In addition to the Timer or Counter functions, Timer 0 and Timer 1 have four operating modes: 13-bit timer, 16-bit timer, 8-bit auto-reload, split timer. TIMERS: OSCILLATOR FREQUENCY

12D

TR

SFR’S USED IN TIMERS The special function registers used in timers are, 

TMOD Register



TCON Register

TLX

THX

TFX



Timer(T0) & timer(T1) Registers

(i) TMOD Register: TMOD is dedicated solely to the two timers (T0 & T1). 

The timer mode SFR is used to configure the mode of operation of each of the two timers. Using this SFR your program may configure each timer to be a 16-bit timer, or 13 bit timer, 8-bit auto reload timer, or two separate timers. Additionally you may configure the timers to only count when an external pin is activated or to count “events” that are indicated on an external pin.



It can consider as two duplicate 4-bit registers, each of which controls the action of one of the timers.

(ii) TCON Register 

The timer control SFR is used to configure and modify the way in which the 8051’s two timers operate. This SFR controls whether each of the two timers is running or stopped and contains a flag to indicate that each timer has overflowed. Additionally, some nontimer related bits are located in TCON SFR.



These bits are used to configure the way in which the external interrupt flags are activated, which are set when an external interrupt occurs.

(iii) TIMER 0 (T0): 

TO (Timer 0 low/high, address 8A/8C h) These two SFR’s taken together represent timer 0. Their exact behavior depends on how the timer is configured in the TMOD SFR; however, these timers always count up. What is configurable is how and when they increment in value.

TH0

TL0

(iv) TIMER 1 (T1): 

T1 (Timer 1 Low/High, address 8B/ 8D h)

These two SFR’s, taken together, represent timer 1. Their exact behavior depends on how the timer is configured in the TMOD SFR; however, these timers always count up. What is Configurable is how and when they increment in value.

TH1

TL1

The Timer or Counter function is selected by control bits C/T in the Special Function Register TMOD. These two Timer/Counters have four operating modes, which are selected by bit pairs (M1, M0) in TMOD. Modes 0, 1, and 2 are the same for both Timer/Counters, but Mode 3 is different. The four modes are described in the following sections. Mode 0: Both Timers in Mode 0 are 8-bit Counters with a divide-by-32 pre scalar. Figure 8 shows the Mode 0 operation as it applies to Timer 1. In this mode, the Timer register is configured as a 13-bit register. As the count rolls over from all 1s to all 0s, it sets the Timer interrupt flag TF1. The counted input is enabled to the Timer when TR1 = 1 and either GATE = 0 or INT1 = 1. Setting GATE = 1 allows the Timer to be controlled by external input INT1, to facilitate pulse width measurements. TR1 is a control bit in the Special Function Register TCON. Gate is in TMOD.

The 13-bit register consists of all eight bits of TH1 and the lower five bits of TL1. The upper three bits of TL1 are indeterminate and should be ignored. Setting the run flag (TR1) does not clear the registers. Mode 0 operation is the same for Timer 0 as for Timer 1, except that TR0, TF0 and INT0 replace the corresponding Timer 1 signals. There are two different GATE bits, one for Timer 1 (TMOD.7) and one for Timer 0 (TMOD.3). Mode 1 Mode 1 is the same as Mode 0, except that the Timer register is run with all 16 bits. The clock is applied to the combined high and low timer registers (TL1/TH1). As clock pulses are received, the timer counts up: 0000H, 0001H, 0002H, etc. An overflow occurs on the FFFFH-to0000H overflow flag. The timer continues to count. The overflow flag is the TF1 bit in TCON that is read or written by software Mode 2 Mode 2 configures the Timer register as an 8-bit Counter (TL1) with automatic reload, as shown in Figure 10. Overflow from TL1 not only sets TF1, but also reloads TL1 with the contents of TH1, which is preset by software. The reload leaves the TH1 unchanged. Mode 2 operation is the same for Timer/Counter 0.

Mode 3 Timer 1 in Mode 3 simply holds its count. The effect is the same as setting TR1 = 0. Timer 0 in Mode 3 establishes TL0and TH0 as two separate counters. The logic for Mode 3 on Timer 0 is shown in Figure 11. TL0 uses the Timer 0 control bits: C/T, GATE, TR0, INT0, and TF0. TH0 is locked into a timer function (counting machine cycles) and over the use of TR1 and TF1 from Timer 1. Thus, TH0 now controls the Timer 1 interrupt. Mode 3 is for applications requiring an extra 8-bit timer or counter. With Timer 0 in Mode 3, the AT89C51 can appear to have three Timer/Counters. When Timer 0 is in Mode 3, Timer 1 can be turned on and off by switching it out of and into its own Mode 3. In this case,

Timer 1 can still be used by the serial port as a baud rate generator or in any application not requiring an interrupt.

INTERRUPT SYSTEM An interrupt is an external or internal event that suspends the operation of micro controller to inform it that a device needs its service. In interrupt method, whenever any device needs its service, the device notifies the micro controller by sending it an interrupt signal. Upon receiving an interrupt signal, the micro controller interrupts whatever it is doing and serves the device. The program associated with interrupt is called as interrupt service subroutine (ISR).Main advantage with interrupts is that the micro controller can serve many devices. Baud Rate The baud rate in Mode 0 is fixed as shown in the following equation. Mode 0 Baud Rate = Oscillator Frequency /12 the baud rate in Mode 2 depends on the value of the SMOD bit in Special Function Register PCON. If SMOD = 0 the baud rate is 1/64 of the oscillator frequency. If SMOD = 1, the baud rate is 1/32 of the oscillator frequency. Mode 2 Baud Rate = 2SMODx (Oscillator Frequency)/64. In the IS89C51, the Timer 1 overflow rate determines the baud rates in Modes 1 and 3. NUMBER OF INTERRUPTS IN 89C51: There are basically five interrupts available to the user. Reset is also considered as an interrupt. There are two interrupts for timer, two interrupts for external hardware interrupt and one interrupt for serial communication. Memory location

Interrupt name

0000H

Reset

0003H

External interrupt 0

000BH

Timer interrupt 0

0013H

External interrupt 1

001BH

Timer interrupt 1

0023H

Serial COM interrupt

Lower the vector, higher the priority. The External Interrupts INT0 and INT1 can each be either level-activated or transition-activated, depending on bits IT0 and IT1 in Register TCON. The flags that actually generate these interrupts are the IE0 and IE1 bits in TCON. When the service routine is vectored, hardware clears the flag that generated an external interrupt only if the interrupt was transition-activated. If the interrupt was level-activated, then the external requesting source (rather than the on-chip hardware) controls the request flag. The Timer 0 and Timer 1 Interrupts are generated by TF0and TF1, which are set by a rollover in their respective Timer/Counter registers (except for Timer 0 in Mode 3).When a timer interrupt is generated, the on-chip hardware clears the flag that is generated. The Serial Port Interrupt is generated by the logical OR of RI and TI. The service routine normally must determine whether RI or TI generated the interrupt, and the bit must be cleared in software. All of the bits that generate interrupts can be set or cleared by software, with the same result as though they had been set or cleared by hardware. That is, interrupts can be generated and pending interrupts can be canceled in software. Each of these interrupt sources can be individually enabled or disabled by setting or clearing a bit in Special Function Register IE (interrupt enable) at address 0A8H. There is a global enable/disable bit that is cleared to disable all interrupts or to set the interrupts. IE (Interrupt enable register) Steps in enabling an interrupt

Bit D7 of the IE register must be set to high to allow the rest of register to take effect. If EA=1, interrupts are enabled and will be responded to if their corresponding bits in IE are high. If EA=0, no interrupt will be responded to even if the associated bit in the IE register is high. Description of each bit in IE register D7 bit: Disables all interrupts. If EA =0, no interrupt is acknowledged, if EA=1 each interrupt source is individually enabled or disabled by setting or clearing its enable bit. D6 bit: Reserved. D5 bit: Enables or disables timer 2 over flow interrupt (in 8052). D4 bit: Enables or disables serial port interrupt. D3 bit: Enables or disables timer 1 over flow interrupt. D2 bit: Enables or disables external interrupt 1. D1 bit: Enables or disables timer 0 over flow interrupt. D0 bit: Enables or disables external interrupt 0. Interrupt priority in 89C51 There is one more SRF to assign priority to the interrupts which is named as interrupt priority (IP). User has given the provision to assign priority to one interrupt. Writing one to that particular bit in the IP register fulfils the task of assigning the priority. Description of each bit in IP register D7 bit: Reserved. D6 bit: Reserved. D5 bit: Timer 2 interrupt priority bit (in 8052). D4 bit: Serial port interrupt priority bit. D3 bit: Timer 1 interrupt priority bit.

D2 bit: External interrupt 1 priority bit. D1 bit: Timer 0 interrupt priority bit. D0 bit: External interrupt 0 priority bit.

RPi" redirects here. For other uses, see RPI. For the dessert, see Raspberry pie (food).

Raspberry Pi

Raspberry Pi 3 Model B+

Also known as

RPi

Release date

29 February 2012; 7 years ago

Introductory price

US$35[1]

Operating system

Linux FreeBSD NetBSD OpenBSD Plan 9 RISC OS Windows 10 IoT Core Windows 10 ARM64[2]

System-on-

Broadcom BCM2837B0

chip used

CPU

1.4 GHz 64/32-bit quad-core ARM Cortex-A53

Memory

1 GB LPDDR2 RAM at 900 MHz[3]

Storage

MicroSDHC slot

Graphics

Broadcom VideoCore IV 300 MHz/400 MHz

Power

1.5 W (average when idle) to 6.7 W (maximum under stress)[4]

Website

raspberrypi.org

The Raspberry Pi is a series of small single-board computers developed in the United Kingdom by the Raspberry Pi Foundationto promote teaching of basic computer science in schools and in developing countries.[5][6][7] The original model became far more popular than anticipated,[8] selling outside its target market for uses such as robotics. It does not include peripherals (such as keyboards and mice) and cases. However, some accessories have been included in several official and unofficial bundles.[8] The organisation behind the Raspberry Pi consists of two arms. The first two models were developed by the Raspberry Pi Foundation. After the Pi Model B was released, the Foundation set up Raspberry Pi Trading, with Eben Upton as CEO, to develop the third model, the B+. Raspberry Pi Trading is responsible for developing the technology while the Foundation is an educational charity to promote the teaching of basic computer science in schools and in developing countries.

According to the Raspberry Pi Foundation, more than 5 million Raspberry Pis were sold by February 2015, making it the best-selling British computer.[9] By November 2016 they had sold 11 million units,[10][11] and 12.5m by March 2017, making it the third best-selling "general purpose computer".[12] In July 2017, sales reached nearly 15 million.[13] In March 2018, sales reached 19 million.[1] Most Pis are made in a Sony factory in Pencoed, Wales;[14] some are made in China or Japan.[15] Several generations of Raspberry Pis have been released. All models feature a Broadcom system on a chip (SoC) with an integrated ARM-compatible central processing unit (CPU) and on-chip graphics processing unit (GPU). Processor speed ranges from 700 MHz to 1.4 GHz for the Pi 3 Model B+; on-board memory ranges from 256 MB to 1 GB RAM.Secure Digital (SD) cards in MicroSDHC form factor (SDHC on early models) are used to store the operating system and program memory. The boards have one to four USB ports. For video output, HDMI and composite video are supported, with a standard 3.5 mm tip-ring-sleevejack for audio output. Lower-level output is provided by a number of GPIO pins, which support common protocols like I²C. The B-models have an 8P8C Ethernet port and the Pi 3 and Pi Zero W have on-board Wi-Fi 802.11n and Bluetooth. Prices range from US$5 to $35. The first generation (Raspberry Pi 1 Model B) was released in February 2012, followed by the simpler and cheaper Model A. In 2014, the Foundation released a board with an improved design, Raspberry Pi 1 Model B+. These boards are approximately credit-card sized and represent the standard mainline form-factor. Improved A+ and B+ models were released a year later. A "Compute Module" was released in April 2014 for embedded applications. The Raspberry Pi 2, which added more random-access memory, was released in February 2015. A Raspberry Pi Zero with smaller size and reduced input/output (I/O) and general-purpose input/output (GPIO) capabilities was released in November 2015 for US$5. By 2017, it became the newest mainline Raspberry Pi. On 28 February 2017, the Raspberry Pi Zero W was launched, a version of the Zero with Wi-Fi and Bluetooth capabilities, for US$10.[16][17] On 12 January 2018, the Raspberry Pi Zero WH was launched, a version of the Zero W with pre-soldered GPIO headers.[18] Raspberry Pi 3 Model B was released in February 2016 with a 1.2 GHz 64-bit quad core processor, on-board WiFi, Bluetooth and USB boot capabilities.[19] On Pi Day 2018 the Raspberry Pi 3 Model B+ was launched with a faster 1.4 GHz processor and a three-times faster gigabit Ethernet (throughput limited to ca. 300 Mbit/s by the internal USB 2.0 connection) or 2.4 / 5 GHz dual-band Wi-Fi (100 Mbit/s).[1] Other features are Power over Ethernet (PoE), USB boot and network boot (an SD card is no longer required). Family

Model

Released

Discontinued

B

2012

Yes

GPIO

Ethernet

Wireless

Size

No

85.60 mm × 56.5 mm

Yes 26-pin

Raspberry Pi 1

A

2013

B+

2014

Yes

No

40-pin

Yes

Family

Raspberry Pi 2

Model

Released

A+

2014

B

2015

Zero

2015

Raspberry Pi Zero

GPIO

Ethernet

Wireless

65 mm × 56.5 mm

Yes

85.60 mm × 56.5 mm

No

No

2017

Yes

B

2016

Yes

A+

2018

No

B+

2018

Size

No

No W/WH

Raspberry Pi 3

Discontinued

65 mm × 30 mm

85.60 mm × 56.5 mm

Yes

Yes

Hardware[edit] The Raspberry Pi hardware has evolved through several versions that feature variations in memory capacity and peripheral-device support.

65 mm × 56.5 mm

85.60 mm × 56.5 mm

This block diagram describes Model B and B+; Model A, A+, and the Pi Zero are similar, but lack the Ethernet and USB hub components. The Ethernet adapter is internally connected to an additional USB port. In Model A, A+, and the Pi Zero, the USB port is connected directly to the system on a chip (SoC). On the Pi 1 Model B+ and later models the USB/Ethernet chip contains a five-port USB hub, of which four ports are available, while the Pi 1 Model B only provides two. On the Pi Zero, the USB port is also connected directly to the SoC, but it uses a micro USB (OTG) port.

Processor[edit]

The Raspberry Pi 2B uses a 32-bit 900 MHz quad-core ARM Cortex-A7processor.

The Broadcom BCM2835 SoC used in the first generation Raspberry Pi[20] includes a 700 MHz ARM11 76JZF-S processor, VideoCore IV graphics processing unit (GPU),[21] and RAM. It has a level 1 (L1) cache of 16 KB and a level 2 (L2) cache of 128 KB. The level 2 cache is used primarily by the GPU. The SoC is stacked underneath the RAM chip, so only its edge is visible. The 1176JZ(F)-S is the same CPU used in the original iPhone,[22] although at a higher clock rate, and mated with a much faster GPU. The earlier V1.1 model of the Raspberry Pi 2 used a Broadcom BCM2836 SoC with a 900 MHz 32bit, quad-core ARM Cortex-A7 processor, with 256 KB shared L2 cache.[23] The Raspberry Pi 2 V1.2 was upgraded to a Broadcom BCM2837 SoC with a 1.2 GHz 64-bit quad-core ARM CortexA53 processor,[24] the same SoC which is used on the Raspberry Pi 3, but underclocked (by default) to the same 900 MHz CPU clock speed as the V1.1. The BCM2836 SoC is no longer in production as of late 2016. The Raspberry Pi 3+ uses a Broadcom BCM2837B0 SoC with a 1.4 GHz 64-bit quad-core ARM Cortex-A53 processor, with 512 KB shared L2 cache.[1] Performance[edit] While operating at 700 MHz by default, the first generation Raspberry Pi provided a real-world performance roughly equivalent to 0.041 GFLOPS.[25][26] On the CPU level the performance is similar to a 300 MHz Pentium II of 1997–99. The GPU provides 1 Gpixel/s or 1.5 Gtexel/s of graphics processing or 24 GFLOPS of general purpose computing performance. The graphical capabilities of the Raspberry Pi are roughly equivalent to the performance of the Xbox of 2001. Raspberry Pi 2 V1.1 included a quad-core Cortex-A7 CPU running at 900 MHz and 1 GB RAM. It was described as 4–6 times more powerful than its predecessor. The GPU was identical to the original.[23] In parallelised benchmarks, the Raspberry Pi 2 V1.1 could be up to 14 times faster than a Raspberry Pi 1 Model B+.[27] The Raspberry Pi 3, with a quad-core ARM Cortex-A53 processor, is described as having ten times the performance of a Raspberry Pi 1.[28] This was suggested[by whom?] to be highly dependent upon task threading and instruction set use.[citation needed] Benchmarks showed the Raspberry Pi 3 to be approximately 80% faster than the Raspberry Pi 2 in parallelised tasks.[29]

Overclocking[edit] Most Raspberry Pi systems-on-chip could be overclocked to 800 MHz, and some to 1000 MHz. There are reports the Raspberry Pi 2 can be similarly overclocked, in extreme cases, even to 1500 MHz (discarding all safety features and over-voltage limitations). In the Raspbian Linux distro the overclocking options on boot can be done by a software command running "sudo raspiconfig" without voiding the warranty.[30] In those cases the Pi automatically shuts the overclocking down if the chip temperature reaches 85 °C (185 °F), but it is possible to override automatic overvoltage and overclocking settings (voiding the warranty); an appropriately sized heat sink is needed to protect the chip from serious overheating. Newer versions of the firmware contain the option to choose between five overclock ("turbo") presets that when used, attempt to maximise the performance of the SoC without impairing the lifetime of the board. This is done by monitoring the core temperature of the chip and the CPU load, and dynamically adjusting clock speeds and the core voltage. When the demand is low on the CPU or it is running too hot the performance is throttled, but if the CPU has much to do and the chip's temperature is acceptable, performance is temporarily increased with clock speeds of up to 1 GHz, depending on the board version and on which of the turbo settings is used. The seven overclock presets are:       

none; 700 MHz ARM, 250 MHz core, 400 MHz SDRAM, 0 overvolting modest; 800 MHz ARM, 250 MHz core, 400 MHz SDRAM, 0 overvolting, medium; 900 MHz ARM, 250 MHz core, 450 MHz SDRAM, 2 overvolting, high; 950 MHz ARM, 250 MHz core, 450 MHz SDRAM, 6 overvolting, turbo; 1000 MHz ARM, 500 MHz core, 600 MHz SDRAM, 6 overvolting, Pi 2; 1000 MHz ARM, 500 MHz core, 500 MHz SDRAM, 2 overvolting, Pi 3; 1100 MHz ARM, 550 MHz core, 500 MHz SDRAM, 6 overvolting. In system information the CPU speed will appear as 1200 MHz. When idling, speed lowers to 600 MHz.[30][31]

In the highest (turbo) preset the SDRAM clock was originally 500 MHz, but this was later changed to 600 MHz because 500 MHz sometimes causes SD card corruption. Simultaneously in high mode the core clock speed was lowered from 450 to 250 MHz, and in medium mode from 333 to 250 MHz. The Raspberry Pi Zero runs at 1 GHz. The CPU on the first and second generation Raspberry Pi board did not require cooling, such as a heat sink or fan, even when overclocked, but the Raspberry Pi 3 may generate more heat when overclocked.[32]

RAM[edit] On the older beta Model B boards, 128 MB was allocated by default to the GPU, leaving 128 MB for the CPU.[33] On the first 256 MB release Model B (and Model A), three different splits were possible. The default split was 192 MB (RAM for CPU), which should be sufficient for standalone 1080p video decoding, or for simple 3D, but probably not for both together. 224 MB was for Linux only, with only a 1080p framebuffer, and was likely to fail for any video or 3D. 128 MB was for heavy 3D, possibly also with video decoding (e.g. XBMC).[34] Comparatively the Nokia 701 uses 128 MB for the Broadcom VideoCore IV.[35] For the later Model B with 512 MB RAM, new standard memory split files (arm256_start.elf, arm384_start.elf, arm496_start.elf) were initially released for 256 MB, 384 MB and 496 MB CPU RAM (and 256 MB, 128 MB and 16 MB video RAM) respectively. But a week or so later the RPF released a new version of start.elf that could read a new entry in config.txt (gpu_mem=xx) and could dynamically assign an amount of RAM (from 16 to 256 MB in 8 MB steps) to the GPU, so the older

method of memory splits became obsolete, and a single start.elf worked the same for 256 MB and 512 MB Raspberry Pis.[36] The Raspberry Pi 2 and the Raspberry Pi 3 have 1 GB of RAM.[37][38] The Raspberry Pi Zero and Zero W have 512 MB of RAM.

Networking[edit] The Model A, A+ and Pi Zero have no Ethernet circuitry and are commonly connected to a network using an external user-supplied USB Ethernet or Wi-Fi adapter. On the Model B and B+ the Ethernet port is provided by a built-in USB Ethernet adapter using the SMSC LAN9514 chip.[39] The Raspberry Pi 3 and Pi Zero W (wireless) are equipped with 2.4 GHz WiFi 802.11n (150 Mbit/s) and Bluetooth 4.1 (24 Mbit/s) based on the Broadcom BCM43438 FullMAC chip with no official support for monitor mode but implemented through unofficial firmware patching[40] and the Pi 3 also has a 10/100 Mbit/s Ethernet port. The Raspberry Pi 3B+ features dual-band IEEE 802.11b/g/n/ac WiFi, Bluetooth 4.2, and Gigabit Ethernet (limited to approximately 300 Mbit/s by the USB 2.0 bus between it and the SoC).

Special-purpose features[edit] The Pi Zero can be used as a USB device or "USB gadget", plugged into another computer via a USB port on another machine. It can be configured in multiple ways, for example to show up as a serial device or an ethernet device.[41] Although originally requiring software patches, this was added into the mainline Raspbian distribution in May 2016.[41] The Pi 3 can boot from USB, such as from a flash drive.[42] Because of firmware limitations in other models, the Pi 3 is the only board that can do this.

Peripherals[edit]

The Model 2B boards incorporate four USB ports for connecting peripherals.

The Raspberry Pi may be operated with any generic USB computer keyboard and mouse.[43] It may also be used with USB storage, USB to MIDI converters, and virtually any other device/component with USB capabilities. Other peripherals can be attached through the various pins and connectors on the surface of the Raspberry Pi.[44]

Video[edit]

The early Raspberry Pi 1 Model A, with an HDMI port and a standard RCA composite video port for older displays

The video controller can generate standard modern TV resolutions, such as HD and Full HD, and higher or lower monitor resolutions as well as older NTSC or PAL standard CRT TV resolutions. As shipped (i.e., without custom overclocking) it can support the following resolutions: 640×350 EGA; 640×480 VGA; 800×600 SVGA; 1024×768 XGA; 1280×720 720p HDTV; 1280×768 WXGA variant; 1280×800 WXGA variant; 1280×1024 SXGA; 1366×768 WXGA variant; 1400×1050 SXGA+; 1600×1200 UXGA; 1680×1050 WXGA+; 1920×1080 1080p HDTV; 1920×1200 WUXGA.[45] Higher resolutions, up to 2048×1152, may work[46][47] or even 3840×2160 at 15 Hz (too low a frame rate for convincing video).[48] Note also that allowing the highest resolutions does not imply that the GPU can decode video formats at these resolutions; in fact, the Pis are known to not work reliably for H.265 (at those high resolutions), commonly used for very high resolutions (however, most common formats up to Full HD do work). Although the Raspberry Pi 3 does not have H.265 decoding hardware, the CPU is more powerful than its predecessors, potentially fast enough to allow the decoding of H.265-encoded videos in software.[49] The GPU in the Raspberry Pi 3 runs at higher clock frequencies of 300 MHz or 400 MHz, compared to previous versions which ran at 250 MHz.[50] The Raspberry Pis can also generate 576i and 480i composite video signals, as used on old-style (CRT) TV screens and less-expensive monitors through standard connectors – either RCA or 3.5 mm phono connector depending on model. The television signal standards supported are PALBGHID, PAL-M, PAL-N, NTSC and NTSC-J.[51]

Real-time clock[edit] None of the current Raspberry Pi models have a built-in real-time clock, so they are unable to keep track of the time of day independently. Instead, a program running on the Pi can retrieve the time from a network time server or from user input at boot time, thus knowing the time while powered on. To provide consistency of time for the file system, the Pi automatically saves the current system time on shutdown, and re-loads that time at boot. A real-time hardware clock with battery backup, such as the DS1307, may be added (often via the I²C interface). Note however that this conflicts with the camera's CSI interface, effectively disabling the camera.

Specifications[edit]

Model A

Ve rsi on

RPi 1 Model A

Rel ea Febru se ary [52 dat 2013 ] e

Model B

R Pi 1 M RPi 3 RPi 1 o Mod Model d el A+ B el A +

N ov e m b Nove er mber 2 2018 0 1 4[5

April– June 2012

Compute Module*

C o R R m Pi Pi RP p 2 1 RPi i3 Com ut M RPi 3 M 2 M pute e od Mod od Mod od Mod M el el B+ el el B el ule 1 o B B B d v1 + ul .2 e 3

Jul y 20 14[ 54]

Oc Febr to uary be 201 r 20 5[23] 16[ 55]

Fe br ua ry 20 16[

14 Marc h 2018[

C o R R m Pi Pi p Z Z ut Com er er R e pute o o Pi M Mod P P Ze o ule 3 C C ro d + B B W ul v v e 1. 1. 3 2 3 lit e

Janua April ry 2014 2017[5 [56][57] 8]

Janu ary 2019[ 59]

1]

28]

3]

Tar get pri ce $25[52] (U SD )

$ 2 0[5

So

Broadcom BCM2835[2

N ov e m b er 2 0 1 5[6

M a y 2 0 1 6

28 Fe br ua ry 20 17

0]

$25

$35[61]

$30 (in batc hes of 100)[

$2 5[62 $35 ]

3]

Ins tru ARMv6Z cti (32-bit) on set

Zero

$ 3 0

$25

$5[60]

$1 0

63]

ARM v8 (64bit)

ARMv6Z (32-bit)

AR Mv7 -A (32bit)

Broa Broadcom Bro dcom BCM2835[20 adc

ARMv8-A (64/32-bit)

Broadc om BC

ARM v6Z ARMv8-A (32- (64/32-bit) bit)

Broa Broa dcom dco

Broad com B

Broa dco

ARMv6Z (32-bit)

Broadcom

C

FP U

0]

BCM 2837 B0[1]

VFPv2; NEON not supported

1× ARM11 CP 76JZF-S U 700 MHz

]

omB M2837 CM 283 6

mBC CM28 M28 37 35[63]

mBC BCM2835 M28 37B0

VFP v2; NEO VFPv4 + VFPv4 + NEON N NEON not supp orted

VFPv VFPv2; 4+ NEON not NEO supported N

VFP v3 + NE ON

4× C ortex A531 .4 G Hz

4× C 4× ort Cort ex exA79 A5 00 39 MHz 00 M Hz

1× ARM11 76JZF-S 700 MHz

BCM 2837 B0[1]

4× C ort exA5 31 .2 G Hz

4× C ortex A531 .4 G Hz

1× A RM1 176J 4× CortexZF-S A53 1.2 GHz 700 MHz

VFPv2; NEON not supported

1× ARM11 76JZF-S 1 GHz

Broadcom VideoCore IV @ 250 MHz (BCM2837: 3D part of GPU @ 300 MHz, video part of GPU @ 400 MHz)[64][65] GP OpenGL ES 2.0 (BCM2835, BCM2836: 24 GFLOPS / BCM2837: 28.8 GFLOPS) U MPEG-2 and VC-1 (with license),[66] 1080p30 H.264/MPEG-4 AVC high-profile decoder and encoder[20] (BCM2837: 1080p60)

Me mo ry (S DR AM )

US B 2.0 po rts[ 43]

256 M B (share d with GPU)

512 MB (shared with GPU) as of 4 May 2016. Older boards had 256 MB (shared with GPU)[67]

1 (direct from BCM2835 chip)

1 (direc t from BCM 2837

2 (via onboard 3-port USB hub)[68]

1 GB (shared with GPU)

4 (via on-board 5-port USB hub)[39][54][69]

512 MB (shar 1 GB (shared ed with GPU) with GPU )

512 MB (shared with GPU)

1 (dire ct from BCM 2835 chip)

1 MicroUSB (direct from BCM2835 chip)

1 (direct from BCM2 837 chip)

B0 chip)

Vid eo 15-pin MIPI camera interface (CSI) connector, used with inp the Raspberry Pi camera or Raspberry Pi NoIR camera[70] ut

2× MIPI camera interface (CSI)[63][71][72]

N o n e

MIPI camer a interfa ce (CSI)[73 ]

HDMI (rev 1.3) co mposit e video ( RCA Vid jack), eo MIPI out displa put y s interfa ce (DSI) for raw L CD pa nels

HDMI (rev 1.3), composit e video (3.5 mm TRRS jack), MIPI display interface (DSI) for raw LCD panels

HDMI (rev 1.3), compo site video (RCA jack), MIPI displa y interfa ce (DSI) for raw L CDpa nels

HDMI (rev 1.3), composite video (3.5 mm TRRS jack), MIPI display interface (DSI) for raw LCD panels

HDMI, 2× MIPI display interface (DSI) for raw LCD pan els,[63][72][74][75]co mposite video[71][76]

Mini-HDMI, 1080p60,[60] composite video via marked points on PCB for optional header pins[77]

Au dio As of revision 2 boards via I²S[78] inp uts Au dio Analog via 3.5 mm phone jack; digital via HDMI and, as of Analog, out revision 2 boards, I²S HDMI, I²S put s SD, M MC, On SDIO card bo slot ard (3.3 V sto with rag card e[43] power only) On -

None[80]

MicroSD HC slot[54]

2.4 GHz

SD, M MC, SDIO card slot

MicroSDHC sl ot

10/100 Mbit/s Ethernet (8P8C) USB adapter

MicroSDH C slot, USB Boot Mode[79]

4 GB eM MC flash memory chip[63]

10/ 10/10 None 10 0/100

Mini-HDMI, stereo audio through PWM on GPIO

MicroSDHC

80 2.

bo ard net wo rk[4 3]

8× GP IO[82]pl us the followi ng, which can also Lo be w- used lev as el GPIO: per UART, iph I²Cbu era s, SPI ls bus with two ch ip select s, I²Sa udio[83] +3.3 V , +5 V,

and 5 on the USB hub[68] GHz IEE 802.1 1.b/g/ n/ac wirel ess LAN, Bluet ooth 4.2/B LE

0 Mb it/s Et he rn et, 80 2.1 1b/ g/n sin gle ba nd 2.4 G Hz wir ele ss, Bl uet oot h 4.1 BL E

0 Mbi t/s Ether net[69] (real spee d max 300 Mbit/ s[81]), 802.1 1b/g/ n/ac dual band 2.4/5 GHz wirel ess, Bluet ooth 4.2 LS BLE

8× GP IOplus the followi ng, which can also be 17× GPIO used plus the as same 17× GPIO plus the same GPIO: specific specific functions, and HAT UART functions, ID bus , I²Cbu and HAT s, SPI ID bus bus with two ch ip select s, I²Sa udio +3.3 V , +5 V,

11 b/ g/ n si ng le ba nd 2. 4 G Hz wi rel es s, Bl ue to ot h 4. 1 BL E

46× GPIO, some of which can be used for specific functions including I²C, SPI, UART, P CM, PWM[85]

17× GPIO plus the same specific functions, and HAT ID bus[60]

groun d[64][84]

groun d. An additio nal 4× GP IOare availa ble on the P5 pad if the user is willing to make solder conne ctions

Po we r rati ng s

300 m A (1.5 W )[86]

2 0 0 m A (1 W )[87 ]

700 m A (3.5 W )

20 0 m A (1 W) av er ag e wh en idl e, 35 0 m A (1. 75 W ) m axi m u m un de r str es

30 0 m A (1. 5 W) av 220 mA er (1.1 W) ag average e when wh idle, en 820 mA idl (4.1 W) e, maximum 1.3 under 4 stress A (monitor, (6. keyboard 7 and W) mouse ma connecte xi d)[4] mu m un de r str es s (m

459 mA (2.29 5 W) avera ge when idle, 1.13 A (5.66 1 W) maxi mum unde r stres s (moni tor, keyb oard, mous e and WiFi conn ected )[88]

200 mA (1 W )

700 m A (3.5 W)

100 mA (0.5 W) average when idle, 350 mA (1.75 W) maximum under stress (monitor, keyboard and mouse connected)[ 4]

s (m on ito r, ke yb oa rd an d m ou se co nn ec te d)[

oni tor , ke yb oa rd, mo us e an d Wi Fi co nn ect ed )[4]

4]

Po we r 5 V via MicroUSB or GPIO header so urc e

85.60 mm × 56.5 mm (3.370 in Siz × 2.22 e 4 in), exclud ing protru ding conne ctors

6 5 m m × 5 6. 5 m m × 1 0 m m (2 .5 6i n × 2. 2 2i n × 0.

65 mm x 56.5 mm

85.60 mm × 56.5 mm (3.370 in × 2.224 in), excluding protruding connectors

85.60 mm × 56.5 mm × 17[89] mm (3.370 in × 2.224 in × 0.669 in)

67.6 mm × 30 mm (2.66 in × 1.1 8 in)

67.6 mm × 31 mm (2.66 in × 1.22 in)

65 mm × 30 mm × 5 mm (2.56 in × 1.18 in × 0.20 in)

3 9i n) , sa m e as H A T b o ar d 2 3 g We 31 g (0 igh (1.1 oz .8 t ) 1 oz )

7g (0.25 oz)[90]

45 g (1.6 oz)

9g (0.32 oz)[91]

Co Adding a USB network interface via tethering[80] or a serial cable with optional GPIO power ns connector[92] ole Ge ner 1 ati on

Ob sol es ce nc e n/a Sta te me nt

1 +

n/ a

3+

in prod uctio n until at least Janu ary 2023

1

n/a

1 +

n/ a

2

n/a

2 ve r 1. 2

n/ a

3

3+

in prod uctio n until n/a at least Janu ary 2023

1

n/a

3

n/ a

P C B ve r 1. 2

3 lit e

3+ lite

P C B v er 1. 3

W (w ire le ss )

n/ a

Z er o CM3 n/ is + will a, c rema or ur in in se re prod e nt uctio P ly n C st until B at at ve e least r d Janu 1. a ary 3 s 2026 b ei n

n/ a

g n ot b ef or e J a n u ar y 2 0 2 2 Ty pe

Model A

Model B

Compute Module*

Zero

* all interfaces are via 200-pin DDR2 SO-DIMM connector.

Connectors[edit] Pi Zero[edit] 

Model A[edit]

M



Location of connectors and main ICs Location of connectors and main ICs on Raspberry Pi 1 Model A

L



Location of connectors and main ICs on Raspberry Pi 1 Model A+ revision 1.1

L a

L

General purpose input-output (GPIO) connector[edit] Raspberry Pi 1 Models A+ and B+, Pi 2 Model B, Pi 3 Models A+, B and B+, and Pi Zero and Zero W GPIO J8 have a 40-pin pinout.[93][94] Raspberry Pi 1 Models A and B have only the first 26 pins.[95][96][97] GPIO#

2nd func.

Pin#

Pin#

2nd func.

+3.3 V

1

2

+5 V

2

SDA1 (I²C)

3

4

+5 V

3

SCL1 (I²C)

5

6

GND

GPIO#

4

GCLK

7

8

TXD0 (UART)

GND

9

10

RXD0 (UART) 15

17

GEN0

11

12

GEN1

27

GEN2

13

14

GND

22

GEN3

15

16

GEN4

23

+3.3 V

17

18

GEN5

24

10

MOSI (SPI) 19

20

GND

9

MISO (SPI) 21

22

GEN6

25

11

SCLK (SPI) 23

24

CE0_N (SPI)

8

GND

26

CE1_N (SPI)

7

25

14

18

(Pi 1 Models A and B stop here)

EEPROM ID_SD

27

28

ID_SC

5

N/A

29

30

GND

6

N/A

31

32

13

N/A

33

34

EEPROM

12

GND

19

N/A

35

36

N/A

16

26

N/A

37

38

Digital IN

20

GND

39

40

Digital OUT

21

Model B rev. 2 also has a pad (called P5 on the board and P6 on the schematics) of 8 pins offering access to an additional 4 GPIO connections.[98] Function

2nd func.

Pin#

Pin#

1

2

+3.3 V

GPIO28

GPIO_GEN7 3

4

GPIO_GEN8

GPIO30

GPIO_GEN9 5

6

GPIO_GEN10 GPIO31

GND

8

GND

+5 V

7

2nd func.

Function

GPIO29

Models A and B provide GPIO access to the ACT status LED using GPIO 16. Models A+ and B+ provide GPIO access to the ACT status LED using GPIO 47, and the power status LED using GPIO 35.

Accessories[edit] 



 

Gertboard – A Raspberry Pi Foundation sanctioned device, designed for educational purposes, that expands the Raspberry Pi's GPIO pins to allow interface with and control of LEDs, switches, analog signals, sensors and other devices. It also includes an optional Arduino compatible controller to interface with the Pi.[99] Camera – On 14 May 2013, the foundation and the distributors RS Components & Premier Farnell/Element 14 launched the Raspberry Pi camera board alongside a firmware update to accommodate it.[100] The camera board is shipped with a flexible flat cable that plugs into the CSI connector which is located between the Ethernet and HDMI ports. In Raspbian, the user must enable the use of the camera board by running Raspi-config and selecting the camera option. The camera module costs €20 in Europe (9 September 2013).[101] It can produce 1080p, 720p and 640x480p video. The dimensions are 25 mm × 20 mm × 9 mm.[101] In May 2016, v2 of the camera came out, and is an 8 megapixel camera. Infrared Camera – In October 2013, the foundation announced that they would begin producing a camera module without an infrared filter, called the Pi NoIR.[102] Official Display – On 8 September 2015, The foundation and the distributors RS Components & Premier Farnell/Element 14 launched the Raspberry Pi Touch Display[103]



HAT (Hardware Attached on Top) expansion boards – Together with the Model B+, inspired by the Arduino shield boards, the interface for HAT boards was devised by the Raspberry Pi Foundation. Each HAT board carries a small EEPROM (typically a CAT24C32WIGT3)[104] containing the relevant details of the board,[105] so that the Raspberry Pi's OS is informed of the HAT, and the technical details of it, relevant to the OS using the HAT.[106] Mechanical details of a HAT board, which uses the four mounting holes in their rectangular formation, are available online.[107][108]

Software[edit] Operating systems[edit]

Various operating systems for the Raspberry Pi can be installed on a MicroSD, MiniSD or SD card, depending on the board and available adapters; seen here is the MicroSD slot located on the bottom of a Raspberry Pi 2 board.

The Raspberry Pi Foundation provides Raspbian, a Debian-based Linux distribution for download, as well as third-party Ubuntu, Windows 10 IoT Core, RISC OS, and specialised media centre distributions.[109] It promotes Python and Scratch as the main programming languages, with support for many other languages.[110] The default firmware is closed source, while an unofficial open source is available.[111][112][113]Many other operating systems can also run on the Raspberry Pi, including the formally verified microkernel, seL4.[114] Other third-party operating systems available via the official website include Ubuntu MATE, Windows 10 IoT Core, RISC OS and specialised distributions for the Kodi media centre and classroom management.[115] Other operating systems (not Linux-based) 

     

Broadcom VCOS – Proprietary operating system which includes an abstraction layer designed to integrate with existing kernels, such as ThreadX (which is used on the VideoCore4 processor), providing drivers and middleware for application development. In case of Raspberry Pi this includes an application to start the ARM processor(s) and provide the publicly documented API over a mailbox interface, serving as its firmware. An incomplete source of a Linux port of VCOS is available as part of the reference graphics driver published by Broadcom.[116] RISC OS Pi (a special cut down version RISC OS Pico, for 16 MB cards and larger for all models of Pi 1 & 2, has also been made available.) FreeBSD[117][118] NetBSD[119][120] OpenBSD (only on 64-bit platforms, such as Raspberry Pi 3)[121] Plan 9 from Bell Labs[122][123] and Inferno[124] (in beta) Windows 10 IoT Core – a no-cost edition of Windows 10 offered by Microsoft that runs natively on the Raspberry Pi 2.[125]



Haiku – an open source BeOS clone that has been compiled for the Raspberry Pi and several other ARM boards.[126] Work on Pi 1 began in 2011, but only the Pi 2 will be supported.[citation needed]  HelenOS – a portable microkernel-based multiserver operating system; has basic Raspberry Pi support since version 0.6.0[127] Other operating systems (Linux-based)            

       

N a

Android Things – an embedded version of the Android operating system designed for IoT device development. Arch Linux ARM – a port of Arch Linux for ARM processors. openSUSE[128] SUSE Linux Enterprise Server 12 SP2[129] SUSE Linux Enterprise Server 12 SP3 (Commercial support)[129] Gentoo Linux[130] Lubuntu[131] Xubuntu[131] Devuan CentOS for Raspberry Pi 2 and later RedSleeve (a RHEL port) for Raspberry Pi 1 Slackware ARM – version 13.37 and later runs on the Raspberry Pi without modification.[132][133][134][135] The 128–496 MB of available memory on the Raspberry Pi is at least twice the minimum requirement of 64 MB needed to run Slackware Linux on an ARM or i386 system.[136] (Whereas the majority of Linux systems boot into a graphical user interface, Slackware's default user environment is the textual shell / command line interface.[137]) The Fluxbox window manager running under the X Window System requires an additional 48 MB of RAM.[138] Kali Linux – a Debian-derived distro designed for digital forensics and penetration testing. SolydXK – a light Debian-derived distro with Xfce. Ark OS – designed for website and email self-hosting. Sailfish OS with Raspberry Pi 2 (due to use ARM Cortex-A7 CPU; Raspberry Pi 1 uses different ARMv6 architecture and Sailfish requires ARMv7.)[139] Tiny Core Linux – a minimal Linux operating system focused on providing a base system using BusyBox and FLTK. Designed to run primarily in RAM. Alpine Linux – a Linux distribution based on musl and BusyBox, primarily designed for "power users who appreciate security, simplicity and resource efficiency". Void Linux – a rolling release Linux distribution which was designed and implemented from scratch, provides images based on musl or glibc. Fedora – supports Pi 2 and later since Fedora 25 (Pi 1 is supported by some unofficial derivatives, e.g. listed here.). F o

K e

U s

Model A

Model B

Compute Module*

Zero

m e

c u s

r n e l

e r S p a c e

2

1 1

1 3

1

+

2

v e r

3 3

+

3 +

1

3

1 . 2

Net Op wor en kin Wrt g

Lin ux

GN U/D ebia n

Ye s[14

?

?

0]

Ye s[14

Ye s[14

Ye s[14

1]

2]

3]

?

Par tial[ 144]

?

?

?

l i t e

?

P C B

P C B

v e r

v e r

1 . 2

1 . 3

?

?

W ( w ir e l e s s )

Part ial[14 5]

Driver APIs[edit] See also: VideoCore § Linux support

Scheme of the implemented APIs: OpenMAX, OpenGL ES and OpenVG

Raspberry Pi can use a VideoCore IV GPU via a binary blob, which is loaded into the GPU at boot time from the SD-card, and additional software, that initially was closed source.[146] This part of the driver code was later released.[147] However, much of the actual driver work is done using the closed source GPU code. Application software makes calls to closed source run-time libraries (OpenMax, OpenGL ES or OpenVG), which in turn call an open source driver inside the Linux kernel, which then calls the closed source VideoCore IV GPU driver code. The API of the kernel driver is specific for these closed libraries. Video applications use OpenMAX, 3D applications use OpenGL ES and 2D applications use OpenVG, which both in turn use EGL. OpenMAX and EGL use the open source kernel driver in turn.[148]

Firmware[edit] The official firmware is a freely redistributable[149] binary blob, that is closed-source.[126] A minimal proof-of-concept open source firmware is also available, mainly aimed at initializing and starting the ARM cores as well as performing minimal startup that is required on the ARM side. It is also capable of booting a very minimal Linux kernel, with patches to remove the dependency on the mailbox

interface being responsive. It is known to work on Raspberry Pi 1, 2 and 3, as well as some variants of Raspberry Pi Zero. While it is in a working state, it is not actively developed, with last significant commits made around mid-2017.[150]

Third party application software[edit]  



 

 

AstroPrint – AstroPrint's wireless 3D printing software can be run on the Pi 2.[151] C/C++ Interpreter Ch – Released 3 January 2017, C/C++ interpreter Ch and Embedded Ch are released free for non-commercial use for Raspberry Pi, ChIDE is also included for the beginners to learn C/C++.[152] Mathematica & the Wolfram Language – Since 21 November 2013, Raspbian includes a full installation of this proprietary software for free.[153][154][155] As of 24 August 2015, the version is Mathematica 10.2.[156] Programs can be run either from a command line interface or from a Notebook interface. There are Wolfram Language functions for accessing connected devices.[157] There is also a Wolfram Language desktop development kit allowing development for Raspberry Pi in Mathematica from desktop machines, including features from the loaded Mathematica version such as image processing and machine learning.[158][159][160] Minecraft – Released 11 February 2013, a modified version that allows players to directly alter the world with computer code.[161] RealVNC – Since 28 September 2016, Raspbian includes RealVNC's remote access server and viewer software.[162][163][164] This includes a new capture technology which allows directly-rendered content (e.g. Minecraft, camera preview and omxplayer) as well as non-X11 applications to be viewed and controlled remotely.[165][166] UserGate Web Filter – On 20 September 2013, Florida-based security vendor Entensys announced porting UserGate Web Filter to Raspberry Pi platform.[167] Steam Link – On 13 December 2018, Valve released official Steam Link game streaming client for the Raspberry Pi 3 and 3 B+.[168][169]

Software development tools[edit]     

 

   

Arduino IDE – for programming an Arduino. Algoid – for teaching programming to children and beginners. BlueJ – for teaching Java to beginners. Greenfoot – Greenfoot teaches object orientation with Java. Create 'actors' which live in 'worlds' to build games, simulations, and other graphical programs. Julia – an interactive and cross-platform programming language/environment, that runs on the Pi 1 and later.[170] IDEs for Julia, such as Juno, are available. See also Pi-specific Github repository JuliaBerry. Lazarus – a Free Pascal RAD IDE resembling Delphi LiveCode – an educational RAD IDE descended from HyperCard using English-like language to write event-handlers for WYSIWYG widgets runnable on desktop, mobile and Raspberry Pi platforms. Ninja-IDE – a cross-platform integrated development environment (IDE) for Python. Object Pascal[171] – an object oriented variant (the one used in Delphi and Lazarus) of Niklaus Wirth's original Pascal language. Free Pascal is the compiler in Lazarus Processing – an IDE built for the electronic arts, new media art, and visual design communities with the purpose of teaching the fundamentals of computer programming in a visual context. Scratch – a cross platform teaching IDE using visual blocks that stack like Lego, originally developed by MIT's Life Long Kindergarten group. The Pi version is very heavily optimised[172] for the limited compute resources available and is implemented in the Squeak Smalltalk system. The latest version compatible with The 2 B is 1.6.

    

Squeak Smalltalk – a full scale open Smalltalk. TensorFlow – an artificial intelligence framework developed by Google. The Raspberry Pi Foundation worked with Google to simplify the installation process through pre-built binaries.[173] V-Play Game Engine – a cross-platform development framework that supports mobile game and app development with the V-Play Game Engine, V-Play apps and V-Play plugins. Xojo – a cross-platform RAD tool that can create desktop, web and console apps for Pi 2 and Pi 3. C-STEM Studio – a platform for hands-on integrated learning of computing, science, technology, engineering, and mathematics (C-STEM) with robotics.

Reception and use[edit]

NASA's Open Source Roverpowered by a Raspberry Pi 3

Technology writer Glyn Moody described the project in May 2011 as a "potential BBC Micro 2.0", not by replacing PC compatible machines but by supplementing them.[174] In March 2012 Stephen Pritchard echoed the BBC Micro successor sentiment in ITPRO.[175] Alex Hope, co-author of the Next Gen report, is hopeful that the computer will engage children with the excitement of programming.[176] Co-author Ian Livingstone suggested that the BBC could be involved in building support for the device, possibly branding it as the BBC Nano.[177] Chris Williams, writing in The Register sees the inclusion of programming languages such as Kids Ruby, Scratch and BASIC as a "good start" to equip children with the skills needed in the future – although it remains to be seen how effective their use will be.[178] The Centre for Computing History strongly supports the Raspberry Pi project, feeling that it could "usher in a new era".[179] Before release, the board was showcased by ARM's CEO Warren East at an event in Cambridge outlining Google's ideas to improve UK science and technology education.[180] Harry Fairhead, however, suggests that more emphasis should be put on improving the educational software available on existing hardware, using tools such as Google App Inventorto return programming to schools, rather than adding new hardware choices.[181] Simon Rockman, writing in a ZDNet blog, was of the opinion that teens will have "better things to do", despite what happened in the 1980s.[182] In October 2012, the Raspberry Pi won T3's Innovation of the Year award,[183] and futurist Mark Pesce cited a (borrowed) Raspberry Pi as the inspiration for his ambient deviceproject MooresCloud.[184] In October 2012, the British Computer Society reacted to the announcement of enhanced specifications by stating, "it's definitely something we'll want to sink our teeth into."[185] In February 2015, a switched-mode power supply chip, designated U16, of the Raspberry Pi 2 Model B version 1.1 (the initially released version) was found to be vulnerable to flashes of light,[186] particularly the light from xenon camera flashes and green[187] and red laser pointers. However, other bright lights, particularly ones that are on continuously, were found to have no effect. The symptom was the Raspberry Pi 2 spontaneously rebooting or turning off when these lights were flashed at the chip. Initially, some users and commenters suspected that the electromagnetic pulse (EMP) from the xenon flash tube was causing the problem by interfering with the computer's digital circuitry, but this was ruled out by tests where the light was either blocked by a card or aimed

at the other side of the Raspberry Pi 2, both of which did not cause a problem. The problem was narrowed down to the U16 chip by covering first the system on a chip (main processor) and then U16 with Blu-Tack (an opaque poster mounting compound). Light being the sole culprit, instead of EMP, was further confirmed by the laser pointer tests,[187] where it was also found that less opaque covering was needed to shield against the laser pointers than to shield against the xenon flashes.[186] The U16 chip seems to be bare silicon without a plastic cover (i.e. a chip-scale package or wafer-level package), which would, if present, block the light. Unofficial workarounds include covering U16 with opaque material (such as electrical tape,[186][187] lacquer, poster mounting compound, or even balled-up bread[186]), putting the Raspberry Pi 2 in a case,[187] and avoiding taking photos of the top side of the board with a xenon flash. This issue was not caught before the release of the Raspberry Pi 2 because while commercial electronic devices are routinely subjected to tests of susceptibility to radio interference, it is not standard or common practice to test their susceptibility to optical interference.[186] In June 2017, Raspberry Pi won the Royal Academy of Engineering MacRobert Award.[188] The citation for the award to the Raspberry Pi said it was "for its inexpensive credit card-sized microcomputers, which are redefining how people engage with computing, inspiring students to learn coding and computer science and providing innovative control solutions for industry."[189]

Community[edit] The Raspberry Pi community was described by Jamie Ayre of FLOSS software company AdaCore as one of the most exciting parts of the project.[190] Community blogger Russell Davis said that the community strength allows the Foundation to concentrate on documentation and teaching.[190] The community developed a fanzine around the platform called The MagPi[191] which in 2015, was handed over to the Raspberry Pi Foundation by its volunteers to be continued inhouse.[192] A series of community Raspberry Jam events have been held across the UK and around the world.[193]

Use in education[edit] As of January 2012, enquiries about the board in the United Kingdom have been received from schools in both the state and private sectors, with around five times as much interest from the latter. It is hoped that businesses will sponsor purchases for less advantaged schools.[194] The CEO of Premier Farnell said that the government of a country in the Middle East has expressed interest in providing a board to every schoolgirl, to enhance her employment prospects.[195][196] In 2014, the Raspberry Pi Foundation hired a number of its community members including exteachers and software developers to launch a set of free learning resources for its website.[197] The Foundation also started a teacher training course called Picademy with the aim of helping teachers prepare for teaching the new computing curriculum using the Raspberry Pi in the classroom.[198] In 2018, NASA launched the JPL Open Source Rover Project, which is a scaled down of Curiosity rover and uses a Raspberry Pi as the control module, to encourage students and hobbyists to get involved in mechanical, software, electronics, and robotics engineering.[199]

Use in home automation[edit] There are a number of developers and applications that are leveraging the Raspberry Pi for home automation. These programmers are making an effort to modify the Raspberry Pi into a costaffordable solution in energy monitoring and power consumption. Because of the relatively low cost of the Raspberry Pi, this has become a popular and economical alternative to the more expensive commercial solutions.[200]

Use in industrial automation[edit]

In June 2014, Polish industrial automation manufacturer TECHBASE released ModBerry, an industrial computer based on the Raspberry Pi Compute Module. The device has a number of interfaces, most notably RS-485/232 serial ports, digital and analogue inputs/outputs, CAN and economical 1-Wire buses, all of which are widely used in the automation industry. The design allows the use of the Compute Module in harsh industrial environments, leading to the conclusion that the Raspberry Pi is no longer limited to home and science projects, but can be widely used as an Industrial IoT solution and achieve goals of Industry 4.0.[201] In March 2018, SUSE announced commercial support for SUSE Linux Enterprise on the Raspberry Pi 3 Model B to support a number of undisclosed customers implementing industrial monitoring with the Raspberry Pi.[202]

Use in commercial products[edit] OTTO is a digital camera created by Next Thing Co. It incorporates a Raspberry Pi Compute Module. It was successfully crowd-funded in a May 2014 Kickstarter campaign.[203] Slice is a digital media player which also uses a Compute Module as its heart. It was crowd-funded in an August 2014 Kickstarter campaign. The software running on Slice is based on Kodi.[204]

Astro Pi[edit] A project was launched in December 2014 at an event held by the UK Space Agency. The Astro Pi competition was officially opened in January and was opened to all primary and secondary school aged children who were residents of the United Kingdom. During his mission, British ESA astronaut Tim Peake deployed the computers on board the International Space Station.[205] He loaded the winning code while in orbit, collected the data generated and then sent this to Earth where it was distributed to the winning teams. Covered themes during the competition included Spacecraft Sensors, Satellite Imaging, Space Measurements, Data Fusion and Space Radiation. The organisations involved in the Astro Pi competition include the UK Space Agency, UKspace, Raspberry Pi, ESERO-UK and ESA.

History[edit] This section is in a list format that may be better presented using prose. You can help by converting this section to prose, if appropriate. Editing help is available. (February 2015)

An early alpha-test board in operation using different layout from later beta and production boards

In 2006, early concepts of the Raspberry Pi were based on the Atmel ATmega644 microcontroller. Its schematics and PCB layout are publicly available.[206] Foundation trustee Eben Upton assembled a group of teachers, academics and computer enthusiasts to devise a computer to inspire

children.[194] The computer is inspired by Acorn's BBC Micro of 1981.[207][208] The Model A, Model B and Model B+ names are references to the original models of the British educational BBC Micro computer, developed by Acorn Computers.[178] The first ARM prototype version of the computer was mounted in a package the same size as a USB memory stick.[209] It had a USB port on one end and an HDMI port on the other. The Foundation's goal was to offer two versions, priced at US$25 and $35. They started accepting orders for the higher priced Model B on 29 February 2012,[210] the lower cost Model A on 4 February 2013.[211] and the even lower cost (US$20) A+ on 10 November 2014.[53] On 26 November 2015, the cheapest Raspberry Pi yet, the Raspberry Pi Zero, was launched at US$5 or £4.[212]

Pre-launch[edit] 



 



July 2011: Trustee Eben Upton publicly approached the RISC OS Open community in July 2011 to enquire about assistance with a port.[213] Adrian Lees at Broadcom has since worked on the port,[214][215] with his work being cited in a discussion regarding the graphics drivers.[216] This port is now included in NOOBS. August 2011 – 50 alpha boards are manufactured. These boards were functionally identical to the planned Model B,[217] but they were physically larger to accommodate debug headers. Demonstrations of the board showed it running the LXDE desktop on Debian, Quake 3 at 1080p,[218] and Full HD MPEG-4 video over HDMI.[219] October 2011 – A version of RISC OS 5 was demonstrated in public, and following a year of development the port was released for general consumption in November 2012.[220][221][222][223] December 2011 – Twenty-five Model B Beta boards were assembled and tested[224] from one hundred unpopulated PCBs.[225] The component layout of the Beta boards was the same as on production boards. A single error was discovered in the board design where some pins on the CPU were not held high; it was fixed for the first production run.[226]The Beta boards were demonstrated booting Linux, playing a 1080p movie trailer and the Rightware Samurai OpenGL ES benchmark.[227] Early 2012 – During the first week of the year, the first 10 boards were put up for auction on eBay.[228][229] One was bought anonymously and donated to the museum at The Centre for Computing History in Cambridge, England.[179][230] The ten boards (with a total retail price of £220) together raised over £16,000,[231] with the last to be auctioned, serial number No. 01, raising £3,500.[232] In advance of the anticipated launch at the end of February 2012, the Foundation's servers struggled to cope with the load placed by watchers repeatedly refreshing their browsers.[233]

Launch[edit] 



19 February 2012 – The first proof of concept SD card image that could be loaded onto an SD card to produce a preliminary operating system is released. The image was based on Debian 6.0 (Squeeze), with the LXDE desktop and the Midori browser, plus various programming tools. The image also runs on QEMU allowing the Raspberry Pi to be emulated on various other platforms.[234][235] 29 February 2012 – Initial sales commence 29 February 2012[236] at 06:00 UTC;. At the same time, it was announced that the model A, originally to have had 128 MB of RAM, was to be upgraded to 256 MB before release.[210] The Foundation's website also announced: "Six years after the project's inception, we're nearly at the end of our first run of development – although it's just the beginning of the Raspberry Pi story."[237] The web-shops of the two licensed manufacturers selling Raspberry Pi's within the United Kingdom, Premier Farnell and RS Components, had their websites stalled by heavy web traffic immediately after the launch (RS Components briefly going down completely).[238][239]Unconfirmed reports suggested that there were over two million expressions of interest or pre-orders.[240] The official Raspberry Pi Twitter



 

account reported that Premier Farnell sold out within a few minutes of the initial launch, while RS Components took over 100,000 pre orders on day one.[210] Manufacturers were reported in March 2012 to be taking a "healthy number" of pre-orders.[190] March 2012 – Shipping delays for the first batch were announced in March 2012, as the result of installation of an incorrect Ethernet port,[241][242] but the Foundation expected that manufacturing quantities of future batches could be increased with little difficulty if required.[243] "We have ensured we can get them [the Ethernet connectors with magnetics] in large numbers and Premier Farnell and RS Components [the two distributors] have been fantastic at helping to source components," Upton said. The first batch of 10,000 boards was manufactured in Taiwan and China.[244][245] 8 March 2012 – Release Raspberry Pi Fedora Remix, the recommended Linux distribution,[246] developed at Seneca College in Canada.[247] March 2012 – The Debian port is initiated by Mike Thompson, former CTO of Atomz. The effort was largely carried out by Thompson and Peter Green, a volunteer Debian developer, with some support from the Foundation, who tested the resulting binaries that the two produced during the early stages (neither Thompson nor Green had physical access to the hardware, as boards were not widely accessible at the time due to demand).[248] While the preliminary proof of concept image distributed by the Foundation before launch was also Debian-based, it differed from Thompson and Green's Raspbian effort in a couple of ways. The POC image was based on then-stable Debian Squeeze, while Raspbian aimed to track then-upcoming Debian Wheezy packages.[235] Aside from the updated packages that would come with the new release, Wheezy was also set to introduce the armhf architecture,[249] which became the raison d'être for the Raspbian effort. The Squeeze-based POC image was limited to the armel architecture, which was, at the time of Squeeze's release, the latest attempt by the Debian project to have Debian run on the newest ARM embedded-application binary interface (EABI).[250] The armhfarchitecture in Wheezy intended to make Debian run on the ARM VFP hardware floating-point unit, while armel was limited to emulating floating point operations in software.[251][252] Since the Raspberry Pi included a VFP, being able to make use of the hardware unit would result in performance gains and reduced power use for floating point operations.[248] The armhf effort in mainline Debian, however, was orthogonal to the work surrounding the Pi and only intended to allow Debian to run on ARMv7 at a minimum, which would mean the Pi, an ARMv6 device, would not benefit.[249] As a result, Thompson and Green set out to build the 19,000 Debian packages for the device using a custom build cluster.[248]

Post-launch[edit]       

16 April 2012 – Reports appear from the first buyers who had received their Raspberry Pi.[253][254] 20 April 2012 – The schematics for the Model A and Model B are released.[255] 18 May 2012 – The Foundation reported on its blog about a prototype camera module they had tested.[256] The prototype used a 14-megapixel module. 22 May 2012 – Over 20,000 units had been shipped.[257] July 2012 – Release of Raspbian.[258] 16 July 2012 – It was announced that 4,000 units were being manufactured per day, allowing Raspberry Pis to be bought in bulk.[259][260] 24 August 2012 – Hardware accelerated video (H.264) encoding becomes available after it became known that the existing license also covered encoding. Formerly it was thought that encoding would be added with the release of the announced camera module.[261][262] However, no stable software exists for hardware H.264 encoding.[263] At the same time the Foundation released two additional codecs that can be bought separately, MPEG-2 and Microsoft's VC-1. Also it was announced that the Pi will implement CEC, enabling it to be controlled with the television's remote control.[66]





 







  

5 September 2012 – The Foundation announced a second revision of the Raspberry Pi Model B.[264] A revision 2.0 board is announced, with a number of minor corrections and improvements.[265] 6 September 2012 – Announcement that in future the bulk of Raspberry Pi units would be manufactured in the UK, at Sony's manufacturing facility in Pencoed, Wales. The Foundation estimated that the plant would produce 30,000 units per month, and would create about 30 new jobs.[266][267] 15 October 2012 – It is announced that new Raspberry Pi Model Bs are to be fitted with 512 MB instead of 256 MB RAM.[268] 24 October 2012 – The Foundation announces that "all of the VideoCore driver code which runs on the ARM" had been released as free software under a BSD-style license, making it "the first ARM-based multimedia SoC with fully-functional, vendor-provided (as opposed to partial, reverse engineered) fully open-source drivers", although this claim has not been universally accepted.[147] On 28 February 2014, they also announced the release of full documentation for the VideoCore IV graphics core, and a complete source release of the graphics stack under a 3-clause BSD license[269][270] October 2012 – It was reported that some customers of one of the two main distributors had been waiting more than six months for their orders. This was reported to be due to difficulties in sourcing the CPU and conservative sales forecasting by this distributor.[271] 17 December 2012 – The Foundation, in collaboration with IndieCity and Velocix, opens the Pi Store, as a "one-stop shop for all your Raspberry Pi (software) needs". Using an application included in Raspbian, users can browse through several categories and download what they want. Software can also be uploaded for moderation and release.[272] 3 June 2013 – 'New Out of Box Software or NOOBS is introduced. This makes the Raspberry Pi easier to use by simplifying the installation of an operating system. Instead of using specific software to prepare an SD card, a file is unzipped and the contents copied over to a FAT formatted (4 GB or bigger) SD card. That card can then be booted on the Raspberry Pi and a choice of six operating systems is presented for installation on the card. The system also contains a recovery partition that allows for the quick restoration of the installed OS, tools to modify the config.txt and an online help button and web browser which directs to the Raspberry Pi Forums.[273] October 2013 – The Foundation announces that the one millionth Pi had been manufactured in the United Kingdom.[274] November 2013: they announce that the two millionth Pi shipped between 24 and 31 October.[275] 28 February 2014 – On the day of the second anniversary of the Raspberry Pi, Broadcom, together with the Raspberry Pi foundation, announced the release of full documentation for the VideoCore IV graphics core,[clarification needed] and a complete source release of the graphics stack under a 3-clause BSD license.[269][270]

Raspberry Pi Compute Module

Raspberry Pi Model B



 















7 April 2014 – The official Raspberry Pi blog announced the Raspberry Pi Compute Module, a device in a 200-pin DDR2 SO-DIMM-configured memory module (though not in any way compatible with such RAM), intended for consumer electronics designers to use as the core of their own products.[63] June 2014 – The official Raspberry Pi blog mentioned that the three millionth Pi shipped in early May 2014.[276] 14 July 2014 – The official Raspberry Pi blog announced the Raspberry Pi Model B+, "the final evolution of the original Raspberry Pi. For the same price as the original Raspberry Pi model B, but incorporating numerous small improvements people have been asking for".[54] 10 November 2014 – The official Raspberry Pi blog announced the Raspberry Pi Model A+.[53] It is the smallest and cheapest (US$20)Raspberry Pi so far and has the same processor and RAM as the Model A. Like the A, it has no Ethernet port, and only one USB port, but does have the other innovations of the B+, like lower power, micro-SD-card slot, and 40-pin HAT compatible GPIO. 2 February 2015 – The official Raspberry Pi blog announced the Raspberry Pi 2. Looking like a Model B+, it has a 900 MHz quad-core ARMv7 Cortex-A7 CPU, twice the memory (for a total of 1 GB) and complete compatibility with the original generation of Raspberry Pis.[277] 14 May 2015 – The price of Model B+ was decreased from US$35 to $25, purportedly as a "side effect of the production optimizations" from the Pi 2 development.[278] Industry observers have skeptically noted, however, that the price drop appeared to be a direct response to the CHIP, a lower-priced competitor discontinued in April 2017.[279] 26 November 2015 – The Raspberry Pi Foundation launched the Raspberry Pi Zero, the smallest and cheapest member of the Raspberry Pi family yet, at 65 mm × 30 mm, and US$5. The Zero is similar to the Model A+ without camera and LCD connectors, while smaller and uses less power. It was given away with the Raspberry Pi magazine Magpi No. 40 that was distributed in the UK and US that day – the MagPi was sold out at almost every retailer internationally due to the freebie.[60] 29 February 2016 – Raspberry Pi 3 with a BCM2837 1.2 GHz 64-bit quad processor based on the ARMv8 Cortex-A53, with built-in Wi-Fi BCM43438 802.11n 2.4 GHz and Bluetooth 4.1 Low Energy (BLE). Starting with a 32-bit Raspbian version, with a 64-bit version later to come if "there is value in moving to 64-bit mode". In the same announcement it was said that a new BCM2837 based Compute Module was expected to be introduced a few months later.[280] February 2016 – The Raspberry Pi Foundation announces that they had sold eight million devices (for all models combined), making it the best-selling UK personal computer, ahead of the Amstrad PCW.[281][282] Sales reached ten million in September 2016.[8] 25 April 2016 – Raspberry Pi Camera v2.1 announced with 8 Mpixels, in normal and NoIR (can receive IR) versions. The camera uses the Sony IMX219 chip with a resolution of 3280 × 2464. To make use of the new resolution the software has to be updated.[283]

 

   

 

10 October 2016 – NEC Display Solutions announces that select models of commercial displays to be released in early 2017 will incorporate a Raspberry Pi 3 Compute Module.[284] 14 October 2016 – Raspberry Pi Foundation announces their co-operation with NEC Display Solutions. They expect that the Raspberry Pi 3 Compute Module will be available to the general public by the end of 2016.[285] 25 November 2016 – 11 million units sold.[10] 16 January 2017 – Compute Module 3 and Compute Module 3 Lite are launched.[58] 28 February 2017 – Raspberry Pi Zero W with WiFi and Bluetooth via chip scale antennas launched.[286][287] 14 March 2018 – On Pi Day, Raspberry Pi Foundation introduced Raspberry Pi 3 Model B+ with improvements in the Raspberry PI 3B computers performance, updated version of the Broadcom application processor, better wireless Wi-Fi and Bluetooth performance and addition of the 5GHz band.[288] 15 November 2018 – Raspberry Pi 3 Model A+ launched.[289] 28 January 2019 – Compute Module 3+ (CM3+/Lite, CM3+/8GB, CM3+/16GB and CM3+/32GB) launched.[59]

picamera This package provides a pure Python interface to the Raspberry Pi camera module for Python 2.7 (or above) or Python 3.2 (or above).

Links    

The code is licensed under the BSD license The source code can be obtained from GitHub, which also hosts the bug tracker The documentation (which includes installation, quick-start examples, and lots of code recipes) can be read on ReadTheDocs Packages can be downloaded from PyPI, but reading the installation instructions is more likely to be useful

1. Installation 1.1. Raspbian installation If you are using the Raspbian distro, you probably have picamera installed by default. You can find out simply by starting Python and trying to import picamera: $ python -c "import picamera" $ python3 -c "import picamera"

If you get no error, you’ve already got picamera installed! Just continue to Getting Started. If you don’t have picamera installed you’ll see something like the following: $ python -c "import picamera" Traceback (most recent call last): File "<string>", line 1, in <module> ImportError: No module named picamera $ python3 -c "import picamera" Traceback (most recent call last): File "<string>", line 1, in <module> ImportError: No module named 'picamera'

To install picamera on Raspbian, it is best to use the system’s package manager: apt. This will ensure that picamera is easy to keep up to date, and easy to remove should you wish to do so. It will also make picamera available for all users on the system. To install picamera using apt simply run: $ sudo apt-get update $ sudo apt-get install python-picamera python3-picamera

To upgrade your installation when new releases are made you can simply use apt’s normal upgrade procedure: $ sudo apt-get update $ sudo apt-get upgrade

If you ever need to remove your installation: $ sudo apt-get remove python-picamera python3-picamera

1.2. Alternate distro installation On distributions other than Raspbian, it is probably simplest to install system wide using Python’s pip tool: $ sudo pip install picamera

If you wish to use the classes in the

picamera.array

module then specify the “array”

option which will pull in numpy as a dependency: $ sudo pip install "picamera[array]"

Warning Be warned that older versions of pip will attempt to build numpy from source. This will take a very long time on a Pi (several hours on slower models). Modern versions of pip will download and install a pre-built numpy “wheel” instead which is much faster. To upgrade your installation when new releases are made: $ sudo pip install -U picamera

If you ever need to remove your installation: $ sudo pip uninstall picamera

1.3. Firmware upgrades The behaviour of the Pi’s camera module is dictated by the Pi’s firmware. Over time, considerable work has gone into fixing bugs and extending the functionality of the Pi’s camera module through new firmware releases. Whilst the picamera library attempts to maintain backward compatibility with older Pi firmwares, it is only tested against the latest firmware at the time of release, and not all functionality may be available if you are running an older firmware. As an example, the annotate_text attribute relies on a recent firmware; older firmwares lacked the functionality. You can determine the revision of your current firmware with the following command: $ uname -a

The firmware revision is the number after the

#:

Linux kermit 3.12.26+ #707 PREEMPT Sat Aug 30 17:39:19 BST 2014 armv6l GNU/Linux / / firmware revision --+

On Raspbian, the standard upgrade procedure should keep your firmware up to date:

$ sudo apt-get update $ sudo apt-get upgrade

Warning Previously, these documents have suggested using the rpi-update utility to update the Pi’s firmware; this is now discouraged. If you have previously used the rpiupdate utility to update your firmware, you can switch back to using apt to manage it with the following commands: $ sudo apt-get update $ sudo apt-get install --reinstall libraspberrypi0 libraspberrypi-{bin,dev,doc} z > raspberrypi-bootloader $ sudo rm /boot/.firmware_revision

You will need to reboot after doing so.

2. Getting Started Warning Make sure your Pi is off while installing the camera module. Although it is possible to install the camera while the Pi is on, this isn’t good practice (if the camera is active when removed, it’s possible to damage it). Connect your camera module to the CSI port on your Raspberry Pi; this is the long thin port adjacent to the HDMI socket. Gently lift the collar on top of the CSI port (if it comes off, don’t worry, you can push it back in but try to be more gentle in future!). Slide the ribbon cable of the camera module into the port with the blue side facing the Ethernet port (or where the Ethernet port would be if you’ve got a model A/A+). Once the cable is seated in the port, press the collar back down to lock the cable in place. If done properly you should be able to easily lift the Pi by the camera’s cable without it falling out. The following illustrations show a well-seated camera cable with the correct orientation:

Make sure the camera module isn’t sat on anything conductive (e.g. the Pi’s USB ports or its GPIO pins).

2.1. Pi Zero The 1.2 model of the Raspberry Pi Zero includes a small form-factor CSI port which requires a camera adapter cable.

To attach a camera module to a Pi Zero: 1. Remove the existing camera module’s cable by gently lifting the collar on the camera module and pulling the cable out. 2. Next, insert the wider end of the adapter cable with the conductors facing in the same direction as the camera’s lens. 3. Finally, attach the adapter to the Pi Zero by gently lifting the collar at the edge of the board (be careful with this as they are more delicate than the collars on the regular CSI ports) and inserting the smaller end of the adapter with the conductors facing the back of the Pi Zero. Your setup should look something like this:

2.2. Testing Now, apply power to your Pi. Once booted, start the Raspberry Pi Configuration utility and enable the camera module:

You will need to reboot after doing this (but this is one-time setup so you won’t need to do it again unless you re-install your operating system or switch SD cards). Once rebooted, start a terminal and try the following command: raspistill -o image.jpg

If everything is working correctly, the camera should start, a preview from the camera should appear on the display and, after a 5 second delay it should capture an image (storing it as image.jpg ) before shutting down the camera. Proceed to the Basic Recipes. If something else happens, read any error message displayed and try any recommendations suggested by such messages. If your Pi reboots as soon as you run this command, your power supply is insufficient for running your Pi plus the camera module (and whatever other peripherals you have attached).

3. Basic Recipes The following recipes should be reasonably accessible to Python programmers of all skill levels. Please feel free to suggest enhancements or additional recipes. Warning When trying out these scripts do not name your file

picamera.py .

Naming scripts after

existing Python modules will cause errors when you try and import those modules (because Python checks the current directory before checking other paths).

3.1. Capturing to a file Capturing an image to a file is as simple as specifying the name of the file as the output of whatever capture() method you require: from time import sleep from picamera import PiCamera camera = PiCamera() camera.resolution = (1024, 768) camera.start_preview() # Camera warm-up time sleep(2) camera.capture('foo.jpg')

Note that files opened by picamera (as in the case above) will be flushed and closed so that when the capture() method returns, the data should be accessible to other processes.

3.2. Capturing to a stream Capturing an image to a file-like object (a

socket() ,

a

io.BytesIO

stream, an existing

open file object, etc.) is as simple as specifying that object as the output of whatever capture() method you’re using: from io import BytesIO from time import sleep from picamera import PiCamera # Create an in-memory stream my_stream = BytesIO() camera = PiCamera() camera.start_preview() # Camera warm-up time sleep(2) camera.capture(my_stream, 'jpeg')

Note that the format is explicitly specified in the case above. The

BytesIO

object has

no filename, so the camera can’t automatically figure out what format to use. One thing to bear in mind is that (unlike specifying a filename), the stream is not automatically closed after capture; picamera assumes that since it didn’t open the stream it can’t presume to close it either. However, if the object has a flush method, this will be called prior to capture returning. This should ensure that once capture returns the data is accessible to other processes although the object still needs to be closed: from time import sleep from picamera import PiCamera # Explicitly open a new file called my_image.jpg my_file = open('my_image.jpg', 'wb') camera = PiCamera() camera.start_preview() sleep(2) camera.capture(my_file) # At this point my_file.flush() has been called, but the file has # not yet been closed my_file.close()

Note that in the case above, we didn’t have to specify the format as the camera interrogated the my_file object for its filename (specifically, it looks for a name attribute on the provided object). As well as using stream classes built into Python (like BytesIO ) you can also construct your own custom outputs.

3.3. Capturing to a PIL Image This is a variation on Capturing to a stream. First we’ll capture an image to a BytesIO stream (Python’s in-memory stream class), then we’ll rewind the position of the stream to the start, and read the stream into a PIL Image object: from from from from

io import BytesIO time import sleep picamera import PiCamera PIL import Image

# Create the in-memory stream stream = BytesIO() camera = PiCamera() camera.start_preview() sleep(2) camera.capture(stream, format='jpeg') # "Rewind" the stream to the beginning so we can read its content

stream.seek(0) image = Image.open(stream)

3.4. Capturing resized images Sometimes, particularly in scripts which will perform some sort of analysis or processing on images, you may wish to capture smaller images than the current resolution of the camera. Although such resizing can be performed using libraries like PIL or OpenCV, it is considerably more efficient to have the Pi’s GPU perform the resizing when capturing the image. This can be done with the resizeparameter of the capture() methods: from time import sleep from picamera import PiCamera camera = PiCamera() camera.resolution = (1024, 768) camera.start_preview() # Camera warm-up time sleep(2) camera.capture('foo.jpg', resize=(320, 240))

The resize parameter can also be specified when recording video with the start_recording() method.

3.5. Capturing consistent images You may wish to capture a sequence of images all of which look the same in terms of brightness, color, and contrast (this can be useful in timelapse photography, for example). Various attributes need to be used in order to ensure consistency across multiple shots. Specifically, you need to ensure that the camera’s exposure time, white balance, and gains are all fixed:    

To fix exposure time, set the shutter_speed attribute to a reasonable value. Optionally, set iso to a fixed value. To fix exposure gains, let analog_gain and digital_gain settle on reasonable values, then set exposure_mode to 'off' . To fix white balance, set the awb_mode to 'off' , then set awb_gains to a (red, blue) tuple of gains.

It can be difficult to know what appropriate values might be for these attributes. For iso , a simple rule of thumb is that 100 and 200 are reasonable values for

daytime, while 400 and 800 are better for low light. To determine a reasonable value for shutter_speed you can query the exposure_speed attribute. For exposure gains, it’s usually enough to wait until analog_gain is greater than 1 before exposure_mode is set to 'off' . Finally, to determine reasonable values for awb_gains simply query the property while awb_mode is set to something other than 'off' . Again, this will tell you the camera’s white balance gains as determined by the auto-white-balance algorithm. The following script provides a brief example of configuring these settings: from time import sleep from picamera import PiCamera camera = PiCamera(resolution=(1280, 720), framerate=30) # Set ISO to the desired value camera.iso = 100 # Wait for the automatic gain control to settle sleep(2) # Now fix the values camera.shutter_speed = camera.exposure_speed camera.exposure_mode = 'off' g = camera.awb_gains camera.awb_mode = 'off' camera.awb_gains = g # Finally, take several photos with the fixed settings camera.capture_sequence(['image%02d.jpg' % i for i in range(10)])

3.6. Capturing timelapse sequences The simplest way to capture long time-lapse sequences is with the capture_continuous() method. With this method, the camera captures images continually until you tell it to stop. Images are automatically given unique names and you can easily control the delay between captures. The following example shows how to capture images with a 5 minute delay between each shot: from time import sleep from picamera import PiCamera camera = PiCamera() camera.start_preview() sleep(2) for filename in camera.capture_continuous('img{counter:03d}.jpg'): print('Captured %s' % filename) sleep(300) # wait 5 minutes

However, you may wish to capture images at a particular time, say at the start of every hour. This simply requires a refinement of the delay in the loop

(the datetime module is slightly easier to use for calculating dates and times; this example also demonstrates the timestamp template in the captured filenames): from time import sleep from picamera import PiCamera from datetime import datetime, timedelta def wait(): # Calculate the delay to the start of the next hour next_hour = (datetime.now() + timedelta(hour=1)).replace( minute=0, second=0, microsecond=0) delay = (next_hour - datetime.now()).seconds sleep(delay) camera = PiCamera() camera.start_preview() wait() for filename in camera.capture_continuous('img{timestamp:%Y-%m-%d-%H-%M}.jpg'): print('Captured %s' % filename) wait()

3.7. Capturing in low light Using similar tricks to those in Capturing consistent images, the Pi’s camera can capture images in low light conditions. The primary objective is to set a high gain, and a long exposure time to allow the camera to gather as much light as possible. However, the shutter_speed attribute is constrained by the camera’s framerate so the first thing we need to do is set a very slow framerate. The following script captures an image with a 6 second exposure time (the maximum the Pi’s V1 camera module is capable of; the V2 camera module can manage 10 second exposures): from picamera import PiCamera from time import sleep from fractions import Fraction # Force sensor mode 3 (the long exposure mode), set # the framerate to 1/6fps, the shutter speed to 6s, # and ISO to 800 (for maximum gain) camera = PiCamera( resolution=(1280, 720), framerate=Fraction(1, 6), sensor_mode=3) camera.shutter_speed = 6000000 camera.iso = 800 # Give the camera a good long time to set gains and # measure AWB (you may wish to use fixed AWB instead) sleep(30) camera.exposure_mode = 'off' # Finally, capture an image with a 6s exposure. Due # to mode switching on the still port, this will take # longer than 6 seconds camera.capture('dark.jpg')

In anything other than dark conditions, the image produced by this script will most likely be completely white or at least heavily over-exposed. Note The Pi’s camera module uses a rolling shutter. This means that moving subjects may appear distorted if they move relative to the camera. This effect will be exaggerated by using longer exposure times. When using long exposures, it is often preferable to use framerate_range instead of framerate . This allows the camera to vary the framerate on the fly and use shorter framerates where possible (leading to shorter capture delays). This hasn’t been used in the script above as the shutter speed is forced to 6 seconds (the maximum possible on the V1 camera module) which would make a framerate range pointless.

3.8. Capturing to a network stream This is a variation of Capturing timelapse sequences. Here we have two scripts: a server (presumably on a fast machine) which listens for a connection from the Raspberry Pi, and a client which runs on the Raspberry Pi and sends a continual stream of images to the server. We’ll use a very simple protocol for communication: first the length of the image will be sent as a 32-bit integer (in Little Endian format), then this will be followed by the bytes of image data. If the length is 0, this indicates that the connection should be closed as no more images will be forthcoming. This protocol is illustrated below:

Firstly the server script (which relies on PIL for reading JPEGs, but you could replace this with any other suitable graphics library, e.g. OpenCV or GraphicsMagick): import io import socket import struct from PIL import Image # Start a socket listening for connections on 0.0.0.0:8000 (0.0.0.0 means # all interfaces) server_socket = socket.socket()

server_socket.bind(('0.0.0.0', 8000)) server_socket.listen(0) # Accept a single connection and make a file-like object out of it connection = server_socket.accept()[0].makefile('rb') try: while True: # Read the length of the image as a 32-bit unsigned int. If the # length is zero, quit the loop image_len = struct.unpack('
Now for the client side of things, on the Raspberry Pi: import import import import import

io socket struct time picamera

# Connect a client socket to my_server:8000 (change my_server to the # hostname of your server) client_socket = socket.socket() client_socket.connect(('my_server', 8000)) # Make a file-like object out of the connection connection = client_socket.makefile('wb') try: camera = picamera.PiCamera() camera.resolution = (640, 480) # Start a preview and let the camera warm up for 2 seconds camera.start_preview() time.sleep(2) # Note the start time and construct a stream to hold image data # temporarily (we could write it directly to connection but in this # case we want to find out the size of each capture first to keep # our protocol simple) start = time.time() stream = io.BytesIO() for foo in camera.capture_continuous(stream, 'jpeg'): # Write the length of the capture to the stream and flush to # ensure it actually gets sent connection.write(struct.pack('
# Rewind the stream and send the image data over the wire stream.seek(0) connection.write(stream.read()) # If we've been capturing for more than 30 seconds, quit if time.time() - start > 30: break # Reset the stream for the next capture stream.seek(0) stream.truncate() # Write a length of zero to the stream to signal we're done connection.write(struct.pack('
The server script should be run first to ensure there’s a listening socket ready to accept a connection from the client script.

3.9. Recording video to a file Recording a video to a file is simple: import picamera camera = picamera.PiCamera() camera.resolution = (640, 480) camera.start_recording('my_video.h264') camera.wait_recording(60) camera.stop_recording()

Note that we use wait_recording() in the example above instead of time.sleep() which we’ve been using in the image capture recipes above. The wait_recording() method is similar in that it will pause for the number of seconds specified, but unlike time.sleep() it will continually check for recording errors (e.g. an out of disk space condition) while it is waiting. If we had used time.sleep() instead, such errors would only be raised by the stop_recording() call (which could be long after the error actually occurred).

3.10. Recording video to a stream This is very similar to Recording video to a file: from io import BytesIO from picamera import PiCamera stream = BytesIO() camera = PiCamera() camera.resolution = (640, 480) camera.start_recording(stream, format='h264', quality=23)

camera.wait_recording(15) camera.stop_recording()

Here, we’ve set the quality parameter to indicate to the encoder the level of image quality that we’d like it to try and maintain. The camera’s H.264 encoder is primarily constrained by two parameters: 



bitrate limits the encoder’s output to a certain number of bits per second. The default is 17000000 (17Mbps), and the maximum value is 25000000 (25Mbps). Higher values give the encoder more “freedom” to encode at higher qualities. You will likely find that the default doesn’t constrain the encoder at all except at higher recording resolutions. quality tells the encoder what level of image quality to maintain. Values can be between 1 (highest quality) and 40 (lowest quality), with typical values providing a reasonable trade-off between bandwidth and quality being between 20 and 25.

As well as using stream classes built into Python (like

BytesIO )

you can also

construct your own custom outputs. This is particularly useful for video recording, as discussed in the linked recipe.

3.11. Recording over multiple files If you wish split your recording over multiple files, you can use the split_recording() method to accomplish this: import picamera camera = picamera.PiCamera(resolution=(640, 480)) camera.start_recording('1.h264') camera.wait_recording(5) for i in range(2, 11): camera.split_recording('%d.h264' % i) camera.wait_recording(5) camera.stop_recording()

This should produce 10 video files named 1.h264 , 2.h264 , etc. each of which is approximately 5 seconds long (approximately because the split_recording() method will only split files at a key-frame). The

record_sequence()

code:

method can also be used to achieve this with slightly cleaner

import picamera camera = picamera.PiCamera(resolution=(640, 480)) for filename in camera.record_sequence( '%d.h264' % i for i in range(1, 11)): camera.wait_recording(5)

Changed in version 1.3: The

record_sequence()

method was introduced in version 1.3

3.12. Recording to a circular stream This is similar to Recording video to a stream but uses a special kind of in-memory stream provided by the picamera library. The PiCameraCircularIO class implements a ring buffer based stream, specifically for video recording. This enables you to keep an in-memory stream containing the last nseconds of video recorded (where n is determined by the bitrate of the video recording and the size of the ring buffer underlying the stream). A typical use-case for this sort of storage is security applications where one wishes to detect motion and only record to disk the video where motion was detected. This example keeps 20 seconds of video in memory until the write_now function returns True (in this implementation this is random but one could, for example, replace this with some sort of motion detection algorithm). Once write_now returns True , the script waits 10 more seconds (so that the buffer contains 10 seconds of video from before the event, and 10 seconds after) and writes the resulting video to disk before going back to waiting: import io import random import picamera def motion_detected(): # Randomly return True (like a fake motion detection routine) return random.randint(0, 10) == 0 camera = picamera.PiCamera() stream = picamera.PiCameraCircularIO(camera, seconds=20) camera.start_recording(stream, format='h264') try: while True: camera.wait_recording(1) if motion_detected(): # Keep recording for 10 seconds and only then write the # stream to disk camera.wait_recording(10) stream.copy_to('motion.h264') finally:

camera.stop_recording()

In the above script we use the special

copy_to()

method to copy the stream to a disk

file. This automatically handles details like finding the start of the first key-frame in the circular buffer, and also provides facilities like writing a specific number of bytes or seconds. Note Note that at least 20 seconds of video are in the stream. This is an estimate only; if the H.264 encoder requires less than the specified bitrate (17Mbps by default) for recording the video, then more than 20 seconds of video will be available in the stream. New in version 1.0. Changed in version 1.11: Added use of the

copy_to()

3.13. Recording to a network stream This is similar to Recording video to a stream but instead of an in-memory stream like BytesIO , we will use a file-like object created from a socket() . Unlike the example in Capturing to a network stream we don’t need to complicate our network protocol by writing things like the length of images. This time we’re sending a continual stream of video frames (which necessarily incorporates such information, albeit in a much more efficient form), so we can simply dump the recording straight to the network socket. Firstly, the server side script which will simply read the video stream and pipe it to a media player for display: import socket import subprocess # Start a socket listening for connections on 0.0.0.0:8000 (0.0.0.0 means # all interfaces) server_socket = socket.socket() server_socket.bind(('0.0.0.0', 8000)) server_socket.listen(0) # Accept a single connection and make a file-like object out of it connection = server_socket.accept()[0].makefile('rb') try: # Run a viewer with an appropriate command line. Uncomment the mplayer

# version if you would prefer to use mplayer instead of VLC cmdline = ['vlc', '--demux', 'h264', '-'] #cmdline = ['mplayer', '-fps', '25', '-cache', '1024', '-'] player = subprocess.Popen(cmdline, stdin=subprocess.PIPE) while True: # Repeatedly read 1k of data from the connection and write it to # the media player's stdin data = connection.read(1024) if not data: break player.stdin.write(data) finally: connection.close() server_socket.close() player.terminate()

Note If you run this script on Windows you will probably need to provide a complete path to the VLC or mplayer executable. If you run this script on Mac OS X, and are using Python installed from MacPorts, please ensure you have also installed VLC or mplayer from MacPorts. You will probably notice several seconds of latency with this setup. This is normal and is because media players buffer several seconds to guard against unreliable network streams. Some media players (notably mplayer in this case) permit the user to skip to the end of the buffer (press the right cursor key in mplayer), reducing the latency by increasing the risk that delayed / dropped network packets will interrupt the playback. Now for the client side script which simply starts a recording over a file-like object created from the network socket: import socket import time import picamera # Connect a client socket to my_server:8000 (change my_server to the # hostname of your server) client_socket = socket.socket() client_socket.connect(('my_server', 8000)) # Make a file-like object out of the connection connection = client_socket.makefile('wb') try: camera = picamera.PiCamera() camera.resolution = (640, 480) camera.framerate = 24 # Start a preview and let the camera warm up for 2 seconds camera.start_preview() time.sleep(2) # Start recording, sending the output to the connection for 60

# seconds, then stop camera.start_recording(connection, format='h264') camera.wait_recording(60) camera.stop_recording() finally: connection.close() client_socket.close()

It should also be noted that the effect of the above is much more easily achieved (at least on Linux) with a combination of netcat and the raspivid executable. For example: # on the server $ nc -l 8000 | vlc --demux h264 # on the client raspivid -w 640 -h 480 -t 60000 -o - | nc my_server 8000

However, this recipe does serve as a starting point for video streaming applications. It’s also possible to reverse the direction of this recipe relatively easily. In this scenario, the Pi acts as the server, waiting for a connection from the client. When it accepts a connection, it starts streaming video over it for 60 seconds. Another variation (just for the purposes of demonstration) is that we initialize the camera straight away instead of waiting for a connection to allow the streaming to start faster on connection: import socket import time import picamera camera = picamera.PiCamera() camera.resolution = (640, 480) camera.framerate = 24 server_socket = socket.socket() server_socket.bind(('0.0.0.0', 8000)) server_socket.listen(0) # Accept a single connection and make a file-like object out of it connection = server_socket.accept()[0].makefile('wb') try: camera.start_recording(connection, format='h264') camera.wait_recording(60) camera.stop_recording() finally: connection.close() server_socket.close()

One advantage of this setup is that no script is needed on the client side - we can simply use VLC with a network URL: vlc tcp/h264://my_pi_address:8000/

Note VLC (or mplayer) will not work for playback on a Pi. Neither is (currently) capable of using the GPU for decoding, and thus they attempt to perform video decoding on the Pi’s CPU (which is not powerful enough for the task). You will need to run these applications on a faster machine (though “faster” is a relative term here: even an Atom powered netbook should be quick enough for the task at non-HD resolutions).

3.14. Overlaying images on the preview The camera preview system can operate multiple layered renderers simultaneously. While the picamera library only permits a single renderer to be connected to the camera’s preview port, it does permit additional renderers to be created which display a static image. These overlaid renderers can be used to create simple user interfaces. Note Overlay images will not appear in image captures or video recordings. If you need to embed additional information in the output of the camera, please refer to Overlaying text on the output. One difficulty of working with overlay renderers is that they expect unencoded RGB input which is padded up to the camera’s block size. The camera’s block size is 32x16 so any image data provided to a renderer must have a width which is a multiple of 32, and a height which is a multiple of 16. The specific RGB format expected is interleaved unsigned bytes. If all this sounds complicated, don’t worry; it’s quite simple to produce in practice. The following example demonstrates loading an arbitrary size image with PIL, padding it to the required size, and producing the unencoded RGB data for the call to add_overlay() : import picamera from PIL import Image from time import sleep camera = picamera.PiCamera() camera.resolution = (1280, 720) camera.framerate = 24 camera.start_preview() # Load the arbitrarily sized image

img = Image.open('overlay.png') # Create an image padded to the required size with # mode 'RGB' pad = Image.new('RGB', ( ((img.size[0] + 31) // 32) * 32, ((img.size[1] + 15) // 16) * 16, )) # Paste the original image into the padded one pad.paste(img, (0, 0)) # Add the overlay with the padded image as the source, # but the original image's dimensions o = camera.add_overlay(pad.tobytes(), size=img.size) # By default, the overlay is in layer 0, beneath the # preview (which defaults to layer 2). Here we make # the new overlay semi-transparent, then move it above # the preview o.alpha = 128 o.layer = 3 # Wait indefinitely until the user terminates the script while True: sleep(1)

Alternatively, instead of using an image file as the source, you can produce an overlay directly from a numpy array. In the following example, we construct a numpy array with the same resolution as the screen, then draw a white cross through the center and overlay it on the preview as a simple cross-hair: import time import picamera import numpy as np # Create an array representing a 1280x720 image of # a cross through the center of the display. The shape of # the array must be of the form (height, width, color) a = np.zeros((720, 1280, 3), dtype=np.uint8) a[360, :, :] = 0xff a[:, 640, :] = 0xff camera = picamera.PiCamera() camera.resolution = (1280, 720) camera.framerate = 24 camera.start_preview() # Add the overlay directly into layer 3 with transparency; # we can omit the size parameter of add_overlay as the # size is the same as the camera's resolution o = camera.add_overlay(np.getbuffer(a), layer=3, alpha=64) try: # Wait indefinitely until the user terminates the script while True: time.sleep(1) finally: camera.remove_overlay(o)

Given that overlaid renderers can be hidden (by moving them below the preview’s layer which defaults to 2), made semi-transparent (with

the

alpha

property), and resized so that they don’t

fill the screen ,

they can be used

to construct simple user interfaces. New in version 1.8.

3.15. Overlaying text on the output The camera includes a rudimentary annotation facility which permits up to 255 characters of ASCII text to be overlaid on all output (including the preview, image captures and video recordings). To achieve this, simply assign a string to the annotate_text attribute: import picamera import time camera = picamera.PiCamera() camera.resolution = (640, 480) camera.framerate = 24 camera.start_preview() camera.annotate_text = 'Hello world!' time.sleep(2) # Take a picture including the annotation camera.capture('foo.jpg')

With a little ingenuity, it’s possible to display longer strings: import picamera import time import itertools s = "This message would be far too long to display normally..." camera = picamera.PiCamera() camera.resolution = (640, 480) camera.framerate = 24 camera.start_preview() camera.annotate_text = ' ' * 31 for c in itertools.cycle(s): camera.annotate_text = camera.annotate_text[1:31] + c time.sleep(0.1)

And of course, it can be used to display (and embed) a timestamp in recordings (this recipe also demonstrates drawing a background behind the timestamp for contrast with the annotate_background attribute): import picamera import datetime as dt camera = picamera.PiCamera(resolution=(1280, 720), framerate=24) camera.start_preview()

camera.annotate_background = picamera.Color('black') camera.annotate_text = dt.datetime.now().strftime('%Y-%m-%d %H:%M:%S') camera.start_recording('timestamped.h264') start = dt.datetime.now() while (dt.datetime.now() - start).seconds < 30: camera.annotate_text = dt.datetime.now().strftime('%Y-%m-%d %H:%M:%S') camera.wait_recording(0.2) camera.stop_recording()

New in version 1.7.

3.16. Controlling the LED In certain circumstances, you may find the V1 camera module’s red LED a hindrance (the V2 camera module lacks an LED). For example, in the case of automated close-up wild-life photography, the LED may scare off animals. It can also cause unwanted reflected red glare with close-up subjects. One trivial way to deal with this is simply to place some opaque covering on the LED (e.g. blue-tack or electricians tape). Another method is to use the disable_camera_led option in the boot configuration. However, provided you have the RPi.GPIO package installed, and provided your Python process is running with sufficient privileges (typically this means running as root with sudo python ), you can also control the LED via the led attribute: import picamera camera = picamera.PiCamera() # Turn the camera's LED off camera.led = False # Take a picture while the LED remains off camera.capture('foo.jpg')

Note The camera LED cannot currently be controlled when the module is attached to a Raspberry Pi 3 Model B as the GPIO that controls the LED has moved to a GPIO expander not directly accessible to the ARM processor. Warning Be aware when you first use the LED property it will set the GPIO library to Broadcom (BCM) mode with GPIO.setmode(GPIO.BCM) and disable warnings with GPIO.setwarnings(False) . The LED cannot be controlled when the library is in BOARD mode.

4. Advanced Recipes The following recipes involve advanced techniques and may not be “beginner friendly”. Please feel free to suggest enhancements or additional recipes. Warning When trying out these scripts do not name your file

picamera.py .

Naming scripts after

existing Python modules will cause errors when you try and import those modules (because Python checks the current directory before checking other paths).

4.1. Capturing to a numpy array Since 1.11, picamera can capture directly to any object which supports Python’s buffer protocol (including numpy’s ndarray ). Simply pass the object as the destination of the capture and the image data will be written directly to the object. The target object must fulfil various requirements (some of which are dependent on the version of Python you are using): 1. The buffer object must be writeable (e.g. you cannot capture to a

bytes

object as

it is immutable). 2. The buffer object must be large enough to receive all the image data. 3. (Python 2.x only) The buffer object must be 1-dimensional. 4. (Python 2.x only) The buffer object must have byte-sized items. For example, to capture directly to a three-dimensional numpy

ndarray

(Python 3.x

only): import time import picamera import numpy as np with picamera.PiCamera() as camera: camera.resolution = (320, 240) camera.framerate = 24 time.sleep(2) output = np.empty((240, 320, 3), dtype=np.uint8) camera.capture(output, 'rgb')

It is also important to note that when outputting to unencoded formats, the camera rounds the requested resolution. The horizontal resolution is rounded up to the nearest multiple of 32 pixels, while the vertical resolution is rounded up to the nearest multiple of 16 pixels. For example, if the requested resolution is 100x100,

the capture will actually contain 128x112 pixels worth of data, but pixels beyond 100x100 will be uninitialized. So, to capture a 100x100 image we first need to provide a 128x112 array, then strip off the uninitialized pixels afterward. The following example demonstrates this along with the re-shaping necessary under Python 2.x: import time import picamera import numpy as np with picamera.PiCamera() as camera: camera.resolution = (100, 100) camera.framerate = 24 time.sleep(2) output = np.empty((112 * 128 * 3,), dtype=np.uint8) camera.capture(output, 'rgb') output = output.reshape((112, 128, 3)) output = output[:100, :100, :]

Warning Under certain circumstances (non-resized, non-YUV, video-port captures), the resolution is rounded to 16x16 blocks instead of 32x16. Adjust your resolution rounding accordingly. New in version 1.11.

4.2. Capturing to an OpenCV object This is a variation on Capturing to a numpy array. OpenCV uses numpy arrays as images and defaults to colors in planar BGR. Hence, the following is all that’s required to capture an OpenCV compatible image: import import import import

time picamera numpy as np cv2

with picamera.PiCamera() as camera: camera.resolution = (320, 240) camera.framerate = 24 time.sleep(2) image = np.empty((240 * 320 * 3,), dtype=np.uint8) camera.capture(image, 'bgr') image = image.reshape((240, 320, 3))

Changed in version 1.11: Replaced recipe with direct array capture example.

4.3. Unencoded image capture (YUV format) If you want images captured without loss of detail (due to JPEG’s lossy compression), you are probably better off exploring PNG as an alternate image format (PNG uses lossless compression). However, some applications (particularly scientific ones) simply require the image data in numeric form. For this, the 'yuv' format is provided: import time import picamera with picamera.PiCamera() as camera: camera.resolution = (100, 100) camera.start_preview() time.sleep(2) camera.capture('image.data', 'yuv')

The specific YUV format used is YUV420 (planar). This means that the Y (luminance) values occur first in the resulting data and have full resolution (one 1byte Y value for each pixel in the image). The Y values are followed by the U (chrominance) values, and finally the V (chrominance) values. The UV values have one quarter the resolution of the Y components (4 1-byte Y values in a square for each 1-byte U and 1-byte V value). This is illustrated in the diagram below:

It is also important to note that when outputting to unencoded formats, the camera rounds the requested resolution. The horizontal resolution is rounded up to the nearest multiple of 32 pixels, while the vertical resolution is rounded up to the nearest multiple of 16 pixels. For example, if the requested resolution is 100x100, the capture will actually contain 128x112 pixels worth of data, but pixels beyond 100x100 will be uninitialized. Given that the YUV420 format contains 1.5 bytes worth of data for each pixel (a 1byte Y value for each pixel, and 1-byte U and V values for every 4 pixels), and taking into account the resolution rounding, the size of a 100x100 YUV capture will be:

The first 14336 bytes of the data (128*112) will be Y values, the next 3584 bytes ( ) will be U values, and the final 3584 bytes will be the V values. The following code demonstrates capturing YUV image data, loading the data into a set of numpyarrays, and converting the data to RGB format in an efficient manner: from __future__ import division import time import picamera import numpy as np width = 100 height = 100 stream = open('image.data', 'w+b') # Capture the image in YUV format with picamera.PiCamera() as camera: camera.resolution = (width, height) camera.start_preview() time.sleep(2) camera.capture(stream, 'yuv') # Rewind the stream for reading stream.seek(0) # Calculate the actual image size in the stream (accounting for rounding # of the resolution) fwidth = (width + 31) // 32 * 32 fheight = (height + 15) // 16 * 16 # Load the Y (luminance) data from the stream Y = np.fromfile(stream, dtype=np.uint8, count=fwidth*fheight).\ reshape((fheight, fwidth)) # Load the UV (chrominance) data from the stream, and double its size U = np.fromfile(stream, dtype=np.uint8, count=(fwidth//2)*(fheight//2)).\ reshape((fheight//2, fwidth//2)).\ repeat(2, axis=0).repeat(2, axis=1) V = np.fromfile(stream, dtype=np.uint8, count=(fwidth//2)*(fheight//2)).\ reshape((fheight//2, fwidth//2)).\ repeat(2, axis=0).repeat(2, axis=1) # Stack the YUV channels together, crop the actual resolution, convert to # floating point for later calculations, and apply the standard biases YUV = np.dstack((Y, U, V))[:height, :width, :].astype(np.float) YUV[:, :, 0] = YUV[:, :, 0] - 16 # Offset Y by 16 YUV[:, :, 1:] = YUV[:, :, 1:] - 128 # Offset UV by 128 # YUV conversion matrix from ITU-R BT.601 version (SDTV) # Y U V M = np.array([[1.164, 0.000, 1.596], # R [1.164, -0.392, -0.813], # G [1.164, 2.017, 0.000]]) # B # Take the dot product with the matrix to produce RGB output, clamp the # results to byte range and convert to bytes RGB = YUV.dot(M.T).clip(0, 255).astype(np.uint8)

Note

You may note that we are using open() in the code above instead of io.open() as in the other examples. This is because numpy’s numpy.fromfile() method annoyingly only accepts “real” file objects. This recipe is now encapsulated in the

PiYUVArray

class in the

picamera.array

module,

which means the same can be achieved as follows: import time import picamera import picamera.array with picamera.PiCamera() as camera: with picamera.array.PiYUVArray(camera) as stream: camera.resolution = (100, 100) camera.start_preview() time.sleep(2) camera.capture(stream, 'yuv') # Show size of YUV data print(stream.array.shape) # Show size of RGB converted data print(stream.rgb_array.shape)

As of 1.11 you can also capture directly to numpy arrays (see Capturing to a numpy array). Due to the difference in resolution of the Y and UV components, this isn’t directly useful (if you need all three components, you’re better off using PiYUVArray as this rescales the UV components for convenience). However, if you only require the Y plane you can provide a buffer just large enough for this plane and ignore the error that occurs when writing to the buffer (picamera will deliberately write as much as it can to the buffer before raising an exception to support this use-case): import import import import

time picamera picamera.array numpy as np

with picamera.PiCamera() as camera: camera.resolution = (100, 100) time.sleep(2) y_data = np.empty((112, 128), dtype=np.uint8) try: camera.capture(y_data, 'yuv') except IOError: pass y_data = y_data[:100, :100] # y_data now contains the Y-plane only

Alternatively, see Unencoded image capture (RGB format) for a method of having the camera output RGB data directly. Note

Capturing so-called “raw” formats ( 'yuv' ,

'rgb' ,

etc.) does not provide the raw bayer

data from the camera’s sensor. Rather, it provides access to the image data after GPU processing, but before format encoding (JPEG, PNG, etc). Currently, the only method of accessing the raw bayer data is via the bayer parameter to the capture() method. See Raw Bayer data captures for more information. Changed in version 1.0: The raw_format attribute is now deprecated, as is the 'raw' format specification for the capture() method. Simply use the 'yuv' format instead, as shown in the code above. Changed in version 1.5: Added note about new

picamera.array

module.

Changed in version 1.11: Added instructions for direct array capture.

4.4. Unencoded image capture (RGB format) The RGB format is rather larger than the YUV format discussed in the section above, but is more useful for most analyses. To have the camera produce output in RGB format, you simply need to specify 'rgb' as the format for the capture() method instead: import time import picamera with picamera.PiCamera() as camera: camera.resolution = (100, 100) camera.start_preview() time.sleep(2) camera.capture('image.data', 'rgb')

The size of RGB data can be calculated similarly to YUV captures. Firstly round the resolution appropriately (see Unencoded image capture (YUV format) for the specifics), then multiply the number of pixels by 3 (1 byte of red, 1 byte of green, and 1 byte of blue intensity). Hence, for a 100x100 capture, the amount of data produced is:

Warning

Under certain circumstances (non-resized, non-YUV, video-port captures), the resolution is rounded to 16x16 blocks instead of 32x16. Adjust your resolution rounding accordingly. The resulting RGB data is interleaved. That is to say that the red, green and blue values for a given pixel are grouped together, in that order. The first byte of the data is the red value for the pixel at (0, 0), the second byte is the green value for the same pixel, and the third byte is the blue value for that pixel. The fourth byte is the red value for the pixel at (1, 0), and so on. As the planes in RGB data are all equally sized (in contrast to YUV420) it is trivial to capture directly into a numpy array (Python 3.x only; see Capturing to a numpy array for Python 2.x instructions): import import import import

time picamera picamera.array numpy as np

with picamera.PiCamera() as camera: camera.resolution = (100, 100) time.sleep(2) image = np.empty((128, 112, 3), dtype=np.uint8) camera.capture(image, 'rgb') image = image[:100, :100]

Note RGB captures from the still port do not work at the full resolution of the camera (they result in an out of memory error). Either use YUV captures, or capture from the video port if you require full resolution. Changed in version 1.0: The raw_format attribute is now deprecated, as is the 'raw' format specification for the capture() method. Simply use the 'rgb' format instead, as shown in the code above. Changed in version 1.5: Added note about new

picamera.array

module.

Changed in version 1.11: Added instructions for direct array capture.

4.5. Custom outputs

All methods in the picamera library which accept a filename also accept file-like objects. Typically, this is only used with actual file objects, or with memory streams (like io.BytesIO ). However, building a custom output object is extremely easy and in certain cases very useful. A file-like object (as far as picamera is concerned) is simply an object with a write method which must accept a single parameter consisting of a byte-string, and which can optionally return the number of bytes written. The object can optionally implement a flush method (which has no parameters), which will be called at the end of output. Custom outputs are particularly useful with video recording as the custom output’s write method will be called (at least) once for every frame that is output, allowing you to implement code that reacts to each and every frame without going to the bother of a full custom encoder. However, one should bear in mind that because the write method is called so frequently, its implementation must be sufficiently rapid that it doesn’t stall the encoder (it must perform its processing and return before the next write is due to arrive if you wish to avoid dropping frames). The following trivial example demonstrates an incredibly simple custom output which simply throws away the output while counting the number of bytes that would have been written and prints this at the end of the output: import picamera class MyOutput(object): def __init__(self): self.size = 0 def write(self, s): self.size += len(s) def flush(self): print('%d bytes would have been written' % self.size) with picamera.PiCamera() as camera: camera.resolution = (640, 480) camera.framerate = 60 camera.start_recording(MyOutput(), format='h264') camera.wait_recording(10) camera.stop_recording()

The following example shows how to use a custom output to construct a crude motion detection system. We construct a custom output object which is used as the destination for motion vector data (this is particularly simple as motion vector data

always arrives as single chunks; frame data by contrast sometimes arrives in several separate chunks). The output object doesn’t actually write the motion data anywhere; instead it loads it into a numpy array and analyses whether there are any significantly large vectors in the data, printing a message to the console if there are. As we are not concerned with keeping the actual video output in this example, we use /dev/null as the destination for the video data: from __future__ import division import picamera import numpy as np motion_dtype = np.dtype([ ('x', 'i1'), ('y', 'i1'), ('sad', 'u2'), ]) class MyMotionDetector(object): def __init__(self, camera): width, height = camera.resolution self.cols = (width + 15) // 16 self.cols += 1 # there's always an extra column self.rows = (height + 15) // 16 def write(self, s): # Load the motion data from the string to a numpy array data = np.fromstring(s, dtype=motion_dtype) # Re-shape it and calculate the magnitude of each vector data = data.reshape((self.rows, self.cols)) data = np.sqrt( np.square(data['x'].astype(np.float)) + np.square(data['y'].astype(np.float)) ).clip(0, 255).astype(np.uint8) # If there're more than 10 vectors with a magnitude greater # than 60, then say we've detected motion if (data > 60).sum() > 10: print('Motion detected!') # Pretend we wrote all the bytes of s return len(s) with picamera.PiCamera() as camera: camera.resolution = (640, 480) camera.framerate = 30 camera.start_recording( # Throw away the video data, but make sure we're using H.264 '/dev/null', format='h264', # Record motion data to our custom output object motion_output=MyMotionDetector(camera) ) camera.wait_recording(30) camera.stop_recording()

You may wish to investigate the classes in the

picamera.array

module which

implement several custom outputs for analysis of data with numpy. In particular,

the

PiMotionAnalysis

class can be used to remove much of the boiler plate code from

the recipe above: import picamera import picamera.array import numpy as np class MyMotionDetector(picamera.array.PiMotionAnalysis): def analyse(self, a): a = np.sqrt( np.square(a['x'].astype(np.float)) + np.square(a['y'].astype(np.float)) ).clip(0, 255).astype(np.uint8) # If there're more than 10 vectors with a magnitude greater # than 60, then say we've detected motion if (a > 60).sum() > 10: print('Motion detected!') with picamera.PiCamera() as camera: camera.resolution = (640, 480) camera.framerate = 30 camera.start_recording( '/dev/null', format='h264', motion_output=MyMotionDetector(camera) ) camera.wait_recording(30) camera.stop_recording()

New in version 1.5.

4.6. Unconventional file outputs As noted in prior sections, picamera accepts a wide variety of things as an output:    

A string, which will be treated as a filename. A file-like object, e.g. as returned by open() . A custom output. Any mutable object that implements the buffer interface.

The simplest of these, the filename, hides a certain amount of complexity. It can be important to understand exactly how picamera treats files, especially when dealing with “unconventional” files (e.g. pipes, FIFOs, etc.) When given a filename, picamera does the following:

1. Opens the specified file with the

'wb'

mode, i.e. open for writing, truncating the

file first, in binary mode. 2. The file is opened with a larger-than-normal buffer size, specifically 64Kb. A large buffer size is utilized because it improves performance and system load with the majority use-case, i.e. sequentially writing video to the disk. 3. The requested data (image captures, video recording, etc.) is written to the open file. 4. Finally, the file is flushed and closed. Note that this is the only circumstance in which picamera will presume to close the output for you, because picamera opened the output for you. As noted above, this fits the majority use case (sequentially writing video to a file) very well. However, if you are piping data to another process via a FIFO (which picamera will simply treat as any other file), you may wish to avoid all the buffering. In this case, you can simply open the output yourself with no buffering. As noted above, you will then be responsible for closing the output when you are finished with it (you opened it, so the responsibility for closing it is yours as well). For example: import io import os import picamera with picamera.PiCamera(resolution='VGA') as camera: os.mkfifo('video_fifo') f = io.open('video_fifo', 'wb', buffering=0) try: camera.start_recording(f, format='h264') camera.wait_recording(10) camera.stop_recording() finally: f.close() os.unlink('video_fifo')

4.7. Rapid capture and processing The camera is capable of capturing a sequence of images extremely rapidly by utilizing its video-capture capabilities with a JPEG encoder (via the use_video_port parameter). However, there are several things to note about using this technique:



 

When using video-port based capture only the video recording area is captured; in some cases this may be smaller than the normal image capture area (see discussion in Sensor Modes). No Exif information is embedded in JPEG images captured through the videoport. Captures typically appear “grainier” with this technique. Captures from the still port use a slower, more intensive denoise algorithm.

All capture methods support the use_video_port option, but the methods differ in their ability to rapidly capture sequential frames. So, whilst capture() and capture_continuous() both supportuse_video_port, capture_sequence() is by far the fastest method (because it does not re-initialize an encoder prior to each capture). Using this method, the author has managed 30fps JPEG captures at a resolution of 1024x768. By default,

capture_sequence()

is particularly suited to capturing a fixed number of

frames rapidly, as in the following example which captures a “burst” of 5 images: import time import picamera with picamera.PiCamera() as camera: camera.resolution = (1024, 768) camera.framerate = 30 camera.start_preview() time.sleep(2) camera.capture_sequence([ 'image1.jpg', 'image2.jpg', 'image3.jpg', 'image4.jpg', 'image5.jpg', ], use_video_port=True)

We can refine this slightly by using a generator expression to provide the filenames for processing instead of specifying every single filename manually: import time import picamera frames = 60 with picamera.PiCamera() as camera: camera.resolution = (1024, 768) camera.framerate = 30 camera.start_preview() # Give the camera some warm-up time

time.sleep(2) start = time.time() camera.capture_sequence([ 'image%02d.jpg' % i for i in range(frames) ], use_video_port=True) finish = time.time() print('Captured %d frames at %.2ffps' % ( frames, frames / (finish - start)))

However, this still doesn’t let us capture an arbitrary number of frames until some condition is satisfied. To do this we need to use a generator function to provide the list of filenames (or more usefully, streams) to the capture_sequence() method: import time import picamera frames = 60 def filenames(): frame = 0 while frame < frames: yield 'image%02d.jpg' % frame frame += 1 with picamera.PiCamera(resolution='720p', framerate=30) as camera: camera.start_preview() # Give the camera some warm-up time time.sleep(2) start = time.time() camera.capture_sequence(filenames(), use_video_port=True) finish = time.time() print('Captured %d frames at %.2ffps' % ( frames, frames / (finish - start)))

The major issue with capturing this rapidly is firstly that the Raspberry Pi’s IO bandwidth is extremely limited and secondly that, as a format, JPEG is considerably less efficient than the H.264 video format (which is to say that, for the same number of bytes, H.264 will provide considerably better quality over the same number of frames). At higher resolutions (beyond 800x600) you are likely to find you cannot sustain 30fps captures to the Pi’s SD card for very long (before exhausting the disk cache). If you are intending to perform processing on the frames after capture, you may be better off just capturing video and decoding frames from the resulting file rather than dealing with individual JPEG captures. Thankfully this is relatively easy as the JPEG format has a simple magic number( FF D8 ). This means we can use a custom

output to separate the frames out of an MJPEG video recording by inspecting the first two bytes of each buffer: import io import time import picamera class SplitFrames(object): def __init__(self): self.frame_num = 0 self.output = None def write(self, buf): if buf.startswith(b'\xff\xd8'): # Start of new frame; close the old one (if any) and # open a new output if self.output: self.output.close() self.frame_num += 1 self.output = io.open('image%02d.jpg' % self.frame_num, 'wb') self.output.write(buf) with picamera.PiCamera(resolution='720p', framerate=30) as camera: camera.start_preview() # Give the camera some warm-up time time.sleep(2) output = SplitFrames() start = time.time() camera.start_recording(output, format='mjpeg') camera.wait_recording(2) camera.stop_recording() finish = time.time() print('Captured %d frames at %.2ffps' % ( output.frame_num, output.frame_num / (finish - start)))

So far, we’ve just saved the captured frames to disk. This is fine if you’re intending to process later with another script, but what if we want to perform all processing within the current script? In this case, we may not need to involve the disk (or network) at all. We can set up a pool of parallel threads to accept and process image streams as captures come in: import import import import

io time threading picamera

class ImageProcessor(threading.Thread): def __init__(self, owner): super(ImageProcessor, self).__init__() self.stream = io.BytesIO() self.event = threading.Event() self.terminated = False self.owner = owner self.start()

def run(self): # This method runs in a separate thread while not self.terminated: # Wait for an image to be written to the stream if self.event.wait(1): try: self.stream.seek(0) # Read the image and do some processing on it #Image.open(self.stream) #... #... # Set done to True if you want the script to terminate # at some point #self.owner.done=True finally: # Reset the stream and event self.stream.seek(0) self.stream.truncate() self.event.clear() # Return ourselves to the available pool with self.owner.lock: self.owner.pool.append(self) class ProcessOutput(object): def __init__(self): self.done = False # Construct a pool of 4 image processors along with a lock # to control access between threads self.lock = threading.Lock() self.pool = [ImageProcessor(self) for i in range(4)] self.processor = None def write(self, buf): if buf.startswith(b'\xff\xd8'): # New frame; set the current processor going and grab # a spare one if self.processor: self.processor.event.set() with self.lock: if self.pool: self.processor = self.pool.pop() else: # No processor's available, we'll have to skip # this frame; you may want to print a warning # here to see whether you hit this case self.processor = None if self.processor: self.processor.stream.write(buf) def flush(self): # When told to flush (this indicates end of recording), shut # down in an orderly fashion. First, add the current processor # back to the pool if self.processor: with self.lock: self.pool.append(self.processor) self.processor = None # Now, empty the pool, joining each thread as we go while True: with self.lock:

try: proc = self.pool.pop() except IndexError: pass # pool is empty proc.terminated = True proc.join() with picamera.PiCamera(resolution='VGA') as camera: camera.start_preview() time.sleep(2) output = ProcessOutput() camera.start_recording(output, format='mjpeg') while not output.done: camera.wait_recording(1) camera.stop_recording()

4.8. Unencoded video capture Just as unencoded RGB data can be captured as images, the Pi’s camera module can also capture an unencoded stream of RGB (or YUV) video data. Combining this with the methods presented in Custom outputs (via the classes from picamera.array ), we can produce a fairly rapid color detection script: import picamera import numpy as np from picamera.array import PiRGBAnalysis from picamera.color import Color class MyColorAnalyzer(PiRGBAnalysis): def __init__(self, camera): super(MyColorAnalyzer, self).__init__(camera) self.last_color = '' def analyze(self, a): # Convert the average color of the pixels in the middle box c = Color( r=int(np.mean(a[30:60, 60:120, 0])), g=int(np.mean(a[30:60, 60:120, 1])), b=int(np.mean(a[30:60, 60:120, 2])) ) # Convert the color to hue, saturation, lightness h, l, s = c.hls c = 'none' if s > 1/3: if h > 8/9 or h < 1/36: c = 'red' elif 5/9 < h < 2/3: c = 'blue' elif 5/36 < h < 4/9: c = 'green' # If the color has changed, update the display if c != self.last_color: self.camera.annotate_text = c self.last_color = c with picamera.PiCamera(resolution='160x90', framerate=24) as camera: # Fix the camera's white-balance gains

camera.awb_mode = 'off' camera.awb_gains = (1.4, 1.5) # Draw a box over the area we're going to watch camera.start_preview(alpha=128) box = np.zeros((96, 160, 3), dtype=np.uint8) box[30:60, 60:120, :] = 0x80 camera.add_overlay(memoryview(box), size=(160, 90), layer=3, alpha=64) # Construct the analysis output and start recording data to it with MyColorAnalyzer(camera) as analyzer: camera.start_recording(analyzer, 'rgb') try: while True: camera.wait_recording(1) finally: camera.stop_recording()

4.9. Rapid capture and streaming Following on from Rapid capture and processing, we can combine the video capture technique with Capturing to a network stream. The server side script doesn’t change (it doesn’t really care what capture technique is being used - it just reads JPEGs off the wire). The changes to the client side script can be minimal at first - just set use_video_port to True in the capture_continuous() call: import import import import import

io socket struct time picamera

client_socket = socket.socket() client_socket.connect(('my_server', 8000)) connection = client_socket.makefile('wb') try: with picamera.PiCamera() as camera: camera.resolution = (640, 480) camera.framerate = 30 time.sleep(2) start = time.time() count = 0 stream = io.BytesIO() # Use the video-port for captures... for foo in camera.capture_continuous(stream, 'jpeg', use_video_port=True): connection.write(struct.pack(' 30: break stream.seek(0) stream.truncate() connection.write(struct.pack('
client_socket.close() finish = time.time() print('Sent %d images in %d seconds at %.2ffps' % ( count, finish-start, count / (finish-start)))

Using this technique, the author can manage about 19fps of streaming at 640x480. However, utilizing the MJPEG splitting demonstrated in Rapid capture and processing we can manage much faster: import import import import import

io socket struct time picamera

class SplitFrames(object): def __init__(self, connection): self.connection = connection self.stream = io.BytesIO() self.count = 0 def write(self, buf): if buf.startswith(b'\xff\xd8'): # Start of new frame; send the old one's length # then the data size = self.stream.tell() if size > 0: self.connection.write(struct.pack('
The above script achieves 30fps with ease.

4.10. Web streaming Streaming video over the web is surprisingly complicated. At the time of writing, there are still no video standards that are universally supported by all web browsers on all platforms. Furthermore, HTTP was originally designed as a one-shot protocol for serving web-pages. Since its invention, various additions have been bolted on to cater for its ever increasing use cases (file downloads, resumption, streaming, etc.) but the fact remains there’s no “simple” solution for video streaming at the moment. If you want to have a play with streaming a “real” video format (specifically, MPEG1) you may want to have a look at the pistreaming demo. However, for the purposes of this recipe we’ll be using a much simpler format: MJPEG. The following script uses Python’s built-in http.server module to make a simple video streaming server: import io import picamera import logging import socketserver from threading import Condition from http import server PAGE="""\ picamera MJPEG streaming demo

PiCamera MJPEG Streaming Demo

""" class StreamingOutput(object): def __init__(self): self.frame = None self.buffer = io.BytesIO() self.condition = Condition() def write(self, buf): if buf.startswith(b'\xff\xd8'): # New frame, copy the existing buffer's content and notify all # clients it's available self.buffer.truncate() with self.condition: self.frame = self.buffer.getvalue() self.condition.notify_all() self.buffer.seek(0) return self.buffer.write(buf) class StreamingHandler(server.BaseHTTPRequestHandler):

def do_GET(self): if self.path == '/': self.send_response(301) self.send_header('Location', '/index.html') self.end_headers() elif self.path == '/index.html': content = PAGE.encode('utf-8') self.send_response(200) self.send_header('Content-Type', 'text/html') self.send_header('Content-Length', len(content)) self.end_headers() self.wfile.write(content) elif self.path == '/stream.mjpg': self.send_response(200) self.send_header('Age', 0) self.send_header('Cache-Control', 'no-cache, private') self.send_header('Pragma', 'no-cache') self.send_header('Content-Type', 'multipart/x-mixed-replace; boundary=FRAME') self.end_headers() try: while True: with output.condition: output.condition.wait() frame = output.frame self.wfile.write(b'--FRAME\r\n') self.send_header('Content-Type', 'image/jpeg') self.send_header('Content-Length', len(frame)) self.end_headers() self.wfile.write(frame) self.wfile.write(b'\r\n') except Exception as e: logging.warning( 'Removed streaming client %s: %s', self.client_address, str(e)) else: self.send_error(404) self.end_headers() class StreamingServer(socketserver.ThreadingMixIn, server.HTTPServer): allow_reuse_address = True daemon_threads = True with picamera.PiCamera(resolution='640x480', framerate=24) as camera: output = StreamingOutput() camera.start_recording(output, format='mjpeg') try: address = ('', 8000) server = StreamingServer(address, StreamingHandler) server.serve_forever() finally: camera.stop_recording()

Once the script is running, visit view the video stream. Note

http://your-pi-address:8000/

with your web-browser to

This recipe assumes Python 3.x (the http.server module was named SimpleHTTPServer in Python 2.x)

4.11. Capturing images whilst recording The camera is capable of capturing still images while it is recording video. However, if one attempts this using the stills capture mode, the resulting video will have dropped frames during the still image capture. This is because images captured via the still port require a mode change, causing the dropped frames (this is the flicker to a higher resolution that one sees when capturing while a preview is running). However, if the use_video_port parameter is used to force a video-port based image capture (see Rapid capture and processing) then the mode change does not occur, and the resulting video should not have dropped frames, assuming the image can be produced before the next video frame is due: import picamera with picamera.PiCamera() as camera: camera.resolution = (800, 600) camera.start_preview() camera.start_recording('foo.h264') camera.wait_recording(10) camera.capture('foo.jpg', use_video_port=True) camera.wait_recording(10) camera.stop_recording()

The above code should produce a 20 second video with no dropped frames, and a still frame from 10 seconds into the video. Higher resolutions or non-JPEG image formats may still cause dropped frames (only JPEG encoding is hardware accelerated).

4.12. Recording at multiple resolutions The camera is capable of recording multiple streams at different resolutions simultaneously by use of the video splitter. This is probably most useful for performing analysis on a low-resolution stream, while simultaneously recording a high resolution stream for storage or viewing.

The following simple recipe demonstrates using the splitter_port parameter of the start_recording() method to begin two simultaneous recordings, each with a different resolution: import picamera with picamera.PiCamera() as camera: camera.resolution = (1024, 768) camera.framerate = 30 camera.start_recording('highres.h264') camera.start_recording('lowres.h264', splitter_port=2, resize=(320, 240)) camera.wait_recording(30) camera.stop_recording(splitter_port=2) camera.stop_recording()

There are 4 splitter ports in total that can be used (numbered 0, 1, 2, and 3). The video recording methods default to using splitter port 1, while the image capture methods default to splitter port 0 (when the use_video_port parameter is also True). A splitter port cannot be simultaneously used for video recording and image capture so you are advised to avoid splitter port 0 for video recordings unless you never intend to capture images whilst recording. New in version 1.3.

4.13. Recording motion vector data The Pi’s camera is capable of outputting the motion vector estimates that the camera’s H.264 encoder calculates while generating compressed video. These can be directed to a separate output file (or file-like object) with the motion_output parameter of the start_recording() method. Like the normal output parameter this accepts a string representing a filename, or a file-like object: import picamera with picamera.PiCamera() as camera: camera.resolution = (640, 480) camera.framerate = 30 camera.start_recording('motion.h264', motion_output='motion.data') camera.wait_recording(10) camera.stop_recording()

Motion data is calculated at the macro-block level (an MPEG macro-block represents a 16x16 pixel region of the frame), and includes one extra column of

data. Hence, if the camera’s resolution is 640x480 (as in the example above) there will be 41 columns of motion data (

), in 30 rows (

).

Motion data values are 4-bytes long, consisting of a signed 1-byte x vector, a signed 1-byte y vector, and an unsigned 2-byte SAD (Sum of Absolute Differences) value for each macro-block. Hence in the example above, each frame will generate 4920 bytes of motion data ( ). Assuming the data contains 300 frames (in practice it may contain a few more) the motion data should be 1,476,000 bytes in total. The following code demonstrates loading the motion data into a three-dimensional numpy array. The first dimension represents the frame, with the latter two representing rows and finally columns. A structured data-type is used for the array permitting easy access to x, y, and SAD values: from __future__ import division import numpy as np width = 640 height = 480 cols = (width + 15) // 16 cols += 1 # there's always an extra column rows = (height + 15) // 16 motion_data = np.fromfile( 'motion.data', dtype=[ ('x', 'i1'), ('y', 'i1'), ('sad', 'u2'), ]) frames = motion_data.shape[0] // (cols * rows) motion_data = motion_data.reshape((frames, rows, cols)) # Access the data for the first frame motion_data[0] # Access just the x-vectors from the fifth frame motion_data[4]['x'] # Access SAD values for the tenth frame motion_data[9]['sad']

You can calculate the amount of motion the vector represents simply by calculating the magnitude of the vector with Pythagoras’ theorem. The SAD (Sum of Absolute Differences) value can be used to determine how well the encoder thinks the vector represents the original reference frame.

The following code extends the example above to use PIL to produce a PNG image from the magnitude of each frame’s motion vectors: from __future__ import division import numpy as np from PIL import Image width = 640 height = 480 cols = (width + 15) // 16 cols += 1 rows = (height + 15) // 16 m = np.fromfile( 'motion.data', dtype=[ ('x', 'i1'), ('y', 'i1'), ('sad', 'u2'), ]) frames = m.shape[0] // (cols * rows) m = m.reshape((frames, rows, cols)) for frame in range(frames): data = np.sqrt( np.square(m[frame]['x'].astype(np.float)) + np.square(m[frame]['y'].astype(np.float)) ).clip(0, 255).astype(np.uint8) img = Image.fromarray(data) filename = 'frame%03d.png' % frame print('Writing %s' % filename) img.save(filename)

You may wish to investigate the PiMotionArray and PiMotionAnalysis classes in the picamera.array module which simplifies the above recipes to the following: import numpy as np import picamera import picamera.array from PIL import Image with picamera.PiCamera() as camera: with picamera.array.PiMotionArray(camera) as stream: camera.resolution = (640, 480) camera.framerate = 30 camera.start_recording('/dev/null', format='h264', motion_output=stream) camera.wait_recording(10) camera.stop_recording() for frame in range(stream.array.shape[0]): data = np.sqrt( np.square(stream.array[frame]['x'].astype(np.float)) + np.square(stream.array[frame]['y'].astype(np.float)) ).clip(0, 255).astype(np.uint8) img = Image.fromarray(data) filename = 'frame%03d.png' % frame print('Writing %s' % filename) img.save(filename)

The following command line can be used to generate an animation from the generated PNGs with ffmpeg (this will take a very long time on the Pi so you may wish to transfer the images to a faster machine for this step): avconv -r 30 -i frame%03d.png -filter:v scale=640:480 -c:v libx264 motion.mp4

Finally, as a demonstration of what can be accomplished with motion vectors, here’s a gesture detection system: import os import numpy as np import picamera from picamera.array import PiMotionAnalysis class GestureDetector(PiMotionAnalysis): QUEUE_SIZE = 10 # the number of consecutive frames to analyze THRESHOLD = 4.0 # the minimum average motion required in either axis def __init__(self, camera): super(GestureDetector, self).__init__(camera) self.x_queue = np.zeros(self.QUEUE_SIZE, dtype=np.float) self.y_queue = np.zeros(self.QUEUE_SIZE, dtype=np.float) self.last_move = '' def analyze(self, a): # Roll the queues and overwrite the first element with a new # mean (equivalent to pop and append, but faster) self.x_queue[1:] = self.x_queue[:-1] self.y_queue[1:] = self.y_queue[:-1] self.x_queue[0] = a['x'].mean() self.y_queue[0] = a['y'].mean() # Calculate the mean of both queues x_mean = self.x_queue.mean() y_mean = self.y_queue.mean() # Convert left/up to -1, right/down to 1, and movement below # the threshold to 0 x_move = ( '' if abs(x_mean) < self.THRESHOLD else 'left' if x_mean < 0.0 else 'right') y_move = ( '' if abs(y_mean) < self.THRESHOLD else 'down' if y_mean < 0.0 else 'up') # Update the display movement = ('%s %s' % (x_move, y_move)).strip() if movement != self.last_move: self.last_move = movement if movement: print(movement) with picamera.PiCamera(resolution='VGA', framerate=24) as camera: with GestureDetector(camera) as detector: camera.start_recording( os.devnull, format='h264', motion_output=detector) try: while True:

camera.wait_recording(1) finally: camera.stop_recording()

Within a few inches of the camera, move your hand up, down, left, and right, parallel to the camera and you should see the direction displayed on the console. New in version 1.5.

4.14. Splitting to/from a circular stream This example builds on the one in Recording to a circular stream and the one in Capturing images whilst recording to demonstrate the beginnings of a security application. As before, a PiCameraCircularIO instance is used to keep the last few seconds of video recorded in memory. While the video is being recorded, video-portbased still captures are taken to provide a motion detection routine with some input (the actual motion detection algorithm is left as an exercise for the reader). Once motion is detected, the last 10 seconds of video are written to disk, and video recording is split to another disk file to proceed until motion is no longer detected. Once motion is no longer detected, we split the recording back to the in-memory ring-buffer: import io import random import picamera from PIL import Image prior_image = None def detect_motion(camera): global prior_image stream = io.BytesIO() camera.capture(stream, format='jpeg', use_video_port=True) stream.seek(0) if prior_image is None: prior_image = Image.open(stream) return False else: current_image = Image.open(stream) # Compare current_image to prior_image to detect motion. This is # left as an exercise for the reader! result = random.randint(0, 10) == 0 # Once motion detection is done, make the prior image the current prior_image = current_image return result with picamera.PiCamera() as camera:

camera.resolution = (1280, 720) stream = picamera.PiCameraCircularIO(camera, seconds=10) camera.start_recording(stream, format='h264') try: while True: camera.wait_recording(1) if detect_motion(camera): print('Motion detected!') # As soon as we detect motion, split the recording to # record the frames "after" motion camera.split_recording('after.h264') # Write the 10 seconds "before" motion to disk as well stream.copy_to('before.h264', seconds=10) stream.clear() # Wait until motion is no longer detected, then split # recording back to the in-memory circular buffer while detect_motion(camera): camera.wait_recording(1) print('Motion stopped!') camera.split_recording(stream) finally: camera.stop_recording()

This example also demonstrates using the seconds parameter of the copy_to() method to limit the before file to 10 seconds of data (given that the circular buffer may contain considerably more than this). New in version 1.0. Changed in version 1.11: Added use of

copy_to()

4.15. Custom encoders You can override and/or extend the encoder classes used during image or video capture. This is particularly useful with video capture as it allows you to run your own code in response to every frame, although naturally whatever code runs within the encoder’s callback has to be reasonably quick to avoid stalling the encoder pipeline. Writing a custom encoder is quite a bit harder than writing a custom output and in most cases there’s little benefit. The only thing a custom encoder gives you that a custom output doesn’t is access to the buffer header flags. For many output formats (MJPEG and YUV for example), these won’t tell you anything interesting (i.e. they’ll simply indicate that the buffer contains a full frame and nothing else). Currently, the only format where the buffer header flags contain useful information is H.264. Even then, most of the information (I-frame, P-frame, motion information, etc.) would be

accessible from the frame attribute which you could access from your custom output’s write method. The encoder classes defined by picamera form the following hierarchy (dark classes are actually instantiated by the implementation in picamera, light classes implement base functionality but aren’t technically “abstract”):

The following table details which

methods use which encoder classes, and

PiCamera

which method they call to construct these encoders: Method(s)

Calls

Returns

capture() capture_continuous()captu

_get_image_enco

PiCookedOneImageEncoderPiRawOneIma

re_sequence()

der()

geEncoder

_get_images_enc

PiCookedMultiImageEncoderPiRawMult

oder()

iImageEncoder

_get_video_enco

PiCookedVideoEncoderPiRawVideoEnco

der()

der

capture_sequence()

start_recording()record_sequence()

It is recommended, particularly in the case of the image encoder classes, that you familiarize yourself with the specific function of these classes so that you can determine the best class to extend for your particular needs. You may find that one of the intermediate classes is a better basis for your own modifications. In the following example recipe we will extend the

PiCookedVideoEncoder

class to store

how many I-frames and P-frames are captured (the camera’s encoder doesn’t use B-frames): import picamera import picamera.mmal as mmal # Override PiVideoEncoder to keep track of the number of each type of frame

class MyEncoder(picamera.PiCookedVideoEncoder): def start(self, output, motion_output=None): self.parent.i_frames = 0 self.parent.p_frames = 0 super(MyEncoder, self).start(output, motion_output) def _callback_write(self, buf): # Only count when buffer indicates it's the end of a frame, and # it's not an SPS/PPS header (..._CONFIG) if ( (buf.flags & mmal.MMAL_BUFFER_HEADER_FLAG_FRAME_END) and not (buf.flags & mmal.MMAL_BUFFER_HEADER_FLAG_CONFIG) ): if buf.flags & mmal.MMAL_BUFFER_HEADER_FLAG_KEYFRAME: self.parent.i_frames += 1 else: self.parent.p_frames += 1 # Remember to return the result of the parent method! return super(MyEncoder, self)._callback_write(buf) # Override PiCamera to use our custom encoder for video recording class MyCamera(picamera.PiCamera): def __init__(self): super(MyCamera, self).__init__() self.i_frames = 0 self.p_frames = 0 def _get_video_encoder( self, camera_port, output_port, format, resize, **options): return MyEncoder( self, camera_port, output_port, format, resize, **options) with MyCamera() as camera: camera.start_recording('foo.h264') camera.wait_recording(10) camera.stop_recording() print('Recording contains %d I-frames and %d P-frames' % ( camera.i_frames, camera.p_frames))

Please note that the above recipe is flawed: PiCamera is capable of initiating multiple simultaneous recordings. If this were used with the above recipe, then each encoder would wind up incrementing the i_frames and p_frames attributes on the MyCamera instance leading to incorrect results. New in version 1.5.

4.16. Raw Bayer data captures The

bayer

parameter of the

capture()

method causes the raw Bayer data recorded

by the camera’s sensor to be output as part of the image meta-data. Note

The bayer parameter only operates with the JPEG format, and only for captures from the still port (i.e. when use_video_port is False, as it is by default). Raw Bayer data differs considerably from simple unencoded captures; it is the data recorded by the camera’s sensor prior to any GPU processing including auto white balance, vignette compensation, smoothing, down-scaling, etc. This also means: 

Bayer data is always full resolution, regardless of the camera’s output resolution and any resize parameter.



Bayer data occupies the last 6,404,096 bytes of the output file for the V1 module, or the last 10,270,208 bytes for the V2 module. The first 32,768 bytes of this is header data which starts with the string 'BRCM' .



Bayer data consists of 10-bit values, because this is the sensitivity of the OV5647 and IMX219sensors used in the Pi’s camera modules. The 10-bit values are organized as 4 8-bit values, followed by the low-order 2-bits of the 4 values packed into a fifth byte.



Bayer data is organized in a BGGR pattern (a minor variation of the common Bayer CFA). The raw data therefore has twice as many green pixels as red or blue and if viewed “raw” will look distinctly strange (too dark, too green, and with zippering effects along any straight edges).



To make a “normal” looking image from raw Bayer data you will need to perform de-mosaicingat the very least, and probably some form of color balance.

This (heavily commented) example script causes the camera to capture an image including the raw Bayer data. It then proceeds to unpack the Bayer data into a 3dimensional numpy array representing the raw RGB data and finally performs a rudimentary de-mosaic step with weighted averages. A couple of numpy tricks are used to improve performance but bear in mind that all processing is happening on the CPU and will be considerably slower than normal image captures: from __future__ import (

unicode_literals, absolute_import, print_function, division, )

import io import time import picamera import numpy as np from numpy.lib.stride_tricks import as_strided stream = io.BytesIO() with picamera.PiCamera() as camera: # Let the camera warm up for a couple of seconds time.sleep(2) # Capture the image, including the Bayer data camera.capture(stream, format='jpeg', bayer=True) ver = { 'RP_ov5647': 1, 'RP_imx219': 2, }[camera.exif_tags['IFD0.Model']] # Extract the raw Bayer data from the end of the stream, check the # header and strip if off before converting the data into a numpy array offset = { 1: 6404096, 2: 10270208, }[ver] data = stream.getvalue()[-offset:] assert data[:4] == 'BRCM' data = data[32768:] data = np.fromstring(data, dtype=np.uint8) # # # # # # # # # #

For the V1 module, the data consists of 1952 rows of 3264 bytes of data. The last 8 rows of data are unused (they only exist because the maximum resolution of 1944 rows is rounded up to the nearest 16). For the V2 module, the data consists of 2480 rows of 4128 bytes of data. There's actually 2464 rows of data, but the sensor's raw size is 2466 rows, rounded up to the nearest multiple of 16: 2480. Likewise, the last few bytes of each row are unused (why?). Here we reshape the data and strip off the unused bytes.

reshape, crop = { 1: ((1952, 3264), (1944, 3240)), 2: ((2480, 4128), (2464, 4100)), }[ver] data = data.reshape(reshape)[:crop[0], :crop[1]] # # # # # # # #

Horizontally, each row consists of 10-bit values. Every four bytes are the high 8-bits of four values, and the 5th byte contains the packed low 2-bits of the preceding four values. In other words, the bits of the values A, B, C, D and arranged like so: byte 1 byte 2 byte 3 byte 4 byte 5 AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD AABBCCDD

# Here, we convert our data into a 16-bit array, shift all values left by # 2-bits and unpack the low-order bits from every 5th byte in each row, # then remove the columns containing the packed bits data = data.astype(np.uint16) << 2 for byte in range(4): data[:, byte::5] |= ((data[:, 4::5] >> ((4 - byte) * 2)) & 0b11) data = np.delete(data, np.s_[4::5], 1) # # # # # # # # # # # #

Now to split the data up into its red, green, and blue components. The Bayer pattern of the OV5647 sensor is BGGR. In other words the first row contains alternating green/blue elements, the second row contains alternating red/green elements, and so on as illustrated below: GBGBGBGBGBGBGB RGRGRGRGRGRGRG GBGBGBGBGBGBGB RGRGRGRGRGRGRG Please note that if you use vflip or hflip to change the orientation of the capture, you must flip the Bayer pattern accordingly

rgb = np.zeros(data.shape + (3,), dtype=data.dtype) rgb[1::2, 0::2, 0] = data[1::2, 0::2] # Red rgb[0::2, 0::2, 1] = data[0::2, 0::2] # Green rgb[1::2, 1::2, 1] = data[1::2, 1::2] # Green rgb[0::2, 1::2, 2] = data[0::2, 1::2] # Blue # # # # # # # #

At this point we now have the raw Bayer data with the correct values and colors but the data still requires de-mosaicing and post-processing. If you wish to do this yourself, end the script here! Below we present a fairly naive de-mosaic method that simply calculates the weighted average of a pixel based on the pixels surrounding it. The weighting is provided by a byte representation of the Bayer filter which we construct first:

bayer = np.zeros(rgb.shape, dtype=np.uint8) bayer[1::2, 0::2, 0] = 1 # Red bayer[0::2, 0::2, 1] = 1 # Green bayer[1::2, 1::2, 1] = 1 # Green bayer[0::2, 1::2, 2] = 1 # Blue # # # # #

Allocate an array to hold our output with the same shape as the input data. After this we define the size of window that will be used to calculate each weighted average (3x3). Then we pad out the rgb and bayer arrays, adding blank pixels at their edges to compensate for the size of the window when calculating averages for edge pixels.

output = np.empty(rgb.shape, dtype=rgb.dtype) window = (3, 3) borders = (window[0] - 1, window[1] - 1) border = (borders[0] // 2, borders[1] // 2) rgb = np.pad(rgb, [ (border[0], border[0]), (border[1], border[1]), (0, 0), ], 'constant') bayer = np.pad(bayer, [ (border[0], border[0]),

(border[1], border[1]), (0, 0), ], 'constant') # # # # #

For each plane in the RGB data, we use a nifty numpy trick (as_strided) to construct a view over the plane of 3x3 matrices. We do the same for the bayer array, then use Einstein summation on each (np.sum is simpler, but copies the data so it's slower), and divide the results to get our weighted average:

for plane in range(3): p = rgb[..., plane] b = bayer[..., plane] pview = as_strided(p, shape=( p.shape[0] - borders[0], p.shape[1] - borders[1]) + window, strides=p.strides * 2) bview = as_strided(b, shape=( b.shape[0] - borders[0], b.shape[1] - borders[1]) + window, strides=b.strides * 2) psum = np.einsum('ijkl->ij', pview) bsum = np.einsum('ijkl->ij', bview) output[..., plane] = psum // bsum # # # # # # # #

At this point output should contain a reasonably "normal" looking image, although it still won't look as good as the camera's normal output (as it lacks vignette compensation, AWB, etc). If you want to view this in most packages (like GIMP) you'll need to convert it to 8-bit RGB data. The simplest way to do this is by right-shifting everything by 2-bits (yes, this makes all that unpacking work at the start rather redundant...)

output = (output >> 2).astype(np.uint8) with open('image.data', 'wb') as f: output.tofile(f)

An enhanced version of this recipe (which also handles different bayer orders caused by flips and rotations) is also encapsulated in the PiBayerArray class in the picamera.array module, which means the same can be achieved as follows: import import import import

time picamera picamera.array numpy as np

with picamera.PiCamera() as camera: with picamera.array.PiBayerArray(camera) as stream: camera.capture(stream, 'jpeg', bayer=True) # Demosaic data and write to output (just use stream.array if you # want to skip the demosaic step) output = (stream.demosaic() >> 2).astype(np.uint8) with open('image.data', 'wb') as f: output.tofile(f)

New in version 1.3. Changed in version 1.5: Added note about new

picamera.array

module.

4.17. Using a flash with the camera The Pi’s camera module includes an LED flash driver which can be used to illuminate a scene upon capture. The flash driver has two configurable GPIO pins: 



one for connection to an LED based flash (xenon flashes won’t work with the camera module due to it having a rolling shutter). This will fire before (flash metering) and during capture one for an optional privacy indicator (a requirement for cameras in some jurisdictions). This will fire after taking a picture to indicate that the camera has been used

These pins are configured by updating the VideoCore device tree blob. Firstly, install the device tree compiler, then grab a copy of the default device tree source: $ sudo apt-get install device-tree-compiler $ wget https://github.com/raspberrypi/firmware/raw/master/extra/dt-blob.dts

The device tree source contains a number of sections enclosed in curly braces, which form a hierarchy of definitions. The section to edit will depend on which revision of Raspberry Pi you have (check the silk-screen writing on the board for the revision number if you are unsure): Model

Section

Raspberry Pi Model B rev 1

/videocore/pins_rev1

Raspberry Pi Model A and Model B rev 2

/videocore/pins_rev2

Raspberry Pi Model A+

/videocore/pins_aplus

Raspberry Pi Model B+ rev 1.1

/videocore/pins_bplus1

Raspberry Pi Model B+ rev 1.2

/videocore/pins_bplus2

Model

Section

Raspberry Pi 2 Model B rev 1.0

/videocore/pins_2b1

Raspberry Pi 2 Model B rev 1.1 and rev 1.2

/videocore/pins_2b2

Raspberry Pi 3 Model B rev 1.0

/videocore/pins_3b1

Raspberry Pi 3 Model B rev 1.2

/videocore/pins_3b2

Raspberry Pi Zero rev 1.2 and rev 1.3

/videocore/pins_pi0

Under the section for your particular model of Pi you will find pin_config and pin_defines sections. Under the pin_config section you need to configure the GPIO pins you want to use for the flash and privacy indicator as using pull down termination. Then, under the pin_defines section you need to associate those pins with the FLASH_0_ENABLE and FLASH_0_INDICATOR pins. For example, to configure GPIO 17 as the flash pin, leaving the privacy indicator pin absent, on a Raspberry Pi 2 Model B rev 1.1 you would add the following line under the /videocore/pins_2b2/pin_config section: pin@p17 { function = "output"; termination = "pull_down"; };

Please note that GPIO pins will be numbered according to the Broadcom pin numbers (BCM mode in the RPi.GPIO library, not BOARD mode). Then change the following section under /videocore/pins_2b2/pin_defines . Specifically, change the type from “absent” to “internal”, and add a number property defining the flash pin as GPIO 17: pin_define@FLASH_0_ENABLE { type = "internal"; number = <17>; };

With the device tree source updated, you now need to compile it into a binary blob for the firmware to read. This is done with the following command line:

$ dtc -q -I dts -O dtb dt-blob.dts -o dt-blob.bin

Dissecting this command line, the following components are present:     

- Execute the device tree compiler -I dts - The input file is in device tree source format -O dtb - The output file should be produced in device tree binary format dt-blob.dts - The first anonymous parameter is the input filename -o dt-blob.bin - The output filename dtc

This should output nothing. If you get lots of warnings, you’ve forgotten the q switch; you can ignore the warnings. If anything else is output, it will most likely be an error message indicating you have made a mistake in the device tree source. In this case, review your edits carefully (note that sections and properties must be semi-colon terminated for example), and try again. Now the device tree binary blob has been produced, it needs to be placed on the first partition of the SD card. In the case of non-NOOBS Raspbian installs, this is generally the partition mounted as /boot : $ sudo cp dt-blob.bin /boot/

However, in the case of NOOBS Raspbian installs, this is the recovery partition, which is not mounted by default: $ $ $ $ $

sudo sudo sudo sudo sudo

mkdir /mnt/recovery mount /dev/mmcblk0p1 /mnt/recovery cp dt-blob.bin /mnt/recovery umount /mnt/recovery rmdir /mnt/recovery

Please note that the filename and location are important. The binary blob must be named dt-blob.bin (all lowercase), and it must be placed in the root directory of the first partition on the SD card. Once you have rebooted the Pi (to activate the new device tree configuration) you can test the flash with the following simple script: import picamera with picamera.PiCamera() as camera: camera.flash_mode = 'on' camera.capture('foo.jpg')

You should see your flash LED blink twice during the execution of the script.

Warning The GPIOs only have a limited current drive which is insufficient for powering the sort of LEDs typically used as flashes in mobile phones. You will require a suitable drive circuit to power such devices, or risk damaging your Pi. One developer on the Pi forums notes: For reference, the flash driver chips we have used on mobile phones will often drive up to 500mA into the LED. If you’re aiming for that, then please think about your power supply too. If you wish to experiment with the flash driver without attaching anything to the GPIO pins, you can also reconfigure the camera’s own LED to act as the flash LED. Obviously this is no good for actual flash photography but it can demonstrate whether your configuration is good. In this case you need not add anything to the pin_config section (the camera’s LED pin is already defined to use pull down termination), but you do need to set CAMERA_0_LED to absent, and FLASH_0_ENABLE to the old CAMERA_0_LED definition (this will be pin 5 in the case of pins_rev1 and pins_rev2 , and pin 32 in the case of everything else). For example, change: pin_define@CAMERA_0_LED { type = "internal"; number = <5>; }; pin_define@FLASH_0_ENABLE { type = "absent"; };

into this: pin_define@CAMERA_0_LED { type = "absent"; }; pin_define@FLASH_0_ENABLE { type = "internal"; number = <5>; };

After compiling and installing the device tree blob according to the instructions above, and rebooting the Pi, you should find the camera LED now acts as a flash LED with the Python script above.

Related Documents

Batch
October 2019 43
Batch-17
August 2019 48
Batch-9
August 2019 32
Batch Toolbox
June 2020 20
Fileaid - Batch
July 2020 23
Yamen Batch
June 2020 37

More Documents from "Iin Mochamad Solihin"