Тел. (495) 972-27-12

Энкодеры, Ардуино и планетарий Cartes du Ciel

Обсуждаем Arduino, Raspberry Pi и другие электронные компоненты и проекты DIY

Энкодеры, Ардуино и планетарий Cartes du Ciel

Сообщение Oleg1601 » 08 фев 2016, 20:55

Здравствуйте.
На сайте http://msfastro.net/articles/arduinodsc/ нашел скетч для отображения положения телескопа на карте программы-планетария Cartes du Ciel при помощи энкодеров.
Использую Cartes du Ciel версии 2.76. Всё работает и отображается нормально, но есть одно НО - отключение платы Ардуино от сети (USB) приводит к тому, что при последующем её подключении к компьютеру программа-планетарий Cartes du Ciel её не видит и подключиться к ней (к энкодерам) не может. Для того чтобы Cartes du Ciel увидела энкодеры приходится заново заливать скетч а Ардуино, лишь после этого энкодеры подключаются и всё работает нормально. И так до следующего отключения...
Может, что-то не так со скетчем? Посмотрите пожалуйста.

Вот этот скетч:

Code: [Выделить всё] [Expand/Collapse]
  1.         /*
  2.         Arduino based Digital Setting Circle
  3.        
  4.         Michael Fulbright 2010-06-06
  5.        
  6.         <mike.fulbright at pobox.com>
  7.        
  8.         Feel free to modify and share - please let me know if you make any changes so I can keep my version up to date
  9.        
  10.         2011-08-29: Support for setting encoder resolutions
  11.         2010-06-06: Initial relase - supports 2X encoding
  12.        
  13.         */
  14.        
  15.         // constants won't change. They're used here to
  16.         // set pin numbers:
  17.        
  18.         //#define DEBUG
  19.        
  20.         const int AZ_enc_A = 6; // digital pin 6 = PD6
  21.         const int AZ_enc_B = 7; // digital pin 7 = PD7
  22.        
  23.         const int ALT_enc_A = 9; // digital pin 9 = PB1
  24.         const int ALT_enc_B = 10; // digital pin 10 = PB2
  25.        
  26.         int RES_ALT = 4000; // resolution of encoders
  27.         int RES_AZ = 4000;
  28.        
  29.         byte beenAligned = 0;
  30.        
  31.         long ALT_pos = RES_ALT/2; // initial position of encoders is
  32.         long AZ_pos = RES_AZ/2; // half their resolution
  33.        
  34.         void setup() {
  35.            
  36.             // initialize the encoder inputs
  37.             pinMode(ALT_enc_A, INPUT);
  38.             pinMode(ALT_enc_B, INPUT);
  39.             pinMode(AZ_enc_A, INPUT);
  40.             pinMode(AZ_enc_B, INPUT);
  41.            
  42.             Serial.begin(9600);
  43.            
  44.             // Pin change interrupt control register - enables interrupt vectors
  45.             // Bit 2 = enable PC vector 2 (PCINT23..16)
  46.             // Bit 1 = enable PC vector 1 (PCINT14..8)
  47.             // Bit 0 = enable PC vector 0 (PCINT7..0)
  48.             PCICR |= (1 << PCIE2);
  49.             PCICR |= (1 << PCIE0);
  50.            
  51.             // Pin change mask registers decide which pins are enabled as triggers
  52.             PCMSK2 |= (1 << PCINT23); // arduino pin 7 = PD7 = az encoder A
  53.             PCMSK0 |= (1 << PCINT1); // arduino pin 9 = PB1 = alt encoder A
  54.            
  55.             // enable interrupts
  56.             interrupts();
  57.         }
  58.        
  59.         byte readByte() {
  60.             int nloop=0;
  61.             while (!Serial.available())
  62.             {
  63.                 delay(50);
  64.                
  65.                 if (nloop++ > 20)
  66.                 return 0;
  67.             }
  68.            
  69.             return Serial.read();
  70.         }
  71.        
  72.         void readLine(char *p, int maxlen) {
  73.             int i=0;
  74.             char *s = p;
  75.            
  76.             do
  77.             {
  78.                 *s = readByte();
  79.                
  80.                 if (!*s)
  81.                 return;
  82.                
  83.                 if (*s == '\r')
  84.                 break;
  85.                
  86.                 s++;
  87.             } while (i++ < maxlen-1);
  88.            
  89.             *s = '\0';
  90.         }
  91.        
  92.         void loop(){
  93.            
  94.            
  95.             // see if command sent and reply if appropriate
  96.             //
  97.            
  98.             byte inchar;
  99.             char cmd[80];
  100.            
  101.            
  102.             // throw away rest of command - we don't need it
  103.             //Serial.flush();
  104.            
  105.             inchar = readByte();
  106.            
  107.             if (inchar == 'Q')
  108.             {
  109.                 printEncoderValue(AZ_pos);
  110.                 Serial.print("\t");
  111.                 printEncoderValue(ALT_pos);
  112.                 Serial.print("\r");
  113.             }
  114.             else if (inchar == 'R' || inchar == 'Z' || inchar == 'I')
  115.             {
  116.                 // read to a <CR>
  117.                 readLine(cmd, 79);
  118.                
  119.                 #ifdef DEBUG
  120.                 Serial.println(cmd);
  121.                 #endif
  122.                
  123.                 if (inchar == 'R' || inchar == 'I') {
  124.                     parseSetResolutionCmd(cmd);
  125.                     Serial.print("R");
  126.                 }
  127.                 else if (inchar == 'Z')
  128.                 {
  129.                     parseSetResolutionCmd(cmd);
  130.                     Serial.print("*");
  131.                 }
  132.                
  133.             }
  134.             else if (inchar == 'z')
  135.             {
  136.                 parseEkSetResolutionCmd();
  137.             }
  138.             else if (inchar == 'r' || inchar == 'H')
  139.             {
  140.                 // print out resolution
  141.                 printEncoderValue(RES_AZ);
  142.                 Serial.print("\t");
  143.                 printEncoderValue(RES_ALT);
  144.                 Serial.print("\r");
  145.             }
  146.             else if (inchar == 'V')
  147.             {
  148.                 //version
  149.                 Serial.print("V1.0.0\r");
  150.             }
  151.             else if (inchar == 'T')
  152.             {
  153.                 printEncoderValue(RES_AZ);
  154.                 Serial.print("\t");
  155.                 printEncoderValue(RES_ALT);
  156.                 Serial.print("\t00000\r");
  157.             }
  158.             else if (inchar == 'q')
  159.             {
  160.                 // error count
  161.                 Serial.print("00000\r");
  162.             }
  163.             else if (inchar == 'P')
  164.             {
  165.                 // encoder power up
  166.                 Serial.print("P");
  167.             }
  168.             else if (inchar == 'p')
  169.             {
  170.                 //
  171.                 // dave eks error command
  172.                 Serial.print("00");
  173.             }
  174.             else if (inchar == 'h')
  175.             {
  176.                 // report resolution in Dave Eks format
  177.                 printHexEncoderValue(RES_ALT);
  178.                 printHexEncoderValue(RES_AZ);
  179.             }
  180.             else if (inchar == 'y')
  181.             {
  182.                 // report encoders in Dave Eks format
  183.                 printHexEncoderValue(ALT_pos);
  184.                 printHexEncoderValue(AZ_pos);
  185.             }
  186.             else if (inchar == 'a')
  187.             {
  188.                 if (beenAligned)
  189.                 Serial.print("Y");
  190.                 else
  191.                 Serial.print("N");
  192.             }
  193.             else if (inchar == 'A')
  194.             {
  195.                 beenAligned = 1;
  196.             }
  197.            
  198.             #ifdef DEBUG
  199.             Serial.print(digitalRead(AZ_enc_A));
  200.             Serial.print(" ");
  201.             Serial.print(digitalRead(AZ_enc_B));
  202.             Serial.print(" ");
  203.             Serial.print(digitalRead(ALT_enc_A));
  204.             Serial.print(" ");
  205.             Serial.print(digitalRead(ALT_enc_B));
  206.             Serial.println();
  207.            
  208.             //return;
  209.            
  210.             Serial.print(AZ_pos);
  211.             Serial.print(" ");
  212.             Serial.print(ALT_pos);
  213.             Serial.println();
  214.            
  215.             delay(500);
  216.             #endif
  217.            
  218.            
  219.         }
  220.        
  221.        
  222.         // print encoder value with leading zeros
  223.         void printEncoderValue(long val)
  224.         {
  225.             unsigned long aval;
  226.            
  227.             if (val < 0)
  228.             Serial.print("-");
  229.             else
  230.             Serial.print("+");
  231.            
  232.             aval = abs(val);
  233.            
  234.             if (aval < 10)
  235.             Serial.print("0000");
  236.             else if (aval < 100)
  237.             Serial.print("000");
  238.             else if (aval < 1000)
  239.             Serial.print("00");
  240.             else if (aval < 10000)
  241.             Serial.print("0");
  242.            
  243.             Serial.print(aval);
  244.         }
  245.        
  246.         void printHexEncoderValue(long val)
  247.         {
  248.             byte low, high;
  249.            
  250.             high = val / 256;
  251.            
  252.             low = val - high*256;
  253.            
  254.             Serial.write(low);
  255.             Serial.write(high);
  256.            
  257.             return;
  258.         }
  259.        
  260.         /* string is of format #<tab>#<cr> */
  261.         void parseSetResolutionCmd(char *cmd)
  262.         {
  263.             char *p;
  264.             int altres, azres;
  265.            
  266.             for (p=cmd; *p && *p != '\t'; p++);
  267.            
  268.             /* hit tab */
  269.             if (*p) {
  270.                 *p = '\0';
  271.                
  272.                 azres = atoi(cmd);
  273.                 altres = atoi(p+1);
  274.                
  275.                 #ifdef DEBUG
  276.                 Serial.print(azres);
  277.                 Serial.print(" ");
  278.                 Serial.print(altres);
  279.                 Serial.println();
  280.                 #endif
  281.                
  282.                 RES_ALT = altres;
  283.                 RES_AZ = azres;
  284.             }
  285.         }
  286.        
  287.         void parseEkSetResolutionCmd()
  288.         {
  289.             byte b1 = readByte();
  290.             byte b2 = readByte();
  291.             RES_ALT = b2*256+b1;
  292.            
  293.             b1 = readByte();
  294.             b2 = readByte();
  295.             RES_AZ = b2*256+b1;
  296.            
  297.             //#ifdef DEBUG
  298.             Serial.print(RES_ALT);
  299.             Serial.print(" ");
  300.             Serial.print(RES_AZ);
  301.             Serial.println();
  302.             //#endif
  303.         }
  304.        
  305.         // we have to write our own interrupt vector handler..
  306.         ISR(PCINT2_vect){
  307.            
  308.             if (digitalRead(AZ_enc_A) == digitalRead(AZ_enc_B))
  309.             {
  310.                 AZ_pos++;
  311.                 if (AZ_pos >= RES_AZ)
  312.                 AZ_pos = 0;
  313.             }
  314.             else
  315.             {
  316.                 AZ_pos--;
  317.                
  318.                 if (AZ_pos < 0)
  319.                 AZ_pos = RES_AZ - 1;
  320.             }
  321.         }
  322.        
  323.        
  324.         ISR(PCINT0_vect){
  325.            
  326.             if (digitalRead(ALT_enc_A) == digitalRead(ALT_enc_B))
  327.             {
  328.                 ALT_pos++;
  329.                
  330.                 if (ALT_pos >= RES_ALT)
  331.                 ALT_pos = 0;
  332.             }
  333.             else
  334.             {
  335.                 ALT_pos--;
  336.                
  337.                 if (ALT_pos < 0)
  338.                 ALT_pos = RES_ALT - 1;
  339.             }
  340.            
  341.         }
  342.  
