СМС отправка кол-ва импульсов

eleberet
Offline
Зарегистрирован: 02.11.2016

Здравствуйте уважаемые знатоки

Есть такая задача: при получении входящего вызова на сим, ардуино начинает считать кол-во импульсов (реле) в течении 10 секунд. Затем подсчитанное колличество отправляется в ответном СМС сообщении.

Есть такой вот скетч, и терзают сомнения по поводу его правильности. При проверке СМС приходит пустая, да и в мониторе импульсы (щелкаю тактовой кнопкой) не совпадают.

Плата Arduino Leonardo + GPRS shield от амперки

#include <GPRS_Shield_Arduino.h>
#include <SoftwareSerial.h>
#include <MsTimer2.h>

volatile int colImp = 0;   // Счетчик импульсов
volatile int T = 0;       
const int ledPin = 3;     // Подаю импульсы на 3 ножку

#define PHONE_NUMBER  "+70000000000" // номер на который будем отправлять сообщение
 
GPRS gprs;
void setup()
{
  pinMode(ledPin, INPUT);
  digitalWrite(ledPin, HIGH);          // Сомневаюсь что нужно HIGH или LOW. подтягивающего резистора на кнопке нет
  attachInterrupt(0, D2Int, RISING);   // Прерывание по приходу импульса
  MsTimer2::set(10000, flash);         // 10000 ms  = 10 s
     
  
  gprs.powerUpDown();        // включаем GPRS шилд
  Serial.begin(9600);        // открываем последовательный порт для мониторинга действий в программе
  while (!Serial) {}         // ждем открытия монитора
  while (!gprs.init())       // проверяем есть ли связь с GPRS устройством
  {
    // если связи нет, ждём 1 секунду
    // и выводим сообщение об ошибке
    // процесс повторяется в цикле,
    // пока не появится ответ от GPRS устройства
    delay(1000);
    Serial.print("Init error\r\n");
  }
  // вывод об удачной инициализации GPRS Shield
  Serial.println("GPRS init success");
  // сообщаем об ожидании звонка
  Serial.println("Wait to call ");
}

void D2Int()
{
  colImp++;    // увеличиваем на 1 колличество импульсов
}

void flash()   //вызывается раз в 10 сек
{
  T = colImp;  // по прошествию 10 сек
  colImp = 0;  //обнуляем колличество накопленных импульсов
}

void loop()
{
  // ожидаем звонка
  if (gprs.ifcallNow()) 
  {
    Serial.println("Incoming call"); // выводим сообщение о входящем вызове
    delay(3000);
    gprs.callEnd();  // по истечении 3 секунд скидываем трубку
	
    MsTimer2::start(); // запускаем таймер который 10 сек считает импульсы
    String MESSAGE = "String"; // здесь я перевожу колво импульсов из int в string
    MESSAGE = String(T, DEC);  // чтобы потом отправить все это по смс
    Serial.println(MESSAGE);  // проверка в мониторе
    Serial.println("Call over. SMS Sending");
    gprs.sendSMS(PHONE_NUMBER, MESSAGE);
    Serial.println("SMS done");
    
  }
}

 

Andy
Andy аватар
Offline
Зарегистрирован: 01.01.2016

eleberet пишет:
в мониторе импульсы (щелкаю тактовой кнопкой) не совпадают.
Дребезг

eleberet
Offline
Зарегистрирован: 02.11.2016

На счет дребезга я думаю влепить небольшую задержку в D2int

	void D2Int()
{
colImp++;    // увеличиваем на 1 колличество импульсов
delay (50);
}

 Больше интересует с 58 строки код, с правильного места ли я стартую таймер и можно ли так переводить число в строку для вывода в смс

    String MESSAGE = "String"; // здесь я перевожу колво импульсов из int в string
    MESSAGE = String(T, DEC);  // чтобы потом отправить все это по смс
    Serial.println(MESSAGE);  // проверка в мониторе
    Serial.println("Call over. SMS Sending");
    gprs.sendSMS(PHONE_NUMBER, MESSAGE);

 

