NTP demo for cypress Pioneer and Proto Dev kits also reads available analogue sensors

main.cpp

Committer:
reedas
Date:
2020-07-03
Revision:
8:4d13f66d6b5f
Parent:
7:a92448410a8e

File content as of revision 8:4d13f66d6b5f:

#include "GUI.h"
#include "mbed.h"
#include "mbed_events.h"
#include "ntp-client/NTPClient.h"

#undef CY8CKIT_TFT // Light or Temperature?
Thread netTimeThreadHandle;
WiFiInterface *wifi;
#define MBED_CONF_APP_WIFI_SSID "brackenhillc"
#define MBED_CONF_APP_WIFI_PASSWORD "1broches"

/* Reference resistor in series with the thermistor is of 10 KOhm */
#define R_REFERENCE (float)(10000)

/* Beta constant of this thermistor is 3380 Kelvin. See the thermistor
   (NCP18XH103F03RB) data sheet for more details. */
#define B_CONSTANT (float)(3380)

/* Resistance of the thermistor is 10K at 25 degrees C (from data sheet)
   Therefore R0 = 10000 Ohm, and T0 = 298.15 Kelvin, which gives
   R_INFINITY = R0 e^(-B_CONSTANT / T0) = 0.1192855 */
#define R_INFINITY (float)(0.1192855)

/* Zero Kelvin in degree C */
#define ABSOLUTE_ZERO (float)(-273.15)

EventQueue *displayQueue;
Semaphore WiFiSemaphore;
#define SENSOR_BOARD
#ifdef CY8CKIT_TFT
DigitalOut PwrEnable(P6_2);
#ifdef SENSOR_BOARD
AnalogIn ALS(P10_7); // Sensor Board
#else
AnalogIn ALS(P10_0); // TFT Board
#endif
static float lightlevel;
#else
#define GUI_ \/\/
DigitalOut PwrEnable(P10_0);
DigitalOut ThermGnd(P10_3);
AnalogIn Thermistor(P10_1);
static float TempAverage;
#endif
/******************************************************************************************
 *
 * Display Functions
 *
 ********************************************************************************************/