GeSHi © Codebox Plus
Oleg1601
 
Сообщения: 47
Зарегистрирован: 26 апр 2015, 11:25

Re: Энкодеры, Ардуино и планетарий Cartes du Ciel

Сообщение Mr.Kubikus » 10 фев 2016, 00:43

Привет!

Какая модель Arduino у вас используется?
С уважением, Григорий
GitHub FB ВК TW
Аватара пользователя
Mr.Kubikus
Сотрудник ПАКПАК
 
Сообщения: 878
Изображения: 49
Зарегистрирован: 22 окт 2010, 23:57
Откуда: Москва

Re: Энкодеры, Ардуино и планетарий Cartes du Ciel

Сообщение Oleg1601 » 10 фев 2016, 09:15

Mr.Kubikus писал(а):Привет!

Какая модель Arduino у вас используется?

Пробовал этот скетч и на Arduino Uno и на Arduino Nano - результат везде одинаковый.
Oleg1601
 
Сообщения: 47
Зарегистрирован: 26 апр 2015, 11:25

Re: Энкодеры, Ардуино и планетарий Cartes du Ciel

Сообщение Oleg1601 » 14 фев 2016, 17:09

Так что, ни у кого никаких мыслей нет?
Oleg1601
 
Сообщения: 47
Зарегистрирован: 26 апр 2015, 11:25

