chiark / gitweb /
Manpage gpio(1): Regularise header
[wiringPi.git] / examples / lcd-adafruit.c
1 /*
2  * lcd-adafruit.c:
3  *      Text-based LCD driver test code
4  *      This is designed to drive the Adafruit RGB LCD Plate
5  *      with the additional 5 buttons for the Raspberry Pi
6  *
7  * Copyright (c) 2012-2013 Gordon Henderson.
8  ***********************************************************************
9  * This file is part of wiringPi:
10  *      https://projects.drogon.net/raspberry-pi/wiringpi/
11  *
12  *    wiringPi is free software: you can redistribute it and/or modify
13  *    it under the terms of the GNU Lesser General Public License as published by
14  *    the Free Software Foundation, either version 3 of the License, or
15  *    (at your option) any later version.
16  *
17  *    wiringPi is distributed in the hope that it will be useful,
18  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
19  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  *    GNU Lesser General Public License for more details.
21  *
22  *    You should have received a copy of the GNU Lesser General Public License
23  *    along with wiringPi.  If not, see <http://www.gnu.org/licenses/>.
24  ***********************************************************************
25  */
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <unistd.h>
30 #include <string.h>
31 #include <time.h>
32
33 #include <wiringPi.h>
34 #include <mcp23017.h>
35 #include <lcd.h>
36
37 #ifndef TRUE
38 #  define       TRUE    (1==1)
39 #  define       FALSE   (1==2)
40 #endif
41
42
43 // Defines for the Adafruit Pi LCD interface board
44
45 #define AF_BASE         100
46 #define AF_RED          (AF_BASE + 6)
47 #define AF_GREEN        (AF_BASE + 7)
48 #define AF_BLUE         (AF_BASE + 8)
49
50 #define AF_E            (AF_BASE + 13)
51 #define AF_RW           (AF_BASE + 14)
52 #define AF_RS           (AF_BASE + 15)
53
54 #define AF_DB4          (AF_BASE + 12)
55 #define AF_DB5          (AF_BASE + 11)
56 #define AF_DB6          (AF_BASE + 10)
57 #define AF_DB7          (AF_BASE +  9)
58
59 #define AF_SELECT       (AF_BASE +  0)
60 #define AF_RIGHT        (AF_BASE +  1)
61 #define AF_DOWN         (AF_BASE +  2)
62 #define AF_UP           (AF_BASE +  3)
63 #define AF_LEFT         (AF_BASE +  4)
64
65
66 // User-Defined character test
67
68 static unsigned char newChar [8] = 
69 {
70   0b00100,
71   0b00100,
72   0b00000,
73   0b00100,
74   0b01110,
75   0b11011,
76   0b11011,
77   0b10001,
78 } ;
79
80 // Global lcd handle:
81
82 static int lcdHandle ;
83
84 /*
85  * usage:
86  *********************************************************************************
87  */
88
89 int usage (const char *progName)
90 {
91   fprintf (stderr, "Usage: %s colour\n", progName) ;
92   return EXIT_FAILURE ;
93 }
94
95
96 /*
97  * scrollMessage:
98  *********************************************************************************
99  */
100
101 static const char *message =
102   "                    "
103   "Wiring Pi by Gordon Henderson. HTTP://WIRINGPI.COM/"
104   "                    " ;
105
106 void scrollMessage (int line, int width)
107 {
108   char buf [32] ;
109   static int position = 0 ;
110   static int timer = 0 ;
111
112   if (millis () < timer)
113     return ;
114
115   timer = millis () + 200 ;
116
117   strncpy (buf, &message [position], width) ;
118   buf [width] = 0 ;
119   lcdPosition (lcdHandle, 0, line) ;
120   lcdPuts (lcdHandle, buf) ;
121
122   if (++position == (strlen (message) - width))
123     position = 0 ;
124 }
125
126
127 /*
128  * setBacklightColour:
129  *      The colour outputs are inverted.
130  *********************************************************************************
131  */
132
133 static void setBacklightColour (int colour)
134 {
135   colour &= 7 ;
136
137   digitalWrite (AF_RED,   !(colour & 1)) ;
138   digitalWrite (AF_GREEN, !(colour & 2)) ;
139   digitalWrite (AF_BLUE,  !(colour & 4)) ;
140 }
141
142
143 /*
144  * adafruitLCDSetup:
145  *      Setup the Adafruit board by making sure the additional pins are
146  *      set to the correct modes, etc.
147  *********************************************************************************
148  */
149
150 static void adafruitLCDSetup (int colour)
151 {
152   int i ;
153
154 //      Backlight LEDs
155
156   pinMode (AF_RED,   OUTPUT) ;
157   pinMode (AF_GREEN, OUTPUT) ;
158   pinMode (AF_BLUE,  OUTPUT) ;
159   setBacklightColour (colour) ;
160
161 //      Input buttons
162
163   for (i = 0 ; i <= 4 ; ++i)
164   {
165     pinMode (AF_BASE + i, INPUT) ;
166     pullUpDnControl (AF_BASE + i, PUD_UP) ;     // Enable pull-ups, switches close to 0v
167   }
168
169 // Control signals
170
171   pinMode (AF_RW, OUTPUT) ; digitalWrite (AF_RW, LOW) ; // Not used with wiringPi - always in write mode
172
173 // The other control pins are initialised with lcdInit ()
174
175   lcdHandle = lcdInit (2, 16, 4, AF_RS, AF_E, AF_DB4,AF_DB5,AF_DB6,AF_DB7, 0,0,0,0) ;
176
177   if (lcdHandle < 0)
178   {
179     fprintf (stderr, "lcdInit failed\n") ;
180     exit (EXIT_FAILURE) ;
181   }
182 }
183
184
185 /*
186  * waitForEnter:
187  *      On the Adafruit display, wait for the select button
188  *********************************************************************************
189  */
190
191 static void waitForEnter (void)
192 {
193   printf ("Press SELECT to continue: ") ; fflush (stdout) ;
194
195   while (digitalRead (AF_SELECT) == HIGH)       // Wait for push
196     delay (1) ;
197
198   while (digitalRead (AF_SELECT) == LOW)        // Wait for release
199     delay (1) ;
200
201   printf ("OK\n") ;
202 }
203
204
205 /*
206  * speedTest:
207  *      Test the update speed of the display
208  *********************************************************************************
209  */
210
211 static void speedTest (void)
212 {
213   unsigned int start, end, taken ;
214   int times ;
215
216   lcdClear (lcdHandle) ;
217   start = millis () ;
218   for (times = 0 ; times < 10 ; ++times)
219   {
220     lcdPuts (lcdHandle, "0123456789ABCDEF") ;
221     lcdPuts (lcdHandle, "0123456789ABCDEF") ;
222   }
223   end   = millis () ;
224   taken = (end - start) / 10;
225
226   lcdClear (lcdHandle) ;
227   lcdPosition (lcdHandle, 0, 0) ; lcdPrintf (lcdHandle, "Speed: %dmS", taken) ;
228   lcdPosition (lcdHandle, 0, 1) ; lcdPrintf (lcdHandle, "For full update") ;
229
230   waitForEnter () ;
231
232   lcdClear (lcdHandle) ;
233   lcdPosition (lcdHandle, 0, 0) ; lcdPrintf (lcdHandle, "Time: %dmS", taken / 32) ;
234   lcdPosition (lcdHandle, 0, 1) ; lcdPrintf (lcdHandle, "Per character") ;
235
236   waitForEnter () ;
237
238   lcdClear (lcdHandle) ;
239   lcdPosition (lcdHandle, 0, 0) ; lcdPrintf (lcdHandle, "%d cps...", 32000 / taken) ;
240
241   waitForEnter () ;
242 }
243
244
245 /*
246  * The works
247  *********************************************************************************
248  */
249
250 int main (int argc, char *argv[])
251 {
252   int colour ;
253   int cols = 16 ;
254   int waitForRelease = FALSE ;
255
256   struct tm *t ;
257   time_t tim ;
258
259   char buf [32] ;
260
261   if (argc != 2)
262     return usage (argv [0]) ;
263
264   printf ("Raspberry Pi Adafruit LCD test\n") ;
265   printf ("==============================\n") ;
266
267   colour = atoi (argv [1]) ;
268
269   wiringPiSetupSys () ;
270   mcp23017Setup (AF_BASE, 0x20) ;
271
272   adafruitLCDSetup (colour) ;
273
274   lcdPosition (lcdHandle, 0, 0) ; lcdPuts (lcdHandle, "Gordon Henderson") ;
275   lcdPosition (lcdHandle, 0, 1) ; lcdPuts (lcdHandle, "  wiringpi.com  ") ;
276
277   waitForEnter () ;
278
279   lcdPosition (lcdHandle, 0, 1) ; lcdPuts (lcdHandle, "Adafruit RGB LCD") ;
280
281   waitForEnter () ;
282
283   lcdCharDef  (lcdHandle, 2, newChar) ;
284
285   lcdClear    (lcdHandle) ;
286   lcdPosition (lcdHandle, 0, 0) ;
287   lcdPuts     (lcdHandle, "User Char: ") ;
288   lcdPutchar  (lcdHandle, 2) ;
289
290   lcdCursor      (lcdHandle, TRUE) ;
291   lcdCursorBlink (lcdHandle, TRUE) ;
292
293   waitForEnter () ;
294
295   lcdCursor      (lcdHandle, FALSE) ;
296   lcdCursorBlink (lcdHandle, FALSE) ;
297
298   speedTest () ;
299
300   lcdClear (lcdHandle) ;
301
302   for (;;)
303   {
304     scrollMessage (0, cols) ;
305     
306     tim = time (NULL) ;
307     t = localtime (&tim) ;
308
309     sprintf (buf, "%02d:%02d:%02d", t->tm_hour, t->tm_min, t->tm_sec) ;
310
311     lcdPosition (lcdHandle, (cols - 8) / 2, 1) ;
312     lcdPuts     (lcdHandle, buf) ;
313
314 // Check buttons to cycle colour
315
316 // If Up or Down are still pushed, then skip
317
318     if (waitForRelease)
319     {
320       if ((digitalRead (AF_UP) == LOW) || (digitalRead (AF_DOWN) == LOW))
321         continue ;
322       else
323         waitForRelease = FALSE ;
324     }
325
326     if (digitalRead (AF_UP) == LOW)     // Pushed
327     {
328       colour = colour + 1 ;
329       if (colour == 8)
330         colour = 0 ;
331       setBacklightColour (colour) ;
332       waitForRelease = TRUE ;
333     }
334
335     if (digitalRead (AF_DOWN) == LOW)   // Pushed
336     {
337       colour = colour - 1 ;
338       if (colour == -1)
339         colour = 7 ;
340       setBacklightColour (colour) ;
341       waitForRelease = TRUE ;
342     }
343
344   }
345
346   return 0 ;
347 }