глюк в подсчете прерываний. НАВЕДЕНКА?
- Войдите на сайт для отправки комментариев
Добрый день!
Есть программа, считающая кол-во прерываний на двух пинах (назовем их входы А и В)на плате ардуино УНО. При запросе по смс (модуль А6) необходимо в ответном смс отправить количество прерываний в десятках (например, если было 37 прерываний, то нужно отправить в ответ 3.7).
Для тестирования стабильности и правильности работы gsm-модуля и программы в целом (пока что без учета прерываний, т.е к пинам 2, 3 ничего не было подключено) ввел некоторые значения А, В (чтобы в ответном смс приходило будто произошло 72 и 51 прерывание соответственно). В первые пару часов отправлял периодически смс и получал в ответ как и положено А=7.2, В=5.1 (4 раза отправлял смс и получал верные значения), но через несколько часов работы (часов через 8-10) отправил смс и в ответ получил А=0,1, В=5.1 (напомню, что к пинам 2, 3 ничего не было поключено. Даже если бы и было подключено, то А уменьшаться не должно было никак, только если увеличиваться).
Как могло такое получиться?
Возможно наведенка ( ардуинка и gsm-модем все это время лежали около жк телевизора и домашнего стационарного телефона, могли ли они превнести помехи и исказить показания значений? Для более точного представления отмечу, что телевизор работал часто из этого периода времени, а телефон не звонил ни разу)?
скетч на всякий случай прикрепляю:
#include <AltSoftSerial.h> //8,9 rx,tx const int nN = 1;///количество номеров//////////////////////////////////////////////////////////////////// char* trueNum[] = { "+79xxxxxxxx"//,//1 //"+79xxxxxхххх" //2 }; const char* Name[] = { "kol-vo: "//, //"kol-vo: " }; String val = ""; String str = ""; boolean ok = false; volatile float A=7.20; volatile float A_celoe=0.00; volatile float kol_A=0.00; volatile float B=5.10; volatile float B_celoe=0.00; volatile float kol_B=0.00; AltSoftSerial altSerial; void setup() { Serial.begin(9600); do { altSerial.begin(115200); delay(200); altSerial.println(F("ATZ+IPR=9600")); delay(500); altSerial.end(); delay(200); altSerial.begin(9600); delay(200); altSerial.println(F("ATE 0"));//отключаем эхо delay(200); altSerial.println(F("AT")); delay(200); str = ""; while (altSerial.available()) { char ch = altSerial.read(); str += ch; delay(5); } if (str.indexOf(F("OK")) > -1) { ok = true; Serial.println("IPR:9600 OK"); delay(200); altSerial.println(F("AT+CNMI=2,2")); delay(200); altSerial.println(F("AT+CMGF=1")); delay(200); } else { altSerial.end(); delay(500); ok = false; Serial.println("IPR not 9600"); } } while (ok==false); delay(5000); ////////////////////////////////////////////////////////////////// attachInterrupt(1, blink_A, RISING); attachInterrupt(0, blink_B, RISING); ////////////////////////////////////////////////////////////////// } void loop() { ///если что то пришло, читаем if (altSerial.available()) { delay(5); char ch = altSerial.read(); val += char(ch); } for (int i = 0; i < nN; i++) { if (val.indexOf(trueNum[i]) > -1 && val.indexOf("sendme") > -1) { Serial.write("nashe sms"); Serial.println(val); smsSend(trueNum[i], String(Name[i]) + "A= " + String(A) + ", B" + String(B)); } } ///////////////////////////////////// //затираем переменную после отправки смс//// if (val.indexOf("CMGS:") > -1) { val = ""; } ////////////////////////////////////// } void smsSend(char tel[12], String text){ altSerial.print("AT+CMGS=\""); delay(200); for(int i = 0; i < 12; i++)altSerial.write(tel[i]); delay(300); altSerial.print(char(34)); delay(200); altSerial.write(0x0D); delay(100); altSerial.print(text); delay(300); altSerial.println(char(26)); delay(50); val = ""; delay(50); Serial.println("sms otpravleno"); } //////////////////////////////////////////////////////////////////// void blink_A() { delay(100); if (digitalRead(3) == HIGH) { kol_A+=1.00; A= A_celoe+kol_A/10.00; if (kol_A == 10.00) { kol_A=0.00; A_celoe++; } } } void blink_B() { delay(100); if (digitalRead(2) == HIGH) { kol_B+=1.00; B= B_celoe+kol_B/10.00; if (kol_B == 10.00) kol_B=0.00; B_celoe++; } } }
Ниже цитата с ЭТОГО сайта, того, на котором мы находимся. НА РУССКОМ ЯЗЫКЕ!
...
Замечание по использованию
Внутри функции обработки прерывания не работает delay(), значения возвращаемые millis() не изменяются. Возможна потеря данный передаваемых по последовательному соединению (Serial data) в момент выполнения функциии обработки прерывания. Переменные, изменяемые в функции, должным быть объявлены как volatile.
Спасибо за ответ!
Я начинаю только изучать программирование на ардуино, поэтому иногда глупые ошибки..
По поводу ответа (цитаты): я так понял, что потеря данных возможна лишь при выполнении выполнении функций blink_A и blink_B, но в моем эксперименте не было прерываний никаких (к пинам 2, 3 не было подключено ничего), если бы были блинки, то да, можно было бы смело сказать , что это причина неверных данных. delay из кода (в blink'ах) уберу, они просто не будут выполняться , но на работу программы никак не влияют (от этих выдержек времени глюков в программе возникнуть не может).
Вопрос, на мой взгляд, остался актуальным.
Ну и сразу на будущее вопрос в связи с преведенной выше цитатой: как можно избежать (программно или аппаратно) потери данных при передаче данных через сериал порт при выполнении фунции прерывания?