Version 0.0.2. Added LCD display using wiringPi library. The display is connected via a LCM1602 IIC board.

Fri, 02 May 2014 21:04:20 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Fri, 02 May 2014 21:04:20 +0200
changeset 16
f4cbe008da72
parent 15
01fec4ddad17
child 17
b802305046dc

Version 0.0.2. Added LCD display using wiringPi library. The display is connected via a LCM1602 IIC board.

configure file | annotate | diff | comparison | revisions
configure.ac file | annotate | diff | comparison | revisions
lib/Makefile file | annotate | diff | comparison | revisions
lib/lcd-pcf8574.c file | annotate | diff | comparison | revisions
lib/mbselib.h file | annotate | diff | comparison | revisions
thermometers/main.c file | annotate | diff | comparison | revisions
--- a/configure	Tue Apr 29 20:57:16 2014 +0200
+++ b/configure	Fri May 02 21:04:20 2014 +0200
@@ -1878,7 +1878,7 @@
 
 
 PACKAGE="mbsePi-apps"
-VERSION="0.0.1"
+VERSION="0.0.2"
 COPYRIGHT="Copyright (C) 2014 Michiel Broek, All Rights Reserved"
 CYEARS="2014"
 
@@ -2942,6 +2942,55 @@
   as_fn_error $? "libmosquitto not found" "$LINENO" 5
 fi
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for wiringPiSetup in -lwiringPi" >&5
+$as_echo_n "checking for wiringPiSetup in -lwiringPi... " >&6; }
+if ${ac_cv_lib_wiringPi_wiringPiSetup+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lwiringPi  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char wiringPiSetup ();
+int
+main ()
+{
+return wiringPiSetup ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_wiringPi_wiringPiSetup=yes
+else
+  ac_cv_lib_wiringPi_wiringPiSetup=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_wiringPi_wiringPiSetup" >&5
+$as_echo "$ac_cv_lib_wiringPi_wiringPiSetup" >&6; }
+if test "x$ac_cv_lib_wiringPi_wiringPiSetup" = xyes; then :
+  result=yes
+else
+  result=no
+fi
+
+if test "$result" = "yes"; then
+  LIBS="$LIBS -lwiringPi -lwiringPiDev"
+else
+  as_fn_error $? "libwiringPi not found" "$LINENO" 5
+fi
+
+
 #
 # Additional commandline switches
 #
--- a/configure.ac	Tue Apr 29 20:57:16 2014 +0200
+++ b/configure.ac	Fri May 02 21:04:20 2014 +0200
@@ -8,7 +8,7 @@
 dnl General settings
 dnl After changeing the version number, run autoconf!
 PACKAGE="mbsePi-apps"
-VERSION="0.0.1"
+VERSION="0.0.2"
 COPYRIGHT="Copyright (C) 2014 Michiel Broek, All Rights Reserved"
 CYEARS="2014"
 AC_SUBST(PACKAGE)
@@ -40,6 +40,14 @@
   AC_MSG_ERROR(libmosquitto not found)
 fi
 
+AC_CHECK_LIB(wiringPi,wiringPiSetup,result=yes,result=no)
+if test "$result" = "yes"; then
+  LIBS="$LIBS -lwiringPi -lwiringPiDev"
+else
+  AC_MSG_ERROR(libwiringPi not found)
+fi
+
+
 #
 # Additional commandline switches
 #
--- a/lib/Makefile	Tue Apr 29 20:57:16 2014 +0200
+++ b/lib/Makefile	Fri May 02 21:04:20 2014 +0200
@@ -2,8 +2,8 @@
 
 include ../Makefile.global
 
-SRCS		= xutil.c rdconfig.c
-OBJS		= xutil.o rdconfig.o
+SRCS		= xutil.c rdconfig.c lcd-pcf8574.c
+OBJS		= xutil.o rdconfig.o lcd-pcf8574.o
 HDRS		= mbselib.h
 TARGET		= libmbse.a
 
@@ -46,4 +46,5 @@
 # Dependencies generated by make depend
 xutil.o: ../config.h mbselib.h
 rdconfig.o: ../config.h mbselib.h
+lcd-pcf8574.o: ../config.h mbselib.h
 # End of generated dependencies
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/lcd-pcf8574.c	Fri May 02 21:04:20 2014 +0200
@@ -0,0 +1,121 @@
+/*
+ * lcd-pcf8574.c:
+ *	Text-based LCD driver library code
+ *	This is designed to drive the HD44780U LCD display connected via
+ *	a "LCM1602 IIC  A0 A1 A2" board with a PCF8574 I2C controller.
+ *
+ * Copyright (c) 2012-2013 Gordon Henderson.
+ * Copyright (c) 2014 Michiel Broek.
+ ***********************************************************************
+ *
+ *    mbsePi is free software: you can redistribute it and/or modify
+ *    it under the terms of the GNU Lesser General Public License as published by
+ *    the Free Software Foundation, either version 3 of the License, or
+ *    (at your option) any later version.
+ *
+ *    mbsePi is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU Lesser General Public License for more details.
+ *
+ *    You should have received a copy of the GNU Lesser General Public License
+ *    along with wiringPi.  If not, see <http://www.gnu.org/licenses/>.
+ ***********************************************************************
+ */
+
+#include "../config.h"
+#include "mbselib.h"
+
+//#include <stdio.h>
+//#include <stdlib.h>
+//#include <unistd.h>
+//#include <stdint.h>
+
+//#include <string.h>
+//#include <time.h>
+
+//#include <wiringPi.h>
+//#include <pcf8574.h>
+//#include <lcd.h>
+
+//#ifndef	TRUE
+//#  define	TRUE	(1==1)
+//#  define	FALSE	(1==2)
+//#endif
+
+
+// Defines for the pcf8574 Pi LCD interface board
+
+//#define	AF_BASE		100
+
+//#define AF_RS		(AF_BASE + 0)
+//#define AF_RW		(AF_BASE + 1)
+//#define AF_E		(AF_BASE + 2)
+//#define AF_BACKLIGHT	(AF_BASE + 3)
+
+//#define	AF_DB4		(AF_BASE + 4)
+//#define	AF_DB5		(AF_BASE + 5)
+//#define	AF_DB6		(AF_BASE + 6)
+//#define	AF_DB7		(AF_BASE + 7)
+
+
+// User-Defined character test
+
+// Global lcd handle:
+
+int lcdHandle;
+
+
+/*
+ * setBacklight:
+ *********************************************************************************
+ */
+
+void setBacklight (int value)
+{
+  pinMode (AF_BACKLIGHT, OUTPUT) ;
+  digitalWrite (AF_BACKLIGHT, (value & 1)) ;
+}
+
+
+
+/*
+ * initLCD:
+ *********************************************************************************
+ */
+
+int initLCD (int cols, int rows)
+{
+  if (!((rows == 1) || (rows == 2) || (rows == 4)))
+  {
+    fprintf (stderr, "rows must be 1, 2 or 4\n") ;
+    return EXIT_FAILURE ;
+  }
+
+  if (!((cols == 16) || (cols == 20)))
+  {
+    fprintf (stderr, "cols must be 16 or 20\n") ;
+    return EXIT_FAILURE ;
+  }
+
+  wiringPiSetupSys () ;
+  pcf8574Setup (AF_BASE, 0x27) ;
+
+  setBacklight (1) ;
+
+  pinMode (AF_RW, OUTPUT) ;
+  digitalWrite (AF_RW, LOW) ;        // Not used with wiringPi - always in write mode
+
+  // The other control pins are initialised with lcdInit ()
+
+  lcdHandle = lcdInit (rows, cols, 4, AF_RS, AF_E, AF_DB4, AF_DB5, AF_DB6, AF_DB7, 0, 0, 0, 0) ;
+
+  if (lcdHandle < 0)
+  {
+    fprintf (stderr, "lcdInit failed\n") ;
+    return -1 ;
+  }
+
+  lcdClear (lcdHandle) ;
+  return 0 ;
+}
--- a/lib/mbselib.h	Tue Apr 29 20:57:16 2014 +0200
+++ b/lib/mbselib.h	Fri May 02 21:04:20 2014 +0200
@@ -16,8 +16,13 @@
 #include <signal.h>
 #include <getopt.h>
 
+/* mosquitto */
 #include <mosquitto.h>
 
+/* wiringPi */
+#include <wiringPi.h>
+#include <pcf8574.h>
+#include <lcd.h>
 
 #define TRUE 1
 #define FALSE 0
@@ -59,5 +64,23 @@
 char *xstrcpy(char *);
 char *xstrcat(char *, char *);
 
+
+/* lcd-pcf8574.c */
+// Defines for the pcf8574 Pi LCD interface board
+
+#define AF_BASE         100
+
+#define AF_RS           (AF_BASE + 0)
+#define AF_RW           (AF_BASE + 1)
+#define AF_E            (AF_BASE + 2)
+#define AF_BACKLIGHT    (AF_BASE + 3)
+#define AF_DB4          (AF_BASE + 4)
+#define AF_DB5          (AF_BASE + 5)
+#define AF_DB6          (AF_BASE + 6)
+#define AF_DB7          (AF_BASE + 7)
+
+void setBacklight (int);
+int  initLCD (int, int);
+
 #endif
 
--- a/thermometers/main.c	Tue Apr 29 20:57:16 2014 +0200
+++ b/thermometers/main.c	Fri May 02 21:04:20 2014 +0200
@@ -42,6 +42,7 @@
 
 extern bool		debug;
 extern sys_config	Config;
+extern int		lcdHandle;
 
 int server(void);
 void help(void);
@@ -122,10 +123,19 @@
 
 
 
+void stopLCD(void)
+{
+   lcdClear(lcdHandle);
+   setBacklight(0);
+}
+
+
+
 int main(int argc, char *argv[])
 {
     int		rc, c, i;
     pid_t	frk;
+    char	buf[80];
 
     while (1) {
 	int option_index = 0;
@@ -168,6 +178,16 @@
 	    signal(i, (void (*))die);
     }
 
+    if ((rc = initLCD (16, 2))) {
+	fprintf(stderr, "Cannot initialize LCD display, rc=%d\n", rc);
+	return 1;
+    }
+
+    lcdPosition(lcdHandle, 0, 0);
+    lcdPuts(lcdHandle, "Thermometers");
+    lcdPosition(lcdHandle, 0, 1);
+    sprintf(buf, "Version %s", VERSION);
+    lcdPuts(lcdHandle, buf);
 
     if (debug) {
 	/*
@@ -193,6 +213,7 @@
 	    case -1:	
 		    	syslog(LOG_NOTICE, "Daemon fork failed: %s", strerror(errno));
 			syslog(LOG_NOTICE, "Finished, rc=1");
+			stopLCD();
 			exit(1);
 	    case 0:	/*
 			 * Run the daemon
@@ -237,7 +258,7 @@
     char                *id = NULL, *state = NULL;
     struct mosquitto    *mosq = NULL;
     char                hostname[256], buf[1024];
-    int                 temp, rc, deviation, keepalive = 60;
+    int                 temp, rc, deviation, keepalive = 60, lcdupdate;
     unsigned int        max_inflight = 20;
     char                err[1024];
     w1_therm		*tmp1, *old1;
@@ -357,6 +378,8 @@
 
     do {
 	if (status == STATUS_CONNACK_RECVD) {
+	    lcdupdate = FALSE;
+
 	    /*
 	     * Here send our 1-wire sensors values
 	     */
@@ -406,8 +429,9 @@
 			     * value with the previous one. If the difference is too
 			     * much, we don't send that value. That also means that if
 			     * the next value is ok again, it will be marked invalid too.
+			     * Maximum error is 20 degrees for now.
 			     */
-			    deviation = (temp + tmp1->lastval) / 10;
+			    deviation = 20000;
 			    if ((tmp1->lastval == 0) ||
 				(tmp1->lastval && (temp > (tmp1->lastval - deviation)) && (temp < (tmp1->lastval + deviation)))) {
 			    	/*
@@ -421,10 +445,13 @@
 				    	syslog(LOG_NOTICE, "mainloop: error %d from mosquitto_publish", rc);
 			    	}
 			    } else {
-				if (debug)
-				    syslog(LOG_NOTICE, "deviation error deviation=%d, old=%d new=%d", deviation, tmp1->lastval, temp);
+				syslog(LOG_NOTICE, "deviation error deviation=%d, old=%d new=%d", deviation, tmp1->lastval, temp);
+				if (debug) {
+				    fprintf(stdout, "deviation error deviation=%d, old=%d new=%d\n", deviation, tmp1->lastval, temp);
+				}
 			    }
 			    tmp1->lastval = temp;
+			    lcdupdate = TRUE;
 			}
 		    } else {
 			syslog(LOG_NOTICE, "sensor %s/%s CRC error", tmp1->master, tmp1->name);
@@ -442,7 +469,18 @@
 		free(alias);
 		alias = NULL;
 	    }
-	    usleep(100000);
+
+	    if (lcdupdate) {
+		lcdPosition(lcdHandle, 0, 0);
+		tmp1 = Config.w1therms;
+		snprintf(buf, 16, "%5.1f %cC %s            ", tmp1->lastval / 1000.0, 0xdf, tmp1->alias);
+		lcdPuts(lcdHandle, buf);
+		old1 = tmp1->next;
+		tmp1 = old1;
+		lcdPosition(lcdHandle, 0, 1);
+		snprintf(buf, 16, "%5.1f %cC %s            ", tmp1->lastval / 1000.0, 0xdf, tmp1->alias);
+		lcdPuts(lcdHandle, buf);
+	    }
 
 	    if (shutdown) {
 		/*
@@ -452,7 +490,13 @@
 		mosquitto_publish(mosq, &mid_sent, state, strlen(buf), buf, qos, true);
 		last_mid = mid_sent;
 		status = STATUS_WAITING;
+		lcdClear(lcdHandle);
+		lcdPosition(lcdHandle, 0, 0);
+		lcdPuts(lcdHandle, "Shuting down ...");
 	    }
+
+	    usleep(100000);
+
 	} else if (status == STATUS_WAITING) {
 	    if (debug)
 	    	fprintf(stdout, (char *)"Waiting\n");
@@ -473,6 +517,8 @@
     mosquitto_destroy(mosq);
     mosquitto_lib_cleanup();
 
+    stopLCD();
+
     return rc;
 }
 

mercurial