Часы стрелочные Ардуино Нано и 1.8TFT SPI

valeryLem
Offline
Зарегистрирован: 24.02.2017
//#include <TinyGPSplus.h>   //жпс парсер-источник точного времени
//#include <SoftwareSerial.h>//связь с модулем жпс
#include <SPI.h>
#include <TFT.h>  
#define cs   10
#define dc   8
#define rst  9
#define TFT_SCLK 13   // set these to be whatever pins you like! (slow connection)
#define TFT_MOSI 11   // set these to be whatever pins you like!
#define halfheght 64
#define halfwidth 80
#define seclen 50
#define minlen 48
#define hwrlen 40

// заготовка для данных от жпс
//static const uint32_t GPSBaud = 9600;
//TinyGPSPlus gps;//example of gps class
//SoftwareSerial ss(6, 7);//NMEA protocol connection

TFT TFTscreen = TFT(cs, dc, rst);
int clockCenterX=80;
int clockCenterY=64;
int oldsec=0;
volatile float x1, y1, x2, y2, x3, y3, x4, y4;
byte sec,mnt,hwr=0;


void drawSec(float s) {//отрисовка секундной стрелки
  float ps = s-1;
  TFTscreen.stroke(0, 0, 0);
  if (ps==-1)ps=59;
  ps=ps*6;
  ps=ps+270;
  drawSecHand(ps);
  TFTscreen.stroke(255, 0, 255);
  s=s*6;
  s=s+270;//270
  drawSecHand(s);
}

void drawSecHand(float s){
  x1=seclen*cos(s*0.0175); //6.28/360=001745
  y1=seclen*sin(s*0.0175);
  x2=5*cos(s*0.0175);
  y2=5*sin(s*0.0175); 
  Serial.print(s);  Serial.print("s,");Serial.print(s*0.0175);  Serial.println(":угол");  
  TFTscreen.line(x1+clockCenterX, y1+clockCenterY, x2+clockCenterX, y2+clockCenterY);
}
void drawHwrHand(float h){
  
  x1=hwrlen*cos(h*0.0175);
  y1=hwrlen*sin(h*0.0175);
  x2=5*cos(h*0.0175);
  y2=5*sin(h*0.0175);
  x3=20*cos((h+5)*0.0175);
  y3=20*sin((h+5)*0.0175);
  x4=20*cos((h-5)*0.0175);
  y4=20*sin((h-5)*0.0175);
  
  TFTscreen.line(x1+clockCenterX, y1+clockCenterY, x3+clockCenterX, y3+clockCenterY);
  TFTscreen.line(x3+clockCenterX, y3+clockCenterY, x2+clockCenterX, y2+clockCenterY);
  TFTscreen.line(x2+clockCenterX, y2+clockCenterY, x4+clockCenterX, y4+clockCenterY);
  TFTscreen.line(x4+clockCenterX, y4+clockCenterY, x1+clockCenterX, y1+clockCenterY);
}

void drawMinHand(float m){  

  x1=minlen*cos(m*0.0175);
  y1=minlen*sin(m*0.0175);
  x2=5*cos(m*0.0175);
  y2=5*sin(m*0.0175);
  x3=30*cos((m+4)*0.0175);
  y3=30*sin((m+4)*0.0175);
  x4=30*cos((m-4)*0.0175);
  y4=30*sin((m-4)*0.0175);
  
 TFTscreen.line(x1+clockCenterX, y1+clockCenterY, x3+clockCenterX, y3+clockCenterY);
 TFTscreen.line(x3+clockCenterX, y3+clockCenterY, x2+clockCenterX, y2+clockCenterY);
 TFTscreen.line(x2+clockCenterX, y2+clockCenterY, x4+clockCenterX, y4+clockCenterY);
 TFTscreen.line(x4+clockCenterX, y4+clockCenterY, x1+clockCenterX, y1+clockCenterY);
}

 
void drawDisplay()
{
  // Очистка дисплея
  TFTscreen.background(0, 0, 0);
  
  
  // Рисуем циферблат
  TFTscreen.stroke(255, 255, 255);
  TFTscreen.background(0, 0, 0);
  for (int i=0; i<3; i++)
  {
    TFTscreen.circle(clockCenterX, clockCenterY, halfheght-i);
  }
  for (int i=0; i<5; i++)
  {
    TFTscreen.circle(clockCenterX, clockCenterY, i);
  }
  
  //Отображаем числа на циферблате
  TFTscreen.stroke(192, 192, 255);
  TFTscreen.text("3", clockCenterX+halfwidth-28, clockCenterY-3);
  TFTscreen.text("6", clockCenterX-2, clockCenterY+halfheght-12);
  TFTscreen.text("9", clockCenterX-halfwidth+23, clockCenterY-3);
  TFTscreen.text("12", clockCenterX-8, clockCenterY-halfheght+6);
  
  //Рисуем метки часов в виде рысочек
  for (int i=0; i<12; i++)
  {
    if ((i % 3)!=0)
      drawMark(i);
  }  
 // t = rtc.getTime();
  drawMin(mnt);
  drawHour(hwr, mnt);
  drawSec(sec);
  oldsec=sec;
}
 
