Arduino подсчет импульсов от Меркурий 201

Тема в разделе "Arduino & Shields", создана пользователем Goerg, 18 сен 2014.

  1. ImrDuke

    ImrDuke Гик

    Данные отправляются приложению Blynk
    [​IMG]
     
  2. ImrDuke

    ImrDuke Гик

    Код (C++):
    //Загрузчик от Arduino UNO
    #include <DallasTemperature.h>
    #include <EEPROMex.h>
    #include <nRF24L01.h>
    #include <avr/wdt.h>
    #include <OneWire.h>
    #include <RF24.h>
    #include <SPI.h>

    //--------------------- НАСТРОЙКИ -------------------------------
    #define DeviceID  3             // Номер устройства
    #define btnBlink  2             // Вход датчика электросчетчика
    #define btnAlarm  3             // Вход датчика охраны
    #define tempPIN   4             // Датчик температуры
    #define ctrPIN    5             // Управление реле
    #define CH_NUM    0x5e          // Номер канала (должен совпадать с приёмником)
    #define SIG_POWER RF24_PA_MAX   // УРОВЕНЬ МОЩНОСТИ RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX
    #define SIG_SPEED RF24_1MBPS    // СКОРОСТЬ ОБМЕНА RF24_2MBPS, RF24_1MBPS, RF24_250KBPS
    //--------------------- НАСТРОЙКИ -------------------------------
    RF24 radio(9, 10);              // "Создать" модуль CE-PIN9;CSN-PIN10;SCK-PIN13;MOSI-PIN11;MISO-PIN12
    uint32_t Received_Data[6];      // Массив принятых данных;
    uint32_t Transmit_Data[6];      // Массив, хранящий передаваемые данные;
    const uint64_t Pipe_Tx = ;
    const uint64_t Pipe_Rx = ;

    OneWire oneWire(tempPIN);            // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
    DallasTemperature sensors(&oneWire); // Pass our oneWire reference to Dallas Temperature.
    DeviceAddress insideThermometer;     // arrays to hold device address

    float tempC = 0;
    volatile unsigned int state    = 3200;
    volatile unsigned int blinkMin = 0;
    unsigned int  Wm  = 0;
    unsigned int  kWh = 0;
    unsigned long ms  = 0;
    unsigned long ms1 = 0;
    unsigned long ms2 = 0;
    unsigned long cnt = 0;                    // Счетчик 1 секундных тактов
    int p;
    int p2;

    void setup() {
      wdt_disable();
      //Serial.begin(9600);                   // Инициируем порт отладки
      Serial.println("Start!");
      byte pin;
      switch (btnBlink) {
        case 2: pin = 0;
          break;
        case 3: pin = 1;
          break;
      }
      pinMode(btnBlink, INPUT_PULLUP);        // Пин D2/D3 подтянут к Vcc
      attachInterrupt(pin, Blink, RISING);    // Arduino Uno цифровые пины 2 (int 0) и 3 (int 1)
      pinMode(ctrPIN, OUTPUT);                // Инициируем выход управления
      digitalWrite(ctrPIN, HIGH);             // Включить питание устройства
      //EEPROM.writeInt(1, 994);              // Запись начального показания эл.счетчика
      kWh = EEPROM.readInt(1);                // Читаем показания электросчетчика из EEPROM
      RadioSetup();                           // Настройки радиомодуля

      Serial.print("Locating devices..."); // locate devices on the bus
      sensors.begin();
      Serial.print("Found ");
      Serial.print(sensors.getDeviceCount(), DEC);
      Serial.println(" devices.");
      Serial.print("Parasite power is: ");  // report parasite power requirements
      if (sensors.isParasitePowerMode())
        Serial.println("ON");
      else
        Serial.println("OFF");
      if (!sensors.getAddress(insideThermometer, 0))
        Serial.println("Unable to find address for Device 0");
      Serial.print("Device 0 Address: ");
      printAddress(insideThermometer);
      Serial.println();
      // set the resolution to 9 bit (Each Dallas/Maxim device is capable of several different resolutions)
      sensors.setResolution(insideThermometer, 9);
      Serial.print("Device 0 Resolution: ");
      Serial.print(sensors.getResolution(insideThermometer), DEC);
      Serial.println();

      wdt_enable (WDTO_8S);
    }

    void loop() {
      ms = millis();
      p = ms - ms1;
      if ( p < 0 || p > 1000 ) {  // Проверка, что прошло не менее 1 сек
        cnt++;
        if ( cnt % 60 == 0 ) {    // Каждые 60 секунд отправка данных
          Wm = blinkMin;
          blinkMin = 0;
          Transmit(0);
        }
        ms1 = ms;
      }
      wdt_reset();
    }

    void Blink() {
      state--;
      if (state == 0 || state > 3200) {
        kWh++;
        EEPROM.writeInt(1, kWh); //Записываем текущее показание электросчетчика
        state = 3200;
      }
      blinkMin++;
    }

    void Transmit(boolean _Flag) {
      noInterrupts();
      radio.powerUp();                                       // Включить передатчик
      radio.stopListening();                                 // не слушаем радиоэфир, мы передатчик
      delayMicroseconds(128);
      p2 = millis() - ms2;
      if ( p2 < 0 || p2 > 300000 ) {                         // Проверка, что прошло не менее 300 сек (5 мин)
        sensors.requestTemperatures();                       // Запрос температуры
        tempC = sensors.getTempC(insideThermometer);
        ms2 = millis();
      }
      memset(Transmit_Data, 0, sizeof(Transmit_Data));       // Обнуляем массив
      Transmit_Data[0] = DeviceID;                           // Номер устройства
      Transmit_Data[1] = kWh;                                // Показание эл.счетчика кВт⋅ч
      Transmit_Data[2] = Wm;                                 // Текущее потребление Вт⋅мин
      Transmit_Data[3] = (float)tempC * 100;                 // Температура
      Transmit_Data[4] = _Flag;                              // Геркон
      Transmit_Data[5] = 0;                                  // Реле
      radio.flush_tx();
      radio.write(&Transmit_Data, sizeof(Transmit_Data));    // Отправить по радио
      radio.startListening();                                // начинаем слушать эфир, мы приёмный модуль
      delayMicroseconds(128);
      interrupts();
    }

    void RadioSetup() {
      radio.begin();                         // Активировать модуль
      radio.setCRCLength(RF24_CRC_16);       // Использовать CRC-16
      radio.setAutoAck(true);                // Режим подтверждения приёма
      radio.setRetries(15, 15);              // Время между попыткой достучаться, число попыток
      radio.setPayloadSize(32);              // Размер пакета, в байтах
      radio.openWritingPipe(Pipe_Tx);        // Открываем канал для передачи данных
      radio.openReadingPipe(1, Pipe_Rx);     //
      radio.setChannel(CH_NUM);              // Выбираем канал (в котором нет шумов!)
      radio.setPALevel(SIG_POWER);           // УРОВЕНЬ МОЩНОСТИ RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX
      radio.setDataRate(SIG_SPEED);          // СКОРОСТЬ ОБМЕНА RF24_2MBPS, RF24_1MBPS, RF24_250KBPS
      radio.powerUp();                       // Начать работу
      radio.stopListening();                 // Не слушаем радиоэфир, мы передатчик
      delayMicroseconds(128);
    }

    int Vbg() {
      ADMUX = (1 << REFS0) | (0 << REFS1) | (1 << MUX3) | (1 << MUX2) | (1 << MUX1) | (0 << MUX0);
      long buffersamp = 0;
      for (int n = 0x0; n <= 0xff; n++ ) {
        ADCSRA |= (1 << ADSC) | (1 << ADEN); //Starts a new conversion
        while (bit_is_set(ADCSRA, ADSC));
        buffersamp += ADC;
      }
      buffersamp >>= 4; //16368 full scale 14bit
      ADCSRA &= ~(1 << ADEN);  // отключаем АЦП
      return buffersamp;
    }

    void printAddress(DeviceAddress deviceAddress) { // function to print a device address
      for (uint8_t i = 0; i < 8; i++)   {
        if (deviceAddress[i] < 16)
          Serial.print("0");
        Serial.print(deviceAddress[i], HEX);
      }
    }