RPi Locator and Display Services
a2d_display_client.c File Reference
#include "skn_network_helpers.h"
#include <wiringPi.h>
#include <pcf8591.h>
#include <math.h>
+ Include dependency graph for a2d_display_client.c:

Go to the source code of this file.

Macros

#define A2D_BASE   120
 
#define LED   120
 
#define A2D_THERM   A2D_BASE + 2
 
#define A2D_PHOTO   A2D_BASE + 3
 
#define THERMISTORNOMINAL   10000
 
#define TEMPERATURENOMINAL   25
 
#define BCOEFFICIENT   4207.0
 
#define SERIESRESISTOR   10240
 
#define A2D_PERCISION   255.0
 
#define MAXREADS   5
 
#define sA   1.129148E-03
 
#define sB   2.34125E-04
 
#define sC   8.76741E-08
 
#define calibrationOffset   -0.5
 

Functions

double adcToOhms (int rawADC)
 
double steinhartAdcToCelsius (int rawADC)
 
double betaAdcToCelsius (int rawADC)
 
double readAverageSensorValue (int sensor)
 
int sknGetModuleTemp (char *buffer)
 
int sknGetModuleBright (char *buffer)
 
int main (int argc, char *argv[])
 

Macro Definition Documentation

#define A2D_BASE   120

a2d_display_client.c

which is based on the I2C controller PCF8591T to access:

  • - on-board temperature sensor; NTC, MF58103J3950, B value 3950K, 1 K ohm 5% Cantherm
  • - on-board light sensors; GL5537-1 CdS Photoresistor
  • example: **_a2d_display_client -i 73_**

Definition at line 17 of file a2d_display_client.c.

Referenced by main().

#define A2D_PERCISION   255.0

Definition at line 34 of file a2d_display_client.c.

Referenced by adcToOhms().

#define A2D_PHOTO   A2D_BASE + 3

Definition at line 20 of file a2d_display_client.c.

Referenced by sknGetModuleBright().

#define A2D_THERM   A2D_BASE + 2

Definition at line 19 of file a2d_display_client.c.

Referenced by sknGetModuleTemp().

#define BCOEFFICIENT   4207.0

Definition at line 30 of file a2d_display_client.c.

Referenced by betaAdcToCelsius().

#define calibrationOffset   -0.5

Definition at line 43 of file a2d_display_client.c.

Referenced by betaAdcToCelsius(), and steinhartAdcToCelsius().

#define LED   120

Definition at line 18 of file a2d_display_client.c.

Referenced by main().

#define MAXREADS   5

Definition at line 36 of file a2d_display_client.c.

Referenced by readAverageSensorValue().

#define sA   1.129148E-03

Definition at line 40 of file a2d_display_client.c.

Referenced by steinhartAdcToCelsius().

#define sB   2.34125E-04

Definition at line 41 of file a2d_display_client.c.

Referenced by steinhartAdcToCelsius().

#define sC   8.76741E-08

Definition at line 42 of file a2d_display_client.c.

Referenced by steinhartAdcToCelsius().

#define SERIESRESISTOR   10240

Definition at line 32 of file a2d_display_client.c.

Referenced by adcToOhms().

#define TEMPERATURENOMINAL   25

Definition at line 28 of file a2d_display_client.c.

Referenced by betaAdcToCelsius().

#define THERMISTORNOMINAL   10000

Definition at line 26 of file a2d_display_client.c.

Referenced by betaAdcToCelsius().

Function Documentation

double adcToOhms ( int  rawADC)

Convert rawADC into Ohms

Definition at line 48 of file a2d_display_client.c.

References A2D_PERCISION, and SERIESRESISTOR.

Referenced by betaAdcToCelsius(), and steinhartAdcToCelsius().

48  {
49  double resistance = 0.0;
50 
51  resistance = (double)(( A2D_PERCISION / rawADC) - 1.0);
52  resistance = (double)( SERIESRESISTOR / resistance );
53 
54  return resistance;
55 }
#define A2D_PERCISION
#define SERIESRESISTOR

+ Here is the caller graph for this function:

double betaAdcToCelsius ( int  rawADC)

Inputs ADC Value from Thermistor and outputs Temperature in Celsius

Utilizes the Beta Factor Equation: 1/T = 1/To + 1/B * ln(R/Ro) I'm concerned about R1, in resistance, which is really 1K not 10K https://learn.adafruit.com/thermistor/using-a-thermistor

Definition at line 87 of file a2d_display_client.c.

