RPi Locator and Display Services
a2d_display_client.c
Go to the documentation of this file.
1 
11 #include "skn_network_helpers.h"
12 #include <wiringPi.h>
13 #include <pcf8591.h>
14 #include <math.h>
15 
16 /* I2C Constants */
17 #define A2D_BASE 120
18 #define LED 120
19 #define A2D_THERM A2D_BASE + 2
20 #define A2D_PHOTO A2D_BASE + 3
21 
22 
23 /* Steinhart Coefficents */
24 
25 /* resistance at 25 degrees C */
26 #define THERMISTORNOMINAL 10000
27 /* temp. for nominal resistance (almost always 25 C) */
28 #define TEMPERATURENOMINAL 25
29 /* The beta coefficient of the thermistor (usually 3000-4000) */
30 #define BCOEFFICIENT 4207.0 // 3977.0 // 4791.8420 // 3977 // 3950
31 /* the value of the 'other' resistor */
32 #define SERIESRESISTOR 10240
33 /* A2D Resolution or bits */
34 #define A2D_PERCISION 255.0
35 /* Number of reads to average */
36 #define MAXREADS 5
37 
38 
39 /* steinhart-hart coefficents for 10K Ohm resistor, -55 C to 150 C */
40 #define sA 1.129148E-03 // 1.129241E-03 // 1.129148E-03
41 #define sB 2.34125E-04 // 2.341077E-04 // 2.34125E-04
42 #define sC 8.76741E-08 // 8.775468E-08 // 8.76741E-08
43 #define calibrationOffset -0.5
44 
48 double adcToOhms( int rawADC ) {
49  double resistance = 0.0;
50 
51  resistance = (double)(( A2D_PERCISION / rawADC) - 1.0);
52  resistance = (double)( SERIESRESISTOR / resistance );
53 
54  return resistance;
55 }
56 
69 double steinhartAdcToCelsius(int rawADC) {
70  double kelvin = 0.0, celsius = 0.0;
71 
72  kelvin = log( adcToOhms(rawADC) );
73  kelvin = 1 / (sA + (sB * kelvin) + sC * kelvin * kelvin * kelvin );
74  celsius = kelvin - 273.15; // Convert Kelvin to Celsius
75 
76  return celsius + calibrationOffset; // Return the Temperature in C, with correction offset
77 }
78 
87 double betaAdcToCelsius(int rawADC) {
88  double kelvin = 0.0, celsius = 0.0;
89 
90  kelvin = adcToOhms(rawADC) / THERMISTORNOMINAL; // (R/Ro)
91  kelvin = log(kelvin); // ln(R/Ro)
92  kelvin /= BCOEFFICIENT; // 1/B * ln(R/Ro)
93  kelvin += 1.0 / (TEMPERATURENOMINAL + 273.15); // + (1/To)
94  kelvin = 1.0 / kelvin; // Invert
95 
96  celsius = kelvin - 273.15; // convert to C from Kelvins
97 
98  return celsius + calibrationOffset; // Return the Temperature in C, with correction offset
99 }
100 
104 double readAverageSensorValue(int sensor) {
105  int rvalue[MAXREADS+3], index;
106 
107  /*
108  * Temperature Sensor */
109  for (index = 0, rvalue[MAXREADS] = 0; index < MAXREADS; index++) {
110  rvalue[index] = analogRead(sensor) ;
111  rvalue[MAXREADS] += rvalue[index];
112  delay(10);
113  }
114 
115  return rvalue[MAXREADS] / MAXREADS * 1.0;
116 }
117 
121 int sknGetModuleTemp(char *buffer) {
122  double fTemp = 0.0, cTemp = 0.0, value = 0.0;
123 
125 
126  /*
127  * Steinhart Method */
128  cTemp = steinhartAdcToCelsius(value);
129  fTemp = (cTemp * 1.8) + 32.0; // Convert to USA
130 
131  /*
132  * Write to output buffer */
133  snprintf( buffer, (SZ_INFO_BUFF - 1),"[A] %.0fC %.0fF", cTemp, fTemp);
134 
135  return EXIT_SUCCESS;
136 }
137 
141 int sknGetModuleBright(char *buffer) {
142  double value = 0.0;
143  char *plights;
144 
145  /*
146  * Photo Sensor Lumens */
148  value = 256.0 - value;
149 
150  if (value < 2.5) {
151  plights = "Dark";
152  } else if (value < 50.0) {
153  plights = "Dim";
154  } else if (value < 125.0) {
155  plights = "Light";
156  } else if (value < 199.0) {
157  plights = "Bright";
158  } else {
159  plights = "Brightest";
160  }
161 
162  /*
163  * Write to output buffer */
164  snprintf( buffer, (SZ_INFO_BUFF - 1), "%s", plights);
165 
166  return EXIT_SUCCESS;
167 }
168 
169 
170 int main(int argc, char *argv[])
171 {
172  char request[SZ_INFO_BUFF];
173  char registry[SZ_CHAR_BUFF];
174  PServiceRegistry psr = NULL;
175  PRegistryEntry pre = NULL;
176  PServiceRequest pnsr = NULL;
177  int vIndex = 0;
178 
179  gd_i_i2c_address = 0;
180 
181  memset(registry, 0, sizeof(registry));
182  memset(request, 0, sizeof(request));
183  strncpy(registry, "DisplayClient: Raspberry Pi where are you?", sizeof(registry) - 1);
184 
186  "a2d_display_client",
187  "Send Measured Temperature and Light(lux) to Display Service."
188  );
189 
190  /* Parse any command line options,
191  * like request string override */
192  if (skn_handle_locator_command_line(argc, argv) == EXIT_FAILURE) {
193  exit(EXIT_FAILURE);
194  }
195  if (gd_pch_message != NULL) {
196  strncpy(request, gd_pch_message, sizeof(request));
197  free(gd_pch_message); // from strdup()
198  gd_pch_message = request;
199  } else if (argc == 2) {
200  strcpy(request, argv[1]);
201  }
202 
203  skn_logger(SD_DEBUG, "Request Message [%s]", request);
204  skn_logger(SD_DEBUG, "Registry Message [%s]", registry);
205 
206  /* Initialize Signal handler */
207  signals_init();
208 
209  // wiringPiSetup () ;
210  wiringPiSetupSys();
211 
212  // Add in the pcf8591
213  if (gd_i_i2c_address == 0) {
214  gd_i_i2c_address = 0x49;
215  }
216  pcf8591Setup (A2D_BASE, gd_i_i2c_address) ;
217 
218  pinMode (LED, OUTPUT) ; // On-board LED
219  analogWrite(LED, 0) ; // Turn off the LED
220 
221  /* Create local socket for sending requests */
223  if (gd_i_socket == EXIT_FAILURE) {
225  exit(EXIT_FAILURE);
226  }
227 
228  skn_logger(SD_NOTICE, "Application Active...");
229 
230  /* Get the ServiceRegistry from Provider
231  * - could return null if error */
233  if (psr != NULL && service_registry_entry_count(psr) != 0) {
234  char *service_name = "lcd_display_service";
235 
236  if (gd_pch_service_name != NULL) {
237  service_name = gd_pch_service_name;
238  }
239 
240  /* find a single entry */
241  pre = service_registry_find_entry(psr, service_name);
242  if (pre != NULL) {
243  skn_logger(" ", "\nLCD DisplayService (%s) is located at IPv4: %s:%d\n", pre->name, pre->ip, pre->port);
244  }
245 
246  /*
247  * Switch to non-broadcast type socket */
248  close(gd_i_socket); gd_i_socket = -1;
250  if (gd_i_socket == EXIT_FAILURE) {
251  if (psr != NULL) service_registry_destroy(psr);
253  exit(EXIT_FAILURE);
254  }
255  }
256 
257  // we have the location
258  if (pre != NULL) {
259  if (request[0] == 0) {
260  sknGetModuleTemp(request);
261  }
262  pnsr = skn_service_request_create(pre, gd_i_socket, request);
263  }
264  if (pnsr != NULL) {
265  do {
266  analogWrite(LED, 255) ; // Flicker the LED
267 
268  /*
269  * Do Work */
270  sknGetModuleTemp(pnsr->request);
271  vIndex = skn_udp_service_request(pnsr);
272  if ((vIndex == EXIT_FAILURE) && (gd_i_update == 0)) { // ignore if non-stop is set
273  break;
274  }
275 
276  sleep(3);
277 
278  /*
279  * Do Work */
281  vIndex = skn_udp_service_request(pnsr);
282  if ((vIndex == EXIT_FAILURE) && (gd_i_update == 0)) { // ignore if non-stop is set
283  break;
284  }
285 
286  analogWrite(LED, 0) ; // Flicker the LED
287 
288  sleep(gd_i_update);
289  } while(gd_i_update != 0 && gi_exit_flag == SKN_RUN_MODE_RUN);
290  free(pnsr); // Done
291 
292  } else {
293  skn_logger(SD_WARNING, "Unable to create Network Request.");
294  }
295 
296  /* Cleanup and shutdown
297  * - if shutdown was caused by signal handler
298  * then a termination signal will be sent via signal()
299  * otherwise, a normal exit occurs
300  */
301  analogWrite(LED, 0) ; // LED off
302  if (gd_i_socket) close(gd_i_socket);
303  if (psr != NULL) service_registry_destroy(psr);
305 
306  exit(EXIT_SUCCESS);
307 }
int skn_udp_host_create_regular_socket(int port, double rcvTimeout)
char * gd_pch_service_name
#define MAXREADS
int service_registry_entry_count(PServiceRegistry psr)
#define SD_DEBUG
int port
void signals_init()
#define sC
#define SZ_CHAR_BUFF
Definition: cmdDC.c:57
#define sB
int gd_i_update
void signals_cleanup(int sig)
int skn_handle_locator_command_line(int argc, char **argv)
char * gd_pch_message
int gd_i_i2c_address
#define SD_WARNING
int sknGetModuleTemp(char *buffer)
#define sA
#define A2D_THERM
#define SZ_INFO_BUFF
Definition: cmdDC.c:56
PServiceRegistry service_registry_get_via_udp_broadcast(int i_socket, char *request)
#define LED
#define BCOEFFICIENT
double betaAdcToCelsius(int rawADC)
#define SKN_RUN_MODE_RUN
char name[SZ_INFO_BUFF]
int main(int argc, char *argv[])
double adcToOhms(int rawADC)
sig_atomic_t gi_exit_flag
#define calibrationOffset
void service_registry_destroy(PServiceRegistry psreg)
#define A2D_PHOTO
char request[SZ_INFO_BUFF]
#define TEMPERATURENOMINAL
PServiceRequest skn_service_request_create(PRegistryEntry pre, int host_socket, char *request)
#define SD_NOTICE
#define A2D_PERCISION
int skn_udp_service_request(PServiceRequest psr)
int skn_udp_host_create_broadcast_socket(int port, double rcvTimeout)
double steinhartAdcToCelsius(int rawADC)
#define SERIESRESISTOR
#define A2D_BASE
double readAverageSensorValue(int sensor)
char ip[SZ_INFO_BUFF]
void skn_program_name_and_description_set(const char *name, const char *desc)
PRegistryEntry service_registry_find_entry(PServiceRegistry psreg, char *serviceName)
#define THERMISTORNOMINAL
int sknGetModuleBright(char *buffer)
int gd_i_socket