Sunday, May 8, 2016

My DiY Smartwatch Project: Teensy LC is the clear Winner(for now)

I have decided to use the Teensy-LC for now because of the availability of libraries, easy to use, lots of existing examples and so many ports and digital/anolog/pwm pins. I am ditching Esp-12E and I will be using ESP-01 instead as the wifi module. And it's a weekend and I had spent sometime creating a simple sketch to make the smartwatch work. And so far, I have created a sketch using the ESP-01, 1.44" tft screen and the expensive 4-wire touch panel. Below is the connection diagram I used:
I even had to prepare a development board for ESP-12 and included in the board the 1.44"tft lcd with the 4-wire touch panel attached into its surface. I was so lucky that the technician I hired did not made any mistake and the soldering is like a pro:


The sketch I created is based on the existing examples when I loaded the teensyduino into the Arduino IDE. I also used the adafrruit 4-wire touch panel library and I did not had difficulty using it.  To summarize what the sketch do, I program the whole screen as a button, so when I hard-press the screen, it will automatically activate the wifi to search for existing wifi hotspots and display them on the screen and after 5 seconds, it display the wartch face again.
here is the watchface:
And here is the sketch:
#include <stdint.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <TFT_ILI9163C.h>
#include "TouchScreen.h"
// Color definitions
#define    BLACK   0x0000
#define    BLUE    0x001F
#define    RED     0xF800
#define    GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0 
#define WHITE   0xFFFF
#define YP A0  // must be an analog pin, use "An" notation!
#define XM A1  // must be an analog pin, use "An" notation!
#define YM 6   // can be a digital pin
#define XP 7   // can be a digital pin
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);

/*
Teensy3.x and Arduino's
You are using 4 wire SPI here, so:
 MOSI:  11//Teensy3.x/Arduino UNO (for MEGA/DUE refere to arduino site)
 MISO:  12//Teensy3.x/Arduino UNO (for MEGA/DUE refere to arduino site)
 SCK:   13//Teensy3.x/Arduino UNO (for MEGA/DUE refere to arduino site)
 the rest of pin below:
 */
#define __CS 10
#define __DC 9
/*
Teensy 3.x can use: 2,6,9,10,15,20,21,22,23
Arduino's 8 bit: any
DUE: check arduino site
If you do not use reset, tie it to +3V3
*/


TFT_ILI9163C tft = TFT_ILI9163C(__CS, __DC,8);

uint16_t ccenterx,ccentery;//center x,y of the clock
const uint16_t cradius = 63;//radius of the clock
const float scosConst = 0.0174532925;
float sx = 0, sy = 1, mx = 1, my = 0, hx = -1, hy = 0;
float sdeg=0, mdeg=0, hdeg=0;
uint16_t osx,osy,omx,omy,ohx,ohy;
uint16_t x0 = 0, x1 = 0, yy0 = 0, yy1 = 0;
uint32_t targetTime = 0;// for next 1 second timeout
uint8_t hh,mm,ss;  //containers for current time


void drawClockFace(){
  tft.fillCircle(ccenterx, ccentery, cradius, BLUE);
  tft.fillCircle(ccenterx, ccentery, cradius-4, BLACK);
  // Draw 12 lines
  for(int i = 0; i<360; i+= 30) {
    sx = cos((i-90)*scosConst);
    sy = sin((i-90)*scosConst);
    x0 = sx*(cradius-4)+ccenterx;
    yy0 = sy*(cradius-4)+ccentery;
    x1 = sx*(cradius-11)+ccenterx;
    yy1 = sy*(cradius-11)+ccentery;
    tft.drawLine(x0, yy0, x1, yy1, BLUE);
  }
}

static uint8_t conv2d(const char* p) {
  uint8_t v = 0;
  if ('0' <= *p && *p <= '9') v = *p - '0';
  return 10 * v + *++p - '0';
}

void setup(void) {
  tft.begin();

  tft.setTextColor(WHITE, BLACK);
  ccenterx = tft.width()/2;
  ccentery = tft.height()/2;
  osx = ccenterx;
  osy = ccentery;
  omx = ccenterx;
  omy = ccentery;
  ohx = ccenterx;
  ohy = ccentery;
  drawClockFace();// Draw clock face
  //get current time from compiler
  hh = conv2d(__TIME__);
  mm = conv2d(__TIME__+3);
  ss = conv2d(__TIME__+6);
  targetTime = millis() + 1000;
   Serial.begin(9600);
   Serial1.begin(115200);
}