void drawMark(int h)//Отрисовка меток
{
  float x1, y1, x2, y2;
  h=h*30;
  h=h+270;
  
  x1=(halfheght-4)*cos(h*0.0175);
  y1=(halfheght-4)*sin(h*0.0175);
  x2=(halfheght-9)*cos(h*0.0175);
  y2=(halfheght-9)*sin(h*0.0175);
  
  TFTscreen.line(x1+clockCenterX, y1+clockCenterY, x2+clockCenterX, y2+clockCenterY);
}
 
 
void drawMin(int m)//отрисовка минутной стрелки
{
  int pm = m-1;
  
  TFTscreen.stroke(0, 0, 0);
  if (pm==-1)
    pm=59;
  pm=pm*6;
  pm=pm+270;
  
drawMinHand(pm);
 
  TFTscreen.stroke(0, 255, 0);
  m=m*6;
  m=m+270;
  
drawMinHand(m);

}
 
void drawHour(int h, int m)//отрисовка часовой стрелки
{
  int ph = h;
  
  TFTscreen.stroke(0, 0, 0);
  if (m==0)
  {
    ph=((ph-1)*30)+((m+59)/2);
  }
  else
  {
    ph=(ph*30)+((m-1)/2);
  }
  ph=ph+270;
  drawHwrHand(ph);
 
  TFTscreen.stroke(255, 255, 100);
  h=(h*30)+(m/2);
  h=h+270;
  
drawHwrHand(h);
}

void setup(){
  
  //Serial.begin(9600); //отладка
  //ss.begin(GPSBaud);  //связь с жпс
  TFTscreen.begin();
  TFTscreen.setTextSize(1);
  TFTscreen.background(0, 0, 0);
    drawDisplay();
}

void loop()//основной цикл работы стрелочных часов
{
   sec++;
  if (sec>59) {
    sec=0;
    mnt++;
    if (mnt>59) {
      mnt=0;
      hwr++;
      if (hwr>11) hwr=0;
    }
  }
  delay(100);//(1000)//100 - для отладки, 1000- работа
   int x, y;
  //t = rtc.getTime();
 
     if (oldsec!=sec)
     {
      int t1=0; 
       int t2=0;
       int t3=0;
      if(hwr>=12){
         t1=(hwr-12)*5;
       }
        else
       {
         t1=hwr*5;
      }
       t2=mnt/12;
      t3=t1+t2;
        byte a=mnt+1;
        byte b=mnt+2;
        byte c=mnt+3;
        byte d=t3+1;
        byte e=t3+2;
        byte f=t3+3;
        byte g=t3+4;
        if ((sec==d)||(sec==e)||(sec==f)||(sec==g))
       {
         drawHour(hwr,mnt);
       }
        if ((sec==a)||(sec==b)||(sec==c))
       {
        drawMin(mnt);
       }
    
      if (sec==0)
      {
        drawMin(mnt);
        drawHour(hwr, mnt);
      }
       
      drawSec(sec);
       oldsec=sec;
     }
     // Serial.print("часы-минуты ");Serial.print(hwr);Serial.println(mnt);

}

 

valeryLem
Offline
Зарегистрирован: 24.02.2017

Это модифицированный файл. При незначительной доработке с запасом влез в НАНО. 

Исходник взят сдесь http://arduino-project.net/analog-clock-arduino-mega/

Посмотреть можно здесь https://youtu.be/9y7nvNXAOv0

Дисплей цветной 1.8TFT SPI 128x160 ST7735

yucan
Offline
Зарегистрирован: 20.04.2015

Дисплей на каком контроллере?

valeryLem
Offline
Зарегистрирован: 24.02.2017

ST7735

valeryLem
Offline
Зарегистрирован: 24.02.2017

valeryLem
Offline
Зарегистрирован: 24.02.2017