Re: Энкодеры, Ардуино и планетарий Cartes du Ciel

Сообщение Mr.Kubikus » 15 фев 2016, 16:00

Если просто нажать на RESET на плате ардуино - это не помогает? Обязательно надо заново заливать прошивку?
С уважением, Григорий
GitHub FB ВК TW
Аватара пользователя
Mr.Kubikus
Сотрудник ПАКПАК
 
Сообщения: 878
Изображения: 49
Зарегистрирован: 22 окт 2010, 23:57
Откуда: Москва

Re: Энкодеры, Ардуино и планетарий Cartes du Ciel

Сообщение Oleg1601 » 15 фев 2016, 17:51

Mr.Kubikus писал(а):Если просто нажать на RESET на плате ардуино - это не помогает? Обязательно надо заново заливать прошивку?

Если честно, то так я не пробовал.
Хотя... даже если это и поможет, сама плата будет установлена в корпусе, т.е. до кнопки будет не добраться, разве что сделать выносную...
Oleg1601
 
Сообщения: 47
Зарегистрирован: 26 апр 2015, 11:25

Re: Энкодеры, Ардуино и планетарий Cartes du Ciel

Сообщение Oleg1601 » 20 фев 2016, 08:20

Mr.Kubikus писал(а):Если просто нажать на RESET на плате ардуино - это не помогает? Обязательно надо заново заливать прошивку?