#define DISP_LEFTMARGIN 10
#define DISP_TOPMARGIN 4
#define DISP_LINESPACE 2
// updateDisplayWiFiStatus
// Used to display the wifi status
void updateDisplayWiFiStatus(char *status) {
  GUI_SetFont(GUI_FONT_16_1);
  GUI_DispStringAt(status, DISP_LEFTMARGIN, DISP_TOPMARGIN);
  printf("%s\r\n", status);
  free(status);
}
// updateDisplayWiFiConnectAttempts
// This function displays the number of attempted connections
void updateDisplayWiFiConnectAttempts(int count) {
  char buffer[128];
  snprintf(buffer, sizeof(buffer), "WiFi Connect Attempts = %d", count);
  GUI_SetFont(GUI_FONT_16_1);
  GUI_DispStringAt(buffer, DISP_LEFTMARGIN,
                   DISP_TOPMARGIN + (GUI_GetFontSizeY() + DISP_LINESPACE));
}
// updateDisplayNTPFailed
// updates the display with the number of time the NTP Server has been called
// and got a failed response
void updateDisplayNTPFailed(void) {
  static int count = 0;
  char buffer[128];
  count = count + 1;
  snprintf(buffer, sizeof(buffer), "NTP Update Failure = %d\n", count);
  GUI_SetFont(GUI_FONT_16_1);
  GUI_DispStringHCenterAt(buffer, LCD_GetXSize() / 2,
                          LCD_GetYSize() -
                              2 * GUI_GetFontSizeY()); // near the bottom
}
// updateDisplayNTPCount
// updates the display with the number of time the NTP Server has been called
void updateDisplayNTPCount(void) {
  static int count = 0;
  char buffer[128];
  count = count + 1;
  snprintf(buffer, sizeof(buffer), "NTP Updates = %d\n", count);
  GUI_SetFont(GUI_FONT_16_1);
  GUI_DispStringHCenterAt(buffer, LCD_GetXSize() / 2,
                          LCD_GetYSize() -
                              GUI_GetFontSizeY()); // near the bottom
}
// updateDisplayTime
// This function updates the time on the screen
void updateDisplayTime() {
  time_t rawtime;
  struct tm *timeinfo;
  char buffer[128];
  time(&rawtime);
  // rawtime = rawtime - (4*60*60); // UTC - 4hours ... serious hack which only
  // works in summer
  rawtime = rawtime + 3600; // GMT + 1 for BST
  timeinfo = localtime(&rawtime);
  strftime(buffer, sizeof(buffer), " %T  ", timeinfo);
  GUI_SetFont(GUI_FONT_32B_1);
  GUI_DispStringHCenterAt(buffer, LCD_GetXSize() / 2,
                          LCD_GetYSize() / 2 - GUI_GetFontSizeY() / 2 - 20);
  printf("%s%c[K\r\n", buffer, 0x1b);
  strftime(buffer, sizeof(buffer), " %A   ", timeinfo);
  GUI_SetFont(GUI_FONT_32B_1);
  GUI_DispStringHCenterAt(buffer, LCD_GetXSize() / 2,
                          LCD_GetYSize() / 2 - GUI_GetFontSizeY() / 2 + 20);
  printf("%s%c[K\r\n", buffer, 0x1b);
  strftime(buffer, sizeof(buffer), " %d/%m/%y   ", timeinfo);
  GUI_SetFont(GUI_FONT_32B_1);
  GUI_DispStringHCenterAt(buffer, LCD_GetXSize() / 2,
                          LCD_GetYSize() / 2 - GUI_GetFontSizeY() / 2 + 60);
  printf("%s%c[K\r\n", buffer, 0x1b);
#ifdef CY8CKIT_TFT
  sprintf(buffer, " Light = %d%c   ", int(lightlevel * 100), '%');
  GUI_SetFont(GUI_FONT_32B_1);
  GUI_DispStringHCenterAt(buffer, LCD_GetXSize() / 2,
                          LCD_GetYSize() / 2 - GUI_GetFontSizeY() / 2 - 60);
  printf("%s%c[K", buffer, 0x1b);
#else
  float temperature =
      (B_CONSTANT /
       (logf((R_REFERENCE / (1 / TempAverage - 1)) / R_INFINITY))) +
      ABSOLUTE_ZERO;

  sprintf(buffer, " Temperature = %d.%1d C\r\n", int(temperature),
          int((temperature - (int)temperature) * 10));
  GUI_SetFont(GUI_FONT_32B_1);
  GUI_DispStringHCenterAt(buffer, LCD_GetXSize() / 2,
                          LCD_GetYSize() / 2 - GUI_GetFontSizeY() / 2 - 60);
  printf("%s%c[K\r", buffer, 0x1b);
#endif
  printf("%c[4A", 0x1b);  // Cursor up 4
}
void readSensors() {
  PwrEnable = 1;
#ifdef CY8CKIT_TFT
  static int lcount = 0;
  static float Light[8];
  Light[lcount] = ALS;
  lcount = (lcount + 1) & 0x7;
  if (lcount == 0) {
    lightlevel = 0;
    for (int i = 0; i < 8; i++)
      lightlevel += Light[i];
    lightlevel = lightlevel / 8;
#ifdef SENSOR_BOARD
    lightlevel = 1 - lightlevel;
#endif
#else
  ThermGnd = 0;
  static int lcount = 0;
  static float Therm[8];
  float thermValue;
  float rThermistor;
  thermValue = Thermistor;
  Therm[lcount] = thermValue;
  lcount = (lcount + 1) & 0x7;
  if (lcount == 0) {
    TempAverage = 0;
    for (int i = 0; i < 8; i++)
      TempAverage += Therm[i];
    TempAverage = TempAverage / 8;
    /*        rThermistor = (R_REFERENCE/(1 / TempAverage -1 ));
     *       temperature =
     *         (B_CONSTANT / (logf(rThermistor / R_INFINITY))) + ABSOLUTE_ZERO;
     *
     *       temperature = (B_CONSTANT / (logf((R_REFERENCE / ( 1 / TempAverage
     * - 1 )) / R_INFINITY))) + ABSOLUTE_ZERO;
     *
     *        printf("Temp is %d\r\n",(int)(temperature*10));
     *        for (int i = 0; i < 8; i++)
     *            printf("%d ", (int)(Therm[i]*1000));
     *        printf("therm=%d\r\n", (int)(thermValue*1000));
     */

#endif
    PwrEnable = 0;
  }
}
/******************************************************************************************
 * NTPTimeThread
 * This thread calls the NTP Timeserver to get the UTC time
 * It then updates the time in the RTC
 * And it updates the display by adding an event to the display queue
 ********************************************************************************************/
void NTPTimeThread() {
  static time_t old_timestamp = 0, timestamp;
  NTPClient ntpclient(wifi);
  while (1) {
    if (wifi->get_connection_status() == NSAPI_STATUS_GLOBAL_UP) {
      timestamp = ntpclient.get_timestamp();
      if (timestamp < 1593627000) {
        displayQueue->call(updateDisplayNTPFailed);
        printf("faulty timestamp %d\r\n", timestamp);
      } else {
        set_time(timestamp);
        old_timestamp = timestamp;
        displayQueue->call(updateDisplayNTPCount);
      }
    }
    ThisThread::sleep_for(300s); // Goto the NTP server every 5 minutes
  }
}
/******************************************************************************************
 *
 * Main & WiFi Thread
 *
 ********************************************************************************************/
// wifiStatusCallback
// Changes the display when the wifi status is changed
void wifiStatusCallback(nsapi_event_t status, intptr_t param) {
  const int buffSize = 40;
  char *statusText;
  SocketAddress a;
  statusText = (char *)malloc(buffSize);
  switch (param) {
  case NSAPI_STATUS_LOCAL_UP:
    wifi->get_ip_address(&a);
    snprintf(statusText, buffSize, "WiFi IP = %s", a.get_ip_address());
    break;
  case NSAPI_STATUS_GLOBAL_UP:
    wifi->get_ip_address(&a);
    snprintf(statusText, buffSize, "WiFi IP = %s", a.get_ip_address());
    break;
  case NSAPI_STATUS_DISCONNECTED:
    WiFiSemaphore.release();
    snprintf(statusText, buffSize, "WiFi Disconnected");
    break;
  case NSAPI_STATUS_CONNECTING:
    snprintf(statusText, buffSize, "WiFi Connecting");
    break;
  default:
    snprintf(statusText, buffSize, "Not Supported");
    break;
  }
  displayQueue->call(updateDisplayWiFiStatus, statusText);
}
int main() {
  int wifiConnectionAttempts;
  int ret;
  GUI_Init();
  printf("%c[2J", 0x1b);   // Clear Screen
  printf("%c[?25l", 0x1b); // Cursor Off
  printf("%c[H", 0x1b); // Cursor Home
  displayQueue = mbed_event_queue();
  displayQueue->call_every(1s, &updateDisplayTime);
  displayQueue->call_every(100ms, &readSensors);
  wifi = WiFiInterface::get_default_instance();
  wifi->attach(&wifiStatusCallback);

  while (1) {
    wifiConnectionAttempts = 1;
    do {
      ret = wifi->connect(MBED_CONF_APP_WIFI_SSID, MBED_CONF_APP_WIFI_PASSWORD,
                          NSAPI_SECURITY_WPA_WPA2);
      displayQueue->call(updateDisplayWiFiConnectAttempts,
                         wifiConnectionAttempts);
      if (ret != 0) {
        wifiConnectionAttempts += 1;
        ThisThread::sleep_for(
            2s); // If for some reason it doesnt work wait 2s and try again
      }
    } while (ret != 0);
    // If the NTPThread is not running... then start it up
    if (netTimeThreadHandle.get_state() == Thread::Deleted)
      netTimeThreadHandle.start(NTPTimeThread);
    WiFiSemaphore.acquire();
  }
}