Т.к. появился вопрос, я решил чуть почистить чужой код от избыточности. Это сообщение компоновщика: "Скетч использует 11694 байт (38%) памяти устройства. Всего доступно 30720 байт.Глобальные переменные используют 134 байт (6%) динамической памяти, оставляя 1914 байт для локальных переменных. Максимум: 2048 байт.",  код прилагаю...


//#include <TinyGPSplus.h>    //жпс парсер-источник точного времени
//#include <SoftwareSerial.h> //связь с модулем жпс 
//#include <Adafruit_BMP085.h>//и по i2c с датчиком давления BMP180
#include <SPI.h>
#include <TFT.h>  
#define cs   10
#define dc   8
#define rst  9
#define TFT_SCLK 13   // set these to be whatever pins you like! (slow connection)
#define TFT_MOSI 11   // set these to be whatever pins you like!
#define clockCenterY 64  //середина экрана
#define clockCenterX 80
#define seclen 50     //длины стрелок
#define minlen 48
#define hwrlen 40
 
//это заготовка для приема данных от жпс и 
//static const uint32_t GPSBaud = 9600;
//TinyGPSPlus gps;        //example of gps class
//SoftwareSerial ss(6, 7);//NMEA protocol connection
//Adafruit_BMP085 bmp;    //example of bmp180 class
 
TFT TFTscreen = TFT(cs, dc, rst);//
byte oldsec=0;
volatile float x1, y1, x2, y2, x3, y3, x4, y4;
byte sec,mnt,hwr=0;
 
void drawSecHand(float s){
  x1=seclen*cos(s*0.0175); //6.28/360=001745
  y1=seclen*sin(s*0.0175);
  x2=5*cos(s*0.0175);
  y2=5*sin(s*0.0175);  
  TFTscreen.line(x1+clockCenterX, y1+clockCenterY, x2+clockCenterX, y2+clockCenterY);
}
void drawHand(float m,byte l){  
  x1=l*cos(m*0.0175);
  y1=l*sin(m*0.0175);
  x2=5*cos(m*0.0175);
  y2=5*sin(m*0.0175);
  x3=20*cos((m+5)*0.0175);
  y3=20*sin((m+5)*0.0175);
  x4=20*cos((m-5)*0.0175);
  y4=20*sin((m-5)*0.0175); 
 TFTscreen.line(x1+clockCenterX, y1+clockCenterY, x3+clockCenterX, y3+clockCenterY);
 TFTscreen.line(x3+clockCenterX, y3+clockCenterY, x2+clockCenterX, y2+clockCenterY);
 TFTscreen.line(x2+clockCenterX, y2+clockCenterY, x4+clockCenterX, y4+clockCenterY);
 TFTscreen.line(x4+clockCenterX, y4+clockCenterY, x1+clockCenterX, y1+clockCenterY);
}
void drawDisplay(){
  // Рисуем циферблат
  TFTscreen.stroke(255, 255, 255);
  TFTscreen.background(0, 0, 0);
  for (int i=0; i<3; i++) TFTscreen.circle(clockCenterX, clockCenterY, clockCenterY-i);
  for (int i=0; i<5; i++) TFTscreen.circle(clockCenterX, clockCenterY, i);
  //Отображаем числа на циферблате
  TFTscreen.stroke(192, 192, 255);
  TFTscreen.text("3", 2*clockCenterX-28, clockCenterY-3);
  TFTscreen.text("6", clockCenterX-2, 2*clockCenterY-12);
  TFTscreen.text("9", 23, clockCenterY-3);
  TFTscreen.text("12", clockCenterX-8, 6); 
  //Рисуем метки часов в виде рисок
  for (int i=0; i<12; i++) if ((i % 3)!=0) drawMark(i);
}
 
void drawMark(int h){//Отрисовка меток
 
  h=h*30;
  h=h+270;
  x1=(clockCenterY-4)*cos(h*0.0175);
  y1=(clockCenterY-4)*sin(h*0.0175);
  x2=(clockCenterY-9)*cos(h*0.0175);
  y2=(clockCenterY-9)*sin(h*0.0175);
  TFTscreen.line(x1+clockCenterX, y1+clockCenterY, x2+clockCenterX, y2+clockCenterY);
}
 
