Hi all, I have been having a nightmare with uploading the following sketch to an Uno R3 and also tried Arduino Mega; this a link to this massive sketch......SpotNik/spotnik.ino at main · surfer-max/SpotNik · GitHub
I've asked the original program writer for help but he was no longer involved with these projects. What would be great is if someone out there with the arduino know-how could try uploading the sketch themselves and see if they can? I'd be very pleased to fix this issue and unfortunately I cannot fix myself as I'm totally entry level arduino guy....with NO programming knowledge or ability. I am hopeful!!!
Welcome to the forum
What problems do you have when trying to upload the sketch ?
Please post your full sketch, using code tags when you do
Posting your code using code tags prevents parts of it being interpreted as HTML coding and makes it easier to copy for examination
In my experience the easiest way to tidy up the code and add the code tags is as follows
Start by tidying up your code by using Tools/Auto Format in the IDE to make it easier to read. Then use Edit/Copy for Forum and paste what was copied in a new reply. Code tags will have been added to the code to make it easy to read in the forum thus making it easier to provide help.
It is also helpful to post full error messages in code tags as it makes it easier to scroll through them and copy them for examination
To post the error message, click the "COPY ERROR MESSAGES" button in the IDE, paste the copied messages in a reply here, select all of it and click the < CODE > icon above the reply editor to add the code tags and then save the reply
Welcome!
That could be many things, I have a blue, what do I have? we need more information, such as the code and the problems you are having. If it is errors from the upload capture them and upload using code tags.
At this point I can only guess and say check your cable and be sure it is ok, try uploading one of the example sketches. Is your power source stable?
The code compiles and uploads without problems.
You have installed the LiquidCrystal library, right?
Interesting piece of code.
It is unclear what the problems are you are encountering?
Can you elaborate?
Hi Maximo, yes , I checked the list of things in the library and LCD is definitely there.
What exactly is the problem you are having?
Note that if you have a bluetooth module connected to the Rx and Tx pins of the arduino, you will need to disconnect the bluetooth module while uploading a sketch.
[code]
void setup() {
// put your setup code here, to run once:
/* ///////////////////////////////////////////////////////////////////////////////////
SpotNik - by Max Reinecke
Created: May 2021
SpotNik is software for a stepto system for telescopes
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
/////////////////////////////////////////////////////////////////////////////////*/
#define VERSION 2.0
//###############################################################################################################
// to be changed by user according to EQ mount - see instructions
// total numbers of impulse of the rotary encoder of RA axis when turned 24h
#define IMPULSE24HRA 2772 // 6h - 690 Impulse --> 24h - 4 * 693 = 2772 / ~ 1:138
// total numbers of impulse of the rotary encoder of DEC axis when turned 360° // +/- for correct direction
#define IMPULSE360DEGDEC 1784 // 90° - 446 Impulse --> 360° - 4 * 446 = 1784 / ~ 1:88
//###############################################################################################################
#include <LiquidCrystal.h> // I2C LCD arbeitet nicht vernünftig mit Rotary Encoder zusammen,daher normales nehmen
#include <EEPROM.h>
//#include <MemoryFree.h> // only used for testing
//###############################################################################################################
// LCD
#define LCD_CONTRAST_PIN 11 // LCD contrast - V0 // use high frequency PWM to avoid flickering (Leonardo,Micro,Yún 3 and 11: 980 Hz // Mega pins 4 and 13: 980 Hz)
#define LCD_BACKLIGHT_PIN 10 // LCD backlight - LCD A
// EEPROM
#define EEPROM_SIGNATURE 117 // value 0-255 (byte) - signature/mark to recognize if the value fits to this sketch
#define EEPROM_VALUE_ADDR_SIGNATURE 0
// rotary enoder HMI
#define ROTARY_SW 3 // use interrupt pin - digital pins for interrupts on Micro,Leonardo and other 32u4 based 0,1,2,3,7
#define ROTARY_DT 4
#define ROTARY_CLK 5
// Sensor RA
#define SENS_RA_DT A0 // analog pins used as UNO has not that many digital pins
#define SENS_RA_CLK A1
// Sensor DEC
#define SENS_DEC_DT A2
#define SENS_DEC_CLK A3
// LX200 connection
#define BT_SWITCH 2
//###############################################################################################################
// lookup table with names of deep sky objects
//###############################################################################################################
struct DSONameStruct
{
char objectName[9];
};
const struct DSONameStruct DSO_NAME_PROGMEM[202] PROGMEM =
{
{"3C273"},
{"B"},
{"IC"},
{"M"},
{"NGC"},
{"#a"},
{"#aA"},
{"#aB"},
{"#b"},
{"#c"},
{"#d"},
{"#e"},
{"#e1"},
{"#e2"},
{"#g"},
{"#h"},
{"#i"},
{"#j"},
{"#k"},
{"#l"},
{"#m"},
{"#n"},
{"#o"},
{"#p"},
{"#q"},
{"#r"},
{"#s"},
{"#t"},
{"#u"},
{"#w"},
{"#x"},
{"#z"},
{"AC"},
{"Achernar"},
{"Acrab"},
{"Acrux"},
{"Adhara"},
{"Agena"},
{"Alamak"},
{"Aldebara"},
{"Alderami"},
{"AlDhanab"},
{"Algenib"},
{"Algieba"},
{"Algol"},
{"Alhena"},
{"Alioth"},
{"Alkaid"},
{"AlNair"},
{"Alnilam"},
{"Alnitak"},
{"Alphard"},
{"Alphecca"},
{"Alpherat"},
{"Alsuhail"},
{"Altair"},
{"Aludra"},
{"Ankaa"},
{"Antares"},
{"AQ"},
{"Arcturus"},
{"Arneb"},
{"Aspidisk"},
{"Atria"},
{"Avior"},
{"AW"},
{"AX"},
{"BD"},
{"Becrux"},
{"Bellatri"},
{"Betelgeu"},
{"BF"},
{"BG"},
{"BL"},
{"BM"},
{"BX"},
{"Canopus"},
{"Capella"},
{"Caph"},
{"Castor"},
{"Cih"},
{"CY"},
{"Deneb"},
{"DenebKai"},
{"Denebola"},
{"Diphda"},
{"DR"},
{"Dschubba"},
{"Dubhe"},
{"EL"},
{"ElNath"},
{"Eltanin"},
{"Enif"},
{"FO"},
{"Fomalhau"},
{"FU"},
{"Gacrux"},
{"Gemma"},
{"Gienah"},
{"Girtab"},
{"GK"},
{"GY"},
{"H"},
{"Hadar"},
{"Hamal"},
{"Han"},
{"HD"},
{"HJ"},
{"HK"},
{"HN"},
{"Izar"},
{"JC"},
{"KausAust"},
{"Kochab"},
{"KooShe"},
{"Markab"},
{"Menkalin"},
{"Menkar"},
{"Menkent"},
{"Merak"},
{"Miaplaci"},
{"Mimosa"},
{"Mintaka"},
{"Mirach"},
{"Mirfak"},
{"Mirzam"},
{"Mizar"},
{"Naos"},
{"NQ"},
{"NSV"},
{"Nunki"},
{"O#F"},
{"Peacock"},
{"Phecda"},
{"Polaris"},
{"Pollux"},
{"Procyon"},
{"PZ6"},
{"R"},
{"RasAlhag"},
{"Regulus"},
{"Rigel"},
{"RigilKen"},
{"RR"},
{"RS"},
{"RT"},
{"RU"},
{"RV"},
{"RX"},
{"RY"},
{"RZ"},
{"S"},
{"S605"},
{"Sabik"},
{"Sadr"},
{"Saiph"},
{"SAO"},
{"Sargas"},
{"Scheat"},
{"Schedar"},
{"Shaula"},
{"SHJ"},
{"Sirius"},
{"Spica"},
{"SS"},
{"ST"},
{"SU"},
{"SV"},
{"SY"},
{"SZ"},
{"T"},
{"TT"},
{"TU"},
{"Tureis"},
{"TW"},
{"TX"},
{"U"},
{"UU"},
{"UV"},
{"UX"},
{"UY"},
{"V"},
{"Vega"},
{"VW"},
{"VX"},
{"VY"},
{"W"},
{"Wei"},
{"Wezen"},
{"WO"},
{"WW"},
{"WX"},
{"WZ"},
{"X"},
{"XS"},
{"XX"},
{"Y"},
{"Z"},
{"Zozma"},
{"β648"},
{"#F"},
{"extern"}
};
//###############################################################################################################
//###############################################################################################################
// data of deep sky objects
//###############################################################################################################
struct DSOstruct
{
byte objectPreFixNameNo; // number of name for lookup table
unsigned int objectNumber; // if name contains a number
byte objectTypeMagnitude; // object type & magnitude coded in one byte
byte objectConst; // constellation of object
unsigned int objectRA; //HHMM(SS/6)
int objectDEC; //sHHMM
};
DSOstruct myTarget; // object to store data of selected target
DSOstruct myReference; // object to store data of selected target
const unsigned int DSO_PROGMEM_size = 1204;
const struct DSOstruct DSO_PROGMEM[DSO_PROGMEM_size] PROGMEM =
{
{1, 0, 27, 86, 12291, 203},
{2, 33, 42, 60, 5409, -228},
{2, 65, 42, 77, 18027, -2750},
{2, 86, 42, 59, 17196, -2642},
{3, 342, 54, 11, 3468, 6806},
{3, 405, 66, 8, 5165, 3421},
{3, 410, 64, 8, 5227, 3325},
{3, 434, 67, 60, 5410, -227},
{3, 1396, 74, 16, 21391, 5730},
{3, 4406, 95, 50, 14224, -4409},
{3, 5067, 64, 31, 20508, 4421},
{3, 5146, 80, 31, 21534, 4716},
{4, 1, 106, 78, 5345, 2201},
{4, 2, 119, 5, 21335, -49},
{4, 3, 118, 30, 13422, 2823},
{4, 4, 117, 72, 16236, -2632},
{4, 5, 118, 74, 15186, 205},
{4, 6, 130, 72, 17403, -3215},
{4, 7, 129, 72, 17539, -3448},
{4, 8, 75, 77, 18037, -2423},
{4, 9, 120, 59, 17192, -1831},
{4, 10, 119, 59, 16571, -406},
{4, 11, 132, 73, 18511, -616},
{4, 12, 118, 59, 16472, -157},
{4, 13, 118, 40, 16417, 3628},
{4, 14, 120, 59, 17376, -315},
{4, 15, 118, 62, 21300, 1210},
{4, 16, 76, 74, 18188, -1347},
{4, 17, 76, 77, 18208, -1611},
{4, 18, 133, 77, 18199, -1708},
{4, 19, 119, 59, 17026, -2616},
{4, 20, 76, 77, 18027, -2258},
{4, 21, 132, 77, 18042, -2229},
{4, 22, 117, 77, 18364, -2354},
{4, 23, 132, 77, 17571, -1859},
{4, 24, 129, 77, 18266, -1823},
{4, 25, 131, 77, 18318, -1907},
{4, 26, 134, 73, 18452, -924},
{4, 27, 91, 88, 19596, 2243},
{4, 28, 119, 77, 18245, -2452},
{4, 29, 133, 31, 20239, 3832},
{4, 30, 119, 12, 21404, -2311},
{4, 31, 45, 1, 427, 4116},
{4, 32, 50, 1, 427, 4052},
{4, 33, 48, 81, 1339, 3039},
{4, 34, 131, 63, 2421, 4247},
{4, 35, 131, 38, 6089, 2421},
{4, 36, 132, 8, 5363, 3408},
{4, 37, 132, 8, 5523, 3233},
{4, 38, 132, 8, 5287, 3551},
{4, 39, 131, 31, 21322, 4826},
{4, 40, 149, 83, 12219, 5806},
{4, 41, 131, 20, 6460, -2045},
{4, 42, 74, 60, 5353, -523},
{4, 43, 63, 60, 5355, -516},
{4, 44, 129, 22, 8400, 1940},
{4, 45, 71, 78, 3470, 2407},
{4, 46, 132, 68, 7418, -1449},
{4, 47, 130, 68, 7366, -1429},
{4, 48, 132, 42, 8137, -545},
{4, 49, 50, 86, 12298, 800},
{4, 50, 132, 55, 7025, -823},
{4, 51, 50, 30, 13299, 4712},
{4, 52, 133, 14, 23242, 6135},
{4, 53, 120, 24, 13129, 1810},
{4, 54, 120, 77, 18551, -3029},
{4, 55, 118, 77, 19400, -3058},
{4, 56, 120, 52, 19166, 3011},
{4, 57, 93, 52, 18536, 3302},
{4, 58, 52, 86, 12377, 1149},
{4, 59, 52, 86, 12420, 1139},
{4, 60, 51, 86, 12437, 1133},
{4, 61, 52, 86, 12219, 428},
{4, 62, 118, 59, 17012, -3007},
{4, 63, 51, 30, 13158, 4202},
{4, 64, 51, 24, 12567, 2141},
{4, 65, 51, 46, 11189, 1305},
{4, 66, 51, 46, 11202, 1300},
{4, 67, 133, 22, 8508, 1149},
{4, 68, 119, 42, 12395, -2645},
{4, 69, 120, 77, 18314, -3221},
{4, 70, 120, 77, 18432, -3218},
{4, 71, 120, 76, 19538, 1847},
{4, 72, 121, 5, 20535, -1232},
{4, 73, 136, 5, 20590, -1238},
{4, 74, 51, 67, 1367, 1547},
{4, 75, 121, 77, 20061, -2155},
{4, 76, 94, 63, 1423, 5135},
{4, 77, 51, 17, 2427, -1},
{4, 78, 64, 60, 5468, 5},
{4, 79, 120, 47, 5242, -2431},
{4, 80, 119, 72, 16170, -2259},
{4, 81, 49, 83, 9556, 6904},
{4, 82, 50, 83, 9559, 6941},
{4, 83, 50, 42, 13370, -2952},
{4, 84, 51, 86, 12251, 1253},
{4, 85, 51, 24, 12254, 1811},
{4, 86, 51, 86, 12262, 1257},
{4, 87, 51, 86, 12308, 1223},
{4, 88, 52, 24, 12320, 1425},
{4, 89, 52, 86, 12357, 1233},
{4, 90, 52, 86, 12368, 1310},
{4, 91, 52, 24, 12354, 1430},
{4, 92, 119, 40, 17171, 4308},
{4, 93, 132, 68, 7445, -2351},
{4, 94, 50, 30, 12509, 4107},
{4, 95, 52, 46, 10440, 1142},
{4, 96, 51, 46, 10468, 1149},
{4, 97, 95, 83, 11148, 5501},
{4, 98, 52, 24, 12138, 1454},
{4, 99, 52, 24, 12188, 1425},
{4, 100, 51, 24, 12229, 1549},
{4, 101, 50, 83, 14032, 5421},
{4, 102, 52, 34, 15065, 5546},
{4, 103, 133, 14, 1334, 6039},
{4, 104, 50, 86, 12400, -1137},
{4, 105, 51, 46, 10478, 1235},
{4, 106, 50, 30, 12190, 4718},
{4, 107, 120, 59, 16325, -1303},
{4, 108, 52, 83, 11115, 5540},
{4, 109, 52, 83, 11576, 5322},
{4, 110, 50, 1, 404, 4141},
{5, 40, 94, 16, 130, 7231},
{5, 55, 50, 71, 149, -3911},
{5, 129, 133, 14, 300, 6013},
{5, 136, 137, 14, 315, 6131},
{5, 147, 52, 14, 332, 4830},
{5, 157, 52, 17, 348, -824},
{5, 185, 51, 14, 390, 4820},
{5, 188, 134, 16, 475, 8514},
{5, 210, 52, 17, 406, -1352},
{5, 225, 133, 14, 436, 6146},
{5, 246, 94, 17, 471, -1152},
{5, 247, 51, 17, 471, -2046},
{5, 253, 49, 71, 476, -2518},
{5, 278, 52, 14, 521, 4733},
{5, 281, 77, 14, 530, 5637},
{5, 288, 120, 71, 528, -2635},
{5, 300, 50, 71, 549, -3741},
{5, 381, 135, 14, 1084, 6135},
{5, 404, 52, 1, 1094, 3543},
{5, 436, 135, 14, 1160, 5849},
{5, 457, 132, 14, 1195, 5817},
{5, 488, 52, 67, 1218, 515},
{5, 524, 52, 67, 1248, 932},
{5, 559, 136, 14, 1295, 6319},
{5, 584, 52, 17, 1313, -652},
{5, 596, 52, 17, 1329, -702},
{5, 613, 52, 71, 1343, -2925},
{5, 615, 53, 17, 1351, -720},
{5, 637, 134, 14, 1431, 6402},
{5, 654, 133, 14, 1440, 6153},
{5, 659, 134, 14, 1444, 6040},
{5, 663, 133, 14, 1460, 6115},
{5, 672, 52, 81, 1479, 2726},
{5, 720, 52, 17, 1530, -1344},
{5, 752, 132, 1, 1577, 3740},
{5, 772, 52, 7, 1593, 1900},
{5, 779, 53, 17, 1597, -558},
{5, 869, 131, 63, 2191, 5708},
{5, 884, 132, 63, 2225, 5709},
{5, 891, 52, 1, 2226, 4221},
{5, 908, 52, 17, 2231, -2114},
{5, 925, 52, 81, 2273, 3335},
{5, 936, 52, 17, 2276, -109},
{5, 986, 52, 37, 2336, -3903},
{5, 1022, 53, 17, 2385, -641},
{5, 1023, 51, 63, 2404, 3904},
{5, 1027, 133, 14, 2426, 6136},
{5, 1052, 52, 17, 2411, -815},
{5, 1055, 52, 17, 2418, 27},
{5, 1084, 52, 36, 2460, -735},
{5, 1097, 52, 37, 2463, -3017},
{5, 1232, 52, 36, 3098, -2035},
{5, 1245, 134, 63, 3147, 4714},
{5, 1261, 120, 41, 3123, -5513},
{5, 1275, 53, 63, 3198, 4131},
{5, 1291, 51, 36, 3173, -4106},
{5, 1300, 52, 36, 3197, -1925},
{5, 1316, 51, 37, 3227, -3713},
{5, 1325, 53, 36, 3244, -2133},
{5, 1332, 52, 36, 3263, -2120},
{5, 1342, 133, 63, 3317, 3722},
{5, 1360, 93, 37, 3332, -2552},
{5, 1365, 52, 37, 3336, -3608},
{5, 1374, 53, 37, 3353, -3514},
{5, 1380, 54, 37, 3368, -3444},
{5, 1398, 52, 37, 3389, -2620},
{5, 1399, 52, 37, 3385, -3527},
{5, 1407, 52, 36, 3402, -1835},
{5, 1433, 52, 41, 3420, -4713},
{5, 1444, 133, 63, 3494, 5240},
{5, 1491, 70, 63, 4032, 5119},
{5, 1499, 61, 63, 4032, 3622},
{5, 1501, 96, 11, 4070, 6055},
{5, 1502, 133, 11, 4078, 6220},
{5, 1513, 134, 63, 4099, 4931},
{5, 1514, 94, 78, 4093, 3047},
{5, 1528, 132, 63, 4153, 5113},
{5, 1532, 52, 36, 4121, -3252},
{5, 1535, 93, 36, 4143, -1244},
{5, 1545, 132, 63, 4209, 5015},
{5, 1549, 52, 33, 4158, -5536},
{5, 1566, 52, 33, 4200, -5456},
{5, 1647, 132, 78, 4459, 1906},
{5, 1664, 134, 8, 4511, 4341},
{5, 1672, 52, 33, 4457, -5915},
{5, 1788, 70, 60, 5069, -320},
{5, 1792, 52, 23, 5052, -3759},
{5, 1808, 52, 23, 5077, -3731},
{5, 1817, 134, 78, 5124, 1641},
{5, 1851, 119, 23, 5141, -4003},
{5, 1857, 133, 8, 5201, 3921},
{5, 1907, 134, 8, 5281, 3520},
{5, 1909, 70, 36, 5045, -716},
{5, 1931, 80, 8, 5314, 3415},
{5, 1961, 53, 11, 5421, 6923},
{5, 1964, 52, 47, 5334, -2157},
{5, 1973, 63, 60, 5351, -444},
{5, 1980, 73, 60, 5354, -555},
{5, 1999, 70, 60, 5364, -643},
{5, 2022, 95, 60, 5421, 905},
{5, 2024, 70, 60, 5417, -151},
{5, 2126, 136, 8, 6025, 4952},
{5, 2129, 133, 38, 6007, 2319},
{5, 2158, 135, 38, 6074, 2406},
{5, 2169, 132, 60, 6084, 1358},
{5, 2175, 77, 60, 6096, 2029},
{5, 2185, 70, 55, 6110, -614},
{5, 2186, 135, 60, 6121, 528},
{5, 2194, 135, 60, 6138, 1248},
{5, 2204, 135, 20, 6155, -1840},
{5, 2207, 52, 20, 6164, -2122},
{5, 2215, 134, 55, 6208, -717},
{5, 2232, 130, 55, 6280, -451},
{5, 2237, 76, 55, 6309, 503},
{5, 2238, 62, 55, 6307, 501},
{5, 2239, 131, 55, 6319, 457},
{5, 2245, 70, 55, 6327, 1009},
{5, 2251, 133, 55, 6346, 822},
{5, 2261, 70, 55, 6392, 845},
{5, 2264, 74, 55, 6410, 954},
{5, 2266, 136, 38, 6433, 2658},
{5, 2281, 131, 8, 6483, 4105},
{5, 2286, 134, 55, 6477, -309},
{5, 2300, 53, 16, 7323, 8543},
{5, 2301, 132, 55, 6518, 28},
{5, 2304, 136, 38, 6552, 1759},
{5, 2311, 136, 55, 6578, -437},
{5, 2324, 134, 55, 7041, 103},
{5, 2335, 133, 55, 7068, -1002},
{5, 2343, 133, 55, 7081, -1037},
{5, 2346, 96, 55, 7094, -48},
{5, 2353, 133, 55, 7145, -1016},
{5, 2354, 133, 20, 7143, -2542},
{5, 2355, 136, 38, 7170, 1345},
{5, 2359, 70, 20, 7185, -1314},
{5, 2360, 133, 20, 7177, -1538},
{5, 2362, 130, 20, 7187, -2457},
{5, 2371, 95, 38, 7256, 2929},
{5, 2372, 95, 38, 7256, 2930},
{5, 2383, 134, 20, 7247, -2057},
{5, 2384, 133, 20, 7252, -2101},
{5, 2392, 93, 38, 7292, 2055},
{5, 2395, 134, 38, 7272, 1337},
{5, 2403, 51, 11, 7368, 6536},
{5, 2419, 122, 51, 7381, 3853},
{5, 2420, 134, 38, 7384, 2134},
{5, 2421, 134, 68, 7362, -2037},
{5, 2423, 133, 68, 7371, -1352},
{5, 2438, 95, 68, 7418, -1444},
{5, 2439, 133, 68, 7408, -3142},
{5, 2440, 95, 68, 7419, -1813},
{5, 2467, 77, 68, 7525, -2626},
{5, 2477, 132, 68, 7522, -3832},
{5, 2479, 136, 68, 7551, -1742},
{5, 2482, 133, 68, 7552, -2415},
{5, 2489, 134, 68, 7563, -3004},
{5, 2506, 134, 55, 8000, -1046},
{5, 2509, 135, 68, 8008, -1903},
{5, 2527, 133, 68, 8050, -2809},
{5, 2539, 133, 68, 8106, -1249},
{5, 2547, 131, 85, 8102, -4912},
{5, 2567, 133, 68, 8185, -3039},
{5, 2571, 133, 68, 8189, -2945},
{5, 2613, 52, 69, 8334, -2258},
{5, 2627, 134, 69, 8372, -2957},
{5, 2655, 52, 11, 8556, 7813},
{5, 2681, 52, 83, 8535, 5119},
{5, 2683, 52, 51, 8527, 3325},
{5, 2742, 53, 83, 9076, 6029},
{5, 2768, 52, 83, 9116, 6002},
{5, 2775, 52, 22, 9103, 702},
{5, 2782, 53, 51, 9141, 4007},
{5, 2784, 52, 42, 9123, -2410},
{5, 2787, 52, 83, 9193, 6912},
{5, 2811, 53, 42, 9162, -1619},
{5, 2835, 52, 42, 9179, -2221},
{5, 2841, 51, 83, 9220, 5059},
{5, 2859, 52, 49, 9243, 3431},
{5, 2867, 94, 13, 9214, -5819},
{5, 2903, 51, 46, 9322, 2130},
{5, 2950, 52, 83, 9426, 5851},
{5, 2964, 53, 46, 9429, 3151},
{5, 2974, 52, 75, 9426, -342},
{5, 2976, 52, 83, 9472, 6755},
{5, 2985, 52, 83, 9504, 7217},
{5, 2997, 51, 2, 9456, -3111},
{5, 3077, 52, 83, 10033, 6844},
{5, 3079, 52, 83, 10020, 5541},
{5, 3109, 52, 42, 10031, -2610},
{5, 3115, 51, 75, 10052, -743},
{5, 3132, 92, 85, 10070, -4026},
{5, 3147, 52, 34, 10169, 7324},
{5, 3166, 52, 75, 10138, 326},
{5, 3169, 52, 75, 10142, 328},
{5, 3184, 52, 83, 10183, 4125},
{5, 3190, 53, 46, 10181, 2150},
{5, 3193, 52, 46, 10184, 2154},
{5, 3198, 52, 83, 10199, 4533},
{5, 3201, 119, 85, 10176, -4625},
{5, 3226, 53, 46, 10234, 1954},
{5, 3227, 52, 46, 10235, 1952},
{5, 3242, 93, 42, 10248, -1839},
{5, 3245, 52, 49, 10273, 2830},
{5, 3277, 53, 49, 10329, 2831},
{5, 3294, 53, 49, 10363, 3719},
{5, 3310, 52, 83, 10388, 5330},
{5, 3344, 52, 49, 10435, 2455},
{5, 3359, 52, 83, 10466, 6313},
{5, 3372, 59, 13, 10451, -5952},
{5, 3377, 52, 46, 10477, 1359},
{5, 3384, 52, 46, 10483, 1238},
{5, 3395, 54, 49, 10498, 3259},
{5, 3412, 52, 46, 10509, 1325},
{5, 3414, 53, 49, 10513, 2758},
{5, 3432, 53, 49, 10525, 3637},
{5, 3486, 52, 49, 11004, 2859},
{5, 3489, 52, 46, 11003, 1354},
{5, 3504, 53, 49, 11032, 2758},
{5, 3521, 51, 46, 11058, -2},
{5, 3532, 129, 13, 11052, -5844},
{5, 3593, 52, 46, 11146, 1249},
{5, 3607, 52, 46, 11169, 1803},
{5, 3608, 52, 46, 11170, 1809},
{5, 3610, 52, 83, 11184, 5847},
{5, 3613, 52, 83, 11186, 5800},
{5, 3619, 53, 83, 11194, 5745},
{5, 3621, 52, 42, 11183, -3249},
{5, 3626, 53, 46, 11201, 1821},
{5, 3628, 52, 46, 11203, 1335},
{5, 3631, 52, 83, 11210, 5310},
{5, 3640, 52, 46, 11211, 314},
{5, 3655, 53, 46, 11229, 1635},
{5, 3665, 52, 83, 11247, 3846},
{5, 3675, 52, 83, 11261, 4335},
{5, 3686, 53, 46, 11277, 1713},
{5, 3717, 53, 42, 11315, -3019},
{5, 3718, 52, 83, 11326, 5304},
{5, 3726, 52, 83, 11333, 4702},
{5, 3729, 53, 83, 11338, 5308},
{5, 3810, 52, 46, 11410, 1128},
{5, 3813, 53, 83, 11413, 3633},
{5, 3877, 53, 83, 11461, 4730},
{5, 3893, 52, 83, 11486, 4843},
{5, 3898, 52, 83, 11493, 5605},
{5, 3900, 53, 46, 11492, 2701},
{5, 3912, 54, 46, 11501, 2629},
{5, 3918, 92, 15, 11503, -5711},
{5, 3923, 52, 42, 11510, -2848},
{5, 3938, 52, 83, 11528, 4407},
{5, 3941, 52, 83, 11529, 3659},
{5, 3945, 52, 83, 11532, 6040},
{5, 3949, 53, 83, 11537, 4752},
{5, 3953, 52, 83, 11538, 5219},
{5, 3962, 52, 27, 11547, -1359},
{5, 3982, 53, 83, 11565, 5507},
{5, 3998, 52, 83, 11579, 5527},
{5, 4013, 53, 83, 11585, 4357},
{5, 4026, 52, 83, 11594, 5058},
{5, 4027, 53, 29, 11595, -1916},
{5, 4030, 52, 86, 12004, -106},
{5, 4036, 52, 83, 12015, 6154},
{5, 4038, 52, 29, 12019, -1852},
{5, 4039, 52, 29, 12019, -1853},
{5, 4041, 53, 83, 12022, 6208},
{5, 4051, 52, 83, 12032, 4432},
{5, 4085, 54, 83, 12054, 5021},
{5, 4088, 52, 83, 12056, 5032},
{5, 4096, 52, 83, 12060, 4729},
{5, 4102, 53, 83, 12064, 5243},
{5, 4105, 52, 42, 12067, -2946},
{5, 4111, 52, 30, 12070, 4304},
{5, 4125, 52, 34, 12081, 6510},
{5, 4143, 52, 30, 12096, 4232},
{5, 4147, 122, 24, 12101, 1833},
{5, 4150, 53, 24, 12106, 3024},
{5, 4151, 52, 30, 12105, 3924},
{5, 4179, 53, 86, 12129, 118},
{5, 4203, 52, 24, 12151, 3312},
{5, 4214, 52, 30, 12156, 3620},
{5, 4216, 52, 86, 12159, 1309},
{5, 4236, 52, 34, 12167, 6928},
{5, 4244, 52, 30, 12175, 3748},
{5, 4245, 53, 24, 12176, 2936},
{5, 4251, 52, 24, 12181, 2810},
{5, 4261, 52, 86, 12194, 549},
{5, 4273, 53, 86, 12199, 521},
{5, 4274, 52, 24, 12198, 2937},
{5, 4278, 52, 24, 12201, 2917},
{5, 4281, 53, 86, 12204, 523},
{5, 4293, 52, 24, 12212, 1823},
{5, 4314, 52, 24, 12225, 2954},
{5, 4346, 53, 30, 12235, 4700},
{5, 4350, 53, 24, 12240, 1642},
{5, 4361, 94, 29, 12245, -1847},
{5, 4365, 52, 86, 12245, 719},
{5, 4371, 52, 86, 12249, 1142},
{5, 4388, 53, 86, 12258, 1240},
{5, 4394, 52, 24, 12259, 1813},
{5, 4395, 52, 30, 12258, 3333},
{5, 4414, 52, 24, 12265, 3113},
{5, 4419, 53, 24, 12269, 1503},
{5, 4429, 52, 86, 12274, 1106},
{5, 4435, 52, 86, 12277, 1305},
{5, 4438, 52, 86, 12278, 1300},
{5, 4442, 52, 86, 12281, 948},
{5, 4448, 53, 24, 12283, 2837},
{5, 4449, 52, 30, 12282, 4406},
{5, 4450, 52, 24, 12285, 1705},
{5, 4459, 52, 24, 12290, 1359},
{5, 4473, 52, 24, 12298, 1326},
{5, 4477, 52, 24, 12300, 1338},
{5, 4478, 53, 86, 12303, 1220},
{5, 4485, 53, 30, 12305, 4142},
{5, 4490, 52, 30, 12306, 4139},
{5, 4494, 52, 24, 12314, 2546},
{5, 4517, 52, 86, 12328, 7},
{5, 4526, 52, 86, 12340, 742},
{5, 4527, 52, 86, 12341, 239},
{5, 4535, 52, 86, 12343, 812},
{5, 4536, 52, 86, 12344, 211},
{5, 4546, 52, 86, 12355, -348},
{5, 4550, 53, 86, 12355, 1213},
{5, 4559, 52, 24, 12360, 2758},
{5, 4565, 52, 24, 12363, 2559},
{5, 4567, 53, 86, 12365, 1115},
{5, 4568, 52, 86, 12366, 1114},
{5, 4570, 52, 86, 12369, 715},
{5, 4596, 52, 86, 12399, 1011},
{5, 4605, 52, 83, 12400, 6136},
{5, 4618, 52, 30, 12416, 4109},
{5, 4631, 51, 30, 12421, 3232},
{5, 4636, 52, 86, 12428, 241},
{5, 4643, 52, 86, 12433, 159},
{5, 4654, 52, 86, 12439, 1308},
{5, 4656, 52, 30, 12440, 3210},
{5, 4660, 53, 86, 12445, 1111},
{5, 4665, 52, 86, 12451, 303},
{5, 4666, 52, 86, 12451, -28},
{5, 4689, 52, 24, 12478, 1346},
{5, 4697, 51, 86, 12486, -548},
{5, 4698, 52, 86, 12484, 829},
{5, 4699, 52, 86, 12490, -840},
{5, 4725, 51, 24, 12504, 2530},
{5, 4753, 52, 86, 12524, -112},
{5, 4754, 52, 86, 12523, 1119},
{5, 4762, 52, 86, 12529, 1114},
{5, 4781, 53, 86, 12544, -1032},
{5, 4800, 53, 30, 12546, 4632},
{5, 4845, 53, 86, 12580, 135},
{5, 4856, 52, 86, 12594, -1503},
{5, 4866, 53, 86, 12595, 1410},
{5, 4889, 53, 24, 13001, 2759},
{5, 4900, 53, 86, 13007, 230},
{5, 4902, 52, 86, 13010, -1431},
{5, 4945, 51, 15, 13054, -4928},
{5, 4958, 52, 86, 13058, -801},
{5, 4995, 53, 86, 13097, -750},
{5, 5005, 52, 30, 13109, 3703},
{5, 5033, 52, 30, 13135, 3636},
{5, 5053, 122, 24, 13165, 1742},
{5, 5054, 52, 86, 13170, -1638},
{5, 5068, 52, 86, 13189, -2102},
{5, 5078, 53, 42, 13198, -2725},
{5, 5102, 52, 15, 13220, -3638},
{5, 5128, 49, 15, 13255, -4301},
{5, 5139, 116, 15, 13268, -4729},
{5, 5247, 52, 86, 13380, -1753},
{5, 5248, 52, 9, 13375, 853},
{5, 5273, 53, 30, 13421, 3539},
{5, 5286, 119, 15, 13464, -5122},
{5, 5322, 52, 83, 13492, 6011},
{5, 5350, 53, 30, 13534, 4022},
{5, 5353, 53, 30, 13534, 4017},
{5, 5354, 53, 30, 13534, 4018},
{5, 5363, 52, 86, 13561, 515},
{5, 5364, 52, 86, 13562, 501},
{5, 5371, 52, 30, 13557, 4028},
{5, 5427, 53, 86, 14034, -602},
{5, 5466, 121, 9, 14055, 2832},
{5, 5473, 53, 83, 14047, 5454},
{5, 5474, 52, 83, 14050, 5340},
{5, 5557, 53, 9, 14184, 3630},
{5, 5566, 52, 86, 14203, 356},
{5, 5576, 53, 86, 14211, 316},
{5, 5631, 53, 83, 14266, 5635},
{5, 5634, 122, 86, 14296, -559},
{5, 5643, 52, 50, 14327, -4411},
{5, 5676, 53, 9, 14328, 4927},
{5, 5689, 53, 9, 14355, 4844},
{5, 5694, 122, 42, 14396, -2632},
{5, 5746, 52, 86, 14449, 157},
{5, 5813, 52, 86, 15012, 142},
{5, 5822, 133, 50, 15044, -5424},
{5, 5823, 134, 19, 15055, -5536},
{5, 5824, 121, 50, 15040, -3304},
{5, 5846, 52, 86, 15065, 136},
{5, 5850, 52, 86, 15071, 133},
{5, 5897, 120, 48, 15174, -2101},
{5, 5907, 52, 34, 15159, 5620},
{5, 5927, 120, 50, 15280, -5040},
{5, 5946, 120, 57, 15355, -5040},
{5, 5982, 53, 34, 15387, 5921},
{5, 5986, 120, 50, 15461, -3747},
{5, 6067, 132, 57, 16132, -5413},
{5, 6118, 53, 74, 16218, -217},
{5, 6124, 132, 72, 16253, -4039},
{5, 6134, 133, 57, 16278, -4909},
{5, 6144, 121, 72, 16272, -2601},
{5, 6192, 135, 72, 16404, -4322},
{5, 6193, 131, 6, 16413, -4846},
{5, 6204, 134, 6, 16462, -4701},
{5, 6207, 53, 40, 16431, 3650},
{5, 6210, 94, 40, 16445, 2348},
{5, 6217, 53, 84, 16326, 7812},
{5, 6222, 136, 72, 16494, -4444},
{5, 6229, 121, 40, 16470, 4732},
{5, 6231, 129, 72, 16542, -4149},
{5, 6235, 121, 59, 16534, -2211},
{5, 6242, 132, 72, 16556, -3928},
{5, 6259, 134, 72, 17008, -4439},
{5, 6281, 131, 72, 17047, -3759},
{5, 6284, 121, 59, 17045, -2446},
{5, 6287, 121, 59, 17052, -2242},
{5, 6293, 120, 59, 17102, -2635},
{5, 6302, 96, 72, 17137, -3706},
{5, 6304, 120, 59, 17145, -2928},
{5, 6309, 95, 59, 17141, -1255},
{5, 6316, 120, 59, 17166, -2808},
{5, 6334, 70, 72, 17208, -3606},
{5, 6342, 122, 59, 17212, -1935},
{5, 6352, 120, 6, 17255, -4825},
{5, 6355, 121, 59, 17240, -2621},
{5, 6356, 120, 59, 17236, -1749},
{5, 6366, 122, 59, 17277, -505},
{5, 6369, 95, 59, 17293, -2346},
{5, 6388, 119, 72, 17363, -4444},
{5, 6397, 117, 6, 17407, -5340},
{5, 6401, 119, 59, 17386, -2355},
{5, 6426, 122, 59, 17449, 310},
{5, 6440, 121, 77, 17489, -2022},
{5, 6441, 119, 72, 17502, -3703},
{5, 6445, 97, 77, 17493, -2001},
{5, 6451, 134, 72, 17507, -3013},
{5, 6453, 122, 72, 17509, -3436},
{5, 6503, 52, 34, 17495, 7009},
{5, 6517, 122, 59, 18018, -858},
{5, 6520, 134, 77, 18034, -2753},
{5, 6522, 122, 77, 18036, -3002},
{5, 6528, 122, 77, 18048, -3003},
{5, 6535, 121, 74, 18038, -18},
{5, 6539, 121, 74, 18048, -735},
{5, 6541, 118, 25, 18080, -4342},
{5, 6543, 92, 34, 17586, 6638},
{5, 6544, 120, 77, 18073, -2500},
{5, 6553, 120, 77, 18093, -2554},
{5, 6568, 135, 77, 18128, -2135},
{5, 6569, 120, 77, 18136, -3150},
{5, 6572, 92, 59, 18121, 651},
{5, 6583, 136, 77, 18158, -2208},
{5, 6603, 137, 77, 18184, -1824},
{5, 6624, 120, 77, 18237, -3022},
{5, 6629, 94, 77, 18257, -2312},
{5, 6633, 131, 59, 18273, 631},
{5, 6638, 121, 77, 18309, -2530},
{5, 6642, 121, 77, 18319, -2329},
{5, 6645, 135, 77, 18320, -1653},
{5, 6649, 135, 73, 18335, -1024},
{5, 6652, 121, 77, 18358, -3259},
{5, 6664, 134, 73, 18366, -749},
{5, 6712, 120, 73, 18531, -842},
{5, 6723, 119, 77, 18596, -3638},
{5, 6726, 70, 25, 19017, -3653},
{5, 6727, 70, 25, 19017, -3653},
{5, 6729, 70, 25, 19019, -3657},
{5, 6752, 117, 61, 19109, -5959},
{5, 6755, 134, 4, 19078, 416},
{5, 6756, 136, 4, 19087, 442},
{5, 6760, 121, 4, 19112, 102},
{5, 6781, 95, 4, 19185, 632},
{5, 6791, 136, 52, 19207, 3751},
{5, 6802, 135, 88, 19306, 2016},
{5, 6818, 94, 77, 19440, -1409},
{5, 6819, 133, 31, 19413, 4011},
{5, 6822, 51, 77, 19449, -1448},
{5, 6823, 133, 88, 19432, 2318},
{5, 6826, 93, 31, 19448, 5032},
{5, 6830, 134, 88, 19510, 2306},
{5, 6834, 134, 31, 19522, 2924},
{5, 6857, 67, 31, 20028, 3331},
{5, 6866, 134, 31, 20039, 4410},
{5, 6885, 134, 88, 20119, 2629},
{5, 6888, 66, 31, 20128, 3819},
{5, 6905, 96, 32, 20224, 2006},
{5, 6907, 53, 12, 20251, -2449},
{5, 6910, 133, 31, 20232, 4047},
{5, 6934, 121, 32, 20342, 724},
{5, 6939, 134, 16, 20315, 6040},
{5, 6940, 132, 88, 20344, 2817},
{5, 6946, 51, 16, 20349, 6009},
{5, 6960, 105, 31, 20457, 3043},
{5, 6974, 112, 31, 20511, 3150},
{5, 6979, 70, 31, 20510, 3208},
{5, 6992, 105, 31, 20564, 3143},
{5, 6995, 105, 31, 20571, 3113},
{5, 7000, 60, 31, 21018, 4412},
{5, 7006, 122, 32, 21015, 1611},
{5, 7008, 96, 31, 21005, 5433},
{5, 7009, 92, 5, 21042, -1122},
{5, 7023, 77, 16, 21005, 6810},
{5, 7026, 96, 31, 21063, 4751},
{5, 7027, 94, 31, 21070, 4214},
{5, 7044, 138, 31, 21129, 4229},
{5, 7062, 134, 31, 21235, 4623},
{5, 7086, 134, 31, 21305, 5136},
{5, 7090, 52, 44, 21365, -5433},
{5, 7128, 136, 31, 21440, 5343},
{5, 7129, 81, 16, 21430, 6607},
{5, 7142, 135, 16, 21452, 6546},
{5, 7160, 132, 16, 21537, 6236},
{5, 7184, 52, 5, 22027, -2049},
{5, 7209, 134, 45, 22051, 4629},
{5, 7217, 52, 62, 22079, 3122},
{5, 7243, 132, 45, 22151, 4954},
{5, 7293, 90, 5, 22296, -2050},
{5, 7296, 136, 45, 22282, 5217},
{5, 7320, 54, 62, 22361, 3357},
{5, 7331, 52, 62, 22371, 3425},
{5, 7380, 133, 16, 22473, 5808},
{5, 7424, 52, 39, 22573, -4104},
{5, 7448, 53, 62, 23001, 1559},
{5, 7479, 52, 62, 23049, 1219},
{5, 7510, 134, 16, 23115, 6034},
{5, 7582, 52, 39, 23184, -4222},
{5, 7606, 52, 5, 23191, -829},
{5, 7619, 53, 62, 23202, 812},
{5, 7635, 67, 14, 23202, 6111},
{5, 7662, 93, 1, 23259, 4232},
{5, 7686, 132, 1, 23301, 4908},
{5, 7723, 53, 5, 23390, -1258},
{5, 7727, 52, 5, 23399, -1218},
{5, 7789, 133, 14, 23574, 5643},
{5, 7790, 135, 14, 23584, 6113},
{5, 7793, 51, 71, 23578, -3236},
{5, 7814, 52, 62, 32, 1609},
{0, 36, 146, 1, 550, +2338},
{15, 0, 142, 1, 2039, +4220},
{201, 228, 147, 1, 2140, +4729},
{201, 3050, 146, 1, 23595, +3343},
{0, 56, 146, 1, 1562, +3715},
{0, 59, 146, 1, 2109, +3902},
{24, 0, 146, 4, 19487, +1149},
{201, 2404, 147, 4, 18508, +1059},
{201, 2532, 146, 4, 19302, 254},
{0, 5, 146, 4, 18465, -58},
{0, 11, 145, 4, 18591, +1338},
{0, 15, 146, 4, 19050, -402},
{0, 57, 146, 4, 19546, -814},
{201, 2838, 146, 5, 21546, -318},
{32, 0, 144, 5, 22288, -1},
{0, 12, 146, 5, 21041, -549},
{0, 41, 146, 5, 22143, -2104},
{0, 53, 146, 5, 22266, -1645},
{0, 94, 145, 5, 23191, -1328},
{0, 107, 146, 5, 23460, -1841},
{12, 0, 145, 7, 2592, +2120},
{15, 0, 145, 7, 1535, +1918},
{20, 0, 145, 7, 1579, +2336},
{24, 0, 145, 7, 2493, +1728},
{201, 394, 147, 7, 3280, +2028},
{0, 1, 146, 7, 1501, +2217},
{0, 30, 147, 7, 2370, +2439},
{0, 33, 145, 7, 2407, +2704},
{16, 0, 143, 8, 5597, +3713},
{201, 644, 147, 8, 5103, +3718},
{201, 698, 147, 8, 5252, +3451},
{201, 872, 147, 8, 6156, +3609},
{29, 0, 145, 8, 4593, +3753},
{30, 0, 145, 8, 6467, +4335},
{0, 14, 145, 8, 5154, +3241},
{0, 26, 145, 8, 5386, +3030},
{0, 41, 146, 8, 6116, +4843},
{132, 147, 147, 8, 6343, +3805},
{11, 0, 144, 9, 15155, +3319},
{12, 0, 143, 9, 14450, +2704},
{17, 0, 145, 9, 14162, +5122},
{19, 0, 145, 9, 14135, +5147},
{21, 0, 144, 9, 15245, +3723},
{24, 0, 145, 9, 14407, +1625},
{201, 1825, 146, 9, 14165, +2007},
{201, 1835, 145, 9, 14234, +827},
{201, 1884, 147, 9, 14484, +2422},
{31, 0, 145, 9, 14514, +1906},
{32, 0, 144, 9, 14411, +1344},
{0, 39, 146, 9, 14497, +4843},
{0, 44, 145, 9, 15038, +4739},
{162, 191, 147, 9, 14596, +5352},
{201, 1694, 145, 11, 12492, +8325},
{201, 400, 147, 11, 3350, +6002},
{201, 485, 147, 11, 4078, +6220},
{0, 1, 146, 11, 4320, +5355},
{0, 11, 145, 11, 5061, +5858},
{6, 0, 144, 12, 20176, -1230},
{23, 0, 146, 12, 20299, -1835},
{24, 0, 145, 12, 20273, -1813},
{26, 0, 145, 12, 20289, -1749},
{27, 0, 145, 12, 20194, -1907},
{17, 0, 145, 14, 2291, +6724},
{18, 0, 144, 14, 491, +5749},
{27, 0, 145, 14, 23590, +5545},
{201, 163, 147, 14, 1513, +6451},
{201, 3053, 146, 14, 26, +6606},
{201, 3062, 146, 14, 63, +5826},
{0, 3, 145, 15, 13518, -3300},
{9, 0, 143, 16, 21287, +7034},
{11, 0, 144, 16, 22292, +5825},
{19, 0, 144, 16, 20089, +7743},
{201, 2780, 147, 16, 21118, +5959},
{201, 2816, 146, 16, 21390, +5729},
{201, 2840, 146, 16, 21520, +5548},
{201, 460, 146, 16, 4100, +8042},
{31, 0, 144, 16, 22038, +6438},
{132, 461, 147, 16, 22039, +5949},
{10, 0, 145, 17, 1496, -1041},
{15, 0, 144, 17, 2433, +314},
{201, 186, 147, 17, 1559, +151},
{0, 66, 146, 17, 2128, -224},
{6, 0, 140, 20, 6451, -1643},
{12, 0, 142, 20, 6586, -2858},
{21, 0, 145, 20, 6561, -1403},
{108, 3945, 145, 20, 7166, -2319},
{17, 0, 144, 22, 8467, +2846},
{25, 0, 146, 22, 8268, +2656},
{201, 1177, 147, 22, 8056, +2732},
{201, 1245, 146, 22, 8358, 637},
{201, 1254, 147, 22, 8404, +1940},
{201, 1311, 147, 22, 9074, +2259},
{32, 0, 145, 22, 8122, +1739},
{0, 57, 146, 22, 8542, +3035},
{0, 66, 146, 22, 9014, +3215},
{201, 1633, 147, 24, 12207, +2703},
{201, 1639, 147, 24, 12244, +2535},
{0, 2, 146, 24, 12043, +2128},
{0, 24, 145, 24, 12351, +1823},
{0, 35, 145, 24, 12533, +2115},
{15, 0, 145, 25, 19064, -3704},
{19, 0, 146, 25, 18334, -3844},
{15, 0, 144, 26, 15427, +2618},
{18, 0, 146, 26, 15232, +3017},
{27, 0, 146, 26, 16147, +3352},
{32, 0, 145, 26, 15394, +3638},
{132, 128, 146, 26, 16117, +3321},
{11, 0, 143, 29, 12299, -1631},
{201, 1604, 147, 29, 12095, -1151},
{6, 0, 143, 30, 12560, +3819},
{0, 2, 146, 30, 12161, +4040},
{9, 0, 143, 31, 19307, +2758},
{11, 0, 143, 31, 19450, +4508},
{20, 0, 145, 31, 20474, +3629},
{21, 0, 145, 31, 21441, +2845},
{21, 0, 145, 31, 21441, +2845},
{201, 2486, 147, 31, 19121, +4951},
{30, 0, 145, 31, 19556, +5226},
{0, 16, 146, 31, 19418, +5032},
{0, 31, 144, 31, 20136, +4644},
{0, 49, 146, 31, 20410, +3218},
{0, 61, 145, 31, 21069, +3845},
{132, 130, 146, 31, 21208, +3227},
{103, 5137, 146, 31, 19459, +3501},
{15, 0, 144, 32, 20467, +1607},
{12, 0, 144, 34, 19482, +7016},
{21, 0, 146, 34, 17053, +5428},
{22, 0, 145, 34, 17322, +5511},
{23, 0, 145, 34, 18512, +5923},
{201, 2155, 147, 34, 17161, +6043},
{201, 2348, 146, 34, 18339, +5221},
{30, 0, 145, 34, 17419, +7209},
{0, 17, 145, 34, 16362, +5255},
{0, 41, 146, 34, 18002, +8000},
{132, 123, 147, 34, 13271, +6444},
{12, 0, 145, 35, 20591, +418},
{201, 2742, 147, 35, 21022, +711},
{16, 0, 143, 36, 2583, -4018},
{11, 5, 146, 36, 1398, -5612},
{0, 55, 147, 36, 4436, -848},
{108, 3556, 146, 36, 3124, -4425},
{29, 0, 145, 37, 2338, -2814},
{6, 0, 142, 38, 7346, +3153},
{11, 0, 144, 38, 7201, +2159},
{19, 0, 144, 38, 7444, +2424},
{201, 1083, 147, 38, 7256, +2030},
{201, 1108, 147, 38, 7328, +2253},
{0, 38, 145, 38, 6546, +1311},
{162, 70, 147, 38, 6278, +2047},
{6, 0, 143, 40, 17146, +1423},
{11, 0, 143, 40, 17150, +2450},
{19, 0, 145, 40, 16081, +1703},
{26, 0, 145, 40, 17237, +3709},
{201, 2052, 147, 40, 16289, +1825},
{201, 2063, 146, 40, 16318, +4536},
{201, 2315, 147, 40, 18250, +2724},
{201, 2411, 147, 40, 18523, +1432},
{0, 37, 146, 40, 16406, +413},
{0, 56, 146, 40, 16550, +2544},
{0, 95, 145, 40, 18015, +2136},
{0, 100, 146, 40, 18078, +2606},
{132, 129, 147, 40, 18359, +1659},
{12, 0, 143, 42, 8468, +625},
{201, 1348, 148, 42, 9245, +621},
{201, 1355, 147, 42, 9273, +614},
{201, 1365, 147, 42, 9315, +128},
{28, 0, 145, 42, 9291, -246},
{103, 396, 146, 42, 11323, -2916},
{201, 2894, 146, 45, 22189, +3746},
{0, 8, 146, 45, 22359, +3938},
{6, 0, 141, 46, 10084, +1158},
{15, 0, 142, 46, 10200, +1950},
{28, 0, 145, 46, 11279, +251},
{0, 6, 145, 46, 9320, +943},
{0, 49, 146, 46, 10350, +839},
{0, 54, 144, 46, 10556, +2445},
{0, 81, 146, 46, 11256, +1627},
{0, 83, 147, 46, 11268, +301},
{0, 90, 146, 46, 11347, +1648},
{132, 215, 147, 46, 10163, +1744},
{15, 0, 144, 47, 5445, -2227},
{108, 3750, 145, 47, 5204, -2114},
{21, 0, 145, 48, 14493, -1409},
{23, 0, 146, 48, 15210, -1533},
{201, 1962, 146, 48, 15387, -847},
{31, 0, 145, 50, 15569, -3358},
{201, 1282, 147, 51, 8508, +3504},
{201, 1333, 147, 51, 9184, +3522},
{201, 1338, 147, 51, 9210, +3811},
{201, 1369, 147, 51, 9354, +3958},
{201, 958, 146, 51, 6482, +5542},
{0, 12, 145, 51, 6462, +5927},
{0, 19, 146, 51, 7229, +5517},
{0, 38, 144, 51, 9188, +3648},
{9, 0, 144, 52, 18501, +3322},
{13, 0, 145, 52, 18443, +3940},
{14, 0, 145, 52, 18443, +3940},
{18, 0, 144, 52, 19138, +3909},
{201, 2474, 147, 52, 19091, +3436},
{32, 0, 144, 52, 18448, +3736},
{200, 0, 145, 52, 18570, +3254},
{162, 282, 146, 52, 18549, +3358},
{108, 5218, 147, 54, 20454, -3029},
{9, 0, 145, 55, 6288, -702},
{12, 0, 144, 55, 6238, +436},
{20, 0, 144, 59, 16309, +159},
{23, 0, 145, 59, 17180, -2417},
{26, 0, 145, 59, 16256, -2327},
{201, 2276, 147, 59, 18057, +1200},
{28, 0, 145, 59, 18031, -811},
{0, 36, 145, 59, 17153, -2636},
{0, 61, 146, 59, 17446, +235},
{0, 70, 144, 59, 18055, +230},
{9, 0, 140, 60, 5145, -812},
{11, 0, 142, 60, 5320, -18},
{16, 0, 145, 60, 5353, -523},
{17, 0, 143, 60, 5354, -555},
{18, 0, 144, 60, 5245, -224},
{20, 0, 144, 60, 5351, +956},
{26, 0, 145, 60, 5133, +252},
{27, 0, 144, 60, 5387, -236},
{201, 747, 145, 60, 5350, -600},
{201, 790, 146, 60, 5460, -416},
{32, 0, 142, 60, 5407, -157},
{0, 14, 146, 60, 5079, +830},
{0, 23, 145, 60, 5228, +333},
{0, 32, 144, 60, 5308, 557},
{0, 33, 146, 60, 5312, +318},
{0, 52, 146, 60, 5480, +627},
{12, 0, 143, 62, 21442, +953},
{201, 2841, 146, 62, 21543, +1943},
{201, 3007, 147, 62, 23228, +2034},
{0, 1, 144, 62, 21221, +1948},
{18, 0, 144, 63, 2507, +5554},
{201, 162, 146, 63, 1493, +4754},
{201, 331, 145, 63, 3009, +5221},
{201, 336, 147, 63, 3015, +3225},
{201, 369, 147, 63, 3171, +4029},
{0, 56, 146, 63, 4246, +3358},
{11, 24, 146, 66, 22366, -3140},
{6, 0, 144, 67, 2020, +246},
{201, 22, 147, 67, 174, +853},
{201, 3009, 147, 67, 23243, +343},
{30, 0, 145, 67, 1057, +2128},
{32, 0, 145, 67, 1137, +735},
{0, 35, 144, 67, 150, +849},
{0, 55, 146, 67, 399, +2126},
{0, 65, 146, 67, 499, +2743},
{0, 66, 146, 67, 546, +1911},
{0, 77, 146, 67, 1058, +455},
{112, 0, 145, 68, 7183, -3644},
{110, 19, 146, 68, 7343, -2328},
{103, 327, 144, 68, 7388, -2648},
{6, 0, 141, 72, 16294, -2626},
{9, 0, 143, 72, 16054, -1948},
{22, 0, 144, 72, 16120, -1928},
{31, 0, 145, 72, 16044, -1122},
{11, 0, 144, 74, 15348, +1032},
{16, 0, 145, 74, 18562, +412},
{201, 1919, 147, 74, 15127, +1917},
{0, 59, 145, 74, 18272, +12},
{132, 127, 146, 74, 15402, +1203},
{15, 0, 145, 75, 9525, -806},
{153, 0, 147, 75, 9541, +457},
{0, 35, 146, 75, 10433, +445},
{0, 40, 147, 75, 10493, -401},
{32, 0, 145, 76, 19490, +1909},
{110, 84, 146, 76, 19394, +1634},
{138, 0, 145, 77, 17591, -3015},
{0, 54, 145, 77, 19407, -1618},
{108, 5082, 146, 77, 19031, -1915},
{10, 0, 145, 78, 4226, +2538},
{25, 0, 145, 78, 4204, +2721},
{201, 422, 146, 78, 3368, +35},
{201, 495, 146, 78, 4077, +1510},
{201, 572, 147, 78, 4385, +2656},
{0, 7, 147, 78, 3344, +2428},
{0, 62, 146, 78, 4240, +2418},
{0, 118, 146, 78, 5293, +2509},
{201, 239, 147, 81, 2174, +2845},
{0, 6, 145, 81, 2124, +3018},
{27, 0, 145, 83, 9104, +6708},
{201, 1520, 147, 83, 11161, +5246},
{201, 1523, 144, 83, 11182, +3132},
{201, 1695, 146, 83, 12563, +5406},
{32, 0, 142, 83, 13239, +5456},
{132, 126, 146, 83, 11323, +6105},
{6, 0, 142, 84, 2318, +8916},
{201, 1972, 147, 84, 15292, +8027},
{108, 2682, 147, 84, 13407, +7651},
{11, 70, 145, 85, 8295, -4443},
{108, 4191, 145, 85, 9144, -4314},
{15, 0, 143, 86, 12417, -127},
{28, 0, 144, 86, 14016, +133},
{0, 17, 147, 86, 12225, +518},
{60, 0, 161, 1, 275, 3535},
{166, 0, 162, 1, 23388, 3546},
{167, 0, 162, 1, 46, 4333},
{167, 0, 162, 1, 46, 4333},
{181, 0, 161, 1, 2384, 3910},
{185, 0, 162, 1, 199, 4443},
{107, 5223, 162, 1, 542, 2404},
{130, 15196, 162, 1, 542, 2404},
{179, 0, 162, 4, 18585, 1422},
{182, 0, 161, 4, 19044, -541},
{182, 1469, 162, 4, 20011, 931},
{130, 11960, 161, 4, 19232, -1042},
{147, 0, 163, 5, 23244, -1719},
{182, 0, 162, 7, 2150, 1214},
{90, 0, 163, 8, 5034, 5038},
{96, 0, 162, 8, 5481, 3038},
{148, 0, 164, 8, 6348, 4230},
{152, 0, 162, 8, 5271, 3409},
{176, 0, 163, 8, 5091, 3900},
{178, 0, 159, 8, 6365, 3827},
{179, 0, 161, 8, 5218, 3231},
{182, 0, 163, 8, 6240, 4742},
{182, 346, 163, 8, 4526, 3830},
{149, 0, 163, 9, 14242, 2542},
{147, 0, 162, 11, 7217, 6940},
{152, 0, 162, 11, 5410, 6848},
{166, 0, 161, 11, 4512, 6810},
{177, 0, 161, 11, 3418, 6239},
{179, 0, 162, 11, 4059, 6148},
{196, 0, 161, 11, 4086, 5322},
{146, 0, 161, 12, 20171, -2119},
{129, 0, 164, 14, 246, 5417},
{166, 0, 165, 14, 175, 1714},
{187, 0, 162, 14, 549, 5834},
{191, 0, 163, 14, 1336, 5745},
{193, 0, 161, 14, 13, 6021},
{182, 623, 161, 14, 3114, 5754},
{21, 0, 162, 16, 21435, 5848},
{152, 0, 161, 16, 21352, 7837},
{107, 16115, 162, 17, 2351, -927},
{157, 129989, 162, 17, 2351, -9264},
{187, 0, 160, 20, 7081, -1155},
{139, 0, 161, 21, 7087, 1001},
{171, 0, 162, 22, 8567, 1931},
{194, 0, 160, 22, 8554, 1714},
{139, 0, 160, 26, 15486, 2809},
{182, 0, 161, 26, 15495, 3934},
{172, 0, 162, 30, 12594, 3749},
{197, 0, 159, 30, 12451, 4526},
{66, 0, 161, 31, 19288, 4603},
{67, 0, 162, 31, 19572, 4416},
{82, 0, 162, 31, 20468, 4603},
{145, 0, 161, 31, 20134, 3844},
{148, 0, 161, 31, 21433, 3801},
{150, 0, 163, 31, 20104, 3557},
{168, 0, 163, 31, 20095, 4752},
{172, 0, 161, 31, 19409, 3237},
{177, 0, 160, 31, 20196, 4754},
{182, 0, 162, 31, 20413, 4808},
{182, 0, 162, 31, 20413, 4808},
{192, 0, 163, 31, 20186, 3727},
{182, 460, 160, 31, 21420, 3531},
{107, 189256, 162, 31, 19572, 4418},
{157, 106516, 162, 32, 20486, 1750},
{150, 0, 160, 34, 12564, 6560},
{171, 0, 161, 34, 17564, 5813},
{180, 0, 160, 34, 19216, 7634},
{169, 0, 162, 36, 5098, -531},
{75, 0, 162, 38, 7209, 2460},
{129, 0, 161, 38, 7319, 2430},
{173, 0, 161, 38, 6109, 2601},
{184, 0, 162, 38, 6421, 3127},
{33, 0, 161, 40, 18303, 2152},
{144, 0, 162, 40, 16042, 5030},
{157, 46574, 161, 40, 17135, 4206},
{177, 0, 159, 42, 10376, -1323},
{182, 0, 161, 42, 10516, -2115},
{197, 0, 161, 42, 9511, -2301},
{139, 0, 160, 46, 9476, 1124},
{139, 0, 160, 47, 4596, -1448},
{197, 0, 161, 51, 7282, 460},
{109, 0, 162, 52, 18428, 3658},
{171, 0, 162, 52, 18323, 3660},
{177, 0, 162, 52, 19202, 3753},
{73, 0, 163, 55, 6564, 76},
{96, 0, 163, 55, 6224, 325},
{102, 0, 162, 55, 6532, -435},
{148, 0, 161, 55, 6584, 610},
{150, 0, 162, 55, 7069, -733},
{182, 614, 161, 55, 7010, -315},
{175, 0, 161, 59, 17297, -1928},
{182, 0, 161, 59, 16267, -1226},
{74, 0, 160, 60, 6255, 1443},
{101, 0, 164, 60, 6177, 831},
{146, 0, 162, 60, 5332, 709},
{190, 0, 160, 60, 5054, 111},
{149, 0, 162, 62, 21564, 2248},
{33, 0, 163, 63, 3451, 4447},
{149, 0, 162, 63, 21564, 2252},
{151, 0, 162, 63, 22059, 3330},
{197, 0, 162, 63, 3277, 4411},
{182, 466, 162, 63, 3415, 5130},
{176, 0, 159, 67, 23464, 329},
{198, 0, 161, 67, 1161, 2546},
{107, 26, 162, 67, 54, 847},
{157, 109003, 162, 67, 54, 847},
{157, 128396, 163, 67, 23491, 623},
{147, 0, 162, 68, 8075, -2255},
{148, 0, 163, 73, 18474, -1313},
{149, 0, 162, 73, 18370, -736},
{165, 0, 160, 73, 18583, -754},
{171, 0, 162, 73, 18554, -86},
{87, 0, 162, 74, 18474, 530},
{94, 0, 163, 74, 18194, -1537},
{72, 0, 163, 76, 20024, 2105},
{76, 0, 162, 76, 20024, 2036},
{195, 0, 161, 76, 20051, 2039},
{60, 0, 161, 77, 19343, -1622},
{170, 0, 162, 77, 17449, -1839},
{182, 1942, 161, 77, 19192, -1555},
{167, 0, 163, 78, 5491, 1904},
{172, 0, 162, 78, 4515, 2832},
{173, 0, 160, 78, 5452, 2425},
{197, 0, 161, 78, 5457, 2042},
{146, 0, 163, 83, 9184, 5124},
{186, 0, 160, 83, 10451, 6725},
{147, 0, 162, 86, 12473, 409},
{165, 0, 160, 86, 12252, 46},
{107, 113801, 163, 86, 13064, -2004},
{157, 157721, 163, 86, 13064, -2004},
{68, 0, 162, 88, 20373, 2630},
{130, 13571, 162, 88, 21099, 2637},
{34, 0, 169, 36, 1377, -5714},
{35, 0, 171, 72, 16054, -1948},
{36, 0, 169, 28, 12266, -6306},
{37, 0, 170, 20, 6586, -2858},
{38, 0, 169, 15, 14038, -6022},
{39, 0, 170, 1, 2039, 4220},
{40, 0, 169, 78, 4359, 1631},
{41, 0, 170, 16, 21186, 6235},
{42, 0, 170, 39, 22427, -4653},
{43, 0, 170, 63, 3243, 4952},
{44, 0, 170, 46, 10200, 1950},
{45, 0, 170, 63, 3082, 4057},
{46, 0, 170, 38, 6377, 1624},
{47, 0, 170, 83, 12540, 5558},
{48, 0, 170, 83, 13475, 4919},
{49, 0, 170, 39, 22082, -4658},
{50, 0, 170, 60, 5362, -112},
{51, 0, 170, 60, 5408, -157},
{52, 0, 170, 42, 9276, -840},
{53, 0, 170, 26, 15347, 2643},
{54, 0, 170, 1, 84, 2905},
{55, 0, 170, 85, 8095, -4720},
{56, 0, 169, 4, 19508, 852},
{57, 0, 170, 20, 7241, -2918},
{58, 0, 170, 64, 263, -4218},
{59, 0, 169, 72, 16294, -2626},
{61, 0, 168, 9, 14157, 1911},
{62, 0, 171, 47, 5327, -1749},
{63, 0, 170, 13, 9171, -5917},
{64, 0, 170, 80, 16487, -6902},
{65, 0, 170, 13, 8225, -5931},
{69, 0, 169, 28, 12477, -5941},
{70, 0, 170, 60, 5251, 621},
{71, 0, 169, 60, 5552, 724},
{77, 0, 168, 13, 6240, -5242},
{78, 0, 168, 8, 5167, 4560},
{79, 0, 170, 14, 92, 5909},
{80, 0, 170, 38, 7346, 3153},
{81, 0, 170, 14, 567, 6043},
{83, 0, 169, 31, 20414, 4517},
{84, 0, 170, 17, 436, -1759},
{85, 0, 170, 46, 11491, 1434},
{86, 0, 170, 17, 436, -1759},
{88, 0, 170, 72, 16003, -2237},
{89, 0, 170, 83, 11037, 6145},
{91, 0, 170, 78, 5263, 2836},
{92, 0, 170, 34, 17566, 5129},
{93, 0, 170, 62, 21442, 953},
{95, 0, 169, 66, 22577, -2937},
{97, 0, 170, 28, 12312, -5707},
{98, 0, 170, 26, 15347, 2643},
{99, 0, 171, 31, 20462, 3358},
{100, 0, 170, 72, 17425, -3902},
{104, 0, 169, 15, 14038, -6022},
{105, 0, 170, 7, 2072, 2328},
{106, 0, 171, 59, 16372, -1034},
{111, 0, 170, 9, 14450, 2704},
{113, 0, 170, 77, 18242, -3423},
{114, 0, 170, 84, 14507, 7409},
{115, 0, 170, 85, 8447, -5443},
{116, 0, 170, 62, 23048, 1512},
{117, 0, 170, 8, 5595, 4457},
{118, 0, 171, 17, 3023, 405},
{119, 0, 170, 15, 14067, -3622},
{120, 0, 170, 83, 11018, 5623},
{121, 0, 170, 13, 9132, -6943},
{122, 0, 169, 28, 12477, -5941},
{123, 0, 170, 60, 5320, -18},
{124, 0, 170, 1, 1097, 3537},
{125, 0, 170, 63, 3243, 4952},
{126, 0, 170, 20, 6227, -1757},
{127, 0, 170, 83, 13239, 5456},
{128, 0, 170, 68, 8036, -4000},
{131, 0, 170, 77, 18553, -2618},
{133, 0, 170, 61, 20256, -5644},
{134, 0, 170, 83, 11538, 5342},
{135, 0, 170, 84, 2318, 8916},
{136, 0, 169, 38, 7453, 2802},
{137, 0, 168, 21, 7393, 514},
{140, 0, 170, 59, 17349, 1234},
{141, 0, 169, 46, 10084, 1158},
{142, 0, 168, 60, 5145, -812},
{143, 0, 168, 15, 14396, -6050},
{154, 0, 170, 59, 17104, -1543},
{155, 0, 170, 31, 20222, 4015},
{156, 0, 170, 60, 5478, -940},
{158, 0, 170, 72, 17373, -4260},
{159, 0, 170, 62, 23038, 2805},
{160, 0, 170, 14, 405, 5632},
{161, 0, 170, 72, 17336, -3706},
{163, 0, 168, 20, 6451, -1643},
{164, 0, 169, 86, 13252, -1110},
{174, 0, 170, 13, 9171, -5917},
{183, 0, 168, 52, 18369, 3847},
{188, 0, 170, 72, 16502, -3418},
{189, 0, 170, 20, 7084, -2624},
{199, 0, 171, 46, 11141, 2031},
{7, 0, 168, 15, 14396, -6050},
{8, 0, 169, 15, 14396, -6050},
{6, 0, 170, 50, 14419, -4723},
{9, 0, 170, 39, 22427, -4653},
{15, 0, 170, 14, 567, 6043},
{15, 0, 170, 15, 12415, -4858},
{11, 0, 171, 15, 12084, -5043},
{11, 0, 170, 85, 8447, -5443},
{12, 0, 170, 15, 13399, -5328},
{32, 0, 171, 15, 13555, -4717},
{32, 0, 171, 59, 16372, -1034},
{18, 0, 170, 15, 14355, -4209},
{19, 0, 170, 85, 9221, -5501},
{20, 0, 170, 85, 9080, -4326}
};
//###############################################################################################################
//###############################################################################################################
// variables for button - instead of bounce lib - save flash memory
//###############################################################################################################
const int DEBOUNCE_DELAY = 50; // the debounce time; increase if the output flickers
int lastSteadyState = LOW; // the previous steady state from the input pin
int lastFlickerableState = LOW; // the previous flickerable state from the input pin
int currentState; // the current reading from the input pin
unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
unsigned long lastPressedTime = 0;
//###############################################################################################################
//###############################################################################################################
// LCD - VSS - GND // VCC - 5V // RW - GND // K - GND
//###############################################################################################################
const byte rs = 12;
const byte en = 13;
const byte d4 = 9;
const byte d5 = 8;
const byte d6 = 7;
const byte d7 = 6;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
byte myLCDbacklight = 255;
byte myLCDcontrast = 100;
//###############################################################################################################
//###############################################################################################################
// variables to steer menu
//###############################################################################################################
byte myDisplayMode = 0;
const char *const menuTopic[] = {"DEC", "Align", "Target", "Region", "Const", "Brightness", "Contrast", "Sensors", "LX200"};
const byte menuTopic_size = sizeof(menuTopic) / sizeof(menuTopic[0]);
byte myMenuTopicNo = 0;
//###############################################################################################################
//###############################################################################################################
// definition of special / greek characters - for LCD 1602 chinese version - adapt to your LCD if needed
//###############################################################################################################
// used lcd is like this https://www.waveshare.com/datasheet/LCD_en_PDF/LCD1602.pdf (see 14. font table)
const char ch_deg = (char)(223); // degree symbol
const char ch_sigma = (char)(246); // uppercase Sigma
// greek alphabet 1-24 = α β γ δ ε ζ η θ ι κ λ μ ν ξ ο π ρ σ τ υ φ χ ψ ω
// maximum 8 custom characters
// γ
char ch_def_1 = 'g'; // for identificatrion & replacement
byte ch_custom_1[] = {
B00000,
B10011,
B10010,
B10010,
B01110,
B00100,
B00100,
B00100
};
// δ
char ch_def_2 = 'd';
byte ch_custom_2[] = {
B00110,
B01001,
B00100,
B01110,
B10001,
B10001,
B01110,
B00000
};
// ζ
char ch_def_3 = 'z';
byte ch_custom_3[] = {
B01111,
B00010,
B00100,
B01000,
B01000,
B01111,
B00001,
B00110
};
// λ
char ch_def_4 = 'l';
byte ch_custom_4[] = {
B01100,
B00100,
B00100,
B01010,
B01010,
B10001,
B10001,
B00000
};
// ξ
char ch_def_5 = 'x';
byte ch_custom_5[] = {
B11111,
B00100,
B01000,
B00111,
B01000,
B10000,
B11111,
B00010
};
// φ
char ch_def_6 = 'p';
byte ch_custom_6[] = {
B00000,
B10111,
B10101,
B10101,
B10101,
B01110,
B00100,
B00100
};
// ψ
char ch_def_7 = 's';
byte ch_custom_7[] = {
B00000,
B00100,
B10101,
B10101,
B10101,
B01110,
B00100,
B00100
};
// Δ
char ch_def_8 = 'D';
byte ch_custom_8[] = {
B00000,
B00100,
B01010,
B01010,
B10001,
B10001,
B11111,
B00000
};
// lookup table placeholder chars with greek symbols
struct greekSymbols {
char originalChar;
char replaceChar;
};
const unsigned int greekSymbols_size = 26;
const struct greekSymbols greekSymbols[greekSymbols_size] =
{
{'a', (char)(224)}, // α
{'b', (char)(226)}, // β
{'g', 'g'}, // γ custom character
{'d', 'd'}, // δ custom character
{'e', (char)(227)}, // ε
{'z', 'z'}, // ζ custom character
{'j', 'n'}, // η
{'h', (char)(242)}, // θ
{'i', 'l'}, // ι
{'k', 'k'}, // κ
{'l', 'l'}, // λ custom character
{'m', (char)(228)}, // μ
{'n', 'v'}, // ν
{'x', 'x'}, // ξ custom character
{'o', 'o'}, // ο
{'p', (char)(247)}, // π
{'r', (char)(230)}, // ρ
{'s', (char)(229)}, // σ
{'t', 't'}, // τ
{'y', (char)(232)}, // υ
{'q', 'p'}, // φ custom character
{'c', 'x'}, // χ
{'w', 's'}, // ψ custom character
{'u', 'w'},
{'F', (char)(246)}, // Σ
{'D', '/'} // Δ
};
//###############################################################################################################
//###############################################################################################################
// definition of constellation names
//###############################################################################################################
struct constStruct {
char constName[4];
};
constStruct myConstellation;
const unsigned int constStruct_size = 89;
const struct constStruct const_PROGMEM[constStruct_size] PROGMEM = {
{"all"}, {"And"}, {"Ant"}, {"Aps"}, {"Aql"}, {"Aqr"}, {"Ara"}, {"Ari"}, {"Aur"}, {"Boo"}, {"Cae"}, {"Cam"}, {"Cap"}, {"Car"}, {"Cas"}, {"Cen"}, {"Cep"}, {"Cet"}, {"Cha"}, {"Cir"},
{"CMa"}, {"CMi"}, {"Cnc"}, {"Col"}, {"Com"}, {"CrA"}, {"CrB"}, {"Crt"}, {"Cru"}, {"Crv"}, {"CVn"}, {"Cyg"}, {"Del"}, {"Dor"}, {"Dra"}, {"Equ"}, {"Eri"}, {"For"}, {"Gem"}, {"Gru"},
{"Her"}, {"Hor"}, {"Hya"}, {"Hyi"}, {"Ind"}, {"Lac"}, {"Leo"}, {"Lep"}, {"Lib"}, {"LMi"}, {"Lup"}, {"Lyn"}, {"Lyr"}, {"Men"}, {"Mic"}, {"Mon"}, {"Mus"}, {"Nor"}, {"Oct"}, {"Oph"},
{"Ori"}, {"Pav"}, {"Peg"}, {"Per"}, {"Phe"}, {"Pic"}, {"PsA"}, {"Psc"}, {"Pup"}, {"Pyx"}, {"Ret"}, {"Scl"}, {"Sco"}, {"Sct"}, {"Ser"}, {"Sex"}, {"Sge"}, {"Sgr"}, {"Tau"}, {"Tel"},
{"TrA"}, {"Tri"}, {"Tuc"}, {"UMa"}, {"UMi"}, {"Vel"}, {"Vir"}, {"Vol"}, {"Vul"}
};
byte myConstellationNo = 0;
String myConstellationName = "";
//###############################################################################################################
//###############################################################################################################
// object type name and variables for deep sky objects
//###############################################################################################################
const char* myObjectTypeName[] = {"Quasar", "Dark Nebula", "Galaxy", "Bright Neb", "Clust + Neb", "Planet Neb", "SN Rem", "Glob Cluster", "Open Cluster", "Double Star", "Red Star", "Reference", "any"};
unsigned int myRefNo = 0; // number of selected reference star
unsigned int myTargetNo = 0; // number of selected target
//###############################################################################################################
//###############################################################################################################
// definition of cellestial regions = constellations of seasons defined in groups (as in Deep Sky Atlas) to filter targets and reference stars
//###############################################################################################################
// constellation for which deep sky objects exist in the list 0 = all
const byte myAllCONST[] = {0, 1, 2, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 44, 45, 46, 47, 48, 49, 50, 51, 52, 54, 55, 57, 59, 60, 61, 62, 63, 64, 66, 67, 68, 69, 71, 72, 73, 74, 75, 76, 77, 78, 80, 81, 83, 84, 85, 86, 88};
const byte myAllCONST_size = sizeof(myAllCONST) / sizeof(myAllCONST[0]);
// North - UMI,UMA,DRA,CEP,CAS,CAM
const byte myNorthCONST[] = {84, 83, 34, 16, 14, 11};
const byte myNorthCONST_size = sizeof(myNorthCONST) / sizeof(myNorthCONST[0]);
// Spring - LEO,LMI,SEX,HYA,CVN,COM,VIR,CRT,CRV,BOO,CRB,SER
const byte mySpringCONST[] = {46, 49, 75, 42, 30, 24, 86, 27, 29, 9, 26, 74};
const byte mySpringCONST_size = sizeof(mySpringCONST) / sizeof(mySpringCONST[0]);
// Summer - HER,LYR,OPH,SCO,CYG,VUL,SGE,DEL,EQU,AQL,SCT,SER,SGR,CAP
const byte mySummerCONST[] = {40, 52, 59, 72, 31, 88, 76, 32, 35, 4, 73, 74, 77, 12};
const byte mySummerCONST_size = sizeof(mySummerCONST) / sizeof(mySummerCONST[0]);
// Autumn - LAC,PEG,AQR,PSA,AND,TRI,PER,ARI,PSC,CET,SCL,FOR,ERI
const byte myAutumnCONST[] = {45, 62, 5, 66, 1, 81, 63, 7, 67, 17, 71, 37, 36};
const byte myAutumnCONST_size = sizeof(myAutumnCONST) / sizeof(myAutumnCONST[0]);
// Winter - AUR,TAU,ORI,LEP,LYN,GEM,CMI,MON,CMA,PUP,CNC
const byte myWinterCONST[] = {8, 78, 60, 47, 51, 38, 21, 55, 20, 68, 22};
const byte myWinterCONST_size = sizeof(myWinterCONST) / sizeof(myWinterCONST[0]);
// South - ANT,VEL,CAR,VOL,CHA,MUS,CRU,CEN,CRU,TRA,LUP,NOR,ARA,SCO,SGR,CRA,TEL,MIC,IND,PAV,GRU,PHE,SCL,FOR,ERI,HOR,RET,HYI,TUC,DOR,CAE,COL,PUP,PYX,PIC,MEN,APS,OCT
const byte mySouthCONST[] = {2, 85, 13, 28, 15, 28, 80, 50, 57, 6, 72, 77, 25, 54, 44, 61, 39, 64, 71, 37, 36, 41, 33, 23, 68, 69, 65};
const byte mySouthCONST_size = sizeof(mySouthCONST) / sizeof(mySouthCONST[0]);
const char* myregionNAME[] = {"all", "North", "Spring", "Summer", "Autumn", "Winter", "South"}; // no south to save flash
const byte regionArraySize = sizeof(myregionNAME) / sizeof(myregionNAME[0]); // Anzahl der Einträge
byte myRegionNo = 0; // all - 0; North - 1; .... ; South - 6
String myregionName = "";
//###############################################################################################################
//###############################################################################################################
// variables for calculation of position // all positions are calculated in seconds
//###############################################################################################################
long myRefStartTimeSec = 0; // Startzeit beim Setzen des Referenzsterns in Sekunden
long myCurrentRAsec = 0; // meine aktuelle Rektaszension in Sekunden
long myCurrentDECsec = 0; // meine aktuelle Deklination in Sekunden
long myLastRAsec = 0; // meine letzte Rektaszension in Sekunden
long myLastDECsec = 0; // meine letzte Deklination in Sekunden
long myReferenceRAsec = 0; // meine Rektaszensionsreferenz in Sekunden
long myReferenceDECsec = 0; // meine Deklinationsreferenz in Sekunden
long mySensorRAsec = 0; // Sensorwert der Rektaszension in Sekunden
long mySensorDECsec = 0; // Sensorwert der Deklination in Sekunden
long myTargetRAsec = 0; // Rektaszension des Ziels in Sekunden
long myTargetDECsec = 0; // Deklination des Ziels in Sekunden
const int secPerStepRA = 86400L / IMPULSE24HRA; // defines how many seconds RA is changed per rotary step // (24h * 3600sec = 86400sec) / (1:139 * 20 impulse = 2780) --> 31,079 sec / i
const int secPerStepDEC = 1296000L / IMPULSE360DEGDEC; // defines how many seconds DEC is changed per rotary step // (360° * 3600sec = 1296000sec) / (1:96 * 20 impulse = 1920) / --> 675 sec / i
int myDirectionDEC = 1; // saves the value of the direction of the DEC axis, important if the telescope is turned over
//###############################################################################################################
//###############################################################################################################
// for rotary encoders
//###############################################################################################################
static uint8_t prevNextCode_ROT = 0;
static uint16_t store_ROT = 0;
static uint8_t prevNextCode_RA = 0;
static uint16_t store_RA = 0;
static uint8_t prevNextCode_DEC = 0;
static uint16_t store_DEC = 0;
static int8_t val_ROT, val_RA, val_DEC;
int myImpulseRA = 0, myImpulseDEC = 0;
int myLastImpulseRA = 0, myLastImpulseDEC = 0;
const int8_t enc_table[] = {0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0};
//###############################################################################################################
//###############################################################################################################
// variables for LX200
//###############################################################################################################
byte statusLX200 = 0; // 0 - BT switched off / 1 - BT switched on / 2 - connected via BT & LX200 (frequent connect to LX200)
byte statusLX200old = 0;
byte btStatus = 0; // 0 - off / 1 - on
unsigned long lastLX200Message = 0;
DSOstruct externalObject; // instance LX200 object
//###############################################################################################################
//###############################################################################################################
// setup
//###############################################################################################################
void setup()
{
// for LX200 protocol & debugging
Serial.begin (9600);
// while(!Serial); // attention - only for debugging when in use with IDE!
// Serial.println(F("started"));
getSettingsFromEeprom(); // load settings (brightness,contrast,...)
setReference(); // set reference object to saved values
setTarget(); // set target object to saved values
setupLCD();
createCustomCharacters();
setupRotaryEncoders();
initExternalObject();
}
// software reset Two Ways to Reset Arduino in Software (with Pictures) - Instructables
void(* resetFunc) (void) = 0;//declare reset function at address 0
void setupLCD()
{
lcd.begin(16, 2);
updateLCD();
pinMode(LCD_BACKLIGHT_PIN, OUTPUT);
analogWrite(LCD_CONTRAST_PIN, myLCDcontrast); //set contrast
}
//Creating custom characters in CG-RAM
void createCustomCharacters()
{
lcd.createChar(1 , ch_custom_1);
lcd.createChar(2 , ch_custom_2);
lcd.createChar(3 , ch_custom_3);
lcd.createChar(4 , ch_custom_4);
lcd.createChar(5 , ch_custom_5);
lcd.createChar(6 , ch_custom_6);
lcd.createChar(7 , ch_custom_7);
lcd.createChar(8 , ch_custom_8);
}
void setupRotaryEncoders()
{
// HMI rotary encoder button
pinMode(ROTARY_SW, INPUT_PULLUP);
// HMI rotary encoder
pinMode(ROTARY_CLK, INPUT);
pinMode(ROTARY_DT, INPUT);
// it is better to use the integrated pull-ups of KY-040 (this requires "+" to be connected to 5V) - https://forum.arduino.cc/index.php?topic=242356.0
// as analog pins are used for rotary encoders - internal pull-ups are additionally used to avoid akward behaviour if not connected to sensors
// RA rotary encoder
pinMode(SENS_RA_CLK, INPUT_PULLUP);
pinMode(SENS_RA_DT, INPUT_PULLUP);
// DEC rotary encoder
pinMode(SENS_DEC_CLK, INPUT_PULLUP);
pinMode(SENS_DEC_DT, INPUT_PULLUP);
// switch for BT module
pinMode(BT_SWITCH, OUTPUT);
}
// initialise external object struct for receiving via LX200
void initExternalObject()
{
externalObject.objectPreFixNameNo = 202; // is "external" in DSO PROGMEM
externalObject.objectNumber = 0; // empty - no number in name
externalObject.objectTypeMagnitude = 0;
externalObject.objectConst = 0; // "all" in constellations
externalObject.objectRA = 0;
externalObject.objectDEC = 0;
}
//###############################################################################################################
// \setup
//###############################################################################################################
//###############################################################################################################
// loop
//###############################################################################################################
void loop()
{
analogWrite(LCD_BACKLIGHT_PIN, myLCDbacklight); // LCD backlight analogWrite: values from 0 to 255
updateRotaryEncoderButton();
updateRotaryEncoders();
calcCurrentPosition();
if (myDisplayMode == 9) displaySensorValue();
if (myDisplayMode == 11) displayCurrPos();
if (myDisplayMode == 12) displayTargetPos();
if (myDisplayMode == 13) displayDiffTargetCurrPos();
// LX200 status
updateLX200Status();
readSendLX200();
}
//###############################################################################################################
// \loop
//###############################################################################################################
//###############################################################################################################
// read sensor values
//###############################################################################################################
// reads rotary encoders
void updateRotaryEncoders()
{
if (val_ROT = read_rotary_ROT()) switchSelection(val_ROT);
if (val_RA = read_rotary_RA())
{
mySensorRAsec = mySensorRAsec + val_RA * secPerStepRA;
myImpulseRA = myImpulseRA + val_RA; // for sensor test
}
if (val_DEC = read_rotary_DEC())
{
mySensorDECsec = mySensorDECsec + val_DEC * secPerStepDEC * myDirectionDEC;
myImpulseDEC = myImpulseDEC + val_DEC * myDirectionDEC; // for sensor test
}
}
// reads rotary encoder button
void updateRotaryEncoderButton()
{
// copy from Arduino - Button - Debounce | Arduino Tutorial
currentState = digitalRead(ROTARY_SW);
if (currentState != lastFlickerableState)
{
lastDebounceTime = millis();
lastFlickerableState = currentState;
}
if ((millis() - lastDebounceTime) > DEBOUNCE_DELAY)
{
if (lastSteadyState == HIGH && currentState == LOW)
{
switchMode();
updateLCD();
lastPressedTime = millis();
}
else if (lastSteadyState == LOW && currentState == HIGH)
{
// if button pressed > 5 seconds -> reset
if (millis() - lastPressedTime > 5000) resetFunc(); // call reset
}
lastSteadyState = currentState;
}
}
// read rotary encoder for HMI
// robust rotary encoder reading Rotary Encoder: Immediately Tame your Noisy Encoder!
// A vald CW or CCW move returns 1,invalid returns 0.
int8_t read_rotary_ROT()
{
prevNextCode_ROT <<= 2;
if (digitalRead(ROTARY_DT)) prevNextCode_ROT |= 0x02;
if (digitalRead(ROTARY_CLK)) prevNextCode_ROT |= 0x01;
prevNextCode_ROT &= 0x0f;
// If valid then store as 16 bit data.
if (enc_table[prevNextCode_ROT] )
{
store_ROT <<= 4;
store_ROT |= prevNextCode_ROT;
if ((store_ROT & 0xff) == 0x2b) return -1;
if ((store_ROT & 0xff) == 0x17) return 1;
}
return 0;
}
// read rotary encoder for RA
int8_t read_rotary_RA()
{
prevNextCode_RA <<= 2;
if (digitalRead(SENS_RA_DT)) prevNextCode_RA |= 0x02;
if (digitalRead(SENS_RA_CLK)) prevNextCode_RA |= 0x01;
prevNextCode_RA &= 0x0f;
// If valid then store as 16 bit data.
if (enc_table[prevNextCode_RA] )
{
store_RA <<= 4;
store_RA |= prevNextCode_RA;
if ((store_RA & 0xff) == 0x2b) return -1;
if ((store_RA & 0xff) == 0x17) return 1;
}
return 0;
}
// read rotary encoder for DEC
int8_t read_rotary_DEC()
{
prevNextCode_DEC <<= 2;
if (digitalRead(SENS_DEC_DT)) prevNextCode_DEC |= 0x02;
if (digitalRead(SENS_DEC_CLK)) prevNextCode_DEC |= 0x01;
prevNextCode_DEC &= 0x0f;
// If valid then store as 16 bit data.
if (enc_table[prevNextCode_DEC] )
{
store_DEC <<= 4;
store_DEC |= prevNextCode_DEC;
if ((store_DEC & 0xff) == 0x2b) return -1;
if ((store_DEC & 0xff) == 0x17) return 1;
}
return 0;
}
//###############################################################################################################
// read sensor values
//###############################################################################################################
//###############################################################################################################
// get & set of object data
//###############################################################################################################
// returns the type as number of a deep sky object
byte getObjectType(byte typeMagnitude)
{
return (typeMagnitude / 14); // decoding of object type from typeMagnitude
}
// returns the type as string of a deep sky object
String getObjectTypeName(byte typeMagnitude)
{
return myObjectTypeName[(typeMagnitude / 14) - 1];
}
// returns the magnitude of a deep sky object
String getMagnitude(byte typeMagnitude) // calcs the right magnitude - here modulo 14 as coded
{
String strFlMag = (String)(typeMagnitude % 14) + "m";
return strFlMag;
}
// returns the name of a constellation as string from a lookup tabel according to its number
String getConstName(int no)
{
constStruct oneConstellation;
// copy constellations data from PROGMEM into oneConstellation according to no
memcpy_P (&oneConstellation, &const_PROGMEM[no], sizeof oneConstellation);
return (String)oneConstellation.constName;
}
// returns the current constellation for filtering
String getCurrentConstName()
{
String constellationName;
constellationName = getConstName(myConstellationNo);
return constellationName;
}
// returns the current cellestial region
String getSetregionName()
{
return myregionNAME[myRegionNo];
}
// set reference star
void setReference()
{
// copy reference data from PROGMEM into myReference according to myRefNo
memcpy_P (&myReference, &DSO_PROGMEM[myRefNo], sizeof myReference);
setReferenceRA_DEC();
}
// RA and DEC of selected target are set
void setReferenceRA_DEC()
{
// transfer RA / DEC into internal format (seconds)
myReferenceRAsec = calcRAsecFromRA(myReference.objectRA);
myReferenceDECsec = calcDECsecFromDEC(myReference.objectDEC);
}
// set target
void setTarget()
{
// copy reference data from PROGMEM into myTarget according to myTargetNo
memcpy_P (&myTarget, &DSO_PROGMEM[myTargetNo], sizeof myTarget);
setTargetRA_DEC();
}
// RA and DEC of selected target are set
void setTargetRA_DEC()
{
// transfer RA / DEC into internal format (seconds)
myTargetRAsec = calcRAsecFromRA(myTarget.objectRA);
myTargetDECsec = calcDECsecFromDEC(myTarget.objectDEC);
}
//###############################################################################################################
// \get & set of object data
//###############################################################################################################
//###############################################################################################################
// calculations and settings of positions
//###############################################################################################################
// calculation of RA seconds
unsigned int calcRAsecFromRA(unsigned int ra)
{
int h = ra / 1000;
int m = (ra - h * 1000) / 10;
int s = (ra - h * 1000 - m * 10) * 6;
unsigned int raSec = h * 3600L + m * 60 + s;
return raSec;
}
// calculation of DEC seconds
long calcDECsecFromDEC(int dec)
{
int deg = dec / 100;
int m = (dec - deg * 100);
long decSec = deg * 3600L + m * 60;
return decSec;
}
// calculation of current telescope position
void calcCurrentPosition()
{
myCurrentRAsec = myReferenceRAsec + myRefStartTimeSec + mySensorRAsec - millis() / 1000;
myCurrentDECsec = myReferenceDECsec + mySensorDECsec;
}
// sets the sensor values to zero - needed for alignment with reference star
void resetSensorTime()
{
mySensorRAsec = 0; // Sensorwert der Rektaszension
mySensorDECsec = 0; // Sensorwert der Deklination
myRefStartTimeSec = millis() / 1000;
}
//###############################################################################################################
// \calculations and settings of positions
//###############################################################################################################
//###############################################################################################################
// display information
//###############################################################################################################
// display the current position
void displayCurrPos()
{
if (myLastRAsec != myCurrentRAsec || myLastDECsec != myCurrentDECsec)
{
myLastRAsec = myCurrentRAsec;
myLastDECsec = myCurrentDECsec;
displayRA_DEC("Curr ", "Coord", myCurrentRAsec, myCurrentDECsec);
}
}
// display position of selected target
void displayTargetPos()
{
displayRA_DEC(getObjectName(myTarget.objectPreFixNameNo, myTarget.objectNumber, myTarget.objectConst), "Coord", myTargetRAsec, myTargetDECsec);
}
// calulation & display of difference between current position & target position
void displayDiffTargetCurrPos()
{
long diffRAsec = myTargetRAsec - myCurrentRAsec;
long diffDECsec = myTargetDECsec - myCurrentDECsec;
if (myLastRAsec != myCurrentRAsec || myLastDECsec != myCurrentDECsec) // only if position has changed
{
myLastRAsec = myCurrentRAsec;
myLastDECsec = myCurrentDECsec;
displayRA_DEC(getObjectName(myTarget.objectPreFixNameNo, myTarget.objectNumber, myTarget.objectConst), "Diff ", diffRAsec , diffDECsec);
}
}
// display of RA and DEC - generic use for reference stars & target
void displayRA_DEC(String text1, String text2, long rekSec, long dekSec)
{
// Rektaszension //
int sign = 1.0;
if (rekSec < 0) sign = -1.0;
byte s = (abs(rekSec)) % 60; // Das Zeichen: "%" ist der Modulo-Operator // vorher int
byte m = (abs(rekSec / 60)) % 60;
byte h = (abs(rekSec / 3600)) % 24;
lcd.setCursor(0, 0);
printObjectName(text1);
lcd.setCursor(8, 0);
if (sign < 0) lcd.print(F("-"));
else lcd.print(F("+"));
if (h < 10) lcd.print(F(" "));
lcd.print(h);
lcd.print(F(":"));
if (m < 10) lcd.print(F("0"));
lcd.print(m);
lcd.print(F(","));
lcd.print(s / 6);
// DEC // +90° - -90°
sign = 1.0;
if (dekSec < 0) sign = -1.0;
s = (abs(dekSec)) % 60; // Das Zeichen: "%" ist der Modulo-Operator
m = (abs(dekSec / 60)) % 60;
h = (abs(dekSec / 3600)) % 180;
lcd.setCursor(0, 1);
lcd.print(text2);
lcd.setCursor(8, 1);
if (sign < 0) lcd.print(F("-"));
else lcd.print(F("+"));
if (h < 10) lcd.print(F(" "));
lcd.print(h);
lcd.print(ch_deg);
if (m < 10) lcd.print(F("0"));
lcd.print(m);
lcd.print(F("'"));
}
// display current sensor values
void displaySensorValue()
{
if (myImpulseRA != myLastImpulseRA || myImpulseDEC != myLastImpulseDEC)
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Imp RA"));
lcd.setCursor(0, 1);
lcd.print(F("Imp DEC"));
lcd.setCursor(10, 0);
lcd.print(myImpulseRA);
lcd.setCursor(10, 1);
lcd.print(myImpulseDEC);
myLastImpulseRA = myImpulseRA;
myLastImpulseDEC = myImpulseDEC;
}
}
// update LCD according to selected display mode
void updateLCD()
{
lcd.clear();
lcd.setCursor(0, 0);
if (myDisplayMode == 0)
{
lcd.print(F("SpotNik v")); // DO NOT REMOVE
lcd.print(VERSION);
lcd.setCursor(0, 1);
lcd.print(F("developed by MR")); // DO NOT REMOVE
}
if (myDisplayMode == 1) // main menu
{
lcd.print(F(">"));
lcd.setCursor(1, 0);
lcd.print(menuTopic[myMenuTopicNo]); // {" reverse", "Ref","Target","region","Const","Bright","Contr","Test"};
lcd.setCursor(8, 0);
switch (myMenuTopicNo) {
case 0:
if (myDirectionDEC == 1) lcd.print(F("normal"));
else lcd.print(F("reverse"));
break;
case 1:
printObjectName(getObjectName(myReference.objectPreFixNameNo, myReference.objectNumber, myReference.objectConst));
break;
case 2:
printObjectName(getObjectName(myTarget.objectPreFixNameNo, myTarget.objectNumber, myTarget.objectConst));
//if (statusLX200 != 2) printObjectName(getObjectName(myTarget.objectPreFixNameNo,myTarget.objectNumber,myTarget.objectConst));
//else lcd.print(F("external")); // if connection to LX200 source - no usage of internal star database
break;
case 3:
lcd.print(getSetregionName());
// if (statusLX200 != 2) lcd.print(getSetregionName());
// else lcd.print(F("external"));
break;
case 4:
lcd.print(getCurrentConstName());
// if (statusLX200 != 2) lcd.print(getCurrentConstName());
// else lcd.print(F("external"));
break;
case 8:
if (statusLX200 == 0) lcd.print(F("BT off"));
if (statusLX200 == 1) lcd.print(F("BT on"));
if (statusLX200 == 2) lcd.print(F("conn"));
break;
}
lcd.setCursor(1, 1);
if (myMenuTopicNo + 1 < menuTopic_size)
{
lcd.print(menuTopic[myMenuTopicNo + 1]);
}
else
{
lcd.print(menuTopic[0]);
}
}
if (myDisplayMode == 2)
{
lcd.print(F("Direction of DEC"));
lcd.setCursor(0, 1);
lcd.print(F(">"));
if (myDirectionDEC == 1) lcd.print(F("normal"));
else lcd.print(F("reverse"));
}
if (myDisplayMode == 3)
{
printObjectName(getObjectName(myReference.objectPreFixNameNo, myReference.objectNumber, myReference.objectConst));
lcd.setCursor(13, 0);
lcd.print(getConstName(myReference.objectConst));
lcd.setCursor(0, 1);
lcd.print(getObjectTypeName(myReference.objectTypeMagnitude));
lcd.setCursor(13, 1);
lcd.print(getMagnitude(myReference.objectTypeMagnitude));
}
if (myDisplayMode == 4)
{
printObjectName(getObjectName(myTarget.objectPreFixNameNo, myTarget.objectNumber, myTarget.objectConst));
lcd.setCursor(13, 0);
lcd.print(getConstName(myTarget.objectConst));
lcd.setCursor(0, 1);
lcd.print(getObjectTypeName(myTarget.objectTypeMagnitude));
lcd.setCursor(13, 1);
lcd.print(getMagnitude(myTarget.objectTypeMagnitude));
}
if (myDisplayMode == 5)
{
lcd.print(F("Celestial Region"));
lcd.setCursor(0, 1);
lcd.print(F(">"));
lcd.print(getSetregionName());
}
if (myDisplayMode == 6)
{
lcd.print(F("Constellation"));
lcd.setCursor(11, 1);
lcd.print(getSetregionName());
lcd.setCursor(0, 1);
lcd.print(F(">"));
lcd.print(getCurrentConstName());
}
if (myDisplayMode == 7)
{
lcd.print(F("LCD Brightness"));
lcd.setCursor(0, 1);
lcd.print(F(">"));
lcd.print(myLCDbacklight);
}
if (myDisplayMode == 8)
{
lcd.print(F("LCD Contrast"));
lcd.setCursor(0, 1);
lcd.print(F(">"));
lcd.print(myLCDcontrast);
}
if (myDisplayMode == 9)
{
lcd.print(F("For test"));
lcd.setCursor(0, 1);
lcd.print(F("turn DEC / RA"));
myImpulseRA = 0;
myImpulseDEC = 0;
myLastImpulseRA = 0;
myLastImpulseDEC = 0;
}
if (myDisplayMode == 10)
{
lcd.print(F("LX200 Connection"));
lcd.setCursor(0, 1);
lcd.print(F(">"));
if (statusLX200 == 0) lcd.print(F("Bluetooth off"));
if (statusLX200 == 1) lcd.print(F("Bluetooth on"));
if (statusLX200 == 2) lcd.print(F("LX200 connected"));
}
}
// returns name of deep sky object based on coded name its number and its constellation
String getObjectName(byte objectprefixNameNo, unsigned int objectNumber, byte objectConst)
{
String objectName = "";
int indexOfHash = -1;
DSONameStruct oneDSONameStruct;
if (objectprefixNameNo > 0)
{
// get name accordng to name number from lookup table
memcpy_P (&oneDSONameStruct, &DSO_NAME_PROGMEM[objectprefixNameNo - 1], sizeof oneDSONameStruct);
objectName = oneDSONameStruct.objectName;
indexOfHash = objectName.indexOf('#');
if (indexOfHash > -1)
{
// replace char with greek char
String charToReplace = objectName.substring(indexOfHash + 1, indexOfHash + 2);
objectName = objectName.substring(0, indexOfHash) + objectName.substring(indexOfHash + 2); // delete # and next char from string
// loop over the greek symbols
for (int i; i < greekSymbols_size; i++)
{
if ((String)charToReplace == (String)greekSymbols[i].originalChar)
{
charToReplace = greekSymbols[i].replaceChar;
objectName = objectName + charToReplace;
break;
}
}
}
}
if (objectNumber > 0)
{
objectName = objectName + (String)objectNumber;
}
// if object is only number,greek Symbol or max. two characters,accept 'M' - add constellation for identification
if (objectName.charAt(1) == NULL || objectprefixNameNo == 0 || (objectName.charAt(2) == NULL && objectNumber == 0)) // oder nur Zahlen!!!
{
objectName = objectName + ' ' + getConstName(objectConst);
}
return objectName;
}
// some greek symbols are custom, print function needed
void printObjectName(String objectName)
{
byte customChar = 0;
char charAt0 = objectName.charAt(0);
if (charAt0 == ch_def_1) customChar = 1;
else if (charAt0 == ch_def_2) customChar = 2;
else if (charAt0 == ch_def_3) customChar = 3;
else if (charAt0 == ch_def_4) customChar = 4;
else if (charAt0 == ch_def_5) customChar = 5;
else if (charAt0 == ch_def_6) customChar = 6;
else if (charAt0 == ch_def_7) customChar = 7;
if (customChar > 0) lcd.write(customChar);
else
{
lcd.print(objectName);
return;
}
lcd.print(F(" "));
lcd.print(objectName.substring(2, 8));
}
//###############################################################################################################
// \display information
//###############################################################################################################
//###############################################################################################################
// switching
//###############################################################################################################
// myDisplayMode - rotary encoder for change
// 0 = welcome, 1 = top menu, 2 = change direction, 3 = set reference, 4 = set target, 5 = set region, 6 = set constellation, 7 = set LCD brightness, 8 = set LCD contrast
// 9 = sensor test, 10 = set bluetooth, 11 = show current position, 12 = show target position, 13 = show difference target - current position
void switchMode()
{
saveSettingsToEeprom(); // save settings to eeprom each time the button is pressed
if (myDisplayMode == 0) // welcome
{
myDisplayMode = 1; // top menue
}
else if (myDisplayMode == 1)
{
myDisplayMode = myMenuTopicNo + 2;
}
else if (myDisplayMode == 3) // set reference
{
resetSensorTime();
myLastDECsec = 0; // set once to zero to update display
myDisplayMode = 11; // show current position
}
else if (myDisplayMode == 4) // set target
{
setTargetRA_DEC();
myDisplayMode = 13; // show diff position
}
// set direction // region // constellation // set brightness // set contrast // sensor test // show current position // show diff position
else if (myDisplayMode == 2 || myDisplayMode >= 5)
{
myDisplayMode = 1; // return to top level menu
}
lcd.clear();
}
// function of rotary encoder changes acording to current display mode
void switchSelection(int dir)
{
if (myDisplayMode == 0)
{
myDisplayMode = 1;
updateLCD();
}
else if (myDisplayMode == 1) changeMenu(dir);
if (myDisplayMode == 2) changeDirectionDEC(dir);
if (myDisplayMode == 3) changeReference(dir);
if (myDisplayMode == 4) changeTarget(dir);
if (myDisplayMode == 5) changeregion(dir);
if (myDisplayMode == 6) changeConstellation(dir);
if (myDisplayMode == 7) changeLCDBacklight(dir);
if (myDisplayMode == 8) changeLCDcontrast(dir);
if (myDisplayMode == 10) changeBTconnection(dir);
if (myDisplayMode == 11 || myDisplayMode == 12 || myDisplayMode == 13) changeView(dir);
updateLCD();
}
// change menu topics
void changeMenu(int dir)
{
if (dir == 1)
{
if ((myMenuTopicNo + 1) < menuTopic_size)
{
myMenuTopicNo = myMenuTopicNo + 1;
}
else
{
myMenuTopicNo = 0;
}
}
else if (dir == -1)
{
if (myMenuTopicNo > 0)
{
myMenuTopicNo = myMenuTopicNo - 1;
}
else
{
myMenuTopicNo = menuTopic_size - 1;
}
}
}
// according to the direction of the DEC axis the value of the DEC sensor has to be reverted
void changeDirectionDEC(int dir)
{
if (dir == 1 || dir == -1)
{
if (myDirectionDEC == 1) myDirectionDEC = -1;
else myDirectionDEC = 1;
}
}
// calls changeObject for object type reference
void changeReference (int dir)
{
changeObject(dir, 'r');
}
// calls changeObject for object type target
void changeTarget(int dir)
{
changeObject(dir, 't');
}
// change referenc star including filter according to selected sky region
void changeObject (int dir, char objectType)
{
bool constFound = false;
DSOstruct oneObject; // instance of reference for search & filter
unsigned int objectNo;
unsigned int numberOfLoops = 0;
if (objectType == 'r')
{
objectNo = myRefNo; // set start no of object
}
else
{
objectNo = myTargetNo;
}
while (constFound == false)
{
if (dir == 1)
{
if ((objectNo + 1) < DSO_PROGMEM_size)
{
objectNo = objectNo + 1;
}
else
{
objectNo = 0;
}
}
if (dir == -1) // before else if - but what if no fitting star at beginning before rotary turning?
{
if (objectNo > 0)
{
objectNo = objectNo - 1;
}
else
{
objectNo = DSO_PROGMEM_size - 1;
}
}
memcpy_P (&oneObject, &DSO_PROGMEM[objectNo], sizeof oneObject); // get next DSO object from struct and copy it into oneObject
// filter on a constellation
// if a constellation is selected,object is a target and constellation of object fits to selected constellation
if (objectType == 't' && myConstellationNo > 0 && getObjectType(oneObject.objectTypeMagnitude) > 0 && getObjectType(oneObject.objectTypeMagnitude) < 12 && oneObject.objectConst == myConstellationNo)
{
constFound = true;
}
// filter on regions
else if ( (objectType == 'r' && getObjectType(oneObject.objectTypeMagnitude) == 12) || // reference stars // filter on objects of type "reference" = no 12
(myConstellationNo == 0 && objectType == 't' && getObjectType(oneObject.objectTypeMagnitude) > 0 && getObjectType(oneObject.objectTypeMagnitude) < 12)) // target objects
{
// filter targets by constellations of the selected region
// myregionNAME[]={"All","North","Spring","Summer","Autumn","Winter","South"};
if (myRegionNo == 1) // region = north
{
for (int i = 0; i < myNorthCONST_size; i++)
{
if (oneObject.objectConst == myNorthCONST[i])
{
constFound = true;
break;
}
}
}
else if (myRegionNo == 2) // region = spring
{
for (int i = 0; i < mySpringCONST_size; i++)
{
if (oneObject.objectConst == mySpringCONST[i])
{
constFound = true;
break;
}
}
}
else if (myRegionNo == 3) // region = summer
{
for (int i = 0; i < mySummerCONST_size; i++)
{
if (oneObject.objectConst == mySummerCONST[i])
{
constFound = true;
break;
}
}
}
else if (myRegionNo == 4) // region = autumn
{
for (int i = 0; i < myAutumnCONST_size; i++)
{
if (oneObject.objectConst == myAutumnCONST[i])
{
constFound = true;
break;
}
}
}
else if (myRegionNo == 5) // region = winter
{
for (int i = 0; i < myWinterCONST_size; i++)
{
if (oneObject.objectConst == myWinterCONST[i])
{
constFound = true;
break;
}
}
}
else if (myRegionNo == 6) // region = south
{
for (int i = 0; i < mySouthCONST_size; i++)
{
if (oneObject.objectConst == mySouthCONST[i])
{
constFound = true;
break;
}
}
}
else // all constellations
{
constFound = true;
}
}
}// end while
if (objectType == 'r')
{
myRefNo = objectNo;
myReference = oneObject; // copy selected reference object in my reference object
setReferenceRA_DEC();
}
else
{
myTargetNo = objectNo;
myTarget = oneObject; // copy selected target object in my target object
setTargetRA_DEC();
}
updateLCD();
}
// change region
void changeregion(int dir)
{
if (dir == 1)
{
if ((myRegionNo + 1) < regionArraySize) {
myRegionNo = myRegionNo + 1;
}
else {
myRegionNo = 0;
}
}
else if (dir == -1)
{
if (myRegionNo > 0) {
myRegionNo = myRegionNo - 1;
}
else {
myRegionNo = regionArraySize - 1;
}
}
myTargetNo = 0; // reset target,when aera has changed
myConstellationNo = 0; // reset constellation,when aera has changed
updateLCD();
}
// set constellation
void changeConstellation(int dir)
{
bool constFound = false;
while (constFound == false)
{
if (dir == 1)
{
if ((myConstellationNo) < constStruct_size - 1) {
myConstellationNo = myConstellationNo + 1;
}
else {
myConstellationNo = 0;
}
}
else if (dir == -1)
{
if (myConstellationNo > 0) {
myConstellationNo = myConstellationNo - 1;
}
else {
myConstellationNo = constStruct_size - 1;
}
}
// filter targets by constellations of the selected region
// myregionNAME[]={"All","North","Spring","Summer","Autumn","Winter","South"};
if (myRegionNo == 1) // region = north
{
for (int i = 0; i < myNorthCONST_size; i++)
{
if (myConstellationNo == myNorthCONST[i])
{
constFound = true;
break;
}
}
}
else if (myRegionNo == 2) // region = spring
{
for (int i = 0; i < mySpringCONST_size; i++)
{
if (myConstellationNo == mySpringCONST[i])
{
constFound = true;
break;
}
}
}
else if (myRegionNo == 3) // region = summer
{
for (int i = 0; i < mySummerCONST_size; i++)
{
if (myConstellationNo == mySummerCONST[i])
{
constFound = true;
break;
}
}
}
else if (myRegionNo == 4) // region = autumn
{
for (int i = 0; i < myAutumnCONST_size; i++)
{
if (myConstellationNo == myAutumnCONST[i])
{
constFound = true;
break;
}
}
}
else if (myRegionNo == 5) // region = winter
{
for (int i = 0; i < myWinterCONST_size; i++)
{
if (myConstellationNo == myWinterCONST[i])
{
constFound = true;
break;
}
}
}
else if (myRegionNo == 6) // region = south
{
for (int i = 0; i < mySouthCONST_size; i++)
{
if (myConstellationNo == mySouthCONST[i])
{
constFound = true;
break;
}
}
}
else // all constellations
{
for (int i = 0; i < myAllCONST_size; i++)
{
if (myConstellationNo == myAllCONST[i])
{
constFound = true;
break;
}
}
}
}
myTargetNo = 0; // reset target every time when constellation was changed
updateLCD();
}
// switch view between current position, diff position & target coordinates
void changeView(int dir)
{
lcd.clear();
myDisplayMode = myDisplayMode + dir;
if (myDisplayMode > 13) myDisplayMode = 11;
if (myDisplayMode < 11) myDisplayMode = 13;
}
// set LCD brightness
void changeLCDBacklight(int dir)
{
myLCDbacklight = myLCDbacklight + dir * 8;
if (myLCDbacklight > 255) myLCDbacklight = 0;
if (myLCDbacklight < 0) myLCDbacklight = 255;
}
// set LCD contrast
void changeLCDcontrast(int dir)
{
myLCDcontrast = myLCDcontrast + dir * 5;
if (myLCDcontrast > 255) myLCDcontrast = 0;
if (myLCDcontrast < 0) myLCDcontrast = 255;
analogWrite(LCD_CONTRAST_PIN, myLCDcontrast);
}
// 0 - BT switched off / 1 - BT switched on
void changeBTconnection(int dir)
{
if (btStatus == 0) // switch BT on if off
{
btStatus = 1;
statusLX200 = 1;
digitalWrite(BT_SWITCH, HIGH);
}
else if (btStatus != 0) // switch BT off
{
btStatus = 0;
statusLX200 = 0;
digitalWrite(BT_SWITCH, LOW);
}
updateLCD();
}
//###############################################################################################################
// \switching
//###############################################################################################################
//###############################################################################################################
// LX200 communication
//###############################################################################################################
// set the status of LX200 to control LCD etc
void updateLX200Status()
{
// 0 - BT switched off / 1 - BT switched on
if (btStatus == 1)
{
// if frequent feedback from LX200 - last request > 4 sek
if ((millis() - lastLX200Message) > 4000)
{
statusLX200 = 1; // BT on - but no LX200 connection
}
else
{
statusLX200 = 2; // LX200 connected
}
}
// LX200 status changend - update lcd in relevant views (main menu & BT)
if (statusLX200 != statusLX200old && (myDisplayMode == 10 || myDisplayMode == 1))
{
updateLCD();
statusLX200old = statusLX200;
}
}
// called if a LX200 message was received
void receivedLX200message() // received
{
lastLX200Message = millis();
}
// read the bluetooth message and trigger functions according to message type
void readSendLX200()
{
if (Serial.available())
{
char message[14] = "";
byte i = 0;
while (Serial.available() > 0)
{
char a = Serial.read(); // Stores current byte
message[i] += a; // Append current byte to message String
delay(10);
i++;
}
// all LX200 info from https://www.meade.com/support/TelescopeProtocol_2010-10.pdf
// LX200 message :GR#
// Get Telescope RA
// Returns: HH:MM.T# or HH:MM:SS#Depending which precision is set for the telescope
if (message[0] == ':' && message[1] == 'G' && message[2] == 'R' && message[3] == '#')
{
receivedLX200message();
sendLX200RA();
}
// LX200 message :GD# or :RS#:GD# or :RM#:GD#
// Get Telescope Declination.
// Returns: sDD*MM# or sDD*MM’SS#Depending upon the current precision setting for the telescope.
if (message[0] == ':' && message[1] == 'G' && message[2] == 'D' && message[3] == '#' ||
message[4] == ':' && message[5] == 'G' && message[6] == 'D' && message[7] == '#')
{
receivedLX200message();
sendLX200DEC();
}
// LX200 message :CM#
// Synchronizes the telescope's position with the currently selected database object's coordinates.
// Returns:LX200's - a "#" terminated string with the name of the object that was synced
if (message[0] == ':' && message[1] == 'C' && message[2] == 'M')
{
receivedLX200message();
Serial.print("#");
}
// LX200 message :SrHH:MM.T# or :SrHH:MM:SS#
// Set target object RA to HH:MM.T or HH:MM:SS depending on the current precision setting.
// Returns:0 – Invalid1 - Valid
// output HHMM(S/6)
if (message[0] == ':' && message[1] == 'S' && message[2] == 'r')
{
setRAtoLX200message(message);
}
// LX200 message :SdsDD*MM#
// Set target object declination to sDD*MM or sDD*MM:SS depending on the current precision setting
// Returns:1 - Dec Accepted0 – Dec invalid
// output sHHMM
if (message[0] == ':' && message[1] == 'S' && message[2] == 'd')
{
setDECtoLX200message(message);
}
// Serial.print("BT message "); // for debugging
// Serial.println(message);
}
}
// set RA coordinates of placeholder externalobject to received LX200 message
void setRAtoLX200message(char message[10])
{
externalObject.objectRA =
long(atoi(message + 3)) * 1000 + // HH // access at array different when using atoi - use address
long(atoi(message + 6)) * 10; // MM - Minuten passen noch nicht bei zweistelligen gibt es Fehler
if (message[8] == ':') // : or .
{
externalObject.objectRA = externalObject.objectRA +
long(atoi(message + 9)) / 6; // SS/6
}
else if (message[8] == '.')
{
externalObject.objectRA = externalObject.objectRA + atoi(message + 9); // T
}
Serial.println(); // leave this command, as otherwise no update on goto from LX200 source
}
// set DEC coordinates of placeholder externalobject to received LX200 message & update the (reference or target) object
void setDECtoLX200message(char message[9])
{
int sign;
if (message[3] == '-') sign = -1;
else sign = 1;
externalObject.objectDEC =
sign * ( // s
long(atoi(message + 4)) * 100 + // DD
long(atoi(message + 7))); // MM
// assumption - first RA then DEC - then set target to external object
if (myDisplayMode == 3 || myDisplayMode == 11) // if view shows reference selection or current position then copy external object into reference object
{
externalObject.objectTypeMagnitude = 168;
myReference = externalObject; // copy external object to my reference object
setReferenceRA_DEC();
resetSensorTime();
}
else // in all other cases copy to target
{
externalObject.objectTypeMagnitude = 182;
myTarget = externalObject; // copy external object to my target object
setTargetRA_DEC();
}
updateLCD();
}
// send current RA coordinate of telescope from SpotNik to LX200 server (e.g. Sky Safari)
void sendLX200RA()
{
byte s = (abs(myCurrentRAsec)) % 60; // Das Zeichen: "%" ist der Modulo-Operator
byte m = (abs(myCurrentRAsec / 60)) % 60;
byte h = (abs(myCurrentRAsec / 3600)) % 24;
String posString = "";
if (h < 10) posString = "0";
posString = posString + String(h);
posString = posString + ":";
if (m < 10) posString = posString + "0";
posString = posString + String(m);
posString = posString + ":";
if (s < 10) posString = posString + "0";
posString = posString + String(s);
posString = posString + "#";
Serial.print(posString);
}
// send current DEC coordinate of telescope from SpotNik to LX200 server (e.g. Sky Safari)
void sendLX200DEC()
{
byte s = (abs(myCurrentDECsec)) % 60; // Das Zeichen: "%" ist der Modulo-Operator
byte m = (abs(myCurrentDECsec / 60)) % 60;
byte h = (abs(myCurrentDECsec / 3600)) % 180;
String posString = "";
if (myCurrentDECsec > 0) posString = "+";
else posString = "-";
if (h < 10) posString = "0";
posString = posString + String(h);
posString = posString + "*";
if (m < 10) posString = posString + "0";
posString = posString + String(m);
posString = posString + "#";
Serial.print(posString);
}
//###############################################################################################################
// \LX200 communication
//###############################################################################################################
//###############################################################################################################
// EEPROM
//###############################################################################################################
// save relevant data for next startup (e.g. target no,LCD brightness)
void saveSettingsToEeprom()
{
// Serial.print(F("freeMemory()=")); //only used for testing
// Serial.println(freeMemory());
byte addr = EEPROM_VALUE_ADDR_SIGNATURE;
byte myTargetNoLowByte = lowByte(myTargetNo); // myTargetNo is of type int - transfer into two bytes
byte myTargetNoHighByte = highByte(myTargetNo);
byte myReferenceNoLowByte = lowByte(myRefNo); // myTargetNo is of type int - transfer into two bytes
byte myReferenceNoHighByte = highByte(myRefNo);
EEPROM.update(addr, EEPROM_SIGNATURE); // use update for longer eeprom life
addr += sizeof(EEPROM_SIGNATURE);
EEPROM.update(addr, myReferenceNoLowByte);
addr += sizeof(myReferenceNoLowByte);
EEPROM.update(addr, myReferenceNoHighByte);
addr += sizeof(myReferenceNoHighByte);
EEPROM.update(addr, myTargetNoLowByte);
addr += sizeof(myTargetNoLowByte);
EEPROM.update(addr, myTargetNoHighByte);
addr += sizeof(myTargetNoHighByte);
EEPROM.update(addr, myRegionNo);
addr += sizeof(myRegionNo);
EEPROM.update(addr, myConstellationNo);
addr += sizeof(myConstellationNo);
EEPROM.update(addr, myLCDbacklight);
addr += sizeof(myLCDbacklight);
EEPROM.update(addr, myLCDcontrast);
}
// load relevant data at startup (e.g. target no, LCD brightness)
void getSettingsFromEeprom()
{
byte addr = EEPROM_VALUE_ADDR_SIGNATURE, signature = 0, value, myReferenceNoLowByte, myReferenceNoHighByte, myTargetNoLowByte, myTargetNoHighByte; // myTargetNo is of type int,need to concatenated from two bytes
EEPROM.get(addr, signature);
if (signature != EEPROM_SIGNATURE) return; // maybe data from another sketch
addr += sizeof(EEPROM_SIGNATURE);
EEPROM.get(addr, value);
myReferenceNoLowByte = value;
addr += sizeof(myReferenceNoLowByte);
EEPROM.get(addr, value);
myReferenceNoHighByte = value;
if (value >= 0 && value <= 32767) myRefNo = word(myReferenceNoHighByte, myReferenceNoLowByte);
addr += sizeof(myReferenceNoHighByte);
EEPROM.get(addr, value);
myTargetNoLowByte = value;
addr += sizeof(myTargetNoLowByte);
EEPROM.get(addr, value);
myTargetNoHighByte = value;
if (value >= 0 && value <= 32767) myTargetNo = word(myTargetNoHighByte, myTargetNoLowByte);
addr += sizeof(myTargetNoHighByte);
EEPROM.get(addr, value);
if (value >= 0 && value <= 255) myRegionNo = value;
addr += sizeof(myRegionNo);
EEPROM.get(addr, value);
if (value >= 0 && value <= 255) myConstellationNo = value;
addr += sizeof(myConstellationNo);
EEPROM.get(addr, value);
if (value >= 0 && value <= 255) myLCDbacklight = value;
addr += sizeof(myLCDbacklight);
EEPROM.get(addr, value);
if (value >= 0 && value <= 255) myLCDcontrast = value;
}
//###############################################################################################################
// \EEPROM
//###############################################################################################################
}
void loop() {
// put your main code here, to run repeatedly:
}Use code tags to format code for the forum
[
/code]
here's the error code bar.........Arduino: 1.8.20 Hourly Build 2021/12/20 07:33 (Windows 10), Board: "Arduino Mega or Mega 2560, ATmega2560 (Mega 2560)"
In file included from C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\sketch_jul09b\sketch_jul09b.ino:30:0:
\\admin-che\c$\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\EEPROM\src/EEPROM.h: In function 'void setup()':
\\admin-che\c$\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\EEPROM\src/EEPROM.h:130:5: error: invalid declaration of member template in local class
template< typename T > T &get( int idx, T &t ){
^~~~~~~~
\\admin-che\c$\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\EEPROM\src/EEPROM.h:137:5: error: invalid declaration of member template in local class
template< typename T > const T &put( int idx, const T &t ){
^~~~~~~~
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\sketch_jul09b\sketch_jul09b.ino:1496:3: warning: narrowing conversion of '129989' from 'long int' to 'unsigned int' inside { } [-Wnarrowing]
};
^
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\sketch_jul09b\sketch_jul09b.ino:1496:3: warning: large integer implicitly truncated to unsigned type [-Woverflow]
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\sketch_jul09b\sketch_jul09b.ino:1496:3: warning: narrowing conversion of '189256' from 'long int' to 'unsigned int' inside { } [-Wnarrowing]
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\sketch_jul09b\sketch_jul09b.ino:1496:3: warning: large integer implicitly truncated to unsigned type [-Woverflow]
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\sketch_jul09b\sketch_jul09b.ino:1496:3: warning: narrowing conversion of '106516' from 'long int' to 'unsigned int' inside { } [-Wnarrowing]
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\sketch_jul09b\sketch_jul09b.ino:1496:3: warning: large integer implicitly truncated to unsigned type [-Woverflow]
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\sketch_jul09b\sketch_jul09b.ino:1496:3: warning: narrowing conversion of '109003' from 'long int' to 'unsigned int' inside { } [-Wnarrowing]
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\sketch_jul09b\sketch_jul09b.ino:1496:3: warning: large integer implicitly truncated to unsigned type [-Woverflow]
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\sketch_jul09b\sketch_jul09b.ino:1496:3: warning: narrowing conversion of '128396' from 'long int' to 'unsigned int' inside { } [-Wnarrowing]
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\sketch_jul09b\sketch_jul09b.ino:1496:3: warning: large integer implicitly truncated to unsigned type [-Woverflow]
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\sketch_jul09b\sketch_jul09b.ino:1496:3: warning: narrowing conversion of '113801' from 'long int' to 'unsigned int' inside { } [-Wnarrowing]
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\sketch_jul09b\sketch_jul09b.ino:1496:3: warning: large integer implicitly truncated to unsigned type [-Woverflow]
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\sketch_jul09b\sketch_jul09b.ino:1496:3: warning: narrowing conversion of '157721' from 'long int' to 'unsigned int' inside { } [-Wnarrowing]
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\sketch_jul09b\sketch_jul09b.ino:1496:3: warning: large integer implicitly truncated to unsigned type [-Woverflow]
sketch_jul09b:1781:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:1800:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:1809:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:1821:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:1844:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:1860:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:1885:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:1903:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:1934:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:1953:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:1972:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:1998:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:2004:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:2010:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:2017:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:2026:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:2034:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:2040:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:2048:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:2056:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:2064:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:2079:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:2089:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:2098:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:2105:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:2120:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:2131:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:2137:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:2151:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:2194:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:2213:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:2357:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:2405:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:2437:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:2469:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:2491:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:2518:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:2528:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:2534:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:2540:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:2684:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:2710:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:2819:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:2828:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:2836:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:2845:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:2870:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:2895:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:2901:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:2967:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:2986:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:3015:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:3035:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:3061:3: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09b:3092:3: error: a function-definition is not allowed here before '{' token
{
^
In file included from C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\sketch_jul09b\sketch_jul09b.ino:29:0:
\\admin-che\c$\Program Files (x86)\Arduino\libraries\LiquidCrystal\src/LiquidCrystal.h: At global scope:
\\admin-che\c$\Program Files (x86)\Arduino\libraries\LiquidCrystal\src/LiquidCrystal.h:55:3: warning: 'setup()::LiquidCrystal::LiquidCrystal(uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t)' used but never defined
LiquidCrystal(uint8_t rs, uint8_t enable,
^~~~~~~~~~~~~
exit status 1
a function-definition is not allowed here before '{' token
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
type or paste code here
`type or paste code here`
```Use code tags to format code for the forum
Hi Uk Helibob, I hope this is sufficient for you to have a look at? Thanks.Use code tags to format code for the forum
Looks like this got added to the sketch at the very beginning, almost like you pasted the sketch into the middle of an empty sketch.
< edit >
There is also this that has been added to the end of the sketch:
This is what it should look like:
/* ///////////////////////////////////////////////////////////////////////////////////
SpotNik - by Max Reinecke
Created: May 2021
SpotNik is software for a stepto system for telescopes
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
/////////////////////////////////////////////////////////////////////////////////*/
#define VERSION 2.0
//###############################################################################################################
// to be changed by user according to EQ mount - see instructions
// total numbers of impulse of the rotary encoder of RA axis when turned 24h
#define IMPULSE24HRA 2772 // 6h - 690 Impulse --> 24h - 4 * 693 = 2772 / ~ 1:138
// total numbers of impulse of the rotary encoder of DEC axis when turned 360° // +/- for correct direction
#define IMPULSE360DEGDEC 1784 // 90° - 446 Impulse --> 360° - 4 * 446 = 1784 / ~ 1:88
//###############################################################################################################
#include <LiquidCrystal.h> // I2C LCD arbeitet nicht vernünftig mit Rotary Encoder zusammen,daher normales nehmen
#include <EEPROM.h>
//#include <MemoryFree.h> // only used for testing
//###############################################################################################################
// LCD
#define LCD_CONTRAST_PIN 11 // LCD contrast - V0 // use high frequency PWM to avoid flickering (Leonardo,Micro,Yún 3 and 11: 980 Hz // Mega pins 4 and 13: 980 Hz)
#define LCD_BACKLIGHT_PIN 10 // LCD backlight - LCD A
// EEPROM
#define EEPROM_SIGNATURE 117 // value 0-255 (byte) - signature/mark to recognize if the value fits to this sketch
#define EEPROM_VALUE_ADDR_SIGNATURE 0
// rotary enoder HMI
#define ROTARY_SW 3 // use interrupt pin - digital pins for interrupts on Micro,Leonardo and other 32u4 based 0,1,2,3,7
#define ROTARY_DT 4
#define ROTARY_CLK 5
// Sensor RA
#define SENS_RA_DT A0 // analog pins used as UNO has not that many digital pins
#define SENS_RA_CLK A1
// Sensor DEC
#define SENS_DEC_DT A2
#define SENS_DEC_CLK A3
// LX200 connection
#define BT_SWITCH 2
//###############################################################################################################
// lookup table with names of deep sky objects
//###############################################################################################################
struct DSONameStruct
{
char objectName[9];
};
const struct DSONameStruct DSO_NAME_PROGMEM[202] PROGMEM =
{
{"3C273"},
{"B"},
{"IC"},
{"M"},
{"NGC"},
{"#a"},
{"#aA"},
{"#aB"},
{"#b"},
{"#c"},
{"#d"},
{"#e"},
{"#e1"},
{"#e2"},
{"#g"},
{"#h"},
{"#i"},
{"#j"},
{"#k"},
{"#l"},
{"#m"},
{"#n"},
{"#o"},
{"#p"},
{"#q"},
{"#r"},
{"#s"},
{"#t"},
{"#u"},
{"#w"},
{"#x"},
{"#z"},
{"AC"},
{"Achernar"},
{"Acrab"},
{"Acrux"},
{"Adhara"},
{"Agena"},
{"Alamak"},
{"Aldebara"},
{"Alderami"},
{"AlDhanab"},
{"Algenib"},
{"Algieba"},
{"Algol"},
{"Alhena"},
{"Alioth"},
{"Alkaid"},
{"AlNair"},
{"Alnilam"},
{"Alnitak"},
{"Alphard"},
{"Alphecca"},
{"Alpherat"},
{"Alsuhail"},
{"Altair"},
{"Aludra"},
{"Ankaa"},
{"Antares"},
{"AQ"},
{"Arcturus"},
{"Arneb"},
{"Aspidisk"},
{"Atria"},
{"Avior"},
{"AW"},
{"AX"},
{"BD"},
{"Becrux"},
{"Bellatri"},
{"Betelgeu"},
{"BF"},
{"BG"},
{"BL"},
{"BM"},
{"BX"},
{"Canopus"},
{"Capella"},
{"Caph"},
{"Castor"},
{"Cih"},
{"CY"},
{"Deneb"},
{"DenebKai"},
{"Denebola"},
{"Diphda"},
{"DR"},
{"Dschubba"},
{"Dubhe"},
{"EL"},
{"ElNath"},
{"Eltanin"},
{"Enif"},
{"FO"},
{"Fomalhau"},
{"FU"},
{"Gacrux"},
{"Gemma"},
{"Gienah"},
{"Girtab"},
{"GK"},
{"GY"},
{"H"},
{"Hadar"},
{"Hamal"},
{"Han"},
{"HD"},
{"HJ"},
{"HK"},
{"HN"},
{"Izar"},
{"JC"},
{"KausAust"},
{"Kochab"},
{"KooShe"},
{"Markab"},
{"Menkalin"},
{"Menkar"},
{"Menkent"},
{"Merak"},
{"Miaplaci"},
{"Mimosa"},
{"Mintaka"},
{"Mirach"},
{"Mirfak"},
{"Mirzam"},
{"Mizar"},
{"Naos"},
{"NQ"},
{"NSV"},
{"Nunki"},
{"O#F"},
{"Peacock"},
{"Phecda"},
{"Polaris"},
{"Pollux"},
{"Procyon"},
{"PZ6"},
{"R"},
{"RasAlhag"},
{"Regulus"},
{"Rigel"},
{"RigilKen"},
{"RR"},
{"RS"},
{"RT"},
{"RU"},
{"RV"},
{"RX"},
{"RY"},
{"RZ"},
{"S"},
{"S605"},
{"Sabik"},
{"Sadr"},
{"Saiph"},
{"SAO"},
{"Sargas"},
{"Scheat"},
{"Schedar"},
{"Shaula"},
{"SHJ"},
{"Sirius"},
{"Spica"},
{"SS"},
{"ST"},
{"SU"},
{"SV"},
{"SY"},
{"SZ"},
{"T"},
{"TT"},
{"TU"},
{"Tureis"},
{"TW"},
{"TX"},
{"U"},
{"UU"},
{"UV"},
{"UX"},
{"UY"},
{"V"},
{"Vega"},
{"VW"},
{"VX"},
{"VY"},
{"W"},
{"Wei"},
{"Wezen"},
{"WO"},
{"WW"},
{"WX"},
{"WZ"},
{"X"},
{"XS"},
{"XX"},
{"Y"},
{"Z"},
{"Zozma"},
{"β648"},
{"#F"},
{"extern"}
};
//###############################################################################################################
//###############################################################################################################
// data of deep sky objects
//###############################################################################################################
struct DSOstruct
{
byte objectPreFixNameNo; // number of name for lookup table
unsigned int objectNumber; // if name contains a number
byte objectTypeMagnitude; // object type & magnitude coded in one byte
byte objectConst; // constellation of object
unsigned int objectRA; //HHMM(SS/6)
int objectDEC; //sHHMM
};
DSOstruct myTarget; // object to store data of selected target
DSOstruct myReference; // object to store data of selected target
const unsigned int DSO_PROGMEM_size = 1204;
const struct DSOstruct DSO_PROGMEM[DSO_PROGMEM_size] PROGMEM =
{
{1, 0, 27, 86, 12291, 203},
{2, 33, 42, 60, 5409, -228},
{2, 65, 42, 77, 18027, -2750},
{2, 86, 42, 59, 17196, -2642},
{3, 342, 54, 11, 3468, 6806},
{3, 405, 66, 8, 5165, 3421},
{3, 410, 64, 8, 5227, 3325},
{3, 434, 67, 60, 5410, -227},
{3, 1396, 74, 16, 21391, 5730},
{3, 4406, 95, 50, 14224, -4409},
{3, 5067, 64, 31, 20508, 4421},
{3, 5146, 80, 31, 21534, 4716},
{4, 1, 106, 78, 5345, 2201},
{4, 2, 119, 5, 21335, -49},
{4, 3, 118, 30, 13422, 2823},
{4, 4, 117, 72, 16236, -2632},
{4, 5, 118, 74, 15186, 205},
{4, 6, 130, 72, 17403, -3215},
{4, 7, 129, 72, 17539, -3448},
{4, 8, 75, 77, 18037, -2423},
{4, 9, 120, 59, 17192, -1831},
{4, 10, 119, 59, 16571, -406},
{4, 11, 132, 73, 18511, -616},
{4, 12, 118, 59, 16472, -157},
{4, 13, 118, 40, 16417, 3628},
{4, 14, 120, 59, 17376, -315},
{4, 15, 118, 62, 21300, 1210},
{4, 16, 76, 74, 18188, -1347},
{4, 17, 76, 77, 18208, -1611},
{4, 18, 133, 77, 18199, -1708},
{4, 19, 119, 59, 17026, -2616},
{4, 20, 76, 77, 18027, -2258},
{4, 21, 132, 77, 18042, -2229},
{4, 22, 117, 77, 18364, -2354},
{4, 23, 132, 77, 17571, -1859},
{4, 24, 129, 77, 18266, -1823},
{4, 25, 131, 77, 18318, -1907},
{4, 26, 134, 73, 18452, -924},
{4, 27, 91, 88, 19596, 2243},
{4, 28, 119, 77, 18245, -2452},
{4, 29, 133, 31, 20239, 3832},
{4, 30, 119, 12, 21404, -2311},
{4, 31, 45, 1, 427, 4116},
{4, 32, 50, 1, 427, 4052},
{4, 33, 48, 81, 1339, 3039},
{4, 34, 131, 63, 2421, 4247},
{4, 35, 131, 38, 6089, 2421},
{4, 36, 132, 8, 5363, 3408},
{4, 37, 132, 8, 5523, 3233},
{4, 38, 132, 8, 5287, 3551},
{4, 39, 131, 31, 21322, 4826},
{4, 40, 149, 83, 12219, 5806},
{4, 41, 131, 20, 6460, -2045},
{4, 42, 74, 60, 5353, -523},
{4, 43, 63, 60, 5355, -516},
{4, 44, 129, 22, 8400, 1940},
{4, 45, 71, 78, 3470, 2407},
{4, 46, 132, 68, 7418, -1449},
{4, 47, 130, 68, 7366, -1429},
{4, 48, 132, 42, 8137, -545},
{4, 49, 50, 86, 12298, 800},
{4, 50, 132, 55, 7025, -823},
{4, 51, 50, 30, 13299, 4712},
{4, 52, 133, 14, 23242, 6135},
{4, 53, 120, 24, 13129, 1810},
{4, 54, 120, 77, 18551, -3029},
{4, 55, 118, 77, 19400, -3058},
{4, 56, 120, 52, 19166, 3011},
{4, 57, 93, 52, 18536, 3302},
{4, 58, 52, 86, 12377, 1149},
{4, 59, 52, 86, 12420, 1139},
{4, 60, 51, 86, 12437, 1133},
{4, 61, 52, 86, 12219, 428},
{4, 62, 118, 59, 17012, -3007},
{4, 63, 51, 30, 13158, 4202},
{4, 64, 51, 24, 12567, 2141},
{4, 65, 51, 46, 11189, 1305},
{4, 66, 51, 46, 11202, 1300},
{4, 67, 133, 22, 8508, 1149},
{4, 68, 119, 42, 12395, -2645},
{4, 69, 120, 77, 18314, -3221},
{4, 70, 120, 77, 18432, -3218},
{4, 71, 120, 76, 19538, 1847},
{4, 72, 121, 5, 20535, -1232},
{4, 73, 136, 5, 20590, -1238},
{4, 74, 51, 67, 1367, 1547},
{4, 75, 121, 77, 20061, -2155},
{4, 76, 94, 63, 1423, 5135},
{4, 77, 51, 17, 2427, -1},
{4, 78, 64, 60, 5468, 5},
{4, 79, 120, 47, 5242, -2431},
{4, 80, 119, 72, 16170, -2259},
{4, 81, 49, 83, 9556, 6904},
{4, 82, 50, 83, 9559, 6941},
{4, 83, 50, 42, 13370, -2952},
{4, 84, 51, 86, 12251, 1253},
{4, 85, 51, 24, 12254, 1811},
{4, 86, 51, 86, 12262, 1257},
{4, 87, 51, 86, 12308, 1223},
{4, 88, 52, 24, 12320, 1425},
{4, 89, 52, 86, 12357, 1233},
{4, 90, 52, 86, 12368, 1310},
{4, 91, 52, 24, 12354, 1430},
{4, 92, 119, 40, 17171, 4308},
{4, 93, 132, 68, 7445, -2351},
{4, 94, 50, 30, 12509, 4107},
{4, 95, 52, 46, 10440, 1142},
{4, 96, 51, 46, 10468, 1149},
{4, 97, 95, 83, 11148, 5501},
{4, 98, 52, 24, 12138, 1454},
{4, 99, 52, 24, 12188, 1425},
{4, 100, 51, 24, 12229, 1549},
{4, 101, 50, 83, 14032, 5421},
{4, 102, 52, 34, 15065, 5546},
{4, 103, 133, 14, 1334, 6039},
{4, 104, 50, 86, 12400, -1137},
{4, 105, 51, 46, 10478, 1235},
{4, 106, 50, 30, 12190, 4718},
{4, 107, 120, 59, 16325, -1303},
{4, 108, 52, 83, 11115, 5540},
{4, 109, 52, 83, 11576, 5322},
{4, 110, 50, 1, 404, 4141},
{5, 40, 94, 16, 130, 7231},
{5, 55, 50, 71, 149, -3911},
{5, 129, 133, 14, 300, 6013},
{5, 136, 137, 14, 315, 6131},
{5, 147, 52, 14, 332, 4830},
{5, 157, 52, 17, 348, -824},
{5, 185, 51, 14, 390, 4820},
{5, 188, 134, 16, 475, 8514},
{5, 210, 52, 17, 406, -1352},
{5, 225, 133, 14, 436, 6146},
{5, 246, 94, 17, 471, -1152},
{5, 247, 51, 17, 471, -2046},
{5, 253, 49, 71, 476, -2518},
{5, 278, 52, 14, 521, 4733},
{5, 281, 77, 14, 530, 5637},
{5, 288, 120, 71, 528, -2635},
{5, 300, 50, 71, 549, -3741},
{5, 381, 135, 14, 1084, 6135},
{5, 404, 52, 1, 1094, 3543},
{5, 436, 135, 14, 1160, 5849},
{5, 457, 132, 14, 1195, 5817},
{5, 488, 52, 67, 1218, 515},
{5, 524, 52, 67, 1248, 932},
{5, 559, 136, 14, 1295, 6319},
{5, 584, 52, 17, 1313, -652},
{5, 596, 52, 17, 1329, -702},
{5, 613, 52, 71, 1343, -2925},
{5, 615, 53, 17, 1351, -720},
{5, 637, 134, 14, 1431, 6402},
{5, 654, 133, 14, 1440, 6153},
{5, 659, 134, 14, 1444, 6040},
{5, 663, 133, 14, 1460, 6115},
{5, 672, 52, 81, 1479, 2726},
{5, 720, 52, 17, 1530, -1344},
{5, 752, 132, 1, 1577, 3740},
{5, 772, 52, 7, 1593, 1900},
{5, 779, 53, 17, 1597, -558},
{5, 869, 131, 63, 2191, 5708},
{5, 884, 132, 63, 2225, 5709},
{5, 891, 52, 1, 2226, 4221},
{5, 908, 52, 17, 2231, -2114},
{5, 925, 52, 81, 2273, 3335},
{5, 936, 52, 17, 2276, -109},
{5, 986, 52, 37, 2336, -3903},
{5, 1022, 53, 17, 2385, -641},
{5, 1023, 51, 63, 2404, 3904},
{5, 1027, 133, 14, 2426, 6136},
{5, 1052, 52, 17, 2411, -815},
{5, 1055, 52, 17, 2418, 27},
{5, 1084, 52, 36, 2460, -735},
{5, 1097, 52, 37, 2463, -3017},
{5, 1232, 52, 36, 3098, -2035},
{5, 1245, 134, 63, 3147, 4714},
{5, 1261, 120, 41, 3123, -5513},
{5, 1275, 53, 63, 3198, 4131},
{5, 1291, 51, 36, 3173, -4106},
{5, 1300, 52, 36, 3197, -1925},
{5, 1316, 51, 37, 3227, -3713},
{5, 1325, 53, 36, 3244, -2133},
{5, 1332, 52, 36, 3263, -2120},
{5, 1342, 133, 63, 3317, 3722},
{5, 1360, 93, 37, 3332, -2552},
{5, 1365, 52, 37, 3336, -3608},
{5, 1374, 53, 37, 3353, -3514},
{5, 1380, 54, 37, 3368, -3444},
{5, 1398, 52, 37, 3389, -2620},
{5, 1399, 52, 37, 3385, -3527},
{5, 1407, 52, 36, 3402, -1835},
{5, 1433, 52, 41, 3420, -4713},
{5, 1444, 133, 63, 3494, 5240},
{5, 1491, 70, 63, 4032, 5119},
{5, 1499, 61, 63, 4032, 3622},
{5, 1501, 96, 11, 4070, 6055},
{5, 1502, 133, 11, 4078, 6220},
{5, 1513, 134, 63, 4099, 4931},
{5, 1514, 94, 78, 4093, 3047},
{5, 1528, 132, 63, 4153, 5113},
{5, 1532, 52, 36, 4121, -3252},
{5, 1535, 93, 36, 4143, -1244},
{5, 1545, 132, 63, 4209, 5015},
{5, 1549, 52, 33, 4158, -5536},
{5, 1566, 52, 33, 4200, -5456},
{5, 1647, 132, 78, 4459, 1906},
{5, 1664, 134, 8, 4511, 4341},
{5, 1672, 52, 33, 4457, -5915},
{5, 1788, 70, 60, 5069, -320},
{5, 1792, 52, 23, 5052, -3759},
{5, 1808, 52, 23, 5077, -3731},
{5, 1817, 134, 78, 5124, 1641},
{5, 1851, 119, 23, 5141, -4003},
{5, 1857, 133, 8, 5201, 3921},
{5, 1907, 134, 8, 5281, 3520},
{5, 1909, 70, 36, 5045, -716},
{5, 1931, 80, 8, 5314, 3415},
{5, 1961, 53, 11, 5421, 6923},
{5, 1964, 52, 47, 5334, -2157},
{5, 1973, 63, 60, 5351, -444},
{5, 1980, 73, 60, 5354, -555},
{5, 1999, 70, 60, 5364, -643},
{5, 2022, 95, 60, 5421, 905},
{5, 2024, 70, 60, 5417, -151},
{5, 2126, 136, 8, 6025, 4952},
{5, 2129, 133, 38, 6007, 2319},
{5, 2158, 135, 38, 6074, 2406},
{5, 2169, 132, 60, 6084, 1358},
{5, 2175, 77, 60, 6096, 2029},
{5, 2185, 70, 55, 6110, -614},
{5, 2186, 135, 60, 6121, 528},
{5, 2194, 135, 60, 6138, 1248},
{5, 2204, 135, 20, 6155, -1840},
{5, 2207, 52, 20, 6164, -2122},
{5, 2215, 134, 55, 6208, -717},
{5, 2232, 130, 55, 6280, -451},
{5, 2237, 76, 55, 6309, 503},
{5, 2238, 62, 55, 6307, 501},
{5, 2239, 131, 55, 6319, 457},
{5, 2245, 70, 55, 6327, 1009},
{5, 2251, 133, 55, 6346, 822},
{5, 2261, 70, 55, 6392, 845},
{5, 2264, 74, 55, 6410, 954},
{5, 2266, 136, 38, 6433, 2658},
{5, 2281, 131, 8, 6483, 4105},
{5, 2286, 134, 55, 6477, -309},
{5, 2300, 53, 16, 7323, 8543},
{5, 2301, 132, 55, 6518, 28},
{5, 2304, 136, 38, 6552, 1759},
{5, 2311, 136, 55, 6578, -437},
{5, 2324, 134, 55, 7041, 103},
{5, 2335, 133, 55, 7068, -1002},
{5, 2343, 133, 55, 7081, -1037},
{5, 2346, 96, 55, 7094, -48},
{5, 2353, 133, 55, 7145, -1016},
{5, 2354, 133, 20, 7143, -2542},
{5, 2355, 136, 38, 7170, 1345},
{5, 2359, 70, 20, 7185, -1314},
{5, 2360, 133, 20, 7177, -1538},
{5, 2362, 130, 20, 7187, -2457},
{5, 2371, 95, 38, 7256, 2929},
{5, 2372, 95, 38, 7256, 2930},
{5, 2383, 134, 20, 7247, -2057},
{5, 2384, 133, 20, 7252, -2101},
{5, 2392, 93, 38, 7292, 2055},
{5, 2395, 134, 38, 7272, 1337},
{5, 2403, 51, 11, 7368, 6536},
{5, 2419, 122, 51, 7381, 3853},
{5, 2420, 134, 38, 7384, 2134},
{5, 2421, 134, 68, 7362, -2037},
{5, 2423, 133, 68, 7371, -1352},
{5, 2438, 95, 68, 7418, -1444},
{5, 2439, 133, 68, 7408, -3142},
{5, 2440, 95, 68, 7419, -1813},
{5, 2467, 77, 68, 7525, -2626},
{5, 2477, 132, 68, 7522, -3832},
{5, 2479, 136, 68, 7551, -1742},
{5, 2482, 133, 68, 7552, -2415},
{5, 2489, 134, 68, 7563, -3004},
{5, 2506, 134, 55, 8000, -1046},
{5, 2509, 135, 68, 8008, -1903},
{5, 2527, 133, 68, 8050, -2809},
{5, 2539, 133, 68, 8106, -1249},
{5, 2547, 131, 85, 8102, -4912},
{5, 2567, 133, 68, 8185, -3039},
{5, 2571, 133, 68, 8189, -2945},
{5, 2613, 52, 69, 8334, -2258},
{5, 2627, 134, 69, 8372, -2957},
{5, 2655, 52, 11, 8556, 7813},
{5, 2681, 52, 83, 8535, 5119},
{5, 2683, 52, 51, 8527, 3325},
{5, 2742, 53, 83, 9076, 6029},
{5, 2768, 52, 83, 9116, 6002},
{5, 2775, 52, 22, 9103, 702},
{5, 2782, 53, 51, 9141, 4007},
{5, 2784, 52, 42, 9123, -2410},
{5, 2787, 52, 83, 9193, 6912},
{5, 2811, 53, 42, 9162, -1619},
{5, 2835, 52, 42, 9179, -2221},
{5, 2841, 51, 83, 9220, 5059},
{5, 2859, 52, 49, 9243, 3431},
{5, 2867, 94, 13, 9214, -5819},
{5, 2903, 51, 46, 9322, 2130},
{5, 2950, 52, 83, 9426, 5851},
{5, 2964, 53, 46, 9429, 3151},
{5, 2974, 52, 75, 9426, -342},
{5, 2976, 52, 83, 9472, 6755},
{5, 2985, 52, 83, 9504, 7217},
{5, 2997, 51, 2, 9456, -3111},
{5, 3077, 52, 83, 10033, 6844},
{5, 3079, 52, 83, 10020, 5541},
{5, 3109, 52, 42, 10031, -2610},
{5, 3115, 51, 75, 10052, -743},
{5, 3132, 92, 85, 10070, -4026},
{5, 3147, 52, 34, 10169, 7324},
{5, 3166, 52, 75, 10138, 326},
{5, 3169, 52, 75, 10142, 328},
{5, 3184, 52, 83, 10183, 4125},
{5, 3190, 53, 46, 10181, 2150},
{5, 3193, 52, 46, 10184, 2154},
{5, 3198, 52, 83, 10199, 4533},
{5, 3201, 119, 85, 10176, -4625},
{5, 3226, 53, 46, 10234, 1954},
{5, 3227, 52, 46, 10235, 1952},
{5, 3242, 93, 42, 10248, -1839},
{5, 3245, 52, 49, 10273, 2830},
{5, 3277, 53, 49, 10329, 2831},
{5, 3294, 53, 49, 10363, 3719},
{5, 3310, 52, 83, 10388, 5330},
{5, 3344, 52, 49, 10435, 2455},
{5, 3359, 52, 83, 10466, 6313},
{5, 3372, 59, 13, 10451, -5952},
{5, 3377, 52, 46, 10477, 1359},
{5, 3384, 52, 46, 10483, 1238},
{5, 3395, 54, 49, 10498, 3259},
{5, 3412, 52, 46, 10509, 1325},
{5, 3414, 53, 49, 10513, 2758},
{5, 3432, 53, 49, 10525, 3637},
{5, 3486, 52, 49, 11004, 2859},
{5, 3489, 52, 46, 11003, 1354},
{5, 3504, 53, 49, 11032, 2758},
{5, 3521, 51, 46, 11058, -2},
{5, 3532, 129, 13, 11052, -5844},
{5, 3593, 52, 46, 11146, 1249},
{5, 3607, 52, 46, 11169, 1803},
{5, 3608, 52, 46, 11170, 1809},
{5, 3610, 52, 83, 11184, 5847},
{5, 3613, 52, 83, 11186, 5800},
{5, 3619, 53, 83, 11194, 5745},
{5, 3621, 52, 42, 11183, -3249},
{5, 3626, 53, 46, 11201, 1821},
{5, 3628, 52, 46, 11203, 1335},
{5, 3631, 52, 83, 11210, 5310},
{5, 3640, 52, 46, 11211, 314},
{5, 3655, 53, 46, 11229, 1635},
{5, 3665, 52, 83, 11247, 3846},
{5, 3675, 52, 83, 11261, 4335},
{5, 3686, 53, 46, 11277, 1713},
{5, 3717, 53, 42, 11315, -3019},
{5, 3718, 52, 83, 11326, 5304},
{5, 3726, 52, 83, 11333, 4702},
{5, 3729, 53, 83, 11338, 5308},
{5, 3810, 52, 46, 11410, 1128},
{5, 3813, 53, 83, 11413, 3633},
{5, 3877, 53, 83, 11461, 4730},
{5, 3893, 52, 83, 11486, 4843},
{5, 3898, 52, 83, 11493, 5605},
{5, 3900, 53, 46, 11492, 2701},
{5, 3912, 54, 46, 11501, 2629},
{5, 3918, 92, 15, 11503, -5711},
{5, 3923, 52, 42, 11510, -2848},
{5, 3938, 52, 83, 11528, 4407},
{5, 3941, 52, 83, 11529, 3659},
{5, 3945, 52, 83, 11532, 6040},
{5, 3949, 53, 83, 11537, 4752},
{5, 3953, 52, 83, 11538, 5219},
{5, 3962, 52, 27, 11547, -1359},
{5, 3982, 53, 83, 11565, 5507},
{5, 3998, 52, 83, 11579, 5527},
{5, 4013, 53, 83, 11585, 4357},
{5, 4026, 52, 83, 11594, 5058},
{5, 4027, 53, 29, 11595, -1916},
{5, 4030, 52, 86, 12004, -106},
{5, 4036, 52, 83, 12015, 6154},
{5, 4038, 52, 29, 12019, -1852},
{5, 4039, 52, 29, 12019, -1853},
{5, 4041, 53, 83, 12022, 6208},
{5, 4051, 52, 83, 12032, 4432},
{5, 4085, 54, 83, 12054, 5021},
{5, 4088, 52, 83, 12056, 5032},
{5, 4096, 52, 83, 12060, 4729},
{5, 4102, 53, 83, 12064, 5243},
{5, 4105, 52, 42, 12067, -2946},
{5, 4111, 52, 30, 12070, 4304},
{5, 4125, 52, 34, 12081, 6510},
{5, 4143, 52, 30, 12096, 4232},
{5, 4147, 122, 24, 12101, 1833},
{5, 4150, 53, 24, 12106, 3024},
{5, 4151, 52, 30, 12105, 3924},
{5, 4179, 53, 86, 12129, 118},
{5, 4203, 52, 24, 12151, 3312},
{5, 4214, 52, 30, 12156, 3620},
{5, 4216, 52, 86, 12159, 1309},
{5, 4236, 52, 34, 12167, 6928},
{5, 4244, 52, 30, 12175, 3748},
{5, 4245, 53, 24, 12176, 2936},
{5, 4251, 52, 24, 12181, 2810},
{5, 4261, 52, 86, 12194, 549},
{5, 4273, 53, 86, 12199, 521},
{5, 4274, 52, 24, 12198, 2937},
{5, 4278, 52, 24, 12201, 2917},
{5, 4281, 53, 86, 12204, 523},
{5, 4293, 52, 24, 12212, 1823},
{5, 4314, 52, 24, 12225, 2954},
{5, 4346, 53, 30, 12235, 4700},
{5, 4350, 53, 24, 12240, 1642},
{5, 4361, 94, 29, 12245, -1847},
{5, 4365, 52, 86, 12245, 719},
{5, 4371, 52, 86, 12249, 1142},
{5, 4388, 53, 86, 12258, 1240},
{5, 4394, 52, 24, 12259, 1813},
{5, 4395, 52, 30, 12258, 3333},
{5, 4414, 52, 24, 12265, 3113},
{5, 4419, 53, 24, 12269, 1503},
{5, 4429, 52, 86, 12274, 1106},
{5, 4435, 52, 86, 12277, 1305},
{5, 4438, 52, 86, 12278, 1300},
{5, 4442, 52, 86, 12281, 948},
{5, 4448, 53, 24, 12283, 2837},
{5, 4449, 52, 30, 12282, 4406},
{5, 4450, 52, 24, 12285, 1705},
{5, 4459, 52, 24, 12290, 1359},
{5, 4473, 52, 24, 12298, 1326},
{5, 4477, 52, 24, 12300, 1338},
{5, 4478, 53, 86, 12303, 1220},
{5, 4485, 53, 30, 12305, 4142},
{5, 4490, 52, 30, 12306, 4139},
{5, 4494, 52, 24, 12314, 2546},
{5, 4517, 52, 86, 12328, 7},
{5, 4526, 52, 86, 12340, 742},
{5, 4527, 52, 86, 12341, 239},
{5, 4535, 52, 86, 12343, 812},
{5, 4536, 52, 86, 12344, 211},
{5, 4546, 52, 86, 12355, -348},
{5, 4550, 53, 86, 12355, 1213},
{5, 4559, 52, 24, 12360, 2758},
{5, 4565, 52, 24, 12363, 2559},
{5, 4567, 53, 86, 12365, 1115},
{5, 4568, 52, 86, 12366, 1114},
{5, 4570, 52, 86, 12369, 715},
{5, 4596, 52, 86, 12399, 1011},
{5, 4605, 52, 83, 12400, 6136},
{5, 4618, 52, 30, 12416, 4109},
{5, 4631, 51, 30, 12421, 3232},
{5, 4636, 52, 86, 12428, 241},
{5, 4643, 52, 86, 12433, 159},
{5, 4654, 52, 86, 12439, 1308},
{5, 4656, 52, 30, 12440, 3210},
{5, 4660, 53, 86, 12445, 1111},
{5, 4665, 52, 86, 12451, 303},
{5, 4666, 52, 86, 12451, -28},
{5, 4689, 52, 24, 12478, 1346},
{5, 4697, 51, 86, 12486, -548},
{5, 4698, 52, 86, 12484, 829},
{5, 4699, 52, 86, 12490, -840},
{5, 4725, 51, 24, 12504, 2530},
{5, 4753, 52, 86, 12524, -112},
{5, 4754, 52, 86, 12523, 1119},
{5, 4762, 52, 86, 12529, 1114},
{5, 4781, 53, 86, 12544, -1032},
{5, 4800, 53, 30, 12546, 4632},
{5, 4845, 53, 86, 12580, 135},
{5, 4856, 52, 86, 12594, -1503},
{5, 4866, 53, 86, 12595, 1410},
{5, 4889, 53, 24, 13001, 2759},
{5, 4900, 53, 86, 13007, 230},
{5, 4902, 52, 86, 13010, -1431},
{5, 4945, 51, 15, 13054, -4928},
{5, 4958, 52, 86, 13058, -801},
{5, 4995, 53, 86, 13097, -750},
{5, 5005, 52, 30, 13109, 3703},
{5, 5033, 52, 30, 13135, 3636},
{5, 5053, 122, 24, 13165, 1742},
{5, 5054, 52, 86, 13170, -1638},
{5, 5068, 52, 86, 13189, -2102},
{5, 5078, 53, 42, 13198, -2725},
{5, 5102, 52, 15, 13220, -3638},
{5, 5128, 49, 15, 13255, -4301},
{5, 5139, 116, 15, 13268, -4729},
{5, 5247, 52, 86, 13380, -1753},
{5, 5248, 52, 9, 13375, 853},
{5, 5273, 53, 30, 13421, 3539},
{5, 5286, 119, 15, 13464, -5122},
{5, 5322, 52, 83, 13492, 6011},
{5, 5350, 53, 30, 13534, 4022},
{5, 5353, 53, 30, 13534, 4017},
{5, 5354, 53, 30, 13534, 4018},
{5, 5363, 52, 86, 13561, 515},
{5, 5364, 52, 86, 13562, 501},
{5, 5371, 52, 30, 13557, 4028},
{5, 5427, 53, 86, 14034, -602},
{5, 5466, 121, 9, 14055, 2832},
{5, 5473, 53, 83, 14047, 5454},
{5, 5474, 52, 83, 14050, 5340},
{5, 5557, 53, 9, 14184, 3630},
{5, 5566, 52, 86, 14203, 356},
{5, 5576, 53, 86, 14211, 316},
{5, 5631, 53, 83, 14266, 5635},
{5, 5634, 122, 86, 14296, -559},
{5, 5643, 52, 50, 14327, -4411},
{5, 5676, 53, 9, 14328, 4927},
{5, 5689, 53, 9, 14355, 4844},
{5, 5694, 122, 42, 14396, -2632},
{5, 5746, 52, 86, 14449, 157},
{5, 5813, 52, 86, 15012, 142},
{5, 5822, 133, 50, 15044, -5424},
{5, 5823, 134, 19, 15055, -5536},
{5, 5824, 121, 50, 15040, -3304},
{5, 5846, 52, 86, 15065, 136},
{5, 5850, 52, 86, 15071, 133},
{5, 5897, 120, 48, 15174, -2101},
{5, 5907, 52, 34, 15159, 5620},
{5, 5927, 120, 50, 15280, -5040},
{5, 5946, 120, 57, 15355, -5040},
{5, 5982, 53, 34, 15387, 5921},
{5, 5986, 120, 50, 15461, -3747},
{5, 6067, 132, 57, 16132, -5413},
{5, 6118, 53, 74, 16218, -217},
{5, 6124, 132, 72, 16253, -4039},
{5, 6134, 133, 57, 16278, -4909},
{5, 6144, 121, 72, 16272, -2601},
{5, 6192, 135, 72, 16404, -4322},
{5, 6193, 131, 6, 16413, -4846},
{5, 6204, 134, 6, 16462, -4701},
{5, 6207, 53, 40, 16431, 3650},
{5, 6210, 94, 40, 16445, 2348},
{5, 6217, 53, 84, 16326, 7812},
{5, 6222, 136, 72, 16494, -4444},
{5, 6229, 121, 40, 16470, 4732},
{5, 6231, 129, 72, 16542, -4149},
{5, 6235, 121, 59, 16534, -2211},
{5, 6242, 132, 72, 16556, -3928},
{5, 6259, 134, 72, 17008, -4439},
{5, 6281, 131, 72, 17047, -3759},
{5, 6284, 121, 59, 17045, -2446},
{5, 6287, 121, 59, 17052, -2242},
{5, 6293, 120, 59, 17102, -2635},
{5, 6302, 96, 72, 17137, -3706},
{5, 6304, 120, 59, 17145, -2928},
{5, 6309, 95, 59, 17141, -1255},
{5, 6316, 120, 59, 17166, -2808},
{5, 6334, 70, 72, 17208, -3606},
{5, 6342, 122, 59, 17212, -1935},
{5, 6352, 120, 6, 17255, -4825},
{5, 6355, 121, 59, 17240, -2621},
{5, 6356, 120, 59, 17236, -1749},
{5, 6366, 122, 59, 17277, -505},
{5, 6369, 95, 59, 17293, -2346},
{5, 6388, 119, 72, 17363, -4444},
{5, 6397, 117, 6, 17407, -5340},
{5, 6401, 119, 59, 17386, -2355},
{5, 6426, 122, 59, 17449, 310},
{5, 6440, 121, 77, 17489, -2022},
{5, 6441, 119, 72, 17502, -3703},
{5, 6445, 97, 77, 17493, -2001},
{5, 6451, 134, 72, 17507, -3013},
{5, 6453, 122, 72, 17509, -3436},
{5, 6503, 52, 34, 17495, 7009},
{5, 6517, 122, 59, 18018, -858},
{5, 6520, 134, 77, 18034, -2753},
{5, 6522, 122, 77, 18036, -3002},
{5, 6528, 122, 77, 18048, -3003},
{5, 6535, 121, 74, 18038, -18},
{5, 6539, 121, 74, 18048, -735},
{5, 6541, 118, 25, 18080, -4342},
{5, 6543, 92, 34, 17586, 6638},
{5, 6544, 120, 77, 18073, -2500},
{5, 6553, 120, 77, 18093, -2554},
{5, 6568, 135, 77, 18128, -2135},
{5, 6569, 120, 77, 18136, -3150},
{5, 6572, 92, 59, 18121, 651},
{5, 6583, 136, 77, 18158, -2208},
{5, 6603, 137, 77, 18184, -1824},
{5, 6624, 120, 77, 18237, -3022},
{5, 6629, 94, 77, 18257, -2312},
{5, 6633, 131, 59, 18273, 631},
{5, 6638, 121, 77, 18309, -2530},
{5, 6642, 121, 77, 18319, -2329},
{5, 6645, 135, 77, 18320, -1653},
{5, 6649, 135, 73, 18335, -1024},
{5, 6652, 121, 77, 18358, -3259},
{5, 6664, 134, 73, 18366, -749},
{5, 6712, 120, 73, 18531, -842},
{5, 6723, 119, 77, 18596, -3638},
{5, 6726, 70, 25, 19017, -3653},
{5, 6727, 70, 25, 19017, -3653},
{5, 6729, 70, 25, 19019, -3657},
{5, 6752, 117, 61, 19109, -5959},
{5, 6755, 134, 4, 19078, 416},
{5, 6756, 136, 4, 19087, 442},
{5, 6760, 121, 4, 19112, 102},
{5, 6781, 95, 4, 19185, 632},
{5, 6791, 136, 52, 19207, 3751},
{5, 6802, 135, 88, 19306, 2016},
{5, 6818, 94, 77, 19440, -1409},
{5, 6819, 133, 31, 19413, 4011},
{5, 6822, 51, 77, 19449, -1448},
{5, 6823, 133, 88, 19432, 2318},
{5, 6826, 93, 31, 19448, 5032},
{5, 6830, 134, 88, 19510, 2306},
{5, 6834, 134, 31, 19522, 2924},
{5, 6857, 67, 31, 20028, 3331},
{5, 6866, 134, 31, 20039, 4410},
{5, 6885, 134, 88, 20119, 2629},
{5, 6888, 66, 31, 20128, 3819},
{5, 6905, 96, 32, 20224, 2006},
{5, 6907, 53, 12, 20251, -2449},
{5, 6910, 133, 31, 20232, 4047},
{5, 6934, 121, 32, 20342, 724},
{5, 6939, 134, 16, 20315, 6040},
{5, 6940, 132, 88, 20344, 2817},
{5, 6946, 51, 16, 20349, 6009},
{5, 6960, 105, 31, 20457, 3043},
{5, 6974, 112, 31, 20511, 3150},
{5, 6979, 70, 31, 20510, 3208},
{5, 6992, 105, 31, 20564, 3143},
{5, 6995, 105, 31, 20571, 3113},
{5, 7000, 60, 31, 21018, 4412},
{5, 7006, 122, 32, 21015, 1611},
{5, 7008, 96, 31, 21005, 5433},
{5, 7009, 92, 5, 21042, -1122},
{5, 7023, 77, 16, 21005, 6810},
{5, 7026, 96, 31, 21063, 4751},
{5, 7027, 94, 31, 21070, 4214},
{5, 7044, 138, 31, 21129, 4229},
{5, 7062, 134, 31, 21235, 4623},
{5, 7086, 134, 31, 21305, 5136},
{5, 7090, 52, 44, 21365, -5433},
{5, 7128, 136, 31, 21440, 5343},
{5, 7129, 81, 16, 21430, 6607},
{5, 7142, 135, 16, 21452, 6546},
{5, 7160, 132, 16, 21537, 6236},
{5, 7184, 52, 5, 22027, -2049},
{5, 7209, 134, 45, 22051, 4629},
{5, 7217, 52, 62, 22079, 3122},
{5, 7243, 132, 45, 22151, 4954},
{5, 7293, 90, 5, 22296, -2050},
{5, 7296, 136, 45, 22282, 5217},
{5, 7320, 54, 62, 22361, 3357},
{5, 7331, 52, 62, 22371, 3425},
{5, 7380, 133, 16, 22473, 5808},
{5, 7424, 52, 39, 22573, -4104},
{5, 7448, 53, 62, 23001, 1559},
{5, 7479, 52, 62, 23049, 1219},
{5, 7510, 134, 16, 23115, 6034},
{5, 7582, 52, 39, 23184, -4222},
{5, 7606, 52, 5, 23191, -829},
{5, 7619, 53, 62, 23202, 812},
{5, 7635, 67, 14, 23202, 6111},
{5, 7662, 93, 1, 23259, 4232},
{5, 7686, 132, 1, 23301, 4908},
{5, 7723, 53, 5, 23390, -1258},
{5, 7727, 52, 5, 23399, -1218},
{5, 7789, 133, 14, 23574, 5643},
{5, 7790, 135, 14, 23584, 6113},
{5, 7793, 51, 71, 23578, -3236},
{5, 7814, 52, 62, 32, 1609},
{0, 36, 146, 1, 550, +2338},
{15, 0, 142, 1, 2039, +4220},
{201, 228, 147, 1, 2140, +4729},
{201, 3050, 146, 1, 23595, +3343},
{0, 56, 146, 1, 1562, +3715},
{0, 59, 146, 1, 2109, +3902},
{24, 0, 146, 4, 19487, +1149},
{201, 2404, 147, 4, 18508, +1059},
{201, 2532, 146, 4, 19302, 254},
{0, 5, 146, 4, 18465, -58},
{0, 11, 145, 4, 18591, +1338},
{0, 15, 146, 4, 19050, -402},
{0, 57, 146, 4, 19546, -814},
{201, 2838, 146, 5, 21546, -318},
{32, 0, 144, 5, 22288, -1},
{0, 12, 146, 5, 21041, -549},
{0, 41, 146, 5, 22143, -2104},
{0, 53, 146, 5, 22266, -1645},
{0, 94, 145, 5, 23191, -1328},
{0, 107, 146, 5, 23460, -1841},
{12, 0, 145, 7, 2592, +2120},
{15, 0, 145, 7, 1535, +1918},
{20, 0, 145, 7, 1579, +2336},
{24, 0, 145, 7, 2493, +1728},
{201, 394, 147, 7, 3280, +2028},
{0, 1, 146, 7, 1501, +2217},
{0, 30, 147, 7, 2370, +2439},
{0, 33, 145, 7, 2407, +2704},
{16, 0, 143, 8, 5597, +3713},
{201, 644, 147, 8, 5103, +3718},
{201, 698, 147, 8, 5252, +3451},
{201, 872, 147, 8, 6156, +3609},
{29, 0, 145, 8, 4593, +3753},
{30, 0, 145, 8, 6467, +4335},
{0, 14, 145, 8, 5154, +3241},
{0, 26, 145, 8, 5386, +3030},
{0, 41, 146, 8, 6116, +4843},
{132, 147, 147, 8, 6343, +3805},
{11, 0, 144, 9, 15155, +3319},
{12, 0, 143, 9, 14450, +2704},
{17, 0, 145, 9, 14162, +5122},
{19, 0, 145, 9, 14135, +5147},
{21, 0, 144, 9, 15245, +3723},
{24, 0, 145, 9, 14407, +1625},
{201, 1825, 146, 9, 14165, +2007},
{201, 1835, 145, 9, 14234, +827},
{201, 1884, 147, 9, 14484, +2422},
{31, 0, 145, 9, 14514, +1906},
{32, 0, 144, 9, 14411, +1344},
{0, 39, 146, 9, 14497, +4843},
{0, 44, 145, 9, 15038, +4739},
{162, 191, 147, 9, 14596, +5352},
{201, 1694, 145, 11, 12492, +8325},
{201, 400, 147, 11, 3350, +6002},
{201, 485, 147, 11, 4078, +6220},
{0, 1, 146, 11, 4320, +5355},
{0, 11, 145, 11, 5061, +5858},
{6, 0, 144, 12, 20176, -1230},
{23, 0, 146, 12, 20299, -1835},
{24, 0, 145, 12, 20273, -1813},
{26, 0, 145, 12, 20289, -1749},
{27, 0, 145, 12, 20194, -1907},
{17, 0, 145, 14, 2291, +6724},
{18, 0, 144, 14, 491, +5749},
{27, 0, 145, 14, 23590, +5545},
{201, 163, 147, 14, 1513, +6451},
{201, 3053, 146, 14, 26, +6606},
{201, 3062, 146, 14, 63, +5826},
{0, 3, 145, 15, 13518, -3300},
{9, 0, 143, 16, 21287, +7034},
{11, 0, 144, 16, 22292, +5825},
{19, 0, 144, 16, 20089, +7743},
{201, 2780, 147, 16, 21118, +5959},
{201, 2816, 146, 16, 21390, +5729},
{201, 2840, 146, 16, 21520, +5548},
{201, 460, 146, 16, 4100, +8042},
{31, 0, 144, 16, 22038, +6438},
{132, 461, 147, 16, 22039, +5949},
{10, 0, 145, 17, 1496, -1041},
{15, 0, 144, 17, 2433, +314},
{201, 186, 147, 17, 1559, +151},
{0, 66, 146, 17, 2128, -224},
{6, 0, 140, 20, 6451, -1643},
{12, 0, 142, 20, 6586, -2858},
{21, 0, 145, 20, 6561, -1403},
{108, 3945, 145, 20, 7166, -2319},
{17, 0, 144, 22, 8467, +2846},
{25, 0, 146, 22, 8268, +2656},
{201, 1177, 147, 22, 8056, +2732},
{201, 1245, 146, 22, 8358, 637},
{201, 1254, 147, 22, 8404, +1940},
{201, 1311, 147, 22, 9074, +2259},
{32, 0, 145, 22, 8122, +1739},
{0, 57, 146, 22, 8542, +3035},
{0, 66, 146, 22, 9014, +3215},
{201, 1633, 147, 24, 12207, +2703},
{201, 1639, 147, 24, 12244, +2535},
{0, 2, 146, 24, 12043, +2128},
{0, 24, 145, 24, 12351, +1823},
{0, 35, 145, 24, 12533, +2115},
{15, 0, 145, 25, 19064, -3704},
{19, 0, 146, 25, 18334, -3844},
{15, 0, 144, 26, 15427, +2618},
{18, 0, 146, 26, 15232, +3017},
{27, 0, 146, 26, 16147, +3352},
{32, 0, 145, 26, 15394, +3638},
{132, 128, 146, 26, 16117, +3321},
{11, 0, 143, 29, 12299, -1631},
{201, 1604, 147, 29, 12095, -1151},
{6, 0, 143, 30, 12560, +3819},
{0, 2, 146, 30, 12161, +4040},
{9, 0, 143, 31, 19307, +2758},
{11, 0, 143, 31, 19450, +4508},
{20, 0, 145, 31, 20474, +3629},
{21, 0, 145, 31, 21441, +2845},
{21, 0, 145, 31, 21441, +2845},
{201, 2486, 147, 31, 19121, +4951},
{30, 0, 145, 31, 19556, +5226},
{0, 16, 146, 31, 19418, +5032},
{0, 31, 144, 31, 20136, +4644},
{0, 49, 146, 31, 20410, +3218},
{0, 61, 145, 31, 21069, +3845},
{132, 130, 146, 31, 21208, +3227},
{103, 5137, 146, 31, 19459, +3501},
{15, 0, 144, 32, 20467, +1607},
{12, 0, 144, 34, 19482, +7016},
{21, 0, 146, 34, 17053, +5428},
{22, 0, 145, 34, 17322, +5511},
{23, 0, 145, 34, 18512, +5923},
{201, 2155, 147, 34, 17161, +6043},
{201, 2348, 146, 34, 18339, +5221},
{30, 0, 145, 34, 17419, +7209},
{0, 17, 145, 34, 16362, +5255},
{0, 41, 146, 34, 18002, +8000},
{132, 123, 147, 34, 13271, +6444},
{12, 0, 145, 35, 20591, +418},
{201, 2742, 147, 35, 21022, +711},
{16, 0, 143, 36, 2583, -4018},
{11, 5, 146, 36, 1398, -5612},
{0, 55, 147, 36, 4436, -848},
{108, 3556, 146, 36, 3124, -4425},
{29, 0, 145, 37, 2338, -2814},
{6, 0, 142, 38, 7346, +3153},
{11, 0, 144, 38, 7201, +2159},
{19, 0, 144, 38, 7444, +2424},
{201, 1083, 147, 38, 7256, +2030},
{201, 1108, 147, 38, 7328, +2253},
{0, 38, 145, 38, 6546, +1311},
{162, 70, 147, 38, 6278, +2047},
{6, 0, 143, 40, 17146, +1423},
{11, 0, 143, 40, 17150, +2450},
{19, 0, 145, 40, 16081, +1703},
{26, 0, 145, 40, 17237, +3709},
{201, 2052, 147, 40, 16289, +1825},
{201, 2063, 146, 40, 16318, +4536},
{201, 2315, 147, 40, 18250, +2724},
{201, 2411, 147, 40, 18523, +1432},
{0, 37, 146, 40, 16406, +413},
{0, 56, 146, 40, 16550, +2544},
{0, 95, 145, 40, 18015, +2136},
{0, 100, 146, 40, 18078, +2606},
{132, 129, 147, 40, 18359, +1659},
{12, 0, 143, 42, 8468, +625},
{201, 1348, 148, 42, 9245, +621},
{201, 1355, 147, 42, 9273, +614},
{201, 1365, 147, 42, 9315, +128},
{28, 0, 145, 42, 9291, -246},
{103, 396, 146, 42, 11323, -2916},
{201, 2894, 146, 45, 22189, +3746},
{0, 8, 146, 45, 22359, +3938},
{6, 0, 141, 46, 10084, +1158},
{15, 0, 142, 46, 10200, +1950},
{28, 0, 145, 46, 11279, +251},
{0, 6, 145, 46, 9320, +943},
{0, 49, 146, 46, 10350, +839},
{0, 54, 144, 46, 10556, +2445},
{0, 81, 146, 46, 11256, +1627},
{0, 83, 147, 46, 11268, +301},
{0, 90, 146, 46, 11347, +1648},
{132, 215, 147, 46, 10163, +1744},
{15, 0, 144, 47, 5445, -2227},
{108, 3750, 145, 47, 5204, -2114},
{21, 0, 145, 48, 14493, -1409},
{23, 0, 146, 48, 15210, -1533},
{201, 1962, 146, 48, 15387, -847},
{31, 0, 145, 50, 15569, -3358},
{201, 1282, 147, 51, 8508, +3504},
{201, 1333, 147, 51, 9184, +3522},
{201, 1338, 147, 51, 9210, +3811},
{201, 1369, 147, 51, 9354, +3958},
{201, 958, 146, 51, 6482, +5542},
{0, 12, 145, 51, 6462, +5927},
{0, 19, 146, 51, 7229, +5517},
{0, 38, 144, 51, 9188, +3648},
{9, 0, 144, 52, 18501, +3322},
{13, 0, 145, 52, 18443, +3940},
{14, 0, 145, 52, 18443, +3940},
{18, 0, 144, 52, 19138, +3909},
{201, 2474, 147, 52, 19091, +3436},
{32, 0, 144, 52, 18448, +3736},
{200, 0, 145, 52, 18570, +3254},
{162, 282, 146, 52, 18549, +3358},
{108, 5218, 147, 54, 20454, -3029},
{9, 0, 145, 55, 6288, -702},
{12, 0, 144, 55, 6238, +436},
{20, 0, 144, 59, 16309, +159},
{23, 0, 145, 59, 17180, -2417},
{26, 0, 145, 59, 16256, -2327},
{201, 2276, 147, 59, 18057, +1200},
{28, 0, 145, 59, 18031, -811},
{0, 36, 145, 59, 17153, -2636},
{0, 61, 146, 59, 17446, +235},
{0, 70, 144, 59, 18055, +230},
{9, 0, 140, 60, 5145, -812},
{11, 0, 142, 60, 5320, -18},
{16, 0, 145, 60, 5353, -523},
{17, 0, 143, 60, 5354, -555},
{18, 0, 144, 60, 5245, -224},
{20, 0, 144, 60, 5351, +956},
{26, 0, 145, 60, 5133, +252},
{27, 0, 144, 60, 5387, -236},
{201, 747, 145, 60, 5350, -600},
{201, 790, 146, 60, 5460, -416},
{32, 0, 142, 60, 5407, -157},
{0, 14, 146, 60, 5079, +830},
{0, 23, 145, 60, 5228, +333},
{0, 32, 144, 60, 5308, 557},
{0, 33, 146, 60, 5312, +318},
{0, 52, 146, 60, 5480, +627},
{12, 0, 143, 62, 21442, +953},
{201, 2841, 146, 62, 21543, +1943},
{201, 3007, 147, 62, 23228, +2034},
{0, 1, 144, 62, 21221, +1948},
{18, 0, 144, 63, 2507, +5554},
{201, 162, 146, 63, 1493, +4754},
{201, 331, 145, 63, 3009, +5221},
{201, 336, 147, 63, 3015, +3225},
{201, 369, 147, 63, 3171, +4029},
{0, 56, 146, 63, 4246, +3358},
{11, 24, 146, 66, 22366, -3140},
{6, 0, 144, 67, 2020, +246},
{201, 22, 147, 67, 174, +853},
{201, 3009, 147, 67, 23243, +343},
{30, 0, 145, 67, 1057, +2128},
{32, 0, 145, 67, 1137, +735},
{0, 35, 144, 67, 150, +849},
{0, 55, 146, 67, 399, +2126},
{0, 65, 146, 67, 499, +2743},
{0, 66, 146, 67, 546, +1911},
{0, 77, 146, 67, 1058, +455},
{112, 0, 145, 68, 7183, -3644},
{110, 19, 146, 68, 7343, -2328},
{103, 327, 144, 68, 7388, -2648},
{6, 0, 141, 72, 16294, -2626},
{9, 0, 143, 72, 16054, -1948},
{22, 0, 144, 72, 16120, -1928},
{31, 0, 145, 72, 16044, -1122},
{11, 0, 144, 74, 15348, +1032},
{16, 0, 145, 74, 18562, +412},
{201, 1919, 147, 74, 15127, +1917},
{0, 59, 145, 74, 18272, +12},
{132, 127, 146, 74, 15402, +1203},
{15, 0, 145, 75, 9525, -806},
{153, 0, 147, 75, 9541, +457},
{0, 35, 146, 75, 10433, +445},
{0, 40, 147, 75, 10493, -401},
{32, 0, 145, 76, 19490, +1909},
{110, 84, 146, 76, 19394, +1634},
{138, 0, 145, 77, 17591, -3015},
{0, 54, 145, 77, 19407, -1618},
{108, 5082, 146, 77, 19031, -1915},
{10, 0, 145, 78, 4226, +2538},
{25, 0, 145, 78, 4204, +2721},
{201, 422, 146, 78, 3368, +35},
{201, 495, 146, 78, 4077, +1510},
{201, 572, 147, 78, 4385, +2656},
{0, 7, 147, 78, 3344, +2428},
{0, 62, 146, 78, 4240, +2418},
{0, 118, 146, 78, 5293, +2509},
{201, 239, 147, 81, 2174, +2845},
{0, 6, 145, 81, 2124, +3018},
{27, 0, 145, 83, 9104, +6708},
{201, 1520, 147, 83, 11161, +5246},
{201, 1523, 144, 83, 11182, +3132},
{201, 1695, 146, 83, 12563, +5406},
{32, 0, 142, 83, 13239, +5456},
{132, 126, 146, 83, 11323, +6105},
{6, 0, 142, 84, 2318, +8916},
{201, 1972, 147, 84, 15292, +8027},
{108, 2682, 147, 84, 13407, +7651},
{11, 70, 145, 85, 8295, -4443},
{108, 4191, 145, 85, 9144, -4314},
{15, 0, 143, 86, 12417, -127},
{28, 0, 144, 86, 14016, +133},
{0, 17, 147, 86, 12225, +518},
{60, 0, 161, 1, 275, 3535},
{166, 0, 162, 1, 23388, 3546},
{167, 0, 162, 1, 46, 4333},
{167, 0, 162, 1, 46, 4333},
{181, 0, 161, 1, 2384, 3910},
{185, 0, 162, 1, 199, 4443},
{107, 5223, 162, 1, 542, 2404},
{130, 15196, 162, 1, 542, 2404},
{179, 0, 162, 4, 18585, 1422},
{182, 0, 161, 4, 19044, -541},
{182, 1469, 162, 4, 20011, 931},
{130, 11960, 161, 4, 19232, -1042},
{147, 0, 163, 5, 23244, -1719},
{182, 0, 162, 7, 2150, 1214},
{90, 0, 163, 8, 5034, 5038},
{96, 0, 162, 8, 5481, 3038},
{148, 0, 164, 8, 6348, 4230},
{152, 0, 162, 8, 5271, 3409},
{176, 0, 163, 8, 5091, 3900},
{178, 0, 159, 8, 6365, 3827},
{179, 0, 161, 8, 5218, 3231},
{182, 0, 163, 8, 6240, 4742},
{182, 346, 163, 8, 4526, 3830},
{149, 0, 163, 9, 14242, 2542},
{147, 0, 162, 11, 7217, 6940},
{152, 0, 162, 11, 5410, 6848},
{166, 0, 161, 11, 4512, 6810},
{177, 0, 161, 11, 3418, 6239},
{179, 0, 162, 11, 4059, 6148},
{196, 0, 161, 11, 4086, 5322},
{146, 0, 161, 12, 20171, -2119},
{129, 0, 164, 14, 246, 5417},
{166, 0, 165, 14, 175, 1714},
{187, 0, 162, 14, 549, 5834},
{191, 0, 163, 14, 1336, 5745},
{193, 0, 161, 14, 13, 6021},
{182, 623, 161, 14, 3114, 5754},
{21, 0, 162, 16, 21435, 5848},
{152, 0, 161, 16, 21352, 7837},
{107, 16115, 162, 17, 2351, -927},
{157, 129989, 162, 17, 2351, -9264},
{187, 0, 160, 20, 7081, -1155},
{139, 0, 161, 21, 7087, 1001},
{171, 0, 162, 22, 8567, 1931},
{194, 0, 160, 22, 8554, 1714},
{139, 0, 160, 26, 15486, 2809},
{182, 0, 161, 26, 15495, 3934},
{172, 0, 162, 30, 12594, 3749},
{197, 0, 159, 30, 12451, 4526},
{66, 0, 161, 31, 19288, 4603},
{67, 0, 162, 31, 19572, 4416},
{82, 0, 162, 31, 20468, 4603},
{145, 0, 161, 31, 20134, 3844},
{148, 0, 161, 31, 21433, 3801},
{150, 0, 163, 31, 20104, 3557},
{168, 0, 163, 31, 20095, 4752},
{172, 0, 161, 31, 19409, 3237},
{177, 0, 160, 31, 20196, 4754},
{182, 0, 162, 31, 20413, 4808},
{182, 0, 162, 31, 20413, 4808},
{192, 0, 163, 31, 20186, 3727},
{182, 460, 160, 31, 21420, 3531},
{107, 189256, 162, 31, 19572, 4418},
{157, 106516, 162, 32, 20486, 1750},
{150, 0, 160, 34, 12564, 6560},
{171, 0, 161, 34, 17564, 5813},
{180, 0, 160, 34, 19216, 7634},
{169, 0, 162, 36, 5098, -531},
{75, 0, 162, 38, 7209, 2460},
{129, 0, 161, 38, 7319, 2430},
{173, 0, 161, 38, 6109, 2601},
{184, 0, 162, 38, 6421, 3127},
{33, 0, 161, 40, 18303, 2152},
{144, 0, 162, 40, 16042, 5030},
{157, 46574, 161, 40, 17135, 4206},
{177, 0, 159, 42, 10376, -1323},
{182, 0, 161, 42, 10516, -2115},
{197, 0, 161, 42, 9511, -2301},
{139, 0, 160, 46, 9476, 1124},
{139, 0, 160, 47, 4596, -1448},
{197, 0, 161, 51, 7282, 460},
{109, 0, 162, 52, 18428, 3658},
{171, 0, 162, 52, 18323, 3660},
{177, 0, 162, 52, 19202, 3753},
{73, 0, 163, 55, 6564, 76},
{96, 0, 163, 55, 6224, 325},
{102, 0, 162, 55, 6532, -435},
{148, 0, 161, 55, 6584, 610},
{150, 0, 162, 55, 7069, -733},
{182, 614, 161, 55, 7010, -315},
{175, 0, 161, 59, 17297, -1928},
{182, 0, 161, 59, 16267, -1226},
{74, 0, 160, 60, 6255, 1443},
{101, 0, 164, 60, 6177, 831},
{146, 0, 162, 60, 5332, 709},
{190, 0, 160, 60, 5054, 111},
{149, 0, 162, 62, 21564, 2248},
{33, 0, 163, 63, 3451, 4447},
{149, 0, 162, 63, 21564, 2252},
{151, 0, 162, 63, 22059, 3330},
{197, 0, 162, 63, 3277, 4411},
{182, 466, 162, 63, 3415, 5130},
{176, 0, 159, 67, 23464, 329},
{198, 0, 161, 67, 1161, 2546},
{107, 26, 162, 67, 54, 847},
{157, 109003, 162, 67, 54, 847},
{157, 128396, 163, 67, 23491, 623},
{147, 0, 162, 68, 8075, -2255},
{148, 0, 163, 73, 18474, -1313},
{149, 0, 162, 73, 18370, -736},
{165, 0, 160, 73, 18583, -754},
{171, 0, 162, 73, 18554, -86},
{87, 0, 162, 74, 18474, 530},
{94, 0, 163, 74, 18194, -1537},
{72, 0, 163, 76, 20024, 2105},
{76, 0, 162, 76, 20024, 2036},
{195, 0, 161, 76, 20051, 2039},
{60, 0, 161, 77, 19343, -1622},
{170, 0, 162, 77, 17449, -1839},
{182, 1942, 161, 77, 19192, -1555},
{167, 0, 163, 78, 5491, 1904},
{172, 0, 162, 78, 4515, 2832},
{173, 0, 160, 78, 5452, 2425},
{197, 0, 161, 78, 5457, 2042},
{146, 0, 163, 83, 9184, 5124},
{186, 0, 160, 83, 10451, 6725},
{147, 0, 162, 86, 12473, 409},
{165, 0, 160, 86, 12252, 46},
{107, 113801, 163, 86, 13064, -2004},
{157, 157721, 163, 86, 13064, -2004},
{68, 0, 162, 88, 20373, 2630},
{130, 13571, 162, 88, 21099, 2637},
{34, 0, 169, 36, 1377, -5714},
{35, 0, 171, 72, 16054, -1948},
{36, 0, 169, 28, 12266, -6306},
{37, 0, 170, 20, 6586, -2858},
{38, 0, 169, 15, 14038, -6022},
{39, 0, 170, 1, 2039, 4220},
{40, 0, 169, 78, 4359, 1631},
{41, 0, 170, 16, 21186, 6235},
{42, 0, 170, 39, 22427, -4653},
{43, 0, 170, 63, 3243, 4952},
{44, 0, 170, 46, 10200, 1950},
{45, 0, 170, 63, 3082, 4057},
{46, 0, 170, 38, 6377, 1624},
{47, 0, 170, 83, 12540, 5558},
{48, 0, 170, 83, 13475, 4919},
{49, 0, 170, 39, 22082, -4658},
{50, 0, 170, 60, 5362, -112},
{51, 0, 170, 60, 5408, -157},
{52, 0, 170, 42, 9276, -840},
{53, 0, 170, 26, 15347, 2643},
{54, 0, 170, 1, 84, 2905},
{55, 0, 170, 85, 8095, -4720},
{56, 0, 169, 4, 19508, 852},
{57, 0, 170, 20, 7241, -2918},
{58, 0, 170, 64, 263, -4218},
{59, 0, 169, 72, 16294, -2626},
{61, 0, 168, 9, 14157, 1911},
{62, 0, 171, 47, 5327, -1749},
{63, 0, 170, 13, 9171, -5917},
{64, 0, 170, 80, 16487, -6902},
{65, 0, 170, 13, 8225, -5931},
{69, 0, 169, 28, 12477, -5941},
{70, 0, 170, 60, 5251, 621},
{71, 0, 169, 60, 5552, 724},
{77, 0, 168, 13, 6240, -5242},
{78, 0, 168, 8, 5167, 4560},
{79, 0, 170, 14, 92, 5909},
{80, 0, 170, 38, 7346, 3153},
{81, 0, 170, 14, 567, 6043},
{83, 0, 169, 31, 20414, 4517},
{84, 0, 170, 17, 436, -1759},
{85, 0, 170, 46, 11491, 1434},
{86, 0, 170, 17, 436, -1759},
{88, 0, 170, 72, 16003, -2237},
{89, 0, 170, 83, 11037, 6145},
{91, 0, 170, 78, 5263, 2836},
{92, 0, 170, 34, 17566, 5129},
{93, 0, 170, 62, 21442, 953},
{95, 0, 169, 66, 22577, -2937},
{97, 0, 170, 28, 12312, -5707},
{98, 0, 170, 26, 15347, 2643},
{99, 0, 171, 31, 20462, 3358},
{100, 0, 170, 72, 17425, -3902},
{104, 0, 169, 15, 14038, -6022},
{105, 0, 170, 7, 2072, 2328},
{106, 0, 171, 59, 16372, -1034},
{111, 0, 170, 9, 14450, 2704},
{113, 0, 170, 77, 18242, -3423},
{114, 0, 170, 84, 14507, 7409},
{115, 0, 170, 85, 8447, -5443},
{116, 0, 170, 62, 23048, 1512},
{117, 0, 170, 8, 5595, 4457},
{118, 0, 171, 17, 3023, 405},
{119, 0, 170, 15, 14067, -3622},
{120, 0, 170, 83, 11018, 5623},
{121, 0, 170, 13, 9132, -6943},
{122, 0, 169, 28, 12477, -5941},
{123, 0, 170, 60, 5320, -18},
{124, 0, 170, 1, 1097, 3537},
{125, 0, 170, 63, 3243, 4952},
{126, 0, 170, 20, 6227, -1757},
{127, 0, 170, 83, 13239, 5456},
{128, 0, 170, 68, 8036, -4000},
{131, 0, 170, 77, 18553, -2618},
{133, 0, 170, 61, 20256, -5644},
{134, 0, 170, 83, 11538, 5342},
{135, 0, 170, 84, 2318, 8916},
{136, 0, 169, 38, 7453, 2802},
{137, 0, 168, 21, 7393, 514},
{140, 0, 170, 59, 17349, 1234},
{141, 0, 169, 46, 10084, 1158},
{142, 0, 168, 60, 5145, -812},
{143, 0, 168, 15, 14396, -6050},
{154, 0, 170, 59, 17104, -1543},
{155, 0, 170, 31, 20222, 4015},
{156, 0, 170, 60, 5478, -940},
{158, 0, 170, 72, 17373, -4260},
{159, 0, 170, 62, 23038, 2805},
{160, 0, 170, 14, 405, 5632},
{161, 0, 170, 72, 17336, -3706},
{163, 0, 168, 20, 6451, -1643},
{164, 0, 169, 86, 13252, -1110},
{174, 0, 170, 13, 9171, -5917},
{183, 0, 168, 52, 18369, 3847},
{188, 0, 170, 72, 16502, -3418},
{189, 0, 170, 20, 7084, -2624},
{199, 0, 171, 46, 11141, 2031},
{7, 0, 168, 15, 14396, -6050},
{8, 0, 169, 15, 14396, -6050},
{6, 0, 170, 50, 14419, -4723},
{9, 0, 170, 39, 22427, -4653},
{15, 0, 170, 14, 567, 6043},
{15, 0, 170, 15, 12415, -4858},
{11, 0, 171, 15, 12084, -5043},
{11, 0, 170, 85, 8447, -5443},
{12, 0, 170, 15, 13399, -5328},
{32, 0, 171, 15, 13555, -4717},
{32, 0, 171, 59, 16372, -1034},
{18, 0, 170, 15, 14355, -4209},
{19, 0, 170, 85, 9221, -5501},
{20, 0, 170, 85, 9080, -4326}
};
//###############################################################################################################
//###############################################################################################################
// variables for button - instead of bounce lib - save flash memory
//###############################################################################################################
const int DEBOUNCE_DELAY = 50; // the debounce time; increase if the output flickers
int lastSteadyState = LOW; // the previous steady state from the input pin
int lastFlickerableState = LOW; // the previous flickerable state from the input pin
int currentState; // the current reading from the input pin
unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
unsigned long lastPressedTime = 0;
//###############################################################################################################
//###############################################################################################################
// LCD - VSS - GND // VCC - 5V // RW - GND // K - GND
//###############################################################################################################
const byte rs = 12;
const byte en = 13;
const byte d4 = 9;
const byte d5 = 8;
const byte d6 = 7;
const byte d7 = 6;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
byte myLCDbacklight = 255;
byte myLCDcontrast = 100;
//###############################################################################################################
//###############################################################################################################
// variables to steer menu
//###############################################################################################################
byte myDisplayMode = 0;
const char *const menuTopic[] = {"DEC", "Align", "Target", "Region", "Const", "Brightness", "Contrast", "Sensors", "LX200"};
const byte menuTopic_size = sizeof(menuTopic) / sizeof(menuTopic[0]);
byte myMenuTopicNo = 0;
//###############################################################################################################
//###############################################################################################################
// definition of special / greek characters - for LCD 1602 chinese version - adapt to your LCD if needed
//###############################################################################################################
// used lcd is like this https://www.waveshare.com/datasheet/LCD_en_PDF/LCD1602.pdf (see 14. font table)
const char ch_deg = (char)(223); // degree symbol
const char ch_sigma = (char)(246); // uppercase Sigma
// greek alphabet 1-24 = α β γ δ ε ζ η θ ι κ λ μ ν ξ ο π ρ σ τ υ φ χ ψ ω
// maximum 8 custom characters
// γ
char ch_def_1 = 'g'; // for identificatrion & replacement
byte ch_custom_1[] = {
B00000,
B10011,
B10010,
B10010,
B01110,
B00100,
B00100,
B00100
};
// δ
char ch_def_2 = 'd';
byte ch_custom_2[] = {
B00110,
B01001,
B00100,
B01110,
B10001,
B10001,
B01110,
B00000
};
// ζ
char ch_def_3 = 'z';
byte ch_custom_3[] = {
B01111,
B00010,
B00100,
B01000,
B01000,
B01111,
B00001,
B00110
};
// λ
char ch_def_4 = 'l';
byte ch_custom_4[] = {
B01100,
B00100,
B00100,
B01010,
B01010,
B10001,
B10001,
B00000
};
// ξ
char ch_def_5 = 'x';
byte ch_custom_5[] = {
B11111,
B00100,
B01000,
B00111,
B01000,
B10000,
B11111,
B00010
};
// φ
char ch_def_6 = 'p';
byte ch_custom_6[] = {
B00000,
B10111,
B10101,
B10101,
B10101,
B01110,
B00100,
B00100
};
// ψ
char ch_def_7 = 's';
byte ch_custom_7[] = {
B00000,
B00100,
B10101,
B10101,
B10101,
B01110,
B00100,
B00100
};
// Δ
char ch_def_8 = 'D';
byte ch_custom_8[] = {
B00000,
B00100,
B01010,
B01010,
B10001,
B10001,
B11111,
B00000
};
// lookup table placeholder chars with greek symbols
struct greekSymbols {
char originalChar;
char replaceChar;
};
const unsigned int greekSymbols_size = 26;
const struct greekSymbols greekSymbols[greekSymbols_size] =
{
{'a', (char)(224)}, // α
{'b', (char)(226)}, // β
{'g', 'g'}, // γ custom character
{'d', 'd'}, // δ custom character
{'e', (char)(227)}, // ε
{'z', 'z'}, // ζ custom character
{'j', 'n'}, // η
{'h', (char)(242)}, // θ
{'i', 'l'}, // ι
{'k', 'k'}, // κ
{'l', 'l'}, // λ custom character
{'m', (char)(228)}, // μ
{'n', 'v'}, // ν
{'x', 'x'}, // ξ custom character
{'o', 'o'}, // ο
{'p', (char)(247)}, // π
{'r', (char)(230)}, // ρ
{'s', (char)(229)}, // σ
{'t', 't'}, // τ
{'y', (char)(232)}, // υ
{'q', 'p'}, // φ custom character
{'c', 'x'}, // χ
{'w', 's'}, // ψ custom character
{'u', 'w'},
{'F', (char)(246)}, // Σ
{'D', '/'} // Δ
};
//###############################################################################################################
//###############################################################################################################
// definition of constellation names
//###############################################################################################################
struct constStruct {
char constName[4];
};
constStruct myConstellation;
const unsigned int constStruct_size = 89;
const struct constStruct const_PROGMEM[constStruct_size] PROGMEM = {
{"all"}, {"And"}, {"Ant"}, {"Aps"}, {"Aql"}, {"Aqr"}, {"Ara"}, {"Ari"}, {"Aur"}, {"Boo"}, {"Cae"}, {"Cam"}, {"Cap"}, {"Car"}, {"Cas"}, {"Cen"}, {"Cep"}, {"Cet"}, {"Cha"}, {"Cir"},
{"CMa"}, {"CMi"}, {"Cnc"}, {"Col"}, {"Com"}, {"CrA"}, {"CrB"}, {"Crt"}, {"Cru"}, {"Crv"}, {"CVn"}, {"Cyg"}, {"Del"}, {"Dor"}, {"Dra"}, {"Equ"}, {"Eri"}, {"For"}, {"Gem"}, {"Gru"},
{"Her"}, {"Hor"}, {"Hya"}, {"Hyi"}, {"Ind"}, {"Lac"}, {"Leo"}, {"Lep"}, {"Lib"}, {"LMi"}, {"Lup"}, {"Lyn"}, {"Lyr"}, {"Men"}, {"Mic"}, {"Mon"}, {"Mus"}, {"Nor"}, {"Oct"}, {"Oph"},
{"Ori"}, {"Pav"}, {"Peg"}, {"Per"}, {"Phe"}, {"Pic"}, {"PsA"}, {"Psc"}, {"Pup"}, {"Pyx"}, {"Ret"}, {"Scl"}, {"Sco"}, {"Sct"}, {"Ser"}, {"Sex"}, {"Sge"}, {"Sgr"}, {"Tau"}, {"Tel"},
{"TrA"}, {"Tri"}, {"Tuc"}, {"UMa"}, {"UMi"}, {"Vel"}, {"Vir"}, {"Vol"}, {"Vul"}
};
byte myConstellationNo = 0;
String myConstellationName = "";
//###############################################################################################################
//###############################################################################################################
// object type name and variables for deep sky objects
//###############################################################################################################
const char* myObjectTypeName[] = {"Quasar", "Dark Nebula", "Galaxy", "Bright Neb", "Clust + Neb", "Planet Neb", "SN Rem", "Glob Cluster", "Open Cluster", "Double Star", "Red Star", "Reference", "any"};
unsigned int myRefNo = 0; // number of selected reference star
unsigned int myTargetNo = 0; // number of selected target
//###############################################################################################################
//###############################################################################################################
// definition of cellestial regions = constellations of seasons defined in groups (as in Deep Sky Atlas) to filter targets and reference stars
//###############################################################################################################
// constellation for which deep sky objects exist in the list 0 = all
const byte myAllCONST[] = {0, 1, 2, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 44, 45, 46, 47, 48, 49, 50, 51, 52, 54, 55, 57, 59, 60, 61, 62, 63, 64, 66, 67, 68, 69, 71, 72, 73, 74, 75, 76, 77, 78, 80, 81, 83, 84, 85, 86, 88};
const byte myAllCONST_size = sizeof(myAllCONST) / sizeof(myAllCONST[0]);
// North - UMI,UMA,DRA,CEP,CAS,CAM
const byte myNorthCONST[] = {84, 83, 34, 16, 14, 11};
const byte myNorthCONST_size = sizeof(myNorthCONST) / sizeof(myNorthCONST[0]);
// Spring - LEO,LMI,SEX,HYA,CVN,COM,VIR,CRT,CRV,BOO,CRB,SER
const byte mySpringCONST[] = {46, 49, 75, 42, 30, 24, 86, 27, 29, 9, 26, 74};
const byte mySpringCONST_size = sizeof(mySpringCONST) / sizeof(mySpringCONST[0]);
// Summer - HER,LYR,OPH,SCO,CYG,VUL,SGE,DEL,EQU,AQL,SCT,SER,SGR,CAP
const byte mySummerCONST[] = {40, 52, 59, 72, 31, 88, 76, 32, 35, 4, 73, 74, 77, 12};
const byte mySummerCONST_size = sizeof(mySummerCONST) / sizeof(mySummerCONST[0]);
// Autumn - LAC,PEG,AQR,PSA,AND,TRI,PER,ARI,PSC,CET,SCL,FOR,ERI
const byte myAutumnCONST[] = {45, 62, 5, 66, 1, 81, 63, 7, 67, 17, 71, 37, 36};
const byte myAutumnCONST_size = sizeof(myAutumnCONST) / sizeof(myAutumnCONST[0]);
// Winter - AUR,TAU,ORI,LEP,LYN,GEM,CMI,MON,CMA,PUP,CNC
const byte myWinterCONST[] = {8, 78, 60, 47, 51, 38, 21, 55, 20, 68, 22};
const byte myWinterCONST_size = sizeof(myWinterCONST) / sizeof(myWinterCONST[0]);
// South - ANT,VEL,CAR,VOL,CHA,MUS,CRU,CEN,CRU,TRA,LUP,NOR,ARA,SCO,SGR,CRA,TEL,MIC,IND,PAV,GRU,PHE,SCL,FOR,ERI,HOR,RET,HYI,TUC,DOR,CAE,COL,PUP,PYX,PIC,MEN,APS,OCT
const byte mySouthCONST[] = {2, 85, 13, 28, 15, 28, 80, 50, 57, 6, 72, 77, 25, 54, 44, 61, 39, 64, 71, 37, 36, 41, 33, 23, 68, 69, 65};
const byte mySouthCONST_size = sizeof(mySouthCONST) / sizeof(mySouthCONST[0]);
const char* myregionNAME[] = {"all", "North", "Spring", "Summer", "Autumn", "Winter", "South"}; // no south to save flash
const byte regionArraySize = sizeof(myregionNAME) / sizeof(myregionNAME[0]); // Anzahl der Einträge
byte myRegionNo = 0; // all - 0; North - 1; .... ; South - 6
String myregionName = "";
//###############################################################################################################
//###############################################################################################################
// variables for calculation of position // all positions are calculated in seconds
//###############################################################################################################
long myRefStartTimeSec = 0; // Startzeit beim Setzen des Referenzsterns in Sekunden
long myCurrentRAsec = 0; // meine aktuelle Rektaszension in Sekunden
long myCurrentDECsec = 0; // meine aktuelle Deklination in Sekunden
long myLastRAsec = 0; // meine letzte Rektaszension in Sekunden
long myLastDECsec = 0; // meine letzte Deklination in Sekunden
long myReferenceRAsec = 0; // meine Rektaszensionsreferenz in Sekunden
long myReferenceDECsec = 0; // meine Deklinationsreferenz in Sekunden
long mySensorRAsec = 0; // Sensorwert der Rektaszension in Sekunden
long mySensorDECsec = 0; // Sensorwert der Deklination in Sekunden
long myTargetRAsec = 0; // Rektaszension des Ziels in Sekunden
long myTargetDECsec = 0; // Deklination des Ziels in Sekunden
const int secPerStepRA = 86400L / IMPULSE24HRA; // defines how many seconds RA is changed per rotary step // (24h * 3600sec = 86400sec) / (1:139 * 20 impulse = 2780) --> 31,079 sec / i
const int secPerStepDEC = 1296000L / IMPULSE360DEGDEC; // defines how many seconds DEC is changed per rotary step // (360° * 3600sec = 1296000sec) / (1:96 * 20 impulse = 1920) / --> 675 sec / i
int myDirectionDEC = 1; // saves the value of the direction of the DEC axis, important if the telescope is turned over
//###############################################################################################################
//###############################################################################################################
// for rotary encoders
//###############################################################################################################
static uint8_t prevNextCode_ROT = 0;
static uint16_t store_ROT = 0;
static uint8_t prevNextCode_RA = 0;
static uint16_t store_RA = 0;
static uint8_t prevNextCode_DEC = 0;
static uint16_t store_DEC = 0;
static int8_t val_ROT, val_RA, val_DEC;
int myImpulseRA = 0, myImpulseDEC = 0;
int myLastImpulseRA = 0, myLastImpulseDEC = 0;
const int8_t enc_table[] = {0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0};
//###############################################################################################################
//###############################################################################################################
// variables for LX200
//###############################################################################################################
byte statusLX200 = 0; // 0 - BT switched off / 1 - BT switched on / 2 - connected via BT & LX200 (frequent connect to LX200)
byte statusLX200old = 0;
byte btStatus = 0; // 0 - off / 1 - on
unsigned long lastLX200Message = 0;
DSOstruct externalObject; // instance LX200 object
//###############################################################################################################
//###############################################################################################################
// setup
//###############################################################################################################
void setup()
{
// for LX200 protocol & debugging
Serial.begin (9600);
// while(!Serial); // attention - only for debugging when in use with IDE!
// Serial.println(F("started"));
getSettingsFromEeprom(); // load settings (brightness,contrast,...)
setReference(); // set reference object to saved values
setTarget(); // set target object to saved values
setupLCD();
createCustomCharacters();
setupRotaryEncoders();
initExternalObject();
}
// software reset https://www.instructables.com/two-ways-to-reset-arduino-in-software/
void(* resetFunc) (void) = 0;//declare reset function at address 0
void setupLCD()
{
lcd.begin(16, 2);
updateLCD();
pinMode(LCD_BACKLIGHT_PIN, OUTPUT);
analogWrite(LCD_CONTRAST_PIN, myLCDcontrast); //set contrast
}
//Creating custom characters in CG-RAM
void createCustomCharacters()
{
lcd.createChar(1 , ch_custom_1);
lcd.createChar(2 , ch_custom_2);
lcd.createChar(3 , ch_custom_3);
lcd.createChar(4 , ch_custom_4);
lcd.createChar(5 , ch_custom_5);
lcd.createChar(6 , ch_custom_6);
lcd.createChar(7 , ch_custom_7);
lcd.createChar(8 , ch_custom_8);
}
void setupRotaryEncoders()
{
// HMI rotary encoder button
pinMode(ROTARY_SW, INPUT_PULLUP);
// HMI rotary encoder
pinMode(ROTARY_CLK, INPUT);
pinMode(ROTARY_DT, INPUT);
// it is better to use the integrated pull-ups of KY-040 (this requires "+" to be connected to 5V) - https://forum.arduino.cc/index.php?topic=242356.0
// as analog pins are used for rotary encoders - internal pull-ups are additionally used to avoid akward behaviour if not connected to sensors
// RA rotary encoder
pinMode(SENS_RA_CLK, INPUT_PULLUP);
pinMode(SENS_RA_DT, INPUT_PULLUP);
// DEC rotary encoder
pinMode(SENS_DEC_CLK, INPUT_PULLUP);
pinMode(SENS_DEC_DT, INPUT_PULLUP);
// switch for BT module
pinMode(BT_SWITCH, OUTPUT);
}
// initialise external object struct for receiving via LX200
void initExternalObject()
{
externalObject.objectPreFixNameNo = 202; // is "external" in DSO PROGMEM
externalObject.objectNumber = 0; // empty - no number in name
externalObject.objectTypeMagnitude = 0;
externalObject.objectConst = 0; // "all" in constellations
externalObject.objectRA = 0;
externalObject.objectDEC = 0;
}
//###############################################################################################################
// \setup
//###############################################################################################################
//###############################################################################################################
// loop
//###############################################################################################################
void loop()
{
analogWrite(LCD_BACKLIGHT_PIN, myLCDbacklight); // LCD backlight analogWrite: values from 0 to 255
updateRotaryEncoderButton();
updateRotaryEncoders();
calcCurrentPosition();
if (myDisplayMode == 9) displaySensorValue();
if (myDisplayMode == 11) displayCurrPos();
if (myDisplayMode == 12) displayTargetPos();
if (myDisplayMode == 13) displayDiffTargetCurrPos();
// LX200 status
updateLX200Status();
readSendLX200();
}
//###############################################################################################################
// \loop
//###############################################################################################################
//###############################################################################################################
// read sensor values
//###############################################################################################################
// reads rotary encoders
void updateRotaryEncoders()
{
if (val_ROT = read_rotary_ROT()) switchSelection(val_ROT);
if (val_RA = read_rotary_RA())
{
mySensorRAsec = mySensorRAsec + val_RA * secPerStepRA;
myImpulseRA = myImpulseRA + val_RA; // for sensor test
}
if (val_DEC = read_rotary_DEC())
{
mySensorDECsec = mySensorDECsec + val_DEC * secPerStepDEC * myDirectionDEC;
myImpulseDEC = myImpulseDEC + val_DEC * myDirectionDEC; // for sensor test
}
}
// reads rotary encoder button
void updateRotaryEncoderButton()
{
// copy from https://arduinogetstarted.com/tutorials/arduino-button-debounce
currentState = digitalRead(ROTARY_SW);
if (currentState != lastFlickerableState)
{
lastDebounceTime = millis();
lastFlickerableState = currentState;
}
if ((millis() - lastDebounceTime) > DEBOUNCE_DELAY)
{
if (lastSteadyState == HIGH && currentState == LOW)
{
switchMode();
updateLCD();
lastPressedTime = millis();
}
else if (lastSteadyState == LOW && currentState == HIGH)
{
// if button pressed > 5 seconds -> reset
if (millis() - lastPressedTime > 5000) resetFunc(); // call reset
}
lastSteadyState = currentState;
}
}
// read rotary encoder for HMI
// robust rotary encoder reading https://www.best-microcontroller-projects.com/rotary-encoder.html
// A vald CW or CCW move returns 1,invalid returns 0.
int8_t read_rotary_ROT()
{
prevNextCode_ROT <<= 2;
if (digitalRead(ROTARY_DT)) prevNextCode_ROT |= 0x02;
if (digitalRead(ROTARY_CLK)) prevNextCode_ROT |= 0x01;
prevNextCode_ROT &= 0x0f;
// If valid then store as 16 bit data.
if (enc_table[prevNextCode_ROT] )
{
store_ROT <<= 4;
store_ROT |= prevNextCode_ROT;
if ((store_ROT & 0xff) == 0x2b) return -1;
if ((store_ROT & 0xff) == 0x17) return 1;
}
return 0;
}
// read rotary encoder for RA
int8_t read_rotary_RA()
{
prevNextCode_RA <<= 2;
if (digitalRead(SENS_RA_DT)) prevNextCode_RA |= 0x02;
if (digitalRead(SENS_RA_CLK)) prevNextCode_RA |= 0x01;
prevNextCode_RA &= 0x0f;
// If valid then store as 16 bit data.
if (enc_table[prevNextCode_RA] )
{
store_RA <<= 4;
store_RA |= prevNextCode_RA;
if ((store_RA & 0xff) == 0x2b) return -1;
if ((store_RA & 0xff) == 0x17) return 1;
}
return 0;
}
// read rotary encoder for DEC
int8_t read_rotary_DEC()
{
prevNextCode_DEC <<= 2;
if (digitalRead(SENS_DEC_DT)) prevNextCode_DEC |= 0x02;
if (digitalRead(SENS_DEC_CLK)) prevNextCode_DEC |= 0x01;
prevNextCode_DEC &= 0x0f;
// If valid then store as 16 bit data.
if (enc_table[prevNextCode_DEC] )
{
store_DEC <<= 4;
store_DEC |= prevNextCode_DEC;
if ((store_DEC & 0xff) == 0x2b) return -1;
if ((store_DEC & 0xff) == 0x17) return 1;
}
return 0;
}
//###############################################################################################################
// read sensor values
//###############################################################################################################
//###############################################################################################################
// get & set of object data
//###############################################################################################################
// returns the type as number of a deep sky object
byte getObjectType(byte typeMagnitude)
{
return (typeMagnitude / 14); // decoding of object type from typeMagnitude
}
// returns the type as string of a deep sky object
String getObjectTypeName(byte typeMagnitude)
{
return myObjectTypeName[(typeMagnitude / 14) - 1];
}
// returns the magnitude of a deep sky object
String getMagnitude(byte typeMagnitude) // calcs the right magnitude - here modulo 14 as coded
{
String strFlMag = (String)(typeMagnitude % 14) + "m";
return strFlMag;
}
// returns the name of a constellation as string from a lookup tabel according to its number
String getConstName(int no)
{
constStruct oneConstellation;
// copy constellations data from PROGMEM into oneConstellation according to no
memcpy_P (&oneConstellation, &const_PROGMEM[no], sizeof oneConstellation);
return (String)oneConstellation.constName;
}
// returns the current constellation for filtering
String getCurrentConstName()
{
String constellationName;
constellationName = getConstName(myConstellationNo);
return constellationName;
}
// returns the current cellestial region
String getSetregionName()
{
return myregionNAME[myRegionNo];
}
// set reference star
void setReference()
{
// copy reference data from PROGMEM into myReference according to myRefNo
memcpy_P (&myReference, &DSO_PROGMEM[myRefNo], sizeof myReference);
setReferenceRA_DEC();
}
// RA and DEC of selected target are set
void setReferenceRA_DEC()
{
// transfer RA / DEC into internal format (seconds)
myReferenceRAsec = calcRAsecFromRA(myReference.objectRA);
myReferenceDECsec = calcDECsecFromDEC(myReference.objectDEC);
}
// set target
void setTarget()
{
// copy reference data from PROGMEM into myTarget according to myTargetNo
memcpy_P (&myTarget, &DSO_PROGMEM[myTargetNo], sizeof myTarget);
setTargetRA_DEC();
}
// RA and DEC of selected target are set
void setTargetRA_DEC()
{
// transfer RA / DEC into internal format (seconds)
myTargetRAsec = calcRAsecFromRA(myTarget.objectRA);
myTargetDECsec = calcDECsecFromDEC(myTarget.objectDEC);
}
//###############################################################################################################
// \get & set of object data
//###############################################################################################################
//###############################################################################################################
// calculations and settings of positions
//###############################################################################################################
// calculation of RA seconds
unsigned int calcRAsecFromRA(unsigned int ra)
{
int h = ra / 1000;
int m = (ra - h * 1000) / 10;
int s = (ra - h * 1000 - m * 10) * 6;
unsigned int raSec = h * 3600L + m * 60 + s;
return raSec;
}
// calculation of DEC seconds
long calcDECsecFromDEC(int dec)
{
int deg = dec / 100;
int m = (dec - deg * 100);
long decSec = deg * 3600L + m * 60;
return decSec;
}
// calculation of current telescope position
void calcCurrentPosition()
{
myCurrentRAsec = myReferenceRAsec + myRefStartTimeSec + mySensorRAsec - millis() / 1000;
myCurrentDECsec = myReferenceDECsec + mySensorDECsec;
}
// sets the sensor values to zero - needed for alignment with reference star
void resetSensorTime()
{
mySensorRAsec = 0; // Sensorwert der Rektaszension
mySensorDECsec = 0; // Sensorwert der Deklination
myRefStartTimeSec = millis() / 1000;
}
//###############################################################################################################
// \calculations and settings of positions
//###############################################################################################################
//###############################################################################################################
// display information
//###############################################################################################################
// display the current position
void displayCurrPos()
{
if (myLastRAsec != myCurrentRAsec || myLastDECsec != myCurrentDECsec)
{
myLastRAsec = myCurrentRAsec;
myLastDECsec = myCurrentDECsec;
displayRA_DEC("Curr ", "Coord", myCurrentRAsec, myCurrentDECsec);
}
}
// display position of selected target
void displayTargetPos()
{
displayRA_DEC(getObjectName(myTarget.objectPreFixNameNo, myTarget.objectNumber, myTarget.objectConst), "Coord", myTargetRAsec, myTargetDECsec);
}
// calulation & display of difference between current position & target position
void displayDiffTargetCurrPos()
{
long diffRAsec = myTargetRAsec - myCurrentRAsec;
long diffDECsec = myTargetDECsec - myCurrentDECsec;
if (myLastRAsec != myCurrentRAsec || myLastDECsec != myCurrentDECsec) // only if position has changed
{
myLastRAsec = myCurrentRAsec;
myLastDECsec = myCurrentDECsec;
displayRA_DEC(getObjectName(myTarget.objectPreFixNameNo, myTarget.objectNumber, myTarget.objectConst), "Diff ", diffRAsec , diffDECsec);
}
}
// display of RA and DEC - generic use for reference stars & target
void displayRA_DEC(String text1, String text2, long rekSec, long dekSec)
{
// Rektaszension //
int sign = 1.0;
if (rekSec < 0) sign = -1.0;
byte s = (abs(rekSec)) % 60; // Das Zeichen: "%" ist der Modulo-Operator // vorher int
byte m = (abs(rekSec / 60)) % 60;
byte h = (abs(rekSec / 3600)) % 24;
lcd.setCursor(0, 0);
printObjectName(text1);
lcd.setCursor(8, 0);
if (sign < 0) lcd.print(F("-"));
else lcd.print(F("+"));
if (h < 10) lcd.print(F(" "));
lcd.print(h);
lcd.print(F(":"));
if (m < 10) lcd.print(F("0"));
lcd.print(m);
lcd.print(F(","));
lcd.print(s / 6);
// DEC // +90° - -90°
sign = 1.0;
if (dekSec < 0) sign = -1.0;
s = (abs(dekSec)) % 60; // Das Zeichen: "%" ist der Modulo-Operator
m = (abs(dekSec / 60)) % 60;
h = (abs(dekSec / 3600)) % 180;
lcd.setCursor(0, 1);
lcd.print(text2);
lcd.setCursor(8, 1);
if (sign < 0) lcd.print(F("-"));
else lcd.print(F("+"));
if (h < 10) lcd.print(F(" "));
lcd.print(h);
lcd.print(ch_deg);
if (m < 10) lcd.print(F("0"));
lcd.print(m);
lcd.print(F("'"));
}
// display current sensor values
void displaySensorValue()
{
if (myImpulseRA != myLastImpulseRA || myImpulseDEC != myLastImpulseDEC)
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Imp RA"));
lcd.setCursor(0, 1);
lcd.print(F("Imp DEC"));
lcd.setCursor(10, 0);
lcd.print(myImpulseRA);
lcd.setCursor(10, 1);
lcd.print(myImpulseDEC);
myLastImpulseRA = myImpulseRA;
myLastImpulseDEC = myImpulseDEC;
}
}
// update LCD according to selected display mode
void updateLCD()
{
lcd.clear();
lcd.setCursor(0, 0);
if (myDisplayMode == 0)
{
lcd.print(F("SpotNik v")); // DO NOT REMOVE
lcd.print(VERSION);
lcd.setCursor(0, 1);
lcd.print(F("developed by MR")); // DO NOT REMOVE
}
if (myDisplayMode == 1) // main menu
{
lcd.print(F(">"));
lcd.setCursor(1, 0);
lcd.print(menuTopic[myMenuTopicNo]); // {" reverse", "Ref","Target","region","Const","Bright","Contr","Test"};
lcd.setCursor(8, 0);
switch (myMenuTopicNo) {
case 0:
if (myDirectionDEC == 1) lcd.print(F("normal"));
else lcd.print(F("reverse"));
break;
case 1:
printObjectName(getObjectName(myReference.objectPreFixNameNo, myReference.objectNumber, myReference.objectConst));
break;
case 2:
printObjectName(getObjectName(myTarget.objectPreFixNameNo, myTarget.objectNumber, myTarget.objectConst));
//if (statusLX200 != 2) printObjectName(getObjectName(myTarget.objectPreFixNameNo,myTarget.objectNumber,myTarget.objectConst));
//else lcd.print(F("external")); // if connection to LX200 source - no usage of internal star database
break;
case 3:
lcd.print(getSetregionName());
// if (statusLX200 != 2) lcd.print(getSetregionName());
// else lcd.print(F("external"));
break;
case 4:
lcd.print(getCurrentConstName());
// if (statusLX200 != 2) lcd.print(getCurrentConstName());
// else lcd.print(F("external"));
break;
case 8:
if (statusLX200 == 0) lcd.print(F("BT off"));
if (statusLX200 == 1) lcd.print(F("BT on"));
if (statusLX200 == 2) lcd.print(F("conn"));
break;
}
lcd.setCursor(1, 1);
if (myMenuTopicNo + 1 < menuTopic_size)
{
lcd.print(menuTopic[myMenuTopicNo + 1]);
}
else
{
lcd.print(menuTopic[0]);
}
}
if (myDisplayMode == 2)
{
lcd.print(F("Direction of DEC"));
lcd.setCursor(0, 1);
lcd.print(F(">"));
if (myDirectionDEC == 1) lcd.print(F("normal"));
else lcd.print(F("reverse"));
}
if (myDisplayMode == 3)
{
printObjectName(getObjectName(myReference.objectPreFixNameNo, myReference.objectNumber, myReference.objectConst));
lcd.setCursor(13, 0);
lcd.print(getConstName(myReference.objectConst));
lcd.setCursor(0, 1);
lcd.print(getObjectTypeName(myReference.objectTypeMagnitude));
lcd.setCursor(13, 1);
lcd.print(getMagnitude(myReference.objectTypeMagnitude));
}
if (myDisplayMode == 4)
{
printObjectName(getObjectName(myTarget.objectPreFixNameNo, myTarget.objectNumber, myTarget.objectConst));
lcd.setCursor(13, 0);
lcd.print(getConstName(myTarget.objectConst));
lcd.setCursor(0, 1);
lcd.print(getObjectTypeName(myTarget.objectTypeMagnitude));
lcd.setCursor(13, 1);
lcd.print(getMagnitude(myTarget.objectTypeMagnitude));
}
if (myDisplayMode == 5)
{
lcd.print(F("Celestial Region"));
lcd.setCursor(0, 1);
lcd.print(F(">"));
lcd.print(getSetregionName());
}
if (myDisplayMode == 6)
{
lcd.print(F("Constellation"));
lcd.setCursor(11, 1);
lcd.print(getSetregionName());
lcd.setCursor(0, 1);
lcd.print(F(">"));
lcd.print(getCurrentConstName());
}
if (myDisplayMode == 7)
{
lcd.print(F("LCD Brightness"));
lcd.setCursor(0, 1);
lcd.print(F(">"));
lcd.print(myLCDbacklight);
}
if (myDisplayMode == 8)
{
lcd.print(F("LCD Contrast"));
lcd.setCursor(0, 1);
lcd.print(F(">"));
lcd.print(myLCDcontrast);
}
if (myDisplayMode == 9)
{
lcd.print(F("For test"));
lcd.setCursor(0, 1);
lcd.print(F("turn DEC / RA"));
myImpulseRA = 0;
myImpulseDEC = 0;
myLastImpulseRA = 0;
myLastImpulseDEC = 0;
}
if (myDisplayMode == 10)
{
lcd.print(F("LX200 Connection"));
lcd.setCursor(0, 1);
lcd.print(F(">"));
if (statusLX200 == 0) lcd.print(F("Bluetooth off"));
if (statusLX200 == 1) lcd.print(F("Bluetooth on"));
if (statusLX200 == 2) lcd.print(F("LX200 connected"));
}
}
// returns name of deep sky object based on coded name its number and its constellation
String getObjectName(byte objectprefixNameNo, unsigned int objectNumber, byte objectConst)
{
String objectName = "";
int indexOfHash = -1;
DSONameStruct oneDSONameStruct;
if (objectprefixNameNo > 0)
{
// get name accordng to name number from lookup table
memcpy_P (&oneDSONameStruct, &DSO_NAME_PROGMEM[objectprefixNameNo - 1], sizeof oneDSONameStruct);
objectName = oneDSONameStruct.objectName;
indexOfHash = objectName.indexOf('#');
if (indexOfHash > -1)
{
// replace char with greek char
String charToReplace = objectName.substring(indexOfHash + 1, indexOfHash + 2);
objectName = objectName.substring(0, indexOfHash) + objectName.substring(indexOfHash + 2); // delete # and next char from string
// loop over the greek symbols
for (int i; i < greekSymbols_size; i++)
{
if ((String)charToReplace == (String)greekSymbols[i].originalChar)
{
charToReplace = greekSymbols[i].replaceChar;
objectName = objectName + charToReplace;
break;
}
}
}
}
if (objectNumber > 0)
{
objectName = objectName + (String)objectNumber;
}
// if object is only number,greek Symbol or max. two characters,accept 'M' - add constellation for identification
if (objectName.charAt(1) == NULL || objectprefixNameNo == 0 || (objectName.charAt(2) == NULL && objectNumber == 0)) // oder nur Zahlen!!!
{
objectName = objectName + ' ' + getConstName(objectConst);
}
return objectName;
}
// some greek symbols are custom, print function needed
void printObjectName(String objectName)
{
byte customChar = 0;
char charAt0 = objectName.charAt(0);
if (charAt0 == ch_def_1) customChar = 1;
else if (charAt0 == ch_def_2) customChar = 2;
else if (charAt0 == ch_def_3) customChar = 3;
else if (charAt0 == ch_def_4) customChar = 4;
else if (charAt0 == ch_def_5) customChar = 5;
else if (charAt0 == ch_def_6) customChar = 6;
else if (charAt0 == ch_def_7) customChar = 7;
if (customChar > 0) lcd.write(customChar);
else
{
lcd.print(objectName);
return;
}
lcd.print(F(" "));
lcd.print(objectName.substring(2, 8));
}
//###############################################################################################################
// \display information
//###############################################################################################################
//###############################################################################################################
// switching
//###############################################################################################################
// myDisplayMode - rotary encoder for change
// 0 = welcome, 1 = top menu, 2 = change direction, 3 = set reference, 4 = set target, 5 = set region, 6 = set constellation, 7 = set LCD brightness, 8 = set LCD contrast
// 9 = sensor test, 10 = set bluetooth, 11 = show current position, 12 = show target position, 13 = show difference target - current position
void switchMode()
{
saveSettingsToEeprom(); // save settings to eeprom each time the button is pressed
if (myDisplayMode == 0) // welcome
{
myDisplayMode = 1; // top menue
}
else if (myDisplayMode == 1)
{
myDisplayMode = myMenuTopicNo + 2;
}
else if (myDisplayMode == 3) // set reference
{
resetSensorTime();
myLastDECsec = 0; // set once to zero to update display
myDisplayMode = 11; // show current position
}
else if (myDisplayMode == 4) // set target
{
setTargetRA_DEC();
myDisplayMode = 13; // show diff position
}
// set direction // region // constellation // set brightness // set contrast // sensor test // show current position // show diff position
else if (myDisplayMode == 2 || myDisplayMode >= 5)
{
myDisplayMode = 1; // return to top level menu
}
lcd.clear();
}
// function of rotary encoder changes acording to current display mode
void switchSelection(int dir)
{
if (myDisplayMode == 0)
{
myDisplayMode = 1;
updateLCD();
}
else if (myDisplayMode == 1) changeMenu(dir);
if (myDisplayMode == 2) changeDirectionDEC(dir);
if (myDisplayMode == 3) changeReference(dir);
if (myDisplayMode == 4) changeTarget(dir);
if (myDisplayMode == 5) changeregion(dir);
if (myDisplayMode == 6) changeConstellation(dir);
if (myDisplayMode == 7) changeLCDBacklight(dir);
if (myDisplayMode == 8) changeLCDcontrast(dir);
if (myDisplayMode == 10) changeBTconnection(dir);
if (myDisplayMode == 11 || myDisplayMode == 12 || myDisplayMode == 13) changeView(dir);
updateLCD();
}
// change menu topics
void changeMenu(int dir)
{
if (dir == 1)
{
if ((myMenuTopicNo + 1) < menuTopic_size)
{
myMenuTopicNo = myMenuTopicNo + 1;
}
else
{
myMenuTopicNo = 0;
}
}
else if (dir == -1)
{
if (myMenuTopicNo > 0)
{
myMenuTopicNo = myMenuTopicNo - 1;
}
else
{
myMenuTopicNo = menuTopic_size - 1;
}
}
}
// according to the direction of the DEC axis the value of the DEC sensor has to be reverted
void changeDirectionDEC(int dir)
{
if (dir == 1 || dir == -1)
{
if (myDirectionDEC == 1) myDirectionDEC = -1;
else myDirectionDEC = 1;
}
}
// calls changeObject for object type reference
void changeReference (int dir)
{
changeObject(dir, 'r');
}
// calls changeObject for object type target
void changeTarget(int dir)
{
changeObject(dir, 't');
}
// change referenc star including filter according to selected sky region
void changeObject (int dir, char objectType)
{
bool constFound = false;
DSOstruct oneObject; // instance of reference for search & filter
unsigned int objectNo;
unsigned int numberOfLoops = 0;
if (objectType == 'r')
{
objectNo = myRefNo; // set start no of object
}
else
{
objectNo = myTargetNo;
}
while (constFound == false)
{
if (dir == 1)
{
if ((objectNo + 1) < DSO_PROGMEM_size)
{
objectNo = objectNo + 1;
}
else
{
objectNo = 0;
}
}
if (dir == -1) // before else if - but what if no fitting star at beginning before rotary turning?
{
if (objectNo > 0)
{
objectNo = objectNo - 1;
}
else
{
objectNo = DSO_PROGMEM_size - 1;
}
}
memcpy_P (&oneObject, &DSO_PROGMEM[objectNo], sizeof oneObject); // get next DSO object from struct and copy it into oneObject
// filter on a constellation
// if a constellation is selected,object is a target and constellation of object fits to selected constellation
if (objectType == 't' && myConstellationNo > 0 && getObjectType(oneObject.objectTypeMagnitude) > 0 && getObjectType(oneObject.objectTypeMagnitude) < 12 && oneObject.objectConst == myConstellationNo)
{
constFound = true;
}
// filter on regions
else if ( (objectType == 'r' && getObjectType(oneObject.objectTypeMagnitude) == 12) || // reference stars // filter on objects of type "reference" = no 12
(myConstellationNo == 0 && objectType == 't' && getObjectType(oneObject.objectTypeMagnitude) > 0 && getObjectType(oneObject.objectTypeMagnitude) < 12)) // target objects
{
// filter targets by constellations of the selected region
// myregionNAME[]={"All","North","Spring","Summer","Autumn","Winter","South"};
if (myRegionNo == 1) // region = north
{
for (int i = 0; i < myNorthCONST_size; i++)
{
if (oneObject.objectConst == myNorthCONST[i])
{
constFound = true;
break;
}
}
}
else if (myRegionNo == 2) // region = spring
{
for (int i = 0; i < mySpringCONST_size; i++)
{
if (oneObject.objectConst == mySpringCONST[i])
{
constFound = true;
break;
}
}
}
else if (myRegionNo == 3) // region = summer
{
for (int i = 0; i < mySummerCONST_size; i++)
{
if (oneObject.objectConst == mySummerCONST[i])
{
constFound = true;
break;
}
}
}
else if (myRegionNo == 4) // region = autumn
{
for (int i = 0; i < myAutumnCONST_size; i++)
{
if (oneObject.objectConst == myAutumnCONST[i])
{
constFound = true;
break;
}
}
}
else if (myRegionNo == 5) // region = winter
{
for (int i = 0; i < myWinterCONST_size; i++)
{
if (oneObject.objectConst == myWinterCONST[i])
{
constFound = true;
break;
}
}
}
else if (myRegionNo == 6) // region = south
{
for (int i = 0; i < mySouthCONST_size; i++)
{
if (oneObject.objectConst == mySouthCONST[i])
{
constFound = true;
break;
}
}
}
else // all constellations
{
constFound = true;
}
}
}// end while
if (objectType == 'r')
{
myRefNo = objectNo;
myReference = oneObject; // copy selected reference object in my reference object
setReferenceRA_DEC();
}
else
{
myTargetNo = objectNo;
myTarget = oneObject; // copy selected target object in my target object
setTargetRA_DEC();
}
updateLCD();
}
// change region
void changeregion(int dir)
{
if (dir == 1)
{
if ((myRegionNo + 1) < regionArraySize) {
myRegionNo = myRegionNo + 1;
}
else {
myRegionNo = 0;
}
}
else if (dir == -1)
{
if (myRegionNo > 0) {
myRegionNo = myRegionNo - 1;
}
else {
myRegionNo = regionArraySize - 1;
}
}
myTargetNo = 0; // reset target,when aera has changed
myConstellationNo = 0; // reset constellation,when aera has changed
updateLCD();
}
// set constellation
void changeConstellation(int dir)
{
bool constFound = false;
while (constFound == false)
{
if (dir == 1)
{
if ((myConstellationNo) < constStruct_size - 1) {
myConstellationNo = myConstellationNo + 1;
}
else {
myConstellationNo = 0;
}
}
else if (dir == -1)
{
if (myConstellationNo > 0) {
myConstellationNo = myConstellationNo - 1;
}
else {
myConstellationNo = constStruct_size - 1;
}
}
// filter targets by constellations of the selected region
// myregionNAME[]={"All","North","Spring","Summer","Autumn","Winter","South"};
if (myRegionNo == 1) // region = north
{
for (int i = 0; i < myNorthCONST_size; i++)
{
if (myConstellationNo == myNorthCONST[i])
{
constFound = true;
break;
}
}
}
else if (myRegionNo == 2) // region = spring
{
for (int i = 0; i < mySpringCONST_size; i++)
{
if (myConstellationNo == mySpringCONST[i])
{
constFound = true;
break;
}
}
}
else if (myRegionNo == 3) // region = summer
{
for (int i = 0; i < mySummerCONST_size; i++)
{
if (myConstellationNo == mySummerCONST[i])
{
constFound = true;
break;
}
}
}
else if (myRegionNo == 4) // region = autumn
{
for (int i = 0; i < myAutumnCONST_size; i++)
{
if (myConstellationNo == myAutumnCONST[i])
{
constFound = true;
break;
}
}
}
else if (myRegionNo == 5) // region = winter
{
for (int i = 0; i < myWinterCONST_size; i++)
{
if (myConstellationNo == myWinterCONST[i])
{
constFound = true;
break;
}
}
}
else if (myRegionNo == 6) // region = south
{
for (int i = 0; i < mySouthCONST_size; i++)
{
if (myConstellationNo == mySouthCONST[i])
{
constFound = true;
break;
}
}
}
else // all constellations
{
for (int i = 0; i < myAllCONST_size; i++)
{
if (myConstellationNo == myAllCONST[i])
{
constFound = true;
break;
}
}
}
}
myTargetNo = 0; // reset target every time when constellation was changed
updateLCD();
}
// switch view between current position, diff position & target coordinates
void changeView(int dir)
{
lcd.clear();
myDisplayMode = myDisplayMode + dir;
if (myDisplayMode > 13) myDisplayMode = 11;
if (myDisplayMode < 11) myDisplayMode = 13;
}
// set LCD brightness
void changeLCDBacklight(int dir)
{
myLCDbacklight = myLCDbacklight + dir * 8;
if (myLCDbacklight > 255) myLCDbacklight = 0;
if (myLCDbacklight < 0) myLCDbacklight = 255;
}
// set LCD contrast
void changeLCDcontrast(int dir)
{
myLCDcontrast = myLCDcontrast + dir * 5;
if (myLCDcontrast > 255) myLCDcontrast = 0;
if (myLCDcontrast < 0) myLCDcontrast = 255;
analogWrite(LCD_CONTRAST_PIN, myLCDcontrast);
}
// 0 - BT switched off / 1 - BT switched on
void changeBTconnection(int dir)
{
if (btStatus == 0) // switch BT on if off
{
btStatus = 1;
statusLX200 = 1;
digitalWrite(BT_SWITCH, HIGH);
}
else if (btStatus != 0) // switch BT off
{
btStatus = 0;
statusLX200 = 0;
digitalWrite(BT_SWITCH, LOW);
}
updateLCD();
}
//###############################################################################################################
// \switching
//###############################################################################################################
//###############################################################################################################
// LX200 communication
//###############################################################################################################
// set the status of LX200 to control LCD etc
void updateLX200Status()
{
// 0 - BT switched off / 1 - BT switched on
if (btStatus == 1)
{
// if frequent feedback from LX200 - last request > 4 sek
if ((millis() - lastLX200Message) > 4000)
{
statusLX200 = 1; // BT on - but no LX200 connection
}
else
{
statusLX200 = 2; // LX200 connected
}
}
// LX200 status changend - update lcd in relevant views (main menu & BT)
if (statusLX200 != statusLX200old && (myDisplayMode == 10 || myDisplayMode == 1))
{
updateLCD();
statusLX200old = statusLX200;
}
}
// called if a LX200 message was received
void receivedLX200message() // received
{
lastLX200Message = millis();
}
// read the bluetooth message and trigger functions according to message type
void readSendLX200()
{
if (Serial.available())
{
char message[14] = "";
byte i = 0;
while (Serial.available() > 0)
{
char a = Serial.read(); // Stores current byte
message[i] += a; // Append current byte to message String
delay(10);
i++;
}
// all LX200 info from https://www.meade.com/support/TelescopeProtocol_2010-10.pdf
// LX200 message :GR#
// Get Telescope RA
// Returns: HH:MM.T# or HH:MM:SS#Depending which precision is set for the telescope
if (message[0] == ':' && message[1] == 'G' && message[2] == 'R' && message[3] == '#')
{
receivedLX200message();
sendLX200RA();
}
// LX200 message :GD# or :RS#:GD# or :RM#:GD#
// Get Telescope Declination.
// Returns: sDD*MM# or sDD*MM’SS#Depending upon the current precision setting for the telescope.
if (message[0] == ':' && message[1] == 'G' && message[2] == 'D' && message[3] == '#' ||
message[4] == ':' && message[5] == 'G' && message[6] == 'D' && message[7] == '#')
{
receivedLX200message();
sendLX200DEC();
}
// LX200 message :CM#
// Synchronizes the telescope's position with the currently selected database object's coordinates.
// Returns:LX200's - a "#" terminated string with the name of the object that was synced
if (message[0] == ':' && message[1] == 'C' && message[2] == 'M')
{
receivedLX200message();
Serial.print("#");
}
// LX200 message :SrHH:MM.T# or :SrHH:MM:SS#
// Set target object RA to HH:MM.T or HH:MM:SS depending on the current precision setting.
// Returns:0 – Invalid1 - Valid
// output HHMM(S/6)
if (message[0] == ':' && message[1] == 'S' && message[2] == 'r')
{
setRAtoLX200message(message);
}
// LX200 message :SdsDD*MM#
// Set target object declination to sDD*MM or sDD*MM:SS depending on the current precision setting
// Returns:1 - Dec Accepted0 – Dec invalid
// output sHHMM
if (message[0] == ':' && message[1] == 'S' && message[2] == 'd')
{
setDECtoLX200message(message);
}
// Serial.print("BT message "); // for debugging
// Serial.println(message);
}
}
// set RA coordinates of placeholder externalobject to received LX200 message
void setRAtoLX200message(char message[10])
{
externalObject.objectRA =
long(atoi(message + 3)) * 1000 + // HH // access at array different when using atoi - use address
long(atoi(message + 6)) * 10; // MM - Minuten passen noch nicht bei zweistelligen gibt es Fehler
if (message[8] == ':') // : or .
{
externalObject.objectRA = externalObject.objectRA +
long(atoi(message + 9)) / 6; // SS/6
}
else if (message[8] == '.')
{
externalObject.objectRA = externalObject.objectRA + atoi(message + 9); // T
}
Serial.println(); // leave this command, as otherwise no update on goto from LX200 source
}
// set DEC coordinates of placeholder externalobject to received LX200 message & update the (reference or target) object
void setDECtoLX200message(char message[9])
{
int sign;
if (message[3] == '-') sign = -1;
else sign = 1;
externalObject.objectDEC =
sign * ( // s
long(atoi(message + 4)) * 100 + // DD
long(atoi(message + 7))); // MM
// assumption - first RA then DEC - then set target to external object
if (myDisplayMode == 3 || myDisplayMode == 11) // if view shows reference selection or current position then copy external object into reference object
{
externalObject.objectTypeMagnitude = 168;
myReference = externalObject; // copy external object to my reference object
setReferenceRA_DEC();
resetSensorTime();
}
else // in all other cases copy to target
{
externalObject.objectTypeMagnitude = 182;
myTarget = externalObject; // copy external object to my target object
setTargetRA_DEC();
}
updateLCD();
}
// send current RA coordinate of telescope from SpotNik to LX200 server (e.g. Sky Safari)
void sendLX200RA()
{
byte s = (abs(myCurrentRAsec)) % 60; // Das Zeichen: "%" ist der Modulo-Operator
byte m = (abs(myCurrentRAsec / 60)) % 60;
byte h = (abs(myCurrentRAsec / 3600)) % 24;
String posString = "";
if (h < 10) posString = "0";
posString = posString + String(h);
posString = posString + ":";
if (m < 10) posString = posString + "0";
posString = posString + String(m);
posString = posString + ":";
if (s < 10) posString = posString + "0";
posString = posString + String(s);
posString = posString + "#";
Serial.print(posString);
}
// send current DEC coordinate of telescope from SpotNik to LX200 server (e.g. Sky Safari)
void sendLX200DEC()
{
byte s = (abs(myCurrentDECsec)) % 60; // Das Zeichen: "%" ist der Modulo-Operator
byte m = (abs(myCurrentDECsec / 60)) % 60;
byte h = (abs(myCurrentDECsec / 3600)) % 180;
String posString = "";
if (myCurrentDECsec > 0) posString = "+";
else posString = "-";
if (h < 10) posString = "0";
posString = posString + String(h);
posString = posString + "*";
if (m < 10) posString = posString + "0";
posString = posString + String(m);
posString = posString + "#";
Serial.print(posString);
}
//###############################################################################################################
// \LX200 communication
//###############################################################################################################
//###############################################################################################################
// EEPROM
//###############################################################################################################
// save relevant data for next startup (e.g. target no,LCD brightness)
void saveSettingsToEeprom()
{
// Serial.print(F("freeMemory()=")); //only used for testing
// Serial.println(freeMemory());
byte addr = EEPROM_VALUE_ADDR_SIGNATURE;
byte myTargetNoLowByte = lowByte(myTargetNo); // myTargetNo is of type int - transfer into two bytes
byte myTargetNoHighByte = highByte(myTargetNo);
byte myReferenceNoLowByte = lowByte(myRefNo); // myTargetNo is of type int - transfer into two bytes
byte myReferenceNoHighByte = highByte(myRefNo);
EEPROM.update(addr, EEPROM_SIGNATURE); // use update for longer eeprom life
addr += sizeof(EEPROM_SIGNATURE);
EEPROM.update(addr, myReferenceNoLowByte);
addr += sizeof(myReferenceNoLowByte);
EEPROM.update(addr, myReferenceNoHighByte);
addr += sizeof(myReferenceNoHighByte);
EEPROM.update(addr, myTargetNoLowByte);
addr += sizeof(myTargetNoLowByte);
EEPROM.update(addr, myTargetNoHighByte);
addr += sizeof(myTargetNoHighByte);
EEPROM.update(addr, myRegionNo);
addr += sizeof(myRegionNo);
EEPROM.update(addr, myConstellationNo);
addr += sizeof(myConstellationNo);
EEPROM.update(addr, myLCDbacklight);
addr += sizeof(myLCDbacklight);
EEPROM.update(addr, myLCDcontrast);
}
// load relevant data at startup (e.g. target no, LCD brightness)
void getSettingsFromEeprom()
{
byte addr = EEPROM_VALUE_ADDR_SIGNATURE, signature = 0, value, myReferenceNoLowByte, myReferenceNoHighByte, myTargetNoLowByte, myTargetNoHighByte; // myTargetNo is of type int,need to concatenated from two bytes
EEPROM.get(addr, signature);
if (signature != EEPROM_SIGNATURE) return; // maybe data from another sketch
addr += sizeof(EEPROM_SIGNATURE);
EEPROM.get(addr, value);
myReferenceNoLowByte = value;
addr += sizeof(myReferenceNoLowByte);
EEPROM.get(addr, value);
myReferenceNoHighByte = value;
if (value >= 0 && value <= 32767) myRefNo = word(myReferenceNoHighByte, myReferenceNoLowByte);
addr += sizeof(myReferenceNoHighByte);
EEPROM.get(addr, value);
myTargetNoLowByte = value;
addr += sizeof(myTargetNoLowByte);
EEPROM.get(addr, value);
myTargetNoHighByte = value;
if (value >= 0 && value <= 32767) myTargetNo = word(myTargetNoHighByte, myTargetNoLowByte);
addr += sizeof(myTargetNoHighByte);
EEPROM.get(addr, value);
if (value >= 0 && value <= 255) myRegionNo = value;
addr += sizeof(myRegionNo);
EEPROM.get(addr, value);
if (value >= 0 && value <= 255) myConstellationNo = value;
addr += sizeof(myConstellationNo);
EEPROM.get(addr, value);
if (value >= 0 && value <= 255) myLCDbacklight = value;
addr += sizeof(myLCDbacklight);
EEPROM.get(addr, value);
if (value >= 0 && value <= 255) myLCDcontrast = value;
}
//###############################################################################################################
// \EEPROM
//###############################################################################################################
Hi there, I don't really understand how to program so can't speak the technical language your probably quite used to using especially as I'm an absolute beginner?novice......I'll send you the code and the Error messages to see if you can see anything. Here's the Very Long code.......
void setup() {
// put your setup code here, to run once:
/* ///////////////////////////////////////////////////////////////////////////////////
SpotNik - by Max Reinecke
Created: May 2021
SpotNik is software for a stepto system for telescopes
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
/////////////////////////////////////////////////////////////////////////////////*/
#define VERSION 2.0
//###############################################################################################################
// to be changed by user according to EQ mount - see instructions
// total numbers of impulse of the rotary encoder of RA axis when turned 24h
#define IMPULSE24HRA 2772 // 6h - 690 Impulse --> 24h - 4 * 693 = 2772 / ~ 1:138
// total numbers of impulse of the rotary encoder of DEC axis when turned 360° // +/- for correct direction
#define IMPULSE360DEGDEC 1784 // 90° - 446 Impulse --> 360° - 4 * 446 = 1784 / ~ 1:88
//###############################################################################################################
#include <LiquidCrystal.h> // I2C LCD arbeitet nicht vernünftig mit Rotary Encoder zusammen,daher normales nehmen
#include <EEPROM.h>
//#include <MemoryFree.h> // only used for testing
//###############################################################################################################
// LCD
#define LCD_CONTRAST_PIN 11 // LCD contrast - V0 // use high frequency PWM to avoid flickering (Leonardo,Micro,Yún 3 and 11: 980 Hz // Mega pins 4 and 13: 980 Hz)
#define LCD_BACKLIGHT_PIN 10 // LCD backlight - LCD A
// EEPROM
#define EEPROM_SIGNATURE 117 // value 0-255 (byte) - signature/mark to recognize if the value fits to this sketch
#define EEPROM_VALUE_ADDR_SIGNATURE 0
// rotary enoder HMI
#define ROTARY_SW 3 // use interrupt pin - digital pins for interrupts on Micro,Leonardo and other 32u4 based 0,1,2,3,7
#define ROTARY_DT 4
#define ROTARY_CLK 5
// Sensor RA
#define SENS_RA_DT A0 // analog pins used as UNO has not that many digital pins
#define SENS_RA_CLK A1
// Sensor DEC
#define SENS_DEC_DT A2
#define SENS_DEC_CLK A3
// LX200 connection
#define BT_SWITCH 2
//###############################################################################################################
// lookup table with names of deep sky objects
//###############################################################################################################
struct DSONameStruct
{
char objectName[9];
};
const struct DSONameStruct DSO_NAME_PROGMEM[202] PROGMEM =
{
{"3C273"},
{"B"},
{"IC"},
{"M"},
{"NGC"},
{"#a"},
{"#aA"},
{"#aB"},
{"#b"},
{"#c"},
{"#d"},
{"#e"},
{"#e1"},
{"#e2"},
{"#g"},
{"#h"},
{"#i"},
{"#j"},
{"#k"},
{"#l"},
{"#m"},
{"#n"},
{"#o"},
{"#p"},
{"#q"},
{"#r"},
{"#s"},
{"#t"},
{"#u"},
{"#w"},
{"#x"},
{"#z"},
{"AC"},
{"Achernar"},
{"Acrab"},
{"Acrux"},
{"Adhara"},
{"Agena"},
{"Alamak"},
{"Aldebara"},
{"Alderami"},
{"AlDhanab"},
{"Algenib"},
{"Algieba"},
{"Algol"},
{"Alhena"},
{"Alioth"},
{"Alkaid"},
{"AlNair"},
{"Alnilam"},
{"Alnitak"},
{"Alphard"},
{"Alphecca"},
{"Alpherat"},
{"Alsuhail"},
{"Altair"},
{"Aludra"},
{"Ankaa"},
{"Antares"},
{"AQ"},
{"Arcturus"},
{"Arneb"},
{"Aspidisk"},
{"Atria"},
{"Avior"},
{"AW"},
{"AX"},
{"BD"},
{"Becrux"},
{"Bellatri"},
{"Betelgeu"},
{"BF"},
{"BG"},
{"BL"},
{"BM"},
{"BX"},
{"Canopus"},
{"Capella"},
{"Caph"},
{"Castor"},
{"Cih"},
{"CY"},
{"Deneb"},
{"DenebKai"},
{"Denebola"},
{"Diphda"},
{"DR"},
{"Dschubba"},
{"Dubhe"},
{"EL"},
{"ElNath"},
{"Eltanin"},
{"Enif"},
{"FO"},
{"Fomalhau"},
{"FU"},
{"Gacrux"},
{"Gemma"},
{"Gienah"},
{"Girtab"},
{"GK"},
{"GY"},
{"H"},
{"Hadar"},
{"Hamal"},
{"Han"},
{"HD"},
{"HJ"},
{"HK"},
{"HN"},
{"Izar"},
{"JC"},
{"KausAust"},
{"Kochab"},
{"KooShe"},
{"Markab"},
{"Menkalin"},
{"Menkar"},
{"Menkent"},
{"Merak"},
{"Miaplaci"},
{"Mimosa"},
{"Mintaka"},
{"Mirach"},
{"Mirfak"},
{"Mirzam"},
{"Mizar"},
{"Naos"},
{"NQ"},
{"NSV"},
{"Nunki"},
{"O#F"},
{"Peacock"},
{"Phecda"},
{"Polaris"},
{"Pollux"},
{"Procyon"},
{"PZ6"},
{"R"},
{"RasAlhag"},
{"Regulus"},
{"Rigel"},
{"RigilKen"},
{"RR"},
{"RS"},
{"RT"},
{"RU"},
{"RV"},
{"RX"},
{"RY"},
{"RZ"},
{"S"},
{"S605"},
{"Sabik"},
{"Sadr"},
{"Saiph"},
{"SAO"},
{"Sargas"},
{"Scheat"},
{"Schedar"},
{"Shaula"},
{"SHJ"},
{"Sirius"},
{"Spica"},
{"SS"},
{"ST"},
{"SU"},
{"SV"},
{"SY"},
{"SZ"},
{"T"},
{"TT"},
{"TU"},
{"Tureis"},
{"TW"},
{"TX"},
{"U"},
{"UU"},
{"UV"},
{"UX"},
{"UY"},
{"V"},
{"Vega"},
{"VW"},
{"VX"},
{"VY"},
{"W"},
{"Wei"},
{"Wezen"},
{"WO"},
{"WW"},
{"WX"},
{"WZ"},
{"X"},
{"XS"},
{"XX"},
{"Y"},
{"Z"},
{"Zozma"},
{"β648"},
{"#F"},
{"extern"}
};
//###############################################################################################################
//###############################################################################################################
// data of deep sky objects
//###############################################################################################################
struct DSOstruct
{
byte objectPreFixNameNo; // number of name for lookup table
unsigned int objectNumber; // if name contains a number
byte objectTypeMagnitude; // object type & magnitude coded in one byte
byte objectConst; // constellation of object
unsigned int objectRA; //HHMM(SS/6)
int objectDEC; //sHHMM
};
DSOstruct myTarget; // object to store data of selected target
DSOstruct myReference; // object to store data of selected target
const unsigned int DSO_PROGMEM_size = 1204;
const struct DSOstruct DSO_PROGMEM[DSO_PROGMEM_size] PROGMEM =
{
{1, 0, 27, 86, 12291, 203},
{2, 33, 42, 60, 5409, -228},
{2, 65, 42, 77, 18027, -2750},
{2, 86, 42, 59, 17196, -2642},
{3, 342, 54, 11, 3468, 6806},
{3, 405, 66, 8, 5165, 3421},
{3, 410, 64, 8, 5227, 3325},
{3, 434, 67, 60, 5410, -227},
{3, 1396, 74, 16, 21391, 5730},
{3, 4406, 95, 50, 14224, -4409},
{3, 5067, 64, 31, 20508, 4421},
{3, 5146, 80, 31, 21534, 4716},
{4, 1, 106, 78, 5345, 2201},
{4, 2, 119, 5, 21335, -49},
{4, 3, 118, 30, 13422, 2823},
{4, 4, 117, 72, 16236, -2632},
{4, 5, 118, 74, 15186, 205},
{4, 6, 130, 72, 17403, -3215},
{4, 7, 129, 72, 17539, -3448},
{4, 8, 75, 77, 18037, -2423},
{4, 9, 120, 59, 17192, -1831},
{4, 10, 119, 59, 16571, -406},
{4, 11, 132, 73, 18511, -616},
{4, 12, 118, 59, 16472, -157},
{4, 13, 118, 40, 16417, 3628},
{4, 14, 120, 59, 17376, -315},
{4, 15, 118, 62, 21300, 1210},
{4, 16, 76, 74, 18188, -1347},
{4, 17, 76, 77, 18208, -1611},
{4, 18, 133, 77, 18199, -1708},
{4, 19, 119, 59, 17026, -2616},
{4, 20, 76, 77, 18027, -2258},
{4, 21, 132, 77, 18042, -2229},
{4, 22, 117, 77, 18364, -2354},
{4, 23, 132, 77, 17571, -1859},
{4, 24, 129, 77, 18266, -1823},
{4, 25, 131, 77, 18318, -1907},
{4, 26, 134, 73, 18452, -924},
{4, 27, 91, 88, 19596, 2243},
{4, 28, 119, 77, 18245, -2452},
{4, 29, 133, 31, 20239, 3832},
{4, 30, 119, 12, 21404, -2311},
{4, 31, 45, 1, 427, 4116},
{4, 32, 50, 1, 427, 4052},
{4, 33, 48, 81, 1339, 3039},
{4, 34, 131, 63, 2421, 4247},
{4, 35, 131, 38, 6089, 2421},
{4, 36, 132, 8, 5363, 3408},
{4, 37, 132, 8, 5523, 3233},
{4, 38, 132, 8, 5287, 3551},
{4, 39, 131, 31, 21322, 4826},
{4, 40, 149, 83, 12219, 5806},
{4, 41, 131, 20, 6460, -2045},
{4, 42, 74, 60, 5353, -523},
{4, 43, 63, 60, 5355, -516},
{4, 44, 129, 22, 8400, 1940},
{4, 45, 71, 78, 3470, 2407},
{4, 46, 132, 68, 7418, -1449},
{4, 47, 130, 68, 7366, -1429},
{4, 48, 132, 42, 8137, -545},
{4, 49, 50, 86, 12298, 800},
{4, 50, 132, 55, 7025, -823},
{4, 51, 50, 30, 13299, 4712},
{4, 52, 133, 14, 23242, 6135},
{4, 53, 120, 24, 13129, 1810},
{4, 54, 120, 77, 18551, -3029},
{4, 55, 118, 77, 19400, -3058},
{4, 56, 120, 52, 19166, 3011},
{4, 57, 93, 52, 18536, 3302},
{4, 58, 52, 86, 12377, 1149},
{4, 59, 52, 86, 12420, 1139},
{4, 60, 51, 86, 12437, 1133},
{4, 61, 52, 86, 12219, 428},
{4, 62, 118, 59, 17012, -3007},
{4, 63, 51, 30, 13158, 4202},
{4, 64, 51, 24, 12567, 2141},
{4, 65, 51, 46, 11189, 1305},
{4, 66, 51, 46, 11202, 1300},
{4, 67, 133, 22, 8508, 1149},
{4, 68, 119, 42, 12395, -2645},
{4, 69, 120, 77, 18314, -3221},
{4, 70, 120, 77, 18432, -3218},
{4, 71, 120, 76, 19538, 1847},
{4, 72, 121, 5, 20535, -1232},
{4, 73, 136, 5, 20590, -1238},
{4, 74, 51, 67, 1367, 1547},
{4, 75, 121, 77, 20061, -2155},
{4, 76, 94, 63, 1423, 5135},
{4, 77, 51, 17, 2427, -1},
{4, 78, 64, 60, 5468, 5},
{4, 79, 120, 47, 5242, -2431},
{4, 80, 119, 72, 16170, -2259},
{4, 81, 49, 83, 9556, 6904},
{4, 82, 50, 83, 9559, 6941},
{4, 83, 50, 42, 13370, -2952},
{4, 84, 51, 86, 12251, 1253},
{4, 85, 51, 24, 12254, 1811},
{4, 86, 51, 86, 12262, 1257},
{4, 87, 51, 86, 12308, 1223},
{4, 88, 52, 24, 12320, 1425},
{4, 89, 52, 86, 12357, 1233},
{4, 90, 52, 86, 12368, 1310},
{4, 91, 52, 24, 12354, 1430},
{4, 92, 119, 40, 17171, 4308},
{4, 93, 132, 68, 7445, -2351},
{4, 94, 50, 30, 12509, 4107},
{4, 95, 52, 46, 10440, 1142},
{4, 96, 51, 46, 10468, 1149},
{4, 97, 95, 83, 11148, 5501},
{4, 98, 52, 24, 12138, 1454},
{4, 99, 52, 24, 12188, 1425},
{4, 100, 51, 24, 12229, 1549},
{4, 101, 50, 83, 14032, 5421},
{4, 102, 52, 34, 15065, 5546},
{4, 103, 133, 14, 1334, 6039},
{4, 104, 50, 86, 12400, -1137},
{4, 105, 51, 46, 10478, 1235},
{4, 106, 50, 30, 12190, 4718},
{4, 107, 120, 59, 16325, -1303},
{4, 108, 52, 83, 11115, 5540},
{4, 109, 52, 83, 11576, 5322},
{4, 110, 50, 1, 404, 4141},
{5, 40, 94, 16, 130, 7231},
{5, 55, 50, 71, 149, -3911},
{5, 129, 133, 14, 300, 6013},
{5, 136, 137, 14, 315, 6131},
{5, 147, 52, 14, 332, 4830},
{5, 157, 52, 17, 348, -824},
{5, 185, 51, 14, 390, 4820},
{5, 188, 134, 16, 475, 8514},
{5, 210, 52, 17, 406, -1352},
{5, 225, 133, 14, 436, 6146},
{5, 246, 94, 17, 471, -1152},
{5, 247, 51, 17, 471, -2046},
{5, 253, 49, 71, 476, -2518},
{5, 278, 52, 14, 521, 4733},
{5, 281, 77, 14, 530, 5637},
{5, 288, 120, 71, 528, -2635},
{5, 300, 50, 71, 549, -3741},
{5, 381, 135, 14, 1084, 6135},
{5, 404, 52, 1, 1094, 3543},
{5, 436, 135, 14, 1160, 5849},
{5, 457, 132, 14, 1195, 5817},
{5, 488, 52, 67, 1218, 515},
{5, 524, 52, 67, 1248, 932},
{5, 559, 136, 14, 1295, 6319},
{5, 584, 52, 17, 1313, -652},
{5, 596, 52, 17, 1329, -702},
{5, 613, 52, 71, 1343, -2925},
{5, 615, 53, 17, 1351, -720},
{5, 637, 134, 14, 1431, 6402},
{5, 654, 133, 14, 1440, 6153},
{5, 659, 134, 14, 1444, 6040},
{5, 663, 133, 14, 1460, 6115},
{5, 672, 52, 81, 1479, 2726},
{5, 720, 52, 17, 1530, -1344},
{5, 752, 132, 1, 1577, 3740},
{5, 772, 52, 7, 1593, 1900},
{5, 779, 53, 17, 1597, -558},
{5, 869, 131, 63, 2191, 5708},
{5, 884, 132, 63, 2225, 5709},
{5, 891, 52, 1, 2226, 4221},
{5, 908, 52, 17, 2231, -2114},
{5, 925, 52, 81, 2273, 3335},
{5, 936, 52, 17, 2276, -109},
{5, 986, 52, 37, 2336, -3903},
{5, 1022, 53, 17, 2385, -641},
{5, 1023, 51, 63, 2404, 3904},
{5, 1027, 133, 14, 2426, 6136},
{5, 1052, 52, 17, 2411, -815},
{5, 1055, 52, 17, 2418, 27},
{5, 1084, 52, 36, 2460, -735},
{5, 1097, 52, 37, 2463, -3017},
{5, 1232, 52, 36, 3098, -2035},
{5, 1245, 134, 63, 3147, 4714},
{5, 1261, 120, 41, 3123, -5513},
{5, 1275, 53, 63, 3198, 4131},
{5, 1291, 51, 36, 3173, -4106},
{5, 1300, 52, 36, 3197, -1925},
{5, 1316, 51, 37, 3227, -3713},
{5, 1325, 53, 36, 3244, -2133},
{5, 1332, 52, 36, 3263, -2120},
{5, 1342, 133, 63, 3317, 3722},
{5, 1360, 93, 37, 3332, -2552},
{5, 1365, 52, 37, 3336, -3608},
{5, 1374, 53, 37, 3353, -3514},
{5, 1380, 54, 37, 3368, -3444},
{5, 1398, 52, 37, 3389, -2620},
{5, 1399, 52, 37, 3385, -3527},
{5, 1407, 52, 36, 3402, -1835},
{5, 1433, 52, 41, 3420, -4713},
{5, 1444, 133, 63, 3494, 5240},
{5, 1491, 70, 63, 4032, 5119},
{5, 1499, 61, 63, 4032, 3622},
{5, 1501, 96, 11, 4070, 6055},
{5, 1502, 133, 11, 4078, 6220},
{5, 1513, 134, 63, 4099, 4931},
{5, 1514, 94, 78, 4093, 3047},
{5, 1528, 132, 63, 4153, 5113},
{5, 1532, 52, 36, 4121, -3252},
{5, 1535, 93, 36, 4143, -1244},
{5, 1545, 132, 63, 4209, 5015},
{5, 1549, 52, 33, 4158, -5536},
{5, 1566, 52, 33, 4200, -5456},
{5, 1647, 132, 78, 4459, 1906},
{5, 1664, 134, 8, 4511, 4341},
{5, 1672, 52, 33, 4457, -5915},
{5, 1788, 70, 60, 5069, -320},
{5, 1792, 52, 23, 5052, -3759},
{5, 1808, 52, 23, 5077, -3731},
{5, 1817, 134, 78, 5124, 1641},
{5, 1851, 119, 23, 5141, -4003},
{5, 1857, 133, 8, 5201, 3921},
{5, 1907, 134, 8, 5281, 3520},
{5, 1909, 70, 36, 5045, -716},
{5, 1931, 80, 8, 5314, 3415},
{5, 1961, 53, 11, 5421, 6923},
{5, 1964, 52, 47, 5334, -2157},
{5, 1973, 63, 60, 5351, -444},
{5, 1980, 73, 60, 5354, -555},
{5, 1999, 70, 60, 5364, -643},
{5, 2022, 95, 60, 5421, 905},
{5, 2024, 70, 60, 5417, -151},
{5, 2126, 136, 8, 6025, 4952},
{5, 2129, 133, 38, 6007, 2319},
{5, 2158, 135, 38, 6074, 2406},
{5, 2169, 132, 60, 6084, 1358},
{5, 2175, 77, 60, 6096, 2029},
{5, 2185, 70, 55, 6110, -614},
{5, 2186, 135, 60, 6121, 528},
{5, 2194, 135, 60, 6138, 1248},
{5, 2204, 135, 20, 6155, -1840},
{5, 2207, 52, 20, 6164, -2122},
{5, 2215, 134, 55, 6208, -717},
{5, 2232, 130, 55, 6280, -451},
{5, 2237, 76, 55, 6309, 503},
{5, 2238, 62, 55, 6307, 501},
{5, 2239, 131, 55, 6319, 457},
{5, 2245, 70, 55, 6327, 1009},
{5, 2251, 133, 55, 6346, 822},
{5, 2261, 70, 55, 6392, 845},
{5, 2264, 74, 55, 6410, 954},
{5, 2266, 136, 38, 6433, 2658},
{5, 2281, 131, 8, 6483, 4105},
{5, 2286, 134, 55, 6477, -309},
{5, 2300, 53, 16, 7323, 8543},
{5, 2301, 132, 55, 6518, 28},
{5, 2304, 136, 38, 6552, 1759},
{5, 2311, 136, 55, 6578, -437},
{5, 2324, 134, 55, 7041, 103},
{5, 2335, 133, 55, 7068, -1002},
{5, 2343, 133, 55, 7081, -1037},
{5, 2346, 96, 55, 7094, -48},
{5, 2353, 133, 55, 7145, -1016},
{5, 2354, 133, 20, 7143, -2542},
{5, 2355, 136, 38, 7170, 1345},
{5, 2359, 70, 20, 7185, -1314},
{5, 2360, 133, 20, 7177, -1538},
{5, 2362, 130, 20, 7187, -2457},
{5, 2371, 95, 38, 7256, 2929},
{5, 2372, 95, 38, 7256, 2930},
{5, 2383, 134, 20, 7247, -2057},
{5, 2384, 133, 20, 7252, -2101},
{5, 2392, 93, 38, 7292, 2055},
{5, 2395, 134, 38, 7272, 1337},
{5, 2403, 51, 11, 7368, 6536},
{5, 2419, 122, 51, 7381, 3853},
{5, 2420, 134, 38, 7384, 2134},
{5, 2421, 134, 68, 7362, -2037},
{5, 2423, 133, 68, 7371, -1352},
{5, 2438, 95, 68, 7418, -1444},
{5, 2439, 133, 68, 7408, -3142},
{5, 2440, 95, 68, 7419, -1813},
{5, 2467, 77, 68, 7525, -2626},
{5, 2477, 132, 68, 7522, -3832},
{5, 2479, 136, 68, 7551, -1742},
{5, 2482, 133, 68, 7552, -2415},
{5, 2489, 134, 68, 7563, -3004},
{5, 2506, 134, 55, 8000, -1046},
{5, 2509, 135, 68, 8008, -1903},
{5, 2527, 133, 68, 8050, -2809},
{5, 2539, 133, 68, 8106, -1249},
{5, 2547, 131, 85, 8102, -4912},
{5, 2567, 133, 68, 8185, -3039},
{5, 2571, 133, 68, 8189, -2945},
{5, 2613, 52, 69, 8334, -2258},
{5, 2627, 134, 69, 8372, -2957},
{5, 2655, 52, 11, 8556, 7813},
{5, 2681, 52, 83, 8535, 5119},
{5, 2683, 52, 51, 8527, 3325},
{5, 2742, 53, 83, 9076, 6029},
{5, 2768, 52, 83, 9116, 6002},
{5, 2775, 52, 22, 9103, 702},
{5, 2782, 53, 51, 9141, 4007},
{5, 2784, 52, 42, 9123, -2410},
{5, 2787, 52, 83, 9193, 6912},
{5, 2811, 53, 42, 9162, -1619},
{5, 2835, 52, 42, 9179, -2221},
{5, 2841, 51, 83, 9220, 5059},
{5, 2859, 52, 49, 9243, 3431},
{5, 2867, 94, 13, 9214, -5819},
{5, 2903, 51, 46, 9322, 2130},
{5, 2950, 52, 83, 9426, 5851},
{5, 2964, 53, 46, 9429, 3151},
{5, 2974, 52, 75, 9426, -342},
{5, 2976, 52, 83, 9472, 6755},
{5, 2985, 52, 83, 9504, 7217},
{5, 2997, 51, 2, 9456, -3111},
{5, 3077, 52, 83, 10033, 6844},
{5, 3079, 52, 83, 10020, 5541},
{5, 3109, 52, 42, 10031, -2610},
{5, 3115, 51, 75, 10052, -743},
{5, 3132, 92, 85, 10070, -4026},
{5, 3147, 52, 34, 10169, 7324},
{5, 3166, 52, 75, 10138, 326},
{5, 3169, 52, 75, 10142, 328},
{5, 3184, 52, 83, 10183, 4125},
{5, 3190, 53, 46, 10181, 2150},
{5, 3193, 52, 46, 10184, 2154},
{5, 3198, 52, 83, 10199, 4533},
{5, 3201, 119, 85, 10176, -4625},
{5, 3226, 53, 46, 10234, 1954},
{5, 3227, 52, 46, 10235, 1952},
{5, 3242, 93, 42, 10248, -1839},
{5, 3245, 52, 49, 10273, 2830},
{5, 3277, 53, 49, 10329, 2831},
{5, 3294, 53, 49, 10363, 3719},
{5, 3310, 52, 83, 10388, 5330},
{5, 3344, 52, 49, 10435, 2455},
{5, 3359, 52, 83, 10466, 6313},
{5, 3372, 59, 13, 10451, -5952},
{5, 3377, 52, 46, 10477, 1359},
{5, 3384, 52, 46, 10483, 1238},
{5, 3395, 54, 49, 10498, 3259},
{5, 3412, 52, 46, 10509, 1325},
{5, 3414, 53, 49, 10513, 2758},
{5, 3432, 53, 49, 10525, 3637},
{5, 3486, 52, 49, 11004, 2859},
{5, 3489, 52, 46, 11003, 1354},
{5, 3504, 53, 49, 11032, 2758},
{5, 3521, 51, 46, 11058, -2},
{5, 3532, 129, 13, 11052, -5844},
{5, 3593, 52, 46, 11146, 1249},
{5, 3607, 52, 46, 11169, 1803},
{5, 3608, 52, 46, 11170, 1809},
{5, 3610, 52, 83, 11184, 5847},
{5, 3613, 52, 83, 11186, 5800},
{5, 3619, 53, 83, 11194, 5745},
{5, 3621, 52, 42, 11183, -3249},
{5, 3626, 53, 46, 11201, 1821},
{5, 3628, 52, 46, 11203, 1335},
{5, 3631, 52, 83, 11210, 5310},
{5, 3640, 52, 46, 11211, 314},
{5, 3655, 53, 46, 11229, 1635},
{5, 3665, 52, 83, 11247, 3846},
{5, 3675, 52, 83, 11261, 4335},
{5, 3686, 53, 46, 11277, 1713},
{5, 3717, 53, 42, 11315, -3019},
{5, 3718, 52, 83, 11326, 5304},
{5, 3726, 52, 83, 11333, 4702},
{5, 3729, 53, 83, 11338, 5308},
{5, 3810, 52, 46, 11410, 1128},
{5, 3813, 53, 83, 11413, 3633},
{5, 3877, 53, 83, 11461, 4730},
{5, 3893, 52, 83, 11486, 4843},
{5, 3898, 52, 83, 11493, 5605},
{5, 3900, 53, 46, 11492, 2701},
{5, 3912, 54, 46, 11501, 2629},
{5, 3918, 92, 15, 11503, -5711},
{5, 3923, 52, 42, 11510, -2848},
{5, 3938, 52, 83, 11528, 4407},
{5, 3941, 52, 83, 11529, 3659},
{5, 3945, 52, 83, 11532, 6040},
{5, 3949, 53, 83, 11537, 4752},
{5, 3953, 52, 83, 11538, 5219},
{5, 3962, 52, 27, 11547, -1359},
{5, 3982, 53, 83, 11565, 5507},
{5, 3998, 52, 83, 11579, 5527},
{5, 4013, 53, 83, 11585, 4357},
{5, 4026, 52, 83, 11594, 5058},
{5, 4027, 53, 29, 11595, -1916},
{5, 4030, 52, 86, 12004, -106},
{5, 4036, 52, 83, 12015, 6154},
{5, 4038, 52, 29, 12019, -1852},
{5, 4039, 52, 29, 12019, -1853},
{5, 4041, 53, 83, 12022, 6208},
{5, 4051, 52, 83, 12032, 4432},
{5, 4085, 54, 83, 12054, 5021},
{5, 4088, 52, 83, 12056, 5032},
{5, 4096, 52, 83, 12060, 4729},
{5, 4102, 53, 83, 12064, 5243},
{5, 4105, 52, 42, 12067, -2946},
{5, 4111, 52, 30, 12070, 4304},
{5, 4125, 52, 34, 12081, 6510},
{5, 4143, 52, 30, 12096, 4232},
{5, 4147, 122, 24, 12101, 1833},
{5, 4150, 53, 24, 12106, 3024},
{5, 4151, 52, 30, 12105, 3924},
{5, 4179, 53, 86, 12129, 118},
{5, 4203, 52, 24, 12151, 3312},
{5, 4214, 52, 30, 12156, 3620},
{5, 4216, 52, 86, 12159, 1309},
{5, 4236, 52, 34, 12167, 6928},
{5, 4244, 52, 30, 12175, 3748},
{5, 4245, 53, 24, 12176, 2936},
{5, 4251, 52, 24, 12181, 2810},
{5, 4261, 52, 86, 12194, 549},
{5, 4273, 53, 86, 12199, 521},
{5, 4274, 52, 24, 12198, 2937},
{5, 4278, 52, 24, 12201, 2917},
{5, 4281, 53, 86, 12204, 523},
{5, 4293, 52, 24, 12212, 1823},
{5, 4314, 52, 24, 12225, 2954},
{5, 4346, 53, 30, 12235, 4700},
{5, 4350, 53, 24, 12240, 1642},
{5, 4361, 94, 29, 12245, -1847},
{5, 4365, 52, 86, 12245, 719},
{5, 4371, 52, 86, 12249, 1142},
{5, 4388, 53, 86, 12258, 1240},
{5, 4394, 52, 24, 12259, 1813},
{5, 4395, 52, 30, 12258, 3333},
{5, 4414, 52, 24, 12265, 3113},
{5, 4419, 53, 24, 12269, 1503},
{5, 4429, 52, 86, 12274, 1106},
{5, 4435, 52, 86, 12277, 1305},
{5, 4438, 52, 86, 12278, 1300},
{5, 4442, 52, 86, 12281, 948},
{5, 4448, 53, 24, 12283, 2837},
{5, 4449, 52, 30, 12282, 4406},
{5, 4450, 52, 24, 12285, 1705},
{5, 4459, 52, 24, 12290, 1359},
{5, 4473, 52, 24, 12298, 1326},
{5, 4477, 52, 24, 12300, 1338},
{5, 4478, 53, 86, 12303, 1220},
{5, 4485, 53, 30, 12305, 4142},
{5, 4490, 52, 30, 12306, 4139},
{5, 4494, 52, 24, 12314, 2546},
{5, 4517, 52, 86, 12328, 7},
{5, 4526, 52, 86, 12340, 742},
{5, 4527, 52, 86, 12341, 239},
{5, 4535, 52, 86, 12343, 812},
{5, 4536, 52, 86, 12344, 211},
{5, 4546, 52, 86, 12355, -348},
{5, 4550, 53, 86, 12355, 1213},
{5, 4559, 52, 24, 12360, 2758},
{5, 4565, 52, 24, 12363, 2559},
{5, 4567, 53, 86, 12365, 1115},
{5, 4568, 52, 86, 12366, 1114},
{5, 4570, 52, 86, 12369, 715},
{5, 4596, 52, 86, 12399, 1011},
{5, 4605, 52, 83, 12400, 6136},
{5, 4618, 52, 30, 12416, 4109},
{5, 4631, 51, 30, 12421, 3232},
{5, 4636, 52, 86, 12428, 241},
{5, 4643, 52, 86, 12433, 159},
{5, 4654, 52, 86, 12439, 1308},
{5, 4656, 52, 30, 12440, 3210},
{5, 4660, 53, 86, 12445, 1111},
{5, 4665, 52, 86, 12451, 303},
{5, 4666, 52, 86, 12451, -28},
{5, 4689, 52, 24, 12478, 1346},
{5, 4697, 51, 86, 12486, -548},
{5, 4698, 52, 86, 12484, 829},
{5, 4699, 52, 86, 12490, -840},
{5, 4725, 51, 24, 12504, 2530},
{5, 4753, 52, 86, 12524, -112},
{5, 4754, 52, 86, 12523, 1119},
{5, 4762, 52, 86, 12529, 1114},
{5, 4781, 53, 86, 12544, -1032},
{5, 4800, 53, 30, 12546, 4632},
{5, 4845, 53, 86, 12580, 135},
{5, 4856, 52, 86, 12594, -1503},
{5, 4866, 53, 86, 12595, 1410},
{5, 4889, 53, 24, 13001, 2759},
{5, 4900, 53, 86, 13007, 230},
{5, 4902, 52, 86, 13010, -1431},
{5, 4945, 51, 15, 13054, -4928},
{5, 4958, 52, 86, 13058, -801},
{5, 4995, 53, 86, 13097, -750},
{5, 5005, 52, 30, 13109, 3703},
{5, 5033, 52, 30, 13135, 3636},
{5, 5053, 122, 24, 13165, 1742},
{5, 5054, 52, 86, 13170, -1638},
{5, 5068, 52, 86, 13189, -2102},
{5, 5078, 53, 42, 13198, -2725},
{5, 5102, 52, 15, 13220, -3638},
{5, 5128, 49, 15, 13255, -4301},
{5, 5139, 116, 15, 13268, -4729},
{5, 5247, 52, 86, 13380, -1753},
{5, 5248, 52, 9, 13375, 853},
{5, 5273, 53, 30, 13421, 3539},
{5, 5286, 119, 15, 13464, -5122},
{5, 5322, 52, 83, 13492, 6011},
{5, 5350, 53, 30, 13534, 4022},
{5, 5353, 53, 30, 13534, 4017},
{5, 5354, 53, 30, 13534, 4018},
{5, 5363, 52, 86, 13561, 515},
{5, 5364, 52, 86, 13562, 501},
{5, 5371, 52, 30, 13557, 4028},
{5, 5427, 53, 86, 14034, -602},
{5, 5466, 121, 9, 14055, 2832},
{5, 5473, 53, 83, 14047, 5454},
{5, 5474, 52, 83, 14050, 5340},
{5, 5557, 53, 9, 14184, 3630},
{5, 5566, 52, 86, 14203, 356},
{5, 5576, 53, 86, 14211, 316},
{5, 5631, 53, 83, 14266, 5635},
{5, 5634, 122, 86, 14296, -559},
{5, 5643, 52, 50, 14327, -4411},
{5, 5676, 53, 9, 14328, 4927},
{5, 5689, 53, 9, 14355, 4844},
{5, 5694, 122, 42, 14396, -2632},
{5, 5746, 52, 86, 14449, 157},
{5, 5813, 52, 86, 15012, 142},
{5, 5822, 133, 50, 15044, -5424},
{5, 5823, 134, 19, 15055, -5536},
{5, 5824, 121, 50, 15040, -3304},
{5, 5846, 52, 86, 15065, 136},
{5, 5850, 52, 86, 15071, 133},
{5, 5897, 120, 48, 15174, -2101},
{5, 5907, 52, 34, 15159, 5620},
{5, 5927, 120, 50, 15280, -5040},
{5, 5946, 120, 57, 15355, -5040},
{5, 5982, 53, 34, 15387, 5921},
{5, 5986, 120, 50, 15461, -3747},
{5, 6067, 132, 57, 16132, -5413},
{5, 6118, 53, 74, 16218, -217},
{5, 6124, 132, 72, 16253, -4039},
{5, 6134, 133, 57, 16278, -4909},
{5, 6144, 121, 72, 16272, -2601},
{5, 6192, 135, 72, 16404, -4322},
{5, 6193, 131, 6, 16413, -4846},
{5, 6204, 134, 6, 16462, -4701},
{5, 6207, 53, 40, 16431, 3650},
{5, 6210, 94, 40, 16445, 2348},
{5, 6217, 53, 84, 16326, 7812},
{5, 6222, 136, 72, 16494, -4444},
{5, 6229, 121, 40, 16470, 4732},
{5, 6231, 129, 72, 16542, -4149},
{5, 6235, 121, 59, 16534, -2211},
{5, 6242, 132, 72, 16556, -3928},
{5, 6259, 134, 72, 17008, -4439},
{5, 6281, 131, 72, 17047, -3759},
{5, 6284, 121, 59, 17045, -2446},
{5, 6287, 121, 59, 17052, -2242},
{5, 6293, 120, 59, 17102, -2635},
{5, 6302, 96, 72, 17137, -3706},
{5, 6304, 120, 59, 17145, -2928},
{5, 6309, 95, 59, 17141, -1255},
{5, 6316, 120, 59, 17166, -2808},
{5, 6334, 70, 72, 17208, -3606},
{5, 6342, 122, 59, 17212, -1935},
{5, 6352, 120, 6, 17255, -4825},
{5, 6355, 121, 59, 17240, -2621},
{5, 6356, 120, 59, 17236, -1749},
{5, 6366, 122, 59, 17277, -505},
{5, 6369, 95, 59, 17293, -2346},
{5, 6388, 119, 72, 17363, -4444},
{5, 6397, 117, 6, 17407, -5340},
{5, 6401, 119, 59, 17386, -2355},
{5, 6426, 122, 59, 17449, 310},
{5, 6440, 121, 77, 17489, -2022},
{5, 6441, 119, 72, 17502, -3703},
{5, 6445, 97, 77, 17493, -2001},
{5, 6451, 134, 72, 17507, -3013},
{5, 6453, 122, 72, 17509, -3436},
{5, 6503, 52, 34, 17495, 7009},
{5, 6517, 122, 59, 18018, -858},
{5, 6520, 134, 77, 18034, -2753},
{5, 6522, 122, 77, 18036, -3002},
{5, 6528, 122, 77, 18048, -3003},
{5, 6535, 121, 74, 18038, -18},
{5, 6539, 121, 74, 18048, -735},
{5, 6541, 118, 25, 18080, -4342},
{5, 6543, 92, 34, 17586, 6638},
{5, 6544, 120, 77, 18073, -2500},
{5, 6553, 120, 77, 18093, -2554},
{5, 6568, 135, 77, 18128, -2135},
{5, 6569, 120, 77, 18136, -3150},
{5, 6572, 92, 59, 18121, 651},
{5, 6583, 136, 77, 18158, -2208},
{5, 6603, 137, 77, 18184, -1824},
{5, 6624, 120, 77, 18237, -3022},
{5, 6629, 94, 77, 18257, -2312},
{5, 6633, 131, 59, 18273, 631},
{5, 6638, 121, 77, 18309, -2530},
{5, 6642, 121, 77, 18319, -2329},
{5, 6645, 135, 77, 18320, -1653},
{5, 6649, 135, 73, 18335, -1024},
{5, 6652, 121, 77, 18358, -3259},
{5, 6664, 134, 73, 18366, -749},
{5, 6712, 120, 73, 18531, -842},
{5, 6723, 119, 77, 18596, -3638},
{5, 6726, 70, 25, 19017, -3653},
{5, 6727, 70, 25, 19017, -3653},
{5, 6729, 70, 25, 19019, -3657},
{5, 6752, 117, 61, 19109, -5959},
{5, 6755, 134, 4, 19078, 416},
{5, 6756, 136, 4, 19087, 442},
{5, 6760, 121, 4, 19112, 102},
{5, 6781, 95, 4, 19185, 632},
{5, 6791, 136, 52, 19207, 3751},
{5, 6802, 135, 88, 19306, 2016},
{5, 6818, 94, 77, 19440, -1409},
{5, 6819, 133, 31, 19413, 4011},
{5, 6822, 51, 77, 19449, -1448},
{5, 6823, 133, 88, 19432, 2318},
{5, 6826, 93, 31, 19448, 5032},
{5, 6830, 134, 88, 19510, 2306},
{5, 6834, 134, 31, 19522, 2924},
{5, 6857, 67, 31, 20028, 3331},
{5, 6866, 134, 31, 20039, 4410},
{5, 6885, 134, 88, 20119, 2629},
{5, 6888, 66, 31, 20128, 3819},
{5, 6905, 96, 32, 20224, 2006},
{5, 6907, 53, 12, 20251, -2449},
{5, 6910, 133, 31, 20232, 4047},
{5, 6934, 121, 32, 20342, 724},
{5, 6939, 134, 16, 20315, 6040},
{5, 6940, 132, 88, 20344, 2817},
{5, 6946, 51, 16, 20349, 6009},
{5, 6960, 105, 31, 20457, 3043},
{5, 6974, 112, 31, 20511, 3150},
{5, 6979, 70, 31, 20510, 3208},
{5, 6992, 105, 31, 20564, 3143},
{5, 6995, 105, 31, 20571, 3113},
{5, 7000, 60, 31, 21018, 4412},
{5, 7006, 122, 32, 21015, 1611},
{5, 7008, 96, 31, 21005, 5433},
{5, 7009, 92, 5, 21042, -1122},
{5, 7023, 77, 16, 21005, 6810},
{5, 7026, 96, 31, 21063, 4751},
{5, 7027, 94, 31, 21070, 4214},
{5, 7044, 138, 31, 21129, 4229},
{5, 7062, 134, 31, 21235, 4623},
{5, 7086, 134, 31, 21305, 5136},
{5, 7090, 52, 44, 21365, -5433},
{5, 7128, 136, 31, 21440, 5343},
{5, 7129, 81, 16, 21430, 6607},
{5, 7142, 135, 16, 21452, 6546},
{5, 7160, 132, 16, 21537, 6236},
{5, 7184, 52, 5, 22027, -2049},
{5, 7209, 134, 45, 22051, 4629},
{5, 7217, 52, 62, 22079, 3122},
{5, 7243, 132, 45, 22151, 4954},
{5, 7293, 90, 5, 22296, -2050},
{5, 7296, 136, 45, 22282, 5217},
{5, 7320, 54, 62, 22361, 3357},
{5, 7331, 52, 62, 22371, 3425},
{5, 7380, 133, 16, 22473, 5808},
{5, 7424, 52, 39, 22573, -4104},
{5, 7448, 53, 62, 23001, 1559},
{5, 7479, 52, 62, 23049, 1219},
{5, 7510, 134, 16, 23115, 6034},
{5, 7582, 52, 39, 23184, -4222},
{5, 7606, 52, 5, 23191, -829},
{5, 7619, 53, 62, 23202, 812},
{5, 7635, 67, 14, 23202, 6111},
{5, 7662, 93, 1, 23259, 4232},
{5, 7686, 132, 1, 23301, 4908},
{5, 7723, 53, 5, 23390, -1258},
{5, 7727, 52, 5, 23399, -1218},
{5, 7789, 133, 14, 23574, 5643},
{5, 7790, 135, 14, 23584, 6113},
{5, 7793, 51, 71, 23578, -3236},
{5, 7814, 52, 62, 32, 1609},
{0, 36, 146, 1, 550, +2338},
{15, 0, 142, 1, 2039, +4220},
{201, 228, 147, 1, 2140, +4729},
{201, 3050, 146, 1, 23595, +3343},
{0, 56, 146, 1, 1562, +3715},
{0, 59, 146, 1, 2109, +3902},
{24, 0, 146, 4, 19487, +1149},
{201, 2404, 147, 4, 18508, +1059},
{201, 2532, 146, 4, 19302, 254},
{0, 5, 146, 4, 18465, -58},
{0, 11, 145, 4, 18591, +1338},
{0, 15, 146, 4, 19050, -402},
{0, 57, 146, 4, 19546, -814},
{201, 2838, 146, 5, 21546, -318},
{32, 0, 144, 5, 22288, -1},
{0, 12, 146, 5, 21041, -549},
{0, 41, 146, 5, 22143, -2104},
{0, 53, 146, 5, 22266, -1645},
{0, 94, 145, 5, 23191, -1328},
{0, 107, 146, 5, 23460, -1841},
{12, 0, 145, 7, 2592, +2120},
{15, 0, 145, 7, 1535, +1918},
{20, 0, 145, 7, 1579, +2336},
{24, 0, 145, 7, 2493, +1728},
{201, 394, 147, 7, 3280, +2028},
{0, 1, 146, 7, 1501, +2217},
{0, 30, 147, 7, 2370, +2439},
{0, 33, 145, 7, 2407, +2704},
{16, 0, 143, 8, 5597, +3713},
{201, 644, 147, 8, 5103, +3718},
{201, 698, 147, 8, 5252, +3451},
{201, 872, 147, 8, 6156, +3609},
{29, 0, 145, 8, 4593, +3753},
{30, 0, 145, 8, 6467, +4335},
{0, 14, 145, 8, 5154, +3241},
{0, 26, 145, 8, 5386, +3030},
{0, 41, 146, 8, 6116, +4843},
{132, 147, 147, 8, 6343, +3805},
{11, 0, 144, 9, 15155, +3319},
{12, 0, 143, 9, 14450, +2704},
{17, 0, 145, 9, 14162, +5122},
{19, 0, 145, 9, 14135, +5147},
{21, 0, 144, 9, 15245, +3723},
{24, 0, 145, 9, 14407, +1625},
{201, 1825, 146, 9, 14165, +2007},
{201, 1835, 145, 9, 14234, +827},
{201, 1884, 147, 9, 14484, +2422},
{31, 0, 145, 9, 14514, +1906},
{32, 0, 144, 9, 14411, +1344},
{0, 39, 146, 9, 14497, +4843},
{0, 44, 145, 9, 15038, +4739},
{162, 191, 147, 9, 14596, +5352},
{201, 1694, 145, 11, 12492, +8325},
{201, 400, 147, 11, 3350, +6002},
{201, 485, 147, 11, 4078, +6220},
{0, 1, 146, 11, 4320, +5355},
{0, 11, 145, 11, 5061, +5858},
{6, 0, 144, 12, 20176, -1230},
{23, 0, 146, 12, 20299, -1835},
{24, 0, 145, 12, 20273, -1813},
{26, 0, 145, 12, 20289, -1749},
{27, 0, 145, 12, 20194, -1907},
{17, 0, 145, 14, 2291, +6724},
{18, 0, 144, 14, 491, +5749},
{27, 0, 145, 14, 23590, +5545},
{201, 163, 147, 14, 1513, +6451},
{201, 3053, 146, 14, 26, +6606},
{201, 3062, 146, 14, 63, +5826},
{0, 3, 145, 15, 13518, -3300},
{9, 0, 143, 16, 21287, +7034},
{11, 0, 144, 16, 22292, +5825},
{19, 0, 144, 16, 20089, +7743},
{201, 2780, 147, 16, 21118, +5959},
{201, 2816, 146, 16, 21390, +5729},
{201, 2840, 146, 16, 21520, +5548},
{201, 460, 146, 16, 4100, +8042},
{31, 0, 144, 16, 22038, +6438},
{132, 461, 147, 16, 22039, +5949},
{10, 0, 145, 17, 1496, -1041},
{15, 0, 144, 17, 2433, +314},
{201, 186, 147, 17, 1559, +151},
{0, 66, 146, 17, 2128, -224},
{6, 0, 140, 20, 6451, -1643},
{12, 0, 142, 20, 6586, -2858},
{21, 0, 145, 20, 6561, -1403},
{108, 3945, 145, 20, 7166, -2319},
{17, 0, 144, 22, 8467, +2846},
{25, 0, 146, 22, 8268, +2656},
{201, 1177, 147, 22, 8056, +2732},
{201, 1245, 146, 22, 8358, 637},
{201, 1254, 147, 22, 8404, +1940},
{201, 1311, 147, 22, 9074, +2259},
{32, 0, 145, 22, 8122, +1739},
{0, 57, 146, 22, 8542, +3035},
{0, 66, 146, 22, 9014, +3215},
{201, 1633, 147, 24, 12207, +2703},
{201, 1639, 147, 24, 12244, +2535},
{0, 2, 146, 24, 12043, +2128},
{0, 24, 145, 24, 12351, +1823},
{0, 35, 145, 24, 12533, +2115},
{15, 0, 145, 25, 19064, -3704},
{19, 0, 146, 25, 18334, -3844},
{15, 0, 144, 26, 15427, +2618},
{18, 0, 146, 26, 15232, +3017},
{27, 0, 146, 26, 16147, +3352},
{32, 0, 145, 26, 15394, +3638},
{132, 128, 146, 26, 16117, +3321},
{11, 0, 143, 29, 12299, -1631},
{201, 1604, 147, 29, 12095, -1151},
{6, 0, 143, 30, 12560, +3819},
{0, 2, 146, 30, 12161, +4040},
{9, 0, 143, 31, 19307, +2758},
{11, 0, 143, 31, 19450, +4508},
{20, 0, 145, 31, 20474, +3629},
{21, 0, 145, 31, 21441, +2845},
{21, 0, 145, 31, 21441, +2845},
{201, 2486, 147, 31, 19121, +4951},
{30, 0, 145, 31, 19556, +5226},
{0, 16, 146, 31, 19418, +5032},
{0, 31, 144, 31, 20136, +4644},
{0, 49, 146, 31, 20410, +3218},
{0, 61, 145, 31, 21069, +3845},
{132, 130, 146, 31, 21208, +3227},
{103, 5137, 146, 31, 19459, +3501},
{15, 0, 144, 32, 20467, +1607},
{12, 0, 144, 34, 19482, +7016},
{21, 0, 146, 34, 17053, +5428},
{22, 0, 145, 34, 17322, +5511},
{23, 0, 145, 34, 18512, +5923},
{201, 2155, 147, 34, 17161, +6043},
{201, 2348, 146, 34, 18339, +5221},
{30, 0, 145, 34, 17419, +7209},
{0, 17, 145, 34, 16362, +5255},
{0, 41, 146, 34, 18002, +8000},
{132, 123, 147, 34, 13271, +6444},
{12, 0, 145, 35, 20591, +418},
{201, 2742, 147, 35, 21022, +711},
{16, 0, 143, 36, 2583, -4018},
{11, 5, 146, 36, 1398, -5612},
{0, 55, 147, 36, 4436, -848},
{108, 3556, 146, 36, 3124, -4425},
{29, 0, 145, 37, 2338, -2814},
{6, 0, 142, 38, 7346, +3153},
{11, 0, 144, 38, 7201, +2159},
{19, 0, 144, 38, 7444, +2424},
{201, 1083, 147, 38, 7256, +2030},
{201, 1108, 147, 38, 7328, +2253},
{0, 38, 145, 38, 6546, +1311},
{162, 70, 147, 38, 6278, +2047},
{6, 0, 143, 40, 17146, +1423},
{11, 0, 143, 40, 17150, +2450},
{19, 0, 145, 40, 16081, +1703},
{26, 0, 145, 40, 17237, +3709},
{201, 2052, 147, 40, 16289, +1825},
{201, 2063, 146, 40, 16318, +4536},
{201, 2315, 147, 40, 18250, +2724},
{201, 2411, 147, 40, 18523, +1432},
{0, 37, 146, 40, 16406, +413},
{0, 56, 146, 40, 16550, +2544},
{0, 95, 145, 40, 18015, +2136},
{0, 100, 146, 40, 18078, +2606},
{132, 129, 147, 40, 18359, +1659},
{12, 0, 143, 42, 8468, +625},
{201, 1348, 148, 42, 9245, +621},
{201, 1355, 147, 42, 9273, +614},
{201, 1365, 147, 42, 9315, +128},
{28, 0, 145, 42, 9291, -246},
{103, 396, 146, 42, 11323, -2916},
{201, 2894, 146, 45, 22189, +3746},
{0, 8, 146, 45, 22359, +3938},
{6, 0, 141, 46, 10084, +1158},
{15, 0, 142, 46, 10200, +1950},
{28, 0, 145, 46, 11279, +251},
{0, 6, 145, 46, 9320, +943},
{0, 49, 146, 46, 10350, +839},
{0, 54, 144, 46, 10556, +2445},
{0, 81, 146, 46, 11256, +1627},
{0, 83, 147, 46, 11268, +301},
{0, 90, 146, 46, 11347, +1648},
{132, 215, 147, 46, 10163, +1744},
{15, 0, 144, 47, 5445, -2227},
{108, 3750, 145, 47, 5204, -2114},
{21, 0, 145, 48, 14493, -1409},
{23, 0, 146, 48, 15210, -1533},
{201, 1962, 146, 48, 15387, -847},
{31, 0, 145, 50, 15569, -3358},
{201, 1282, 147, 51, 8508, +3504},
{201, 1333, 147, 51, 9184, +3522},
{201, 1338, 147, 51, 9210, +3811},
{201, 1369, 147, 51, 9354, +3958},
{201, 958, 146, 51, 6482, +5542},
{0, 12, 145, 51, 6462, +5927},
{0, 19, 146, 51, 7229, +5517},
{0, 38, 144, 51, 9188, +3648},
{9, 0, 144, 52, 18501, +3322},
{13, 0, 145, 52, 18443, +3940},
{14, 0, 145, 52, 18443, +3940},
{18, 0, 144, 52, 19138, +3909},
{201, 2474, 147, 52, 19091, +3436},
{32, 0, 144, 52, 18448, +3736},
{200, 0, 145, 52, 18570, +3254},
{162, 282, 146, 52, 18549, +3358},
{108, 5218, 147, 54, 20454, -3029},
{9, 0, 145, 55, 6288, -702},
{12, 0, 144, 55, 6238, +436},
{20, 0, 144, 59, 16309, +159},
{23, 0, 145, 59, 17180, -2417},
{26, 0, 145, 59, 16256, -2327},
{201, 2276, 147, 59, 18057, +1200},
{28, 0, 145, 59, 18031, -811},
{0, 36, 145, 59, 17153, -2636},
{0, 61, 146, 59, 17446, +235},
{0, 70, 144, 59, 18055, +230},
{9, 0, 140, 60, 5145, -812},
{11, 0, 142, 60, 5320, -18},
{16, 0, 145, 60, 5353, -523},
{17, 0, 143, 60, 5354, -555},
{18, 0, 144, 60, 5245, -224},
{20, 0, 144, 60, 5351, +956},
{26, 0, 145, 60, 5133, +252},
{27, 0, 144, 60, 5387, -236},
{201, 747, 145, 60, 5350, -600},
{201, 790, 146, 60, 5460, -416},
{32, 0, 142, 60, 5407, -157},
{0, 14, 146, 60, 5079, +830},
{0, 23, 145, 60, 5228, +333},
{0, 32, 144, 60, 5308, 557},
{0, 33, 146, 60, 5312, +318},
{0, 52, 146, 60, 5480, +627},
{12, 0, 143, 62, 21442, +953},
{201, 2841, 146, 62, 21543, +1943},
{201, 3007, 147, 62, 23228, +2034},
{0, 1, 144, 62, 21221, +1948},
{18, 0, 144, 63, 2507, +5554},
{201, 162, 146, 63, 1493, +4754},
{201, 331, 145, 63, 3009, +5221},
{201, 336, 147, 63, 3015, +3225},
{201, 369, 147, 63, 3171, +4029},
{0, 56, 146, 63, 4246, +3358},
{11, 24, 146, 66, 22366, -3140},
{6, 0, 144, 67, 2020, +246},
{201, 22, 147, 67, 174, +853},
{201, 3009, 147, 67, 23243, +343},
{30, 0, 145, 67, 1057, +2128},
{32, 0, 145, 67, 1137, +735},
{0, 35, 144, 67, 150, +849},
{0, 55, 146, 67, 399, +2126},
{0, 65, 146, 67, 499, +2743},
{0, 66, 146, 67, 546, +1911},
{0, 77, 146, 67, 1058, +455},
{112, 0, 145, 68, 7183, -3644},
{110, 19, 146, 68, 7343, -2328},
{103, 327, 144, 68, 7388, -2648},
{6, 0, 141, 72, 16294, -2626},
{9, 0, 143, 72, 16054, -1948},
{22, 0, 144, 72, 16120, -1928},
{31, 0, 145, 72, 16044, -1122},
{11, 0, 144, 74, 15348, +1032},
{16, 0, 145, 74, 18562, +412},
{201, 1919, 147, 74, 15127, +1917},
{0, 59, 145, 74, 18272, +12},
{132, 127, 146, 74, 15402, +1203},
{15, 0, 145, 75, 9525, -806},
{153, 0, 147, 75, 9541, +457},
{0, 35, 146, 75, 10433, +445},
{0, 40, 147, 75, 10493, -401},
{32, 0, 145, 76, 19490, +1909},
{110, 84, 146, 76, 19394, +1634},
{138, 0, 145, 77, 17591, -3015},
{0, 54, 145, 77, 19407, -1618},
{108, 5082, 146, 77, 19031, -1915},
{10, 0, 145, 78, 4226, +2538},
{25, 0, 145, 78, 4204, +2721},
{201, 422, 146, 78, 3368, +35},
{201, 495, 146, 78, 4077, +1510},
{201, 572, 147, 78, 4385, +2656},
{0, 7, 147, 78, 3344, +2428},
{0, 62, 146, 78, 4240, +2418},
{0, 118, 146, 78, 5293, +2509},
{201, 239, 147, 81, 2174, +2845},
{0, 6, 145, 81, 2124, +3018},
{27, 0, 145, 83, 9104, +6708},
{201, 1520, 147, 83, 11161, +5246},
{201, 1523, 144, 83, 11182, +3132},
{201, 1695, 146, 83, 12563, +5406},
{32, 0, 142, 83, 13239, +5456},
{132, 126, 146, 83, 11323, +6105},
{6, 0, 142, 84, 2318, +8916},
{201, 1972, 147, 84, 15292, +8027},
{108, 2682, 147, 84, 13407, +7651},
{11, 70, 145, 85, 8295, -4443},
{108, 4191, 145, 85, 9144, -4314},
{15, 0, 143, 86, 12417, -127},
{28, 0, 144, 86, 14016, +133},
{0, 17, 147, 86, 12225, +518},
{60, 0, 161, 1, 275, 3535},
{166, 0, 162, 1, 23388, 3546},
{167, 0, 162, 1, 46, 4333},
{167, 0, 162, 1, 46, 4333},
{181, 0, 161, 1, 2384, 3910},
{185, 0, 162, 1, 199, 4443},
{107, 5223, 162, 1, 542, 2404},
{130, 15196, 162, 1, 542, 2404},
{179, 0, 162, 4, 18585, 1422},
{182, 0, 161, 4, 19044, -541},
{182, 1469, 162, 4, 20011, 931},
{130, 11960, 161, 4, 19232, -1042},
{147, 0, 163, 5, 23244, -1719},
{182, 0, 162, 7, 2150, 1214},
{90, 0, 163, 8, 5034, 5038},
{96, 0, 162, 8, 5481, 3038},
{148, 0, 164, 8, 6348, 4230},
{152, 0, 162, 8, 5271, 3409},
{176, 0, 163, 8, 5091, 3900},
{178, 0, 159, 8, 6365, 3827},
{179, 0, 161, 8, 5218, 3231},
{182, 0, 163, 8, 6240, 4742},
{182, 346, 163, 8, 4526, 3830},
{149, 0, 163, 9, 14242, 2542},
{147, 0, 162, 11, 7217, 6940},
{152, 0, 162, 11, 5410, 6848},
{166, 0, 161, 11, 4512, 6810},
{177, 0, 161, 11, 3418, 6239},
{179, 0, 162, 11, 4059, 6148},
{196, 0, 161, 11, 4086, 5322},
{146, 0, 161, 12, 20171, -2119},
{129, 0, 164, 14, 246, 5417},
{166, 0, 165, 14, 175, 1714},
{187, 0, 162, 14, 549, 5834},
{191, 0, 163, 14, 1336, 5745},
{193, 0, 161, 14, 13, 6021},
{182, 623, 161, 14, 3114, 5754},
{21, 0, 162, 16, 21435, 5848},
{152, 0, 161, 16, 21352, 7837},
{107, 16115, 162, 17, 2351, -927},
{157, 129989, 162, 17, 2351, -9264},
{187, 0, 160, 20, 7081, -1155},
{139, 0, 161, 21, 7087, 1001},
{171, 0, 162, 22, 8567, 1931},
{194, 0, 160, 22, 8554, 1714},
{139, 0, 160, 26, 15486, 2809},
{182, 0, 161, 26, 15495, 3934},
{172, 0, 162, 30, 12594, 3749},
{197, 0, 159, 30, 12451, 4526},
{66, 0, 161, 31, 19288, 4603},
{67, 0, 162, 31, 19572, 4416},
{82, 0, 162, 31, 20468, 4603},
{145, 0, 161, 31, 20134, 3844},
{148, 0, 161, 31, 21433, 3801},
{150, 0, 163, 31, 20104, 3557},
{168, 0, 163, 31, 20095, 4752},
{172, 0, 161, 31, 19409, 3237},
{177, 0, 160, 31, 20196, 4754},
{182, 0, 162, 31, 20413, 4808},
{182, 0, 162, 31, 20413, 4808},
{192, 0, 163, 31, 20186, 3727},
{182, 460, 160, 31, 21420, 3531},
{107, 189256, 162, 31, 19572, 4418},
{157, 106516, 162, 32, 20486, 1750},
{150, 0, 160, 34, 12564, 6560},
{171, 0, 161, 34, 17564, 5813},
{180, 0, 160, 34, 19216, 7634},
{169, 0, 162, 36, 5098, -531},
{75, 0, 162, 38, 7209, 2460},
{129, 0, 161, 38, 7319, 2430},
{173, 0, 161, 38, 6109, 2601},
{184, 0, 162, 38, 6421, 3127},
{33, 0, 161, 40, 18303, 2152},
{144, 0, 162, 40, 16042, 5030},
{157, 46574, 161, 40, 17135, 4206},
{177, 0, 159, 42, 10376, -1323},
{182, 0, 161, 42, 10516, -2115},
{197, 0, 161, 42, 9511, -2301},
{139, 0, 160, 46, 9476, 1124},
{139, 0, 160, 47, 4596, -1448},
{197, 0, 161, 51, 7282, 460},
{109, 0, 162, 52, 18428, 3658},
{171, 0, 162, 52, 18323, 3660},
{177, 0, 162, 52, 19202, 3753},
{73, 0, 163, 55, 6564, 76},
{96, 0, 163, 55, 6224, 325},
{102, 0, 162, 55, 6532, -435},
{148, 0, 161, 55, 6584, 610},
{150, 0, 162, 55, 7069, -733},
{182, 614, 161, 55, 7010, -315},
{175, 0, 161, 59, 17297, -1928},
{182, 0, 161, 59, 16267, -1226},
{74, 0, 160, 60, 6255, 1443},
{101, 0, 164, 60, 6177, 831},
{146, 0, 162, 60, 5332, 709},
{190, 0, 160, 60, 5054, 111},
{149, 0, 162, 62, 21564, 2248},
{33, 0, 163, 63, 3451, 4447},
{149, 0, 162, 63, 21564, 2252},
{151, 0, 162, 63, 22059, 3330},
{197, 0, 162, 63, 3277, 4411},
{182, 466, 162, 63, 3415, 5130},
{176, 0, 159, 67, 23464, 329},
{198, 0, 161, 67, 1161, 2546},
{107, 26, 162, 67, 54, 847},
{157, 109003, 162, 67, 54, 847},
{157, 128396, 163, 67, 23491, 623},
{147, 0, 162, 68, 8075, -2255},
{148, 0, 163, 73, 18474, -1313},
{149, 0, 162, 73, 18370, -736},
{165, 0, 160, 73, 18583, -754},
{171, 0, 162, 73, 18554, -86},
{87, 0, 162, 74, 18474, 530},
{94, 0, 163, 74, 18194, -1537},
{72, 0, 163, 76, 20024, 2105},
{76, 0, 162, 76, 20024, 2036},
{195, 0, 161, 76, 20051, 2039},
{60, 0, 161, 77, 19343, -1622},
{170, 0, 162, 77, 17449, -1839},
{182, 1942, 161, 77, 19192, -1555},
{167, 0, 163, 78, 5491, 1904},
{172, 0, 162, 78, 4515, 2832},
{173, 0, 160, 78, 5452, 2425},
{197, 0, 161, 78, 5457, 2042},
{146, 0, 163, 83, 9184, 5124},
{186, 0, 160, 83, 10451, 6725},
{147, 0, 162, 86, 12473, 409},
{165, 0, 160, 86, 12252, 46},
{107, 113801, 163, 86, 13064, -2004},
{157, 157721, 163, 86, 13064, -2004},
{68, 0, 162, 88, 20373, 2630},
{130, 13571, 162, 88, 21099, 2637},
{34, 0, 169, 36, 1377, -5714},
{35, 0, 171, 72, 16054, -1948},
{36, 0, 169, 28, 12266, -6306},
{37, 0, 170, 20, 6586, -2858},
{38, 0, 169, 15, 14038, -6022},
{39, 0, 170, 1, 2039, 4220},
{40, 0, 169, 78, 4359, 1631},
{41, 0, 170, 16, 21186, 6235},
{42, 0, 170, 39, 22427, -4653},
{43, 0, 170, 63, 3243, 4952},
{44, 0, 170, 46, 10200, 1950},
{45, 0, 170, 63, 3082, 4057},
{46, 0, 170, 38, 6377, 1624},
{47, 0, 170, 83, 12540, 5558},
{48, 0, 170, 83, 13475, 4919},
{49, 0, 170, 39, 22082, -4658},
{50, 0, 170, 60, 5362, -112},
{51, 0, 170, 60, 5408, -157},
{52, 0, 170, 42, 9276, -840},
{53, 0, 170, 26, 15347, 2643},
{54, 0, 170, 1, 84, 2905},
{55, 0, 170, 85, 8095, -4720},
{56, 0, 169, 4, 19508, 852},
{57, 0, 170, 20, 7241, -2918},
{58, 0, 170, 64, 263, -4218},
{59, 0, 169, 72, 16294, -2626},
{61, 0, 168, 9, 14157, 1911},
{62, 0, 171, 47, 5327, -1749},
{63, 0, 170, 13, 9171, -5917},
{64, 0, 170, 80, 16487, -6902},
{65, 0, 170, 13, 8225, -5931},
{69, 0, 169, 28, 12477, -5941},
{70, 0, 170, 60, 5251, 621},
{71, 0, 169, 60, 5552, 724},
{77, 0, 168, 13, 6240, -5242},
{78, 0, 168, 8, 5167, 4560},
{79, 0, 170, 14, 92, 5909},
{80, 0, 170, 38, 7346, 3153},
{81, 0, 170, 14, 567, 6043},
{83, 0, 169, 31, 20414, 4517},
{84, 0, 170, 17, 436, -1759},
{85, 0, 170, 46, 11491, 1434},
{86, 0, 170, 17, 436, -1759},
{88, 0, 170, 72, 16003, -2237},
{89, 0, 170, 83, 11037, 6145},
{91, 0, 170, 78, 5263, 2836},
{92, 0, 170, 34, 17566, 5129},
{93, 0, 170, 62, 21442, 953},
{95, 0, 169, 66, 22577, -2937},
{97, 0, 170, 28, 12312, -5707},
{98, 0, 170, 26, 15347, 2643},
{99, 0, 171, 31, 20462, 3358},
{100, 0, 170, 72, 17425, -3902},
{104, 0, 169, 15, 14038, -6022},
{105, 0, 170, 7, 2072, 2328},
{106, 0, 171, 59, 16372, -1034},
{111, 0, 170, 9, 14450, 2704},
{113, 0, 170, 77, 18242, -3423},
{114, 0, 170, 84, 14507, 7409},
{115, 0, 170, 85, 8447, -5443},
{116, 0, 170, 62, 23048, 1512},
{117, 0, 170, 8, 5595, 4457},
{118, 0, 171, 17, 3023, 405},
{119, 0, 170, 15, 14067, -3622},
{120, 0, 170, 83, 11018, 5623},
{121, 0, 170, 13, 9132, -6943},
{122, 0, 169, 28, 12477, -5941},
{123, 0, 170, 60, 5320, -18},
{124, 0, 170, 1, 1097, 3537},
{125, 0, 170, 63, 3243, 4952},
{126, 0, 170, 20, 6227, -1757},
{127, 0, 170, 83, 13239, 5456},
{128, 0, 170, 68, 8036, -4000},
{131, 0, 170, 77, 18553, -2618},
{133, 0, 170, 61, 20256, -5644},
{134, 0, 170, 83, 11538, 5342},
{135, 0, 170, 84, 2318, 8916},
{136, 0, 169, 38, 7453, 2802},
{137, 0, 168, 21, 7393, 514},
{140, 0, 170, 59, 17349, 1234},
{141, 0, 169, 46, 10084, 1158},
{142, 0, 168, 60, 5145, -812},
{143, 0, 168, 15, 14396, -6050},
{154, 0, 170, 59, 17104, -1543},
{155, 0, 170, 31, 20222, 4015},
{156, 0, 170, 60, 5478, -940},
{158, 0, 170, 72, 17373, -4260},
{159, 0, 170, 62, 23038, 2805},
{160, 0, 170, 14, 405, 5632},
{161, 0, 170, 72, 17336, -3706},
{163, 0, 168, 20, 6451, -1643},
{164, 0, 169, 86, 13252, -1110},
{174, 0, 170, 13, 9171, -5917},
{183, 0, 168, 52, 18369, 3847},
{188, 0, 170, 72, 16502, -3418},
{189, 0, 170, 20, 7084, -2624},
{199, 0, 171, 46, 11141, 2031},
{7, 0, 168, 15, 14396, -6050},
{8, 0, 169, 15, 14396, -6050},
{6, 0, 170, 50, 14419, -4723},
{9, 0, 170, 39, 22427, -4653},
{15, 0, 170, 14, 567, 6043},
{15, 0, 170, 15, 12415, -4858},
{11, 0, 171, 15, 12084, -5043},
{11, 0, 170, 85, 8447, -5443},
{12, 0, 170, 15, 13399, -5328},
{32, 0, 171, 15, 13555, -4717},
{32, 0, 171, 59, 16372, -1034},
{18, 0, 170, 15, 14355, -4209},
{19, 0, 170, 85, 9221, -5501},
{20, 0, 170, 85, 9080, -4326}
};
//###############################################################################################################
//###############################################################################################################
// variables for button - instead of bounce lib - save flash memory
//###############################################################################################################
const int DEBOUNCE_DELAY = 50; // the debounce time; increase if the output flickers
int lastSteadyState = LOW; // the previous steady state from the input pin
int lastFlickerableState = LOW; // the previous flickerable state from the input pin
int currentState; // the current reading from the input pin
unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
unsigned long lastPressedTime = 0;
//###############################################################################################################
//###############################################################################################################
// LCD - VSS - GND // VCC - 5V // RW - GND // K - GND
//###############################################################################################################
const byte rs = 12;
const byte en = 13;
const byte d4 = 9;
const byte d5 = 8;
const byte d6 = 7;
const byte d7 = 6;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
byte myLCDbacklight = 255;
byte myLCDcontrast = 100;
//###############################################################################################################
//###############################################################################################################
// variables to steer menu
//###############################################################################################################
byte myDisplayMode = 0;
const char *const menuTopic[] = {"DEC", "Align", "Target", "Region", "Const", "Brightness", "Contrast", "Sensors", "LX200"};
const byte menuTopic_size = sizeof(menuTopic) / sizeof(menuTopic[0]);
byte myMenuTopicNo = 0;
//###############################################################################################################
//###############################################################################################################
// definition of special / greek characters - for LCD 1602 chinese version - adapt to your LCD if needed
//###############################################################################################################
// used lcd is like this https://www.waveshare.com/datasheet/LCD_en_PDF/LCD1602.pdf (see 14. font table)
const char ch_deg = (char)(223); // degree symbol
const char ch_sigma = (char)(246); // uppercase Sigma
// greek alphabet 1-24 = α β γ δ ε ζ η θ ι κ λ μ ν ξ ο π ρ σ τ υ φ χ ψ ω
// maximum 8 custom characters
// γ
char ch_def_1 = 'g'; // for identificatrion & replacement
byte ch_custom_1[] = {
B00000,
B10011,
B10010,
B10010,
B01110,
B00100,
B00100,
B00100
};
// δ
char ch_def_2 = 'd';
byte ch_custom_2[] = {
B00110,
B01001,
B00100,
B01110,
B10001,
B10001,
B01110,
B00000
};
// ζ
char ch_def_3 = 'z';
byte ch_custom_3[] = {
B01111,
B00010,
B00100,
B01000,
B01000,
B01111,
B00001,
B00110
};
// λ
char ch_def_4 = 'l';
byte ch_custom_4[] = {
B01100,
B00100,
B00100,
B01010,
B01010,
B10001,
B10001,
B00000
};
// ξ
char ch_def_5 = 'x';
byte ch_custom_5[] = {
B11111,
B00100,
B01000,
B00111,
B01000,
B10000,
B11111,
B00010
};
// φ
char ch_def_6 = 'p';
byte ch_custom_6[] = {
B00000,
B10111,
B10101,
B10101,
B10101,
B01110,
B00100,
B00100
};
// ψ
char ch_def_7 = 's';
byte ch_custom_7[] = {
B00000,
B00100,
B10101,
B10101,
B10101,
B01110,
B00100,
B00100
};
// Δ
char ch_def_8 = 'D';
byte ch_custom_8[] = {
B00000,
B00100,
B01010,
B01010,
B10001,
B10001,
B11111,
B00000
};
// lookup table placeholder chars with greek symbols
struct greekSymbols {
char originalChar;
char replaceChar;
};
const unsigned int greekSymbols_size = 26;
const struct greekSymbols greekSymbols[greekSymbols_size] =
{
{'a', (char)(224)}, // α
{'b', (char)(226)}, // β
{'g', 'g'}, // γ custom character
{'d', 'd'}, // δ custom character
{'e', (char)(227)}, // ε
{'z', 'z'}, // ζ custom character
{'j', 'n'}, // η
{'h', (char)(242)}, // θ
{'i', 'l'}, // ι
{'k', 'k'}, // κ
{'l', 'l'}, // λ custom character
{'m', (char)(228)}, // μ
{'n', 'v'}, // ν
{'x', 'x'}, // ξ custom character
{'o', 'o'}, // ο
{'p', (char)(247)}, // π
{'r', (char)(230)}, // ρ
{'s', (char)(229)}, // σ
{'t', 't'}, // τ
{'y', (char)(232)}, // υ
{'q', 'p'}, // φ custom character
{'c', 'x'}, // χ
{'w', 's'}, // ψ custom character
{'u', 'w'},
{'F', (char)(246)}, // Σ
{'D', '/'} // Δ
};
//###############################################################################################################
//###############################################################################################################
// definition of constellation names
//###############################################################################################################
struct constStruct {
char constName[4];
};
constStruct myConstellation;
const unsigned int constStruct_size = 89;
const struct constStruct const_PROGMEM[constStruct_size] PROGMEM = {
{"all"}, {"And"}, {"Ant"}, {"Aps"}, {"Aql"}, {"Aqr"}, {"Ara"}, {"Ari"}, {"Aur"}, {"Boo"}, {"Cae"}, {"Cam"}, {"Cap"}, {"Car"}, {"Cas"}, {"Cen"}, {"Cep"}, {"Cet"}, {"Cha"}, {"Cir"},
{"CMa"}, {"CMi"}, {"Cnc"}, {"Col"}, {"Com"}, {"CrA"}, {"CrB"}, {"Crt"}, {"Cru"}, {"Crv"}, {"CVn"}, {"Cyg"}, {"Del"}, {"Dor"}, {"Dra"}, {"Equ"}, {"Eri"}, {"For"}, {"Gem"}, {"Gru"},
{"Her"}, {"Hor"}, {"Hya"}, {"Hyi"}, {"Ind"}, {"Lac"}, {"Leo"}, {"Lep"}, {"Lib"}, {"LMi"}, {"Lup"}, {"Lyn"}, {"Lyr"}, {"Men"}, {"Mic"}, {"Mon"}, {"Mus"}, {"Nor"}, {"Oct"}, {"Oph"},
{"Ori"}, {"Pav"}, {"Peg"}, {"Per"}, {"Phe"}, {"Pic"}, {"PsA"}, {"Psc"}, {"Pup"}, {"Pyx"}, {"Ret"}, {"Scl"}, {"Sco"}, {"Sct"}, {"Ser"}, {"Sex"}, {"Sge"}, {"Sgr"}, {"Tau"}, {"Tel"},
{"TrA"}, {"Tri"}, {"Tuc"}, {"UMa"}, {"UMi"}, {"Vel"}, {"Vir"}, {"Vol"}, {"Vul"}
};
byte myConstellationNo = 0;
String myConstellationName = "";
//###############################################################################################################
//###############################################################################################################
// object type name and variables for deep sky objects
//###############################################################################################################
const char* myObjectTypeName[] = {"Quasar", "Dark Nebula", "Galaxy", "Bright Neb", "Clust + Neb", "Planet Neb", "SN Rem", "Glob Cluster", "Open Cluster", "Double Star", "Red Star", "Reference", "any"};
unsigned int myRefNo = 0; // number of selected reference star
unsigned int myTargetNo = 0; // number of selected target
//###############################################################################################################
//###############################################################################################################
// definition of cellestial regions = constellations of seasons defined in groups (as in Deep Sky Atlas) to filter targets and reference stars
//###############################################################################################################
// constellation for which deep sky objects exist in the list 0 = all
const byte myAllCONST[] = {0, 1, 2, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 44, 45, 46, 47, 48, 49, 50, 51, 52, 54, 55, 57, 59, 60, 61, 62, 63, 64, 66, 67, 68, 69, 71, 72, 73, 74, 75, 76, 77, 78, 80, 81, 83, 84, 85, 86, 88};
const byte myAllCONST_size = sizeof(myAllCONST) / sizeof(myAllCONST[0]);
// North - UMI,UMA,DRA,CEP,CAS,CAM
const byte myNorthCONST[] = {84, 83, 34, 16, 14, 11};
const byte myNorthCONST_size = sizeof(myNorthCONST) / sizeof(myNorthCONST[0]);
// Spring - LEO,LMI,SEX,HYA,CVN,COM,VIR,CRT,CRV,BOO,CRB,SER
const byte mySpringCONST[] = {46, 49, 75, 42, 30, 24, 86, 27, 29, 9, 26, 74};
const byte mySpringCONST_size = sizeof(mySpringCONST) / sizeof(mySpringCONST[0]);
// Summer - HER,LYR,OPH,SCO,CYG,VUL,SGE,DEL,EQU,AQL,SCT,SER,SGR,CAP
const byte mySummerCONST[] = {40, 52, 59, 72, 31, 88, 76, 32, 35, 4, 73, 74, 77, 12};
const byte mySummerCONST_size = sizeof(mySummerCONST) / sizeof(mySummerCONST[0]);
// Autumn - LAC,PEG,AQR,PSA,AND,TRI,PER,ARI,PSC,CET,SCL,FOR,ERI
const byte myAutumnCONST[] = {45, 62, 5, 66, 1, 81, 63, 7, 67, 17, 71, 37, 36};
const byte myAutumnCONST_size = sizeof(myAutumnCONST) / sizeof(myAutumnCONST[0]);
// Winter - AUR,TAU,ORI,LEP,LYN,GEM,CMI,MON,CMA,PUP,CNC
const byte myWinterCONST[] = {8, 78, 60, 47, 51, 38, 21, 55, 20, 68, 22};
const byte myWinterCONST_size = sizeof(myWinterCONST) / sizeof(myWinterCONST[0]);
// South - ANT,VEL,CAR,VOL,CHA,MUS,CRU,CEN,CRU,TRA,LUP,NOR,ARA,SCO,SGR,CRA,TEL,MIC,IND,PAV,GRU,PHE,SCL,FOR,ERI,HOR,RET,HYI,TUC,DOR,CAE,COL,PUP,PYX,PIC,MEN,APS,OCT
const byte mySouthCONST[] = {2, 85, 13, 28, 15, 28, 80, 50, 57, 6, 72, 77, 25, 54, 44, 61, 39, 64, 71, 37, 36, 41, 33, 23, 68, 69, 65};
const byte mySouthCONST_size = sizeof(mySouthCONST) / sizeof(mySouthCONST[0]);
const char* myregionNAME[] = {"all", "North", "Spring", "Summer", "Autumn", "Winter", "South"}; // no south to save flash
const byte regionArraySize = sizeof(myregionNAME) / sizeof(myregionNAME[0]); // Anzahl der Einträge
byte myRegionNo = 0; // all - 0; North - 1; .... ; South - 6
String myregionName = "";
//###############################################################################################################
//###############################################################################################################
// variables for calculation of position // all positions are calculated in seconds
//###############################################################################################################
long myRefStartTimeSec = 0; // Startzeit beim Setzen des Referenzsterns in Sekunden
long myCurrentRAsec = 0; // meine aktuelle Rektaszension in Sekunden
long myCurrentDECsec = 0; // meine aktuelle Deklination in Sekunden
long myLastRAsec = 0; // meine letzte Rektaszension in Sekunden
long myLastDECsec = 0; // meine letzte Deklination in Sekunden
long myReferenceRAsec = 0; // meine Rektaszensionsreferenz in Sekunden
long myReferenceDECsec = 0; // meine Deklinationsreferenz in Sekunden
long mySensorRAsec = 0; // Sensorwert der Rektaszension in Sekunden
long mySensorDECsec = 0; // Sensorwert der Deklination in Sekunden
long myTargetRAsec = 0; // Rektaszension des Ziels in Sekunden
long myTargetDECsec = 0; // Deklination des Ziels in Sekunden
const int secPerStepRA = 86400L / IMPULSE24HRA; // defines how many seconds RA is changed per rotary step // (24h * 3600sec = 86400sec) / (1:139 * 20 impulse = 2780) --> 31,079 sec / i
const int secPerStepDEC = 1296000L / IMPULSE360DEGDEC; // defines how many seconds DEC is changed per rotary step // (360° * 3600sec = 1296000sec) / (1:96 * 20 impulse = 1920) / --> 675 sec / i
int myDirectionDEC = 1; // saves the value of the direction of the DEC axis, important if the telescope is turned over
//###############################################################################################################
//###############################################################################################################
// for rotary encoders
//###############################################################################################################
static uint8_t prevNextCode_ROT = 0;
static uint16_t store_ROT = 0;
static uint8_t prevNextCode_RA = 0;
static uint16_t store_RA = 0;
static uint8_t prevNextCode_DEC = 0;
static uint16_t store_DEC = 0;
static int8_t val_ROT, val_RA, val_DEC;
int myImpulseRA = 0, myImpulseDEC = 0;
int myLastImpulseRA = 0, myLastImpulseDEC = 0;
const int8_t enc_table[] = {0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0};
//###############################################################################################################
//###############################################################################################################
// variables for LX200
//###############################################################################################################
byte statusLX200 = 0; // 0 - BT switched off / 1 - BT switched on / 2 - connected via BT & LX200 (frequent connect to LX200)
byte statusLX200old = 0;
byte btStatus = 0; // 0 - off / 1 - on
unsigned long lastLX200Message = 0;
DSOstruct externalObject; // instance LX200 object
//###############################################################################################################
//###############################################################################################################
// setup
//###############################################################################################################
void setup()
{
// for LX200 protocol & debugging
Serial.begin (9600);
// while(!Serial); // attention - only for debugging when in use with IDE!
// Serial.println(F("started"));
getSettingsFromEeprom(); // load settings (brightness,contrast,...)
setReference(); // set reference object to saved values
setTarget(); // set target object to saved values
setupLCD();
createCustomCharacters();
setupRotaryEncoders();
initExternalObject();
}
// software reset https://www.instructables.com/two-ways-to-reset-arduino-in-software/
void(* resetFunc) (void) = 0;//declare reset function at address 0
void setupLCD()
{
lcd.begin(16, 2);
updateLCD();
pinMode(LCD_BACKLIGHT_PIN, OUTPUT);
analogWrite(LCD_CONTRAST_PIN, myLCDcontrast); //set contrast
}
//Creating custom characters in CG-RAM
void createCustomCharacters()
{
lcd.createChar(1 , ch_custom_1);
lcd.createChar(2 , ch_custom_2);
lcd.createChar(3 , ch_custom_3);
lcd.createChar(4 , ch_custom_4);
lcd.createChar(5 , ch_custom_5);
lcd.createChar(6 , ch_custom_6);
lcd.createChar(7 , ch_custom_7);
lcd.createChar(8 , ch_custom_8);
}
void setupRotaryEncoders()
{
// HMI rotary encoder button
pinMode(ROTARY_SW, INPUT_PULLUP);
// HMI rotary encoder
pinMode(ROTARY_CLK, INPUT);
pinMode(ROTARY_DT, INPUT);
// it is better to use the integrated pull-ups of KY-040 (this requires "+" to be connected to 5V) - https://forum.arduino.cc/index.php?topic=242356.0
// as analog pins are used for rotary encoders - internal pull-ups are additionally used to avoid akward behaviour if not connected to sensors
// RA rotary encoder
pinMode(SENS_RA_CLK, INPUT_PULLUP);
pinMode(SENS_RA_DT, INPUT_PULLUP);
// DEC rotary encoder
pinMode(SENS_DEC_CLK, INPUT_PULLUP);
pinMode(SENS_DEC_DT, INPUT_PULLUP);
// switch for BT module
pinMode(BT_SWITCH, OUTPUT);
}
// initialise external object struct for receiving via LX200
void initExternalObject()
{
externalObject.objectPreFixNameNo = 202; // is "external" in DSO PROGMEM
externalObject.objectNumber = 0; // empty - no number in name
externalObject.objectTypeMagnitude = 0;
externalObject.objectConst = 0; // "all" in constellations
externalObject.objectRA = 0;
externalObject.objectDEC = 0;
}
//###############################################################################################################
// \setup
//###############################################################################################################
//###############################################################################################################
// loop
//###############################################################################################################
void loop()
{
analogWrite(LCD_BACKLIGHT_PIN, myLCDbacklight); // LCD backlight analogWrite: values from 0 to 255
updateRotaryEncoderButton();
updateRotaryEncoders();
calcCurrentPosition();
if (myDisplayMode == 9) displaySensorValue();
if (myDisplayMode == 11) displayCurrPos();
if (myDisplayMode == 12) displayTargetPos();
if (myDisplayMode == 13) displayDiffTargetCurrPos();
// LX200 status
updateLX200Status();
readSendLX200();
}
//###############################################################################################################
// \loop
//###############################################################################################################
//###############################################################################################################
// read sensor values
//###############################################################################################################
// reads rotary encoders
void updateRotaryEncoders()
{
if (val_ROT = read_rotary_ROT()) switchSelection(val_ROT);
if (val_RA = read_rotary_RA())
{
mySensorRAsec = mySensorRAsec + val_RA * secPerStepRA;
myImpulseRA = myImpulseRA + val_RA; // for sensor test
}
if (val_DEC = read_rotary_DEC())
{
mySensorDECsec = mySensorDECsec + val_DEC * secPerStepDEC * myDirectionDEC;
myImpulseDEC = myImpulseDEC + val_DEC * myDirectionDEC; // for sensor test
}
}
// reads rotary encoder button
void updateRotaryEncoderButton()
{
// copy from https://arduinogetstarted.com/tutorials/arduino-button-debounce
currentState = digitalRead(ROTARY_SW);
if (currentState != lastFlickerableState)
{
lastDebounceTime = millis();
lastFlickerableState = currentState;
}
if ((millis() - lastDebounceTime) > DEBOUNCE_DELAY)
{
if (lastSteadyState == HIGH && currentState == LOW)
{
switchMode();
updateLCD();
lastPressedTime = millis();
}
else if (lastSteadyState == LOW && currentState == HIGH)
{
// if button pressed > 5 seconds -> reset
if (millis() - lastPressedTime > 5000) resetFunc(); // call reset
}
lastSteadyState = currentState;
}
}
// read rotary encoder for HMI
// robust rotary encoder reading https://www.best-microcontroller-projects.com/rotary-encoder.html
// A vald CW or CCW move returns 1,invalid returns 0.
int8_t read_rotary_ROT()
{
prevNextCode_ROT <<= 2;
if (digitalRead(ROTARY_DT)) prevNextCode_ROT |= 0x02;
if (digitalRead(ROTARY_CLK)) prevNextCode_ROT |= 0x01;
prevNextCode_ROT &= 0x0f;
// If valid then store as 16 bit data.
if (enc_table[prevNextCode_ROT] )
{
store_ROT <<= 4;
store_ROT |= prevNextCode_ROT;
if ((store_ROT & 0xff) == 0x2b) return -1;
if ((store_ROT & 0xff) == 0x17) return 1;
}
return 0;
}
// read rotary encoder for RA
int8_t read_rotary_RA()
{
prevNextCode_RA <<= 2;
if (digitalRead(SENS_RA_DT)) prevNextCode_RA |= 0x02;
if (digitalRead(SENS_RA_CLK)) prevNextCode_RA |= 0x01;
prevNextCode_RA &= 0x0f;
// If valid then store as 16 bit data.
if (enc_table[prevNextCode_RA] )
{
store_RA <<= 4;
store_RA |= prevNextCode_RA;
if ((store_RA & 0xff) == 0x2b) return -1;
if ((store_RA & 0xff) == 0x17) return 1;
}
return 0;
}
// read rotary encoder for DEC
int8_t read_rotary_DEC()
{
prevNextCode_DEC <<= 2;
if (digitalRead(SENS_DEC_DT)) prevNextCode_DEC |= 0x02;
if (digitalRead(SENS_DEC_CLK)) prevNextCode_DEC |= 0x01;
prevNextCode_DEC &= 0x0f;
// If valid then store as 16 bit data.
if (enc_table[prevNextCode_DEC] )
{
store_DEC <<= 4;
store_DEC |= prevNextCode_DEC;
if ((store_DEC & 0xff) == 0x2b) return -1;
if ((store_DEC & 0xff) == 0x17) return 1;
}
return 0;
}
//###############################################################################################################
// read sensor values
//###############################################################################################################
//###############################################################################################################
// get & set of object data
//###############################################################################################################
// returns the type as number of a deep sky object
byte getObjectType(byte typeMagnitude)
{
return (typeMagnitude / 14); // decoding of object type from typeMagnitude
}
// returns the type as string of a deep sky object
String getObjectTypeName(byte typeMagnitude)
{
return myObjectTypeName[(typeMagnitude / 14) - 1];
}
// returns the magnitude of a deep sky object
String getMagnitude(byte typeMagnitude) // calcs the right magnitude - here modulo 14 as coded
{
String strFlMag = (String)(typeMagnitude % 14) + "m";
return strFlMag;
}
// returns the name of a constellation as string from a lookup tabel according to its number
String getConstName(int no)
{
constStruct oneConstellation;
// copy constellations data from PROGMEM into oneConstellation according to no
memcpy_P (&oneConstellation, &const_PROGMEM[no], sizeof oneConstellation);
return (String)oneConstellation.constName;
}
// returns the current constellation for filtering
String getCurrentConstName()
{
String constellationName;
constellationName = getConstName(myConstellationNo);
return constellationName;
}
// returns the current cellestial region
String getSetregionName()
{
return myregionNAME[myRegionNo];
}
// set reference star
void setReference()
{
// copy reference data from PROGMEM into myReference according to myRefNo
memcpy_P (&myReference, &DSO_PROGMEM[myRefNo], sizeof myReference);
setReferenceRA_DEC();
}
// RA and DEC of selected target are set
void setReferenceRA_DEC()
{
// transfer RA / DEC into internal format (seconds)
myReferenceRAsec = calcRAsecFromRA(myReference.objectRA);
myReferenceDECsec = calcDECsecFromDEC(myReference.objectDEC);
}
// set target
void setTarget()
{
// copy reference data from PROGMEM into myTarget according to myTargetNo
memcpy_P (&myTarget, &DSO_PROGMEM[myTargetNo], sizeof myTarget);
setTargetRA_DEC();
}
// RA and DEC of selected target are set
void setTargetRA_DEC()
{
// transfer RA / DEC into internal format (seconds)
myTargetRAsec = calcRAsecFromRA(myTarget.objectRA);
myTargetDECsec = calcDECsecFromDEC(myTarget.objectDEC);
}
//###############################################################################################################
// \get & set of object data
//###############################################################################################################
//###############################################################################################################
// calculations and settings of positions
//###############################################################################################################
// calculation of RA seconds
unsigned int calcRAsecFromRA(unsigned int ra)
{
int h = ra / 1000;
int m = (ra - h * 1000) / 10;
int s = (ra - h * 1000 - m * 10) * 6;
unsigned int raSec = h * 3600L + m * 60 + s;
return raSec;
}
// calculation of DEC seconds
long calcDECsecFromDEC(int dec)
{
int deg = dec / 100;
int m = (dec - deg * 100);
long decSec = deg * 3600L + m * 60;
return decSec;
}
// calculation of current telescope position
void calcCurrentPosition()
{
myCurrentRAsec = myReferenceRAsec + myRefStartTimeSec + mySensorRAsec - millis() / 1000;
myCurrentDECsec = myReferenceDECsec + mySensorDECsec;
}
// sets the sensor values to zero - needed for alignment with reference star
void resetSensorTime()
{
mySensorRAsec = 0; // Sensorwert der Rektaszension
mySensorDECsec = 0; // Sensorwert der Deklination
myRefStartTimeSec = millis() / 1000;
}
//###############################################################################################################
// \calculations and settings of positions
//###############################################################################################################
//###############################################################################################################
// display information
//###############################################################################################################
// display the current position
void displayCurrPos()
{
if (myLastRAsec != myCurrentRAsec || myLastDECsec != myCurrentDECsec)
{
myLastRAsec = myCurrentRAsec;
myLastDECsec = myCurrentDECsec;
displayRA_DEC("Curr ", "Coord", myCurrentRAsec, myCurrentDECsec);
}
}
// display position of selected target
void displayTargetPos()
{
displayRA_DEC(getObjectName(myTarget.objectPreFixNameNo, myTarget.objectNumber, myTarget.objectConst), "Coord", myTargetRAsec, myTargetDECsec);
}
// calulation & display of difference between current position & target position
void displayDiffTargetCurrPos()
{
long diffRAsec = myTargetRAsec - myCurrentRAsec;
long diffDECsec = myTargetDECsec - myCurrentDECsec;
if (myLastRAsec != myCurrentRAsec || myLastDECsec != myCurrentDECsec) // only if position has changed
{
myLastRAsec = myCurrentRAsec;
myLastDECsec = myCurrentDECsec;
displayRA_DEC(getObjectName(myTarget.objectPreFixNameNo, myTarget.objectNumber, myTarget.objectConst), "Diff ", diffRAsec , diffDECsec);
}
}
// display of RA and DEC - generic use for reference stars & target
void displayRA_DEC(String text1, String text2, long rekSec, long dekSec)
{
// Rektaszension //
int sign = 1.0;
if (rekSec < 0) sign = -1.0;
byte s = (abs(rekSec)) % 60; // Das Zeichen: "%" ist der Modulo-Operator // vorher int
byte m = (abs(rekSec / 60)) % 60;
byte h = (abs(rekSec / 3600)) % 24;
lcd.setCursor(0, 0);
printObjectName(text1);
lcd.setCursor(8, 0);
if (sign < 0) lcd.print(F("-"));
else lcd.print(F("+"));
if (h < 10) lcd.print(F(" "));
lcd.print(h);
lcd.print(F(":"));
if (m < 10) lcd.print(F("0"));
lcd.print(m);
lcd.print(F(","));
lcd.print(s / 6);
// DEC // +90° - -90°
sign = 1.0;
if (dekSec < 0) sign = -1.0;
s = (abs(dekSec)) % 60; // Das Zeichen: "%" ist der Modulo-Operator
m = (abs(dekSec / 60)) % 60;
h = (abs(dekSec / 3600)) % 180;
lcd.setCursor(0, 1);
lcd.print(text2);
lcd.setCursor(8, 1);
if (sign < 0) lcd.print(F("-"));
else lcd.print(F("+"));
if (h < 10) lcd.print(F(" "));
lcd.print(h);
lcd.print(ch_deg);
if (m < 10) lcd.print(F("0"));
lcd.print(m);
lcd.print(F("'"));
}
// display current sensor values
void displaySensorValue()
{
if (myImpulseRA != myLastImpulseRA || myImpulseDEC != myLastImpulseDEC)
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Imp RA"));
lcd.setCursor(0, 1);
lcd.print(F("Imp DEC"));
lcd.setCursor(10, 0);
lcd.print(myImpulseRA);
lcd.setCursor(10, 1);
lcd.print(myImpulseDEC);
myLastImpulseRA = myImpulseRA;
myLastImpulseDEC = myImpulseDEC;
}
}
// update LCD according to selected display mode
void updateLCD()
{
lcd.clear();
lcd.setCursor(0, 0);
if (myDisplayMode == 0)
{
lcd.print(F("SpotNik v")); // DO NOT REMOVE
lcd.print(VERSION);
lcd.setCursor(0, 1);
lcd.print(F("developed by MR")); // DO NOT REMOVE
}
if (myDisplayMode == 1) // main menu
{
lcd.print(F(">"));
lcd.setCursor(1, 0);
lcd.print(menuTopic[myMenuTopicNo]); // {" reverse", "Ref","Target","region","Const","Bright","Contr","Test"};
lcd.setCursor(8, 0);
switch (myMenuTopicNo) {
case 0:
if (myDirectionDEC == 1) lcd.print(F("normal"));
else lcd.print(F("reverse"));
break;
case 1:
printObjectName(getObjectName(myReference.objectPreFixNameNo, myReference.objectNumber, myReference.objectConst));
break;
case 2:
printObjectName(getObjectName(myTarget.objectPreFixNameNo, myTarget.objectNumber, myTarget.objectConst));
//if (statusLX200 != 2) printObjectName(getObjectName(myTarget.objectPreFixNameNo,myTarget.objectNumber,myTarget.objectConst));
//else lcd.print(F("external")); // if connection to LX200 source - no usage of internal star database
break;
case 3:
lcd.print(getSetregionName());
// if (statusLX200 != 2) lcd.print(getSetregionName());
// else lcd.print(F("external"));
break;
case 4:
lcd.print(getCurrentConstName());
// if (statusLX200 != 2) lcd.print(getCurrentConstName());
// else lcd.print(F("external"));
break;
case 8:
if (statusLX200 == 0) lcd.print(F("BT off"));
if (statusLX200 == 1) lcd.print(F("BT on"));
if (statusLX200 == 2) lcd.print(F("conn"));
break;
}
lcd.setCursor(1, 1);
if (myMenuTopicNo + 1 < menuTopic_size)
{
lcd.print(menuTopic[myMenuTopicNo + 1]);
}
else
{
lcd.print(menuTopic[0]);
}
}
if (myDisplayMode == 2)
{
lcd.print(F("Direction of DEC"));
lcd.setCursor(0, 1);
lcd.print(F(">"));
if (myDirectionDEC == 1) lcd.print(F("normal"));
else lcd.print(F("reverse"));
}
if (myDisplayMode == 3)
{
printObjectName(getObjectName(myReference.objectPreFixNameNo, myReference.objectNumber, myReference.objectConst));
lcd.setCursor(13, 0);
lcd.print(getConstName(myReference.objectConst));
lcd.setCursor(0, 1);
lcd.print(getObjectTypeName(myReference.objectTypeMagnitude));
lcd.setCursor(13, 1);
lcd.print(getMagnitude(myReference.objectTypeMagnitude));
}
if (myDisplayMode == 4)
{
printObjectName(getObjectName(myTarget.objectPreFixNameNo, myTarget.objectNumber, myTarget.objectConst));
lcd.setCursor(13, 0);
lcd.print(getConstName(myTarget.objectConst));
lcd.setCursor(0, 1);
lcd.print(getObjectTypeName(myTarget.objectTypeMagnitude));
lcd.setCursor(13, 1);
lcd.print(getMagnitude(myTarget.objectTypeMagnitude));
}
if (myDisplayMode == 5)
{
lcd.print(F("Celestial Region"));
lcd.setCursor(0, 1);
lcd.print(F(">"));
lcd.print(getSetregionName());
}
if (myDisplayMode == 6)
{
lcd.print(F("Constellation"));
lcd.setCursor(11, 1);
lcd.print(getSetregionName());
lcd.setCursor(0, 1);
lcd.print(F(">"));
lcd.print(getCurrentConstName());
}
if (myDisplayMode == 7)
{
lcd.print(F("LCD Brightness"));
lcd.setCursor(0, 1);
lcd.print(F(">"));
lcd.print(myLCDbacklight);
}
if (myDisplayMode == 8)
{
lcd.print(F("LCD Contrast"));
lcd.setCursor(0, 1);
lcd.print(F(">"));
lcd.print(myLCDcontrast);
}
if (myDisplayMode == 9)
{
lcd.print(F("For test"));
lcd.setCursor(0, 1);
lcd.print(F("turn DEC / RA"));
myImpulseRA = 0;
myImpulseDEC = 0;
myLastImpulseRA = 0;
myLastImpulseDEC = 0;
}
if (myDisplayMode == 10)
{
lcd.print(F("LX200 Connection"));
lcd.setCursor(0, 1);
lcd.print(F(">"));
if (statusLX200 == 0) lcd.print(F("Bluetooth off"));
if (statusLX200 == 1) lcd.print(F("Bluetooth on"));
if (statusLX200 == 2) lcd.print(F("LX200 connected"));
}
}
// returns name of deep sky object based on coded name its number and its constellation
String getObjectName(byte objectprefixNameNo, unsigned int objectNumber, byte objectConst)
{
String objectName = "";
int indexOfHash = -1;
DSONameStruct oneDSONameStruct;
if (objectprefixNameNo > 0)
{
// get name accordng to name number from lookup table
memcpy_P (&oneDSONameStruct, &DSO_NAME_PROGMEM[objectprefixNameNo - 1], sizeof oneDSONameStruct);
objectName = oneDSONameStruct.objectName;
indexOfHash = objectName.indexOf('#');
if (indexOfHash > -1)
{
// replace char with greek char
String charToReplace = objectName.substring(indexOfHash + 1, indexOfHash + 2);
objectName = objectName.substring(0, indexOfHash) + objectName.substring(indexOfHash + 2); // delete # and next char from string
// loop over the greek symbols
for (int i; i < greekSymbols_size; i++)
{
if ((String)charToReplace == (String)greekSymbols[i].originalChar)
{
charToReplace = greekSymbols[i].replaceChar;
objectName = objectName + charToReplace;
break;
}
}
}
}
if (objectNumber > 0)
{
objectName = objectName + (String)objectNumber;
}
// if object is only number,greek Symbol or max. two characters,accept 'M' - add constellation for identification
if (objectName.charAt(1) == NULL || objectprefixNameNo == 0 || (objectName.charAt(2) == NULL && objectNumber == 0)) // oder nur Zahlen!!!
{
objectName = objectName + ' ' + getConstName(objectConst);
}
return objectName;
}
// some greek symbols are custom, print function needed
void printObjectName(String objectName)
{
byte customChar = 0;
char charAt0 = objectName.charAt(0);
if (charAt0 == ch_def_1) customChar = 1;
else if (charAt0 == ch_def_2) customChar = 2;
else if (charAt0 == ch_def_3) customChar = 3;
else if (charAt0 == ch_def_4) customChar = 4;
else if (charAt0 == ch_def_5) customChar = 5;
else if (charAt0 == ch_def_6) customChar = 6;
else if (charAt0 == ch_def_7) customChar = 7;
if (customChar > 0) lcd.write(customChar);
else
{
lcd.print(objectName);
return;
}
lcd.print(F(" "));
lcd.print(objectName.substring(2, 8));
}
//###############################################################################################################
// \display information
//###############################################################################################################
//###############################################################################################################
// switching
//###############################################################################################################
// myDisplayMode - rotary encoder for change
// 0 = welcome, 1 = top menu, 2 = change direction, 3 = set reference, 4 = set target, 5 = set region, 6 = set constellation, 7 = set LCD brightness, 8 = set LCD contrast
// 9 = sensor test, 10 = set bluetooth, 11 = show current position, 12 = show target position, 13 = show difference target - current position
void switchMode()
{
saveSettingsToEeprom(); // save settings to eeprom each time the button is pressed
if (myDisplayMode == 0) // welcome
{
myDisplayMode = 1; // top menue
}
else if (myDisplayMode == 1)
{
myDisplayMode = myMenuTopicNo + 2;
}
else if (myDisplayMode == 3) // set reference
{
resetSensorTime();
myLastDECsec = 0; // set once to zero to update display
myDisplayMode = 11; // show current position
}
else if (myDisplayMode == 4) // set target
{
setTargetRA_DEC();
myDisplayMode = 13; // show diff position
}
// set direction // region // constellation // set brightness // set contrast // sensor test // show current position // show diff position
else if (myDisplayMode == 2 || myDisplayMode >= 5)
{
myDisplayMode = 1; // return to top level menu
}
lcd.clear();
}
// function of rotary encoder changes acording to current display mode
void switchSelection(int dir)
{
if (myDisplayMode == 0)
{
myDisplayMode = 1;
updateLCD();
}
else if (myDisplayMode == 1) changeMenu(dir);
if (myDisplayMode == 2) changeDirectionDEC(dir);
if (myDisplayMode == 3) changeReference(dir);
if (myDisplayMode == 4) changeTarget(dir);
if (myDisplayMode == 5) changeregion(dir);
if (myDisplayMode == 6) changeConstellation(dir);
if (myDisplayMode == 7) changeLCDBacklight(dir);
if (myDisplayMode == 8) changeLCDcontrast(dir);
if (myDisplayMode == 10) changeBTconnection(dir);
if (myDisplayMode == 11 || myDisplayMode == 12 || myDisplayMode == 13) changeView(dir);
updateLCD();
}
// change menu topics
void changeMenu(int dir)
{
if (dir == 1)
{
if ((myMenuTopicNo + 1) < menuTopic_size)
{
myMenuTopicNo = myMenuTopicNo + 1;
}
else
{
myMenuTopicNo = 0;
}
}
else if (dir == -1)
{
if (myMenuTopicNo > 0)
{
myMenuTopicNo = myMenuTopicNo - 1;
}
else
{
myMenuTopicNo = menuTopic_size - 1;
}
}
}
// according to the direction of the DEC axis the value of the DEC sensor has to be reverted
void changeDirectionDEC(int dir)
{
if (dir == 1 || dir == -1)
{
if (myDirectionDEC == 1) myDirectionDEC = -1;
else myDirectionDEC = 1;
}
}
// calls changeObject for object type reference
void changeReference (int dir)
{
changeObject(dir, 'r');
}
// calls changeObject for object type target
void changeTarget(int dir)
{
changeObject(dir, 't');
}
// change referenc star including filter according to selected sky region
void changeObject (int dir, char objectType)
{
bool constFound = false;
DSOstruct oneObject; // instance of reference for search & filter
unsigned int objectNo;
unsigned int numberOfLoops = 0;
if (objectType == 'r')
{
objectNo = myRefNo; // set start no of object
}
else
{
objectNo = myTargetNo;
}
while (constFound == false)
{
if (dir == 1)
{
if ((objectNo + 1) < DSO_PROGMEM_size)
{
objectNo = objectNo + 1;
}
else
{
objectNo = 0;
}
}
if (dir == -1) // before else if - but what if no fitting star at beginning before rotary turning?
{
if (objectNo > 0)
{
objectNo = objectNo - 1;
}
else
{
objectNo = DSO_PROGMEM_size - 1;
}
}
memcpy_P (&oneObject, &DSO_PROGMEM[objectNo], sizeof oneObject); // get next DSO object from struct and copy it into oneObject
// filter on a constellation
// if a constellation is selected,object is a target and constellation of object fits to selected constellation
if (objectType == 't' && myConstellationNo > 0 && getObjectType(oneObject.objectTypeMagnitude) > 0 && getObjectType(oneObject.objectTypeMagnitude) < 12 && oneObject.objectConst == myConstellationNo)
{
constFound = true;
}
// filter on regions
else if ( (objectType == 'r' && getObjectType(oneObject.objectTypeMagnitude) == 12) || // reference stars // filter on objects of type "reference" = no 12
(myConstellationNo == 0 && objectType == 't' && getObjectType(oneObject.objectTypeMagnitude) > 0 && getObjectType(oneObject.objectTypeMagnitude) < 12)) // target objects
{
// filter targets by constellations of the selected region
// myregionNAME[]={"All","North","Spring","Summer","Autumn","Winter","South"};
if (myRegionNo == 1) // region = north
{
for (int i = 0; i < myNorthCONST_size; i++)
{
if (oneObject.objectConst == myNorthCONST[i])
{
constFound = true;
break;
}
}
}
else if (myRegionNo == 2) // region = spring
{
for (int i = 0; i < mySpringCONST_size; i++)
{
if (oneObject.objectConst == mySpringCONST[i])
{
constFound = true;
break;
}
}
}
else if (myRegionNo == 3) // region = summer
{
for (int i = 0; i < mySummerCONST_size; i++)
{
if (oneObject.objectConst == mySummerCONST[i])
{
constFound = true;
break;
}
}
}
else if (myRegionNo == 4) // region = autumn
{
for (int i = 0; i < myAutumnCONST_size; i++)
{
if (oneObject.objectConst == myAutumnCONST[i])
{
constFound = true;
break;
}
}
}
else if (myRegionNo == 5) // region = winter
{
for (int i = 0; i < myWinterCONST_size; i++)
{
if (oneObject.objectConst == myWinterCONST[i])
{
constFound = true;
break;
}
}
}
else if (myRegionNo == 6) // region = south
{
for (int i = 0; i < mySouthCONST_size; i++)
{
if (oneObject.objectConst == mySouthCONST[i])
{
constFound = true;
break;
}
}
}
else // all constellations
{
constFound = true;
}
}
}// end while
if (objectType == 'r')
{
myRefNo = objectNo;
myReference = oneObject; // copy selected reference object in my reference object
setReferenceRA_DEC();
}
else
{
myTargetNo = objectNo;
myTarget = oneObject; // copy selected target object in my target object
setTargetRA_DEC();
}
updateLCD();
}
// change region
void changeregion(int dir)
{
if (dir == 1)
{
if ((myRegionNo + 1) < regionArraySize) {
myRegionNo = myRegionNo + 1;
}
else {
myRegionNo = 0;
}
}
else if (dir == -1)
{
if (myRegionNo > 0) {
myRegionNo = myRegionNo - 1;
}
else {
myRegionNo = regionArraySize - 1;
}
}
myTargetNo = 0; // reset target,when aera has changed
myConstellationNo = 0; // reset constellation,when aera has changed
updateLCD();
}
// set constellation
void changeConstellation(int dir)
{
bool constFound = false;
while (constFound == false)
{
if (dir == 1)
{
if ((myConstellationNo) < constStruct_size - 1) {
myConstellationNo = myConstellationNo + 1;
}
else {
myConstellationNo = 0;
}
}
else if (dir == -1)
{
if (myConstellationNo > 0) {
myConstellationNo = myConstellationNo - 1;
}
else {
myConstellationNo = constStruct_size - 1;
}
}
// filter targets by constellations of the selected region
// myregionNAME[]={"All","North","Spring","Summer","Autumn","Winter","South"};
if (myRegionNo == 1) // region = north
{
for (int i = 0; i < myNorthCONST_size; i++)
{
if (myConstellationNo == myNorthCONST[i])
{
constFound = true;
break;
}
}
}
else if (myRegionNo == 2) // region = spring
{
for (int i = 0; i < mySpringCONST_size; i++)
{
if (myConstellationNo == mySpringCONST[i])
{
constFound = true;
break;
}
}
}
else if (myRegionNo == 3) // region = summer
{
for (int i = 0; i < mySummerCONST_size; i++)
{
if (myConstellationNo == mySummerCONST[i])
{
constFound = true;
break;
}
}
}
else if (myRegionNo == 4) // region = autumn
{
for (int i = 0; i < myAutumnCONST_size; i++)
{
if (myConstellationNo == myAutumnCONST[i])
{
constFound = true;
break;
}
}
}
else if (myRegionNo == 5) // region = winter
{
for (int i = 0; i < myWinterCONST_size; i++)
{
if (myConstellationNo == myWinterCONST[i])
{
constFound = true;
break;
}
}
}
else if (myRegionNo == 6) // region = south
{
for (int i = 0; i < mySouthCONST_size; i++)
{
if (myConstellationNo == mySouthCONST[i])
{
constFound = true;
break;
}
}
}
else // all constellations
{
for (int i = 0; i < myAllCONST_size; i++)
{
if (myConstellationNo == myAllCONST[i])
{
constFound = true;
break;
}
}
}
}
myTargetNo = 0; // reset target every time when constellation was changed
updateLCD();
}
// switch view between current position, diff position & target coordinates
void changeView(int dir)
{
lcd.clear();
myDisplayMode = myDisplayMode + dir;
if (myDisplayMode > 13) myDisplayMode = 11;
if (myDisplayMode < 11) myDisplayMode = 13;
}
// set LCD brightness
void changeLCDBacklight(int dir)
{
myLCDbacklight = myLCDbacklight + dir * 8;
if (myLCDbacklight > 255) myLCDbacklight = 0;
if (myLCDbacklight < 0) myLCDbacklight = 255;
}
// set LCD contrast
void changeLCDcontrast(int dir)
{
myLCDcontrast = myLCDcontrast + dir * 5;
if (myLCDcontrast > 255) myLCDcontrast = 0;
if (myLCDcontrast < 0) myLCDcontrast = 255;
analogWrite(LCD_CONTRAST_PIN, myLCDcontrast);
}
// 0 - BT switched off / 1 - BT switched on
void changeBTconnection(int dir)
{
if (btStatus == 0) // switch BT on if off
{
btStatus = 1;
statusLX200 = 1;
digitalWrite(BT_SWITCH, HIGH);
}
else if (btStatus != 0) // switch BT off
{
btStatus = 0;
statusLX200 = 0;
digitalWrite(BT_SWITCH, LOW);
}
updateLCD();
}
//###############################################################################################################
// \switching
//###############################################################################################################
//###############################################################################################################
// LX200 communication
//###############################################################################################################
// set the status of LX200 to control LCD etc
void updateLX200Status()
{
// 0 - BT switched off / 1 - BT switched on
if (btStatus == 1)
{
// if frequent feedback from LX200 - last request > 4 sek
if ((millis() - lastLX200Message) > 4000)
{
statusLX200 = 1; // BT on - but no LX200 connection
}
else
{
statusLX200 = 2; // LX200 connected
}
}
// LX200 status changend - update lcd in relevant views (main menu & BT)
if (statusLX200 != statusLX200old && (myDisplayMode == 10 || myDisplayMode == 1))
{
updateLCD();
statusLX200old = statusLX200;
}
}
// called if a LX200 message was received
void receivedLX200message() // received
{
lastLX200Message = millis();
}
// read the bluetooth message and trigger functions according to message type
void readSendLX200()
{
if (Serial.available())
{
char message[14] = "";
byte i = 0;
while (Serial.available() > 0)
{
char a = Serial.read(); // Stores current byte
message[i] += a; // Append current byte to message String
delay(10);
i++;
}
// all LX200 info from https://www.meade.com/support/TelescopeProtocol_2010-10.pdf
// LX200 message :GR#
// Get Telescope RA
// Returns: HH:MM.T# or HH:MM:SS#Depending which precision is set for the telescope
if (message[0] == ':' && message[1] == 'G' && message[2] == 'R' && message[3] == '#')
{
receivedLX200message();
sendLX200RA();
}
// LX200 message :GD# or :RS#:GD# or :RM#:GD#
// Get Telescope Declination.
// Returns: sDD*MM# or sDD*MM’SS#Depending upon the current precision setting for the telescope.
if (message[0] == ':' && message[1] == 'G' && message[2] == 'D' && message[3] == '#' ||
message[4] == ':' && message[5] == 'G' && message[6] == 'D' && message[7] == '#')
{
receivedLX200message();
sendLX200DEC();
}
// LX200 message :CM#
// Synchronizes the telescope's position with the currently selected database object's coordinates.
// Returns:LX200's - a "#" terminated string with the name of the object that was synced
if (message[0] == ':' && message[1] == 'C' && message[2] == 'M')
{
receivedLX200message();
Serial.print("#");
}
// LX200 message :SrHH:MM.T# or :SrHH:MM:SS#
// Set target object RA to HH:MM.T or HH:MM:SS depending on the current precision setting.
// Returns:0 – Invalid1 - Valid
// output HHMM(S/6)
if (message[0] == ':' && message[1] == 'S' && message[2] == 'r')
{
setRAtoLX200message(message);
}
// LX200 message :SdsDD*MM#
// Set target object declination to sDD*MM or sDD*MM:SS depending on the current precision setting
// Returns:1 - Dec Accepted0 – Dec invalid
// output sHHMM
if (message[0] == ':' && message[1] == 'S' && message[2] == 'd')
{
setDECtoLX200message(message);
}
// Serial.print("BT message "); // for debugging
// Serial.println(message);
}
}
// set RA coordinates of placeholder externalobject to received LX200 message
void setRAtoLX200message(char message[10])
{
externalObject.objectRA =
long(atoi(message + 3)) * 1000 + // HH // access at array different when using atoi - use address
long(atoi(message + 6)) * 10; // MM - Minuten passen noch nicht bei zweistelligen gibt es Fehler
if (message[8] == ':') // : or .
{
externalObject.objectRA = externalObject.objectRA +
long(atoi(message + 9)) / 6; // SS/6
}
else if (message[8] == '.')
{
externalObject.objectRA = externalObject.objectRA + atoi(message + 9); // T
}
Serial.println(); // leave this command, as otherwise no update on goto from LX200 source
}
// set DEC coordinates of placeholder externalobject to received LX200 message & update the (reference or target) object
void setDECtoLX200message(char message[9])
{
int sign;
if (message[3] == '-') sign = -1;
else sign = 1;
externalObject.objectDEC =
sign * ( // s
long(atoi(message + 4)) * 100 + // DD
long(atoi(message + 7))); // MM
// assumption - first RA then DEC - then set target to external object
if (myDisplayMode == 3 || myDisplayMode == 11) // if view shows reference selection or current position then copy external object into reference object
{
externalObject.objectTypeMagnitude = 168;
myReference = externalObject; // copy external object to my reference object
setReferenceRA_DEC();
resetSensorTime();
}
else // in all other cases copy to target
{
externalObject.objectTypeMagnitude = 182;
myTarget = externalObject; // copy external object to my target object
setTargetRA_DEC();
}
updateLCD();
}
// send current RA coordinate of telescope from SpotNik to LX200 server (e.g. Sky Safari)
void sendLX200RA()
{
byte s = (abs(myCurrentRAsec)) % 60; // Das Zeichen: "%" ist der Modulo-Operator
byte m = (abs(myCurrentRAsec / 60)) % 60;
byte h = (abs(myCurrentRAsec / 3600)) % 24;
String posString = "";
if (h < 10) posString = "0";
posString = posString + String(h);
posString = posString + ":";
if (m < 10) posString = posString + "0";
posString = posString + String(m);
posString = posString + ":";
if (s < 10) posString = posString + "0";
posString = posString + String(s);
posString = posString + "#";
Serial.print(posString);
}
// send current DEC coordinate of telescope from SpotNik to LX200 server (e.g. Sky Safari)
void sendLX200DEC()
{
byte s = (abs(myCurrentDECsec)) % 60; // Das Zeichen: "%" ist der Modulo-Operator
byte m = (abs(myCurrentDECsec / 60)) % 60;
byte h = (abs(myCurrentDECsec / 3600)) % 180;
String posString = "";
if (myCurrentDECsec > 0) posString = "+";
else posString = "-";
if (h < 10) posString = "0";
posString = posString + String(h);
posString = posString + "*";
if (m < 10) posString = posString + "0";
posString = posString + String(m);
posString = posString + "#";
Serial.print(posString);
}
//###############################################################################################################
// \LX200 communication
//###############################################################################################################
//###############################################################################################################
// EEPROM
//###############################################################################################################
// save relevant data for next startup (e.g. target no,LCD brightness)
void saveSettingsToEeprom()
{
// Serial.print(F("freeMemory()=")); //only used for testing
// Serial.println(freeMemory());
byte addr = EEPROM_VALUE_ADDR_SIGNATURE;
byte myTargetNoLowByte = lowByte(myTargetNo); // myTargetNo is of type int - transfer into two bytes
byte myTargetNoHighByte = highByte(myTargetNo);
byte myReferenceNoLowByte = lowByte(myRefNo); // myTargetNo is of type int - transfer into two bytes
byte myReferenceNoHighByte = highByte(myRefNo);
EEPROM.update(addr, EEPROM_SIGNATURE); // use update for longer eeprom life
addr += sizeof(EEPROM_SIGNATURE);
EEPROM.update(addr, myReferenceNoLowByte);
addr += sizeof(myReferenceNoLowByte);
EEPROM.update(addr, myReferenceNoHighByte);
addr += sizeof(myReferenceNoHighByte);
EEPROM.update(addr, myTargetNoLowByte);
addr += sizeof(myTargetNoLowByte);
EEPROM.update(addr, myTargetNoHighByte);
addr += sizeof(myTargetNoHighByte);
EEPROM.update(addr, myRegionNo);
addr += sizeof(myRegionNo);
EEPROM.update(addr, myConstellationNo);
addr += sizeof(myConstellationNo);
EEPROM.update(addr, myLCDbacklight);
addr += sizeof(myLCDbacklight);
EEPROM.update(addr, myLCDcontrast);
}
// load relevant data at startup (e.g. target no, LCD brightness)
void getSettingsFromEeprom()
{
byte addr = EEPROM_VALUE_ADDR_SIGNATURE, signature = 0, value, myReferenceNoLowByte, myReferenceNoHighByte, myTargetNoLowByte, myTargetNoHighByte; // myTargetNo is of type int,need to concatenated from two bytes
EEPROM.get(addr, signature);
if (signature != EEPROM_SIGNATURE) return; // maybe data from another sketch
addr += sizeof(EEPROM_SIGNATURE);
EEPROM.get(addr, value);
myReferenceNoLowByte = value;
addr += sizeof(myReferenceNoLowByte);
EEPROM.get(addr, value);
myReferenceNoHighByte = value;
if (value >= 0 && value <= 32767) myRefNo = word(myReferenceNoHighByte, myReferenceNoLowByte);
addr += sizeof(myReferenceNoHighByte);
EEPROM.get(addr, value);
myTargetNoLowByte = value;
addr += sizeof(myTargetNoLowByte);
EEPROM.get(addr, value);
myTargetNoHighByte = value;
if (value >= 0 && value <= 32767) myTargetNo = word(myTargetNoHighByte, myTargetNoLowByte);
addr += sizeof(myTargetNoHighByte);
EEPROM.get(addr, value);
if (value >= 0 && value <= 255) myRegionNo = value;
addr += sizeof(myRegionNo);
EEPROM.get(addr, value);
if (value >= 0 && value <= 255) myConstellationNo = value;
addr += sizeof(myConstellationNo);
EEPROM.get(addr, value);
if (value >= 0 && value <= 255) myLCDbacklight = value;
addr += sizeof(myLCDbacklight);
EEPROM.get(addr, value);
if (value >= 0 && value <= 255) myLCDcontrast = value;
}
//###############################################################################################################
// \EEPROM
//###############################################################################################################
}
void loop() {
// put your main code here, to run repeatedly:
}
So. That's the code that I cannot upload to the Arduino Uno R3 board or the Arduino mega either won't work for me!
So, here is a copy off the error report which was generated after an upload attempt.
Hi David, I just tried out what you suggested and sadly--no luck.
here's a copy of the error report from the arduino IDE
Arduino: 1.8.20 Hourly Build 2021/12/20 07:33 (Windows 10), Board: "Arduino Mega or Mega 2560, ATmega2560 (Mega 2560)"
type or paste code here
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\sketch_jul09c\sketch_jul09c.ino: In function 'void setup()':
sketch_jul09c:3:3: error: 'SpotNik' was not declared in this scope
SpotNik - by Max Reinecke
^~~~~~~
sketch_jul09c:3:13: error: 'by' was not declared in this scope
SpotNik - by Max Reinecke
^~
sketch_jul09c:12:31: error: 'without' was not declared in this scope
but WITHOUT ANY WARRANTY; without even the implied warranty of
^~~~~~~
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\sketch_jul09c\sketch_jul09c.ino:12:31: note: suggested alternative: 'stdout'
but WITHOUT ANY WARRANTY; without even the implied warranty of
^~~~~~~
stdout
In file included from C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\sketch_jul09c\sketch_jul09c.ino:29:0:
\\admin-che\c$\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\EEPROM\src/EEPROM.h:130:5: error: invalid declaration of member template in local class
template< typename T > T &get( int idx, T &t ){
^~~~~~~~
\\admin-che\c$\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\EEPROM\src/EEPROM.h:137:5: error: invalid declaration of member template in local class
template< typename T > const T &put( int idx, const T &t ){
^~~~~~~~
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\sketch_jul09c\sketch_jul09c.ino:1495:1: warning: narrowing conversion of '129989' from 'long int' to 'unsigned int' inside { } [-Wnarrowing]
};
^
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\sketch_jul09c\sketch_jul09c.ino:1495:1: warning: large integer implicitly truncated to unsigned type [-Woverflow]
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\sketch_jul09c\sketch_jul09c.ino:1495:1: warning: narrowing conversion of '189256' from 'long int' to 'unsigned int' inside { } [-Wnarrowing]
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\sketch_jul09c\sketch_jul09c.ino:1495:1: warning: large integer implicitly truncated to unsigned type [-Woverflow]
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\sketch_jul09c\sketch_jul09c.ino:1495:1: warning: narrowing conversion of '106516' from 'long int' to 'unsigned int' inside { } [-Wnarrowing]
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\sketch_jul09c\sketch_jul09c.ino:1495:1: warning: large integer implicitly truncated to unsigned type [-Woverflow]
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\sketch_jul09c\sketch_jul09c.ino:1495:1: warning: narrowing conversion of '109003' from 'long int' to 'unsigned int' inside { } [-Wnarrowing]
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\sketch_jul09c\sketch_jul09c.ino:1495:1: warning: large integer implicitly truncated to unsigned type [-Woverflow]
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\sketch_jul09c\sketch_jul09c.ino:1495:1: warning: narrowing conversion of '128396' from 'long int' to 'unsigned int' inside { } [-Wnarrowing]
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\sketch_jul09c\sketch_jul09c.ino:1495:1: warning: large integer implicitly truncated to unsigned type [-Woverflow]
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\sketch_jul09c\sketch_jul09c.ino:1495:1: warning: narrowing conversion of '113801' from 'long int' to 'unsigned int' inside { } [-Wnarrowing]
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\sketch_jul09c\sketch_jul09c.ino:1495:1: warning: large integer implicitly truncated to unsigned type [-Woverflow]
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\sketch_jul09c\sketch_jul09c.ino:1495:1: warning: narrowing conversion of '157721' from 'long int' to 'unsigned int' inside { } [-Wnarrowing]
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\sketch_jul09c\sketch_jul09c.ino:1495:1: warning: large integer implicitly truncated to unsigned type [-Woverflow]
sketch_jul09c:1518:1: error: 'LiquidCrystal' was not declared in this scope
LiquidCrystal lcd(rs,en,d4,d5,d6,d7);
^~~~~~~~~~~~~
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\sketch_jul09c\sketch_jul09c.ino:1518:1: note: suggested alternative: 'LiquidCrystal_h'
LiquidCrystal lcd(rs,en,d4,d5,d6,d7);
^~~~~~~~~~~~~
LiquidCrystal_h
sketch_jul09c:1777:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:1796:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:1805:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:1817:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:1840:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:1856:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:1881:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:1899:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:1930:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:1949:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:1968:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:1994:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:2000:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:2006:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:2013:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:2022:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:2030:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:2036:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:2044:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:2052:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:2060:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:2075:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:2085:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:2094:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:2101:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:2116:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:2127:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:2133:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:2147:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:2190:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:2209:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:2353:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:2401:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:2433:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:2465:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:2487:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:2514:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:2524:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:2530:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:2536:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:2680:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:2706:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:2815:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:2824:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:2832:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:2841:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:2866:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:2891:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:2897:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:2963:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:2982:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:3011:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:3031:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:3057:1: error: a function-definition is not allowed here before '{' token
{
^
sketch_jul09c:3088:1: error: a function-definition is not allowed here before '{' token
{
^
exit status 1
'SpotNik' was not declared in this scope
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
Apart from any other problems you have two setup() functions in your sketch as pointed out by @david_2018
Start by deleting the first line of code, ie this one
void setup() {
or copy the fixed version that he posted
You also have two loop() functions, again not allowed. @david_2018 also fixed that
Hi Uk Helibob, I copied Daves suggested altered sketch and tried running/uploading more endless error messages I'm afraid.........here's a copy of the sketch followed by the error messages. Thanks for your help in this matter, much appreciated.
void setup() {
// /* ///////////////////////////////////////////////////////////////////////////////////
SpotNik - by Max Reinecke
Created: May 2021
SpotNik is software for a stepto system for telescopes
This program is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see < http : //www.gnu.org/licenses/>.
/////////////////////////////////////////////////////////////////////////////////*/
#define VERSION 2.0
//###############################################################################################################
// to be changed by user according to EQ mount - see instructions
// total numbers of impulse of the rotary encoder of RA axis when turned 24h
#define IMPULSE24HRA 2772 // 6h - 690 Impulse --> 24h - 4 * 693 = 2772 / ~ 1:138
// total numbers of impulse of the rotary encoder of DEC axis when turned 360° // +/- for correct direction
#define IMPULSE360DEGDEC 1784 // 90° - 446 Impulse --> 360° - 4 * 446 = 1784 / ~ 1:88
//###############################################################################################################
#include <LiquidCrystal.h> // I2C LCD arbeitet nicht vernünftig mit Rotary Encoder zusammen,daher normales nehmen
#include <EEPROM.h>
//#include <MemoryFree.h> // only used for testing
//###############################################################################################################
// LCD
#define LCD_CONTRAST_PIN 11 // LCD contrast - V0 // use high frequency PWM to avoid flickering (Leonardo,Micro,Yún 3 and 11: 980 Hz // Mega pins 4 and 13: 980 Hz)
#define LCD_BACKLIGHT_PIN 10 // LCD backlight - LCD A
// EEPROM
#define EEPROM_SIGNATURE 117 // value 0-255 (byte) - signature/mark to recognize if the value fits to this sketch
#define EEPROM_VALUE_ADDR_SIGNATURE 0
// rotary enoder HMI
#define ROTARY_SW 3 // use interrupt pin - digital pins for interrupts on Micro,Leonardo and other 32u4 based 0,1,2,3,7
#define ROTARY_DT 4
#define ROTARY_CLK 5
// Sensor RA
#define SENS_RA_DT A0 // analog pins used as UNO has not that many digital pins
#define SENS_RA_CLK A1
// Sensor DEC
#define SENS_DEC_DT A2
#define SENS_DEC_CLK A3
// LX200 connection
#define BT_SWITCH 2
//###############################################################################################################
// lookup table with names of deep sky objects
//###############################################################################################################
struct DSONameStruct
{
char objectName[9];
};
const struct DSONameStruct DSO_NAME_PROGMEM[202] PROGMEM =
{
{"3C273"},
{"B"},
{"IC"},
{"M"},
{"NGC"},
{"#a"},
{"#aA"},
{"#aB"},
{"#b"},
{"#c"},
{"#d"},
{"#e"},
{"#e1"},
{"#e2"},
{"#g"},
{"#h"},
{"#i"},
{"#j"},
{"#k"},
{"#l"},
{"#m"},
{"#n"},
{"#o"},
{"#p"},
{"#q"},
{"#r"},
{"#s"},
{"#t"},
{"#u"},
{"#w"},
{"#x"},
{"#z"},
{"AC"},
{"Achernar"},
{"Acrab"},
{"Acrux"},
{"Adhara"},
{"Agena"},
{"Alamak"},
{"Aldebara"},
{"Alderami"},
{"AlDhanab"},
{"Algenib"},
{"Algieba"},
{"Algol"},
{"Alhena"},
{"Alioth"},
{"Alkaid"},
{"AlNair"},
{"Alnilam"},
{"Alnitak"},
{"Alphard"},
{"Alphecca"},
{"Alpherat"},
{"Alsuhail"},
{"Altair"},
{"Aludra"},
{"Ankaa"},
{"Antares"},
{"AQ"},
{"Arcturus"},
{"Arneb"},
{"Aspidisk"},
{"Atria"},
{"Avior"},
{"AW"},
{"AX"},
{"BD"},
{"Becrux"},
{"Bellatri"},
{"Betelgeu"},
{"BF"},
{"BG"},
{"BL"},
{"BM"},
{"BX"},
{"Canopus"},
{"Capella"},
{"Caph"},
{"Castor"},
{"Cih"},
{"CY"},
{"Deneb"},
{"DenebKai"},
{"Denebola"},
{"Diphda"},
{"DR"},
{"Dschubba"},
{"Dubhe"},
{"EL"},
{"ElNath"},
{"Eltanin"},
{"Enif"},
{"FO"},
{"Fomalhau"},
{"FU"},
{"Gacrux"},
{"Gemma"},
{"Gienah"},
{"Girtab"},
{"GK"},
{"GY"},
{"H"},
{"Hadar"},
{"Hamal"},
{"Han"},
{"HD"},
{"HJ"},
{"HK"},
{"HN"},
{"Izar"},
{"JC"},
{"KausAust"},
{"Kochab"},
{"KooShe"},
{"Markab"},
{"Menkalin"},
{"Menkar"},
{"Menkent"},
{"Merak"},
{"Miaplaci"},
{"Mimosa"},
{"Mintaka"},
{"Mirach"},
{"Mirfak"},
{"Mirzam"},
{"Mizar"},
{"Naos"},
{"NQ"},
{"NSV"},
{"Nunki"},
{"O#F"},
{"Peacock"},
{"Phecda"},
{"Polaris"},
{"Pollux"},
{"Procyon"},
{"PZ6"},
{"R"},
{"RasAlhag"},
{"Regulus"},
{"Rigel"},
{"RigilKen"},
{"RR"},
{"RS"},
{"RT"},
{"RU"},
{"RV"},
{"RX"},
{"RY"},
{"RZ"},
{"S"},
{"S605"},
{"Sabik"},
{"Sadr"},
{"Saiph"},
{"SAO"},
{"Sargas"},
{"Scheat"},
{"Schedar"},
{"Shaula"},
{"SHJ"},
{"Sirius"},
{"Spica"},
{"SS"},
{"ST"},
{"SU"},
{"SV"},
{"SY"},
{"SZ"},
{"T"},
{"TT"},
{"TU"},
{"Tureis"},
{"TW"},
{"TX"},
{"U"},
{"UU"},
{"UV"},
{"UX"},
{"UY"},
{"V"},
{"Vega"},
{"VW"},
{"VX"},
{"VY"},
{"W"},
{"Wei"},
{"Wezen"},
{"WO"},
{"WW"},
{"WX"},
{"WZ"},
{"X"},
{"XS"},
{"XX"},
{"Y"},
{"Z"},
{"Zozma"},
{"β648"},
{"#F"},
{"extern"}
};
//###############################################################################################################
//###############################################################################################################
// data of deep sky objects
//###############################################################################################################
struct DSOstruct
{
byte objectPreFixNameNo; // number of name for lookup table
unsigned int objectNumber; // if name contains a number
byte objectTypeMagnitude; // object type & magnitude coded in one byte
byte objectConst; // constellation of object
unsigned int objectRA; //HHMM(SS/6)
int objectDEC; //sHHMM
};
DSOstruct myTarget; // object to store data of selected target
DSOstruct myReference; // object to store data of selected target
const unsigned int DSO_PROGMEM_size = 1204;
const struct DSOstruct DSO_PROGMEM[DSO_PROGMEM_size] PROGMEM =
{
{1, 0, 27, 86, 12291, 203},
{2, 33, 42, 60, 5409, -228},
{2, 65, 42, 77, 18027, -2750},
{2, 86, 42, 59, 17196, -2642},
{3, 342, 54, 11, 3468, 6806},
{3, 405, 66, 8, 5165, 3421},
{3, 410, 64, 8, 5227, 3325},
{3, 434, 67, 60, 5410, -227},
{3, 1396, 74, 16, 21391, 5730},
{3, 4406, 95, 50, 14224, -4409},
{3, 5067, 64, 31, 20508, 4421},
{3, 5146, 80, 31, 21534, 4716},
{4, 1, 106, 78, 5345, 2201},
{4, 2, 119, 5, 21335, -49},
{4, 3, 118, 30, 13422, 2823},
{4, 4, 117, 72, 16236, -2632},
{4, 5, 118, 74, 15186, 205},
{4, 6, 130, 72, 17403, -3215},
{4, 7, 129, 72, 17539, -3448},
{4, 8, 75, 77, 18037, -2423},
{4, 9, 120, 59, 17192, -1831},
{4, 10, 119, 59, 16571, -406},
{4, 11, 132, 73, 18511, -616},
{4, 12, 118, 59, 16472, -157},
{4, 13, 118, 40, 16417, 3628},
{4, 14, 120, 59, 17376, -315},
{4, 15, 118, 62, 21300, 1210},
{4, 16, 76, 74, 18188, -1347},
{4, 17, 76, 77, 18208, -1611},
{4, 18, 133, 77, 18199, -1708},
{4, 19, 119, 59, 17026, -2616},
{4, 20, 76, 77, 18027, -2258},
{4, 21, 132, 77, 18042, -2229},
{4, 22, 117, 77, 18364, -2354},
{4, 23, 132, 77, 17571, -1859},
{4, 24, 129, 77, 18266, -1823},
{4, 25, 131, 77, 18318, -1907},
{4, 26, 134, 73, 18452, -924},
{4, 27, 91, 88, 19596, 2243},
{4, 28, 119, 77, 18245, -2452},
{4, 29, 133, 31, 20239, 3832},
{4, 30, 119, 12, 21404, -2311},
{4, 31, 45, 1, 427, 4116},
{4, 32, 50, 1, 427, 4052},
{4, 33, 48, 81, 1339, 3039},
{4, 34, 131, 63, 2421, 4247},
{4, 35, 131, 38, 6089, 2421},
{4, 36, 132, 8, 5363, 3408},
{4, 37, 132, 8, 5523, 3233},
{4, 38, 132, 8, 5287, 3551},
{4, 39, 131, 31, 21322, 4826},
{4, 40, 149, 83, 12219, 5806},
{4, 41, 131, 20, 6460, -2045},
{4, 42, 74, 60, 5353, -523},
{4, 43, 63, 60, 5355, -516},
{4, 44, 129, 22, 8400, 1940},
{4, 45, 71, 78, 3470, 2407},
{4, 46, 132, 68, 7418, -1449},
{4, 47, 130, 68, 7366, -1429},
{4, 48, 132, 42, 8137, -545},
{4, 49, 50, 86, 12298, 800},
{4, 50, 132, 55, 7025, -823},
{4, 51, 50, 30, 13299, 4712},
{4, 52, 133, 14, 23242, 6135},
{4, 53, 120, 24, 13129, 1810},
{4, 54, 120, 77, 18551, -3029},
{4, 55, 118, 77, 19400, -3058},
{4, 56, 120, 52, 19166, 3011},
{4, 57, 93, 52, 18536, 3302},
{4, 58, 52, 86, 12377, 1149},
{4, 59, 52, 86, 12420, 1139},
{4, 60, 51, 86, 12437, 1133},
{4, 61, 52, 86, 12219, 428},
{4, 62, 118, 59, 17012, -3007},
{4, 63, 51, 30, 13158, 4202},
{4, 64, 51, 24, 12567, 2141},
{4, 65, 51, 46, 11189, 1305},
{4, 66, 51, 46, 11202, 1300},
{4, 67, 133, 22, 8508, 1149},
{4, 68, 119, 42, 12395, -2645},
{4, 69, 120, 77, 18314, -3221},
{4, 70, 120, 77, 18432, -3218},
{4, 71, 120, 76, 19538, 1847},
{4, 72, 121, 5, 20535, -1232},
{4, 73, 136, 5, 20590, -1238},
{4, 74, 51, 67, 1367, 1547},
{4, 75, 121, 77, 20061, -2155},
{4, 76, 94, 63, 1423, 5135},
{4, 77, 51, 17, 2427, -1},
{4, 78, 64, 60, 5468, 5},
{4, 79, 120, 47, 5242, -2431},
{4, 80, 119, 72, 16170, -2259},
{4, 81, 49, 83, 9556, 6904},
{4, 82, 50, 83, 9559, 6941},
{4, 83, 50, 42, 13370, -2952},
{4, 84, 51, 86, 12251, 1253},
{4, 85, 51, 24, 12254, 1811},
{4, 86, 51, 86, 12262, 1257},
{4, 87, 51, 86, 12308, 1223},
{4, 88, 52, 24, 12320, 1425},
{4, 89, 52, 86, 12357, 1233},
{4, 90, 52, 86, 12368, 1310},
{4, 91, 52, 24, 12354, 1430},
{4, 92, 119, 40, 17171, 4308},
{4, 93, 132, 68, 7445, -2351},
{4, 94, 50, 30, 12509, 4107},
{4, 95, 52, 46, 10440, 1142},
{4, 96, 51, 46, 10468, 1149},
{4, 97, 95, 83, 11148, 5501},
{4, 98, 52, 24, 12138, 1454},
{4, 99, 52, 24, 12188, 1425},
{4, 100, 51, 24, 12229, 1549},
{4, 101, 50, 83, 14032, 5421},
{4, 102, 52, 34, 15065, 5546},
{4, 103, 133, 14, 1334, 6039},
{4, 104, 50, 86, 12400, -1137},
{4, 105, 51, 46, 10478, 1235},
{4, 106, 50, 30, 12190, 4718},
{4, 107, 120, 59, 16325, -1303},
{4, 108, 52, 83, 11115, 5540},
{4, 109, 52, 83, 11576, 5322},
{4, 110, 50, 1, 404, 4141},
{5, 40, 94, 16, 130, 7231},
{5, 55, 50, 71, 149, -3911},
{5, 129, 133, 14, 300, 6013},
{5, 136, 137, 14, 315, 6131},
{5, 147, 52, 14, 332, 4830},
{5, 157, 52, 17, 348, -824},
{5, 185, 51, 14, 390, 4820},
{5, 188, 134, 16, 475, 8514},
{5, 210, 52, 17, 406, -1352},
{5, 225, 133, 14, 436, 6146},
{5, 246, 94, 17, 471, -1152},
{5, 247, 51, 17, 471, -2046},
{5, 253, 49, 71, 476, -2518},
{5, 278, 52, 14, 521, 4733},
{5, 281, 77, 14, 530, 5637},
{5, 288, 120, 71, 528, -2635},
{5, 300, 50, 71, 549, -3741},
{5, 381, 135, 14, 1084, 6135},
{5, 404, 52, 1, 1094, 3543},
{5, 436, 135, 14, 1160, 5849},
{5, 457, 132, 14, 1195, 5817},
{5, 488, 52, 67, 1218, 515},
{5, 524, 52, 67, 1248, 932},
{5, 559, 136, 14, 1295, 6319},
{5, 584, 52, 17, 1313, -652},
{5, 596, 52, 17, 1329, -702},
{5, 613, 52, 71, 1343, -2925},
{5, 615, 53, 17, 1351, -720},
{5, 637, 134, 14, 1431, 6402},
{5, 654, 133, 14, 1440, 6153},
{5, 659, 134, 14, 1444, 6040},
{5, 663, 133, 14, 1460, 6115},
{5, 672, 52, 81, 1479, 2726},
{5, 720, 52, 17, 1530, -1344},
{5, 752, 132, 1, 1577, 3740},
{5, 772, 52, 7, 1593, 1900},
{5, 779, 53, 17, 1597, -558},
{5, 869, 131, 63, 2191, 5708},
{5, 884, 132, 63, 2225, 5709},
{5, 891, 52, 1, 2226, 4221},
{5, 908, 52, 17, 2231, -2114},
{5, 925, 52, 81, 2273, 3335},
{5, 936, 52, 17, 2276, -109},
{5, 986, 52, 37, 2336, -3903},
{5, 1022, 53, 17, 2385, -641},
{5, 1023, 51, 63, 2404, 3904},
{5, 1027, 133, 14, 2426, 6136},
{5, 1052, 52, 17, 2411, -815},
{5, 1055, 52, 17, 2418, 27},
{5, 1084, 52, 36, 2460, -735},
{5, 1097, 52, 37, 2463, -3017},
{5, 1232, 52, 36, 3098, -2035},
{5, 1245, 134, 63, 3147, 4714},
{5, 1261, 120, 41, 3123, -5513},
{5, 1275, 53, 63, 3198, 4131},
{5, 1291, 51, 36, 3173, -4106},
{5, 1300, 52, 36, 3197, -1925},
{5, 1316, 51, 37, 3227, -3713},
{5, 1325, 53, 36, 3244, -2133},
{5, 1332, 52, 36, 3263, -2120},
{5, 1342, 133, 63, 3317, 3722},
{5, 1360, 93, 37, 3332, -2552},
{5, 1365, 52, 37, 3336, -3608},
{5, 1374, 53, 37, 3353, -3514},
{5, 1380, 54, 37, 3368, -3444},
{5, 1398, 52, 37, 3389, -2620},
{5, 1399, 52, 37, 3385, -3527},
{5, 1407, 52, 36, 3402, -1835},
{5, 1433, 52, 41, 3420, -4713},
{5, 1444, 133, 63, 3494, 5240},
{5, 1491, 70, 63, 4032, 5119},
{5, 1499, 61, 63, 4032, 3622},
{5, 1501, 96, 11, 4070, 6055},
{5, 1502, 133, 11, 4078, 6220},
{5, 1513, 134, 63, 4099, 4931},
{5, 1514, 94, 78, 4093, 3047},
{5, 1528, 132, 63, 4153, 5113},
{5, 1532, 52, 36, 4121, -3252},
{5, 1535, 93, 36, 4143, -1244},
{5, 1545, 132, 63, 4209, 5015},
{5, 1549, 52, 33, 4158, -5536},
{5, 1566, 52, 33, 4200, -5456},
{5, 1647, 132, 78, 4459, 1906},
{5, 1664, 134, 8, 4511, 4341},
{5, 1672, 52, 33, 4457, -5915},
{5, 1788, 70, 60, 5069, -320},
{5, 1792, 52, 23, 5052, -3759},
{5, 1808, 52, 23, 5077, -3731},
{5, 1817, 134, 78, 5124, 1641},
{5, 1851, 119, 23, 5141, -4003},
{5, 1857, 133, 8, 5201, 3921},
{5, 1907, 134, 8, 5281, 3520},
{5, 1909, 70, 36, 5045, -716},
{5, 1931, 80, 8, 5314, 3415},
{5, 1961, 53, 11, 5421, 6923},
{5, 1964, 52, 47, 5334, -2157},
{5, 1973, 63, 60, 5351, -444},
{5, 1980, 73, 60, 5354, -555},
{5, 1999, 70, 60, 5364, -643},
{5, 2022, 95, 60, 5421, 905},
{5, 2024, 70, 60, 5417, -151},
{5, 2126, 136, 8, 6025, 4952},
{5, 2129, 133, 38, 6007, 2319},
{5, 2158, 135, 38, 6074, 2406},
{5, 2169, 132, 60, 6084, 1358},
{5, 2175, 77, 60, 6096, 2029},
{5, 2185, 70, 55, 6110, -614},
{5, 2186, 135, 60, 6121, 528},
{5, 2194, 135, 60, 6138, 1248},
{5, 2204, 135, 20, 6155, -1840},
{5, 2207, 52, 20, 6164, -2122},
{5, 2215, 134, 55, 6208, -717},
{5, 2232, 130, 55, 6280, -451},
{5, 2237, 76, 55, 6309, 503},
{5, 2238, 62, 55, 6307, 501},
{5, 2239, 131, 55, 6319, 457},
{5, 2245, 70, 55, 6327, 1009},
{5, 2251, 133, 55, 6346, 822},
{5, 2261, 70, 55, 6392, 845},
{5, 2264, 74, 55, 6410, 954},
{5, 2266, 136, 38, 6433, 2658},
{5, 2281, 131, 8, 6483, 4105},
{5, 2286, 134, 55, 6477, -309},
{5, 2300, 53, 16, 7323, 8543},
{5, 2301, 132, 55, 6518, 28},
{5, 2304, 136, 38, 6552, 1759},
{5, 2311, 136, 55, 6578, -437},
{5, 2324, 134, 55, 7041, 103},
{5, 2335, 133, 55, 7068, -1002},
{5, 2343, 133, 55, 7081, -1037},
{5, 2346, 96, 55, 7094, -48},
{5, 2353, 133, 55, 7145, -1016},
{5, 2354, 133, 20, 7143, -2542},
{5, 2355, 136, 38, 7170, 1345},
{5, 2359, 70, 20, 7185, -1314},
{5, 2360, 133, 20, 7177, -1538},
{5, 2362, 130, 20, 7187, -2457},
{5, 2371, 95, 38, 7256, 2929},
{5, 2372, 95, 38, 7256, 2930},
{5, 2383, 134, 20, 7247, -2057},
{5, 2384, 133, 20, 7252, -2101},
{5, 2392, 93, 38, 7292, 2055},
{5, 2395, 134, 38, 7272, 1337},
{5, 2403, 51, 11, 7368, 6536},
{5, 2419, 122, 51, 7381, 3853},
{5, 2420, 134, 38, 7384, 2134},
{5, 2421, 134, 68, 7362, -2037},
{5, 2423, 133, 68, 7371, -1352},
{5, 2438, 95, 68, 7418, -1444},
{5, 2439, 133, 68, 7408, -3142},
{5, 2440, 95, 68, 7419, -1813},
{5, 2467, 77, 68, 7525, -2626},
{5, 2477, 132, 68, 7522, -3832},
{5, 2479, 136, 68, 7551, -1742},
{5, 2482, 133, 68, 7552, -2415},
{5, 2489, 134, 68, 7563, -3004},
{5, 2506, 134, 55, 8000, -1046},
{5, 2509, 135, 68, 8008, -1903},
{5, 2527, 133, 68, 8050, -2809},
{5, 2539, 133, 68, 8106, -1249},
{5, 2547, 131, 85, 8102, -4912},
{5, 2567, 133, 68, 8185, -3039},
{5, 2571, 133, 68, 8189, -2945},
{5, 2613, 52, 69, 8334, -2258},
{5, 2627, 134, 69, 8372, -2957},
{5, 2655, 52, 11, 8556, 7813},
{5, 2681, 52, 83, 8535, 5119},
{5, 2683, 52, 51, 8527, 3325},
{5, 2742, 53, 83, 9076, 6029},
{5, 2768, 52, 83, 9116, 6002},
{5, 2775, 52, 22, 9103, 702},
{5, 2782, 53, 51, 9141, 4007},
{5, 2784, 52, 42, 9123, -2410},
{5, 2787, 52, 83, 9193, 6912},
{5, 2811, 53, 42, 9162, -1619},
{5, 2835, 52, 42, 9179, -2221},
{5, 2841, 51, 83, 9220, 5059},
{5, 2859, 52, 49, 9243, 3431},
{5, 2867, 94, 13, 9214, -5819},
{5, 2903, 51, 46, 9322, 2130},
{5, 2950, 52, 83, 9426, 5851},
{5, 2964, 53, 46, 9429, 3151},
{5, 2974, 52, 75, 9426, -342},
{5, 2976, 52, 83, 9472, 6755},
{5, 2985, 52, 83, 9504, 7217},
{5, 2997, 51, 2, 9456, -3111},
{5, 3077, 52, 83, 10033, 6844},
{5, 3079, 52, 83, 10020, 5541},
{5, 3109, 52, 42, 10031, -2610},
{5, 3115, 51, 75, 10052, -743},
{5, 3132, 92, 85, 10070, -4026},
{5, 3147, 52, 34, 10169, 7324},
{5, 3166, 52, 75, 10138, 326},
{5, 3169, 52, 75, 10142, 328},
{5, 3184, 52, 83, 10183, 4125},
{5, 3190, 53, 46, 10181, 2150},
{5, 3193, 52, 46, 10184, 2154},
{5, 3198, 52, 83, 10199, 4533},
{5, 3201, 119, 85, 10176, -4625},
{5, 3226, 53, 46, 10234, 1954},
{5, 3227, 52, 46, 10235, 1952},
{5, 3242, 93, 42, 10248, -1839},
{5, 3245, 52, 49, 10273, 2830},
{5, 3277, 53, 49, 10329, 2831},
{5, 3294, 53, 49, 10363, 3719},
{5, 3310, 52, 83, 10388, 5330},
{5, 3344, 52, 49, 10435, 2455},
{5, 3359, 52, 83, 10466, 6313},
{5, 3372, 59, 13, 10451, -5952},
{5, 3377, 52, 46, 10477, 1359},
{5, 3384, 52, 46, 10483, 1238},
{5, 3395, 54, 49, 10498, 3259},
{5, 3412, 52, 46, 10509, 1325},
{5, 3414, 53, 49, 10513, 2758},
{5, 3432, 53, 49, 10525, 3637},
{5, 3486, 52, 49, 11004, 2859},
{5, 3489, 52, 46, 11003, 1354},
{5, 3504, 53, 49, 11032, 2758},
{5, 3521, 51, 46, 11058, -2},
{5, 3532, 129, 13, 11052, -5844},
{5, 3593, 52, 46, 11146, 1249},
{5, 3607, 52, 46, 11169, 1803},
{5, 3608, 52, 46, 11170, 1809},
{5, 3610, 52, 83, 11184, 5847},
{5, 3613, 52, 83, 11186, 5800},
{5, 3619, 53, 83, 11194, 5745},
{5, 3621, 52, 42, 11183, -3249},
{5, 3626, 53, 46, 11201, 1821},
{5, 3628, 52, 46, 11203, 1335},
{5, 3631, 52, 83, 11210, 5310},
{5, 3640, 52, 46, 11211, 314},
{5, 3655, 53, 46, 11229, 1635},
{5, 3665, 52, 83, 11247, 3846},
{5, 3675, 52, 83, 11261, 4335},
{5, 3686, 53, 46, 11277, 1713},
{5, 3717, 53, 42, 11315, -3019},
{5, 3718, 52, 83, 11326, 5304},
{5, 3726, 52, 83, 11333, 4702},
{5, 3729, 53, 83, 11338, 5308},
{5, 3810, 52, 46, 11410, 1128},
{5, 3813, 53, 83, 11413, 3633},
{5, 3877, 53, 83, 11461, 4730},
{5, 3893, 52, 83, 11486, 4843},
{5, 3898, 52, 83, 11493, 5605},
{5, 3900, 53, 46, 11492, 2701},
{5, 3912, 54, 46, 11501, 2629},
{5, 3918, 92, 15, 11503, -5711},
{5, 3923, 52, 42, 11510, -2848},
{5, 3938, 52, 83, 11528, 4407},
{5, 3941, 52, 83, 11529, 3659},
{5, 3945, 52, 83, 11532, 6040},
{5, 3949, 53, 83, 11537, 4752},
{5, 3953, 52, 83, 11538, 5219},
{5, 3962, 52, 27, 11547, -1359},
{5, 3982, 53, 83, 11565, 5507},
{5, 3998, 52, 83, 11579, 5527},
{5, 4013, 53, 83, 11585, 4357},
{5, 4026, 52, 83, 11594, 5058},
{5, 4027, 53, 29, 11595, -1916},
{5, 4030, 52, 86, 12004, -106},
{5, 4036, 52, 83, 12015, 6154},
{5, 4038, 52, 29, 12019, -1852},
{5, 4039, 52, 29, 12019, -1853},
{5, 4041, 53, 83, 12022, 6208},
{5, 4051, 52, 83, 12032, 4432},
{5, 4085, 54, 83, 12054, 5021},
{5, 4088, 52, 83, 12056, 5032},
{5, 4096, 52, 83, 12060, 4729},
{5, 4102, 53, 83, 12064, 5243},
{5, 4105, 52, 42, 12067, -2946},
{5, 4111, 52, 30, 12070, 4304},
{5, 4125, 52, 34, 12081, 6510},
{5, 4143, 52, 30, 12096, 4232},
{5, 4147, 122, 24, 12101, 1833},
{5, 4150, 53, 24, 12106, 3024},
{5, 4151, 52, 30, 12105, 3924},
{5, 4179, 53, 86, 12129, 118},
{5, 4203, 52, 24, 12151, 3312},
{5, 4214, 52, 30, 12156, 3620},
{5, 4216, 52, 86, 12159, 1309},
{5, 4236, 52, 34, 12167, 6928},
{5, 4244, 52, 30, 12175, 3748},
{5, 4245, 53, 24, 12176, 2936},
{5, 4251, 52, 24, 12181, 2810},
{5, 4261, 52, 86, 12194, 549},
{5, 4273, 53, 86, 12199, 521},
{5, 4274, 52, 24, 12198, 2937},
{5, 4278, 52, 24, 12201, 2917},
{5, 4281, 53, 86, 12204, 523},
{5, 4293, 52, 24, 12212, 1823},
{5, 4314, 52, 24, 12225, 2954},
{5, 4346, 53, 30, 12235, 4700},
{5, 4350, 53, 24, 12240, 1642},
{5, 4361, 94, 29, 12245, -1847},
{5, 4365, 52, 86, 12245, 719},
{5, 4371, 52, 86, 12249, 1142},
{5, 4388, 53, 86, 12258, 1240},
{5, 4394, 52, 24, 12259, 1813},
{5, 4395, 52, 30, 12258, 3333},
{5, 4414, 52, 24, 12265, 3113},
{5, 4419, 53, 24, 12269, 1503},
{5, 4429, 52, 86, 12274, 1106},
{5, 4435, 52, 86, 12277, 1305},
{5, 4438, 52, 86, 12278, 1300},
{5, 4442, 52, 86, 12281, 948},
{5, 4448, 53, 24, 12283, 2837},
{5, 4449, 52, 30, 12282, 4406},
{5, 4450, 52, 24, 12285, 1705},
{5, 4459, 52, 24, 12290, 1359},
{5, 4473, 52, 24, 12298, 1326},
{5, 4477, 52, 24, 12300, 1338},
{5, 4478, 53, 86, 12303, 1220},
{5, 4485, 53, 30, 12305, 4142},
{5, 4490, 52, 30, 12306, 4139},
{5, 4494, 52, 24, 12314, 2546},
{5, 4517, 52, 86, 12328, 7},
{5, 4526, 52, 86, 12340, 742},
{5, 4527, 52, 86, 12341, 239},
{5, 4535, 52, 86, 12343, 812},
{5, 4536, 52, 86, 12344, 211},
{5, 4546, 52, 86, 12355, -348},
{5, 4550, 53, 86, 12355, 1213},
{5, 4559, 52, 24, 12360, 2758},
{5, 4565, 52, 24, 12363, 2559},
{5, 4567, 53, 86, 12365, 1115},
{5, 4568, 52, 86, 12366, 1114},
{5, 4570, 52, 86, 12369, 715},
{5, 4596, 52, 86, 12399, 1011},
{5, 4605, 52, 83, 12400, 6136},
{5, 4618, 52, 30, 12416, 4109},
{5, 4631, 51, 30, 12421, 3232},
{5, 4636, 52, 86, 12428, 241},
{5, 4643, 52, 86, 12433, 159},
{5, 4654, 52, 86, 12439, 1308},
{5, 4656, 52, 30, 12440, 3210},
{5, 4660, 53, 86, 12445, 1111},
{5, 4665, 52, 86, 12451, 303},
{5, 4666, 52, 86, 12451, -28},
{5, 4689, 52, 24, 12478, 1346},
{5, 4697, 51, 86, 12486, -548},
{5, 4698, 52, 86, 12484, 829},
{5, 4699, 52, 86, 12490, -840},
{5, 4725, 51, 24, 12504, 2530},
{5, 4753, 52, 86, 12524, -112},
{5, 4754, 52, 86, 12523, 1119},
{5, 4762, 52, 86, 12529, 1114},
{5, 4781, 53, 86, 12544, -1032},
{5, 4800, 53, 30, 12546, 4632},
{5, 4845, 53, 86, 12580, 135},
{5, 4856, 52, 86, 12594, -1503},
{5, 4866, 53, 86, 12595, 1410},
{5, 4889, 53, 24, 13001, 2759},
{5, 4900, 53, 86, 13007, 230},
{5, 4902, 52, 86, 13010, -1431},
{5, 4945, 51, 15, 13054, -4928},
{5, 4958, 52, 86, 13058, -801},
{5, 4995, 53, 86, 13097, -750},
{5, 5005, 52, 30, 13109, 3703},
{5, 5033, 52, 30, 13135, 3636},
{5, 5053, 122, 24, 13165, 1742},
{5, 5054, 52, 86, 13170, -1638},
{5, 5068, 52, 86, 13189, -2102},
{5, 5078, 53, 42, 13198, -2725},
{5, 5102, 52, 15, 13220, -3638},
{5, 5128, 49, 15, 13255, -4301},
{5, 5139, 116, 15, 13268, -4729},
{5, 5247, 52, 86, 13380, -1753},
{5, 5248, 52, 9, 13375, 853},
{5, 5273, 53, 30, 13421, 3539},
{5, 5286, 119, 15, 13464, -5122},
{5, 5322, 52, 83, 13492, 6011},
{5, 5350, 53, 30, 13534, 4022},
{5, 5353, 53, 30, 13534, 4017},
{5, 5354, 53, 30, 13534, 4018},
{5, 5363, 52, 86, 13561, 515},
{5, 5364, 52, 86, 13562, 501},
{5, 5371, 52, 30, 13557, 4028},
{5, 5427, 53, 86, 14034, -602},
{5, 5466, 121, 9, 14055, 2832},
{5, 5473, 53, 83, 14047, 5454},
{5, 5474, 52, 83, 14050, 5340},
{5, 5557, 53, 9, 14184, 3630},
{5, 5566, 52, 86, 14203, 356},
{5, 5576, 53, 86, 14211, 316},
{5, 5631, 53, 83, 14266, 5635},
{5, 5634, 122, 86, 14296, -559},
{5, 5643, 52, 50, 14327, -4411},
{5, 5676, 53, 9, 14328, 4927},
{5, 5689, 53, 9, 14355, 4844},
{5, 5694, 122, 42, 14396, -2632},
{5, 5746, 52, 86, 14449, 157},
{5, 5813, 52, 86, 15012, 142},
{5, 5822, 133, 50, 15044, -5424},
{5, 5823, 134, 19, 15055, -5536},
{5, 5824, 121, 50, 15040, -3304},
{5, 5846, 52, 86, 15065, 136},
{5, 5850, 52, 86, 15071, 133},
{5, 5897, 120, 48, 15174, -2101},
{5, 5907, 52, 34, 15159, 5620},
{5, 5927, 120, 50, 15280, -5040},
{5, 5946, 120, 57, 15355, -5040},
{5, 5982, 53, 34, 15387, 5921},
{5, 5986, 120, 50, 15461, -3747},
{5, 6067, 132, 57, 16132, -5413},
{5, 6118, 53, 74, 16218, -217},
{5, 6124, 132, 72, 16253, -4039},
{5, 6134, 133, 57, 16278, -4909},
{5, 6144, 121, 72, 16272, -2601},
{5, 6192, 135, 72, 16404, -4322},
{5, 6193, 131, 6, 16413, -4846},
{5, 6204, 134, 6, 16462, -4701},
{5, 6207, 53, 40, 16431, 3650},
{5, 6210, 94, 40, 16445, 2348},
{5, 6217, 53, 84, 16326, 7812},
{5, 6222, 136, 72, 16494, -4444},
{5, 6229, 121, 40, 16470, 4732},
{5, 6231, 129, 72, 16542, -4149},
{5, 6235, 121, 59, 16534, -2211},
{5, 6242, 132, 72, 16556, -3928},
{5, 6259, 134, 72, 17008, -4439},
{5, 6281, 131, 72, 17047, -3759},
{5, 6284, 121, 59, 17045, -2446},
{5, 6287, 121, 59, 17052, -2242},
{5, 6293, 120, 59, 17102, -2635},
{5, 6302, 96, 72, 17137, -3706},
{5, 6304, 120, 59, 17145, -2928},
{5, 6309, 95, 59, 17141, -1255},
{5, 6316, 120, 59, 17166, -2808},
{5, 6334, 70, 72, 17208, -3606},
{5, 6342, 122, 59, 17212, -1935},
{5, 6352, 120, 6, 17255, -4825},
{5, 6355, 121, 59, 17240, -2621},
{5, 6356, 120, 59, 17236, -1749},
{5, 6366, 122, 59, 17277, -505},
{5, 6369, 95, 59, 17293, -2346},
{5, 6388, 119, 72, 17363, -4444},
{5, 6397, 117, 6, 17407, -5340},
{5, 6401, 119, 59, 17386, -2355},
{5, 6426, 122, 59, 17449, 310},
{5, 6440, 121, 77, 17489, -2022},
{5, 6441, 119, 72, 17502, -3703},
{5, 6445, 97, 77, 17493, -2001},
{5, 6451, 134, 72, 17507, -3013},
{5, 6453, 122, 72, 17509, -3436},
{5, 6503, 52, 34, 17495, 7009},
{5, 6517, 122, 59, 18018, -858},
{5, 6520, 134, 77, 18034, -2753},
{5, 6522, 122, 77, 18036, -3002},
{5, 6528, 122, 77, 18048, -3003},
{5, 6535, 121, 74, 18038, -18},
{5, 6539, 121, 74, 18048, -735},
{5, 6541, 118, 25, 18080, -4342},
{5, 6543, 92, 34, 17586, 6638},
{5, 6544, 120, 77, 18073, -2500},
{5, 6553, 120, 77, 18093, -2554},
{5, 6568, 135, 77, 18128, -2135},
{5, 6569, 120, 77, 18136, -3150},
{5, 6572, 92, 59, 18121, 651},
{5, 6583, 136, 77, 18158, -2208},
{5, 6603, 137, 77, 18184, -1824},
{5, 6624, 120, 77, 18237, -3022},
{5, 6629, 94, 77, 18257, -2312},
{5, 6633, 131, 59, 18273, 631},
{5, 6638, 121, 77, 18309, -2530},
{5, 6642, 121, 77, 18319, -2329},
{5, 6645, 135, 77, 18320, -1653},
{5, 6649, 135, 73, 18335, -1024},
{5, 6652, 121, 77, 18358, -3259},
{5, 6664, 134, 73, 18366, -749},
{5, 6712, 120, 73, 18531, -842},
{5, 6723, 119, 77, 18596, -3638},
{5, 6726, 70, 25, 19017, -3653},
{5, 6727, 70, 25, 19017, -3653},
{5, 6729, 70, 25, 19019, -3657},
{5, 6752, 117, 61, 19109, -5959},
{5, 6755, 134, 4, 19078, 416},
{5, 6756, 136, 4, 19087, 442},
{5, 6760, 121, 4, 19112, 102},
{5, 6781, 95, 4, 19185, 632},
{5, 6791, 136, 52, 19207, 3751},
{5, 6802, 135, 88, 19306, 2016},
{5, 6818, 94, 77, 19440, -1409},
{5, 6819, 133, 31, 19413, 4011},
{5, 6822, 51, 77, 19449, -1448},
{5, 6823, 133, 88, 19432, 2318},
{5, 6826, 93, 31, 19448, 5032},
{5, 6830, 134, 88, 19510, 2306},
{5, 6834, 134, 31, 19522, 2924},
{5, 6857, 67, 31, 20028, 3331},
{5, 6866, 134, 31, 20039, 4410},
{5, 6885, 134, 88, 20119, 2629},
{5, 6888, 66, 31, 20128, 3819},
{5, 6905, 96, 32, 20224, 2006},
{5, 6907, 53, 12, 20251, -2449},
{5, 6910, 133, 31, 20232, 4047},
{5, 6934, 121, 32, 20342, 724},
{5, 6939, 134, 16, 20315, 6040},
{5, 6940, 132, 88, 20344, 2817},
{5, 6946, 51, 16, 20349, 6009},
{5, 6960, 105, 31, 20457, 3043},
{5, 6974, 112, 31, 20511, 3150},
{5, 6979, 70, 31, 20510, 3208},
{5, 6992, 105, 31, 20564, 3143},
{5, 6995, 105, 31, 20571, 3113},
{5, 7000, 60, 31, 21018, 4412},
{5, 7006, 122, 32, 21015, 1611},
{5, 7008, 96, 31, 21005, 5433},
{5, 7009, 92, 5, 21042, -1122},
{5, 7023, 77, 16, 21005, 6810},
{5, 7026, 96, 31, 21063, 4751},
{5, 7027, 94, 31, 21070, 4214},
{5, 7044, 138, 31, 21129, 4229},
{5, 7062, 134, 31, 21235, 4623},
{5, 7086, 134, 31, 21305, 5136},
{5, 7090, 52, 44, 21365, -5433},
{5, 7128, 136, 31, 21440, 5343},
{5, 7129, 81, 16, 21430, 6607},
{5, 7142, 135, 16, 21452, 6546},
{5, 7160, 132, 16, 21537, 6236},
{5, 7184, 52, 5, 22027, -2049},
{5, 7209, 134, 45, 22051, 4629},
{5, 7217, 52, 62, 22079, 3122},
{5, 7243, 132, 45, 22151, 4954},
{5, 7293, 90, 5, 22296, -2050},
{5, 7296, 136, 45, 22282, 5217},
{5, 7320, 54, 62, 22361, 3357},
{5, 7331, 52, 62, 22371, 3425},
{5, 7380, 133, 16, 22473, 5808},
{5, 7424, 52, 39, 22573, -4104},
{5, 7448, 53, 62, 23001, 1559},
{5, 7479, 52, 62, 23049, 1219},
{5, 7510, 134, 16, 23115, 6034},
{5, 7582, 52, 39, 23184, -4222},
{5, 7606, 52, 5, 23191, -829},
{5, 7619, 53, 62, 23202, 812},
{5, 7635, 67, 14, 23202, 6111},
{5, 7662, 93, 1, 23259, 4232},
{5, 7686, 132, 1, 23301, 4908},
{5, 7723, 53, 5, 23390, -1258},
{5, 7727, 52, 5, 23399, -1218},
{5, 7789, 133, 14, 23574, 5643},
{5, 7790, 135, 14, 23584, 6113},
{5, 7793, 51, 71, 23578, -3236},
{5, 7814, 52, 62, 32, 1609},
{0, 36, 146, 1, 550, +2338},
{15, 0, 142, 1, 2039, +4220},
{201, 228, 147, 1, 2140, +4729},
{201, 3050, 146, 1, 23595, +3343},
{0, 56, 146, 1, 1562, +3715},
{0, 59, 146, 1, 2109, +3902},
{24, 0, 146, 4, 19487, +1149},
{201, 2404, 147, 4, 18508, +1059},
{201, 2532, 146, 4, 19302, 254},
{0, 5, 146, 4, 18465, -58},
{0, 11, 145, 4, 18591, +1338},
{0, 15, 146, 4, 19050, -402},
{0, 57, 146, 4, 19546, -814},
{201, 2838, 146, 5, 21546, -318},
{32, 0, 144, 5, 22288, -1},
{0, 12, 146, 5, 21041, -549},
{0, 41, 146, 5, 22143, -2104},
{0, 53, 146, 5, 22266, -1645},
{0, 94, 145, 5, 23191, -1328},
{0, 107, 146, 5, 23460, -1841},
{12, 0, 145, 7, 2592, +2120},
{15, 0, 145, 7, 1535, +1918},
{20, 0, 145, 7, 1579, +2336},
{24, 0, 145, 7, 2493, +1728},
{201, 394, 147, 7, 3280, +2028},
{0, 1, 146, 7, 1501, +2217},
{0, 30, 147, 7, 2370, +2439},
{0, 33, 145, 7, 2407, +2704},
{16, 0, 143, 8, 5597, +3713},
{201, 644, 147, 8, 5103, +3718},
{201, 698, 147, 8, 5252, +3451},
{201, 872, 147, 8, 6156, +3609},
{29, 0, 145, 8, 4593, +3753},
{30, 0, 145, 8, 6467, +4335},
{0, 14, 145, 8, 5154, +3241},
{0, 26, 145, 8, 5386, +3030},
{0, 41, 146, 8, 6116, +4843},
{132, 147, 147, 8, 6343, +3805},
{11, 0, 144, 9, 15155, +3319},
{12, 0, 143, 9, 14450, +2704},
{17, 0, 145, 9, 14162, +5122},
{19, 0, 145, 9, 14135, +5147},
{21, 0, 144, 9, 15245, +3723},
{24, 0, 145, 9, 14407, +1625},
{201, 1825, 146, 9, 14165, +2007},
{201, 1835, 145, 9, 14234, +827},
{201, 1884, 147, 9, 14484, +2422},
{31, 0, 145, 9, 14514, +1906},
{32, 0, 144, 9, 14411, +1344},
{0, 39, 146, 9, 14497, +4843},
{0, 44, 145, 9, 15038, +4739},
{162, 191, 147, 9, 14596, +5352},
{201, 1694, 145, 11, 12492, +8325},
{201, 400, 147, 11, 3350, +6002},
{201, 485, 147, 11, 4078, +6220},
{0, 1, 146, 11, 4320, +5355},
{0, 11, 145, 11, 5061, +5858},
{6, 0, 144, 12, 20176, -1230},
{23, 0, 146, 12, 20299, -1835},
{24, 0, 145, 12, 20273, -1813},
{26, 0, 145, 12, 20289, -1749},
{27, 0, 145, 12, 20194, -1907},
{17, 0, 145, 14, 2291, +6724},
{18, 0, 144, 14, 491, +5749},
{27, 0, 145, 14, 23590, +5545},
{201, 163, 147, 14, 1513, +6451},
{201, 3053, 146, 14, 26, +6606},
{201, 3062, 146, 14, 63, +5826},
{0, 3, 145, 15, 13518, -3300},
{9, 0, 143, 16, 21287, +7034},
{11, 0, 144, 16, 22292, +5825},
{19, 0, 144, 16, 20089, +7743},
{201, 2780, 147, 16, 21118, +5959},
{201, 2816, 146, 16, 21390, +5729},
{201, 2840, 146, 16, 21520, +5548},
{201, 460, 146, 16, 4100, +8042},
{31, 0, 144, 16, 22038, +6438},
{132, 461, 147, 16, 22039, +5949},
{10, 0, 145, 17, 1496, -1041},
{15, 0, 144, 17, 2433, +314},
{201, 186, 147, 17, 1559, +151},
{0, 66, 146, 17, 2128, -224},
{6, 0, 140, 20, 6451, -1643},
{12, 0, 142, 20, 6586, -2858},
{21, 0, 145, 20, 6561, -1403},
{108, 3945, 145, 20, 7166, -2319},
{17, 0, 144, 22, 8467, +2846},
{25, 0, 146, 22, 8268, +2656},
{201, 1177, 147, 22, 8056, +2732},
{201, 1245, 146, 22, 8358, 637},
{201, 1254, 147, 22, 8404, +1940},
{201, 1311, 147, 22, 9074, +2259},
{32, 0, 145, 22, 8122, +1739},
{0, 57, 146, 22, 8542, +3035},
{0, 66, 146, 22, 9014, +3215},
{201, 1633, 147, 24, 12207, +2703},
{201, 1639, 147, 24, 12244, +2535},
{0, 2, 146, 24, 12043, +2128},
{0, 24, 145, 24, 12351, +1823},
{0, 35, 145, 24, 12533, +2115},
{15, 0, 145, 25, 19064, -3704},
{19, 0, 146, 25, 18334, -3844},
{15, 0, 144, 26, 15427, +2618},
{18, 0, 146, 26, 15232, +3017},
{27, 0, 146, 26, 16147, +3352},
{32, 0, 145, 26, 15394, +3638},
{132, 128, 146, 26, 16117, +3321},
{11, 0, 143, 29, 12299, -1631},
{201, 1604, 147, 29, 12095, -1151},
{6, 0, 143, 30, 12560, +3819},
{0, 2, 146, 30, 12161, +4040},
{9, 0, 143, 31, 19307, +2758},
{11, 0, 143, 31, 19450, +4508},
{20, 0, 145, 31, 20474, +3629},
{21, 0, 145, 31, 21441, +2845},
{21, 0, 145, 31, 21441, +2845},
{201, 2486, 147, 31, 19121, +4951},
{30, 0, 145, 31, 19556, +5226},
{0, 16, 146, 31, 19418, +5032},
{0, 31, 144, 31, 20136, +4644},
{0, 49, 146, 31, 20410, +3218},
{0, 61, 145, 31, 21069, +3845},
{132, 130, 146, 31, 21208, +3227},
{103, 5137, 146, 31, 19459, +3501},
{15, 0, 144, 32, 20467, +1607},
{12, 0, 144, 34, 19482, +7016},
{21, 0, 146, 34, 17053, +5428},
{22, 0, 145, 34, 17322, +5511},
{23, 0, 145, 34, 18512, +5923},
{201, 2155, 147, 34, 17161, +6043},
{201, 2348, 146, 34, 18339, +5221},
{30, 0, 145, 34, 17419, +7209},
{0, 17, 145, 34, 16362, +5255},
{0, 41, 146, 34, 18002, +8000},
{132, 123, 147, 34, 13271, +6444},
{12, 0, 145, 35, 20591, +418},
{201, 2742, 147, 35, 21022, +711},
{16, 0, 143, 36, 2583, -4018},
{11, 5, 146, 36, 1398, -5612},
{0, 55, 147, 36, 4436, -848},
{108, 3556, 146, 36, 3124, -4425},
{29, 0, 145, 37, 2338, -2814},
{6, 0, 142, 38, 7346, +3153},
{11, 0, 144, 38, 7201, +2159},
{19, 0, 144, 38, 7444, +2424},
{201, 1083, 147, 38, 7256, +2030},
{201, 1108, 147, 38, 7328, +2253},
{0, 38, 145, 38, 6546, +1311},
{162, 70, 147, 38, 6278, +2047},
{6, 0, 143, 40, 17146, +1423},
{11, 0, 143, 40, 17150, +2450},
{19, 0, 145, 40, 16081, +1703},
{26, 0, 145, 40, 17237, +3709},
{201, 2052, 147, 40, 16289, +1825},
{201, 2063, 146, 40, 16318, +4536},
{201, 2315, 147, 40, 18250, +2724},
{201, 2411, 147, 40, 18523, +1432},
{0, 37, 146, 40, 16406, +413},
{0, 56, 146, 40, 16550, +2544},
{0, 95, 145, 40, 18015, +2136},
{0, 100, 146, 40, 18078, +2606},
{132, 129, 147, 40, 18359, +1659},
{12, 0, 143, 42, 8468, +625},
{201, 1348, 148, 42, 9245, +621},
{201, 1355, 147, 42, 9273, +614},
{201, 1365, 147, 42, 9315, +128},
{28, 0, 145, 42, 9291, -246},
{103, 396, 146, 42, 11323, -2916},
{201, 2894, 146, 45, 22189, +3746},
{0, 8, 146, 45, 22359, +3938},
{6, 0, 141, 46, 10084, +1158},
{15, 0, 142, 46, 10200, +1950},
{28, 0, 145, 46, 11279, +251},
{0, 6, 145, 46, 9320, +943},
{0, 49, 146, 46, 10350, +839},
{0, 54, 144, 46, 10556, +2445},
{0, 81, 146, 46, 11256, +1627},
{0, 83, 147, 46, 11268, +301},
{0, 90, 146, 46, 11347, +1648},
{132, 215, 147, 46, 10163, +1744},
{15, 0, 144, 47, 5445, -2227},
{108, 3750, 145, 47, 5204, -2114},
{21, 0, 145, 48, 14493, -1409},
{23, 0, 146, 48, 15210, -1533},
{201, 1962, 146, 48, 15387, -847},
{31, 0, 145, 50, 15569, -3358},
{201, 1282, 147, 51, 8508, +3504},
{201, 1333, 147, 51, 9184, +3522},
{201, 1338, 147, 51, 9210, +3811},
{201, 1369, 147, 51, 9354, +3958},
{201, 958, 146, 51, 6482, +5542},
{0, 12, 145, 51, 6462, +5927},
{0, 19, 146, 51, 7229, +5517},
{0, 38, 144, 51, 9188, +3648},
{9, 0, 144, 52, 18501, +3322},
{13, 0, 145, 52, 18443, +3940},
{14, 0, 145, 52, 18443, +3940},
{18, 0, 144, 52, 19138, +3909},
{201, 2474, 147, 52, 19091, +3436},
{32, 0, 144, 52, 18448, +3736},
{200, 0, 145, 52, 18570, +3254},
{162, 282, 146, 52, 18549, +3358},
{108, 5218, 147, 54, 20454, -3029},
{9, 0, 145, 55, 6288, -702},
{12, 0, 144, 55, 6238, +436},
{20, 0, 144, 59, 16309, +159},
{23, 0, 145, 59, 17180, -2417},
{26, 0, 145, 59, 16256, -2327},
{201, 2276, 147, 59, 18057, +1200},
{28, 0, 145, 59, 18031, -811},
{0, 36, 145, 59, 17153, -2636},
{0, 61, 146, 59, 17446, +235},
{0, 70, 144, 59, 18055, +230},
{9, 0, 140, 60, 5145, -812},
{11, 0, 142, 60, 5320, -18},
{16, 0, 145, 60, 5353, -523},
{17, 0, 143, 60, 5354, -555},
{18, 0, 144, 60, 5245, -224},
{20, 0, 144, 60, 5351, +956},
{26, 0, 145, 60, 5133, +252},
{27, 0, 144, 60, 5387, -236},
{201, 747, 145, 60, 5350, -600},
{201, 790, 146, 60, 5460, -416},
{32, 0, 142, 60, 5407, -157},
{0, 14, 146, 60, 5079, +830},
{0, 23, 145, 60, 5228, +333},
{0, 32, 144, 60, 5308, 557},
{0, 33, 146, 60, 5312, +318},
{0, 52, 146, 60, 5480, +627},
{12, 0, 143, 62, 21442, +953},
{201, 2841, 146, 62, 21543, +1943},
{201, 3007, 147, 62, 23228, +2034},
{0, 1, 144, 62, 21221, +1948},
{18, 0, 144, 63, 2507, +5554},
{201, 162, 146, 63, 1493, +4754},
{201, 331, 145, 63, 3009, +5221},
{201, 336, 147, 63, 3015, +3225},
{201, 369, 147, 63, 3171, +4029},
{0, 56, 146, 63, 4246, +3358},
{11, 24, 146, 66, 22366, -3140},
{6, 0, 144, 67, 2020, +246},
{201, 22, 147, 67, 174, +853},
{201, 3009, 147, 67, 23243, +343},
{30, 0, 145, 67, 1057, +2128},
{32, 0, 145, 67, 1137, +735},
{0, 35, 144, 67, 150, +849},
{0, 55, 146, 67, 399, +2126},
{0, 65, 146, 67, 499, +2743},
{0, 66, 146, 67, 546, +1911},
{0, 77, 146, 67, 1058, +455},
{112, 0, 145, 68, 7183, -3644},
{110, 19, 146, 68, 7343, -2328},
{103, 327, 144, 68, 7388, -2648},
{6, 0, 141, 72, 16294, -2626},
{9, 0, 143, 72, 16054, -1948},
{22, 0, 144, 72, 16120, -1928},
{31, 0, 145, 72, 16044, -1122},
{11, 0, 144, 74, 15348, +1032},
{16, 0, 145, 74, 18562, +412},
{201, 1919, 147, 74, 15127, +1917},
{0, 59, 145, 74, 18272, +12},
{132, 127, 146, 74, 15402, +1203},
{15, 0, 145, 75, 9525, -806},
{153, 0, 147, 75, 9541, +457},
{0, 35, 146, 75, 10433, +445},
{0, 40, 147, 75, 10493, -401},
{32, 0, 145, 76, 19490, +1909},
{110, 84, 146, 76, 19394, +1634},
{138, 0, 145, 77, 17591, -3015},
{0, 54, 145, 77, 19407, -1618},
{108, 5082, 146, 77, 19031, -1915},
{10, 0, 145, 78, 4226, +2538},
{25, 0, 145, 78, 4204, +2721},
{201, 422, 146, 78, 3368, +35},
{201, 495, 146, 78, 4077, +1510},
{201, 572, 147, 78, 4385, +2656},
{0, 7, 147, 78, 3344, +2428},
{0, 62, 146, 78, 4240, +2418},
{0, 118, 146, 78, 5293, +2509},
{201, 239, 147, 81, 2174, +2845},
{0, 6, 145, 81, 2124, +3018},
{27, 0, 145, 83, 9104, +6708},
{201, 1520, 147, 83, 11161, +5246},
{201, 1523, 144, 83, 11182, +3132},
{201, 1695, 146, 83, 12563, +5406},
{32, 0, 142, 83, 13239, +5456},
{132, 126, 146, 83, 11323, +6105},
{6, 0, 142, 84, 2318, +8916},
{201, 1972, 147, 84, 15292, +8027},
{108, 2682, 147, 84, 13407, +7651},
{11, 70, 145, 85, 8295, -4443},
{108, 4191, 145, 85, 9144, -4314},
{15, 0, 143, 86, 12417, -127},
{28, 0, 144, 86, 14016, +133},
{0, 17, 147, 86, 12225, +518},
{60, 0, 161, 1, 275, 3535},
{166, 0, 162, 1, 23388, 3546},
{167, 0, 162, 1, 46, 4333},
{167, 0, 162, 1, 46, 4333},
{181, 0, 161, 1, 2384, 3910},
{185, 0, 162, 1, 199, 4443},
{107, 5223, 162, 1, 542, 2404},
{130, 15196, 162, 1, 542, 2404},
{179, 0, 162, 4, 18585, 1422},
{182, 0, 161, 4, 19044, -541},
{182, 1469, 162, 4, 20011, 931},
{130, 11960, 161, 4, 19232, -1042},
{147, 0, 163, 5, 23244, -1719},
{182, 0, 162, 7, 2150, 1214},
{90, 0, 163, 8, 5034, 5038},
{96, 0, 162, 8, 5481, 3038},
{148, 0, 164, 8, 6348, 4230},
{152, 0, 162, 8, 5271, 3409},
{176, 0, 163, 8, 5091, 3900},
{178, 0, 159, 8, 6365, 3827},
{179, 0, 161, 8, 5218, 3231},
{182, 0, 163, 8, 6240, 4742},
{182, 346, 163, 8, 4526, 3830},
{149, 0, 163, 9, 14242, 2542},
{147, 0, 162, 11, 7217, 6940},
{152, 0, 162, 11, 5410, 6848},
{166, 0, 161, 11, 4512, 6810},
{177, 0, 161, 11, 3418, 6239},
{179, 0, 162, 11, 4059, 6148},
{196, 0, 161, 11, 4086, 5322},
{146, 0, 161, 12, 20171, -2119},
{129, 0, 164, 14, 246, 5417},
{166, 0, 165, 14, 175, 1714},
{187, 0, 162, 14, 549, 5834},
{191, 0, 163, 14, 1336, 5745},
{193, 0, 161, 14, 13, 6021},
{182, 623, 161, 14, 3114, 5754},
{21, 0, 162, 16, 21435, 5848},
{152, 0, 161, 16, 21352, 7837},
{107, 16115, 162, 17, 2351, -927},
{157, 129989, 162, 17, 2351, -9264},
{187, 0, 160, 20, 7081, -1155},
{139, 0, 161, 21, 7087, 1001},
{171, 0, 162, 22, 8567, 1931},
{194, 0, 160, 22, 8554, 1714},
{139, 0, 160, 26, 15486, 2809},
{182, 0, 161, 26, 15495, 3934},
{172, 0, 162, 30, 12594, 3749},
{197, 0, 159, 30, 12451, 4526},
{66, 0, 161, 31, 19288, 4603},
{67, 0, 162, 31, 19572, 4416},
{82, 0, 162, 31, 20468, 4603},
{145, 0, 161, 31, 20134, 3844},
{148, 0, 161, 31, 21433, 3801},
{150, 0, 163, 31, 20104, 3557},
{168, 0, 163, 31, 20095, 4752},
{172, 0, 161, 31, 19409, 3237},
{177, 0, 160, 31, 20196, 4754},
{182, 0, 162, 31, 20413, 4808},
{182, 0, 162, 31, 20413, 4808},
{192, 0, 163, 31, 20186, 3727},
{182, 460, 160, 31, 21420, 3531},
{107, 189256, 162, 31, 19572, 4418},
{157, 106516, 162, 32, 20486, 1750},
{150, 0, 160, 34, 12564, 6560},
{171, 0, 161, 34, 17564, 5813},
{180, 0, 160, 34, 19216, 7634},
{169, 0, 162, 36, 5098, -531},
{75, 0, 162, 38, 7209, 2460},
{129, 0, 161, 38, 7319, 2430},
{173, 0, 161, 38, 6109, 2601},
{184, 0, 162, 38, 6421, 3127},
{33, 0, 161, 40, 18303, 2152},
{144, 0, 162, 40, 16042, 5030},
{157, 46574, 161, 40, 17135, 4206},
{177, 0, 159, 42, 10376, -1323},
{182, 0, 161, 42, 10516, -2115},
{197, 0, 161, 42, 9511, -2301},
{139, 0, 160, 46, 9476, 1124},
{139, 0, 160, 47, 4596, -1448},
{197, 0, 161, 51, 7282, 460},
{109, 0, 162, 52, 18428, 3658},
{171, 0, 162, 52, 18323, 3660},
{177, 0, 162, 52, 19202, 3753},
{73, 0, 163, 55, 6564, 76},
{96, 0, 163, 55, 6224, 325},
{102, 0, 162, 55, 6532, -435},
{148, 0, 161, 55, 6584, 610},
{150, 0, 162, 55, 7069, -733},
{182, 614, 161, 55, 7010, -315},
{175, 0, 161, 59, 17297, -1928},
{182, 0, 161, 59, 16267, -1226},
{74, 0, 160, 60, 6255, 1443},
{101, 0, 164, 60, 6177, 831},
{146, 0, 162, 60, 5332, 709},
{190, 0, 160, 60, 5054, 111},
{149, 0, 162, 62, 21564, 2248},
{33, 0, 163, 63, 3451, 4447},
{149, 0, 162, 63, 21564, 2252},
{151, 0, 162, 63, 22059, 3330},
{197, 0, 162, 63, 3277, 4411},
{182, 466, 162, 63, 3415, 5130},
{176, 0, 159, 67, 23464, 329},
{198, 0, 161, 67, 1161, 2546},
{107, 26, 162, 67, 54, 847},
{157, 109003, 162, 67, 54, 847},
{157, 128396, 163, 67, 23491, 623},
{147, 0, 162, 68, 8075, -2255},
{148, 0, 163, 73, 18474, -1313},
{149, 0, 162, 73, 18370, -736},
{165, 0, 160, 73, 18583, -754},
{171, 0, 162, 73, 18554, -86},
{87, 0, 162, 74, 18474, 530},
{94, 0, 163, 74, 18194, -1537},
{72, 0, 163, 76, 20024, 2105},
{76, 0, 162, 76, 20024, 2036},
{195, 0, 161, 76, 20051, 2039},
{60, 0, 161, 77, 19343, -1622},
{170, 0, 162, 77, 17449, -1839},
{182, 1942, 161, 77, 19192, -1555},
{167, 0, 163, 78, 5491, 1904},
{172, 0, 162, 78, 4515, 2832},
{173, 0, 160, 78, 5452, 2425},
{197, 0, 161, 78, 5457, 2042},
{146, 0, 163, 83, 9184, 5124},
{186, 0, 160, 83, 10451, 6725},
{147, 0, 162, 86, 12473, 409},
{165, 0, 160, 86, 12252, 46},
{107, 113801, 163, 86, 13064, -2004},
{157, 157721, 163, 86, 13064, -2004},
{68, 0, 162, 88, 20373, 2630},
{130, 13571, 162, 88, 21099, 2637},
{34, 0, 169, 36, 1377, -5714},
{35, 0, 171, 72, 16054, -1948},
{36, 0, 169, 28, 12266, -6306},
{37, 0, 170, 20, 6586, -2858},
{38, 0, 169, 15, 14038, -6022},
{39, 0, 170, 1, 2039, 4220},
{40, 0, 169, 78, 4359, 1631},
{41, 0, 170, 16, 21186, 6235},
{42, 0, 170, 39, 22427, -4653},
{43, 0, 170, 63, 3243, 4952},
{44, 0, 170, 46, 10200, 1950},
{45, 0, 170, 63, 3082, 4057},
{46, 0, 170, 38, 6377, 1624},
{47, 0, 170, 83, 12540, 5558},
{48, 0, 170, 83, 13475, 4919},
{49, 0, 170, 39, 22082, -4658},
{50, 0, 170, 60, 5362, -112},
{51, 0, 170, 60, 5408, -157},
{52, 0, 170, 42, 9276, -840},
{53, 0, 170, 26, 15347, 2643},
{54, 0, 170, 1, 84, 2905},
{55, 0, 170, 85, 8095, -4720},
{56, 0, 169, 4, 19508, 852},
{57, 0, 170, 20, 7241, -2918},
{58, 0, 170, 64, 263, -4218},
{59, 0, 169, 72, 16294, -2626},
{61, 0, 168, 9, 14157, 1911},
{62, 0, 171, 47, 5327, -1749},
{63, 0, 170, 13, 9171, -5917},
{64, 0, 170, 80, 16487, -6902},
{65, 0, 170, 13, 8225, -5931},
{69, 0, 169, 28, 12477, -5941},
{70, 0, 170, 60, 5251, 621},
{71, 0, 169, 60, 5552, 724},
{77, 0, 168, 13, 6240, -5242},
{78, 0, 168, 8, 5167, 4560},
{79, 0, 170, 14, 92, 5909},
{80, 0, 170, 38, 7346, 3153},
{81, 0, 170, 14, 567, 6043},
{83, 0, 169, 31, 20414, 4517},
{84, 0, 170, 17, 436, -1759},
{85, 0, 170, 46, 11491, 1434},
{86, 0, 170, 17, 436, -1759},
{88, 0, 170, 72, 16003, -2237},
{89, 0, 170, 83, 11037, 6145},
{91, 0, 170, 78, 5263, 2836},
{92, 0, 170, 34, 17566, 5129},
{93, 0, 170, 62, 21442, 953},
{95, 0, 169, 66, 22577, -2937},
{97, 0, 170, 28, 12312, -5707},
{98, 0, 170, 26, 15347, 2643},
{99, 0, 171, 31, 20462, 3358},
{100, 0, 170, 72, 17425, -3902},
{104, 0, 169, 15, 14038, -6022},
{105, 0, 170, 7, 2072, 2328},
{106, 0, 171, 59, 16372, -1034},
{111, 0, 170, 9, 14450, 2704},
{113, 0, 170, 77, 18242, -3423},
{114, 0, 170, 84, 14507, 7409},
{115, 0, 170, 85, 8447, -5443},
{116, 0, 170, 62, 23048, 1512},
{117, 0, 170, 8, 5595, 4457},
{118, 0, 171, 17, 3023, 405},
{119, 0, 170, 15, 14067, -3622},
{120, 0, 170, 83, 11018, 5623},
{121, 0, 170, 13, 9132, -6943},
{122, 0, 169, 28, 12477, -5941},
{123, 0, 170, 60, 5320, -18},
{124, 0, 170, 1, 1097, 3537},
{125, 0, 170, 63, 3243, 4952},
{126, 0, 170, 20, 6227, -1757},
{127, 0, 170, 83, 13239, 5456},
{128, 0, 170, 68, 8036, -4000},
{131, 0, 170, 77, 18553, -2618},
{133, 0, 170, 61, 20256, -5644},
{134, 0, 170, 83, 11538, 5342},
{135, 0, 170, 84, 2318, 8916},
{136, 0, 169, 38, 7453, 2802},
{137, 0, 168, 21, 7393, 514},
{140, 0, 170, 59, 17349, 1234},
{141, 0, 169, 46, 10084, 1158},
{142, 0, 168, 60, 5145, -812},
{143, 0, 168, 15, 14396, -6050},
{154, 0, 170, 59, 17104, -1543},
{155, 0, 170, 31, 20222, 4015},
{156, 0, 170, 60, 5478, -940},
{158, 0, 170, 72, 17373, -4260},
{159, 0, 170, 62, 23038, 2805},
{160, 0, 170, 14, 405, 5632},
{161, 0, 170, 72, 17336, -3706},
{163, 0, 168, 20, 6451, -1643},
{164, 0, 169, 86, 13252, -1110},
{174, 0, 170, 13, 9171, -5917},
{183, 0, 168, 52, 18369, 3847},
{188, 0, 170, 72, 16502, -3418},
{189, 0, 170, 20, 7084, -2624},
{199, 0, 171, 46, 11141, 2031},
{7, 0, 168, 15, 14396, -6050},
{8, 0, 169, 15, 14396, -6050},
{6, 0, 170, 50, 14419, -4723},
{9, 0, 170, 39, 22427, -4653},
{15, 0, 170, 14, 567, 6043},
{15, 0, 170, 15, 12415, -4858},
{11, 0, 171, 15, 12084, -5043},
{11, 0, 170, 85, 8447, -5443},
{12, 0, 170, 15, 13399, -5328},
{32, 0, 171, 15, 13555, -4717},
{32, 0, 171, 59, 16372, -1034},
{18, 0, 170, 15, 14355, -4209},
{19, 0, 170, 85, 9221, -5501},
{20, 0, 170, 85, 9080, -4326}
};
//###############################################################################################################
//###############################################################################################################
// variables for button - instead of bounce lib - save flash memory
//###############################################################################################################
const int DEBOUNCE_DELAY = 50; // the debounce time; increase if the output flickers
int lastSteadyState = LOW; // the previous steady state from the input pin
int lastFlickerableState = LOW; // the previous flickerable state from the input pin
int currentState; // the current reading from the input pin
unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
unsigned long lastPressedTime = 0;
//###############################################################################################################
//###############################################################################################################
// LCD - VSS - GND // VCC - 5V // RW - GND // K - GND
//###############################################################################################################
const byte rs = 12;
const byte en = 13;
const byte d4 = 9;
const byte d5 = 8;
const byte d6 = 7;
const byte d7 = 6;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
byte myLCDbacklight = 255;
byte myLCDcontrast = 100;
//###############################################################################################################
//###############################################################################################################
// variables to steer menu
//###############################################################################################################
byte myDisplayMode = 0;
const char *const menuTopic[] = {"DEC", "Align", "Target", "Region", "Const", "Brightness", "Contrast", "Sensors", "LX200"};
const byte menuTopic_size = sizeof(menuTopic) / sizeof(menuTopic[0]);
byte myMenuTopicNo = 0;
//###############################################################################################################
//###############################################################################################################
// definition of special / greek characters - for LCD 1602 chinese version - adapt to your LCD if needed
//###############################################################################################################
// used lcd is like this https://www.waveshare.com/datasheet/LCD_en_PDF/LCD1602.pdf (see 14. font table)
const char ch_deg = (char)(223); // degree symbol
const char ch_sigma = (char)(246); // uppercase Sigma
// greek alphabet 1-24 = α β γ δ ε ζ η θ ι κ λ μ ν ξ ο π ρ σ τ υ φ χ ψ ω
// maximum 8 custom characters
// γ
char ch_def_1 = 'g'; // for identificatrion & replacement
byte ch_custom_1[] = {
B00000,
B10011,
B10010,
B10010,
B01110,
B00100,
B00100,
B00100
};
// δ
char ch_def_2 = 'd';
byte ch_custom_2[] = {
B00110,
B01001,
B00100,
B01110,
B10001,
B10001,
B01110,
B00000
};
// ζ
char ch_def_3 = 'z';
byte ch_custom_3[] = {
B01111,
B00010,
B00100,
B01000,
B01000,
B01111,
B00001,
B00110
};
// λ
char ch_def_4 = 'l';
byte ch_custom_4[] = {
B01100,
B00100,
B00100,
B01010,
B01010,
B10001,
B10001,
B00000
};
// ξ
char ch_def_5 = 'x';
byte ch_custom_5[] = {
B11111,
B00100,
B01000,
B00111,
B01000,
B10000,
B11111,
B00010
};
// φ
char ch_def_6 = 'p';
byte ch_custom_6[] = {
B00000,
B10111,
B10101,
B10101,
B10101,
B01110,
B00100,
B00100
};
// ψ
char ch_def_7 = 's';
byte ch_custom_7[] = {
B00000,
B00100,
B10101,
B10101,
B10101,
B01110,
B00100,
B00100
};
// Δ
char ch_def_8 = 'D';
byte ch_custom_8[] = {
B00000,
B00100,
B01010,
B01010,
B10001,
B10001,
B11111,
B00000
};
// lookup table placeholder chars with greek symbols
struct greekSymbols {
char originalChar;
char replaceChar;
};
const unsigned int greekSymbols_size = 26;
const struct greekSymbols greekSymbols[greekSymbols_size] =
{
{'a', (char)(224)}, // α
{'b', (char)(226)}, // β
{'g', 'g'}, // γ custom character
{'d', 'd'}, // δ custom character
{'e', (char)(227)}, // ε
{'z', 'z'}, // ζ custom character
{'j', 'n'}, // η
{'h', (char)(242)}, // θ
{'i', 'l'}, // ι
{'k', 'k'}, // κ
{'l', 'l'}, // λ custom character
{'m', (char)(228)}, // μ
{'n', 'v'}, // ν
{'x', 'x'}, // ξ custom character
{'o', 'o'}, // ο
{'p', (char)(247)}, // π
{'r', (char)(230)}, // ρ
{'s', (char)(229)}, // σ
{'t', 't'}, // τ
{'y', (char)(232)}, // υ
{'q', 'p'}, // φ custom character
{'c', 'x'}, // χ
{'w', 's'}, // ψ custom character
{'u', 'w'},
{'F', (char)(246)}, // Σ
{'D', '/'} // Δ
};
//###############################################################################################################
//###############################################################################################################
// definition of constellation names
//###############################################################################################################
struct constStruct {
char constName[4];
};
constStruct myConstellation;
const unsigned int constStruct_size = 89;
const struct constStruct const_PROGMEM[constStruct_size] PROGMEM = {
{"all"}, {"And"}, {"Ant"}, {"Aps"}, {"Aql"}, {"Aqr"}, {"Ara"}, {"Ari"}, {"Aur"}, {"Boo"}, {"Cae"}, {"Cam"}, {"Cap"}, {"Car"}, {"Cas"}, {"Cen"}, {"Cep"}, {"Cet"}, {"Cha"}, {"Cir"},
{"CMa"}, {"CMi"}, {"Cnc"}, {"Col"}, {"Com"}, {"CrA"}, {"CrB"}, {"Crt"}, {"Cru"}, {"Crv"}, {"CVn"}, {"Cyg"}, {"Del"}, {"Dor"}, {"Dra"}, {"Equ"}, {"Eri"}, {"For"}, {"Gem"}, {"Gru"},
{"Her"}, {"Hor"}, {"Hya"}, {"Hyi"}, {"Ind"}, {"Lac"}, {"Leo"}, {"Lep"}, {"Lib"}, {"LMi"}, {"Lup"}, {"Lyn"}, {"Lyr"}, {"Men"}, {"Mic"}, {"Mon"}, {"Mus"}, {"Nor"}, {"Oct"}, {"Oph"},
{"Ori"}, {"Pav"}, {"Peg"}, {"Per"}, {"Phe"}, {"Pic"}, {"PsA"}, {"Psc"}, {"Pup"}, {"Pyx"}, {"Ret"}, {"Scl"}, {"Sco"}, {"Sct"}, {"Ser"}, {"Sex"}, {"Sge"}, {"Sgr"}, {"Tau"}, {"Tel"},
{"TrA"}, {"Tri"}, {"Tuc"}, {"UMa"}, {"UMi"}, {"Vel"}, {"Vir"}, {"Vol"}, {"Vul"}
};
byte myConstellationNo = 0;
String myConstellationName = "";
//###############################################################################################################
//###############################################################################################################
// object type name and variables for deep sky objects
//###############################################################################################################
const char* myObjectTypeName[] = {"Quasar", "Dark Nebula", "Galaxy", "Bright Neb", "Clust + Neb", "Planet Neb", "SN Rem", "Glob Cluster", "Open Cluster", "Double Star", "Red Star", "Reference", "any"};
unsigned int myRefNo = 0; // number of selected reference star
unsigned int myTargetNo = 0; // number of selected target
//###############################################################################################################
//###############################################################################################################
// definition of cellestial regions = constellations of seasons defined in groups (as in Deep Sky Atlas) to filter targets and reference stars
//###############################################################################################################
// constellation for which deep sky objects exist in the list 0 = all
const byte myAllCONST[] = {0, 1, 2, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 44, 45, 46, 47, 48, 49, 50, 51, 52, 54, 55, 57, 59, 60, 61, 62, 63, 64, 66, 67, 68, 69, 71, 72, 73, 74, 75, 76, 77, 78, 80, 81, 83, 84, 85, 86, 88};
const byte myAllCONST_size = sizeof(myAllCONST) / sizeof(myAllCONST[0]);
// North - UMI,UMA,DRA,CEP,CAS,CAM
const byte myNorthCONST[] = {84, 83, 34, 16, 14, 11};
const byte myNorthCONST_size = sizeof(myNorthCONST) / sizeof(myNorthCONST[0]);
// Spring - LEO,LMI,SEX,HYA,CVN,COM,VIR,CRT,CRV,BOO,CRB,SER
const byte mySpringCONST[] = {46, 49, 75, 42, 30, 24, 86, 27, 29, 9, 26, 74};
const byte mySpringCONST_size = sizeof(mySpringCONST) / sizeof(mySpringCONST[0]);
// Summer - HER,LYR,OPH,SCO,CYG,VUL,SGE,DEL,EQU,AQL,SCT,SER,SGR,CAP
const byte mySummerCONST[] = {40, 52, 59, 72, 31, 88, 76, 32, 35, 4, 73, 74, 77, 12};
const byte mySummerCONST_size = sizeof(mySummerCONST) / sizeof(mySummerCONST[0]);
// Autumn - LAC,PEG,AQR,PSA,AND,TRI,PER,ARI,PSC,CET,SCL,FOR,ERI
const byte myAutumnCONST[] = {45, 62, 5, 66, 1, 81, 63, 7, 67, 17, 71, 37, 36};
const byte myAutumnCONST_size = sizeof(myAutumnCONST) / sizeof(myAutumnCONST[0]);
// Winter - AUR,TAU,ORI,LEP,LYN,GEM,CMI,MON,CMA,PUP,CNC
const byte myWinterCONST[] = {8, 78, 60, 47, 51, 38, 21, 55, 20, 68, 22};
const byte myWinterCONST_size = sizeof(myWinterCONST) / sizeof(myWinterCONST[0]);
// South - ANT,VEL,CAR,VOL,CHA,MUS,CRU,CEN,CRU,TRA,LUP,NOR,ARA,SCO,SGR,CRA,TEL,MIC,IND,PAV,GRU,PHE,SCL,FOR,ERI,HOR,RET,HYI,TUC,DOR,CAE,COL,PUP,PYX,PIC,MEN,APS,OCT
const byte mySouthCONST[] = {2, 85, 13, 28, 15, 28, 80, 50, 57, 6, 72, 77, 25, 54, 44, 61, 39, 64, 71, 37, 36, 41, 33, 23, 68, 69, 65};
const byte mySouthCONST_size = sizeof(mySouthCONST) / sizeof(mySouthCONST[0]);
const char* myregionNAME[] = {"all", "North", "Spring", "Summer", "Autumn", "Winter", "South"}; // no south to save flash
const byte regionArraySize = sizeof(myregionNAME) / sizeof(myregionNAME[0]); // Anzahl der Einträge
byte myRegionNo = 0; // all - 0; North - 1; .... ; South - 6
String myregionName = "";
//###############################################################################################################
//###############################################################################################################
// variables for calculation of position // all positions are calculated in seconds
//###############################################################################################################
long myRefStartTimeSec = 0; // Startzeit beim Setzen des Referenzsterns in Sekunden
long myCurrentRAsec = 0; // meine aktuelle Rektaszension in Sekunden
long myCurrentDECsec = 0; // meine aktuelle Deklination in Sekunden
long myLastRAsec = 0; // meine letzte Rektaszension in Sekunden
long myLastDECsec = 0; // meine letzte Deklination in Sekunden
long myReferenceRAsec = 0; // meine Rektaszensionsreferenz in Sekunden
long myReferenceDECsec = 0; // meine Deklinationsreferenz in Sekunden
long mySensorRAsec = 0; // Sensorwert der Rektaszension in Sekunden
long mySensorDECsec = 0; // Sensorwert der Deklination in Sekunden
long myTargetRAsec = 0; // Rektaszension des Ziels in Sekunden
long myTargetDECsec = 0; // Deklination des Ziels in Sekunden
const int secPerStepRA = 86400L / IMPULSE24HRA; // defines how many seconds RA is changed per rotary step // (24h * 3600sec = 86400sec) / (1:139 * 20 impulse = 2780) --> 31,079 sec / i
const int secPerStepDEC = 1296000L / IMPULSE360DEGDEC; // defines how many seconds DEC is changed per rotary step // (360° * 3600sec = 1296000sec) / (1:96 * 20 impulse = 1920) / --> 675 sec / i
int myDirectionDEC = 1; // saves the value of the direction of the DEC axis, important if the telescope is turned over
//###############################################################################################################
//###############################################################################################################
// for rotary encoders
//###############################################################################################################
static uint8_t prevNextCode_ROT = 0;
static uint16_t store_ROT = 0;
static uint8_t prevNextCode_RA = 0;
static uint16_t store_RA = 0;
static uint8_t prevNextCode_DEC = 0;
static uint16_t store_DEC = 0;
static int8_t val_ROT, val_RA, val_DEC;
int myImpulseRA = 0, myImpulseDEC = 0;
int myLastImpulseRA = 0, myLastImpulseDEC = 0;
const int8_t enc_table[] = {0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0};
//###############################################################################################################
//###############################################################################################################
// variables for LX200
//###############################################################################################################
byte statusLX200 = 0; // 0 - BT switched off / 1 - BT switched on / 2 - connected via BT & LX200 (frequent connect to LX200)
byte statusLX200old = 0;
byte btStatus = 0; // 0 - off / 1 - on
unsigned long lastLX200Message = 0;
DSOstruct externalObject; // instance LX200 object
//###############################################################################################################
//###############################################################################################################
// setup
//###############################################################################################################
void setup()
{
// for LX200 protocol & debugging
Serial.begin (9600);
// while(!Serial); // attention - only for debugging when in use with IDE!
// Serial.println(F("started"));
getSettingsFromEeprom(); // load settings (brightness,contrast,...)
setReference(); // set reference object to saved values
setTarget(); // set target object to saved values
setupLCD();
createCustomCharacters();
setupRotaryEncoders();
initExternalObject();
}
// software reset https://www.instructables.com/two-ways-to-reset-arduino-in-software/
void(* resetFunc) (void) = 0;//declare reset function at address 0
void setupLCD()
{
lcd.begin(16, 2);
updateLCD();
pinMode(LCD_BACKLIGHT_PIN, OUTPUT);
analogWrite(LCD_CONTRAST_PIN, myLCDcontrast); //set contrast
}
//Creating custom characters in CG-RAM
void createCustomCharacters()
{
lcd.createChar(1 , ch_custom_1);
lcd.createChar(2 , ch_custom_2);
lcd.createChar(3 , ch_custom_3);
lcd.createChar(4 , ch_custom_4);
lcd.createChar(5 , ch_custom_5);
lcd.createChar(6 , ch_custom_6);
lcd.createChar(7 , ch_custom_7);
lcd.createChar(8 , ch_custom_8);
}
void setupRotaryEncoders()
{
// HMI rotary encoder button
pinMode(ROTARY_SW, INPUT_PULLUP);
// HMI rotary encoder
pinMode(ROTARY_CLK, INPUT);
pinMode(ROTARY_DT, INPUT);
// it is better to use the integrated pull-ups of KY-040 (this requires "+" to be connected to 5V) - https://forum.arduino.cc/index.php?topic=242356.0
// as analog pins are used for rotary encoders - internal pull-ups are additionally used to avoid akward behaviour if not connected to sensors
// RA rotary encoder
pinMode(SENS_RA_CLK, INPUT_PULLUP);
pinMode(SENS_RA_DT, INPUT_PULLUP);
// DEC rotary encoder
pinMode(SENS_DEC_CLK, INPUT_PULLUP);
pinMode(SENS_DEC_DT, INPUT_PULLUP);
// switch for BT module
pinMode(BT_SWITCH, OUTPUT);
}
// initialise external object struct for receiving via LX200
void initExternalObject()
{
externalObject.objectPreFixNameNo = 202; // is "external" in DSO PROGMEM
externalObject.objectNumber = 0; // empty - no number in name
externalObject.objectTypeMagnitude = 0;
externalObject.objectConst = 0; // "all" in constellations
externalObject.objectRA = 0;
externalObject.objectDEC = 0;
}
//###############################################################################################################
// \setup
//###############################################################################################################
//###############################################################################################################
// loop
//###############################################################################################################
void loop()
{
analogWrite(LCD_BACKLIGHT_PIN, myLCDbacklight); // LCD backlight analogWrite: values from 0 to 255
updateRotaryEncoderButton();
updateRotaryEncoders();
calcCurrentPosition();
if (myDisplayMode == 9) displaySensorValue();
if (myDisplayMode == 11) displayCurrPos();
if (myDisplayMode == 12) displayTargetPos();
if (myDisplayMode == 13) displayDiffTargetCurrPos();
// LX200 status
updateLX200Status();
readSendLX200();
}
//###############################################################################################################
// \loop
//###############################################################################################################
//###############################################################################################################
// read sensor values
//###############################################################################################################
// reads rotary encoders
void updateRotaryEncoders()
{
if (val_ROT = read_rotary_ROT()) switchSelection(val_ROT);
if (val_RA = read_rotary_RA())
{
mySensorRAsec = mySensorRAsec + val_RA * secPerStepRA;
myImpulseRA = myImpulseRA + val_RA; // for sensor test
}
if (val_DEC = read_rotary_DEC())
{
mySensorDECsec = mySensorDECsec + val_DEC * secPerStepDEC * myDirectionDEC;
myImpulseDEC = myImpulseDEC + val_DEC * myDirectionDEC; // for sensor test
}
}
// reads rotary encoder button
void updateRotaryEncoderButton()
{
// copy from https://arduinogetstarted.com/tutorials/arduino-button-debounce
currentState = digitalRead(ROTARY_SW);
if (currentState != lastFlickerableState)
{
lastDebounceTime = millis();
lastFlickerableState = currentState;
}
if ((millis() - lastDebounceTime) > DEBOUNCE_DELAY)
{
if (lastSteadyState == HIGH && currentState == LOW)
{
switchMode();
updateLCD();
lastPressedTime = millis();
}
else if (lastSteadyState == LOW && currentState == HIGH)
{
// if button pressed > 5 seconds -> reset
if (millis() - lastPressedTime > 5000) resetFunc(); // call reset
}
lastSteadyState = currentState;
}
}
// read rotary encoder for HMI
// robust rotary encoder reading https://www.best-microcontroller-projects.com/rotary-encoder.html
// A vald CW or CCW move returns 1,invalid returns 0.
int8_t read_rotary_ROT()
{
prevNextCode_ROT <<= 2;
if (digitalRead(ROTARY_DT)) prevNextCode_ROT |= 0x02;
if (digitalRead(ROTARY_CLK)) prevNextCode_ROT |= 0x01;
prevNextCode_ROT &= 0x0f;
// If valid then store as 16 bit data.
if (enc_table[prevNextCode_ROT] )
{
store_ROT <<= 4;
store_ROT |= prevNextCode_ROT;
if ((store_ROT & 0xff) == 0x2b) return -1;
if ((store_ROT & 0xff) == 0x17) return 1;
}
return 0;
}
// read rotary encoder for RA
int8_t read_rotary_RA()
{
prevNextCode_RA <<= 2;
if (digitalRead(SENS_RA_DT)) prevNextCode_RA |= 0x02;
if (digitalRead(SENS_RA_CLK)) prevNextCode_RA |= 0x01;
prevNextCode_RA &= 0x0f;
// If valid then store as 16 bit data.
if (enc_table[prevNextCode_RA] )
{
store_RA <<= 4;
store_RA |= prevNextCode_RA;
if ((store_RA & 0xff) == 0x2b) return -1;
if ((store_RA & 0xff) == 0x17) return 1;
}
return 0;
}
// read rotary encoder for DEC
int8_t read_rotary_DEC()
{
prevNextCode_DEC <<= 2;
if (digitalRead(SENS_DEC_DT)) prevNextCode_DEC |= 0x02;
if (digitalRead(SENS_DEC_CLK)) prevNextCode_DEC |= 0x01;
prevNextCode_DEC &= 0x0f;
// If valid then store as 16 bit data.
if (enc_table[prevNextCode_DEC] )
{
store_DEC <<= 4;
store_DEC |= prevNextCode_DEC;
if ((store_DEC & 0xff) == 0x2b) return -1;
if ((store_DEC & 0xff) == 0x17) return 1;
}
return 0;
}
//###############################################################################################################
// read sensor values
//###############################################################################################################
//###############################################################################################################
// get & set of object data
//###############################################################################################################
// returns the type as number of a deep sky object
byte getObjectType(byte typeMagnitude)
{
return (typeMagnitude / 14); // decoding of object type from typeMagnitude
}
// returns the type as string of a deep sky object
String getObjectTypeName(byte typeMagnitude)
{
return myObjectTypeName[(typeMagnitude / 14) - 1];
}
// returns the magnitude of a deep sky object
String getMagnitude(byte typeMagnitude) // calcs the right magnitude - here modulo 14 as coded
{
String strFlMag = (String)(typeMagnitude % 14) + "m";
return strFlMag;
}
// returns the name of a constellation as string from a lookup tabel according to its number
String getConstName(int no)
{
constStruct oneConstellation;
// copy constellations data from PROGMEM into oneConstellation according to no
memcpy_P (&oneConstellation, &const_PROGMEM[no], sizeof oneConstellation);
return (String)oneConstellation.constName;
}
// returns the current constellation for filtering
String getCurrentConstName()
{
String constellationName;
constellationName = getConstName(myConstellationNo);
return constellationName;
}
// returns the current cellestial region
String getSetregionName()
{
return myregionNAME[myRegionNo];
}
// set reference star
void setReference()
{
// copy reference data from PROGMEM into myReference according to myRefNo
memcpy_P (&myReference, &DSO_PROGMEM[myRefNo], sizeof myReference);
setReferenceRA_DEC();
}
// RA and DEC of selected target are set
void setReferenceRA_DEC()
{
// transfer RA / DEC into internal format (seconds)
myReferenceRAsec = calcRAsecFromRA(myReference.objectRA);
myReferenceDECsec = calcDECsecFromDEC(myReference.objectDEC);
}
// set target
void setTarget()
{
// copy reference data from PROGMEM into myTarget according to myTargetNo
memcpy_P (&myTarget, &DSO_PROGMEM[myTargetNo], sizeof myTarget);
setTargetRA_DEC();
}
// RA and DEC of selected target are set
void setTargetRA_DEC()
{
// transfer RA / DEC into internal format (seconds)
myTargetRAsec = calcRAsecFromRA(myTarget.objectRA);
myTargetDECsec = calcDECsecFromDEC(myTarget.objectDEC);
}
//###############################################################################################################
// \get & set of object data
//###############################################################################################################
//###############################################################################################################
// calculations and settings of positions
//###############################################################################################################
// calculation of RA seconds
unsigned int calcRAsecFromRA(unsigned int ra)
{
int h = ra / 1000;
int m = (ra - h * 1000) / 10;
int s = (ra - h * 1000 - m * 10) * 6;
unsigned int raSec = h * 3600L + m * 60 + s;
return raSec;
}
// calculation of DEC seconds
long calcDECsecFromDEC(int dec)
{
int deg = dec / 100;
int m = (dec - deg * 100);
long decSec = deg * 3600L + m * 60;
return decSec;
}
// calculation of current telescope position
void calcCurrentPosition()
{
myCurrentRAsec = myReferenceRAsec + myRefStartTimeSec + mySensorRAsec - millis() / 1000;
myCurrentDECsec = myReferenceDECsec + mySensorDECsec;
}
// sets the sensor values to zero - needed for alignment with reference star
void resetSensorTime()
{
mySensorRAsec = 0; // Sensorwert der Rektaszension
mySensorDECsec = 0; // Sensorwert der Deklination
myRefStartTimeSec = millis() / 1000;
}
//###############################################################################################################
// \calculations and settings of positions
//###############################################################################################################
//###############################################################################################################
// display information
//###############################################################################################################
// display the current position
void displayCurrPos()
{
if (myLastRAsec != myCurrentRAsec || myLastDECsec != myCurrentDECsec)
{
myLastRAsec = myCurrentRAsec;
myLastDECsec = myCurrentDECsec;
displayRA_DEC("Curr ", "Coord", myCurrentRAsec, myCurrentDECsec);
}
}
// display position of selected target
void displayTargetPos()
{
displayRA_DEC(getObjectName(myTarget.objectPreFixNameNo, myTarget.objectNumber, myTarget.objectConst), "Coord", myTargetRAsec, myTargetDECsec);
}
// calulation & display of difference between current position & target position
void displayDiffTargetCurrPos()
{
long diffRAsec = myTargetRAsec - myCurrentRAsec;
long diffDECsec = myTargetDECsec - myCurrentDECsec;
if (myLastRAsec != myCurrentRAsec || myLastDECsec != myCurrentDECsec) // only if position has changed
{
myLastRAsec = myCurrentRAsec;
myLastDECsec = myCurrentDECsec;
displayRA_DEC(getObjectName(myTarget.objectPreFixNameNo, myTarget.objectNumber, myTarget.objectConst), "Diff ", diffRAsec , diffDECsec);
}
}
// display of RA and DEC - generic use for reference stars & target
void displayRA_DEC(String text1, String text2, long rekSec, long dekSec)
{
// Rektaszension //
int sign = 1.0;
if (rekSec < 0) sign = -1.0;
byte s = (abs(rekSec)) % 60; // Das Zeichen: "%" ist der Modulo-Operator // vorher int
byte m = (abs(rekSec / 60)) % 60;
byte h = (abs(rekSec / 3600)) % 24;
lcd.setCursor(0, 0);
printObjectName(text1);
lcd.setCursor(8, 0);
if (sign < 0) lcd.print(F("-"));
else lcd.print(F("+"));
if (h < 10) lcd.print(F(" "));
lcd.print(h);
lcd.print(F(":"));
if (m < 10) lcd.print(F("0"));
lcd.print(m);
lcd.print(F(","));
lcd.print(s / 6);
// DEC // +90° - -90°
sign = 1.0;
if (dekSec < 0) sign = -1.0;
s = (abs(dekSec)) % 60; // Das Zeichen: "%" ist der Modulo-Operator
m = (abs(dekSec / 60)) % 60;
h = (abs(dekSec / 3600)) % 180;
lcd.setCursor(0, 1);
lcd.print(text2);
lcd.setCursor(8, 1);
if (sign < 0) lcd.print(F("-"));
else lcd.print(F("+"));
if (h < 10) lcd.print(F(" "));
lcd.print(h);
lcd.print(ch_deg);
if (m < 10) lcd.print(F("0"));
lcd.print(m);
lcd.print(F("'"));
}
// display current sensor values
void displaySensorValue()
{
if (myImpulseRA != myLastImpulseRA || myImpulseDEC != myLastImpulseDEC)
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Imp RA"));
lcd.setCursor(0, 1);
lcd.print(F("Imp DEC"));
lcd.setCursor(10, 0);
lcd.print(myImpulseRA);
lcd.setCursor(10, 1);
lcd.print(myImpulseDEC);
myLastImpulseRA = myImpulseRA;
myLastImpulseDEC = myImpulseDEC;
}
}
// update LCD according to selected display mode
void updateLCD()
{
lcd.clear();
lcd.setCursor(0, 0);
if (myDisplayMode == 0)
{
lcd.print(F("SpotNik v")); // DO NOT REMOVE
lcd.print(VERSION);
lcd.setCursor(0, 1);
lcd.print(F("developed by MR")); // DO NOT REMOVE
}
if (myDisplayMode == 1) // main menu
{
lcd.print(F(">"));
lcd.setCursor(1, 0);
lcd.print(menuTopic[myMenuTopicNo]); // {" reverse", "Ref","Target","region","Const","Bright","Contr","Test"};
lcd.setCursor(8, 0);
switch (myMenuTopicNo) {
case 0:
if (myDirectionDEC == 1) lcd.print(F("normal"));
else lcd.print(F("reverse"));
break;
case 1:
printObjectName(getObjectName(myReference.objectPreFixNameNo, myReference.objectNumber, myReference.objectConst));
break;
case 2:
printObjectName(getObjectName(myTarget.objectPreFixNameNo, myTarget.objectNumber, myTarget.objectConst));
//if (statusLX200 != 2) printObjectName(getObjectName(myTarget.objectPreFixNameNo,myTarget.objectNumber,myTarget.objectConst));
//else lcd.print(F("external")); // if connection to LX200 source - no usage of internal star database
break;
case 3:
lcd.print(getSetregionName());
// if (statusLX200 != 2) lcd.print(getSetregionName());
// else lcd.print(F("external"));
break;
case 4:
lcd.print(getCurrentConstName());
// if (statusLX200 != 2) lcd.print(getCurrentConstName());
// else lcd.print(F("external"));
break;
case 8:
if (statusLX200 == 0) lcd.print(F("BT off"));
if (statusLX200 == 1) lcd.print(F("BT on"));
if (statusLX200 == 2) lcd.print(F("conn"));
break;
}
lcd.setCursor(1, 1);
if (myMenuTopicNo + 1 < menuTopic_size)
{
lcd.print(menuTopic[myMenuTopicNo + 1]);
}
else
{
lcd.print(menuTopic[0]);
}
}
if (myDisplayMode == 2)
{
lcd.print(F("Direction of DEC"));
lcd.setCursor(0, 1);
lcd.print(F(">"));
if (myDirectionDEC == 1) lcd.print(F("normal"));
else lcd.print(F("reverse"));
}
if (myDisplayMode == 3)
{
printObjectName(getObjectName(myReference.objectPreFixNameNo, myReference.objectNumber, myReference.objectConst));
lcd.setCursor(13, 0);
lcd.print(getConstName(myReference.objectConst));
lcd.setCursor(0, 1);
lcd.print(getObjectTypeName(myReference.objectTypeMagnitude));
lcd.setCursor(13, 1);
lcd.print(getMagnitude(myReference.objectTypeMagnitude));
}
if (myDisplayMode == 4)
{
printObjectName(getObjectName(myTarget.objectPreFixNameNo, myTarget.objectNumber, myTarget.objectConst));
lcd.setCursor(13, 0);
lcd.print(getConstName(myTarget.objectConst));
lcd.setCursor(0, 1);
lcd.print(getObjectTypeName(myTarget.objectTypeMagnitude));
lcd.setCursor(13, 1);
lcd.print(getMagnitude(myTarget.objectTypeMagnitude));
}
if (myDisplayMode == 5)
{
lcd.print(F("Celestial Region"));
lcd.setCursor(0, 1);
lcd.print(F(">"));
lcd.print(getSetregionName());
}
if (myDisplayMode == 6)
{
lcd.print(F("Constellation"));
lcd.setCursor(11, 1);
lcd.print(getSetregionName());
lcd.setCursor(0, 1);
lcd.print(F(">"));
lcd.print(getCurrentConstName());
}
if (myDisplayMode == 7)
{
lcd.print(F("LCD Brightness"));
lcd.setCursor(0, 1);
lcd.print(F(">"));
lcd.print(myLCDbacklight);
}
if (myDisplayMode == 8)
{
lcd.print(F("LCD Contrast"));
lcd.setCursor(0, 1);
lcd.print(F(">"));
lcd.print(myLCDcontrast);
}
if (myDisplayMode == 9)
{
lcd.print(F("For test"));
lcd.setCursor(0, 1);
lcd.print(F("turn DEC / RA"));
myImpulseRA = 0;
myImpulseDEC = 0;
myLastImpulseRA = 0;
myLastImpulseDEC = 0;
}
if (myDisplayMode == 10)
{
lcd.print(F("LX200 Connection"));
lcd.setCursor(0, 1);
lcd.print(F(">"));
if (statusLX200 == 0) lcd.print(F("Bluetooth off"));
if (statusLX200 == 1) lcd.print(F("Bluetooth on"));
if (statusLX200 == 2) lcd.print(F("LX200 connected"));
}
}
// returns name of deep sky object based on coded name its number and its constellation
String getObjectName(byte objectprefixNameNo, unsigned int objectNumber, byte objectConst)
{
String objectName = "";
int indexOfHash = -1;
DSONameStruct oneDSONameStruct;
if (objectprefixNameNo > 0)
{
// get name accordng to name number from lookup table
memcpy_P (&oneDSONameStruct, &DSO_NAME_PROGMEM[objectprefixNameNo - 1], sizeof oneDSONameStruct);
objectName = oneDSONameStruct.objectName;
indexOfHash = objectName.indexOf('#');
if (indexOfHash > -1)
{
// replace char with greek char
String charToReplace = objectName.substring(indexOfHash + 1, indexOfHash + 2);
objectName = objectName.substring(0, indexOfHash) + objectName.substring(indexOfHash + 2); // delete # and next char from string
// loop over the greek symbols
for (int i; i < greekSymbols_size; i++)
{
if ((String)charToReplace == (String)greekSymbols[i].originalChar)
{
charToReplace = greekSymbols[i].replaceChar;
objectName = objectName + charToReplace;
break;
}
}
}
}
if (objectNumber > 0)
{
objectName = objectName + (String)objectNumber;
}
// if object is only number,greek Symbol or max. two characters,accept 'M' - add constellation for identification
if (objectName.charAt(1) == NULL || objectprefixNameNo == 0 || (objectName.charAt(2) == NULL && objectNumber == 0)) // oder nur Zahlen!!!
{
objectName = objectName + ' ' + getConstName(objectConst);
}
return objectName;
}
// some greek symbols are custom, print function needed
void printObjectName(String objectName)
{
byte customChar = 0;
char charAt0 = objectName.charAt(0);
if (charAt0 == ch_def_1) customChar = 1;
else if (charAt0 == ch_def_2) customChar = 2;
else if (charAt0 == ch_def_3) customChar = 3;
else if (charAt0 == ch_def_4) customChar = 4;
else if (charAt0 == ch_def_5) customChar = 5;
else if (charAt0 == ch_def_6) customChar = 6;
else if (charAt0 == ch_def_7) customChar = 7;
if (customChar > 0) lcd.write(customChar);
else
{
lcd.print(objectName);
return;
}
lcd.print(F(" "));
lcd.print(objectName.substring(2, 8));
}
//###############################################################################################################
// \display information
//###############################################################################################################
//###############################################################################################################
// switching
//###############################################################################################################
// myDisplayMode - rotary encoder for change
// 0 = welcome, 1 = top menu, 2 = change direction, 3 = set reference, 4 = set target, 5 = set region, 6 = set constellation, 7 = set LCD brightness, 8 = set LCD contrast
// 9 = sensor test, 10 = set bluetooth, 11 = show current position, 12 = show target position, 13 = show difference target - current position
void switchMode()
{
saveSettingsToEeprom(); // save settings to eeprom each time the button is pressed
if (myDisplayMode == 0) // welcome
{
myDisplayMode = 1; // top menue
}
else if (myDisplayMode == 1)
{
myDisplayMode = myMenuTopicNo + 2;
}
else if (myDisplayMode == 3) // set reference
{
resetSensorTime();
myLastDECsec = 0; // set once to zero to update display
myDisplayMode = 11; // show current position
}
else if (myDisplayMode == 4) // set target
{
setTargetRA_DEC();
myDisplayMode = 13; // show diff position
}
// set direction // region // constellation // set brightness // set contrast // sensor test // show current position // show diff position
else if (myDisplayMode == 2 || myDisplayMode >= 5)
{
myDisplayMode = 1; // return to top level menu
}
lcd.clear();
}
// function of rotary encoder changes acording to current display mode
void switchSelection(int dir)
{
if (myDisplayMode == 0)
{
myDisplayMode = 1;
updateLCD();
}
else if (myDisplayMode == 1) changeMenu(dir);
if (myDisplayMode == 2) changeDirectionDEC(dir);
if (myDisplayMode == 3) changeReference(dir);
if (myDisplayMode == 4) changeTarget(dir);
if (myDisplayMode == 5) changeregion(dir);
if (myDisplayMode == 6) changeConstellation(dir);
if (myDisplayMode == 7) changeLCDBacklight(dir);
if (myDisplayMode == 8) changeLCDcontrast(dir);
if (myDisplayMode == 10) changeBTconnection(dir);
if (myDisplayMode == 11 || myDisplayMode == 12 || myDisplayMode == 13) changeView(dir);
updateLCD();
}
// change menu topics
void changeMenu(int dir)
{
if (dir == 1)
{
if ((myMenuTopicNo + 1) < menuTopic_size)
{
myMenuTopicNo = myMenuTopicNo + 1;
}
else
{
myMenuTopicNo = 0;
}
}
else if (dir == -1)
{
if (myMenuTopicNo > 0)
{
myMenuTopicNo = myMenuTopicNo - 1;
}
else
{
myMenuTopicNo = menuTopic_size - 1;
}
}
}
// according to the direction of the DEC axis the value of the DEC sensor has to be reverted
void changeDirectionDEC(int dir)
{
if (dir == 1 || dir == -1)
{
if (myDirectionDEC == 1) myDirectionDEC = -1;
else myDirectionDEC = 1;
}
}
// calls changeObject for object type reference
void changeReference (int dir)
{
changeObject(dir, 'r');
}
// calls changeObject for object type target
void changeTarget(int dir)
{
changeObject(dir, 't');
}
// change referenc star including filter according to selected sky region
void changeObject (int dir, char objectType)
{
bool constFound = false;
DSOstruct oneObject; // instance of reference for search & filter
unsigned int objectNo;
unsigned int numberOfLoops = 0;
if (objectType == 'r')
{
objectNo = myRefNo; // set start no of object
}
else
{
objectNo = myTargetNo;
}
while (constFound == false)
{
if (dir == 1)
{
if ((objectNo + 1) < DSO_PROGMEM_size)
{
objectNo = objectNo + 1;
}
else
{
objectNo = 0;
}
}
if (dir == -1) // before else if - but what if no fitting star at beginning before rotary turning?
{
if (objectNo > 0)
{
objectNo = objectNo - 1;
}
else
{
objectNo = DSO_PROGMEM_size - 1;
}
}
memcpy_P (&oneObject, &DSO_PROGMEM[objectNo], sizeof oneObject); // get next DSO object from struct and copy it into oneObject
// filter on a constellation
// if a constellation is selected,object is a target and constellation of object fits to selected constellation
if (objectType == 't' && myConstellationNo > 0 && getObjectType(oneObject.objectTypeMagnitude) > 0 && getObjectType(oneObject.objectTypeMagnitude) < 12 && oneObject.objectConst == myConstellationNo)
{
constFound = true;
}
// filter on regions
else if ( (objectType == 'r' && getObjectType(oneObject.objectTypeMagnitude) == 12) || // reference stars // filter on objects of type "reference" = no 12
(myConstellationNo == 0 && objectType == 't' && getObjectType(oneObject.objectTypeMagnitude) > 0 && getObjectType(oneObject.objectTypeMagnitude) < 12)) // target objects
{
// filter targets by constellations of the selected region
// myregionNAME[]={"All","North","Spring","Summer","Autumn","Winter","South"};
if (myRegionNo == 1) // region = north
{
for (int i = 0; i < myNorthCONST_size; i++)
{
if (oneObject.objectConst == myNorthCONST[i])
{
constFound = true;
break;
}
}
}
else if (myRegionNo == 2) // region = spring
{
for (int i = 0; i < mySpringCONST_size; i++)
{
if (oneObject.objectConst == mySpringCONST[i])
{
constFound = true;
break;
}
}
}
else if (myRegionNo == 3) // region = summer
{
for (int i = 0; i < mySummerCONST_size; i++)
{
if (oneObject.objectConst == mySummerCONST[i])
{
constFound = true;
break;
}
}
}
else if (myRegionNo == 4) // region = autumn
{
for (int i = 0; i < myAutumnCONST_size; i++)
{
if (oneObject.objectConst == myAutumnCONST[i])
{
constFound = true;
break;
}
}
}
else if (myRegionNo == 5) // region = winter
{
for (int i = 0; i < myWinterCONST_size; i++)
{
if (oneObject.objectConst == myWinterCONST[i])
{
constFound = true;
break;
}
}
}
else if (myRegionNo == 6) // region = south
{
for (int i = 0; i < mySouthCONST_size; i++)
{
if (oneObject.objectConst == mySouthCONST[i])
{
constFound = true;
break;
}
}
}
else // all constellations
{
constFound = true;
}
}
}// end while
if (objectType == 'r')
{
myRefNo = objectNo;
myReference = oneObject; // copy selected reference object in my reference object
setReferenceRA_DEC();
}
else
{
myTargetNo = objectNo;
myTarget = oneObject; // copy selected target object in my target object
setTargetRA_DEC();
}
updateLCD();
}
// change region
void changeregion(int dir)
{
if (dir == 1)
{
if ((myRegionNo + 1) < regionArraySize) {
myRegionNo = myRegionNo + 1;
}
else {
myRegionNo = 0;
}
}
else if (dir == -1)
{
if (myRegionNo > 0) {
myRegionNo = myRegionNo - 1;
}
else {
myRegionNo = regionArraySize - 1;
}
}
myTargetNo = 0; // reset target,when aera has changed
myConstellationNo = 0; // reset constellation,when aera has changed
updateLCD();
}
// set constellation
void changeConstellation(int dir)
{
bool constFound = false;
while (constFound == false)
{
if (dir == 1)
{
if ((myConstellationNo) < constStruct_size - 1) {
myConstellationNo = myConstellationNo + 1;
}
else {
myConstellationNo = 0;
}
}
else if (dir == -1)
{
if (myConstellationNo > 0) {
myConstellationNo = myConstellationNo - 1;
}
else {
myConstellationNo = constStruct_size - 1;
}
}
// filter targets by constellations of the selected region
// myregionNAME[]={"All","North","Spring","Summer","Autumn","Winter","South"};
if (myRegionNo == 1) // region = north
{
for (int i = 0; i < myNorthCONST_size; i++)
{
if (myConstellationNo == myNorthCONST[i])
{
constFound = true;
break;
}
}
}
else if (myRegionNo == 2) // region = spring
{
for (int i = 0; i < mySpringCONST_size; i++)
{
if (myConstellationNo == mySpringCONST[i])
{
constFound = true;
break;
}
}
}
else if (myRegionNo == 3) // region = summer
{
for (int i = 0; i < mySummerCONST_size; i++)
{
if (myConstellationNo == mySummerCONST[i])
{
constFound = true;
break;
}
}
}
else if (myRegionNo == 4) // region = autumn
{
for (int i = 0; i < myAutumnCONST_size; i++)
{
if (myConstellationNo == myAutumnCONST[i])
{
constFound = true;
break;
}
}
}
else if (myRegionNo == 5) // region = winter
{
for (int i = 0; i < myWinterCONST_size; i++)
{
if (myConstellationNo == myWinterCONST[i])
{
constFound = true;
break;
}
}
}
else if (myRegionNo == 6) // region = south
{
for (int i = 0; i < mySouthCONST_size; i++)
{
if (myConstellationNo == mySouthCONST[i])
{
constFound = true;
break;
}
}
}
else // all constellations
{
for (int i = 0; i < myAllCONST_size; i++)
{
if (myConstellationNo == myAllCONST[i])
{
constFound = true;
break;
}
}
}
}
myTargetNo = 0; // reset target every time when constellation was changed
updateLCD();
}
// switch view between current position, diff position & target coordinates
void changeView(int dir)
{
lcd.clear();
myDisplayMode = myDisplayMode + dir;
if (myDisplayMode > 13) myDisplayMode = 11;
if (myDisplayMode < 11) myDisplayMode = 13;
}
// set LCD brightness
void changeLCDBacklight(int dir)
{
myLCDbacklight = myLCDbacklight + dir * 8;
if (myLCDbacklight > 255) myLCDbacklight = 0;
if (myLCDbacklight < 0) myLCDbacklight = 255;
}
// set LCD contrast
void changeLCDcontrast(int dir)
{
myLCDcontrast = myLCDcontrast + dir * 5;
if (myLCDcontrast > 255) myLCDcontrast = 0;
if (myLCDcontrast < 0) myLCDcontrast = 255;
analogWrite(LCD_CONTRAST_PIN, myLCDcontrast);
}
// 0 - BT switched off / 1 - BT switched on
void changeBTconnection(int dir)
{
if (btStatus == 0) // switch BT on if off
{
btStatus = 1;
statusLX200 = 1;
digitalWrite(BT_SWITCH, HIGH);
}
else if (btStatus != 0) // switch BT off
{
btStatus = 0;
statusLX200 = 0;
digitalWrite(BT_SWITCH, LOW);
}
updateLCD();
}
//###############################################################################################################
// \switching
//###############################################################################################################
//###############################################################################################################
// LX200 communication
//###############################################################################################################
// set the status of LX200 to control LCD etc
void updateLX200Status()
{
// 0 - BT switched off / 1 - BT switched on
if (btStatus == 1)
{
// if frequent feedback from LX200 - last request > 4 sek
if ((millis() - lastLX200Message) > 4000)
{
statusLX200 = 1; // BT on - but no LX200 connection
}
else
{
statusLX200 = 2; // LX200 connected
}
}
// LX200 status changend - update lcd in relevant views (main menu & BT)
if (statusLX200 != statusLX200old && (myDisplayMode == 10 || myDisplayMode == 1))
{
updateLCD();
statusLX200old = statusLX200;
}
}
// called if a LX200 message was received
void receivedLX200message() // received
{
lastLX200Message = millis();
}
// read the bluetooth message and trigger functions according to message type
void readSendLX200()
{
if (Serial.available())
{
char message[14] = "";
byte i = 0;
while (Serial.available() > 0)
{
char a = Serial.read(); // Stores current byte
message[i] += a; // Append current byte to message String
delay(10);
i++;
}
// all LX200 info from https://www.meade.com/support/TelescopeProtocol_2010-10.pdf
// LX200 message :GR#
// Get Telescope RA
// Returns: HH:MM.T# or HH:MM:SS#Depending which precision is set for the telescope
if (message[0] == ':' && message[1] == 'G' && message[2] == 'R' && message[3] == '#')
{
receivedLX200message();
sendLX200RA();
}
// LX200 message :GD# or :RS#:GD# or :RM#:GD#
// Get Telescope Declination.
// Returns: sDD*MM# or sDD*MM’SS#Depending upon the current precision setting for the telescope.
if (message[0] == ':' && message[1] == 'G' && message[2] == 'D' && message[3] == '#' ||
message[4] == ':' && message[5] == 'G' && message[6] == 'D' && message[7] == '#')
{
receivedLX200message();
sendLX200DEC();
}
// LX200 message :CM#
// Synchronizes the telescope's position with the currently selected database object's coordinates.
// Returns:LX200's - a "#" terminated string with the name of the object that was synced
if (message[0] == ':' && message[1] == 'C' && message[2] == 'M')
{
receivedLX200message();
Serial.print("#");
}
// LX200 message :SrHH:MM.T# or :SrHH:MM:SS#
// Set target object RA to HH:MM.T or HH:MM:SS depending on the current precision setting.
// Returns:0 – Invalid1 - Valid
// output HHMM(S/6)
if (message[0] == ':' && message[1] == 'S' && message[2] == 'r')
{
setRAtoLX200message(message);
}
// LX200 message :SdsDD*MM#
// Set target object declination to sDD*MM or sDD*MM:SS depending on the current precision setting
// Returns:1 - Dec Accepted0 – Dec invalid
// output sHHMM
if (message[0] == ':' && message[1] == 'S' && message[2] == 'd')
{
setDECtoLX200message(message);
}
// Serial.print("BT message "); // for debugging
// Serial.println(message);
}
}
// set RA coordinates of placeholder externalobject to received LX200 message
void setRAtoLX200message(char message[10])
{
externalObject.objectRA =
long(atoi(message + 3)) * 1000 + // HH // access at array different when using atoi - use address
long(atoi(message + 6)) * 10; // MM - Minuten passen noch nicht bei zweistelligen gibt es Fehler
if (message[8] == ':') // : or .
{
externalObject.objectRA = externalObject.objectRA +
long(atoi(message + 9)) / 6; // SS/6
}
else if (message[8] == '.')
{
externalObject.objectRA = externalObject.objectRA + atoi(message + 9); // T
}
Serial.println(); // leave this command, as otherwise no update on goto from LX200 source
}
// set DEC coordinates of placeholder externalobject to received LX200 message & update the (reference or target) object
void setDECtoLX200message(char message[9])
{
int sign;
if (message[3] == '-') sign = -1;
else sign = 1;
externalObject.objectDEC =
sign * ( // s
long(atoi(message + 4)) * 100 + // DD
long(atoi(message + 7))); // MM
// assumption - first RA then DEC - then set target to external object
if (myDisplayMode == 3 || myDisplayMode == 11) // if view shows reference selection or current position then copy external object into reference object
{
externalObject.objectTypeMagnitude = 168;
myReference = externalObject; // copy external object to my reference object
setReferenceRA_DEC();
resetSensorTime();
}
else // in all other cases copy to target
{
externalObject.objectTypeMagnitude = 182;
myTarget = externalObject; // copy external object to my target object
setTargetRA_DEC();
}
updateLCD();
}
// send current RA coordinate of telescope from SpotNik to LX200 server (e.g. Sky Safari)
void sendLX200RA()
{
byte s = (abs(myCurrentRAsec)) % 60; // Das Zeichen: "%" ist der Modulo-Operator
byte m = (abs(myCurrentRAsec / 60)) % 60;
byte h = (abs(myCurrentRAsec / 3600)) % 24;
String posString = "";
if (h < 10) posString = "0";
posString = posString + String(h);
posString = posString + ":";
if (m < 10) posString = posString + "0";
posString = posString + String(m);
posString = posString + ":";
if (s < 10) posString = posString + "0";
posString = posString + String(s);
posString = posString + "#";
Serial.print(posString);
}
// send current DEC coordinate of telescope from SpotNik to LX200 server (e.g. Sky Safari)
void sendLX200DEC()
{
byte s = (abs(myCurrentDECsec)) % 60; // Das Zeichen: "%" ist der Modulo-Operator
byte m = (abs(myCurrentDECsec / 60)) % 60;
byte h = (abs(myCurrentDECsec / 3600)) % 180;
String posString = "";
if (myCurrentDECsec > 0) posString = "+";
else posString = "-";
if (h < 10) posString = "0";
posString = posString + String(h);
posString = posString + "*";
if (m < 10) posString = posString + "0";
posString = posString + String(m);
posString = posString + "#";
Serial.print(posString);
}
//###############################################################################################################
// \LX200 communication
//###############################################################################################################
//###############################################################################################################
// EEPROM
//###############################################################################################################
// save relevant data for next startup (e.g. target no,LCD brightness)
void saveSettingsToEeprom()
{
// Serial.print(F("freeMemory()=")); //only used for testing
// Serial.println(freeMemory());
byte addr = EEPROM_VALUE_ADDR_SIGNATURE;
byte myTargetNoLowByte = lowByte(myTargetNo); // myTargetNo is of type int - transfer into two bytes
byte myTargetNoHighByte = highByte(myTargetNo);
byte myReferenceNoLowByte = lowByte(myRefNo); // myTargetNo is of type int - transfer into two bytes
byte myReferenceNoHighByte = highByte(myRefNo);
EEPROM.update(addr, EEPROM_SIGNATURE); // use update for longer eeprom life
addr += sizeof(EEPROM_SIGNATURE);
EEPROM.update(addr, myReferenceNoLowByte);
addr += sizeof(myReferenceNoLowByte);
EEPROM.update(addr, myReferenceNoHighByte);
addr += sizeof(myReferenceNoHighByte);
EEPROM.update(addr, myTargetNoLowByte);
addr += sizeof(myTargetNoLowByte);
EEPROM.update(addr, myTargetNoHighByte);
addr += sizeof(myTargetNoHighByte);
EEPROM.update(addr, myRegionNo);
addr += sizeof(myRegionNo);
EEPROM.update(addr, myConstellationNo);
addr += sizeof(myConstellationNo);
EEPROM.update(addr, myLCDbacklight);
addr += sizeof(myLCDbacklight);
EEPROM.update(addr, myLCDcontrast);
}
// load relevant data at startup (e.g. target no, LCD brightness)
void getSettingsFromEeprom()
{
byte addr = EEPROM_VALUE_ADDR_SIGNATURE, signature = 0, value, myReferenceNoLowByte, myReferenceNoHighByte, myTargetNoLowByte, myTargetNoHighByte; // myTargetNo is of type int,need to concatenated from two bytes
EEPROM.get(addr, signature);
if (signature != EEPROM_SIGNATURE) return; // maybe data from another sketch
addr += sizeof(EEPROM_SIGNATURE);
EEPROM.get(addr, value);
myReferenceNoLowByte = value;
addr += sizeof(myReferenceNoLowByte);
EEPROM.get(addr, value);
myReferenceNoHighByte = value;
if (value >= 0 && value <= 32767) myRefNo = word(myReferenceNoHighByte, myReferenceNoLowByte);
addr += sizeof(myReferenceNoHighByte);
EEPROM.get(addr, value);
myTargetNoLowByte = value;
addr += sizeof(myTargetNoLowByte);
EEPROM.get(addr, value);
myTargetNoHighByte = value;
if (value >= 0 && value <= 32767) myTargetNo = word(myTargetNoHighByte, myTargetNoLowByte);
addr += sizeof(myTargetNoHighByte);
EEPROM.get(addr, value);
if (value >= 0 && value <= 255) myRegionNo = value;
addr += sizeof(myRegionNo);
EEPROM.get(addr, value);
if (value >= 0 && value <= 255) myConstellationNo = value;
addr += sizeof(myConstellationNo);
EEPROM.get(addr, value);
if (value >= 0 && value <= 255) myLCDbacklight = value;
addr += sizeof(myLCDbacklight);
EEPROM.get(addr, value);
if (value >= 0 && value <= 255) myLCDcontrast = value;
}
//###############################################################################################################
// \EEPROM
//###############################################################################################################put your setup code here, to run once:
}
void loop() {
// put your main code here, to run repeatedly:
}
And here's the latest error message compilation...
The sketch name had to be modified.
Sketch names must start with a letter or number, followed by letters,
numbers, dashes, dots and underscores. Maximum length is 63 characters.
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\spotnik_thursday\spotnik_thursday.ino: In function 'void setup()':
spotnik_thursday:3:3: error: 'SpotNik' was not declared in this scope
SpotNik - by Max Reinecke
^~~~~~~
spotnik_thursday:3:13: error: 'by' was not declared in this scope
SpotNik - by Max Reinecke
^~
spotnik_thursday:12:38: error: 'without' was not declared in this scope
but WITHOUT ANY WARRANTY; without even the implied warranty of
^~~~~~~
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\spotnik_thursday\spotnik_thursday.ino:12:38: note: suggested alternative: 'stdout'
but WITHOUT ANY WARRANTY; without even the implied warranty of
^~~~~~~
stdout
In file included from C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\spotnik_thursday\spotnik_thursday.ino:29:0:
\\admin-che\c$\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\EEPROM\src/EEPROM.h:130:5: error: invalid declaration of member template in local class
template< typename T > T &get( int idx, T &t ){
^~~~~~~~
\\admin-che\c$\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\EEPROM\src/EEPROM.h:137:5: error: invalid declaration of member template in local class
template< typename T > const T &put( int idx, const T &t ){
^~~~~~~~
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\spotnik_thursday\spotnik_thursday.ino:1495:3: warning: narrowing conversion of '129989' from 'long int' to 'unsigned int' inside { } [-Wnarrowing]
};
^
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\spotnik_thursday\spotnik_thursday.ino:1495:3: warning: large integer implicitly truncated to unsigned type [-Woverflow]
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\spotnik_thursday\spotnik_thursday.ino:1495:3: warning: narrowing conversion of '189256' from 'long int' to 'unsigned int' inside { } [-Wnarrowing]
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\spotnik_thursday\spotnik_thursday.ino:1495:3: warning: large integer implicitly truncated to unsigned type [-Woverflow]
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\spotnik_thursday\spotnik_thursday.ino:1495:3: warning: narrowing conversion of '106516' from 'long int' to 'unsigned int' inside { } [-Wnarrowing]
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\spotnik_thursday\spotnik_thursday.ino:1495:3: warning: large integer implicitly truncated to unsigned type [-Woverflow]
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\spotnik_thursday\spotnik_thursday.ino:1495:3: warning: narrowing conversion of '109003' from 'long int' to 'unsigned int' inside { } [-Wnarrowing]
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\spotnik_thursday\spotnik_thursday.ino:1495:3: warning: large integer implicitly truncated to unsigned type [-Woverflow]
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\spotnik_thursday\spotnik_thursday.ino:1495:3: warning: narrowing conversion of '128396' from 'long int' to 'unsigned int' inside { } [-Wnarrowing]
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\spotnik_thursday\spotnik_thursday.ino:1495:3: warning: large integer implicitly truncated to unsigned type [-Woverflow]
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\spotnik_thursday\spotnik_thursday.ino:1495:3: warning: narrowing conversion of '113801' from 'long int' to 'unsigned int' inside { } [-Wnarrowing]
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\spotnik_thursday\spotnik_thursday.ino:1495:3: warning: large integer implicitly truncated to unsigned type [-Woverflow]
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\spotnik_thursday\spotnik_thursday.ino:1495:3: warning: narrowing conversion of '157721' from 'long int' to 'unsigned int' inside { } [-Wnarrowing]
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\spotnik_thursday\spotnik_thursday.ino:1495:3: warning: large integer implicitly truncated to unsigned type [-Woverflow]
spotnik_thursday:1518:3: error: 'LiquidCrystal' was not declared in this scope
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
^~~~~~~~~~~~~
C:\users\hendersonc\OneDrive - St. Mary Redcliffe and Temple School\Documents\Arduino\spotnik_thursday\spotnik_thursday.ino:1518:3: note: suggested alternative: 'LiquidCrystal_h'
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
^~~~~~~~~~~~~
LiquidCrystal_h
spotnik_thursday:1780:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:1799:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:1808:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:1820:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:1843:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:1859:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:1884:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:1902:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:1933:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:1952:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:1971:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:1997:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:2003:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:2009:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:2016:3: error: a function-definition is not allowed here before '{' token
{
^Use code tags to format code for the forum
spotnik_thursday:2025:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:2033:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:2039:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:2047:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:2055:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:2063:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:2078:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:2088:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:2097:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:2104:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:2119:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:2130:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:2136:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:2150:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:2193:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:2212:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:2356:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:2404:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:2436:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:2468:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:2490:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:2517:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:2527:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:2533:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:2539:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:2683:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:2709:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:2818:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:2827:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:2835:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:2844:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:2869:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:2894:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:2900:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:2966:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:2985:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:3014:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:3034:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:3060:3: error: a function-definition is not allowed here before '{' token
{
^
spotnik_thursday:3091:3: error: a function-definition is not allowed here before '{' token
{
^
exit status 1
'SpotNik' was not declared in this scope
```Use code tags to format code for the forum
That is not a copy of what @david_2018 posted
The first line of his sketch in post #10 is the start of a block comment. The first line of what you say is a copy of it is
void setup() {
Hi @hendyhenderson. It seems the problems you are experiencing stem from you attempting to copy the code from the GitHub website, then paste it into Arduino IDE. You are ending up corrupting the by fumbling during that procedure.
I recommend starting fresh, but this time just download the file from GitHub, so that you are working with the exact code created by the author. This will leave less opportunities for you to mess up the code. I'll provide instructions you can follow to do that:
- Click the following link to open the GitHub page for the sketch file:
https://github.com/surfer-max/SpotNik/blob/main/spotnik.ino - Click the downward pointing arrow icon ("Download raw file") at the right side of the toolbar:
- Wait for the download to finish.
- Start Arduino IDE if it is not already running.
- Select File > Open... from the Arduino IDE menus.
The "Open" dialog will open. - Select the downloaded
spotnik.inoin the dialog.
The "Moving" dialog will open:The file "spotnik.ino" needs to be inside a sketch folder named "spotnik".
Create this folder, move the file, and continue? - Click the "OK" button in the "Moving" dialog.
The "spotnik" sketch will open in a new Arduino IDE window.
Now try compiling that "spotnik" sketch. Hopefully everything will work as expected this time.
