Sign in Join
Wiki copytemporary

Raspberry Pi : BerryClip: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: Raspberry Pi : BerryClip

OldNewLine
1+# Raspberry Pi : BerryClip
2+
3+![](/wiki-images/3/3f/Pi_berryclip.png)
4+
5+The BerryClip 6 LED Board is a add-on board for the Raspberry Pi. It consists of a PCB populated with 6 coloured LEDs, one switch and one buzzer. It is easy to attach to the Pi’s GPIO header.
6+
7+## Hardware
8+
9+![](/wiki-images/b/bd/Pi_berryclip_sch.png)
10+
11+The following list shows the mapping between the components, the header pins and the GPIO references :
12+
13+- LED 1 - Pin 7 - GPIO4
14+- LED 2 - Pin 11 - GPIO17
15+- LED 3 - Pin 15 - GPIO22
16+- LED 4 - Pin 19 - GPIO10
17+- LED 5 - Pin 21 - GPIO9
18+- LED 6 - Pin 23 - GPIO11
19+- Buzzer - Pin 24 - GPIO8
20+- Switch - Pin 26 - GPIO7
21+
22+| GPIO | Pin | | Pin | GPIO |
23+|--------|-----|-----|-----|--------|
24+| GPIO7 | 26 | | 25 | GND |
25+| GPIO8 | 24 | | 23 | GPIO11 |
26+| GPIO25 | 22 | | 21 | GPIO9 |
27+| GND | 20 | | 19 | GPIO10 |
28+| GPIO24 | 18 | | 17 |  +3.3V |
29+| GPIO23 | 16 | | 15 | GPIO22 |
30+| GND | 14 | | 13 | GPIO27 |
31+| GPIO18 | 12 | | 11 | GPIO17 |
32+| GPIO15 | 10 | | 9 | GND |
33+| GPIO14 | 8 | | 7 | GPIO4 |
34+| GND | 6 | | 5 | GPIO3 |
35+|  +5V | 4 | | 3 | GPIO2 |
36+|  +5V | 2 | | 1 |  +3.3V |
37+
38+## Software
39+
40+![](/wiki-images/c/c5/Pi_berryclip_uml.png)
41+
42+The following example lists a program that controls berryClip.
43+
44+The code requires to be run as root (eg. sudo ./berryclipdemo).
45+
46+| Level | | Unit |
47+|----|----|----|
48+| 1 | User interface, Application level | unit1.pas, unit1.lfm, berryclipdemo.lpr |
49+| 2 | Board level | uberryclip.pas |
50+| 3 | | uraspberrypi.pas |
51+| 4 | I/O driver | pi_io_unit.pas |
52+
53+### User interface
54+
55+![](/wiki-images/e/e5/Pi_berryclipdemo.png)
56+
57+The user interface consists of the buttons that control the LEDs and buzzer. In addition, the switch status is displayed on LED. LEDs state on the circuit board is displayed with the LEDs on the form. The berryclipdemo program uses the following components: [[TApplicationProperties]], [[TButton]], [[TShape]] and [[TToggleBox]].
58+
59+#### unit1.pas
60+
61+``` pascal
62+unit Unit1;
63+
64+{$mode objfpc}{$H+}
65+
66+interface
67+
68+uses
69+ Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
70+ ExtCtrls, uberryclip;
71+
72+type
73+
74+ { TForm1 }
75+
76+ TForm1 = class(TForm)
77+ ApplicationProperties1: TApplicationProperties;
78+ Button1: TButton;
79+ Led4ToggleBox: TToggleBox;
80+ Led6ToggleBox: TToggleBox;
81+ Led2ToggleBox: TToggleBox;
82+ Led3ToggleBox: TToggleBox;
83+ Led1ToggleBox: TToggleBox;
84+ Led5ToggleBox: TToggleBox;
85+ Shape1: TShape;
86+ Shape2: TShape;
87+ Shape3: TShape;
88+ Shape4: TShape;
89+ Shape5: TShape;
90+ Shape6: TShape;
91+ Shape7: TShape;
92+ procedure ApplicationProperties1Idle(Sender: TObject; var Done: Boolean);
93+ procedure Button1MouseDown(Sender: TObject; Button: TMouseButton;
94+ Shift: TShiftState; X, Y: Integer);
95+ procedure Button1MouseUp(Sender: TObject; Button: TMouseButton;
96+ Shift: TShiftState; X, Y: Integer);
97+ procedure FormCreate(Sender: TObject);
98+ procedure FormDestroy(Sender: TObject);
99+ procedure Led1ToggleBoxChange(Sender: TObject);
100+ procedure Led2ToggleBoxChange(Sender: TObject);
101+ procedure Led3ToggleBoxChange(Sender: TObject);
102+ procedure Led4ToggleBoxChange(Sender: TObject);
103+ procedure Led5ToggleBoxChange(Sender: TObject);
104+ procedure Led6ToggleBoxChange(Sender: TObject);
105+ private
106+ { private declarations }
107+ Berry_Clip:TBerryClip;
108+ public
109+ { public declarations }
110+ end;
111+
112+var
113+ Form1: TForm1;
114+
115+implementation
116+
117+{$R *.lfm}
118+
119+{ TForm1 }
120+
121+procedure TForm1.ApplicationProperties1Idle(Sender: TObject; var Done: Boolean);
122+begin
123+ if Berry_Clip.ReadSwitch
124+ then shape7.Brush.Color:=clBlack
125+ else shape7.Brush.Color:=clWhite;
126+end;
127+
128+procedure TForm1.Button1MouseDown(Sender: TObject; Button: TMouseButton;
129+ Shift: TShiftState; X, Y: Integer);
130+begin
131+ Berry_Clip.SetBuzzerOn;
132+end;
133+
134+procedure TForm1.Button1MouseUp(Sender: TObject; Button: TMouseButton;
135+ Shift: TShiftState; X, Y: Integer);
136+begin
137+ Berry_Clip.SetBuzzerOff;
138+end;
139+
140+procedure TForm1.FormCreate(Sender: TObject);
141+begin
142+ Berry_Clip := TBerryClip.Create;
143+end;
144+
145+procedure TForm1.FormDestroy(Sender: TObject);
146+begin
147+ Berry_Clip.Free;
148+end;
149+
150+procedure TForm1.Led1ToggleBoxChange(Sender: TObject);
151+begin
152+ if Led1ToggleBox.Checked then
153+ begin
154+ Berry_Clip.SetLedOn(1);
155+ shape1.Brush.Color:=clRed ;
156+ end
157+ else
158+ begin
159+ Berry_Clip.SetLedOff(1);
160+ shape1.Brush.Color:=clWhite;
161+ end;
162+end;
163+
164+procedure TForm1.Led2ToggleBoxChange(Sender: TObject);
165+begin
166+ if Led2ToggleBox.Checked then
167+ begin
168+ Berry_Clip.SetLedOn(2);
169+ shape2.Brush.Color:=clRed;
170+ end
171+ else
172+ begin
173+ Berry_Clip.SetLedOff(2);
174+ shape2.Brush.Color:=clWhite;
175+ end;
176+end;
177+
178+procedure TForm1.Led3ToggleBoxChange(Sender: TObject);
179+begin
180+ if Led3ToggleBox.Checked then
181+ begin
182+ Berry_Clip.SetLedOn(3);
183+ shape3.Brush.Color:=clYellow;
184+ end
185+ else
186+ begin
187+ Berry_Clip.SetLedOff(3);
188+ shape3.Brush.Color:=clWhite;
189+ end;
190+end;
191+
192+procedure TForm1.Led4ToggleBoxChange(Sender: TObject);
193+begin
194+ if Led4ToggleBox.Checked then
195+ begin
196+ Berry_Clip.SetLedOn(4);
197+ shape4.Brush.Color:=clYellow;
198+ end
199+ else
200+ begin
201+ Berry_Clip.SetLedOff(4);
202+ shape4.Brush.Color:=clWhite;
203+ end;
204+end;
205+
206+procedure TForm1.Led5ToggleBoxChange(Sender: TObject);
207+begin
208+ if Led5ToggleBox.Checked then
209+ begin
210+ Berry_Clip.SetLedOn(5);
211+ shape5.Brush.Color:=clGreen;
212+ end
213+ else
214+ begin
215+ Berry_Clip.SetLedOff(5);
216+ shape5.Brush.Color:=clWhite;
217+ end;
218+end;
219+
220+procedure TForm1.Led6ToggleBoxChange(Sender: TObject);
221+begin
222+ if Led6ToggleBox.Checked then
223+ begin
224+ Berry_Clip.SetLedOn(6);
225+ shape6.Brush.Color:=clGreen;
226+ end
227+ else
228+ begin
229+ Berry_Clip.SetLedOff(6);
230+ shape6.Brush.Color:=clWhite;
231+ end;
232+end;
233+
234+end.
235+```
236+
237+#### unit1.lfm
238+
239+``` pascal
240+object Form1: TForm1
241+ Left = 269
242+ Height = 184
243+ Top = 175
244+ Width = 176
245+ Caption = 'BerryClip'
246+ ClientHeight = 184
247+ ClientWidth = 176
248+ OnCreate = FormCreate
249+ OnDestroy = FormDestroy
250+ object Led2ToggleBox: TToggleBox
251+ Left = 8
252+ Height = 24
253+ Top = 32
254+ Width = 128
255+ Caption = 'Led2ToggleBox'
256+ OnChange = Led2ToggleBoxChange
257+ TabOrder = 0
258+ end
259+ object Led1ToggleBox: TToggleBox
260+ Left = 8
261+ Height = 24
262+ Top = 8
263+ Width = 128
264+ Caption = 'Led1ToggleBox'
265+ OnChange = Led1ToggleBoxChange
266+ TabOrder = 1
267+ end
268+ object Led3ToggleBox: TToggleBox
269+ Left = 8
270+ Height = 24
271+ Top = 56
272+ Width = 128
273+ Caption = 'Led3ToggleBox'
274+ OnChange = Led3ToggleBoxChange
275+ TabOrder = 2
276+ end
277+ object Led4ToggleBox: TToggleBox
278+ Left = 8
279+ Height = 24
280+ Top = 80
281+ Width = 128
282+ Caption = 'Led4ToggleBox'
283+ OnChange = Led4ToggleBoxChange
284+ TabOrder = 3
285+ end
286+ object Led5ToggleBox: TToggleBox
287+ Left = 8
288+ Height = 24
289+ Top = 104
290+ Width = 128
291+ Caption = 'Led5ToggleBox'
292+ OnChange = Led5ToggleBoxChange
293+ TabOrder = 4
294+ end
295+ object Led6ToggleBox: TToggleBox
296+ Left = 8
297+ Height = 24
298+ Top = 128
299+ Width = 128
300+ Caption = 'Led6ToggleBox'
301+ OnChange = Led6ToggleBoxChange
302+ TabOrder = 5
303+ end
304+ object Shape1: TShape
305+ Left = 144
306+ Height = 18
307+ Top = 12
308+ Width = 16
309+ Shape = stCircle
310+ end
311+ object Shape2: TShape
312+ Left = 144
313+ Height = 18
314+ Top = 34
315+ Width = 16
316+ Shape = stCircle
317+ end
318+ object Shape3: TShape
319+ Left = 144
320+ Height = 18
321+ Top = 58
322+ Width = 16
323+ Shape = stCircle
324+ end
325+ object Shape4: TShape
326+ Left = 144
327+ Height = 18
328+ Top = 82
329+ Width = 16
330+ Shape = stCircle
331+ end
332+ object Shape5: TShape
333+ Left = 144
334+ Height = 18
335+ Top = 106
336+ Width = 16
337+ Shape = stCircle
338+ end
339+ object Shape6: TShape
340+ Left = 144
341+ Height = 18
342+ Top = 130
343+ Width = 16
344+ Shape = stCircle
345+ end
346+ object Shape7: TShape
347+ Left = 144
348+ Height = 18
349+ Top = 158
350+ Width = 16
351+ Shape = stCircle
352+ end
353+ object Button1: TButton
354+ Left = 8
355+ Height = 25
356+ Top = 151
357+ Width = 64
358+ Caption = 'Buzzer'
359+ OnMouseDown = Button1MouseDown
360+ OnMouseUp = Button1MouseUp
361+ TabOrder = 6
362+ end
363+ object ApplicationProperties1: TApplicationProperties
364+ OnIdle = ApplicationProperties1Idle
365+ left = 72
366+ top = 152
367+ end
368+end
369+```
370+
371+### Main
372+
373+``` pascal
374+program berryclipdemo;
375+
376+{$mode objfpc}{$H+}
377+
378+uses
379+ {$IFDEF UNIX}{$IFDEF UseCThreads}
380+ cthreads,
381+ {$ENDIF}{$ENDIF}
382+ Interfaces, // this includes the LCL widgetset
383+ Forms, Unit1, pi_io_unit, uberryclip, uraspberrypi
384+ { you can add units after this };
385+
386+{$R *.res}
387+
388+begin
389+ RequireDerivedFormResource := True;
390+ Application.Initialize;
391+ Application.CreateForm(TForm1, Form1);
392+ Application.Run;
393+end.
394+```
395+
396+### Board
397+
398+#### uberryclip.pas
399+
400+``` pascal
401+unit uberryclip;
402+
403+{$mode objfpc}{$H+}
404+
405+interface
406+
407+uses
408+ Classes, SysUtils,
409+ uRaspberrypi;
410+type
411+
412+ { TBerryClip }
413+
414+ TBerryClip = class
415+ private
416+ RaspBerryPi : TRaspBerryPi;
417+ public
418+ constructor Create;
419+ procedure SetLedOn( led_no :integer );
420+ procedure SetLedOff( led_no :integer );
421+ procedure SetBuzzerOn;
422+ procedure SetBuzzerOff;
423+ function ReadSwitch:boolean;
424+ destructor Destroy; override;
425+ end;
426+implementation
427+
428+{ TBerryClip }
429+
430+constructor TBerryClip.Create;
431+begin
432+ RaspBerryPi := TRaspBerryPi.Create;
433+ RaspBerryPi.SetGpioPinOutput(GPIO4); // Led 1
434+ RaspBerryPi.SetGpioPinOutput(GPIO9); // Led 2
435+ RaspBerryPi.SetGpioPinOutput(GPIO10);// Led 3
436+ RaspBerryPi.SetGpioPinOutput(GPIO11);// Led 4
437+ RaspBerryPi.SetGpioPinOutput(GPIO17);// Led 5
438+ RaspBerryPi.SetGpioPinOutput(GPIO22);// Led 6
439+ RaspBerryPi.SetGpioPinInput(GPIO7); // Switch
440+ RaspBerryPi.SetGpioPinOutput(GPIO8); // Buzzer
441+end;
442+
443+procedure TBerryClip.SetLedOn(led_no: integer);
444+begin
445+ case led_no of
446+ 1 : RaspBerryPi.SetGpioBit(GPIO4);
447+ 2 : RaspBerryPi.SetGpioBit(GPIO17);
448+ 3 : RaspBerryPi.SetGpioBit(GPIO22);
449+ 4 : RaspBerryPi.SetGpioBit(GPIO10);
450+ 5 : RaspBerryPi.SetGpioBit(GPIO9);
451+ 6 : RaspBerryPi.SetGpioBit(GPIO11);
452+ end;
453+end;
454+
455+procedure TBerryClip.SetLedOff(led_no: integer);
456+begin
457+ case led_no of
458+ 1 : RaspBerryPi.ClearGpioBit(GPIO4);
459+ 2 : RaspBerryPi.ClearGpioBit(GPIO17);
460+ 3 : RaspBerryPi.ClearGpioBit(GPIO22);
461+ 4 : RaspBerryPi.ClearGpioBit(GPIO10);
462+ 5 : RaspBerryPi.ClearGpioBit(GPIO9);
463+ 6 : RaspBerryPi.ClearGpioBit(GPIO11);
464+ end;
465+
466+end;
467+
468+procedure TBerryClip.SetBuzzerOn;
469+begin
470+ RaspBerryPi.SetGpioBit(GPIO8);
471+end;
472+
473+procedure TBerryClip.SetBuzzerOff;
474+begin
475+ RaspBerryPi.ClearGpioBit(GPIO8);
476+end;
477+
478+function TBerryClip.ReadSwitch: boolean;
479+begin
480+ result := RaspBerryPi.GetGpioBit(GPIO7);
481+end;
482+
483+destructor TBerryClip.Destroy;
484+begin
485+ RaspBerryPi.Free;
486+ inherited Destroy;
487+end;
488+
489+end.
490+```
491+
492+#### uraspberrypi.pas
493+
494+``` pascal
495+unit uraspberrypi;
496+
497+{$mode objfpc}{$H+}
498+
499+interface
500+
501+uses
502+ Classes, SysUtils, pi_io_unit, dialogs;
503+
504+const
505+
506+ GPIO4 = 4;
507+ GPIO7 = 7;
508+ GPIO8 = 8;
509+ GPIO9 = 9;
510+ GPIO10= 10;
511+ GPIO11= 11;
512+ GPIO17= 17;
513+ GPIO22= 22;
514+
515+type
516+
517+ { TRaspBerryPi }
518+
519+ TRaspBerryPi = class
520+ private
521+ io_port: T_IO_Port;
522+ public
523+ constructor Create;
524+ procedure ClearGpioBit(no:byte);
525+ function GetGpioBit(no:byte):boolean;
526+ procedure SetGpioBit(no:byte);
527+ procedure SetGpioPinInput( no:byte);
528+ procedure SetGpioPinOutput( no:byte);
529+ destructor Destroy; override;
530+ end;
531+
532+implementation
533+
534+{ TRaspBerryPi }
535+
536+constructor TRaspBerryPi.Create;
537+begin
538+ if not MapIo
539+ then ShowMessage('Error mapping gpio')
540+ else
541+ begin
542+ io_port := T_IO_Port.Create;
543+ io_port.f_gpio := CreatePort(GPIO_BASE);
544+ end ;
545+end;
546+
547+procedure TRaspBerryPi.ClearGpioBit(no: byte);
548+begin
549+ io_port.ClearBit(no);
550+end;
551+
552+function TRaspBerryPi.GetGpioBit(no: byte): boolean;
553+begin
554+ result := io_port.GetBit(no);
555+end;
556+
557+procedure TRaspBerryPi.SetGpioBit(no: byte);
558+begin
559+ io_port.SetBit(no);
560+end;
561+
562+procedure TRaspBerryPi.SetGpioPinInput(no: byte);
563+begin
564+ io_port.SetPinMode(no,INPUT);
565+end;
566+
567+procedure TRaspBerryPi.SetGpioPinOutput(no: byte);
568+begin
569+ io_port.SetPinMode(no,OUTPUT);
570+end;
571+
572+destructor TRaspBerryPi.Destroy;
573+begin
574+ io_port.ClearBit(GPIO4);
575+ io_port.ClearBit(GPIO9);
576+ io_port.ClearBit(GPIO10);
577+ io_port.ClearBit(GPIO11);
578+ io_port.ClearBit(GPIO17);
579+ io_port.ClearBit(GPIO22);
580+ io_port.ClearBit(GPIO8);
581+ UnMapIo(io_port);
582+ io_port.free;
583+ inherited Destroy;
584+end;
585+
586+end.
587+```
588+
589+#### pi_io_unit.pas
590+
591+``` pascal
592+unit pi_io_unit;
593+// This code is tested only RPI2B Processor
594+{$mode objfpc}{$H+}
595+
596+interface
597+
598+uses
599+ Classes, SysUtils, Unix, BaseUnix;
600+
601+const
602+ BCM2709_PBASE= $3F000000; // Peripheral Base in Bytes (RPI2B Processor)
603+ // BCM2708_PBASE= $20000000; // Peripheral Base (maybe RPI1 )
604+ REG_GPIO = BCM2709_PBASE div $1000; // $3F000 ;
605+ PAGE_SIZE = $1000;
606+
607+ GPIO_BASE = (REG_GPIO + $200);
608+
609+ INPUT = 0;
610+ OUTPUT = 1;
611+
612+ GPSET = $1C; // GPIO Pin Output Set
613+ GPCLR = $28; // GPIO Pin Output Clear
614+ GPLEV = $34; // GPIO Pin Level
615+
616+type
617+
618+ { T_IO_Port }
619+
620+ T_IO_Port = class
621+ private
622+ public
623+ f_gpio: PLongWord;
624+ procedure SetPinMode(a_io_pin, a_mode: byte);
625+ function GetBit(a_io_pin : byte):boolean;inline;
626+ procedure ClearBit(a_io_pin : byte);inline;
627+ procedure SetBit(a_io_pin : byte);inline;
628+ end;
629+
630+ function MapIo:boolean;// creates io mapping
631+ procedure UnMapIo(a_Map: T_IO_Port);// close io
632+ function CreatePort(PortGpio: LongWord): PLongWord;
633+
634+implementation
635+
636+var
637+ fd: integer;// /dev/mem file handle
638+
639+function MapIo: boolean;
640+begin
641+ result := true;
642+ fd := fpopen('/dev/mem', O_RdWr or O_Sync);
643+ if fd < 0 then result := false; // unsuccessful mapping
644+end;
645+
646+procedure UnMapIo( a_Map: T_IO_Port);
647+begin
648+ if a_Map.f_gpio <> nil then
649+ begin
650+ fpMUnmap(a_Map.f_gpio, PAGE_SIZE);
651+ a_Map.f_gpio := nil;
652+ end;
653+end;
654+
655+function CreatePort(PortGpio: LongWord): PLongWord;
656+begin
657+ result := FpMmap(nil, PAGE_SIZE, PROT_READ or PROT_WRITE, MAP_SHARED, fd, PortGpio);
658+end;
659+
660+procedure T_IO_Port.SetPinMode(a_io_pin, a_mode: byte);
661+var
662+ fSel, shift : byte;
663+ iof : PLongWord;
664+begin
665+ fSel := (a_io_pin div $A)*4 ;
666+ shift := (a_io_pin mod $A)*3 ;
667+ iof := Pointer(LongWord(Self.f_gpio)+fSel);
668+ case a_mode of
669+ INPUT : iof^ := iof^ and ($FFFFFFFF - (7 shl shift));
670+ OUTPUT : iof^ := iof^ and ($FFFFFFFF - (7 shl shift)) or (1 shl shift);
671+ end;
672+end;
673+
674+procedure T_IO_Port.SetBit(a_io_pin : byte);
675+var
676+ iof : PLongWord;
677+begin
678+ iof := Pointer(LongWord(Self.f_gpio) + GPSET + (a_io_pin shr 5) shl 2);
679+ iof^ := 1 shl a_io_pin;
680+end;
681+
682+procedure T_IO_Port.ClearBit(a_io_pin : byte);
683+var
684+ iof : PLongWord;
685+begin
686+ iof := Pointer(LongWord(Self.f_gpio) + GPCLR + (a_io_pin shr 5) shl 2);
687+ iof^ := 1 shl a_io_pin;
688+end;
689+
690+function T_IO_Port.GetBit(a_io_pin : byte):boolean;
691+var
692+ iof : PLongWord;
693+begin
694+ result := true;
695+ iof := Pointer(LongWord(Self.f_gpio) + GPLEV + (a_io_pin shr 5) shl 2);
696+ if (iof^ and (1 shl a_io_pin)) = 0 then result := false;
697+end;
698+end.
699+```
700+
701+---
702+*From the Free Pascal wiki, page "Raspberry Pi : BerryClip", as it stood on 2020-02-23 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history