void drawSec(float s) {//отрисовка секундной стрелки
  float ps = s-1;
  TFTscreen.stroke(0, 0, 0);
  if (ps==-1)ps=59;
  ps=ps*6;
  ps=ps+270;
  drawSecHand(ps);
  TFTscreen.stroke(255, 0, 255);
  s=s*6;
  s=s+270;//270
  drawSecHand(s);
void drawMin(float m) {//отрисовка минутной стрелки
  float pm = m-1;
  TFTscreen.stroke(0, 0, 0);
  if (pm==-1)pm=59;
  pm=pm*6;
  pm=pm+270;
  drawHand(pm,minlen);
  TFTscreen.stroke(0, 255, 0);
  m=m*6;
  m=m+270;
  drawHand(m,minlen);
}
 
void drawHour(float h, byte m){//отрисовка часовой стрелки
  float ph = h;
  TFTscreen.stroke(0, 0, 0);
  if (m==0)ph=((ph-1)*30)+((m+59)/2);
  else ph=(ph*30)+((m-1)/2);
  ph=ph+270;
  drawHand(ph,hwrlen);
  TFTscreen.stroke(255, 255, 100);
  h=(h*30)+(m/2);
  h=h+270;
  drawHand(h,hwrlen);
}
 
 void setup(){ 
  //Serial.begin(9600); //для отладки
  //ss.begin(GPSBaud);  //связь с жпс
  //bmp.begin(); связь по i2c-давление (пины А4,А5)
  TFTscreen.begin();
  TFTscreen.setTextSize(1);
  TFTscreen.background(0, 0, 0);
  drawDisplay();
}
 
void loop(){//основной цикл работы стрелочных часов
   sec++;
   if (sec>59) {
    sec=0;
    mnt++;
    if (mnt>59) {
      mnt=0;
      hwr++;
      if (hwr>11) hwr=0;
    }
  }
  delay(10);//(1000)//10- для отладки, 1000- работа
  if (oldsec!=sec){
      byte t1=0; 
      byte t2=0;
      byte t3=0;
      if(hwr>=12) t1=(hwr-12)*5;
        else      t1=hwr*5;
      t2=mnt/12;
      t3=t1+t2;
        byte a=mnt+1;
        byte b=mnt+2;
        byte c=mnt+3;
        byte d=t3+1;
        byte e=t3+2;
        byte f=t3+3;
        byte g=t3+4;
        if ((sec==d)||(sec==e)||(sec==f)||(sec==g))drawHour(hwr,mnt);
        if ((sec==a)||(sec==b)||(sec==c))drawMin(mnt);
        if (sec==0){
          drawMin(mnt);
          drawHour(hwr, mnt);
        }
        drawSec(sec);
        oldsec=sec;
     }
}
 
shinkorenko.m
Offline
Зарегистрирован: 13.01.2019

Этот скеч будет работать с модулем NEOWAY  M590E ?

Если будет, то как его вживить в скеч ?

valeryLem
Offline
Зарегистрирован: 24.02.2017

Я не в курсе. Между gps и gsm слишком велика разница.  У меня gps корректировал время, у них там на орбите оно точнее нашего по телевизору. А с другой стороны минуты ничго не решат. В любом случае для gps протокол обычно NMEA, и вопрос только в скорости обмена по rs232 или его модификациям

b707
Онлайн
Зарегистрирован: 26.05.2017

сорри за скепсис... но вообще аналоговые часы - это стандартный пример к библиотеке TFT экрана... В чем новизна конкретно вашего проекта?

valeryLem
Offline
Зарегистрирован: 24.02.2017

Хотелось вместить в мой камень, он меньше размером памяти. Заодно оптимизировать код. После этого я его еще двое сократил. Но это мало кого заинтересовало. Давно это было, сейчас я все пишу на ассемблере.

b707
Онлайн
Зарегистрирован: 26.05.2017

valeryLem пишет:

Хотелось вместить в мой камень, он меньше размером памяти.

А не подскажете, какой Вы камень использовали? - просто в заголовке темы указан Нано... В Нано-то скетч из примеров влезает легко, он по моему всего килобайт 10-12 занимает

Цитата:
сейчас я все пишу на ассемблере.

все? на ардуине? Большие проекты с разветвленной логикой - на асме?

Простите, но по-моему это бессмысленная трата времени. Какие-то небольшие критичные к времени куски - да, но весь проект...

 

valeryLem
Offline
Зарегистрирован: 24.02.2017

Кто-то играет в шахматы, кто-то пьет водку, кто-то мусорит в лесах и на озерах, много кто программирует на си++, я их не критикую. Не могу критиковать того, кого не понимаю. Материть - могу, а критиковать бесполезно.