void drawClockHands(uint8_t h,uint8_t m,uint8_t s){
  // Pre-compute hand degrees, x & y coords for a fast screen update
  sdeg = s * 6;                  // 0-59 -> 0-354
  mdeg = m * 6 + sdeg * 0.01666667;  // 0-59 -> 0-360 - includes seconds
  hdeg = h * 30 + mdeg * 0.0833333;  // 0-11 -> 0-360 - includes minutes and seconds
  hx = cos((hdeg-90)*scosConst);   
  hy = sin((hdeg-90)*scosConst);
  mx = cos((mdeg-90)*scosConst);   
  my = sin((mdeg-90)*scosConst);
  sx = cos((sdeg-90)*scosConst);   
  sy = sin((sdeg-90)*scosConst);

  // Erase just old hand positions
  tft.drawLine(ohx, ohy, ccenterx+1, ccentery+1, BLACK); 
  tft.drawLine(omx, omy, ccenterx+1, ccentery+1, BLACK); 
  tft.drawLine(osx, osy, ccenterx+1, ccentery+1, BLACK);
  // Draw new hand positions 
  tft.drawLine(hx*(cradius-28)+ccenterx+1, hy*(cradius-28)+ccentery+1, ccenterx+1, ccentery+1, WHITE);
  tft.drawLine(mx*(cradius-17)+ccenterx+1, my*(cradius-17)+ccentery+1, ccenterx+1, ccentery+1, WHITE);
  tft.drawLine(sx*(cradius-14)+ccenterx+1, sy*(cradius-14)+ccentery+1, ccenterx+1, ccentery+1, RED);
  tft.fillCircle(ccenterx+1, ccentery+1, 3, RED);

  // Update old x&y coords
  osx = sx*(cradius-14)+ccenterx+1;
  osy = sy*(cradius-14)+ccentery+1;
  omx = mx*(cradius-17)+ccenterx+1;
  omy = my*(cradius-17)+ccentery+1;
  ohx = hx*(cradius-28)+ccenterx+1;
  ohy = hy*(cradius-28)+ccentery+1;
}


void loop() {
  delay(100);
   TSPoint p = ts.getPoint();
   if (p.x > 300 and p.y > 300 and p.z < 300) {
  tft.fillScreen();
  tft.setCursor(0, 0);
  tft.setTextColor(WHITE);
  tft.setTextSize(2);
  tft.println("CHECK WIFI NETWORKS");
  tft.setTextColor(BLUE);
   tft.setTextSize(1);
  Serial1.write("AT+CWLAP\r\n");
  delay(500);
    while (Serial1.available()) {
        char c = Serial1.read();
        tft.print(c);
    }
  delay(5000);
  tft.fillScreen();
   tft.setTextColor(WHITE, BLACK);
  ccenterx = tft.width()/2;
  ccentery = tft.height()/2;
  osx = ccenterx;
  osy = ccentery;
  omx = ccenterx;
  omy = ccentery;
  ohx = ccenterx;
  ohy = ccentery;
  drawClockFace();// Draw clock face
  //get current time from compiler
  hh = conv2d(__TIME__);
  mm = conv2d(__TIME__+3);
  ss = conv2d(__TIME__+6);
  targetTime = millis() + 1000;
   }
   else {
  if (targetTime < millis()) {
    targetTime = millis()+1000;
    ss++;
    if (ss == 60) {
      ss = 0;
      mm++;
      if(mm > 59) {
        mm = 0;
        hh++;
        if (hh > 23) hh = 0;
      }
    }
    drawClockHands(hh,mm,ss);

   }
   }
}


Thursday, May 5, 2016

ESP-12E vs Teensy-LC for my DIY Smartwatch Project

Today, my Teensy-LC and ESP-12E just arrived and I am so excited to experiment with them over the weekend. I have not decided which of the two MCU's should I use for my DIY Smartwatch Project.So I want to list down their strength and weaknesses to help me which I should choose.

1. Microcontroller(MCU) Speed
Teensy uses MKL26Z64 ARM Based Chip rated at 40Mhz while ESP-12E uses ESP8266 which is rated at 80Mhz but can be overclocked at 160Mhz. Clearly, ESP-12E is the winner.

2. Arduino Compatibility
Recently ESP-12E and its variant can already be programmed using the Arduino IDE and while Teensy-LC is already programmable in the same IDE so both are tied on this. But I still don't know if all commands in Arduino is supported by both MCU's all I know is in the case of Teensy, some are not supported.

3. Power Consumptions in Sleep Mode and Normal Mode
I am totally new to this microcontrollers so I cant compare them based on this category. Probably when I get to program them, that will be the time for me to be able to decide which one is better than the other.

4. GPIO/Ports/Availability of Libraries
Teensy has so many GPIO's(dont know exactly how many), PWM Pins, 3 Serial Ports, 1 SPI Port and No built in RTC and since it can be programmed in the Arduino IDE, I assume the SPI, I2C libraries will work, while ESP-12E has very few exposed GPIO and PWM pins, 1 SPI and 1 I2C port and I also assume that the Arduino SPI and I2C libraries will work. It seems I have a problem here because I need at least 2 SPI ports(the LCD Display and SD Card uses SPI ports) because I have not tried connecting 2 devices in 1 SPI port but I have read somewhere that it is possible for several devices to share 1 SPI port. The smartwatch does not need too much GPIO and PWM pins. I give the credit to Teensy in this category though.

In conclusion, I am still not able to decide which one is better than the other although ES-12E has built-in wifi radio and while the Teensy do needs ESP-12E.