D E L P H I, L A Z A R U S, O X Y G E N E, S M A R T M O B I L E, A N D P A S C AL R E L A T E D L A N G U A G E S A N D R O I D, I O S, M A C , W I N D O W S & L I N U X
BLAISE BL AISE PASCAL PASCAL MAGAZINE 49 49
MAGAZ I N NE CA L
S P A E S
2015
I
A
L B
E N C R Y P T I O N I N P R A C T I C E - B Y A N D R E A THALES OF MILETUS - A PRE-SOCRATIC GREEK PHILOSOPHER -
FOR
RAIMON DI BY ED IT OR
Fast Reports
MAPPING USING DELPHI - BY PETER VAN DER SMAN KWANTUM COMPUTIN G - B must Y ED TOR Reporting beIFast! FAST REPOR T S V C L ( 4 )DELPHI I N A NTO U T DELPHI S H E L L -/ B Y J O H NPASCAL KUIP ER OVERVIEW BLAISE S T A R T W I T H A R D U I N O P R O G R A M M I N G V 3 . 1 - B Y M A X K L E I N E R
(HISTORY)
DRAG AND DROP EXPLAINED LAZARUS A R D U I N OFOR : T HYOU E V IFOR SUIN O P R O J EAN C TD- DELPHI PART 2 VAN C O L L E C T D A T A A N D W OBY R KMICHAEL WITH IT I NCANNEYT DELPHI
B Y B O I PACKAGE AN MITOV THE TMS LCL HW PACK FOR RASPBERRY PI OPEN-SOURCE
LOG, DEBU G AND AUDI T T HE KBMM W WAY BY BRUNO FIERENS
KIM MADS EN TFRAMESTAND VERSION 1.1 RELEASED:B Y WHAT'S NEW!
BY ANDREA MAGNI
THE QUEENS PUZZLE PROGRAMMING DESCRIPTION BY DAVID DIRKSE
INTERNET OF THINGS WITH ESP8266 AND VISUINO BY BOIAN MITOV
BLAISE BLAI SE PASCAL PASCAL MAGAZINE 49 D E L P H I, L A Z A R U S, S M A R T M A N D P A S C A L R E L A T E D F O R A N D R O I D, I O S, M A C, W I N
O B I L L A N D O W S
E S T U D G U A G & L I N U X
I E
O, S
CONTENTS NR1 2016 ARTICLES OVERVIEW DELPHI TO DELPHI / BLAISE PASCAL (HISTORY) PAGE 4 /5
DRAG AND DROP EXPLAINED FOR YOU FOR LAZARU S AND DELPHI BY MICHAEL VAN CANNEYT PAGE 9
THE TMS LCL HW PACK FOR RASPBERRY PI OPEN-SOURCE PACKAGE BY BRUNO FIERENS PAGE 31
TFRAMESTAND VERSION 1.1 RELEASED: WHAT'S NEW! BY ANDREA MAGNI PAGE 6
THE QUEENS PUZZLE PROGRAMMING DESCRIPTION BY DAVID DIRKSE PAGE 37
INTERNET OF THINGS WITH ESP8266 AND VISUINO BY BOIAN MITOV PAGE 15
productivity software buiding blocks
L MAGAZ I N E A C S
P A
E
S
2015
I
A
L B
FOR
Fast Reports Reporting must be Fast!
Advertisers Barnsten PAGE 30 COMPONENTS 4 DEVELOPERS PAGE 40 FASTREPORT PAGE 14 UPSCENE PAGE 36 MITOV SOFTWARE PAGE 28
2
Publisher: Foundation for Supporting the Pascal Programming Language in collaboration with the Dutch Pascal User Group (Pascal Gebruikers Groep) © Stichting Ondersteuning Programmeertaal Pascal
Issue Nr 1 2016 BLAISE PASCAL MAGAZINE
BLAISE BLAI SE PASCAL PASCAL MAGAZINE 49 D E L P H I, L A Z A R U S, S M A R T M A N D P A S C A L R E L A T E D F O R A N D R O I D, I O S, M A C, W I N
O B I L L A N D O W S
E S T U D G U A G & L I N U X
I E
O, S
CONTENTS NR1 2016 ARTICLES OVERVIEW DELPHI TO DELPHI / BLAISE PASCAL (HISTORY) PAGE 4 /5
DRAG AND DROP EXPLAINED FOR YOU FOR LAZARU S AND DELPHI BY MICHAEL VAN CANNEYT PAGE 9
THE TMS LCL HW PACK FOR RASPBERRY PI OPEN-SOURCE PACKAGE BY BRUNO FIERENS PAGE 31
TFRAMESTAND VERSION 1.1 RELEASED: WHAT'S NEW! BY ANDREA MAGNI PAGE 6
THE QUEENS PUZZLE PROGRAMMING DESCRIPTION BY DAVID DIRKSE PAGE 37
INTERNET OF THINGS WITH ESP8266 AND VISUINO BY BOIAN MITOV PAGE 15
productivity software buiding blocks
L MAGAZ I N E A C S
P A
E
S
2015
I
A
L B
FOR
Fast Reports Reporting must be Fast!
Advertisers Barnsten PAGE 30 COMPONENTS 4 DEVELOPERS PAGE 40 FASTREPORT PAGE 14 UPSCENE PAGE 36 MITOV SOFTWARE PAGE 28
2
Publisher: Foundation for Supporting the Pascal Programming Language in collaboration with the Dutch Pascal User Group (Pascal Gebruikers Groep) © Stichting Ondersteuning Programmeertaal Pascal
Issue Nr 1 2016 BLAISE PASCAL MAGAZINE
Stephen Ball http://delphiaball.co.uk @DelphiABall
Peter Bijlsma -Editor peter @ blaisepasca blaisepascal.eu l.eu
Dmitry Boyarintsev
Michaël Van Canneyt, michael @ freepascal freepascal.org .org
Marco Cantù www.marcocantu.com marco.cantu marco.cant u @ gmail.com gmail.com
David Dirkse www.davdata.nl E-mail: David @ davdata.nl
Benno Evers b.evers @ everscustomtechnology.nl
Bruno Fierens Primož Gabrijelčič www.tmssoftware.com www. gabrijelcic.org c.org m bruno.fierens bruno.fier ens @ tmssoftware.c tmssoftware.co o m primoz @ gabrijelci
Fikret Hasovic fhasovic @ yahoo.com
Cary Jensen www.jensendatasystems.com http://caryjensen.blogspot.nl
John Kuiper john_kuiper @ kpnmail.nl
Wagner R. Landgraf wagner @ tmssoftware.com
Andrea Magni www.andreamagni.eu
[email protected] www.andreamagni.eu/wp
dmitry.living @ gmail.com
Max Kleiner www.softwareschule.ch max @ kleiner.com kleiner.com Kim Madsen www.component4developers
Boian Mitov mi tov@ mito v@mi mito tov. v.co com m
Jeremy North
jeremy.north @ gmail.com
Detlef Overbeek - Editor in Chief www.blaisepascal.eu editor @ blaisepascal.eu
Howard Page Clark hdpc @ talktalk.net
Andrea Raimondi andrea.raimondi @ gmail.com
Wim Van Ingen Schenau -Editor wisone @ xs4all.nl
Peter van der Sman sman @ prisman.nl
Rik Smit rik @ blaisepascal.eu
Bob Swart www.eBob42.com Bob @ eBob42.com
B.J. Rao
[email protected]
Daniele Teti www.danieleteti.it d.teti @ bittime.it
Anton Vogelaar ajv @ vogelaar-electronics.com
Siegfried Zuhr siegfried @ zuhr.nl
Authors - Christian name in alphabethical order A Andrea Raimondi , B Stephen Ball, Peter Bijlsma, Dmitry Boyarintsev C Michaël Van Canneyt, Marco Cantù, D David Dirkse, Daniele Teti F Bruno Fierens G Primož Gabrijelčič, Mattias Gaertner H Fikret Hasovic J Cary Jensen
L K M N O P S Z
Wagner R. Landgraf, Sergey Lyubeznyy Max Kleiner Kim Madsen, Felipe Monteiro de Cavalho Jeremy North, Inoussa Ouedraogo Howard Page-Clark, Rik Smit, Bob Swart, Siegfried Zuhr
Editor - in - chief
Detlef D. Overbeek, Netherlands Tel.: +31 (0)30 890.66.44 / Mobile: +31 (0)6 21.23.62.68 News and Press Releases email only to
[email protected] Editors
Peter Bijlsma, W. (Wim) van Ingen Schenau, Rik Smit, Correctors
Howard Page-Clark, James D. Duff Trademarks
All trademarks used are acknowledged as the property of their respective owners. Caveat Whilst we endeavour to ensure that what is published in the magazine is correct, we cannot accept responsibility for any errors or omissions. If you notice something which may be incorrect, please contact the Editor and we will publish a correction where relevant. Subscriptions ( 2013 prices ) 1: Printed version: subscription € 80.-- Incl. VAT VAT 6 % (including code, code, programs and printed magazine, 10 issues per year excluding postage). 2: Electronic - non printed subscription € 50.-- Incl. VAT VAT 21% (including code, programs and download magazine) Subscriptions can be taken out online at www.blaisepascal.eu or by written order, or by sending an email to
[email protected] u Subscriptions can start at any date. All issues published in the calendar year of the subscription will be sent as well. Subscriptions run 365 days. Subscriptions will not be prolonged without notice. Receipt Receipt of payment will be sent by email. Subscriptions can be paid by sending the payment to: ABN AMRO Bank Account no. 44 19 60 863 or by credit card: Paypal Name: Pro Pascal Foundation-Foundation for Supporting the Pascal Programming Language (Stichting Ondersteuning Programeertaal Pascal) IBAN: NL82 ABNA 0441960863 BIC ABNANL2A VAT no.: 81 42 54 147 (Stichting Programmeertaal Pascal) 21.23.62.68 Subscription department Edelstenenbaan 21 / 3402 XA IJsselstein, The Netherlands / Tel.: + 31 (0) 30 890.66.44 / Mobile: + 31 (0) 6 21.23.62.68
[email protected]
Copyright notice All material published in Blaise Pascal is copyright © SOPP Stichting Ondersteuning Programeertaal Pascal unless otherwise noted and may not be copied, distributed or republished without written permission. Authors agree that code associated with their articles will be made available to subscribers after publication by placing it on the website of the PGG for download, and that articles and code will be placed on distributable data storage media. Use of program listings by subscribers for research and study purposes is allowed, but not for commercial purposes. Commercial use of program listings and code is prohibited without the written permission of the author.
Issue Nr 1 2016 BLAISE PASCAL MAGAZINE
3
OVERVIEW OF DELPHI TO DELPHI HISTORY
DELPHI XE8
On February 8, 2006 Borland announced that it was
looking for a buyer for its IDE and database line of products, including Delphi, to concentrate on its ALM line. On November 14, 2006 Borland transferred the development tools group to an independent subsidiary company named CodeGear, CodeGear, instead of selling it. Borland sold CodeGear to Embarcadero Technologies in 2008. Embarcadero retained the CodeGear division created by Borland to identify its tool and database offerings, but identified its own database tools under the DatabaseGear name.
Embarcadero Technologies in 2008. Codegear Delphi 2007. DELPHI 7 released in August 2002
DELPHI released February 14, 1995
The roots of Turbo Pascal v1.0 started in Denmark. Denmark. The first step, step,
in 1981, was the Blue Label Software Pascal Compiler - BLS Pascal Compiler v1.2, copyright 1981 by Poly-Data microcenter ApS, Strandboulvarden Strandboulvar den 63, DK 2100 Copenhagen - written by Anders Hejlsberg for the NASCOM kit computer.
Turbo Pascal
Developer(s) Anders Hejlsberg while Developer(s) working at Borland Operating system CP/M, CP/M-86, DOS, Windows 3.x, Macintosh Platform 8080/Z80, 8085, x86
Lisa - Pascal
was a Pascal implementation for the Apple Lisa workstation. It was an extension of the earlier Apple Pascal for Apple II machines, but generated object code for 68000 processors that had to be linked against the required libraries in the Lisa OS workshop. Lisa Pascal laid the foundation for the development of Clascal and Mac Pascal the first implementations of Object Pascal.
Windows
Niklaus Wirth
Charles Babbage - mathematician conceived of the first programmable computer in the 1830s
born February 15, 1934 He is a Swiss computer scientist, best known for designing several programming languages, including Pascal, and for pioneering several classic topics in software engineering.
Babbage never built his Difference Engine - a mechanical calculator with thousands of parts because of cost overruns and political disagreements, but the inventor passed on plans for its completion, and in 1991, the Science Museum in London actually built it (the printing component was finished in 2000). As suspected, it actually works.
Blaise Pascal (19 June 1623 – 19 August 1662)
was a French mathematician, physicist, inventor, writer and Christian philosopher.
Discovery of America by Columbus Columbus led his three ships - the Nina,
creates the first calculators
the Pinta and the Santa Maria out of the Spanish port of Palos on August 3, 1492. Discovery of Amerca by the Vikings 990 - 1050 Building of Spain 912 and Portugal 800 Building of France 58–52 BC
Decay of the Roman Empire 500 Building of Europe
Archimedes
Mathematician Archimedes of Syracuse was an Ancient Greek mathematician, physicist, engineer engineer,, inventor, and astronomer. He is regarded as one of the leading scientists in classical antiquity. Wikipedia Born: 287 - 212 BC, Syracuse, Italy
Roman Empire 700 BC
Plato in Classical Attic;
428/427 or 424/423 – 348/347 BC) was a philosopher, philosopher, as well as mathematician, in Classical Greece. Euclid Mathematician
Born Mid-4th century BC - 3rd century BC Residence Alexandria, Hellenistic Egypt Fields Mathematics Known for Euclidean geometry / Euclid's Elements Euclidean algorithm Pythagoras Philosopher
Pythagoras of Samos was an Ionian Greek philosopher philosopher,, mathematician, and founder of the religious movement called Pythagoreanism. Born: 571 - 495 BC, Thales Philosopher
Thales of Miletus was a pre-Socratic Greek philosopher from Miletus in Asia Minor and one of the Seven Sages of Greece. Many, most notably Aristotle, regard him as the first philosopher in the Greek tradition. Born: 624 BC - 546
Difference Engine No. 1, portion,1832
DELPHI
The cult of Apollo at Delphi probably dates back to the 700s B . C .,
ISSUE 40
Page 9 WATER CLOCK - CHINA - BEGINNING OF TIME (BC 4000)
Some authors claim that water clocks appeared in China as early as 4000 BC
Babbage Difference Engine No. 2
BLAISE PASCAL WAS THE INVENTOR OF THE MECHANICAL CALCULATOR IN 1642 334 YEARS AGO BLAISE PASCAL (19 June 1623 – 19 August 1662) was a French mathematician, physicist, inventor, writer an d Christian philosopher. He was a child prodigy who was educated by his father. On 23 November 1654, between 10:30 and 12:30 at night, Pascal had an intense religious vision and immediately recorded the experience in a brief note to himself which began: "Fire. God of Abraham, God of Isaac, God of Jacob, not of the philosophers and the scholars..." and concluded by quoting Psalm 119:16: "I will not forget thy word. Amen. " He seems to have carefu lly sewn this document into h is coat and always transferred it when he changed clothes. Following this experience, he began writing influential works on philosophy and theology. His two most famous works date from this period: the Lettres provinciales and the Pensées. Pascal had poor health, especially after his 18th year, and his death came just two months after his 39th birthday.
As Chateaubriand described in his The Genius of Christianity the fascinating author of “Lettres à un provincial and Pensées”. No wonder Jacques Attali, former student of the “Ecole Polytechnique” and the “Ecole Nationale d'Administration, writer and dramatist, economist and convinced believer with strong interest in the life and work of Pascal has rediscovered. In the biography, he not only describes the tragic fate of a child prodigy, an indisputable genius. The man who was thrown back and forth between his love for the truth and his religion, but also dominated the history of half a century in which France intellectual area ruled the world.
Models of pipes to test the vacuous
“There once was a man who, when he was twelve, with sticks and circles created the mathematics, which, when he was sixteen, the cleverest treatise on conic wrote since Antiquity, who, when he was nineteen, a theoretical knowledge applied in a machine, which, when he was twenty-three, formulated the theory of air pressure and thus wiped one of the great mistake s of the old physics of the table. And this at an age when other people are barely aware of their existence, had gone through the whole cycle of human sciences, realized how insignificant they were, and pointed to the religion, which, from that moment until his death at age thirty-nine, despite illness and pain, languages of Bossuet and Racine provided, which could write exceptionally funny but also could argue quite firm, and whom, finally, during the short period between his illnesses in, by abstraction, one of the biggest problems in mathematics managed to solve and wrote down thoughts about God and man. That 'frightening' genius named Blaise Pascal. "
Issue Nr 1 2016 BLAISE PASCAL MAGAZINE
Blaise Pascal was the inventor of the mechanical calculator in the early 17th century. Pascal designed the machine in 1642. He was spurred to it when participating in the burden of arithmetical labor involved in his father's official work as supervisor of taxes at Rouen. First called the Arithmetic Machine, Pascal's Calculator and later Pascaline, his invention was primarily intended as an adding machine which could add and subtract two numbers directly although its description could be extended to a "mechanical calculator with which it was possible to multiply and divide by repetition." Pascal went through 50 prototypes before presenting his first machine to the public in 1645. He dedicated it to Pierre Séguier, the chancellor of France at the time. He built around twenty more machines during the next decade, often improving on his original design. Nine machines have survived the centuries, most of them being on display in European museums. In 1649 a royal privilege, signed by Louis XIV of France, gave him the exclusivity of the design and manufacturing of calculating machines in France.
5
TFRAMESTAND VERSION 1.1 RELEASED: WHAT'S NEW! PAGE 1/3
BY ANDREA MAGNI starter
expert Delphi
INTRODUCTION
In a previous article, published within issue 4546, I have covered the basic functionalit ies of TFrameStand, a FMX component to ease the use of TFrame(s) in FMX applications. Since then I've added a few significant features and this article will cover them. Before proceeding, I wanted to leave you a link ( https://youtu.be/Z6_ZvnCmFCw ) with the replay of my TFrameStand session on CodeRage X, the online Embarcadero conference held on October, 2015. It is a 50 minutes session covering all the basic functionalities of the component. Another resource (italian only) covering the aim and the basics of TFrameStand is an a udio interview I released to delphipodcast.com (by Marco Breveglieri) website ( http://www.delphipodcast.com/episode/6/massi mizzare-user-experience-con-tframestand ).
THE COMPONENT EDITOR
A good design-time support is a great addition to every Delphi component. It can save a lot of time ( thus improving developer's productivity) and make easy some tasks for the developer. The TFrameStand component lets you combine a stand (defined and stored in a TStyleBook) with a TFrame instance . You may want to add here and there animations while showing and/or hiding the framestand and it quickly becomes not so trivial to guess how the final result will look at runtime, since you cannot run animations in the designer. Thanks to Delphi's IDE, design-time editors for the stand ( the Style Designer) and the TFrame ( the Form Designer ) are available but what you really need is a way to easily test the stand' s final behavior , without having to compile and run the application each time you change something.
AVAILABILITY THROUGH GETIT
This is not properly a new feature but a really nice news: TFrameStand is now available through GetIt (Embarcadero's integrated Package Manager )! This means that adding TFrameStand to your IDE now only takes a 2-click install process. Simply look for TFrameStand in GetIt ( IDE → Tools → Get It Package Manager ) and click Install, accept the license agreement and confirm: done! The component will be immediately available in your component palette and properly configured.
The current release (both on GetIt and GitHub) is v.1.1.
6
Issue Nr 1 2016 BLAISE PASCAL MAGAZINE
TFRAMESTAND VERSION 1.1 RELEASED: WHAT'S NEW! PAGE 2/3 AUTOMATIC HIDE DELAY SUPPORT
Still talking about Hide transitions, another common problem was that you had to specify (in an argument of the Hide method) how long the component should wait between the Hide call and the actual hiding of the framestand. This amount of time was needed to accomplish the hide transition (if there were animations tied to the Hide transition, of course) before making the components invisible (and possibly, free them ). This sounded a bit annoying to me because it would tie the code ( the Hide call) to the needs of a specific stand. If you switched the stand, you would have to change the code. This is where the TFrameStand's component editor can help you . In fact, strictly speaking, at the moment it is more a previewer than a real component editor. Simply double-click on a TFrameStand instance at design-time and you will get a form on the screen, where you can select one of the stands you have defined ( if any ), tune some parameters ( like the size of the frame and its Align property ) and test the Show and Hide actions. Obviously there is no easy way to preview one of your actual TFrame instances, so a placeholder frame is provided (j ust to give an idea of where the actual frame will be at runtime). The testbed area provided in the preview form can represent your main form or any parent object you may want to show the framestand in. Consider checking the value of the TestBed.ClipChildren property in order to properly tune your preview. BETTER HIDE MANAGEMENT One of the key features ( especially on mobile side) of the component is the ability to add transitions (animations) in the show/hide phases. There was a problem with v.1.0 because you could call the Hide method of framestand multiple times resulting in a continuous reset of the transition ( and if you do this in an event handler that is called very often, the result is very annoying). Thus, now the component is aware of its state (if there is already a runing transition or not ) and the problem is solved. You can still call multiple times the Hide method but the result will be fine.
Issue Nr 1 2016 BLAISE PASCAL MAGAZINE
Now, v.1.1 solves this by inspecting the stand ( and the frame also) and automatically it determinates how long the Hide animations (if any) will take to finish. So you can simply omit the Delay argument of the Hide call and let TFrameStand use a proper value instead. TACTIONLIST COMMON ACTIONS SUPPORT The concept of CommonActions has been extended and now it is possible to link a TActionList and use it as a repository for CommonActions. This means that you can bind any action-enabled control to a specific Action through TFrameStand. The Action is selected among those in the bound TActionList through a (tunable) naming convention based approach. Some benefits of this approach are that you can use standard TAction mechanisms (such as OnUpdate events) and that it is now easier than ever to keep presentation code apart from application code. The typical scenario for a standard mobile application, can be described like this: a main form, a main datamodule, some frames. Put a TFrameStand and a TActionList on the datamodule and link them together. Implement some actions in the TActionList and then use the new TFrameStand functionality to bind the actions all over your stands and frames. This should help you in keeping your application code in the datamodule ( that can act as the state holder of your application ) and nowhere else, while letting you to bind actions wherever you needed.
7
TFRAMESTAND VERSION 1.1 RELEASED: WHAT'S NEW! PAGE 3/3
DEFAULT PARENT PROPERTY
The last small improvement I added to the component is a new property to let you set the default parent object for the framestands. In v.1.0, if you did not specify a parent in the Show/Use methods, the form owning TFrameStand instance was used. Now, you can set (at design-time) the control to be used as a parent, where not differently specified.
CONCLUSION
About the author Andrea Magni (http://www.andreamagni.eu) is
an italian computer engineer. He is 33 years old and lives near Monza (Milan area) with his wife Marta and his daughter Federica. Andrea is an experienced Delphi developer ( using Delphi since version 2 ) who had the luck to work many years with the best Delphi experts in Italy and has collected experiences on (very) different projects during his activity as a freelance software developer ( 15 years and counting ). Andrea has joined the Embarcadero MVP program since 2014. He also has expertise with web and mobile technologies and embedded systems.
8
This article illustrates the major improvements introduced with v.1.1 of TFrameStand project. Many developers are currently using this component (mostly in mobile applications) an d I have received a good feedback both from the public presentations (live and online) I did and via personal e-mail messages. I am also very happy some people are starting to contribute (providing bugfixes), keep doing it! I already have a couple of additions to implement in the next version and a couple of new demos are coming soon. So stay tuned and follow my blog ( tag TFrameStand: http://www.andreamagni.eu/wp/tag/ tframestand/ ) for the latest news!
Andrea Magni Web: www.andreamagni.eu Blog: www.andreamagni.eu/wp Twitter: @andreamagni82
Issue Nr 1 2016 BLAISE PASCAL MAGAZINE
STARTING WITH DRAG & DROP IN LAZARUS AND DELPHI PAGE 1/5 BY MICHAËL VAN CANNEYT starter
expert
ABSTRACT
In this article we sh ow how to implement drag and drop operations in your application.
procedure TMainForm. HandleDrops( var Msg: tagMSG; var Handled: Boolean) begin ; end
The second method is to drop a TApplicationEvents component on the form, and to assign its OnMessage event handler (It has the same signature as the above HandleDrops procedure). In the HandleDrops message handler, the actual file drop handling must be done. The file drop message can be processed with the DragQueryFile call. This call looks as follows:
INTRODUCTION
Drag and Drop is a common operation in a wellthought of GUI. It makes life for the user easier. It is therefore good to have some knowledge on how to implement drag and drop for simple (or less simple) cases. In this art icle, we'll look at 2 types of Drag&Drop: 1.Files dragged onto your application from a file manager program (such a s file explorer on windows): The expectation of the user is then that the application will open the files if it supports the file format.
function DragQueryFile( Drop: HDROP; FileIndex: UINT; FileName: LPWSTR; cb: UINT): UINT stdcall ; ;
2.Drag and drop between visual elements (controls) in an application. For instance, the user drags selected text to another location; Or drags items from one list to anoth er list. Both kinds of drag&drop must be explicitly enabled an d programmed, and they are handled in a completely different way. Drag and drop is implemented in the same way in Lazarus and Delphi for the second case (drag and drop within an application), but for the first case, the mechanisms are different.
Drag and drop of files in Delphi In Deplhi, Drag&Drop of files must be implemented manually. In the OnCreate event (or OnShow), the DragAcceptFiles call from the WinAPI.ShellAPI unit must be called to notify Windows that the form accepts files. This call looks as follows:
It serves 2 purposes: 1. Retrieve the number of files that was dropped (FileIndex equals $FFFFFFFF). 2. Retrieve the filenames of each of the files: FileIndex (>0) indicates the index of the file. The name of the file will be placed in a buffer, whose size must be reported in cb. Once the files were accepted, windows must be notified that the drop is completed, this happens with the DragFinish routine: Procedure DragFinish( Drop: HDROP); stdcall;
Both calls accept as the first parameter a handle to a drag&drop structure. The Drag&Drop structure handle is passed in the windows message WParam field. The following implementation will retrieve all files, and calls a NewEditor routine for each dropped file. This could be used in for example a small text editor application which - like so many editors - displays each file in a memo on a tab page:
proc edure DragAcceptFiles( Wnd: HWND; Accept : BOOL); stdcall ;
The following code will then enable dropping of files on a form: procedure TMainForm. FormCreate( Sender: TObject); begin DragAcceptFiles( Handle, True); ; end
To actually accept the files, the WM_DROPFILES message that is sent to the application handle must be handled. There are 2 possible options. The first is to assign the Application.OnMessage handler in the OnCreate event handler of the form: procedure TMainForm. FormCreate( Sender: TObject); begin DragAcceptFiles( Handle, True); Application. OnMessage:= HandleDrops ; end
Issue Nr 1 2016 BLAISE PASCAL MAGAZINE
procedure TMainForm. HandleDrops(var Msg: tagMSG; var Handled: Boolean); Var NrFiles, I : Integer; Buffer : Array[0..255] of Char; begin H andled:= Msg Message . = WM_DROPFILES; if not Handled then exit; NrFiles:= D rag Que ry Fil e( M sg. W par am,$FFFFFFFF, Buf fer,256); For I:=0 to NrFiles-1 do
begin
DragQueryFile( Msg. Wparam, I, Buffer,256); NewEditor( StrPas( Buffer)); ; end DragFinish ( Msg. WParam); ; end
9
STARTING WITH DRAG & DROP IN LAZARUS AND DELPHI PAGE 2/5
Figure 1: File drag and drop in action
The end result of this code can be viewed in figure 1 on on this page 3 DRAG AND DROP OF FILES IN LAZARUS
Handling drag and drop of files in Lazarus is quite easy. One property, and one event handler of TForm are involved: AllowDropFiles when this property is set to True, it enables files to be dropped on the form. (When dragging files, the cursor will change shape to indicate this). OnDropFiles This event is invoked when files have been dropped on the form. The event will not be invoked when ’AllowDropFiles’ is set to False when created by the IDE, the event handler looks as follows: procedure TMainForm. FormDropFiles( Sender: TObject; const FileNames: array of String); begin ; end
The FileNames parameter is an array of strings, which contains the full pathnames of all the files that were dropped on the form. What is to be done with the dropped filenames depends on the application. Typically, it will open the file and display the contents. If we repeat the idea of a small text editor application which - like so many editors displays each file in a memo on a tab page, then the following code will open the file and edit it: 10
procedure TMainForm. FormDropFiles( Sender: TObject; const FileNames: array of String); I Integer ; Var : begin // High(FileNames) is the last element in an open array For I:=0 to High( FileNames) do begin
NewEditor( FileNames[ i]);
; end ; end
In the above code, the FileNames array is traversed, and for each file, a new editor is opened. That is all there is to drag&drop of files. In a real-world application, probably the extension of the file would be examined to see if it is a supported file format. 4 SIMPLE DRAG AND DROP WITHIN AN APPLICATION To support drag and drop within an application requires somewhat more properties than file drag and drop. These properties must be set on all the controls that are involved in the drag an drop operation(s). DragMode
This controls how a drag&drop operation is started: When set to dmAutomatic, then a drag&drop is started as soon as the user drags the mouse over the control. If it is set to dmManual, then a drag&drop operation must be started with the StartDrag method. This can be needed for instance to mark the difference between a drag&drop and a docking operation.
Issue Nr 1 2016 BLAISE PASCAL MAGAZINE
STARTING WITH DRAG & DROP IN LAZARUS AND DELPHI PAGE 3/5 The same code can be used for the LBRight listbox. When the user relased the mouse at the end of a drag&drop operation, the OnDragDrop event is triggered. This event has almost the same signature as the DragOver event handler: it doesn't have the Accept parameter. For the left listbox, this means the eventhandler can be coded as follows:
OnStartDrag
This event is called whenever a drag-&-drop operation is started. This will change the cursor to a drag&drop cursor and initiates the other drag&drop events. OnDragOver
This event called when something is dragged over the control. It can be used to indicate whether the dragged item can actually be dropped on this control. OnDragDrop
procedure TMainForm.LBLeftDragDrop( Sender, Source: TObject; X, Y: Integer);
This event is called when something is dropped Var on the control. DragCursor
Cursor to display during the drag&drop operation. DragKind
This can be used to decide whether dragging the mouse starts a drag&drop operation or a docking operation.
LBFrom,LBTO : TListBox;
begin LBFrom:=(Source as TListBox); LBTo:=(Sender as TListBox); If (LBTo=LBFrom) then MoveItemsToIndex(LBTo ,LBTo .GetIndexAtXY(X ,Y ))
else MoveItemsToListBox(LBTo ,LBFrom ,LBTo.GetIndexAtXY(X ,Y ));
Typical use for these events is to implement a end ; drag&drop operation between 2 lists (be it a listview, listbox or tree), or within a single list, to The MoveItemsToIndex and reorder the items in a list. This will be MoveItemsToListbox handle the demonstrated with a small application using reordering of the items and copying of items, two listboxes. Moving the items between the respectively. The X and Y parameters are used listboxes can be done using buttons, but also to determine at what position the items should with drag and drop. The items can also be rebe inserted. That is all there is to it. The ordered in a listbox, again using drag-and-drop. Lazarus application in action can be seen in The demo application has two listboxes ( called figure 2 page 14 . LBLeft and LBRight). Both listboxes must have their DragMode property set to dmAutomatic. To make it more interesting, they have their MultiSelect set to True. For this simple example, the OnStartDrag event will not be used. But the DragOver event will be used. This event has the following parameters: Sender
Is the control that triggered the event (LBLeft in this case). Source
This is normally the control that initiated the Drag&Drop operation ( but it can be manipulated). X,Y
The coordinates of the mouse relative to the control. Accept
A boolean parameter that must be set by the routine to indicate whether a drop on this control is allowed. Knowing this, the OnDragOver event of the LBLeft listbox can be codes as follows to accept drops from itself, or from the right combobox: procedure TMainForm.LBLeftDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
begin Accept:=(Source=LBLeft) or (Source=LBRight);
Figure 2 : Drag and drop in action
5 MORE ADVANCED DRAG AND DROP As shown, drag and drop can be implemented rather easily for simple cases: the source and target control are on the same form, there are only 2 controls, so checking is easy. But when multiple forms are in play, or there are many controls, some of them created dynamically, then the implementation becomes more difficult.
; end
Issue Nr 1 2016 BLAISE PASCAL MAGAZINE
11
STARTING WITH DRAG & DROP IN LAZARUS AND DELPHI PAGE 4/5 How can the Memo, Listview or ListBox Drag&Drop operations are handled internally controls on the secondary forms communicate in the LCL and VCL using a TDragObject class. The LCL and VCL differ somewhat in the to the main form what items are dragged by the descendent objects that they make available, user ? but other than that the mechanisms are For this, a descendent of TDragObject is identical. created which can contain the items that will be The VCL and LCL allow the programmer to dragged. Since all controls show lists of strings, create a custom instance of TDragObject this object will have a property called Items of when the drag operation is started: the type TStrings: OnStartDrag event handler can be used for // For Delphi, the parent class is TDragControlObject this. This instance is then used as the Source TStringsDragObject = Class(TDragObjectEx) parameter of the OnDragOver and private OnDragDrop events, instead of the control FItems: Tstrings; // to keep the items in. that started the drag operation. procedure SetItems(const AValue: Tstrings); Public
By creating a descendent of the TDragObject Constructor Create(AControl : TControl); override; class, it is possible to pass any desired Destructor Destroy; override; information to the event handlers used in the Property Items : TStrings Read FItems Write SetItems; Drag&Drop operation. ; end To demonstrate this, we will extend the listbox example: First of all we'll make it an application with multiple forms: • A form with a listbox (TListBoxForm). • A form with a memo (TMemoForm). • A form with a listview (TListViewForm) • A main form with a listbox, and 3 buttons to create the above secondary forms, as often as the user clicks on the button.
NOTE that the base object for Delphi is named differently than in Lazarus TDragControlObject instead of TDragControlEx.
The constructor with the TControl typed parameter is introduced in different classes. Other than that, the code is identical. The methods of this class are self-explanatory, they just do some memory management.
Each of the forms, when created, first procedure TStringsDragObject.SetItems(const AValue: Tstrings); sets the caption of the form to some begin unique text so the window can be if FItems=AValue then exit; identified by the user. Then it FItems.Assign(AValue); populates the control it has, with ; end some items. NOTE that these secondary forms all contain controls that somehow can constructor TStringsDragObject.Create(AControl : TControl); begin represent a list of strings, which the Create(AControl); inherited user can select. From each of these FItems TStringList := .Create; secondary forms, the user will be ; end able to drag items from the list to the listbox on the main form. destructor TStringsDragObject.Destroy; In the main form, the procedures begin to create a secondary form are FreeAndNil(FItems); quite simple, and look like this: Destroy; inherited ; end procedure TMainForm.BListBoxWindowClick(Sender: TObject); begin With TListBoxForm.Create(Self) do Show; ; end
NOTE that no reference to the created forms is kept: this means that the main form cannot directly check where a drag operation was initiated, and therefor cannot decide whether a drop on the listbox is allowed or not.
12
This object is implemented in a separate unit: dragdroplist, which is used in all forms of the project. An instance of this object can be created in the OnStartDrag event handlers of the listview, listbox and memo controls of the secondary forms. When the object is created, it is filled with the currently selected items in the control. For the ListBoxForm, the OnStartDrag event handler that creates an instance of this class looks as follows:
Issue Nr 1 2016 BLAISE PASCAL MAGAZINE
STARTING WITH DRAG & DROP IN LAZARUS AND DELPHI PAGE 5/5 procedure TListBoxForm.LBItemsStartDrag(Sender: TObject; The biggest part of this routine has in fact var DragObject: TDragObject); Var SDO : TStringsDragObject; I : Integer; begin SDO:=TStringsDragObject.Create(LBItems); DragObject:=SDO; For I:=0 to LBItems.Count-1 do If LBItems.Selected[i] then SDO .Items.Add(LBItems.Items[i ]); ; end
After creating an instance of the TStringDragObject class, its Items property is filled with the selected items from the listbox. Similar code can be created for the listview and memo forms. The start of the drag operation is herewith modified, and now the drop end of the operation must still be handled. For this, the OnDragOver event of the main listbox must be modified, so it checks that the Source parameter is a
little to do with Drag & Drop: The position in the list of the drop is calculated (with some safety checks): that is where the items will be added. Note that for Delphi, the first line must be changed to
L:=LBMain.ItemAtPos(TPOint.Create(X,Y),true);
Once the position is known, all items from the TStringDragObject instance are copied over to the listbox. The final application (in Lazarus) can be seen in figure 3 .
TStringDragObject,
in which case it knows it can accept the items, and therefore a drop is allowed procedure TMainForm. LBMainDragOver(Sender, Source: TObject; X , Y: Integer ; State: TDragState; var Accept: Boolean); begin Accept:= Source is TStringsDragObject; end ;
All that remains to be done, is implementing the actual drop. Here again, the Source parameter will be the TStringDragObject, and this can be used to determine the items that must be added to the listbox: procedure TMainForm.LBMainDragDrop (Sender, Source: TObject; X , Y: Integer); Var I,L : Integer; SDO : TStringsDragObject; begin L:=LBMain.GetIndexAtY(Y); If L=-1 then begin L:=LBMain.Count-1; If L=-1 then L:=0; ; end SDO:=Source as TStringsDragObject; For I:=SDO.Items.Count-1 downto 0 do LBMain.Items.Insert(L,SDO.Items[i ]); ; end
Figure 3 : Extended drag and drop in a ction
Conclusion
This article has shown that Drag&Drop is really easy to imple ment be it from a file manager to a program or inside a program: It makes the operation of the program more intuitive for the use r, so adding Drag&Dr op should be considere d by any Delphi or Lazarus programmer, when it is appropr iate for the functioning of the program . One form of drag&drop has not yet been discussed, and that is dragging from one program to for example the file manager. Exploring this is left for a future contribution.
13
WE CONGRATULATE FASTREPORT WITH THE WINNING OF THE BLAISE PASCAL MAGAZINE1ST PRIZE AWARD 2015 L MAGAZ I N E A C S
IT ALL STARTED WITH AN IDEA.
Fast Reports started their way creating reporting tools in 1998. Back then Michael (CEO) and Alexander (CTO) once had to create components t o integrate for themselves, while working together for a different company. As it turned out - it was a solution to may people's problem. Some time later FastReport became developers' lifesaver. That was the year FastReport VCL was born.
P A
E
S
2015
I
A
L B
FOR
The company started growing: from a tiny office in the basement to wide recognition, certain number of employees, awards, such as “Delphi Product of the Year” and new products (data analysis tool FastCube was released in 2007). Nowadays Fast Reports is an international company known for its state-of-art report ing software applications, libraries and add-ons that guarantee fast reporting for developers of the business software. Fast Reports has a strong team of almost 30 employees all over the world. Having a group of likeminded people helps to excel on every level, whether it's working, creating or traveling. Here are the solutions that Fast Reports is happy to offer to its customers:
Fast Reports Reporting must be Fast! FASTREPORT VCL:
FastReport VCL is an add-on component that allows your application to generate reports quickly and efficiently. FastReport® provides all the tools necessary for developing report s, including a visu al report designer, a reporting core, and a preview window. Also available Lazarus edition. FASTREPORT FMX 2:
FastReport FMX 2 is a Multi-platform report generator for Apple Mac OS X an d Microsoft Windows, compatible with Embarcadero RAD Studio XE (FMX library), F ireMonkey FM3. FASTCUBE FMX, FASTCUBE VCL 2:
FastCube enables you to analyze data and to build summary tables (data slices) as well as create a variety of reports and graphs both easily and instantly. It's a handy tool for the efficient analysis of data arrays.
INTERNET OF THINGS WITH ESP8266 AND VISUINO PAGE 1/15 MEET THE ESP8266. BY BOIAN MITOV Last year I introduced you to visual development for Arduino with Visuino, in a series of 4 articles ending with an article on Ethernet socket communication between Arduino and Delphi application. I also promised to continue with more articles on Internet Of Things, and Arduino to Arduino communication. Since that last article, a lot has happened. The Raspberry Pi Zero made a splash as a $5 microcomputer, and for a good reason. However, while the Raspberry Pi Zero was sealing the spotlight, and the Arduino was dominating the micro controllers, there was something else lurking bellow the surface, and rapidly gaining momentum. Something even bigger, or as it turns out, actually smaller. Meet the ESP8266.
Yes, you heard it right. Not a catchy name, and yet this is probably the biggest thing to happen in the IoT world yet, and it already has made a huge impact. Much like the Japanese companies in the old days, the Chinese companies nowadays tend to have the bad rap of cheap knockoffs. I am not sure what exactly was the day, or the product that changed the perception of Japanese companies from cheap copycats, into superior engineering designers, but as far as I am concerned the ESP8266 appears to be exactly such product for the Chinese industry. This is a genuine chip developed by the Chinese company Espressif, and, as far as I know, it is superior to anything else available. When it was originally introduced in 2014, it came with 80 MHz, 32 bit RISK CPU, 64KiB Instruction RAM, 96KiB Data RAM, option for external flash up to 10MiB, 16 GPIO pins, 1 10-bit ADC, SPI, I2C, I2S, 3 Serial Ports, and most importantly on the chip WiFi, and all this on a single roughly 5x5 mm chip, powered by 3.3V. In essence this was a powerful, single chip, ready to use WiFi enabled, IoT device. Oddly enough the chip was initially marketed in the form of low cost WiFi ESP-01 communication module for Raspberry Pi, and Arduino boards. When I wrote the Ethernet article, I mentioned the ESP8266 module, as one of the ways supported in Visuino, to connect Arduino boards over WiFi. The ESP-01 module is a small board 14.3x24.8 mm with the ESP8266 chip, some flash, and on-board WiFi antenna.
Issue Nr 1 2016 BLAISE PASCAL MAGAZINE
The module was designed to be controlled over serial communication by another board, and to handle all WiFi tasks internally. Being available for less than $2 it rapidl y became the WiFi solution of choice for many Arduino and Raspberry Pi users . What was hidden in the module was that it also was fully programmable, and even had 2 GPIO pins available for general purpose tasks on the board. The ESPRESSIF company also offered an SDK for programming the module. It did not take long before some people noticed, and started programming the module as a cheap WiFi enabled stand alone controller, capable of being powered by a small 3.3V LiIon battery. While this was happening ESPRESSIF released a number of other versions of modules with the ESP8266 chip – ESP-02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 12E, 12F, and 13 . From those probably the most interesting and popular is the ESP-12. The module is similar size to the venerable 01, at 16x24 mm, but packs up to 11 GPIO pins in its E version, 3 serial ports, one ADC, end exposes the SPI and I2C pins, all this again for a price of around $2. This is a very capable stand alone controller with built in WiFi capability. The story does not end here. As I am writing this article, the ESPRESSIF has started shipping beta versions of their new ESP32 chip. The details are still sketchy, but from what is known, it features Dual core 160 MHz processor, ~400KiB RAM, faster WiFi up to 144.4 Mbps, more ADC inputs, over 30 GPI O pins, touch enabled pins, and Bluetooth Low Energy and Classic. The ESP8266 modules were here, and there was SDK for them. The problem was that few people were familiar with the SDK, and it was designed for the more experienced developers. The rest of the community took notice however and jumped to action. One of the ESP8266 projects was a Lua programing for ESP8266 modules. The Lua project also needed an easy way to program the modules, and created a host board with USB connector on it as well as power adapter for 3.3V and all the necessary parts for easy programming the ESP controller.
15
INTERNET OF THINGS WITH ESP8266 AND VISUINO PAGE 2/15 These hosting boards were called NodeMCU, and although a bit more expensive in the $5-$8 range depending on the version, they are currently the easiest way to start with the ESP8266 development. While the Lua group was busy with their development, another group focused on making Arduino library interface for the ESP8266 module, thus in the second part of last year, it became possible to program ESP8266 modules with the Arduino IDE using the same API. It did not take long for me to notice, and to start working on Visuino support for the ESP8266. At present the Visuino has full support for the Digital, Analog pins, of the ESP, the I2C, SPI, Serial, and the WiFi networking.
Since I already promissed to write an article on IoT with Visuino, and the ESP Modules are probably the best option for IoT, I decided to make this article using ESP8266 modules. Most of it can be used with other Arduino compatible boards, but they will require additional hardware for the networking. A simple IoT project is a remote thermostat. We will use 2 NodeMCU modules. We will attach Thermometer to one of the modules, and Relay to the other. The first module will read the temperature and send it over WiFi to the second one, and the second one will control the relay based on temperature. There are many ways we can setup the 2 modules to talk to each other. First we need to decide how they will be connected to the same subnet. They can both connect to existing Hotspot, or one of them can be a hotspot for the other. In this case I will use the second approach, one of them will be a hotspot with SSID “Thermometer”, and the other will connect to it. They also can use many ways to communicate. UDP, TCP/IP Client and Server sockets are all possible options. In this case we will use UDP sockets, but if you prefer, you can modify the project to use TCP/IP.: First we need to prepare the hardware. 1. We will need 2 ESP8266 modules. I used NodeMCU version 0.9. 2. One Maxim DS18B20 Thermometer module. I got my one for about $1 o n eBay. You can use other Thermometer types, but you will need to change a bit the Visuino project with a different thermometer component.
16
3. 4.
One Relay module. I got my one also for about $1 on eBay. 6 Female-Female jumper wires
Next we need to connect the thermometer to one of the ESP8266 modules: Connect 3 jumper wires to the 3 pins of the Thermometer module for the Ground (-)(Black wire), Power(+)(Red wire), and Signal (Yellow wire)
Connect the other end of the Signal wire (The yellow wire on the picture) to the D2 pin of the NodeMCU ESP8266 module:
Connect the other end of the Ground wire (Black wire) to the Ground pin of the NodeMCU ESP8266 module. Connect the other end of the Power(+) wire(Red wire) to the 3.3V pin of the NodeMCU ESP8266 module:
The Thermometer module is ready. Now we need to prepare the Relay module: Connect 3 jumper wires to the 3 pins of the Relay module for the Ground(-)(Black wire), Power(+)(Red wire), and Signal(Yellow wire):
Issue Nr 1 2016 BLAISE PASCAL MAGAZINE
INTERNET OF THINGS WITH ESP8266 AND VISUINO PAGE 3/15
• Connect the other end of the Signal wire (The yellow wire on the picture) to the D2 pin of the second NodeMCU ESP8266 module as we did with the Thermometer module. • Connect the other end of the Ground wire (Black wire) to the Ground pin of the second NodeMCU ESP8266 module. • Connect the other end of the Power(+) wire (Red wire) to the 5V pin of the sec ond NodeMCU ESP8266 module:
For the “Additional Boards Manager URLs”, in the Preferences dialog set one of the following: If you want to use the stable release of the ESP8266 libraries: http://arduino.esp8266.com/stable/ package_esp8266com_index.json If you want to use the latest staging version of the ESP8266 libraries: http://arduino.esp8266.com/staging/ package_esp8266com_index.json
Before we can program the ESP8266 modules, we need to add the ESP8266 boards support in the Arduino IDE. The latest versions of the IDE comes with boards manager that makes it very easy to install support for new boards and their tool chains. Start the Arduino IDE. I recommend you to use version 1.6.7 at present. Avoid version 1.6.6 as there are a lot of critical bugs in it. From the Menu select |File|Preferences|:
Issue Nr 1 2016 BLAISE PASCAL MAGAZINE
17
INTERNET OF THINGS WITH ESP8266 AND VISUINO PAGE 4/15
Click OK. The ESP8266 project is available on github here: https://github.com/ esp8266/Arduino I used the Staging version, however, I had some issues with it, and had to manually get the latest changes with GIT. From the Menu select |Tools|Board:......|Boards Manager...|:
In the text box of the Boards Manager type ESP, then select the “esp8266 by ESP8266 Community ” and click on the Install button:
18
Issue Nr 1 2016 BLAISE PASCAL MAGAZINE
INTERNET OF THINGS WITH ESP8266 AND VISUINO PAGE 5/15
The installation will take some time to download and install all the ESP8266 tools and libraries:
When the installation finishes, clock on the “Close” button:
Issue Nr 1 2016 BLAISE PASCAL MAGAZINE
19
INTERNET OF THINGS WITH ESP8266 AND VISUINO PAGE 6/15
After the installation, you may decide to get the latest files from GIT as I did. If you need to do this, the Arduino by default installs the ESP8266 support in this directory: C:\Users\{USER_NAME}\AppData\Local\ Arduino15\packages\esp8266 You can check out the latest files from github with GIT and then you can use BeyondCompare or other tool to merge the files into C:\Users\{USER_NAME}\AppData\Local \Arduino15\packages\esp8266 directory. Now that the Arduino IDE is ready to program ESP8266 modules, we can start with our project.
From the list select the ESP8266 board that you will use. I have ModeMCU ESP-12, so I selected it:
First we will program the Thermometer module. Start Visuino. To select the type of the ESP8266 board that you will use, click on the button of the Arduino component:
Next we need to set the board as WiFi Hotspot with SSID “Thermometer”. In the Object Inspector, expand the Modules property, then the WiFi sub property, then the AccessPoint sub property. Set the value of the SSID sub property of the AccessPoint, to “Thermometer”:
20
Issue Nr 1 2016 BLAISE PASCAL MAGAZINE
INTERNET OF THINGS WITH ESP8266 AND VISUINO PAGE 7/15
To make sure the Access Point will be on the 200.200.200.X subnet, we need to assign a fixed address. Expand the Config sub property of the AccessPoint property. Set the value of the “Enabled” sub property of the Config to “True”. Set the value of the “IP” sub property to 200.200.200.100:
Next we need to add a UDP socket for the communication. In the Object Inspector, click on the button next to the value of the Sockets sub property of the WiFi:
In the Sockets editor select “UDP Socket”, and then click on the button In the Object Inspector set the value of the “RemotePort” to “8888”:
Issue Nr 1 2016 BLAISE PASCAL MAGAZINE
21
INTERNET OF THINGS WITH ESP8266 AND VISUINO PAGE 8/15 In the Object Inspector, set the value of the “RemoteIPAddress” property to “200.200.200.200” – this is the fixed IP address that we will assign to the other module later on:
The connection is ready. Next we need to add a Thermometer component. In the filter box of the Component Toolbar, type “ther”, then select the “Maxim 1-Wire Thermometer” component:
and drop it in the design area in the center. Connect the “OneWire” output pin of the Thermometer1 component to the “Digital” input pin of the “Digital[ 2 ]” channel of the “NodeMCU ESP-12” component:
The easiest way to send the data is in binary floating point format. For this we will use a structure component with a single floating point binary element to make the UDP packet. In the filter box of the Component Toolbar, type “make”, then select the “Make Structure” component:
And drop it in the design area in the center. Click on the button of the MakeStructure1 component:
In the Elements editor select the “Analog” element, and then click on the button:
22
Issue Nr 1 2016 BLAISE PASCAL MAGAZINE
INTERNET OF THINGS WITH ESP8266 AND VISUINO PAGE 9/15
to add Analog element:
The project can be used as it is, but if you run it it will overwhelm the network with UDP packets, as it will keep sending thermometer readings very fast one after another. It is better to read the thermometer only once a second. The Thermometer component has a “Clock” pin, that can be used to control when the thermometer will perform a reading and send the value to the socket. We will use a Clock Generator component to control the Thermometer. In the filter box of the Component Toolbar, type “clock”, then select the “Clock Generator” component:
Then close the dialog. Connect the “Out” pin of the Thermometer1 component to the “In” pin of the “Elements.Analog1” element of the MakeStructure1 component:
And drop it in the design area in the center. Connect the “Out” pin of the ClockGenerator1 component to the “Clock” pin of the Thermometer1 component:
Connect the “Out” pin of the MakeStructure1 component to the “In” pin of the “Modules.WiFi.Sockets.UDPSocket1” of the “NodeMCU ESP-12” component:
Issue Nr 1 2016 BLAISE PASCAL MAGAZINE
23
INTERNET OF THINGS WITH ESP8266 AND VISUINO PAGE 10/15 The Thermometer project is ready. Now you can click on the ESP8266 code, and open the Arduino IDE:
button, or press F9 to generate the
Connect with USB cable the first NodeMCU module (the one with the Thermometer connected to it) to the computer. In the Arduino IDE from the menu select the type of the board that you have. In my case this is “NodeMCU 0.9 (ESP-12 Module)”:
24
Issue Nr 1 2016 BLAISE PASCAL MAGAZINE
INTERNET OF THINGS WITH ESP8266 AND VISUINO PAGE 11/15 Also from the Arduino IDE menu, select the Serial Port to which the module is connected:
Click on the upload the
button to compile and code to your module:
The Thermometer module is ready. Now we will program the Relay module. Start a new Visuino project, and select the module as we did in the previous project. Next we need to add a remote acces s point to which the module will connect. In the Object Inspector, expand the “Modules” property, then the “WiFi” sub property, then the “AccessPoints” sub property, and click on the button next to its value:
In the AccessPoins editor, select “WiFi Access Point”, and then click on the button to add the access point
Issue Nr 1 2016 BLAISE PASCAL MAGAZINE
25
INTERNET OF THINGS WITH ESP8266 AND VISUINO PAGE 12/15 In the Object Inspector, set the value of the SSID property to “Thermometer”:
In the Object Inspector, expand the “Config” property, and set the value of the “Enabled” sub property to “True”:
In the Object Inspector, set the value of the “IP” sub property to “200.200.200.200”:
This will assign a fixed IP address of 200.200.200.200 for the module. Close the AccessPoints editor. Next we need to add UDP socket for the communication. In the Object Inspector, click on the button next to the value of the “Sockets” sub property of the “WiFi” property
In the Sockets editor add an “UDP Socket” as you did in the previous project. In the Object Inspector set the value of the “Port” property to “8888”: 26
Issue Nr 1 2016 BLAISE PASCAL MAGAZINE
INTERNET OF THINGS WITH ESP8266 AND VISUINO PAGE 13/15
Then close the Sockets editor. The Thermometer module sends the temperature in binary floating point form as a packet. We need to decode it properly. For this we need a “Split Structure” component with “Analog” element in it. In the filter box of the Component Toolbar, type “split”, then select the “Split Structure” component: And drop it in the design area in the center. Click on the button of the SplitStructure1 component:
In the Elements editor select the “Analog” element, and then click on the to add “Analog” element:
button:
Then close the Elements editor. We need to turn on the relay when the temperature reaches above some temperature. For this we can use “Compare Analog Value” component. In the filter box of the Component Toolbar, type “compar”, then select the “Compare Analog Value” component: And drop it in the design area in the center. In the Object Inspector set the value of the “CompareType” property to “ctBigger”:
Issue Nr 1 2016 BLAISE PASCAL MAGAZINE
27
INTERNET OF THINGS WITH ESP8266 AND VISUINO PAGE 14/15 In the Object Inspector set the value of the “Value” property to the temperature in Celsius above which we want to turn the Relay on, as example “20”:
Connect the “Out” pin of the “Modules.WiFi.Sockets.UDPSocket1” of the “NodeMCU ESP-12” component, to the “In” pin of the SplitStructure1 component.
Connect the “Out” pin of the Elements.Analog1 element of the SplitStructure1 component to the “In” pin of the CompareAnalogValue1 component:
Connect the “Out” pin of the CompareAnalogValue1 component to the “Digital” input pin of the “Digital[ 2 ]” channel of the “NodeMCU ESP-12” component:
The Relay project is ready. Now you can click on the button, or press F9 to generate the ESP8266 code, and open the Arduino IDE:
28
Issue Nr 1 2016 BLAISE PASCAL MAGAZINE
INTERNET OF THINGS WITH ESP8266 AND VISUINO PAGE 15/15
Connect with USB cable the second NodeMCU module(the one with the Relay connected to it) to the computer. If necessary in the Arduino IDE, select the module board type, and serial port, as you did for the previous project. Click on the
button to compile and upload the code to your module: You are done. If you power t he two modules, they will automatically connect to each other and if the temperature measured by the module with the thermometer goes above 20 degrees, the second module will turn the relay on. If the temperature drops bellow 20 degrees, the relay module will turn the relay off. CONCLUSION
So far in 5 articles you have learned how to create simple Arduin o projects with Visuino, how to communicate between Arduino and Delphi, over Serial Port, and Ethernet, how to create your own Visuino components, and finally how to program ESP8266 modules to communicate with each other as part of Internet Of Things solution. In the following issues I will continue with even more interesting pr ojects, connecting different type of modules together, as well as integrating them with web servers into the even more exciting world of the Intern et Of Everything.
Issue Nr 10 2015 BLAISE PASCAL MAGAZINE
29
BELGIUM Practicum: Delphi 10 Seattle with VCL and Mobile Development 1-Day Practicum March 3, 2016 - Hote l Ter Elst Edege m (BE) During this session you will start using Delph i 10 Seattle together with pre sentors Pawel Glowacki and Danny Wind. Six differtent top ics are covered this day. Every topic will take ab out one hour. Pawel or Danny will explain more ab out the specific topic and show you some code. After this you will get some time for practices using the training materi als written by Pawel and Danny. Topics this day are: how to build VCL Windows 10 applications integrate with the new Windows 10 API the use of the Parallel Programming Library for responsive applications access to databases using FireDAC create scalable and multitier solutions with DataSnap and REST build and publish apps for the Google Play and iOS AppStore During this Practicum you can bring your own laptop with Del phi 10 Seattle Enterpr ise installed.The sp ecial price of this Practicu m is € 99,-- excl. VAT when you have bought or will buy the 10 Seattle version via Barnsten . Also customers with an active Update Subscription can join this p racticum for € 9 9,00 excl. VAT. Otherwise the price is € 295,00 excl. VAT.
or call: +31 (0)235422227 http://www.barnsten.com/default/development-tools/training/ practicum-delphi-10-seattle-met-vcl-en-mobile-ontwikkeling
NEDERLAND TRAININGEN
Barnsten organise ert in samenwerking met Danny Wind van de Delphi Company diverse Delphi en Fire Monkey trainingen . Het doel van de trainingen is u, als De lphi ontwikkelaa r, snel productief te laten wer ken. Er zijn zowel Essentials als Advanced trainingen en daarmee aanbod voor zowel de beg innende als de ervaren Delph i ontwikkelaar. Tijdens de trainingen maakt u gebrui k van uw eigen laptop met daarop Delphi 10 Seattle inclusi ef InterBase XE7 geïnstalleerd (eventueel trial versie). Datum
Training Locatie Prijs
27-29 januari 17-18 februari 3 maart 11 maart
Delphi Essentials VCL Training = VOLGEBOEKT Delphi Update FireMonkey & Android Practicum: Delphi met VCL en Mobile Ontwikkeling Migratietraining BDE en Unicode (halve dag)
Capelle a/d IJssel Amersfoort Edegem (BE) Amersfoort
€ 1.350,00 € 895,00 € 99,00 € 295,00
or call: +31 (0)235422227 http://www.barnsten.com/nl/development-tools/training
THE TMS LCL HW PACK FOR RASPBERRY PI OPEN-SOURCE PACKAGE
starter
PAGE 1/5
The protocol is described here: https://en.wikipedia.org/wiki /I%C2%B2C. In a nutshell, data is digitally serialized and sent on a bus. By means of an address + read/write instruction, data can be read or written from a master who drives the clock. In this case, the master is the Raspberry Pi.
expert
INTRODUCTION
At TMS software, we have recently published a first version of the free and open-source TMS LCL HW Pack for Raspberry Pi that you can download from: http://www.tmssoftware.com/site/tmslclhwpack.as p. The goal of the TMS LCL HW Pack for Raspberry Pi is to make it very simple to do IO from Pascal SDA applications. One of the things that makes the SCL Raspberry Pi so versatile is its IO capabilit ies, B1 B2 S especially the Raspberry Pi 2 with a 40 pins header that exposes generic GPIO pin s, I2C, UART and SPI Serialized data on the i2c 2-wire bu s. pins.
BN
P
productivity software buiding blocks
Raspberry Pi 2 40 pin header
The generic GPIO pins are pins that can be programmatically configured as digital inputs and outputs. There are 6 such generic GPIO pins for a Raspberry Pi 2.Under programmatic control, you can set a logic 1 or 0 for these pins that translates into a VCC or GND signal on the pin or you can read the voltage VCC or GND on the pin as either 1 or 0. This is useful for digital signals but sadly the Raspberry Pi doesn't offer built-in analog programmable pins like the Arduino does. Next is the i2c bus, which is a two-wire protocol to read & write data on a bus of i2c devices.
Typical connection between i2c master and slaves
The next option is the SPI bus (https://en.wikipedia.org/wiki/ Serial_Peripheral_Interface_Bus ) which is a 4 wire bus protocol also based on master/slave principle where the Raspberry Pi is the master. Along with a device select signal and serial clock, there are two data wires, one for input and one for output.
Typical connection of an SPI master to SPI slaves
31
THE TMS LCL HW PACK FOR RASPBERRY PI PAGE 2/5 THE TOWERS OF HANOI PAGE 2/4 OPEN-SOURCE PACKAGE Finally, the last option on the 40 pin connector is a classic UART or serial port with TX, RX pins to do classic serial port communication. In this article, we'll focus on the i2c and SPI ports. GETTING DEVICES TO EXTEND YOUR RASPBERRY PI
Lots of devices exist that can extend your Raspberry Pi. From off the shelve ICs with i2c or SPI interfaces that you use together with some control circuitry and connect to the Raspberry Pi header to ready-made little boards or extenders from well-known companies such as Adafruit (www.adafruit.com) or Sparkfun (www.sparkfun.com) USING I2C
Each i2c device on the i2c bus has a 7bit address meaning that theoretically 128 devices can be connected. Data is serially transmitted and the clock rate can be selected. 400kbs is a realistic speed that can be used also with devices connected to the Raspberry Pi via a breadboard. Typically, along with the address, data is written or read in blocks of 8 bit. In order to make accessing i2c devices easily accessible from Pascal applications, we have created a base class: TTMSLCLRaspiI2C. This class has property I2CAddress to set the address of the i2c device you want to access and I2CPort to select what I2C port of the Raspberry Pi to use. To make a connection to an i2c device, call the function TTMSLCLRaspiI2C.Open: boolean. To close the connection again, there is the TTMSLCLRaspiI2C.Close function and with TTMSLCLRaspiI2C.Connected: boolean, you can check at all times the connection state. When there is a connection, you can write one byte of data to the device with TTMSLCLRaspiI2C.SetByteRegister and read with TTMSLCLRaspiI2C.GetByteRegister.
ENCAPSULATING I2C DEVICE FUNCTIONALITY
Typically, a useful communication with an i2c device comes down to read & write bytes in the proper and desired sequence to get the device to do something useful. We have therefore created a number of classes that descend from TTMSLCLRaspiI2C and that encapsulate typical setup & communication with commonly used i2c devices: - TTMSLCLAdaQuad7SegLed:
component to control a quad 7 segment LED - TTMSLCLAdaADC12B:
component to read data from a quad analog digital convertor - TTMSLCLADADAC12B:
component to write data to a digital analog convertor - TTMSLCLADADISPL128X32:
component to drive a 128x32 OLED display - TTMSLCLAdaDispl16x2:
component to drive a 16x2 LCD display and read its 5 key inputs - TTMSLCLAdaBarTemp:
component to retrieve temperature & barometric data from a sensor - TTMSLCLAdaI2CIOExpander:
component to control 16 i2c addressed extra GPIO pins - TTMSLCLAda8x8MatrixLed:
component to drive a 8x8 LED matrix
Interface of the base i2c class: TTMSLCLRaspiI2C = class(TComponent)
public constructor Create(AOwner: TComponent); override; function Open: boolean; virtual; function Close: boolean; virtual; function Connected: boolean; function SetByteRegister(RegNo: Integer; Val: Byte): Integer; function GetByteRegister(RegNo: Integer): byte; published property I2CAddress: integer read FI2CAddress write FI2CAddress; property I2CPort: CInt read FI2CPort write FI2CPort; ; end
i2c quad 7 segment LED
i2c 128x32 OLED display
32 productivity software buiding blocks
Issue Nr 1 102016 2015 BLAISE BLAISE PASCAL PASCAL MAGAZINE MAGAZINE
THE TMS LCL HW PACK FOR RASPBERRY PI PAGE 3/5 OPEN-SOURCE PACKAGE At this time, there is one component descending from TTMSLCLRaspiSPI that controls the TTMSLCLAdaFram8KSPI device, an 8K FRAM device.
i2c digital analog convertor
i2c 4 channel analog digital convertor SPI 8k FRAM
Reading and writing in the FRAM (ferroelectric memory that can keep its memory also when not powered) is simple with read & write commands per byte: function WriteByte(Adr: word; val : byte): boolean; function ReadByte(Adr: word; var val: byte): boolean; i2c 16x2 LCD display + 5 key keypad
i2c 8x8 LED array
i2c temperature & barometric sensor
i2c 16 channel GPIO extender
USING SPI The SPI protocol is similar to i2c and is encapsulated in the class TTMSLCLRaspiSPI. It has a PortNum property to select the Raspberry Pi which one of the two SPI por ts to use. There is no device address involved with SPI as a device on SPI is accessed by driving the device selector pin low for the device. This limits the number of devices that can be directly connected to the Raspberry Pi. The Raspberry Pi SPI clock speed is configurable and maximum speed is 125MHz. The TTMSLCLRaspiSPI class also has Open & Close functions and a Connected property to read the state. To transfer data via SPI to a device, there are also the functions SetByteRegister and GetByteRegister. In addition, there are functions: ReadTransfer and WriteTransfer.
PUTTING IT TOGETH ER IN A FUN PROJECT
To put the pieces together, we create a small project. We'll use the TTMSLCLAdaBarTemp component to read out temperature and air pressure from this BMP180 sensor. The values read will be displayed alternatingly on a 128x32 pixel OLED screen connected to the Raspberry Pi. While both devices are i2C devices, there is one thing particular about the 128x32 OLED screen and that is that it needs to get a reset pulse to get initialized. So, the TTMSLCLAdaDispl128x32 assumes the Raspberry Pi GPIO pin 17 is connected to the RST pin of the 128x32 OLED screen as its method TTMSLCLAdaDispl128x32.InitGPIO will configure and pull this RST pin low to reset the device. ASSEMBLING THE HARDWARE
To quickly put the hardware together, you can use a breadboard and a 40 pin flatcable with breadboard connector. Wire up the Raspberry Pi connector signals GPIO 2 (SDA) to the SDA pin on both the Adafruit BMP180 (https://www.adafruit.com/ pr od uc ts /1 60 3) and 128x32 OLED ( See: https://www.adafruit.com/ pr od uc ts /9 31 ). Do the same for GPIO 3 (SCL) to the SCL pin. function ReadTransfer(buf: pointer; wsize, rsize: integer): boolean; function WriteTransfer(buf: pointer; wsize: integer): boolean; Connect a connector GND and VCC pin also the BMP180 and 128x32 respective GND and VCC pins. Read transfer will send wsize number of bytes Finally, the temperature and barometric from the buffer pointed to by buf and read back sensor requires a 3V3 pin, so connect this to a in the buffer rsize number of bytes. Raspberry Pi header 3.3V pin and for the reset The WriteTransfer function will write wsize pulse of the OLED display, connect GPIO 17 bytes from the buffer pointed to by buf. to the OLED128x32 pin RST.
Issue Nr 1 2016 BLAISE PASCAL MAGAZINE
productivity software buiding blocks
33
THE TMS LCL HW PACK FOR RASPBERRY PI PAGE 4/5 OPEN-SOURCE PACKAGE
Schema: procedure TForm1.FormShow( Sender: TObject); begin // this initializes GPIO 17 and pulse // the reset pin on the display low to initialize displ.InitGPIO; // open the display and show a startup text if displ.Open then begin displ.Clear; displ.DrawTextLarge(0,4 ,'Ready....' ); displ.Display; ; end // open the sensor sensor.Open; ; end
Hardware assembled on a breadboard
Putting the software together To access the BPM180 sensor, drop the component TTMSLCLAdaBarTemp on the form and set its name to 'sensor'. For the OLED display, drop the TTMSLCLAdaDispl128x32 on the form and set its name to 'displ'. Drop a TCheckBox and TTimer on the form and set the TTimer interval to 2000ms and Enabled to false.
Next, to start displaying the temperature and air pressure alternatingly, check the checkbox to start the timer: procedure TForm1.CheckBox1Change(Sender: TObject); begin timer1.Enabled := Checkbox1.Checked; ; end
Then, from the TTimer.OnTimer event, alternatingly we read the temperature and air pressure from the sensor and show it on the display:
In the form's OnShow event, we'll open the connection the BPM180 and OLED display by calling the Open method: 34 productivity software buiding blocks
Issue Nr 1 2016 BLAISE PASCAL MAGAZINE
THE TMS LCL HW PACK FOR RASPBERRY PI PAGE 5/5 OPEN-SOURCE PACKAGE procedure TForm1.Timer1Timer( Sender: TObject); var f: single; s: string; begin if sensor.Connected then begin if ShowTemp then begin f := sensor.GetTemperature; s := 'T:' + Format('%.2f',[f]) + ' C'; end else begin f := sensor.GetPressure; s := 'P:' + Format('%.0f',[f]) + 'mBar'; ; end displ.Clear; displ.DrawTextLarge(0,4,s); displ.Display; ShowTemp := not ShowTemp; ; end ; end
About the author Bruno Fierens
Studied civil electronic engineering at university of Ghent, Belgium (1987-1992) and started a career as R&D digital hardware engineer. Besides the fascination for electronics, Bruno Fierens set the first steps in programming with Turbo Pascal v3.0 and used all Borland Pascal & Delphi versions since that time. In 1996, he founded TMS software for the activity of application and component development with Delphi. TMS software became Borland Technology Partner in 1998, developed Delphi Informant award-winning grid & scheduling components and now has an international team of software developers working on a large portfolio of components. Bruno Fierens is from 2012 Embarcadero MVP and frequent speaker at Delphi conferences world-wide. He does and oversees VCL, IntraWeb, .NET and FireMonkey component development
One important note: configuring the GPIO pins as input or output on Raspberry Pi requires admin privileges, so you might want to make sure the app runs with admin privileges.
Project in action 1: showing barometric pressure
Project in action 2: showing ambient temperature
CONCLUSION
With a few classes that enable you to directly access hardware extensions for the Raspberry Pi, accessing this hardware becomes dead-easy and you can fully focus on being creative hooking up a ll kinds of devices to the Raspberry Pi and automati ng things. At this time we have classes for 9 hardware extensions and we're busy developing more f or other extensions. As the TMS LCL HW Pack is an opensource project, we also invite anyone to participate and share classes that you might have created that wraps other hardware devices. Yes, it's 2016 and programming in Pascal has never been more fun!
productivity software buiding blocks
productivity software buiding blocks
35
36
Issue Nr 1 102016 2015 BLAISE BLAISE PASCAL PASCAL MAGAZINE MAGAZINE
THE QUEENS PUZZLE PAGE 1/3 PROGRAMMING DESCRIPTION starter
expert
BY DAVID DIRKSE
A chessboard has 8 * 8 fields (colums * rows). The board is painted in paintbox1 on form1. A field counts 60 * 60 pixels. The quee n is a bitmap of 50*50 pixels and is painted by the canvas.draw method.
How many queens are needed minimally to cover all fields of a chessboard? Th is Delphi program helps finding the answer. Before writing any program the objectives must be clear. We want to: 1. have the user search for solutions by adding/removi ng queens 2. have the program search for solutio ns 3. interrupt a program search, thus keeping control 4. select the number of queens allowed
type TField = record Q : byte; // 0: empty 1:queen lines : byte; //1:-- 2:| 4:/ 8:\ ; end Tpos = record x,y : byte; ; end
USER / PROGRAM MODE Two SpeedButto ns are placed on form1, named var Qlist : array[1..8] of Tpos; //place of queen on board SolveBtn and TryBtn. Their groupIndex is 1, only one Qcount : byte; button may be UP the the time. board : array[1..8,1..8] of TField; The buttons share the OnClick event: playermode : boolean = false; procedure TForm1.tryBtnClick( Sender: TObject); begin Tfield .Q = 1 if it holds a queen, else it is 0 playermode := tryBtn.Down; Tfield.lines uses bits 0..3 A bit is set if it holds …........ ; end a line indicating coverage by a queen on another field. Board[1..8,1..8] is a 2 dimensional array holding all the Variable playermode is true for allowing the player fields. Qlist[1..8] is a list of queens by board to modify the board. If the program searches for a position . Qcount is the number of queens on the solution, there are some states: board, so the number of valid ent ries in 1. a new search starts Qlist[1..8] 2. a search ends with no solution found
3. a search ends with a solutio n found 4. a search is temporaril y pauzed to keep contact with the Windows system Therefore we introduce type TsearchResult = (srStart,srSolved,srNoSolution,srTimeout ); …. and the call: procedure GoSolve(var sr : TsearchResult); variabele sr defines the start condition and also reports the exit condition. After a while, the GoSolve procedure exits with sr=srTimeout just to allow the processing of messages by the operating system. A call with sr=srTimeout will resume the search process. The main tasks during the search is adding/removing queens to/from a field.
ADD / DELETE QUEENS To add a queen in field at column i and row j: procedure addqueen(i,j : byte); begin inc(Qcount); board[ i,j].Q := 1; paintfield(i ,j); fixlines(i,j); Qlist[Qcount].x := i; Qlist[Qcount].y := j; ; end
CODING THE BOARD
Paintfield(i,j) paints the field, see the source code for details. Fixlines(i,j) adds horizont al, vertical and diagonal lines to all fields that are covered by the new queen. Also for each cov ered field the correspo nding bit in Tfield.lines is set. Deleting a queen is very similar, see the source code. The Fixlines( ) procedure needs some explanation.
FIXLINES(I,J)
Issue Nr 1 2016 BLAISE PASCAL MAGAZINE
37
THE QUEENS PUZZLE PAGE 2/3 PROGRAMMING DESCRIPTION
BY DAVID DIRKSE
Say we add a queen at field(3,4) Then we cover a row from (1,4) …. (8,4) and a column from (3,1) … (3,8). The diagon al lines are a problem and in mind we extend the board left and right. Now we cover by line / : (-1,8) … (6,1) and by line \ : (0,1) … (7,8). These are 8 fields each, but of course we only paint fields in the range from 1..8. In general, adding a queen in field (i,j) affects fields:
Qcount holds the number of queens on the chessboard. Adding a queen increments Qcount and adds the (i,j) values to Qlist[Qcount]. Deleting a queen decrements Qcount. All actions (addqueen,deletequeen,next free field) apply to field[i,j]. Only nextfreefield modifies i and j , indicating the next free field.
for / starting at (i+j-8 , 1) and next 7 fields diagonally up. for \ starting at (i-j+1 , 1) and next 7 f ields diagonally down.
SOLVING THE PUZZLE The method used is basically of the type “brute force”. This means that simply all possibilities are tried until, by accident, a solution is found. However, there is a time saving measure. We do not place a queen on a covered field which is simply done by avoiding fields which have .Q > 0 or .lines > 0. Also we must try all possibilities in a systematical way not to forget solutions.
Array Qlist[1..8] of Txy holds the (x,y) positions of the queens and this array is rega rded a counter. [1] is the upper- and [8] is the lower element. A (x, y) field counts x from 1 ..8 and on overflow y is incremented by 1. So the first (lowest) count is (1,1) and to upper count is (8,8). The GoSolve procedure does the work. It is small but rather tricky and requires concentr ation to understand. Below is the flowchart:
At the start, i and j are set to 1, Qcount = 0. (1,1) is the next free field and here the first queen is placed. The next queens are placed in the next free fields until the selected queencount is reached. Next the last queen is deleted at (i,j) and the next free field after (i,j) is selected. If no free field is found and the board is empty, the no-solution exit is taken. Reloading i,j from Qlist[Qcount] selects the position of the previous element if a queen was deleted before which decremented Qcount. If the maximal number of queens is 4, which are all placed then number 4 is deleted, but i,j unchanged. Then a new free field is selected to place queen number 4. If no free field is found, then i,j is loaded from queen 3 which is deleted and a next free field is searched for. On the next page is the complete Gosolve procedure:
38
Issue Nr 1 2016 BLAISE PASCAL MAGAZINE
THE QUEENS PUZZLE PAGE 3/3 PROGRAMMING DESCRIPTION
BY DAVID DIRKSE
procedure GoSolve(var sr : TsearchResult); //try solve puzzle for Qcount number of queens //maxQueen has been set var i,j : byte; fnext : boolean; //solution check flag timeout : word; begin timeout := 0; case sr of srStart : begin i := 0; j := 0; ; end srSolved : begin i := Qlist[Qcount].x; j := Qlist[Qcount].y; ; end srNosolution : exit; srTimeout : begin i := saveI; j := saveJ; ; end ; end // repeat inc(timeout); if timeout = 100 then begin saveI := i; saveJ := j; searchresult := srTimeout; exit; ; end if (Qcount = MaxQueen) then deleteQueen(i,j); if nextFreeField(i ,j) then begin fnext := true; addQueen(i,j); end else begin fnext := false; if Qcount > 0 then begin i := Qlist[Qcount].x; j := Qlist[Qcount].y; deleteQueen(i,j); end else begin sr := srNoSolution; exit; ; end ; // else end checksolution; until fnext and sr := srSolved; ; end
A trick is the last line : c he ck so lu ti on ; until f ne xt and In the menu: project/options/compiler, full boolean evaluation must not be checked. The expression is false if fnext is false and the checksolution procedure will not be called.
KEEPING CONTROL In most cases, the search will terminate after a very short time. However if it takes longer we want to be able to terminate the process prematurily. This requires that Windows is
Issue Nr 1 2016 BLAISE PASCAL MAGAZINE
granted some time to process any pending messages. The trick here is a timeout variable, called TimeOut. At the start it is set to zero and it is incremented each time the repeat loop is execu ted. If a value of 100 is reached, the local variables i,j are stored in saveI,saveJ and the search procedure is exited with the srTimeOut search result. Upon reentry i,j are reloaded and the search continues. Let's look who calls the GoSolve procedure: procedure TForm1.GoBtnClick(Sender: TObject); begin if searchbusy then exit; searchbusy := true; case searchresult of srStart : begin clearPuzzle; paintBoard; GoProc; ; end srNoSolution : msg(11); srSolved : GoProc; ;//case end searchbusy := false; ; end
The search result will be stStart after a RESET or after clearing the boa rd. In the case of a solved puzzle, a new search is started to find another solution. WHAT DOES GOPROC procedure GoProc; begin repeat msg(10); GoSolve(searchresult); application.processmessages ; until (searchresult <> srTimeOut) orresetRequest; if resetRequest then begin ProcReset; msg(13); end else case searchresult of srSolved : msg(9); srNoSolution : msg(12); ;//case end ; end
GoSolve is repeated until there is no timout (so a yes/no solution). Also the application.processmessages lets Windows process pending messages, which allows the RESET button to be pressed. Boolean variable resetRequest is set if the RESET button is pressed while searching is in progress. For details please refer to the source code listing.
39