References adcToOhms(), BCOEFFICIENT, calibrationOffset, TEMPERATURENOMINAL, and THERMISTORNOMINAL.

87  {
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 }
#define BCOEFFICIENT
double adcToOhms(int rawADC)
#define calibrationOffset
#define TEMPERATURENOMINAL
#define THERMISTORNOMINAL

+ Here is the call graph for this function:

int main ( int  argc,
char *  argv[] 
)

Definition at line 170 of file a2d_display_client.c.

References A2D_BASE, gd_i_i2c_address, gd_i_socket, gd_i_update, gd_pch_message, gd_pch_service_name, gi_exit_flag, _serviceEntry::ip, LED, _serviceEntry::name, _serviceEntry::port, _serviceRequest::request, SD_DEBUG, SD_NOTICE, SD_WARNING, service_registry_destroy(), service_registry_entry_count(), service_registry_find_entry(), service_registry_get_via_udp_broadcast(), signals_cleanup(), signals_init(), skn_handle_locator_command_line(), skn_program_name_and_description_set(), SKN_RUN_MODE_RUN, skn_service_request_create(), skn_udp_host_create_broadcast_socket(), skn_udp_host_create_regular_socket(), skn_udp_service_request(), sknGetModuleBright(), sknGetModuleTemp(), SZ_CHAR_BUFF, and SZ_INFO_BUFF.

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
int service_registry_entry_count(PServiceRegistry psr)
#define SD_DEBUG
int port
void signals_init()
#define SZ_CHAR_BUFF
Definition: cmdDC.c:57
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 SZ_INFO_BUFF
Definition: cmdDC.c:56
PServiceRegistry service_registry_get_via_udp_broadcast(int i_socket, char *request)
#define LED
#define SKN_RUN_MODE_RUN
char name[SZ_INFO_BUFF]
sig_atomic_t gi_exit_flag
void service_registry_destroy(PServiceRegistry psreg)
char request[SZ_INFO_BUFF]
PServiceRequest skn_service_request_create(PRegistryEntry pre, int host_socket, char *request)
#define SD_NOTICE
int skn_udp_service_request(PServiceRequest psr)
int skn_udp_host_create_broadcast_socket(int port, double rcvTimeout)
#define A2D_BASE
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)
int sknGetModuleBright(char *buffer)
int gd_i_socket

+ Here is the call graph for this function:

double readAverageSensorValue ( int  sensor)

Averages sensor value from five reads

Definition at line 104 of file a2d_display_client.c.

References MAXREADS.

Referenced by sknGetModuleBright(), and sknGetModuleTemp().

104  {
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 }
#define MAXREADS

+ Here is the caller graph for this function:

int sknGetModuleBright ( char *  buffer)

Photo Resistor Brightness Indicator

Definition at line 141 of file a2d_display_client.c.

References A2D_PHOTO, readAverageSensorValue(), and SZ_INFO_BUFF.

Referenced by main().

141  {
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 }
#define SZ_INFO_BUFF
Definition: cmdDC.c:56
#define A2D_PHOTO
double readAverageSensorValue(int sensor)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int sknGetModuleTemp ( char *  buffer)

Free Air Temps

Definition at line 121 of file a2d_display_client.c.

References A2D_THERM, readAverageSensorValue(), steinhartAdcToCelsius(), and SZ_INFO_BUFF.

Referenced by main().

121  {
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 }
#define A2D_THERM
#define SZ_INFO_BUFF
Definition: cmdDC.c:56
double steinhartAdcToCelsius(int rawADC)
double readAverageSensorValue(int sensor)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

double steinhartAdcToCelsius ( int  rawADC)

Inputs ADC Value from Thermistor and outputs Temperature in Celsius

Utilizes the Steinhart-Hart Thermistor Equation:

If r is the thermistor resistance we can use the Steinhart-Hart equation to calculate the temperature t in degrees kelvin: return Celsius t = 1 / (sA + sB * ln(r) + sC * ln(r) * ln(r) * ln(r))

Temperature in Kelvin = 1 / (A + B * ln(r) + C * ln(r) * ln(r) * ln(r)) where A = 0.001129148, B = 0.000234125 and C = 8.76741E-08

Definition at line 69 of file a2d_display_client.c.

References adcToOhms(), calibrationOffset, sA, sB, and sC.

Referenced by sknGetModuleTemp().

69  {
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 }
#define sC
#define sB
#define sA
double adcToOhms(int rawADC)
#define calibrationOffset

+ Here is the call graph for this function:

+ Here is the caller graph for this function: