Nie chciałbym kraść wątku, ale dostałem kilka pytań na priv, więc napiszę trochę o mojej "wizji" rotora
Kod:
/*
-komunikaty wysyłane po Serial.print:
- 1 [xxx] - pozycja docelowa [0-360]
- 2 [xx] - prędkość obrotu rotora
- 3 [x] - Żądanie zwrotu ....
- 3 3 - ...prędkości opbrotu rotora
- 3 5 - ...aktualnej pozycji rotora
*/
#include <Adafruit_GFX.h> // biblioteka graficzna
#include <Adafruit_TFTLCD.h> // biblioteka wyswietlacza
#include <TouchScreen.h> // biblioteka panelu dotykowego
#include <EEPROM.h>
#define LCD_CS A3 // Chip Select goes to Analog 3
#define LCD_CD A2 // Command/Data goes to Analog 2
#define LCD_WR A1 // LCD Write goes to Analog 1
#define LCD_RD A0 // LCD Read goes to Analog 0
#define LCD_RESET A4 // Can alternately just connect to Arduino's reset pin
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF
/*piny i ustawienia dotyku*/
#define YP A3 // must be an analog pin, use "An" notation!
#define XM A2 // must be an analog pin, use "An" notation!
#define YM 9 // can be a digital pin
#define XP 8 // can be a digital pin
#define TS_MINX 207
#define TS_MINY 180 //200
#define TS_MAXX 893
#define TS_MAXY 951
#define MINPRESSURE 20
#define MAXPRESSURE 1000
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
// Assign human-readable names to some common 16-bit color values:
/*zmienne*/
int pozDocel = 0; //cocelowa pozycja rotora
int pozDocelOld = 0, // -/-
pozAkt = 0, //aktualna pozycja rotora
pozAktOld = 0, // -/-
/*
menuX=0 - menu1 dolne
menuX=1 - busola
menuX=2 - menu pozycji rotora (domyślne)
menuX=3 - WEJŚCIE DO OPCJI
menuX=31 - menu aZymutu operatora
menuX=32 - menu wyboru przemiennika
*/
/*ADRESY EEPROM:
[0-1] - przechowywanie początkowej komurki adresowania EEPROM (eeMem)
[eeMem]+[0-1] - azymut operatora (mAz)
*/
eeMem = 2, // początkowa komurka EEPROM
menuX = 1,
oldmenuX = 0,
x1,
px, // przeliczona pozycja x dotyku
py, // przeliczona pozycja y dotyku
x, y, // dane do obliczeń azymutu
pres, // informacja dla "void'ów" że ekran został naciśnięty
kompas,
gamma,
nr, w, // numer zmiennej i jej wartość w komunikacji szeregowej
enc, // odczyt danych z enkodera
rotSpeed,
pd = 0; // strefa dotyku ekranu
int mAz = 0, // moj azymut (przekręca busolę względem góry ekranu)
n_mAz; // moj Nowy azymut (wykorzystany w menu 31)
int a, b = 1;
Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
unsigned long currentTime;
unsigned long lastTime;
// If using the shield, all control and data lines are fixed, and
// a simpler declaration can optionally be used:
// Adafruit_TFTLCD tft;
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void setup(void) {
Serial.begin(9600);
Serial.setTimeout (20);
tft.begin(0x9341);
Serial.println ("3 3");
Serial.println ("3 5");
mAz = (EEPROM.read (eeMem) * 255 + EEPROM.read (eeMem + 1)); // odczytanie azymutu operatora po restarcie
delay (300);
while (Serial.available()) {
serialDane();
}
/*========================================
tft.drawRoundRect (1, 1, 238, 35, 5, GREEN);
tft.setTextSize(3);
tft.setCursor(5, 5);
tft.setTextColor(GREEN); tft.println("ROTOR "); tft.setTextColor(RED); tft.print("by SQ4KDG");
delay (2000);
===============*/
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void loop() {
// {
// serialek();
// }
{
dotyk();
}
{
menu();
}
switch (menuX) {
case 1: {
busola();
} break;
case 2: {
rotor();
} break;
case 3: {
opcje();
} break;
case 31: {
azymutOp();
} break;
}
//Serial.print("x:"); Serial.print(px); Serial.print(" y:"); Serial.print(py); Serial.print("menu"); Serial.println(menuX);
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void serialEvent() {
if (Serial.available()) {
serialDane();
}
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void serialDane() {
nr = Serial.parseInt();
w = Serial.parseInt();
switch (nr) {
case 1: {
enc = w;
} break;
case 2: {
pozAkt = w;
} break;
case 3: {
rotSpeed = w;
} break;
}
}
void dotyk() {
digitalWrite(13, HIGH);
TSPoint p = ts.getPoint();
digitalWrite(13, LOW);
// if sharing pins, you'll need to fix the directions of the touchscreen pins
pinMode(XP, OUTPUT);
pinMode(XM, OUTPUT);
pinMode(YP, OUTPUT);
// skalowanie dotyku na TFT
if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {
px = map(p.x, TS_MINX, TS_MAXX, tft.width(), 0) ;
px = constrain (px, 0, tft.width() ) ;
py = map(p.y, TS_MINY, TS_MAXY, tft.height(), 0);
py = constrain (py, 0, tft.height()) ;
pres = 1;
// Serial.println ("dotyk");
}
if (pres) {
if (menuX == 2 || menuX == 31) {
if (py > 45 && py < 280) {
x = -py + 150;
y = px - 120;
gamma = (atan2 (y, x) * 180 / PI);
kompas = 1;
pres = 0;
}
}
else if (menuX == 3) {
if (py < 40) {
pd = 31;
}
}
if (py >= 282) {
if (px > 180) {
pd = 3;
}
else if (px > 80) {
pd = 2;
}
else {
pd = 1;
}
}
// Serial.println ("press");
}
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void menu() { //(menuX=0)
if (oldmenuX != menuX) {
tft.fillRect (0, 280, 240, 60, BLACK);
/*rysowanie PRZYCISKU ENTER=================================*/
tft.drawRoundRect (170, 280, 67, 35, 5, GREEN);
tft.setTextColor(GREEN);
tft.setTextSize(2);
tft.setCursor(174, 290);
tft.println("ENTER");
/*rysowanie PRZYCISKU MENU=================================*/
tft.drawRoundRect (80, 280, 80, 35, 5, YELLOW);
tft.setTextColor(YELLOW);
tft.setTextSize(2);
tft.setCursor(95, 290);
tft.println("MENU");
/*rysowanie PRZYCISKU MENU=================================*/
tft.drawRoundRect (1, 280, 67, 35, 5, RED);
tft.setTextColor(RED);
tft.setTextSize(2);
tft.setCursor(5, 290);
tft.println(" <-- ");
//Serial.print (kompas); Serial.print (" menu "); Serial.println (gamma + mAz);
// Serial.println ("menu");
}
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void busola() { /*rysowanie busoli*/ // (menuX=1)
tft.fillScreen(BLACK);
tft.fillRoundRect (1, 245, 80, 30, 5, WHITE); tft.fillRoundRect (160, 245, 80, 30, 5, WHITE);
tft.setTextColor(BLACK);
tft.setTextSize(2);
tft.setCursor(3, 247);
tft.println(rotSpeed); tft.setTextSize(1); tft.println(" Rotor Speed");
tft.fillCircle(120, 150, 121, BLACK);
tft.drawCircle(120, 150, 110, YELLOW);
tft.drawCircle(120, 150, 119, WHITE);
for (uint8_t i = 0; i < 24; i++) {
tft.drawLine(120 + ( sin ((i * 15 - mAz)* PI / 180 ) * 105), 150 - ( cos ((i * 15 - mAz) * PI / 180 ) * 105),
120 + ( sin ((i * 15 - mAz) * PI / 180 ) * 119), 150 - ( cos ((i * 15 - mAz) * PI / 180 ) * 119), WHITE);
}
char kierunki[8][3] = {"N", "NE", "E", "SE", "S", "SW", "W", "NW"};
uint16_t color[] = {BLUE, 0xC618, YELLOW, 0xC618, RED, 0xC618, YELLOW, 0xC618};
int siz[] = {2, 1, 2, 1, 2, 1, 2, 1};
for (uint8_t i = 0; i < 8; i++) {
tft.setTextColor(color[i]);
tft.setTextSize(siz[i]);
tft.setCursor(120 + ( sin ((i * 45 - mAz) * PI / 180 ) * 95) - 5,
150 - ( cos ((i * 45 - mAz) * PI / 180 ) * 95) - 5);
tft.print(kierunki[i]);
}
// Serial.println ("busola");
menuX = 2;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void rotor() { //(menuX=2)
/*przyjmij koordynaty z dotyku*/
if (kompas) {
pozDocel = gamma + mAz; // przeliczenie ze wspolzednych prostokatnych na biegunowe https://pl.wikipedia.org/wiki/Uk%C5%82ad_wsp%C3%B3%C5%82rz%C4%99dnych_biegunowych
kompas = 0;
// Serial.println ("rotor-kompas");
}
else if (enc) {
pozDocel = pozDocel + enc;
enc = 0;
// Serial.println ("rotor-enc");
}
// else {
// pozDocel = pozDocelOld;
// }
/*zamknij pozycję docelową rotora w 360 stopniach*/
if (pozDocel < 0) {
pozDocel = 360 + pozDocel;
}
if (pozDocel > 359) {
pozDocel = pozDocel % 360;
}
if (oldmenuX != menuX) { // rysowanie 1 raz aktualnych pozycji przy starcie programu lub powrocie z menu
if (pozAkt != pozDocel) {
tft.drawLine(120, 150, 120 + ( sin ((pozDocel - mAz) * PI / 180 ) * 80), 150 - ( cos ((pozDocel - mAz) * PI / 180 ) * 80), YELLOW);
tft.drawLine(120, 150, 120 + ( sin ((pozAkt - mAz) * PI / 180 ) * 80), 150 - ( cos ((pozAkt - mAz) * PI / 180 ) * 80), RED);
tft.fillRoundRect (0, 0, 170, 28, 5, YELLOW);
tft.setTextColor(BLACK);
tft.setTextSize(3);
tft.setCursor(5, 5);
tft.print("Cel: "); tft.println(pozDocel);
tft.fillRoundRect (175, 0, 64, 35, 5, YELLOW);
tft.setTextColor(BLACK);
tft.setTextSize(2); tft.setCursor(180, 5); tft.println(pozAkt);
tft.setTextSize(1); tft.setCursor(180, 25); tft.println("ANTENA");
}
if (pozAkt == pozDocel) {
tft.drawLine(120, 150, 120 + ( sin ((pozAkt - mAz) * PI / 180 ) * 80), 150 - ( cos ((pozAkt - mAz) * PI / 180 ) * 80), GREEN);
tft.fillRoundRect (0, 0, 170, 28, 5, GREEN);
tft.setTextColor(BLACK);
tft.setTextSize(3);
tft.setCursor(5, 5);
tft.print("Cel: "); tft.println(pozDocel);
tft.fillRoundRect (175, 0, 64, 35, 5, GREEN);
tft.setTextColor(BLACK);
tft.setTextSize(2); tft.setCursor(180, 5); tft.println(pozAkt);
tft.setTextSize(1); tft.setCursor(180, 25); tft.println("ANTENA");
}
// b = 0;
oldmenuX = menuX;
// Serial.println ("rotor-a");
}
else { //jeżeli nastąpiła zmiana pozycji docelowej
if (pozDocelOld != pozDocel ) { //rysowanie nowej DOCELOWEJ pozycji rotora
tft.drawLine(120, 150, 120 + ( sin ((pozDocelOld - mAz) * PI / 180 ) * 80), 150 - ( cos ((pozDocelOld - mAz)*PI / 180 ) * 80), BLACK);
tft.drawLine(120, 150, 120 + ( sin ((pozDocel - mAz) * PI / 180 ) * 80), 150 - ( cos ((pozDocel - mAz) * PI / 180 ) * 80), YELLOW);
tft.drawLine(120, 150, 120 + ( sin ((pozAkt - mAz) * PI / 180 ) * 80), 150 - ( cos ((pozAkt - mAz) * PI / 180 ) * 80), RED);
pozDocelOld = pozDocel;
tft.fillRoundRect (0, 0, 170, 28, 5, YELLOW);
tft.setTextColor(BLACK);
tft.setTextSize(3);
tft.setCursor(3, 3);
tft.print("Cel: "); tft.println(pozDocel);
//Serial.print(4); Serial.print(' '); Serial.println(pozDocel);
a = 1;
// Serial.println ("rotor-b");
}
if (pozAktOld != pozAkt ) { //jeżeli nastąpiła zmiana pozycji aktualnej
//rysowanie nowej AKTUALNEJ pozycji rotora
tft.drawLine(120, 150, 120 + ( sin ((pozAktOld - mAz) * PI / 180 ) * 80), 150 - ( cos ((pozAktOld - mAz) * PI / 180 ) * 80), BLACK);
tft.drawLine(120, 150, 120 + ( sin ((pozAkt - mAz) * PI / 180 ) * 80), 150 - ( cos ((pozAkt - mAz) * PI / 180 ) * 80), RED);
pozAktOld = pozAkt;
tft.fillRoundRect (175, 0, 64, 35, 5, YELLOW);
tft.setTextColor(BLACK);
tft.setTextSize(2); tft.setCursor(180, 5); tft.println(pozAkt);
tft.setTextSize(1); tft.setCursor(180, 25); tft.println("ANTENA");
a = 0;
// Serial.println ("rotor-c");
}
if (pozAktOld == pozAkt && pozAkt != pozDocel && a) {
tft.fillRoundRect (175, 0, 64, 35, 5, RED);
tft.setTextColor(BLACK);
tft.setTextSize(2); tft.setCursor(180, 5); tft.println(pozAkt);
tft.setTextSize(1); tft.setCursor(180, 25); tft.println("ANTENA");
tft.drawLine(120, 150, 120 + ( sin ((pozAkt - mAz) * PI / 180 ) * 80), 150 - ( cos ((pozAkt - mAz) * PI / 180 ) * 80), RED);
a = 0;
// Serial.println ("rotor-d");
}
if (pozAkt == pozDocel && !a) { //jeżeli pozycja aktualna osiągnęła pozycję docelową
//rysowanie nowej AKTUALNEJ pozycji rotora
tft.drawLine(120, 150, 120 + ( sin ((pozAktOld - mAz) * PI / 180 ) * 80), 150 - ( cos ((pozAktOld - mAz) * PI / 180 ) * 80), BLACK);
tft.drawLine(120, 150, 120 + ( sin ((pozAkt - mAz) * PI / 180 ) * 80), 150 - ( cos ((pozAkt - mAz) * PI / 180 ) * 80), GREEN);
tft.fillRoundRect (0, 0, 170, 28, 5, GREEN);
tft.setTextColor(BLACK);
tft.setTextSize(3);
tft.setCursor(5, 5);
tft.print("Cel: "); tft.println(pozDocel);
tft.fillRoundRect (175, 0, 64, 35, 5, GREEN);
tft.setTextColor(BLACK);
tft.setTextSize(2); tft.setCursor(180, 5); tft.println(pozAkt);
tft.setTextSize(1); tft.setCursor(180, 25); tft.println("ANTENA");
a = 1;
// Serial.println ("rotor-e");
}
}
if (pres) {
if (pd == 3) { //wysłanie nowej pozycji do rotora (nakazanie obrotu)
Serial.print (1); Serial.print (" "); Serial.println (pozDocel);
pd = 0;
delay (400);
}
if (pd == 2) { // przejście do opcji
menuX = 3;
pd = 0;
}
pres = 0;
// Serial.println ("rotor-pres");
}
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void opcje() { //(menuX=3)
if (oldmenuX != menuX) {
pd = 0;
tft.fillRect (0, 0, 240, 279, BLACK);
tft.setTextSize(2);
int space = 6,
wys = 40;
char* label[] = {"AZYMUT Operatora", "POZYCJA Operatora", "PRZEMIENNIKI", "ULUBIONE", "DODAJ do ulubionych", "SERWIS"};
uint16_t color[] = {YELLOW, 0xC618, 0xC618, 0xC618, 0xC618, RED};
for (uint8_t i = 0; i < 6; i++) {
tft.drawRoundRect (1, (wys + space)*i, 238, wys, 12, color[i]);
tft.setTextColor(color[i]);
tft.setCursor(8, (wys + space)*i + 12);
tft.print(label[i]);
}
oldmenuX = menuX;
}
if (pres == 1) {
if (pd == 1) {
b = 1;
menuX = 1;
pres = 0;
Serial.println ("3 3");
}
if (pd == 31) {
b = 1;
menuX = 31;
}
// Serial.print (pres); Serial.print (" "); Serial.println (pd);
pres = 0;
}
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void azymutOp() { // (menuX=31) - menu aZymutu operatora
if (oldmenuX != menuX) {
tft.fillRect (0, 0, 240, 279, BLACK);
n_mAz = mAz;
pd = 0;
for (uint8_t i = 0; i < 24; i++) {
tft.drawLine(120 + ( sin (i * 15 * PI / 180 ) * 107), 150 - ( cos (i * 15 * PI / 180 ) * 107),
120 + ( sin (i * 15 * PI / 180 ) * 119), 150 - ( cos (i * 15 * PI / 180 ) * 119), WHITE);
}
tft.drawCircle(120, 150, 110, YELLOW);
tft.drawCircle(120, 150, 119, WHITE);
char kierunki[8][6] = {"0", "315", "270", "225", "180", "135", "90", "45"};
uint16_t color[] = {GREEN, BLUE, YELLOW, BLUE, RED, BLUE, YELLOW, BLUE};
int siz[] = {2, 1, 1, 1, 1, 1, 1, 1};
for (uint8_t i = 0; i < 8; i++) {
tft.setTextColor(color[i]);
tft.setTextSize(siz[i]);
tft.setCursor(120 + ( sin ((i * 45 ) * PI / 180 ) * 95) - 5,
150 - ( cos ((i * 45 ) * PI / 180 ) * 95) - 5);
tft.print(kierunki[i]);
}
b = 0;
oldmenuX = menuX;
}
int old_n_mAz = n_mAz;
if (kompas == 1) {
n_mAz = 360 - gamma;
b = 0;
kompas = 0;
}
if (enc != 0) {
n_mAz = n_mAz - enc;
enc = 0;
b = 0;
}
if (n_mAz < 0) {
n_mAz = 360 + n_mAz;
}
if (n_mAz > 359) {
n_mAz = n_mAz % 360;
}
if (oldmenuX != menuX) {
n_mAz = mAz;
}
if (b == 0) {
tft.drawLine(120, 150, 120 + ( sin (-old_n_mAz * PI / 180 ) * 80), 150 - ( cos (-old_n_mAz * PI / 180 ) * 80), BLACK);
tft.drawLine(120, 150, 120, 80, GREEN);
tft.drawLine(120, 150, 120 + ( sin (-n_mAz * PI / 180 ) * 80), 150 - ( cos (-n_mAz * PI / 180 ) * 80), BLUE);
tft.fillRoundRect (0, 0, 239, 28, 5, WHITE);
tft.setTextColor(BLACK);
tft.setTextSize(3);
tft.setCursor(3, 3);
tft.print("Azymut: "); tft.println(n_mAz);
b = 1;
}
if (pres == 1) {
if (pd == 1) {
menuX = 1;
pd = 0;
}
if (pd == 2) { // przejście do opcji
menuX = 3;
pd = 0;
}
if (pd == 3) {
mAz = n_mAz;
EEPROM.update (eeMem, mAz / 255); EEPROM.update (eeMem + 1, mAz % 255);
menuX = 1;
pd = 0;
}
pres = 0;
}
}