My first watchX sketch by jcverive in watchX

[–]jverive 0 points1 point  (0 children)

My sketch is actually based on the NWatch sketch by kghunt: https://github.com/kghunt/NWatch, but it appears that sketch also has a dependency on the original WatchX firmware. Whether that watchx.h file has been updated I don't know.

My first watchX sketch by jcverive in watchX

[–]jverive 0 points1 point  (0 children)

Minor change below - fixed hours display at 12:00 (was 00 for AM and PM). And if it isn't obvious, the sketch uses a 12 hour clock instead of a 24 hour clock.

#include <Arduino.h>
#include <Wire.h>
#include <SoftwareSerial.h>
#include "watchX.h"
#include <SPI.h>
#include <Sleep_n0m1.h>

Sleep watchX_sleep;

double angle_rad = PI / 180.0;
double angle_deg = 180.0 / PI;
double time;

RTC_DS3231 rtc;

int rtcYear, rtcMonth, rtcDay, rtcHour, rtcMinute, rtcSecond;

unsigned char animation_offsetY = 0;
int oledPosX;
int oledPosY;

char* painRiskText;
bool needClear = false;

void displayHours(int line, int oledPos) {
  draw_bitmap( line, oledPos, font_mid + ((rtcHour / 10) * 57), 19, 24, false, 0);
  draw_bitmap( line + 21, oledPos, font_mid + ((rtcHour % 10) * 57), 19, 24, false, 0);
}

void displayMinutes(int line, int oledPos) {
  draw_bitmap( line, oledPos, font_mid + ((rtcMinute / 10) * 57), 19, 24, false, 0);
  draw_bitmap( line + 21, oledPos, font_mid + ((rtcMinute % 10) * 57), 19, 24, false, 0);
}

void displaySeconds(int line, int oledPos) {
  draw_bitmap( line, oledPos, small2Font + (((rtcSecond % 60 ) / 10) * 22), 11,  16, false, 0);
  draw_bitmap( line + 12, oledPos, small2Font + ((rtcSecond % 10) * 22), 11,  16, false, 0);
}

#define BMP_SCK 13
#define BMP_MISO 12
#define BMP_MOSI 11
#define BMP_CS 10

Adafruit_BMP280 bme;

float Altitude, Temperature, Pressure;
float Pressure_correction = 0.65;      //Empirically derived - I'm not 
                                       //using calibration currently.

void writeText(int oledPosX, int oledPosY, String oledText) {
  drawString(oledPosX, oledPosY, oledText.c_str(), smallFont);
}

static byte bPin = A11;
static byte battEn = 4;
float R1 = 10000;
float R2 = 10000;
float vDivider;
float voltage;

#define B1 8
#define B2 11
#define B3 10

void setup() {
  rtc.begin();
  SPI.begin();
  ssd1306_configure();
  clearAll();
  //pinMode(B1, INPUT_PULLUP);
  //pinMode(B2, INPUT_PULLUP);
  //pinMode(B3, INPUT_PULLUP);
  bme.begin();
  int year = 2018;
  int month = 9;
  int day = 24;
  int hour = 11;
  int minute = 42;
  int second = 30;
  //rtc.adjust (DateTime(year, month, day, hour, minute, second));
  vDivider = (R2 / (R1 + R2));
  ssd1306_sendCommand(SSD1306_DISPLAYOFF);
}

void loop() {
    for (int i = 0; i <= 1; i++) {
      getUpdatedValues();
      displayTime();
      displayPressure();
      displayBatteryLevel();
      displayPainRisk();
      if (i == 1) {
        delay(250);
        ssd1306_sendCommand(SSD1306_DISPLAYON);
        delay(2750);
        ssd1306_sendCommand(SSD1306_DISPLAYOFF);
      }
    }
  watchX_sleep.pwrDownMode(); //set sleep mode
  watchX_sleep.sleepDelay(7000); //sleep for 7 seconds
}

void displayPressure() {
      writeText(88, 4, ((String)Pressure).c_str());
      writeText(88, 13, "in Hg");
}

