Priliminary

Dependencies:   DS1307 MAX17048 MODSERIAL SSD1308_128x64_I2C WatchDog mbed-rpc mbed

Fork of ECGAFE_copy by Zainul Charbiwala

main.cpp

Committer:
zainulcharbiwala
Date:
2015-09-30
Revision:
0:ee0649a9025a

File content as of revision 0:ee0649a9025a:

// Copyright 2013, Zainul Charbiwala

/* Includes */
#include "mbed.h"
#include "ADS1298.h"
#include "SSD1308.h"
#include "ds1307.h"
#include "MAX17048.h"
#include "WatchDog.h"
#include "oledicons.h"
#include "mbed_rpc.h"
#include "DebouncedIn.h"
#include "MODSERIAL.h"

/* mbed Objects */
DigitalOut myled(LED1);
DigitalOut lWatchdog(LED4);
WatchDog_ms wdt(10000);
Ticker wdtTicker;
MODSERIAL pc(USBTX, USBRX);
Timer tt;
I2C i2c(p28, p27); // sda, scl
SSD1308 oled = SSD1308(i2c, SSD1308_SA0);
ADS1298 ads = ADS1298(p5, p6, p7, p24, p23, p22, p21); //mosi, miso, sclk, cs, reset, drdy, start
DS1307 rtc(p28,p27); // start DS1307 class and give it pins for connections of the DS1307 device
MAX17048 gauge(p28, p27);
DigitalIn battChging(p14);           
DebouncedIn button(p20);

/* Constants */
#define OLEDPAGEMAX 14
// Page 0 for general use
// Page 1-12 for signals
// Page 13 for network status
// Page 14 for something else

/* Global Variables */
uint8_t buf[27];
char rpcInBuf[256], rpcOutBuf[256];
int vCapturing;

static char oledstr[16];
static int vOledPage;

/* External Functions */

/* Local Functions */
static void dataReady(void);
static void wdtKicker();
static void oledBattery(uint8_t percentage, uint8_t charging);
static void oledNetwork(uint8_t percentage, const char *mode);
static void oledTime();
static void fCaptureStart(Arguments *arg, Reply *r);
static void fCaptureStop(Arguments *arg, Reply *r);
static void fButtonLongPress();
static void fButtonShortPress();
static void fOledPage0();
static void fOledPageSignal();
static void fOledPageNetwork();
static void fOledPageSomethingElse();


/* RPC Variables */
RPCVariable<int> rpc_vCapturing(&vCapturing, "vCapturing");

/* RPC Functions */
RPCFunction rpc_fCaptureStart(&fCaptureStart, "fCaptureStart");
RPCFunction rpc_fCaptureStop(&fCaptureStop, "fCaptureStop");


static void wdtKicker() {
        wdt.feed();
}

static void fCaptureStart(Arguments *arg, Reply *r){
  vCapturing = 1;                                                 
  ads.startCapture();
  oled.writeString(7, 0, "Capture started.");
}

static void fCaptureStop(Arguments *arg, Reply *r){
  vCapturing = 0;                                                 
  ads.stopCapture();
  oled.writeString(7, 0, "Capture stopped.");                                                 
}

static void fOledPage0() {
  oled.writeString(5, 0, "  HR:  xxx bpm  ");
  oled.writeString(6, 0, "  LO:           ");

  sprintf(oledstr, "Display Page: %02d", vOledPage); 
  oled.writeString(7, 0, oledstr);
  
}

static void fOledPageSignal() {
  sprintf(oledstr, "Display Page: %02d", vOledPage); 
  oled.writeString(7, 0, oledstr);
  
}

static void fOledPageNetwork() {
  sprintf(oledstr, "Display Page: %02d", vOledPage); 
  oled.writeString(7, 0, oledstr);
  
}

static void fOledPageSomethingElse() {
  sprintf(oledstr, "Display Page: %02d", vOledPage); 
  oled.writeString(7, 0, oledstr);
  
}

static void fButtonShortPress()
{
  // Scroll to the next page of the oled display
  vOledPage++;
  if (vOledPage > OLEDPAGEMAX) {
    vOledPage = 0;
  }
  if (vOledPage == 0) {
    fOledPage0();
  }
  if (vOledPage >= 1 && vOledPage <= 12) {
    fOledPageSignal();
  }
  if (vOledPage == 13) {
    fOledPageNetwork();
  }
  if (vOledPage == 0) {
    fOledPageSomethingElse();
  }
}

static void fButtonLongPress()
{
  // If in capture mode, stop capture
  // If not in capture mode, start capture 
  if (vCapturing) {
    oled.writeString(7, 0, "Capture Stopping");
    fCaptureStop(NULL, NULL);
  } else {
    oled.writeString(7, 0, "Capture Starting");
    fCaptureStart(NULL, NULL);
  }
}