Проверил - не помогает.
Oleg1601
 
Сообщения: 47
Зарегистрирован: 26 апр 2015, 11:25

Re: Энкодеры, Ардуино и планетарий Cartes du Ciel

Сообщение Mr.Kubikus » 22 фев 2016, 06:29

На первый взгляд ничего подозрительного в приведенном коде нет. Сначала настраивается UART и обработка прерываний при изменении состояния на входах, к которым подключены сигналы от энкодеров. Затем циклически выполняется разбор данных поступивших через UART в буфер. В результате разбора данных в зависимости от поступившей команды выполнятся то или иное действие.

Странным выглядит только обращение к функции interrupts(), которая разрешает обработку прерываний, в строке 56. При этом запрета обработки прерываний нигде до этого не было.
С уважением, Григорий
GitHub FB ВК TW
Аватара пользователя
Mr.Kubikus
Сотрудник ПАКПАК
 
Сообщения: 878
Изображения: 49
Зарегистрирован: 22 окт 2010, 23:57
Откуда: Москва

Re: Энкодеры, Ардуино и планетарий Cartes du Ciel

Сообщение Oleg1601 » 22 фев 2016, 11:04

Mr.Kubikus писал(а):Странным выглядит только обращение к функции interrupts(), которая разрешает обработку прерываний, в строке 56. При этом запрета обработки прерываний нигде до этого не было.

Да, действительно странно, ведь по умолчанию, прерывания в Arduino разрешены.
Хотя, читал ( http://robotosha.ru/arduino/arduino-interrupts.html) , что "вы можете включить прерывания внутри обработчика прерываний, если посчитаете, что вам это жизненно необходимо". Но в этой же статье прочел - Не пытайтесь использовать функцию delay. А тут она уже в 63 строке...
Ничего не понял :?
Oleg1601
 
Сообщения: 47
Зарегистрирован: 26 апр 2015, 11:25

Re: Энкодеры, Ардуино и планетарий Cartes du Ciel

Сообщение Oleg1601 » 30 мар 2016, 17:29

Никаких мыслей нет, как решить мой вопрос?
Oleg1601
 
Сообщения: 47
Зарегистрирован: 26 апр 2015, 11:25

След.

Вернуться в Arduino и Ко. ♥♥♥



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1

cron