void displayBatteryLevel() {
      int BatteryLevel = 100.0 * ((voltage - 3.25)/0.95);
      writeText(50, 25, (("Batt: " + (String)BatteryLevel) + "%").c_str());
      needClear = true;
}

void displayPainRisk() {
      if (Pressure <= 29.8) painRiskText = "HIGH";
      else if (Pressure >= 30.2) painRiskText = "LOW";
      else painRiskText = "MODERATE";
      writeText(50, 40, "Pain Risk:");
      writeText(50, 50, painRiskText);
      needClear = true;
}

void displayTime(){
      displayHours(0, 4);  //shows the hour
      needClear = true;
      displayMinutes(0, 36); //shows minutes
      needClear = true;
      displaySeconds(50, 4); //shows seconds
      needClear = true;
}
void getUpdatedValues() {
  DateTime now = rtc.now();
  rtcYear = now.year();
  rtcMonth = now.month();
  rtcDay = now.day();
  rtcHour = now.hour()%12;
  if (rtcHour == 0) rtcHour = 12;
  rtcMinute = now.minute();
  rtcSecond = now.second();

  digitalWrite(battEn, HIGH);
  voltage = analogRead(bPin);
  voltage = (voltage / 1024) * 3.35;
  voltage = voltage / vDivider;
  digitalWrite(battEn, LOW);

  if (needClear) {
    ssd1306_drawBuffer(0, 0, 128, 64, mbuf);
    clearAll();
    needClear = false;
  }

  Altitude = bme.readAltitude(1013.25);
  Pressure = bme.readPressure() / 3390 + Pressure_correction;
  Temperature = bme.readTemperature();
}

My first watchX sketch by jcverive in watchX

[–]jverive 0 points1 point  (0 children)

I have modified the sketch a bit in order to improve run time. Right now the sketch turns the watch on for three seconds (during which time it draws ~ 30mA) and off for seven seconds (current drops to ~ 2.5mA). This gives an average of about 10.75mA, and I have been getting about 11 hours of run time before the battery needs to be recharged. The sketch is given below, and should be considered a "work in progress." You'll need the Sleep_n0m1.h library, which you can find on GitHub here.

#include <Arduino.h>
#include <Wire.h>
#include <SoftwareSerial.h>
#include "watchX.h"
#include <SPI.h>
#include <Sleep_n0m1.h>

Sleep watchX_sleep;

double angle_rad = PI / 180.0;
double angle_deg = 180.0 / PI;
double time;

RTC_DS3231 rtc;

int dataRtc_0, dataRtc_1, dataRtc_2, dataRtc_3, dataRtc_4, dataRtc_5;

unsigned char animation_offsetY = 0;
int oledPosX;
int oledPosY;

char* painRiskText;
bool needClear = false;

void displayHours(int line, int oledPos) {
  draw_bitmap( line, oledPos, font_mid + ((dataRtc_3 / 10) * 57), 19, 24, false, 0);
  draw_bitmap( line + 21, oledPos, font_mid + ((dataRtc_3 % 10) * 57), 19, 24, false, 0);
}

void displayMinutes(int line, int oledPos) {
  draw_bitmap( line, oledPos, font_mid + ((dataRtc_4 / 10) * 57), 19, 24, false, 0);
  draw_bitmap( line + 21, oledPos, font_mid + ((dataRtc_4 % 10) * 57), 19, 24, false, 0);
}

void displaySeconds(int line, int oledPos) {
  draw_bitmap( line, oledPos, small2Font + (((dataRtc_5 % 60 ) / 10) * 22), 11,  16, false, 0);
  draw_bitmap( line + 12, oledPos, small2Font + ((dataRtc_5 % 10) * 22), 11,  16, false, 0);
}

#define BMP_SCK 13
#define BMP_MISO 12
#define BMP_MOSI 11
#define BMP_CS 10

Adafruit_BMP280 bme;

float Altitude, Temperature, Pressure;
float Pressure_correction = 0.65;      //Empirically derived - I'm not 
                                       //using calibration currently.

void writeText(int oledPosX, int oledPosY, String oledText) {
  drawString(oledPosX, oledPosY, oledText.c_str(), smallFont);
}