Araris
Offline
Зарегистрирован: 09.11.2012

1. Внутри функции обработки прерывания delay() не работает.

2. http://arduino.ru/Reference/StringConstructor

eleberet
Offline
Зарегистрирован: 02.11.2016

Итак, заменил я значится свою функцию D2Int()  и добавил туда антидребезг

на выходе получилось такое 

void D2Int()
{
    static byte prevButtonState=false;      // состояние кнопки при прошлом проходе loop
    byte buttonState=!digitalRead(ledPin);  // читаем текущие состояние кнопки
    static unsigned long buttonPressTime=0;        // тут будем хранить время нажатия кнопки
    if(!prevButtonState && buttonState && (millis()-buttonPressTime>50)){ // была не нажата, стала нажата и с прошлого нажатия прошло 50ms
     Serial.println("Button Pressed");
    colImp++;    // увеличиваем на 1 колличество импульсов
     buttonPressTime=millis();    // запомнили когда у нас была нажата кнопка
  }
  prevButtonState=buttonState;

все замечательно, считает по +1 при нажатии, НО

кнопку теперь он не считает каждый раз, из 10 нажатий за 5 сек понимает максимум 6, задержку на buttonPressTime менял, эффекта нет. Подскажике где может быть зарыта проблема

p.masyukov
p.masyukov аватар
Offline
Зарегистрирован: 14.11.2015

eleberet пишет:

Итак, заменил я значится свою функцию D2Int()  и добавил туда антидребезг

на выходе получилось такое 

void D2Int()
{
    static byte prevButtonState=false;      // состояние кнопки при прошлом проходе loop
    byte buttonState=!digitalRead(ledPin);  // читаем текущие состояние кнопки
    static unsigned long buttonPressTime=0;        // тут будем хранить время нажатия кнопки
    if(!prevButtonState && buttonState && (millis()-buttonPressTime>50)){ // была не нажата, стала нажата и с прошлого нажатия прошло 50ms
     Serial.println("Button Pressed");
    colImp++;    // увеличиваем на 1 колличество импульсов
     buttonPressTime=millis();    // запомнили когда у нас была нажата кнопка
  }
  prevButtonState=buttonState;

все замечательно, считает по +1 при нажатии, НО

кнопку теперь он не считает каждый раз, из 10 нажатий за 5 сек понимает максимум 6, задержку на buttonPressTime менял, эффекта нет. Подскажике где может быть зарыта проблема

А простой инкремент с флагом состояния не работает? Если включить PULLUP

eleberet
Offline
Зарегистрирован: 02.11.2016

Ну ведь PULLUP это нагрузочный резистор, тоесть входное сопротивление станет 20-50 кОм, как я понимаю, а как это поможет избавиться от дребезга?

p.masyukov
p.masyukov аватар
Offline
Зарегистрирован: 14.11.2015

eleberet пишет:

Ну ведь PULLUP это нагрузочный резистор, тоесть входное сопротивление станет 20-50 кОм, как я понимаю, а как это поможет избавиться от дребезга?

Дребезг убирается задержкой (а тут либо delay() либо millis()), в прерываниях считать то же самое будет - но только можешь пропустить импульсы.

Если так и будет кнопка для подсчета, убери из прерываний и поставь задержки между обновлениями счетчика.

eleberet
Offline
Зарегистрирован: 02.11.2016

Подключил встроенный резистор

   pinMode(ledPin, INPUT);
   igitalWrite(ledPin, HIGH);
   

В loop закинул просто счетчик с задержкой 

 

void loop()
{
  if (digitalRead(ledPin) == HIGH){
  colImp++;
  Serial.println("Click!");
  delay(100);
  }}

В мониторе вижу постоянный "клик", это значит что встроенный резистор не сработал и надо вешать наружний подтягивающий?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Наоборот.

Встроенный резистор поддтягивает только вверх (потому и называется потдтягивающим). Значит, именно он и делает "постоянный "клик"". Запишите if(!digitalRead(ledPin)){...

PS. Кстати, у Вас названия неудачные. Почему ledPin?