static void oledBattery(uint8_t percentage, uint8_t charging)
{
    // Hardcoded a 24 column, 1 page high battery meter icon
    // It has 18 columns that can be set
    uint8_t battimg[24];
    uint8_t i;
    percentage=(percentage>100?100:percentage);
    memcpy((uint8_t *)battimg, (uint8_t *)iconBattery, 24);
    for (i=2; i<2+(18*percentage)/100; i++) {
        battimg[i] |= 0x3C;
    }
    
    if (charging) {
        for (i=0; i<20; i++) {
            battimg[i+2] ^= iconBattChg[i];
        }
    } 
    oled.writeBitmap((uint8_t*) battimg, 0, 0, 104, 127);
}

static void oledNetwork(uint8_t percentage, const char *mode)
{
    // Hardcoded a 16 column, 1 page high network meter icon
    // It has 6 columns that can be set
    uint8_t netwimg[16];
    percentage=(percentage>100?100:percentage);
    memcpy((uint8_t *)netwimg, (uint8_t *)iconNetwork, 16);
    
    if (percentage > 0)
        netwimg[1] = 0xF0;
    if (percentage > 16)
        netwimg[2] = 0xF0;
    if (percentage > 33)
        netwimg[6] = 0xFC;
    if (percentage > 49)
        netwimg[7] = 0xFC;
    if (percentage > 66)
        netwimg[11] = 0xFF;
    if (percentage > 83)
        netwimg[12] = 0xFF;
   
    oled.writeBitmap((uint8_t*) netwimg, 0, 0, 0, 15);
    oled.writeString(0, 2, mode);
}

static void oledTime()
{
    int sec = 0, min = 0, hours = 0;
    int day = 0, date = 0, month = 0, year = 0;
    int ret = 0;

    char timestr[7];
    ret = rtc.gettime( &sec, &min, &hours, &day, &date, &month, &year);
    if (ret == 0) {
        if (hours == 0) {
            sprintf(timestr, "%02d:%02da", hours+12, min);
        } else if (hours == 12) {
            sprintf(timestr, "%02d:%02dp", hours, min);        
        } else if (hours>12) {
            sprintf(timestr, "%02d:%02dp", hours-12, min);
        } else {
            sprintf(timestr, "%02d:%02da", hours, min);
        }
        oled.writeString(0, 5, timestr);
    } else {
        oled.writeString(0, 5, "00:00!");
    }
    
}

static void fSetTime()
{
}

void dataReady()
{
  ads.readData(buf);
  ads.updateLeadOff(buf);
    
  if (vCapturing) {
    // Send it to the serial port
    // How much time does this take ?
    // We have 2ms until the next interrupt comes
    //pc.printf("\r\n%d", tt.read_ms());
    for (int i=0; i<27; i++) {
        //if (!(i%3)) pc.printf(" ");
        //pc.printf("%02x", buf[i]);
        pc.putc(buf[i]);
    }
  }
  myled = !myled;
}



int main() {
    uint8_t lev=0;
    char ch;

    vOledPage = 0;
    vCapturing = 0;
    i2c.frequency(400000); // according to the spec the max bitrate for the SSD1308 is 400 kbit/s
    battChging.mode(PullUp);
    pc.baud(921600);
    pc.printf("starting\r\n");

    wdtTicker.attach(&wdtKicker, 5);

    myled=1;
    oled.setDisplayOn();
    oled.writeString(7, 0, "Initializing... ");
    ads.initialize(&dataReady);
    if (!gauge.open()) {
        oled.writeString(7, 0, "Gauge Error !!!");
        wait(5);
    }
    
    fCaptureStart(NULL, NULL);
    
    while(1) {
      wait(0.1);
      
      // Check if there's a command over RPC
      if (pc.readable()) {
        pc.gets(rpcInBuf, 256);
        RPC::call(rpcInBuf, rpcOutBuf); 
        //pc.printf("%s", rpcOutBuf);
      }
      
      // Check if there's a user event
      if (button.releasing()) {
        // Short press
        if (button.pressed() < 50) {
          fButtonShortPress();
        } 
        // Long press
        if (button.pressed() > 100) {
          fButtonLongPress();
        }
      }
      
      // Update battery status icon
      oledBattery(gauge.socInt(), !battChging);
      // Update time
      oledTime();
      // Update network
      if (++lev > 100) lev = 0;
      oledNetwork(lev, "H");
    
      //Print the current state of charge
      sprintf(oledstr, "VCell = %.2fV\n", gauge.vcell());
      oled.writeString(3, 0, oledstr);
    
      //myled = !myled;
    }


}