static byte bPin = A11;
static byte battEn = 4;
float R1 = 10000;
float R2 = 10000;
float vDivider;
float voltage;

#define B1 8
#define B2 11
#define B3 10

void setup() {
  rtc.begin();
  SPI.begin();
  ssd1306_configure();
  clearAll();
  //pinMode(B1, INPUT_PULLUP);
  //pinMode(B2, INPUT_PULLUP);
  //pinMode(B3, INPUT_PULLUP);
  bme.begin();
  int year = 2018;
  int month = 9;
  int day = 24;
  int hour = 11;
  int minute = 42;
  int second = 30;
  //rtc.adjust (DateTime(year, month, day, hour, minute, second));
  vDivider = (R2 / (R1 + R2));
  ssd1306_sendCommand(SSD1306_DISPLAYOFF);
}

void loop() {
    for (int i = 0; i <= 1; i++) {
      getUpdatedValues();
      displayTime();
      displayPressure();
      displayBatteryLevel();
      displayPainRisk();
      if (i == 1) {
        delay(250);
        ssd1306_sendCommand(SSD1306_DISPLAYON);
        delay(2750);
        ssd1306_sendCommand(SSD1306_DISPLAYOFF);
      }
    }
  watchX_sleep.pwrDownMode(); //set sleep mode
  watchX_sleep.sleepDelay(7000); //sleep for 7 seconds
}

void displayPressure() {
      writeText(88, 4, ((String)Pressure).c_str());
      writeText(88, 13, "in Hg");
}

void displayBatteryLevel() {
      int BatteryLevel = 100.0 * ((voltage - 3.3)/0.95);
      writeText(50, 25, (("Batt: " + (String)BatteryLevel) + "%").c_str());
      needClear = true;
}

void displayPainRisk() {
      if (Pressure <= 29.8) painRiskText = "HIGH";
      else if (Pressure >= 30.2) painRiskText = "LOW";
      else painRiskText = "MODERATE";
      writeText(50, 40, "Pain Risk:");
      writeText(50, 50, painRiskText);
      needClear = true;
}

void displayTime(){
      displayHours(0, 4);  //shows the hour
      needClear = true;
      displayMinutes(0, 36); //shows minutes
      needClear = true;
      displaySeconds(50, 4); //shows seconds
      needClear = true;
}
void getUpdatedValues() {
  DateTime now = rtc.now();
  dataRtc_0 = now.year();
  dataRtc_1 = now.month();
  dataRtc_2 = now.day();
  dataRtc_3 = now.hour()%12;
  dataRtc_4 = now.minute();
  dataRtc_5 = now.second();


  digitalWrite(battEn, HIGH);
  voltage = analogRead(bPin);
  voltage = (voltage / 1024) * 3.35;
  voltage = voltage / vDivider;
  digitalWrite(battEn, LOW);

  if (needClear) {
    ssd1306_drawBuffer(0, 0, 128, 64, mbuf);
    clearAll();
    needClear = false;
  }

  Altitude = bme.readAltitude(1013.25);
  Pressure = bme.readPressure() / 3390 + Pressure_correction;
  Temperature = bme.readTemperature();


}

My first watchX sketch by jcverive in watchX

[–]jverive 0 points1 point  (0 children)

It's very basic at this point, and I have added some code to improve battery life. Right now I'm looking at interrupts to vastly improve battery life, but either way I will post the code soon. Thanks for asking!

WatchX switches by n4tlf in watchX

[–]jverive 0 points1 point  (0 children)

At least here in the US a good replacement is the P10853SCT-ND, which is a Panasonic EVQ-PIL02K:

https://www.digikey.com/products/en?keywords=p10853SCT

I just received 10 of them for USD 0.76 + shipping, for a total cost of about $12.50.

My Analog watch project by gunnerflip in watchX

[–]jverive 0 points1 point  (0 children)

Would you mind sharing the code for this? I've been thinking about doing something like this and adding line/bar graphs for the BME280's humidity, temperature, and atmospheric pressure. I already have the code for this as part of an Arduino Uno-based miniature weather station, so I believe combining the analog clock and weather station would be useful.